From ad85518214de31df7e3a7b2b7d37e781a5e75e2f Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 10 Jan 2025 17:18:10 -0500 Subject: [PATCH] Debug Kit: Handle more than two TEXT/DATA segments. ELF files may have more than one, in which case we need to collect the addresses and sizes from all of them. (runtime_loader already does this when building image_info.) Fixes #19021. Change-Id: I379c4065976e9569a7bd7a538f46787ebcf6d3e8 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8819 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- src/kits/debug/Image.cpp | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/kits/debug/Image.cpp b/src/kits/debug/Image.cpp index 1e9973ec98..8e7bc5309a 100644 --- a/src/kits/debug/Image.cpp +++ b/src/kits/debug/Image.cpp @@ -306,25 +306,43 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize, } // find the text and data segment -- we need load address and size - *_textAddress = 0; - *_textSize = 0; - *_dataAddress = 0; - *_dataSize = 0; + // in case of multiple segments of the same type, combine them + addr_t textBase = 0; + addr_t textEnd = 0; + addr_t dataBase = 0; + addr_t dataEnd = 0; for (int32 i = 0; i < programHeaderCount; i++) { elf_phdr* header = (elf_phdr*) ((uint8*)programHeaders + i * elfHeader->e_phentsize); - if (header->p_type == PT_LOAD) { - if ((header->p_flags & PF_WRITE) == 0) { - *_textAddress = header->p_vaddr; - *_textSize = header->p_memsz; + if (header->p_type != PT_LOAD) + continue; + + addr_t base = header->p_vaddr; + addr_t end = base + header->p_memsz; + if ((header->p_flags & PF_WRITE) == 0) { + if (textEnd == 0) { + textBase = base; + textEnd = end; } else { - *_dataAddress = header->p_vaddr; - *_dataSize = header->p_memsz; - break; + textBase = min_c(textBase, base); + textEnd = max_c(textEnd, end); + } + } else { + if (dataEnd == 0) { + dataBase = base; + dataEnd = end; + } else { + dataBase = min_c(dataBase, base); + dataEnd = max_c(dataEnd, end); } } } + *_textAddress = textBase; + *_textSize = textEnd - textBase; + *_dataAddress = dataBase; + *_dataSize = dataEnd - dataBase; + status_t error = _FindTableInSection(elfHeader, SHT_SYMTAB); if (error != B_OK) error = _FindTableInSection(elfHeader, SHT_DYNSYM);