aboutsummaryrefslogtreecommitdiff
path: root/binutils/elfedit.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-11-16 14:14:56 -0800
committerH.J. Lu <hjl.tools@gmail.com>2021-11-17 05:15:48 -0800
commitc9dcc18f8ded97ed7cd1dd64da8c7b37b86f61bb (patch)
tree27dc86ebf37b6e7510cc507a28f0cf28dffbf8f0 /binutils/elfedit.c
parent65e4a99a26452d99d586f6e5a0c43e24348a5125 (diff)
downloadbinutils-c9dcc18f8ded97ed7cd1dd64da8c7b37b86f61bb.zip
binutils-c9dcc18f8ded97ed7cd1dd64da8c7b37b86f61bb.tar.gz
binutils-c9dcc18f8ded97ed7cd1dd64da8c7b37b86f61bb.tar.bz2
elfedit: Add --output-abiversion option to update ABIVERSION
* 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.
Diffstat (limited to 'binutils/elfedit.c')
-rw-r--r--binutils/elfedit.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/binutils/elfedit.c b/binutils/elfedit.c
index e33c340..374a648 100644
--- a/binutils/elfedit.c
+++ b/binutils/elfedit.c
@@ -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;