From dbfc3d5e83c2e2f65d15a5d74c6edaa61abc68f6 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 7 Sep 2022 18:48:52 +0200 Subject: [PATCH 1/2] Enable DWARF debug information emitting for Mach-O --- .../objwriter/debugInfo/dwarf/dwarfAbbrev.cpp | 4 +++ .../objwriter/debugInfo/dwarf/dwarfGen.cpp | 28 ++++++++++++++++++- .../debugInfo/dwarf/dwarfTypeBuilder.cpp | 6 ++-- llvm/tools/objwriter/objwriter.cpp | 19 +++++++------ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp index 362d5df76017b..47ba63646da92 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp @@ -38,6 +38,10 @@ void Dump(MCObjectStreamer *Streamer, uint16_t DwarfVersion, unsigned TargetPoin dwarf::DW_TAG_compile_unit, dwarf::DW_CHILDREN_yes, dwarf::DW_AT_producer, dwarf::DW_FORM_string, dwarf::DW_AT_language, dwarf::DW_FORM_data2, + dwarf::DW_AT_name, dwarf::DW_FORM_string, + dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, + dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + dwarf::DW_AT_high_pc, DW_FORM_size, dwarf::DW_AT_stmt_list, (DwarfVersion >= 4 ? dwarf::DW_FORM_sec_offset : dwarf::DW_FORM_data4), 0, 0, diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfGen.cpp b/llvm/tools/objwriter/debugInfo/dwarf/dwarfGen.cpp index b2ad3f4bd3d56..555bb2ccb8a43 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfGen.cpp +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfGen.cpp @@ -816,7 +816,7 @@ void SubprogramInfo::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTy EmitInfoOffset(Streamer, MethodTypeInfo, 4); // DW_AT_low_pc - MCSymbol *Sym = context.getOrCreateSymbol(Twine(Name)); + MCSymbol *Sym = context.lookupSymbol(Twine(Name)); const MCExpr *SymExpr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, context); Streamer->emitValue(SymExpr, TargetPointerSize); @@ -907,6 +907,7 @@ void DwarfGen::SetTypeBuilder(UserDefinedDwarfTypesBuilder *TypeBuilder) { void DwarfGen::EmitCompileUnit() { MCContext &context = Streamer->getContext(); + unsigned TargetPointerSize = context.getAsmInfo()->getCodePointerSize(); MCSymbol *LineSectionSymbol = nullptr; MCSymbol *AbbrevSectionSymbol = nullptr; @@ -966,6 +967,31 @@ void DwarfGen::EmitCompileUnit() { Streamer->emitIntValue(dwarf::DW_LANG_C_plus_plus, 2); #endif + // We need to generate DW_AT_name and DW_AT_compdir to get Apple's ld64 to correctly + // generate debug map in final executable. If we don't generate it then the linker + // will skip over the object file. + // Ref: https://github.com/apple-oss-distributions/ld64/blob/dbf8f7feb5579761f1623b004bd468bdea7c6225/src/ld/OutputFile.cpp#L7166 + + // DW_AT_name + Streamer->emitBytes(StringRef("IL.c")); + Streamer->emitIntValue(0, 1); + + // DW_AT_compdir + Streamer->emitBytes(StringRef("/tmp")); + Streamer->emitIntValue(0, 1); + + // There need to be global DW_AT_low_pc/DW_AT_high_pc symbols to indicate the base and + // size of the range covered by the symbols. Currently we use a shortcut where we emit + // a range starting at the beginning of file and ending at the start of the debug section + // which is located at the end of the object file. + + // DW_AT_low_pc + Streamer->emitIntValue(0, TargetPointerSize); + + // DW_AT_high_pc + const MCExpr *SymExpr = MCSymbolRefExpr::create(debugSection->getBeginSymbol(), MCSymbolRefExpr::VK_None, context); + Streamer->emitValue(SymExpr, TargetPointerSize); + // DW_AT_stmt_list if (LineSectionSymbol == nullptr) { Streamer->emitIntValue(0, 4); diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp b/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp index 6d663e0512884..e7e2d18fefe10 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp @@ -652,8 +652,10 @@ void DwarfMemberFunctionIdTypeInfo::DumpTypeInfo(MCObjectStreamer *Streamer, Use EmitInfoOffset(Streamer, ArgTypeInfo, 4); } - // Ternimate DIE - Streamer->emitIntValue(0, 1); + // Terminate DIE (skip for SubprogramStaticNoChildrenSpec which has no children) + if (!IsStatic || HasParameters) { + Streamer->emitIntValue(0, 1); + } } // DwarfTypesBuilder diff --git a/llvm/tools/objwriter/objwriter.cpp b/llvm/tools/objwriter/objwriter.cpp index 3fe42df9b7a3b..f4906580786e8 100644 --- a/llvm/tools/objwriter/objwriter.cpp +++ b/llvm/tools/objwriter/objwriter.cpp @@ -152,10 +152,8 @@ bool ObjectWriter::Init(llvm::StringRef ObjectFilePath, const char* tripleName) unsigned TargetPointerSize = Streamer->getContext().getAsmInfo()->getCodePointerSize(); TypeBuilder->SetTargetPointerSize(TargetPointerSize); - if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsELF) { - DwarfGenerator.reset(new DwarfGen()); - DwarfGenerator->SetTypeBuilder(static_cast(TypeBuilder.get())); - } + DwarfGenerator.reset(new DwarfGen()); + DwarfGenerator->SetTypeBuilder(static_cast(TypeBuilder.get())); CFIsPerOffset.set_size(0); @@ -256,6 +254,12 @@ MCSection *ObjectWriter::GetSpecificSection(const char *SectionName, if (attributes & CustomSectionAttributes_MachO_Init_Func_Pointers) { typeAndAttributes |= MachO::SectionType::S_MOD_INIT_FUNC_POINTERS; } + if (attributes & CustomSectionAttributes_Executable) { + // Needs to be set on sections with actual code. The linker uses + // it to determine code sections and emit information about function + // boundaries. + typeAndAttributes |= MachO::S_ATTR_PURE_INSTRUCTIONS; + } Section = OutContext->getMachOSection( (attributes & CustomSectionAttributes_Executable) ? "__TEXT" : "__DATA", SectionName, typeAndAttributes, Kind); @@ -882,9 +886,8 @@ void ObjectWriter::EmitDebugFunctionInfo(const char *FunctionName, Streamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); Streamer->emitELFSize(Sym, MCConstantExpr::create(FunctionSize, *OutContext)); - EmitDwarfFunctionInfo(FunctionName, FunctionSize, MethodTypeIndex); } - // TODO: Should test it for Macho. + EmitDwarfFunctionInfo(FunctionName, FunctionSize, MethodTypeIndex); } } @@ -963,12 +966,10 @@ void ObjectWriter::EmitDebugModuleInfo() { Streamer->SwitchSection(Section); Streamer->emitCVFileChecksumsDirective(); Streamer->emitCVStringTableDirective(); - } else if (ObjFileInfo->getObjectFileType() == ObjFileInfo->IsELF) { + } else { DwarfGenerator->EmitAbbrev(); DwarfGenerator->EmitAranges(); DwarfGenerator->Finish(); - } else { - OutContext->setGenDwarfForAssembly(true); } } From 61182d65e8076cbfc8a665b7055753a2af89e9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 24 Jan 2022 13:58:56 +0900 Subject: [PATCH 2/2] Fix llvm-dwarfdump warnings (#164) Fixes https://github.com/dotnet/runtimelab/issues/1535. No warnings left with llvm-dwarfdump from LLVM 12. --- llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp | 11 +++++++++++ llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.h | 1 + .../objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp | 6 +++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp index 47ba63646da92..200431a34cdef 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.cpp @@ -129,6 +129,17 @@ void Dump(MCObjectStreamer *Streamer, uint16_t DwarfVersion, unsigned TargetPoin dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, 0, 0, + SubprogramStaticNoChildrenSpec, + dwarf::DW_TAG_subprogram, dwarf::DW_CHILDREN_no, + dwarf::DW_AT_name, dwarf::DW_FORM_strp, + dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, + dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, + dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, + dwarf::DW_AT_type, dwarf::DW_FORM_ref4, + dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, + dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, + 0, 0, + Variable, dwarf::DW_TAG_variable, dwarf::DW_CHILDREN_no, dwarf::DW_AT_name, dwarf::DW_FORM_strp, diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.h b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.h index 3cd8cea23772c..1a79930824c15 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.h +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfAbbrev.h @@ -30,6 +30,7 @@ enum DwarfAbbrev : uint16_t SubprogramStatic, SubprogramSpec, SubprogramStaticSpec, + SubprogramStaticNoChildrenSpec, Variable, VariableLoc, VariableStatic, diff --git a/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp b/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp index e7e2d18fefe10..f124d239a06f5 100644 --- a/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp +++ b/llvm/tools/objwriter/debugInfo/dwarf/dwarfTypeBuilder.cpp @@ -601,8 +601,12 @@ void DwarfMemberFunctionIdTypeInfo::DumpStrings(MCObjectStreamer *Streamer) { void DwarfMemberFunctionIdTypeInfo::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) { // Abbrev Number bool IsStatic = MemberFunctionTypeInfo->IsStatic(); + bool HasParameters = MemberFunctionTypeInfo->GetArgTypes().size(); - Streamer->emitULEB128IntValue(IsStatic ? DwarfAbbrev::SubprogramStaticSpec : DwarfAbbrev::SubprogramSpec); + Streamer->emitULEB128IntValue( + IsStatic ? (HasParameters ? DwarfAbbrev::SubprogramStaticSpec + : DwarfAbbrev::SubprogramStaticNoChildrenSpec) + : DwarfAbbrev::SubprogramSpec); // DW_AT_name EmitSectionOffset(Streamer, StrSymbol, 4);