================ @@ -983,6 +1005,73 @@ llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( } } +bool ProcessElfCore::IsElf(const lldb::addr_t address) { + uint8_t buf[4]; + Status error; + size_t byte_read = ReadMemory(address, buf, 4, error); + if (byte_read != 4) + return false; + return elf::ELFHeader::MagicBytesMatch(buf); +} + +std::optional<UUID> ProcessElfCore::FindNote(const lldb::addr_t address, + const uint32_t type) { + if (!IsElf(address)) + return std::nullopt; + const uint32_t addr_size = GetAddressByteSize(); + const lldb::offset_t ehdr_phoff_offset = ELFOFFSETOF(Ehdr, e_phoff); + const lldb::offset_t ehdr_phentsize_offset = ELFOFFSETOF(Ehdr, e_phentsize); + const lldb::offset_t ehdr_phnum_offset = ELFOFFSETOF(Ehdr, e_phnum); + const size_t elf_header_size = addr_size == 4 ? sizeof(llvm::ELF::Elf32_Ehdr) + : sizeof(llvm::ELF::Elf64_Ehdr); + + unsigned char buf[4096]; + Status error; + size_t byte_read = ReadMemory(address, buf, elf_header_size, error); + DataExtractor data(buf, 4096, GetByteOrder(), addr_size); + lldb::offset_t offset = ehdr_phoff_offset; + lldb::offset_t phoff = data.GetAddress(&offset); + + offset = ehdr_phentsize_offset; + lldb::offset_t phentsize = data.GetU16(&offset); + offset = ehdr_phnum_offset; + lldb::offset_t phnum = data.GetU16(&offset); + + Section_Note note; + const lldb::addr_t ph_addr = address + phoff; + + for (unsigned int i = 0; i < phnum; ++i) { + byte_read = ReadMemory(ph_addr + i * phentsize, buf, phentsize, error); + if (byte_read != phentsize) + break; + offset = 0; + uint32_t p_type = data.GetU32(&offset); + if (p_type != llvm::ELF::PT_NOTE) + continue; + offset = ELFOFFSETOF(Phdr, p_vaddr); + lldb::addr_t p_vaddr = data.GetAddress(&offset); + offset = ELFOFFSETOF(Phdr, p_memsz); + lldb::addr_t p_memsz = data.GetAddress(&offset); + + byte_read = ReadMemory(p_vaddr, buf, p_memsz, error); + if (byte_read != p_memsz) + continue; + offset = 0; + while ( + offset < p_memsz && + data.GetU32(&offset, ¬e, sizeof(Section_Note) / sizeof(uint32_t))) { + if (note.namesz == 4 && note.type == type) { + const char *name = data.GetCStr(&offset); + if (name && strcmp("GNU", name) == 0) + return UUID( + llvm::ArrayRef<uint8_t>(buf + offset, note.descsz /*byte size*/)); + } + offset += note.namesz + note.descsz; + } ---------------- labath wrote:
And `parseSegment` for this (despite the generic name, this is really for parsing note segments, maybe you could rename it while you're in here). 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