bool operator()(const SymbolRef &A, const SymbolRef &B) { SymbolRef::Type AType, BType; A.getType(AType); B.getType(BType); uint64_t AAddr, BAddr; if (AType != SymbolRef::ST_Function) AAddr = 0; else A.getAddress(AAddr); if (BType != SymbolRef::ST_Function) BAddr = 0; else B.getAddress(BAddr); return AAddr < BAddr; }
void ModuleInfo::addSymbol(const SymbolRef &Symbol) { SymbolRef::Type SymbolType; if (error(Symbol.getType(SymbolType))) return; if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data) return; uint64_t SymbolAddress; if (error(Symbol.getAddress(SymbolAddress)) || SymbolAddress == UnknownAddressOrSize) return; uint64_t SymbolSize; // Getting symbol size is linear for Mach-O files, so assume that symbol // occupies the memory range up to the following symbol. if (isa<MachOObjectFile>(Module)) SymbolSize = 0; else if (error(Symbol.getSize(SymbolSize)) || SymbolSize == UnknownAddressOrSize) return; StringRef SymbolName; if (error(Symbol.getName(SymbolName))) return; // Mach-O symbol table names have leading underscore, skip it. if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_') SymbolName = SymbolName.drop_front(); // FIXME: If a function has alias, there are two entries in symbol table // with same address size. Make sure we choose the correct one. SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; SymbolDesc SD = { SymbolAddress, SymbolSize }; M.insert(std::make_pair(SD, SymbolName)); }
explicit symbol(const SymbolRef& sym) { StringRef name; if(error_code err = sym.getName(name)) llvm_binary_fail(err); this->name_ = name.str(); if (error_code err = sym.getType(this->kind_)) llvm_binary_fail(err); if (error_code err = sym.getAddress(this->addr_)) llvm_binary_fail(err); if (error_code err = sym.getSize(this->size_)) llvm_binary_fail(err); uint32_t flags; if (error_code err = sym.getFlags(flags)) llvm_binary_fail(err); if (flags & SymbolRef::SF_Undefined) { uint64_t addr; if (error_code err = sym.getValue(addr)) llvm_binary_fail(err); // This will not work for x86-64, since they usually zero // the value. BFD library uses index correspondence // between plt entry and relocation, to name the plt // entry. We can't afford this. if (addr) { addr_ = addr; size_ = 8; } } }
// Given a symbol sym this functions returns the address and section of it. static error_code resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym, const coff_section *&ResolvedSection, uint64_t &ResolvedAddr) { if (error_code ec = Sym.getAddress(ResolvedAddr)) return ec; section_iterator iter(Obj->begin_sections()); if (error_code ec = Sym.getSection(iter)) return ec; ResolvedSection = Obj->getCOFFSection(iter); return object_error::success; }
// Given a symbol sym this functions returns the address and section of it. static std::error_code resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym, const coff_section *&ResolvedSection, uint64_t &ResolvedAddr) { if (std::error_code EC = Sym.getAddress(ResolvedAddr)) return EC; section_iterator iter(Obj->section_begin()); if (std::error_code EC = Sym.getSection(iter)) return EC; ResolvedSection = Obj->getCOFFSection(*iter); return std::error_code(); }
// Given a symbol sym this functions returns the address and section of it. static std::error_code resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym, const coff_section *&ResolvedSection, uint64_t &ResolvedAddr) { ErrorOr<uint64_t> ResolvedAddrOrErr = Sym.getAddress(); if (std::error_code EC = ResolvedAddrOrErr.getError()) return EC; ResolvedAddr = *ResolvedAddrOrErr; Expected<section_iterator> Iter = Sym.getSection(); if (!Iter) return errorToErrorCode(Iter.takeError()); ResolvedSection = Obj->getCOFFSection(**Iter); return std::error_code(); }
explicit symbol(const SymbolRef& sym) { StringRef name; if(error_code err = sym.getName(name)) llvm_binary_fail(err); this->name_ = name.str(); if (error_code err = sym.getType(this->kind_)) llvm_binary_fail(err); if (error_code err = sym.getAddress(this->addr_)) llvm_binary_fail(err); if (error_code err = sym.getSize(this->size_)) llvm_binary_fail(err); }
static std::error_code resolveRelocation(const Dumper::Context &Ctx, const coff_section *Section, uint64_t Offset, const coff_section *&ResolvedSection, uint64_t &ResolvedAddress) { SymbolRef Symbol; if (std::error_code EC = Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) return EC; ErrorOr<uint64_t> ResolvedAddressOrErr = Symbol.getAddress(); if (std::error_code EC = ResolvedAddressOrErr.getError()) return EC; ResolvedAddress = *ResolvedAddressOrErr; ErrorOr<section_iterator> SI = Symbol.getSection(); ResolvedSection = Ctx.COFF.getCOFFSection(**SI); return std::error_code(); }
std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize, DataExtractor *OpdExtractor, uint64_t OpdAddress) { ErrorOr<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType(); if (auto EC = SymbolTypeOrErr.getError()) return EC; SymbolRef::Type SymbolType = *SymbolTypeOrErr; if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data) return std::error_code(); ErrorOr<uint64_t> SymbolAddressOrErr = Symbol.getAddress(); if (auto EC = SymbolAddressOrErr.getError()) return EC; uint64_t SymbolAddress = *SymbolAddressOrErr; if (OpdExtractor) { // For big-endian PowerPC64 ELF, symbols in the .opd section refer to // function descriptors. The first word of the descriptor is a pointer to // the function's code. // For the purposes of symbolization, pretend the symbol's address is that // of the function's code, not the descriptor. uint64_t OpdOffset = SymbolAddress - OpdAddress; uint32_t OpdOffset32 = OpdOffset; if (OpdOffset == OpdOffset32 && OpdExtractor->isValidOffsetForAddress(OpdOffset32)) SymbolAddress = OpdExtractor->getAddress(&OpdOffset32); } Expected<StringRef> SymbolNameOrErr = Symbol.getName(); if (!SymbolNameOrErr) return errorToErrorCode(SymbolNameOrErr.takeError()); StringRef SymbolName = *SymbolNameOrErr; // Mach-O symbol table names have leading underscore, skip it. if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_') SymbolName = SymbolName.drop_front(); // FIXME: If a function has alias, there are two entries in symbol table // with same address size. Make sure we choose the correct one. auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; SymbolDesc SD = { SymbolAddress, SymbolSize }; M.insert(std::make_pair(SD, SymbolName)); return std::error_code(); }
static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { uint64_t Address; if (std::error_code EC = Sym.getAddress(Address)) return EC; if (Address == UnknownAddressOrSize) { Result = UnknownAddressOrSize; return object_error::success; } const ObjectFile *Obj = Sym.getObject(); section_iterator SecI(Obj->section_begin()); if (std::error_code EC = Sym.getSection(SecI)) return EC; if (SecI == Obj->section_end()) { Result = UnknownAddressOrSize; return object_error::success; } uint64_t SectionAddress = SecI->getAddress(); Result = Address - SectionAddress; return object_error::success; }
error_or<uint64_t> get_addr(const SymbolRef &sym, const COFFObjectFile &obj) { auto er_addr = sym.getAddress(); return of_llvm_error_or(er_addr); }