summaryrefslogtreecommitdiff
path: root/src/unstrip.c
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2022-03-27 21:08:36 +0200
committerMark Wielaard <mark@klomp.org>2022-03-30 16:40:05 +0200
commitdec6d82cf2e9c79b9b45a29de5ea2d8f25cc633b (patch)
tree2bc33be084fe10b7b404f9c05800a3bfcc9e92c4 /src/unstrip.c
parent4a22e01277e37540d753e3513c4df3bd2b6e1246 (diff)
downloadelfutils-dec6d82cf2e9c79b9b45a29de5ea2d8f25cc633b.tar.gz
Introduce error_exit as a noreturn variant of error (EXIT_FAILURE, ...)
error (EXIT_FAILURE, ...) should be noreturn but on some systems it isn't. This may cause warnings about code that should not be reachable. So have an explicit error_exit wrapper that is noreturn (because it calls exit explicitly). Use error_exit in all tools under the src directory. https://bugzilla.redhat.com/show_bug.cgi?id=2068692 Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'src/unstrip.c')
-rw-r--r--src/unstrip.c166
1 files changed, 82 insertions, 84 deletions
diff --git a/src/unstrip.c b/src/unstrip.c
index aacc9aad..3472637a 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -225,7 +225,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
do \
{ \
if (unlikely (!(call))) \
- error (EXIT_FAILURE, 0, msg, elf_errmsg (-1)); \
+ error_exit (0, msg, elf_errmsg (-1)); \
} while (0)
/* Copy INELF to newly-created OUTELF, exit via error for any problems. */
@@ -316,7 +316,7 @@ make_directories (const char *path)
if (errno == ENOENT)
make_directories (dir);
else
- error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
+ error_exit (errno, _("cannot create directory '%s'"), dir);
}
free (dir);
}
@@ -440,7 +440,7 @@ adjust_reloc (GElf_Xword *info,
if (ndx != STN_UNDEF)
{
if (ndx > map_size)
- error (EXIT_FAILURE, 0, "bad symbol ndx section");
+ error_exit (0, "bad symbol ndx section");
*info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info));
}
}
@@ -456,7 +456,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
{
case SHT_REL:
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "REL section cannot have zero sh_entsize");
+ error_exit (0, "REL section cannot have zero sh_entsize");
for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
{
@@ -471,7 +471,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
case SHT_RELA:
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "RELA section cannot have zero sh_entsize");
+ error_exit (0, "RELA section cannot have zero sh_entsize");
for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
{
@@ -501,13 +501,13 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
/* We must expand the table and rejigger its contents. */
{
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "HASH section cannot have zero sh_entsize");
+ error_exit (0, "HASH section cannot have zero sh_entsize");
if (symshdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
+ error_exit (0, "Symbol table cannot have zero sh_entsize");
const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
const size_t onent = shdr->sh_size / shdr->sh_entsize;
if (data->d_size != shdr->sh_size)
- error (EXIT_FAILURE, 0, "HASH section has inconsistent size");
+ error_exit (0, "HASH section has inconsistent size");
#define CONVERT_HASH(Hash_Word) \
{ \
@@ -517,7 +517,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
const Hash_Word *const old_bucket = &old_hash[2]; \
const Hash_Word *const old_chain = &old_bucket[nbucket]; \
if (onent != 2 + nbucket + nchain) \
- error (EXIT_FAILURE, 0, "HASH section has inconsistent entsize"); \
+ error_exit (0, "HASH section has inconsistent entsize"); \
\
const size_t nent = 2 + nbucket + nsym; \
Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]); \
@@ -562,10 +562,9 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
/* We must expand the table and move its elements around. */
{
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0,
- "GNU_versym section cannot have zero sh_entsize");
+ error_exit (0, "GNU_versym section cannot have zero sh_entsize");
if (symshdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
+ error_exit (0, "Symbol table cannot have zero sh_entsize");
const size_t nent = symshdr->sh_size / symshdr->sh_entsize;
const size_t onent = shdr->sh_size / shdr->sh_entsize;
assert (nent >= onent);
@@ -591,9 +590,9 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
break;
default:
- error (EXIT_FAILURE, 0,
- _("unexpected section type in [%zu] with sh_link to symtab"),
- elf_ndxscn (inscn));
+ error_exit (0,
+ _("unexpected section type in [%zu] with sh_link to symtab"),
+ elf_ndxscn (inscn));
}
}
@@ -632,7 +631,7 @@ add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0, "Symbol table section cannot have zero sh_entsize");
+ error_exit (0, "Symbol table section cannot have zero sh_entsize");
const size_t nsym = shdr->sh_size / shdr->sh_entsize;
size_t symndx_map[nsym - 1];
@@ -865,8 +864,8 @@ collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
if (sym->st_name >= strdata->d_size
|| memrchr (strdata->d_buf + sym->st_name, '\0',
strdata->d_size - sym->st_name) == NULL)
- error (EXIT_FAILURE, 0,
- _("invalid string offset in symbol [%zu]"), i);
+ error_exit (0,
+ _("invalid string offset in symbol [%zu]"), i);
struct symbol *s = &table[i - 1];
s->map = &map[i - 1];
@@ -948,13 +947,13 @@ compare_symbols_output (const void *a, const void *b)
/* binutils always puts section symbols in section index order. */
CMP (shndx);
else if (s1 != s2)
- error (EXIT_FAILURE, 0, "section symbols in unexpected order");
+ error_exit (0, "section symbols in unexpected order");
}
/* Nothing really matters, so preserve the original order. */
CMP (map);
else if (s1 != s2)
- error (EXIT_FAILURE, 0, "found two identical symbols");
+ error_exit (0, "found two identical symbols");
}
return cmp;
@@ -1024,8 +1023,8 @@ static inline const char *
get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
{
if (shdr->sh_name >= shstrtab->d_size)
- error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
- ndx, elf_errmsg (-1));
+ error_exit (0, _("cannot read section [%zu] name: %s"),
+ ndx, elf_errmsg (-1));
return shstrtab->d_buf + shdr->sh_name;
}
@@ -1039,30 +1038,30 @@ get_group_sig (Elf *elf, GElf_Shdr *shdr)
Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
if (symscn == NULL)
- error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"),
- elf_errmsg (-1));
+ error_exit (0, _("bad sh_link for group section: %s"),
+ elf_errmsg (-1));
GElf_Shdr symshdr_mem;
GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
if (symshdr == NULL)
- error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"),
- elf_errmsg (-1));
+ error_exit (0, _("couldn't get shdr for group section: %s"),
+ elf_errmsg (-1));
Elf_Data *symdata = elf_getdata (symscn, NULL);
if (symdata == NULL)
- error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"),
- elf_errmsg (-1));
+ error_exit (0, _("bad data for group symbol section: %s"),
+ elf_errmsg (-1));
GElf_Sym sym_mem;
GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
if (sym == NULL)
- error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"),
- elf_errmsg (-1));
+ error_exit (0, _("couldn't get symbol for group section: %s"),
+ elf_errmsg (-1));
const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name);
if (sig == NULL)
- error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"),
- elf_errmsg (-1));
+ error_exit (0, _("bad symbol name for group section: %s"),
+ elf_errmsg (-1));
return sig;
}
@@ -1154,8 +1153,8 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
- error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
- (size_t) shnum, ".gnu.prelink_undo");
+ error_exit (0, _("overflow with shnum = %zu in '%s' section"),
+ (size_t) shnum, ".gnu.prelink_undo");
--shnum;
@@ -1165,8 +1164,8 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
src.d_type = ELF_T_SHDR;
if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
|| undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
- error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
- ".gnu.prelink_undo");
+ error_exit (0, _("invalid contents in '%s' section"),
+ ".gnu.prelink_undo");
const size_t shdr_bytes = shnum * shsize;
void *shdr = xmalloc (shdr_bytes);
@@ -1363,7 +1362,7 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
_("cannot update section header string table data: %s"));
if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
- error (EXIT_FAILURE, 0, "Not enough memory to create string table");
+ error_exit (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)
@@ -1405,11 +1404,11 @@ copy_elided_sections (Elf *unstripped, Elf *stripped,
_("cannot get section count: %s"));
if (unlikely (stripped_shnum > unstripped_shnum))
- error (EXIT_FAILURE, 0, _("\
+ error_exit (0, _("\
more sections in stripped file than debug file -- arguments reversed?"));
if (unlikely (stripped_shnum == 0))
- error (EXIT_FAILURE, 0, _("no sections in stripped file"));
+ error_exit (0, _("no sections in stripped file"));
/* Used as sanity check for allocated section offset, if the section
offset needs to be preserved. We want to know the max size of the
@@ -1432,8 +1431,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
sections[i].name = elf_strptr (stripped, stripped_shstrndx,
shdr->sh_name);
if (sections[i].name == NULL)
- error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
- elf_ndxscn (scn), elf_errmsg (-1));
+ error_exit (0, _("cannot read section [%zu] name: %s"),
+ elf_ndxscn (scn), elf_errmsg (-1));
sections[i].scn = scn;
sections[i].outscn = NULL;
sections[i].strent = NULL;
@@ -1552,9 +1551,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
}
if (sec == NULL)
- error (EXIT_FAILURE, 0,
- _("cannot find matching section for [%zu] '%s'"),
- elf_ndxscn (scn), name);
+ error_exit (0, _("cannot find matching section for [%zu] '%s'"),
+ elf_ndxscn (scn), name);
sec->outscn = scn;
}
@@ -1689,17 +1687,17 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (sec->shdr.sh_link != SHN_UNDEF)
{
if (sec->shdr.sh_link > ndx_sec_num)
- error (EXIT_FAILURE, 0,
- "section [%zd] has invalid sh_link %" PRId32,
- elf_ndxscn (sec->scn), sec->shdr.sh_link);
+ error_exit (0,
+ "section [%zd] has invalid sh_link %" PRId32,
+ elf_ndxscn (sec->scn), sec->shdr.sh_link);
shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1];
}
if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0)
{
if (sec->shdr.sh_info > ndx_sec_num)
- error (EXIT_FAILURE, 0,
- "section [%zd] has invalid sh_info %" PRId32,
- elf_ndxscn (sec->scn), sec->shdr.sh_info);
+ error_exit (0,
+ "section [%zd] has invalid sh_info %" PRId32,
+ elf_ndxscn (sec->scn), sec->shdr.sh_info);
shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
}
@@ -1717,9 +1715,9 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
{
if (max_off > 0 && sec->shdr.sh_offset > (Elf64_Off) max_off)
- error (EXIT_FAILURE, 0,
- "allocated section offset too large [%zd] %" PRIx64,
- elf_ndxscn (sec->scn), sec->shdr.sh_offset);
+ error_exit (0,
+ "allocated section offset too large [%zd] %" PRIx64,
+ elf_ndxscn (sec->scn), sec->shdr.sh_offset);
shdr_mem.sh_offset = sec->shdr.sh_offset;
placed[elf_ndxscn (sec->outscn) - 1] = true;
@@ -1740,8 +1738,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
Elf_Data *shndxdata = NULL; /* XXX */
if (shdr_mem.sh_entsize == 0)
- error (EXIT_FAILURE, 0,
- "SYMTAB section cannot have zero sh_entsize");
+ error_exit (0,
+ "SYMTAB section cannot have zero sh_entsize");
for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i)
{
GElf_Sym sym_mem;
@@ -1756,8 +1754,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
{
if (shndx >= stripped_shnum)
- error (EXIT_FAILURE, 0,
- _("symbol [%zu] has invalid section index"), i);
+ error_exit (0,
+ _("symbol [%zu] has invalid section index"), i);
shndx = ndx_section[shndx - 1];
if (shndx < SHN_LORESERVE)
@@ -1788,8 +1786,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
Elf32_Word *shndx = (Elf32_Word *) outdata->d_buf;
for (size_t i = 1; i < shdr_mem.sh_size / sizeof (Elf32_Word); ++i)
if (shndx[i] == SHN_UNDEF || shndx[i] >= stripped_shnum)
- error (EXIT_FAILURE, 0,
- _("group has invalid section index [%zd]"), i);
+ error_exit (0,
+ _("group has invalid section index [%zd]"), i);
else
shndx[i] = ndx_section[shndx[i] - 1];
}
@@ -1815,8 +1813,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
if (shdr->sh_entsize == 0)
- error (EXIT_FAILURE, 0,
- "unstripped SYMTAB section cannot have zero sh_entsize");
+ error_exit (0,
+ "unstripped SYMTAB section cannot have zero sh_entsize");
const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize;
/* First collect all the symbols from both tables. */
@@ -1936,7 +1934,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
}
if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL)
- error (EXIT_FAILURE, 0, "Not enough memory to create symbol table");
+ error_exit (0, "Not enough memory to create symbol table");
elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
@@ -2194,7 +2192,7 @@ DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"),
(stripped_ehdr->e_type == ET_REL
? DEFFILEMODE : ACCESSPERMS));
if (outfd < 0)
- error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file);
+ error_exit (errno, _("cannot open '%s'"), output_file);
Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s"));
@@ -2223,7 +2221,7 @@ open_file (const char *file, bool writable)
{
int fd = open (file, writable ? O_RDWR : O_RDONLY);
if (fd < 0)
- error (EXIT_FAILURE, errno, _("cannot open '%s'"), file);
+ error_exit (errno, _("cannot open '%s'"), file);
return fd;
}
@@ -2306,13 +2304,13 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, &file, NULL);
if (file == NULL)
- error (EXIT_FAILURE, 0,
- _("cannot find stripped file for module '%s': %s"),
- modname, dwfl_errmsg (-1));
+ error_exit (0,
+ _("cannot find stripped file for module '%s': %s"),
+ modname, dwfl_errmsg (-1));
else
- error (EXIT_FAILURE, 0,
- _("cannot open stripped file '%s' for module '%s': %s"),
- modname, file, dwfl_errmsg (-1));
+ error_exit (0,
+ _("cannot open stripped file '%s' for module '%s': %s"),
+ modname, file, dwfl_errmsg (-1));
}
Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
@@ -2325,13 +2323,13 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, NULL, &file);
if (file == NULL)
- error (EXIT_FAILURE, 0,
- _("cannot find debug file for module '%s': %s"),
- modname, dwfl_errmsg (-1));
+ error_exit (0,
+ _("cannot find debug file for module '%s': %s"),
+ modname, dwfl_errmsg (-1));
else
- error (EXIT_FAILURE, 0,
- _("cannot open debug file '%s' for module '%s': %s"),
- modname, file, dwfl_errmsg (-1));
+ error_exit (0,
+ _("cannot open debug file '%s' for module '%s': %s"),
+ modname, file, dwfl_errmsg (-1));
}
if (debug == stripped)
@@ -2343,8 +2341,8 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
const char *file;
const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, &file, NULL);
- error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"),
- modname, file);
+ error_exit (0, _("module '%s' file '%s' is not stripped"),
+ modname, file);
}
}
@@ -2373,10 +2371,10 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
get sh_addr values assigned have them, even ones not used in DWARF.
They might still be used in the symbol table. */
if (dwfl_module_relocations (mod) < 0)
- error (EXIT_FAILURE, 0,
- _("cannot cache section addresses for module '%s': %s"),
- dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
- dwfl_errmsg (-1));
+ error_exit (0,
+ _("cannot cache section addresses for module '%s': %s"),
+ dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+ dwfl_errmsg (-1));
}
handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
@@ -2502,7 +2500,7 @@ handle_implicit_modules (const struct arg_info *info)
struct match_module_info mmi = { info->args, NULL, info->match_files };
ptrdiff_t offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, 0);
if (offset == 0)
- error (EXIT_FAILURE, 0, _("no matching modules found"));
+ error_exit (0, _("no matching modules found"));
if (info->list)
do
@@ -2512,7 +2510,7 @@ handle_implicit_modules (const struct arg_info *info)
else if (info->output_dir == NULL)
{
if (dwfl_getmodules (info->dwfl, &match_module, &mmi, offset) != 0)
- error (EXIT_FAILURE, 0, _("matched more than one module"));
+ error_exit (0, _("matched more than one module"));
handle_dwfl_module (info->output_file, false, info->force, mmi.found,
info->all, info->ignore, info->relocate);
}