[llvm-symbolizer] Avoid calling slow getSymbolSize for Mach-O files. Assume that symbols with zero size are in fact large enough.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183213 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexey Samsonov
2013-06-04 07:57:38 +00:00
parent 1c611ecdfd
commit 888ca964a4
3 changed files with 25 additions and 9 deletions

View File

@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include <sstream>
@ -63,7 +64,11 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
SymbolAddress == UnknownAddressOrSize)
continue;
uint64_t SymbolSize;
if (error(si->getSize(SymbolSize)) || SymbolSize == UnknownAddressOrSize)
// Getting symbol size is linear for Mach-O files, so avoid it.
if (isa<MachOObjectFile>(Obj))
SymbolSize = 0;
else if (error(si->getSize(SymbolSize)) ||
SymbolSize == UnknownAddressOrSize)
continue;
StringRef SymbolName;
if (error(si->getName(SymbolName)))
@ -80,11 +85,14 @@ 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())
if (M.empty())
return false;
if (Address < it->first.Addr || Address >= it->first.AddrEnd)
SymbolDesc SD = { Address, Address };
SymbolMapTy::const_iterator it = M.upper_bound(SD);
--it;
// Assume that symbols with zero size are large enough.
if (it->first.Addr < it->first.AddrEnd &&
it->first.AddrEnd <= Address)
return false;
Name = it->second.str();
Addr = it->first.Addr;
@ -236,9 +244,12 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
if (isa<MachOObjectFile>(Obj)) {
const std::string &ResourceName =
getDarwinDWARFResourceForModule(ModuleName);
ObjectFile *ResourceObj = getObjectFile(ResourceName);
if (ResourceObj != 0)
DbgObj = ResourceObj;
bool ResourceFileExists = false;
if (!sys::fs::exists(ResourceName, ResourceFileExists) &&
ResourceFileExists) {
if (ObjectFile *ResourceObj = getObjectFile(ResourceName))
DbgObj = ResourceObj;
}
}
Context = DIContext::getDWARFContext(DbgObj);
assert(Context);