forked from OSchip/llvm-project
parent
594d99588b
commit
ef8fb72fc4
llvm/tools/llvm-symbolizer
|
@ -21,6 +21,12 @@
|
|||
namespace llvm {
|
||||
namespace symbolize {
|
||||
|
||||
static bool error(error_code ec) {
|
||||
if (!ec) return false;
|
||||
errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t getDILineInfoSpecifierFlags(
|
||||
const LLVMSymbolizer::Options &Opts) {
|
||||
uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
|
||||
|
@ -37,6 +43,58 @@ static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
|
|||
LineInfo.getLine(), LineInfo.getColumn());
|
||||
}
|
||||
|
||||
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
||||
: Module(Obj)
|
||||
, DebugInfoContext(DICtx) {
|
||||
error_code ec;
|
||||
for (symbol_iterator si = Module->begin_symbols(),
|
||||
se = Module->end_symbols();
|
||||
si != se; si.increment(ec)) {
|
||||
if (error(ec))
|
||||
return;
|
||||
SymbolRef::Type SymbolType;
|
||||
if (error(si->getType(SymbolType)))
|
||||
continue;
|
||||
if (SymbolType != SymbolRef::ST_Function
|
||||
&& SymbolType != SymbolRef::ST_Data)
|
||||
continue;
|
||||
uint64_t SymbolAddress;
|
||||
if (error(si->getAddress(SymbolAddress))
|
||||
|| SymbolAddress == UnknownAddressOrSize)
|
||||
continue;
|
||||
uint64_t SymbolSize;
|
||||
if (error(si->getSize(SymbolSize))
|
||||
|| SymbolSize == UnknownAddressOrSize)
|
||||
continue;
|
||||
StringRef SymbolName;
|
||||
if (error(si->getName(SymbolName)))
|
||||
continue;
|
||||
// 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, SymbolAddress + SymbolSize};
|
||||
M.insert(std::make_pair(SD, SymbolName));
|
||||
}
|
||||
}
|
||||
|
||||
bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
|
||||
std::string &Name, uint64_t &Addr,
|
||||
uint64_t &Size) const {
|
||||
const SymbolMapTy& M = Type == SymbolRef::ST_Function ?
|
||||
Functions : Objects;
|
||||
SymbolDesc SD = {Address, Address + 1};
|
||||
SymbolMapTy::const_iterator it = M.find(SD);
|
||||
if (it == M.end())
|
||||
return false;
|
||||
if (Address < it->first.Addr || Address >= it->first.AddrEnd)
|
||||
return false;
|
||||
Name = it->second.str();
|
||||
Addr = it->first.Addr;
|
||||
Size = it->first.AddrEnd - it->first.Addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
DILineInfo ModuleInfo::symbolizeCode(uint64_t ModuleOffset,
|
||||
const LLVMSymbolizer::Options& Opts) const {
|
||||
DILineInfo LineInfo;
|
||||
|
@ -94,44 +152,6 @@ bool ModuleInfo::symbolizeData(uint64_t ModuleOffset, std::string &Name,
|
|||
ModuleOffset, Name, Start, Size);
|
||||
}
|
||||
|
||||
static bool error(error_code ec) {
|
||||
if (!ec) return false;
|
||||
errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
|
||||
std::string &Name, uint64_t &Addr,
|
||||
uint64_t &Size) const {
|
||||
assert(Module);
|
||||
error_code ec;
|
||||
for (symbol_iterator si = Module->begin_symbols(),
|
||||
se = Module->end_symbols();
|
||||
si != se; si.increment(ec)) {
|
||||
if (error(ec)) return false;
|
||||
uint64_t SymbolAddress;
|
||||
uint64_t SymbolSize;
|
||||
SymbolRef::Type SymbolType;
|
||||
if (error(si->getAddress(SymbolAddress)) ||
|
||||
SymbolAddress == UnknownAddressOrSize) continue;
|
||||
if (error(si->getSize(SymbolSize)) ||
|
||||
SymbolSize == UnknownAddressOrSize) continue;
|
||||
if (error(si->getType(SymbolType))) continue;
|
||||
// FIXME: If a function has alias, there are two entries in symbol table
|
||||
// with same address size. Make sure we choose the correct one.
|
||||
if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize &&
|
||||
SymbolType == Type) {
|
||||
StringRef SymbolName;
|
||||
if (error(si->getName(SymbolName))) continue;
|
||||
Name = SymbolName.str();
|
||||
Addr = SymbolAddress;
|
||||
Size = SymbolSize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char LLVMSymbolizer::kBadString[] = "??";
|
||||
|
||||
std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
|
||||
|
@ -202,7 +222,6 @@ ModuleInfo *LLVMSymbolizer::getOrCreateModuleInfo(
|
|||
return I->second;
|
||||
|
||||
ObjectFile *Obj = getObjectFile(ModuleName);
|
||||
ObjectFile *DbgObj = Obj;
|
||||
if (Obj == 0) {
|
||||
// Module name doesn't point to a valid object file.
|
||||
Modules.insert(make_pair(ModuleName, (ModuleInfo*)0));
|
||||
|
@ -214,6 +233,7 @@ ModuleInfo *LLVMSymbolizer::getOrCreateModuleInfo(
|
|||
if (getObjectEndianness(Obj, IsLittleEndian)) {
|
||||
// On Darwin we may find DWARF in separate object file in
|
||||
// resource directory.
|
||||
ObjectFile *DbgObj = Obj;
|
||||
if (isa<MachOObjectFile>(Obj)) {
|
||||
const std::string &ResourceName = getDarwinDWARFResourceForModule(
|
||||
ModuleName);
|
||||
|
|
|
@ -63,11 +63,8 @@ private:
|
|||
};
|
||||
|
||||
class ModuleInfo {
|
||||
OwningPtr<ObjectFile> Module;
|
||||
OwningPtr<DIContext> DebugInfoContext;
|
||||
public:
|
||||
ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
||||
: Module(Obj), DebugInfoContext(DICtx) {}
|
||||
ModuleInfo(ObjectFile *Obj, DIContext *DICtx);
|
||||
|
||||
DILineInfo symbolizeCode(
|
||||
uint64_t ModuleOffset, const LLVMSymbolizer::Options& Opts) const;
|
||||
|
@ -80,6 +77,19 @@ class ModuleInfo {
|
|||
bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
|
||||
std::string &Name, uint64_t &Addr,
|
||||
uint64_t &Size) const;
|
||||
OwningPtr<ObjectFile> Module;
|
||||
OwningPtr<DIContext> DebugInfoContext;
|
||||
|
||||
struct SymbolDesc {
|
||||
uint64_t Addr;
|
||||
uint64_t AddrEnd;
|
||||
friend bool operator<(const SymbolDesc& s1, const SymbolDesc& s2) {
|
||||
return s1.AddrEnd <= s2.Addr;
|
||||
}
|
||||
};
|
||||
typedef std::map<SymbolDesc, StringRef> SymbolMapTy;
|
||||
SymbolMapTy Functions;
|
||||
SymbolMapTy Objects;
|
||||
};
|
||||
|
||||
} // namespace symbolize
|
||||
|
|
Loading…
Reference in New Issue