Skip to content

🍒/ganymede/7a204362f5c6cb97308be543f77ace8d8285ffef #2327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion llvm/include/llvm/DWARFLinker/DWARFLinker.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class AddressesMap {
virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) = 0;

/// Relocate the given address offset if a valid relocation exists.
virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) = 0;

/// Returns all valid functions address ranges(i.e., those ranges
/// which points to sections with code).
virtual RangesTy &getValidAddressRanges() = 0;
Expand Down Expand Up @@ -183,7 +186,8 @@ class DwarfEmitter {
///
/// As a side effect, this also switches the current Dwarf version
/// of the MC layer to the one of U.getOrigUnit().
virtual void emitCompileUnitHeader(CompileUnit &Unit) = 0;
virtual void emitCompileUnitHeader(CompileUnit &Unit,
unsigned DwarfVersion) = 0;

/// Recursively emit the DIE tree rooted at \p Die.
virtual void emitDIE(DIE &Die) = 0;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class CompileUnit {
/// Compute the end offset for this unit. Must be called after the CU's DIEs
/// have been cloned. \returns the next unit offset (which is also the
/// current debug_info section size).
uint64_t computeNextUnitOffset();
uint64_t computeNextUnitOffset(uint16_t DwarfVersion);

/// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p
/// Attr. The attribute should be fixed up later to point to the absolute
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DWARFLinker/DWARFStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class DwarfStreamer : public DwarfEmitter {
///
/// As a side effect, this also switches the current Dwarf version
/// of the MC layer to the one of U.getOrigUnit().
void emitCompileUnitHeader(CompileUnit &Unit) override;
void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;

/// Recursively emit the DIE tree rooted at \p Die.
void emitDIE(DIE &Die) override;
Expand Down
4 changes: 1 addition & 3 deletions llvm/include/llvm/MC/MCObjectFileInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,7 @@ class MCObjectFileInfo {
// XCOFF specific sections
MCSection *getTOCBaseSection() const { return TOCBaseSection; }

MCSection *getEHFrameSection() {
return EHFrameSection;
}
MCSection *getEHFrameSection() const { return EHFrameSection; }

enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
Environment getObjectFileType() const { return Env; }
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DWARFLinker/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_llvm_component_library(LLVMDWARFLinker
intrinsics_gen

LINK_COMPONENTS
BinaryFormat
DebugInfoDWARF
AsmPrinter
CodeGen
Expand Down
52 changes: 40 additions & 12 deletions llvm/lib/DWARFLinker/DWARFLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,6 @@ void DWARFLinker::cleanupAuxiliarryData(LinkContext &Context) {
DIEAlloc.Reset();
}


/// Check if a variable describing DIE should be kept.
/// \returns updated TraversalFlags.
unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr,
Expand Down Expand Up @@ -845,9 +844,12 @@ void DWARFLinker::assignAbbrev(DIEAbbrev &Abbrev) {
unsigned DWARFLinker::DIECloner::cloneStringAttribute(
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
Optional<const char *> String = Val.getAsCString();
if (!String)
return 0;

// Switch everything to out of line strings.
const char *String = *Val.getAsCString();
auto StringEntry = StringPool.getEntry(String);
auto StringEntry = StringPool.getEntry(*String);

// Update attributes info.
if (AttrSpec.Attr == dwarf::DW_AT_name)
Expand Down Expand Up @@ -1056,6 +1058,7 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
const CompileUnit &Unit, AttributesInfo &Info) {
dwarf::Form Form = AttrSpec.Form;
uint64_t Addr = *Val.getAsAddress();

if (LLVM_UNLIKELY(Linker.Options.Update)) {
Expand Down Expand Up @@ -1105,8 +1108,19 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
Addr = (Info.OrigCallPc ? Info.OrigCallPc : Addr) + Info.PCOffset;
}

// If this is an indexed address emit the relocated address.
if (Form == dwarf::DW_FORM_addrx) {
if (llvm::Expected<uint64_t> RelocAddr =
ObjFile.Addresses->relocateIndexedAddr(Addr)) {
Addr = *RelocAddr;
Form = dwarf::DW_FORM_addr;
} else {
Linker.reportWarning(toString(RelocAddr.takeError()), ObjFile);
}
}

Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
static_cast<dwarf::Form>(AttrSpec.Form), DIEInteger(Addr));
static_cast<dwarf::Form>(Form), DIEInteger(Addr));
return Unit.getOrigUnit().getAddressByteSize();
}

Expand Down Expand Up @@ -1188,6 +1202,11 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
switch (AttrSpec.Form) {
case dwarf::DW_FORM_strp:
case dwarf::DW_FORM_string:
case dwarf::DW_FORM_strx:
case dwarf::DW_FORM_strx1:
case dwarf::DW_FORM_strx2:
case dwarf::DW_FORM_strx3:
case dwarf::DW_FORM_strx4:
return cloneStringAttribute(Die, AttrSpec, Val, U, StringPool, Info);
case dwarf::DW_FORM_ref_addr:
case dwarf::DW_FORM_ref1:
Expand All @@ -1204,6 +1223,7 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
return cloneBlockAttribute(Die, File, Unit, AttrSpec, Val, AttrSize,
IsLittleEndian);
case dwarf::DW_FORM_addr:
case dwarf::DW_FORM_addrx:
return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info);
case dwarf::DW_FORM_data1:
case dwarf::DW_FORM_data2:
Expand All @@ -1217,9 +1237,10 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
AttrSize, Info);
default:
Linker.reportWarning(
"Unsupported attribute form in cloneAttribute. Dropping.", File,
&InputDIE);
Linker.reportWarning("Unsupported attribute form " +
dwarf::FormEncodingString(AttrSpec.Form) +
" in cloneAttribute. Dropping.",
File, &InputDIE);
}

return 0;
Expand Down Expand Up @@ -1283,6 +1304,9 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
case dwarf::DW_AT_high_pc:
case dwarf::DW_AT_ranges:
return SkipPC;
case dwarf::DW_AT_str_offsets_base:
// FIXME: Use the string offset table with Dwarf 5.
return true;
case dwarf::DW_AT_location:
case dwarf::DW_AT_frame_base:
// FIXME: for some reason dsymutil-classic keeps the location attributes
Expand Down Expand Up @@ -2126,22 +2150,24 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
const uint64_t StartOutputDebugInfoSize = OutputDebugInfoSize;

for (auto &CurrentUnit : CompileUnits) {
const uint16_t DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
const uint32_t UnitHeaderSize = DwarfVersion >= 5 ? 12 : 11;
auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
CurrentUnit->setStartOffset(OutputDebugInfoSize);
if (!InputDIE) {
OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
continue;
}
if (CurrentUnit->getInfo(0).Keep) {
// Clone the InputDIE into your Unit DIE in our compile unit since it
// already has a DIE inside of it.
CurrentUnit->createOutputDIE();
cloneDIE(InputDIE, File, *CurrentUnit, StringPool, 0 /* PC offset */,
11 /* Unit Header size */, 0, IsLittleEndian,
UnitHeaderSize, 0, IsLittleEndian,
CurrentUnit->getOutputUnitDIE());
}

OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);

if (!Linker.Options.NoOutput) {
assert(Emitter);
Expand Down Expand Up @@ -2182,12 +2208,14 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
if (!CurrentUnit->getOutputUnitDIE())
continue;

unsigned DwarfVersion = CurrentUnit->getOrigUnit().getVersion();

assert(Emitter->getDebugInfoSectionSize() ==
CurrentUnit->getStartOffset());
Emitter->emitCompileUnitHeader(*CurrentUnit);
Emitter->emitCompileUnitHeader(*CurrentUnit, DwarfVersion);
Emitter->emitDIE(*CurrentUnit->getOutputUnitDIE());
assert(Emitter->getDebugInfoSectionSize() ==
CurrentUnit->computeNextUnitOffset());
CurrentUnit->computeNextUnitOffset(DwarfVersion));
}
}

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ StringRef CompileUnit::getSysRoot() {
}
return SysRoot;
}

void CompileUnit::markEverythingAsKept() {
unsigned Idx = 0;

Expand Down Expand Up @@ -69,10 +69,10 @@ void CompileUnit::markEverythingAsKept() {
}
}

uint64_t CompileUnit::computeNextUnitOffset() {
uint64_t CompileUnit::computeNextUnitOffset(uint16_t DwarfVersion) {
NextUnitOffset = StartOffset;
if (NewUnit) {
NextUnitOffset += 11 /* Header size */;
NextUnitOffset += (DwarfVersion >= 5) ? 12 : 11; // Header size
NextUnitOffset += NewUnit->getUnitDie().getSize();
}
return NextUnitOffset;
Expand Down
50 changes: 38 additions & 12 deletions llvm/lib/DWARFLinker/DWARFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,23 @@ void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {

/// Emit the compilation unit header for \p Unit in the debug_info section.
///
/// A Dwarf section header is encoded as:
/// A Dwarf 4 section header is encoded as:
/// uint32_t Unit length (omitting this field)
/// uint16_t Version
/// uint32_t Abbreviation table offset
/// uint8_t Address size
///
/// Leading to a total of 11 bytes.
void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
unsigned Version = Unit.getOrigUnit().getVersion();
switchToDebugInfoSection(Version);
///
/// A Dwarf 5 section header is encoded as:
/// uint32_t Unit length (omitting this field)
/// uint16_t Version
/// uint8_t Unit type
/// uint8_t Address size
/// uint32_t Abbreviation table offset
/// Leading to a total of 12 bytes.
void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit,
unsigned DwarfVersion) {
switchToDebugInfoSection(DwarfVersion);

/// The start of the unit within its section.
Unit.setLabelBegin(Asm->createTempSymbol("cu_begin"));
Expand All @@ -140,13 +147,22 @@ void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
// been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
// account for the length field.
Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
Asm->emitInt16(Version);

// We share one abbreviations table across all units so it's always at the
// start of the section.
Asm->emitInt32(0);
Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
DebugInfoSectionSize += 11;
Asm->emitInt16(DwarfVersion);

if (DwarfVersion >= 5) {
Asm->emitInt8(dwarf::DW_UT_compile);
Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
// We share one abbreviations table across all units so it's always at the
// start of the section.
Asm->emitInt32(0);
DebugInfoSectionSize += 12;
} else {
// We share one abbreviations table across all units so it's always at the
// start of the section.
Asm->emitInt32(0);
Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
DebugInfoSectionSize += 11;
}

// Remember this CU.
EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
Expand Down Expand Up @@ -211,6 +227,16 @@ void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
// Emit a null terminator.
Asm->emitInt8(0);
}

#if 0
if (DwarfVersion >= 5) {
// Emit an empty string offset section.
Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrOffSection());
Asm->emitDwarfUnitLength(4, "Length of String Offsets Set");
Asm->emitInt16(DwarfVersion);
Asm->emitInt16(0);
}
#endif
}

void DwarfStreamer::emitDebugNames(
Expand Down
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
59 changes: 59 additions & 0 deletions llvm/test/tools/dsymutil/X86/dwarf5.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Test DWARF5 support in dsymutil. Currently this still generates an empty dSYM.

$ cat dwarf5.c
__attribute__ ((optnone))
int foo() {
volatile i;
return i;
}

int main(int argc, char** argv) {
return foo();
}

$ clang -gdwarf-5 dwarf5.c -c -o dwarf5.o
$ clang dwarf5.o -o dwarf5.out

RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
CHECK-NOT: error:

RUN: llvm-dwarfdump %t.dSYM | FileCheck %s --check-prefix DWARF
DWARF: DW_TAG_compile_unit
DWARF: DW_AT_producer ("clang version 12.0.0
DWARF: DW_AT_language (DW_LANG_C99)
DWARF: DW_AT_name ("dwarf5.c")
DWARF: DW_AT_LLVM_sysroot ("/")
DWARF: DW_AT_stmt_list (0x00000000)
DWARF: DW_AT_comp_dir ("/private/tmp/dwarf5")
DWARF: DW_AT_low_pc (0x0000000100003f80)
DWARF: DW_AT_high_pc (0x0000000100003fb1)
DWARF: DW_AT_addr_base (0x00000008)
DWARF: DW_TAG_subprogram
DWARF: DW_AT_name ("foo")
DWARF: DW_AT_decl_file (0x00)
DWARF: DW_AT_decl_line (2)
DWARF: DW_AT_type (0x0000006c "int")
DWARF: DW_AT_external (true)
DWARF: DW_TAG_variable
DWARF: DW_AT_name ("i")
DWARF: DW_AT_decl_file (0x00)
DWARF: DW_AT_decl_line (3)
DWARF: DW_AT_type (0x00000073 "volatile int")
DWARF: DW_TAG_subprogram
DWARF: DW_AT_name ("main")
DWARF: DW_AT_decl_file (0x00)
DWARF: DW_AT_decl_line (7)
DWARF: DW_AT_prototyped (true)
DWARF: DW_AT_type (0x0000006c "int")
DWARF: DW_AT_external (true)
DWARF: DW_TAG_formal_parameter
DWARF: DW_AT_name ("argc")
DWARF: DW_AT_decl_file (0x00)
DWARF: DW_AT_decl_line (7)
DWARF: DW_AT_type (0x0000006c "int")
DWARF: DW_TAG_formal_parameter
DWARF: DW_AT_name ("argv")
DWARF: DW_AT_decl_file (0x00)
DWARF: DW_AT_decl_line (7)
DWARF: DW_AT_type (0x00000078 "char**")
26 changes: 26 additions & 0 deletions llvm/test/tools/dsymutil/X86/eh_frame.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
REQUIRES: system-darwin

FIXME: Replace otool with llvm-objcopy --dump-section=__TEXT,__eh_frame.

$ cat eh_frame.cpp
int f1()
{
volatile int i;
return i;
}

int main(int argc, char** argv)
{
return f1();
}

$ clang eh_frame.cpp -g -c -o eh_frame.o
$ ld -no_compact_unwind eh_frame.o -o eh_frame.out

RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/eh_frame/eh_frame.out -o %t.dSYM
RUN: llvm-dwarfdump --verify %t.dSYM
RUN: otool -s __TEXT __eh_frame %p/../Inputs/private/tmp/eh_frame/eh_frame.out | FileCheck %s
RUN: otool -s __TEXT __eh_frame %t.dSYM/Contents/Resources/DWARF/eh_frame.out | FileCheck %s

CHECK: 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01
CHECK: 10 0c 07 08 90 01 00 00
2 changes: 1 addition & 1 deletion llvm/test/tools/dsymutil/X86/swift-ast-x86_64.test
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ READOBJ-NEXT: |.|
DWARFDUMP: __swift_ast

RUN: dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -no-output -verbose 2>&1 | FileCheck %s --check-prefix=TIMESTAMP
TIMESTAMP: warning: Timestamp mismatch
TIMESTAMP: warning: {{.*}}/swift-ast.swiftmodule: timestamp mismatch between swift interface file ({{.*}}) and debug map ({{.*}})

RUN: dsymutil -s %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=NAST
NAST-NOT: N_AST
Loading