ROSE  0.9.12.24
BinaryLoaderElf.h
1 #ifndef ROSE_BinaryAnalysis_BinaryLoaderElf_H
2 #define ROSE_BinaryAnalysis_BinaryLoaderElf_H
3 
4 #include "BinaryLoader.h"
5 
6 namespace Rose {
7 namespace BinaryAnalysis {
8 
11 
14 public:
17 
18 public:
19  /* FIXME: These should probably be in SgAsmElfSymver* classes instead. [RPM 2010-09-14] */
21  enum {
22  VER_FLG_BASE=0x1,
23  VER_FLG_WEAK=0x2,
24  VERSYM_HIDDEN=0x8000
25  };
26 
35  private:
36  SgAsmElfSymbol* symbol_;
37  SgAsmElfSymverEntry* versionEntry_;
38  SgAsmElfSymverDefinedEntry* versionDef_;
39  SgAsmElfSymverNeededAux* versionNeed_;
40  public:
42  : symbol_(symbol), versionEntry_(NULL), versionDef_(NULL), versionNeed_(NULL)
43  {}
44 
46  bool isLocal() const;
47 
49  bool isHidden() const;
50 
52  bool isReference() const;
53 
56  bool isBaseDefinition() const;
57 
61  void symbol(SgAsmElfSymbol *symbol) { symbol_ = symbol; }
62  SgAsmElfSymbol* symbol() const { return symbol_; }
67  SgAsmElfSymbolSection *retval = SageInterface::getEnclosingNode<SgAsmElfSymbolSection>(symbol_);
68  ASSERT_not_null(retval);
69  return retval;
70  }
71 
73  std::string getVersion() const;
74 
76  std::string getName() const {
77  return symbol_->get_name()->get_string();
78  }
79 
81  std::string getVersionedName() const;
82 
85  versionEntry_ = entry;
86  }
87 
94  return versionDef_;
95  }
97  ROSE_ASSERT(def->get_flags() == 0 || def->get_flags() == VER_FLG_BASE);
98  versionDef_ = def;
99  }
108  return versionNeed_;
109  }
111  ROSE_ASSERT(need->get_flags() == 0 || need->get_flags() == VER_FLG_WEAK);
112  versionNeed_ = need;
113  }
117  void print(std::ostream&) const;
118 
120  void dump(FILE*, const char *prefix, ssize_t idx) const;
121  };
122 
125  struct SymbolMapEntry {
126  private:
127  /* Base version will be at the front if we have one; other entries are unsorted. */
128  std::vector<VersionedSymbol> versions_;
129  public:
131  const VersionedSymbol &getVSymbol() const {
132  return getBaseVersion();
133  }
134 
137  return getVSymbol().symbol();
138  }
139 
143  VersionedSymbol getVSymbol(const VersionedSymbol &version) const;
144 
147  return getVSymbol().getSection();
148  }
149 
152  void addVersion(const VersionedSymbol &vsymbol);
153 
155  void merge(const SymbolMapEntry&);
156 
158  void dump(FILE*, const char *prefix) const ;
159 
160  private:
161  const VersionedSymbol& getBaseVersion() const {
162  ASSERT_forbid(versions_.empty());
163  return versions_.front();
164  }
165  };
166 
168  class SymbolMap: public std::map<std::string/*symbol name*/, SymbolMapEntry> {
169  public:
171  const SymbolMapEntry *lookup(std::string name) const;
172 
176  const SymbolMapEntry *lookup(std::string name, std::string version) const;
177 
179  void dump(FILE*, const char *prefix) const;
180  };
181 
183  public:
184  typedef std::map<SgAsmElfSymbol*, VersionedSymbol*> VersionedSymbolMap;
185  typedef std::map<uint16_t, SgAsmElfSymverDefinedEntry*> SymbolVersionDefinitionMap;
186  typedef std::map<uint16_t, SgAsmElfSymverNeededAux*> SymbolVersionNeededMap;
187 
188  private:
189  // Map from each ELF Symbol Version Definition Table entry's get_index() to the entry itself.
190  SymbolVersionDefinitionMap symbolVersionDefMap_;
191 
192  // Map from each auxiliary's get_other() to the auxiliary itself. The auxiliaries come from the GNU Symbol Version
193  // Requirements Table, each entry of which points to a list of auxiliaries. The parent of each auxiliary is the table
194  // entry that contained the auxiliary, thus this mapping also maps get_other() to GNU Symbol Version Requirements Table
195  // entries.
196  SymbolVersionNeededMap symbolVersionNeedMap_;
197 
198  // Map from an SgAsmElfSymbol to a VersionedSymbol.
199  VersionedSymbolMap versionedSymbolMap_;
200  public:
202  ctor(header);
203  }
204 
208 
210  void dump(FILE*, const char *prefix, ssize_t idx) const;
211 
212  private:
214  void ctor(SgAsmGenericHeader*);
215 
218  void makeSymbolVersionDefMap(SgAsmElfSymverDefinedSection*);
219 
223  void makeSymbolVersionNeedMap(SgAsmElfSymverNeededSection*);
224 
228  void makeVersionedSymbolMap(SgAsmElfSymbolSection*, SgAsmElfSymverSection*);
229  };
230 
231 protected:
237 
238 protected:
239  BinaryLoaderElf() {}
240 
241  BinaryLoaderElf(const BinaryLoaderElf &other)
242  : BinaryLoader(other)
243  {}
244 
245 public:
247  static Ptr instance() {
248  return Ptr(new BinaryLoaderElf);
249  }
250 
251  virtual ~BinaryLoaderElf() {}
252 
254  virtual BinaryLoaderPtr clone() const ROSE_OVERRIDE {
255  return BinaryLoaderPtr(new BinaryLoaderElf(*this));
256  }
257 
259  virtual bool canLoad(SgAsmGenericHeader*) const ROSE_OVERRIDE;
260 
276  void addLibDefaults(SgAsmGenericHeader *header=NULL);
277 
279  static void getDynamicVars(SgAsmGenericHeader*, std::string &rpath/*out*/, std::string &runpath/*out*/);
280 
281  // documented in superclass
282  virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) ROSE_OVERRIDE;
283 
287  virtual SgAsmGenericSection *findSectionByPreferredVa(SgAsmGenericHeader*, rose_addr_t va);
288 
289 protected:
293  virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader*) ROSE_OVERRIDE;
294 
295 public:
297  virtual rose_addr_t rebase(const MemoryMap::Ptr&, SgAsmGenericHeader*, const SgAsmGenericSectionPtrList&) ROSE_OVERRIDE;
298 
299 protected:
302  rose_addr_t *malign_lo, rose_addr_t *malign_hi,
303  rose_addr_t *va, rose_addr_t *mem_size,
304  rose_addr_t *offset, rose_addr_t *file_size, bool *map_private,
305  rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi,
306  ConflictResolution *resolve) ROSE_OVERRIDE;
307 
312 
313  /*========================================================================================================================
314  * Methods returning prerequisite information for fixups. These names all begin with "fixup_info_".
315  *======================================================================================================================== */
316 protected:
317 
326  SgAsmElfSymbol *fixupInfoRelocSymbol(SgAsmElfRelocEntry*, const SymverResolver&);
327 
337  rose_addr_t fixupInfoTargetVa(SgAsmElfRelocEntry*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
338 
348  rose_addr_t fixupInfoSymbolVa(SgAsmElfSymbol*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
349 
359  rose_addr_t fixupInfoAddend(SgAsmElfRelocEntry*, rose_addr_t target_va, const MemoryMap::Ptr&, size_t nbytes=0);
360 
393  rose_addr_t fixupInfoExpr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver,
394  const MemoryMap::Ptr &memmap, rose_addr_t *target_va_p=NULL);
395 
396 
397 
398  /*========================================================================================================================
399  * Methods that apply a relocation fixup. These names all begin with "fixup_apply_".
400  *======================================================================================================================== */
401 protected:
412  void fixupApply(rose_addr_t value, SgAsmElfRelocEntry*, const MemoryMap::Ptr&, rose_addr_t target_va=0, size_t nbytes=0);
413 
416  void fixupApplySymbolCopy(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
417 
418  /*========================================================================================================================
419  * Functions moved here from the BinaryLoader_ElfSupport name space.
420  *======================================================================================================================== */
421 protected:
422  void performRelocation(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
423  void performRelocations(SgAsmElfFileHeader*, const MemoryMap::Ptr&);
424 };
425 
426 std::ostream& operator<<(std::ostream&, const BinaryLoaderElf::VersionedSymbol&);
427 
428 } // namespace
429 } // namespace
430 
431 #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 smart pointer.
Definition: SharedPointer.h:67
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:109
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:13
MappingContribution
Describes how a section contributes to the overall memory map.
Definition: BinaryLoader.h:63
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:71
Base class for loading a static or dynamic object.
Definition: BinaryLoader.h:54
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.