aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2010-01-08 18:50:39 +0000
committerH.J. Lu <hjl.tools@gmail.com>2010-01-08 18:50:39 +0000
commitdd35de74344bc1dad410ed21fedd14671ab57aff (patch)
tree60b02b39651e7c028cd6c7f22a5b54567a56c554
parent28f2482621e47a82ad59b882d17a390a6cc98734 (diff)
downloadgdb-dd35de74344bc1dad410ed21fedd14671ab57aff.zip
gdb-dd35de74344bc1dad410ed21fedd14671ab57aff.tar.gz
gdb-dd35de74344bc1dad410ed21fedd14671ab57aff.tar.bz2
Add --input-type and --output-type to elfedit
binutils/ 2010-01-08 H.J. Lu <hongjiu.lu@intel.com> * elfedit.c (input_elf_type): New. (output_elf_type): Likewise. (elf_type): Likewise. (update_elf_header): Support updating ELF file type. (command_line_switch): Add OPTION_INPUT_TYPE and OPTION_OUTPUT_TYPE. (options): Likewise. (usage): Add --input-type and --output-type. (main): Handle OPTION_INPUT_TYPE and OPTION_OUTPUT_TYPE. Check one of --output-mach and --output-type must be specified. * doc/binutils.texi: Document --input-type and --output-type for elfedit. binutils/testsuite/ 2010-01-08 H.J. Lu <hongjiu.lu@intel.com> * binutils-all/elfedit-2.d: New. * binutils-all/elfedit.exp: Run elfedit-2.
-rw-r--r--binutils/ChangeLog16
-rw-r--r--binutils/doc/binutils.texi27
-rw-r--r--binutils/elfedit.c72
-rw-r--r--binutils/testsuite/ChangeLog6
-rw-r--r--binutils/testsuite/binutils-all/elfedit-2.d15
-rw-r--r--binutils/testsuite/binutils-all/elfedit.exp1
6 files changed, 123 insertions, 14 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index bbe4ec2..b541744 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,21 @@
2010-01-08 H.J. Lu <hongjiu.lu@intel.com>
+ * elfedit.c (input_elf_type): New.
+ (output_elf_type): Likewise.
+ (elf_type): Likewise.
+ (update_elf_header): Support updating ELF file type.
+ (command_line_switch): Add OPTION_INPUT_TYPE and
+ OPTION_OUTPUT_TYPE.
+ (options): Likewise.
+ (usage): Add --input-type and --output-type.
+ (main): Handle OPTION_INPUT_TYPE and OPTION_OUTPUT_TYPE. Check
+ one of --output-mach and --output-type must be specified.
+
+ * doc/binutils.texi: Document --input-type and --output-type
+ for elfedit.
+
+2010-01-08 H.J. Lu <hongjiu.lu@intel.com>
+
* doc/binutils.texi: Fix a typo.
2010-01-08 H.J. Lu <hongjiu.lu@intel.com>
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 4d9a23f..aedb80f 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -4107,7 +4107,9 @@ objdump(1), and the Info entries for @file{binutils}.
@smallexample
@c man begin SYNOPSIS elfedit
elfedit [@option{--input-mach=}@var{machine}]
+ [@option{--input-type=}@var{type}]
@option{--output-mach=}@var{machine}
+ @option{--output-type=}@var{type}
[@option{-v}|@option{--version}]
[@option{-h}|@option{--help}]
@var{elffile}@dots{}
@@ -4116,9 +4118,9 @@ elfedit [@option{--input-mach=}@var{machine}]
@c man begin DESCRIPTION elfedit
-@command{elfedit} updates the ELF header of ELF files. The
-options control how and which fields in the ELF header should be
-updated.
+@command{elfedit} updates the ELF header of ELF files which have
+the matching ELF machine and file types. The options control how and
+which fields in the ELF header should be updated.
@var{elffile}@dots{} are the ELF files to be updated. 32-bit and
64-bit ELF files are supported, as are archives containing ELF files.
@@ -4127,14 +4129,15 @@ updated.
@c man begin OPTIONS elfedit
The long and short forms of options, shown here as alternatives, are
-equivalent. The @option{--output-mach} option must be given.
+equivalent. At least one of the @option{--output-mach} and
+@option{--output-type} options must be given.
@table @env
@itemx --input-mach=@var{machine}
-Only the input files with ELF machine type, @var{machine}, will be
-updated. If @option{--input-mach} isn't specified, any ELF file
-will be updated.
+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} and @var{x86-64}.
@@ -4142,6 +4145,16 @@ The supported ELF machine types are, @var{L1OM} and @var{x86-64}.
Change the ELF machine type in the ELF header to @var{machine}. The
supported ELF machine types are the same as @option{--input-mach}.
+@itemx --input-type=@var{type}
+Set the matching input ELF file type to @var{type}. If
+@option{--input-type} isn't specified, it will match any ELF file types.
+
+The supported ELF file types are, @var{rel}, @var{exec} and @var{dyn}.
+
+@itemx --output-type=@var{type}
+Change the ELF file type in the ELF header to @var{type}. The
+supported ELF types are the same as @option{--input-type}.
+
@item -v
@itemx --version
Display the version number of @command{elfedit}.
diff --git a/binutils/elfedit.c b/binutils/elfedit.c
index 410d89a..b71990c 100644
--- a/binutils/elfedit.c
+++ b/binutils/elfedit.c
@@ -55,6 +55,8 @@ static Elf32_External_Ehdr ehdr32;
static Elf64_External_Ehdr ehdr64;
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_class = -1;
#define streq(a,b) (strcmp ((a), (b)) == 0)
@@ -228,7 +230,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, status;
+ int class, machine, type, status;
if (elf_header.e_ident[EI_MAG0] != ELFMAG0
|| elf_header.e_ident[EI_MAG1] != ELFMAG1
@@ -276,7 +278,18 @@ update_elf_header (const char *file_name, FILE *file)
return 0;
}
- /* Update e_machine. */
+ type = elf_header.e_type;
+
+ /* Skip if e_type doesn't match. */
+ if (input_elf_type != -1 && type != input_elf_type)
+ {
+ non_fatal
+ (_("%s: Unmatched e_type: %d is not %d\n"),
+ file_name, type, input_elf_type);
+ return 0;
+ }
+
+ /* Update e_machine and e_type. */
switch (class)
{
default:
@@ -284,11 +297,17 @@ update_elf_header (const char *file_name, FILE *file)
abort ();
break;
case ELFCLASS32:
- BYTE_PUT (ehdr32.e_machine, output_elf_machine);
+ if (output_elf_machine != -1)
+ BYTE_PUT (ehdr32.e_machine, output_elf_machine);
+ if (output_elf_type != -1)
+ BYTE_PUT (ehdr32.e_type, output_elf_type);
status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1;
break;
case ELFCLASS64:
- BYTE_PUT (ehdr64.e_machine, output_elf_machine);
+ if (output_elf_machine != -1)
+ BYTE_PUT (ehdr64.e_machine, output_elf_machine);
+ if (output_elf_type != -1)
+ BYTE_PUT (ehdr64.e_type, output_elf_type);
status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1;
break;
}
@@ -1015,16 +1034,39 @@ elf_class (int mach)
}
}
+/* Return ET_XXX for a type string, TYPE. */
+
+static int
+elf_type (const char *type)
+{
+ if (strcasecmp (type, "rel") == 0)
+ return ET_REL;
+ if (strcasecmp (type, "exec") == 0)
+ return ET_EXEC;
+ if (strcasecmp (type, "dyn") == 0)
+ return ET_DYN;
+ if (strcasecmp (type, "none") == 0)
+ return ET_NONE;
+
+ non_fatal (_("Unknown type: %s\n"), type);
+
+ return -1;
+}
+
enum command_line_switch
{
OPTION_INPUT_MACH = 150,
- OPTION_OUTPUT_MACH
+ OPTION_OUTPUT_MACH,
+ OPTION_INPUT_TYPE,
+ OPTION_OUTPUT_TYPE
};
static struct option options[] =
{
{"input-mach", required_argument, 0, OPTION_INPUT_MACH},
{"output-mach", required_argument, 0, OPTION_OUTPUT_MACH},
+ {"input-type", required_argument, 0, OPTION_INPUT_TYPE},
+ {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{0, no_argument, 0, 0}
@@ -1033,13 +1075,15 @@ static struct option options[] =
static void
usage (FILE *stream, int exit_status)
{
- fprintf (stream, _("Usage: %s [option(s)] --output-mach <machine> elffile(s)\n"),
+ fprintf (stream, _("Usage: %s [option(s)] {--output-mach <machine>|--output-type <type>} elffile(s)\n"),
program_name);
fprintf (stream, _(" Update the ELF header of ELF files\n"));
fprintf (stream, _(" The options are:\n"));
fprintf (stream, _("\
--input-mach <machine> Set input machine type to <machine>\n\
--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\
-h --help Display this information\n\
-v --version Display the version number of %s\n\
"),
@@ -1085,6 +1129,18 @@ main (int argc, char ** argv)
return 1;
break;
+ case OPTION_INPUT_TYPE:
+ input_elf_type = elf_type (optarg);
+ if (input_elf_type < 0)
+ return 1;
+ break;
+
+ case OPTION_OUTPUT_TYPE:
+ output_elf_type = elf_type (optarg);
+ if (output_elf_type < 0)
+ return 1;
+ break;
+
case 'h':
usage (stdout, 0);
@@ -1097,7 +1153,9 @@ main (int argc, char ** argv)
}
}
- if (optind == argc || output_elf_machine == -1)
+ if (optind == argc
+ || (output_elf_machine == -1
+ && output_elf_type == -1))
usage (stderr, 1);
status = 0;
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index bd066e1..4ebc7e9 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-01-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * binutils-all/elfedit-2.d: New.
+
+ * binutils-all/elfedit.exp: Run elfedit-2.
+
2010-01-06 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/11131
diff --git a/binutils/testsuite/binutils-all/elfedit-2.d b/binutils/testsuite/binutils-all/elfedit-2.d
new file mode 100644
index 0000000..af07c1d
--- /dev/null
+++ b/binutils/testsuite/binutils-all/elfedit-2.d
@@ -0,0 +1,15 @@
+#PROG: elfedit
+#elfedit: --output-type exec
+#source: empty.s
+#readelf: -h
+#name: Update ELF header 2
+#target: *-*-linux*
+
+#...
+ELF Header:
+ Magic: 7f 45 4c 46 .*
+#...
+ Version:[ \t]+1 \(current\)
+#...
+ Type:[ \t]+EXEC \(Executable file\)
+#...
diff --git a/binutils/testsuite/binutils-all/elfedit.exp b/binutils/testsuite/binutils-all/elfedit.exp
index d43c31a..23d5292 100644
--- a/binutils/testsuite/binutils-all/elfedit.exp
+++ b/binutils/testsuite/binutils-all/elfedit.exp
@@ -29,3 +29,4 @@ if ![is_remote host] {
}
run_dump_test "elfedit-1"
+run_dump_test "elfedit-2"