[WebAssembly] Add support for weak symbols in the binary format
This also introduces the updated format for the
"linking" section which can represent extra
symbol information. See:
https://github.com/WebAssembly/tool-conventions/pull/10
Differential Revision: https://reviews.llvm.org/D34019
llvm-svn: 305769
diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index d4d978f..ad0075c 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
+using object::WasmSection;
namespace {
@@ -22,10 +23,16 @@
public:
WasmDumper(const object::WasmObjectFile &O) : Obj(O) {}
+
ErrorOr<WasmYAML::Object *> dump();
+
+ std::unique_ptr<WasmYAML::CustomSection>
+ dumpCustomSection(const WasmSection &WasmSec);
};
-WasmYAML::Table make_table(const wasm::WasmTable &Table) {
+} // namespace
+
+static WasmYAML::Table make_table(const wasm::WasmTable &Table) {
WasmYAML::Table T;
T.ElemType = Table.ElemType;
T.TableLimits.Flags = Table.Limits.Flags;
@@ -34,7 +41,7 @@
return T;
}
-WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
+static WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
WasmYAML::Limits L;
L.Flags = Limits.Flags;
L.Initial = Limits.Initial;
@@ -42,6 +49,42 @@
return L;
}
+std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
+ std::unique_ptr<WasmYAML::CustomSection> CustomSec;
+ if (WasmSec.Name == "name") {
+ std::unique_ptr<WasmYAML::NameSection> NameSec = make_unique<WasmYAML::NameSection>();
+ for (const object::SymbolRef& Sym: Obj.symbols()) {
+ uint32_t Flags = Sym.getFlags();
+ // Skip over symbols that come from imports or exports
+ if (Flags &
+ (object::SymbolRef::SF_Global | object::SymbolRef::SF_Undefined))
+ continue;
+ Expected<StringRef> NameOrError = Sym.getName();
+ if (!NameOrError)
+ continue;
+ WasmYAML::NameEntry NameEntry;
+ NameEntry.Name = *NameOrError;
+ NameEntry.Index = Sym.getValue();
+ NameSec->FunctionNames.push_back(NameEntry);
+ }
+ CustomSec = std::move(NameSec);
+ } else if (WasmSec.Name == "linking") {
+ std::unique_ptr<WasmYAML::LinkingSection> LinkingSec = make_unique<WasmYAML::LinkingSection>();
+ for (const object::SymbolRef& Sym: Obj.symbols()) {
+ const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
+ if (Symbol.Flags != 0) {
+ WasmYAML::SymbolInfo Info = { Symbol.Name, Symbol.Flags };
+ LinkingSec->SymbolInfos.push_back(Info);
+ }
+ }
+ CustomSec = std::move(LinkingSec);
+ } else {
+ CustomSec = make_unique<WasmYAML::CustomSection>(WasmSec.Name);
+ }
+ CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
+ return CustomSec;
+}
+
ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
auto Y = make_unique<WasmYAML::Object>();
@@ -50,7 +93,7 @@
// Dump sections
for (const auto &Sec : Obj.sections()) {
- const object::WasmSection &WasmSec = Obj.getWasmSection(Sec);
+ const WasmSection &WasmSec = Obj.getWasmSection(Sec);
std::unique_ptr<WasmYAML::Section> S;
switch (WasmSec.Type) {
case wasm::WASM_SEC_CUSTOM: {
@@ -59,27 +102,7 @@
// being represented as a custom section in the YAML output.
continue;
}
- auto CustomSec = make_unique<WasmYAML::CustomSection>();
- CustomSec->Name = WasmSec.Name;
- if (CustomSec->Name == "name") {
- for (const object::SymbolRef& Sym: Obj.symbols()) {
- uint32_t Flags = Sym.getFlags();
- // Skip over symbols that come from imports or exports
- if (Flags &
- (object::SymbolRef::SF_Global | object::SymbolRef::SF_Undefined))
- continue;
- Expected<StringRef> NameOrError = Sym.getName();
- if (!NameOrError)
- continue;
- WasmYAML::NameEntry NameEntry;
- NameEntry.Name = *NameOrError;
- NameEntry.Index = Sym.getValue();
- CustomSec->FunctionNames.push_back(NameEntry);
- }
- } else {
- CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
- }
- S = std::move(CustomSec);
+ S = dumpCustomSection(WasmSec);
break;
}
case wasm::WASM_SEC_TYPE: {
@@ -237,8 +260,6 @@
return Y.release();
}
-} // namespace
-
std::error_code wasm2yaml(raw_ostream &Out, const object::WasmObjectFile &Obj) {
WasmDumper Dumper(Obj);
ErrorOr<WasmYAML::Object *> YAMLOrErr = Dumper.dump();
diff --git a/llvm/tools/yaml2obj/yaml2wasm.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp
index 5c8aba3..cf591e1 100644
--- a/llvm/tools/yaml2obj/yaml2wasm.cpp
+++ b/llvm/tools/yaml2obj/yaml2wasm.cpp
@@ -26,8 +26,9 @@
public:
WasmWriter(WasmYAML::Object &Obj) : Obj(Obj) {}
int writeWasm(raw_ostream &OS);
+
+private:
int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec);
- int writeNameSection(raw_ostream &OS, WasmYAML::CustomSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section);
@@ -42,7 +43,9 @@
int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
-private:
+ // Custom section types
+ int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
+ int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
WasmYAML::Object &Obj;
};
@@ -107,12 +110,30 @@
return 0;
}
-int WasmWriter::writeNameSection(raw_ostream &OS,
- WasmYAML::CustomSection &Section) {
+int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
+ writeStringRef(Section.Name, OS);
+ if (Section.SymbolInfos.size()) {
+ encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
+ std::string OutString;
+ raw_string_ostream StringStream(OutString);
+
+ encodeULEB128(Section.SymbolInfos.size(), StringStream);
+ for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
+ writeStringRef(Info.Name, StringStream);
+ encodeULEB128(Info.Flags, StringStream);
+ }
+
+ StringStream.flush();
+ encodeULEB128(OutString.size(), OS);
+ OS << OutString;
+ }
+ return 0;
+}
+
+int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section) {
writeStringRef(Section.Name, OS);
if (Section.FunctionNames.size()) {
encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS);
-
std::string OutString;
raw_string_ostream StringStream(OutString);
@@ -131,8 +152,12 @@
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::CustomSection &Section) {
- if (Section.Name == "name") {
- writeNameSection(OS, Section);
+ if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
+ if (auto Err = writeSectionContent(OS, *S))
+ return Err;
+ } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
+ if (auto Err = writeSectionContent(OS, *S))
+ return Err;
} else {
Section.Payload.writeAsBinary(OS);
}