std::vector<llvm::gsym::FileEntry> Files;
std::vector<uint8_t> UUID;
Optional<AddressRanges> ValidTextRanges;
+ AddressRanges Ranges;
+ llvm::Optional<uint64_t> BaseAddress;
bool Finalized = false;
public:
/// 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;
/// 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
/// \returns The matching address offset index. This index will be used to
/// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
template <class T>
- uint64_t getAddressOffsetIndex(const uint64_t AddrOffset) const {
+ llvm::Optional<uint64_t> getAddressOffsetIndex(const uint64_t AddrOffset) const {
ArrayRef<T> AIO = getAddrOffsets<T>();
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);
--- /dev/null
+//===- 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
#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 <stdint.h>
bool empty() const { return Ranges.empty(); }
bool contains(uint64_t Addr) const;
bool contains(AddressRange Range) const;
+ Optional<AddressRange> getRangeThatContains(uint64_t Addr) const;
void insert(AddressRange Range);
size_t size() const { return Ranges.size(); }
bool operator==(const AddressRanges &RHS) const {
InlineInfo.cpp
LineTable.cpp
LookupResult.cpp
+ ObjectFileTransformer.cpp
Range.cpp
ADDITIONAL_HEADER_DIRS
// 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);
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;
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();
void GsymCreator::addFunctionInfo(FunctionInfo &&FI) {
std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ Ranges.insert(FI.Range);
Funcs.emplace_back(FI);
}
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<std::recursive_mutex> Guard(Mutex);
+ return Ranges.contains(Addr);
+}
Expected<uint64_t>
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<uint8_t>(AddrOffset);
- case 2: return getAddressOffsetIndex<uint16_t>(AddrOffset);
- case 4: return getAddressOffsetIndex<uint32_t>(AddrOffset);
- case 8: return getAddressOffsetIndex<uint64_t>(AddrOffset);
- default: break;
+ if (Addr >= Hdr->BaseAddress) {
+ const uint64_t AddrOffset = Addr - Hdr->BaseAddress;
+ Optional<uint64_t> AddrOffsetIndex;
+ switch (Hdr->AddrOffSize) {
+ case 1:
+ AddrOffsetIndex = getAddressOffsetIndex<uint8_t>(AddrOffset);
+ break;
+ case 2:
+ AddrOffsetIndex = getAddressOffsetIndex<uint16_t>(AddrOffset);
+ break;
+ case 4:
+ AddrOffsetIndex = getAddressOffsetIndex<uint32_t>(AddrOffset);
+ break;
+ case 8:
+ AddrOffsetIndex = getAddressOffsetIndex<uint64_t>(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<FunctionInfo> GsymReader::getFunctionInfo(uint64_t Addr) const {
}
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 << "<invalid-file>";
else
- OS << '/';
+ OS << SL.Base;
+ OS << ':' << SL.Line;
}
- if (SL.Base.empty())
- OS << "<invalid-file>";
- else
- OS << SL.Base;
- OS << ':' << SL.Line;
return OS;
}
--- /dev/null
+//===- 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 <unordered_set>
+
+#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<uint8_t> getUUID(const object::ObjectFile &Obj) {
+ // Extract the UUID from the object file
+ std::vector<uint8_t> UUID;
+ if (auto *MachO = dyn_cast<object::MachOObjectFile>(&Obj)) {
+ const ArrayRef<uint8_t> MachUUID = MachO->getUuid();
+ if (!MachUUID.empty())
+ UUID.assign(MachUUID.data(), MachUUID.data() + MachUUID.size());
+ } else if (isa<object::ELFObjectFileBase>(&Obj)) {
+ const StringRef GNUBuildID(".note.gnu.build-id");
+ for (const object::SectionRef &Sect : Obj.sections()) {
+ Expected<StringRef> SectNameOrErr = Sect.getName();
+ if (!SectNameOrErr) {
+ consumeError(SectNameOrErr.takeError());
+ continue;
+ }
+ StringRef SectName(*SectNameOrErr);
+ if (SectName != GNUBuildID)
+ continue;
+ StringRef BuildIDData;
+ Expected<StringRef> 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<const uint8_t *>(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<MachOObjectFile>(&Obj);
+ const bool IsELF = isa<ELFObjectFileBase>(&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<SymbolRef::Type> 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<StringRef> 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();
+}
return Range.End <= It[-1].End;
}
+Optional<AddressRange>
+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) << ")";
}
--- /dev/null
+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] <input GSYM files>
+HELP: OPTIONS:
+HELP: Conversion Options:
+HELP: --arch=<arch>
+HELP: --convert=<path>
+HELP: --num-threads=<n>
+HELP: --out-file=<path>
+HELP: --verify
+HELP: Generic Options:
+HELP: --help
+HELP: --version
+HELP: Lookup Options:
+HELP: --address=<addr>
+HELP: Options:
+HELP: --verbose
+
+RUN: llvm-gsymutil --version 2>&1 | FileCheck --check-prefix=VERSION %s
+VERSION: {{ version }}
--- /dev/null
+## 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
+...
--- /dev/null
+## 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
+...
--- /dev/null
+## 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
+...
--- /dev/null
+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
+ )
--- /dev/null
+//===-- 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 <algorithm>
+#include <cstring>
+#include <inttypes.h>
+#include <map>
+#include <string>
+#include <system_error>
+#include <vector>
+
+#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<bool> Help("h", desc("Alias for -help"), Hidden,
+ cat(GeneralOptions));
+
+static opt<bool> Verbose("verbose",
+ desc("Enable verbose logging and encoding details."),
+ cat(GeneralOptions));
+
+static list<std::string> InputFilenames(Positional, desc("<input GSYM files>"),
+ ZeroOrMore, cat(GeneralOptions));
+
+static opt<std::string>
+ 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<std::string>
+ 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<std::string>
+ 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<bool> Verify("verify",
+ desc("Verify the generated GSYM file against the "
+ "information in the file that was converted."),
+ cat(ConversionOptions));
+
+static opt<unsigned>
+ 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<uint64_t> 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<std::string> expandBundle(const std::string &InputPath) {
+ std::vector<std::string> 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 <class ELFT>
+static llvm::Optional<uint64_t>
+getImageBaseAddress(const object::ELFFile<ELFT> *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<uint64_t>
+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<uint64_t> getImageBaseAddress(object::ObjectFile &Obj) {
+ if (const auto *MachO = dyn_cast<object::MachOObjectFile>(&Obj))
+ return getImageBaseAddress(MachO);
+ else if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
+ return getImageBaseAddress(ELFObj->getELFFile());
+ else if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
+ return getImageBaseAddress(ELFObj->getELFFile());
+ else if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
+ return getImageBaseAddress(ELFObj->getELFFile());
+ else if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&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<DWARFContext> 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<std::unique_ptr<Binary>> BinOrErr = object::createBinary(Buffer);
+ error(Filename, errorToErrorCode(BinOrErr.takeError()));
+
+ if (auto *Obj = dyn_cast<ObjectFile>(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<MachOUniversalBinary>(BinOrErr->get())) {
+ // Iterate over all contained architectures and filter out any that were
+ // not specified with the "--arch <arch>" option. If the --arch option was
+ // not specified on the command line, we will process all architectures.
+ std::vector< std::unique_ptr<MachOObjectFile> > 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<std::unique_ptr<MemoryBuffer>> BuffOrErr =
+ MemoryBuffer::getFileOrSTDIN(Filename);
+ error(Filename, BuffOrErr.getError());
+ std::unique_ptr<MemoryBuffer> 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<std::string> 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;
+}