From 376ef75964e7e200e9c5d39400c58cdc53b6a03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 6 Jan 2023 16:06:51 +0100 Subject: [PATCH] Correctly implement LMA calculation. --- src/elfpatch.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/elfpatch.c b/src/elfpatch.c index 100f60f..d98823e 100644 --- a/src/elfpatch.c +++ b/src/elfpatch.c @@ -272,7 +272,8 @@ static int elf_patch_read_program_headers(elfpatch_handle_t *ep) print_err("Error reading program header (%zu): %s\n", i, elf_errmsg(-1)); goto ret_free_err; } - print_debug("Program Header (i): mem_size: %zu, file_size: %zu, vma: %p, lma: %p, file offset: %zu\n", + print_debug("Program Header (%zu): mem_size: %zu, file_size: %zu, vma: %p, lma: %p, file offset: %zu\n", + i, (size_t)hdr->p_memsz, (size_t)hdr->p_filesz, (void *)hdr->p_vaddr, (void *)hdr->p_paddr, hdr->p_offset); } @@ -291,11 +292,37 @@ ret_free_err: static void resolve_section_lmas(elfpatch_handle_t *ep) { SlList *sec_iter; + struct elf_section *sec; + size_t idx; + uint64_t sec_file_offset; + uint64_t section_offset_in_segment; + const GElf_Phdr *phdr; ret_if_ep_err(ep); for (sec_iter = ep->sections; sec_iter; sec_iter = sl_list_next(sec_iter)) { + sec = (struct elf_section *)sec_iter->data; + if (!sec) + continue; + if (sec->section_header.sh_type == SHT_NOBITS) { + /* Section does not contain data. It may be allocated but is not loaded. Therefore, LMA=VMA. */ + sec->lma = (uint64_t)sec->section_header.sh_addr; + continue; + } + + sec_file_offset = (uint64_t) sec->section_header.sh_offset; + + /* Check in which segment the file offset is located */ + for (idx = 0; idx < ep->program_headers_count; idx++) { + phdr = &ep->program_headers[idx]; + if (sec_file_offset >= phdr->p_offset && sec_file_offset < (phdr->p_offset + phdr->p_filesz)) { + /* Section lies within this segment */ + section_offset_in_segment = sec_file_offset - phdr->p_offset; + sec->lma = ((uint64_t)phdr->p_paddr) + section_offset_in_segment; + break; + } + } } }