ROSE  0.11.2.0
BinaryLoaderElf.h
1 #ifndef ROSE_BinaryAnalysis_BinaryLoaderElf_H
2 #define ROSE_BinaryAnalysis_BinaryLoaderElf_H
3 
4 #include "BinaryLoader.h"
5 #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
6 
7 namespace Rose {
8 namespace BinaryAnalysis {
9 
12 
15 public:
18 
19 public:
20  /* FIXME: These should probably be in SgAsmElfSymver* classes instead. [RPM 2010-09-14] */
22  enum {
23  VER_FLG_BASE=0x1,
24  VER_FLG_WEAK=0x2,
25  VERSYM_HIDDEN=0x8000
26  };
27 
36  private:
37  SgAsmElfSymbol* symbol_;
38  SgAsmElfSymverEntry* versionEntry_;
39  SgAsmElfSymverDefinedEntry* versionDef_;
40  SgAsmElfSymverNeededAux* versionNeed_;
41  public:
43  : symbol_(symbol), versionEntry_(NULL), versionDef_(NULL), versionNeed_(NULL)
44  {}
45 
47  bool isLocal() const;
48 
50  bool isHidden() const;
51 
53  bool isReference() const;
54 
57  bool isBaseDefinition() const;
58 
62  void symbol(SgAsmElfSymbol *symbol) { symbol_ = symbol; }
63  SgAsmElfSymbol* symbol() const { return symbol_; }
68  SgAsmElfSymbolSection *retval = SageInterface::getEnclosingNode<SgAsmElfSymbolSection>(symbol_);
69  ASSERT_not_null(retval);
70  return retval;
71  }
72 
74  std::string getVersion() const;
75 
77  std::string getName() const {
78  return symbol_->get_name()->get_string();
79  }
80 
82  std::string getVersionedName() const;
83 
86  versionEntry_ = entry;
87  }
88 
95  return versionDef_;
96  }
98  ROSE_ASSERT(def->get_flags() == 0 || def->get_flags() == VER_FLG_BASE);
99  versionDef_ = def;
100  }
109  return versionNeed_;
110  }
112  ROSE_ASSERT(need->get_flags() == 0 || need->get_flags() == VER_FLG_WEAK);
113  versionNeed_ = need;
114  }
118  void print(std::ostream&) const;
119 
121  void dump(FILE*, const char *prefix, ssize_t idx) const;
122  };
123 
126  struct SymbolMapEntry {
127  private:
128  /* Base version will be at the front if we have one; other entries are unsorted. */
129  std::vector<VersionedSymbol> versions_;
130  public:
132  const VersionedSymbol &getVSymbol() const {
133  return getBaseVersion();
134  }
135 
138  return getVSymbol().symbol();
139  }
140 
144  VersionedSymbol getVSymbol(const VersionedSymbol &version) const;
145 
148  return getVSymbol().getSection();
149  }
150 
153  void addVersion(const VersionedSymbol &vsymbol);
154 
156  void merge(const SymbolMapEntry&);
157 
159  void dump(FILE*, const char *prefix) const ;
160 
161  private:
162  const VersionedSymbol& getBaseVersion() const {
163  ASSERT_forbid(versions_.empty());
164  return versions_.front();
165  }
166  };
167 
169  class SymbolMap: public std::map<std::string/*symbol name*/, SymbolMapEntry> {
170  public:
172  const SymbolMapEntry *lookup(std::string name) const;
173 
177  const SymbolMapEntry *lookup(std::string name, std::string version) const;
178 
180  void dump(FILE*, const char *prefix) const;
181  };
182 
184  public:
185  typedef std::map<SgAsmElfSymbol*, VersionedSymbol*> VersionedSymbolMap;
186  typedef std::map<uint16_t, SgAsmElfSymverDefinedEntry*> SymbolVersionDefinitionMap;
187  typedef std::map<uint16_t, SgAsmElfSymverNeededAux*> SymbolVersionNeededMap;
188 
189  private:
190  // Map from each ELF Symbol Version Definition Table entry's get_index() to the entry itself.
191  SymbolVersionDefinitionMap symbolVersionDefMap_;
192 
193  // Map from each auxiliary's get_other() to the auxiliary itself. The auxiliaries come from the GNU Symbol Version
194  // Requirements Table, each entry of which points to a list of auxiliaries. The parent of each auxiliary is the table
195  // entry that contained the auxiliary, thus this mapping also maps get_other() to GNU Symbol Version Requirements Table
196  // entries.
197  SymbolVersionNeededMap symbolVersionNeedMap_;
198 
199  // Map from an SgAsmElfSymbol to a VersionedSymbol.
200  VersionedSymbolMap versionedSymbolMap_;
201  public:
203  ctor(header);
204  }
205 
209 
211  void dump(FILE*, const char *prefix, ssize_t idx) const;
212 
213  private:
215  void ctor(SgAsmGenericHeader*);
216 
219  void makeSymbolVersionDefMap(SgAsmElfSymverDefinedSection*);
220 
224  void makeSymbolVersionNeedMap(SgAsmElfSymverNeededSection*);
225 
229  void makeVersionedSymbolMap(SgAsmElfSymbolSection*, SgAsmElfSymverSection*);
230  };
231 
232 protected:
238 
239 protected:
240  BinaryLoaderElf() {}
241 
242  BinaryLoaderElf(const BinaryLoaderElf &other)
243  : BinaryLoader(other)
244  {}
245 
246 public:
248  static Ptr instance() {
249  return Ptr(new BinaryLoaderElf);
250  }
251 
252  virtual ~BinaryLoaderElf() {}
253 
255  virtual BinaryLoaderPtr clone() const ROSE_OVERRIDE {
256  return BinaryLoaderPtr(new BinaryLoaderElf(*this));
257  }
258 
260  virtual bool canLoad(SgAsmGenericHeader*) const ROSE_OVERRIDE;
261 
277  void addLibDefaults(SgAsmGenericHeader *header=NULL);
278 
280  static void getDynamicVars(SgAsmGenericHeader*, std::string &rpath/*out*/, std::string &runpath/*out*/);
281 
282  // documented in superclass
283  virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) ROSE_OVERRIDE;
284 
288  virtual SgAsmGenericSection *findSectionByPreferredVa(SgAsmGenericHeader*, rose_addr_t va);
289 
290 protected:
294  virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader*) ROSE_OVERRIDE;
295 
296 public:
298  virtual rose_addr_t rebase(const MemoryMap::Ptr&, SgAsmGenericHeader*, const SgAsmGenericSectionPtrList&) ROSE_OVERRIDE;
299 
300 protected:
303  rose_addr_t *malign_lo, rose_addr_t *malign_hi,
304  rose_addr_t *va, rose_addr_t *mem_size,
305  rose_addr_t *offset, rose_addr_t *file_size, bool *map_private,
306  rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi,
307  ConflictResolution *resolve) ROSE_OVERRIDE;
308 
313 
314  /*========================================================================================================================
315  * Methods returning prerequisite information for fixups. These names all begin with "fixup_info_".
316  *======================================================================================================================== */
317 protected:
318 
327  SgAsmElfSymbol *fixupInfoRelocSymbol(SgAsmElfRelocEntry*, const SymverResolver&);
328 
338  rose_addr_t fixupInfoTargetVa(SgAsmElfRelocEntry*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
339 
349  rose_addr_t fixupInfoSymbolVa(SgAsmElfSymbol*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
350 
360  rose_addr_t fixupInfoAddend(SgAsmElfRelocEntry*, rose_addr_t target_va, const MemoryMap::Ptr&, size_t nbytes=0);
361 
394  rose_addr_t fixupInfoExpr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver,
395  const MemoryMap::Ptr &memmap, rose_addr_t *target_va_p=NULL);
396 
397 
398 
399  /*========================================================================================================================
400  * Methods that apply a relocation fixup. These names all begin with "fixup_apply_".
401  *======================================================================================================================== */
402 protected:
413  void fixupApply(rose_addr_t value, SgAsmElfRelocEntry*, const MemoryMap::Ptr&, rose_addr_t target_va=0, size_t nbytes=0);
414 
417  void fixupApplySymbolCopy(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
418 
419  /*========================================================================================================================
420  * Functions moved here from the BinaryLoader_ElfSupport name space.
421  *======================================================================================================================== */
422 protected:
423  void performRelocation(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
424  void performRelocations(SgAsmElfFileHeader*, const MemoryMap::Ptr&);
425 };
426 
427 std::ostream& operator<<(std::ostream&, const BinaryLoaderElf::VersionedSymbol&);
428 
429 } // namespace
430 } // namespace
431 
432 #endif
433 #endif
The GNU symbol version definitions.
SgAsmElfSymverNeededAux * versionNeed() const
Property: The version requirement of this symbol.
virtual SgAsmGenericSection * findSectionByPreferredVa(SgAsmGenericHeader *, rose_addr_t va)
Find the section containing the specified virtual address.
void versionNeed(SgAsmElfSymverNeededAux *need)
Property: The version requirement of this symbol.
bool isReference() const
Returns true if this symbol is a reference to an object rather than the definition of the object...
Contiguous region of a file.
virtual MappingContribution alignValues(SgAsmGenericSection *, const MemoryMap::Ptr &, rose_addr_t *malign_lo, rose_addr_t *malign_hi, rose_addr_t *va, rose_addr_t *mem_size, rose_addr_t *offset, rose_addr_t *file_size, bool *map_private, rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi, ConflictResolution *resolve) ROSE_OVERRIDE
Linux-specific ELF Segment and Section alignment.
void dump(FILE *, const char *prefix) const
Print debugging information about this SymbolMap.
Auxiliary info for needed symbol version.
One entry of an ELF relocation table.
const VersionedSymbol & getVSymbol() const
Returns the base version.
Represents the file header of an ELF binary container.
SgAsmElfSymbol * fixupInfoRelocSymbol(SgAsmElfRelocEntry *, const SymverResolver &)
Returns the defining symbol for a relocation, if any.
void merge(const SymbolMapEntry &)
Merge the versions from the specified entry into this entry.
STL namespace.
SgAsmElfSymbol * symbol() const
Property: The symbol.
virtual bool canLoad(SgAsmGenericHeader *) const ROSE_OVERRIDE
Capability query.
SgAsmElfSymbolSection * getSection() const
Returns the symbol section (.dynsym) where this symbol was defined.
Main namespace for the ROSE library.
virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader *) ROSE_OVERRIDE
Returns mappable sections in a particular order.
Entry in an ELF symbol version table.
VersionedSymbol getVersionedSymbol(SgAsmElfSymbol *symbol) const
Returns the VersionedSymbol corresponding to the specified symbol.
static void getDynamicVars(SgAsmGenericHeader *, std::string &rpath, std::string &runpath)
Returns the strings associated with certain variables in the ".dynamic" section.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
int get_flags() const
Property: Flags.
SgAsmElfSymbolSection * getSection() const
Returns the section where the base version symbol was defined.
GNU symbol version requirements table.
rose_addr_t fixupInfoAddend(SgAsmElfRelocEntry *, rose_addr_t target_va, const MemoryMap::Ptr &, size_t nbytes=0)
Returns the addend associated with a relocation.
virtual rose_addr_t rebase(const MemoryMap::Ptr &, SgAsmGenericHeader *, const SgAsmGenericSectionPtrList &) ROSE_OVERRIDE
Returns a new, temporary base address which is greater than everything that's been mapped already...
A mapping from symbol name (with optional version in parentheses) to SymbolMapEntry.
Base class for container file headers.
void addLibDefaults(SgAsmGenericHeader *header=NULL)
Sets up library search paths and preloads from the environment.
static Ptr instance()
Allocating constructor.
const SymbolMapEntry * lookup(std::string name) const
Finds and returns the entry having the specified name.
void versionDef(SgAsmElfSymverDefinedEntry *def)
Property: Version definition of this symbol.
ELF file section containing symbols.
void symbol(SgAsmElfSymbol *symbol)
Property: The symbol.
bool isHidden() const
Returns true if this symbol is hidden.
An efficient mapping from an address space to stored data.
Definition: MemoryMap.h:112
One entry from an ELF symbol version definition table.
Represents a single ELF symbol.
Sawyer::SharedPointer< class BinaryLoaderElf > BinaryLoaderElfPtr
Reference counting pointer to BinaryLoaderElf.
rose_addr_t fixupInfoSymbolVa(SgAsmElfSymbol *, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL)
Returns the virtual address of a symbol adjusted for remapping.
void versionEntry(SgAsmElfSymverEntry *entry)
Property: Version pointer for this symbol.
Sawyer::SharedPointer< class BinaryLoader > BinaryLoaderPtr
Reference counting pointer to BinaryLoader.
Definition: BinaryLoader.h:16
MappingContribution
Describes how a section contributes to the overall memory map.
Definition: BinaryLoader.h:66
virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) ROSE_OVERRIDE
Performs relocation fixups on the specified interpretation.
std::string getVersion() const
Returns the version string of this symbol.
int get_flags() const
Property: Flags.
void addVersion(const VersionedSymbol &vsymbol)
Add an additional versioned symbol to this entry.
void dump(FILE *, const char *prefix, ssize_t idx) const
Dump info like for SgAsm* objects.
void buildMasterSymbolTable(SgAsmInterpretation *)
Builds the master symbol table.
ConflictResolution
Describes how conflicts are resolved when mapping a section.
Definition: BinaryLoader.h:74
Base class for loading a static or dynamic object.
Definition: BinaryLoader.h:57
void fixupApply(rose_addr_t value, SgAsmElfRelocEntry *, const MemoryMap::Ptr &, rose_addr_t target_va=0, size_t nbytes=0)
Writes a value into memory at the relocation target.
SymbolMap symbols_
Symbol table for an entire interpretation.
SgAsmElfSymverDefinedEntry * versionDef() const
Property: Version definition of this symbol.
virtual BinaryLoaderPtr clone() const ROSE_OVERRIDE
Copy constructor.
std::string getVersionedName() const
Returns the full, versionioned name of this symbol.
Symbol from .dynsym combined with additional information.
The ELF symbol version table.
bool isBaseDefinition() const
Returns tru if this symbol is a base definition.
Represents an interpretation of a binary container.
std::string getName() const
Returns the name of this symbol.
void dump(FILE *, const char *prefix) const
Print info about this symbol map entry.
void print(std::ostream &) const
Print used by operator<<.
rose_addr_t fixupInfoExpr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver, const MemoryMap::Ptr &memmap, rose_addr_t *target_va_p=NULL)
Evaluates a simple postfix expression and returns the result.
rose_addr_t fixupInfoTargetVa(SgAsmElfRelocEntry *, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL)
Returns the virtual address where a relocation should be supplied.
SgAsmElfSymbol * getSymbol() const
Returns the ELF symbol from the base version.
void fixupApplySymbolCopy(SgAsmElfRelocEntry *, const SymverResolver &, const MemoryMap::Ptr &)
Copies symbol memory to the relocation target.
bool isLocal() const
Returns true if this symbol is visible only locally.
void dump(FILE *, const char *prefix, ssize_t idx) const
Print some info about the resolver.
Sawyer::SharedPointer< class BinaryLoaderElf > Ptr
Reference counting pointer to BinaryLoaderElf.