diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-11-16 14:14:56 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-11-17 05:15:48 -0800 |
commit | c9dcc18f8ded97ed7cd1dd64da8c7b37b86f61bb (patch) | |
tree | 27dc86ebf37b6e7510cc507a28f0cf28dffbf8f0 /binutils/elfedit.c | |
parent | 65e4a99a26452d99d586f6e5a0c43e24348a5125 (diff) | |
download | binutils-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.c | 56 |
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; |