00001 #ifndef ROSE_BINARYLOADERELF_H
00002 #define ROSE_BINARYLOADERELF_H
00003
00004 #include "BinaryLoader.h"
00005
00006 class BinaryLoaderElf: public BinaryLoader {
00007 public:
00008 BinaryLoaderElf() {}
00009
00010 BinaryLoaderElf(const BinaryLoaderElf &other)
00011 : BinaryLoader(other)
00012 {}
00013
00014 virtual ~BinaryLoaderElf() {}
00015
00017 virtual BinaryLoaderElf *clone() const {
00018 return new BinaryLoaderElf(*this);
00019 }
00020
00022 virtual bool can_load(SgAsmGenericHeader*) const;
00023
00039 void add_lib_defaults(SgAsmGenericHeader *header=NULL);
00040
00042 static void get_dynamic_vars(SgAsmGenericHeader*, std::string &rpath, std::string &runpath);
00043
00045 virtual void fixup(SgAsmInterpretation *interp);
00046
00047
00049 enum {
00050 VER_FLG_BASE=0x1,
00051 VER_FLG_WEAK=0x2,
00052 VERSYM_HIDDEN=0x8000
00053 };
00054
00062 class VersionedSymbol {
00063 private:
00064 SgAsmElfSymbol* p_symbol;
00065 SgAsmElfSymverEntry* p_version_entry;
00066 SgAsmElfSymverDefinedEntry* p_version_def;
00067 SgAsmElfSymverNeededAux* p_version_need;
00068 public:
00069 explicit VersionedSymbol(SgAsmElfSymbol* symbol)
00070 : p_symbol(symbol), p_version_entry(NULL), p_version_def(NULL), p_version_need(NULL)
00071 {}
00072
00074 bool is_local() const;
00075
00077 bool is_hidden() const;
00078
00080 bool is_reference() const;
00081
00084 bool is_base_definition() const;
00085
00087 void set_symbol(SgAsmElfSymbol *symbol) {
00088 p_symbol = symbol;
00089 }
00090
00092 SgAsmElfSymbol *get_symbol() const {
00093 return p_symbol;
00094 }
00095
00097 SgAsmElfSymbolSection *get_section() const {
00098 SgAsmElfSymbolSection *retval = SageInterface::getEnclosingNode<SgAsmElfSymbolSection>(p_symbol);
00099 ROSE_ASSERT(retval!=NULL);
00100 return retval;
00101 }
00102
00104 std::string get_version() const;
00105
00107 std::string get_name() const {
00108 return p_symbol->get_name()->get_string();
00109 }
00110
00112 std::string get_versioned_name() const;
00113
00115 void set_version_entry(SgAsmElfSymverEntry *entry) {
00116 p_version_entry = entry;
00117 }
00118
00120 void set_version_def(SgAsmElfSymverDefinedEntry* def) {
00121 ROSE_ASSERT(def->get_flags() == 0 || def->get_flags() == VER_FLG_BASE);
00122 p_version_def = def;
00123 }
00124
00126 void set_version_need(SgAsmElfSymverNeededAux* need) {
00127 ROSE_ASSERT(need->get_flags() == 0 || need->get_flags() == VER_FLG_WEAK);
00128 p_version_need = need;
00129 }
00130
00132 SgAsmElfSymverNeededAux* get_version_need() const {
00133 return p_version_need;
00134 }
00135
00137 SgAsmElfSymverDefinedEntry* get_version_def() const {
00138 return p_version_def;
00139 }
00140 };
00141
00144 struct SymbolMapEntry {
00145 private:
00146
00147 std::vector<VersionedSymbol> p_versions;
00148 public:
00150 const VersionedSymbol &get_vsymbol() const {
00151 return get_base_version();
00152 }
00153
00155 SgAsmElfSymbol *get_symbol() const {
00156 return get_vsymbol().get_symbol();
00157 }
00158
00162 VersionedSymbol get_vsymbol(const VersionedSymbol &version) const;
00163
00165 SgAsmElfSymbolSection *get_section() const {
00166 return get_vsymbol().get_section();
00167 }
00168
00171 void addVersion(const VersionedSymbol &vsymbol);
00172
00174 void merge(const SymbolMapEntry&);
00175
00176 private:
00177 const VersionedSymbol& get_base_version() const {
00178 ROSE_ASSERT(!p_versions.empty());
00179 return p_versions.front();
00180 }
00181 };
00182
00184 class SymbolMap: public std::map<std::string, SymbolMapEntry> {
00185 public:
00187 const SymbolMapEntry *lookup(std::string name) const;
00188
00192 const SymbolMapEntry *lookup(std::string name, std::string version) const;
00193 };
00194
00195 class SymverResolver {
00196 public:
00197 SymverResolver(SgAsmGenericHeader *header) { ctor(header); }
00198
00201 VersionedSymbol get_versioned_symbol(SgAsmElfSymbol *symbol) const;
00202
00203 private:
00205 void ctor(SgAsmGenericHeader*);
00206
00209 void makeSymbolVersionDefMap(SgAsmElfSymverDefinedSection*);
00210
00214 void makeSymbolVersionNeedMap(SgAsmElfSymverNeededSection*);
00215
00219 void makeVersionedSymbolMap(SgAsmElfSymbolSection*, SgAsmElfSymverSection*);
00220
00221 typedef std::map<SgAsmElfSymbol*, VersionedSymbol*> VersionedSymbolMap;
00222 typedef std::map<uint16_t, SgAsmElfSymverDefinedEntry*> SymbolVersionDefinitionMap;
00223 typedef std::map<uint16_t, SgAsmElfSymverNeededAux*> SymbolVersionNeededMap;
00224
00226 SymbolVersionDefinitionMap p_symbolVersionDefMap;
00227
00232 SymbolVersionNeededMap p_symbolVersionNeedMap;
00233
00235 VersionedSymbolMap p_versionedSymbolMap;
00236 };
00237
00238 protected:
00242 virtual SgAsmGenericSectionPtrList get_remap_sections(SgAsmGenericHeader*);
00243
00245 virtual rose_addr_t rebase(MemoryMap*, SgAsmGenericHeader*, const SgAsmGenericSectionPtrList&);
00246
00248 virtual MappingContribution align_values(SgAsmGenericSection*, MemoryMap*,
00249 rose_addr_t *malign_lo, rose_addr_t *malign_hi,
00250 rose_addr_t *va, rose_addr_t *mem_size,
00251 rose_addr_t *offset, rose_addr_t *file_size, bool *map_private,
00252 rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi,
00253 ConflictResolution *resolve);
00254
00258 virtual SgAsmGenericSection *find_section_by_preferred_va(SgAsmGenericHeader*, rose_addr_t va);
00259
00263 void build_master_symbol_table(SgAsmInterpretation*);
00264
00265
00266
00267
00268 protected:
00269
00278 SgAsmElfSymbol *fixup_info_reloc_symbol(SgAsmElfRelocEntry*, const SymverResolver&);
00279
00289 rose_addr_t fixup_info_target_va(SgAsmElfRelocEntry*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
00290
00300 rose_addr_t fixup_info_symbol_va(SgAsmElfSymbol*, SgAsmGenericSection **section_p=NULL, rose_addr_t *adj_p=NULL);
00301
00311 rose_addr_t fixup_info_addend(SgAsmElfRelocEntry*, rose_addr_t target_va, MemoryMap*, size_t nbytes=0);
00312
00345 rose_addr_t fixup_info_expr(const std::string &expression, SgAsmElfRelocEntry *reloc, const SymverResolver &resolver,
00346 MemoryMap *memmap, rose_addr_t *target_va_p=NULL);
00347
00348
00349
00350
00351
00352
00353 protected:
00364 void fixup_apply(rose_addr_t value, SgAsmElfRelocEntry*, MemoryMap*, rose_addr_t target_va=0, size_t nbytes=0);
00365
00368 void fixup_apply_symbol_copy(SgAsmElfRelocEntry*, const SymverResolver&, MemoryMap*);
00369
00370
00371
00372
00373 protected:
00374 void performRelocation(SgAsmElfRelocEntry*, const SymverResolver&, MemoryMap*);
00375 void performRelocations(SgAsmElfFileHeader*, MemoryMap*);
00376
00377
00378
00379
00380 protected:
00381
00384 SymbolMap p_symbols;
00385 };
00386
00387 #endif