Changeset View
Changeset View
Standalone View
Standalone View
contrib/elftoolchain/elfcopy/sections.c
Show All 36 Lines | |||||
ELFTC_VCSID("$Id: sections.c 3646 2018-10-27 02:25:39Z emaste $"); | ELFTC_VCSID("$Id: sections.c 3646 2018-10-27 02:25:39Z emaste $"); | ||||
static void add_gnu_debuglink(struct elfcopy *ecp); | static void add_gnu_debuglink(struct elfcopy *ecp); | ||||
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); | static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); | ||||
static void check_section_rename(struct elfcopy *ecp, struct section *s); | static void check_section_rename(struct elfcopy *ecp, struct section *s); | ||||
static void filter_reloc(struct elfcopy *ecp, struct section *s); | static void filter_reloc(struct elfcopy *ecp, struct section *s); | ||||
static int get_section_flags(struct elfcopy *ecp, const char *name); | static int get_section_flags(struct elfcopy *ecp, const char *name); | ||||
static void insert_sections(struct elfcopy *ecp); | static void insert_sections(struct elfcopy *ecp); | ||||
static void insert_to_strtab(struct section *t, const char *s); | |||||
static int is_append_section(struct elfcopy *ecp, const char *name); | static int is_append_section(struct elfcopy *ecp, const char *name); | ||||
static int is_compress_section(struct elfcopy *ecp, const char *name); | static int is_compress_section(struct elfcopy *ecp, const char *name); | ||||
static int is_debug_section(const char *name); | static int is_debug_section(const char *name); | ||||
static int is_dwo_section(const char *name); | static int is_dwo_section(const char *name); | ||||
static int is_modify_section(struct elfcopy *ecp, const char *name); | static int is_modify_section(struct elfcopy *ecp, const char *name); | ||||
static int is_print_section(struct elfcopy *ecp, const char *name); | static int is_print_section(struct elfcopy *ecp, const char *name); | ||||
static int lookup_string(struct section *t, const char *s); | |||||
static void modify_section(struct elfcopy *ecp, struct section *s); | static void modify_section(struct elfcopy *ecp, struct section *s); | ||||
static void pad_section(struct elfcopy *ecp, struct section *s); | static void pad_section(struct elfcopy *ecp, struct section *s); | ||||
static void print_data(const char *d, size_t sz); | static void print_data(const char *d, size_t sz); | ||||
static void print_section(struct section *s); | static void print_section(struct section *s); | ||||
static void *read_section(struct section *s, size_t *size); | static void *read_section(struct section *s, size_t *size); | ||||
static void set_shstrtab(struct elfcopy *ecp); | |||||
static void update_reloc(struct elfcopy *ecp, struct section *s); | static void update_reloc(struct elfcopy *ecp, struct section *s); | ||||
static void update_section_group(struct elfcopy *ecp, struct section *s); | static void update_section_group(struct elfcopy *ecp, struct section *s); | ||||
int | int | ||||
is_remove_section(struct elfcopy *ecp, const char *name) | is_remove_section(struct elfcopy *ecp, const char *name) | ||||
{ | { | ||||
/* Always keep section name table */ | /* Always keep section name table */ | ||||
▲ Show 20 Lines • Show All 1,265 Lines • ▼ Show 20 Lines | STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) { | ||||
(void) create_external_section(ecp, sa->name, NULL, sa->content, | (void) create_external_section(ecp, sa->name, NULL, sa->content, | ||||
sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); | sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
add_to_shstrtab(struct elfcopy *ecp, const char *name) | add_to_shstrtab(struct elfcopy *ecp, const char *name) | ||||
{ | { | ||||
struct section *s; | |||||
s = ecp->shstrtab; | if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0) | ||||
insert_to_strtab(s, name); | errx(EXIT_FAILURE, "elftc_string_table_insert failed"); | ||||
} | } | ||||
void | void | ||||
update_shdr(struct elfcopy *ecp, int update_link) | update_shdr(struct elfcopy *ecp, int update_link) | ||||
{ | { | ||||
struct section *s; | struct section *s; | ||||
GElf_Shdr osh; | GElf_Shdr osh; | ||||
int elferr; | int elferr; | ||||
/* Finalize the section name string table (.shstrtab). */ | |||||
set_shstrtab(ecp); | |||||
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { | TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { | ||||
if (s->pseudo) | if (s->pseudo) | ||||
continue; | continue; | ||||
if (gelf_getshdr(s->os, &osh) == NULL) | if (gelf_getshdr(s->os, &osh) == NULL) | ||||
errx(EXIT_FAILURE, "gelf_getshdr failed: %s", | errx(EXIT_FAILURE, "gelf_getshdr failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
/* Find section name in string table and set sh_name. */ | /* Find section name in string table and set sh_name. */ | ||||
osh.sh_name = lookup_string(ecp->shstrtab, s->name); | osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab, | ||||
s->name); | |||||
/* | /* | ||||
* sh_link needs to be updated, since the index of the | * sh_link needs to be updated, since the index of the | ||||
* linked section might have changed. | * linked section might have changed. | ||||
*/ | */ | ||||
if (update_link && osh.sh_link != 0) | if (update_link && osh.sh_link != 0) | ||||
osh.sh_link = ecp->secndx[osh.sh_link]; | osh.sh_link = ecp->secndx[osh.sh_link]; | ||||
Show All 33 Lines | init_shstrtab(struct elfcopy *ecp) | ||||
s = ecp->shstrtab; | s = ecp->shstrtab; | ||||
s->name = ".shstrtab"; | s->name = ".shstrtab"; | ||||
s->is = NULL; | s->is = NULL; | ||||
s->sz = 0; | s->sz = 0; | ||||
s->align = 1; | s->align = 1; | ||||
s->loadable = 0; | s->loadable = 0; | ||||
s->type = SHT_STRTAB; | s->type = SHT_STRTAB; | ||||
s->vma = 0; | s->vma = 0; | ||||
s->strtab = elftc_string_table_create(0); | |||||
insert_to_strtab(s, ""); | add_to_shstrtab(ecp, ""); | ||||
insert_to_strtab(s, ".symtab"); | add_to_shstrtab(ecp, ".symtab"); | ||||
insert_to_strtab(s, ".strtab"); | add_to_shstrtab(ecp, ".strtab"); | ||||
insert_to_strtab(s, ".shstrtab"); | add_to_shstrtab(ecp, ".shstrtab"); | ||||
} | } | ||||
void | static void | ||||
set_shstrtab(struct elfcopy *ecp) | set_shstrtab(struct elfcopy *ecp) | ||||
{ | { | ||||
struct section *s; | struct section *s; | ||||
Elf_Data *data; | Elf_Data *data; | ||||
GElf_Shdr sh; | GElf_Shdr sh; | ||||
const char *image; | |||||
s = ecp->shstrtab; | s = ecp->shstrtab; | ||||
if (s->os == NULL) { | if (s->os == NULL) { | ||||
/* Input object does not contain .shstrtab section */ | /* Input object does not contain .shstrtab section */ | ||||
if ((s->os = elf_newscn(ecp->eout)) == NULL) | if ((s->os = elf_newscn(ecp->eout)) == NULL) | ||||
errx(EXIT_FAILURE, "elf_newscn failed: %s", | errx(EXIT_FAILURE, "elf_newscn failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
Show All 16 Lines | if ((data = elf_newdata(s->os)) == NULL) | ||||
errx(EXIT_FAILURE, "elf_newdata() failed: %s", | errx(EXIT_FAILURE, "elf_newdata() failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
/* | /* | ||||
* If we don't have a symbol table, skip those a few bytes | * If we don't have a symbol table, skip those a few bytes | ||||
* which are reserved for this in the beginning of shstrtab. | * which are reserved for this in the beginning of shstrtab. | ||||
*/ | */ | ||||
if (!(ecp->flags & SYMTAB_EXIST)) { | if (!(ecp->flags & SYMTAB_EXIST)) { | ||||
s->sz -= sizeof(".symtab\0.strtab"); | elftc_string_table_remove(s->strtab, ".symtab"); | ||||
memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"), | elftc_string_table_remove(s->strtab, ".strtab"); | ||||
s->sz); | |||||
} | } | ||||
image = elftc_string_table_image(s->strtab, &s->sz); | |||||
sh.sh_size = s->sz; | sh.sh_size = s->sz; | ||||
if (!gelf_update_shdr(s->os, &sh)) | if (!gelf_update_shdr(s->os, &sh)) | ||||
errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", | errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
data->d_align = 1; | data->d_align = 1; | ||||
data->d_buf = s->buf; | data->d_buf = (void *)(uintptr_t)image; | ||||
data->d_size = s->sz; | data->d_size = s->sz; | ||||
data->d_off = 0; | data->d_off = 0; | ||||
data->d_type = ELF_T_BYTE; | data->d_type = ELF_T_BYTE; | ||||
data->d_version = EV_CURRENT; | data->d_version = EV_CURRENT; | ||||
if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) | if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) | ||||
errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", | errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | if (ecp->oed == ELFDATA2LSB) { | ||||
sa->content[crc_off] = crc >> 24; | sa->content[crc_off] = crc >> 24; | ||||
sa->content[crc_off + 1] = (crc >> 16) & 0xFF; | sa->content[crc_off + 1] = (crc >> 16) & 0xFF; | ||||
sa->content[crc_off + 2] = (crc >> 8) & 0xFF; | sa->content[crc_off + 2] = (crc >> 8) & 0xFF; | ||||
sa->content[crc_off + 3] = crc & 0xFF; | sa->content[crc_off + 3] = crc & 0xFF; | ||||
} | } | ||||
STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); | STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); | ||||
ecp->flags |= SEC_ADD; | ecp->flags |= SEC_ADD; | ||||
} | |||||
static void | |||||
insert_to_strtab(struct section *t, const char *s) | |||||
{ | |||||
const char *r; | |||||
char *b, *c; | |||||
size_t len, slen; | |||||
int append; | |||||
if (t->sz == 0) { | |||||
t->cap = 512; | |||||
if ((t->buf = malloc(t->cap)) == NULL) | |||||
err(EXIT_FAILURE, "malloc failed"); | |||||
} | |||||
slen = strlen(s); | |||||
append = 0; | |||||
b = t->buf; | |||||
for (c = b; c < b + t->sz;) { | |||||
len = strlen(c); | |||||
if (!append && len >= slen) { | |||||
r = c + (len - slen); | |||||
if (strcmp(r, s) == 0) | |||||
return; | |||||
} else if (len < slen && len != 0) { | |||||
r = s + (slen - len); | |||||
if (strcmp(c, r) == 0) { | |||||
t->sz -= len + 1; | |||||
memmove(c, c + len + 1, t->sz - (c - b)); | |||||
append = 1; | |||||
continue; | |||||
} | |||||
} | |||||
c += len + 1; | |||||
} | |||||
while (t->sz + slen + 1 >= t->cap) { | |||||
t->cap *= 2; | |||||
if ((t->buf = realloc(t->buf, t->cap)) == NULL) | |||||
err(EXIT_FAILURE, "realloc failed"); | |||||
} | |||||
b = t->buf; | |||||
strncpy(&b[t->sz], s, slen); | |||||
b[t->sz + slen] = '\0'; | |||||
t->sz += slen + 1; | |||||
} | |||||
static int | |||||
lookup_string(struct section *t, const char *s) | |||||
{ | |||||
const char *b, *c, *r; | |||||
size_t len, slen; | |||||
slen = strlen(s); | |||||
b = t->buf; | |||||
for (c = b; c < b + t->sz;) { | |||||
len = strlen(c); | |||||
if (len >= slen) { | |||||
r = c + (len - slen); | |||||
if (strcmp(r, s) == 0) | |||||
return (r - b); | |||||
} | |||||
c += len + 1; | |||||
} | |||||
return (-1); | |||||
} | } | ||||
static uint32_t crctable[256] = | static uint32_t crctable[256] = | ||||
{ | { | ||||
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, | 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, | ||||
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, | 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, | ||||
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, | 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, | ||||
0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, | 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |