@@ -281,7 +281,14 @@ ParseFunctions(SectionSP code_section_sp) {
281
281
return functions;
282
282
}
283
283
284
- static llvm::Expected<std::vector<AddressRange>>
284
+ struct WasmSegment {
285
+ WasmSegment (SectionSP section_sp, lldb::offset_t offset, uint32_t size)
286
+ : address_range(section_sp, offset, size) {};
287
+ std::string name;
288
+ AddressRange address_range;
289
+ };
290
+
291
+ static llvm::Expected<std::vector<WasmSegment>>
285
292
ParseData (SectionSP data_section_sp) {
286
293
DataExtractor data;
287
294
data_section_sp->GetSectionData (data);
@@ -292,16 +299,32 @@ ParseData(SectionSP data_section_sp) {
292
299
if (segment_count > std::numeric_limits<uint32_t >::max ())
293
300
return llvm::createStringError (" segment count overflows uint32_t" );
294
301
295
- std::vector<AddressRange > segments;
302
+ std::vector<WasmSegment > segments;
296
303
segments.reserve (segment_count);
297
304
298
305
for (uint32_t i = 0 ; i < segment_count; ++i) {
299
306
const uint64_t flags = data.GetULEB128 (&offset);
300
307
if (flags > std::numeric_limits<uint32_t >::max ())
301
308
return llvm::createStringError (" segment flags overflows uint32_t" );
302
309
310
+ // Data segments have a mode that identifies them as either passive or
311
+ // active. An active data segment copies its contents into a memory during
312
+ // instantiation, as specified by a memory index and a constant expression
313
+ // defining an offset into that memory.
314
+ if (flags & llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) {
315
+ const uint64_t memidx = data.GetULEB128 (&offset);
316
+ if (memidx > std::numeric_limits<uint32_t >::max ())
317
+ return llvm::createStringError (" memidx overflows uint32_t" );
318
+ }
319
+
320
+ if ((flags & llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0 ) {
321
+ // Skip over the constant expression.
322
+ for (uint8_t b = 0 ; b != llvm::wasm::WASM_OPCODE_END;)
323
+ b = data.GetU8 (&offset);
324
+ }
325
+
303
326
const uint64_t segment_size = data.GetULEB128 (&offset);
304
- if (flags > std::numeric_limits<uint32_t >::max ())
327
+ if (segment_size > std::numeric_limits<uint32_t >::max ())
305
328
return llvm::createStringError (" segment size overflows uint32_t" );
306
329
307
330
segments.emplace_back (data_section_sp, offset, segment_size);
@@ -319,7 +342,7 @@ ParseData(SectionSP data_section_sp) {
319
342
static llvm::Expected<std::vector<Symbol>>
320
343
ParseNames (SectionSP name_section_sp,
321
344
const std::vector<AddressRange> &function_ranges,
322
- const std::vector<AddressRange > &segment_ranges ) {
345
+ std::vector<WasmSegment > &segments ) {
323
346
DataExtractor name_section_data;
324
347
name_section_sp->GetSectionData (name_section_data);
325
348
@@ -358,12 +381,14 @@ ParseNames(SectionSP name_section_sp,
358
381
for (uint64_t i = 0 ; c && i < count; ++i) {
359
382
const uint64_t idx = data.getULEB128 (c);
360
383
const std::optional<std::string> name = GetWasmString (data, c);
361
- if (!name || idx >= segment_ranges .size ())
384
+ if (!name || idx >= segments .size ())
362
385
continue ;
386
+ // Update the segment name.
387
+ segments[i].name = *name;
363
388
symbols.emplace_back (
364
389
symbols.size (), Mangled (*name), lldb::eSymbolTypeData,
365
390
/* external=*/ false , /* is_debug=*/ false , /* is_trampoline=*/ false ,
366
- /* is_artificial=*/ false , segment_ranges[idx] ,
391
+ /* is_artificial=*/ false , segments[i]. address_range ,
367
392
/* size_is_valid=*/ true , /* contains_linker_annotations=*/ false ,
368
393
/* flags=*/ 0 );
369
394
}
@@ -391,33 +416,34 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
391
416
392
417
// The name section contains names and indexes. First parse the data from the
393
418
// relevant sections so we can access it by its index.
394
- std::vector<AddressRange> function_ranges ;
395
- std::vector<AddressRange> segment_ranges ;
419
+ std::vector<AddressRange> functions ;
420
+ std::vector<WasmSegment> segments ;
396
421
397
422
// Parse the code section.
398
423
if (SectionSP code_section_sp =
399
424
m_sections_up->FindSectionByType (lldb::eSectionTypeCode, false )) {
400
- llvm::Expected<std::vector<AddressRange>> functions =
425
+ llvm::Expected<std::vector<AddressRange>> maybe_functions =
401
426
ParseFunctions (code_section_sp);
402
- if (!functions ) {
403
- LLDB_LOG_ERROR (log, functions .takeError (),
427
+ if (!maybe_functions ) {
428
+ LLDB_LOG_ERROR (log, maybe_functions .takeError (),
404
429
" Failed to parse Wasm code section: {0}" );
405
430
return ;
406
431
}
407
- function_ranges = *functions ;
432
+ functions = *maybe_functions ;
408
433
}
409
434
410
435
// 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 =
436
+ SectionSP data_section_sp =
437
+ m_sections_up->FindSectionByType (lldb::eSectionTypeData, false );
438
+ if (data_section_sp) {
439
+ llvm::Expected<std::vector<WasmSegment>> maybe_segments =
414
440
ParseData (data_section_sp);
415
- if (!segments ) {
416
- LLDB_LOG_ERROR (log, segments .takeError (),
441
+ if (!maybe_segments ) {
442
+ LLDB_LOG_ERROR (log, maybe_segments .takeError (),
417
443
" Failed to parse Wasm data section: {0}" );
418
444
return ;
419
445
}
420
- segment_ranges = *segments ;
446
+ segments = *maybe_segments ;
421
447
}
422
448
423
449
// Parse the name section.
@@ -429,7 +455,7 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
429
455
}
430
456
431
457
llvm::Expected<std::vector<Symbol>> symbols =
432
- ParseNames (name_section_sp, function_ranges, segment_ranges );
458
+ ParseNames (name_section_sp, functions, segments );
433
459
if (!symbols) {
434
460
LLDB_LOG_ERROR (log, symbols.takeError (), " Failed to parse Wasm names: {0}" );
435
461
return ;
@@ -438,6 +464,26 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
438
464
for (const Symbol &symbol : *symbols)
439
465
symtab.AddSymbol (symbol);
440
466
467
+ lldb::user_id_t segment_id = 0 ;
468
+ for (const WasmSegment &segment : segments) {
469
+ const lldb::addr_t segment_addr =
470
+ segment.address_range .GetBaseAddress ().GetFileAddress ();
471
+ const size_t segment_size = segment.address_range .GetByteSize ();
472
+ SectionSP segment_sp = std::make_shared<Section>(
473
+ /* parent_section_sp=*/ data_section_sp, GetModule (),
474
+ /* obj_file=*/ this ,
475
+ ++segment_id << 8 , // 1-based segment index, shifted by 8 bits to avoid
476
+ // collision with section IDs.
477
+ ConstString (segment.name ), eSectionTypeData,
478
+ /* file_vm_addr=*/ segment_addr,
479
+ /* vm_size=*/ segment_size,
480
+ /* file_offset=*/ segment_addr,
481
+ /* file_size=*/ segment_size,
482
+ /* log2align=*/ 0 , /* flags=*/ 0 );
483
+ m_sections_up->AddSection (segment_sp);
484
+ GetModule ()->GetSectionList ()->AddSection (segment_sp);
485
+ }
486
+
441
487
symtab.Finalize ();
442
488
}
443
489
0 commit comments