ROSE  0.11.145.0
BinaryLoaderElf.h
1 #ifndef ROSE_BinaryAnalysis_BinaryLoaderElf_H
2 #define ROSE_BinaryAnalysis_BinaryLoaderElf_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 #include <Rose/BinaryAnalysis/BinaryLoader.h>
6 
7 namespace Rose {
8 namespace BinaryAnalysis {
9 
12 public:
15 
16 public:
17  /* FIXME: These should probably be in SgAsmElfSymver* classes instead. [RPM 2010-09-14] */
19  enum {
20  VER_FLG_BASE=0x1,
21  VER_FLG_WEAK=0x2,
22  VERSYM_HIDDEN=0x8000
23  };
24 
33  private:
34  SgAsmElfSymbol* symbol_;
35  SgAsmElfSymverEntry* versionEntry_;
36  SgAsmElfSymverDefinedEntry* versionDef_;
37  SgAsmElfSymverNeededAux* versionNeed_;
38  public:
40  : symbol_(symbol), versionEntry_(NULL), versionDef_(NULL), versionNeed_(NULL)
41  {}
42 
44  bool isLocal() const;
45 
47  bool isHidden() const;
48 
50  bool isReference() const;
51 
54  bool isBaseDefinition() const;
55 
59  void symbol(SgAsmElfSymbol *symbol) { symbol_ = symbol; }
60  SgAsmElfSymbol* symbol() const { return symbol_; }
65  SgAsmElfSymbolSection *retval = SageInterface::getEnclosingNode<SgAsmElfSymbolSection>(symbol_);
66  ASSERT_not_null(retval);
67  return retval;
68  }
69 
71  std::string getVersion() const;
72 
74  std::string getName() const {
75  return symbol_->get_name()->get_string();
76  }
77 
79  std::string getVersionedName() const;
80 
83  versionEntry_ = entry;
84  }
85 
92  return versionDef_;
93  }
95  ROSE_ASSERT(def->get_flags() == 0 || def->get_flags() == VER_FLG_BASE);
96  versionDef_ = def;
97  }
106  return versionNeed_;
107  }
109  ROSE_ASSERT(need->get_flags() == 0 || need->get_flags() == VER_FLG_WEAK);
110  versionNeed_ = need;
111  }
115  void print(std::ostream&) const;
116 
118  void dump(FILE*, const char *prefix, ssize_t idx) const;
119  };
120 
123  struct SymbolMapEntry {
124  private:
125  /* Base version will be at the front if we have one; other entries are unsorted. */
126  std::vector<VersionedSymbol> versions_;
127  public:
129  const VersionedSymbol &getVSymbol() const {
130  return getBaseVersion();
131  }
132 
135  return getVSymbol().symbol();
136  }
137 
141  VersionedSymbol getVSymbol(const VersionedSymbol &version) const;
142 
145  return getVSymbol().getSection();
146  }
147 
150  void addVersion(const VersionedSymbol &vsymbol);
151 
153  void merge(const SymbolMapEntry&);
154 
156  void dump(FILE*, const char *prefix) const ;
157 
158  private:
159  const VersionedSymbol& getBaseVersion() const {
160  ASSERT_forbid(versions_.empty());
161  return versions_.front();
162  }
163  };
164 
166  class SymbolMap: public std::map<std::string/*symbol name*/, SymbolMapEntry> {
167  public:
169  const SymbolMapEntry *lookup(std::string name) const;
170 
174  const SymbolMapEntry *lookup(std::string name, std::string version) const;
175 
177  void dump(FILE*, const char *prefix) const;
178  };
179 
181  public:
182  typedef std::map<SgAsmElfSymbol*, VersionedSymbol*> VersionedSymbolMap;
183  typedef std::map<uint16_t, SgAsmElfSymverDefinedEntry*> SymbolVersionDefinitionMap;
184  typedef std::map<uint16_t, SgAsmElfSymverNeededAux*> SymbolVersionNeededMap;
185 
186  private:
187  // Map from each ELF Symbol Version Definition Table entry's get_index() to the entry itself.
188  SymbolVersionDefinitionMap symbolVersionDefMap_;
189 
190  // Map from each auxiliary's get_other() to the auxiliary itself. The auxiliaries come from the GNU Symbol Version
191  // Requirements Table, each entry of which points to a list of auxiliaries. The parent of each auxiliary is the table
192  // entry that contained the auxiliary, thus this mapping also maps get_other() to GNU Symbol Version Requirements Table
193  // entries.
194  SymbolVersionNeededMap symbolVersionNeedMap_;
195 
196  // Map from an SgAsmElfSymbol to a VersionedSymbol.
197  VersionedSymbolMap versionedSymbolMap_;
198  public:
200  ctor(header);
201  }
202 
206 
208  void dump(FILE*, const char *prefix, ssize_t idx) const;
209 
210  private:
212  void ctor(SgAsmGenericHeader*);
213 
216  void makeSymbolVersionDefMap(SgAsmElfSymverDefinedSection*);
217 
221  void makeSymbolVersionNeedMap(SgAsmElfSymverNeededSection*);
222 
226  void makeVersionedSymbolMap(SgAsmElfSymbolSection*, SgAsmElfSymverSection*);
227  };
228 
229 protected:
235 
236 protected:
237  BinaryLoaderElf() {}
238 
239  BinaryLoaderElf(const BinaryLoaderElf &other)
240  : BinaryLoader(other)
241  {}
242 
243 public:
245  static Ptr instance() {
246  return Ptr(new BinaryLoaderElf);
247  }
248 
249  virtual ~BinaryLoaderElf() {}
250 
252  virtual BinaryLoaderPtr clone() const override {
253  return BinaryLoaderPtr(new BinaryLoaderElf(*this));
254  }
255 
257  virtual bool canLoad(SgAsmGenericHeader*) const override;
258 
274  void addLibDefaults(SgAsmGenericHeader *header=NULL);
275 
277  static void getDynamicVars(SgAsmGenericHeader*, std::string &rpath/*out*/, std::string &runpath/*out*/);
278 
279  // documented in superclass
280  virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) override;
281 
286 
287 protected:
291  virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader*) override;
292 
293 public:
295  virtual rose_addr_t rebase(const MemoryMap::Ptr&, SgAsmGenericHeader*, const SgAsmGenericSectionPtrList&) override;
296 
297 protected:
300  rose_addr_t *malign_lo, rose_addr_t *malign_hi,
301  rose_addr_t *va, rose_addr_t *mem_size,
302  rose_addr_t *offset, rose_addr_t *file_size, bool *map_private,
303  rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi,
304  ConflictResolution *resolve) override;
305 
310 
311  /*========================================================================================================================
312  * Methods returning prerequisite information for fixups. These names all begin with "fixup_info_".
313  *======================================================================================================================== */
314 protected:
315 
324  SgAsmElfSymbol *fixupInfoRelocSymbol(SgAsmElfRelocEntry*, const SymverResolver&);
325 
335  rose_addr_t fixupInfoTargetVa(SgAsmElfRelocEntry*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
336 
346  rose_addr_t fixupInfoSymbolVa(SgAsmElfSymbol*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
347 
357  rose_addr_t fixupInfoAddend(SgAsmElfRelocEntry*, rose_addr_t target_va, const MemoryMap::Ptr&, size_t nbytes=0);
358 
391  rose_addr_t fixupInfoExpr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver,
392  const MemoryMap::Ptr &memmap, rose_addr_t *target_va_p=NULL);
393 
394 
395 
396  /*========================================================================================================================
397  * Methods that apply a relocation fixup. These names all begin with "fixup_apply_".
398  *======================================================================================================================== */
399 protected:
410  void fixupApply(rose_addr_t value, SgAsmElfRelocEntry*, const MemoryMap::Ptr&, rose_addr_t target_va=0, size_t nbytes=0);
411 
414  void fixupApplySymbolCopy(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
415 
416  /*========================================================================================================================
417  * Functions moved here from the BinaryLoader_ElfSupport name space.
418  *======================================================================================================================== */
419 protected:
420  void performRelocation(SgAsmElfRelocEntry*, const SymverResolver&, const MemoryMap::Ptr&);
421  void performRelocations(SgAsmElfFileHeader*, const MemoryMap::Ptr&);
422 };
423 
424 std::ostream& operator<<(std::ostream&, const BinaryLoaderElf::VersionedSymbol&);
425 
426 } // namespace
427 } // namespace
428 
429 #endif
430 #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.
int const & get_flags() const
Property: Flags.
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.
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.
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) override
Linux-specific ELF Segment and Section alignment.
void merge(const SymbolMapEntry &)
Merge the versions from the specified entry into this entry.
Sawyer::SharedPointer< BinaryLoader > BinaryLoaderPtr
Reference counting pointer.
SgAsmElfSymbol * symbol() const
Property: The symbol.
virtual BinaryLoaderPtr clone() const override
Copy constructor.
SgAsmElfSymbolSection * getSection() const
Returns the symbol section (.dynsym) where this symbol was defined.
Main namespace for the ROSE library.
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.
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.
int const & get_flags() const
Property: Flags.
virtual void fixup(SgAsmInterpretation *interp, FixupErrors *errors=NULL) override
Performs relocation fixups on the specified interpretation.
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.
One entry from an ELF symbol version definition table.
Represents a single ELF symbol.
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.
SgAsmGenericString * get_name() const
Property: Name.
void versionEntry(SgAsmElfSymverEntry *entry)
Property: Version pointer for this symbol.
Sawyer::SharedPointer< BinaryLoaderElf > BinaryLoaderElfPtr
Reference counting pointer.
MappingContribution
Describes how a section contributes to the overall memory map.
Definition: BinaryLoader.h:63
BinaryLoaderElfPtr Ptr
Reference counting pointer to BinaryLoaderElf.
std::string getVersion() const
Returns the version string of this symbol.
virtual SgAsmGenericSectionPtrList getRemapSections(SgAsmGenericHeader *) override
Returns mappable sections in a particular order.
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
virtual std::string get_string(bool escape=false) const
Property: String value.
virtual rose_addr_t rebase(const MemoryMap::Ptr &, SgAsmGenericHeader *, const SgAsmGenericSectionPtrList &) override
Returns a new, temporary base address which is greater than everything that's been mapped already...
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.
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.
virtual bool canLoad(SgAsmGenericHeader *) const override
Capability query.
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.