From 1d2ce4da8414de8775c134eb1c7e2c9436b443df Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Sun, 3 Jul 2022 16:46:31 -0400 Subject: [PATCH] [Object] Add ELF section type for offloading objects Currently we use the `.llvm.offloading` section to store device-side objects inside the host, creating a fat binary. The contents of these sections is currently determined by the name of the section while it should ideally be determined by its type. This patch adds the new `SHT_LLVM_OFFLOADING` section type to the ELF section types. Which should make it easier to identify this specific data format. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D129052 --- llvm/docs/Extensions.rst | 12 ++++++++++ llvm/include/llvm/BinaryFormat/ELF.h | 1 + llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 3 +++ llvm/lib/MC/MCParser/ELFAsmParser.cpp | 2 ++ llvm/lib/MC/MCSectionELF.cpp | 2 ++ llvm/lib/Object/ELF.cpp | 1 + llvm/lib/ObjectYAML/ELFYAML.cpp | 1 + llvm/test/CodeGen/X86/offload_sections.ll | 2 +- llvm/test/MC/AsmParser/llvm_section_types.s | 4 ++++ llvm/test/ObjectYAML/ELF/sht-offloading.yaml | 28 +++++++++++++++++++++++ 10 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 llvm/test/ObjectYAML/ELF/sht-offloading.yaml diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst index 65cae4f..4534ba3 100644 --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -450,6 +450,18 @@ Example: .uleb128 .LBB_END0_1-.LBB0_1 # BB_1 size .byte y # BB_1 metadata +``SHT_LLVM_OFFLOADING`` Section (offloading data) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This section stores the binary data used to perform offloading device linking +and execution, creating a fat binary. This section is emitted during compilation +of offloading languages such as OpenMP or CUDA. If the data is intended to be +used by the device linker only, it should use the ``SHF_EXCLUDE`` flag so it is +automatically stripped from the final executable or shared library. + +The binary data stored in this section conforms to a custom binary format used +for storing offloading metadata. This format is effectively a string table +containing metadata accompanied by a device image. + CodeView-Dependent ------------------ diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 1e0ef613..1fd0257 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -990,6 +990,7 @@ enum : unsigned { // backward-compatibility). SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c09, // LLVM Call Graph Profile. SHT_LLVM_BB_ADDR_MAP = 0x6fff4c0a, // LLVM Basic Block Address Map. + SHT_LLVM_OFFLOADING = 0x6fff4c0b, // LLVM device offloading data. // 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/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index f3d68bd..dbac474 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -501,6 +501,9 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { if (hasPrefix(Name, ".preinit_array")) return ELF::SHT_PREINIT_ARRAY; + if (hasPrefix(Name, ".llvm.offloading")) + return ELF::SHT_LLVM_OFFLOADING; + if (K.isBSS() || K.isThreadBSS()) return ELF::SHT_NOBITS; diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 04a234b..563d348 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -660,6 +660,8 @@ EndStmt: Type = ELF::SHT_LLVM_SYMPART; else if (TypeName == "llvm_bb_addr_map") Type = ELF::SHT_LLVM_BB_ADDR_MAP; + else if (TypeName == "llvm_offloading") + Type = ELF::SHT_LLVM_OFFLOADING; 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 index 27dc182..077cee1 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -167,6 +167,8 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, OS << "llvm_bb_addr_map"; else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP_V0) OS << "llvm_bb_addr_map_v0"; + else if (Type == ELF::SHT_LLVM_OFFLOADING) + OS << "llvm_offloading"; 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 index 6acf454..0d5aa91 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -297,6 +297,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP); + STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING); 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/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index cdd180c..b778006 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -656,6 +656,7 @@ void ScalarEnumerationTraits::enumeration( ECase(SHT_LLVM_PART_PHDR); ECase(SHT_LLVM_BB_ADDR_MAP_V0); ECase(SHT_LLVM_BB_ADDR_MAP); + ECase(SHT_LLVM_OFFLOADING); ECase(SHT_GNU_ATTRIBUTES); ECase(SHT_GNU_HASH); ECase(SHT_GNU_verdef); diff --git a/llvm/test/CodeGen/X86/offload_sections.ll b/llvm/test/CodeGen/X86/offload_sections.ll index b6a438b..c3ad26b 100644 --- a/llvm/test/CodeGen/X86/offload_sections.ll +++ b/llvm/test/CodeGen/X86/offload_sections.ll @@ -4,5 +4,5 @@ @llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading" @llvm.compiler.used = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm.metadata" -; CHECK-ELF: .section .llvm.offloading,"e" +; CHECK-ELF: .section .llvm.offloading,"e",@llvm_offloading ; CHECK-COFF: .section .llvm.offloading,"dr" diff --git a/llvm/test/MC/AsmParser/llvm_section_types.s b/llvm/test/MC/AsmParser/llvm_section_types.s index bbbb527..91cee6c 100644 --- a/llvm/test/MC/AsmParser/llvm_section_types.s +++ b/llvm/test/MC/AsmParser/llvm_section_types.s @@ -13,6 +13,8 @@ .byte 1 .section .section6,"",@llvm_dependent_libraries .byte 1 +.section .section7,"",@llvm_offloading +.byte 1 # CHECK: Name: .section1 # CHECK-NEXT: Type: SHT_LLVM_BB_ADDR_MAP @@ -26,3 +28,5 @@ # CHECK-NEXT: Type: SHT_LLVM_SYMPART # CHECK: Name: .section6 # CHECK-NEXT: Type: SHT_LLVM_DEPENDENT_LIBRARIES +# CHECK: Name: .section7 +# CHECK-NEXT: Type: SHT_LLVM_OFFLOADING diff --git a/llvm/test/ObjectYAML/ELF/sht-offloading.yaml b/llvm/test/ObjectYAML/ELF/sht-offloading.yaml new file mode 100644 index 0000000..b234b96 --- /dev/null +++ b/llvm/test/ObjectYAML/ELF/sht-offloading.yaml @@ -0,0 +1,28 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --sections %t | FileCheck -check-prefix=OBJ %s +# RUN: obj2yaml %t | FileCheck -check-prefix=YAML %s + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL +Sections: + - Name: .llvm.offloading + Type: SHT_LLVM_OFFLOADING + Flags: [ SHF_EXCLUDE ] + +# OBJ: Sections [ +# OBJ: Section { +# OBJ: Index: 1 +# OBJ-NEXT: Name: .llvm.offloading (1) +# OBJ-NEXT: Type: SHT_LLVM_OFFLOADING (0x6FFF4C0B) +# OBJ-NEXT: Flags [ (0x80000000) +# OBJ-NEXT: SHF_EXCLUDE (0x80000000) +# OBJ-NEXT: ] + + +# YAML: Sections: +# YAML-NEXT: - Name: .llvm.offloading +# YAML-NEXT: Type: SHT_LLVM_OFFLOADING +# YAML-NEXT: Flags: [ SHF_EXCLUDE ] -- 2.7.4