00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #if !defined(_Object_elf_h_)
00038 #define _Object_elf_h_
00039
00040 #if defined(USES_DWARF_DEBUG)
00041
00042 #include "libdwarf.h"
00043 #include "dwarf/h/dwarfHandle.h"
00044 #endif
00045
00046 #include<vector>
00047 #include "common/h/headers.h"
00048 #include "common/h/Types.h"
00049 #include "common/h/MappedFile.h"
00050 #include "common/h/IntervalTree.h"
00051
00052 #if 0
00053 #include "symtabAPI/h/Symbol.h"
00054 #include "symtabAPI/h/Symtab.h"
00055 #endif
00056
00057
00058 #include <elf.h>
00059 #include <libelf.h>
00060 #include <string>
00061
00062 #include "elf/h/Elf_X.h"
00063
00064 #include <fcntl.h>
00065 #include <stdlib.h>
00066 #include <unistd.h>
00067 #include <set>
00068 #include <sys/types.h>
00069 #include <sys/mman.h>
00070 #include <sys/stat.h>
00071
00072
00073 namespace Dyninst{
00074
00075 namespace Dwarf {
00076 class DwarfFrameParser;
00077 typedef boost::shared_ptr<DwarfFrameParser> DwarfFrameParserPtr;
00078 }
00079
00080 namespace SymtabAPI{
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 struct stab32 {
00093 unsigned int name;
00094 unsigned char type;
00095 unsigned char other;
00096 unsigned short desc;
00097 unsigned int val;
00098
00099 };
00100 struct stab64 {
00101
00102
00103
00104
00105
00106 unsigned int name;
00107 unsigned char type;
00108 unsigned char other;
00109 unsigned short desc;
00110
00111 unsigned int val;
00112
00113 };
00114
00115
00116
00117
00118 class stab_entry {
00119 public:
00120 stab_entry(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
00121 : stabptr(_stabptr), stabstr(_stabstr), nsyms(_nsyms) { }
00122 virtual ~stab_entry() {};
00123
00124 virtual const char *name(int i) = 0;
00125 virtual unsigned long nameIdx(int i) = 0;
00126 virtual unsigned char type(int i) = 0;
00127 virtual unsigned char other(int i) = 0;
00128 virtual unsigned short desc(int i) = 0;
00129 virtual unsigned long val(int i) = 0;
00130
00131 unsigned long count() { return nsyms; }
00132 void setStringBase(const char *ptr) { stabstr = const_cast<char *>(ptr); }
00133 const char *getStringBase() { return stabstr; }
00134
00135 protected:
00136 void *stabptr;
00137 const char *stabstr;
00138 long nsyms;
00139 };
00140
00141 class stab_entry_32 : public stab_entry {
00142 public:
00143 stab_entry_32(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
00144 : stab_entry(_stabptr, _stabstr, _nsyms) { }
00145 virtual ~stab_entry_32() {};
00146
00147 const char *name(int i = 0) {
00148 if (!stabptr) {
00149 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00150 FILE__, __LINE__);
00151 return "bad_name";
00152 }
00153 return stabstr + ((stab32 *)stabptr)[i].name;
00154 }
00155 unsigned long nameIdx(int i = 0) {
00156 if (!stabptr) {
00157 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00158 FILE__, __LINE__);
00159 return 0L;
00160 }
00161 return ((stab32 *)stabptr)[i].name;
00162 }
00163 unsigned char type(int i = 0) {
00164 if (!stabptr) {
00165 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00166 FILE__, __LINE__);
00167 return 0;
00168 }
00169 return ((stab32 *)stabptr)[i].type;
00170 }
00171 unsigned char other(int i = 0) {
00172 if (!stabptr) {
00173 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00174 FILE__, __LINE__);
00175 return 0;
00176 }
00177 return ((stab32 *)stabptr)[i].other;
00178 }
00179 unsigned short desc(int i = 0) {
00180 if (!stabptr) {
00181 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00182 FILE__, __LINE__);
00183 return 0;
00184 }
00185 return ((stab32 *)stabptr)[i].desc;
00186 }
00187 unsigned long val(int i = 0) {
00188 if (!stabptr) {
00189 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00190 FILE__, __LINE__);
00191 return 0L;
00192 }
00193 return ((stab32 *)stabptr)[i].val;
00194 }
00195 };
00196
00197 class stab_entry_64 : public stab_entry {
00198 public:
00199 stab_entry_64(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
00200 : stab_entry(_stabptr, _stabstr, _nsyms) { }
00201 virtual ~stab_entry_64() {};
00202
00203 const char *name(int i = 0) {
00204 if (!stabptr) {
00205 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00206 FILE__, __LINE__);
00207 return "bad_name";
00208 }
00209 return stabstr + ((stab64 *)stabptr)[i].name;
00210 }
00211 unsigned long nameIdx(int i = 0) {
00212 if (!stabptr) {
00213 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00214 FILE__, __LINE__);
00215 return 0L;
00216 }
00217 return ((stab64 *)stabptr)[i].name;
00218 }
00219 unsigned char type(int i = 0) {
00220 if (!stabptr) {
00221 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00222 FILE__, __LINE__);
00223 return 0;
00224 }
00225 return ((stab64 *)stabptr)[i].type;
00226 }
00227 unsigned char other(int i = 0) {
00228 if (!stabptr) {
00229 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00230 FILE__, __LINE__);
00231 return 0;
00232 }
00233 return ((stab64 *)stabptr)[i].other;
00234 }
00235 unsigned short desc(int i = 0) {
00236 if (!stabptr) {
00237 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00238 FILE__, __LINE__);
00239 return 0;
00240 }
00241 return ((stab64 *)stabptr)[i].desc;
00242 }
00243 unsigned long val(int i = 0) {
00244 if (!stabptr) {
00245 fprintf(stderr, "%s[%d]: warning, accessing uninitialized stab_entry\n",
00246 FILE__, __LINE__);
00247 return 0L;
00248 }
00249 return ((stab64 *)stabptr)[i].val;
00250 }
00251 };
00252
00253
00254 #define N_UNDF 0x00
00255 #define N_GSYM 0x20
00256 #define N_FUN 0x24
00257 #define N_STSYM 0x26
00258 #define N_LCSYM 0x28
00259 #define N_ROSYM 0x2c
00260 #define N_OPT 0x3c
00261 #define N_ENDM 0x62
00262 #define N_SO 0x64
00263 #define N_ENTRY 0xa4
00264 #define N_BCOMM 0xe2
00265 #define N_ECOMM 0xe4
00266
00267
00268 #define N_SO_AS 1
00269 #define N_SO_C 2
00270 #define N_SO_ANSI_C 3
00271 #define N_SO_CC 4
00272 #define N_SO_FORTRAN 5
00273 #define N_SO_PASCAL 6
00274 #define N_SO_F90 7
00275
00276
00277 #define N_SLINE 0x44
00278 #define N_SOL 0x84
00279
00280
00281
00282
00283 #define SD_GLOBAL_FUN 'F'
00284 #define SD_PROTOTYPE 'P'
00285 #define SD_GLOBAL_VAR 'G'
00286
00287
00288
00289 class pdElfShdr;
00290
00291 class Symtab;
00292 class Region;
00293 class Object;
00294 class emitElf;
00295 class emitElf64;
00296
00297 class Object : public AObject {
00298 friend class emitElf;
00299 friend class emitElf64;
00300 public:
00301 Object() {}
00302 Object(MappedFile *, bool, void (*)(const char *) = log_msg, bool alloc_syms = true);
00303 Object(MappedFile *, dyn_hash_map<std::string, LineInformation> &, std::vector<Region *> &, void (*)(const char *) = log_msg);
00304 Object(MappedFile *, std::string &member_name, Offset offset,
00305 void (*)(const char *) = log_msg, void *base = NULL, bool alloc_syms = true);
00306 Object(const Object &);
00307 virtual ~Object();
00308
00309
00310 bool emitDriver(Symtab *obj, std::string fName, std::vector<Symbol *>&allSymbols, unsigned flag);
00311
00312 const char *elf_vaddr_to_ptr(Offset vaddr) const;
00313 bool hasStabInfo() const { return ! ( !stab_off_ || !stab_size_ || !stabstr_off_ ); }
00314 bool hasDwarfInfo() const { return dwarvenDebugInfo; }
00315 stab_entry * get_stab_info() const;
00316 const char * getFileName() const { return mf->filename().c_str(); }
00317 void getModuleLanguageInfo(dyn_hash_map<std::string, supportedLanguages> *mod_langs);
00318 void parseFileLineInfo(Symtab *obj, dyn_hash_map<std::string, LineInformation> &li);
00319 void parseTypeInfo(Symtab *obj);
00320
00321 bool needs_function_binding() const { return (plt_addr_ > 0); }
00322 bool get_func_binding_table(std::vector<relocationEntry> &fbt) const;
00323 bool get_func_binding_table_ptr(const std::vector<relocationEntry> *&fbt) const;
00324 void getDependencies(std::vector<std::string> &deps);
00325 std::vector<std::string> &libsRMd();
00326
00327 bool addRelocationEntry(relocationEntry &re);
00328
00329
00330 Offset getLoadAddress() const { return loadAddress_; }
00331
00332 Offset getEntryAddress() const { return entryAddress_; }
00333
00334 Offset getBaseAddress() const { return 0; }
00335 static bool truncateLineFilenames;
00336
00337 void insertPrereqLibrary(std::string libname);
00338 bool removePrereqLibrary(std::string libname);
00339 void insertDynamicEntry(long name, long value);
00340
00341 virtual char *mem_image() const
00342 {
00343 assert(mf);
00344 return (char *)mf->base_addr();
00345 }
00346
00347 SYMTAB_EXPORT ObjectType objType() const;
00348 const char *interpreter_name() const;
00349
00350
00351
00352
00353
00354
00355 Offset getTOCoffset(Offset off) const;
00356
00357
00358
00359 void setTOCoffset(Offset off);
00360
00361 const std::ostream &dump_state_info(std::ostream &s);
00362 bool isEEL() { return EEL; }
00363
00364
00365
00366 bool isinText(Offset addr, Offset baseaddr) const {
00367
00368 if(addr > text_addr_ + baseaddr &&
00369 addr < text_addr_ + baseaddr + text_size_ ) {
00370 return true;
00371 }
00372 return false;
00373 }
00374
00375
00376
00377 Offset getPltSlot(std::string funcName) const ;
00378 Offset textAddress(){ return text_addr_;}
00379 bool isText( Offset addr ) const
00380 {
00381 if( addr >= text_addr_ && addr <= text_addr_ + text_size_ )
00382 return true;
00383 return false;
00384 }
00385
00386 Dyninst::Architecture getArch();
00387
00388 bool is_offset_in_plt(Offset offset) const;
00389 Elf_X_Shdr *getRegionHdrByAddr(Offset addr);
00390 int getRegionHdrIndexByAddr(Offset addr);
00391 Elf_X_Shdr *getRegionHdrByIndex(unsigned index);
00392 bool isRegionPresent(Offset segmentStart, Offset segmentSize, unsigned newPerms);
00393
00394 bool getRegValueAtFrame(Address pc,
00395 Dyninst::MachRegister reg,
00396 Dyninst::MachRegisterVal ®_result,
00397 MemRegReader *reader);
00398 bool hasFrameDebugInfo();
00399
00400 bool convertDebugOffset(Offset off, Offset &new_off);
00401
00402 std::vector< std::vector<Offset> > getMoveSecAddrRange() const {return moveSecAddrRange;};
00403 dyn_hash_map<int, Region*> getTagRegionMapping() const { return secTagRegionMapping;}
00404
00405 bool hasReldyn() const {return hasReldyn_;}
00406 bool hasReladyn() const {return hasReladyn_;}
00407 bool hasRelplt() const {return hasRelplt_;}
00408 bool hasRelaplt() const {return hasRelaplt_;}
00409 bool isBlueGeneP() const {return isBlueGeneP_;}
00410 bool isBlueGeneQ() const {return isBlueGeneQ_;}
00411 bool hasNoteSection() const {return hasNoteSection_;}
00412 Region::RegionType getRelType() const { return relType_; }
00413
00414 Offset getTextAddr() const {return text_addr_;}
00415 Offset getSymtabAddr() const {return symtab_addr_;}
00416 Offset getStrtabAddr() const {return strtab_addr_;}
00417 Offset getDynamicAddr() const {return dynamic_addr_;}
00418 Offset getDynsymSize() const {return dynsym_size_;}
00419 Offset getElfHashAddr() const {return elf_hash_addr_;}
00420 Offset getGnuHashAddr() const {return gnu_hash_addr_;}
00421 Offset getRelPLTAddr() const { return rel_plt_addr_; }
00422 Offset getRelPLTSize() const { return rel_plt_size_; }
00423 Offset getRelDynAddr() const { return rel_addr_; }
00424 Offset getRelDynSize() const { return rel_size_; }
00425
00426 std::vector<relocationEntry> &getPLTRelocs() { return fbt_; }
00427 std::vector<relocationEntry> &getDynRelocs() { return relocation_table_; }
00428
00429 Offset getInitAddr() const {return init_addr_; }
00430 Offset getFiniAddr() const { return fini_addr_; }
00431
00432 virtual void setTruncateLinePaths(bool value);
00433 virtual bool getTruncateLinePaths();
00434
00435 Elf_X * getElfHandle() { return elfHdr; }
00436
00437 unsigned gotSize() const { return got_size_; }
00438 Offset gotAddr() const { return got_addr_; }
00439
00440 SYMTAB_EXPORT virtual void getSegmentsSymReader(std::vector<SymSegment> &segs);
00441
00442 private:
00443 static void log_elferror (void (*)(const char *), const char *);
00444
00445 Elf_X *elfHdr;
00446
00447 std::vector< std::vector<Offset> > moveSecAddrRange;
00448 dyn_hash_map<Offset, int> secAddrTagMapping;
00449 dyn_hash_map<int, unsigned long> secTagSizeMapping;
00450 dyn_hash_map<int, Region*> secTagRegionMapping;
00451
00452 bool hasReldyn_;
00453 bool hasReladyn_;
00454 bool hasRelplt_;
00455 bool hasRelaplt_;
00456 Region::RegionType relType_;
00457
00458 bool isBlueGeneP_;
00459 bool isBlueGeneQ_;
00460 bool hasNoteSection_;
00461
00462 Offset elf_hash_addr_;
00463 Offset gnu_hash_addr_;
00464
00465 Offset dynamic_offset_;
00466 size_t dynamic_size_;
00467 size_t dynsym_size_;
00468 Offset init_addr_;
00469 Offset fini_addr_;
00470 Offset text_addr_;
00471 Offset text_size_;
00472 Offset symtab_addr_;
00473 Offset strtab_addr_;
00474 Offset dynamic_addr_;
00475 Offset dynsym_addr_;
00476 Offset dynstr_addr_;
00477 Offset got_addr_;
00478 unsigned got_size_;
00479 Offset plt_addr_;
00480 unsigned plt_size_;
00481 unsigned plt_entry_size_;
00482 Offset rel_plt_addr_;
00483 unsigned rel_plt_size_;
00484 unsigned rel_plt_entry_size_;
00485 Offset rel_addr_;
00486 unsigned rel_size_;
00487 unsigned rel_entry_size_;
00488 Offset opd_addr_;
00489 unsigned opd_size_;
00490
00491 Offset stab_off_;
00492 unsigned stab_size_;
00493 Offset stabstr_off_;
00494
00495 Offset stab_indx_off_;
00496 unsigned stab_indx_size_;
00497 Offset stabstr_indx_off_;
00498
00499 bool dwarvenDebugInfo;
00500 Offset loadAddress_;
00501
00502 Offset entryAddress_;
00503 char *interpreter_name_;
00504 bool isStripped;
00505
00506 std::map<Offset, Offset> TOC_table_;
00507
00508 public:
00509 Dyninst::Dwarf::DwarfHandle::ptr dwarf;
00510 private:
00511
00512 bool EEL;
00513 bool did_open;
00514 ObjectType obj_type_;
00515
00516
00517
00518
00519
00520
00521
00522
00523 std::vector<relocationEntry> relocation_table_;
00524 std::vector<relocationEntry> fbt_;
00525
00526
00527
00528 std::vector<Elf_X_Shdr*> allRegionHdrs;
00529 std::vector<Elf_X_Shdr*> allRegionHdrsByShndx;
00530
00531
00532 dyn_hash_map<unsigned, std::vector<std::string> >versionMapping;
00533 dyn_hash_map<unsigned, std::string> versionFileNameMapping;
00534
00535 std::vector<std::string> deps_;
00536 std::vector<std::string> rmd_deps;
00537
00538 bool loaded_elf( Offset &, Offset &,
00539 Elf_X_Shdr* &,
00540 Elf_X_Shdr* &, Elf_X_Shdr* &,
00541 Elf_X_Shdr* &, Elf_X_Shdr* &,
00542 Elf_X_Shdr* &, Elf_X_Shdr* &,
00543 Elf_X_Shdr*& rel_plt_scnp, Elf_X_Shdr*& plt_scnp,
00544 Elf_X_Shdr*& got_scnp, Elf_X_Shdr*& dynsym_scnp,
00545 Elf_X_Shdr*& dynstr_scnp, Elf_X_Shdr*& dynamic_scnp, Elf_X_Shdr*& eh_frame,
00546 Elf_X_Shdr*& gcc_except, Elf_X_Shdr *& interp_scnp,
00547 Elf_X_Shdr *&opd_scnp,
00548 bool a_out=false);
00549
00550 Symbol *handle_opd_symbol(Region *opd, Symbol *sym);
00551 void handle_opd_relocations();
00552 void parse_opd(Elf_X_Shdr *);
00553 void parseStabFileLineInfo(Symtab *, dyn_hash_map<std::string, LineInformation> &li);
00554 void parseDwarfFileLineInfo(dyn_hash_map<std::string, LineInformation> &li);
00555
00556 void parseDwarfTypes(Symtab *obj);
00557 void parseStabTypes(Symtab *obj);
00558
00559 void load_object(bool);
00560 void load_shared_object(bool);
00561
00562
00563 bool get_relocation_entries(Elf_X_Shdr *&rel_plt_scnp,
00564 Elf_X_Shdr *&dynsym_scnp,
00565 Elf_X_Shdr *&dynstr_scnp);
00566
00567 bool get_relocationDyn_entries( unsigned rel_index,
00568 Elf_X_Shdr *&dynsym_scnp,
00569 Elf_X_Shdr *&dynstr_scnp );
00570
00571
00572
00573 bool parse_all_relocations(Elf_X &, Elf_X_Shdr *, Elf_X_Shdr *,
00574 Elf_X_Shdr *, Elf_X_Shdr *);
00575
00576 void parseDynamic(Elf_X_Shdr *& dyn_scnp, Elf_X_Shdr *&dynsym_scnp,
00577 Elf_X_Shdr *&dynstr_scnp);
00578
00579 bool parse_symbols(Elf_X_Data &symdata, Elf_X_Data &strdata,
00580 Elf_X_Shdr* bssscnp,
00581 Elf_X_Shdr* symscnp,
00582 bool shared_library,
00583 std::string module);
00584
00585 void parse_dynamicSymbols( Elf_X_Shdr *& dyn_scnp, Elf_X_Data &symdata,
00586 Elf_X_Data &strdata, bool shared_library,
00587 std::string module);
00588
00589 void find_code_and_data(Elf_X &elf,
00590 Offset txtaddr, Offset dataddr);
00591
00592 bool fix_global_symbol_modules_static_stab(Elf_X_Shdr *stabscnp,
00593 Elf_X_Shdr *stabstrscnp);
00594 bool fix_global_symbol_modules_static_dwarf();
00595
00596 void get_valid_memory_areas(Elf_X &elf);
00597
00598 bool find_catch_blocks(Elf_X_Shdr *eh_frame, Elf_X_Shdr *except_scn,
00599 Address textaddr, Address dataaddr,
00600 std::vector<ExceptionBlock> &catch_addrs);
00601
00602 #if defined(USES_DWARF_DEBUG)
00603 std::string find_symbol(std::string name);
00604 bool fixSymbolsInModule(Dwarf_Debug dbg, std::string & moduleName, Dwarf_Die dieEntry);
00605 unsigned fixSymbolsInModuleByRange(IntervalTree<Dwarf_Addr, std::string> &module_ranges);
00606 #endif
00607
00608 public:
00609 struct DbgAddrConversion_t {
00610 DbgAddrConversion_t() : dbg_offset(0x0), dbg_size(0x0), orig_offset(0x0) {}
00611 std::string name;
00612 Offset dbg_offset;
00613 unsigned dbg_size;
00614 Offset orig_offset;
00615 };
00616 private:
00617 bool DbgSectionMapSorted;
00618 std::vector<DbgAddrConversion_t> DebugSectionMap;
00619
00620 public:
00621 std::set<std::string> prereq_libs;
00622 std::vector<std::pair<long, long> > new_dynamic_entries;
00623 };
00624
00625
00626
00627 }
00628 }
00629
00630 #endif