elfedit: Add --output-abiversion option to update ABIVERSION
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 16 Nov 2021 22:14:56 +0000 (14:14 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 17 Nov 2021 13:15:48 +0000 (05:15 -0800)
* NEWS: Mention --output-abiversion.
* elfedit.c (input_elf_abiversion): New.
(output_elf_abiversion): Likewise.
(update_elf_header): Update EI_ABIVERSION.
(command_line_switch): Add OPTION_INPUT_ABIVERSION and
OPTION_OUTPUT_ABIVERSION.
(options): Add --input-abiversion and --output-abiversion.
(usage): Likewise.
(main): Handle --input-abiversion and --output-abiversion.
* doc/binutils.texi: Document --input-abiversion and
--output-abiversion.
* testsuite/binutils-all/elfedit.exp: Run elfedit-6.
* testsuite/binutils-all/elfedit-6.d: New file.

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

index f3881250fce4dc02b498a4e20205068c235b68ed..6a2eba87e2742ad3255926fd8c61e2980bf27f46 100644 (file)
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* elfedit: Add --output-abiversion option to update ABIVERSION.
+
 * Add support for the LoongArch instruction set.
 
 * Tools which display symbols or strings (readelf, strings, nm, objdump)
index 5de0631f3f4dc567ed4d76b9737c447f5d40e7c2..fb5dc8ed56823c5c5cb68c52b6a711761297dd7c 100644 (file)
@@ -5206,9 +5206,11 @@ objdump(1), and the Info entries for @file{binutils}.
 elfedit [@option{--input-mach=}@var{machine}]
         [@option{--input-type=}@var{type}]
         [@option{--input-osabi=}@var{osabi}]
+        [@option{--input-abiversion=}@var{version}]
         @option{--output-mach=}@var{machine}
         @option{--output-type=}@var{type}
         @option{--output-osabi=}@var{osabi}
+        @option{--output-abiversion=}@var{version}
         @option{--enable-x86-feature=}@var{feature}
         @option{--disable-x86-feature=}@var{feature}
         [@option{-v}|@option{--version}]
@@ -5233,6 +5235,7 @@ should be updated.
 The long and short forms of options, shown here as alternatives, are
 equivalent. At least one of the @option{--output-mach},
 @option{--output-type}, @option{--output-osabi},
+@option{--output-abiversion},
 @option{--enable-x86-feature} and @option{--disable-x86-feature}
 options must be given.
 
@@ -5274,6 +5277,15 @@ The supported ELF OSABIs are, @var{none}, @var{HPUX}, @var{NetBSD},
 Change the ELF OSABI in the ELF header to @var{osabi}.  The
 supported ELF OSABI are the same as @option{--input-osabi}.
 
+@item --input-abiversion=@var{version}
+Set the matching input ELF file ABIVERSION to @var{version}.
+@var{version} must be between 0 and 255.  If @option{--input-abiversion}
+isn't specified, it will match any ELF ABIVERSIONs.
+
+@item --output-abiversion=@var{version}
+Change the ELF ABIVERSION in the ELF header to @var{version}.
+@var{version} must be between 0 and 255.
+
 @item --enable-x86-feature=@var{feature}
 Set the @var{feature} bit in program property in @var{exec} or @var{dyn}
 ELF files with machine types of @var{i386} or @var{x86-64}.  The
index e33c340d758ce78f17706d6cc6a5ee81b6aac8d8..374a648c2660415f496b3a3d89a7c7447cfc27e2 100644 (file)
@@ -56,6 +56,8 @@ 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_abiversion = -1;
+static int output_elf_abiversion = -1;
 enum elfclass
   {
     ELF_CLASS_UNKNOWN = -1,
@@ -309,7 +311,7 @@ elf_class (int mach)
 static int
 update_elf_header (const char *file_name, FILE *file)
 {
-  int class, machine, type, status, osabi;
+  int class, machine, type, status, osabi, abiversion;
 
   if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
     {
@@ -380,6 +382,18 @@ update_elf_header (const char *file_name, FILE *file)
       return 0;
     }
 
+  abiversion = elf_header.e_ident[EI_ABIVERSION];
+
+  /* Skip if ABIVERSION doesn't match. */
+  if (input_elf_abiversion != -1
+      && abiversion != input_elf_abiversion)
+    {
+      error
+       (_("%s: Unmatched EI_ABIVERSION: %d is not %d\n"),
+        file_name, abiversion, input_elf_abiversion);
+      return 0;
+    }
+
   /* Update e_machine, e_type and EI_OSABI.  */
   switch (class)
     {
@@ -394,6 +408,8 @@ update_elf_header (const char *file_name, FILE *file)
        BYTE_PUT (ehdr32.e_type, output_elf_type);
       if (output_elf_osabi != -1)
        ehdr32.e_ident[EI_OSABI] = output_elf_osabi;
+      if (output_elf_abiversion != -1)
+       ehdr32.e_ident[EI_ABIVERSION] = output_elf_abiversion;
       status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
       break;
     case ELFCLASS64:
@@ -403,6 +419,8 @@ update_elf_header (const char *file_name, FILE *file)
        BYTE_PUT (ehdr64.e_type, output_elf_type);
       if (output_elf_osabi != -1)
        ehdr64.e_ident[EI_OSABI] = output_elf_osabi;
+      if (output_elf_abiversion != -1)
+       ehdr64.e_ident[EI_ABIVERSION] = output_elf_abiversion;
       status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
       break;
     }
@@ -884,6 +902,8 @@ enum command_line_switch
     OPTION_OUTPUT_TYPE,
     OPTION_INPUT_OSABI,
     OPTION_OUTPUT_OSABI,
+    OPTION_INPUT_ABIVERSION,
+    OPTION_OUTPUT_ABIVERSION,
 #ifdef HAVE_MMAP
     OPTION_ENABLE_X86_FEATURE,
     OPTION_DISABLE_X86_FEATURE,
@@ -898,6 +918,8 @@ static struct option options[] =
   {"output-type",      required_argument, 0, OPTION_OUTPUT_TYPE},
   {"input-osabi",      required_argument, 0, OPTION_INPUT_OSABI},
   {"output-osabi",     required_argument, 0, OPTION_OUTPUT_OSABI},
+  {"input-abiversion", required_argument, 0, OPTION_INPUT_ABIVERSION},
+  {"output-abiversion",        required_argument, 0, OPTION_OUTPUT_ABIVERSION},
 #ifdef HAVE_MMAP
   {"enable-x86-feature",
                        required_argument, 0, OPTION_ENABLE_X86_FEATURE},
@@ -934,7 +956,11 @@ usage (FILE *stream, int exit_status)
   --input-osabi [%s]\n\
                               Set input OSABI\n\
   --output-osabi [%s]\n\
-                              Set output OSABI\n"),
+                              Set output OSABI\n\
+  --input-abiversion [0-255]\n\
+                              Set input ABIVERSION\n\
+  --output-abiversion [0-255]\n\
+                              Set output ABIVERSION\n"),
           osabi, osabi);
 #ifdef HAVE_MMAP
   fprintf (stream, _("\
@@ -958,6 +984,7 @@ int
 main (int argc, char ** argv)
 {
   int c, status;
+  char *end;
 
 #ifdef HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
@@ -1015,6 +1042,28 @@ main (int argc, char ** argv)
            return 1;
          break;
 
+       case OPTION_INPUT_ABIVERSION:
+         input_elf_abiversion = strtoul (optarg, &end, 0);
+         if (*end != '\0'
+             || input_elf_abiversion < 0
+             || input_elf_abiversion > 255)
+           {
+             error (_("Invalid ABIVERSION: %s\n"), optarg);
+             return 1;
+           }
+         break;
+
+       case OPTION_OUTPUT_ABIVERSION:
+         output_elf_abiversion = strtoul (optarg, &end, 0);
+         if (*end != '\0'
+             || output_elf_abiversion < 0
+             || output_elf_abiversion > 255)
+           {
+             error (_("Invalid ABIVERSION: %s\n"), optarg);
+             return 1;
+           }
+         break;
+
 #ifdef HAVE_MMAP
        case OPTION_ENABLE_X86_FEATURE:
          if (elf_x86_feature (optarg, 1) < 0)
@@ -1046,7 +1095,8 @@ main (int argc, char ** argv)
         && ! disable_x86_features
 #endif
          && output_elf_type == -1
-         && output_elf_osabi == -1))
+         && output_elf_osabi == -1
+         && output_elf_abiversion == -1))
     usage (stderr, 1);
 
   status = 0;
diff --git a/binutils/testsuite/binutils-all/elfedit-6.d b/binutils/testsuite/binutils-all/elfedit-6.d
new file mode 100644 (file)
index 0000000..d30c6dc
--- /dev/null
@@ -0,0 +1,15 @@
+#PROG: elfedit
+#elfedit: --output-abiversion 20
+#source: empty.s
+#readelf: -h
+#name: Update ELF header 6
+#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi
+
+#...
+ELF Header:
+  Magic:   7f 45 4c 46 .*
+#...
+  Version:[ \t]+1 \(current\)
+#...
+  ABI Version:[ \t]+20
+#...
index 8ce8c8b592a312842d7cf79935c1a1d5d7947662..6531984bc7bf19f80068f48d12f73d46edfe0c42 100644 (file)
@@ -25,3 +25,4 @@ run_dump_test "elfedit-2"
 run_dump_test "elfedit-3"
 run_dump_test "elfedit-4"
 run_dump_test "elfedit-5"
+run_dump_test "elfedit-6"