std::vector<uint32_t> Functions;
};
+// Represents the location of a Wasm data symbol within a WasmDataSegment, as
+// the index of the segment, and the offset and size within the segment.
+struct WasmDataReference {
+ uint32_t Segment;
+ uint32_t Offset;
+ uint32_t Size;
+};
+
struct WasmRelocation {
uint32_t Type; // The type of the relocation.
- uint32_t Index; // Index into function or global index space.
+ uint32_t Index; // Index into either symbol or type index space.
uint64_t Offset; // Offset from the start of the section.
int64_t Addend; // A value to add to the symbol.
};
struct WasmInitFunc {
uint32_t Priority;
- uint32_t FunctionIndex;
+ uint32_t Symbol;
+};
+
+struct WasmSymbolInfo {
+ StringRef Name;
+ uint32_t Kind;
+ uint32_t Flags;
+ union {
+ // For function or global symbols, the index in function of global index
+ // space.
+ uint32_t ElementIndex;
+ // For a data symbols, the address of the data relative to segment.
+ WasmDataReference DataRef;
+ };
};
struct WasmFunctionName {
struct WasmLinkingData {
uint32_t DataSize;
std::vector<WasmInitFunc> InitFunctions;
+ std::vector<WasmSymbolInfo> SymbolTable;
};
enum : unsigned {
// Kind codes used in the custom "linking" section
enum : unsigned {
- WASM_SYMBOL_INFO = 0x2,
WASM_DATA_SIZE = 0x3,
WASM_SEGMENT_INFO = 0x5,
WASM_INIT_FUNCS = 0x6,
WASM_COMDAT_INFO = 0x7,
+ WASM_SYMBOL_TABLE = 0x8,
};
// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
WASM_COMDAT_FUNCTION = 0x1,
};
+// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
+enum WasmSymbolType : unsigned {
+ WASM_SYMBOL_TYPE_FUNCTION = 0x0,
+ WASM_SYMBOL_TYPE_DATA = 0x1,
+ WASM_SYMBOL_TYPE_GLOBAL = 0x2,
+};
+
const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
-const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4;
+const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
+const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
#define WASM_RELOC(name, value) name = value,
#undef WASM_RELOC
-struct Global {
- ValType Type;
- bool Mutable;
-
- // The initial value for this global is either the value of an imported
- // global, in which case InitialModule and InitialName specify the global
- // import, or a value, in which case InitialModule is empty and InitialValue
- // holds the value.
- StringRef InitialModule;
- StringRef InitialName;
- uint64_t InitialValue;
-};
-
} // end namespace wasm
} // end namespace llvm
// The offset of the MC function/data section in the wasm code/data section.
// For data relocations the offset is relative to start of the data payload
// itself and does not include the size of the section header.
- uint64_t SectionOffset;
+ uint64_t SectionOffset = 0;
- // For data sections, this is the offset of the corresponding wasm data
+ // For data sections, this is the index of of the corresponding wasm data
// segment
- uint64_t MemoryOffset;
+ uint32_t SegmentIndex = 0;
friend class MCContext;
MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group,
unsigned UniqueID, MCSymbol *Begin)
: MCSection(SV_Wasm, K, Begin), SectionName(Section), UniqueID(UniqueID),
- Group(group), SectionOffset(0) {}
+ Group(group) {}
void setSectionName(StringRef Name) { SectionName = Name; }
uint64_t getSectionOffset() const { return SectionOffset; }
void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; }
- uint32_t getMemoryOffset() const { return MemoryOffset; }
- void setMemoryOffset(uint32_t Offset) { MemoryOffset = Offset; }
+ uint32_t getSegmentIndex() const { return SegmentIndex; }
+ void setSegmentIndex(uint32_t Index) { SegmentIndex = Index; }
static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
};
namespace llvm {
class MCSymbolWasm : public MCSymbol {
- bool IsFunction = false;
+ wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_DATA;
bool IsWeak = false;
bool IsHidden = false;
bool IsComdat = false;
std::string ModuleName;
SmallVector<wasm::ValType, 1> Returns;
SmallVector<wasm::ValType, 4> Params;
+ wasm::WasmGlobalType GlobalType;
bool ParamsSet = false;
bool ReturnsSet = false;
+ bool GlobalTypeSet = false;
/// An expression describing how to calculate the size of a symbol. If a
/// symbol has no size this field will be NULL.
const MCExpr *getSize() const { return SymbolSize; }
void setSize(const MCExpr *SS) { SymbolSize = SS; }
- bool isFunction() const { return IsFunction; }
- void setIsFunction(bool isFunc) { IsFunction = isFunc; }
+ bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
+ bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
+ bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
+ wasm::WasmSymbolType getType() const { return Type; }
+ void setType(wasm::WasmSymbolType type) { Type = type; }
bool isWeak() const { return IsWeak; }
void setWeak(bool isWeak) { IsWeak = isWeak; }
ParamsSet = true;
Params = std::move(Pars);
}
+
+ const wasm::WasmGlobalType &getGlobalType() const {
+ assert(GlobalTypeSet);
+ return GlobalType;
+ }
+
+ void setGlobalType(wasm::WasmGlobalType GT) {
+ GlobalTypeSet = true;
+ GlobalType = GT;
+ }
};
} // end namespace llvm
class WasmSymbol {
public:
- enum class SymbolType {
- FUNCTION_IMPORT,
- FUNCTION_EXPORT,
- GLOBAL_IMPORT,
- GLOBAL_EXPORT,
- };
-
- WasmSymbol(StringRef Name, SymbolType Type, uint32_t ElementIndex,
- uint32_t FunctionType = 0)
- : Name(Name), Type(Type), ElementIndex(ElementIndex),
- FunctionType(FunctionType) {}
-
- StringRef Name;
- SymbolType Type;
- uint32_t Flags = 0;
-
- // Index into either the function or global index space.
- uint32_t ElementIndex;
-
- // For function, the type index
- uint32_t FunctionType;
-
- // Symbols can be both exported and imported (in the case of the weakly
- // defined symbol). In this the import index is stored as AltIndex.
- uint32_t AltIndex = 0;
- bool HasAltIndex = false;
-
- void setAltIndex(uint32_t Index) {
- HasAltIndex = true;
- AltIndex = Index;
- }
+ WasmSymbol(const wasm::WasmSymbolInfo &Info,
+ const wasm::WasmSignature *FunctionType,
+ const wasm::WasmGlobalType *GlobalType)
+ : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {}
+
+ const wasm::WasmSymbolInfo &Info;
+ const wasm::WasmSignature *FunctionType;
+ const wasm::WasmGlobalType *GlobalType;
bool isTypeFunction() const {
- return Type == SymbolType::FUNCTION_IMPORT ||
- Type == SymbolType::FUNCTION_EXPORT;
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
}
+ bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
+
bool isTypeGlobal() const {
- return Type == SymbolType::GLOBAL_IMPORT ||
- Type == SymbolType::GLOBAL_EXPORT;
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
}
+ bool isDefined() const { return !isUndefined(); }
+
+ bool isUndefined() const {
+ return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
+ }
bool isBindingWeak() const {
return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
}
unsigned getBinding() const {
- return Flags & wasm::WASM_SYMBOL_BINDING_MASK;
+ return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
}
bool isHidden() const {
}
unsigned getVisibility() const {
- return Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
+ return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
}
void print(raw_ostream &Out) const {
- Out << "Name=" << Name << ", Type=" << static_cast<int>(Type)
- << ", Flags=" << Flags << " ElemIndex=" << ElementIndex;
+ Out << "Name=" << Info.Name << ", Kind=" << Info.Kind
+ << ", Flags=" << Info.Flags;
+ if (!isTypeData()) {
+ Out << ", ElemIndex=" << Info.ElementIndex;
+ } else if (isDefined()) {
+ Out << ", Segment=" << Info.DataRef.Segment;
+ Out << ", Offset=" << Info.DataRef.Offset;
+ Out << ", Size=" << Info.DataRef.Size;
+ }
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
ArrayRef<StringRef> comdats() const { return Comdats; }
ArrayRef<wasm::WasmFunctionName> debugNames() const { return DebugNames; }
uint32_t startFunction() const { return StartFunction; }
+ uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
+ uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
void moveSymbolNext(DataRefImpl &Symb) const override;
private:
bool isValidFunctionIndex(uint32_t Index) const;
bool isDefinedFunctionIndex(uint32_t Index) const;
- wasm::WasmFunction& getDefinedFunction(uint32_t Index);
+ bool isValidGlobalIndex(uint32_t Index) const;
+ bool isDefinedGlobalIndex(uint32_t Index) const;
+ bool isValidFunctionSymbolIndex(uint32_t Index) const;
+ wasm::WasmFunction &getDefinedFunction(uint32_t Index);
+ wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
const WasmSection &getWasmSection(DataRefImpl Ref) const;
const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
// Custom section types
Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseLinkingSectionSymtab(const uint8_t *&Ptr, const uint8_t *End);
Error parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End);
Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
const uint8_t *End);
- void populateSymbolTable();
-
wasm::WasmObjectHeader Header;
std::vector<WasmSection> Sections;
std::vector<wasm::WasmSignature> Signatures;
uint32_t NumImportedFunctions = 0;
uint32_t CodeSection = 0;
uint32_t DataSection = 0;
-
- StringMap<uint32_t> SymbolMap;
+ uint32_t GlobalSection = 0;
};
} // end namespace object
LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
};
struct SymbolInfo {
+ uint32_t Index;
StringRef Name;
+ SymbolKind Kind;
SymbolFlags Flags;
+ union {
+ uint32_t ElementIndex;
+ wasm::WasmDataReference DataRef;
+ };
};
struct InitFunction {
uint32_t Priority;
- uint32_t FunctionIndex;
+ uint32_t Symbol;
};
struct ComdatEntry {
}
uint32_t DataSize;
- std::vector<SymbolInfo> SymbolInfos;
+ std::vector<SymbolInfo> SymbolTable;
std::vector<SegmentInfo> SegmentInfos;
std::vector<InitFunction> InitFunctions;
std::vector<Comdat> Comdats;
static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
};
+template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
+ static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
+};
+
template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
};
break;
case MCSA_ELF_TypeFunction:
- Symbol->setIsFunction(true);
+ Symbol->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
break;
case MCSA_ELF_TypeObject:
- Symbol->setIsFunction(false);
+ Symbol->setType(wasm::WASM_SYMBOL_TYPE_DATA);
break;
default:
// Maps function symbols to the table element index space. Used
// for TABLE_INDEX relocation types (i.e. address taken functions).
DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
- // Maps function/global symbols to the function/global index space.
+ // Maps function/global symbols to the (shared) Symbol index space.
DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
+ // Maps function/global symbols to the function/global Wasm index space.
+ DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
+ // Maps data symbols to the Wasm segment and offset/size with the segment.
+ DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
FunctionTypeIndices;
SmallVector<WasmFunctionType, 4> FunctionTypes;
SmallVector<WasmGlobal, 4> Globals;
+ SmallVector<WasmDataSegment, 4> DataSegments;
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
DataRelocations.clear();
TypeIndices.clear();
SymbolIndices.clear();
+ WasmIndices.clear();
TableIndices.clear();
+ DataLocations.clear();
FunctionTypeIndices.clear();
FunctionTypes.clear();
Globals.clear();
+ DataSegments.clear();
MCObjectWriter::reset();
NumFunctionImports = 0;
NumGlobalImports = 0;
void writeElemSection(ArrayRef<uint32_t> TableElems);
void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
ArrayRef<WasmFunction> Functions);
- void writeDataSection(ArrayRef<WasmDataSegment> Segments);
+ void writeDataSection();
void writeCodeRelocSection();
void writeDataRelocSection();
void writeLinkingMetaDataSection(
- ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
- ArrayRef<std::pair<StringRef, uint32_t>> SymbolFlags,
+ uint32_t DataSize, ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
- const std::map<StringRef, std::vector<WasmComdatEntry>>& Comdats);
+ const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
assert(Sym->isFunction());
return TableIndices[Sym];
}
- case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- // Provisional value is function/type/global index itself
+ // Provisional value is same as the index
return getRelocationIndexValue(RelEntry);
+ case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
+ // Provisional value is function/global Wasm index
+ if (!WasmIndices.count(RelEntry.Symbol))
+ report_fatal_error("symbol not found in wasm index space: " +
+ RelEntry.Symbol->getName());
+ return WasmIndices[RelEntry.Symbol];
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
// For undefined symbols, use zero
if (!Sym->isDefined())
return 0;
-
- if (!SymbolIndices.count(Sym))
- report_fatal_error("symbol not found in function/global index space: " +
- Sym->getName());
- uint32_t GlobalIndex = SymbolIndices[Sym];
- const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports];
- uint64_t Address = Global.InitialValue + RelEntry.Addend;
-
+ const wasm::WasmDataReference &Ref = DataLocations[Sym];
+ const WasmDataSegment &Segment = DataSegments[Ref.Segment];
// Ignore overflow. LLVM allows address arithmetic to silently wrap.
- return Address;
+ return Segment.Offset + Ref.Offset + RelEntry.Addend;
}
default:
llvm_unreachable("invalid relocation type");
DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
- size_t LastFragmentSize = 0;
for (const MCFragment &Frag : DataSection) {
if (Frag.hasInstructions())
report_fatal_error("only data supported in data sections");
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
- LastFragmentSize = Contents.size();
}
}
- // Don't allow empty segments, or segments that end with zero-sized
- // fragment, otherwise the linker cannot map symbols to a unique
- // data segment. This can be triggered by zero-sized structs
- // See: test/MC/WebAssembly/bss.ll
- if (LastFragmentSize == 0)
- DataBytes.resize(DataBytes.size() + 1);
DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
}
}
if (!SymbolIndices.count(RelEntry.Symbol))
- report_fatal_error("symbol not found in function/global index space: " +
+ report_fatal_error("symbol not found in symbol index space: " +
RelEntry.Symbol->getName());
return SymbolIndices[RelEntry.Symbol];
}
endSection(Section);
}
-void WasmObjectWriter::writeDataSection(ArrayRef<WasmDataSegment> Segments) {
- if (Segments.empty())
+void WasmObjectWriter::writeDataSection() {
+ if (DataSegments.empty())
return;
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_DATA);
- encodeULEB128(Segments.size(), getStream()); // count
+ encodeULEB128(DataSegments.size(), getStream()); // count
- for (const WasmDataSegment & Segment : Segments) {
+ for (const WasmDataSegment &Segment : DataSegments) {
encodeULEB128(0, getStream()); // memory index
write8(wasm::WASM_OPCODE_I32_CONST);
encodeSLEB128(Segment.Offset, getStream()); // offset
}
void WasmObjectWriter::writeLinkingMetaDataSection(
- ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
- ArrayRef<std::pair<StringRef, uint32_t>> SymbolFlags,
+ uint32_t DataSize, ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
- const std::map<StringRef, std::vector<WasmComdatEntry>>& Comdats) {
+ const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
SectionBookkeeping SubSection;
- if (SymbolFlags.size() != 0) {
- startSection(SubSection, wasm::WASM_SYMBOL_INFO);
- encodeULEB128(SymbolFlags.size(), getStream());
- for (auto Pair: SymbolFlags) {
- writeString(Pair.first);
- encodeULEB128(Pair.second, getStream());
+ if (SymbolInfos.size() != 0) {
+ startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
+ encodeULEB128(SymbolInfos.size(), getStream());
+ for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
+ encodeULEB128(Sym.Kind, getStream());
+ encodeULEB128(Sym.Flags, getStream());
+ switch (Sym.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ encodeULEB128(Sym.ElementIndex, getStream());
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ writeString(Sym.Name);
+ break;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ writeString(Sym.Name);
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ encodeULEB128(Sym.DataRef.Segment, getStream());
+ encodeULEB128(Sym.DataRef.Offset, getStream());
+ encodeULEB128(Sym.DataRef.Size, getStream());
+ }
+ break;
+ default:
+ llvm_unreachable("unexpected kind");
+ }
}
endSection(SubSection);
}
endSection(SubSection);
}
- if (Segments.size()) {
+ if (DataSegments.size()) {
startSection(SubSection, wasm::WASM_SEGMENT_INFO);
- encodeULEB128(Segments.size(), getStream());
- for (const WasmDataSegment &Segment : Segments) {
+ encodeULEB128(DataSegments.size(), getStream());
+ for (const WasmDataSegment &Segment : DataSegments) {
writeString(Segment.Name);
encodeULEB128(Segment.Alignment, getStream());
encodeULEB128(Segment.Flags, getStream());
const MCAsmLayout &Layout) {
DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
MCContext &Ctx = Asm.getContext();
- int32_t PtrType = is64Bit() ? wasm::WASM_TYPE_I64 : wasm::WASM_TYPE_I32;
// Collect information from the available symbols.
SmallVector<WasmFunction, 4> Functions;
SmallVector<uint32_t, 4> TableElems;
SmallVector<wasm::WasmImport, 4> Imports;
SmallVector<wasm::WasmExport, 4> Exports;
- SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags;
+ SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
- SmallVector<WasmDataSegment, 4> DataSegments;
+ unsigned NumSymbols = 0;
uint32_t DataSize = 0;
+ auto AddSymbol = [&](const MCSymbolWasm &WS) {
+ uint32_t Flags = 0;
+ if (WS.isWeak())
+ Flags |= wasm::WASM_SYMBOL_BINDING_WEAK;
+ if (WS.isHidden())
+ Flags |= wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
+ if (!WS.isExternal() && WS.isDefined())
+ Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+ if (WS.isUndefined())
+ Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+
+ wasm::WasmSymbolInfo Info;
+ Info.Name = WS.getName();
+ Info.Kind = WS.getType();
+ Info.Flags = Flags;
+ if (!WS.isData())
+ Info.ElementIndex = WasmIndices[&WS];
+ else if (WS.isDefined())
+ Info.DataRef = DataLocations[&WS];
+ SymbolInfos.emplace_back(Info);
+ SymbolIndices[&WS] = NumSymbols++;
+ };
+
// For now, always emit the memory import, since loads and stores are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no loads or stores.
continue;
// If the symbol is not defined in this translation unit, import it.
- if ((!WS.isDefined() && !WS.isComdat()) ||
- WS.isVariable()) {
- wasm::WasmImport Import;
- Import.Module = WS.getModuleName();
- Import.Field = WS.getName();
-
+ if (!WS.isDefined() && !WS.isComdat()) {
if (WS.isFunction()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getModuleName();
+ Import.Field = WS.getName();
Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
Import.SigIndex = getFunctionType(WS);
- SymbolIndices[&WS] = NumFunctionImports;
- ++NumFunctionImports;
- } else {
+ Imports.push_back(Import);
+ WasmIndices[&WS] = NumFunctionImports++;
+ } else if (WS.isGlobal()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getModuleName();
+ Import.Field = WS.getName();
Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- Import.Global.Type = PtrType;
- // If this global is the stack pointer, make it mutable.
- if (WS.getName() == "__stack_pointer")
- Import.Global.Mutable = true;
- else
- Import.Global.Mutable = false;
-
- SymbolIndices[&WS] = NumGlobalImports;
- ++NumGlobalImports;
+ Import.Global = WS.getGlobalType();
+ Imports.push_back(Import);
+ WasmIndices[&WS] = NumGlobalImports++;
}
- Imports.push_back(Import);
+ // TODO(ncw) We shouldn't be adding the symbol to the symbol table here!
+ // Instead it should be done by removing the "if (WS.isDefined())" block
+ // in the big loop below (line ~1284). However - that would reorder all
+ // the symbols and thus require all the tests to be updated. I think it's
+ // better to make that change therefore in a future commit, to isolate
+ // each test update from the change that caused it.
+ AddSymbol(WS);
}
}
Segment.Alignment = Section.getAlignment();
Segment.Flags = 0;
DataSize += Segment.Data.size();
- Section.setMemoryOffset(Segment.Offset);
+ Section.setSegmentIndex(SegmentIndex);
if (const MCSymbolWasm *C = Section.getGroup()) {
Comdats[C->getName()].emplace_back(
<< " isHidden=" << WS.isHidden()
<< " isVariable=" << WS.isVariable() << "\n");
- if (WS.isWeak() || WS.isHidden()) {
- uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) |
- (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0);
- SymbolFlags.emplace_back(WS.getName(), Flags);
- }
-
if (WS.isVariable())
continue;
-
- unsigned Index;
+ if (WS.isComdat() && !WS.isDefined())
+ continue;
if (WS.isFunction()) {
+ unsigned Index;
if (WS.isDefined()) {
if (WS.getOffset() != 0)
report_fatal_error(
report_fatal_error(
"function symbols must have a size set with .size");
- // A definition. Take the next available index.
+ // A definition. Write out the function body.
Index = NumFunctionImports + Functions.size();
-
- // Prepare the function.
WasmFunction Func;
Func.Type = getFunctionType(WS);
Func.Sym = &WS;
- SymbolIndices[&WS] = Index;
+ WasmIndices[&WS] = Index;
Functions.push_back(Func);
+
+ auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
+ if (const MCSymbolWasm *C = Section.getGroup()) {
+ Comdats[C->getName()].emplace_back(
+ WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
+ }
} else {
// An import; the index was assigned above.
- Index = SymbolIndices.find(&WS)->second;
+ Index = WasmIndices.find(&WS)->second;
}
DEBUG(dbgs() << " -> function index: " << Index << "\n");
- } else {
+ } else if (WS.isData()) {
if (WS.isTemporary() && !WS.getSize())
continue;
- if (!WS.isDefined())
+ if (!WS.isDefined()) {
+ DEBUG(dbgs() << " -> segment index: -1");
continue;
+ }
if (!WS.getSize())
report_fatal_error("data symbols must have a size set with .size: " +
if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
report_fatal_error(".size expression must be evaluatable");
- // For each global, prepare a corresponding wasm global holding its
- // address. For externals these will also be named exports.
- Index = NumGlobalImports + Globals.size();
auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
assert(DataSection.isWasmData());
- WasmGlobal Global;
- Global.Type.Type = PtrType;
- Global.Type.Mutable = false;
- Global.InitialValue = DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS);
- SymbolIndices[&WS] = Index;
- DEBUG(dbgs() << " -> global index: " << Index << "\n");
- Globals.push_back(Global);
- }
-
- // If the symbol is visible outside this translation unit, export it.
- if (WS.isDefined()) {
- wasm::WasmExport Export;
- Export.Name = WS.getName();
- Export.Index = Index;
- if (WS.isFunction())
- Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
- else
- Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
- Exports.push_back(Export);
-
- if (!WS.isExternal())
- SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
-
- if (WS.isFunction()) {
- auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
- if (const MCSymbolWasm *C = Section.getGroup())
- Comdats[C->getName()].emplace_back(
- WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
+ // For each data symbol, export it in the symtab as a reference to the
+ // corresponding Wasm data segment.
+ wasm::WasmDataReference Ref = wasm::WasmDataReference{
+ DataSection.getSegmentIndex(),
+ static_cast<uint32_t>(Layout.getSymbolOffset(WS)),
+ static_cast<uint32_t>(Size)};
+ DataLocations[&WS] = Ref;
+ DEBUG(dbgs() << " -> segment index: " << Ref.Segment);
+ } else {
+ // A "true" Wasm global (currently just __stack_pointer)
+ unsigned WasmIndex;
+ if (WS.isDefined()) {
+ report_fatal_error("don't yet support defined globals");
+ } else {
+ // An import; the index was assigned above
+ WasmIndex = WasmIndices.find(&WS)->second;
}
+
+ DEBUG(dbgs() << " -> global index: " << WasmIndex << "\n");
}
+
+ if (WS.isDefined())
+ AddSymbol(WS);
}
// Handle weak aliases. We need to process these in a separate pass because
const auto &WS = static_cast<const MCSymbolWasm &>(S);
const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS);
DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n");
- assert(SymbolIndices.count(ResolvedSym) > 0);
- uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
- DEBUG(dbgs() << " -> index:" << Index << "\n");
- wasm::WasmExport Export;
- Export.Name = WS.getName();
- Export.Index = Index;
- if (WS.isFunction())
- Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
- else
- Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
- Exports.push_back(Export);
-
- if (!WS.isExternal())
- SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
+ if (WS.isFunction()) {
+ assert(WasmIndices.count(ResolvedSym) > 0);
+ uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second;
+ WasmIndices[&WS] = WasmIndex;
+ DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
+ } else if (WS.isData()) {
+ assert(DataLocations.count(ResolvedSym) > 0);
+ const wasm::WasmDataReference &Ref =
+ DataLocations.find(ResolvedSym)->second;
+ DataLocations[&WS] = Ref;
+ DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
+ } else {
+ report_fatal_error("don't yet support global aliases");
+ }
+
+ AddSymbol(WS);
}
{
return;
assert(Rel.Symbol->isFunction());
const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol);
- uint32_t SymbolIndex = SymbolIndices.find(&WS)->second;
+ uint32_t FunctionIndex = WasmIndices.find(&WS)->second;
uint32_t TableIndex = TableElems.size() + kInitialTableOffset;
if (TableIndices.try_emplace(&WS, TableIndex).second) {
DEBUG(dbgs() << " -> adding " << WS.getName()
<< " to table: " << TableIndex << "\n");
- TableElems.push_back(SymbolIndex);
+ TableElems.push_back(FunctionIndex);
registerFunctionType(WS);
}
};
writeExportSection(Exports);
writeElemSection(TableElems);
writeCodeSection(Asm, Layout, Functions);
- writeDataSection(DataSegments);
+ writeDataSection();
writeCodeRelocSection();
writeDataRelocSection();
- writeLinkingMetaDataSection(DataSegments, DataSize, SymbolFlags,
- InitFuncs, Comdats);
+ writeLinkingMetaDataSection(DataSize, SymbolInfos, InitFuncs, Comdats);
// TODO: Translate the .comment section to the output.
// TODO: Translate debug sections to the output.
return Error::success();
}
-void WasmObjectFile::populateSymbolTable() {
- // Add imports to symbol table
- size_t GlobalIndex = 0;
- size_t FunctionIndex = 0;
- for (const wasm::WasmImport& Import : Imports) {
- switch (Import.Kind) {
- case wasm::WASM_EXTERNAL_GLOBAL:
- assert(Import.Global.Type == wasm::WASM_TYPE_I32);
- SymbolMap.try_emplace(Import.Field, Symbols.size());
- Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
- GlobalIndex++);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- break;
- case wasm::WASM_EXTERNAL_FUNCTION:
- SymbolMap.try_emplace(Import.Field, Symbols.size());
- Symbols.emplace_back(Import.Field,
- WasmSymbol::SymbolType::FUNCTION_IMPORT,
- FunctionIndex++, Import.SigIndex);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- break;
- default:
- break;
- }
- }
-
- // Add exports to symbol table
- for (const wasm::WasmExport& Export : Exports) {
- if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
- Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
- WasmSymbol::SymbolType ExportType =
- Export.Kind == wasm::WASM_EXTERNAL_FUNCTION
- ? WasmSymbol::SymbolType::FUNCTION_EXPORT
- : WasmSymbol::SymbolType::GLOBAL_EXPORT;
- auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size());
- if (Pair.second) {
- Symbols.emplace_back(Export.Name, ExportType, Export.Index);
- DEBUG(dbgs() << "Adding export: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- } else {
- uint32_t SymIndex = Pair.first->second;
- const WasmSymbol &OldSym = Symbols[SymIndex];
- WasmSymbol NewSym(Export.Name, ExportType, Export.Index);
- NewSym.setAltIndex(OldSym.ElementIndex);
- Symbols[SymIndex] = NewSym;
-
- DEBUG(dbgs() << "Replacing existing symbol: " << NewSym
- << " sym index:" << SymIndex << "\n");
- }
- }
- if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION &&
- isDefinedFunctionIndex(Export.Index)) {
- auto &Function = getDefinedFunction(Export.Index);
- if (Function.Name.empty()) {
- // Use the export's name to set a name for the Function, but only if one
- // hasn't already been set.
- Function.Name = Export.Name;
- }
- }
- }
-}
-
Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
const uint8_t *End) {
HasLinkingSection = true;
"Linking data must come after code section", object_error::parse_failed);
}
- // Only populate the symbol table with imports and exports if the object
- // has a linking section (i.e. its a relocatable object file). Otherwise
- // the global might not represent symbols at all.
- populateSymbolTable();
-
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);
- uint32_t Flags = readVaruint32(Ptr);
- auto iter = SymbolMap.find(Symbol);
- if (iter == SymbolMap.end()) {
- return make_error<GenericBinaryError>(
- "Invalid symbol name in linking section: " + Symbol,
- 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 << " expected:"
- << Symbol << " flags: " << Flags << "\n");
- }
+ case wasm::WASM_SYMBOL_TABLE:
+ if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd))
+ return Err;
break;
- }
case wasm::WASM_DATA_SIZE:
LinkingData.DataSize = readVaruint32(Ptr);
break;
for (uint32_t i = 0; i < Count; i++) {
wasm::WasmInitFunc Init;
Init.Priority = readVaruint32(Ptr);
- Init.FunctionIndex = readVaruint32(Ptr);
- if (!isValidFunctionIndex(Init.FunctionIndex))
- return make_error<GenericBinaryError>("Invalid function index: " +
- Twine(Init.FunctionIndex),
+ Init.Symbol = readVaruint32(Ptr);
+ if (!isValidFunctionSymbolIndex(Init.Symbol))
+ return make_error<GenericBinaryError>("Invalid function symbol: " +
+ Twine(Init.Symbol),
object_error::parse_failed);
LinkingData.InitFunctions.emplace_back(Init);
}
return Error::success();
}
+Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr,
+ const uint8_t *End) {
+ uint32_t Count = readVaruint32(Ptr);
+ LinkingData.SymbolTable.reserve(Count);
+ Symbols.reserve(Count);
+ StringSet<> SymbolNames;
+
+ std::vector<wasm::WasmImport *> ImportedGlobals;
+ std::vector<wasm::WasmImport *> ImportedFunctions;
+ ImportedGlobals.reserve(Imports.size());
+ ImportedFunctions.reserve(Imports.size());
+ for (auto &I : Imports) {
+ if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
+ ImportedFunctions.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
+ ImportedGlobals.emplace_back(&I);
+ }
+
+ while (Count--) {
+ wasm::WasmSymbolInfo Info;
+ const wasm::WasmSignature *FunctionType = nullptr;
+ const wasm::WasmGlobalType *GlobalType = nullptr;
+
+ Info.Kind = readUint8(Ptr);
+ Info.Flags = readVaruint32(Ptr);
+ bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
+
+ switch (Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ Info.ElementIndex = readVaruint32(Ptr);
+ if (!isValidFunctionIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid function symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ptr);
+ unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
+ FunctionType = &Signatures[FunctionTypes[FuncIndex]];
+ auto &Function = Functions[FuncIndex];
+ if (Function.Name.empty()) {
+ // Use the symbol's name to set a name for the Function, but only if
+ // one hasn't already been set.
+ Function.Name = Info.Name;
+ }
+ } else {
+ wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
+ FunctionType = &Signatures[Import.SigIndex];
+ Info.Name = Import.Field;
+ }
+ break;
+
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ Info.ElementIndex = readVaruint32(Ptr);
+ if (!isValidGlobalIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid global symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ptr);
+ unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
+ GlobalType = &Globals[GlobalIndex].Type;
+ } else {
+ wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
+ Info.Name = Import.Field;
+ GlobalType = &Import.Global;
+ }
+ break;
+
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ Info.Name = readString(Ptr);
+ if (IsDefined) {
+ uint32_t Index = readVaruint32(Ptr);
+ if (Index >= DataSegments.size())
+ return make_error<GenericBinaryError>("invalid data symbol index",
+ object_error::parse_failed);
+ uint32_t Offset = readVaruint32(Ptr);
+ uint32_t Size = readVaruint32(Ptr);
+ if (Offset + Size > DataSegments[Index].Data.Content.size())
+ return make_error<GenericBinaryError>("invalid data symbol index",
+ object_error::parse_failed);
+ Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
+ }
+ break;
+
+ default:
+ return make_error<GenericBinaryError>("Invalid symbol type",
+ object_error::parse_failed);
+ }
+
+ if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
+ wasm::WASM_SYMBOL_BINDING_LOCAL &&
+ !SymbolNames.insert(Info.Name).second)
+ return make_error<GenericBinaryError>("Duplicate symbol name " +
+ Twine(Info.Name),
+ object_error::parse_failed);
+ LinkingData.SymbolTable.emplace_back(Info);
+ Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
+ GlobalType);
+ DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
+ }
+
+ return Error::success();
+}
+
Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr,
const uint8_t *End)
{
}
Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) {
+ GlobalSection = Sections.size();
uint32_t Count = readVaruint32(Ptr);
Globals.reserve(Count);
while (Count--) {
return make_error<GenericBinaryError>("Invalid function export",
object_error::parse_failed);
break;
- case wasm::WASM_EXTERNAL_GLOBAL: {
- if (Ex.Index >= Globals.size() + NumImportedGlobals)
+ case wasm::WASM_EXTERNAL_GLOBAL:
+ if (!isValidGlobalIndex(Ex.Index))
return make_error<GenericBinaryError>("Invalid global export",
object_error::parse_failed);
break;
- }
case wasm::WASM_EXTERNAL_MEMORY:
case wasm::WASM_EXTERNAL_TABLE:
break;
}
bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
- return Index < FunctionTypes.size() + NumImportedFunctions;
+ return Index < NumImportedFunctions + FunctionTypes.size();
}
bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
}
-wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) {
+bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
+ return Index < NumImportedGlobals + Globals.size();
+}
+
+bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
+ return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
+}
+
+bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeFunction();
+}
+
+wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
assert(isDefinedFunctionIndex(Index));
return Functions[Index - NumImportedFunctions];
}
+wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
+ assert(isDefinedGlobalIndex(Index));
+ return Globals[Index - NumImportedGlobals];
+}
+
Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
StartFunction = readVaruint32(Ptr);
if (!isValidFunctionIndex(StartFunction))
Result |= SymbolRef::SF_Global;
if (Sym.isHidden())
Result |= SymbolRef::SF_Hidden;
-
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
- break;
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
- Result |= SymbolRef::SF_Executable;
- break;
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
+ if (!Sym.isDefined())
Result |= SymbolRef::SF_Undefined;
- break;
- case WasmSymbol::SymbolType::GLOBAL_EXPORT:
- break;
- }
-
+ if (Sym.isTypeFunction())
+ Result |= SymbolRef::SF_Executable;
return Result;
}
}
Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
- return getWasmSymbol(Symb).Name;
+ return getWasmSymbol(Symb).Info.Name;
}
Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
}
uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
- return Sym.ElementIndex;
- case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
- uint32_t GlobalIndex = Sym.ElementIndex - NumImportedGlobals;
- assert(GlobalIndex < Globals.size());
- const wasm::WasmGlobal &Global = Globals[GlobalIndex];
- // WasmSymbols correspond only to I32_CONST globals
- assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
- return Global.InitExpr.Value.Int32;
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ return Sym.Info.ElementIndex;
+ case wasm::WASM_SYMBOL_TYPE_DATA: {
+ // The value of a data symbol is the segment offset, plus the symbol
+ // offset within the segment.
+ uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
+ const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
+ assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
+ return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
}
}
llvm_unreachable("invalid symbol type");
WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
const WasmSymbol &Sym = getWasmSymbol(Symb);
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
return SymbolRef::ST_Function;
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
- case WasmSymbol::SymbolType::GLOBAL_EXPORT:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ return SymbolRef::ST_Other;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
return SymbolRef::ST_Data;
}
Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
- DataRefImpl Ref;
const WasmSymbol& Sym = getWasmSymbol(Symb);
- if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT)
- Ref.d.a = DataSection;
- else if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT)
- Ref.d.a = CodeSection;
- else
+ if (Sym.isUndefined())
return section_end();
+
+ DataRefImpl Ref;
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ Ref.d.a = CodeSection;
+ break;
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ Ref.d.a = GlobalSection;
+ break;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ Ref.d.a = DataSection;
+ break;
+ default:
+ llvm_unreachable("Unknown WasmSymbol::SymbolType");
+ }
return section_iterator(SectionRef(Ref, this));
}
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
IO.mapRequired("DataSize", Section.DataSize);
- IO.mapOptional("SymbolInfo", Section.SymbolInfos);
+ IO.mapOptional("SymbolTable", Section.SymbolTable);
IO.mapOptional("SegmentInfo", Section.SegmentInfos);
IO.mapOptional("InitFunctions", Section.InitFunctions);
IO.mapOptional("Comdats", Section.Comdats);
void MappingTraits<WasmYAML::InitFunction>::mapping(
IO &IO, WasmYAML::InitFunction &Init) {
IO.mapRequired("Priority", Init.Priority);
- IO.mapRequired("FunctionIndex", Init.FunctionIndex);
+ IO.mapRequired("Symbol", Init.Symbol);
}
void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
WasmYAML::SymbolInfo &Info) {
+ IO.mapRequired("Index", Info.Index);
+ IO.mapRequired("Kind", Info.Kind);
IO.mapRequired("Name", Info.Name);
IO.mapRequired("Flags", Info.Flags);
+ if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
+ IO.mapRequired("Function", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+ IO.mapRequired("Global", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ IO.mapRequired("Segment", Info.DataRef.Segment);
+ IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
+ IO.mapRequired("Size", Info.DataRef.Size);
+ }
+ } else {
+ llvm_unreachable("unsupported symbol kind");
+ }
}
void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
BCaseMask(BINDING_MASK, BINDING_LOCAL);
//BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
+ BCaseMask(UNDEFINED, UNDEFINED);
#undef BCaseMask
}
+void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
+ IO &IO, WasmYAML::SymbolKind &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
+ ECase(FUNCTION);
+ ECase(DATA);
+ ECase(GLOBAL);
+#undef ECase
+}
+
void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
IO &IO, WasmYAML::ValueType &Type) {
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
WasmSym->setParams(std::move(ValParams));
WasmSym->setReturns(std::move(ValResults));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
return WasmSym;
const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
// __stack_pointer is a global variable; all other external symbols used by
- // CodeGen are functions.
- if (strcmp(Name, "__stack_pointer") == 0)
+ // CodeGen are functions. It's OK to hardcode knowledge of specific symbols
+ // here; this method is precisely there for fetching the signatures of known
+ // Clang-provided symbols.
+ if (strcmp(Name, "__stack_pointer") == 0) {
+ wasm::ValType iPTR =
+ Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true});
return WasmSym;
+ }
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
return WasmSym;
}
MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym);
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
const MCExpr *Expr =
MCSymbolRefExpr::create(WasmSym,
; CHECK: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 2
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: gBd
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: gBd
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 2
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .data
@foo = global %union.u1 zeroinitializer, align 1
@bar = global %union.u1 zeroinitializer, align 1
-; CHECK: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 4
-; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 8
-; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 9
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: g0
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 0
-; CHECK-NEXT: - Name: g1
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: foo
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: bar
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Type: DATA
-; CHECK-NEXT: Segments:
+; CHECK: - Type: DATA
+; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: MemoryIndex: 0
-; CHECK-NEXT: Offset:
+; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: Content: '00000000'
; CHECK-NEXT: - SectionOffset: 15
; CHECK-NEXT: MemoryIndex: 0
-; CHECK-NEXT: Offset:
+; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 4
; CHECK-NEXT: Content: '00000000'
; CHECK-NEXT: - SectionOffset: 24
; CHECK-NEXT: MemoryIndex: 0
-; CHECK-NEXT: Offset:
+; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
-; CHECK-NEXT: Content: '00'
-; CHECK-NEXT: - SectionOffset: 30
+; CHECK-NEXT: Content: ''
+; CHECK-NEXT: - SectionOffset: 29
; CHECK-NEXT: MemoryIndex: 0
-; CHECK-NEXT: Offset:
+; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 9
-; CHECK-NEXT: Content: '00'
+; CHECK-NEXT: Value: 8
+; CHECK-NEXT: Content: ''
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
-; CHECK-NEXT: DataSize: 10
+; CHECK-NEXT: DataSize: 8
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: g0
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: g1
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 1
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: foo
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 2
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: bar
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 3
+; CHECK-NEXT: Size: 0
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .bss.g0
; CHECK-NEXT: SigIndex: 0
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ]
-; CHECK-NEXT: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: callImport
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: basicInlineFn
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: sharedFn
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Name: constantData
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 0
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 3
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: basicInlineFn
-; CHECK-NEXT: Flags: [ BINDING_WEAK ]
-; CHECK-NEXT: - Name: sharedFn
-; CHECK-NEXT: Flags: [ BINDING_WEAK ]
-; CHECK-NEXT: - Name: constantData
-; CHECK-NEXT: Flags: [ BINDING_WEAK ]
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: funcImport
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: callImport
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Function: 1
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: basicInlineFn
+; CHECK-NEXT: Flags: [ BINDING_WEAK ]
+; CHECK-NEXT: Function: 2
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: sharedFn
+; CHECK-NEXT: Flags: [ BINDING_WEAK ]
+; CHECK-NEXT: Function: 3
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: constantData
+; CHECK-NEXT: Flags: [ BINDING_WEAK ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 3
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .rodata.constantData
; CHECK-NEXT: Alignment: 1
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: Comdats:
-; CHECK-NEXT: - Name: basicInlineFn
+; CHECK-NEXT: Name: basicInlineFn
; CHECK-NEXT: Entries:
; CHECK-NEXT: - Kind: FUNCTION
; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: sharedComdat
+; CHECK-NEXT: Name: sharedComdat
; CHECK-NEXT: Entries:
; CHECK-NEXT: - Kind: FUNCTION
; CHECK-NEXT: Index: 3
@global2 = global i64 7, align 8, section ".sec1"
@global3 = global i32 8, align 8, section ".sec2"
-; CHECK: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 8
-; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 16
-; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 24
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: global0
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 0
-; CHECK-NEXT: - Name: global1
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: global2
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: global3
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Type: DATA
+
+; CHECK: - Type: DATA
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 24
; CHECK-NEXT: Content: '08000000'
-
-; CHECK: - Type: CUSTOM
+; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 28
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: global0
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: global1
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 1
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: global2
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 1
+; CHECK-NEXT: Offset: 8
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: global3
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 2
+; CHECK-NEXT: Size: 4
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .data.global0
; CHECK: }
; CHECK: Relocations [
-; CHECK: Section (6) CODE {
+; CHECK: Section (5) CODE {
; CHECK: Relocation {
; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
; CHECK: Offset: 0x4
; CHECK: Relocation {
; CHECK: Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1)
; CHECK: Offset: 0x1E
-; CHECK: Index: 0x2
+; CHECK: Index: 0x3
; CHECK: }
; CHECK: }
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 1
; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: __dso_handle
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: GlobalType: I32
-; CHECK-NEXT: GlobalMutable: false
-; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __cxa_atexit
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 2
; CHECK-NEXT: SigIndex: 1
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1 ]
-; CHECK-NEXT: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: .Lcall_dtors.42
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 5
-; CHECK-NEXT: - Name: .Lregister_call_dtors.42
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 6
-; CHECK-NEXT: - Name: .Lcall_dtors
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 7
-; CHECK-NEXT: - Name: .Lregister_call_dtors
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 8
-; CHECK-NEXT: - Name: global1
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 1
; CHECK-NEXT: - Type: ELEM
; CHECK-NEXT: Segments:
; CHECK-NEXT: - Offset:
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000004
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; CHECK-NEXT: Index: 5
+; CHECK-NEXT: Index: 6
; CHECK-NEXT: Offset: 0x0000000F
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; CHECK-NEXT: Index: 0
+; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000017
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT: Index: 1
+; CHECK-NEXT: Index: 2
; CHECK-NEXT: Offset: 0x0000001D
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT: Index: 2
+; CHECK-NEXT: Index: 3
; CHECK-NEXT: Offset: 0x0000002C
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; CHECK-NEXT: Index: 7
+; CHECK-NEXT: Index: 8
; CHECK-NEXT: Offset: 0x00000037
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; CHECK-NEXT: Index: 0
+; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000003F
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT: Index: 1
+; CHECK-NEXT: Index: 2
; CHECK-NEXT: Offset: 0x00000045
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 4
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: __dso_handle
-; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: .Lcall_dtors.42
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: func3
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: __dso_handle
+; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: __cxa_atexit
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 1
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: func2
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 2
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: func1
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 3
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: func0
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 4
+; CHECK-NEXT: - Index: 6
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: .Lcall_dtors.42
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
-; CHECK-NEXT: - Name: .Lregister_call_dtors.42
+; CHECK-NEXT: Function: 5
+; CHECK-NEXT: - Index: 7
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: .Lregister_call_dtors.42
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
-; CHECK-NEXT: - Name: .Lcall_dtors
+; CHECK-NEXT: Function: 6
+; CHECK-NEXT: - Index: 8
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: .Lcall_dtors
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
-; CHECK-NEXT: - Name: .Lregister_call_dtors
+; CHECK-NEXT: Function: 7
+; CHECK-NEXT: - Index: 9
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: .Lregister_call_dtors
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
+; CHECK-NEXT: Function: 8
+; CHECK-NEXT: - Index: 10
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: global1
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 4
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .data.global1
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: InitFunctions:
; CHECK-NEXT: - Priority: 42
-; CHECK-NEXT: FunctionIndex: 3
+; CHECK-NEXT: Symbol: 4
; CHECK-NEXT: - Priority: 42
-; CHECK-NEXT: FunctionIndex: 6
+; CHECK-NEXT: Symbol: 7
; CHECK-NEXT: - Priority: 65535
-; CHECK-NEXT: FunctionIndex: 4
+; CHECK-NEXT: Symbol: 5
; CHECK-NEXT: - Priority: 65535
-; CHECK-NEXT: FunctionIndex: 8
+; CHECK-NEXT: Symbol: 9
; CHECK-NEXT: ...
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (6) CODE {
+; CHECK-NEXT: Section (4) CODE {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
; CHECK-NEXT: Offset: 0x9
-; CHECK-NEXT: Index: 0x0
+; CHECK-NEXT: Index: 0x3
; CHECK-NEXT: Addend: 0
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
; CHECK-NEXT: Offset: 0x14
-; CHECK-NEXT: Index: 0x1
+; CHECK-NEXT: Index: 0x4
; CHECK-NEXT: Addend: 0
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (4) DATA {
+; CHECK-NEXT: Section (2) DATA {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5)
; CHECK-NEXT: Offset: 0x13
; CHECK: Type: FUNCTION (0x3)
; CHECK: }
; CHECK: Section {
-; CHECK: Type: GLOBAL (0x6)
-; CHECK: }
-; CHECK: Section {
-; CHECK: Type: EXPORT (0x7)
-; CHECK: }
-; CHECK: Section {
; CHECK: Type: CODE (0xA)
; CHECK: }
; CHECK: Section {
@b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8
-; CHECK: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 6
-; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 16
-; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 24
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: .L.str1
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 0
-; CHECK-NEXT: - Name: .L.str2
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: a
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: b
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Type: DATA
+; CHECK: - Type: DATA
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
; CHECK-NEXT: Index: 0
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 28
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: .L.str1
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: .L.str1
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
-; CHECK-NEXT: - Name: .L.str2
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 6
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: .L.str2
; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
+; CHECK-NEXT: Segment: 1
+; CHECK-NEXT: Size: 6
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: a
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 2
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: b
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 3
+; CHECK-NEXT: Size: 4
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .rodata..L.str1
; CHECK: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 0
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: hiddenVis
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: defaultVis
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: hiddenVis
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 1
; CHECK-NEXT: ...
; CHECK-NEXT: ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000001
-; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: foo_alias
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: SigIndex: 0
-; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: bar_alias
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: GlobalType: I32
-; CHECK-NEXT: GlobalMutable: false
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
-; CHECK-NEXT: - Type: GLOBAL
-; CHECK-NEXT: Globals:
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 8
-; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 16
-; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Type: I32
-; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
-; CHECK-NEXT: Opcode: I32_CONST
-; CHECK-NEXT: Value: 0
-; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
-; CHECK-NEXT: - Name: foo
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: call_direct
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: call_alias
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Name: call_direct_ptr
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 4
-; CHECK-NEXT: - Name: direct_address
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: call_alias_ptr
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 5
-; CHECK-NEXT: - Name: alias_address
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: bar
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Name: foo_alias
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: bar_alias
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: Index: 3
; CHECK-NEXT: - Type: ELEM
; CHECK-NEXT: Segments:
; CHECK-NEXT: - Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
-; CHECK-NEXT: Functions: [ 1 ]
+; CHECK-NEXT: Functions: [ 0 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT: Index: 1
+; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000009
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT: Index: 0
+; CHECK-NEXT: Index: 8
; CHECK-NEXT: Offset: 0x00000012
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT: Index: 1
+; CHECK-NEXT: Index: 4
; CHECK-NEXT: Offset: 0x0000001E
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000024
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT: Index: 2
+; CHECK-NEXT: Index: 6
; CHECK-NEXT: Offset: 0x00000031
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000037
; CHECK-NEXT: Functions:
-; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 41000B
-; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Locals:
-; CHECK-NEXT: Body: 1081808080000B
-; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Body: 1080808080000B
+; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 1080808080000B
-; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 410028028880808000118080808000000B
-; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 410028029080808000118080808000000B
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
-; CHECK-NEXT: Index: 1
+; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x0000000F
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
-; CHECK-NEXT: Index: 0
+; CHECK-NEXT: Index: 8
; CHECK-NEXT: Offset: 0x00000018
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 20
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: foo_alias
-; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: bar_alias
-; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: foo
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: foo
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: call_direct
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: call_direct
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: call_alias
+; CHECK-NEXT: Function: 1
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: call_alias
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: call_direct_ptr
+; CHECK-NEXT: Function: 2
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: call_direct_ptr
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: - Name: call_alias_ptr
+; CHECK-NEXT: Function: 3
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: direct_address
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 1
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: call_alias_ptr
; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 4
+; CHECK-NEXT: - Index: 6
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: alias_address
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 2
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 7
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: bar
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: - Index: 8
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: foo_alias
+; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 9
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: bar_alias
+; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Segment: 0
+; CHECK-NEXT: Size: 4
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .data.bar
; CHECK-NEXT: ...
; CHECK-SYMS: SYMBOL TABLE:
-; CHECK-SYMS-NEXT: 00000001 gw F CODE .hidden foo_alias
-; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias
-; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden foo
-; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_direct
-; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_alias
-; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_direct_ptr
+; CHECK-SYMS-NEXT: 00000000 g F CODE .hidden foo
+; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden call_direct
+; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_alias
+; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_direct_ptr
; CHECK-SYMS-NEXT: 00000008 g DATA direct_address
-; CHECK-SYMS-NEXT: 00000005 g F CODE .hidden call_alias_ptr
+; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_alias_ptr
; CHECK-SYMS-NEXT: 00000010 g DATA alias_address
; CHECK-SYMS-NEXT: 00000000 g DATA bar
+; CHECK-SYMS-NEXT: 00000000 gw F CODE .hidden foo_alias
+; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias
; CHECK-NEXT: Field: __linear_memory
; CHECK: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
-; CHECK: - Module: env
-; CHECK-NEXT: Field: weak_external_data
-; CHECK-NEXT: Kind: GLOBAL
-; CHECK-NEXT: GlobalType: I32
-; CHECK-NEXT: GlobalMutable: false
; CHECK: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 0
-; CHECK-NEXT: SymbolInfo:
-; CHECK-NEXT: - Name: weak_external_data
-; CHECK-NEXT: Flags: [ BINDING_WEAK ]
-; CHECK-NEXT: - Name: weak_function
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: weak_external_data
+; CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ]
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: weak_function
; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 0
; CHECK-NEXT: ...
COFF32-NEXT: 00000000 T _main
COFF32-NEXT: U _puts
-WASM: U SomeOtherFunction
+
+WASM: 00000000 d .L.str
+WASM-NEXT: U SomeOtherFunction
WASM-NEXT: 00000002 T main
WASM-NEXT: U puts
WASM-NEXT: 00000010 D var
+
COFF64: 00000000 d .data
COFF64-NEXT: 00000000 t .text
COFF64-NEXT: 00000000 r ??__Ex@@YAXXZ
ELF-AVR-NEXT: Section: .data
ELF-AVR-NEXT: Value: 0x0000000000800060
+
WASM: --- !WASM
WASM-NEXT: FileHeader:
WASM-NEXT: Version: 0x00000001
-WASM: - Type: EXPORT
-WASM-NEXT: Exports:
-WASM-NEXT: - Name: main
-WASM-NEXT: Kind: FUNCTION
-WASM-NEXT: Index: 2
-WASM-NEXT: - Name: var
-WASM-NEXT: Kind: GLOBAL
-WASM-NEXT: Index: 1
+WASM: - Type: CUSTOM
+WASM-NEXT: Name: linking
+WASM-NEXT: DataSize: 20
+WASM-NEXT: SymbolTable:
+WASM-NEXT: - Index: 0
+WASM-NEXT: Kind: FUNCTION
+WASM-NEXT: Name: puts
+WASM-NEXT: Flags: [ UNDEFINED ]
+WASM-NEXT: Function: 0
+WASM-NEXT: - Index: 1
+WASM: Name: SomeOtherFunction
+WASM: - Index: 2
+WASM: Name: main
+WASM: - Index: 3
+WASM-NEXT: Kind: DATA
+WASM-NEXT: Name: .L.str
+WASM-NEXT: Flags: [ BINDING_LOCAL ]
+WASM-NEXT: Segment: 0
+WASM-NEXT: Size: 13
+WASM-NEXT: - Index: 4
+WASM: Name: var
+WASM: SegmentInfo:
+WASM-NEXT: - Index: 0
+WASM-NEXT: Name: .rodata..L.str
+WASM-NEXT: Alignment: 1
+WASM-NEXT: Flags: [ ]
+WASM-NEXT: - Index: 1
+WASM: ...
+
ELF-X86-64-UNWIND: - Name: .eh_frame
ELF-X86-64-UNWIND-NEXT: Type: SHT_X86_64_UNWIND
ELF-MIPSEL: R_MIPS_CALL16 SomeOtherFunction
WASM: CODE
-WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 0+0
+WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 3+0
WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 0+0
WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 1+0
- Type: CUSTOM
Name: linking
DataSize: 999
- SymbolInfo:
- - Name: bar
- Flags: [ BINDING_WEAK ]
+ SymbolTable:
+ - Index: 0
+ Kind: FUNCTION
+ Name: bar
+ Flags: [ BINDING_WEAK, UNDEFINED ]
+ Function: 0
SegmentInfo:
- Index: 0
Alignment: 4
Name: moredata
InitFunctions:
- Priority: 1
- FunctionIndex: 0
+ Symbol: 0
...
# CHECK: - Type: CUSTOM
# CHECK-NEXT: Name: linking
# CHECK-NEXT: DataSize: 999
-# CHECK-NEXT: SymbolInfo:
-# CHECK-NEXT: - Name: bar
-# CHECK-NEXT: Flags: [ BINDING_WEAK ]
+# CHECK-NEXT: SymbolTable:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Name: bar
+# CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ]
+# CHECK-NEXT: Function: 0
# CHECK-NEXT: SegmentInfo:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: mydata
# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: InitFunctions:
# CHECK-NEXT: - Priority: 1
-# CHECK-NEXT: FunctionIndex: 0
+# CHECK-NEXT: Symbol: 0
# CHECK-NEXT: ...
- Type: CUSTOM
Name: linking
DataSize: 10
- SymbolInfo:
- - Name: function_export
+ SymbolTable:
+ - Index: 0
+ Kind: FUNCTION
+ Name: function_export
Flags: [ BINDING_WEAK ]
- - Name: global_export
+ Function: 0
+ - Index: 1
+ Kind: GLOBAL
+ Name: global_export
Flags: [ BINDING_WEAK ]
+ Global: 0
...
# CHECK: --- !WASM
# CHECK: FileHeader:
# CHECK: - Type: CUSTOM
# CHECK: Name: linking
# CHECK: DataSize: 10
-# CHECK: SymbolInfo:
-# CHECK: - Name: function_export
-# CHECK: Flags: [ BINDING_WEAK ]
-# CHECK: - Name: global_export
-# CHECK: Flags: [ BINDING_WEAK ]
+# CHECK: SymbolTable:
+# CHECK: - Index: 0
+# CHECK: Kind: FUNCTION
+# CHECK: Name: function_export
+# CHECK: Flags: [ BINDING_WEAK ]
+# CHECK: Function: 0
+# CHECK: - Index: 1
+# CHECK: Kind: GLOBAL
+# CHECK: Name: global_export
+# CHECK: Flags: [ BINDING_WEAK ]
+# CHECK: Global: 0
# RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
-# That wasm exports of functions and globals are displayed as global data and
-# code symbols.
+# Check that wasm exports of functions/globals/data are displayed correctly
--- !WASM
FileHeader:
ReturnType: I32
ParamTypes:
- I32
- - Type: IMPORT
- Imports:
- - Module: env
- Field: fimport
- Kind: FUNCTION
- SigIndex: 0
- - Module: env
- Field: gimport
- Kind: GLOBAL
- GlobalType: I32
- GlobalMutable: false
- Type: FUNCTION
- FunctionTypes: [ 0, 0, 0, 0, 0 ]
+ FunctionTypes: [ 0 ]
- Type: GLOBAL
Globals:
- - Index: 1
+ - Index: 0
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
Value: 32
- - Index: 2
- Type: I32
- Mutable: false
- InitExpr:
- Opcode: I32_CONST
- Value: 64
- - Index: 3
- Type: I32
- Mutable: false
- InitExpr:
- Opcode: I32_CONST
- Value: 1024
- - Type: EXPORT
- Exports:
- - Name: foo
- Kind: FUNCTION
- Index: 0x00000004
- - Name: bar
- Kind: GLOBAL
- Index: 0x00000003
- Type: CODE
Functions:
- - Index: 1
- Locals:
- Body: 00
- - Index: 2
- Locals:
- Body: 00
- - Index: 3
- Locals:
- Body: 00
- - Index: 4
- Locals:
- Body: 00
- - Index: 5
+ - Index: 0
Locals:
Body: 00
+ - Type: DATA
+ Segments:
+ - SectionOffset: 6
+ MemoryIndex: 0
+ Offset:
+ Opcode: I32_CONST
+ Value: 0
+ Content: '616263'
- Type: CUSTOM
- Name: "linking"
- DataSize: 0
+ Name: linking
+ DataSize: 3
+ SymbolTable:
+ - Index: 0
+ Kind: FUNCTION
+ Name: fexport
+ Flags: [ ]
+ Function: 0
+ - Index: 1
+ Kind: GLOBAL
+ Name: gexport
+ Flags: [ ]
+ Global: 0
+ - Index: 2
+ Kind: DATA
+ Name: dexport
+ Flags: [ ]
+ Segment: 0
+ Size: 3
+ SegmentInfo:
+ - Index: 0
+ Name: .rodata.constantData
+ Alignment: 1
+ Flags: [ ]
-# CHECK: 00000400 D bar
-# CHECK-NEXT: U fimport
-# CHECK-NEXT: 00000004 T foo
-# CHECK-NEXT: U gimport
+# CHECK: 00000000 D dexport
+# CHECK-NEXT: 00000000 T fexport
+# CHECK-NEXT: 00000000 D gexport
# RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
+# Check that wasm import of functions/globals/data are displayed correctly
+
--- !WASM
FileHeader:
Version: 0x00000001
- Type: IMPORT
Imports:
- Module: env
- Field: foo
+ Field: fimport
Kind: FUNCTION
SigIndex: 0
- Module: env
- Field: bar
+ Field: gimport
Kind: GLOBAL
GlobalType: I32
GlobalMutable: false
- Type: CUSTOM
- Name: "linking"
- DataSize: 0
+ Name: linking
+ DataSize: 3
+ SymbolTable:
+ - Index: 0
+ Kind: FUNCTION
+ Name: fimport
+ Flags: [ UNDEFINED ]
+ Function: 0
+ - Index: 1
+ Kind: GLOBAL
+ Name: gimport
+ Flags: [ UNDEFINED ]
+ Global: 0
+ - Index: 2
+ Kind: DATA
+ Name: dimport
+ Flags: [ UNDEFINED ]
-# CHECK: U bar
-# CHECK: U foo
+# CHECK: U dimport
+# CHECK-NEXT: U fimport
+# CHECK-NEXT: U gimport
# RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
-# That wasm exports of functions and globals are displayed as global data and
-# code symbols.
+# Check that wasm weak function/global/data symbols are displayed correctly
--- !WASM
FileHeader:
Kind: FUNCTION
SigIndex: 0
- Module: env
- Field: weak_import_data
+ Field: weak_import_global
Kind: GLOBAL
GlobalType: I32
GlobalMutable: false
- Type: FUNCTION
- FunctionTypes: [ 0, 0, 0, 0 ]
+ FunctionTypes: [ 0 ]
- Type: GLOBAL
Globals:
- Index: 1
InitExpr:
Opcode: I64_CONST
Value: 32
- - Index: 2
- Type: I32
- Mutable: false
- InitExpr:
- Opcode: I32_CONST
- Value: 64
- - Index: 3
- Type: I32
- Mutable: false
- InitExpr:
- Opcode: I32_CONST
- Value: 1024
- - Type: EXPORT
- Exports:
- - Name: weak_global_func
- Kind: FUNCTION
- Index: 0x00000004
- - Name: weak_global_data
- Kind: GLOBAL
- Index: 0x00000003
- Type: CODE
Functions:
- Index: 1
Locals:
Body: 00
- - Index: 2
- Locals:
- Body: 00
- - Index: 3
- Locals:
- Body: 00
- - Index: 4
- Locals:
- Body: 00
+ - Type: DATA
+ Segments:
+ - SectionOffset: 6
+ MemoryIndex: 0
+ Offset:
+ Opcode: I32_CONST
+ Value: 0
+ Content: '616263'
- Type: CUSTOM
Name: linking
- DataSize: 0
- SymbolInfo:
- - Name: weak_global_func
- Flags: [ BINDING_WEAK ]
- - Name: weak_global_data
- Flags: [ BINDING_WEAK ]
- - Name: weak_import_func
- Flags: [ BINDING_WEAK ]
- - Name: weak_import_data
- Flags: [ BINDING_WEAK ]
+ DataSize: 3
+ SymbolTable:
+ - Index: 0
+ Kind: DATA
+ Name: weak_defined_data
+ Flags: [ BINDING_WEAK ]
+ Segment: 0
+ Size: 3
+ - Index: 1
+ Kind: FUNCTION
+ Name: weak_defined_func
+ Flags: [ BINDING_WEAK ]
+ Function: 1
+ - Index: 2
+ Kind: GLOBAL
+ Name: weak_defined_global
+ Flags: [ BINDING_WEAK ]
+ Global: 1
+ - Index: 3
+ Kind: DATA
+ Name: weak_import_data
+ Flags: [ BINDING_WEAK, UNDEFINED ]
+ - Index: 4
+ Kind: FUNCTION
+ Name: weak_import_func
+ Flags: [ BINDING_WEAK, UNDEFINED ]
+ Function: 0
+ - Index: 5
+ Kind: GLOBAL
+ Name: weak_import_global
+ Flags: [ BINDING_WEAK, UNDEFINED ]
+ Global: 0
+ SegmentInfo:
+ - Index: 0
+ Name: .rodata.constantData
+ Alignment: 1
+ Flags: [ ]
+
-# CHECK: 00000400 W weak_global_data
-# CHECK: 00000004 W weak_global_func
-# CHECK: w weak_import_data
-# CHECK: w weak_import_func
+# CHECK: 00000000 W weak_defined_data
+# CHECK-NEXT: 00000001 W weak_defined_func
+# CHECK-NEXT: 00000001 W weak_defined_global
+# CHECK-NEXT: w weak_import_data
+# CHECK-NEXT: w weak_import_func
+# CHECK-NEXT: w weak_import_global
CHECK-NEXT: 00000000 g F *UND* puts
CHECK-NEXT: 00000000 g F *UND* SomeOtherFunction
CHECK-NEXT: 00000002 g F CODE main
+CHECK-NEXT: 00000000 l DATA .L.str
CHECK-NEXT: 00000010 g DATA var
-
# CHECK: Sections:
# CHECK-NEXT: Idx Name Size Address Type
-# CHECK-NEXT: 0 TYPE 0000000e 0000000000000000
-# CHECK-NEXT: 1 IMPORT 00000024 0000000000000000
-# CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000
-# CHECK-NEXT: 3 TABLE 00000004 0000000000000000
-# CHECK-NEXT: 4 MEMORY 00000003 0000000000000000
-# CHECK-NEXT: 5 GLOBAL 0000000b 0000000000000000
-# CHECK-NEXT: 6 EXPORT 0000000e 0000000000000000
-# CHECK-NEXT: 7 CODE 00000019 0000000000000000 TEXT
-# CHECK-NEXT: 8 DATA 0000001a 0000000000000000 DATA
-# CHECK-NEXT: 9 name 0000002b 0000000000000000
-# CHECK-NEXT: 10 reloc.CODE 00000017 0000000000000000
-# CHECK-NEXT: 11 linking 00000016 0000000000000000
+# CHECK-NEXT: 0 TYPE 0000000e 0000000000000000
+# CHECK-NEXT: 1 IMPORT 0000005d 0000000000000000
+# CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000
+# CHECK-NEXT: 3 CODE 00000019 0000000000000000 TEXT
+# CHECK-NEXT: 4 DATA 0000001c 0000000000000000 DATA
+# CHECK-NEXT: 5 reloc.CODE 00000017 0000000000000000
+# CHECK-NEXT: 6 linking 0000005c 0000000000000000
# RUN: llvm-objdump -p %p/Inputs/trivial.obj.wasm | FileCheck %s -check-prefix CHECK-HEADER
MACHO-ARM-NEXT: ]
WASM: Relocations [
-WASM-NEXT: Section (8) CODE {
+WASM-NEXT: Section (4) CODE {
WASM-NEXT: Relocation {
WASM-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB (4)
WASM-NEXT: Offset: 0x4
-WASM-NEXT: Index: 0x0
+WASM-NEXT: Index: 0x3
WASM-NEXT: Addend: 0
WASM-NEXT: }
WASM-NEXT: Relocation {
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: IMPORT (0x2)
-WASM-NEXT: Size: 36
+WASM-NEXT: Size: 93
WASM-NEXT: Offset: 28
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: FUNCTION (0x3)
WASM-NEXT: Size: 2
-WASM-NEXT: Offset: 70
-WASM-NEXT: }
-WASM-NEXT: Section {
-WASM-NEXT: Type: TABLE (0x4)
-WASM-NEXT: Size: 4
-WASM-NEXT: Offset: 78
-WASM-NEXT: }
-WASM-NEXT: Section {
-WASM-NEXT: Type: MEMORY (0x5)
-WASM-NEXT: Size: 3
-WASM-NEXT: Offset: 88
-WASM-NEXT: Memories [
-WASM-NEXT: Memory {
-WASM-NEXT: InitialPages: 1
-WASM-NEXT: }
-WASM-NEXT: ]
-WASM-NEXT: }
-WASM-NEXT: Section {
-WASM-NEXT: Type: GLOBAL (0x6)
-WASM-NEXT: Size: 6
-WASM-NEXT: Offset: 97
-WASM-NEXT: }
-WASM-NEXT: Section {
-WASM-NEXT: Type: EXPORT (0x7)
-WASM-NEXT: Size: 8
-WASM-NEXT: Offset: 109
+WASM-NEXT: Offset: 127
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: CODE (0xA)
WASM-NEXT: Size: 25
-WASM-NEXT: Offset: 123
+WASM-NEXT: Offset: 135
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: DATA (0xB)
WASM-NEXT: Size: 19
-WASM-NEXT: Offset: 154
+WASM-NEXT: Offset: 166
WASM-NEXT: Segments [
WASM-NEXT: Segment {
+WASM-NEXT: Name: .rodata..L.str
WASM-NEXT: Size: 13
WASM-NEXT: Offset: 0
WASM-NEXT: }
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: CUSTOM (0x0)
-WASM-NEXT: Size: 43
-WASM-NEXT: Offset: 179
-WASM-NEXT: Name: name
-WASM-NEXT: }
-WASM-NEXT: Section {
-WASM-NEXT: Type: CUSTOM (0x0)
WASM-NEXT: Size: 23
-WASM-NEXT: Offset: 228
+WASM-NEXT: Offset: 191
WASM-NEXT: Name: reloc.CODE
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: CUSTOM (0x0)
-WASM-NEXT: Size: 22
-WASM-NEXT: Offset: 257
+WASM-NEXT: Size: 72
+WASM-NEXT: Offset: 220
WASM-NEXT: Name: linking
WASM-NEXT: DataSize: 13
WASM-NEXT: }
WASM: Symbols [
WASM-NEXT: Symbol {
WASM-NEXT: Name: puts
-WASM-NEXT: Type: FUNCTION_IMPORT (0x0)
-WASM-NEXT: Flags: 0x0
+WASM-NEXT: Type: FUNCTION (0x0)
+WASM-NEXT: Flags: 0x10
WASM-NEXT: }
WASM-NEXT: Symbol {
WASM-NEXT: Name: SomeOtherFunction
-WASM-NEXT: Type: FUNCTION_IMPORT (0x0)
-WASM-NEXT: Flags: 0x0
+WASM-NEXT: Type: FUNCTION (0x0)
+WASM-NEXT: Flags: 0x10
WASM-NEXT: }
WASM-NEXT: Symbol {
WASM-NEXT: Name: main
-WASM-NEXT: Type: FUNCTION_EXPORT (0x1)
+WASM-NEXT: Type: FUNCTION (0x0)
WASM-NEXT: Flags: 0x0
WASM-NEXT: }
+WASM-NEXT: Symbol {
+WASM-NEXT: Name: .L.str
+WASM-NEXT: Type: DATA (0x1)
+WASM-NEXT: Flags: 0x2
+WASM-NEXT: }
WASM-NEXT: ]
namespace {
static const EnumEntry<unsigned> WasmSymbolTypes[] = {
-#define ENUM_ENTRY(X) { #X, static_cast<unsigned>(WasmSymbol::SymbolType::X) }
- ENUM_ENTRY(FUNCTION_IMPORT),
- ENUM_ENTRY(FUNCTION_EXPORT),
- ENUM_ENTRY(GLOBAL_IMPORT),
- ENUM_ENTRY(GLOBAL_EXPORT),
+#define ENUM_ENTRY(X) { #X, wasm::WASM_SYMBOL_TYPE_##X }
+ ENUM_ENTRY(FUNCTION),
+ ENUM_ENTRY(DATA),
+ ENUM_ENTRY(GLOBAL),
#undef ENUM_ENTRY
};
if (!LinkingData.InitFunctions.empty()) {
ListScope Group(W, "InitFunctions");
for (const wasm::WasmInitFunc &F: LinkingData.InitFunctions)
- W.startLine() << F.FunctionIndex << " (priority=" << F.Priority
- << ")\n";
+ W.startLine() << F.Symbol << " (priority=" << F.Priority << ")\n";
}
}
break;
void WasmDumper::printSymbol(const SymbolRef &Sym) {
DictScope D(W, "Symbol");
WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl());
- W.printString("Name", Symbol.Name);
- W.printEnum("Type", static_cast<unsigned>(Symbol.Type), makeArrayRef(WasmSymbolTypes));
- W.printHex("Flags", Symbol.Flags);
+ W.printString("Name", Symbol.Info.Name);
+ W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes));
+ W.printHex("Flags", Symbol.Info.Flags);
}
}
}
SegmentIndex++;
}
- 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.emplace_back(Info);
+ uint32_t SymbolIndex = 0;
+ for (const wasm::WasmSymbolInfo &Symbol : Obj.linkingData().SymbolTable) {
+ WasmYAML::SymbolInfo Info;
+ Info.Index = SymbolIndex++;
+ Info.Kind = static_cast<uint32_t>(Symbol.Kind);
+ Info.Name = Symbol.Name;
+ Info.Flags = Symbol.Flags;
+ switch (Symbol.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ Info.DataRef = Symbol.DataRef;
+ break;
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ Info.ElementIndex = Symbol.ElementIndex;
+ break;
}
+ LinkingSec->SymbolTable.emplace_back(Info);
}
LinkingSec->DataSize = Obj.linkingData().DataSize;
for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) {
- WasmYAML::InitFunction F{Func.Priority, Func.FunctionIndex};
+ WasmYAML::InitFunction F{Func.Priority, Func.Symbol};
LinkingSec->InitFunctions.emplace_back(F);
}
CustomSec = std::move(LinkingSec);
///
//===----------------------------------------------------------------------===//
//
+
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/LEB128.h"
encodeULEB128(Section.DataSize, SubSection.GetStream());
SubSection.Done();
- // SYMBOL_INFO subsection
- if (Section.SymbolInfos.size()) {
- encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
-
- encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream());
- for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
- writeStringRef(Info.Name, SubSection.GetStream());
+ // SYMBOL_TABLE subsection
+ if (Section.SymbolTable.size()) {
+ encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS);
+
+ encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream());
+#ifndef _NDEBUG
+ uint32_t SymbolIndex = 0;
+#endif
+ for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) {
+ assert(Info.Index == SymbolIndex++);
+ encodeULEB128(Info.Kind, SubSection.GetStream());
encodeULEB128(Info.Flags, SubSection.GetStream());
+ switch (Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ encodeULEB128(Info.ElementIndex, SubSection.GetStream());
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ writeStringRef(Info.Name, SubSection.GetStream());
+ break;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ writeStringRef(Info.Name, SubSection.GetStream());
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ encodeULEB128(Info.DataRef.Segment, SubSection.GetStream());
+ encodeULEB128(Info.DataRef.Offset, SubSection.GetStream());
+ encodeULEB128(Info.DataRef.Size, SubSection.GetStream());
+ }
+ break;
+ default:
+ llvm_unreachable("unexpected kind");
+ }
}
SubSection.Done();
encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
encodeULEB128(Func.Priority, SubSection.GetStream());
- encodeULEB128(Func.FunctionIndex, SubSection.GetStream());
+ encodeULEB128(Func.Symbol, SubSection.GetStream());
}
SubSection.Done();
}