@@ -251,19 +251,19 @@ bool ObjectFileWasm::ParseHeader() {
251
251
252
252
static llvm::Expected<std::vector<AddressRange>>
253
253
ParseFunctions (SectionSP code_section_sp) {
254
- DataExtractor code_section_data ;
255
- code_section_sp->GetSectionData (code_section_data );
254
+ DataExtractor data ;
255
+ code_section_sp->GetSectionData (data );
256
256
lldb::offset_t offset = 0 ;
257
257
258
- const uint64_t function_count = code_section_data .GetULEB128 (&offset);
258
+ const uint64_t function_count = data .GetULEB128 (&offset);
259
259
if (function_count > std::numeric_limits<uint32_t >::max ())
260
260
return llvm::createStringError (" function count overflows uint32_t" );
261
261
262
262
std::vector<AddressRange> functions;
263
263
functions.reserve (function_count);
264
264
265
265
for (uint32_t i = 0 ; i < function_count; ++i) {
266
- const uint64_t function_size = code_section_data .GetULEB128 (&offset);
266
+ const uint64_t function_size = data .GetULEB128 (&offset);
267
267
if (function_size > std::numeric_limits<uint32_t >::max ())
268
268
return llvm::createStringError (" function size overflows uint32_t" );
269
269
// llvm-objdump considers the ULEB with the function size to be part of the
@@ -281,9 +281,45 @@ ParseFunctions(SectionSP code_section_sp) {
281
281
return functions;
282
282
}
283
283
284
+ static llvm::Expected<std::vector<AddressRange>>
285
+ ParseData (SectionSP data_section_sp) {
286
+ DataExtractor data;
287
+ data_section_sp->GetSectionData (data);
288
+
289
+ lldb::offset_t offset = 0 ;
290
+
291
+ const uint64_t segment_count = data.GetULEB128 (&offset);
292
+ if (segment_count > std::numeric_limits<uint32_t >::max ())
293
+ return llvm::createStringError (" segment count overflows uint32_t" );
294
+
295
+ std::vector<AddressRange> segments;
296
+ segments.reserve (segment_count);
297
+
298
+ for (uint32_t i = 0 ; i < segment_count; ++i) {
299
+ const uint64_t flags = data.GetULEB128 (&offset);
300
+ if (flags > std::numeric_limits<uint32_t >::max ())
301
+ return llvm::createStringError (" segment flags overflows uint32_t" );
302
+
303
+ const uint64_t segment_size = data.GetULEB128 (&offset);
304
+ if (flags > std::numeric_limits<uint32_t >::max ())
305
+ return llvm::createStringError (" segment size overflows uint32_t" );
306
+
307
+ segments.emplace_back (data_section_sp, offset, segment_size);
308
+
309
+ std::optional<lldb::offset_t > next_offset =
310
+ llvm::checkedAddUnsigned (offset, segment_size);
311
+ if (!next_offset)
312
+ return llvm::createStringError (" segment offset overflows uint64_t" );
313
+ offset = *next_offset;
314
+ }
315
+
316
+ return segments;
317
+ }
318
+
284
319
static llvm::Expected<std::vector<Symbol>>
285
320
ParseNames (SectionSP name_section_sp,
286
- const std::vector<AddressRange> &functions) {
321
+ const std::vector<AddressRange> &function_ranges,
322
+ const std::vector<AddressRange> &segment_ranges) {
287
323
DataExtractor name_section_data;
288
324
name_section_sp->GetSectionData (name_section_data);
289
325
@@ -305,17 +341,34 @@ ParseNames(SectionSP name_section_sp,
305
341
for (uint64_t i = 0 ; c && i < count; ++i) {
306
342
const uint64_t idx = data.getULEB128 (c);
307
343
const std::optional<std::string> name = GetWasmString (data, c);
308
- if (!name || idx >= functions .size ())
344
+ if (!name || idx >= function_ranges .size ())
309
345
continue ;
310
346
symbols.emplace_back (
311
347
symbols.size (), Mangled (*name), lldb::eSymbolTypeCode,
312
348
/* external=*/ false , /* is_debug=*/ false , /* is_trampoline=*/ false ,
313
- /* is_artificial=*/ false , functions [idx],
349
+ /* is_artificial=*/ false , function_ranges [idx],
314
350
/* size_is_valid=*/ true , /* contains_linker_annotations=*/ false ,
315
351
/* flags=*/ 0 );
316
352
}
317
353
} break ;
318
- case llvm::wasm::WASM_NAMES_DATA_SEGMENT:
354
+ case llvm::wasm::WASM_NAMES_DATA_SEGMENT: {
355
+ const uint64_t count = data.getULEB128 (c);
356
+ if (count > std::numeric_limits<uint32_t >::max ())
357
+ return llvm::createStringError (" data count overflows uint32_t" );
358
+ for (uint64_t i = 0 ; c && i < count; ++i) {
359
+ const uint64_t idx = data.getULEB128 (c);
360
+ const std::optional<std::string> name = GetWasmString (data, c);
361
+ if (!name || idx >= segment_ranges.size ())
362
+ continue ;
363
+ symbols.emplace_back (
364
+ symbols.size (), Mangled (*name), lldb::eSymbolTypeData,
365
+ /* external=*/ false , /* is_debug=*/ false , /* is_trampoline=*/ false ,
366
+ /* is_artificial=*/ false , segment_ranges[idx],
367
+ /* size_is_valid=*/ true , /* contains_linker_annotations=*/ false ,
368
+ /* flags=*/ 0 );
369
+ }
370
+
371
+ } break ;
319
372
case llvm::wasm::WASM_NAMES_GLOBAL:
320
373
case llvm::wasm::WASM_NAMES_LOCAL:
321
374
default :
@@ -336,21 +389,35 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
336
389
assert (m_sections_up && " sections must be parsed" );
337
390
Log *log = GetLog (LLDBLog::Object);
338
391
339
- // The name section contains names and indexes. First parse the functions from
340
- // the code section so we can access them by their index.
341
- SectionSP code_section_sp =
342
- m_sections_up->FindSectionByType (lldb::eSectionTypeCode, false );
343
- if (!code_section_sp) {
344
- LLDB_LOG (log, " Failed to parse Wasm symbol table: no functions section" );
345
- return ;
392
+ // The name section contains names and indexes. First parse the data from the
393
+ // relevant sections so we can access it by its index.
394
+ std::vector<AddressRange> function_ranges;
395
+ std::vector<AddressRange> segment_ranges;
396
+
397
+ // Parse the code section.
398
+ if (SectionSP code_section_sp =
399
+ m_sections_up->FindSectionByType (lldb::eSectionTypeCode, false )) {
400
+ llvm::Expected<std::vector<AddressRange>> functions =
401
+ ParseFunctions (code_section_sp);
402
+ if (!functions) {
403
+ LLDB_LOG_ERROR (log, functions.takeError (),
404
+ " Failed to parse Wasm code section: {0}" );
405
+ return ;
406
+ }
407
+ function_ranges = *functions;
346
408
}
347
409
348
- llvm::Expected<std::vector<AddressRange>> functions =
349
- ParseFunctions (code_section_sp);
350
- if (!functions) {
351
- LLDB_LOG_ERROR (log, functions.takeError (),
352
- " Failed to parse Wasm functions: {0}" );
353
- return ;
410
+ // Parse the data section.
411
+ if (SectionSP data_section_sp =
412
+ m_sections_up->FindSectionByType (lldb::eSectionTypeData, false )) {
413
+ llvm::Expected<std::vector<AddressRange>> segments =
414
+ ParseData (data_section_sp);
415
+ if (!segments) {
416
+ LLDB_LOG_ERROR (log, segments.takeError (),
417
+ " Failed to parse Wasm data section: {0}" );
418
+ return ;
419
+ }
420
+ segment_ranges = *segments;
354
421
}
355
422
356
423
// Parse the name section.
@@ -362,7 +429,7 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
362
429
}
363
430
364
431
llvm::Expected<std::vector<Symbol>> symbols =
365
- ParseNames (name_section_sp, *functions );
432
+ ParseNames (name_section_sp, function_ranges, segment_ranges );
366
433
if (!symbols) {
367
434
LLDB_LOG_ERROR (log, symbols.takeError (), " Failed to parse Wasm names: {0}" );
368
435
return ;
@@ -408,6 +475,9 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
408
475
// For this reason Section::GetFileAddress() must return zero for the
409
476
// Code section.
410
477
vm_addr = 0 ;
478
+ } else if (llvm::wasm::WASM_SEC_DATA == sect_info.id ) {
479
+ section_type = eSectionTypeData;
480
+ section_name = ConstString (" data" );
411
481
} else {
412
482
section_type = GetSectionTypeFromName (sect_info.name .GetStringRef ());
413
483
if (section_type == eSectionTypeOther)
0 commit comments