[llvm-objdump][WebAssembly] Fix llvm-objdump on files without symbols

If a file has no symbols, perhaps because it is a linked executable,
synthesize some symbols by walking the code section.  Otherwise the
disassembler will try to treat the whole code section as a function,
which won't parse.  Fixes https://bugs.llvm.org/show_bug.cgi?id=50957.

Differential Revision: https://reviews.llvm.org/D105539
This commit is contained in:
Andy Wingo 2021-07-07 11:13:13 +02:00
parent 4504e1134c
commit db69ea40a9
3 changed files with 131 additions and 0 deletions

View File

@ -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 <CODE>:
# CHECK-NEXT: # 2 functions in section.
# CHECK-EMPTY:
# CHECK-NEXT: 00000001 <f>:
# CHECK-EMPTY:
# CHECK-NEXT: 3: 0b end
# CHECK-EMPTY:
# CHECK-NEXT: 00000004 <g>:
# CHECK-EMPTY:
# CHECK-NEXT: 6: 20 00 local.get 0
# CHECK-NEXT: 8: 0b end

View File

@ -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 <CODE>:
# 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

View File

@ -736,6 +736,43 @@ addDynamicElfSymbols(const ObjectFile *Obj,
llvm_unreachable("Unsupported binary format");
}
static Optional<SectionRef> 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<SectionRef, SectionSymbolsTy> &AllSymbols) {
Optional<SectionRef> Section = getWasmCodeSection(Obj);
if (!Section)
return;
SectionSymbolsTy &Symbols = AllSymbols[*Section];
std::set<uint64_t> 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<SectionRef, SectionSymbolsTy> &AllSymbols,
StringSaver &Saver) {
@ -1126,6 +1163,9 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (AllSymbols.empty() && Obj->isELF())
addDynamicElfSymbols(Obj, AllSymbols);
if (Obj->isWasm())
addMissingWasmCodeSymbols(cast<WasmObjectFile>(Obj), AllSymbols);
BumpPtrAllocator A;
StringSaver Saver(A);
addPltEntries(Obj, AllSymbols, Saver);