forked from OSchip/llvm-project
[llvm-dsymutil] Add support for __swift_ast MachO DWARF section
Summary: Xcode's dsymutil emits a __swift_ast DWARF section, which is required for debugging, and which contains a byte-for-byte dump of the swiftmodule file. Add this feature to llvm-dsymutil. Tested with `gobjdump --dwarf=info -s`, by verifying that the contents of `__DWARF.__swift_ast` match between Xcode's dsymutil and llvm-dsymutil (Xcode's dwarfdump and llvm-dwarfdump don't currently recognize the __swift_ast section). Reviewers: aprantl, friss Subscribers: llvm-commits, JDevlieghere Differential Revision: https://reviews.llvm.org/D38504 llvm-svn: 315066
This commit is contained in:
parent
3333494132
commit
8aedfde298
|
@ -123,6 +123,9 @@ protected:
|
|||
/// Section for newer gnu pubtypes.
|
||||
MCSection *DwarfGnuPubTypesSection;
|
||||
|
||||
// Section for Swift AST
|
||||
MCSection *DwarfSwiftASTSection;
|
||||
|
||||
MCSection *COFFDebugSymbolsSection;
|
||||
MCSection *COFFDebugTypesSection;
|
||||
|
||||
|
@ -267,6 +270,7 @@ public:
|
|||
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
|
||||
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
|
||||
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
|
||||
MCSection *getDwarfSwiftASTSection() const { return DwarfSwiftASTSection; }
|
||||
|
||||
MCSection *getCOFFDebugSymbolsSection() const {
|
||||
return COFFDebugSymbolsSection;
|
||||
|
|
|
@ -214,6 +214,10 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
|
|||
Ctx->getMachOSection("__DWARF", "__apple_types", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata(), "types_begin");
|
||||
|
||||
DwarfSwiftASTSection =
|
||||
Ctx->getMachOSection("__DWARF", "__swift_ast", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata());
|
||||
|
||||
DwarfAbbrevSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_abbrev", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata(), "section_abbrev");
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
SWIFTMODULE DATA
|
|
@ -0,0 +1,14 @@
|
|||
RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/swift-ast.dSYM -verbose | FileCheck %s --check-prefix=DSYMUTIL
|
||||
RUN: llvm-readobj -sections -section-data %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=READOBJ
|
||||
|
||||
The tested object file has been created by the dummy Swift code:
|
||||
let x = 1
|
||||
|
||||
Compiled with: swiftc /tmp/test.swift -Onone -target x86_64-apple-macosx10.9 -c
|
||||
Linked with: ld swift-ast.o -add_ast_path Inputs/swift-ast.swiftmodule -arch x86_64 -lSystem -macosx_version_min 10.9.0
|
||||
|
||||
DSYMUTIL: filename:{{.*}}swift-ast.swiftmodule
|
||||
DSYMUTIL: DEBUG MAP OBJECT:{{.*}}swift-ast.swiftmodule
|
||||
|
||||
READOBJ: Name:{{.*}}__swift_ast
|
||||
READOBJ: |SWIFTMODULE DATA|
|
|
@ -66,6 +66,12 @@ class BinaryHolder {
|
|||
MapArchiveAndGetMemberBuffers(StringRef Filename,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp);
|
||||
|
||||
void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf);
|
||||
ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T);
|
||||
|
||||
public:
|
||||
BinaryHolder(bool Verbose) : Verbose(Verbose) {}
|
||||
|
||||
/// Return the MemoryBufferRef that holds the memory mapping for the
|
||||
/// given \p Filename. This function will try to parse archive
|
||||
/// member specifications of the form /path/to/archive.a(member.o).
|
||||
|
@ -79,12 +85,6 @@ class BinaryHolder {
|
|||
GetMemoryBuffersForFile(StringRef Filename,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp);
|
||||
|
||||
void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf);
|
||||
ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T);
|
||||
|
||||
public:
|
||||
BinaryHolder(bool Verbose) : Verbose(Verbose) {}
|
||||
|
||||
/// Get the ObjectFiles designated by the \p Filename. This
|
||||
/// might be an archive member specification of the form
|
||||
/// /path/to/archive.a(member.o).
|
||||
|
|
|
@ -21,8 +21,9 @@ namespace dsymutil {
|
|||
using namespace llvm::object;
|
||||
|
||||
DebugMapObject::DebugMapObject(StringRef ObjectFilename,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp)
|
||||
: Filename(ObjectFilename), Timestamp(Timestamp) {}
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp,
|
||||
uint8_t Type)
|
||||
: Filename(ObjectFilename), Timestamp(Timestamp), Type(Type) {}
|
||||
|
||||
bool DebugMapObject::addSymbol(StringRef Name, Optional<uint64_t> ObjectAddress,
|
||||
uint64_t LinkedAddress, uint32_t Size) {
|
||||
|
@ -64,8 +65,9 @@ void DebugMapObject::dump() const { print(errs()); }
|
|||
|
||||
DebugMapObject &
|
||||
DebugMap::addDebugMapObject(StringRef ObjectFilePath,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp) {
|
||||
Objects.emplace_back(new DebugMapObject(ObjectFilePath, Timestamp));
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp,
|
||||
uint8_t Type) {
|
||||
Objects.emplace_back(new DebugMapObject(ObjectFilePath, Timestamp, Type));
|
||||
return *Objects.back();
|
||||
}
|
||||
|
||||
|
@ -241,7 +243,7 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
|
|||
}
|
||||
}
|
||||
|
||||
dsymutil::DebugMapObject Res(Path, sys::toTimePoint(Timestamp));
|
||||
dsymutil::DebugMapObject Res(Path, sys::toTimePoint(Timestamp), MachO::N_OSO);
|
||||
for (auto &Entry : Entries) {
|
||||
auto &Mapping = Entry.second;
|
||||
Optional<uint64_t> ObjAddress;
|
||||
|
|
|
@ -94,7 +94,8 @@ public:
|
|||
/// debug map.
|
||||
DebugMapObject &
|
||||
addDebugMapObject(StringRef ObjectFilePath,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp);
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp,
|
||||
uint8_t Type);
|
||||
|
||||
const Triple &getTriple() const { return BinaryTriple; }
|
||||
|
||||
|
@ -154,6 +155,8 @@ public:
|
|||
return Timestamp;
|
||||
}
|
||||
|
||||
uint8_t getType() const { return Type; }
|
||||
|
||||
iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const {
|
||||
return make_range(Symbols.begin(), Symbols.end());
|
||||
}
|
||||
|
@ -166,12 +169,13 @@ private:
|
|||
friend class DebugMap;
|
||||
/// DebugMapObjects can only be constructed by the owning DebugMap.
|
||||
DebugMapObject(StringRef ObjectFilename,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp);
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);
|
||||
|
||||
std::string Filename;
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp;
|
||||
StringMap<SymbolMapping> Symbols;
|
||||
DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
|
||||
uint8_t Type;
|
||||
|
||||
/// For YAMLIO support.
|
||||
///@{
|
||||
|
|
|
@ -525,6 +525,9 @@ public:
|
|||
/// Emit the string table described by \p Pool.
|
||||
void emitStrings(const NonRelocatableStringpool &Pool);
|
||||
|
||||
/// Emit the swift_ast section stored in \p Buffers.
|
||||
void emitSwiftAST(const std::vector<MemoryBufferRef> &Buffers);
|
||||
|
||||
/// Emit debug_ranges for \p FuncRange by translating the
|
||||
/// original \p Entries.
|
||||
void emitRangesEntries(
|
||||
|
@ -708,6 +711,15 @@ void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
|
|||
StringRef(Entry->getKey().data(), Entry->getKey().size() + 1));
|
||||
}
|
||||
|
||||
/// Emit the swift_ast section stored in \p Buffers.
|
||||
void DwarfStreamer::emitSwiftAST(const std::vector<MemoryBufferRef> &Buffers) {
|
||||
MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
|
||||
SwiftASTSection->setAlignment(1 << 5);
|
||||
MS->SwitchSection(SwiftASTSection);
|
||||
for (auto Buf : Buffers)
|
||||
MS->EmitBytes(Buf.getBuffer());
|
||||
}
|
||||
|
||||
/// Emit the debug_range section contents for \p FuncRange by
|
||||
/// translating the original \p Entries. The debug_range section
|
||||
/// format is totally trivial, consisting just of pairs of address
|
||||
|
@ -3329,8 +3341,8 @@ void DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
|
|||
else
|
||||
sys::path::append(Path, Filename);
|
||||
BinaryHolder ObjHolder(Options.Verbose);
|
||||
auto &Obj =
|
||||
ModuleMap.addDebugMapObject(Path, sys::TimePoint<std::chrono::seconds>());
|
||||
auto &Obj = ModuleMap.addDebugMapObject(
|
||||
Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO);
|
||||
auto ErrOrObj = loadObject(ObjHolder, Obj, ModuleMap);
|
||||
if (!ErrOrObj) {
|
||||
// Try and emit more helpful warnings by applying some heuristics.
|
||||
|
@ -3475,6 +3487,19 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
|||
|
||||
if (Options.Verbose)
|
||||
outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
|
||||
|
||||
// N_AST objects (swiftmodule files) should get dumped directly into the
|
||||
// appropriate DWARF section.
|
||||
if (Obj->getType() == MachO::N_AST) {
|
||||
auto ErrOrMemBufferRefs = BinHolder.GetMemoryBuffersForFile(
|
||||
Obj->getObjectFilename(), Obj->getTimestamp());
|
||||
if (ErrOrMemBufferRefs.getError())
|
||||
continue;
|
||||
if (!Options.NoOutput)
|
||||
Streamer->emitSwiftAST(ErrOrMemBufferRefs.get());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto ErrOrObj = loadObject(BinHolder, *Obj, Map);
|
||||
if (!ErrOrObj)
|
||||
continue;
|
||||
|
|
|
@ -135,7 +135,8 @@ void MachODebugMapParser::switchToNewDebugMapObject(
|
|||
Err.message() + "\n");
|
||||
}
|
||||
|
||||
CurrentDebugMapObject = &Result->addDebugMapObject(Path, Timestamp);
|
||||
CurrentDebugMapObject =
|
||||
&Result->addDebugMapObject(Path, Timestamp, MachO::N_OSO);
|
||||
loadCurrentObjectFileSymbols(*ErrOrAchObj);
|
||||
}
|
||||
|
||||
|
@ -349,6 +350,13 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
|
|||
if (Type == MachO::N_OSO)
|
||||
return switchToNewDebugMapObject(Name, sys::toTimePoint(Value));
|
||||
|
||||
if (Type == MachO::N_AST) {
|
||||
SmallString<80> Path(PathPrefix);
|
||||
sys::path::append(Path, Name);
|
||||
Result->addDebugMapObject(Path, sys::toTimePoint(Value), Type);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the last N_OSO object file wasn't found,
|
||||
// CurrentDebugMapObject will be null. Do not update anything
|
||||
// until we find the next valid N_OSO entry.
|
||||
|
|
Loading…
Reference in New Issue