ROSE  0.11.22.0
BinaryLoaderElf.h
1 #ifndef ROSE_BinaryAnalysis_BinaryLoaderElf_H
2 #define ROSE_BinaryAnalysis_BinaryLoaderElf_H
3 
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include "BinaryLoader.h"
7 
8 namespace Rose {
9 namespace BinaryAnalysis {
10 
13 
16 public:
19 
20 public:
21  /* FIXME: These should probably be in SgAsmElfSymver* classes instead. [RPM 2010-09-14] */
23  enum {
24  VER_FLG_BASE=0x1,
25  VER_FLG_WEAK=0x2,
26  VERSYM_HIDDEN=0x8000
27  };
28 
37  private:
38  SgAsmElfSymbol* symbol_;
39  SgAsmElfSymverEntry* versionEntry_;
40  SgAsmElfSymverDefinedEntry* versionDef_;
41  SgAsmElfSymverNeededAux* versionNeed_;
42  public:
44  : symbol_(symbol), versionEntry_(NULL), versionDef_(NULL), versionNeed_(NULL)
45  {}
46 
48  bool isLocal() const;
49 
51  bool isHidden() const;
52 
54  bool isReference() const;
55 
58  bool isBaseDefinition() const;
59 
63  void symbol(SgAsmElfSymbol *symbol) { symbol_ = symbol; }
64  SgAsmElfSymbol* symbol() const { return symbol_; }
69  SgAsmElfSymbolSection *retval = SageInterface::getEnclosingNode<SgAsmElfSymbolSection>(symbol_);
70  ASSERT_not_null(retval);
71  return retval;
72  }
73 
75  std::string getVersion() const;
76 
78  std::string getName() const {
79  return symbol_->get_name()->get_string();
80  }
81 
83  std::string getVersionedName() const;
84 
87  versionEntry_ = entry;
88  }
89 
96  return versionDef_;
97  }
99  ROSE_ASSERT(def->get_flags() == 0 || def->get_flags() == VER_FLG_BASE);
100  versionDef_ = def;
101  }
110  return versionNeed_;
111  }
113  ROSE_ASSERT(need->get_flags() == 0 || need->get_flags() == VER_FLG_WEAK);
114  versionNeed_ = need;
115  }
119  void print(std::ostream&) const;
120 
122  void dump(FILE*, const char *prefix, ssize_t idx) const;
123  };
124 
127  struct SymbolMapEntry {
128  private:
129  /* Base version will be at the front if we have one; other entries are unsorted. */
130  std::vector<VersionedSymbol> versions_;
131  public:
133  const VersionedSymbol &getVSymbol() const {
134  return getBaseVersion();
135  }
136 
139  return getVSymbol().symbol();
140  }
141 
145  VersionedSymbol getVSymbol(const VersionedSymbol &version) const;
146 
149  return getVSymbol().getSection();
150  }
151 
154  void addVersion(const VersionedSymbol &vsymbol);
155 
157  void merge(const SymbolMapEntry&);
158 
160  void dump(FILE*, const char *prefix) const ;
161 
162  private:
163  const VersionedSymbol& getBaseVersion() const {
164  ASSERT_forbid(versions_.empty());
165  return versions_.front();
166  }
167  };
168 
170  class SymbolMap: public std::map<std::string/*symbol name*/, SymbolMapEntry> {
171  public:
173  const SymbolMapEntry *lookup(std::string name) const;
174 
178  const SymbolMapEntry *lookup(std::string name, std::string version) const;
179 
181  void dump(FILE*, const char *prefix) const;
182  };
183 
185  public:
186  typedef std::map<SgAsmElfSymbol*, VersionedSymbol*> VersionedSymbolMap;
187  typedef std::map<uint16_t, SgAsmElfSymverDefinedEntry*> SymbolVersionDefinitionMap;
188  typedef std::map<uint16_t, SgAsmElfSymverNeededAux*> SymbolVersionNeededMap;
189 
190  private:
191  // Map from each ELF Symbol Version Definition Table entry's get_index() to the entry itself.
192  SymbolVersionDefinitionMap symbolVersionDefMap_;
193 
194  // Map from each auxiliary's get_other() to the auxiliary itself. The auxiliaries come from the GNU Symbol Version
195  // Requirements Table, each entry of which points to a list of auxiliaries. The parent of each auxiliary is the table
196  // entry that contained the auxiliary, thus this mapping also maps get_other() to GNU Symbol Version Requirements Table
197  // entries.
198  SymbolVersionNeededMap symbolVersionNeedMap_;
199 
200  // Map from an SgAsmElfSymbol to a VersionedSymbol.
201  VersionedSymbolMap versionedSymbolMap_;
202  public:
204  ctor(header);
205  }
206 
210 
212  void dump(FILE*, const char *prefix, ssize_t idx) const;
213 
214  private:
216  void ctor(SgAsmGenericHeader*);
217 
220  void makeSymbolVersionDefMap(SgAsmElfSymverDefinedSection*);
221 
225  void makeSymbolVersionNeedMap(SgAsmElfSymverNeededSection*);
226 
230  void makeVersionedSymbolMap(SgAsmElfSymbolSection*, SgAsmElfSymverSection*);
231  };
232 
233 protected:
239 
240 protected:
241  BinaryLoaderElf() {}
242 
243  BinaryLoaderElf(const BinaryLoaderElf &other)
244  : BinaryLoader(other)
245  {}
246 
247 public:
249  static Ptr instance() {
250  return Ptr(new BinaryLoaderElf);
251  }
252 
253  virtual ~BinaryLoaderElf() {}
254 
256  virtual BinaryLoaderPtr clone() const ROSE_OVERRIDE {
257  return BinaryLoaderPtr(new BinaryLoaderElf(*this));
258  }
259 
261  virtual bool canLoad(SgAsmGenericHeader*) const ROSE_OVERRIDE;
262 
278  void addLibDefaults(SgAsmGenericHeader *header=NULL);
279 
281  static void getDynamicVars(SgAsmGenericHeader*, std::string &rpath/*out*/, std::string &runpath/*out*/);
282 
283  // documented in superclass
284  virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) ROSE_OVERRIDE;
285 
289  virtual SgAsmGenericSection *findSectionByPreferredVa(SgAsmGenericHeader*, rose_addr_t va);
290 
291 protected:
295  virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader*) ROSE_OVERRIDE;
296 
297 public:
299  virtual rose_addr_t rebase(const MemoryMap::Ptr&, SgAsmGenericHeader*, const SgAsmGenericSectionPtrList&) ROSE_OVERRIDE;
300 
301 protected:
304  rose_addr_t *malign_lo, rose_addr_t *malign_hi,
305  rose_addr_t *va, rose_addr_t *mem_size,
306  rose_addr_t *offset, rose_addr_t *file_size, bool *map_private,
307  rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi,
308  ConflictResolution *resolve) ROSE_OVERRIDE;
309 
314 
315  /*========================================================================================================================
316  * Methods returning prerequisite information for fixups. These names all begin with "fixup_info_".
317  *======================================================================================================================== */
318 protected:
319 
328  SgAsmElfSymbol *fixupInfoRelocSymbol(SgAsmElfRelocEntry*, const SymverResolver&);
329 
339  rose_addr_t fixupInfoTargetVa(SgAsmElfRelocEntry*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
340 
350  rose_addr_t fixupInfoSymbolVa(SgAsmElfSymbol*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
351 
361  rose_addr_t fixupInfoAddend(SgAsmElfRelocEntry*, rose_addr_t target_va, const MemoryMap::Ptr&, size_t nbytes=0);
362 
395  rose_addr_t fixupInfoExpr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver,
396  const MemoryMap::Ptr &memmap, rose_addr_t *target_va_p=NULL);
397 
398 
399 
400  /*========================================================================================================================
401  * Methods that apply a relocation fixup. These names all begin with "fixup_apply_".
402  *======================================================================================================================== */
403 protected:
414  void fixupApply(rose_addr_t value, SgAsmElfRelocEntry*, const MemoryMap::Ptr&, rose_addr_t target_va=0, size_t nbytes=0);
415 
418  void fixupApplySymbolCopy(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
419 
420  /*========================================================================================================================
421  * Functions moved here from the BinaryLoader_ElfSupport name space.
422  *======================================================================================================================== */
423 protected:
424  void performRelocation(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
425  void performRelocations(SgAsmElfFileHeader*, const MemoryMap::Ptr&);
426 };
427 
428 std::ostream& operator<<(std::ostream&, const BinaryLoaderElf::VersionedSymbol&);
429 
430 } // namespace
431 } // namespace
432 
433 #endif
434 #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.