public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add --update-section option to objcopy.
@ 2015-02-23 13:26 Andrew Burgess
  2015-02-23 15:36 ` [PATCH 2/2] objcopy: Add --update-section option Andrew Burgess
  2015-02-23 15:47 ` [PATCH 1/2] objcopy: Factor out some of the option parsing code Andrew Burgess
  0 siblings, 2 replies; 11+ messages in thread
From: Andrew Burgess @ 2015-02-23 13:26 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Burgess

A new `--update-section' option for objcopy allows the contents of a
section to be replaced without having to do `--remove-section' then
`--add-section'.

The problem with the remove then add strategy is that, the flags and
addresses for section being added back are lost, and need to be
restored using `--set-section-flags' and `--change-section-vma'.
However, for ELF format files the section to segment mapping is also
lost by removing the section, and there's currently no way to restore
the mapping.

The new `--update-section' changes the contents, and size of a section
"in-place", maintaining the address, flags, and for ELF files the
section to segment mapping.

The first patch is just a small refactor to allow some code to be
reused in the second patch.

The second patch adds the new option along with a test.

---

Andrew Burgess (2):
  objcopy: Factor out some of the option parsing code.
  objcopy: Add --update-section option.

 binutils/ChangeLog                                 |  19 ++
 binutils/doc/binutils.texi                         |  10 +
 binutils/objcopy.c                                 | 222 +++++++++++++++------
 binutils/testsuite/ChangeLog                       |   7 +
 binutils/testsuite/binutils-all/update-1.s         |   2 +
 binutils/testsuite/binutils-all/update-2.s         |   2 +
 binutils/testsuite/binutils-all/update-3.s         |   3 +
 binutils/testsuite/binutils-all/update-section.exp |  84 ++++++++
 8 files changed, 283 insertions(+), 66 deletions(-)
 create mode 100644 binutils/testsuite/binutils-all/update-1.s
 create mode 100644 binutils/testsuite/binutils-all/update-2.s
 create mode 100644 binutils/testsuite/binutils-all/update-3.s
 create mode 100644 binutils/testsuite/binutils-all/update-section.exp

-- 
2.2.2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/2] objcopy: Add --update-section option.
  2015-02-23 13:26 [PATCH 0/2] Add --update-section option to objcopy Andrew Burgess
@ 2015-02-23 15:36 ` Andrew Burgess
  2015-02-26  2:57   ` Richard Sandiford
  2015-02-23 15:47 ` [PATCH 1/2] objcopy: Factor out some of the option parsing code Andrew Burgess
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Burgess @ 2015-02-23 15:36 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Burgess

New option for objcopy --update-section allows the contents of a section
to be updated while maintaining the section flags, and, for ELF files,
the section to segment mapping.

New test uses --dump-section and --update-section to check that a
section can be made larger and smaller with an update.

binutils/ChangeLog:

	* objcopy.c (update_sections): New list.
	(command_line_switch): Add OPTION_UPDATE_SECTION.
	(copy_options): Add update-section.
	(copy_usage): Document new option.
	(copy_object): Update size and content of requested sections.
	(is_update_section): New function.
	(skip_section): Don't copy for updated sections.
	(copy_main): Handle --update-section.
	* doc/binutils.texi (objcopy): Add description of --update-section
	option.

binutils/testsuite/ChangeLog:

	* binutils-all/update-1.s: New file.
	* binutils-all/update-2.s: New file.
	* binutils-all/update-3.s: New file.
	* binutils-all/update-section.exp: New file.
---
 binutils/ChangeLog                                 | 13 ++++
 binutils/doc/binutils.texi                         | 10 +++
 binutils/objcopy.c                                 | 79 ++++++++++++++++++++
 binutils/testsuite/ChangeLog                       |  7 ++
 binutils/testsuite/binutils-all/update-1.s         |  2 +
 binutils/testsuite/binutils-all/update-2.s         |  2 +
 binutils/testsuite/binutils-all/update-3.s         |  3 +
 binutils/testsuite/binutils-all/update-section.exp | 84 ++++++++++++++++++++++
 8 files changed, 200 insertions(+)
 create mode 100644 binutils/testsuite/binutils-all/update-1.s
 create mode 100644 binutils/testsuite/binutils-all/update-2.s
 create mode 100644 binutils/testsuite/binutils-all/update-3.s
 create mode 100644 binutils/testsuite/binutils-all/update-section.exp

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 2e5985f..ad9113d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,18 @@
 2015-02-20  Andrew Burgess  <andrew.burgess@embecosm.com>
 
+	* objcopy.c (update_sections): New list.
+	(command_line_switch): Add OPTION_UPDATE_SECTION.
+	(copy_options): Add update-section.
+	(copy_usage): Document new option.
+	(copy_object): Update size and content of requested sections.
+	(is_update_section): New function.
+	(skip_section): Don't copy for updated sections.
+	(copy_main): Handle --update-section.
+	* doc/binutils.texi (objcopy): Add description of --update-section
+	option.
+
+2015-02-20  Andrew Burgess  <andrew.burgess@embecosm.com>
+
 	* objcopy.c (init_section_add): New function.
 	(section_add_load_file): New function.
 	(copy_main): Make use of new functions.
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index a5bfd4c..9a26a12 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1091,6 +1091,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{--set-section-flags} @var{sectionpattern}=@var{flags}]
         [@option{--add-section} @var{sectionname}=@var{filename}]
         [@option{--dump-section} @var{sectionname}=@var{filename}]
+        [@option{--update-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}]
@@ -1489,6 +1490,15 @@ 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 --update-section @var{sectionname}=@var{filename}
+Replace the contents of section named @var{sectionname} with the
+contents of file @var{filename}, replacing any existing section
+contents.  The size of the section will be adjusted to the size of the
+file.  The section flags for @var{sectionname} will be unchanged.  For
+ELF format files the section to segment mapping will also remain
+unchanged, something which is not possible using
+@option{--remove-section} followed by @option{--add-section}.
+
 @item --rename-section @var{oldname}=@var{newname}[,@var{flags}]
 Rename a section from @var{oldname} to @var{newname}, optionally
 changing the section's flags to @var{flags} in the process.  This has
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index eb26320..7365bb2 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 update in the output BFD.  */
+static struct section_add *update_sections;
+
 /* List of sections to dump from the output BFD.  */
 static struct section_add *dump_sections;
 
@@ -262,6 +265,7 @@ static enum long_section_name_handling long_section_names = KEEP;
 enum command_line_switch
   {
     OPTION_ADD_SECTION=150,
+    OPTION_UPDATE_SECTION,
     OPTION_DUMP_SECTION,
     OPTION_CHANGE_ADDRESSES,
     OPTION_CHANGE_LEADING_CHAR,
@@ -361,6 +365,7 @@ static struct option copy_options[] =
 {
   {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
   {"add-section", required_argument, 0, OPTION_ADD_SECTION},
+  {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
   {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
@@ -553,6 +558,9 @@ copy_usage (FILE *stream, int exit_status)
      --set-section-flags <name>=<flags>\n\
                                    Set section <name>'s properties to <flags>\n\
      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
+     --update-section <name>=<file>\n\
+                                   Update contents of section <name> with\n\
+                                   contents found in <file>.\n\
      --dump-section <name>=<file>  Dump the contents of section <name> into <file>\n\
      --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
      --long-section-names {enable|disable|keep}\n\
@@ -1865,6 +1873,31 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	}
     }
 
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+	   pupdate != NULL;
+	   pupdate = pupdate->next)
+	{
+	  pupdate->section = bfd_get_section_by_name (obfd, pupdate->name);
+	  if (pupdate->section == NULL)
+	    {
+	      bfd_nonfatal_message (NULL, obfd, NULL,
+				    _("can't update section '%s'"),
+				    pupdate->name);
+	      return FALSE;
+	    }
+
+	  if (! bfd_set_section_size (obfd, pupdate->section, pupdate->size))
+	    {
+	      bfd_nonfatal_message (NULL, obfd, pupdate->section, NULL);
+	      return FALSE;
+	    }
+	}
+    }
+
   if (dump_sections != NULL)
     {
       struct section_add * pdump;
@@ -2150,6 +2183,24 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	}
     }
 
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+           pupdate != NULL;
+           pupdate = pupdate->next)
+	{
+          if (! bfd_set_section_contents (obfd, pupdate->section,
+                                          pupdate->contents,
+					  0, pupdate->size))
+	    {
+	      bfd_nonfatal_message (NULL, obfd, pupdate->section, NULL);
+	      return FALSE;
+	    }
+	}
+    }
+
   if (gnu_debuglink_filename != NULL)
     {
       if (! bfd_fill_in_gnu_debuglink_section
@@ -2861,6 +2912,25 @@ loser:
   bfd_nonfatal_message (NULL, obfd, osection, err);
 }
 
+static bfd_boolean
+is_update_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+           pupdate != NULL;
+           pupdate = pupdate->next)
+	{
+          if (strcmp (sec->name, pupdate->name) == 0)
+            return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 /* Return TRUE if input section ISECTION should be skipped.  */
 
 static bfd_boolean
@@ -2881,6 +2951,9 @@ skip_section (bfd *ibfd, sec_ptr isection)
   if (is_strip_section (ibfd, isection))
     return TRUE;
 
+  if (is_update_section (ibfd, isection))
+    return TRUE;
+
   flags = bfd_get_section_flags (ibfd, isection);
   if ((flags & SEC_GROUP) != 0)
     return TRUE;
@@ -3795,6 +3868,12 @@ copy_main (int argc, char *argv[])
           section_add_load_file (add_sections);
 	  break;
 
+	case OPTION_UPDATE_SECTION:
+	  update_sections = init_section_add (optarg, update_sections,
+                                              "--update-section");
+	  section_add_load_file (update_sections);
+	  break;
+
 	case OPTION_DUMP_SECTION:
           dump_sections = init_section_add (optarg, dump_sections,
                                             "--dump-section");
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index c73a6c3..05d71db 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-23  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* binutils-all/update-1.s: New file.
+	* binutils-all/update-2.s: New file.
+	* binutils-all/update-3.s: New file.
+	* binutils-all/update-section.exp: New file.
+
 2015-01-01  Alan Modra  <amodra@gmail.com>
 
 	Update year range in copyright notice of all files.
diff --git a/binutils/testsuite/binutils-all/update-1.s b/binutils/testsuite/binutils-all/update-1.s
new file mode 100644
index 0000000..84df14f
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-1.s
@@ -0,0 +1,2 @@
+        .section ".data", "aw"
+        .word 1, 1, 1, 1
diff --git a/binutils/testsuite/binutils-all/update-2.s b/binutils/testsuite/binutils-all/update-2.s
new file mode 100644
index 0000000..f0577a2
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-2.s
@@ -0,0 +1,2 @@
+        .section ".data", "aw"
+        .word 2, 2, 2, 2, 2, 2
diff --git a/binutils/testsuite/binutils-all/update-3.s b/binutils/testsuite/binutils-all/update-3.s
new file mode 100644
index 0000000..f902c26
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-3.s
@@ -0,0 +1,3 @@
+        .section ".data", "aw"
+        .word 3, 3
+
diff --git a/binutils/testsuite/binutils-all/update-section.exp b/binutils/testsuite/binutils-all/update-section.exp
new file mode 100644
index 0000000..7cc056e
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-section.exp
@@ -0,0 +1,84 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+if { [is_remote host] } then {
+    return
+}
+
+send_user "Version [binutil_version $OBJCOPY]"
+
+proc do_assemble {srcfile} {
+    global srcdir
+    global subdir
+    set objfile [regsub "\.s^" srcfile ".o"]
+    if {![binutils_assemble $srcdir/$subdir/${srcfile} tmpdir/${objfile}]} then {
+        return 0;
+    }
+    return 1;
+}
+
+proc do_objcopy {objfile extraflags} {
+    global OBJCOPY
+    global OBJCOPYFLAGS
+
+    set testname "objcopy $extraflags ${objfile}"
+    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS ${extraflags} tmpdir/${objfile}"]
+    if ![string match "" $got] then {
+        fail "objcopy ($testname)"
+        return 0
+    }
+    return 1
+}
+
+proc do_compare {file1 file2} {
+    set src1 "tmpdir/${file1}"
+    set src2 "tmpdir/${file2}"
+    set status [remote_exec build cmp "${src1} ${src2}"]
+    set exec_output [lindex $status 1]
+    set exec_output [prune_warnings $exec_output]
+
+    set testname "compare ${file1} ${file2}"
+    if [string match "" $exec_output] then {
+        pass "objcopy ($testname)"
+    } else {
+        send_log "$exec_output\n"
+        verbose "$exec_output" 1
+        fail "objcopy ($testname)"
+        return 0
+    }
+    return 1
+}
+
+#
+# Start Of Tests
+#
+
+if { ![do_assemble update-1.s]
+     || ![do_assemble update-2.s]
+     || ![do_assemble update-3.s] } then {
+    unsupported "update-section.exp"
+    return
+}
+
+# If any of these return false then a FAIL will already have been reported.
+if { ![do_objcopy update-1.o "--dump-section .data=tmpdir/dumped-contents"]
+     || ![do_objcopy update-2.o "--update-section .data=tmpdir/dumped-contents"]
+     || ![do_objcopy update-3.o "--update-section .data=tmpdir/dumped-contents"] } then {
+    return
+}
+
+do_compare update-1.o update-2.o
+do_compare update-1.o update-3.o
-- 
2.2.2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-23 13:26 [PATCH 0/2] Add --update-section option to objcopy Andrew Burgess
  2015-02-23 15:36 ` [PATCH 2/2] objcopy: Add --update-section option Andrew Burgess
@ 2015-02-23 15:47 ` Andrew Burgess
  2015-02-26  0:03   ` Richard Sandiford
  2015-02-26 18:08   ` Steve Ellcey
  1 sibling, 2 replies; 11+ messages in thread
From: Andrew Burgess @ 2015-02-23 15:47 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Burgess

This patch splits out some of the option parsing code, increasing code
reuse.

binutils/ChangeLog:

	* objcopy.c (init_section_add): New function.
	(section_add_load_file): New function.
	(copy_main): Make use of new functions.
---
 binutils/ChangeLog |   6 +++
 binutils/objcopy.c | 145 ++++++++++++++++++++++++++++-------------------------
 2 files changed, 84 insertions(+), 67 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 21e1f84..2e5985f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2015-02-20  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* objcopy.c (init_section_add): New function.
+	(section_add_load_file): New function.
+	(copy_main): Make use of new functions.
+
 2015-02-20  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
 	* readelf.c (get_note_type): Add NT_S390_VXRS_LOW and
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 8320793..eb26320 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3546,6 +3546,79 @@ convert_efi_target (char *efi)
     }
 }
 
+/* Allocate and return a pointer to a struct section_add, initialising the
+   structure using OPTARG, a string in the format "sectionname=filename".
+   The returned structure will have its next pointer set to NEXT.  The
+   OPTION field is the name of the command line option currently being
+   parsed, and is only used if an error needs to be reported.  */
+
+static struct section_add *
+init_section_add (const char *optarg,
+                  struct section_add *next,
+                  const char *option)
+{
+  struct section_add *pa;
+  const char *s;
+
+  s = strchr (optarg, '=');
+  if (s == NULL)
+    fatal (_("bad format for %s"), option);
+
+  pa = (struct section_add *) xmalloc (sizeof (struct section_add));
+  pa->name = xstrndup (optarg, s - optarg);
+  pa->filename = s + 1;
+  pa->next = next;
+  pa->contents = NULL;
+  pa->size = 0;
+
+  return pa;
+}
+
+/* Load the file specified in PA, allocating memory to hold the file
+   contents, and store a pointer to the allocated memory in the contents
+   field of PA.  The size field of PA is also updated.  All errors call
+   FATAL.  */
+
+static void
+section_add_load_file (struct section_add *pa)
+{
+  size_t off, alloc;
+  FILE *f;
+
+  /* We don't use get_file_size so that we can do
+     --add-section .note.GNU_stack=/dev/null
+     get_file_size doesn't work on /dev/null.  */
+
+  f = fopen (pa->filename, FOPEN_RB);
+  if (f == NULL)
+    fatal (_("cannot open: %s: %s"),
+           pa->filename, strerror (errno));
+
+  off = 0;
+  alloc = 4096;
+  pa->contents = (bfd_byte *) xmalloc (alloc);
+  while (!feof (f))
+    {
+      off_t got;
+
+      if (off == alloc)
+        {
+          alloc <<= 1;
+          pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc);
+        }
+
+      got = fread (pa->contents + off, 1, alloc - off, f);
+      if (ferror (f))
+        fatal (_("%s: fread failed"), pa->filename);
+
+      off += got;
+    }
+
+  pa->size = off;
+
+  fclose (f);
+}
+
 static int
 copy_main (int argc, char *argv[])
 {
@@ -3717,76 +3790,14 @@ copy_main (int argc, char *argv[])
 	  break;
 
 	case OPTION_ADD_SECTION:
-	  {
-	    const char *s;
-	    size_t off, alloc;
-	    struct section_add *pa;
-	    FILE *f;
-
-	    s = strchr (optarg, '=');
-
-	    if (s == NULL)
-	      fatal (_("bad format for %s"), "--add-section");
-
-	    pa = (struct section_add *) xmalloc (sizeof (struct section_add));
-	    pa->name = xstrndup (optarg, s - optarg);
-	    pa->filename = s + 1;
-
-	    /* We don't use get_file_size so that we can do
-	         --add-section .note.GNU_stack=/dev/null
-	       get_file_size doesn't work on /dev/null.  */
-
-	    f = fopen (pa->filename, FOPEN_RB);
-	    if (f == NULL)
-	      fatal (_("cannot open: %s: %s"),
-		     pa->filename, strerror (errno));
-
-	    off = 0;
-	    alloc = 4096;
-	    pa->contents = (bfd_byte *) xmalloc (alloc);
-	    while (!feof (f))
-	      {
-		off_t got;
-
-		if (off == alloc)
-		  {
-		    alloc <<= 1;
-		    pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc);
-		  }
-
-		got = fread (pa->contents + off, 1, alloc - off, f);
-		if (ferror (f))
-		  fatal (_("%s: fread failed"), pa->filename);
-
-		off += got;
-	      }
-
-	    pa->size = off;
-
-	    fclose (f);
-
-	    pa->next = add_sections;
-	    add_sections = pa;
-	  }
+          add_sections = init_section_add (optarg, add_sections,
+                                           "--add-section");
+          section_add_load_file (add_sections);
 	  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;
-	  }
+          dump_sections = init_section_add (optarg, dump_sections,
+                                            "--dump-section");
 	  break;
 	  
 	case OPTION_CHANGE_START:
-- 
2.2.2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-23 15:47 ` [PATCH 1/2] objcopy: Factor out some of the option parsing code Andrew Burgess
@ 2015-02-26  0:03   ` Richard Sandiford
  2015-02-26  6:48     ` Andrew Burgess
  2015-02-26 18:08   ` Steve Ellcey
  1 sibling, 1 reply; 11+ messages in thread
From: Richard Sandiford @ 2015-02-26  0:03 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: binutils

Andrew Burgess <andrew.burgess@embecosm.com> writes:
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index 8320793..eb26320 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -3546,6 +3546,79 @@ convert_efi_target (char *efi)
>      }
>  }
>  
> +/* Allocate and return a pointer to a struct section_add, initialising the

Nit: "initializing".  (binutils uses US spelling.)

OK with that change, thanks.  I think this should go in independently
of patch 2, since it's a clean-up in its own right.

Richard

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/2] objcopy: Add --update-section option.
  2015-02-23 15:36 ` [PATCH 2/2] objcopy: Add --update-section option Andrew Burgess
@ 2015-02-26  2:57   ` Richard Sandiford
  2015-02-27 12:25     ` Andrew Burgess
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Sandiford @ 2015-02-26  2:57 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: binutils

Andrew Burgess <andrew.burgess@embecosm.com> writes:
> New option for objcopy --update-section allows the contents of a section
> to be updated while maintaining the section flags, and, for ELF files,
> the section to segment mapping.
>
> New test uses --dump-section and --update-section to check that a
> section can be made larger and smaller with an update.

Thanks for doing this.  Looks like a very nice feature.

> +     --update-section <name>=<file>\n\
> +                                   Update contents of section <name> with\n\
> +                                   contents found in <file>.\n\

Nit: Other options don't have a "." at the end of the explanation.

This might seem like feature creep, sorry, but it'd be nice to have
a specific error message for the case where the user tries to both
update and remove a section, like we do for the case where the user
tries to remove and keep a section (via --only-section).  At the moment
we get the generic:

can't update section '.text': File in wrong format

I think this can be done by adding a specific error to
is_strip_section_1.  (Adding a new SECTION_CONTEXT_* doesn't seem
appropriate since the new option doesn't accept wildcards.)

It'd also be nice to have the option work with --rename-section, e.g.

  --update-section .foo=/file --rename-section .foo=.bar

At the moment this fails in the same way as above.  I think this is just
a case of applying the rename list before calling bfd_get_section_by_name.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-26  0:03   ` Richard Sandiford
@ 2015-02-26  6:48     ` Andrew Burgess
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Burgess @ 2015-02-26  6:48 UTC (permalink / raw)
  To: binutils, rdsandiford

* Richard Sandiford <rdsandiford@googlemail.com> [2015-02-25 21:07:41 +0000]:

> Andrew Burgess <andrew.burgess@embecosm.com> writes:
> > diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> > index 8320793..eb26320 100644
> > --- a/binutils/objcopy.c
> > +++ b/binutils/objcopy.c
> > @@ -3546,6 +3546,79 @@ convert_efi_target (char *efi)
> >      }
> >  }
> >
> > +/* Allocate and return a pointer to a struct section_add, initialising the
>
> Nit: "initializing".  (binutils uses US spelling.)
>
> OK with that change, thanks.  I think this should go in independently
> of patch 2, since it's a clean-up in its own right.

Thanks for the review, I pushed with the suggested fix.

Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-23 15:47 ` [PATCH 1/2] objcopy: Factor out some of the option parsing code Andrew Burgess
  2015-02-26  0:03   ` Richard Sandiford
@ 2015-02-26 18:08   ` Steve Ellcey
  2015-02-26 22:18     ` Andrew Burgess
  1 sibling, 1 reply; 11+ messages in thread
From: Steve Ellcey @ 2015-02-26 18:08 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: binutils

On Mon, 2015-02-23 at 12:52 +0000, Andrew Burgess wrote:
> This patch splits out some of the option parsing code, increasing code
> reuse.
> 
> binutils/ChangeLog:
> 
> 	* objcopy.c (init_section_add): New function.
> 	(section_add_load_file): New function.
> 	(copy_main): Make use of new functions.

> +static struct section_add *
> +init_section_add (const char *optarg,
> +                  struct section_add *next,
> +                  const char *option)

Andrew,

This change is breaking the binutils build for me.  The build dies with:

/scratch/sellcey/repos/objcopy/src/binutils/binutils/objcopy.c: In function 'init_section_add':
/scratch/sellcey/repos/objcopy/src/binutils/binutils/objcopy.c:3556:31: error: declaration of 'optarg' shadows a global declaration [-Werror=shadow]
cc1: all warnings being treated as errors

optarg is defined as a global variable in include/getopt.h in the binutils
sources.  Could you rename the optarg argument to something else?  I am not
sure if other people are seeing this or not, I am building binutils on ubuntu 12.04
with GCC 4.6.3.

Steve Ellcey
sellcey@imgtec.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-26 18:08   ` Steve Ellcey
@ 2015-02-26 22:18     ` Andrew Burgess
  2015-02-26 22:20       ` Steve Ellcey
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Burgess @ 2015-02-26 22:18 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: binutils

* Steve Ellcey <sellcey@imgtec.com> [2015-02-26 08:51:41 -0800]:

> On Mon, 2015-02-23 at 12:52 +0000, Andrew Burgess wrote:
> > This patch splits out some of the option parsing code, increasing code
> > reuse.
> > 
> > binutils/ChangeLog:
> > 
> > 	* objcopy.c (init_section_add): New function.
> > 	(section_add_load_file): New function.
> > 	(copy_main): Make use of new functions.
> 
> > +static struct section_add *
> > +init_section_add (const char *optarg,
> > +                  struct section_add *next,
> > +                  const char *option)
>
> This change is breaking the binutils build for me.  The build dies with:
> 
> /scratch/sellcey/repos/objcopy/src/binutils/binutils/objcopy.c: In function 'init_section_add':
> /scratch/sellcey/repos/objcopy/src/binutils/binutils/objcopy.c:3556:31: error: declaration of 'optarg' shadows a global declaration [-Werror=shadow]

That error looks correct.  Strangely though using:
  gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
I'm not seeing the error message, even though I do have optarg
available as a global .... very strange.

Does the patch below fix the issue for you?  I rename optarg to arg,
which I don't believe is a global, but given that I have no faith in
the shadow detection in my version of GCC, I'm nervous to just push
this without it being confirmed to fix the issue.

If you can confirm this then I'll push it.  Alternatively, I'll setup
an alternative GCC to compile with that hopefully will give me the
shadow warning you see.

Sorry for the breakage,
Andrew

---

In commit 7173b38a442c007a554ea200817a0eadce89c87b I used optarg as the
name for a function parameter, shadowing the global of that name.  This
commit changes the function parameter to be called arg.

binutils/ChangeLog:

	* objcopy.c (init_section_add): Rename optarg to arg in order to
	avoid shadowing a global variable.
---
 binutils/ChangeLog | 5 +++++
 binutils/objcopy.c | 8 ++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 3a42b72..6caa4fa 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2015-02-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* objcopy.c (init_section_add): Rename optarg to arg in order to
+	avoid shadowing a global variable.
+
 2015-02-26  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/17512
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 5cb4b13..7f094d3 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3547,25 +3547,25 @@ convert_efi_target (char *efi)
 }
 
 /* Allocate and return a pointer to a struct section_add, initializing the
-   structure using OPTARG, a string in the format "sectionname=filename".
+   structure using ARG, a string in the format "sectionname=filename".
    The returned structure will have its next pointer set to NEXT.  The
    OPTION field is the name of the command line option currently being
    parsed, and is only used if an error needs to be reported.  */
 
 static struct section_add *
-init_section_add (const char *optarg,
+init_section_add (const char *arg,
                   struct section_add *next,
                   const char *option)
 {
   struct section_add *pa;
   const char *s;
 
-  s = strchr (optarg, '=');
+  s = strchr (arg, '=');
   if (s == NULL)
     fatal (_("bad format for %s"), option);
 
   pa = (struct section_add *) xmalloc (sizeof (struct section_add));
-  pa->name = xstrndup (optarg, s - optarg);
+  pa->name = xstrndup (arg, s - arg);
   pa->filename = s + 1;
   pa->next = next;
   pa->contents = NULL;
-- 
2.2.2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-26 22:20       ` Steve Ellcey
@ 2015-02-26 22:20         ` Andrew Burgess
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Burgess @ 2015-02-26 22:20 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: binutils

* Steve Ellcey <sellcey@imgtec.com> [2015-02-26 09:46:35 -0800]:

> On Thu, 2015-02-26 at 17:40 +0000, Andrew Burgess wrote:
> 
> > Does the patch below fix the issue for you?  I rename optarg to arg,
> > which I don't believe is a global, but given that I have no faith in
> > the shadow detection in my version of GCC, I'm nervous to just push
> > this without it being confirmed to fix the issue.
> > 
> > If you can confirm this then I'll push it.  Alternatively, I'll setup
> > an alternative GCC to compile with that hopefully will give me the
> > shadow warning you see.
> > 
> > Sorry for the breakage,
> > Andrew
> 
> Yes, that patch fixed the build problem for me.

Then I've pushed it.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] objcopy: Factor out some of the option parsing code.
  2015-02-26 22:18     ` Andrew Burgess
@ 2015-02-26 22:20       ` Steve Ellcey
  2015-02-26 22:20         ` Andrew Burgess
  0 siblings, 1 reply; 11+ messages in thread
From: Steve Ellcey @ 2015-02-26 22:20 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: binutils

On Thu, 2015-02-26 at 17:40 +0000, Andrew Burgess wrote:

> Does the patch below fix the issue for you?  I rename optarg to arg,
> which I don't believe is a global, but given that I have no faith in
> the shadow detection in my version of GCC, I'm nervous to just push
> this without it being confirmed to fix the issue.
> 
> If you can confirm this then I'll push it.  Alternatively, I'll setup
> an alternative GCC to compile with that hopefully will give me the
> shadow warning you see.
> 
> Sorry for the breakage,
> Andrew

Yes, that patch fixed the build problem for me.

Steve Ellcey
sellcey@imgtec.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/2] objcopy: Add --update-section option.
  2015-02-26  2:57   ` Richard Sandiford
@ 2015-02-27 12:25     ` Andrew Burgess
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Burgess @ 2015-02-27 12:25 UTC (permalink / raw)
  To: binutils, rdsandiford

* Richard Sandiford <rdsandiford@googlemail.com> [2015-02-25 21:19:37 +0000]:

> Andrew Burgess <andrew.burgess@embecosm.com> writes:
> > New option for objcopy --update-section allows the contents of a section
> > to be updated while maintaining the section flags, and, for ELF files,
> > the section to segment mapping.
> >
> > +     --update-section <name>=<file>\n\
> > +                                   Update contents of section <name> with\n\
> > +                                   contents found in <file>.\n\
>
> Nit: Other options don't have a "." at the end of the explanation.

Fixed.

>
> This might seem like feature creep, sorry, but it'd be nice to have
> a specific error message for the case where the user tries to both
> update and remove a section, like we do for the case where the user
> tries to remove and keep a section (via --only-section).

This case is now handled, and an error reported.

>
> It'd also be nice to have the option work with --rename-section, e.g.
>
>   --update-section .foo=/file --rename-section .foo=.bar
>

This now works.

Test cases have been expanded to cover the new functionality.

Thanks for the review.
Andrew

---

New option for objcopy --update-section allows the contents of a section
to be updated while maintaining the section flags, and, for ELF files,
the section to segment mapping.

New test uses --dump-section and --update-section to check that a
section can be made larger and smaller with an update.

binutils/ChangeLog:

	* objcopy.c (update_sections): New list.
	(find_section_update): New function.
	(is_strip_section_1): Add check for attempt to update and remove
	the same section.
	(command_line_switch): Add OPTION_UPDATE_SECTION.
	(copy_options): Add update-section.
	(copy_usage): Document new option.
	(copy_object): Update size and content of requested sections.
	(is_update_section): New function.
	(skip_section): Don't copy for updated sections.
	(copy_main): Handle --update-section.
	* doc/binutils.texi (objcopy): Add description of --update-section
	option.

binutils/testsuite/ChangeLog:

	* binutils-all/update-1.s: New file.
	* binutils-all/update-2.s: New file.
	* binutils-all/update-3.s: New file.
	* binutils-all/update-4.s: New file.
	* binutils-all/update-section.exp: New file.
---
 binutils/ChangeLog                                 |  16 ++++
 binutils/doc/binutils.texi                         |  17 ++++
 binutils/objcopy.c                                 | 103 ++++++++++++++++++++
 binutils/testsuite/ChangeLog                       |   8 ++
 binutils/testsuite/binutils-all/update-1.s         |   2 +
 binutils/testsuite/binutils-all/update-2.s         |   2 +
 binutils/testsuite/binutils-all/update-3.s         |   3 +
 binutils/testsuite/binutils-all/update-4.s         |   2 +
 binutils/testsuite/binutils-all/update-section.exp | 104 +++++++++++++++++++++
 9 files changed, 257 insertions(+)
 create mode 100644 binutils/testsuite/binutils-all/update-1.s
 create mode 100644 binutils/testsuite/binutils-all/update-2.s
 create mode 100644 binutils/testsuite/binutils-all/update-3.s
 create mode 100644 binutils/testsuite/binutils-all/update-4.s
 create mode 100644 binutils/testsuite/binutils-all/update-section.exp

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6caa4fa..58ba287 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,21 @@
 2015-02-26  Andrew Burgess  <andrew.burgess@embecosm.com>
 
+	* objcopy.c (update_sections): New list.
+	(find_section_update): New function.
+	(is_strip_section_1): Add check for attempt to update and remove
+	the same section.
+	(command_line_switch): Add OPTION_UPDATE_SECTION.
+	(copy_options): Add update-section.
+	(copy_usage): Document new option.
+	(copy_object): Update size and content of requested sections.
+	(is_update_section): New function.
+	(skip_section): Don't copy for updated sections.
+	(copy_main): Handle --update-section.
+	* doc/binutils.texi (objcopy): Add description of --update-section
+	option.
+
+2015-02-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
 	* objcopy.c (init_section_add): Rename optarg to arg in order to
 	avoid shadowing a global variable.
 
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index a5bfd4c..a0ac326 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1091,6 +1091,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{--set-section-flags} @var{sectionpattern}=@var{flags}]
         [@option{--add-section} @var{sectionname}=@var{filename}]
         [@option{--dump-section} @var{sectionname}=@var{filename}]
+        [@option{--update-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}]
@@ -1489,6 +1490,22 @@ 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 --update-section @var{sectionname}=@var{filename}
+Replace the contents of section named @var{sectionname} with the
+contents of file @var{filename}, replacing any existing section
+contents.  The size of the section will be adjusted to the size of the
+file.  The section flags for @var{sectionname} will be unchanged.  For
+ELF format files the section to segment mapping will also remain
+unchanged, something which is not possible using
+@option{--remove-section} followed by @option{--add-section}.  The
+option can be specified more than once.
+
+Note - it is possible to use @option{--rename-section} and
+@option{--update-section} to both update and rename a section from one
+command line.  In this case, pass the original section name to
+@option{--update-section}, and the original, and new section names to
+@option{--rename-section}.
+
 @item --rename-section @var{oldname}=@var{newname}[,@var{flags}]
 Rename a section from @var{oldname} to @var{newname}, optionally
 changing the section's flags to @var{flags} in the process.  This has
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 7f094d3..4aac602 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 update in the output BFD.  */
+static struct section_add *update_sections;
+
 /* List of sections to dump from the output BFD.  */
 static struct section_add *dump_sections;
 
@@ -262,6 +265,7 @@ static enum long_section_name_handling long_section_names = KEEP;
 enum command_line_switch
   {
     OPTION_ADD_SECTION=150,
+    OPTION_UPDATE_SECTION,
     OPTION_DUMP_SECTION,
     OPTION_CHANGE_ADDRESSES,
     OPTION_CHANGE_LEADING_CHAR,
@@ -361,6 +365,7 @@ static struct option copy_options[] =
 {
   {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
   {"add-section", required_argument, 0, OPTION_ADD_SECTION},
+  {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
   {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
@@ -553,6 +558,9 @@ copy_usage (FILE *stream, int exit_status)
      --set-section-flags <name>=<flags>\n\
                                    Set section <name>'s properties to <flags>\n\
      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
+     --update-section <name>=<file>\n\
+                                   Update contents of section <name> with\n\
+                                   contents found in <file>\n\
      --dump-section <name>=<file>  Dump the contents of section <name> into <file>\n\
      --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
      --long-section-names {enable|disable|keep}\n\
@@ -808,6 +816,25 @@ find_section_list (const char *name, bfd_boolean add, unsigned int context)
   return p;
 }
 
+/* Find entry in UPDATE_SECTIONS list matching NAME.  Return pointer to
+   matching list entry if one is found, otherwise return NULL.  */
+
+static struct section_add *
+find_section_update (const char *name)
+{
+  struct section_add *pupdate;
+
+  for (pupdate = update_sections;
+       pupdate != NULL;
+       pupdate = pupdate->next)
+    {
+      if (strcmp (pupdate->name, name) == 0)
+        return pupdate;
+    }
+
+  return NULL;
+}
+
 /* There is htab_hash_string but no htab_eq_string. Makes sense.  */
 
 static int
@@ -1053,15 +1080,20 @@ is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
     {
       struct section_list *p;
       struct section_list *q;
+      struct section_add *r;
 
       p = find_section_list (bfd_get_section_name (abfd, sec), FALSE,
 			     SECTION_CONTEXT_REMOVE);
       q = find_section_list (bfd_get_section_name (abfd, sec), FALSE,
 			     SECTION_CONTEXT_COPY);
+      r = find_section_update (bfd_get_section_name (abfd, sec));
 
       if (p && q)
 	fatal (_("error: section %s matches both remove and copy options"),
 	       bfd_get_section_name (abfd, sec));
+      if (p && r)
+        fatal (_("error: section %s matches both update and remove options"),
+               bfd_get_section_name (abfd, sec));
 
       if (p != NULL)
 	return TRUE;
@@ -1865,6 +1897,29 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	}
     }
 
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+	   pupdate != NULL;
+	   pupdate = pupdate->next)
+	{
+	  asection *osec;
+
+	  pupdate->section = bfd_get_section_by_name (ibfd, pupdate->name);
+	  if (pupdate->section == NULL)
+	    fatal (_("error: %s not found, can't be updated"), pupdate->name);
+
+	  osec = pupdate->section->output_section;
+	  if (! bfd_set_section_size (obfd, osec, pupdate->size))
+	    {
+	      bfd_nonfatal_message (NULL, obfd, osec, NULL);
+	      return FALSE;
+	    }
+	}
+    }
+
   if (dump_sections != NULL)
     {
       struct section_add * pdump;
@@ -2150,6 +2205,26 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	}
     }
 
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+           pupdate != NULL;
+           pupdate = pupdate->next)
+	{
+	  asection *osec;
+
+	  osec = pupdate->section->output_section;
+	  if (! bfd_set_section_contents (obfd, osec, pupdate->contents,
+	                                  0, pupdate->size))
+	    {
+	      bfd_nonfatal_message (NULL, obfd, osec, NULL);
+	      return FALSE;
+	    }
+	}
+    }
+
   if (gnu_debuglink_filename != NULL)
     {
       if (! bfd_fill_in_gnu_debuglink_section
@@ -2861,6 +2936,25 @@ loser:
   bfd_nonfatal_message (NULL, obfd, osection, err);
 }
 
+static bfd_boolean
+is_update_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+  if (update_sections != NULL)
+    {
+      struct section_add *pupdate;
+
+      for (pupdate = update_sections;
+           pupdate != NULL;
+           pupdate = pupdate->next)
+	{
+          if (strcmp (sec->name, pupdate->name) == 0)
+            return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 /* Return TRUE if input section ISECTION should be skipped.  */
 
 static bfd_boolean
@@ -2881,6 +2975,9 @@ skip_section (bfd *ibfd, sec_ptr isection)
   if (is_strip_section (ibfd, isection))
     return TRUE;
 
+  if (is_update_section (ibfd, isection))
+    return TRUE;
+
   flags = bfd_get_section_flags (ibfd, isection);
   if ((flags & SEC_GROUP) != 0)
     return TRUE;
@@ -3795,6 +3892,12 @@ copy_main (int argc, char *argv[])
           section_add_load_file (add_sections);
 	  break;
 
+	case OPTION_UPDATE_SECTION:
+	  update_sections = init_section_add (optarg, update_sections,
+                                              "--update-section");
+	  section_add_load_file (update_sections);
+	  break;
+
 	case OPTION_DUMP_SECTION:
           dump_sections = init_section_add (optarg, dump_sections,
                                             "--dump-section");
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 8e78434..ef8efa3 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-02-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* binutils-all/update-1.s: New file.
+	* binutils-all/update-2.s: New file.
+	* binutils-all/update-3.s: New file.
+	* binutils-all/update-4.s: New file.
+	* binutils-all/update-section.exp: New file.
+
 2015-02-24  Nick Clifton  <nickc@redhat.com>
 
 	* binutils-all/objcopy.exp: Skip the strip-10 test for the V850.
diff --git a/binutils/testsuite/binutils-all/update-1.s b/binutils/testsuite/binutils-all/update-1.s
new file mode 100644
index 0000000..8ef51a0
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-1.s
@@ -0,0 +1,2 @@
+        .section ".foo", "aw"
+        .word 1, 1, 1, 1
diff --git a/binutils/testsuite/binutils-all/update-2.s b/binutils/testsuite/binutils-all/update-2.s
new file mode 100644
index 0000000..b720812
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-2.s
@@ -0,0 +1,2 @@
+        .section ".foo", "aw"
+        .word 2, 2, 2, 2, 2, 2
diff --git a/binutils/testsuite/binutils-all/update-3.s b/binutils/testsuite/binutils-all/update-3.s
new file mode 100644
index 0000000..087986f
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-3.s
@@ -0,0 +1,3 @@
+        .section ".foo", "aw"
+        .word 3, 3
+
diff --git a/binutils/testsuite/binutils-all/update-4.s b/binutils/testsuite/binutils-all/update-4.s
new file mode 100644
index 0000000..ae8a844
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-4.s
@@ -0,0 +1,2 @@
+        .section ".bar", "aw"
+        .word 5
diff --git a/binutils/testsuite/binutils-all/update-section.exp b/binutils/testsuite/binutils-all/update-section.exp
new file mode 100644
index 0000000..9094484
--- /dev/null
+++ b/binutils/testsuite/binutils-all/update-section.exp
@@ -0,0 +1,104 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+if { [is_remote host] } then {
+    return
+}
+
+send_user "Version [binutil_version $OBJCOPY]"
+
+proc do_assemble {srcfile} {
+    global srcdir
+    global subdir
+    set objfile [regsub -- "\.s$" $srcfile ".o"]
+    if {![binutils_assemble $srcdir/$subdir/${srcfile} tmpdir/${objfile}]} then {
+        return 0;
+    }
+    return 1;
+}
+
+proc do_objcopy {objfile extraflags {pattern ""}} {
+    global OBJCOPY
+    global OBJCOPYFLAGS
+
+    set testname "objcopy $extraflags ${objfile}"
+    set got [binutils_run $OBJCOPY \
+                 "$OBJCOPYFLAGS ${extraflags} tmpdir/${objfile}"]
+    if ![regexp $pattern $got] then {
+        fail "objcopy ($testname)"
+        return 0
+    }
+    if { $pattern != "" } then {
+        pass "objcopy ($testname)"
+    }
+    return 1
+}
+
+proc do_compare {file1 file2} {
+    set src1 "tmpdir/${file1}"
+    set src2 "tmpdir/${file2}"
+    set status [remote_exec build cmp "${src1} ${src2}"]
+    set exec_output [lindex $status 1]
+    set exec_output [prune_warnings $exec_output]
+
+    set testname "compare ${file1} ${file2}"
+    if [string match "" $exec_output] then {
+        pass "objcopy ($testname)"
+    } else {
+        send_log "$exec_output\n"
+        verbose "$exec_output" 1
+        fail "objcopy ($testname)"
+        return 0
+    }
+    return 1
+}
+
+#
+# Start Of Tests
+#
+
+foreach f [list update-1.s update-2.s update-3.s update-4.s] {
+    if { ![do_assemble $f] } then {
+        unsupported "update-section.exp"
+        return
+    }
+}
+
+if { ![do_objcopy update-1.o \
+           "--dump-section .foo=tmpdir/dumped-contents"]
+     || ![do_objcopy update-2.o \
+              "--update-section .foo=tmpdir/dumped-contents"]
+     || ![do_objcopy update-3.o \
+              "--update-section .foo=tmpdir/dumped-contents"]
+     || ![do_objcopy update-4.o \
+              "--update-section .bar=tmpdir/dumped-contents \
+               --rename-section .bar=.foo"] } then {
+    # If any of the above tests failed then a FAIL will already have
+    # been reported.
+    return
+}
+
+# Check that the updated object files are as expected.
+do_compare update-1.o update-2.o
+do_compare update-1.o update-3.o
+do_compare update-1.o update-4.o
+
+# Check that --update-section on an unknown section will fail.
+if { ![do_objcopy update-2.o \
+           "--update-section .bar=tmpdir/dumped-contents" \
+           "error: .bar not found, can't be updated"] } then {
+    return
+}
-- 
2.2.2

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-02-27  0:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-23 13:26 [PATCH 0/2] Add --update-section option to objcopy Andrew Burgess
2015-02-23 15:36 ` [PATCH 2/2] objcopy: Add --update-section option Andrew Burgess
2015-02-26  2:57   ` Richard Sandiford
2015-02-27 12:25     ` Andrew Burgess
2015-02-23 15:47 ` [PATCH 1/2] objcopy: Factor out some of the option parsing code Andrew Burgess
2015-02-26  0:03   ` Richard Sandiford
2015-02-26  6:48     ` Andrew Burgess
2015-02-26 18:08   ` Steve Ellcey
2015-02-26 22:18     ` Andrew Burgess
2015-02-26 22:20       ` Steve Ellcey
2015-02-26 22:20         ` Andrew Burgess

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).