reimplement reading of program headers. They are needed to derive the LMA of sections
This commit is contained in:
parent
2c50964581
commit
eeb2027884
@ -45,6 +45,8 @@ struct elfpatch {
|
||||
GElf_Ehdr ehdr;
|
||||
int class;
|
||||
SlList *sections;
|
||||
GElf_Phdr *program_headers; /**< @brief Program headers */
|
||||
size_t program_headers_count; /**< @brief Number of program headers in the program headers array */
|
||||
};
|
||||
|
||||
#define ELFPATCH_MAGIC 0x8545637Aul
|
||||
@ -228,6 +230,60 @@ ret_free_section_list:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read program headers from ELF file and store them more conviniently in a linkled list
|
||||
* @param ep Elfpatch object
|
||||
* @return 0 if successful
|
||||
* @return negative if error.
|
||||
* @note The function will succeed even if no program heder is found in the file.
|
||||
*/
|
||||
static int elf_patch_read_program_headers(elfpatch_handle_t *ep)
|
||||
{
|
||||
size_t header_count = 0ull;
|
||||
GElf_Phdr *hdr;
|
||||
size_t i;
|
||||
|
||||
ret_val_if_ep_err(ep, -1001);
|
||||
|
||||
if (ep->program_headers_count > 0 && ep->program_headers) {
|
||||
/* Free the program headers. They are owned by the ELF object. So no need to free them */
|
||||
free(ep->program_headers);
|
||||
ep->program_headers_count = 0;
|
||||
}
|
||||
|
||||
if (elf_getphdrnum(ep->elf, &header_count)) {
|
||||
print_err("Error reading program headers: %s\n", elf_errmsg(-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ep->program_headers = (GElf_Phdr *)malloc(header_count * sizeof(GElf_Phdr));
|
||||
if (!ep->program_headers) {
|
||||
/* Mem error. Abort. Program will crash eventually */
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0u; i < header_count; i++) {
|
||||
hdr = &ep->program_headers[i];
|
||||
if (gelf_getphdr(ep->elf, (int)i, hdr) != hdr) {
|
||||
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",
|
||||
(size_t)hdr->p_memsz, (size_t)hdr->p_filesz, (void *)hdr->p_vaddr, (void *)hdr->p_paddr,
|
||||
hdr->p_offset);
|
||||
}
|
||||
|
||||
ep->program_headers_count = header_count;
|
||||
|
||||
return 0;
|
||||
|
||||
ret_free_err:
|
||||
if (ep->program_headers)
|
||||
free(ep->program_headers);
|
||||
ep->program_headers_count = 0u;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int elf_patch_update_info(elfpatch_handle_t *ep)
|
||||
{
|
||||
Elf_Kind ek;
|
||||
@ -273,6 +329,11 @@ static int elf_patch_update_info(elfpatch_handle_t *ep)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (elf_patch_read_program_headers(ep)) {
|
||||
print_err("Error reading program headers.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -293,6 +354,11 @@ elfpatch_handle_t *elf_patch_open(const char *path, bool readonly, bool expect_l
|
||||
ep->magic = ELFPATCH_MAGIC;
|
||||
ep->readonly = readonly;
|
||||
|
||||
/* This shouldn't really be necessary due to the use of calloc() */
|
||||
ep->sections = NULL;
|
||||
ep->program_headers = NULL;
|
||||
ep->program_headers_count = 0u;
|
||||
|
||||
ep->fd = open(path, readonly ? O_RDONLY : O_RDWR, 0);
|
||||
if (ep->fd < 0) {
|
||||
print_err("Error opening file: %s\n", path);
|
||||
@ -697,6 +763,12 @@ void elf_patch_close_and_free(elfpatch_handle_t *ep)
|
||||
sl_list_free_full(ep->sections, (void (*)(void *))free_elf_section_element);
|
||||
ep->sections = NULL;
|
||||
|
||||
if (ep->program_headers) {
|
||||
free(ep->program_headers);
|
||||
ep->program_headers = NULL;
|
||||
}
|
||||
ep->program_headers_count = 0u;
|
||||
|
||||
ep->elf = NULL;
|
||||
ep->fd = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user