optimization for elfloader

use a rel/rela section's sh_info to resolve which section this rel will be applied to, rather than the section's name
This commit is contained in:
daishengdong
2020-06-10 10:13:42 +08:00
parent 5e16690f7b
commit 842e8a0458
3 changed files with 37 additions and 52 deletions

View File

@@ -29,7 +29,7 @@
#include "tos_elfloader_relocate.h" #include "tos_elfloader_relocate.h"
typedef struct el_section_st { typedef struct el_section_st {
uint8_t shndx; int8_t shndx;
void *address; void *address;
} el_section_t; } el_section_t;

View File

@@ -152,19 +152,16 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
el_err_t err; el_err_t err;
elf32_ehdr_t ehdr; elf32_ehdr_t ehdr;
elf32_shdr_t shdr; elf32_shdr_t shdr;
elf32_shdr_t shstrtab;
static el_section_t bss, data, rodata, text; static el_section_t bss = { -1, K_NULL };
static el_section_t data = { -1, K_NULL };
#define SECTION_NAME_MAX 20 static el_section_t rodata = { -1, K_NULL };
static char section_name[SECTION_NAME_MAX]; static el_section_t text = { -1, K_NULL };
void *base = K_NULL, *addr_sec2cp; /* ram base for LOAD sections */ void *base = K_NULL, *addr_sec2cp; /* ram base for LOAD sections */
uint32_t shdr_offset; uint32_t shdr_offset;
uint32_t shstrtab_offset;
uint32_t strtab_offset, strtab_size = 0; uint32_t strtab_offset, strtab_size = 0;
uint32_t symtab_offset, symtab_size = 0, symtab_entsize; uint32_t symtab_offset, symtab_size = 0, symtab_entsize;
@@ -202,13 +199,6 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
return ELFLOADER_ERR_TYPE_INVALID; return ELFLOADER_ERR_TYPE_INVALID;
} }
if (elfloader_fd_read(fd, ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shstrndx,
&shstrtab, ehdr.e_shentsize) != ELFLOADER_ERR_NONE) {
return ELFLOADER_ERR_FD_READ_FAILED;
}
shstrtab_offset = shstrtab.sh_offset;
shdr_offset = ehdr.e_shoff; shdr_offset = ehdr.e_shoff;
for (i = 0; i < ehdr.e_shnum; ++i) { for (i = 0; i < ehdr.e_shnum; ++i) {
@@ -216,10 +206,6 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
return ELFLOADER_ERR_FD_READ_FAILED; return ELFLOADER_ERR_FD_READ_FAILED;
} }
if (elfloader_fd_read(fd, shstrtab_offset + shdr.sh_name, section_name, sizeof(section_name)) != ELFLOADER_ERR_NONE) {
return ELFLOADER_ERR_FD_READ_FAILED;
}
/* /*
|-----------------------------------------------------| |-----------------------------------------------------|
| Name | sh_type | sh_flag | | Name | sh_type | sh_flag |
@@ -258,39 +244,35 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
text_size = shdr.sh_size; text_size = shdr.sh_size;
text.shndx = i; text.shndx = i;
} else if (shdr.sh_type == SHT_REL && } else if (shdr.sh_type == SHT_REL) {
strncmp(".rel.data", section_name, 9) == 0) { if (shdr.sh_info == data.shndx) {
rel_data_offset = shdr.sh_offset; rel_data_offset = shdr.sh_offset;
rel_data_size = shdr.sh_size; rel_data_size = shdr.sh_size;
rel_data_entsize = shdr.sh_entsize; rel_data_entsize = shdr.sh_entsize;
} else if (shdr.sh_type == SHT_RELA && } else if (shdr.sh_info == rodata.shndx) {
strncmp(".rela.data", section_name, 10) == 0) {
rela_data_offset = shdr.sh_offset;
rela_data_size = shdr.sh_size;
rela_data_entsize = shdr.sh_entsize;
} else if (shdr.sh_type == SHT_REL &&
(strncmp(".rel.rodata", section_name, 11) == 0 ||
strncmp(".rel.constdata", section_name, 14) == 0)) {
rel_rodata_offset = shdr.sh_offset; rel_rodata_offset = shdr.sh_offset;
rel_rodata_size = shdr.sh_size; rel_rodata_size = shdr.sh_size;
rel_rodata_entsize = shdr.sh_entsize; rel_rodata_entsize = shdr.sh_entsize;
} else if (shdr.sh_type == SHT_RELA && } else if (shdr.sh_info == text.shndx) {
(strncmp(".rela.rodata", section_name, 12) == 0 ||
strncmp(".rela.constdata", section_name, 15) == 0)) {
rela_rodata_offset = shdr.sh_offset;
rela_rodata_size = shdr.sh_size;
rela_rodata_entsize = shdr.sh_entsize;
} else if (shdr.sh_type == SHT_REL &&
strncmp(".rel.text", section_name, 9) == 0) {
rel_text_offset = shdr.sh_offset; rel_text_offset = shdr.sh_offset;
rel_text_size = shdr.sh_size; rel_text_size = shdr.sh_size;
rel_text_entsize = shdr.sh_entsize; rel_text_entsize = shdr.sh_entsize;
} else if (shdr.sh_type == SHT_RELA && }
strncmp(".rela.text", section_name, 10) == 0) { } else if (shdr.sh_type == SHT_RELA) {
if (shdr.sh_info == data.shndx) {
rela_data_offset = shdr.sh_offset;
rela_data_size = shdr.sh_size;
rela_data_entsize = shdr.sh_entsize;
} else if (shdr.sh_info == rodata.shndx) {
rela_rodata_offset = shdr.sh_offset;
rela_rodata_size = shdr.sh_size;
rela_rodata_entsize = shdr.sh_entsize;
} else if (shdr.sh_info == text.shndx) {
rela_text_offset = shdr.sh_offset; rela_text_offset = shdr.sh_offset;
rela_text_size = shdr.sh_size; rela_text_size = shdr.sh_size;
rela_text_entsize = shdr.sh_entsize; rela_text_entsize = shdr.sh_entsize;
} }
}
shdr_offset += ehdr.e_shentsize; shdr_offset += ehdr.e_shentsize;
} }
@@ -343,11 +325,13 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
addr_sec2cp = (void *)((uint32_t)addr_sec2cp + data_size); addr_sec2cp = (void *)((uint32_t)addr_sec2cp + data_size);
} }
/* clear bss */
if (bss_size > 0) { if (bss_size > 0) {
bss.address = addr_sec2cp; bss.address = addr_sec2cp;
memset(bss.address, 0, bss_size); memset(bss.address, 0, bss_size);
} }
/* do relocation */
if (rel_data_size > 0) { if (rel_data_size > 0) {
err = elfloader_relocate(fd, data.address, err = elfloader_relocate(fd, data.address,
bss, data, rodata, text, bss, data, rodata, text,

View File

@@ -289,6 +289,7 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
phdr_offset += ehdr.e_phentsize; phdr_offset += ehdr.e_phentsize;
} }
/* do relocation */
if (rel_dyn_size > 0) { if (rel_dyn_size > 0) {
err = elfloader_relocate(fd, load_bias, err = elfloader_relocate(fd, load_bias,
rel_dyn_offset, rel_dyn_size, rel_entsize, rel_dyn_offset, rel_dyn_size, rel_entsize,