svn commit: r348657 - head/contrib/elftoolchain/elfcopy
Mark Johnston
markj at FreeBSD.org
Tue Jun 4 18:34:07 UTC 2019
Author: markj
Date: Tue Jun 4 18:34:05 2019
New Revision: 348657
URL: https://svnweb.freebsd.org/changeset/base/348657
Log:
elfcopy: Use libelftc's string table routines to build .shstrtab.
This replaces some hand-rolled routines and is substantially faster
since libelftc uses a hash table for lookups and insertions, whereas
elfcopy would perform a linear scan of the table.
PR: 234949
Reviewed by: emaste
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D20473
Modified:
head/contrib/elftoolchain/elfcopy/ascii.c
head/contrib/elftoolchain/elfcopy/binary.c
head/contrib/elftoolchain/elfcopy/elfcopy.h
head/contrib/elftoolchain/elfcopy/main.c
head/contrib/elftoolchain/elfcopy/sections.c
Modified: head/contrib/elftoolchain/elfcopy/ascii.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/ascii.c Tue Jun 4 18:31:52 2019 (r348656)
+++ head/contrib/elftoolchain/elfcopy/ascii.c Tue Jun 4 18:34:05 2019 (r348657)
@@ -378,9 +378,6 @@ done:
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
elf_errmsg(-1));
- /* Generate section name string table (.shstrtab). */
- set_shstrtab(ecp);
-
/* Update sh_name pointer for each section header entry. */
update_shdr(ecp, 0);
@@ -604,9 +601,6 @@ done:
if (gelf_update_ehdr(ecp->eout, &oeh) == 0)
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
elf_errmsg(-1));
-
- /* Generate section name string table (.shstrtab). */
- set_shstrtab(ecp);
/* Update sh_name pointer for each section header entry. */
update_shdr(ecp, 0);
Modified: head/contrib/elftoolchain/elfcopy/binary.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/binary.c Tue Jun 4 18:31:52 2019 (r348656)
+++ head/contrib/elftoolchain/elfcopy/binary.c Tue Jun 4 18:34:05 2019 (r348657)
@@ -250,11 +250,8 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, c
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
elf_errmsg(-1));
- /* Generate section name string table (.shstrtab). */
- ecp->flags |= SYMTAB_EXIST;
- set_shstrtab(ecp);
-
/* Update sh_name pointer for each section header entry. */
+ ecp->flags |= SYMTAB_EXIST;
update_shdr(ecp, 0);
/* Properly set sh_link field of .symtab section. */
Modified: head/contrib/elftoolchain/elfcopy/elfcopy.h
==============================================================================
--- head/contrib/elftoolchain/elfcopy/elfcopy.h Tue Jun 4 18:31:52 2019 (r348656)
+++ head/contrib/elftoolchain/elfcopy/elfcopy.h Tue Jun 4 18:34:05 2019 (r348657)
@@ -135,6 +135,8 @@ struct section {
int pseudo;
int nocopy;
+ Elftc_String_Table *strtab;
+
TAILQ_ENTRY(section) sec_list; /* next section */
};
@@ -313,7 +315,6 @@ struct sec_action *lookup_sec_act(struct elfcopy *_ecp
struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
unsigned int _op);
void resync_sections(struct elfcopy *_ecp);
-void set_shstrtab(struct elfcopy *_ecp);
void setup_phdr(struct elfcopy *_ecp);
void update_shdr(struct elfcopy *_ecp, int _update_link);
Modified: head/contrib/elftoolchain/elfcopy/main.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/main.c Tue Jun 4 18:31:52 2019 (r348656)
+++ head/contrib/elftoolchain/elfcopy/main.c Tue Jun 4 18:34:05 2019 (r348657)
@@ -388,9 +388,6 @@ create_elf(struct elfcopy *ecp)
*/
copy_content(ecp);
- /* Generate section name string table (.shstrtab). */
- set_shstrtab(ecp);
-
/*
* Second processing of output sections: Update section headers.
* At this stage we set name string index, update st_link and st_info
@@ -485,6 +482,9 @@ free_elf(struct elfcopy *ecp)
/* Free symbol table buffers. */
free_symtab(ecp);
+
+ /* Free section name string table. */
+ elftc_string_table_destroy(ecp->shstrtab->strtab);
/* Free internal section list. */
if (!TAILQ_EMPTY(&ecp->v_sec)) {
Modified: head/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/sections.c Tue Jun 4 18:31:52 2019 (r348656)
+++ head/contrib/elftoolchain/elfcopy/sections.c Tue Jun 4 18:34:05 2019 (r348657)
@@ -42,19 +42,18 @@ static void check_section_rename(struct elfcopy *ecp,
static void filter_reloc(struct elfcopy *ecp, struct section *s);
static int get_section_flags(struct elfcopy *ecp, const char *name);
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_compress_section(struct elfcopy *ecp, const char *name);
static int is_debug_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_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 pad_section(struct elfcopy *ecp, struct section *s);
static void print_data(const char *d, size_t sz);
static void print_section(struct section *s);
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_section_group(struct elfcopy *ecp, struct section *s);
@@ -1336,10 +1335,9 @@ insert_sections(struct elfcopy *ecp)
void
add_to_shstrtab(struct elfcopy *ecp, const char *name)
{
- struct section *s;
- s = ecp->shstrtab;
- insert_to_strtab(s, name);
+ if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
+ errx(EXIT_FAILURE, "elftc_string_table_insert failed");
}
void
@@ -1349,6 +1347,9 @@ update_shdr(struct elfcopy *ecp, int update_link)
GElf_Shdr osh;
int elferr;
+ /* Finalize the section name string table (.shstrtab). */
+ set_shstrtab(ecp);
+
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
if (s->pseudo)
continue;
@@ -1358,7 +1359,8 @@ update_shdr(struct elfcopy *ecp, int update_link)
elf_errmsg(-1));
/* 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
@@ -1408,19 +1410,22 @@ init_shstrtab(struct elfcopy *ecp)
s->loadable = 0;
s->type = SHT_STRTAB;
s->vma = 0;
+ s->strtab = elftc_string_table_create(0);
- insert_to_strtab(s, "");
- insert_to_strtab(s, ".symtab");
- insert_to_strtab(s, ".strtab");
- insert_to_strtab(s, ".shstrtab");
+ add_to_shstrtab(ecp, "");
+ add_to_shstrtab(ecp, ".symtab");
+ add_to_shstrtab(ecp, ".strtab");
+ add_to_shstrtab(ecp, ".shstrtab");
}
-void
+static void
set_shstrtab(struct elfcopy *ecp)
{
struct section *s;
Elf_Data *data;
GElf_Shdr sh;
+ const char *image;
+ size_t sz;
s = ecp->shstrtab;
@@ -1453,19 +1458,21 @@ set_shstrtab(struct elfcopy *ecp)
* which are reserved for this in the beginning of shstrtab.
*/
if (!(ecp->flags & SYMTAB_EXIST)) {
- s->sz -= sizeof(".symtab\0.strtab");
- memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
- s->sz);
+ elftc_string_table_remove(s->strtab, ".symtab");
+ elftc_string_table_remove(s->strtab, ".strtab");
}
- sh.sh_size = s->sz;
+ image = elftc_string_table_image(s->strtab, &sz);
+ s->sz = sz;
+
+ sh.sh_size = sz;
if (!gelf_update_shdr(s->os, &sh))
errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
elf_errmsg(-1));
data->d_align = 1;
- data->d_buf = s->buf;
- data->d_size = s->sz;
+ data->d_buf = (void *)(uintptr_t)image;
+ data->d_size = sz;
data->d_off = 0;
data->d_type = ELF_T_BYTE;
data->d_version = EV_CURRENT;
@@ -1589,73 +1596,6 @@ add_gnu_debuglink(struct elfcopy *ecp)
STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
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] =
More information about the svn-src-head
mailing list