use dwarf_next_lines to read .debug_line without .debug_info
[dyninst.git] / symtabAPI / src / Object-elf.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 /************************************************************************
32  * $Id: Object-elf.h,v 1.21 2008/06/23 18:45:42 legendre Exp $
33  * Object-elf.h: Object class for ELF file format
34 ************************************************************************/
35
36
37 #if !defined(_Object_elf_h_)
38 #define _Object_elf_h_
39
40 #if defined(cap_dwarf)
41 //#include "dwarf.h"
42 #include "elfutils/libdw.h"
43 #include "dwarfHandle.h"
44 #endif
45
46 #include <vector>
47 #include "headers.h"
48 #include "Types.h"
49 #include "MappedFile.h"
50 #include "IntervalTree.h"
51
52 #include <elf.h>
53 #include <libelf.h>
54 #include <string>
55
56 #include "Elf_X.h"
57
58 #include <fcntl.h>
59 #include <stdlib.h>
60 #include <unistd.h>
61 #include <set>
62 #include <sys/types.h>
63 #include <sys/mman.h>
64 #include <sys/stat.h>
65
66
67 namespace Dyninst{
68
69 namespace DwarfDyninst {
70    class DwarfFrameParser;
71    typedef boost::shared_ptr<DwarfFrameParser> DwarfFrameParserPtr;
72 }
73
74 namespace SymtabAPI{
75 /*
76  * The standard symbol table in an elf file is the .symtab section. This section does
77  * not have information to find the module to which a global symbol belongs, so we must
78  * also read the .stab section to get this info.
79  */
80
81 // Declarations for the .stab section.
82 // These are not declared in any system header files, so we must provide our own
83 // declarations. The declarations below were taken from:
84 //       SPARCWorks 3.0.x Debugger Interface, July 1994
85 // 
86 struct stab32 {
87     unsigned int name;  // stabstr table index for this symbol
88     unsigned char type; // type of this symbol
89     unsigned char other;
90     unsigned short desc;
91     unsigned int val;   // value of this symbol -- usually zero. The real value must
92                         // be obtained from the symtab section
93 };
94 struct stab64 {
95     // XXX ELF stabs are currently not implementing actual 64-bit support
96     //     on AMD-64, for which this separation was introduced. Until we
97     //     start seeing stab records with fields of the appropriate length,
98     //     we should assume the smaller records.
99     //unsigned long name; // stabstr table index for this symbol
100     unsigned int name; // stabstr table index for this symbol
101     unsigned char type; // type of this symbol
102     unsigned char other;
103     unsigned short desc;
104     //unsigned long val;
105     unsigned int val;  // value of this symbol -- usually zero. The real value must
106                         // be obtained from the symtab section
107 };
108
109 // 
110 // Extended to a class for 32/64-bit stab entries at runtime. - Ray
111 // 
112 class stab_entry {
113   public:
114     stab_entry(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
115         : stabptr(_stabptr), stabstr(_stabstr), nsyms(_nsyms) { }
116     virtual ~stab_entry() {};
117
118     virtual const char *name(int i) = 0;
119     virtual unsigned long nameIdx(int i) = 0;
120     virtual unsigned char type(int i) = 0;
121     virtual unsigned char other(int i) = 0;
122     virtual unsigned short desc(int i) = 0;
123     virtual unsigned long val(int i) = 0;
124
125     unsigned long count() { return nsyms; }
126     void setStringBase(const char *ptr) { stabstr = const_cast<char *>(ptr); }
127     const char *getStringBase() { return stabstr; }
128
129   protected:
130     void *stabptr;
131     const char *stabstr;
132     long nsyms;
133 };
134
135 class stab_entry_32 : public stab_entry {
136   public:
137     stab_entry_32(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
138         : stab_entry(_stabptr, _stabstr, _nsyms) { }
139     virtual ~stab_entry_32() {};
140
141     const char *name(int i = 0) { 
142        if (!stabptr) {
143           return "bad_name";
144        }
145        return stabstr + ((stab32 *)stabptr)[i].name; 
146     }
147     unsigned long nameIdx(int i = 0) {
148        if (!stabptr) {
149           return 0L;
150        }
151        return ((stab32 *)stabptr)[i].name; 
152     }
153     unsigned char type(int i = 0) {
154        if (!stabptr) {
155           return 0;
156        }
157        return ((stab32 *)stabptr)[i].type; 
158     }
159     unsigned char other(int i = 0) {
160        if (!stabptr) {
161           return 0;
162        }
163        return ((stab32 *)stabptr)[i].other; 
164     }
165     unsigned short desc(int i = 0) { 
166        if (!stabptr) {
167           return 0;
168        }
169        return ((stab32 *)stabptr)[i].desc; 
170     }
171     unsigned long val(int i = 0) { 
172        if (!stabptr) {
173           return 0L;
174        }
175        return ((stab32 *)stabptr)[i].val; 
176     }
177 };
178
179 class stab_entry_64 : public stab_entry {
180   public:
181     stab_entry_64(void *_stabptr = 0, const char *_stabstr = 0, long _nsyms = 0)
182         : stab_entry(_stabptr, _stabstr, _nsyms) { }
183     virtual ~stab_entry_64() {};
184
185     const char *name(int i = 0) { 
186        if (!stabptr) {
187           return "bad_name";
188        }
189        return stabstr + ((stab64 *)stabptr)[i].name; 
190     }
191     unsigned long nameIdx(int i = 0) {
192        if (!stabptr) {
193           return 0L;
194        }
195        return ((stab64 *)stabptr)[i].name; 
196     }
197     unsigned char type(int i = 0) {
198        if (!stabptr) {
199           return 0;
200        }
201        return ((stab64 *)stabptr)[i].type; 
202     }
203     unsigned char other(int i = 0) { 
204        if (!stabptr) {
205           return 0;
206        }
207        return ((stab64 *)stabptr)[i].other; 
208     }
209     unsigned short desc(int i = 0) { 
210        if (!stabptr) {
211           return 0;
212        }
213        return ((stab64 *)stabptr)[i].desc; 
214     }
215     unsigned long val(int i = 0) { 
216        if (!stabptr) {
217           return 0L;
218        }
219        return ((stab64 *)stabptr)[i].val; 
220     }
221 };
222
223 // Types 
224 #define N_UNDF  0x00 /* start of object file */
225 #define N_GSYM  0x20 /* global symbol */
226 #define N_FUN   0x24 /* function or procedure */
227 #define N_STSYM 0x26 /* initialized static symbol */
228 #define N_LCSYM 0x28 /* unitialized static symbol */
229 #define N_ROSYM 0x2c /* read-only static symbol */
230 #define N_OPT   0x3c /* compiler options */
231 #define N_ENDM  0x62 /* end module */
232 #define N_SO    0x64 /* source directory and file */
233 #define N_ENTRY 0xa4 /* fortran alternate subroutine entry point */
234 #define N_BCOMM 0xe2 /* start fortran named common block */
235 #define N_ECOMM 0xe4 /* start fortran named common block */
236
237 // Language code -- the desc field in a N_SO entry is a language code
238 #define N_SO_AS      1 /* assembler source */
239 #define N_SO_C       2 /* K & R C source */
240 #define N_SO_ANSI_C  3 /* ANSI C source */
241 #define N_SO_CC      4 /* C++ source */
242 #define N_SO_FORTRAN 5 /* fortran source */
243 #define N_SO_PASCAL  6 /* Pascal source */
244 #define N_SO_F90     7 /* Fortran90 source */
245
246 //line information data
247 #define N_SLINE  0x44 /* line number in text segment */
248 #define N_SOL    0x84 /* name of the include file*/
249
250 // Symbol descriptors
251 // The format of a name is "<name>:<symbol descriptor><rest of name>
252 // The following are the descriptors of interest
253 #define SD_GLOBAL_FUN 'F' /* global function or procedure */
254 #define SD_PROTOTYPE  'P'  /* function prototypes */
255 #define SD_GLOBAL_VAR 'G' /* global variable */
256
257 // end of stab declarations
258
259 class pdElfShdr;
260 class Symtab;
261 class Region;
262 class Object;
263
264 class Object : public AObject 
265 {
266   friend class Module;
267
268   // declared but not implemented; no copying allowed
269   Object(const Object &);
270   const Object& operator=(const Object &);
271
272 public:
273
274   Object(MappedFile *, bool, void (*)(const char *) = log_msg, bool alloc_syms = true, Symtab* st = NULL);
275   virtual ~Object();
276
277   bool emitDriver(std::string fName, std::set<Symbol *> &allSymbols, unsigned flag);
278   
279   const char *elf_vaddr_to_ptr(Offset vaddr) const;
280   bool hasStabInfo() const { return ! ( !stab_off_ || !stab_size_ || !stabstr_off_ ); }
281   bool hasDwarfInfo() const { return dwarvenDebugInfo; }
282   stab_entry * get_stab_info() const;
283   std::string getFileName() const;
284   void getModuleLanguageInfo(dyn_hash_map<std::string, supportedLanguages> *mod_langs);
285   void parseFileLineInfo();
286   
287   void parseTypeInfo();
288
289   bool needs_function_binding() const { return (plt_addr_ > 0); } 
290   bool get_func_binding_table(std::vector<relocationEntry> &fbt) const;
291   bool get_func_binding_table_ptr(const std::vector<relocationEntry> *&fbt) const;
292   void getDependencies(std::vector<std::string> &deps);
293   std::vector<std::string> &libsRMd();
294
295   bool addRelocationEntry(relocationEntry &re);
296
297   //getLoadAddress may return 0 on shared objects
298   Offset getLoadAddress() const { return loadAddress_; }
299
300   Offset getEntryAddress() const { return entryAddress_; }
301   // To be changed later - Giri
302   Offset getBaseAddress() const { return 0; }
303   static bool truncateLineFilenames;
304
305   void insertPrereqLibrary(std::string libname);
306   bool removePrereqLibrary(std::string libname);
307   void insertDynamicEntry(long name, long value);
308  
309   virtual char *mem_image() const 
310   {
311      assert(mf);
312      return (char *)mf->base_addr();
313   }
314
315   SYMTAB_EXPORT ObjectType objType() const;
316   const char *interpreter_name() const;
317
318
319   // On most platforms, the TOC offset doesn't exist and is thus null. 
320   // On PPC64, it varies _by function_ and is used to point into the GOT,
321   // a big data table. We can look it up by parsing the OPD, a function
322   // descriptor table. 
323   Offset getTOCoffset(Offset off) const;
324
325   // This is an override for the whole thing; we could do per-function but 
326   // we're missing a _lot_ of hardware for that. 
327   void setTOCoffset(Offset off);
328
329   const std::ostream &dump_state_info(std::ostream &s);
330   bool isEEL() { return EEL; }
331
332         //to determine if a mutation falls in the text section of
333         // a shared library
334         bool isinText(Offset addr, Offset baseaddr) const { 
335                 if(addr > text_addr_ + baseaddr     &&
336                    addr < text_addr_ + baseaddr + text_size_ ) {
337                         return true;
338                 }
339                 return false;
340         } 
341         // to determine where in the .plt this function is listed 
342         // returns an offset from the base address of the object
343         // so the entry can easily be located in memory
344         Offset getPltSlot(std::string funcName) const ;
345         Offset textAddress(){ return text_addr_;}
346         bool isText( Offset addr ) const
347         {
348             if( addr >= text_addr_ && addr <= text_addr_ + text_size_ )
349                 return true;
350             return false;
351         }
352
353    Dyninst::Architecture getArch() const;
354    bool isBigEndianDataEncoding() const;
355    bool getABIVersion(int &major, int &minor) const;
356         bool is_offset_in_plt(Offset offset) const;
357     Elf_X_Shdr *getRegionHdrByAddr(Offset addr);
358     int getRegionHdrIndexByAddr(Offset addr);
359     Elf_X_Shdr *getRegionHdrByIndex(unsigned index);
360     bool isRegionPresent(Offset segmentStart, Offset segmentSize, unsigned newPerms);
361
362     bool getRegValueAtFrame(Address pc, 
363                             Dyninst::MachRegister reg, 
364                             Dyninst::MachRegisterVal &reg_result,
365                             MemRegReader *reader);
366     bool hasFrameDebugInfo();
367     
368     bool convertDebugOffset(Offset off, Offset &new_off);
369
370     std::vector< std::vector<Offset> > getMoveSecAddrRange() const {return moveSecAddrRange;};
371     dyn_hash_map<int, Region*> getTagRegionMapping() const { return secTagRegionMapping;}
372
373     bool hasReldyn() const {return hasReldyn_;}
374     bool hasReladyn() const {return hasReladyn_;}
375     bool hasRelplt() const {return hasRelplt_;}
376     bool hasRelaplt() const {return hasRelaplt_;}
377     bool isBlueGeneP() const {return isBlueGeneP_;}
378     bool isBlueGeneQ() const {return isBlueGeneQ_;}
379     bool hasNoteSection() const {return hasNoteSection_;}
380     Region::RegionType getRelType() const { return relType_; }
381
382     Offset getTextAddr() const {return text_addr_;}
383     Offset getSymtabAddr() const {return symtab_addr_;}
384     Offset getStrtabAddr() const {return strtab_addr_;}
385     Offset getDynamicAddr() const {return dynamic_addr_;}
386     Offset getDynsymSize() const {return dynsym_size_;}
387     Offset getElfHashAddr() const {return elf_hash_addr_;}
388     Offset getGnuHashAddr() const {return gnu_hash_addr_;}
389     Offset getRelPLTAddr() const { return rel_plt_addr_; }
390     Offset getRelPLTSize() const { return rel_plt_size_; }
391     Offset getRelDynAddr() const { return rel_addr_; }
392     Offset getRelDynSize() const { return rel_size_; }
393
394     std::vector<relocationEntry> &getPLTRelocs() { return fbt_; }
395     std::vector<relocationEntry> &getDynRelocs() { return relocation_table_; }
396
397     Offset getInitAddr() const {return init_addr_; }
398     Offset getFiniAddr() const { return fini_addr_; }
399
400     virtual void setTruncateLinePaths(bool value);
401     virtual bool getTruncateLinePaths();
402     
403     Elf_X * getElfHandle() { return elfHdr; }
404
405     unsigned gotSize() const { return got_size_; }
406     Offset gotAddr() const { return got_addr_; }
407
408     SYMTAB_EXPORT virtual void getSegmentsSymReader(std::vector<SymSegment> &segs); 
409
410     private:
411     std::vector<std::vector<boost::shared_ptr<void> > > freeList;
412   static void log_elferror (void (*)(const char *), const char *);
413     
414   Elf_X *elfHdr;
415  
416   std::vector< std::vector<Offset> > moveSecAddrRange;
417   dyn_hash_map<Offset, int> secAddrTagMapping;
418   dyn_hash_map<int, unsigned long> secTagSizeMapping;
419   dyn_hash_map<int, Region*> secTagRegionMapping;
420
421   bool hasReldyn_;
422   bool hasReladyn_;
423   bool hasRelplt_;
424   bool hasRelaplt_;
425   Region::RegionType relType_;
426
427   bool isBlueGeneP_;
428   bool isBlueGeneQ_;
429   bool hasNoteSection_;
430
431   Offset   elf_hash_addr_;       //.hash section 
432   Offset   gnu_hash_addr_;       //.gnu.hash section 
433
434   Offset   dynamic_offset_;
435   size_t   dynamic_size_;
436   size_t   dynsym_size_;
437   Offset   init_addr_;
438   Offset   fini_addr_;
439   Offset   text_addr_;   //.text section 
440   Offset   text_size_;   //.text section size
441   Offset   symtab_addr_;
442   Offset   strtab_addr_;
443   Offset   dynamic_addr_;        //.dynamic section
444   Offset   dynsym_addr_;        // .dynsym section
445   Offset   dynstr_addr_;        // .dynstr section
446   Offset   got_addr_;           // global offset table
447   unsigned got_size_;           // global offset table
448   Offset   plt_addr_;           // procedure linkage table
449   unsigned plt_size_;           // procedure linkage table
450   unsigned plt_entry_size_;     // procedure linkage table
451   Offset   rel_plt_addr_;       // .rel[a].plt section
452   unsigned rel_plt_size_;       // .rel[a].plt section
453   unsigned rel_plt_entry_size_; // .rel[a].plt section
454   Offset    rel_addr_;
455   unsigned  rel_size_;       // DT_REL/DT_RELA in dynamic section
456   unsigned  rel_entry_size_; // DT_REL/DT_RELA in dynamic section
457   Offset   opd_addr_;
458   unsigned opd_size_;
459
460   Offset   stab_off_;           // .stab section
461   unsigned stab_size_;          // .stab section
462   Offset   stabstr_off_;        // .stabstr section
463
464   Offset   stab_indx_off_;       // .stab.index section
465   unsigned  stab_indx_size_;     // .stab.index section
466   Offset   stabstr_indx_off_;    // .stabstr.index section
467
468   bool      dwarvenDebugInfo;    // is DWARF debug info present?
469   Offset   loadAddress_;      // The object may specify a load address
470                                //   Set to 0 if it may load anywhere
471   Offset entryAddress_;
472   char *interpreter_name_;
473   bool  isStripped;
474
475   std::map<Offset, Offset> TOC_table_;
476
477   public:
478   Dyninst::DwarfDyninst::DwarfHandle::ptr dwarf;
479   private:
480
481   bool      EEL;                 // true if EEL rewritten
482   bool      did_open;           // true if the file has been mmapped
483   ObjectType obj_type_;
484
485   // for sparc-solaris this is a table of PLT entry addr, function_name
486   // for x86-solaris this is a table of GOT entry addr, function_name
487   // on sparc-solaris the runtime linker modifies the PLT entry when it
488   // binds a function, on X86 the PLT entry is not modified, but it uses
489   // an indirect jump to a GOT entry that is modified when the function 
490   // is bound....is this correct???? or should it be <PLTentry_addr, name> 
491   // for both?
492   std::vector<relocationEntry> relocation_table_;
493   std::vector<relocationEntry> fbt_;
494
495   // all section headers, sorted by address
496   // we use these to do a better job of finding the end of symbols
497   std::vector<Elf_X_Shdr*> allRegionHdrs;
498   std::vector<Elf_X_Shdr*> allRegionHdrsByShndx;
499
500   // Symbol version mappings. used to store symbol version names.
501   dyn_hash_map<unsigned, std::vector<std::string> >versionMapping;
502   dyn_hash_map<unsigned, std::string> versionFileNameMapping;
503
504   std::vector<std::string> deps_;
505   std::vector<std::string> rmd_deps;
506
507   bool loaded_elf( Offset &, Offset &,
508                     Elf_X_Shdr* &,
509                     Elf_X_Shdr* &, Elf_X_Shdr* &, 
510                     Elf_X_Shdr* &, Elf_X_Shdr* &, 
511                     Elf_X_Shdr* &, Elf_X_Shdr* &, 
512                     Elf_X_Shdr*& rel_plt_scnp, Elf_X_Shdr*& plt_scnp, 
513                     Elf_X_Shdr*& got_scnp, Elf_X_Shdr*& dynsym_scnp,
514                     Elf_X_Shdr*& dynstr_scnp, Elf_X_Shdr*& dynamic_scnp, Elf_X_Shdr*& eh_frame,
515                     Elf_X_Shdr*& gcc_except, Elf_X_Shdr *& interp_scnp,
516                    Elf_X_Shdr *&opd_scnp,
517           bool a_out=false);
518   
519   Symbol *handle_opd_symbol(Region *opd, Symbol *sym);
520   void handle_opd_relocations();
521   void parse_opd(Elf_X_Shdr *);
522   void parseStabFileLineInfo();
523  public:
524   void parseDwarfFileLineInfo();
525   void parseLineInfoForAddr(Offset addr_to_find);
526
527   bool hasDebugInfo();
528
529 private:
530     void parseLineInfoForCU(Module::DebugInfoT cuDIE, LineInformation* li);
531     void parseLineInfo(LineInformation* li);
532     bool dwarf_parse_aranges(::Dwarf *dbg, std::set<Dwarf_Off>& dies_seen);
533
534   void parseDwarfTypes(Symtab *obj);
535   void parseStabTypes();
536
537   void load_object(bool);
538   void load_shared_object(bool);
539
540   // initialize relocation_table_ from .rel[a].plt section entries 
541   bool get_relocation_entries(Elf_X_Shdr *&rel_plt_scnp,
542                               Elf_X_Shdr *&dynsym_scnp, 
543                               Elf_X_Shdr *&dynstr_scnp);
544
545   bool get_relocationDyn_entries( unsigned rel_index,
546                      Elf_X_Shdr *&dynsym_scnp,
547                      Elf_X_Shdr *&dynstr_scnp );
548
549   // Parses sections with relocations and links these relocations to
550   // existing symbols
551   bool parse_all_relocations(Elf_X &, Elf_X_Shdr *, Elf_X_Shdr *,
552           Elf_X_Shdr *, Elf_X_Shdr *);
553   
554   void parseDynamic(Elf_X_Shdr *& dyn_scnp, Elf_X_Shdr *&dynsym_scnp, 
555                     Elf_X_Shdr *&dynstr_scnp);
556   
557   bool parse_symbols(Elf_X_Data &symdata, Elf_X_Data &strdata,
558                      Elf_X_Shdr* bssscnp,
559                      Elf_X_Shdr* symscnp,
560                      bool shared_library,
561                      std::string module);
562   
563   void parse_dynamicSymbols( Elf_X_Shdr *& dyn_scnp, Elf_X_Data &symdata,
564                              Elf_X_Data &strdata, bool shared_library,
565                              std::string module);
566
567   void find_code_and_data(Elf_X &elf,
568        Offset txtaddr, Offset dataddr);
569   bool fix_global_symbol_modules_static_stab(Elf_X_Shdr *stabscnp,
570                                              Elf_X_Shdr *stabstrscnp);
571   bool fix_global_symbol_modules_static_dwarf();
572
573   void get_valid_memory_areas(Elf_X &elf);
574
575   bool find_catch_blocks(Elf_X_Shdr *eh_frame, Elf_X_Shdr *except_scn,
576                          Address textaddr, Address dataaddr,
577                          std::vector<ExceptionBlock> &catch_addrs);
578   // Line info: CUs to skip
579   std::set<std::string> modules_parsed_for_line_info;
580 #if defined(cap_dwarf)
581   std::string find_symbol(std::string name);
582
583 #endif
584
585  public:
586   struct DbgAddrConversion_t {
587      DbgAddrConversion_t() : dbg_offset(0x0), dbg_size(0x0), orig_offset(0x0) {}
588      std::string name;
589      Offset dbg_offset;
590      unsigned dbg_size;
591      Offset orig_offset;
592   };
593  private:
594   bool DbgSectionMapSorted;
595   std::vector<DbgAddrConversion_t> DebugSectionMap;
596
597  public:  
598   std::set<std::string> prereq_libs;
599   std::vector<std::pair<long, long> > new_dynamic_entries;
600  private:
601   const char* soname_;
602   
603 };
604
605 }//namespace SymtabAPI
606 }//namespace Dyninst
607
608 #endif /* !defined(_Object_elf_h_) */