dwarfHandle.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #include "libdwarf.h"
00032 #include "elf/h/Elf_X.h"
00033 #include "dwarf/h/dwarfHandle.h"
00034 #include "dwarf/h/dwarfFrameParser.h"
00035 #include "common/h/debug_common.h"
00036 #include <cstring>
00037 
00038 using namespace Dyninst;
00039 using namespace Dwarf;
00040 using namespace std;
00041 
00042 void DwarfHandle::defaultDwarfError(Dwarf_Error , Dwarf_Ptr) {
00043 
00044 }
00045 
00046 Dwarf_Handler DwarfHandle::defaultErrFunc = DwarfHandle::defaultDwarfError;
00047 
00048 DwarfHandle::DwarfHandle(string filename_, Elf_X *file_,
00049                          Dwarf_Handler err_func_, Dwarf_Ptr err_data_) :
00050    init_dwarf_status(dwarf_status_uninitialized),
00051    dbg_file_data(NULL),
00052    file_data(NULL),
00053    line_data(NULL),
00054    type_data(NULL),
00055    frame_data(NULL),
00056    file(file_),
00057    dbg_file(NULL),
00058    err_func(err_func_),
00059    err_data(err_data_),
00060    filename(filename_)
00061 {
00062 
00063    locate_dbg_file();
00064 }
00065 
00066 void DwarfHandle::locate_dbg_file()
00067 {
00068    char *buffer;
00069    unsigned long buffer_size;
00070    bool result = file->findDebugFile(filename, debug_filename, buffer, buffer_size);
00071    if (!result)
00072       return;
00073    dbg_file = Elf_X::newElf_X(buffer, buffer_size, debug_filename);
00074    if (!dbg_file->isValid()) {
00075       dwarf_printf("Invalid ELF file for debug info: %s\n", debug_filename.c_str());
00076       dbg_file->end();
00077       dbg_file = NULL;
00078    }
00079 }
00080 
00081 bool DwarfHandle::init_dbg()
00082 {
00083    int status;
00084    Dwarf_Error err;
00085    if (init_dwarf_status == dwarf_status_ok) {
00086       return true;
00087    }
00088 
00089    if (init_dwarf_status == dwarf_status_error) {
00090       return false;
00091    }
00092 
00093    status = dwarf_elf_init(file->e_elfp(), DW_DLC_READ, 
00094                            err_func, err_data, &file_data, &err);
00095    if (status != DW_DLV_OK) {
00096       init_dwarf_status = dwarf_status_error;
00097       return false;
00098    }
00099 
00100    if (dbg_file) {
00101       status = dwarf_elf_init(dbg_file->e_elfp(), DW_DLC_READ, 
00102                               err_func, err_data, &dbg_file_data, &err);
00103       if (status != DW_DLV_OK) {
00104          init_dwarf_status = dwarf_status_error;
00105          return false;
00106       }
00107 
00108       //Have a debug file, choose which file to use for different lookups.
00109       line_data = &dbg_file_data;
00110       type_data = &dbg_file_data;
00111 
00112       if (hasFrameData(dbg_file))
00113          frame_data = &dbg_file_data;
00114       else
00115          frame_data = &file_data;
00116    }
00117    else {
00118       //No debug file, take everything from file
00119       line_data = &file_data;
00120       type_data = &file_data;
00121       frame_data = &file_data;
00122    }
00123    
00124    Dyninst::Architecture arch;
00125    switch (file->e_machine()) {
00126       case EM_386:
00127          arch = Arch_x86;
00128          break;
00129       case EM_X86_64:
00130          arch = Arch_x86_64;
00131          break;
00132       case EM_PPC:
00133          arch = Arch_ppc32;
00134          break;
00135       case EM_PPC64:
00136          arch = Arch_ppc64;
00137          break;
00138       default:
00139          assert(0 && "Unsupported archiecture in ELF file.");
00140    }
00141    sw = Dwarf::DwarfFrameParser::create(*frame_data, arch);
00142 
00143    init_dwarf_status = dwarf_status_ok;
00144    return true;
00145 }
00146 
00147 const char* frame_section_names[] = { ".debug_frame", ".eh_frame", NULL };
00148 bool DwarfHandle::hasFrameData(Elf_X *e)
00149 {
00150    unsigned short shstrtab_idx = e->e_shstrndx();
00151    Elf_X_Shdr &shstrtab = e->get_shdr(shstrtab_idx);
00152    if (!shstrtab.isValid())
00153       return false;
00154    Elf_X_Data data = shstrtab.get_data();
00155    if (!data.isValid())
00156       return false;
00157    const char *shnames = data.get_string();
00158 
00159    unsigned short num_sections = e->e_shnum();
00160    for (unsigned i = 0; i < num_sections; i++) {
00161       Elf_X_Shdr &shdr = e->get_shdr(i);
00162       if (!shdr.isValid())
00163          continue;
00164       if (shdr.sh_type() == SHT_NOBITS)
00165          continue;
00166       unsigned long name_idx = shdr.sh_name();
00167       for (const char **s = frame_section_names; *s; s++) {
00168          if (strcmp(*s, shnames + name_idx) == 0) {
00169             return true;
00170          }
00171       }
00172    }
00173    return false;
00174 }
00175 
00176 Elf_X *DwarfHandle::origFile()
00177 {
00178    return file;
00179 }
00180 
00181 Elf_X *DwarfHandle::debugLinkFile()
00182 {
00183    return dbg_file;
00184 }
00185 
00186 Dwarf_Debug *DwarfHandle::line_dbg()
00187 {
00188    if (!init_dbg()) 
00189       return NULL;
00190    return line_data;
00191 }
00192 
00193 Dwarf_Debug *DwarfHandle::type_dbg()
00194 {
00195    if (!init_dbg()) 
00196       return NULL;
00197    return type_data;
00198 }
00199 
00200 Dwarf_Debug *DwarfHandle::frame_dbg()
00201 {
00202    if (!init_dbg()) 
00203       return NULL;
00204    return frame_data;
00205 }
00206 
00207 
00208 DwarfHandle::~DwarfHandle()
00209 {
00210    if (init_dwarf_status != dwarf_status_ok) 
00211       return;
00212 
00213    Dwarf_Error err;
00214    if (dbg_file_data)
00215       dwarf_finish(dbg_file_data, &err);
00216    if (file_data)
00217       dwarf_finish(file_data, &err);
00218 }
00219 
00220 map<std::string, DwarfHandle::ptr> DwarfHandle::all_dwarf_handles;
00221 DwarfHandle::ptr DwarfHandle::createDwarfHandle(string filename_, Elf_X *file_, 
00222                                                 Dwarf_Handler err_func_, Dwarf_Ptr err_data_)
00223 {   
00224    map<string, DwarfHandle::ptr>::iterator i;
00225    i = all_dwarf_handles.find(filename_);
00226    if (i != all_dwarf_handles.end()) {
00227       return i->second;
00228    }
00229    
00230    DwarfHandle::ptr ret = DwarfHandle::ptr(new DwarfHandle(filename_, file_, err_func_, err_data_));
00231    all_dwarf_handles.insert(make_pair(filename_, ret));
00232    return ret;
00233 }
00234 
00235 DwarfFrameParserPtr DwarfHandle::frameParser() { 
00236    return sw;
00237 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1