diff options
author | Mark Wielaard <mark@klomp.org> | 2022-03-27 21:08:36 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2022-03-30 16:40:05 +0200 |
commit | dec6d82cf2e9c79b9b45a29de5ea2d8f25cc633b (patch) | |
tree | 2bc33be084fe10b7b404f9c05800a3bfcc9e92c4 /src/unstrip.c | |
parent | 4a22e01277e37540d753e3513c4df3bd2b6e1246 (diff) | |
download | elfutils-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.c | 166 |
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); } |