@@ -281,7 +281,14 @@ ParseFunctions(SectionSP code_section_sp) {
281281 return functions;
282282}
283283
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>>
285292ParseData (SectionSP data_section_sp) {
286293 DataExtractor data;
287294 data_section_sp->GetSectionData (data);
@@ -292,16 +299,32 @@ ParseData(SectionSP data_section_sp) {
292299 if (segment_count > std::numeric_limits<uint32_t >::max ())
293300 return llvm::createStringError (" segment count overflows uint32_t" );
294301
295- std::vector<AddressRange > segments;
302+ std::vector<WasmSegment > segments;
296303 segments.reserve (segment_count);
297304
298305 for (uint32_t i = 0 ; i < segment_count; ++i) {
299306 const uint64_t flags = data.GetULEB128 (&offset);
300307 if (flags > std::numeric_limits<uint32_t >::max ())
301308 return llvm::createStringError (" segment flags overflows uint32_t" );
302309
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+
303326 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 ())
305328 return llvm::createStringError (" segment size overflows uint32_t" );
306329
307330 segments.emplace_back (data_section_sp, offset, segment_size);
@@ -319,7 +342,7 @@ ParseData(SectionSP data_section_sp) {
319342static llvm::Expected<std::vector<Symbol>>
320343ParseNames (SectionSP name_section_sp,
321344 const std::vector<AddressRange> &function_ranges,
322- const std::vector<AddressRange > &segment_ranges ) {
345+ std::vector<WasmSegment > &segments ) {
323346 DataExtractor name_section_data;
324347 name_section_sp->GetSectionData (name_section_data);
325348
@@ -358,12 +381,14 @@ ParseNames(SectionSP name_section_sp,
358381 for (uint64_t i = 0 ; c && i < count; ++i) {
359382 const uint64_t idx = data.getULEB128 (c);
360383 const std::optional<std::string> name = GetWasmString (data, c);
361- if (!name || idx >= segment_ranges .size ())
384+ if (!name || idx >= segments .size ())
362385 continue ;
386+ // Update the segment name.
387+ segments[i].name = *name;
363388 symbols.emplace_back (
364389 symbols.size (), Mangled (*name), lldb::eSymbolTypeData,
365390 /* external=*/ false , /* is_debug=*/ false , /* is_trampoline=*/ false ,
366- /* is_artificial=*/ false , segment_ranges[idx] ,
391+ /* is_artificial=*/ false , segments[i]. address_range ,
367392 /* size_is_valid=*/ true , /* contains_linker_annotations=*/ false ,
368393 /* flags=*/ 0 );
369394 }
@@ -391,33 +416,34 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
391416
392417 // The name section contains names and indexes. First parse the data from the
393418 // 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 ;
396421
397422 // Parse the code section.
398423 if (SectionSP code_section_sp =
399424 m_sections_up->FindSectionByType (lldb::eSectionTypeCode, false )) {
400- llvm::Expected<std::vector<AddressRange>> functions =
425+ llvm::Expected<std::vector<AddressRange>> maybe_functions =
401426 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 (),
404429 " Failed to parse Wasm code section: {0}" );
405430 return ;
406431 }
407- function_ranges = *functions ;
432+ functions = *maybe_functions ;
408433 }
409434
410435 // 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 =
414440 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 (),
417443 " Failed to parse Wasm data section: {0}" );
418444 return ;
419445 }
420- segment_ranges = *segments ;
446+ segments = *maybe_segments ;
421447 }
422448
423449 // Parse the name section.
@@ -429,7 +455,7 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
429455 }
430456
431457 llvm::Expected<std::vector<Symbol>> symbols =
432- ParseNames (name_section_sp, function_ranges, segment_ranges );
458+ ParseNames (name_section_sp, functions, segments );
433459 if (!symbols) {
434460 LLDB_LOG_ERROR (log, symbols.takeError (), " Failed to parse Wasm names: {0}" );
435461 return ;
@@ -438,6 +464,26 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
438464 for (const Symbol &symbol : *symbols)
439465 symtab.AddSymbol (symbol);
440466
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+
441487 symtab.Finalize ();
442488}
443489
0 commit comments