Add --input-type and --output-type to elfedit
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 8 Jan 2010 18:50:39 +0000 (18:50 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 8 Jan 2010 18:50:39 +0000 (18:50 +0000)
binutils/

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

* elfedit.c (input_elf_type): New.
(output_elf_type): Likewise.
(elf_type): Likewise.
(update_elf_header): Support updating ELF file type.
(command_line_switch): Add OPTION_INPUT_TYPE and
OPTION_OUTPUT_TYPE.
(options): Likewise.
(usage): Add --input-type and --output-type.
(main): Handle OPTION_INPUT_TYPE and OPTION_OUTPUT_TYPE.  Check
one of --output-mach and --output-type must be specified.

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

binutils/testsuite/

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

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

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

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

index bbe4ec2b1fbb9165705736c673160fc5664ca53e..b5417446fef5dbdb16dc6dcdfdecaa8492b701fe 100644 (file)
@@ -1,3 +1,19 @@
+2010-01-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elfedit.c (input_elf_type): New.
+       (output_elf_type): Likewise.
+       (elf_type): Likewise.
+       (update_elf_header): Support updating ELF file type.
+       (command_line_switch): Add OPTION_INPUT_TYPE and
+       OPTION_OUTPUT_TYPE.
+       (options): Likewise.
+       (usage): Add --input-type and --output-type.
+       (main): Handle OPTION_INPUT_TYPE and OPTION_OUTPUT_TYPE.  Check
+       one of --output-mach and --output-type must be specified.
+
+       * doc/binutils.texi: Document --input-type and --output-type
+       for elfedit.
+
 2010-01-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        * doc/binutils.texi: Fix a typo.
index 4d9a23f7e0558ebeacfd0f3172bed02b747c7136..aedb80f9263b60884fdd4c9a2dc959ec7a2f2494 100644 (file)
@@ -4107,7 +4107,9 @@ objdump(1), and the Info entries for @file{binutils}.
 @smallexample
 @c man begin SYNOPSIS elfedit
 elfedit [@option{--input-mach=}@var{machine}]
+        [@option{--input-type=}@var{type}]
         @option{--output-mach=}@var{machine}
+        @option{--output-type=}@var{type}
         [@option{-v}|@option{--version}]
         [@option{-h}|@option{--help}]
         @var{elffile}@dots{}
@@ -4116,9 +4118,9 @@ elfedit [@option{--input-mach=}@var{machine}]
 
 @c man begin DESCRIPTION elfedit
 
-@command{elfedit} updates the ELF header of ELF files.  The
-options control how and which fields in the ELF header should be
-updated.
+@command{elfedit} updates the ELF header of ELF files which have
+the matching ELF machine and file types.  The options control how and
+which fields in the ELF header should be updated.
 
 @var{elffile}@dots{} are the ELF files to be updated.  32-bit and
 64-bit ELF files are supported, as are archives containing ELF files.
@@ -4127,14 +4129,15 @@ updated.
 @c man begin OPTIONS elfedit
 
 The long and short forms of options, shown here as alternatives, are
-equivalent. The @option{--output-mach} option must be given.
+equivalent. At least one of the @option{--output-mach} and
+@option{--output-type} options must be given.
 
 @table @env
 
 @itemx --input-mach=@var{machine}
-Only the input files with ELF machine type, @var{machine}, will be
-updated. If @option{--input-mach} isn't specified, any ELF file
-will be updated.
+Set the matching input ELF machine type to @var{machine}.  If
+@option{--input-mach} isn't specified, it will match any ELF
+machine types.
 
 The supported ELF machine types are, @var{L1OM} and @var{x86-64}.
 
@@ -4142,6 +4145,16 @@ The supported ELF machine types are, @var{L1OM} and @var{x86-64}.
 Change the ELF machine type in the ELF header to @var{machine}.  The
 supported ELF machine types are the same as @option{--input-mach}.
 
+@itemx --input-type=@var{type}
+Set the matching input ELF file type to @var{type}.  If
+@option{--input-type} isn't specified, it will match any ELF file types.
+
+The supported ELF file types are, @var{rel}, @var{exec} and @var{dyn}.
+
+@itemx --output-type=@var{type}
+Change the ELF file type in the ELF header to @var{type}.  The
+supported ELF types are the same as @option{--input-type}.
+
 @item -v
 @itemx --version
 Display the version number of @command{elfedit}.
index 410d89af273485242a3b63adad1771a159041ee7..b71990ce2616dd00fd01f64831f7d700de634fc4 100644 (file)
@@ -55,6 +55,8 @@ static Elf32_External_Ehdr ehdr32;
 static Elf64_External_Ehdr ehdr64;
 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_class = -1;
 
 #define streq(a,b)       (strcmp ((a), (b)) == 0)
@@ -228,7 +230,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, status;
+  int class, machine, type, status;
 
   if (elf_header.e_ident[EI_MAG0] != ELFMAG0
       || elf_header.e_ident[EI_MAG1] != ELFMAG1
@@ -276,7 +278,18 @@ update_elf_header (const char *file_name, FILE *file)
       return 0;
     }
 
-  /* Update e_machine.  */
+  type = elf_header.e_type;
+
+  /* Skip if e_type doesn't match. */
+  if (input_elf_type != -1 && type != input_elf_type)
+    {
+      non_fatal
+       (_("%s: Unmatched e_type: %d is not %d\n"),
+        file_name, type, input_elf_type);
+      return 0;
+    }
+
+  /* Update e_machine and e_type.  */
   switch (class)
     {
     default:
@@ -284,11 +297,17 @@ update_elf_header (const char *file_name, FILE *file)
       abort ();
       break;
     case ELFCLASS32:
-      BYTE_PUT (ehdr32.e_machine, output_elf_machine);
+      if (output_elf_machine != -1)
+       BYTE_PUT (ehdr32.e_machine, output_elf_machine);
+      if (output_elf_type != -1)
+       BYTE_PUT (ehdr32.e_type, output_elf_type);
       status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
       break;
     case ELFCLASS64:
-      BYTE_PUT (ehdr64.e_machine, output_elf_machine);
+      if (output_elf_machine != -1)
+       BYTE_PUT (ehdr64.e_machine, output_elf_machine);
+      if (output_elf_type != -1)
+       BYTE_PUT (ehdr64.e_type, output_elf_type);
       status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
       break;
     }
@@ -1015,16 +1034,39 @@ elf_class (int mach)
     }
 }
 
+/* Return ET_XXX for a type string, TYPE.  */
+
+static int
+elf_type (const char *type)
+{
+  if (strcasecmp (type, "rel") == 0)
+    return ET_REL;
+  if (strcasecmp (type, "exec") == 0)
+    return ET_EXEC;
+  if (strcasecmp (type, "dyn") == 0)
+    return ET_DYN;
+  if (strcasecmp (type, "none") == 0)
+    return ET_NONE;
+
+  non_fatal (_("Unknown type: %s\n"), type);
+
+  return -1;
+}
+
 enum command_line_switch
   {
     OPTION_INPUT_MACH = 150,
-    OPTION_OUTPUT_MACH
+    OPTION_OUTPUT_MACH,
+    OPTION_INPUT_TYPE,
+    OPTION_OUTPUT_TYPE
   };
 
 static struct option options[] =
 {
   {"input-mach",       required_argument, 0, OPTION_INPUT_MACH},
   {"output-mach",      required_argument, 0, OPTION_OUTPUT_MACH},
+  {"input-type",       required_argument, 0, OPTION_INPUT_TYPE},
+  {"output-type",      required_argument, 0, OPTION_OUTPUT_TYPE},
   {"version",          no_argument, 0, 'v'},
   {"help",             no_argument, 0, 'h'},
   {0,                  no_argument, 0, 0}
@@ -1033,13 +1075,15 @@ static struct option options[] =
 static void
 usage (FILE *stream, int exit_status)
 {
-  fprintf (stream, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
+  fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
           program_name);
   fprintf (stream, _(" Update the ELF header of ELF files\n"));
   fprintf (stream, _(" The options are:\n"));
   fprintf (stream, _("\
   --input-mach <machine>      Set input machine type to <machine>\n\
   --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\
   -h --help                   Display this information\n\
   -v --version                Display the version number of %s\n\
 "),
@@ -1085,6 +1129,18 @@ main (int argc, char ** argv)
            return 1;
          break;
 
+       case OPTION_INPUT_TYPE:
+         input_elf_type = elf_type (optarg);
+         if (input_elf_type < 0)
+           return 1;
+         break;
+
+       case OPTION_OUTPUT_TYPE:
+         output_elf_type = elf_type (optarg);
+         if (output_elf_type < 0)
+           return 1;
+         break;
+
        case 'h':
          usage (stdout, 0);
 
@@ -1097,7 +1153,9 @@ main (int argc, char ** argv)
        }
     }
 
-  if (optind == argc || output_elf_machine == -1)
+  if (optind == argc
+      || (output_elf_machine == -1
+         && output_elf_type == -1))
     usage (stderr, 1);
 
   status = 0;
index bd066e1f10b42dbf3e9cae6331afb351a788cee9..4ebc7e931cdf4b21a270b58f7cb83bd32a565020 100644 (file)
@@ -1,3 +1,9 @@
+2010-01-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * binutils-all/elfedit-2.d: New.
+
+       * binutils-all/elfedit.exp: Run elfedit-2.
+
 2010-01-06  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/11131
diff --git a/binutils/testsuite/binutils-all/elfedit-2.d b/binutils/testsuite/binutils-all/elfedit-2.d
new file mode 100644 (file)
index 0000000..af07c1d
--- /dev/null
@@ -0,0 +1,15 @@
+#PROG: elfedit
+#elfedit: --output-type exec
+#source: empty.s
+#readelf: -h
+#name: Update ELF header 2
+#target: *-*-linux*
+
+#...
+ELF Header:
+  Magic:   7f 45 4c 46 .*
+#...
+  Version:[ \t]+1 \(current\)
+#...
+  Type:[ \t]+EXEC \(Executable file\)
+#...
index d43c31a476fdae494320cbc7332b51fc92b5a783..23d52924474cffb994745bb4d5996196aecf32a9 100644 (file)
@@ -29,3 +29,4 @@ if ![is_remote host] {
 }
 
 run_dump_test "elfedit-1"
+run_dump_test "elfedit-2"
This page took 0.036936 seconds and 4 git commands to generate.