From bbad633bb88cf35a8865a07b80609b57d2f29bdd Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 31 Dec 2013 09:52:24 +0000 Subject: [PATCH] * objcopy.c (dump_sections): New list. (command_line_switch): Add OPTION_DUMP_SECTION. (copy_options): Add dump-section. (copy_usage): Document new option. (copy_object): Dump requested sections. (copy_main): Handle --dump-section. * doc/binutils.texi: Document --dump-section option. * NEWS: Mention new feature. --- binutils/ChangeLog | 11 ++++++ binutils/NEWS | 2 + binutils/doc/binutils.texi | 12 ++++++ binutils/objcopy.c | 78 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 04ad95c26c2..541de444b3f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,14 @@ +2013-12-31 Nick Clifton + + * objcopy.c (dump_sections): New list. + (command_line_switch): Add OPTION_DUMP_SECTION. + (copy_options): Add dump-section. + (copy_usage): Document new option. + (copy_object): Dump requested sections. + (copy_main): Handle --dump-section. + * doc/binutils.texi: Document --dump-section option. + * NEWS: Mention new feature. + 2013-12-20 Nick Clifton PR binutils/16218 diff --git a/binutils/NEWS b/binutils/NEWS index f1f00613a0c..b19f87b4232 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add --dump-section option to objcopy. + * Add support for the Andes NDS32. Changes in 2.24: diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 6abcae29dbb..39aa077fec9 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1089,6 +1089,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{--change-warnings}] [@option{--no-change-warnings}] [@option{--set-section-flags} @var{sectionpattern}=@var{flags}] [@option{--add-section} @var{sectionname}=@var{filename}] + [@option{--dump-section} @var{sectionname}=@var{filename}] [@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]] [@option{--long-section-names} @{enable,disable,keep@}] [@option{--change-leading-char}] [@option{--remove-leading-char}] @@ -1475,6 +1476,17 @@ Add a new section named @var{sectionname} while copying the file. The contents of the new section are taken from the file @var{filename}. The size of the section will be the size of the file. This option only works on file formats which can support sections with arbitrary names. +Note - it may be necessary to use the @option{--set-section-flags} +option to set the attributes of the newly created section. + +@item --dump-section @var{sectionname}=@var{filename} +Place the contents of section named @var{sectionname} into the file +@var{filename}, overwriting any contents that may have been there +previously. This option is the inverse of @option{--add-section}. +This option is similar to the @option{--only-section} option except +that it does not create a formatted file, it just dumps the contents +as raw binary data, without applying any relocations. The option can +be specified more than once. @item --rename-section @var{oldname}=@var{newname}[,@var{flags}] Rename a section from @var{oldname} to @var{newname}, optionally diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 14f6b96c7d6..9a6bb72d385 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -186,6 +186,9 @@ struct section_add /* List of sections to add to the output BFD. */ static struct section_add *add_sections; +/* List of sections to dump from the output BFD. */ +static struct section_add *dump_sections; + /* If non-NULL the argument to --add-gnu-debuglink. This should be the filename to store in the .gnu_debuglink section. */ static const char * gnu_debuglink_filename = NULL; @@ -259,6 +262,7 @@ static enum long_section_name_handling long_section_names = KEEP; enum command_line_switch { OPTION_ADD_SECTION=150, + OPTION_DUMP_SECTION, OPTION_CHANGE_ADDRESSES, OPTION_CHANGE_LEADING_CHAR, OPTION_CHANGE_START, @@ -377,6 +381,7 @@ static struct option copy_options[] = {"disable-deterministic-archives", no_argument, 0, 'U'}, {"discard-all", no_argument, 0, 'x'}, {"discard-locals", no_argument, 0, 'X'}, + {"dump-section", required_argument, 0, OPTION_DUMP_SECTION}, {"enable-deterministic-archives", no_argument, 0, 'D'}, {"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO}, {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL}, @@ -548,6 +553,7 @@ copy_usage (FILE *stream, int exit_status) --set-section-flags =\n\ Set section 's properties to \n\ --add-section = Add section found in to output\n\ + --dump-section = Dump the contents of section into \n\ --rename-section =[,] Rename section to \n\ --long-section-names {enable|disable|keep}\n\ Handle long section names in Coff objects.\n\ @@ -1826,6 +1832,59 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) } } + if (dump_sections != NULL) + { + struct section_add * pdump; + + for (pdump = dump_sections; pdump != NULL; pdump = pdump->next) + { + asection * sec; + + sec = bfd_get_section_by_name (ibfd, pdump->name); + if (sec == NULL) + { + bfd_nonfatal_message (NULL, ibfd, NULL, + _("can't dump section '%s' - it does not exist"), + pdump->name); + continue; + } + + if ((bfd_get_section_flags (ibfd, sec) & SEC_HAS_CONTENTS) == 0) + { + bfd_nonfatal_message (NULL, ibfd, sec, + _("can't dump section - it has no contents")); + continue; + } + + bfd_size_type size = bfd_get_section_size (sec); + if (size == 0) + { + bfd_nonfatal_message (NULL, ibfd, sec, + _("can't dump section - it is empty")); + continue; + } + + FILE * f; + f = fopen (pdump->filename, FOPEN_WB); + if (f == NULL) + { + bfd_nonfatal_message (pdump->filename, NULL, NULL, + _("could not open section dump file")); + continue; + } + + bfd_byte * contents = xmalloc (size); + if (bfd_get_section_contents (ibfd, sec, contents, 0, size)) + fwrite (contents, 1, size, f); + else + bfd_nonfatal_message (NULL, ibfd, sec, + _("could not retrieve section contents")); + + fclose (f); + free (contents); + } + } + if (gnu_debuglink_filename != NULL) { /* PR 15125: Give a helpful warning message if @@ -3653,6 +3712,25 @@ copy_main (int argc, char *argv[]) } break; + case OPTION_DUMP_SECTION: + { + const char *s; + struct section_add *pa; + + s = strchr (optarg, '='); + + if (s == NULL) + fatal (_("bad format for %s"), "--dump-section"); + + pa = (struct section_add *) xmalloc (sizeof * pa); + pa->name = xstrndup (optarg, s - optarg); + pa->filename = s + 1; + pa->next = dump_sections; + pa->contents = NULL; + dump_sections = pa; + } + break; + case OPTION_CHANGE_START: change_start = parse_vma (optarg, "--change-start"); break; -- 2.30.2