WASM_SEGMENT_NAMES = 0x5,
};
+const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
+
enum : unsigned {
- WASM_SYMBOL_FLAG_WEAK = 0x1,
+ WASM_SYMBOL_BINDING_GLOBAL = 0x0,
+ WASM_SYMBOL_BINDING_WEAK = 0x1,
+ WASM_SYMBOL_BINDING_LOCAL = 0x2,
};
#define WASM_RELOC(name, value) name = value,
uint32_t ElementIndex;
bool isWeak() const {
- return Flags & wasm::WASM_SYMBOL_FLAG_WEAK;
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
+ }
+
+ bool isGlobal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
+ }
+
+ bool isLocal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
+ }
+
+ unsigned getBinding() const {
+ return Flags & wasm::WASM_SYMBOL_BINDING_MASK;
}
void print(raw_ostream &Out) const {
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getWasmSymbolValue(const WasmSymbol& Sym) const;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t NumFuncImports);
void writeCodeRelocSection();
void writeDataRelocSection();
- void writeLinkingMetaDataSection(ArrayRef<WasmDataSegment> Segments,
- uint32_t DataSize, uint32_t DataAlignment,
- ArrayRef<StringRef> WeakSymbols,
- bool HasStackPointer,
- uint32_t StackPointerGlobal);
+ void writeLinkingMetaDataSection(
+ ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
+ uint32_t DataAlignment,
+ SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
+ bool HasStackPointer, uint32_t StackPointerGlobal);
uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
void WasmObjectWriter::writeLinkingMetaDataSection(
ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
- uint32_t DataAlignment, ArrayRef<StringRef> WeakSymbols,
+ uint32_t DataAlignment,
+ SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
bool HasStackPointer, uint32_t StackPointerGlobal) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
endSection(SubSection);
}
- if (WeakSymbols.size() != 0) {
+ if (SymbolFlags.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());
+ encodeULEB128(SymbolFlags.size(), getStream());
+ for (auto Pair: SymbolFlags) {
+ writeString(Pair.first);
+ encodeULEB128(Pair.second, getStream());
}
endSection(SubSection);
}
SmallVector<uint32_t, 4> TableElems;
SmallVector<WasmImport, 4> Imports;
SmallVector<WasmExport, 4> Exports;
- SmallVector<StringRef, 4> WeakSymbols;
+ SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags;
SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
unsigned NumFuncImports = 0;
SmallVector<WasmDataSegment, 4> DataSegments;
<< " isVariable=" << WS.isVariable() << "\n");
if (WS.isWeak())
- WeakSymbols.push_back(WS.getName());
+ SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_WEAK);
if (WS.isVariable())
continue;
}
// If the symbol is visible outside this translation unit, export it.
- if ((WS.isExternal() && WS.isDefined(/*SetUsed=*/false))) {
+ if (WS.isDefined(/*SetUsed=*/false)) {
WasmExport Export;
Export.FieldName = WS.getName();
Export.Index = Index;
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);
}
}
for (const MCSymbol &S : Asm.symbols()) {
if (!S.isVariable())
continue;
+
assert(S.isDefined(/*SetUsed=*/false));
// Find the target symbol of this weak alias and export that index
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);
}
// Add types for indirect function calls.
writeCodeRelocSection();
writeDataRelocSection();
writeLinkingMetaDataSection(DataSegments, DataSize, DataAlignment,
- WeakSymbols, HasStackPointer, StackPointerGlobal);
+ SymbolFlags, HasStackPointer, StackPointerGlobal);
// TODO: Translate the .comment section to the output.
// TODO: Translate debug sections to the output.
const WasmSymbol &Sym = getWasmSymbol(Symb);
DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
- if (Sym.Flags & wasm::WASM_SYMBOL_FLAG_WEAK)
+ if (Sym.isWeak())
Result |= SymbolRef::SF_Weak;
+ else if (Sym.isGlobal())
+ Result |= SymbolRef::SF_Global;
switch (Sym.Type) {
case WasmSymbol::SymbolType::FUNCTION_IMPORT:
Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
break;
case WasmSymbol::SymbolType::FUNCTION_EXPORT:
- Result |= SymbolRef::SF_Global | SymbolRef::SF_Executable;
+ Result |= SymbolRef::SF_Executable;
break;
case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
Result |= SymbolRef::SF_Executable;
Result |= SymbolRef::SF_Undefined;
break;
case WasmSymbol::SymbolType::GLOBAL_EXPORT:
- Result |= SymbolRef::SF_Global;
break;
}
return getSymbolValue(Symb);
}
-uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- const WasmSymbol& Sym = getWasmSymbol(Symb);
+uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
switch (Sym.Type) {
case WasmSymbol::SymbolType::FUNCTION_IMPORT:
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
llvm_unreachable("invalid symbol type");
}
+uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
+ return getWasmSymbolValue(getWasmSymbol(Symb));
+}
+
uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
llvm_unreachable("not yet implemented");
return 0;
; CHECK-NEXT: Value: 16
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
-; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 24
; CHECK-NEXT: - Type: EXPORT
-; CHECK-NEXT: Exports:
+; 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: linking
; CHECK-NEXT: DataSize: 28
; CHECK-NEXT: DataAlignment: 8
+; CHECK-NEXT: SymbolInfo:
+; CHECK-NEXT: - Name: .L.str1
+; CHECK-NEXT: Flags: 2
+; CHECK-NEXT: - Name: .L.str2
+; CHECK-NEXT: Flags: 2
; CHECK-NEXT: SegmentNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .rodata..L.str1
; CHECK-NEXT: Name: .data.a
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: .data.b
-; CHECK-NEXT: ...
+; CHECK_NEXT: ...
--- /dev/null
+; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm -o %t.o %s
+; RUN: llvm-nm %t.o | FileCheck %s
+
+@foo = internal global i32 1, align 4
+@bar = global i32 1, align 4
+
+; CHECK: 00000004 D bar
+; CHECK: 00000000 d foo
RUN: llvm-objdump -t %p/../Inputs/trivial.obj.wasm | FileCheck %s
CHECK: SYMBOL TABLE:
-CHECK-NEXT: 00000000 l F name puts
-CHECK-NEXT: 00000001 l F name SomeOtherFunction
-CHECK-NEXT: 00000002 l F name main
-CHECK-NEXT: 00000000 l F IMPORT puts
-CHECK-NEXT: 00000000 l F IMPORT SomeOtherFunction
+CHECK-NEXT: 00000000 g F name puts
+CHECK-NEXT: 00000001 g F name SomeOtherFunction
+CHECK-NEXT: 00000002 g F name main
+CHECK-NEXT: 00000000 g F IMPORT puts
+CHECK-NEXT: 00000000 g F IMPORT SomeOtherFunction
CHECK-NEXT: 00000002 g F EXPORT main
CHECK-NEXT: 00000010 g EXPORT var
AllTargetsDisassemblers
AllTargetsInfos
MC
+ Object
MCParser
Object
Support
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)
+ const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
+ if (Symbol.Type != object::WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME)
continue;
WasmYAML::NameEntry NameEntry;
- NameEntry.Name = *NameOrError;
+ NameEntry.Name = Symbol.Name;
NameEntry.Index = Sym.getValue();
NameSec->FunctionNames.push_back(NameEntry);
}