@@ -251,19 +251,19 @@ bool ObjectFileWasm::ParseHeader() {
251251
252252static llvm::Expected<std::vector<AddressRange>>
253253ParseFunctions (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 );
256256 lldb::offset_t offset = 0 ;
257257
258- const uint64_t function_count = code_section_data .GetULEB128 (&offset);
258+ const uint64_t function_count = data .GetULEB128 (&offset);
259259 if (function_count > std::numeric_limits<uint32_t >::max ())
260260 return llvm::createStringError (" function count overflows uint32_t" );
261261
262262 std::vector<AddressRange> functions;
263263 functions.reserve (function_count);
264264
265265 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);
267267 if (function_size > std::numeric_limits<uint32_t >::max ())
268268 return llvm::createStringError (" function size overflows uint32_t" );
269269 // llvm-objdump considers the ULEB with the function size to be part of the
@@ -281,9 +281,45 @@ ParseFunctions(SectionSP code_section_sp) {
281281 return functions;
282282}
283283
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+
284319static llvm::Expected<std::vector<Symbol>>
285320ParseNames (SectionSP name_section_sp,
286- const std::vector<AddressRange> &functions) {
321+ const std::vector<AddressRange> &function_ranges,
322+ const std::vector<AddressRange> &segment_ranges) {
287323 DataExtractor name_section_data;
288324 name_section_sp->GetSectionData (name_section_data);
289325
@@ -305,17 +341,34 @@ ParseNames(SectionSP name_section_sp,
305341 for (uint64_t i = 0 ; c && i < count; ++i) {
306342 const uint64_t idx = data.getULEB128 (c);
307343 const std::optional<std::string> name = GetWasmString (data, c);
308- if (!name || idx >= functions .size ())
344+ if (!name || idx >= function_ranges .size ())
309345 continue ;
310346 symbols.emplace_back (
311347 symbols.size (), Mangled (*name), lldb::eSymbolTypeCode,
312348 /* external=*/ false , /* is_debug=*/ false , /* is_trampoline=*/ false ,
313- /* is_artificial=*/ false , functions [idx],
349+ /* is_artificial=*/ false , function_ranges [idx],
314350 /* size_is_valid=*/ true , /* contains_linker_annotations=*/ false ,
315351 /* flags=*/ 0 );
316352 }
317353 } 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 ;
319372 case llvm::wasm::WASM_NAMES_GLOBAL:
320373 case llvm::wasm::WASM_NAMES_LOCAL:
321374 default :
@@ -336,21 +389,35 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
336389 assert (m_sections_up && " sections must be parsed" );
337390 Log *log = GetLog (LLDBLog::Object);
338391
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;
346408 }
347409
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;
354421 }
355422
356423 // Parse the name section.
@@ -362,7 +429,7 @@ void ObjectFileWasm::ParseSymtab(Symtab &symtab) {
362429 }
363430
364431 llvm::Expected<std::vector<Symbol>> symbols =
365- ParseNames (name_section_sp, *functions );
432+ ParseNames (name_section_sp, function_ranges, segment_ranges );
366433 if (!symbols) {
367434 LLDB_LOG_ERROR (log, symbols.takeError (), " Failed to parse Wasm names: {0}" );
368435 return ;
@@ -408,6 +475,9 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
408475 // For this reason Section::GetFileAddress() must return zero for the
409476 // Code section.
410477 vm_addr = 0 ;
478+ } else if (llvm::wasm::WASM_SEC_DATA == sect_info.id ) {
479+ section_type = eSectionTypeData;
480+ section_name = ConstString (" data" );
411481 } else {
412482 section_type = GetSectionTypeFromName (sect_info.name .GetStringRef ());
413483 if (section_type == eSectionTypeOther)
0 commit comments