From f8f9476a1b0c36cf397478f7da6a54a05f266a9a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 31 May 2015 23:15:35 +0000 Subject: For COFF and MachO, compute the gap between to symbols. Before r238028 we used to do this in O(N^2), now we do it in O(N log N). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238698 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-rtdyld/llvm-rtdyld.cpp | 48 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'tools/llvm-rtdyld') diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 7cf182e6fd0..eb06f90a6c2 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -247,6 +247,36 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { std::unique_ptr Context( new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); + // FIXME: This is generally useful. Figure out a place in lib/Object to + // put utility functions. + std::map> FuncAddresses; + if (!isa(SymbolObj)) { + for (object::SymbolRef Sym : SymbolObj->symbols()) { + object::SymbolRef::Type SymType; + if (Sym.getType(SymType)) + continue; + if (SymType != object::SymbolRef::ST_Function) + continue; + uint64_t Addr; + if (Sym.getAddress(Addr)) + continue; + object::section_iterator Sec = SymbolObj->section_end(); + if (Sym.getSection(Sec)) + continue; + std::vector &Addrs = FuncAddresses[*Sec]; + if (Addrs.empty()) { + uint64_t SecAddr = Sec->getAddress(); + uint64_t SecSize = Sec->getSize(); + Addrs.push_back(SecAddr + SecSize); + } + Addrs.push_back(Addr); + } + for (auto &Pair : FuncAddresses) { + std::vector &Addrs = Pair.second; + array_pod_sort(Addrs.begin(), Addrs.end()); + } + } + // Use symbol info to iterate functions in the object. for (object::SymbolRef Sym : SymbolObj->symbols()) { object::SymbolRef::Type SymType; @@ -255,13 +285,25 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { if (SymType == object::SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; - uint64_t Size; if (Sym.getName(Name)) continue; if (Sym.getAddress(Addr)) continue; - if (Sym.getSize(Size)) - continue; + + uint64_t Size; + if (isa(SymbolObj)) { + if (Sym.getSize(Size)) + continue; + } else { + object::section_iterator Sec = SymbolObj->section_end(); + if (Sym.getSection(Sec)) + continue; + const std::vector &Addrs = FuncAddresses[*Sec]; + auto AddrI = std::find(Addrs.begin(), Addrs.end(), Addr); + assert(AddrI != Addrs.end() && (AddrI + 1) != Addrs.end()); + assert(*AddrI == Addr); + Size = *(AddrI + 1) - Addr; + } // If we're not using the debug object, compute the address of the // symbol in memory (rather than that in the unrelocated object file) -- cgit v1.2.3