/* elfedit.c -- Update the ELF header of an ELF format file
- Copyright 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
This file is part of GNU Binutils.
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
\f
-#include "config.h"
#include "sysdep.h"
#include <assert.h>
-#include <sys/stat.h>
#if __GNUC__ >= 2
/* Define BFD64 here, even if our default architecture is 32 bit ELF
static int output_elf_type = -1;
static int input_elf_osabi = -1;
static int output_elf_osabi = -1;
-static int input_elf_class = -1;
+enum elfclass
+ {
+ ELF_CLASS_UNKNOWN = -1,
+ ELF_CLASS_NONE = ELFCLASSNONE,
+ ELF_CLASS_32 = ELFCLASS32,
+ ELF_CLASS_64 = ELFCLASS64,
+ ELF_CLASS_BOTH
+ };
+static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN;
+static enum elfclass output_elf_class = ELF_CLASS_BOTH;
+
+/* Return ELF class for a machine type, MACH. */
+
+static enum elfclass
+elf_class (int mach)
+{
+ switch (mach)
+ {
+ case EM_386:
+ case EM_IAMCU:
+ return ELF_CLASS_32;
+ case EM_L1OM:
+ case EM_K1OM:
+ return ELF_CLASS_64;
+ case EM_X86_64:
+ case EM_NONE:
+ return ELF_CLASS_BOTH;
+ default:
+ return ELF_CLASS_BOTH;
+ }
+}
static int
update_elf_header (const char *file_name, FILE *file)
return 1;
class = elf_header.e_ident[EI_CLASS];
+ machine = elf_header.e_machine;
/* Skip if class doesn't match. */
- if (input_elf_class != -1 && class != input_elf_class)
+ if (input_elf_class == ELF_CLASS_UNKNOWN)
+ input_elf_class = elf_class (machine);
+
+ if (input_elf_class != ELF_CLASS_BOTH
+ && (int) input_elf_class != class)
{
error
- (_("%s: Unmatched EI_CLASS: %d is not %d\n"),
+ (_("%s: Unmatched input EI_CLASS: %d is not %d\n"),
file_name, class, input_elf_class);
return 0;
}
- machine = elf_header.e_machine;
+ if (output_elf_class != ELF_CLASS_BOTH
+ && (int) output_elf_class != class)
+ {
+ error
+ (_("%s: Unmatched output EI_CLASS: %d is not %d\n"),
+ file_name, class, output_elf_class);
+ return 0;
+ }
/* Skip if e_machine doesn't match. */
if (input_elf_machine != -1 && machine != input_elf_machine)
{ ELFOSABI_NONE, "none" },
{ ELFOSABI_HPUX, "HPUX" },
{ ELFOSABI_NETBSD, "NetBSD" },
- { ELFOSABI_LINUX, "Linux" },
- { ELFOSABI_HURD, "Hurd" },
+ { ELFOSABI_GNU, "GNU" },
+ { ELFOSABI_GNU, "Linux" },
{ ELFOSABI_SOLARIS, "Solaris" },
{ ELFOSABI_AIX, "AIX" },
{ ELFOSABI_IRIX, "Irix" },
static int
elf_machine (const char *mach)
{
+ if (strcasecmp (mach, "i386") == 0)
+ return EM_386;
+ if (strcasecmp (mach, "iamcu") == 0)
+ return EM_IAMCU;
if (strcasecmp (mach, "l1om") == 0)
return EM_L1OM;
+ if (strcasecmp (mach, "k1om") == 0)
+ return EM_K1OM;
if (strcasecmp (mach, "x86_64") == 0)
return EM_X86_64;
if (strcasecmp (mach, "x86-64") == 0)
return -1;
}
-/* Return ELF class for a machine type, MACH. */
-
-static int
-elf_class (int mach)
-{
- switch (mach)
- {
- case EM_L1OM:
- case EM_X86_64:
- return ELFCLASS64;
- case EM_NONE:
- return ELFCLASSNONE;
- default:
- error (_("Unknown machine type: %d\n"), mach);
- return -1;
- }
-}
-
/* Return ET_XXX for a type string, TYPE. */
static int
{0, no_argument, 0, 0}
};
-static void
+ATTRIBUTE_NORETURN static void
usage (FILE *stream, int exit_status)
{
fprintf (stream, _("Usage: %s <option(s)> elffile(s)\n"),
if (input_elf_machine < 0)
return 1;
input_elf_class = elf_class (input_elf_machine);
- if (input_elf_class < 0)
+ if (input_elf_class == ELF_CLASS_UNKNOWN)
return 1;
break;
output_elf_machine = elf_machine (optarg);
if (output_elf_machine < 0)
return 1;
+ output_elf_class = elf_class (output_elf_machine);
+ if (output_elf_class == ELF_CLASS_UNKNOWN)
+ return 1;
break;
case OPTION_INPUT_TYPE: