1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[WebAssembly] Add Object and ObjectWriter support for wasm COMDAT sections

Allow sections to be placed into COMDAT groups, in addtion to functions and data
segments.

Also make section symbols unnamed, which allows sections with identical names
(section names are independent of their section symbols, but previously we
gave the symbols the same name as their sections, which results in collisions
when sections are identically-named).

Differential Revision: https://reviews.llvm.org/D92691
This commit is contained in:
Derek Schuff 2020-12-04 13:45:42 -08:00
parent 98a0dc8d53
commit 24b9266a7e
10 changed files with 87 additions and 16 deletions

View File

@ -330,6 +330,8 @@ enum : unsigned {
enum : unsigned {
WASM_COMDAT_DATA = 0x0,
WASM_COMDAT_FUNCTION = 0x1,
// GLOBAL, EVENT, and TABLE are in here but LLVM doesn't use them yet.
WASM_COMDAT_SECTION = 0x5,
};
// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE

View File

@ -108,6 +108,7 @@ struct WasmSection {
uint32_t Type = 0; // Section type (See below)
uint32_t Offset = 0; // Offset with in the file
StringRef Name; // Section name (User-defined sections only)
uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
ArrayRef<uint8_t> Content; // Section content
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
};

View File

@ -644,7 +644,7 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
StringRef CachedName = Entry.first.SectionName;
MCSymbol *Begin = createSymbol(CachedName, false, false);
MCSymbol *Begin = createSymbol(CachedName, true, false);
cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
MCSectionWasm *Result = new (WasmAllocator.Allocate())

View File

@ -974,9 +974,6 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
utostr(Hash));
case Triple::Wasm:
// FIXME: When using dwarf 5, the .debug_info section is used for type units
// but that section already exists, so attempting to get it as a comdate
// section triggers an assert.
return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
MCContext::GenericSectionID);
case Triple::MachO:

View File

@ -1421,6 +1421,16 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
continue;
}
// Custom sections can also belong to COMDAT groups. In this case the
// decriptor's "index" field is the section index (in the final object
// file), but that is not known until after layout, so it must be fixed up
// later
if (const MCSymbolWasm *C = Section.getGroup()) {
Comdats[C->getName()].emplace_back(
WasmComdatEntry{wasm::WASM_COMDAT_SECTION,
static_cast<uint32_t>(CustomSections.size())});
}
CustomSections.emplace_back(Name, &Section);
}
}
@ -1799,9 +1809,17 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
DataSectionIndex = writeDataSection(Layout);
}
for (auto &CustomSection : CustomSections) {
writeCustomSection(CustomSection, Asm, Layout);
// The Sections in the COMDAT list have placeholder indices (their index among
// custom sections, rather than among all sections). Fix them up here.
for (auto &Group : Comdats) {
for (auto &Entry : Group.second) {
if (Entry.Kind == wasm::WASM_COMDAT_SECTION) {
Entry.Index += SectionCount;
}
}
}
for (auto &CustomSection : CustomSections)
writeCustomSection(CustomSection, Asm, Layout);
if (Mode != DwoMode::DwoOnly) {
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);

View File

@ -745,6 +745,15 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
object_error::parse_failed);
getDefinedFunction(Index).Comdat = ComdatIndex;
break;
case wasm::WASM_COMDAT_SECTION:
if (Index >= Sections.size())
return make_error<GenericBinaryError>(
"COMDAT section index out of range", object_error::parse_failed);
if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
return make_error<GenericBinaryError>(
"Non-custom section in a COMDAT", object_error::parse_failed);
Sections[Index].Comdat = ComdatIndex;
break;
}
}
}

View File

@ -472,6 +472,7 @@ void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
ECase(FUNCTION);
ECase(DATA);
ECase(SECTION);
#undef ECase
}

View File

@ -8,17 +8,15 @@
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-4
; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-4
; TODO: enable testing for dwarf v5 with type units
; (See the FIXME in MCObjectFileInfo::getDwarfComdatSection)
; RU N: llc -dwarf-version=5 -generate-type-units \
; RU N: -filetype=obj -O0 -mtriple= < %s \
; RU N: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
; RUN: llc -dwarf-version=5 -generate-type-units \
; RUN: -filetype=obj -O0 -mtriple= < %s \
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
; RU N: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
; RU N: -dwarf-version=5 -generate-type-units \
; RU N: -filetype=obj -O0 -mtriple= < %s \
; RU N: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
; RU N: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
; RUN: -dwarf-version=5 -generate-type-units \
; RUN: -filetype=obj -O0 -mtriple= < %s \
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
; This test is derived from test/CodeGen/X86/dwarf-headers.ll

View File

@ -0,0 +1,37 @@
; RUN: llc -dwarf-version=4 -generate-type-units \
; RUN: -filetype=obj -O0 -mtriple=wasm32-unknown-unknown < %s \
; RUN: | obj2yaml | FileCheck %s
; CHECK: Comdats:
; CHECK: - Name: '4721183873463917179'
; CHECK: Entries:
; CHECK: - Kind: SECTION
; CHECK: Index: 3
; ModuleID = 't.cpp'
source_filename = "t.cpp"
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown-wasm"
%struct.S = type { i32 }
@s = global %struct.S zeroinitializer, align 4, !dbg !0
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!10, !11}
!llvm.ident = !{!12}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 5, type: !6, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 295942)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
!3 = !DIFile(filename: "t.cpp", directory: "/home/probinson/projects/scratch")
!4 = !{}
!5 = !{!0}
!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !3, line: 1, size: 32, elements: !7, identifier: "_ZTS1S")
!7 = !{!8}
!8 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !6, file: !3, line: 2, baseType: !9, size: 32)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!10 = !{i32 2, !"Dwarf Version", i32 4}
!11 = !{i32 2, !"Debug Info Version", i32 3}
!12 = !{!"clang version 5.0.0 (trunk 295942)"}

View File

@ -107,6 +107,14 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
}
SegmentIndex++;
}
uint32_t SectionIndex = 0;
for (const auto &Sec : Obj.sections()) {
const WasmSection &WasmSec = Obj.getWasmSection(Sec);
if (WasmSec.Comdat != UINT32_MAX)
LinkingSec->Comdats[WasmSec.Comdat].Entries.emplace_back(
WasmYAML::ComdatEntry{wasm::WASM_COMDAT_SECTION, SectionIndex});
SectionIndex++;
}
uint32_t SymbolIndex = 0;
for (const wasm::WasmSymbolInfo &Symbol : Obj.linkingData().SymbolTable) {