Add EM_386/EM_IAMCU support to elfedit.c
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 11 May 2015 16:57:20 +0000 (09:57 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 11 May 2015 16:57:21 +0000 (09:57 -0700)
binutils/

* elfedit.c (enum elfclass): New.
(input_elf_class): Change type to enum elfclass.
(output_elf_class): New.
(elf_class): Change return type to enum elfclass.  Support EM_386
and EM_IAMCU.
(update_elf_header): Check if input and output ELF classes match.
(elf_machine): Support EM_386 and EM_IAMCU.
(main): Update input_elf_class.  Set output_elf_class.
* doc/binutils.texi: Update elfedit.

binutils/testsuite/

* binutils-all/elfedit-5.d: New file.
* binutils-all/elfedit.exp: Run elfedit-5.

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

index 37378a5558344c5f20891e2c867595631f811c2b..70b9aaea50ca370d6672d88c2262b402ef103147 100644 (file)
@@ -1,3 +1,15 @@
+2015-05-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elfedit.c (enum elfclass): New.
+       (input_elf_class): Change type to enum elfclass.
+       (output_elf_class): New.
+       (elf_class): Change return type to enum elfclass.  Support EM_386
+       and EM_IAMCU.
+       (update_elf_header): Check if input and output ELF classes match.
+       (elf_machine): Support EM_386 and EM_IAMCU.
+       (main): Update input_elf_class.  Set output_elf_class.
+       * doc/binutils.texi: Update elfedit.
+
 2015-05-11  H.J. Lu  <hongjiu.lu@intel.com>
 
        * dwarf.c (init_dwarf_regnames): Replace EM_486 with EM_IAMCU.
index dbf44c93b48c140927e2499b5fb120f11e33e59c..601de480bbcdaf84dd0cea8349aa0600ee2db490 100644 (file)
@@ -4614,8 +4614,8 @@ 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}, @var{K1OM} and
-@var{x86-64}.
+The supported ELF machine types are, @var{i386}, @var{IAMCU}, @var{L1OM},
+@var{K1OM} and @var{x86-64}.
 
 @item --output-mach=@var{machine}
 Change the ELF machine type in the ELF header to @var{machine}.  The
index 5b2bf86d79875d47ecc0267b9f4a3a1692b356bb..1bcb48aba89bb87b9394fe27cd5ea7d971f36af3 100644 (file)
@@ -54,7 +54,38 @@ 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;
+enum elfclass
+  {
+    ELF_CLASS_UNKNOWN = -1,
+    ELF_CLASS_NONE = ELFCLASSNONE,
+    ELF_CLASS_32 = ELFCLASS32,
+    ELF_CLASS_64 = ELFCLASS64,
+    ELF_CLASS_BOTH
+  };
+static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN;
+static enum elfclass output_elf_class = ELF_CLASS_BOTH;
+
+/* Return ELF class for a machine type, MACH.  */
+
+static enum elfclass
+elf_class (int mach)
+{
+  switch (mach)
+    {
+    case EM_386:
+    case EM_IAMCU:
+      return ELF_CLASS_32;
+    case EM_L1OM:
+    case EM_K1OM:
+      return ELF_CLASS_64;
+    case EM_X86_64:
+    case EM_NONE:
+      return ELF_CLASS_BOTH;
+    default:
+      error (_("Unknown machine type: %d\n"), mach);
+      return ELF_CLASS_UNKNOWN;
+    }
+}
 
 static int
 update_elf_header (const char *file_name, FILE *file)
@@ -86,17 +117,29 @@ update_elf_header (const char *file_name, FILE *file)
     return 1;
 
   class = elf_header.e_ident[EI_CLASS];
+  machine = elf_header.e_machine;
 
   /* Skip if class doesn't match. */
-  if (input_elf_class != -1 && class != input_elf_class)
+  if (input_elf_class == ELF_CLASS_UNKNOWN)
+    input_elf_class = elf_class (machine);
+
+  if (input_elf_class != ELF_CLASS_BOTH
+      && (int) input_elf_class != class)
     {
       error
-       (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
+       (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
         file_name, class, input_elf_class);
       return 0;
     }
 
-  machine = elf_header.e_machine;
+  if (output_elf_class != ELF_CLASS_BOTH
+      && (int) output_elf_class != class)
+    {
+      error
+       (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
+        file_name, class, output_elf_class);
+      return 0;
+    }
 
   /* Skip if e_machine doesn't match. */
   if (input_elf_machine != -1 && machine != input_elf_machine)
@@ -551,6 +594,10 @@ elf_osabi (const char *osabi)
 static int
 elf_machine (const char *mach)
 {
+  if (strcasecmp (mach, "i386") == 0)
+    return EM_386;
+  if (strcasecmp (mach, "iamcu") == 0)
+    return EM_IAMCU;
   if (strcasecmp (mach, "l1om") == 0)
     return EM_L1OM;
   if (strcasecmp (mach, "k1om") == 0)
@@ -567,25 +614,6 @@ elf_machine (const char *mach)
   return -1;
 }
 
-/* Return ELF class for a machine type, MACH.  */
-
-static int
-elf_class (int mach)
-{
-  switch (mach)
-    {
-    case EM_L1OM:
-    case EM_K1OM:
-    case EM_X86_64:
-      return ELFCLASS64;
-    case EM_NONE:
-      return ELFCLASSNONE;
-    default:
-      error (_("Unknown machine type: %d\n"), mach);
-      return -1;
-    }
-}
-
 /* Return ET_XXX for a type string, TYPE.  */
 
 static int
@@ -677,7 +705,7 @@ main (int argc, char ** argv)
          if (input_elf_machine < 0)
            return 1;
          input_elf_class = elf_class (input_elf_machine);
-         if (input_elf_class < 0)
+         if (input_elf_class == ELF_CLASS_UNKNOWN)
            return 1;
          break;
 
@@ -685,6 +713,9 @@ main (int argc, char ** argv)
          output_elf_machine = elf_machine (optarg);
          if (output_elf_machine < 0)
            return 1;
+         output_elf_class = elf_class (output_elf_machine);
+         if (output_elf_class == ELF_CLASS_UNKNOWN)
+           return 1;
          break;
 
        case OPTION_INPUT_TYPE:
index b9b7b3e6416ebae53f4ed2a40e7b969522b36ebe..2dd3f0e09bdb8c1462facc160269999bbb46cd91 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * binutils-all/elfedit-5.d: New file.
+       * binutils-all/elfedit.exp: Run elfedit-5.
+
 2015-04-30  Nick Clifton  <nickc@redhat.com>
 
        * binutils-all/objdump.exp (cpus_expected): Add MeP CPU names.
diff --git a/binutils/testsuite/binutils-all/elfedit-5.d b/binutils/testsuite/binutils-all/elfedit-5.d
new file mode 100644 (file)
index 0000000..44b3c71
--- /dev/null
@@ -0,0 +1,17 @@
+#PROG: elfedit
+#elfedit: --output-mach iamcu
+#source: empty.s
+#as: --32
+#readelf: -h
+#name: Update ELF header 5
+#target: x86_64-*-* i386-*-*
+
+#...
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+#...
+  Machine:                           Intel MCU
+#...
index 465c39dedd3af10c4d20a38c9d20a584aed99507..742dd1562cdf3573dac3cd3dd13b54674fb22893 100644 (file)
@@ -32,3 +32,4 @@ run_dump_test "elfedit-1"
 run_dump_test "elfedit-2"
 run_dump_test "elfedit-3"
 run_dump_test "elfedit-4"
+run_dump_test "elfedit-5"