From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============1487027393510625189==" MIME-Version: 1.0 From: Mark Wielaard To: elfutils-devel@lists.fedorahosted.org Subject: [PATCH] unstrip: Add --force to force combining files when ELF headers don't match. Date: Mon, 26 May 2014 22:15:08 +0200 Message-ID: <1401135308-7570-1-git-send-email-mjw@redhat.com> --===============1487027393510625189== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Older versions of GNU binutils strip would drop some ELF header flags. Causing the main ELF file and the separate .debug file to have mismatched ELF header fields. Unfortunately some distros are still shipping such files. eu-unstrip doesn't want to recombine such files. Add a more explicit explanation which fields don't match and provide a --force, -F flag to force combining such files anyway (producing a warning). https://bugzilla.redhat.com/show_bug.cgi?id=3D698005 https://bugzilla.redhat.com/show_bug.cgi?id=3D806474 Signed-off-by: Mark Wielaard --- ChangeLog | 4 +++ NEWS | 5 ++++ src/ChangeLog | 15 +++++++++++++ src/unstrip.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----------= --- 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84dd193..b05f5bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-05-26 Mark Wielaard + + * NEWS: New section 0.160. Add unstrip --force. + 2014-05-17 Mark Wielaard = * configure.ac: Set version to 0.159. diff --git a/NEWS b/NEWS index 8ac4631..4050200 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Version 0.160 + +unstrip: New option -F, --force to combining files even if some ELF headers + don't seem to match. + Version 0.159 = stack: New option -d, --debugname to lookup DWARF debuginfo name for frame. diff --git a/src/ChangeLog b/src/ChangeLog index 4197ccd..4067583 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2014-05-26 Mark Wielaard + + * unstrip.c (options): Add --force, -F. + (struct arg_info): Add bool force. + (parse_opt): Handle 'F', set force. + (handle_explicit_files): Add force argument, add warn function, + separate check ehdr field checks, use warn. + (handle_dwfl_module): Add force argument, pass on to + handle_explicit_files. + (handle_output_dir_module): Add force argument, pass on to + handle_dwfl_module. + (handle_implicit_modules): Pass info->force to handle_dwfl_module and + handle_output_dir_module. + (main): Pass info.force to handle_explicit_files. + 2014-05-19 Mark Wielaard = * elflint.c (check_reloc_shdr): Check ebl_check_reloc_target_type. diff --git a/src/unstrip.c b/src/unstrip.c index f6660a3..4738abb 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -1,5 +1,5 @@ /* Combine stripped files with separate symbols and debug information. - Copyright (C) 2007-2012 Red Hat, Inc. + Copyright (C) 2007-2012, 2014 Red Hat, Inc. This file is part of elfutils. Written by Roland McGrath , 2007. = @@ -82,6 +82,9 @@ static const struct argp_option options[] =3D N_("Apply relocations to section contents in ET_REL files"), 0 }, { "list-only", 'n', NULL, 0, N_("Only list module and file names, build IDs"), 0 }, + { "force", 'F', NULL, 0, + N_("Force combining files even if some ELF headers don't seem to match= "), + 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; = @@ -97,6 +100,7 @@ struct arg_info bool modnames; bool match_files; bool relocate; + bool force; }; = /* Handle program arguments. */ @@ -147,6 +151,9 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'R': info->relocate =3D true; break; + case 'F': + info->force =3D true; + break; = case ARGP_KEY_ARGS: case ARGP_KEY_NO_ARGS: @@ -1935,9 +1942,20 @@ open_file (const char *file, bool writable) = /* Handle a pair of files we need to open by name. */ static void -handle_explicit_files (const char *output_file, bool create_dirs, +handle_explicit_files (const char *output_file, bool create_dirs, bool for= ce, const char *stripped_file, const char *unstripped_file) { + + /* Warn, and exit if not forced to continue, if some ELF header + sanity check for the stripped and unstripped files failed. */ + void warn (const char *msg) + { + error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.", + force ? _("WARNING: ") : "", + stripped_file, unstripped_file, msg, + force ? "" : _(", use --force")); + } + int stripped_fd =3D open_file (stripped_file, false); Elf *stripped =3D elf_begin (stripped_fd, ELF_C_READ, NULL); GElf_Ehdr stripped_ehdr; @@ -1956,12 +1974,23 @@ handle_explicit_files (const char *output_file, boo= l create_dirs, ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr), _("cannot create ELF descriptor: %s")); = - if (memcmp (stripped_ehdr.e_ident, unstripped_ehdr.e_ident, EI_NIDEN= T) - || stripped_ehdr.e_type !=3D unstripped_ehdr.e_type - || stripped_ehdr.e_machine !=3D unstripped_ehdr.e_machine - || stripped_ehdr.e_phnum !=3D unstripped_ehdr.e_phnum) - error (EXIT_FAILURE, 0, _("'%s' and '%s' do not seem to match"), - stripped_file, unstripped_file); + if (memcmp (stripped_ehdr.e_ident, + unstripped_ehdr.e_ident, EI_NIDENT) !=3D 0) + warn (_("ELF header identification (e_ident) different")); + + if (stripped_ehdr.e_type !=3D unstripped_ehdr.e_type) + warn (_("ELF header type (e_type) different")); + + if (stripped_ehdr.e_machine !=3D unstripped_ehdr.e_machine) + warn (_("ELF header machine type (e_machine) different")); + + if (stripped_ehdr.e_phnum !=3D unstripped_ehdr.e_phnum) + { + /* Don't even try, not even with --force. */ + error (EXIT_FAILURE, 0, + "'%s' and '%s' program header numbers (e_phnum) different.", + stripped_file, unstripped_file); + } } = handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstrip= ped); @@ -1976,7 +2005,7 @@ handle_explicit_files (const char *output_file, bool = create_dirs, = /* Handle a pair of files opened implicitly by libdwfl for one module. */ static void -handle_dwfl_module (const char *output_file, bool create_dirs, +handle_dwfl_module (const char *output_file, bool create_dirs, bool force, Dwfl_Module *mod, bool all, bool ignore, bool relocate) { GElf_Addr bias; @@ -2048,7 +2077,7 @@ handle_dwfl_module (const char *output_file, bool cre= ate_dirs, (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, &stripped_file, &unstripped_file); = - handle_explicit_files (output_file, create_dirs, + handle_explicit_files (output_file, create_dirs, force, stripped_file, unstripped_file); return; } @@ -2068,7 +2097,7 @@ handle_dwfl_module (const char *output_file, bool cre= ate_dirs, = /* Handle one module being written to the output directory. */ static void -handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, +handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool f= orce, bool all, bool ignore, bool modnames, bool relocate) { if (! modnames) @@ -2089,7 +2118,7 @@ handle_output_dir_module (const char *output_dir, Dwf= l_Module *mod, if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file)= < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); = - handle_dwfl_module (output_file, true, mod, all, ignore, relocate); + handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate= ); } = = @@ -2201,12 +2230,12 @@ handle_implicit_modules (const struct arg_info *inf= o) { if (next (offset) !=3D 0) error (EXIT_FAILURE, 0, _("matched more than one module")); - handle_dwfl_module (info->output_file, false, mmi.found, + handle_dwfl_module (info->output_file, false, info->force, mmi.found, info->all, info->ignore, info->relocate); } else do - handle_output_dir_module (info->output_dir, mmi.found, + handle_output_dir_module (info->output_dir, mmi.found, info->force, info->all, info->ignore, info->modnames, info->relocate); while ((offset =3D next (offset)) > 0); @@ -2296,11 +2325,12 @@ or - if no debuginfo was found, or . if FILE contai= ns the debug information.\ char *file; if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); - handle_explicit_files (file, true, info.args[0], info.args[1]); + handle_explicit_files (file, true, info.force, + info.args[0], info.args[1]); free (file); } else - handle_explicit_files (info.output_file, false, + handle_explicit_files (info.output_file, false, info.force, info.args[0], info.args[1]); } else -- = 1.7.1 --===============1487027393510625189==--