Introduce and use a new section type for the bb_addr_map section.

This patch lets the bb_addr_map (renamed to __llvm_bb_addr_map) section use a special section type (SHT_LLVM_BB_ADDR_MAP) instead of SHT_PROGBITS. This would help parsers, dumpers and other tools to use the sh_type ELF field to identify this section rather than relying on string comparison on the section name.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D88199
This commit is contained in:
Rahman Lavaee 2020-10-08 11:12:40 -07:00
parent dacb3eca7f
commit 194be1c7dd
11 changed files with 78 additions and 19 deletions

View File

@ -395,6 +395,30 @@ the symbol that belongs to the partition. It may be constructed as follows:
.. _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
------------------

View File

@ -856,10 +856,11 @@ enum : unsigned {
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.

View File

@ -1023,9 +1023,10 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
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 @@ static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
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();

View File

@ -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``.
//
//===----------------------------------------------------------------------===//

View File

@ -1002,7 +1002,7 @@ MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
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<MCSymbolELF>(TextSec.getBeginSymbol()));
}

View File

@ -626,6 +626,8 @@ EndStmt:
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");
}

View File

@ -156,6 +156,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
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());

View File

@ -276,6 +276,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
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);

View File

@ -5,11 +5,11 @@ $_Z4fooTIiET_v = comdat any
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 @@ define dso_local i32 @_Z3foov() {
; 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]]

View File

@ -39,7 +39,7 @@ declare i32 @__gxx_personality_v0(...)
; 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

View File

@ -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