Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -188,8 +188,12 @@ 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, Index: include/llvm/Object/Wasm.h =================================================================== --- include/llvm/Object/Wasm.h +++ include/llvm/Object/Wasm.h @@ -56,7 +56,19 @@ 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 { @@ -132,6 +144,7 @@ Expected getSymbolName(DataRefImpl Symb) const override; Expected 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; Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -280,11 +280,11 @@ uint32_t NumFuncImports); void writeCodeRelocSection(); void writeDataRelocSection(); - void writeLinkingMetaDataSection(ArrayRef Segments, - uint32_t DataSize, uint32_t DataAlignment, - ArrayRef WeakSymbols, - bool HasStackPointer, - uint32_t StackPointerGlobal); + void writeLinkingMetaDataSection( + ArrayRef Segments, uint32_t DataSize, + uint32_t DataAlignment, + SmallVector, 4> SymbolFlags, + bool HasStackPointer, uint32_t StackPointerGlobal); uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry); void applyRelocations(ArrayRef Relocations, @@ -914,7 +914,8 @@ void WasmObjectWriter::writeLinkingMetaDataSection( ArrayRef Segments, uint32_t DataSize, - uint32_t DataAlignment, ArrayRef WeakSymbols, + uint32_t DataAlignment, + SmallVector, 4> SymbolFlags, bool HasStackPointer, uint32_t StackPointerGlobal) { SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_CUSTOM, "linking"); @@ -926,12 +927,12 @@ 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); } @@ -993,7 +994,7 @@ SmallVector TableElems; SmallVector Imports; SmallVector Exports; - SmallVector WeakSymbols; + SmallVector, 4> SymbolFlags; SmallPtrSet IsAddressTaken; unsigned NumFuncImports = 0; SmallVector DataSegments; @@ -1164,7 +1165,7 @@ << " 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; @@ -1235,7 +1236,7 @@ } // 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; @@ -1245,6 +1246,8 @@ 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); } } @@ -1254,6 +1257,7 @@ 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 @@ -1273,6 +1277,9 @@ 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. @@ -1301,7 +1308,7 @@ 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. Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -767,15 +767,17 @@ 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; @@ -785,7 +787,6 @@ Result |= SymbolRef::SF_Undefined; break; case WasmSymbol::SymbolType::GLOBAL_EXPORT: - Result |= SymbolRef::SF_Global; break; } @@ -820,8 +821,7 @@ 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: @@ -842,6 +842,10 @@ 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; Index: test/MC/WebAssembly/unnamed-data.ll =================================================================== --- test/MC/WebAssembly/unnamed-data.ll +++ test/MC/WebAssembly/unnamed-data.ll @@ -26,11 +26,17 @@ ; 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 @@ -74,6 +80,11 @@ ; 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 @@ -83,4 +94,4 @@ ; CHECK-NEXT: Name: .data.a ; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Name: .data.b -; CHECK-NEXT: ... +; CHECK_NEXT: ... Index: test/tools/llvm-nm/wasm/local-symbols.ll =================================================================== --- /dev/null +++ test/tools/llvm-nm/wasm/local-symbols.ll @@ -0,0 +1,8 @@ +; 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 Index: test/tools/llvm-objdump/WebAssembly/symbol-table.test =================================================================== --- test/tools/llvm-objdump/WebAssembly/symbol-table.test +++ test/tools/llvm-objdump/WebAssembly/symbol-table.test @@ -1,11 +1,11 @@ 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 Index: tools/llvm-cfi-verify/CMakeLists.txt =================================================================== --- tools/llvm-cfi-verify/CMakeLists.txt +++ tools/llvm-cfi-verify/CMakeLists.txt @@ -5,6 +5,7 @@ AllTargetsDisassemblers AllTargetsInfos MC + Object MCParser Support ) Index: tools/obj2yaml/wasm2yaml.cpp =================================================================== --- tools/obj2yaml/wasm2yaml.cpp +++ tools/obj2yaml/wasm2yaml.cpp @@ -54,16 +54,11 @@ if (WasmSec.Name == "name") { std::unique_ptr NameSec = make_unique(); 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 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); }