diff --git a/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h b/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h --- a/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h +++ b/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h @@ -141,6 +141,8 @@ std::vector Files; std::vector UUID; Optional ValidTextRanges; + AddressRanges Ranges; + llvm::Optional BaseAddress; bool Finalized = false; public: @@ -231,6 +233,17 @@ /// object. size_t getNumFunctionInfos() const; + /// Check if an address has already been added as a function info. + /// + /// FunctionInfo data can come from many sources: debug info, symbol tables, + /// exception information, and more. Symbol tables should be added after + /// debug info and can use this function to see if a symbol's start address + /// has already been added to the GsymReader. Calling this before adding + /// a function info from a source other than debug info avoids clients adding + /// many redundant FunctionInfo objects from many sources only for them to be + /// removed during the finalize() call. + bool hasFunctionInfoForAddress(uint64_t Addr) const; + /// Set valid .text address ranges that all functions must be contained in. void SetValidTextRanges(AddressRanges &TextRanges) { ValidTextRanges = TextRanges; @@ -262,6 +275,20 @@ /// text ranges have been set, false otherwise. bool IsValidTextAddress(uint64_t Addr) const; + /// Set the base address to use for the GSYM file. + /// + /// Setting the base address to use for the GSYM file. Object files typically + /// get loaded from a base address when the OS loads them into memory. Using + /// GSYM files for symbolication becomes easier if the base address in the + /// GSYM header is the same address as it allows addresses to be easily slid + /// and allows symbolication without needing to find the original base + /// address in the original object file. + /// + /// \param Addr The address to use as the base address of the GSYM file + /// when it is saved to disk. + void setBaseAddress(uint64_t Addr) { + BaseAddress = Addr; + } }; } // namespace gsym diff --git a/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h b/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h --- a/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h +++ b/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h @@ -257,11 +257,15 @@ /// \returns The matching address offset index. This index will be used to /// extract the FunctionInfo data's offset from the AddrInfoOffsets array. template - uint64_t getAddressOffsetIndex(const uint64_t AddrOffset) const { + llvm::Optional getAddressOffsetIndex(const uint64_t AddrOffset) const { ArrayRef AIO = getAddrOffsets(); const auto Begin = AIO.begin(); const auto End = AIO.end(); auto Iter = std::lower_bound(Begin, End, AddrOffset); + // Watch for addresses that fall between the gsym::Header::BaseAddress and + // the first address offset. + if (Iter == Begin && AddrOffset < *Begin) + return llvm::None; if (Iter == End || AddrOffset < *Iter) --Iter; return std::distance(Begin, Iter); diff --git a/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h b/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h @@ -0,0 +1,51 @@ +//===- ObjectFileTransformer.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H +#define LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H + +#include "llvm/Support/Error.h" + +namespace llvm { + +class raw_ostream; + +namespace object { +class ObjectFile; +} + +namespace gsym { + +struct CUInfo; +class GsymCreator; + +class ObjectFileTransformer { +public: + /// Extract any object file data that is needed by the GsymCreator. + /// + /// The extracted information includes the UUID of the binary and converting + /// all function symbols from any symbol tables into FunctionInfo objects. + /// + /// \param Obj The object file that contains the DWARF debug info. + /// + /// \param Log The stream to log warnings and non fatal issues to. + /// + /// \param Gsym The GSYM creator to populate with the function information + /// from the debug info. + /// + /// \returns An error indicating any fatal issues that happen when parsing + /// the DWARF, or Error::success() if all goes well. + static llvm::Error convert(const object::ObjectFile &Obj, + raw_ostream &Log, + GsymCreator &Gsym); +}; + +} // namespace gsym +} // namespace llvm + +#endif // #ifndef LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H diff --git a/llvm/include/llvm/DebugInfo/GSYM/Range.h b/llvm/include/llvm/DebugInfo/GSYM/Range.h --- a/llvm/include/llvm/DebugInfo/GSYM/Range.h +++ b/llvm/include/llvm/DebugInfo/GSYM/Range.h @@ -9,6 +9,7 @@ #ifndef LLVM_DEBUGINFO_GSYM_RANGE_H #define LLVM_DEBUGINFO_GSYM_RANGE_H +#include "llvm/ADT/Optional.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include @@ -89,6 +90,7 @@ bool empty() const { return Ranges.empty(); } bool contains(uint64_t Addr) const; bool contains(AddressRange Range) const; + Optional getRangeThatContains(uint64_t Addr) const; void insert(AddressRange Range); size_t size() const { return Ranges.size(); } bool operator==(const AddressRanges &RHS) const { diff --git a/llvm/lib/DebugInfo/GSYM/CMakeLists.txt b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt --- a/llvm/lib/DebugInfo/GSYM/CMakeLists.txt +++ b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt @@ -12,6 +12,7 @@ InlineInfo.cpp LineTable.cpp LookupResult.cpp + ObjectFileTransformer.cpp Range.cpp ADDITIONAL_HEADER_DIRS diff --git a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp --- a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp +++ b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp @@ -170,7 +170,7 @@ // This function will be called with the result of a binary search of the // address table, we must still make sure the address does not fall into a // gap between functions are after the last function. - if (Addr >= LR.FuncRange.End) + if (LR.FuncRange.size() > 0 && !LR.FuncRange.contains(Addr)) return createStringError(std::errc::io_error, "address 0x%" PRIx64 " is not in GSYM", Addr); diff --git a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp --- a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp +++ b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp @@ -62,7 +62,8 @@ if (Funcs.size() > UINT32_MAX) return createStringError(std::errc::invalid_argument, "too many FunctionInfos"); - const uint64_t MinAddr = Funcs.front().startAddress(); + + const uint64_t MinAddr = BaseAddress ? *BaseAddress : Funcs.front().startAddress(); const uint64_t MaxAddr = Funcs.back().startAddress(); const uint64_t AddrDelta = MaxAddr - MinAddr; Header Hdr; @@ -238,6 +239,17 @@ Prev = Curr++; } + // If our last function info entry doesn't have a size and if we have valid + // text ranges, we should set the size of the last entry since any search for + // a high address might match our last entry. By fixing up this size, we can + // help ensure we don't cause lookups to always return the last symbol that + // has no size when doing lookups. + if (!Funcs.empty() && Funcs.back().Range.size() == 0 && ValidTextRanges) { + if (auto Range = ValidTextRanges->getRangeThatContains( + Funcs.back().Range.Start)) { + Funcs.back().Range.End = Range->End; + } + } OS << "Pruned " << NumBefore - Funcs.size() << " functions, ended with " << Funcs.size() << " total\n"; return Error::success(); @@ -263,6 +275,7 @@ void GsymCreator::addFunctionInfo(FunctionInfo &&FI) { std::lock_guard Guard(Mutex); + Ranges.insert(FI.Range); Funcs.emplace_back(FI); } @@ -294,3 +307,8 @@ return ValidTextRanges->contains(Addr); return true; // No valid text ranges has been set, so accept all ranges. } + +bool GsymCreator::hasFunctionInfoForAddress(uint64_t Addr) const { + std::lock_guard Guard(Mutex); + return Ranges.contains(Addr); +} diff --git a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp --- a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp +++ b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp @@ -225,20 +225,33 @@ Expected GsymReader::getAddressIndex(const uint64_t Addr) const { - if (Addr < Hdr->BaseAddress) - return createStringError(std::errc::invalid_argument, - "address 0x%" PRIx64 " is not in GSYM", Addr); - const uint64_t AddrOffset = Addr - Hdr->BaseAddress; - switch (Hdr->AddrOffSize) { - case 1: return getAddressOffsetIndex(AddrOffset); - case 2: return getAddressOffsetIndex(AddrOffset); - case 4: return getAddressOffsetIndex(AddrOffset); - case 8: return getAddressOffsetIndex(AddrOffset); - default: break; + if (Addr >= Hdr->BaseAddress) { + const uint64_t AddrOffset = Addr - Hdr->BaseAddress; + Optional AddrOffsetIndex; + switch (Hdr->AddrOffSize) { + case 1: + AddrOffsetIndex = getAddressOffsetIndex(AddrOffset); + break; + case 2: + AddrOffsetIndex = getAddressOffsetIndex(AddrOffset); + break; + case 4: + AddrOffsetIndex = getAddressOffsetIndex(AddrOffset); + break; + case 8: + AddrOffsetIndex = getAddressOffsetIndex(AddrOffset); + break; + default: + return createStringError(std::errc::invalid_argument, + "unsupported address offset size %u", + Hdr->AddrOffSize); + } + if (AddrOffsetIndex) + return *AddrOffsetIndex; } return createStringError(std::errc::invalid_argument, - "unsupported address offset size %u", - Hdr->AddrOffSize); + "address 0x%" PRIx64 " is not in GSYM", Addr); + } llvm::Expected GsymReader::getFunctionInfo(uint64_t Addr) const { diff --git a/llvm/lib/DebugInfo/GSYM/LookupResult.cpp b/llvm/lib/DebugInfo/GSYM/LookupResult.cpp --- a/llvm/lib/DebugInfo/GSYM/LookupResult.cpp +++ b/llvm/lib/DebugInfo/GSYM/LookupResult.cpp @@ -35,19 +35,24 @@ } raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const SourceLocation &SL) { - OS << SL.Name << " @ "; - if (!SL.Dir.empty()) { - OS << SL.Dir; - if (SL.Dir.contains('\\') and not SL.Dir.contains('/')) - OS << '\\'; + OS << SL.Name; + if (SL.Offset > 0) + OS << " + " << SL.Offset; + if (SL.Dir.size() || SL.Base.size()) { + OS << " @ "; + if (!SL.Dir.empty()) { + OS << SL.Dir; + if (SL.Dir.contains('\\') and not SL.Dir.contains('/')) + OS << '\\'; + else + OS << '/'; + } + if (SL.Base.empty()) + OS << ""; else - OS << '/'; + OS << SL.Base; + OS << ':' << SL.Line; } - if (SL.Base.empty()) - OS << ""; - else - OS << SL.Base; - OS << ':' << SL.Line; return OS; } diff --git a/llvm/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp b/llvm/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp @@ -0,0 +1,107 @@ +//===- ObjectFileTransformer.cpp --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/raw_ostream.h" + +#include "llvm/DebugInfo/GSYM/ObjectFileTransformer.h" +#include "llvm/DebugInfo/GSYM/GsymCreator.h" + +using namespace llvm; +using namespace gsym; + +constexpr uint32_t NT_GNU_BUILD_ID_TAG = 0x03; + +static std::vector getUUID(const object::ObjectFile &Obj) { + // Extract the UUID from the object file + std::vector UUID; + if (auto *MachO = dyn_cast(&Obj)) { + const ArrayRef MachUUID = MachO->getUuid(); + if (!MachUUID.empty()) + UUID.assign(MachUUID.data(), MachUUID.data() + MachUUID.size()); + } else if (isa(&Obj)) { + const StringRef GNUBuildID(".note.gnu.build-id"); + for (const object::SectionRef &Sect : Obj.sections()) { + Expected SectNameOrErr = Sect.getName(); + if (!SectNameOrErr) { + consumeError(SectNameOrErr.takeError()); + continue; + } + StringRef SectName(*SectNameOrErr); + if (SectName != GNUBuildID) + continue; + StringRef BuildIDData; + Expected E = Sect.getContents(); + if (E) + BuildIDData = *E; + else { + consumeError(E.takeError()); + continue; + } + DataExtractor Decoder(BuildIDData, Obj.makeTriple().isLittleEndian(), 8); + uint64_t Offset = 0; + const uint32_t NameSize = Decoder.getU32(&Offset); + const uint32_t PayloadSize = Decoder.getU32(&Offset); + const uint32_t PayloadType = Decoder.getU32(&Offset); + StringRef Name(Decoder.getFixedLengthString(&Offset, NameSize)); + if (Name == "GNU" && PayloadType == NT_GNU_BUILD_ID_TAG) { + Offset = alignTo(Offset, 4); + StringRef UUIDBytes(Decoder.getBytes(&Offset, PayloadSize)); + if (!UUIDBytes.empty()) { + auto Ptr = reinterpret_cast(UUIDBytes.data()); + UUID.assign(Ptr, Ptr + UUIDBytes.size()); + } + } + } + } + return UUID; +} + +llvm::Error ObjectFileTransformer::convert(const object::ObjectFile &Obj, + raw_ostream &Log, + GsymCreator &Gsym) { + using namespace llvm::object; + + const bool IsMachO = isa(&Obj); + const bool IsELF = isa(&Obj); + + // Read build ID. + Gsym.setUUID(getUUID(Obj)); + + // Parse the symbol table. + size_t NumBefore = Gsym.getNumFunctionInfos(); + for (const object::SymbolRef &Sym : Obj.symbols()) { + Expected SymType = Sym.getType(); + const uint64_t Addr = Sym.getValue(); + if (!SymType || SymType.get() != SymbolRef::Type::ST_Function || + !Gsym.IsValidTextAddress(Addr) || Gsym.hasFunctionInfoForAddress(Addr)) + continue; + // Function size for MachO files will be 0 + constexpr bool NoCopy = false; + const uint64_t size = IsELF ? ELFSymbolRef(Sym).getSize() : 0; + Expected Name = Sym.getName(); + if (!Name) { + logAllUnhandledErrors(Name.takeError(), Log, "ObjectFileTransformer: "); + continue; + } + // Remove the leading '_' character in any symbol names if there is one + // for mach-o files. + if (IsMachO) + Name->consume_front("_"); + Gsym.addFunctionInfo(FunctionInfo(Addr, size, + Gsym.insertString(*Name, NoCopy))); + } + size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore; + Log << "Loaded " << FunctionsAddedCount << " functions from symbol table.\n"; + return Error::success(); +} diff --git a/llvm/lib/DebugInfo/GSYM/Range.cpp b/llvm/lib/DebugInfo/GSYM/Range.cpp --- a/llvm/lib/DebugInfo/GSYM/Range.cpp +++ b/llvm/lib/DebugInfo/GSYM/Range.cpp @@ -53,6 +53,16 @@ return Range.End <= It[-1].End; } +Optional +AddressRanges::getRangeThatContains(uint64_t Addr) const { + auto It = std::partition_point( + Ranges.begin(), Ranges.end(), + [=](const AddressRange &R) { return R.Start <= Addr; }); + if (It != Ranges.begin() && Addr < It[-1].End) + return It[-1]; + return llvm::None; +} + raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) { return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")"; } diff --git a/llvm/test/tools/llvm-gsymutil/cmdline.test b/llvm/test/tools/llvm-gsymutil/cmdline.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-gsymutil/cmdline.test @@ -0,0 +1,21 @@ +RUN: llvm-gsymutil -h 2>&1 | FileCheck --check-prefix=HELP %s +RUN: llvm-gsymutil --help 2>&1 | FileCheck --check-prefix=HELP %s +HELP: OVERVIEW: A tool for dumping, searching and creating GSYM files. +HELP: USAGE: llvm-gsymutil{{[^ ]*}} [options] +HELP: OPTIONS: +HELP: Conversion Options: +HELP: --arch= +HELP: --convert= +HELP: --num-threads= +HELP: --out-file= +HELP: --verify +HELP: Generic Options: +HELP: --help +HELP: --version +HELP: Lookup Options: +HELP: --address= +HELP: Options: +HELP: --verbose + +RUN: llvm-gsymutil --version 2>&1 | FileCheck --check-prefix=VERSION %s +VERSION: {{ version }} diff --git a/llvm/test/tools/llvm-gsymutil/elf-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/elf-dwarf.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-gsymutil/elf-dwarf.yaml @@ -0,0 +1,687 @@ +## Test loading an ELF file with DWARF. First we make the ELF file from yaml, +## then we convert the ELF file to GSYM, then we do lookups on the newly +## created GSYM, and finally we dump the entire GSYM. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=CONVERT +# RUN: llvm-gsymutil --address=0x400391 --address=0x4004cd %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDR +# RUN: llvm-gsymutil --address=0x400391 --address=0x4004cd --verbose %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDRV --dump-input=always +# RUN: llvm-gsymutil %t.gsym 2>&1 | FileCheck %s --check-prefix=DUMP + +# ADDR: Looking up addresses in "{{.*\.yaml\.tmp\.gsym}}": +# ADDR: 0x0000000000400391: _init +# ADDR: 0x00000000004004cd: main @ /tmp/main.cpp:1 + +# ADDRV: Looking up addresses in "{{.*\.yaml\.tmp\.gsym}}": +# ADDRV: FunctionInfo for 0x0000000000400391: +# ADDRV: [0x0000000000400390 - 0x0000000000400390) "_init" +# ADDRV: LookupResult for 0x0000000000400391: +# ADDRV: 0x0000000000400391: _init +# ADDRV: FunctionInfo for 0x00000000004004cd: +# ADDRV: [0x00000000004004cd - 0x00000000004004df) "main" +# ADDRV: LineTable: +# ADDRV: 0x00000000004004cd /tmp/main.cpp:1 +# ADDRV: 0x00000000004004d8 /tmp/main.cpp:2 +# ADDRV: 0x00000000004004dd /tmp/main.cpp:3 +# ADDRV: LookupResult for 0x00000000004004cd: +# ADDRV: 0x00000000004004cd: main @ /tmp/main.cpp:1 + +# CONVERT: Input file: {{.*\.yaml\.tmp}} +# CONVERT: Output file (x86_64): {{.*\.yaml\.tmp\.gsym}} +# CONVERT: Loaded 1 functions from DWARF. +# CONVERT: Loaded 9 functions from symbol table. +# CONVERT: Pruned 0 functions, ended with 10 total + +# DUMP: Header: +# DUMP-NEXT: Magic = 0x4753594d +# DUMP-NEXT: Version = 0x0001 +# DUMP-NEXT: AddrOffSize = 0x02 +# DUMP-NEXT: UUIDSize = 0x14 +# DUMP-NEXT: BaseAddress = 0x0000000000400000 +# DUMP-NEXT: NumAddresses = 0x0000000a +# DUMP-NEXT: StrtabOffset = 0x00000080 +# DUMP-NEXT: StrtabSize = 0x00000091 +# DUMP-NEXT: UUID = 0e62be89cad89206110ed1375b618656f32ac906 + +# DUMP: Address Table: +# DUMP-NEXT: INDEX OFFSET16 (ADDRESS) +# DUMP-NEXT: ====== =============================== +# DUMP-NEXT: [ 0] 0x0390 (0x0000000000400390) +# DUMP-NEXT: [ 1] 0x03e0 (0x00000000004003e0) +# DUMP-NEXT: [ 2] 0x0410 (0x0000000000400410) +# DUMP-NEXT: [ 3] 0x0440 (0x0000000000400440) +# DUMP-NEXT: [ 4] 0x0480 (0x0000000000400480) +# DUMP-NEXT: [ 5] 0x04a0 (0x00000000004004a0) +# DUMP-NEXT: [ 6] 0x04cd (0x00000000004004cd) +# DUMP-NEXT: [ 7] 0x04e0 (0x00000000004004e0) +# DUMP-NEXT: [ 8] 0x0550 (0x0000000000400550) +# DUMP-NEXT: [ 9] 0x0554 (0x0000000000400554) + +# DUMP: Address Info Offsets: +# DUMP-NEXT: INDEX Offset +# DUMP-NEXT: ====== ========== +# DUMP-NEXT: [ 0] 0x00000114 +# DUMP-NEXT: [ 1] 0x00000124 +# DUMP-NEXT: [ 2] 0x00000134 +# DUMP-NEXT: [ 3] 0x00000144 +# DUMP-NEXT: [ 4] 0x00000154 +# DUMP-NEXT: [ 5] 0x00000164 +# DUMP-NEXT: [ 6] 0x00000174 +# DUMP-NEXT: [ 7] 0x00000194 +# DUMP-NEXT: [ 8] 0x000001a4 +# DUMP-NEXT: [ 9] 0x000001b4 + +# DUMP: Files: +# DUMP-NEXT: INDEX DIRECTORY BASENAME PATH +# DUMP-NEXT: ====== ========== ========== ============================== +# DUMP-NEXT: [ 0] 0x00000000 0x00000000 +# DUMP-NEXT: [ 1] 0x00000006 0x0000000b /tmp/main.cpp + +# DUMP: String table: +# DUMP-NEXT: 0x00000000: "" +# DUMP-NEXT: 0x00000001: "main" +# DUMP-NEXT: 0x00000006: "/tmp" +# DUMP-NEXT: 0x0000000b: "main.cpp" +# DUMP-NEXT: 0x00000014: "deregister_tm_clones" +# DUMP-NEXT: 0x00000029: "register_tm_clones" +# DUMP-NEXT: 0x0000003c: "__do_global_dtors_aux" +# DUMP-NEXT: 0x00000052: "frame_dummy" +# DUMP-NEXT: 0x0000005e: "__libc_csu_fini" +# DUMP-NEXT: 0x0000006e: "_fini" +# DUMP-NEXT: 0x00000074: "__libc_csu_init" +# DUMP-NEXT: 0x00000084: "_start" +# DUMP-NEXT: 0x0000008b: "_init" +# DUMP: FunctionInfo @ 0x00000114: [0x0000000000400390 - 0x0000000000400390) "_init" +# DUMP: FunctionInfo @ 0x00000124: [0x00000000004003e0 - 0x00000000004003e0) "_start" +# DUMP: FunctionInfo @ 0x00000134: [0x0000000000400410 - 0x0000000000400410) "deregister_tm_clones" +# DUMP: FunctionInfo @ 0x00000144: [0x0000000000400440 - 0x0000000000400440) "register_tm_clones" +# DUMP: FunctionInfo @ 0x00000154: [0x0000000000400480 - 0x0000000000400480) "__do_global_dtors_aux" +# DUMP: FunctionInfo @ 0x00000164: [0x00000000004004a0 - 0x00000000004004a0) "frame_dummy" +# DUMP: FunctionInfo @ 0x00000174: [0x00000000004004cd - 0x00000000004004df) "main" +# DUMP-NEXT: LineTable: +# DUMP-NEXT: 0x00000000004004cd /tmp/main.cpp:1 +# DUMP-NEXT: 0x00000000004004d8 /tmp/main.cpp:2 +# DUMP-NEXT: 0x00000000004004dd /tmp/main.cpp:3 +# DUMP: FunctionInfo @ 0x00000194: [0x00000000004004e0 - 0x0000000000400545) "__libc_csu_init" +# DUMP: FunctionInfo @ 0x000001a4: [0x0000000000400550 - 0x0000000000400552) "__libc_csu_fini" +# DUMP: FunctionInfo @ 0x000001b4: [0x0000000000400554 - 0x000000000040055d) "_fini" +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x00000000004003E0 +Sections: + - Name: .interp + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400238 + AddressAlign: 0x0000000000000001 + Content: 2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200 + - Name: .note.ABI-tag + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400254 + AddressAlign: 0x0000000000000004 + Notes: + - Name: GNU + Desc: '00000000020000000600000020000000' + Type: 0x00000001 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400274 + AddressAlign: 0x0000000000000004 + Notes: + - Name: GNU + Desc: 0E62BE89CAD89206110ED1375B618656F32AC906 + Type: 0x00000003 + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400298 + Link: .dynsym + AddressAlign: 0x0000000000000008 + Header: + SymNdx: 0x00000001 + Shift2: 0x00000000 + BloomFilter: [ 0x0000000000000000 ] + HashBuckets: [ 0x00000000 ] + HashValues: [ ] + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400338 + Link: .dynsym + AddressAlign: 0x0000000000000002 + EntSize: 0x0000000000000002 + Entries: [ 0, 2, 0 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400340 + Link: .dynstr + AddressAlign: 0x0000000000000008 + Info: 0x0000000000000001 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400360 + Link: .dynsym + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000018 + Relocations: + - Offset: 0x0000000000600FF8 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x0000000000400378 + Link: .dynsym + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000018 + Info: .got.plt + Relocations: + - Offset: 0x0000000000601018 + Symbol: __libc_start_main + Type: R_X86_64_JUMP_SLOT + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400390 + AddressAlign: 0x0000000000000004 + Content: 4883EC08488B055D0C20004885C07405E82B0000004883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004003B0 + AddressAlign: 0x0000000000000010 + EntSize: 0x0000000000000010 + Content: FF35520C2000FF25540C20000F1F4000FF25520C20006800000000E9E0FFFFFF + - Name: .plt.got + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004003D0 + AddressAlign: 0x0000000000000008 + Content: FF25220C20006690 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004003E0 + AddressAlign: 0x0000000000000010 + Content: 31ED4989D15E4889E24883E4F0505449C7C05005400048C7C1E004400048C7C7CD044000E8B7FFFFFFF4660F1F440000B82F10600055482D281060004883F80E4889E577025DC3B8000000004885C074F45DBF28106000FFE00F1F8000000000B82810600055482D2810600048C1F8034889E54889C248C1EA3F4801D048D1F875025DC3BA000000004885D274F45D4889C6BF28106000FFE20F1F8000000000803D9D0B2000007511554889E5E87EFFFFFF5DC6058A0B200001F3C30F1F400048833D7809200000741EB8000000004885C0741455BF200E60004889E5FFD05DE97BFFFFFF0F1F00E973FFFFFF554889E5897DFC488975F0B8000000005DC39041574189FF41564989F641554989D541544C8D251809200055488D2D18092000534C29E531DB48C1FD034883EC08E87DFEFFFF4885ED741E0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400554 + AddressAlign: 0x0000000000000004 + Content: 4883EC084883C408C3 + - Name: .rodata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400560 + AddressAlign: 0x0000000000000008 + Content: '01000200000000000000000000000000' + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400570 + AddressAlign: 0x0000000000000004 + Content: 011B033B340000000500000040FEFFFF8000000070FEFFFF500000005DFFFFFFA800000070FFFFFFC8000000E0FFFFFF10010000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x00000000004005A8 + AddressAlign: 0x0000000000000008 + Content: 1400000000000000017A5200017810011B0C070890010710140000001C00000018FEFFFF2A00000000000000000000001400000000000000017A5200017810011B0C070890010000240000001C000000B8FDFFFF20000000000E10460E184A0F0B770880003F1A3B2A332422000000001C00000044000000ADFEFFFF1200000000410E108602430D064D0C07080000004400000064000000A0FEFFFF6500000000420E108F02450E188E03450E208D04450E288C05480E308606480E3883074D0E406C0E38410E30410E28420E20420E18420E10420E080014000000AC000000C8FEFFFF02000000000000000000000000000000 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000600E10 + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000008 + Content: A004400000000000 + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000600E18 + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000008 + Content: '8004400000000000' + - Name: .jcr + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000600E20 + AddressAlign: 0x0000000000000008 + Content: '0000000000000000' + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000600E28 + Link: .dynstr + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000010 + Entries: + - Tag: DT_NEEDED + Value: 0x0000000000000001 + - Tag: DT_INIT + Value: 0x0000000000400390 + - Tag: DT_FINI + Value: 0x0000000000400554 + - Tag: DT_INIT_ARRAY + Value: 0x0000000000600E10 + - Tag: DT_INIT_ARRAYSZ + Value: 0x0000000000000008 + - Tag: DT_FINI_ARRAY + Value: 0x0000000000600E18 + - Tag: DT_FINI_ARRAYSZ + Value: 0x0000000000000008 + - Tag: DT_GNU_HASH + Value: 0x0000000000400298 + - Tag: DT_STRTAB + Value: 0x0000000000400300 + - Tag: DT_SYMTAB + Value: 0x00000000004002B8 + - Tag: DT_STRSZ + Value: 0x0000000000000038 + - Tag: DT_SYMENT + Value: 0x0000000000000018 + - Tag: DT_DEBUG + Value: 0x0000000000000000 + - Tag: DT_PLTGOT + Value: 0x0000000000601000 + - Tag: DT_PLTRELSZ + Value: 0x0000000000000018 + - Tag: DT_PLTREL + Value: 0x0000000000000007 + - Tag: DT_JMPREL + Value: 0x0000000000400378 + - Tag: DT_RELA + Value: 0x0000000000400360 + - Tag: DT_RELASZ + Value: 0x0000000000000018 + - Tag: DT_RELAENT + Value: 0x0000000000000018 + - Tag: DT_VERNEED + Value: 0x0000000000400340 + - Tag: DT_VERNEEDNUM + Value: 0x0000000000000001 + - Tag: DT_VERSYM + Value: 0x0000000000400338 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000600FF8 + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000008 + Content: '0000000000000000' + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000601000 + AddressAlign: 0x0000000000000008 + EntSize: 0x0000000000000008 + Content: 280E60000000000000000000000000000000000000000000C603400000000000 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000601020 + AddressAlign: 0x0000000000000001 + Content: '00000000' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000601024 + AddressAlign: 0x0000000000000001 + Size: 0x0000000000000004 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + EntSize: 0x0000000000000001 + Content: 4743433A2028474E552920342E382E3520323031353036323320285265642048617420342E382E352D33362900 + - Name: .debug_aranges + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 2C000000020000000000080000000000CD04400000000000120000000000000000000000000000000000000000000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 8700000004000000000008011D000000040F00000005000000CD04400000000000120000000000000000000000020A00000001016B000000CD044000000000001200000000000000019C6B000000031800000001016B00000002916C030000000001017200000002916000040405696E740005087800000005087E00000006830000000701066B00000000 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 011101250E130B030E1B0E1101120710170000022E013F19030E3A0B3B0B491311011207401897421901130000030500030E3A0B3B0B4913021800000424000B0B3E0B03080000050F000B0B49130000062600491300000724000B0B3E0B030E000000 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 3800000002001F0000000101FB0E0D000101010100000001000001006D61696E2E6370700000000000000902CD0440000000000001AD590202000101 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + EntSize: 0x0000000000000001 + Content: 61726776002F746D70006D61696E006D61696E2E637070006172676300474E5520432B2B20342E382E3520323031353036323320285265642048617420342E382E352D333629202D6D74756E653D67656E65726963202D6D617263683D7838362D3634202D67202D4F30006368617200 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + VAddr: 0x0000000000400000 + PAddr: 0x0000000000400000 + Align: 1024 + Sections: + - Section: .interp + - Section: .interp + - Section: .note.ABI-tag + - Section: .note.gnu.build-id + - Section: .gnu.hash + - Section: .dynsym + - Section: .dynstr + - Section: .gnu.version + - Section: .gnu.version_r + - Section: .rela.dyn + - Section: .rela.plt + - Section: .init + - Section: .plt + - Section: .plt.got + - Section: .text + - Section: .fini + - Section: .rodata + - Section: .eh_frame_hdr + - Section: .eh_frame +Symbols: + - Name: .interp + Type: STT_SECTION + Section: .interp + Value: 0x0000000000400238 + - Name: .note.ABI-tag + Type: STT_SECTION + Section: .note.ABI-tag + Value: 0x0000000000400254 + - Name: .note.gnu.build-id + Type: STT_SECTION + Section: .note.gnu.build-id + Value: 0x0000000000400274 + - Name: .gnu.hash + Type: STT_SECTION + Section: .gnu.hash + Value: 0x0000000000400298 + - Name: .dynsym + Type: STT_SECTION + Section: .dynsym + Value: 0x00000000004002B8 + - Name: .dynstr + Type: STT_SECTION + Section: .dynstr + Value: 0x0000000000400300 + - Name: .gnu.version + Type: STT_SECTION + Section: .gnu.version + Value: 0x0000000000400338 + - Name: .gnu.version_r + Type: STT_SECTION + Section: .gnu.version_r + Value: 0x0000000000400340 + - Name: .rela.dyn + Type: STT_SECTION + Section: .rela.dyn + Value: 0x0000000000400360 + - Name: .rela.plt + Type: STT_SECTION + Section: .rela.plt + Value: 0x0000000000400378 + - Name: .init + Type: STT_SECTION + Section: .init + Value: 0x0000000000400390 + - Name: .plt + Type: STT_SECTION + Section: .plt + Value: 0x00000000004003B0 + - Name: .plt.got + Type: STT_SECTION + Section: .plt.got + Value: 0x00000000004003D0 + - Name: .text + Type: STT_SECTION + Section: .text + Value: 0x00000000004003E0 + - Name: .fini + Type: STT_SECTION + Section: .fini + Value: 0x0000000000400554 + - Name: .rodata + Type: STT_SECTION + Section: .rodata + Value: 0x0000000000400560 + - Name: .eh_frame_hdr + Type: STT_SECTION + Section: .eh_frame_hdr + Value: 0x0000000000400570 + - Name: .eh_frame + Type: STT_SECTION + Section: .eh_frame + Value: 0x00000000004005A8 + - Name: .init_array + Type: STT_SECTION + Section: .init_array + Value: 0x0000000000600E10 + - Name: .fini_array + Type: STT_SECTION + Section: .fini_array + Value: 0x0000000000600E18 + - Name: .jcr + Type: STT_SECTION + Section: .jcr + Value: 0x0000000000600E20 + - Name: .dynamic + Type: STT_SECTION + Section: .dynamic + Value: 0x0000000000600E28 + - Name: .got + Type: STT_SECTION + Section: .got + Value: 0x0000000000600FF8 + - Name: .got.plt + Type: STT_SECTION + Section: .got.plt + Value: 0x0000000000601000 + - Name: .data + Type: STT_SECTION + Section: .data + Value: 0x0000000000601020 + - Name: .bss + Type: STT_SECTION + Section: .bss + Value: 0x0000000000601024 + - Name: .comment + Type: STT_SECTION + Section: .comment + - Name: .debug_aranges + Type: STT_SECTION + Section: .debug_aranges + - Name: .debug_info + Type: STT_SECTION + Section: .debug_info + - Name: .debug_abbrev + Type: STT_SECTION + Section: .debug_abbrev + - Name: .debug_line + Type: STT_SECTION + Section: .debug_line + - Name: .debug_str + Type: STT_SECTION + Section: .debug_str + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: __JCR_LIST__ + Type: STT_OBJECT + Section: .jcr + Value: 0x0000000000600E20 + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x0000000000400410 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x0000000000400440 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x0000000000400480 + - Name: completed.6355 + Type: STT_OBJECT + Section: .bss + Value: 0x0000000000601024 + Size: 0x0000000000000001 + - Name: __do_global_dtors_aux_fini_array_entry + Type: STT_OBJECT + Section: .fini_array + Value: 0x0000000000600E18 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x00000000004004A0 + - Name: __frame_dummy_init_array_entry + Type: STT_OBJECT + Section: .init_array + Value: 0x0000000000600E10 + - Name: main.cpp + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c [1]' + Type: STT_FILE + Index: SHN_ABS + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x0000000000400698 + - Name: __JCR_END__ + Type: STT_OBJECT + Section: .jcr + Value: 0x0000000000600E20 + - Type: STT_FILE + Index: SHN_ABS + - Name: __init_array_end + Section: .init_array + Value: 0x0000000000600E18 + - Name: _DYNAMIC + Type: STT_OBJECT + Section: .dynamic + Value: 0x0000000000600E28 + - Name: __init_array_start + Section: .init_array + Value: 0x0000000000600E10 + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x0000000000400570 + - Name: _GLOBAL_OFFSET_TABLE_ + Type: STT_OBJECT + Section: .got.plt + Value: 0x0000000000601000 + - Name: __libc_csu_fini + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x0000000000400550 + Size: 0x0000000000000002 + - Name: data_start + Section: .data + Binding: STB_WEAK + Value: 0x0000000000601020 + - Name: _edata + Section: .data + Binding: STB_GLOBAL + Value: 0x0000000000601024 + - Name: _fini + Type: STT_FUNC + Section: .fini + Binding: STB_GLOBAL + Value: 0x0000000000400554 + - Name: '__libc_start_main@@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __data_start + Section: .data + Binding: STB_GLOBAL + Value: 0x0000000000601020 + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: __dso_handle + Type: STT_OBJECT + Section: .rodata + Binding: STB_GLOBAL + Value: 0x0000000000400568 + Other: [ STV_HIDDEN ] + - Name: _IO_stdin_used + Type: STT_OBJECT + Section: .rodata + Binding: STB_GLOBAL + Value: 0x0000000000400560 + Size: 0x0000000000000004 + - Name: __libc_csu_init + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x00000000004004E0 + Size: 0x0000000000000065 + - Name: _end + Section: .bss + Binding: STB_GLOBAL + Value: 0x0000000000601028 + - Name: _start + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x00000000004003E0 + - Name: __bss_start + Section: .bss + Binding: STB_GLOBAL + Value: 0x0000000000601024 + - Name: main + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x00000000004004CD + Size: 0x0000000000000012 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .data + Binding: STB_GLOBAL + Value: 0x0000000000601028 + Other: [ STV_HIDDEN ] + - Name: _init + Type: STT_FUNC + Section: .init + Binding: STB_GLOBAL + Value: 0x0000000000400390 +DynamicSymbols: + - Name: __libc_start_main + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK +... diff --git a/llvm/test/tools/llvm-gsymutil/fat-macho-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/fat-macho-dwarf.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-gsymutil/fat-macho-dwarf.yaml @@ -0,0 +1,995 @@ +## For mach-o files we might have a universal (fat) mach-o file which +## complicates the GSYM creation process as we need to be prepared to parse +## more than one architecture. If no architectures are specified or more than +## one architectures are specified on the command line, then all architectures +## will be parsed and each GSYM file will have the architecture name appended +## as an extension (.armv7 or .arm64). If a single architecture is specified, +## then the GSYM file will be created in the normal location. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-gsymutil --convert %t --arch armv7 -o %t.armv7.gsym 2>&1 | FileCheck %s --check-prefix=ARMV7 +# RUN: llvm-gsymutil --convert %t --arch arm64 -o %t.arm64.gsym 2>&1 | FileCheck %s --check-prefix=ARM64 +# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=FAT + +# ARMV7: Input file: {{.*\.yaml\.tmp}} +# ARMV7-NEXT: Output file (armv7): {{.*\.yaml\.tmp\.armv7\.gsym}} +# ARMV7-NEXT: Loaded 1 functions from DWARF. +# ARMV7-NEXT: Loaded 0 functions from symbol table. +# ARMV7-NEXT: Pruned 0 functions, ended with 1 total + +# ARM64: Input file: {{.*\.yaml\.tmp}} +# ARM64-NEXT: Output file (arm64): {{.*\.yaml\.tmp\.arm64\.gsym}} +# ARM64-NEXT: Loaded 1 functions from DWARF. +# ARM64-NEXT: Loaded 0 functions from symbol table. +# ARM64-NEXT: Pruned 0 functions, ended with 1 total + +# FAT: Input file: {{.*\.yaml\.tmp}} +# FAT-NEXT: Output file (armv7): {{.*\.yaml\.tmp\.gsym\.armv7}} +# FAT-NEXT: Loaded 1 functions from DWARF. +# FAT-NEXT: Loaded 0 functions from symbol table. +# FAT-NEXT: Pruned 0 functions, ended with 1 total +# FAT-NEXT: Output file (arm64): {{.*\.yaml\.tmp\.gsym\.arm64}} +# FAT-NEXT: Loaded 1 functions from DWARF. +# FAT-NEXT: Loaded 0 functions from symbol table. +# FAT-NEXT: Pruned 0 functions, ended with 1 total + +--- !fat-mach-o +FatHeader: + magic: 0xCAFEBABE + nfat_arch: 2 +FatArchs: + - cputype: 0x0000000C + cpusubtype: 0x00000009 + offset: 0x0000000000000040 + size: 8884 + align: 5 + - cputype: 0x0100000C + cpusubtype: 0x00000000 + offset: 0x0000000000002300 + size: 8908 + align: 5 +Slices: + - !mach-o + FileHeader: + magic: 0xFEEDFACE + cputype: 0x0000000C + cpusubtype: 0x00000009 + filetype: 0x0000000A + ncmds: 6 + sizeofcmds: 1088 + flags: 0x00000000 + LoadCommands: + - cmd: LC_UUID + cmdsize: 24 + uuid: 7B08A997-C561-3D42-B774-0C3CD02345C7 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4096 + nsyms: 2 + stroff: 4120 + strsize: 28 + - cmd: LC_SEGMENT + cmdsize: 56 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT + cmdsize: 124 + segname: __TEXT + vmaddr: 16384 + vmsize: 32768 + fileoff: 0 + filesize: 0 + maxprot: 5 + initprot: 5 + nsects: 1 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x000000000000BFF0 + size: 16 + offset: 0x00000000 + align: 1 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CEFAEDFE0C000000090000000A000000 + - cmd: LC_SEGMENT + cmdsize: 56 + segname: __LINKEDIT + vmaddr: 49152 + vmsize: 4096 + fileoff: 4096 + filesize: 52 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT + cmdsize: 804 + segname: __DWARF + vmaddr: 53248 + vmsize: 4096 + fileoff: 8192 + filesize: 692 + maxprot: 7 + initprot: 3 + nsects: 11 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x000000000000D000 + size: 59 + offset: 0x00002000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 37000000040020000000010101FB0E0D000101010100000001000001006D61696E2E6370700000000000000502F0BF00000105020A9F0206000101 + - sectname: __debug_pubnames + segname: __DWARF + addr: 0x000000000000D03B + size: 27 + offset: 0x0000203B + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 1700000002000000000077000000260000006D61696E0000000000 + - sectname: __debug_pubtypes + segname: __DWARF + addr: 0x000000000000D056 + size: 35 + offset: 0x00002056 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 1F0000000200000000007700000059000000696E74006F000000636861720000000000 + - sectname: __debug_aranges + segname: __DWARF + addr: 0x000000000000D079 + size: 32 + offset: 0x00002079 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 1C000000020000000000040000000000F0BF0000100000000000000000000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x000000000000D099 + size: 119 + offset: 0x00002099 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 73000000040000000000040101000000040031000000000000003A000000F0BF00001000000002F0BF00001000000001573F0000000101590000000103027D044400000001015900000003027D004900000001016000000000044E00000005040565000000056A000000066F0000000452000000060100 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x000000000000D110 + size: 87 + offset: 0x00002110 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 011101250E1305030E10171B0EB44219110112060000022E01110112064018030E3A0B3B0B49103F19E37F0C00000305000218030E3A0B3B0B49100000042400030E3E0B0B0B0000050F00491000000626004910000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x000000000000D167 + size: 87 + offset: 0x00002167 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 004170706C6520636C616E672076657273696F6E2031312E302E302028636C616E672D313130302E302E33332E313729006D61696E2E637070002F746D70006D61696E0061726763006172677600696E74006368617200 + - sectname: __apple_names + segname: __DWARF + addr: 0x000000000000D1BE + size: 60 + offset: 0x000021BE + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000010000000C000000000000000100000001000600000000006A7F9A7C2C0000003F000000010000002600000000000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x000000000000D1FA + size: 36 + offset: 0x000021FA + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + - sectname: __apple_types + segname: __DWARF + addr: 0x000000000000D21E + size: 114 + offset: 0x0000221E + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 48534148010000000200000002000000180000000000000004000000010006000300050005000B000600060000000000010000003080880B6320957C440000005B0000004E0000000100000059000000240000A4283A0C0000000052000000010000006F00000024000057D77B9300000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x000000000000D290 + size: 36 + offset: 0x00002290 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + LinkEditData: + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 16384 + - n_strx: 22 + n_type: 0x0F + n_sect: 1 + n_desc: 8 + n_value: 49136 + StringTable: + - '' + - '' + - __mh_execute_header + - _main + DWARF: + debug_str: + - '' + - 'Apple clang version 11.0.0 (clang-1100.0.33.17)' + - main.cpp + - '/tmp' + - main + - argc + - argv + - int + - char + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_GNU_pubnames + Form: DW_FORM_flag_present + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Attribute: DW_AT_APPLE_isa + Form: DW_FORM_flag + - Code: 0x00000003 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000004 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + - Code: 0x00000005 + Tag: DW_TAG_pointer_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000006 + Tag: DW_TAG_const_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + debug_aranges: + - Length: + TotalLength: 28 + Version: 2 + CuOffset: 0 + AddrSize: 4 + SegSize: 0 + Descriptors: + - Address: 0x000000000000BFF0 + Length: 16 + debug_pubnames: + Length: + TotalLength: 23 + Version: 2 + UnitOffset: 0 + UnitSize: 119 + Entries: + - DieOffset: 0x00000026 + Name: main + debug_pubtypes: + Length: + TotalLength: 31 + Version: 2 + UnitOffset: 0 + UnitSize: 119 + Entries: + - DieOffset: 0x00000059 + Name: int + - DieOffset: 0x0000006F + Name: char + debug_info: + - Length: + TotalLength: 115 + Version: 4 + AbbrOffset: 0 + AddrSize: 4 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000031 + - Value: 0x0000000000000000 + - Value: 0x000000000000003A + - Value: 0x0000000000000001 + - Value: 0x000000000000BFF0 + - Value: 0x0000000000000010 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000BFF0 + - Value: 0x0000000000000010 + - Value: 0x0000000000000001 + BlockData: [ 0x57 ] + - Value: 0x000000000000003F + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000059 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x7D, 0x04 ] + - Value: 0x0000000000000044 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000059 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x7D, 0x00 ] + - Value: 0x0000000000000049 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000060 + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x00000004 + Values: + - Value: 0x000000000000004E + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000005 + Values: + - Value: 0x0000000000000065 + - AbbrCode: 0x00000005 + Values: + - Value: 0x000000000000006A + - AbbrCode: 0x00000006 + Values: + - Value: 0x000000000000006F + - AbbrCode: 0x00000004 + Values: + - Value: 0x0000000000000052 + - Value: 0x0000000000000006 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000000 + Values: [] + debug_line: + - Length: + TotalLength: 55 + Version: 4 + PrologueLength: 32 + MinInstLength: 1 + MaxOpsPerInst: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: [] + Files: + - Name: main.cpp + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 5 + SubOpcode: DW_LNE_set_address + Data: 49136 + - Opcode: DW_LNS_copy + Data: 0 + - Opcode: DW_LNS_set_column + Data: 2 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: 0x9F + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 6 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x0100000C + cpusubtype: 0x00000000 + filetype: 0x0000000A + ncmds: 7 + sizeofcmds: 1400 + flags: 0x00000000 + reserved: 0x00000000 + LoadCommands: + - cmd: LC_UUID + cmdsize: 24 + uuid: E74896D8-32D6-3EB2-BB23-4AA9A0F54CB2 + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 2 + minos: 852480 + sdk: 852480 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4096 + nsyms: 2 + stroff: 4128 + strsize: 28 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 32768 + fileoff: 0 + filesize: 0 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100007F9C + size: 28 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE0C000001000000000A000000070000007805000000000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100007FB8 + size: 72 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE0C000001000000000A000000070000007805000000000000000000001B00000018000000E74896D832D63EB2BB234AA9A0F54CB232000000180000000200000000020D00 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4295000064 + vmsize: 4096 + fileoff: 4096 + filesize: 60 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 952 + segname: __DWARF + vmaddr: 4295004160 + vmsize: 4096 + fileoff: 8192 + filesize: 716 + maxprot: 7 + initprot: 3 + nsects: 11 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x0000000100009000 + size: 63 + offset: 0x00002000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 3B000000040020000000010101FB0E0D000101010100000001000001006D61696E2E63707000000000000009029C7F0000010000000105020AF3020C000101 + - sectname: __debug_pubnames + segname: __DWARF + addr: 0x000000010000903F + size: 27 + offset: 0x0000203F + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 170000000200000000007E0000002A0000006D61696E0000000000 + - sectname: __debug_pubtypes + segname: __DWARF + addr: 0x000000010000905A + size: 35 + offset: 0x0000205A + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 1F0000000200000000007E00000060000000696E740076000000636861720000000000 + - sectname: __debug_aranges + segname: __DWARF + addr: 0x000000010000907D + size: 48 + offset: 0x0000207D + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 2C0000000200000000000800000000009C7F0000010000001C0000000000000000000000000000000000000000000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00000001000090AD + size: 126 + offset: 0x000020AD + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 7A000000040000000000080101000000040031000000000000003A0000009C7F0000010000001C000000029C7F0000010000001C000000016F3F0000000101600000000302910844000000010160000000030291004900000001016700000000044E0000000504056C000000057100000006760000000452000000060100 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x000000010000912B + size: 84 + offset: 0x0000212B + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 011101250E1305030E10171B0EB44219110112060000022E01110112064018030E3A0B3B0B49103F1900000305000218030E3A0B3B0B49100000042400030E3E0B0B0B0000050F00491000000626004910000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x000000010000917F + size: 87 + offset: 0x0000217F + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 004170706C6520636C616E672076657273696F6E2031312E302E302028636C616E672D313130302E302E33332E313729006D61696E2E637070002F746D70006D61696E0061726763006172677600696E74006368617200 + - sectname: __apple_names + segname: __DWARF + addr: 0x00000001000091D6 + size: 60 + offset: 0x000021D6 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000010000000C000000000000000100000001000600000000006A7F9A7C2C0000003F000000010000002A00000000000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x0000000100009212 + size: 36 + offset: 0x00002212 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + - sectname: __apple_types + segname: __DWARF + addr: 0x0000000100009236 + size: 114 + offset: 0x00002236 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 48534148010000000200000002000000180000000000000004000000010006000300050005000B000600060000000000010000003080880B6320957C440000005B0000004E0000000100000060000000240000A4283A0C0000000052000000010000007600000024000057D77B9300000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x00000001000092A8 + size: 36 + offset: 0x000022A8 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + LinkEditData: + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294999964 + StringTable: + - '' + - '' + - __mh_execute_header + - _main + DWARF: + debug_str: + - '' + - 'Apple clang version 11.0.0 (clang-1100.0.33.17)' + - main.cpp + - '/tmp' + - main + - argc + - argv + - int + - char + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_GNU_pubnames + Form: DW_FORM_flag_present + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Code: 0x00000003 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000004 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + - Code: 0x00000005 + Tag: DW_TAG_pointer_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000006 + Tag: DW_TAG_const_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + debug_aranges: + - Length: + TotalLength: 44 + Version: 2 + CuOffset: 0 + AddrSize: 8 + SegSize: 0 + Descriptors: + - Address: 0x0000000100007F9C + Length: 28 + debug_pubnames: + Length: + TotalLength: 23 + Version: 2 + UnitOffset: 0 + UnitSize: 126 + Entries: + - DieOffset: 0x0000002A + Name: main + debug_pubtypes: + Length: + TotalLength: 31 + Version: 2 + UnitOffset: 0 + UnitSize: 126 + Entries: + - DieOffset: 0x00000060 + Name: int + - DieOffset: 0x00000076 + Name: char + debug_info: + - Length: + TotalLength: 122 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000031 + - Value: 0x0000000000000000 + - Value: 0x000000000000003A + - Value: 0x0000000000000001 + - Value: 0x0000000100007F9C + - Value: 0x000000000000001C + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000100007F9C + - Value: 0x000000000000001C + - Value: 0x0000000000000001 + BlockData: [ 0x6F ] + - Value: 0x000000000000003F + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000060 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x08 ] + - Value: 0x0000000000000044 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000060 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x00 ] + - Value: 0x0000000000000049 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000067 + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x00000004 + Values: + - Value: 0x000000000000004E + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000005 + Values: + - Value: 0x000000000000006C + - AbbrCode: 0x00000005 + Values: + - Value: 0x0000000000000071 + - AbbrCode: 0x00000006 + Values: + - Value: 0x0000000000000076 + - AbbrCode: 0x00000004 + Values: + - Value: 0x0000000000000052 + - Value: 0x0000000000000006 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000000 + Values: [] + debug_line: + - Length: + TotalLength: 59 + Version: 4 + PrologueLength: 32 + MinInstLength: 1 + MaxOpsPerInst: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: [] + Files: + - Name: main.cpp + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294999964 + - Opcode: DW_LNS_copy + Data: 0 + - Opcode: DW_LNS_set_column + Data: 2 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: 0xF3 + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 12 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 +... diff --git a/llvm/test/tools/llvm-gsymutil/mach-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/mach-dwarf.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-gsymutil/mach-dwarf.yaml @@ -0,0 +1,784 @@ +## Test loading a skinny mach-o file with DWARF. First we make the mach-o file, +## from yaml, then we convert the object file to a GSYM file, then we do +## lookups on the newly created GSYM, and finally we dump the entire GSYM. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=CONVERT +# RUN: llvm-gsymutil --address=0 --address=0x100000000 --address=0x100000f90 --address=0x100000faa --address=0x200000000 %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDR +# RUN: llvm-gsymutil --verbose --address=0x100000000 --address=0x100000f90 --address=0x100000faa %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDRV +# RUN: llvm-gsymutil %t.gsym 2>&1 | FileCheck %s --check-prefix=DUMP + +# CONVERT: Input file: {{.*\.yaml\.tmp}} +# CONVERT: Output file (x86_64): {{.*\.yaml\.tmp\.gsym}} +# CONVERT: Loaded 2 functions from DWARF. +# CONVERT: Loaded 0 functions from symbol table. +# CONVERT: Pruned 0 functions, ended with 2 total + +# ADDR: Looking up addresses in "{{.*\.yaml\.tmp\.gsym}}": +# ADDR-NEXT: 0x0000000000000000: error: address 0x0 is not in GSYM +# ADDR-NEXT: 0x0000000100000000: error: address 0x100000000 is not in GSYM +# ADDR-NEXT: 0x0000000100000f90: main @ /tmp/main.cpp:4 +# ADDR-NEXT: 0x0000000100000faa: _Z3fooi @ /tmp/main.cpp:2 [inlined] +# ADDR-NEXT: main + 26 @ /tmp/main.cpp:5 +# ADDR-NEXT: 0x0000000200000000: error: address 0x200000000 is not in GSYM + +# ADDRV: error: address 0x100000000 is not in GSYM +# ADDRV: FunctionInfo for 0x0000000100000f90: +# ADDRV-NEXT: [0x0000000100000f90 - 0x0000000100000fb5) "main" +# ADDRV-NEXT: LineTable: +# ADDRV-NEXT: 0x0000000100000f90 /tmp/main.cpp:4 +# ADDRV-NEXT: 0x0000000100000fa4 /tmp/main.cpp:5 +# ADDRV-NEXT: 0x0000000100000faa /tmp/main.cpp:2 +# ADDRV-NEXT: 0x0000000100000fb0 /tmp/main.cpp:5 +# ADDRV-NEXT: 0x0000000100000fb3 /tmp/main.cpp:6 +# ADDRV-NEXT: InlineInfo: +# ADDRV-NEXT: [0x0000000100000f90 - 0x0000000100000fb5) main +# ADDRV-NEXT: [0x0000000100000faa - 0x0000000100000fb0) _Z3fooi called from /tmp/main.cpp:5 + +# ADDRV: LookupResult for 0x0000000100000f90: +# ADDRV-NEXT: 0x0000000100000f90: main @ /tmp/main.cpp:4 + +# ADDRV: FunctionInfo for 0x0000000100000faa: +# ADDRV-NEXT: [0x0000000100000f90 - 0x0000000100000fb5) "main" +# ADDRV-NEXT: LineTable: +# ADDRV-NEXT: 0x0000000100000f90 /tmp/main.cpp:4 +# ADDRV-NEXT: 0x0000000100000fa4 /tmp/main.cpp:5 +# ADDRV-NEXT: 0x0000000100000faa /tmp/main.cpp:2 +# ADDRV-NEXT: 0x0000000100000fb0 /tmp/main.cpp:5 +# ADDRV-NEXT: 0x0000000100000fb3 /tmp/main.cpp:6 +# ADDRV-NEXT: InlineInfo: +# ADDRV-NEXT: [0x0000000100000f90 - 0x0000000100000fb5) main +# ADDRV-NEXT: [0x0000000100000faa - 0x0000000100000fb0) _Z3fooi called from /tmp/main.cpp:5 + +# ADDRV: LookupResult for 0x0000000100000faa: +# ADDRV-NEXT: 0x0000000100000faa: _Z3fooi @ /tmp/main.cpp:2 [inlined] +# ADDRV-NEXT: main + 26 @ /tmp/main.cpp:5 + +# DUMP: Header: +# DUMP-NEXT: Magic = 0x4753594d +# DUMP-NEXT: Version = 0x0001 +# DUMP-NEXT: AddrOffSize = 0x02 +# DUMP-NEXT: UUIDSize = 0x10 +# DUMP-NEXT: BaseAddress = 0x0000000100000000 +# DUMP-NEXT: NumAddresses = 0x00000002 +# DUMP-NEXT: StrtabOffset = 0x00000050 +# DUMP-NEXT: StrtabSize = 0x0000001c +# DUMP-NEXT: UUID = f6241b5209ed3bbea6bc8a7f5a4817cd + +# DUMP: Address Table: +# DUMP-NEXT: INDEX OFFSET16 (ADDRESS) +# DUMP-NEXT: ====== =============================== +# DUMP-NEXT: [ 0] 0x0f70 (0x0000000100000f70) +# DUMP-NEXT: [ 1] 0x0f90 (0x0000000100000f90) + +# DUMP: Address Info Offsets: +# DUMP-NEXT: INDEX Offset +# DUMP-NEXT: ====== ========== +# DUMP-NEXT: [ 0] 0x0000006c +# DUMP-NEXT: [ 1] 0x0000008c + +# DUMP: Files: +# DUMP-NEXT: INDEX DIRECTORY BASENAME PATH +# DUMP-NEXT: ====== ========== ========== ============================== +# DUMP-NEXT: [ 0] 0x00000000 0x00000000 +# DUMP-NEXT: [ 1] 0x00000009 0x0000000e /tmp/main.cpp + +# DUMP: String table: +# DUMP-NEXT: 0x00000000: "" +# DUMP-NEXT: 0x00000001: "_Z3fooi" +# DUMP-NEXT: 0x00000009: "/tmp" +# DUMP-NEXT: 0x0000000e: "main.cpp" +# DUMP-NEXT: 0x00000017: "main" + +# DUMP: FunctionInfo @ 0x0000006c: [0x0000000100000f70 - 0x0000000100000f81) "_Z3fooi" +# DUMP-NEXT: LineTable: +# DUMP-NEXT: 0x0000000100000f70 /tmp/main.cpp:1 +# DUMP-NEXT: 0x0000000100000f77 /tmp/main.cpp:2 +# DUMP-NEXT: FunctionInfo @ 0x0000008c: [0x0000000100000f90 - 0x0000000100000fb5) "main" +# DUMP-NEXT: LineTable: +# DUMP-NEXT: 0x0000000100000f90 /tmp/main.cpp:4 +# DUMP-NEXT: 0x0000000100000fa4 /tmp/main.cpp:5 +# DUMP-NEXT: 0x0000000100000faa /tmp/main.cpp:2 +# DUMP-NEXT: 0x0000000100000fb0 /tmp/main.cpp:5 +# DUMP-NEXT: 0x0000000100000fb3 /tmp/main.cpp:6 +# DUMP-NEXT: InlineInfo: +# DUMP-NEXT: [0x0000000100000f90 - 0x0000000100000fb5) main +# DUMP-NEXT: [0x0000000100000faa - 0x0000000100000fb0) _Z3fooi called from /tmp/main.cpp:5 + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 7 + sizeofcmds: 1400 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_UUID + cmdsize: 24 + uuid: F6241B52-09ED-3BBE-A6BC-8A7F5A4817CD + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 1 + minos: 658944 + sdk: 658944 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4096 + nsyms: 3 + stroff: 4144 + strsize: 37 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 0 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F70 + size: 69 + offset: 0x00000000 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000F6241B5209ED3BBEA6BC8A7F5A4817CD32000000180000000100000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000FB8 + size: 72 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000F6241B5209ED3BBEA6BC8A7F5A4817CD320000001800000001000000000E0A00 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 4096 + filesize: 85 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 952 + segname: __DWARF + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 1055 + maxprot: 7 + initprot: 3 + nsects: 11 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x0000000100002000 + size: 106 + offset: 0x00002000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 66000000040020000000010101FB0E0D000101010100000001000001006D61696E2E6370700000000000000902700F00000100000001050C0A75050B063C05033C0204000101000902900F00000100000015050E0A083D050C63050B063C0506063F05023D0202000101 + - sectname: __debug_pubnames + segname: __DWARF + addr: 0x000000010000206A + size: 47 + offset: 0x0000206A + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 2B000000020000000000E00000002A0000005F5A33666F6F69002A000000666F6F00690000006D61696E0000000000 + - sectname: __debug_pubtypes + segname: __DWARF + addr: 0x0000000100002099 + size: 35 + offset: 0x00002099 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 1F000000020000000000E000000062000000696E7400D8000000636861720000000000 + - sectname: __debug_aranges + segname: __DWARF + addr: 0x00000001000020BC + size: 64 + offset: 0x000020BC + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 3C000000020000000000080000000000700F0000010000001100000000000000900F000001000000250000000000000000000000000000000000000000000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00000001000020FC + size: 224 + offset: 0x000020FC + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: DC000000040000000000080101000000040031000000000000003A000000700F0000010000004500000002700F000001000000110000000156460000000302917C5600000000043F0000004700000001016200000001054B00000001016200000000064D000000050407900F000001000000250000000156510000000104620000000802917456000000010462000000080291685B0000000104C9000000090291644B0000000105620000000A46000000AA0F0000010000000600000001050302917C5600000000000BCE0000000BD30000000CD80000000660000000060100 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x00000001000021DC + size: 168 + offset: 0x000021DC + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 011101250E1305030E10171B0EB44219110112060000022E0111011206401831100000030500021831100000042E016E0E030E3A0B3B0B49103F19200B0000050500030E3A0B3B0B49100000062400030E3E0B0B0B0000072E01110112064018030E3A0B3B0B49103F1900000805000218030E3A0B3B0B491000000934000218030E3A0B3B0B491000000A1D01311011011206580B590B00000B0F00491000000C26004910000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x0000000100002284 + size: 101 + offset: 0x00002284 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 004170706C6520636C616E672076657273696F6E2031312E302E302028636C616E672D313130302E302E33332E313729006D61696E2E637070002F746D70005F5A33666F6F6900666F6F006900696E74006D61696E00617267630061726776006368617200 + - sectname: __apple_names + segname: __DWARF + addr: 0x00000001000022E9 + size: 124 + offset: 0x000022E9 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000003000000030000000C0000000000000001000000010006000000000002000000FFFFFFFF8973880BDE28616A6A7F9A7C44000000580000006C00000047000000020000002A000000AC000000000000003F000000020000002A000000AC0000000000000051000000010000006900000000000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x0000000100002365 + size: 36 + offset: 0x00002365 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + - sectname: __apple_types + segname: __DWARF + addr: 0x0000000100002389 + size: 114 + offset: 0x00002389 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 48534148010000000200000002000000180000000000000004000000010006000300050005000B000600060000000000010000003080880B6320957C440000005B0000004D0000000100000062000000240000A4283A0C000000006000000001000000D800000024000057D77B9300000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x00000001000023FB + size: 36 + offset: 0x000023FB + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF +LinkEditData: + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971248 + - n_strx: 11 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 31 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971280 + StringTable: + - '' + - '' + - __Z3fooi + - __mh_execute_header + - _main +DWARF: + debug_str: + - '' + - 'Apple clang version 11.0.0 (clang-1100.0.33.17)' + - main.cpp + - '/tmp' + - _Z3fooi + - foo + - i + - int + - main + - argc + - argv + - char + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_GNU_pubnames + Form: DW_FORM_flag_present + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_abstract_origin + Form: DW_FORM_ref_addr + - Code: 0x00000003 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_abstract_origin + Form: DW_FORM_ref_addr + - Code: 0x00000004 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_linkage_name + Form: DW_FORM_strp + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Attribute: DW_AT_inline + Form: DW_FORM_data1 + - Code: 0x00000005 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000006 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + - Code: 0x00000007 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Code: 0x00000008 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x00000009 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x0000000A + Tag: DW_TAG_inlined_subroutine + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_abstract_origin + Form: DW_FORM_ref_addr + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_call_file + Form: DW_FORM_data1 + - Attribute: DW_AT_call_line + Form: DW_FORM_data1 + - Code: 0x0000000B + Tag: DW_TAG_pointer_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x0000000C + Tag: DW_TAG_const_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + debug_aranges: + - Length: + TotalLength: 60 + Version: 2 + CuOffset: 0 + AddrSize: 8 + SegSize: 0 + Descriptors: + - Address: 0x0000000100000F70 + Length: 17 + - Address: 0x0000000100000F90 + Length: 37 + debug_pubnames: + Length: + TotalLength: 43 + Version: 2 + UnitOffset: 0 + UnitSize: 224 + Entries: + - DieOffset: 0x0000002A + Name: _Z3fooi + - DieOffset: 0x0000002A + Name: foo + - DieOffset: 0x00000069 + Name: main + debug_pubtypes: + Length: + TotalLength: 31 + Version: 2 + UnitOffset: 0 + UnitSize: 224 + Entries: + - DieOffset: 0x00000062 + Name: int + - DieOffset: 0x000000D8 + Name: char + debug_info: + - Length: + TotalLength: 220 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000031 + - Value: 0x0000000000000000 + - Value: 0x000000000000003A + - Value: 0x0000000000000001 + - Value: 0x0000000100000F70 + - Value: 0x0000000000000045 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000100000F70 + - Value: 0x0000000000000011 + - Value: 0x0000000000000001 + BlockData: [ 0x56 ] + - Value: 0x0000000000000046 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x7C ] + - Value: 0x0000000000000056 + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x00000004 + Values: + - Value: 0x000000000000003F + - Value: 0x0000000000000047 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000062 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000005 + Values: + - Value: 0x000000000000004B + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000062 + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x00000006 + Values: + - Value: 0x000000000000004D + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000007 + Values: + - Value: 0x0000000100000F90 + - Value: 0x0000000000000025 + - Value: 0x0000000000000001 + BlockData: [ 0x56 ] + - Value: 0x0000000000000051 + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000062 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000008 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x74 ] + - Value: 0x0000000000000056 + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000062 + - AbbrCode: 0x00000008 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x68 ] + - Value: 0x000000000000005B + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x00000000000000C9 + - AbbrCode: 0x00000009 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x64 ] + - Value: 0x000000000000004B + - Value: 0x0000000000000001 + - Value: 0x0000000000000005 + - Value: 0x0000000000000062 + - AbbrCode: 0x0000000A + Values: + - Value: 0x0000000000000046 + - Value: 0x0000000100000FAA + - Value: 0x0000000000000006 + - Value: 0x0000000000000001 + - Value: 0x0000000000000005 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x7C ] + - Value: 0x0000000000000056 + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x00000000 + Values: [] + - AbbrCode: 0x0000000B + Values: + - Value: 0x00000000000000CE + - AbbrCode: 0x0000000B + Values: + - Value: 0x00000000000000D3 + - AbbrCode: 0x0000000C + Values: + - Value: 0x00000000000000D8 + - AbbrCode: 0x00000006 + Values: + - Value: 0x0000000000000060 + - Value: 0x0000000000000006 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000000 + Values: [] + debug_line: + - Length: + TotalLength: 102 + Version: 4 + PrologueLength: 32 + MinInstLength: 1 + MaxOpsPerInst: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: [] + Files: + - Name: main.cpp + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294971248 + - Opcode: DW_LNS_copy + Data: 0 + - Opcode: DW_LNS_set_column + Data: 12 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: 0x75 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 11 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: 0x3C + Data: 0 + - Opcode: DW_LNS_set_column + Data: 3 + - Opcode: 0x3C + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 4 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294971280 + - Opcode: 0x15 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 14 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: DW_LNS_const_add_pc + Data: 0 + - Opcode: 0x3D + Data: 0 + - Opcode: DW_LNS_set_column + Data: 12 + - Opcode: 0x63 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 11 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: 0x3C + Data: 0 + - Opcode: DW_LNS_set_column + Data: 6 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: 0x3F + Data: 0 + - Opcode: DW_LNS_set_column + Data: 2 + - Opcode: 0x3D + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 2 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 +... diff --git a/llvm/tools/llvm-gsym/CMakeLists.txt b/llvm/tools/llvm-gsym/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/llvm/tools/llvm-gsym/CMakeLists.txt @@ -0,0 +1,19 @@ +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + DebugInfoDWARF + DebugInfoGSYM + AsmPrinter + AllTargetsDescs + AllTargetsInfos + MC + Object + Support + Target + ) + +add_llvm_tool(llvm-gsymutil + llvm-gsymutil.cpp + + DEPENDS + intrinsics_gen + ) diff --git a/llvm/tools/llvm-gsym/llvm-gsymutil.cpp b/llvm/tools/llvm-gsym/llvm-gsymutil.cpp new file mode 100644 --- /dev/null +++ b/llvm/tools/llvm-gsym/llvm-gsymutil.cpp @@ -0,0 +1,503 @@ +//===-- llvm-gsymutil.cpp - GSYM dumping and creation utility for llvm ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Triple.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/Object/Archive.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include +#include +#include +#include + +#include "llvm/DebugInfo/GSYM/DwarfTransformer.h" +#include "llvm/DebugInfo/GSYM/FunctionInfo.h" +#include "llvm/DebugInfo/GSYM/GsymCreator.h" +#include "llvm/DebugInfo/GSYM/GsymReader.h" +#include "llvm/DebugInfo/GSYM/InlineInfo.h" +#include "llvm/DebugInfo/GSYM/LookupResult.h" +#include "llvm/DebugInfo/GSYM/ObjectFileTransformer.h" + +using namespace llvm; +using namespace gsym; +using namespace object; + +/// @} +/// Command line options. +/// @{ + +namespace { +using namespace cl; + +OptionCategory GeneralOptions("Options"); +OptionCategory ConversionOptions("Conversion Options"); +OptionCategory LookupOptions("Lookup Options"); + +static opt Help("h", desc("Alias for -help"), Hidden, + cat(GeneralOptions)); + +static opt Verbose("verbose", + desc("Enable verbose logging and encoding details."), + cat(GeneralOptions)); + +static list InputFilenames(Positional, desc(""), + ZeroOrMore, cat(GeneralOptions)); + +static opt + ConvertFilename("convert", cl::init(""), + cl::desc("Convert the specified file to the GSYM format.\n" + "Supported files include ELF and mach-o files " + "that will have their debug info (DWARF) and " + "symbol table converted."), + cl::value_desc("path"), cat(ConversionOptions)); + +static list + ArchFilters("arch", + desc("Process debug information for the specified CPU " + "architecture only.\nArchitectures may be specified by " + "name or by number.\nThis option can be specified " + "multiple times, once for each desired architecture."), + cl::value_desc("arch"), cat(ConversionOptions)); + +static opt + OutputFilename("out-file", cl::init(""), + cl::desc("Specify the path where the converted GSYM file " + "will be saved.\nWhen not specified, a '.gsym' " + "extension will be appended to the file name " + "specified in the --convert option."), + cl::value_desc("path"), cat(ConversionOptions)); +static alias OutputFilenameAlias("o", desc("Alias for -out-file."), + aliasopt(OutputFilename), + cat(ConversionOptions)); + +static opt Verify("verify", + desc("Verify the generated GSYM file against the " + "information in the file that was converted."), + cat(ConversionOptions)); + +static opt + NumThreads("num-threads", + desc("Specify the maximum number (n) of simultaneous threads " + "to use when converting files to GSYM.\nDefaults to the " + "number of cores on the current machine."), + cl::value_desc("n"), cat(ConversionOptions)); + +static list LookupAddresses("address", + desc("Lookup an address in a GSYM file"), + cl::value_desc("addr"), + cat(LookupOptions)); + + + +} // namespace +/// @} +//===----------------------------------------------------------------------===// + +static void error(StringRef Prefix, llvm::Error Err) { + if (!Err) + return; + errs() << Prefix << ": " << Err << "\n"; + consumeError(std::move(Err)); + exit(1); +} + +static void error(StringRef Prefix, std::error_code EC) { + if (!EC) + return; + errs() << Prefix << ": " << EC.message() << "\n"; + exit(1); +} + + +/// If the input path is a .dSYM bundle (as created by the dsymutil tool), +/// replace it with individual entries for each of the object files inside the +/// bundle otherwise return the input path. +static std::vector expandBundle(const std::string &InputPath) { + std::vector BundlePaths; + SmallString<256> BundlePath(InputPath); + // Manually open up the bundle to avoid introducing additional dependencies. + if (sys::fs::is_directory(BundlePath) && + sys::path::extension(BundlePath) == ".dSYM") { + std::error_code EC; + sys::path::append(BundlePath, "Contents", "Resources", "DWARF"); + for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + const std::string &Path = Dir->path(); + sys::fs::file_status Status; + EC = sys::fs::status(Path, Status); + error(Path, EC); + switch (Status.type()) { + case sys::fs::file_type::regular_file: + case sys::fs::file_type::symlink_file: + case sys::fs::file_type::type_unknown: + BundlePaths.push_back(Path); + break; + default: /*ignore*/; + } + } + error(BundlePath, EC); + } + if (!BundlePaths.size()) + BundlePaths.push_back(InputPath); + return BundlePaths; +} + +static uint32_t getCPUType(MachOObjectFile &MachO) { + if (MachO.is64Bit()) + return MachO.getHeader64().cputype; + else + return MachO.getHeader().cputype; +} + +/// Return true if the object file has not been filtered by an --arch option. +static bool filterArch(MachOObjectFile &Obj) { + if (ArchFilters.empty()) + return true; + + StringRef ObjArch = Obj.getArchTriple().getArchName(); + + for (auto Arch : ArchFilters) { + // Match name. + if (Arch == ObjArch) + return true; + + // Match architecture number. + unsigned Value; + if (!StringRef(Arch).getAsInteger(0, Value)) + if (Value == getCPUType(Obj)) + return true; + } + return false; +} + +/// Determine the virtual address that is considered the base address of an ELF +/// object file. +/// +/// The base address of an ELF file is the the "p_vaddr" of the first program +/// header whose "p_type" is PT_LOAD. +/// +/// \param ELFFile An ELF object file we will search. +/// +/// \returns A valid image base address if we are able to extract one. +template +static llvm::Optional +getImageBaseAddress(const object::ELFFile *ELFFile) { + auto PhdrRangeOrErr = ELFFile->program_headers(); + if (!PhdrRangeOrErr) { + consumeError(PhdrRangeOrErr.takeError()); + return llvm::None; + } + for (const typename ELFT::Phdr &Phdr : *PhdrRangeOrErr) + if (Phdr.p_type == ELF::PT_LOAD) + return (uint64_t)Phdr.p_vaddr; + return llvm::None; +} + +/// Determine the virtual address that is considered the base address of mach-o +/// object file. +/// +/// The base address of a mach-o file is the vmaddr of the "__TEXT" segment. +/// +/// \param MachO A mach-o object file we will search. +/// +/// \returns A valid image base address if we are able to extract one. +static llvm::Optional +getImageBaseAddress(const object::MachOObjectFile *MachO) { + for (const auto &Command : MachO->load_commands()) { + if (Command.C.cmd == MachO::LC_SEGMENT) { + MachO::segment_command SLC = MachO->getSegmentLoadCommand(Command); + StringRef SegName = SLC.segname; + if (SegName == "__TEXT") + return SLC.vmaddr; + } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { + MachO::segment_command_64 SLC = MachO->getSegment64LoadCommand(Command); + StringRef SegName = SLC.segname; + if (SegName == "__TEXT") + return SLC.vmaddr; + } + } + return llvm::None; +} + +/// Determine the virtual address that is considered the base address of an +/// object file. +/// +/// Since GSYM files are used for symbolication, many clients will need to +/// easily adjust addresses they find in stack traces so the lookups happen +/// on unslid addresses from the original object file. If the base address of +/// a GSYM file is set to the base address of the image, then this address +/// adjusting is much easier. +/// +/// \param Obj An object file we will search. +/// +/// \returns A valid image base address if we are able to extract one. +static llvm::Optional getImageBaseAddress(object::ObjectFile &Obj) { + if (const auto *MachO = dyn_cast(&Obj)) + return getImageBaseAddress(MachO); + else if (const auto *ELFObj = dyn_cast(&Obj)) + return getImageBaseAddress(ELFObj->getELFFile()); + else if (const auto *ELFObj = dyn_cast(&Obj)) + return getImageBaseAddress(ELFObj->getELFFile()); + else if (const auto *ELFObj = dyn_cast(&Obj)) + return getImageBaseAddress(ELFObj->getELFFile()); + else if (const auto *ELFObj = dyn_cast(&Obj)) + return getImageBaseAddress(ELFObj->getELFFile()); + return llvm::None; +} + + +static llvm::Error handleObjectFile(ObjectFile &Obj, + const std::string &OutFile) { + auto ThreadCount = + NumThreads > 0 ? NumThreads : std::thread::hardware_concurrency(); + auto &OS = outs(); + + GsymCreator Gsym; + + // See if we can figure out the base address for a given object file, and if + // we can, then set the base address to use to this value. This will ease + // symbolication since clients can slide the GSYM lookup addresses by using + // the load bias of the shared library. + if (auto ImageBaseAddr = getImageBaseAddress(Obj)) + Gsym.setBaseAddress(*ImageBaseAddr); + + // We need to know where the valid sections are that contain instructions. + // See header documentation for DWARFTransformer::SetValidTextRanges() for + // defails. + AddressRanges TextRanges; + for (const object::SectionRef &Sect : Obj.sections()) { + if (!Sect.isText()) + continue; + const uint64_t Size = Sect.getSize(); + if (Size == 0) + continue; + const uint64_t StartAddr = Sect.getAddress(); + TextRanges.insert(AddressRange(StartAddr, StartAddr + Size)); + } + + // Make sure there is DWARF to convert first. + std::unique_ptr DICtx = DWARFContext::create(Obj); + if (!DICtx) + return createStringError(std::errc::invalid_argument, + "unable to create DWARF context"); + logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), OS, + "DwarfTransformer: "); + + // Make a DWARF transformer object and populate the ranges of the code + // so we don't end up adding invalid functions to GSYM data. + DwarfTransformer DT(*DICtx, OS, Gsym); + if (!TextRanges.empty()) + Gsym.SetValidTextRanges(TextRanges); + + // Convert all DWARF to GSYM. + if (auto Err = DT.convert(ThreadCount)) + return Err; + + // Get the UUID and convert symbol table to GSYM. + if (auto Err = ObjectFileTransformer::convert(Obj, OS, Gsym)) + return Err; + + // Finalize the GSYM to make it ready to save to disk. This will remove + // duplicate FunctionInfo entries where we might have found an entry from + // debug info and also a symbol table entry from the object file. + if (auto Err = Gsym.finalize(OS)) + return Err; + + // Save the GSYM file to disk. + support::endianness Endian = Obj.makeTriple().isLittleEndian() ? + support::little : support::big; + if (auto Err = Gsym.save(OutFile.c_str(), Endian)) + return Err; + + // Verify the DWARF if requested. This will ensure all the info in the DWARF + // can be looked up in the GSYM and that all lookups get matching data. + if (Verify) { + if (auto Err = DT.verify(OutFile)) + return Err; + } + + return Error::success(); +} + +static llvm::Error handleBuffer(StringRef Filename, MemoryBufferRef Buffer, + const std::string &OutFile) { + Expected> BinOrErr = object::createBinary(Buffer); + error(Filename, errorToErrorCode(BinOrErr.takeError())); + + if (auto *Obj = dyn_cast(BinOrErr->get())) { + auto ArchName = Obj->makeTriple().getArchName(); + outs() << "Output file (" << ArchName << "): " << OutFile << "\n"; + if (auto Err = handleObjectFile(*Obj, OutFile.c_str())) + return Err; + } else if (auto *Fat = dyn_cast(BinOrErr->get())) { + // Iterate over all contained architectures and filter out any that were + // not specified with the "--arch " option. If the --arch option was + // not specified on the command line, we will process all architectures. + std::vector< std::unique_ptr > FilterObjs; + for (auto &ObjForArch : Fat->objects()) { + if (auto MachOOrErr = ObjForArch.getAsObjectFile()) { + auto &Obj = **MachOOrErr; + if (filterArch(Obj)) + FilterObjs.emplace_back(MachOOrErr->release()); + } else { + error(Filename, MachOOrErr.takeError()); + } + } + if (FilterObjs.empty()) + error(Filename, createStringError(std::errc::invalid_argument, + "no matching architectures found")); + + // Now handle each architecture we need to convert. + for (auto &Obj: FilterObjs) { + auto ArchName = Obj->getArchTriple().getArchName(); + std::string ArchOutFile(OutFile); + // If we are only handling a single architecture, then we will use the + // normal output file. If we are handling multiple architectures append + // the architecture name to the end of the out file path so that we + // don't overwrite the previous architecture's gsym file. + if (FilterObjs.size() > 1) { + ArchOutFile.append(1, '.'); + ArchOutFile.append(ArchName.str()); + } + outs() << "Output file (" << ArchName << "): " << ArchOutFile << "\n"; + if (auto Err = handleObjectFile(*Obj, ArchOutFile)) + return Err; + } + } + return Error::success(); +} + +static llvm::Error handleFileConversionToGSYM(StringRef Filename, + const std::string &OutFile) { + ErrorOr> BuffOrErr = + MemoryBuffer::getFileOrSTDIN(Filename); + error(Filename, BuffOrErr.getError()); + std::unique_ptr Buffer = std::move(BuffOrErr.get()); + return handleBuffer(Filename, *Buffer, OutFile); +} + +static llvm::Error convertFileToGSYM(raw_ostream &OS) { + // Expand any .dSYM bundles to the individual object files contained therein. + std::vector Objects; + std::string OutFile = OutputFilename; + if (OutFile.empty()) { + OutFile = ConvertFilename; + OutFile += ".gsym"; + } + + OS << "Input file: " << ConvertFilename << "\n"; + + auto Objs = expandBundle(ConvertFilename); + Objects.insert(Objects.end(), Objs.begin(), Objs.end()); + + for (auto Object : Objects) { + if (auto Err = handleFileConversionToGSYM(Object, OutFile)) + return Err; + } + return Error::success(); +} + +int main(int argc, char const *argv[]) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + + const char *Overview = + "A tool for dumping, searching and creating GSYM files.\n\n" + "Specify one or more GSYM paths as arguments to dump all of the " + "information in each GSYM file.\n" + "Specify a single GSYM file along with one or more --lookup options to " + "lookup addresses within that GSYM file.\n" + "Use the --convert option to specify a file with option --out-file " + "option to convert to GSYM format.\n"; + HideUnrelatedOptions( + {&GeneralOptions, &ConversionOptions, &LookupOptions}); + cl::ParseCommandLineOptions(argc, argv, Overview); + + if (Help) { + PrintHelpMessage(/*Hidden =*/false, /*Categorized =*/true); + return 0; + } + + raw_ostream &OS = outs(); + + if (!ConvertFilename.empty()) { + // Convert DWARF to GSYM + if (!InputFilenames.empty()) { + OS << "error: no input files can be specified when using the --convert " + "option.\n"; + return 1; + } + // Call error() if we have an error and it will exit with a status of 1 + if (auto Err = convertFileToGSYM(OS)) + error("DWARF conversion failed: ", std::move(Err)); + return 0; + } + + // Dump or access data inside GSYM files + for (const auto &GSYMPath : InputFilenames) { + auto Gsym = GsymReader::openFile(GSYMPath); + if (!Gsym) + error(GSYMPath, Gsym.takeError()); + + if (LookupAddresses.empty()) { + Gsym->dump(outs()); + continue; + } + + // Lookup an address in a GSYM file and print any matches. + OS << "Looking up addresses in \"" << GSYMPath << "\":\n"; + for (auto Addr: LookupAddresses) { + if (auto Result = Gsym->lookup(Addr)) { + // If verbose is enabled dump the full function info for the address. + if (Verbose) { + if (auto FI = Gsym->getFunctionInfo(Addr)) { + OS << "FunctionInfo for " << HEX64(Addr) << ":\n"; + Gsym->dump(OS, *FI); + OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; + } + } + OS << Result.get(); + } else { + if (Verbose) + OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; + OS << HEX64(Addr) << ": "; + logAllUnhandledErrors(Result.takeError(), OS, "error: "); + } + if (Verbose) + OS << "\n"; + } + } + return EXIT_SUCCESS; +}