[llvm] b78c85a - [WebAssembly] Convert to new "dylink.0" section format
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 12 05:31:48 PDT 2021
Author: Sam Clegg
Date: 2021-09-12T05:30:38-07:00
New Revision: b78c85a44af300f8e3da582411814385cf70239d
URL: https://github.com/llvm/llvm-project/commit/b78c85a44af300f8e3da582411814385cf70239d
DIFF: https://github.com/llvm/llvm-project/commit/b78c85a44af300f8e3da582411814385cf70239d.diff
LOG: [WebAssembly] Convert to new "dylink.0" section format
This format is based on sub-sections (like the "linking" and "name"
sections) and is therefore easier to extend going forward.
spec change: https://github.com/WebAssembly/tool-conventions/pull/170
binaryen change: https://github.com/WebAssembly/binaryen/pull/4141
wabt change: https://github.com/WebAssembly/wabt/pull/1707
emscripten change: https://github.com/emscripten-core/emscripten/pull/15019
Differential Revision: https://reviews.llvm.org/D109595
Added:
Modified:
lld/test/wasm/pie.ll
lld/test/wasm/shared-needed.s
lld/test/wasm/shared.s
lld/test/wasm/shared64.s
lld/wasm/SyntheticSections.cpp
lld/wasm/SyntheticSections.h
llvm/include/llvm/BinaryFormat/Wasm.h
llvm/include/llvm/Object/Wasm.h
llvm/include/llvm/ObjectYAML/WasmYAML.h
llvm/lib/Object/WasmObjectFile.cpp
llvm/lib/ObjectYAML/WasmEmitter.cpp
llvm/lib/ObjectYAML/WasmYAML.cpp
llvm/test/ObjectYAML/wasm/dylink_section.yaml
llvm/tools/obj2yaml/wasm2yaml.cpp
Removed:
################################################################################
diff --git a/lld/test/wasm/pie.ll b/lld/test/wasm/pie.ll
index af28ddd06e89c..ee2f02777fda9 100644
--- a/lld/test/wasm/pie.ll
+++ b/lld/test/wasm/pie.ll
@@ -34,7 +34,7 @@ declare void @external_func()
; CHECK: Sections:
; CHECK-NEXT: - Type: CUSTOM
-; CHECK-NEXT: Name: dylink
+; CHECK-NEXT: Name: dylink.0
; CHECK-NEXT: MemorySize: 16
; CHECK-NEXT: MemoryAlignment: 2
; CHECK-NEXT: TableSize: 1
diff --git a/lld/test/wasm/shared-needed.s b/lld/test/wasm/shared-needed.s
index c6ebd5ee1060a..12c4597190a3b 100644
--- a/lld/test/wasm/shared-needed.s
+++ b/lld/test/wasm/shared-needed.s
@@ -23,7 +23,7 @@ data:
# SO1: Sections:
# SO1-NEXT: - Type: CUSTOM
-# SO1-NEXT: Name: dylink
+# SO1-NEXT: Name: dylink.0
# SO1-NEXT: MemorySize: 4
# SO1-NEXT: MemoryAlignment: 2
# SO1-NEXT: TableSize: 0
@@ -33,7 +33,7 @@ data:
# SO2: Sections:
# SO2-NEXT: - Type: CUSTOM
-# SO2-NEXT: Name: dylink
+# SO2-NEXT: Name: dylink.0
# SO2-NEXT: MemorySize: 0
# SO2-NEXT: MemoryAlignment: 0
# SO2-NEXT: TableSize: 0
diff --git a/lld/test/wasm/shared.s b/lld/test/wasm/shared.s
index 29cf8f6f996c5..7861485470ffa 100644
--- a/lld/test/wasm/shared.s
+++ b/lld/test/wasm/shared.s
@@ -127,7 +127,7 @@ get_local_func_address:
# CHECK: Sections:
# CHECK-NEXT: - Type: CUSTOM
-# CHECK-NEXT: Name: dylink
+# CHECK-NEXT: Name: dylink.0
# CHECK-NEXT: MemorySize: 24
# CHECK-NEXT: MemoryAlignment: 2
# CHECK-NEXT: TableSize: 2
diff --git a/lld/test/wasm/shared64.s b/lld/test/wasm/shared64.s
index d441dd363cdb2..86d5a521ab334 100644
--- a/lld/test/wasm/shared64.s
+++ b/lld/test/wasm/shared64.s
@@ -128,7 +128,7 @@ get_local_func_address:
# CHECK: Sections:
# CHECK-NEXT: - Type: CUSTOM
-# CHECK-NEXT: Name: dylink
+# CHECK-NEXT: Name: dylink.0
# CHECK-NEXT: MemorySize: 36
# CHECK-NEXT: MemoryAlignment: 2
# CHECK-NEXT: TableSize: 2
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index bb0439653b659..3e6e9fe56d9f9 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -57,13 +57,22 @@ class SubSection {
void DylinkSection::writeBody() {
raw_ostream &os = bodyOutputStream;
- writeUleb128(os, memSize, "MemSize");
- writeUleb128(os, memAlign, "MemAlign");
- writeUleb128(os, out.elemSec->numEntries(), "TableSize");
- writeUleb128(os, 0, "TableAlign");
- writeUleb128(os, symtab->sharedFiles.size(), "Needed");
- for (auto *so : symtab->sharedFiles)
- writeStr(os, llvm::sys::path::filename(so->getName()), "so name");
+ {
+ SubSection sub(WASM_DYLINK_MEM_INFO);
+ writeUleb128(sub.os, memSize, "MemSize");
+ writeUleb128(sub.os, memAlign, "MemAlign");
+ writeUleb128(sub.os, out.elemSec->numEntries(), "TableSize");
+ writeUleb128(sub.os, 0, "TableAlign");
+ sub.writeTo(os);
+ }
+
+ if (symtab->sharedFiles.size()) {
+ SubSection sub(WASM_DYLINK_NEEDED);
+ writeUleb128(sub.os, symtab->sharedFiles.size(), "Needed");
+ for (auto *so : symtab->sharedFiles)
+ writeStr(sub.os, llvm::sys::path::filename(so->getName()), "so name");
+ sub.writeTo(os);
+ }
}
uint32_t TypeSection::registerType(const WasmSignature &sig) {
diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index 12517b65c1635..d26f89b6fd5f1 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -74,7 +74,7 @@ class SyntheticSection : public OutputSection {
// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
class DylinkSection : public SyntheticSection {
public:
- DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink") {}
+ DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink.0") {}
bool isNeeded() const override { return config->isPic; }
void writeBody() override;
diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index 1d0eb7009c7cc..f49828ca87574 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -339,6 +339,12 @@ enum : unsigned {
WASM_SYMBOL_TABLE = 0x8,
};
+// Kind codes used in the custom "dylink" section
+enum : unsigned {
+ WASM_DYLINK_MEM_INFO = 0x1,
+ WASM_DYLINK_NEEDED = 0x2,
+};
+
// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
enum : unsigned {
WASM_COMDAT_DATA = 0x0,
diff --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h
index 2cea950fcf253..d15722df95a55 100644
--- a/llvm/include/llvm/Object/Wasm.h
+++ b/llvm/include/llvm/Object/Wasm.h
@@ -260,6 +260,7 @@ class WasmObjectFile : public ObjectFile {
// Custom section types
Error parseDylinkSection(ReadContext &Ctx);
+ Error parseDylink0Section(ReadContext &Ctx);
Error parseNameSection(ReadContext &Ctx);
Error parseLinkingSection(ReadContext &Ctx);
Error parseLinkingSectionSymtab(ReadContext &Ctx);
diff --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h
index 661e06fba8bd6..8b827bf7f408c 100644
--- a/llvm/include/llvm/ObjectYAML/WasmYAML.h
+++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h
@@ -200,11 +200,11 @@ struct CustomSection : Section {
};
struct DylinkSection : CustomSection {
- DylinkSection() : CustomSection("dylink") {}
+ DylinkSection() : CustomSection("dylink.0") {}
static bool classof(const Section *S) {
auto C = dyn_cast<CustomSection>(S);
- return C && C->Name == "dylink";
+ return C && C->Name == "dylink.0";
}
uint32_t MemorySize;
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 9a4e246f765a1..3b1392e418edc 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -339,7 +339,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
}
Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
- // See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+ // Legacy "dylink" section support.
+ // See parseDylink0Section for the current "dylink.0" section parsing.
HasDylinkSection = true;
DylinkInfo.MemorySize = readVaruint32(Ctx);
DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
@@ -349,12 +350,58 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
while (Count--) {
DylinkInfo.Needed.push_back(readString(Ctx));
}
+
if (Ctx.Ptr != Ctx.End)
return make_error<GenericBinaryError>("dylink section ended prematurely",
object_error::parse_failed);
return Error::success();
}
+Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
+ // See
+ // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+ HasDylinkSection = true;
+
+ const uint8_t *OrigEnd = Ctx.End;
+ while (Ctx.Ptr < OrigEnd) {
+ Ctx.End = OrigEnd;
+ uint8_t Type = readUint8(Ctx);
+ uint32_t Size = readVaruint32(Ctx);
+ LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
+ << "\n");
+ Ctx.End = Ctx.Ptr + Size;
+ uint32_t Count;
+ switch (Type) {
+ case wasm::WASM_DYLINK_MEM_INFO:
+ DylinkInfo.MemorySize = readVaruint32(Ctx);
+ DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
+ DylinkInfo.TableSize = readVaruint32(Ctx);
+ DylinkInfo.TableAlignment = readVaruint32(Ctx);
+ break;
+ case wasm::WASM_DYLINK_NEEDED:
+ Count = readVaruint32(Ctx);
+ while (Count--) {
+ DylinkInfo.Needed.push_back(readString(Ctx));
+ }
+ break;
+ default:
+ return make_error<GenericBinaryError>("unknown dylink.0 sub-section",
+ object_error::parse_failed);
+ Ctx.Ptr += Size;
+ break;
+ }
+ if (Ctx.Ptr != Ctx.End) {
+ return make_error<GenericBinaryError>(
+ "dylink.0 sub-section ended prematurely", object_error::parse_failed);
+ }
+ }
+
+ if (Ctx.Ptr != Ctx.End)
+ return make_error<GenericBinaryError>("dylink.0 section ended prematurely",
+ object_error::parse_failed);
+ return Error::success();
+}
+
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
llvm::DenseSet<uint64_t> SeenFunctions;
llvm::DenseSet<uint64_t> SeenGlobals;
@@ -984,6 +1031,9 @@ Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
if (Sec.Name == "dylink") {
if (Error Err = parseDylinkSection(Ctx))
return Err;
+ } else if (Sec.Name == "dylink.0") {
+ if (Error Err = parseDylink0Section(Ctx))
+ return Err;
} else if (Sec.Name == "name") {
if (Error Err = parseNameSection(Ctx))
return Err;
@@ -1793,6 +1843,7 @@ int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
case wasm::WASM_SEC_CUSTOM:
return StringSwitch<unsigned>(CustomSectionName)
.Case("dylink", WASM_SEC_ORDER_DYLINK)
+ .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
.Case("linking", WASM_SEC_ORDER_LINKING)
.StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
.Case("name", WASM_SEC_ORDER_NAME)
diff --git a/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/lib/ObjectYAML/WasmEmitter.cpp
index 888ba115e2d94..86d4bc0504618 100644
--- a/llvm/lib/ObjectYAML/WasmEmitter.cpp
+++ b/llvm/lib/ObjectYAML/WasmEmitter.cpp
@@ -157,13 +157,24 @@ void WasmWriter::writeInitExpr(raw_ostream &OS,
void WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::DylinkSection &Section) {
writeStringRef(Section.Name, OS);
- encodeULEB128(Section.MemorySize, OS);
- encodeULEB128(Section.MemoryAlignment, OS);
- encodeULEB128(Section.TableSize, OS);
- encodeULEB128(Section.TableAlignment, OS);
- encodeULEB128(Section.Needed.size(), OS);
- for (StringRef Needed : Section.Needed)
- writeStringRef(Needed, OS);
+
+ writeUint8(OS, wasm::WASM_DYLINK_MEM_INFO);
+ SubSectionWriter SubSection(OS);
+ raw_ostream &SubOS = SubSection.getStream();
+ encodeULEB128(Section.MemorySize, SubOS);
+ encodeULEB128(Section.MemoryAlignment, SubOS);
+ encodeULEB128(Section.TableSize, SubOS);
+ encodeULEB128(Section.TableAlignment, SubOS);
+ SubSection.done();
+
+ if (Section.Needed.size()) {
+ writeUint8(OS, wasm::WASM_DYLINK_NEEDED);
+ raw_ostream &SubOS = SubSection.getStream();
+ encodeULEB128(Section.Needed.size(), SubOS);
+ for (StringRef Needed : Section.Needed)
+ writeStringRef(Needed, SubOS);
+ SubSection.done();
+ }
}
void WasmWriter::writeSectionContent(raw_ostream &OS,
diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 365f63cce9bc3..b798987e28905 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -177,7 +177,7 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
} else {
IO.mapRequired("Name", SectionName);
}
- if (SectionName == "dylink") {
+ if (SectionName == "dylink" || SectionName == "dylink.0") {
if (!IO.outputting())
Section.reset(new WasmYAML::DylinkSection());
sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
diff --git a/llvm/test/ObjectYAML/wasm/dylink_section.yaml b/llvm/test/ObjectYAML/wasm/dylink_section.yaml
index 76bb72798be38..a43f678c45194 100644
--- a/llvm/test/ObjectYAML/wasm/dylink_section.yaml
+++ b/llvm/test/ObjectYAML/wasm/dylink_section.yaml
@@ -5,7 +5,7 @@ FileHeader:
Sections:
- Type: CUSTOM
- Name: dylink
+ Name: dylink.0
MemorySize: 4
MemoryAlignment: 2
TableSize: 1
@@ -17,7 +17,7 @@ Sections:
# CHECK: Version: 0x1
# CHECK: Sections:
# CHECK: - Type: CUSTOM
-# CHECK: Name: dylink
+# CHECK: Name: dylink.0
# CHECK: MemorySize: 4
# CHECK: MemoryAlignment: 2
# CHECK: TableSize: 1
diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index 5b4f672dd4d45..9555cb2dea5be 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -51,7 +51,7 @@ static WasmYAML::Table makeTable(uint32_t Index,
std::unique_ptr<WasmYAML::CustomSection>
WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
std::unique_ptr<WasmYAML::CustomSection> CustomSec;
- if (WasmSec.Name == "dylink") {
+ if (WasmSec.Name == "dylink" || WasmSec.Name == "dylink.0") {
std::unique_ptr<WasmYAML::DylinkSection> DylinkSec =
std::make_unique<WasmYAML::DylinkSection>();
const wasm::WasmDylinkInfo& Info = Obj.dylinkInfo();
More information about the llvm-commits
mailing list