================ @@ -983,6 +994,67 @@ llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( } } +UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) { + UUID invalid_uuid; + const uint32_t addr_size = GetAddressByteSize(); + const size_t elf_header_size = addr_size == 4 ? sizeof(llvm::ELF::Elf32_Ehdr) + : sizeof(llvm::ELF::Elf64_Ehdr); + + // 80 bytes buffer is larger enough for the ELF header or program headers + unsigned char buf[80]; + Status error; + size_t byte_read = ReadMemory(address, buf, elf_header_size, error); + if (byte_read != elf_header_size || !elf::ELFHeader::MagicBytesMatch(buf)) + return invalid_uuid; + assert(sizeof(buf) >= elf_header_size); + DataExtractor elf_header_data(buf, elf_header_size, GetByteOrder(), + addr_size); + lldb::offset_t offset = 0; + + elf::ELFHeader elf_header; + elf_header.Parse(elf_header_data, &offset); + + const lldb::addr_t ph_addr = address + elf_header.e_phoff; + + for (unsigned int i = 0; i < elf_header.e_phnum; ++i) { + byte_read = ReadMemory(ph_addr + i * elf_header.e_phentsize, buf, + elf_header.e_phentsize, error); + if (byte_read != elf_header.e_phentsize) + break; + assert(sizeof(buf) >= elf_header.e_phentsize); + DataExtractor program_header_data(buf, elf_header.e_phentsize, + GetByteOrder(), addr_size); + offset = 0; + elf::ELFProgramHeader program_header; + program_header.Parse(program_header_data, &offset); + if (program_header.p_type != llvm::ELF::PT_NOTE) + continue; + + std::vector<uint8_t> note_bytes; + note_bytes.resize(program_header.p_memsz); + + byte_read = ReadMemory(program_header.p_vaddr, note_bytes.data(), + program_header.p_memsz, error); + if (byte_read != program_header.p_memsz) + continue; + assert(sizeof(buf) >= program_header.p_memsz); + DataExtractor segment_data(note_bytes.data(), note_bytes.size(), + GetByteOrder(), addr_size); + auto notes_or_error = parseSegment(segment_data); + if (!notes_or_error) + return invalid_uuid; + for (const CoreNote ¬e : *notes_or_error) { + if (note.info.n_namesz == 4 && + note.info.n_type == llvm::ELF::NT_GNU_BUILD_ID) { + if ("GNU" == note.info.n_name) + return UUID(llvm::ArrayRef<uint8_t>( + note.data.GetDataStart(), note.info.n_descsz /*byte size*/)); ---------------- labath wrote:
In case of a corrupted core file, `note.data` can contain less than `n_descsz` bytes, and this will create a invalid ArrayRef (and possibly crash lldb). Writing this like `return UUID(note.data.GetData())` will ensure that does not happen, although it could return a truncated UUID in that case. If you want to check that case explicitly, then I'd recommend something like: ``` if(note.data.ValidOffsetForDataOfSize(0, note.info.n_descsz)) return UUID(note.data.GetData().take_front(note.info.n_descsz); ``` https://github.com/llvm/llvm-project/pull/92492 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits