Add --input-osabi and --output-osabi to elfedit.
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 23 Aug 2010 16:25:53 +0000 (16:25 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 23 Aug 2010 16:25:53 +0000 (16:25 +0000)
binutils/

2010-08-23  H.J. Lu  <hongjiu.lu@intel.com>

* elfedit.c (input_elf_osabi): New.
(output_elf_osbi): Likewise.
(osabis): Likewise.
(elf_osabi): Likewise.
(update_elf_header): Support updating ELF OSABI.
(make_qualified_name): Break long line.
(command_line_switch): Add OPTION_INPUT_OSABI and
OPTION_OUTPUT_OSABI.
(options): Likewise.
(usage): Add --input-osabi and --output-osabi.
(main): Handle OPTION_INPUT_OSABI and OPTION_OUTPUT_OSABI.

* doc/binutils.texi: Document --input-osabi and --output-osabi
for elfedit.

binutils/testsuite/

2010-08-23  H.J. Lu  <hongjiu.lu@intel.com>

* binutils-all/elfedit-3.d: New.

* binutils-all/elfedit.exp: Run elfedit-3.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/elfedit.c
binutils/testsuite/ChangeLog
binutils/testsuite/binutils-all/elfedit-3.d [new file with mode: 0644]
binutils/testsuite/binutils-all/elfedit.exp

index cac073fa2ec6561e3fa14dd8a124f6c21fdb4500..e7986f780f0119823bcd2a1072d9dad3d4f3bdb8 100644 (file)
@@ -1,3 +1,20 @@
+2010-08-23  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elfedit.c (input_elf_osabi): New.
+       (output_elf_osbi): Likewise.
+       (osabis): Likewise.
+       (elf_osabi): Likewise.
+       (update_elf_header): Support updating ELF OSABI.
+       (make_qualified_name): Break long line.
+       (command_line_switch): Add OPTION_INPUT_OSABI and
+       OPTION_OUTPUT_OSABI.
+       (options): Likewise.
+       (usage): Add --input-osabi and --output-osabi.
+       (main): Handle OPTION_INPUT_OSABI and OPTION_OUTPUT_OSABI.
+
+       * doc/binutils.texi: Document --input-osabi and --output-osabi
+       for elfedit.
+
 2010-08-23  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * readelf.c (display_mips_gnu_attribute): Replace GCC options
index 9f374f8dc217f94367a5fa693747e4dc7030756d..0f0d8ee4b80a25273c851665e83dba46f899f355 100644 (file)
@@ -4121,8 +4121,10 @@ objdump(1), and the Info entries for @file{binutils}.
 @c man begin SYNOPSIS elfedit
 elfedit [@option{--input-mach=}@var{machine}]
         [@option{--input-type=}@var{type}]
+        [@option{--input-osabi=}@var{osbi}]
         @option{--output-mach=}@var{machine}
         @option{--output-type=}@var{type}
+        @option{--output-osabi=}@var{osbi}
         [@option{-v}|@option{--version}]
         [@option{-h}|@option{--help}]
         @var{elffile}@dots{}
@@ -4142,8 +4144,8 @@ which fields in the ELF header should be updated.
 @c man begin OPTIONS elfedit
 
 The long and short forms of options, shown here as alternatives, are
-equivalent. At least one of the @option{--output-mach} and
-@option{--output-type} options must be given.
+equivalent. At least one of the @option{--output-mach},
+@option{--output-type} and @option{--output-osabi} options must be given.
 
 @table @env
 
@@ -4168,6 +4170,19 @@ The supported ELF file types are, @var{rel}, @var{exec} and @var{dyn}.
 Change the ELF file type in the ELF header to @var{type}.  The
 supported ELF types are the same as @option{--input-type}.
 
+@itemx --input-osabi=@var{osabi}
+Set the matching input ELF file OSABI to @var{osbi}.  If
+@option{--input-osabi} isn't specified, it will match any ELF OSABIs.
+
+The supported ELF OSABIs are, @var{none}, @var{HPUX}, @var{NetBSD},
+@var{Linux}, @var{Hurd}, @var{Solaris}, @var{AIX}, @var{Irix},
+@var{FreeBSD}, @var{TRU64}, @var{Modesto}, @var{OpenBSD}, @var{OpenVMS},
+@var{NSK}, @var{AROS} and @var{FenixOS}.
+
+@itemx --output-osabi=@var{osabi}
+Change the ELF OSABI in the ELF header to @var{type}.  The
+supported ELF OSABI are the same as @option{--input-osabi}.
+
 @item -v
 @itemx --version
 Display the version number of @command{elfedit}.
index ce77af4589ebc30f358624f38977aec56c27369b..c9a4b5ab689827b4f379563e69f302def0f0b49b 100644 (file)
@@ -57,6 +57,8 @@ static int input_elf_machine = -1;
 static int output_elf_machine = -1;
 static int input_elf_type = -1;
 static int output_elf_type = -1;
+static int input_elf_osabi = -1;
+static int output_elf_osabi = -1;
 static int input_elf_class = -1;
 
 #define streq(a,b)       (strcmp ((a), (b)) == 0)
@@ -230,7 +232,7 @@ byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
 static int
 update_elf_header (const char *file_name, FILE *file)
 {
-  int class, machine, type, status;
+  int class, machine, type, status, osabi;
 
   if (elf_header.e_ident[EI_MAG0] != ELFMAG0
       || elf_header.e_ident[EI_MAG1] != ELFMAG1
@@ -289,7 +291,18 @@ update_elf_header (const char *file_name, FILE *file)
       return 0;
     }
 
-  /* Update e_machine and e_type.  */
+  osabi = elf_header.e_ident[EI_OSABI];
+
+  /* Skip if OSABI doesn't match. */
+  if (input_elf_osabi != -1 && osabi != input_elf_osabi)
+    {
+      non_fatal
+       (_("%s: Unmatched EI_OSABI: %d is not %d\n"),
+        file_name, osabi, input_elf_osabi);
+      return 0;
+    }
+
+  /* Update e_machine, e_type and EI_OSABI.  */
   switch (class)
     {
     default:
@@ -301,6 +314,8 @@ update_elf_header (const char *file_name, FILE *file)
        BYTE_PUT (ehdr32.e_machine, output_elf_machine);
       if (output_elf_type != -1)
        BYTE_PUT (ehdr32.e_type, output_elf_type);
+      if (output_elf_osabi != -1)
+       ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
       status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
       break;
     case ELFCLASS64:
@@ -308,6 +323,8 @@ update_elf_header (const char *file_name, FILE *file)
        BYTE_PUT (ehdr64.e_machine, output_elf_machine);
       if (output_elf_type != -1)
        BYTE_PUT (ehdr64.e_type, output_elf_type);
+      if (output_elf_osabi != -1)
+       ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
       status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
       break;
     }
@@ -761,7 +778,8 @@ make_qualified_name (struct archive_info * arch,
     }
 
   if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
+    snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+             nested_arch->file_name, member_name);
   else if (arch->is_thin_archive)
     snprintf (name, len, "%s[%s]", arch->file_name, member_name);
   else
@@ -995,6 +1013,47 @@ process_file (const char *file_name)
   return ret;
 }
 
+static const struct
+{
+  int osabi;
+  const char *name;
+}
+osabis[] =
+{
+  { ELFOSABI_NONE, "none" },
+  { ELFOSABI_HPUX, "HPUX" },
+  { ELFOSABI_NETBSD, "NetBSD" },
+  { ELFOSABI_LINUX, "Linux" },
+  { ELFOSABI_HURD, "Hurd" },
+  { ELFOSABI_SOLARIS, "Solaris" },
+  { ELFOSABI_AIX, "AIX" },
+  { ELFOSABI_IRIX, "Irix" },
+  { ELFOSABI_FREEBSD, "FreeBSD" },
+  { ELFOSABI_TRU64, "TRU64" },
+  { ELFOSABI_MODESTO, "Modesto" },
+  { ELFOSABI_OPENBSD, "OpenBSD" },
+  { ELFOSABI_OPENVMS, "OpenVMS" },
+  { ELFOSABI_NSK, "NSK" },
+  { ELFOSABI_AROS, "AROS" },
+  { ELFOSABI_FENIXOS, "FenixOS" }
+};
+
+/* Return ELFOSABI_XXX for an OSABI string, OSABI.  */
+
+static int
+elf_osabi (const char *osabi)
+{
+  unsigned int i;
+
+  for (i = 0; i < ARRAY_SIZE (osabis); i++)
+    if (strcasecmp (osabi, osabis[i].name) == 0)
+      return osabis[i].osabi;
+
+  non_fatal (_("Unknown OSABI: %s\n"), osabi);
+
+  return -1;
+}
+
 /* Return EM_XXX for a machine string, MACH.  */
 
 static int
@@ -1056,7 +1115,9 @@ enum command_line_switch
     OPTION_INPUT_MACH = 150,
     OPTION_OUTPUT_MACH,
     OPTION_INPUT_TYPE,
-    OPTION_OUTPUT_TYPE
+    OPTION_OUTPUT_TYPE,
+    OPTION_INPUT_OSABI,
+    OPTION_OUTPUT_OSABI
   };
 
 static struct option options[] =
@@ -1065,6 +1126,8 @@ static struct option options[] =
   {"output-mach",      required_argument, 0, OPTION_OUTPUT_MACH},
   {"input-type",       required_argument, 0, OPTION_INPUT_TYPE},
   {"output-type",      required_argument, 0, OPTION_OUTPUT_TYPE},
+  {"input-osabi",      required_argument, 0, OPTION_INPUT_OSABI},
+  {"output-osabi",     required_argument, 0, OPTION_OUTPUT_OSABI},
   {"version",          no_argument, 0, 'v'},
   {"help",             no_argument, 0, 'h'},
   {0,                  no_argument, 0, 0}
@@ -1073,7 +1136,7 @@ static struct option options[] =
 static void
 usage (FILE *stream, int exit_status)
 {
-  fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
+  fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
           program_name);
   fprintf (stream, _(" Update the ELF header of ELF files\n"));
   fprintf (stream, _(" The options are:\n"));
@@ -1082,6 +1145,8 @@ usage (FILE *stream, int exit_status)
   --output-mach <machine>     Set output machine type to <machine>\n\
   --input-type <type>         Set input file type to <type>\n\
   --output-type <type>        Set output file type to <type>\n\
+  --input-osabi <osabi>       Set input OSABI to <osabi>\n\
+  --output-osabi <osabi>      Set output OSABI to <osabi>\n\
   -h --help                   Display this information\n\
   -v --version                Display the version number of %s\n\
 "),
@@ -1139,6 +1204,18 @@ main (int argc, char ** argv)
            return 1;
          break;
 
+       case OPTION_INPUT_OSABI:
+         input_elf_osabi = elf_osabi (optarg);
+         if (input_elf_osabi < 0)
+           return 1;
+         break;
+
+       case OPTION_OUTPUT_OSABI:
+         output_elf_osabi = elf_osabi (optarg);
+         if (output_elf_osabi < 0)
+           return 1;
+         break;
+
        case 'h':
          usage (stdout, 0);
 
@@ -1153,7 +1230,8 @@ main (int argc, char ** argv)
 
   if (optind == argc
       || (output_elf_machine == -1
-         && output_elf_type == -1))
+         && output_elf_type == -1
+         && output_elf_osabi == -1))
     usage (stderr, 1);
 
   status = 0;
index 6066eee6db6c20ae498eb3889a83bb37dd20a31e..9299f9e9e7e332c3dfe87bb2cdf73892900de7e7 100644 (file)
@@ -1,3 +1,9 @@
+2010-08-23  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * binutils-all/elfedit-3.d: New.
+
+       * binutils-all/elfedit.exp: Run elfedit-3.
+
 2010-07-19  Andreas Schwab  <schwab@redhat.com>
 
        * binutils-all/readelf.s: Ignore "Key to Flags" contents.
diff --git a/binutils/testsuite/binutils-all/elfedit-3.d b/binutils/testsuite/binutils-all/elfedit-3.d
new file mode 100644 (file)
index 0000000..c877f46
--- /dev/null
@@ -0,0 +1,15 @@
+#PROG: elfedit
+#elfedit: --output-osabi FenixOS
+#source: empty.s
+#readelf: -h
+#name: Update ELF header 3
+#target: *-*-linux*
+
+#...
+ELF Header:
+  Magic:   7f 45 4c 46 .*
+#...
+  Version:[ \t]+1 \(current\)
+#...
+  OS/ABI:[ \t]+FenixOS
+#...
index 23d52924474cffb994745bb4d5996196aecf32a9..21427740021fb55d7aff339b4a1ce941a704712d 100644 (file)
@@ -30,3 +30,4 @@ if ![is_remote host] {
 
 run_dump_test "elfedit-1"
 run_dump_test "elfedit-2"
+run_dump_test "elfedit-3"