diff options
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DIContext.h | 37 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/ExecutionEngine/RuntimeDyld.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/COFF.h | 5 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 33 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/MachO.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/ObjectFile.h | 10 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 44 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | 2 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 7 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/debuglineinfo.test | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 57 |
17 files changed, 199 insertions, 32 deletions
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h index 4fe1f0683ae..dddc7faa73e 100644 --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/include/llvm/DebugInfo/DIContext.h @@ -136,6 +136,43 @@ private: const DIContextKind Kind; }; +/// An inferface for inquiring the load address of a loaded object file +/// to be used by the DIContext implementations when applying relocations +/// on the fly. +class LoadedObjectInfo { +public: + LoadedObjectInfo() {} + virtual ~LoadedObjectInfo() {} + + /// Obtain the Load Address of a section by Name. + /// + /// Calculate the address of the section identified by the passed in Name. + /// The section need not be present in the local address space. The addresses + /// need to be consistent with the addresses used to query the DIContext and + /// the output of this function should be deterministic, i.e. repeated calls with + /// the same Name should give the same address. + virtual uint64_t getSectionLoadAddress(StringRef Name) const = 0; + + /// If conveniently available, return the content of the given Section. + /// + /// When the section is available in the local address space, in relocated (loaded) + /// form, e.g. because it was relocated by a JIT for execution, this function + /// should provide the contents of said section in `Data`. If the loaded section + /// is not available, or the cost of retrieving it would be prohibitive, this + /// function should return false. In that case, relocations will be read from the + /// local (unrelocated) object file and applied on the fly. Note that this method + /// is used purely for optimzation purposes in the common case of JITting in the + /// local address space, so returning false should always be correct. + virtual bool getLoadedSectionContents(StringRef Name, StringRef &Data) const { + return false; + } + + /// Obtain a copy of this LoadedObjectInfo. + /// + /// The caller is responsible for deallocation once the copy is no longer required. + virtual LoadedObjectInfo *clone() const = 0; +}; + } #endif diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index e40d110cdbe..423c0d32f1b 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -255,7 +255,8 @@ class DWARFContextInMemory : public DWARFContext { SmallVector<SmallString<32>, 4> UncompressedSections; public: - DWARFContextInMemory(const object::ObjectFile &Obj); + DWARFContextInMemory(const object::ObjectFile &Obj, + const LoadedObjectInfo *L = nullptr); bool isLittleEndian() const override { return IsLittleEndian; } uint8_t getAddressSize() const override { return AddressSize; } const DWARFSection &getInfoSection() override { return InfoSection; } diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index 5723f058f72..7b3bd939b90 100644 --- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -17,6 +17,7 @@ #include "JITSymbolFlags.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Memory.h" +#include "llvm/DebugInfo/DIContext.h" #include <memory> namespace llvm { @@ -54,7 +55,7 @@ public: }; /// \brief Information about the loaded object. - class LoadedObjectInfo { + class LoadedObjectInfo : public llvm::LoadedObjectInfo { friend class RuntimeDyldImpl; public: LoadedObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index 522bf68c6cb..c83bcec10f2 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -350,6 +350,10 @@ public: return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE; } + bool isSection() const { + return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION; + } + bool isSectionDefinition() const { // C++/CLI creates external ABS symbols for non-const appdomain globals. // These are also followed by an auxiliary section definition. @@ -612,6 +616,7 @@ protected: std::error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; std::error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; std::error_code diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index a6914d5a608..9bd4c324111 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -86,6 +86,7 @@ protected: std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; + section_iterator getSymbolSection(const Elf_Sym *Symb) const; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; @@ -112,6 +113,7 @@ protected: std::error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; std::error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; std::error_code @@ -416,18 +418,23 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { } template <class ELFT> -std::error_code -ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { - const Elf_Sym *ESym = getSymbol(Symb); +section_iterator +ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const { const Elf_Shdr *ESec = EF.getSection(ESym); if (!ESec) - Res = section_end(); + return section_end(); else { DataRefImpl Sec; Sec.p = reinterpret_cast<intptr_t>(ESec); - Res = section_iterator(SectionRef(Sec, this)); + return section_iterator(SectionRef(Sec, this)); } +} + +template <class ELFT> +std::error_code +ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + Res = getSymbolSection(getSymbol(Symb)); return object_error::success; } @@ -588,6 +595,20 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { return symbol_iterator(SymbolRef(SymbolData, this)); } +// ELF relocations can target sections, by targetting a symbol of type +// STT_SECTION +template <class ELFT> +section_iterator +ELFObjectFile<ELFT>::getRelocationSection(DataRefImpl Rel) const { + symbol_iterator Sym = getRelocationSymbol(Rel); + if (Sym == symbol_end()) + return section_end(); + const Elf_Sym *ESym = getSymbol(Sym->getRawDataRefImpl()); + if (ESym->getType() != ELF::STT_SECTION) + return section_end(); + return getSymbolSection(ESym); +} + template <class ELFT> std::error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h index a552aca91d7..0a9b62c9055 100644 --- a/llvm/include/llvm/Object/MachO.h +++ b/llvm/include/llvm/Object/MachO.h @@ -235,6 +235,7 @@ public: std::error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; std::error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; std::error_code @@ -326,7 +327,7 @@ public: unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; - SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const; + SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const; // Walk load commands. LoadCommandInfo getFirstLoadCommandInfo() const; diff --git a/llvm/include/llvm/Object/ObjectFile.h b/llvm/include/llvm/Object/ObjectFile.h index b7e19b941c8..14cd082870b 100644 --- a/llvm/include/llvm/Object/ObjectFile.h +++ b/llvm/include/llvm/Object/ObjectFile.h @@ -32,6 +32,8 @@ class MachOObjectFile; class SymbolRef; class symbol_iterator; +class SectionRef; +typedef content_iterator<SectionRef> section_iterator; /// RelocationRef - This is a value type class that represents a single /// relocation in the list of relocations in the object file. @@ -51,6 +53,7 @@ public: std::error_code getAddress(uint64_t &Result) const; std::error_code getOffset(uint64_t &Result) const; symbol_iterator getSymbol() const; + section_iterator getSection() const; std::error_code getType(uint64_t &Result) const; /// @brief Indicates whether this relocation should hidden when listing @@ -76,8 +79,6 @@ typedef content_iterator<RelocationRef> relocation_iterator; /// SectionRef - This is a value type class that represents a single section in /// the list of sections in the object file. -class SectionRef; -typedef content_iterator<SectionRef> section_iterator; class SectionRef { friend class SymbolRef; DataRefImpl SectionPimpl; @@ -247,6 +248,7 @@ protected: virtual std::error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const = 0; virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; + virtual section_iterator getRelocationSection(DataRefImpl Rel) const = 0; virtual std::error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const = 0; virtual std::error_code @@ -467,6 +469,10 @@ inline symbol_iterator RelocationRef::getSymbol() const { return OwningObject->getRelocationSymbol(RelocationPimpl); } +inline section_iterator RelocationRef::getSection() const { + return OwningObject->getRelocationSection(RelocationPimpl); +} + inline std::error_code RelocationRef::getType(uint64_t &Result) const { return OwningObject->getRelocationType(RelocationPimpl, Result); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 1faa2ba5921..cc2fbbdc8ca 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -540,7 +540,8 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data, return true; } -DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj) +DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, + const LoadedObjectInfo *L) : IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()) { for (const SectionRef &Section : Obj.sections()) { @@ -554,7 +555,12 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj) if (IsVirtual) continue; StringRef data; - Section.getContents(data); + + // Try to obtain an already relocated version of this section. + // Else use the unrelocated section from the object file. We'll have to + // apply relocations ourselves later. + if (!L || !L->getLoadedSectionContents(name,data)) + Section.getContents(data); name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. @@ -622,7 +628,15 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj) continue; StringRef RelSecName; + StringRef RelSecData; RelocatedSection->getName(RelSecName); + + // If the section we're relocating was relocated already by the JIT, + // then we used the relocated version above, so we do not need to process + // relocations for it now. + if (L && L->getLoadedSectionContents(RelSecName,RelSecData)) + continue; + RelSecName = RelSecName.substr( RelSecName.find_first_not_of("._")); // Skip . and _ prefixes. @@ -658,9 +672,33 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj) uint64_t Type; Reloc.getType(Type); uint64_t SymAddr = 0; + uint64_t SectionLoadAddress = 0; object::symbol_iterator Sym = Reloc.getSymbol(); - if (Sym != Obj.symbol_end()) + object::section_iterator RSec = Reloc.getSection(); + + // First calculate the address of the symbol or section as it appears + // in the objct file + if (Sym != Obj.symbol_end()) { Sym->getAddress(SymAddr); + // Also remember what section this symbol is in for later + Sym->getSection(RSec); + } else if (RSec != Obj.section_end()) + SymAddr = RSec->getAddress(); + + // If we are given load addresses for the sections, we need to adjust: + // SymAddr = (Address of Symbol Or Section in File) - + // (Address of Section in File) + + // (Load Address of Section) + if (L != nullptr && RSec != Obj.section_end()) { + // RSec is now either the section being targetted or the section + // containing the symbol being targetted. In either case, + // we need to perform the same computation. + StringRef SecName; + RSec->getName(SecName); + SectionLoadAddress = L->getSectionLoadAddress(SecName); + if (SectionLoadAddress != 0) + SymAddr += SectionLoadAddress - RSec->getAddress(); + } object::RelocVisitor V(Obj); object::RelocToApply R(V.visit(Type, Reloc, SymAddr)); diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp index 8055d550006..0cb1d7bcf1d 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -34,6 +34,8 @@ public: getObjectForDebug(const ObjectFile &Obj) const override { return OwningBinary<ObjectFile>(); } + + RuntimeDyld::LoadedObjectInfo *clone() const { return new LoadedCOFFObjectInfo(*this); } }; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 04b5e4fde18..c22636cc6b3 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -112,6 +112,8 @@ public: OwningBinary<ObjectFile> getObjectForDebug(const ObjectFile &Obj) const override; + + RuntimeDyld::LoadedObjectInfo *clone() const { return new LoadedELFObjectInfo(*this); } }; template <typename ELFT> diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index ee51a754ead..90e61a50a1b 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -203,7 +203,7 @@ protected: SectionList Sections; typedef unsigned SID; // Type for SectionIDs -#define RTDYLD_INVALID_SECTION_ID ((SID)(-1)) +#define RTDYLD_INVALID_SECTION_ID ((RuntimeDyldImpl::SID)(-1)) // Keep a map of sections from object file to the SectionID which // references it. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 675063c81d6..796a69cc836 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -36,6 +36,8 @@ public: getObjectForDebug(const ObjectFile &Obj) const override { return OwningBinary<ObjectFile>(); } + + RuntimeDyld::LoadedObjectInfo *clone() const { return new LoadedMachOObjectInfo(*this); } }; } @@ -75,7 +77,7 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( Value.Offset = RE.Addend; } } else { - SectionRef Sec = Obj.getRelocationSection(RelInfo); + SectionRef Sec = Obj.getAnyRelocationSection(RelInfo); bool IsCode = Sec.isText(); Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); uint64_t Addr = Sec.getAddress(); diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 4c38b8fd2b0..d4f3b430614 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -1044,6 +1044,19 @@ symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { return symbol_iterator(SymbolRef(Ref, this)); } +section_iterator COFFObjectFile::getRelocationSection(DataRefImpl Rel) const { + symbol_iterator Sym = getRelocationSymbol(Rel); + if (Sym == symbol_end()) + return section_end(); + COFFSymbolRef Symb = getCOFFSymbol(*Sym); + if (!Symb.isSection()) + return section_end(); + section_iterator Res(section_end()); + if (getSymbolSection(Sym->getRawDataRefImpl(),Res)) + return section_end(); + return Res; +} + std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { const coff_relocation* R = toRel(Rel); diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 7129aa324ab..fc7b5f2863b 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -710,6 +710,11 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { return symbol_iterator(SymbolRef(Sym, this)); } +section_iterator +MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { + return section_iterator(getAnyRelocationSection(getRelocation(Rel))); +} + std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { MachO::any_relocation_info RE = getRelocation(Rel); @@ -2224,7 +2229,7 @@ MachOObjectFile::getAnyRelocationType( } SectionRef -MachOObjectFile::getRelocationSection( +MachOObjectFile::getAnyRelocationSection( const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) return *section_end(); diff --git a/llvm/test/DebugInfo/debuglineinfo.test b/llvm/test/DebugInfo/debuglineinfo.test index 14d2f82b04a..96a32285be4 100644 --- a/llvm/test/DebugInfo/debuglineinfo.test +++ b/llvm/test/DebugInfo/debuglineinfo.test @@ -1,7 +1,11 @@ RUN: llvm-rtdyld -printline %p/Inputs/test-inline.o \ RUN: | FileCheck %s -check-prefix TEST_INLINE +RUN: llvm-rtdyld -printdebugline %p/Inputs/test-inline.o \ +RUN: | FileCheck %s -check-prefix TEST_INLINE RUN: llvm-rtdyld -printline %p/Inputs/test-parameters.o \ RUN: | FileCheck %s -check-prefix TEST_PARAMETERS +RUN: llvm-rtdyld -printdebugline %p/Inputs/test-parameters.o \ +RUN: | FileCheck %s -check-prefix TEST_PARAMETERS ; This test verifies that relocations are correctly applied to the ; .debug_line section and exercises DIContext::getLineInfoForAddressRange(). diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index b173ce92a0a..84212c94bbb 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -6484,7 +6484,7 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, } auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl()); - SectionRef RelocSection = Obj->getRelocationSection(RE); + SectionRef RelocSection = Obj->getAnyRelocationSection(RE); uint64_t SectionAddr = RelocSection.getAddress(); diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp index c9877c27283..e87f1e2d4c1 100644 --- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -48,6 +48,7 @@ InputFileList(cl::Positional, cl::ZeroOrMore, enum ActionType { AC_Execute, AC_PrintLineInfo, + AC_PrintDebugLineInfo, AC_Verify }; @@ -58,6 +59,8 @@ Action(cl::desc("Action to perform:"), "Load, link, and execute the inputs."), clEnumValN(AC_PrintLineInfo, "printline", "Load, link, and print line information for each function."), + clEnumValN(AC_PrintDebugLineInfo, "printdebugline", + "Load, link, and print line information for each function using the debug object"), clEnumValN(AC_Verify, "verify", "Load, link and verify the resulting memory image."), clEnumValEnd)); @@ -189,7 +192,9 @@ static void loadDylibs() { /* *** */ -static int printLineInfoForInput() { +static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { + assert(LoadObjects || !UseDebugObj); + // Load any dylibs requested on the command line. loadDylibs(); @@ -216,24 +221,32 @@ static int printLineInfoForInput() { ObjectFile &Obj = **MaybeObj; - // Load the object file - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = - Dyld.loadObject(Obj); + OwningBinary<ObjectFile> DebugObj; + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; + ObjectFile *SymbolObj = &Obj; + if (LoadObjects) { + // Load the object file + LoadedObjInfo = + Dyld.loadObject(Obj); - if (Dyld.hasError()) - return Error(Dyld.getErrorString()); + if (Dyld.hasError()) + return Error(Dyld.getErrorString()); - // Resolve all the relocations we can. - Dyld.resolveRelocations(); + // Resolve all the relocations we can. + Dyld.resolveRelocations(); - OwningBinary<ObjectFile> DebugObj = LoadedObjInfo->getObjectForDebug(Obj); + if (UseDebugObj) { + DebugObj = LoadedObjInfo->getObjectForDebug(Obj); + SymbolObj = DebugObj.getBinary(); + } + } std::unique_ptr<DIContext> Context( - new DWARFContextInMemory(*DebugObj.getBinary())); + new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); // Use symbol info to iterate functions in the object. - for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(), - E = DebugObj.getBinary()->symbol_end(); + for (object::symbol_iterator I = SymbolObj->symbol_begin(), + E = SymbolObj->symbol_end(); I != E; ++I) { object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; @@ -245,7 +258,21 @@ static int printLineInfoForInput() { if (I->getAddress(Addr)) continue; if (I->getSize(Size)) continue; - outs() << "Function: " << Name << ", Size = " << Size << "\n"; + // If we're not using the debug object, compute the address of the + // symbol in memory (rather than that in the unrelocated object file) + // and use that to query the DWARFContext. + if (!UseDebugObj && LoadObjects) { + object::section_iterator Sec(SymbolObj->section_end()); + I->getSection(Sec); + StringRef SecName; + Sec->getName(SecName); + uint64_t SectionLoadAddress = + LoadedObjInfo->getSectionLoadAddress(SecName); + if (SectionLoadAddress != 0) + Addr += SectionLoadAddress - Sec->getAddress(); + } + + outs() << "Function: " << Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); DILineInfoTable::iterator Begin = Lines.begin(); @@ -594,8 +621,10 @@ int main(int argc, char **argv) { switch (Action) { case AC_Execute: return executeInput(); + case AC_PrintDebugLineInfo: + return printLineInfoForInput(true,true); case AC_PrintLineInfo: - return printLineInfoForInput(); + return printLineInfoForInput(true,false); case AC_Verify: return linkAndVerify(); } |

