Skip to content

Commit e4afbc6

Browse files
committed
[WebAssembly] Add support for dylink section in object format
See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md. Differential Revision: https://reviews.llvm.org/D54490 llvm-svn: 346880
1 parent 6c94264 commit e4afbc6

File tree

8 files changed

+103
-4
lines changed

8 files changed

+103
-4
lines changed

llvm/include/llvm/BinaryFormat/Wasm.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ struct WasmObjectHeader {
3535
uint32_t Version;
3636
};
3737

38+
struct WasmDylinkInfo {
39+
uint32_t MemorySize; // Memory size in bytes
40+
uint32_t MemoryAlignment; // P2 alignment of memory
41+
uint32_t TableSize; // Table size in elements
42+
uint32_t TableAlignment; // P2 alignment of table
43+
};
44+
3845
struct WasmExport {
3946
StringRef Name;
4047
uint8_t Kind;

llvm/include/llvm/Object/Wasm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class WasmObjectFile : public ObjectFile {
129129

130130
static bool classof(const Binary *v) { return v->isWasm(); }
131131

132+
const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
132133
ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
133134
ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
134135
ArrayRef<wasm::WasmImport> imports() const { return Imports; }
@@ -245,6 +246,7 @@ class WasmObjectFile : public ObjectFile {
245246
Error parseDataSection(ReadContext &Ctx);
246247

247248
// Custom section types
249+
Error parseDylinkSection(ReadContext &Ctx);
248250
Error parseNameSection(ReadContext &Ctx);
249251
Error parseLinkingSection(ReadContext &Ctx);
250252
Error parseLinkingSectionSymtab(ReadContext &Ctx);
@@ -253,6 +255,7 @@ class WasmObjectFile : public ObjectFile {
253255

254256
wasm::WasmObjectHeader Header;
255257
std::vector<WasmSection> Sections;
258+
wasm::WasmDylinkInfo DylinkInfo;
256259
std::vector<wasm::WasmSignature> Signatures;
257260
std::vector<uint32_t> FunctionTypes;
258261
std::vector<wasm::WasmTable> Tables;

llvm/include/llvm/ObjectYAML/WasmYAML.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ struct CustomSection : Section {
183183
yaml::BinaryRef Payload;
184184
};
185185

186+
struct DylinkSection : CustomSection {
187+
DylinkSection() : CustomSection("dylink") {}
188+
189+
static bool classof(const Section *S) {
190+
auto C = dyn_cast<CustomSection>(S);
191+
return C && C->Name == "dylink";
192+
}
193+
194+
uint32_t MemorySize;
195+
uint32_t MemoryAlignment;
196+
uint32_t TableSize;
197+
uint32_t TableAlignment;
198+
};
199+
186200
struct NameSection : CustomSection {
187201
NameSection() : CustomSection("name") {}
188202

llvm/lib/Object/WasmObjectFile.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,18 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
313313
}
314314
}
315315

316+
Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
317+
// See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
318+
DylinkInfo.MemorySize = readVaruint32(Ctx);
319+
DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
320+
DylinkInfo.TableSize = readVaruint32(Ctx);
321+
DylinkInfo.TableAlignment = readVaruint32(Ctx);
322+
if (Ctx.Ptr != Ctx.End)
323+
return make_error<GenericBinaryError>("dylink section ended prematurely",
324+
object_error::parse_failed);
325+
return Error::success();
326+
}
327+
316328
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
317329
llvm::DenseSet<uint64_t> Seen;
318330
if (Functions.size() != FunctionTypes.size()) {
@@ -721,7 +733,10 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
721733
}
722734

723735
Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
724-
if (Sec.Name == "name") {
736+
if (Sec.Name == "dylink") {
737+
if (Error Err = parseDylinkSection(Ctx))
738+
return Err;
739+
} else if (Sec.Name == "name") {
725740
if (Error Err = parseNameSection(Ctx))
726741
return Err;
727742
} else if (Sec.Name == "linking") {

llvm/lib/ObjectYAML/WasmYAML.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) {
4848
IO.mapOptional("Relocations", Section.Relocations);
4949
}
5050

51+
static void sectionMapping(IO &IO, WasmYAML::DylinkSection &Section) {
52+
commonSectionMapping(IO, Section);
53+
IO.mapRequired("Name", Section.Name);
54+
IO.mapRequired("MemorySize", Section.MemorySize);
55+
IO.mapRequired("MemoryAlignment", Section.MemoryAlignment);
56+
IO.mapRequired("TableSize", Section.TableSize);
57+
IO.mapRequired("TableAlignment", Section.TableAlignment);
58+
}
59+
5160
static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
5261
commonSectionMapping(IO, Section);
5362
IO.mapRequired("Name", Section.Name);
@@ -147,7 +156,11 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
147156
} else {
148157
IO.mapRequired("Name", SectionName);
149158
}
150-
if (SectionName == "linking") {
159+
if (SectionName == "dylink") {
160+
if (!IO.outputting())
161+
Section.reset(new WasmYAML::DylinkSection());
162+
sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
163+
} else if (SectionName == "linking") {
151164
if (!IO.outputting())
152165
Section.reset(new WasmYAML::LinkingSection());
153166
sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
2+
--- !WASM
3+
FileHeader:
4+
Version: 0x00000001
5+
6+
Sections:
7+
- Type: CUSTOM
8+
Name: dylink
9+
MemorySize: 4
10+
MemoryAlignment: 2
11+
TableSize: 1
12+
TableAlignment: 0
13+
...
14+
# CHECK: --- !WASM
15+
# CHECK: FileHeader:
16+
# CHECK: Version: 0x00000001
17+
# CHECK: Sections:
18+
# CHECK: - Type: CUSTOM
19+
# CHECK: Name: dylink
20+
# CHECK: MemorySize: 4
21+
# CHECK: MemoryAlignment: 2
22+
# CHECK: TableSize: 1
23+
# CHECK: TableAlignment: 0
24+
# CHECK: ...

llvm/tools/obj2yaml/wasm2yaml.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,16 @@ static WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
5252
std::unique_ptr<WasmYAML::CustomSection>
5353
WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
5454
std::unique_ptr<WasmYAML::CustomSection> CustomSec;
55-
if (WasmSec.Name == "name") {
55+
if (WasmSec.Name == "dylink") {
56+
std::unique_ptr<WasmYAML::DylinkSection> DylinkSec =
57+
make_unique<WasmYAML::DylinkSection>();
58+
const wasm::WasmDylinkInfo& Info = Obj.dylinkInfo();
59+
DylinkSec->MemorySize = Info.MemorySize;
60+
DylinkSec->MemoryAlignment = Info.MemoryAlignment;
61+
DylinkSec->TableSize = Info.TableSize;
62+
DylinkSec->TableAlignment = Info.TableAlignment;
63+
CustomSec = std::move(DylinkSec);
64+
} else if (WasmSec.Name == "name") {
5665
std::unique_ptr<WasmYAML::NameSection> NameSec =
5766
make_unique<WasmYAML::NameSection>();
5867
for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) {

llvm/tools/yaml2obj/yaml2wasm.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class WasmWriter {
4545
int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
4646

4747
// Custom section types
48+
int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
4849
int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
4950
int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
5051
WasmYAML::Object &Obj;
@@ -132,6 +133,16 @@ class SubSectionWriter {
132133
raw_ostream &GetStream() { return StringStream; }
133134
};
134135

136+
int WasmWriter::writeSectionContent(raw_ostream &OS,
137+
WasmYAML::DylinkSection &Section) {
138+
writeStringRef(Section.Name, OS);
139+
encodeULEB128(Section.MemorySize, OS);
140+
encodeULEB128(Section.MemoryAlignment, OS);
141+
encodeULEB128(Section.TableSize, OS);
142+
encodeULEB128(Section.TableAlignment, OS);
143+
return 0;
144+
}
145+
135146
int WasmWriter::writeSectionContent(raw_ostream &OS,
136147
WasmYAML::LinkingSection &Section) {
137148
writeStringRef(Section.Name, OS);
@@ -241,7 +252,10 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
241252

242253
int WasmWriter::writeSectionContent(raw_ostream &OS,
243254
WasmYAML::CustomSection &Section) {
244-
if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
255+
if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) {
256+
if (auto Err = writeSectionContent(OS, *S))
257+
return Err;
258+
} else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
245259
if (auto Err = writeSectionContent(OS, *S))
246260
return Err;
247261
} else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {

0 commit comments

Comments
 (0)