[llvm] r305769 - [WebAssembly] Add support for weak symbols in the binary format
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 21:05:00 PDT 2017
Author: sbc
Date: Mon Jun 19 23:04:59 2017
New Revision: 305769
URL: http://llvm.org/viewvc/llvm-project?rev=305769&view=rev
Log:
[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
Added:
llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml
llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml
Modified:
llvm/trunk/include/llvm/BinaryFormat/Wasm.h
llvm/trunk/include/llvm/MC/MCSymbolWasm.h
llvm/trunk/include/llvm/Object/Wasm.h
llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
llvm/trunk/lib/MC/MCWasmStreamer.cpp
llvm/trunk/lib/MC/WasmObjectWriter.cpp
llvm/trunk/lib/Object/WasmObjectFile.cpp
llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml
llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
llvm/trunk/tools/yaml2obj/yaml2wasm.cpp
Modified: llvm/trunk/include/llvm/BinaryFormat/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Wasm.h?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Wasm.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h Mon Jun 19 23:04:59 2017
@@ -176,6 +176,11 @@ enum class ValType {
// Linking metadata kinds.
enum : unsigned {
WASM_STACK_POINTER = 0x1,
+ WASM_SYMBOL_INFO = 0x2,
+};
+
+enum : unsigned {
+ WASM_SYMBOL_FLAG_WEAK = 0x1,
};
#define WASM_RELOC(name, value) name = value,
Modified: llvm/trunk/include/llvm/MC/MCSymbolWasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbolWasm.h?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbolWasm.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbolWasm.h Mon Jun 19 23:04:59 2017
@@ -17,6 +17,7 @@ namespace llvm {
class MCSymbolWasm : public MCSymbol {
private:
bool IsFunction = false;
+ bool IsWeak = false;
std::string ModuleName;
SmallVector<wasm::ValType, 1> Returns;
SmallVector<wasm::ValType, 4> Params;
@@ -39,6 +40,9 @@ public:
bool isFunction() const { return IsFunction; }
void setIsFunction(bool isFunc) { IsFunction = isFunc; }
+ bool isWeak() const { return IsWeak; }
+ void setWeak(bool isWeak) { IsWeak = isWeak; }
+
const StringRef getModuleName() const { return ModuleName; }
const SmallVector<wasm::ValType, 1> &getReturns() const { return Returns; }
Modified: llvm/trunk/include/llvm/Object/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Wasm.h?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Wasm.h (original)
+++ llvm/trunk/include/llvm/Object/Wasm.h Mon Jun 19 23:04:59 2017
@@ -19,6 +19,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
@@ -48,7 +49,24 @@ public:
StringRef Name;
SymbolType Type;
uint32_t Section;
+ uint32_t Flags = 0;
+
+ // Index into the imports, exports or functions array of the object depending
+ // on the type
uint32_t ElementIndex;
+
+ bool isWeak() const {
+ return Flags & wasm::WASM_SYMBOL_FLAG_WEAK;
+ }
+
+ void print(raw_ostream &Out) const {
+ Out << "Name=" << Name << ", Type=" << static_cast<int>(Type)
+ << ", Flags=" << Flags;
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
+#endif
};
class WasmSection {
@@ -63,6 +81,7 @@ public:
};
class WasmObjectFile : public ObjectFile {
+
public:
WasmObjectFile(MemoryBufferRef Object, Error &Err);
@@ -176,6 +195,7 @@ private:
// Custom section types
Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End);
Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
const uint8_t *End);
@@ -190,13 +210,22 @@ private:
std::vector<wasm::WasmExport> Exports;
std::vector<wasm::WasmElemSegment> ElemSegments;
std::vector<wasm::WasmDataSegment> DataSegments;
- std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmFunction> Functions;
+ std::vector<WasmSymbol> Symbols;
ArrayRef<uint8_t> CodeSection;
uint32_t StartFunction = -1;
+
+ StringMap<uint32_t> SymbolMap;
};
} // end namespace object
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const object::WasmSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+}
+
} // end namespace llvm
#endif // LLVM_OBJECT_WASM_H
Modified: llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h Mon Jun 19 23:04:59 2017
@@ -112,8 +112,13 @@ struct Signature {
ValueType ReturnType;
};
+struct SymbolInfo {
+ StringRef Name;
+ uint32_t Flags;
+};
+
struct Section {
- Section(SectionType SecType) : Type(SecType) {}
+ explicit Section(SectionType SecType) : Type(SecType) {}
virtual ~Section();
SectionType Type;
@@ -121,20 +126,36 @@ struct Section {
};
struct CustomSection : Section {
- CustomSection() : Section(wasm::WASM_SEC_CUSTOM) {}
+ explicit CustomSection(StringRef Name)
+ : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
static bool classof(const Section *S) {
return S->Type == wasm::WASM_SEC_CUSTOM;
}
StringRef Name;
yaml::BinaryRef Payload;
+};
+
+struct NameSection : CustomSection {
+ NameSection() : CustomSection("name") {}
+ static bool classof(const Section *S) {
+ auto C = dyn_cast<CustomSection>(S);
+ return C && C->Name == "name";
+ }
- // The follow is used by the "name" custom section.
- // TODO(sbc): Add support for more then just functions names. The wasm
- // name section can support multiple sub-sections.
std::vector<NameEntry> FunctionNames;
};
+struct LinkingSection : CustomSection {
+ LinkingSection() : CustomSection("linking") {}
+ static bool classof(const Section *S) {
+ auto C = dyn_cast<CustomSection>(S);
+ return C && C->Name == "linking";
+ }
+
+ std::vector<SymbolInfo> SymbolInfos;
+};
+
struct TypeSection : Section {
TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
static bool classof(const Section *S) {
@@ -256,6 +277,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmY
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
namespace llvm {
@@ -329,6 +351,10 @@ template <> struct MappingTraits<WasmYAM
static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
};
+template <> struct MappingTraits<WasmYAML::SymbolInfo> {
+ static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
+};
+
template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
static void enumeration(IO &IO, WasmYAML::ValueType &Type);
};
Modified: llvm/trunk/lib/MC/MCWasmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWasmStreamer.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWasmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCWasmStreamer.cpp Mon Jun 19 23:04:59 2017
@@ -98,18 +98,30 @@ bool MCWasmStreamer::EmitSymbolAttribute
case MCSA_WeakDefAutoPrivate:
case MCSA_Invalid:
case MCSA_IndirectSymbol:
+ case MCSA_Hidden:
return false;
+
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ Symbol->setWeak(true);
+ Symbol->setExternal(true);
+ break;
+
case MCSA_Global:
Symbol->setExternal(true);
break;
+
case MCSA_ELF_TypeFunction:
Symbol->setIsFunction(true);
break;
+
case MCSA_ELF_TypeObject:
Symbol->setIsFunction(false);
break;
+
default:
// unrecognized directive
+ llvm_unreachable("unexpected MCSymbolAttr");
return false;
}
Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Mon Jun 19 23:04:59 2017
@@ -156,9 +156,18 @@ struct WasmRelocationEntry {
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend
<< ", Type=" << Type << ", FixupSection=" << FixupSection;
}
- void dump() const { print(errs()); }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
+#endif
};
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const WasmRelocationEntry &Rel) {
+ Rel.print(OS);
+ return OS;
+}
+
class WasmObjectWriter : public MCObjectWriter {
/// Helper struct for containing some precomputed information on symbols.
struct WasmSymbolData {
@@ -229,6 +238,11 @@ private:
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+ void writeString(const StringRef Str) {
+ encodeULEB128(Str.size(), getStream());
+ writeBytes(Str);
+ }
+
void writeValueType(wasm::ValType Ty) {
encodeSLEB128(int32_t(Ty), getStream());
}
@@ -250,7 +264,8 @@ private:
uint32_t NumFuncImports);
void writeCodeRelocSection();
void writeDataRelocSection(uint64_t DataSectionHeaderSize);
- void writeLinkingMetaDataSection(bool HasStackPointer,
+ void writeLinkingMetaDataSection(ArrayRef<StringRef> WeakSymbols,
+ bool HasStackPointer,
uint32_t StackPointerGlobal);
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
@@ -282,6 +297,7 @@ void WasmObjectWriter::startSection(Sect
assert((Name != nullptr) == (SectionId == wasm::WASM_SEC_CUSTOM) &&
"Only custom sections can have names");
+ DEBUG(dbgs() << "startSection " << SectionId << ": " << Name << "\n");
encodeULEB128(SectionId, getStream());
Section.SizeOffset = getStream().tell();
@@ -295,8 +311,8 @@ void WasmObjectWriter::startSection(Sect
// Custom sections in wasm also have a string identifier.
if (SectionId == wasm::WASM_SEC_CUSTOM) {
- encodeULEB128(strlen(Name), getStream());
- writeBytes(Name);
+ assert(Name);
+ writeString(StringRef(Name));
}
}
@@ -307,6 +323,7 @@ void WasmObjectWriter::endSection(Sectio
if (uint32_t(Size) != Size)
report_fatal_error("section size does not fit in a uint32_t");
+ DEBUG(dbgs() << "endSection size=" << Size << "\n");
unsigned Padding = PaddingFor5ByteULEB128(Size);
// Write the final section size to the payload_len field, which follows
@@ -411,6 +428,7 @@ void WasmObjectWriter::recordRelocation(
unsigned Type = getRelocType(Target, Fixup);
WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
+ DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");
if (FixupSection.hasInstructions())
CodeRelocations.push_back(Rec);
@@ -455,7 +473,7 @@ static uint32_t ProvisionalValue(const W
const MCSymbolWasm *Sym = RelEntry.Symbol;
// For undefined symbols, use a hopefully invalid value.
- if (!Sym->isDefined(false))
+ if (!Sym->isDefined(/*SetUsed=*/false))
return UINT32_MAX;
MCSectionWasm &Section =
@@ -473,17 +491,23 @@ uint32_t WasmObjectWriter::getRelocation
switch (RelEntry.Type) {
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
- assert(IndirectSymbolIndices.count(RelEntry.Symbol));
+ if (!IndirectSymbolIndices.count(RelEntry.Symbol))
+ report_fatal_error("symbol not found table index space:" +
+ RelEntry.Symbol->getName());
return IndirectSymbolIndices[RelEntry.Symbol];
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
- assert(SymbolIndices.count(RelEntry.Symbol));
+ if (!SymbolIndices.count(RelEntry.Symbol))
+ report_fatal_error("symbol not found function/global index space:" +
+ RelEntry.Symbol->getName());
return SymbolIndices[RelEntry.Symbol];
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
- assert(TypeIndices.count(RelEntry.Symbol));
+ if (!TypeIndices.count(RelEntry.Symbol))
+ report_fatal_error("symbol not found in type index space:" +
+ RelEntry.Symbol->getName());
return TypeIndices[RelEntry.Symbol];
default:
llvm_unreachable("invalid relocation type");
@@ -500,6 +524,7 @@ void WasmObjectWriter::applyRelocations(
RelEntry.FixupSection->getSectionOffset() +
RelEntry.Offset;
+ DEBUG(dbgs() << "applyRelocation: " << RelEntry << "\n");
switch (RelEntry.Type) {
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
@@ -577,6 +602,7 @@ void WasmObjectWriter::writeTypeSection(
endSection(Section);
}
+
void WasmObjectWriter::writeImportSection(
const SmallVector<WasmImport, 4> &Imports) {
if (Imports.empty())
@@ -587,13 +613,8 @@ void WasmObjectWriter::writeImportSectio
encodeULEB128(Imports.size(), getStream());
for (const WasmImport &Import : Imports) {
- StringRef ModuleName = Import.ModuleName;
- encodeULEB128(ModuleName.size(), getStream());
- writeBytes(ModuleName);
-
- StringRef FieldName = Import.FieldName;
- encodeULEB128(FieldName.size(), getStream());
- writeBytes(FieldName);
+ writeString(Import.ModuleName);
+ writeString(Import.FieldName);
encodeULEB128(Import.Kind, getStream());
@@ -701,11 +722,8 @@ void WasmObjectWriter::writeExportSectio
encodeULEB128(Exports.size(), getStream());
for (const WasmExport &Export : Exports) {
- encodeULEB128(Export.FieldName.size(), getStream());
- writeBytes(Export.FieldName);
-
+ writeString(Export.FieldName);
encodeSLEB128(Export.Kind, getStream());
-
encodeULEB128(Export.Index, getStream());
}
@@ -750,15 +768,6 @@ void WasmObjectWriter::writeCodeSection(
MCSectionWasm &FuncSection =
static_cast<MCSectionWasm &>(Func.Sym->getSection());
- if (Func.Sym->isVariable())
- report_fatal_error("weak symbols not supported yet");
-
- if (Func.Sym->getOffset() != 0)
- report_fatal_error("function sections must contain one function each");
-
- if (!Func.Sym->getSize())
- report_fatal_error("function symbols must have a size set with .size");
-
int64_t Size = 0;
if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
report_fatal_error(".size expression must be evaluatable");
@@ -819,15 +828,13 @@ void WasmObjectWriter::writeNameSection(
for (const WasmImport &Import : Imports) {
if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
encodeULEB128(Index, getStream());
- encodeULEB128(Import.FieldName.size(), getStream());
- writeBytes(Import.FieldName);
+ writeString(Import.FieldName);
++Index;
}
}
for (const WasmFunction &Func : Functions) {
encodeULEB128(Index, getStream());
- encodeULEB128(Func.Sym->getName().size(), getStream());
- writeBytes(Func.Sym->getName());
+ writeString(Func.Sym->getName());
++Index;
}
@@ -872,22 +879,37 @@ void WasmObjectWriter::writeDataRelocSec
}
void WasmObjectWriter::writeLinkingMetaDataSection(
- bool HasStackPointer, uint32_t StackPointerGlobal) {
- if (!HasStackPointer)
+ ArrayRef<StringRef> WeakSymbols, bool HasStackPointer,
+ uint32_t StackPointerGlobal) {
+ if (!HasStackPointer && WeakSymbols.empty())
return;
+
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
+ SectionBookkeeping SubSection;
- encodeULEB128(1, getStream()); // count
+ if (HasStackPointer) {
+ startSection(SubSection, wasm::WASM_STACK_POINTER);
+ encodeULEB128(StackPointerGlobal, getStream()); // id
+ endSection(SubSection);
+ }
- encodeULEB128(wasm::WASM_STACK_POINTER, getStream()); // type
- encodeULEB128(StackPointerGlobal, getStream()); // id
+ if (WeakSymbols.size() != 0) {
+ startSection(SubSection, wasm::WASM_SYMBOL_INFO);
+ encodeULEB128(WeakSymbols.size(), getStream());
+ for (const StringRef Export: WeakSymbols) {
+ writeString(Export);
+ encodeULEB128(wasm::WASM_SYMBOL_FLAG_WEAK, getStream());
+ }
+ endSection(SubSection);
+ }
endSection(Section);
}
void WasmObjectWriter::writeObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
+ DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
MCContext &Ctx = Asm.getContext();
wasm::ValType PtrType = is64Bit() ? wasm::ValType::I64 : wasm::ValType::I32;
@@ -898,6 +920,7 @@ void WasmObjectWriter::writeObject(MCAss
SmallVector<WasmGlobal, 4> Globals;
SmallVector<WasmImport, 4> Imports;
SmallVector<WasmExport, 4> Exports;
+ SmallVector<StringRef, 4> WeakSymbols;
SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
unsigned NumFuncImports = 0;
unsigned NumGlobalImports = 0;
@@ -906,7 +929,7 @@ void WasmObjectWriter::writeObject(MCAss
bool HasStackPointer = false;
// Populate the IsAddressTaken set.
- for (WasmRelocationEntry RelEntry : CodeRelocations) {
+ for (const WasmRelocationEntry &RelEntry : CodeRelocations) {
switch (RelEntry.Type) {
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
@@ -916,7 +939,7 @@ void WasmObjectWriter::writeObject(MCAss
break;
}
}
- for (WasmRelocationEntry RelEntry : DataRelocations) {
+ for (const WasmRelocationEntry &RelEntry : DataRelocations) {
switch (RelEntry.Type) {
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
@@ -1045,14 +1068,32 @@ void WasmObjectWriter::writeObject(MCAss
StackPointerGlobal = NumGlobalImports + *(const int32_t *)Contents.data();
}
- // Handle defined symbols.
+ // Handle regular defined and undefined symbols.
for (const MCSymbol &S : Asm.symbols()) {
// Ignore unnamed temporary symbols, which aren't ever exported, imported,
// or used in relocations.
if (S.isTemporary() && S.getName().empty())
continue;
+
+ // Variable references (weak references) are handled in a second pass
+ if (S.isVariable())
+ continue;
+
const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ DEBUG(dbgs() << "MCSymbol: '" << S << "'"
+ << " isDefined=" << S.isDefined() << " isExternal="
+ << S.isExternal() << " isTemporary=" << S.isTemporary()
+ << " isFunction=" << WS.isFunction()
+ << " isWeak=" << WS.isWeak()
+ << " isVariable=" << WS.isVariable() << "\n");
+
+ if (WS.isWeak())
+ WeakSymbols.push_back(WS.getName());
+
unsigned Index;
+
+ //<< " function=" << S.isFunction()
+
if (WS.isFunction()) {
// Prepare the function's type, if we haven't seen it yet.
WasmFunctionType F;
@@ -1066,6 +1107,14 @@ void WasmObjectWriter::writeObject(MCAss
int32_t Type = Pair.first->second;
if (WS.isDefined(/*SetUsed=*/false)) {
+ if (WS.getOffset() != 0)
+ report_fatal_error(
+ "function sections must contain one function each");
+
+ if (WS.getSize() == 0)
+ report_fatal_error(
+ "function symbols must have a size set with .size");
+
// A definition. Take the next available index.
Index = NumFuncImports + Functions.size();
@@ -1076,6 +1125,9 @@ void WasmObjectWriter::writeObject(MCAss
SymbolIndices[&WS] = Index;
Functions.push_back(Func);
} else {
+ // Should be no such thing as weak undefined symbol
+ assert(!WS.isVariable());
+
// An import; the index was assigned above.
Index = SymbolIndices.find(&WS)->second;
}
@@ -1089,7 +1141,7 @@ void WasmObjectWriter::writeObject(MCAss
if (WS.isTemporary() && !WS.getSize())
continue;
- if (WS.isDefined(false)) {
+ if (WS.isDefined(/*SetUsed=*/false)) {
if (WS.getOffset() != 0)
report_fatal_error("data sections must contain one variable each: " +
WS.getName());
@@ -1154,21 +1206,46 @@ void WasmObjectWriter::writeObject(MCAss
}
// If the symbol is visible outside this translation unit, export it.
- if (WS.isExternal()) {
- assert(WS.isDefined(false));
+ if (WS.isExternal() && WS.isDefined(/*SetUsed=*/false)) {
WasmExport Export;
Export.FieldName = WS.getName();
Export.Index = Index;
-
if (WS.isFunction())
Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
else
Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
-
Exports.push_back(Export);
}
}
+ // Handle weak aliases
+ for (const MCSymbol &S : Asm.symbols()) {
+ if (!S.isVariable())
+ continue;
+ assert(S.isExternal());
+ assert(S.isDefined(/*SetUsed=*/false));
+
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+
+ // Find the target symbol of this weak alias
+ const MCExpr *Expr = WS.getVariableValue();
+ auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
+ const MCSymbolWasm *ResolvedSym = cast<MCSymbolWasm>(&Inner->getSymbol());
+ uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
+ DEBUG(dbgs() << "Weak alias: '" << WS << "' -> '" << ResolvedSym << "' = " << Index << "\n");
+ SymbolIndices[&WS] = Index;
+
+ WasmExport Export;
+ Export.FieldName = WS.getName();
+ Export.Index = Index;
+ if (WS.isFunction())
+ Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
+ else
+ Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+ WeakSymbols.push_back(Export.FieldName);
+ Exports.push_back(Export);
+ }
+
// Add types for indirect function calls.
for (const WasmRelocationEntry &Fixup : CodeRelocations) {
if (Fixup.Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
@@ -1202,7 +1279,7 @@ void WasmObjectWriter::writeObject(MCAss
writeNameSection(Functions, Imports, NumFuncImports);
writeCodeRelocSection();
writeDataRelocSection(DataSectionHeaderSize);
- writeLinkingMetaDataSection(HasStackPointer, StackPointerGlobal);
+ writeLinkingMetaDataSection(WeakSymbols, HasStackPointer, StackPointerGlobal);
// TODO: Translate the .comment section to the output.
// TODO: Translate debug sections to the output.
Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Mon Jun 19 23:04:59 2017
@@ -28,6 +28,8 @@
#include <cstring>
#include <system_error>
+#define DEBUG_TYPE "wasm-object"
+
using namespace llvm;
using namespace object;
@@ -256,6 +258,7 @@ Error WasmObjectFile::parseNameSection(c
while (Ptr < End) {
uint8_t Type = readVarint7(Ptr);
uint32_t Size = readVaruint32(Ptr);
+ const uint8_t *SubSectionEnd = Ptr + Size;
switch (Type) {
case wasm::WASM_NAMES_FUNCTION: {
uint32_t Count = readVaruint32(Ptr);
@@ -275,6 +278,9 @@ Error WasmObjectFile::parseNameSection(c
Ptr += Size;
break;
}
+ if (Ptr != SubSectionEnd)
+ return make_error<GenericBinaryError>("Name sub-section ended prematurely",
+ object_error::parse_failed);
}
if (Ptr != End)
@@ -283,6 +289,50 @@ Error WasmObjectFile::parseNameSection(c
return Error::success();
}
+Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
+ const uint8_t *End) {
+ while (Ptr < End) {
+ uint8_t Type = readVarint7(Ptr);
+ uint32_t Size = readVaruint32(Ptr);
+ const uint8_t *SubSectionEnd = Ptr + Size;
+ switch (Type) {
+ case wasm::WASM_SYMBOL_INFO: {
+ uint32_t Count = readVaruint32(Ptr);
+ while (Count--) {
+ StringRef Symbol = readString(Ptr);
+ DEBUG(dbgs() << "reading syminfo: " << Symbol << "\n");
+ uint32_t Flags = readVaruint32(Ptr);
+ auto iter = SymbolMap.find(Symbol);
+ if (iter == SymbolMap.end()) {
+ return make_error<GenericBinaryError>(
+ "Invalid symbol name in linking section",
+ object_error::parse_failed);
+ }
+ uint32_t SymIndex = iter->second;
+ assert(SymIndex < Symbols.size());
+ Symbols[SymIndex].Flags = Flags;
+ DEBUG(dbgs() << "Set symbol flags index:"
+ << SymIndex << " name:"
+ << Symbols[SymIndex].Name << " exptected:"
+ << Symbol << " flags: " << Flags << "\n");
+ }
+ break;
+ }
+ case wasm::WASM_STACK_POINTER:
+ default:
+ Ptr += Size;
+ break;
+ }
+ if (Ptr != SubSectionEnd)
+ return make_error<GenericBinaryError>(
+ "Linking sub-section ended prematurely", object_error::parse_failed);
+ }
+ if (Ptr != End)
+ return make_error<GenericBinaryError>("Linking section ended prematurely",
+ object_error::parse_failed);
+ return Error::success();
+}
+
WasmSection* WasmObjectFile::findCustomSectionByName(StringRef Name) {
for (WasmSection& Section : Sections) {
if (Section.Type == wasm::WASM_SEC_CUSTOM && Section.Name == Name)
@@ -351,6 +401,9 @@ Error WasmObjectFile::parseCustomSection
if (Sec.Name == "name") {
if (Error Err = parseNameSection(Ptr, End))
return Err;
+ } else if (Sec.Name == "linking") {
+ if (Error Err = parseLinkingSection(Ptr, End))
+ return Err;
} else if (Sec.Name.startswith("reloc.")) {
if (Error Err = parseRelocSection(Sec.Name, Ptr, End))
return Err;
@@ -402,14 +455,20 @@ Error WasmObjectFile::parseImportSection
switch (Im.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
Im.SigIndex = readVaruint32(Ptr);
+ SymbolMap.try_emplace(Im.Field, Symbols.size());
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT,
Sections.size(), i);
+ DEBUG(dbgs() << "Adding import: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_GLOBAL:
Im.Global.Type = readVarint7(Ptr);
Im.Global.Mutable = readVaruint1(Ptr);
+ SymbolMap.try_emplace(Im.Field, Symbols.size());
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
Sections.size(), i);
+ DEBUG(dbgs() << "Adding import: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_MEMORY:
Im.Memory = readLimits(Ptr);
@@ -498,15 +557,20 @@ Error WasmObjectFile::parseExportSection
Ex.Name = readString(Ptr);
Ex.Kind = readUint8(Ptr);
Ex.Index = readVaruint32(Ptr);
- Exports.push_back(Ex);
switch (Ex.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
+ SymbolMap.try_emplace(Ex.Name, Symbols.size());
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::FUNCTION_EXPORT,
Sections.size(), i);
+ DEBUG(dbgs() << "Adding export: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_GLOBAL:
+ SymbolMap.try_emplace(Ex.Name, Symbols.size());
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::GLOBAL_EXPORT,
Sections.size(), i);
+ DEBUG(dbgs() << "Adding export: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_MEMORY:
case wasm::WASM_EXTERNAL_TABLE:
@@ -515,6 +579,7 @@ Error WasmObjectFile::parseExportSection
return make_error<GenericBinaryError>(
"Unexpected export kind", object_error::parse_failed);
}
+ Exports.push_back(Ex);
}
if (Ptr != End)
return make_error<GenericBinaryError>("Export section ended prematurely",
@@ -622,6 +687,10 @@ uint32_t WasmObjectFile::getSymbolFlags(
uint32_t Result = SymbolRef::SF_None;
const WasmSymbol &Sym = getWasmSymbol(Symb);
+ DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
+ if (Sym.Flags & wasm::WASM_SYMBOL_FLAG_WEAK)
+ Result |= SymbolRef::SF_Weak;
+
switch (Sym.Type) {
case WasmSymbol::SymbolType::FUNCTION_IMPORT:
Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
@@ -631,6 +700,7 @@ uint32_t WasmObjectFile::getSymbolFlags(
break;
case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
Result |= SymbolRef::SF_Executable;
+ Result |= SymbolRef::SF_FormatSpecific;
break;
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
Result |= SymbolRef::SF_Undefined;
@@ -664,8 +734,7 @@ const WasmSymbol &WasmObjectFile::getWas
}
Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
- const WasmSymbol &Sym = getWasmSymbol(Symb);
- return Sym.Name;
+ return getWasmSymbol(Symb).Name;
}
Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
@@ -673,8 +742,17 @@ Expected<uint64_t> WasmObjectFile::getSy
}
uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- const WasmSymbol &Sym = getWasmSymbol(Symb);
- return Sym.ElementIndex;
+ const WasmSymbol& Sym = getWasmSymbol(Symb);
+ switch (Sym.Type) {
+ case WasmSymbol::SymbolType::FUNCTION_IMPORT:
+ case WasmSymbol::SymbolType::GLOBAL_IMPORT:
+ return 0;
+ case WasmSymbol::SymbolType::FUNCTION_EXPORT:
+ case WasmSymbol::SymbolType::GLOBAL_EXPORT:
+ return Exports[Sym.ElementIndex].Index;
+ case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
+ return Sym.ElementIndex;
+ }
}
uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
Modified: llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/WasmYAML.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/WasmYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/WasmYAML.cpp Mon Jun 19 23:04:59 2017
@@ -47,14 +47,22 @@ static void commonSectionMapping(IO &IO,
IO.mapOptional("Relocations", Section.Relocations);
}
+static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapOptional("FunctionNames", Section.FunctionNames);
+}
+
+static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapRequired("SymbolInfo", Section.SymbolInfos);
+}
+
static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
- if (Section.Name == "name") {
- IO.mapOptional("FunctionNames", Section.FunctionNames);
- } else {
- IO.mapRequired("Payload", Section.Payload);
- }
+ IO.mapRequired("Payload", Section.Payload);
}
static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) {
@@ -121,11 +129,29 @@ void MappingTraits<std::unique_ptr<WasmY
IO.mapRequired("Type", SectionType);
switch (SectionType) {
- case wasm::WASM_SEC_CUSTOM:
- if (!IO.outputting())
- Section.reset(new WasmYAML::CustomSection());
- sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get()));
+ case wasm::WASM_SEC_CUSTOM: {
+ StringRef SectionName;
+ if (IO.outputting()) {
+ auto CustomSection = cast<WasmYAML::CustomSection>(Section.get());
+ SectionName = CustomSection->Name;
+ } else {
+ IO.mapRequired("Name", SectionName);
+ }
+ if (SectionName == "linking") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::LinkingSection());
+ sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
+ } else if (SectionName == "name") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::NameSection());
+ sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
+ } else {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::CustomSection(SectionName));
+ sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get()));
+ }
break;
+ }
case wasm::WASM_SEC_TYPE:
if (!IO.outputting())
Section.reset(new WasmYAML::TypeSection());
@@ -321,6 +347,12 @@ void MappingTraits<WasmYAML::DataSegment
IO.mapRequired("Content", Segment.Content);
}
+void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
+ WasmYAML::SymbolInfo &Info) {
+ IO.mapRequired("Name", Info.Name);
+ IO.mapRequired("Flags", Info.Flags);
+}
+
void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
IO &IO, WasmYAML::ValueType &Type) {
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
Added: llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml?rev=305769&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml (added)
+++ llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml Mon Jun 19 23:04:59 2017
@@ -0,0 +1,40 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+--- !WASM
+FileHeader:
+ Version: 0x00000001
+Sections:
+ - Type: EXPORT
+ Exports:
+ - Name: function_export
+ Kind: FUNCTION
+ Index: 1
+ - Name: global_export
+ Kind: GLOBAL
+ Index: 2
+ - Type: CUSTOM
+ Name: linking
+ SymbolInfo:
+ - Name: function_export
+ Flags: 1
+ - Name: global_export
+ Flags: 1
+...
+# CHECK: --- !WASM
+# CHECK: FileHeader:
+# CHECK: Version: 0x00000001
+# CHECK: Sections:
+# CHECK: - Type: EXPORT
+# CHECK: Exports:
+# CHECK: - Name: function_export
+# CHECK: Kind: FUNCTION
+# CHECK: Index: 1
+# CHECK: - Name: global_export
+# CHECK: Kind: GLOBAL
+# CHECK: Index: 2
+# CHECK: - Type: CUSTOM
+# CHECK: Name: linking
+# CHECK: SymbolInfo:
+# CHECK: - Name: function_export
+# CHECK: Flags: 1
+# CHECK: - Name: global_export
+# CHECK: Flags: 1
Modified: llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml (original)
+++ llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml Mon Jun 19 23:04:59 2017
@@ -1,5 +1,8 @@
# RUN: yaml2obj < %s | llvm-nm - | FileCheck %s
+# That wasm exports of functions and globals are displayed as global data and
+# code symbols.
+
--- !WASM
FileHeader:
Version: 0x00000001
@@ -13,10 +16,10 @@ Sections:
Exports:
- Name: foo
Kind: FUNCTION
- Index: 0x00000000
+ Index: 0x00000004
- Name: bar
Kind: GLOBAL
- Index: 0x00000000
+ Index: 0x00000002
-# CHECK: 00000001 D bar
-# CHECK: 00000000 T foo
+# CHECK: 00000002 D bar
+# CHECK: 00000004 T foo
Added: llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml?rev=305769&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml (added)
+++ llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml Mon Jun 19 23:04:59 2017
@@ -0,0 +1,49 @@
+# RUN: yaml2obj < %s | llvm-nm - | FileCheck %s
+
+# That wasm exports of functions and globals are displayed as global data and
+# code symbols.
+
+--- !WASM
+FileHeader:
+ Version: 0x00000001
+Sections:
+ - Type: TYPE
+ Signatures:
+ - ReturnType: I32
+ ParamTypes:
+ - I32
+ - Type: IMPORT
+ Imports:
+ - Module: env
+ Field: weak_import_func
+ Kind: FUNCTION
+ SigIndex: 0
+ - Module: env
+ Field: weak_import_data
+ Kind: GLOBAL
+ GlobalType: I32
+ GlobalMutable: false
+ - Type: EXPORT
+ Exports:
+ - Name: weak_global_func
+ Kind: FUNCTION
+ Index: 0x00000004
+ - Name: weak_global_data
+ Kind: GLOBAL
+ Index: 0x00000002
+ - Type: CUSTOM
+ Name: linking
+ SymbolInfo:
+ - Name: weak_global_func
+ Flags: 1
+ - Name: weak_global_data
+ Flags: 1
+ - Name: weak_import_func
+ Flags: 1
+ - Name: weak_import_data
+ Flags: 1
+
+# CHECK: 00000002 W weak_global_data
+# CHECK: 00000004 W weak_global_func
+# CHECK: w weak_import_data
+# CHECK: w weak_import_func
Modified: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/wasm2yaml.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp Mon Jun 19 23:04:59 2017
@@ -14,6 +14,7 @@
#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
+using object::WasmSection;
namespace {
@@ -22,10 +23,16 @@ class WasmDumper {
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 @@ WasmYAML::Table make_table(const wasm::W
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 @@ WasmYAML::Limits make_limits(const wasm:
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 @@ ErrorOr<WasmYAML::Object *> WasmDumper::
// 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 @@ ErrorOr<WasmYAML::Object *> WasmDumper::
// 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 @@ ErrorOr<WasmYAML::Object *> WasmDumper::
return Y.release();
}
-} // namespace
-
std::error_code wasm2yaml(raw_ostream &Out, const object::WasmObjectFile &Obj) {
WasmDumper Dumper(Obj);
ErrorOr<WasmYAML::Object *> YAMLOrErr = Dumper.dump();
Modified: llvm/trunk/tools/yaml2obj/yaml2wasm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2wasm.cpp?rev=305769&r1=305768&r2=305769&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2wasm.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2wasm.cpp Mon Jun 19 23:04:59 2017
@@ -26,8 +26,9 @@ class WasmWriter {
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 @@ public:
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 @@ static int writeInitExpr(const wasm::Was
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::writeNameSection(raw_ost
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);
}
More information about the llvm-commits
mailing list