diff options
-rw-r--r-- | binutils/ChangeLog | 17 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 19 | ||||
-rw-r--r-- | binutils/elfedit.c | 90 | ||||
-rw-r--r-- | binutils/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/elfedit-3.d | 15 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/elfedit.exp | 1 |
6 files changed, 140 insertions, 8 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index cac073f..e7986f7 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,20 @@ +2010-08-23 H.J. Lu <hongjiu.lu@intel.com> + + * elfedit.c (input_elf_osabi): New. + (output_elf_osbi): Likewise. + (osabis): Likewise. + (elf_osabi): Likewise. + (update_elf_header): Support updating ELF OSABI. + (make_qualified_name): Break long line. + (command_line_switch): Add OPTION_INPUT_OSABI and + OPTION_OUTPUT_OSABI. + (options): Likewise. + (usage): Add --input-osabi and --output-osabi. + (main): Handle OPTION_INPUT_OSABI and OPTION_OUTPUT_OSABI. + + * doc/binutils.texi: Document --input-osabi and --output-osabi + for elfedit. + 2010-08-23 Maciej W. Rozycki <macro@codesourcery.com> * readelf.c (display_mips_gnu_attribute): Replace GCC options diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 9f374f8..0f0d8ee 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -4121,8 +4121,10 @@ objdump(1), and the Info entries for @file{binutils}. @c man begin SYNOPSIS elfedit elfedit [@option{--input-mach=}@var{machine}] [@option{--input-type=}@var{type}] + [@option{--input-osabi=}@var{osbi}] @option{--output-mach=}@var{machine} @option{--output-type=}@var{type} + @option{--output-osabi=}@var{osbi} [@option{-v}|@option{--version}] [@option{-h}|@option{--help}] @var{elffile}@dots{} @@ -4142,8 +4144,8 @@ which fields in the ELF header should be updated. @c man begin OPTIONS elfedit The long and short forms of options, shown here as alternatives, are -equivalent. At least one of the @option{--output-mach} and -@option{--output-type} options must be given. +equivalent. At least one of the @option{--output-mach}, +@option{--output-type} and @option{--output-osabi} options must be given. @table @env @@ -4168,6 +4170,19 @@ The supported ELF file types are, @var{rel}, @var{exec} and @var{dyn}. Change the ELF file type in the ELF header to @var{type}. The supported ELF types are the same as @option{--input-type}. +@itemx --input-osabi=@var{osabi} +Set the matching input ELF file OSABI to @var{osbi}. If +@option{--input-osabi} isn't specified, it will match any ELF OSABIs. + +The supported ELF OSABIs are, @var{none}, @var{HPUX}, @var{NetBSD}, +@var{Linux}, @var{Hurd}, @var{Solaris}, @var{AIX}, @var{Irix}, +@var{FreeBSD}, @var{TRU64}, @var{Modesto}, @var{OpenBSD}, @var{OpenVMS}, +@var{NSK}, @var{AROS} and @var{FenixOS}. + +@itemx --output-osabi=@var{osabi} +Change the ELF OSABI in the ELF header to @var{type}. The +supported ELF OSABI are the same as @option{--input-osabi}. + @item -v @itemx --version Display the version number of @command{elfedit}. diff --git a/binutils/elfedit.c b/binutils/elfedit.c index ce77af4..c9a4b5a 100644 --- a/binutils/elfedit.c +++ b/binutils/elfedit.c @@ -57,6 +57,8 @@ 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_osabi = -1; +static int output_elf_osabi = -1; static int input_elf_class = -1; #define streq(a,b) (strcmp ((a), (b)) == 0) @@ -230,7 +232,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, type, status; + int class, machine, type, status, osabi; if (elf_header.e_ident[EI_MAG0] != ELFMAG0 || elf_header.e_ident[EI_MAG1] != ELFMAG1 @@ -289,7 +291,18 @@ update_elf_header (const char *file_name, FILE *file) return 0; } - /* Update e_machine and e_type. */ + osabi = elf_header.e_ident[EI_OSABI]; + + /* Skip if OSABI doesn't match. */ + if (input_elf_osabi != -1 && osabi != input_elf_osabi) + { + non_fatal + (_("%s: Unmatched EI_OSABI: %d is not %d\n"), + file_name, osabi, input_elf_osabi); + return 0; + } + + /* Update e_machine, e_type and EI_OSABI. */ switch (class) { default: @@ -301,6 +314,8 @@ update_elf_header (const char *file_name, FILE *file) BYTE_PUT (ehdr32.e_machine, output_elf_machine); if (output_elf_type != -1) BYTE_PUT (ehdr32.e_type, output_elf_type); + if (output_elf_osabi != -1) + ehdr32.e_ident[EI_OSABI] = output_elf_osabi; status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1; break; case ELFCLASS64: @@ -308,6 +323,8 @@ update_elf_header (const char *file_name, FILE *file) BYTE_PUT (ehdr64.e_machine, output_elf_machine); if (output_elf_type != -1) BYTE_PUT (ehdr64.e_type, output_elf_type); + if (output_elf_osabi != -1) + ehdr64.e_ident[EI_OSABI] = output_elf_osabi; status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1; break; } @@ -761,7 +778,8 @@ make_qualified_name (struct archive_info * arch, } if (arch->is_thin_archive && arch->nested_member_origin != 0) - snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name); + snprintf (name, len, "%s[%s(%s)]", arch->file_name, + nested_arch->file_name, member_name); else if (arch->is_thin_archive) snprintf (name, len, "%s[%s]", arch->file_name, member_name); else @@ -995,6 +1013,47 @@ process_file (const char *file_name) return ret; } +static const struct +{ + int osabi; + const char *name; +} +osabis[] = +{ + { ELFOSABI_NONE, "none" }, + { ELFOSABI_HPUX, "HPUX" }, + { ELFOSABI_NETBSD, "NetBSD" }, + { ELFOSABI_LINUX, "Linux" }, + { ELFOSABI_HURD, "Hurd" }, + { ELFOSABI_SOLARIS, "Solaris" }, + { ELFOSABI_AIX, "AIX" }, + { ELFOSABI_IRIX, "Irix" }, + { ELFOSABI_FREEBSD, "FreeBSD" }, + { ELFOSABI_TRU64, "TRU64" }, + { ELFOSABI_MODESTO, "Modesto" }, + { ELFOSABI_OPENBSD, "OpenBSD" }, + { ELFOSABI_OPENVMS, "OpenVMS" }, + { ELFOSABI_NSK, "NSK" }, + { ELFOSABI_AROS, "AROS" }, + { ELFOSABI_FENIXOS, "FenixOS" } +}; + +/* Return ELFOSABI_XXX for an OSABI string, OSABI. */ + +static int +elf_osabi (const char *osabi) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (osabis); i++) + if (strcasecmp (osabi, osabis[i].name) == 0) + return osabis[i].osabi; + + non_fatal (_("Unknown OSABI: %s\n"), osabi); + + return -1; +} + /* Return EM_XXX for a machine string, MACH. */ static int @@ -1056,7 +1115,9 @@ enum command_line_switch OPTION_INPUT_MACH = 150, OPTION_OUTPUT_MACH, OPTION_INPUT_TYPE, - OPTION_OUTPUT_TYPE + OPTION_OUTPUT_TYPE, + OPTION_INPUT_OSABI, + OPTION_OUTPUT_OSABI }; static struct option options[] = @@ -1065,6 +1126,8 @@ static struct option options[] = {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH}, {"input-type", required_argument, 0, OPTION_INPUT_TYPE}, {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE}, + {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI}, + {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, no_argument, 0, 0} @@ -1073,7 +1136,7 @@ static struct option options[] = static void usage (FILE *stream, int exit_status) { - fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"), + fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"), program_name); fprintf (stream, _(" Update the ELF header of ELF files\n")); fprintf (stream, _(" The options are:\n")); @@ -1082,6 +1145,8 @@ usage (FILE *stream, int exit_status) --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\ + --input-osabi <osabi> Set input OSABI to <osabi>\n\ + --output-osabi <osabi> Set output OSABI to <osabi>\n\ -h --help Display this information\n\ -v --version Display the version number of %s\n\ "), @@ -1139,6 +1204,18 @@ main (int argc, char ** argv) return 1; break; + case OPTION_INPUT_OSABI: + input_elf_osabi = elf_osabi (optarg); + if (input_elf_osabi < 0) + return 1; + break; + + case OPTION_OUTPUT_OSABI: + output_elf_osabi = elf_osabi (optarg); + if (output_elf_osabi < 0) + return 1; + break; + case 'h': usage (stdout, 0); @@ -1153,7 +1230,8 @@ main (int argc, char ** argv) if (optind == argc || (output_elf_machine == -1 - && output_elf_type == -1)) + && output_elf_type == -1 + && output_elf_osabi == -1)) usage (stderr, 1); status = 0; diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog index 6066eee..9299f9e 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-08-23 H.J. Lu <hongjiu.lu@intel.com> + + * binutils-all/elfedit-3.d: New. + + * binutils-all/elfedit.exp: Run elfedit-3. + 2010-07-19 Andreas Schwab <schwab@redhat.com> * binutils-all/readelf.s: Ignore "Key to Flags" contents. diff --git a/binutils/testsuite/binutils-all/elfedit-3.d b/binutils/testsuite/binutils-all/elfedit-3.d new file mode 100644 index 0000000..c877f46 --- /dev/null +++ b/binutils/testsuite/binutils-all/elfedit-3.d @@ -0,0 +1,15 @@ +#PROG: elfedit +#elfedit: --output-osabi FenixOS +#source: empty.s +#readelf: -h +#name: Update ELF header 3 +#target: *-*-linux* + +#... +ELF Header: + Magic: 7f 45 4c 46 .* +#... + Version:[ \t]+1 \(current\) +#... + OS/ABI:[ \t]+FenixOS +#... diff --git a/binutils/testsuite/binutils-all/elfedit.exp b/binutils/testsuite/binutils-all/elfedit.exp index 23d5292..2142774 100644 --- a/binutils/testsuite/binutils-all/elfedit.exp +++ b/binutils/testsuite/binutils-all/elfedit.exp @@ -30,3 +30,4 @@ if ![is_remote host] { run_dump_test "elfedit-1" run_dump_test "elfedit-2" +run_dump_test "elfedit-3" |