diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test @@ -0,0 +1,49 @@ +# RUN: yaml2obj -o %t.wasm %s +# RUN: llvm-objdump -d %t.wasm | FileCheck %s + +--- !WASM +FileHeader: + Version: 0x1 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ParamTypes: [] + ReturnTypes: [] + - Index: 1 + ParamTypes: + - I32 + ReturnTypes: + - I32 + - Type: FUNCTION + FunctionTypes: [ 0, 1 ] + - Type: CODE + Functions: + - Index: 0 + Locals: [] + Body: 0B + - Index: 1 + Locals: [] + Body: 20000B + - Type: CUSTOM + Name: name + FunctionNames: + - Index: 0 + Name: f + - Index: 1 + Name: g +... + +# CHECK: Disassembly of section CODE: +# CHECK-EMPTY: +# CHECK-NEXT: 00000000 : +# CHECK-NEXT: # 2 functions in section. +# CHECK-EMPTY: +# CHECK-NEXT: 00000001 : +# CHECK-EMPTY: +# CHECK-NEXT: 3: 0b end +# CHECK-EMPTY: +# CHECK-NEXT: 00000004 : +# CHECK-EMPTY: +# CHECK-NEXT: 6: 20 00 local.get 0 +# CHECK-NEXT: 8: 0b end diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test @@ -0,0 +1,42 @@ +# RUN: yaml2obj -o %t.wasm %s +# RUN: llvm-objdump -d %t.wasm | FileCheck %s + +--- !WASM +FileHeader: + Version: 0x1 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ParamTypes: [] + ReturnTypes: [] + - Index: 1 + ParamTypes: + - I32 + ReturnTypes: + - I32 + - Type: FUNCTION + FunctionTypes: [ 0, 1 ] + - Type: CODE + Functions: + - Index: 0 + Locals: [] + Body: 0B + - Index: 1 + Locals: [] + Body: 20000B +... + +# CHECK: Disassembly of section CODE: +# CHECK-EMPTY: +# CHECK-NEXT: 00000000 : +# CHECK-NEXT: # 2 functions in section. +# CHECK-EMPTY: +# CHECK-NEXT: 00000001 <>: +# CHECK-EMPTY: +# CHECK-NEXT: 3: 0b end +# CHECK-EMPTY: +# CHECK-NEXT: 00000004 <>: +# CHECK-EMPTY: +# CHECK-NEXT: 6: 20 00 local.get 0 +# CHECK-NEXT: 8: 0b end diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -736,6 +736,43 @@ llvm_unreachable("Unsupported binary format"); } +static Optional getWasmCodeSection(const WasmObjectFile *Obj) { + for (auto SecI : Obj->sections()) { + const WasmSection &Section = Obj->getWasmSection(SecI); + if (Section.Type == wasm::WASM_SEC_CODE) + return SecI; + } + return None; +} + +static void +addMissingWasmCodeSymbols(const WasmObjectFile *Obj, + std::map &AllSymbols) { + Optional Section = getWasmCodeSection(Obj); + if (!Section) + return; + SectionSymbolsTy &Symbols = AllSymbols[*Section]; + + std::set SymbolAddresses; + for (const auto &Sym : Symbols) + SymbolAddresses.insert(Sym.Addr); + + for (const wasm::WasmFunction &Function : Obj->functions()) { + uint64_t Address = Function.CodeSectionOffset; + // Only add fallback symbols for functions not already present in the symbol + // table. + if (SymbolAddresses.count(Address)) + continue; + // This function has no symbol, so it should have no SymbolName. + assert(Function.SymbolName.empty()); + // We use DebugName for the name, though it may be empty if there is no + // "name" custom section, or that section is missing a name for this + // function. + StringRef Name = Function.DebugName; + Symbols.emplace_back(Address, Name, ELF::STT_NOTYPE); + } +} + static void addPltEntries(const ObjectFile *Obj, std::map &AllSymbols, StringSaver &Saver) { @@ -1126,6 +1163,9 @@ if (AllSymbols.empty() && Obj->isELF()) addDynamicElfSymbols(Obj, AllSymbols); + if (Obj->isWasm()) + addMissingWasmCodeSymbols(cast(Obj), AllSymbols); + BumpPtrAllocator A; StringSaver Saver(A); addPltEntries(Obj, AllSymbols, Saver);