diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -395,6 +395,30 @@ .. _partition: https://lld.llvm.org/Partitions.html +``SHT_LLVM_BB_ADDR_MAP`` Section (basic block address map) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This section stores the binary address of basic blocks along with other related +metadata. This information can be used to map binary profiles (like perf +profiles) directly to machine basic blocks. +This section is emitted with ``-basic-block-sections=labels`` and will contain +a BB address map table for every function which may be constructed as follows: + +.. code-block:: gas + + .section ".llvm_bb_addr_map","",@llvm_bb_addr_map + .quad .Lfunc_begin0 # address of the function + .byte 2 # number of basic blocks + # BB record for BB_0 + .uleb128 .Lfunc_beign0-.Lfunc_begin0 # BB_0 offset relative to function entry (always zero) + .uleb128 .LBB_END0_0-.Lfunc_begin0 # BB_0 size + .byte x # BB_0 metadata + # BB record for BB_1 + .uleb128 .LBB0_1-.Lfunc_begin0 # BB_1 offset relative to function entry + .uleb128 .LBB_END0_1-.Lfunc_begin0 # BB_1 size + .byte y # BB_1 metadata + +This creates a BB address map table for a function with two basic blocks. + CodeView-Dependent ------------------ diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -856,10 +856,11 @@ SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols // for safe ICF. SHT_LLVM_DEPENDENT_LIBRARIES = - 0x6fff4c04, // LLVM Dependent Library Specifiers. - SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification. - SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition. - SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition. + 0x6fff4c04, // LLVM Dependent Library Specifiers. + SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification. + SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition. + SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition. + SHT_LLVM_BB_ADDR_MAP = 0x6fff4c08, // LLVM Basic Block Address Map. // Android's experimental support for SHT_RELR sections. // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512 SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets. diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1023,9 +1023,10 @@ MCConstantExpr::create(FrameOffset, OutContext)); } -/// Returns the BB metadata to be emitted in the bb_addr_map section for a given -/// basic block. This can be used to capture more precise profile information. -/// We use the last 3 bits (LSBs) to ecnode the following information: +/// Returns the BB metadata to be emitted in the .llvm_bb_addr_map section for a +/// given basic block. This can be used to capture more precise profile +/// information. We use the last 3 bits (LSBs) to ecnode the following +/// information: /// * (1): set if return block (ret or tail call). /// * (2): set if ends with a tail call. /// * (3): set if exception handling (EH) landing pad. @@ -1040,7 +1041,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { MCSection *BBAddrMapSection = getObjFileLowering().getBBAddrMapSection(*MF.getSection()); - assert(BBAddrMapSection && ".bb_addr_map section is not initialized."); + assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized."); const MCSymbol *FunctionSymbol = getFunctionBegin(); diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -49,9 +49,9 @@ // ================== // // With -fbasic-block-sections=labels, we emit the offsets of BB addresses of -// every function into a .bb_addr_map section. Along with the function symbols, -// this allows for mapping of virtual addresses in PMU profiles back to the -// corresponding basic blocks. This logic is implemented in AsmPrinter. This +// every function into the .llvm_bb_addr_map section. Along with the function +// symbols, this allows for mapping of virtual addresses in PMU profiles back to +// the corresponding basic blocks. This logic is implemented in AsmPrinter. This // pass only assigns the BBSectionType of every function to ``labels``. // //===----------------------------------------------------------------------===// diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -1002,7 +1002,7 @@ Flags |= ELF::SHF_GROUP; } - return Ctx->getELFSection(".bb_addr_map", ELF::SHT_PROGBITS, Flags, 0, - GroupName, MCSection::NonUniqueID, + return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, + Flags, 0, GroupName, MCSection::NonUniqueID, cast(TextSec.getBeginSymbol())); } diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -626,6 +626,8 @@ Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES; else if (TypeName == "llvm_sympart") Type = ELF::SHT_LLVM_SYMPART; + else if (TypeName == "llvm_bb_addr_map") + Type = ELF::SHT_LLVM_BB_ADDR_MAP; else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -156,6 +156,8 @@ OS << "llvm_dependent_libraries"; else if (Type == ELF::SHT_LLVM_SYMPART) OS << "llvm_sympart"; + else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP) + OS << "llvm_bb_addr_map"; else report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) + " for section " + getName()); diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -276,6 +276,7 @@ STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR); + STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll @@ -5,11 +5,11 @@ define dso_local i32 @_Z3barv() { ret i32 0 } -;; Check we add SHF_LINK_ORDER for .bb_addr_map and link it with the corresponding .text sections. +;; Check we add SHF_LINK_ORDER for .llvm_bb_addr_map and link it with the corresponding .text sections. ; CHECK: .section .text._Z3barv,"ax",@progbits ; CHECK-LABEL: _Z3barv: ; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .bb_addr_map,"o",@progbits,.text._Z3barv{{$}} +; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}} ; CHECK-NEXT: .quad [[BAR_BEGIN]] @@ -20,16 +20,16 @@ ; CHECK: .section .text._Z3foov,"ax",@progbits ; CHECK-LABEL: _Z3foov: ; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .bb_addr_map,"o",@progbits,.text._Z3foov{{$}} +; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}} ; CHECK-NEXT: .quad [[FOO_BEGIN]] define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat { ret i32 0 } -;; Check we add .bb_addr_map section to a COMDAT group with the corresponding .text section if such a COMDAT exists. +;; Check we add .llvm_bb_addr_map section to a COMDAT group with the corresponding .text section if such a COMDAT exists. ; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat ; CHECK-LABEL: _Z4fooTIiET_v: ; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .bb_addr_map,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}} +; CHECK: .section .llvm_bb_addr_map,"Go",@llvm_bb_addr_map,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}} ; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll @@ -39,7 +39,7 @@ ; CHECK-LABEL: .LBB_END0_3: ; CHECK-LABEL: .Lfunc_end0: -; CHECK: .section .bb_addr_map,"o",@progbits,.text +; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text ; CHECK-NEXT: .quad .Lfunc_begin0 ; CHECK-NEXT: .byte 4 ; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 diff --git a/llvm/test/MC/AsmParser/llvm_section_types.s b/llvm/test/MC/AsmParser/llvm_section_types.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AsmParser/llvm_section_types.s @@ -0,0 +1,28 @@ +## Verify that LLVM-specific section types are correctly inferred from assembly input. +# RUN: llvm-mc -triple i386-pc-linux -filetype=obj -o %t %s +# RUN: llvm-readobj -S %t | FileCheck %s +.section .section1,"",@llvm_bb_addr_map +.byte 1 +.section .section2,"",@llvm_call_graph_profile +.byte 1 +.section .section3,"",@llvm_odrtab +.byte 1 +.section .section4,"",@llvm_linker_options +.byte 1 +.section .section5,"",@llvm_sympart +.byte 1 +.section .section6,"",@llvm_dependent_libraries +.byte 1 + +# CHECK: Name: .section1 +# CHECK-NEXT: Type: SHT_LLVM_BB_ADDR_MAP +# CHECK: Name: .section2 +# CHECK-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE +# CHECK: Name: .section3 +# CHECK-NEXT: Type: SHT_LLVM_ODRTAB +# CHECK: Name: .section4 +# CHECK-NEXT: Type: SHT_LLVM_LINKER_OPTIONS +# CHECK: Name: .section5 +# CHECK-NEXT: Type: SHT_LLVM_SYMPART +# CHECK: Name: .section6 +# CHECK-NEXT: Type: SHT_LLVM_DEPENDENT_LIBRARIES