Skip to content

Commit 25476c7

Browse files
authored
Merge pull request #11966 from swiftlang/wasm-imports
[lldb][Wasm] Handle imports when parsing Wasm name sections (llvm#170960)
2 parents f9cba3b + 704654e commit 25476c7

File tree

4 files changed

+125
-38
lines changed

4 files changed

+125
-38
lines changed

lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,41 @@ struct WasmFunction {
307307
uint32_t size = 0;
308308
};
309309

310+
static llvm::Expected<uint32_t> ParseImports(DataExtractor &import_data) {
311+
// Currently this function just returns the number of imported functions.
312+
// If we want to do anything with global names in the future, we'll also
313+
// need to know those.
314+
llvm::DataExtractor data = import_data.GetAsLLVM();
315+
llvm::DataExtractor::Cursor c(0);
316+
317+
llvm::Expected<uint32_t> count = GetULEB32(data, c);
318+
if (!count)
319+
return count.takeError();
320+
321+
uint32_t function_imports = 0;
322+
for (uint32_t i = 0; c && i < *count; ++i) {
323+
// We don't need module and field names, so we can just get them as raw
324+
// strings and discard.
325+
if (!GetWasmString(data, c))
326+
return llvm::createStringError("failed to parse module name");
327+
if (!GetWasmString(data, c))
328+
return llvm::createStringError("failed to parse field name");
329+
330+
uint8_t kind = data.getU8(c);
331+
if (kind == llvm::wasm::WASM_EXTERNAL_FUNCTION)
332+
function_imports++;
333+
334+
// For function imports, this is a type index. For others it's different.
335+
// We don't need it, just need to parse it to advance the cursor.
336+
data.getULEB128(c);
337+
}
338+
339+
if (!c)
340+
return c.takeError();
341+
342+
return function_imports;
343+
}
344+
310345
static llvm::Expected<std::vector<WasmFunction>>
311346
ParseFunctions(DataExtractor &data) {
312347
lldb::offset_t offset = 0;
@@ -410,7 +445,8 @@ static llvm::Expected<std::vector<WasmSegment>> ParseData(DataExtractor &data) {
410445
static llvm::Expected<std::vector<Symbol>>
411446
ParseNames(SectionSP code_section_sp, DataExtractor &name_data,
412447
const std::vector<WasmFunction> &functions,
413-
std::vector<WasmSegment> &segments) {
448+
std::vector<WasmSegment> &segments,
449+
uint32_t num_imported_functions) {
414450

415451
llvm::DataExtractor data = name_data.GetAsLLVM();
416452
llvm::DataExtractor::Cursor c(0);
@@ -434,15 +470,29 @@ ParseNames(SectionSP code_section_sp, DataExtractor &name_data,
434470
llvm::Expected<std::string> name = GetWasmString(data, c);
435471
if (!name)
436472
return name.takeError();
437-
if (*idx >= functions.size())
473+
if (*idx >= num_imported_functions + functions.size())
438474
continue;
439-
symbols.emplace_back(
440-
symbols.size(), *name, lldb::eSymbolTypeCode,
441-
/*external=*/false, /*is_debug=*/false, /*is_trampoline=*/false,
442-
/*is_artificial=*/false, code_section_sp,
443-
functions[i].section_offset, functions[i].size,
444-
/*size_is_valid=*/true, /*contains_linker_annotations=*/false,
445-
/*flags=*/0);
475+
476+
if (*idx < num_imported_functions) {
477+
symbols.emplace_back(symbols.size(), *name, lldb::eSymbolTypeCode,
478+
/*external=*/true, /*is_debug=*/false,
479+
/*is_trampoline=*/false,
480+
/*is_artificial=*/false,
481+
/*section_sp=*/lldb::SectionSP(),
482+
/*value=*/0, /*size=*/0,
483+
/*size_is_valid=*/false,
484+
/*contains_linker_annotations=*/false,
485+
/*flags=*/0);
486+
} else {
487+
const WasmFunction &func = functions[*idx - num_imported_functions];
488+
symbols.emplace_back(symbols.size(), *name, lldb::eSymbolTypeCode,
489+
/*external=*/false, /*is_debug=*/false,
490+
/*is_trampoline=*/false, /*is_artificial=*/false,
491+
code_section_sp, func.section_offset, func.size,
492+
/*size_is_valid=*/true,
493+
/*contains_linker_annotations=*/false,
494+
/*flags=*/0);
495+
}
446496
}
447497
} break;
448498
case llvm::wasm::WASM_NAMES_DATA_SEGMENT: {
@@ -590,6 +640,20 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
590640
}
591641
}
592642

643+
// Parse the import section. The number of functions is needed because the
644+
// function index space used in the name section includes imports.
645+
if (std::optional<section_info> info =
646+
GetSectionInfo(llvm::wasm::WASM_SEC_IMPORT)) {
647+
DataExtractor import_data = ReadImageData(info->offset, info->size);
648+
llvm::Expected<uint32_t> num_imports = ParseImports(import_data);
649+
if (!num_imports) {
650+
LLDB_LOG_ERROR(log, num_imports.takeError(),
651+
"Failed to parse Wasm import section: {0}");
652+
} else {
653+
m_num_imported_functions = *num_imports;
654+
}
655+
}
656+
593657
// Parse the data section.
594658
std::optional<section_info> data_info =
595659
GetSectionInfo(llvm::wasm::WASM_SEC_DATA);
@@ -609,7 +673,7 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
609673
DataExtractor names_data = ReadImageData(info->offset, info->size);
610674
llvm::Expected<std::vector<Symbol>> symbols = ParseNames(
611675
m_sections_up->FindSectionByType(lldb::eSectionTypeCode, false),
612-
names_data, functions, segments);
676+
names_data, functions, segments, m_num_imported_functions);
613677
if (!symbols) {
614678
LLDB_LOG_ERROR(log, symbols.takeError(),
615679
"Failed to parse Wasm names: {0}");

lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class ObjectFileWasm : public ObjectFile {
146146
/// \}
147147

148148
std::vector<section_info> m_sect_infos;
149+
uint32_t m_num_imported_functions = 0;
149150
std::vector<Symbol> m_symbols;
150151
ArchSpec m_arch;
151152
UUID m_uuid;

lldb/test/Shell/Symtab/Inputs/simple.wasm.yaml

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# int j = 2;
1111
# return add(i, j);
1212
# }
13+
# Additional imports have been manually added and indexes adjusted after compiling
1314
--- !WASM
1415
FileHeader:
1516
Version: 0x1
@@ -29,6 +30,21 @@ Sections:
2930
ParamTypes: []
3031
ReturnTypes:
3132
- I32
33+
- Type: IMPORT
34+
Imports:
35+
- Module: env
36+
Field: foo
37+
Kind: FUNCTION
38+
SigIndex: 0
39+
- Module: env
40+
Field: another_import
41+
Kind: FUNCTION
42+
SigIndex: 0
43+
- Module: env
44+
Field: bar
45+
Kind: GLOBAL
46+
GlobalType: I32
47+
GlobalMutable: true
3248
- Type: FUNCTION
3349
FunctionTypes: [ 0, 1, 2, 1 ]
3450
- Type: TABLE
@@ -44,73 +60,73 @@ Sections:
4460
- Minimum: 0x2
4561
- Type: GLOBAL
4662
Globals:
47-
- Index: 0
63+
- Index: 1
4864
Type: I32
4965
Mutable: true
5066
InitExpr:
5167
Opcode: I32_CONST
5268
Value: 66576
53-
- Index: 1
69+
- Index: 2
5470
Type: I32
5571
Mutable: false
5672
InitExpr:
5773
Opcode: I32_CONST
5874
Value: 1036
59-
- Index: 2
75+
- Index: 3
6076
Type: I32
6177
Mutable: false
6278
InitExpr:
6379
Opcode: I32_CONST
6480
Value: 1024
65-
- Index: 3
81+
- Index: 4
6682
Type: I32
6783
Mutable: false
6884
InitExpr:
6985
Opcode: I32_CONST
7086
Value: 1040
71-
- Index: 4
87+
- Index: 5
7288
Type: I32
7389
Mutable: false
7490
InitExpr:
7591
Opcode: I32_CONST
7692
Value: 1040
77-
- Index: 5
93+
- Index: 6
7894
Type: I32
7995
Mutable: false
8096
InitExpr:
8197
Opcode: I32_CONST
8298
Value: 66576
83-
- Index: 6
99+
- Index: 7
84100
Type: I32
85101
Mutable: false
86102
InitExpr:
87103
Opcode: I32_CONST
88104
Value: 1024
89-
- Index: 7
105+
- Index: 8
90106
Type: I32
91107
Mutable: false
92108
InitExpr:
93109
Opcode: I32_CONST
94110
Value: 66576
95-
- Index: 8
111+
- Index: 9
96112
Type: I32
97113
Mutable: false
98114
InitExpr:
99115
Opcode: I32_CONST
100116
Value: 131072
101-
- Index: 9
117+
- Index: 10
102118
Type: I32
103119
Mutable: false
104120
InitExpr:
105121
Opcode: I32_CONST
106122
Value: 0
107-
- Index: 10
123+
- Index: 11
108124
Type: I32
109125
Mutable: false
110126
InitExpr:
111127
Opcode: I32_CONST
112128
Value: 1
113-
- Index: 11
129+
- Index: 12
114130
Type: I32
115131
Mutable: false
116132
InitExpr:
@@ -123,16 +139,16 @@ Sections:
123139
Index: 0
124140
- Name: __wasm_call_ctors
125141
Kind: FUNCTION
126-
Index: 0
142+
Index: 2
127143
- Name: add
128144
Kind: FUNCTION
129-
Index: 1
145+
Index: 3
130146
- Name: __original_main
131147
Kind: FUNCTION
132-
Index: 2
148+
Index: 4
133149
- Name: main
134150
Kind: FUNCTION
135-
Index: 3
151+
Index: 5
136152
- Name: str
137153
Kind: GLOBAL
138154
Index: 1
@@ -174,20 +190,20 @@ Sections:
174190
Index: 11
175191
- Type: CODE
176192
Functions:
177-
- Index: 0
193+
- Index: 2
178194
Locals: []
179195
Body: 0B
180-
- Index: 1
196+
- Index: 3
181197
Locals:
182198
- Type: I32
183199
Count: 1
184200
Body: 23808080800041106B21022002200036020C20022001360208200228020C20022802086A0F0B
185-
- Index: 2
201+
- Index: 4
186202
Locals:
187203
- Type: I32
188204
Count: 2
189205
Body: 23808080800041106B210020002480808080002000410036020C2000410136020820004102360204200028020820002802041081808080002101200041106A24808080800020010F0B
190-
- Index: 3
206+
- Index: 5
191207
Locals: []
192208
Body: 1082808080000F0B
193209
- Type: DATA
@@ -208,15 +224,19 @@ Sections:
208224
Name: name
209225
FunctionNames:
210226
- Index: 0
211-
Name: __wasm_call_ctors
227+
Name: foo
212228
- Index: 1
213-
Name: add
229+
Name: another_import
214230
- Index: 2
215-
Name: __original_main
231+
Name: __wasm_call_ctors
216232
- Index: 3
233+
Name: add
234+
- Index: 4
235+
Name: __original_main
236+
- Index: 5
217237
Name: main
218238
GlobalNames:
219-
- Index: 0
239+
- Index: 1
220240
Name: __stack_pointer
221241
DataSegmentNames:
222242
- Index: 0
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# RUN: yaml2obj %S/Inputs/simple.wasm.yaml -o %t.wasm
22

33
# RUN: %lldb %t.wasm -o 'image dump symtab' | FileCheck %s --check-prefix SYMTAB
4+
SYMTAB: Code 0x0000000000000000 0x0000000000000000 0x00000000 foo
5+
SYMTAB: Code 0x0000000000000000 0x0000000000000000 0x00000000 another_import
46
SYMTAB: Code 0x0000000000000002 0x0000000000000002 0x00000000 __wasm_call_ctors
57
SYMTAB: Code 0x0000000000000005 0x0000000000000029 0x00000000 add
68
SYMTAB: Code 0x000000000000002f 0x000000000000004c 0x00000000 __original_main
79
SYMTAB: Code 0x000000000000007c 0x0000000000000009 0x00000000 main
810

911
# RUN: %lldb %t.wasm -o 'image dump sections' | FileCheck %s --check-prefix SECTIONS
10-
SECTIONS: 0x0000000000000001 code [0x0000000000000000-0x0000000000000085) --- 0x000001a1 0x00000085 0x00000000 symtab-wasm.test.tmp.wasm.code
11-
SECTIONS: 0x0000000000000040 wasm-name --- 0x00000251 0x00000059 0x00000000 symtab-wasm.test.tmp.wasm.name
12-
SECTIONS: 0x0000000000000100 data [0x0000000000000400-0x0000000000000409) --- 0x00000233 0x00000009 0x00000000 symtab-wasm.test.tmp.wasm..rodata
13-
SECTIONS: 0x0000000000000200 data [0x000000000000040c-0x0000000000000410) --- 0x00000242 0x00000004 0x00000000 symtab-wasm.test.tmp.wasm..data
12+
SECTIONS: 0x0000000000000001 code [0x0000000000000000-0x0000000000000085) --- 0x000001d2 0x00000085 0x00000000 symtab-wasm.test.tmp.wasm.code
13+
SECTIONS: 0x0000000000000040 wasm-name --- 0x00000282 0x0000006e 0x00000000 symtab-wasm.test.tmp.wasm.name
14+
SECTIONS: 0x0000000000000100 data [0x0000000000000400-0x0000000000000409) --- 0x00000264 0x00000009 0x00000000 symtab-wasm.test.tmp.wasm..rodata
15+
SECTIONS: 0x0000000000000200 data [0x000000000000040c-0x0000000000000410) --- 0x00000273 0x00000004 0x00000000 symtab-wasm.test.tmp.wasm..data
1416

1517
# RUN: %lldb %t.wasm -o 'x/s 0x0000000000000400' | FileCheck %s --check-prefix STR
1618
STR: "data str"

0 commit comments

Comments
 (0)