summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2016-07-08 14:08:22 +0200
committerMark Wielaard <mjw@redhat.com>2016-08-03 18:19:47 +0200
commitdd906c1b4852be4dd34924017261f89cc5c4c723 (patch)
tree6aac4ef30566095081089eed773711cf00e6e13d /src
parente6ca75ddcf2ba9314077ddc9768eaac2405305e1 (diff)
downloadelfutils-dd906c1b4852be4dd34924017261f89cc5c4c723.tar.gz
dwelf: Add string table functions from ebl.
Move the strtab functions from libebl to libdw. Programs often want to create ELF/DWARF string tables. We don't want (static) linking against ebl since those are internal functions that might change. This introduces dwelf_strtab_init, dwelf_strtab_add, dwelf_strtab_add_len, dwelf_strtab_finalize, dwelf_strent_off, dwelf_strent_str and dwelf_strtab_free. Documentation for each has been added to libdwelf.h. The add fucntion got a variant that takes the length explicitly and finalize was changed to return NULL on out of memory instead of aborting. All code and tests now uses the new functions. Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/Makefile.am2
-rw-r--r--src/elfcompress.c31
-rw-r--r--src/strip.c24
-rw-r--r--src/unstrip.c50
5 files changed, 69 insertions, 46 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d8de529a..e5a3fce3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2016-07-08 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am (strip_LDADD): Add libdw.
+ * elfcompress.c (process_file): Use dwelf_strtab functions instead of
+ ebl_strtab.
+ * strip.c (handle_elf): Likewise.
+ * unstrip.c (new_shstrtab): Likewise.
+
2016-07-06 Mark Wielaard <mjw@redhat.com>
* elf32-i386.script, i386_ld.c, ld.c, ld.h, ldgeneric.c, ldlex.l,
diff --git a/src/Makefile.am b/src/Makefile.am
index 6f796b33..9bb47651 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -71,7 +71,7 @@ readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl \
$(demanglelib)
size_LDADD = $(libelf) $(libeu) $(argp_LDADD)
-strip_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
+strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl
elflint_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
findtextrel_LDADD = $(libdw) $(libelf) $(argp_LDADD)
addr2line_LDADD = $(libdw) $(libelf) $(argp_LDADD) $(demanglelib)
diff --git a/src/elfcompress.c b/src/elfcompress.c
index d0ca469c..86cc7165 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -32,6 +32,7 @@
#include <unistd.h>
#include ELFUTILS_HEADER(elf)
#include ELFUTILS_HEADER(ebl)
+#include ELFUTILS_HEADER(dwelf)
#include <gelf.h>
#include "system.h"
@@ -265,9 +266,9 @@ process_file (const char *fname)
char *snamebuf = NULL;
/* String table (and symbol table), if section names need adjusting. */
- struct Ebl_Strtab *names = NULL;
- struct Ebl_Strent **scnstrents = NULL;
- struct Ebl_Strent **symstrents = NULL;
+ Dwelf_Strtab *names = NULL;
+ Dwelf_Strent **scnstrents = NULL;
+ Dwelf_Strent **symstrents = NULL;
char **scnnames = NULL;
/* Section data from names. */
@@ -308,7 +309,7 @@ process_file (const char *fname)
free (snamebuf);
if (names != NULL)
{
- ebl_strtabfree (names);
+ dwelf_strtab_free (names);
free (scnstrents);
free (symstrents);
free (namesbuf);
@@ -524,14 +525,14 @@ process_file (const char *fname)
if (adjust_names)
{
- names = ebl_strtabinit (true);
+ names = dwelf_strtab_init (true);
if (names == NULL)
{
error (0, 0, "Not enough memory for new strtab");
return cleanup (-1);
}
scnstrents = xmalloc (shnum
- * sizeof (struct Ebl_Strent *));
+ * sizeof (Dwelf_Strent *));
scnnames = xcalloc (shnum, sizeof (char *));
}
@@ -870,7 +871,7 @@ process_file (const char *fname)
/* We need to keep a copy of the name till the strtab is done. */
name = scnnames[ndx] = xstrdup (name);
- if ((scnstrents[ndx] = ebl_strtabadd (names, name, 0)) == NULL)
+ if ((scnstrents[ndx] = dwelf_strtab_add (names, name)) == NULL)
{
error (0, 0, "No memory to add section name string table");
return cleanup (-1);
@@ -916,7 +917,7 @@ process_file (const char *fname)
}
size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT);
size_t syms = symd->d_size / elsize;
- symstrents = xmalloc (syms * sizeof (struct Ebl_Strent *));
+ symstrents = xmalloc (syms * sizeof (Dwelf_Strent *));
for (size_t i = 0; i < syms; i++)
{
GElf_Sym sym_mem;
@@ -938,7 +939,7 @@ process_file (const char *fname)
error (0, 0, "Couldn't get symbol %zd name", i);
return cleanup (-1);
}
- symstrents[i] = ebl_strtabadd (names, symname, 0);
+ symstrents[i] = dwelf_strtab_add (names, symname);
if (symstrents[i] == NULL)
{
error (0, 0, "No memory to add to symbol name");
@@ -970,7 +971,11 @@ process_file (const char *fname)
error (0, 0, "Couldn't create new section header string table data");
return cleanup (-1);
}
- ebl_strtabfinalize (names, data);
+ if (dwelf_strtab_finalize (names, data) == NULL)
+ {
+ error (0, 0, "Not enough memory to create string table");
+ return cleanup (-1);
+ }
namesbuf = data->d_buf;
GElf_Shdr shdr_mem;
@@ -984,7 +989,7 @@ process_file (const char *fname)
/* Note that we also might have to compress and possibly set
sh_off below */
- shdr->sh_name = ebl_strtaboffset (scnstrents[shdrstrndx]);
+ shdr->sh_name = dwelf_strent_off (scnstrents[shdrstrndx]);
shdr->sh_type = SHT_STRTAB;
shdr->sh_flags = 0;
shdr->sh_addr = 0;
@@ -1099,7 +1104,7 @@ process_file (const char *fname)
}
if (adjust_names)
- shdr->sh_name = ebl_strtaboffset (scnstrents[ndx]);
+ shdr->sh_name = dwelf_strent_off (scnstrents[ndx]);
if (gelf_update_shdr (scn, shdr) == 0)
{
@@ -1133,7 +1138,7 @@ process_file (const char *fname)
if (sym->st_name != 0)
{
- sym->st_name = ebl_strtaboffset (symstrents[i]);
+ sym->st_name = dwelf_strent_off (symstrents[i]);
if (gelf_update_sym (symd, i, sym) == 0)
{
diff --git a/src/strip.c b/src/strip.c
index a6042445..23d3d51b 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -42,6 +42,7 @@
#include <elf-knowledge.h>
#include <libebl.h>
+#include "libdwelf.h"
#include <system.h>
typedef uint8_t GElf_Byte;
@@ -432,7 +433,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
Elf32_Word group_idx;
Elf32_Word group_cnt;
Elf_Scn *newscn;
- struct Ebl_Strent *se;
+ Dwelf_Strent *se;
Elf32_Word *newsymidx;
} *shdr_info = NULL;
Elf_Scn *scn;
@@ -443,7 +444,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
GElf_Ehdr *newehdr;
GElf_Ehdr debugehdr_mem;
GElf_Ehdr *debugehdr;
- struct Ebl_Strtab *shst = NULL;
+ Dwelf_Strtab *shst = NULL;
Elf_Data debuglink_crc_data;
bool any_symtab_changes = false;
Elf_Data *shstrtab_data = NULL;
@@ -1043,7 +1044,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
will already be marked as unused. */
/* We need a string table for the section headers. */
- shst = ebl_strtabinit (true);
+ shst = dwelf_strtab_init (true);
if (shst == NULL)
{
cleanup_debug ();
@@ -1071,7 +1072,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
/* Add this name to the section header string table. */
- shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
+ shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name);
}
/* Test whether we are doing anything at all. */
@@ -1083,7 +1084,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (debug_fname != NULL && !remove_shdrs)
{
/* Add the section header string table section name. */
- shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
+ shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15);
shdr_info[cnt].idx = idx++;
/* Create the section header. */
@@ -1146,7 +1147,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
shdridx = cnt;
/* Add the section header string table section name. */
- shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
+ shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".shstrtab", 10);
shdr_info[cnt].idx = idx;
/* Create the section header. */
@@ -1183,7 +1184,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
gettext ("while create section header string table: %s"),
elf_errmsg (-1));
}
- ebl_strtabfinalize (shst, shstrtab_data);
+ if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL)
+ {
+ cleanup_debug ();
+ error (EXIT_FAILURE, 0,
+ gettext ("no memory to create section header string table"));
+ }
/* We have to set the section size. */
shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
@@ -1199,7 +1205,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
elf_assert (scn != NULL);
/* Update the name. */
- shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
+ shdr_info[cnt].shdr.sh_name = dwelf_strent_off (shdr_info[cnt].se);
/* Update the section header from the input file. Some fields
might be section indeces which now have to be adjusted. */
@@ -2171,7 +2177,7 @@ while computing checksum for debug information"));
if (shstrtab_data != NULL)
free (shstrtab_data->d_buf);
if (shst != NULL)
- ebl_strtabfree (shst);
+ dwelf_strtab_free (shst);
/* That was it. Close the descriptors. */
if (elf_end (newelf) != 0)
diff --git a/src/unstrip.c b/src/unstrip.c
index adeb5991..46737381 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -48,6 +48,7 @@
#include <gelf.h>
#include <libebl.h>
#include <libdwfl.h>
+#include "libdwelf.h"
#include "system.h"
#ifndef _
@@ -686,7 +687,7 @@ struct section
Elf_Scn *scn;
const char *name;
Elf_Scn *outscn;
- struct Ebl_Strent *strent;
+ Dwelf_Strent *strent;
GElf_Shdr shdr;
};
@@ -757,7 +758,7 @@ struct symbol
union
{
const char *name;
- struct Ebl_Strent *strent;
+ Dwelf_Strent *strent;
};
union
{
@@ -1214,12 +1215,12 @@ static Elf_Data *
new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
Elf_Data *shstrtab, size_t unstripped_shstrndx,
struct section *sections, size_t stripped_shnum,
- struct Ebl_Strtab *strtab)
+ Dwelf_Strtab *strtab)
{
if (strtab == NULL)
return NULL;
- struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
+ Dwelf_Strent *unstripped_strent[unstripped_shnum - 1];
memset (unstripped_strent, 0, sizeof unstripped_strent);
for (struct section *sec = sections;
sec < &sections[stripped_shnum - 1];
@@ -1228,7 +1229,7 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
{
if (sec->strent == NULL)
{
- sec->strent = ebl_strtabadd (strtab, sec->name, 0);
+ sec->strent = dwelf_strtab_add (strtab, sec->name);
ELF_CHECK (sec->strent != NULL,
_("cannot add section name to string table: %s"));
}
@@ -1243,7 +1244,7 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
const char *name = get_section_name (i + 1, shdr, shstrtab);
- unstripped_strent[i] = ebl_strtabadd (strtab, name, 0);
+ unstripped_strent[i] = dwelf_strtab_add (strtab, name);
ELF_CHECK (unstripped_strent[i] != NULL,
_("cannot add section name to string table: %s"));
}
@@ -1255,7 +1256,8 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
unstripped_shstrndx), NULL);
ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
_("cannot update section header string table data: %s"));
- ebl_strtabfinalize (strtab, strtab_data);
+ if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
+ error (EXIT_FAILURE, 0, "Not enough memory to create string table");
/* Update the sh_name fields of sections we aren't modifying later. */
for (size_t i = 0; i < unstripped_shnum - 1; ++i)
@@ -1264,7 +1266,7 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
Elf_Scn *scn = elf_getscn (unstripped, i + 1);
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]);
+ shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
if (i + 1 == unstripped_shstrndx)
shdr->sh_size = strtab_data->d_size;
update_shdr (scn, shdr);
@@ -1456,7 +1458,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
const struct section *stripped_dynsym = NULL;
size_t debuglink = SHN_UNDEF;
size_t ndx_section[stripped_shnum - 1];
- struct Ebl_Strtab *strtab = NULL;
+ Dwelf_Strtab *strtab = NULL;
for (struct section *sec = sections;
sec < &sections[stripped_shnum - 1];
++sec)
@@ -1508,8 +1510,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
_("cannot add new section: %s"));
if (strtab == NULL)
- strtab = ebl_strtabinit (true);
- sec->strent = ebl_strtabadd (strtab, sec->name, 0);
+ strtab = dwelf_strtab_init (true);
+ sec->strent = dwelf_strtab_add (strtab, sec->name);
ELF_CHECK (sec->strent != NULL,
_("cannot add section name to string table: %s"));
}
@@ -1570,7 +1572,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
if (strtab != NULL)
- shdr_mem.sh_name = ebl_strtaboffset (sec->strent);
+ shdr_mem.sh_name = dwelf_strent_off (sec->strent);
Elf_Data *indata = elf_getdata (sec->scn, NULL);
ELF_CHECK (indata != NULL, _("cannot get section data: %s"));
@@ -1641,7 +1643,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* We may need to update the symbol table. */
Elf_Data *symdata = NULL;
- struct Ebl_Strtab *symstrtab = NULL;
+ Dwelf_Strtab *symstrtab = NULL;
Elf_Data *symstrdata = NULL;
if (unstripped_symtab != NULL && (stripped_symtab != NULL
|| check_prelink /* Section adjustments. */
@@ -1721,13 +1723,13 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* Now a final pass updates the map with the final order,
and builds up the new string table. */
- symstrtab = ebl_strtabinit (true);
+ symstrtab = dwelf_strtab_init (true);
for (size_t i = 0; i < nsym; ++i)
{
assert (symbols[i].name != NULL);
assert (*symbols[i].map != 0);
*symbols[i].map = 1 + i;
- symbols[i].strent = ebl_strtabadd (symstrtab, symbols[i].name, 0);
+ symbols[i].strent = dwelf_strtab_add (symstrtab, symbols[i].name);
}
/* Scan the discarded symbols too, just to update their slots
@@ -1752,7 +1754,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* If symtab and the section header table share the string table
add the section names to the strtab and then (after finalizing)
fixup the section header sh_names. Also dispose of the old data. */
- struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
+ Dwelf_Strent *unstripped_strent[unstripped_shnum - 1];
if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
{
for (size_t i = 0; i < unstripped_shnum - 1; ++i)
@@ -1761,20 +1763,22 @@ more sections in stripped file than debug file -- arguments reversed?"));
GElf_Shdr mem;
GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
const char *name = get_section_name (i + 1, hdr, shstrtab);
- unstripped_strent[i] = ebl_strtabadd (symstrtab, name, 0);
+ unstripped_strent[i] = dwelf_strtab_add (symstrtab, name);
ELF_CHECK (unstripped_strent[i] != NULL,
_("cannot add section name to string table: %s"));
}
if (strtab != NULL)
{
- ebl_strtabfree (strtab);
+ dwelf_strtab_free (strtab);
free (strtab_data->d_buf);
strtab = NULL;
}
}
- ebl_strtabfinalize (symstrtab, symstrdata);
+ if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL)
+ error (EXIT_FAILURE, 0, "Not enough memory to create symbol table");
+
elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
/* And update the section header names if necessary. */
@@ -1785,7 +1789,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
Elf_Scn *sec = elf_getscn (unstripped, i + 1);
GElf_Shdr mem;
GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
- shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]);
+ shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
update_shdr (sec, hdr);
}
}
@@ -1810,7 +1814,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
struct symbol *s = &symbols[i];
/* Fill in the symbol details. */
- sym.st_name = ebl_strtaboffset (s->strent);
+ sym.st_name = dwelf_strent_off (s->strent);
sym.st_value = s->value; /* Already biased to output address. */
sym.st_size = s->size;
sym.st_shndx = s->shndx; /* Already mapped to output index. */
@@ -1959,13 +1963,13 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (strtab != NULL)
{
- ebl_strtabfree (strtab);
+ dwelf_strtab_free (strtab);
free (strtab_data->d_buf);
}
if (symstrtab != NULL)
{
- ebl_strtabfree (symstrtab);
+ dwelf_strtab_free (symstrtab);
free (symstrdata->d_buf);
}
free_new_data ();