[lld] [llvm] [Object][Wasm] Generate symbol info from name section names (PR #81063)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 16:40:23 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Derek Schuff (dschuff)
<details>
<summary>Changes</summary>
Currently symbol info is generated from a linking section or from export names. This PR generates
symbols in a WasmObjectFile from the name section as well, which allows tools like objdump and
nm to show useful information for more linked binaryes. There are some limitations: most notably
that we don't assume any particular ABI, so we don't get detailed information about data symbols
if the segments are merged (which is the default).
---
Full diff: https://github.com/llvm/llvm-project/pull/81063.diff
2 Files Affected:
- (modified) llvm/lib/Object/WasmObjectFile.cpp (+45-4)
- (added) llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml (+87)
``````````diff
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 8c1bbe9c264593..ea1715446d9d90 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -508,10 +508,17 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
llvm::DenseSet<uint64_t> SeenGlobals;
llvm::DenseSet<uint64_t> SeenSegments;
+ // If there is symbol info from the export section, this info will supersede
+ // it, but not info from a linking section
+ if (!HasLinkingSection) {
+ Symbols.clear();
+ }
+
while (Ctx.Ptr < Ctx.End) {
uint8_t Type = readUint8(Ctx);
uint32_t Size = readVaruint32(Ctx);
const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
+
switch (Type) {
case wasm::WASM_NAMES_FUNCTION:
case wasm::WASM_NAMES_GLOBAL:
@@ -521,6 +528,16 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
uint32_t Index = readVaruint32(Ctx);
StringRef Name = readString(Ctx);
wasm::NameType nameType = wasm::NameType::FUNCTION;
+ wasm::WasmSymbolInfo Info{Name,
+ /*Kind */ wasm::WASM_SYMBOL_TYPE_FUNCTION,
+ /* Flags */ 0,
+ /* ImportModule */ std::nullopt,
+ /* ImportName */ std::nullopt,
+ /* ExportName */ std::nullopt,
+ {/* ElementIndex */ Index}};
+ const wasm::WasmSignature *Signature = nullptr;
+ const wasm::WasmGlobalType *GlobalType = nullptr;
+ const wasm::WasmTableType *TableType = nullptr;
if (Type == wasm::WASM_NAMES_FUNCTION) {
if (!SeenFunctions.insert(Index).second)
return make_error<GenericBinaryError>(
@@ -529,26 +546,50 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>("invalid function name entry",
object_error::parse_failed);
- if (isDefinedFunctionIndex(Index))
- getDefinedFunction(Index).DebugName = Name;
+ if (isDefinedFunctionIndex(Index)) {
+ wasm::WasmFunction &F = getDefinedFunction(Index);
+ F.DebugName = Name;
+ Signature = &Signatures[F.SigIndex];
+ if (F.ExportName) {
+ Info.ExportName = F.ExportName;
+ Info.Flags |= wasm::WASM_SYMBOL_BINDING_GLOBAL;
+ } else {
+ Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+ }
+ } else {
+ Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+ }
} else if (Type == wasm::WASM_NAMES_GLOBAL) {
- nameType = wasm::NameType::GLOBAL;
if (!SeenGlobals.insert(Index).second)
return make_error<GenericBinaryError>("global named more than once",
object_error::parse_failed);
if (!isValidGlobalIndex(Index) || Name.empty())
return make_error<GenericBinaryError>("invalid global name entry",
object_error::parse_failed);
+ nameType = wasm::NameType::GLOBAL;
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_GLOBAL;
+ if (isDefinedGlobalIndex(Index)) {
+ GlobalType = &getDefinedGlobal(Index).Type;
+ } else {
+ Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+ }
} else {
- nameType = wasm::NameType::DATA_SEGMENT;
if (!SeenSegments.insert(Index).second)
return make_error<GenericBinaryError>(
"segment named more than once", object_error::parse_failed);
if (Index > DataSegments.size())
return make_error<GenericBinaryError>("invalid data segment name entry",
object_error::parse_failed);
+ nameType = wasm::NameType::DATA_SEGMENT;
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_DATA;
+ Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+ assert(Index < DataSegments.size());
+ Info.DataRef = wasm::WasmDataReference{
+ Index, 0, DataSegments[Index].Data.Content.size()};
}
DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
+ if (!HasLinkingSection)
+ Symbols.emplace_back(Info, GlobalType, TableType, Signature);
}
break;
}
diff --git a/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml b/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml
new file mode 100644
index 00000000000000..622a6060b902a3
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml
@@ -0,0 +1,87 @@
+# RUN: yaml2obj %s -o %t.wasm
+# RUN: llvm-objdump -t %t.wasm | FileCheck %s
+#
+# CHECK: SYMBOL TABLE:
+# CHECK-NEXT: 00000000 F *UND* my_func_import_name
+# CHECK-NEXT: 00000083 g F CODE my_func_export_name
+# CHECK-NEXT: 00000086 l F CODE my_func_local_name
+# CHECK-NEXT: 00000000 *UND* my_global_import_name
+# CHECK-NEXT: 00000001 g GLOBAL my_global_export_name
+# CHECK-NEXT: 00000000 l O DATA my_datasegment_name
+
+--- !WASM
+FileHeader:
+ Version: 0x1
+Sections:
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes: []
+ ReturnTypes: []
+ - Type: IMPORT
+ Imports:
+ - Module: env
+ Field: foo
+ Kind: FUNCTION
+ SigIndex: 0
+ - Module: env
+ Field: bar
+ Kind: GLOBAL
+ GlobalType: I32
+ GlobalMutable: true
+ - Module: env
+ Field: memory
+ Kind: MEMORY
+ Memory:
+ Minimum: 0x1
+ - Type: FUNCTION
+ FunctionTypes: [ 0, 0 ]
+ - Type: GLOBAL
+ Globals:
+ - Index: 1
+ Mutable: false
+ Type: I32
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 42
+ - Type: EXPORT
+ Exports:
+ - Name: my_func_export
+ Kind: FUNCTION
+ Index: 1
+ - Name: my_global_export
+ Kind: GLOBAL
+ Index: 1
+ - Type: CODE
+ Functions:
+ - Index: 1
+ Locals:
+ Body: 00
+ - Index: 2
+ Locals:
+ Body: 00
+ - Type: DATA
+ Segments:
+ - SectionOffset: 0
+ InitFlags: 0
+ Offset:
+ Opcode: I32_CONST
+ Value: 0
+ Content: 'abcd1234'
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: my_func_import_name
+ - Index: 1
+ Name: my_func_export_name
+ - Index: 2
+ Name: my_func_local_name
+ GlobalNames:
+ - Index: 0
+ Name: my_global_import_name
+ - Index: 1
+ Name: my_global_export_name
+ DataSegmentNames:
+ - Index: 0
+ Name: my_datasegment_name
``````````
</details>
https://github.com/llvm/llvm-project/pull/81063
More information about the llvm-commits
mailing list