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; } } }
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)); }
static std::string formatSymbol(const Dumper::Context &Ctx, const coff_section *Section, uint64_t Offset, uint32_t Displacement) { std::string Buffer; raw_string_ostream OS(Buffer); SymbolRef Symbol; if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) { Expected<StringRef> Name = Symbol.getName(); if (Name) { OS << *Name; if (Displacement > 0) OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); else OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); } else { // TODO: Actually report errors helpfully. consumeError(Name.takeError()); } } OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); }
// Given a vector of relocations for a section and an offset into this section // the function returns the name of the symbol used for the relocation at the // offset. static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, uint64_t Offset, StringRef &Name) { SymbolRef Sym; if (error_code ec = resolveSymbol(Rels, Offset, Sym)) return ec; if (error_code ec = Sym.getName(Name)) return ec; return object_error::success; }
// Given a vector of relocations for a section and an offset into this section // the function returns the name of the symbol used for the relocation at the // offset. static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, uint64_t Offset, StringRef &Name) { SymbolRef Sym; if (std::error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; if (std::error_code EC = Sym.getName(Name)) return EC; return std::error_code(); }
// Given a section and an offset into this section the function returns the name // of the symbol used for the relocation at the offset. std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, uint64_t Offset, StringRef &Name) { SymbolRef Symbol; if (std::error_code EC = resolveSymbol(Section, Offset, Symbol)) return EC; if (std::error_code EC = Symbol.getName(Name)) return EC; return object_error::success; }
// Given a vector of relocations for a section and an offset into this section // the function returns the name of the symbol used for the relocation at the // offset. static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, uint64_t Offset, StringRef &Name) { SymbolRef Sym; if (std::error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; Expected<StringRef> NameOrErr = Sym.getName(); if (!NameOrErr) return errorToErrorCode(NameOrErr.takeError()); Name = *NameOrErr; return std::error_code(); }
// Given a vector of relocations for a section and an offset into this section // the function returns the name of the symbol used for the relocation at the // offset. static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, uint64_t Offset, StringRef &Name) { SymbolRef Sym; if (std::error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; ErrorOr<StringRef> NameOrErr = Sym.getName(); if (std::error_code EC = NameOrErr.getError()) return EC; Name = *NameOrErr; return std::error_code(); }
// Given a section and an offset into this section the function returns the name // of the symbol used for the relocation at the offset. std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, uint64_t Offset, StringRef &Name) { SymbolRef Symbol; if (std::error_code EC = resolveSymbol(Section, Offset, Symbol)) return EC; ErrorOr<StringRef> NameOrErr = Symbol.getName(); if (std::error_code EC = NameOrErr.getError()) return EC; Name = *NameOrErr; 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::string formatSymbol(const Dumper::Context &Ctx, const coff_section *Section, uint64_t Offset, uint32_t Displacement) { std::string Buffer; raw_string_ostream OS(Buffer); SymbolRef Symbol; if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) { if (ErrorOr<StringRef> Name = Symbol.getName()) { OS << *Name; if (Displacement > 0) OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); else OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); } } OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); }
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(); }
error_or<std::string> get_name(const SymbolRef &sym) { auto er_name = sym.getName(); auto e = of_llvm_error_or(er_name); return map_value<std::string>(e, [](const StringRef &x){return x.str();}); }