Skip to content

Commit 0a39106

Browse files
committed
[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
1 parent 5fe1a49 commit 0a39106

File tree

10 files changed

+88
-17
lines changed

10 files changed

+88
-17
lines changed

llvm/include/llvm/BinaryFormat/Wasm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ enum : unsigned {
330330
enum : unsigned {
331331
WASM_COMDAT_DATA = 0x0,
332332
WASM_COMDAT_FUNCTION = 0x1,
333+
// GLOBAL, EVENT, and TABLE are in here but LLVM doesn't use them yet.
334+
WASM_COMDAT_SECTION = 0x5,
333335
};
334336

335337
// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE

llvm/include/llvm/Object/Wasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ struct WasmSection {
108108
uint32_t Type = 0; // Section type (See below)
109109
uint32_t Offset = 0; // Offset with in the file
110110
StringRef Name; // Section name (User-defined sections only)
111+
uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
111112
ArrayRef<uint8_t> Content; // Section content
112113
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
113114
};

llvm/lib/MC/MCContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
644644

645645
StringRef CachedName = Entry.first.SectionName;
646646

647-
MCSymbol *Begin = createSymbol(CachedName, false, false);
647+
MCSymbol *Begin = createSymbol(CachedName, true, false);
648648
cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
649649

650650
MCSectionWasm *Result = new (WasmAllocator.Allocate())

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,9 +974,6 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
974974
return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
975975
utostr(Hash));
976976
case Triple::Wasm:
977-
// FIXME: When using dwarf 5, the .debug_info section is used for type units
978-
// but that section already exists, so attempting to get it as a comdate
979-
// section triggers an assert.
980977
return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
981978
MCContext::GenericSectionID);
982979
case Triple::MachO:

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,16 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
14211421
continue;
14221422
}
14231423

1424+
// Custom sections can also belong to COMDAT groups. In this case the
1425+
// decriptor's "index" field is the section index (in the final object
1426+
// file), but that is not known until after layout, so it must be fixed up
1427+
// later
1428+
if (const MCSymbolWasm *C = Section.getGroup()) {
1429+
Comdats[C->getName()].emplace_back(
1430+
WasmComdatEntry{wasm::WASM_COMDAT_SECTION,
1431+
static_cast<uint32_t>(CustomSections.size())});
1432+
}
1433+
14241434
CustomSections.emplace_back(Name, &Section);
14251435
}
14261436
}
@@ -1799,9 +1809,17 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
17991809
DataSectionIndex = writeDataSection(Layout);
18001810
}
18011811

1802-
for (auto &CustomSection : CustomSections) {
1803-
writeCustomSection(CustomSection, Asm, Layout);
1812+
// The Sections in the COMDAT list have placeholder indices (their index among
1813+
// custom sections, rather than among all sections). Fix them up here.
1814+
for (auto &Group : Comdats) {
1815+
for (auto &Entry : Group.second) {
1816+
if (Entry.Kind == wasm::WASM_COMDAT_SECTION) {
1817+
Entry.Index += SectionCount;
1818+
}
1819+
}
18041820
}
1821+
for (auto &CustomSection : CustomSections)
1822+
writeCustomSection(CustomSection, Asm, Layout);
18051823

18061824
if (Mode != DwoMode::DwoOnly) {
18071825
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);

llvm/lib/Object/WasmObjectFile.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,15 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
745745
object_error::parse_failed);
746746
getDefinedFunction(Index).Comdat = ComdatIndex;
747747
break;
748+
case wasm::WASM_COMDAT_SECTION:
749+
if (Index >= Sections.size())
750+
return make_error<GenericBinaryError>(
751+
"COMDAT section index out of range", object_error::parse_failed);
752+
if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
753+
return make_error<GenericBinaryError>(
754+
"Non-custom section in a COMDAT", object_error::parse_failed);
755+
Sections[Index].Comdat = ComdatIndex;
756+
break;
748757
}
749758
}
750759
}

llvm/lib/ObjectYAML/WasmYAML.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
472472
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
473473
ECase(FUNCTION);
474474
ECase(DATA);
475+
ECase(SECTION);
475476
#undef ECase
476477
}
477478

llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-4
99
; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-4
1010

11-
; TODO: enable testing for dwarf v5 with type units
12-
; (See the FIXME in MCObjectFileInfo::getDwarfComdatSection)
13-
; RU N: llc -dwarf-version=5 -generate-type-units \
14-
; RU N: -filetype=obj -O0 -mtriple= < %s \
15-
; RU N: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
16-
17-
; RU N: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
18-
; RU N: -dwarf-version=5 -generate-type-units \
19-
; RU N: -filetype=obj -O0 -mtriple= < %s \
20-
; RU N: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
21-
; RU N: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
11+
; RUN: llc -dwarf-version=5 -generate-type-units \
12+
; RUN: -filetype=obj -O0 -mtriple= < %s \
13+
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
14+
15+
; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
16+
; RUN: -dwarf-version=5 -generate-type-units \
17+
; RUN: -filetype=obj -O0 -mtriple= < %s \
18+
; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
19+
; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
2220

2321
; This test is derived from test/CodeGen/X86/dwarf-headers.ll
2422

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: llc -dwarf-version=4 -generate-type-units \
2+
; RUN: -filetype=obj -O0 -mtriple=wasm32-unknown-unknown < %s \
3+
; RUN: | obj2yaml | FileCheck %s
4+
5+
6+
; CHECK: Comdats:
7+
; CHECK: - Name: '4721183873463917179'
8+
; CHECK: Entries:
9+
; CHECK: - Kind: SECTION
10+
; CHECK: Index: 3
11+
12+
; ModuleID = 't.cpp'
13+
source_filename = "t.cpp"
14+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
15+
target triple = "wasm32-unknown-unknown-wasm"
16+
17+
%struct.S = type { i32 }
18+
19+
@s = global %struct.S zeroinitializer, align 4, !dbg !0
20+
21+
!llvm.dbg.cu = !{!2}
22+
!llvm.module.flags = !{!10, !11}
23+
!llvm.ident = !{!12}
24+
25+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
26+
!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 5, type: !6, isLocal: false, isDefinition: true)
27+
!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)
28+
!3 = !DIFile(filename: "t.cpp", directory: "/home/probinson/projects/scratch")
29+
!4 = !{}
30+
!5 = !{!0}
31+
!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !3, line: 1, size: 32, elements: !7, identifier: "_ZTS1S")
32+
!7 = !{!8}
33+
!8 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !6, file: !3, line: 2, baseType: !9, size: 32)
34+
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
35+
!10 = !{i32 2, !"Dwarf Version", i32 4}
36+
!11 = !{i32 2, !"Debug Info Version", i32 3}
37+
!12 = !{!"clang version 5.0.0 (trunk 295942)"}

llvm/tools/obj2yaml/wasm2yaml.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
107107
}
108108
SegmentIndex++;
109109
}
110+
uint32_t SectionIndex = 0;
111+
for (const auto &Sec : Obj.sections()) {
112+
const WasmSection &WasmSec = Obj.getWasmSection(Sec);
113+
if (WasmSec.Comdat != UINT32_MAX)
114+
LinkingSec->Comdats[WasmSec.Comdat].Entries.emplace_back(
115+
WasmYAML::ComdatEntry{wasm::WASM_COMDAT_SECTION, SectionIndex});
116+
SectionIndex++;
117+
}
110118

111119
uint32_t SymbolIndex = 0;
112120
for (const wasm::WasmSymbolInfo &Symbol : Obj.linkingData().SymbolTable) {

0 commit comments

Comments
 (0)