@@ -46,5 +46,5 @@ elf_memory (char *image, size_t size)
return NULL;
}
- return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL);
+ return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ_MMAP, NULL);
}
@@ -1,4 +1,5 @@
/* Copyright (C) 2015 Red Hat, Inc.
+ Copyright (C) 2024 Mark J. Wielaard <mark@klomp.org>
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -18,16 +19,19 @@
# include <config.h>
#endif
+#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libelf.h>
+#include <errno.h>
#include <gelf.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <sys/mman.h>
int
@@ -38,21 +42,62 @@ main (int argc, char *argv[])
if (argc < 3
|| (strcmp (argv[1], "read") != 0
- && strcmp (argv[1], "mmap") != 0))
+ && strcmp (argv[1], "mmap") != 0
+ && strcmp (argv[1], "mem") != 0))
{
- printf ("Usage: (read|mmap) files...\n");
+ printf ("Usage: (read|mmap|mem) files...\n");
return -1;
}
- bool mmap = strcmp (argv[1], "mmap") == 0;
+ bool do_read = strcmp (argv[1], "read") == 0;
+ bool do_mmap = strcmp (argv[1], "mmap") == 0;
+ bool do_mem = strcmp (argv[1], "mem") == 0;
elf_version (EV_CURRENT);
for (cnt = 2; cnt < argc; ++cnt)
{
int fd = open (argv[cnt], O_RDONLY);
-
- Elf *elf = elf_begin (fd, mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+ void *map_address = NULL;
+ size_t map_size = 0;
+
+ Elf *elf;
+ if (do_read)
+ elf = elf_begin (fd, ELF_C_READ, NULL);
+ else if (do_mmap)
+ elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ else
+ {
+ assert (do_mem);
+ // We mmap the memory ourselves, explicitly PROT_READ only
+ struct stat st;
+ if (fstat (fd, &st) != 0)
+ {
+ printf ("%s cannot stat %s\n", argv[cnt], strerror (errno));
+ result = 1;
+ close (fd);
+ continue;
+ }
+ map_size = st.st_size;
+ map_address = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (map_address == MAP_FAILED)
+ {
+ printf ("%s cannot mmap %s\n", argv[cnt], strerror (errno));
+ result = 1;
+ close (fd);
+ continue;
+ }
+ if (map_size < EI_NIDENT
+ || memcmp (map_address, ELFMAG, SELFMAG) != 0)
+ {
+ printf ("%s isn't an ELF file\n", argv[cnt]);
+ result = 1;
+ munmap (map_address, map_size);
+ close (fd);
+ continue;
+ }
+ elf = elf_memory (map_address, map_size);
+ }
if (elf == NULL)
{
printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
@@ -107,6 +152,21 @@ main (int argc, char *argv[])
elf_end (elf);
close (fd);
+
+ if (do_mem)
+ {
+ /* Make sure we can still get at the memory. */
+ if (memcmp (map_address, ELFMAG, SELFMAG) != 0)
+ {
+ printf ("%s isn't an ELF file anymore???\n", argv[cnt]);
+ result = 1;
+ }
+ if (munmap (map_address, map_size) != 0)
+ {
+ printf ("%s cannot munmap %s\n", argv[cnt], strerror (errno));
+ result = 1;
+ }
+ }
}
return result;
@@ -42,6 +42,17 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu64 <<\EO
8: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgnu64 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 60
+3: .zdebug_info, GNU compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgnu64be
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu64be <<\EOF
1: .text, NOT compressed
@@ -67,6 +78,18 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu64be <<\
9: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgnu64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 60
+4: .zdebug_info, GNU compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgabi64
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi64 <<\EOF
1: .text, NOT compressed
@@ -90,6 +113,17 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi64 <<\E
8: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgabi64 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 60
+3: .debug_info, ELF compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgabi64be
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi64be <<\EOF
1: .text, NOT compressed
@@ -115,6 +149,18 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi64be <<
9: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgabi64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 60
+4: .debug_info, ELF compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgnu32
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu32 <<\EOF
1: .text, NOT compressed
@@ -138,6 +184,17 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu32 <<\EO
8: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgnu32 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 40
+3: .zdebug_info, GNU compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgnu32be
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu32be <<\EOF
1: .text, NOT compressed
@@ -163,6 +220,18 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu32be <<\
9: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgnu32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 40
+4: .zdebug_info, GNU compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgabi32
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi32 <<\EOF
1: .text, NOT compressed
@@ -186,6 +255,17 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi32 <<\E
8: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgabi32 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 40
+3: .debug_info, ELF compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
testfiles testfile-zgabi32be
testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi32be <<\EOF
1: .text, NOT compressed
@@ -211,4 +291,16 @@ testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi32be <<
9: .strtab, NOT compressed
EOF
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mem testfile-zgabi32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 40
+4: .debug_info, ELF compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
exit 0