Index: include/llvm/Object/Wasm.h =================================================================== --- include/llvm/Object/Wasm.h +++ include/llvm/Object/Wasm.h @@ -97,9 +97,11 @@ const uint8_t *getPtr(size_t Offset) const; Error parseCustomSection(wasm::WasmSection &Sec, const uint8_t *Ptr, size_t Length); + Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); wasm::WasmObjectHeader Header; std::vector Sections; + std::vector Symbols; }; } // end namespace object Index: include/llvm/Support/Wasm.h =================================================================== --- include/llvm/Support/Wasm.h +++ include/llvm/Support/Wasm.h @@ -81,6 +81,11 @@ WASM_OPCODE_F64_CONST = 0x44, }; +enum : unsigned { + WASM_NAMES_FUNCTION = 0x1, + WASM_NAMES_LOCAL = 0x2, +}; + #define WASM_RELOC(name, value) name = value, enum : unsigned { Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -103,9 +103,51 @@ } } +Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) { + while (Ptr < End) { + uint32_t Type = readULEB128(Ptr); + uint32_t Size = readULEB128(Ptr); + switch (Type) { + case wasm::WASM_NAMES_FUNCTION: { + uint32_t Count = readULEB128(Ptr); + while (Count--) { + uint32_t Index = readULEB128(Ptr); + StringRef Name = readString(Ptr); + Symbols.push_back(Name); + } + break; + } + case wasm::WASM_NAMES_LOCAL: { + // Ignore local names for now + uint32_t FuncCount = readULEB128(Ptr); + while (FuncCount--) { + uint32_t FuncIndex = readULEB128(Ptr); + uint32_t LocalCount = readULEB128(Ptr); + while (LocalCount--) { + uint32_t LocalIndex = readULEB128(Ptr); + StringRef Name = readString(Ptr); + } + } + break; + } + default: + Ptr += Size; + break; + } + } + + assert(Ptr == End); + return Error::success(); +} + Error WasmObjectFile::parseCustomSection(wasm::WasmSection &Sec, const uint8_t *Ptr, size_t Length) { + const uint8_t *End = Ptr + Length; Sec.Name = readString(Ptr); + if (Sec.Name == "name") { + if (Error Err = parseNameSection(Ptr, End)) + return Err; + } return Error::success(); } @@ -118,26 +160,29 @@ } void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { - llvm_unreachable("not yet implemented"); + Symb.d.a++; } std::error_code WasmObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { - llvm_unreachable("not yet implemented"); - return object_error::invalid_symbol_index; + OS << Symbols[Symb.d.a]; + return std::error_code(); } uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const { - llvm_unreachable("not yet implemented"); - return 0; + return object::SymbolRef::SF_Global | SymbolRef::SF_Executable; } basic_symbol_iterator WasmObjectFile::symbol_begin() const { - return BasicSymbolRef(DataRefImpl(), this); + DataRefImpl Ref; + Ref.d.a = 0; + return BasicSymbolRef(Ref, this); } basic_symbol_iterator WasmObjectFile::symbol_end() const { - return BasicSymbolRef(DataRefImpl(), this); + DataRefImpl Ref; + Ref.d.a = Symbols.size(); + return BasicSymbolRef(Ref, this); } Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const { @@ -146,8 +191,7 @@ } Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { - llvm_unreachable("not yet implemented"); - return errorCodeToError(object_error::invalid_symbol_index); + return (uint64_t)Symb.d.a; } uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { Index: test/tools/llvm-nm/wasm/externalonly.txt =================================================================== --- /dev/null +++ test/tools/llvm-nm/wasm/externalonly.txt @@ -0,0 +1,4 @@ +# RUN: llvm-nm -g %p/Inputs/trivial.obj.wasm | FileCheck %s + +# CHECK: $func0 +# CHECK: $import Index: tools/llvm-nm/llvm-nm.cpp =================================================================== --- tools/llvm-nm/llvm-nm.cpp +++ tools/llvm-nm/llvm-nm.cpp @@ -29,6 +29,7 @@ #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Wasm.h" #include "llvm/Support/COFF.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -270,6 +271,8 @@ return Triple(IRObj->getTargetTriple()).isArch64Bit(); if (isa(Obj)) return false; + if (isa(Obj)) + return false; if (MachOObjectFile *MachO = dyn_cast(&Obj)) return MachO->is64Bit(); return cast(Obj).getBytesInAddress() == 8; @@ -883,6 +886,13 @@ return '?'; } +static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) { + uint32_t Flags = I->getFlags(); + if (Flags & SymbolRef::SF_Executable) + return 't'; + return 'd'; +} + static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { uint32_t Flags = I->getFlags(); // FIXME: should we print 'b'? At the IR level we cannot be sure if this @@ -924,6 +934,8 @@ Ret = getSymbolNMTypeChar(*COFF, I); else if (MachOObjectFile *MachO = dyn_cast(&Obj)) Ret = getSymbolNMTypeChar(*MachO, I); + else if (WasmObjectFile *Wasm = dyn_cast(&Obj)) + Ret = getSymbolNMTypeChar(*Wasm, I); else Ret = getSymbolNMTypeChar(cast(Obj), I);