diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -450,6 +450,18 @@ .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 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -990,6 +990,7 @@ // 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 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -501,6 +501,9 @@ 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 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -660,6 +660,8 @@ 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 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -167,6 +167,8 @@ 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 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -297,6 +297,7 @@ 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 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -656,6 +656,7 @@ 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 --- 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 --- 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 --- /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 ]