aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2022-08-22 11:15:40 +0100
committerNick Clifton <nickc@redhat.com>2022-08-22 11:15:40 +0100
commit521f726815eb426660f6b9ecc005fbab6c1b00ea (patch)
treedbb189b697b1f865d28ee1438cd87d4bf35a7f6e /binutils
parentba86e7501391c1eef4efa8201f39abf127e1084b (diff)
downloadfsf-binutils-gdb-521f726815eb426660f6b9ecc005fbab6c1b00ea.zip
fsf-binutils-gdb-521f726815eb426660f6b9ecc005fbab6c1b00ea.tar.gz
fsf-binutils-gdb-521f726815eb426660f6b9ecc005fbab6c1b00ea.tar.bz2
Have readelf warn users if it is asked to decode a LLVM bitcode file or a golang object file.
* readelf.c (check_magic_number): New function. Checks the magic bytes at the start of a file. If they are not the ELF format magic values, then attempts to generate a helpful error message. (process_file_header): Call check_magic_number.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog7
-rw-r--r--binutils/readelf.c69
2 files changed, 67 insertions, 9 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index e911f44..e01db7d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2022-08-22 Nick Clifton <nickc@redhat.com>
+
+ * readelf.c (check_magic_number): New function. Checks the magic
+ bytes at the start of a file. If they are not the ELF format
+ magic values, then attempts to generate a helpful error message.
+ (process_file_header): Call check_magic_number.
+
2022-08-09 Nick Clifton <nickc@redhat.com>
PR 29457
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1ec2523..b630166 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -5688,6 +5688,64 @@ get_data_encoding (unsigned int encoding)
}
}
+static bool
+check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
+{
+ if (header->e_ident[EI_MAG0] == ELFMAG0
+ && header->e_ident[EI_MAG1] == ELFMAG1
+ && header->e_ident[EI_MAG2] == ELFMAG2
+ && header->e_ident[EI_MAG3] == ELFMAG3)
+ return true;
+
+ /* Some compilers produce object files that are not in the ELF file format.
+ As an aid to users of readelf, try to identify these cases and suggest
+ alternative tools.
+
+ FIXME: It is not clear if all four bytes are used as constant magic
+ valus by all compilers. It may be necessary to recode this function if
+ different tools use different length sequences. */
+
+ static struct
+ {
+ unsigned char magic[4];
+ const char * obj_message;
+ const char * ar_message;
+ }
+ known_magic[] =
+ {
+ { { 'B', 'C', 0xc0, 0xde },
+ N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
+ N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
+ },
+ { { 'g', 'o', ' ', 'o' },
+ N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
+ NULL
+ }
+ };
+ int i;
+
+ for (i = ARRAY_SIZE (known_magic); i--;)
+ {
+ if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
+ && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
+ && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
+ && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
+ {
+ /* Some compiler's analyzer tools do not handle archives,
+ so we provide two different kinds of error message. */
+ if (filedata->archive_file_size > 0
+ && known_magic[i].ar_message != NULL)
+ error (known_magic[i].ar_message);
+ else
+ error (known_magic[i].obj_message);
+ return false;
+ }
+ }
+
+ error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
+ return false;
+}
+
/* Decode the data held in 'filedata->file_header'. */
static bool
@@ -5695,15 +5753,8 @@ process_file_header (Filedata * filedata)
{
Elf_Internal_Ehdr * header = & filedata->file_header;
- if ( header->e_ident[EI_MAG0] != ELFMAG0
- || header->e_ident[EI_MAG1] != ELFMAG1
- || header->e_ident[EI_MAG2] != ELFMAG2
- || header->e_ident[EI_MAG3] != ELFMAG3)
- {
- error
- (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
- return false;
- }
+ if (! check_magic_number (filedata, header))
+ return false;
if (! filedata->is_separate)
init_dwarf_regnames_by_elf_machine_code (header->e_machine);