Page MenuHomeFreeBSD

D24566.id77994.diff
No OneTemporary

D24566.id77994.diff

Index: contrib/elftoolchain/libelf/_libelf.h
===================================================================
--- contrib/elftoolchain/libelf/_libelf.h
+++ contrib/elftoolchain/libelf/_libelf.h
@@ -220,6 +220,7 @@
size_t count);
_libelf_translator_function *_libelf_get_translator(Elf_Type _t,
int _direction, int _elfclass, int _elfmachine);
+void *_libelf_getchdr(Elf_Scn *_e, int _elfclass);
void *_libelf_getphdr(Elf *_e, int _elfclass);
void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass);
void _libelf_init_elf(Elf *_e, Elf_Kind _kind);
Index: contrib/elftoolchain/libelf/gelf.h
===================================================================
--- contrib/elftoolchain/libelf/gelf.h
+++ contrib/elftoolchain/libelf/gelf.h
@@ -39,6 +39,7 @@
typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */
typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */
+typedef Elf64_Chdr GElf_Chdr; /* Compressed section header */
typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */
typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */
typedef Elf64_Phdr GElf_Phdr; /* Program header */
@@ -73,6 +74,7 @@
long gelf_checksum(Elf *_elf);
size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count,
unsigned int _version);
+GElf_Chdr *gelf_getchdr(Elf_Scn *_scn, GElf_Chdr *_dst);
int gelf_getclass(Elf *_elf);
GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst);
GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst);
Index: contrib/elftoolchain/libelf/gelf_chdr.c
===================================================================
--- /dev/null
+++ contrib/elftoolchain/libelf/gelf_chdr.c
@@ -0,0 +1,82 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018 The FreeBSD Foundation
+ *
+ * This software was developed by Tiger Gao under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "_libelf.h"
+
+Elf32_Chdr *
+elf32_getchdr(Elf_Scn *s)
+{
+ return (_libelf_getchdr(s, ELFCLASS32));
+}
+
+Elf64_Chdr *
+elf64_getchdr(Elf_Scn *s)
+{
+ return (_libelf_getchdr(s, ELFCLASS64));
+}
+
+GElf_Chdr *
+gelf_getchdr(Elf_Scn *s, GElf_Chdr *d)
+{
+ int ec;
+ void *ch;
+ Elf32_Chdr *ch32;
+ Elf64_Chdr *ch64;
+
+ if (d == NULL) {
+ LIBELF_SET_ERROR(ARGUMENT, 0);
+ return (NULL);
+ }
+
+ if ((ch = _libelf_getchdr(s, ELFCLASSNONE)) == NULL)
+ return (NULL);
+
+ ec = s->s_elf->e_class;
+ assert(ec == ELFCLASS32 || ec == ELFCLASS64);
+
+ if (ec == ELFCLASS32) {
+ ch32 = (Elf32_Chdr *)ch;
+
+ d->ch_type = (Elf64_Word)ch32->ch_type;
+ d->ch_size = (Elf64_Xword)ch32->ch_size;
+ d->ch_addralign = (Elf64_Xword)ch32->ch_addralign;
+ } else {
+ ch64 = (Elf64_Chdr *)ch;
+ *d = *ch64;
+ }
+
+ return (d);
+}
Index: contrib/elftoolchain/libelf/libelf.h
===================================================================
--- contrib/elftoolchain/libelf/libelf.h
+++ contrib/elftoolchain/libelf/libelf.h
@@ -162,7 +162,9 @@
ELF_E_SEQUENCE, /* API calls out of sequence */
ELF_E_UNIMPL, /* Feature is unimplemented */
ELF_E_VERSION, /* Unknown API version */
- ELF_E_NUM /* Max error number */
+ ELF_E_NUM, /* Max error number */
+ ELF_E_INVALID_SECTION_FLAGS, /* Invalid ELF section header flags */
+ ELF_E_INVALID_SECTION_TYPE /* Invalid ELF section header type */
};
/*
@@ -227,6 +229,7 @@
long elf32_checksum(Elf *_elf);
size_t elf32_fsize(Elf_Type _type, size_t _count,
unsigned int _version);
+Elf32_Chdr *elf32_getchdr(Elf_Scn *_scn);
Elf32_Ehdr *elf32_getehdr(Elf *_elf);
Elf32_Phdr *elf32_getphdr(Elf *_elf);
Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn);
@@ -240,6 +243,7 @@
long elf64_checksum(Elf *_elf);
size_t elf64_fsize(Elf_Type _type, size_t _count,
unsigned int _version);
+Elf64_Chdr *elf64_getchdr(Elf_Scn *_scn);
Elf64_Ehdr *elf64_getehdr(Elf *_elf);
Elf64_Phdr *elf64_getphdr(Elf *_elf);
Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn);
Index: contrib/elftoolchain/libelf/libelf_chdr.c
===================================================================
--- /dev/null
+++ contrib/elftoolchain/libelf/libelf_chdr.c
@@ -0,0 +1,103 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018 The FreeBSD Foundation
+ *
+ * This software was developed by Tiger Gao under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gelf.h>
+#include <libelf.h>
+
+#include "_libelf.h"
+
+void *
+_libelf_getchdr(Elf_Scn *s, int ec)
+{
+ Elf *e;
+ void *sh;
+ Elf32_Shdr *sh32;
+ Elf64_Shdr *sh64;
+
+ sh32 = NULL;
+ sh64 = NULL;
+
+ if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) {
+ LIBELF_SET_ERROR(ARGUMENT, 0);
+ return (NULL);
+ }
+
+ if (ec == ELFCLASSNONE)
+ ec = e->e_class;
+
+ if (ec != e->e_class) {
+ LIBELF_SET_ERROR(CLASS, 0);
+ return (NULL);
+ }
+
+ if ((sh = _libelf_getshdr(s, ec)) == NULL)
+ return (NULL);
+
+ if (ec == ELFCLASS32) {
+ sh32 = (Elf32_Shdr *)sh;
+ if ((sh32->sh_flags & SHF_ALLOC) != 0) {
+ LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0);
+ return (NULL);
+ }
+
+ if (sh32->sh_type == SHT_NULL || sh32->sh_type == SHT_NOBITS) {
+ LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0);
+ return (NULL);
+ }
+
+ if ((sh32->sh_flags & SHF_COMPRESSED) == 0) {
+ LIBELF_SET_ERROR(NOT_COMPRESSED, 0);
+ return (NULL);
+ }
+ } else {
+ sh64 = (Elf64_Shdr *)sh;
+ if ((sh64->sh_flags & SHF_ALLOC) != 0) {
+ LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0);
+ return (NULL);
+ }
+
+ if (sh64->sh_type == SHT_NULL || sh64->sh_type == SHT_NOBITS) {
+ LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0);
+ return (NULL);
+ }
+
+ if ((sh64->sh_flags & SHF_COMPRESSED) == 0) {
+ LIBELF_SET_ERROR(NOT_COMPRESSED, 0);
+ return (NULL);
+ }
+ }
+
+ Elf_Data *d = elf_getdata(s, NULL);
+
+ if (!d)
+ return (NULL);
+
+ return ((void *)d->d_buf);
+}
Index: contrib/elftoolchain/readelf/readelf.c
===================================================================
--- contrib/elftoolchain/readelf/readelf.c
+++ contrib/elftoolchain/readelf/readelf.c
@@ -46,6 +46,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <zlib.h>
#include <libcasper.h>
#include <casper/cap_fileargs.h>
@@ -87,6 +88,7 @@
#define RE_WW 0x00040000
#define RE_W 0x00080000
#define RE_X 0x00100000
+#define RE_Z 0x00200000
/*
* dwarf dump options.
@@ -189,6 +191,7 @@
{"arch-specific", no_argument, NULL, 'A'},
{"archive-index", no_argument, NULL, 'c'},
{"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP},
+ {"decompress", no_argument, 0, 'z'},
{"dynamic", no_argument, NULL, 'd'},
{"file-header", no_argument, NULL, 'h'},
{"full-section-name", no_argument, NULL, 'N'},
@@ -6833,6 +6836,82 @@
return (sym.st_value);
}
+/*
+ * Decompress a data section if needed (using ZLIB).
+ */
+static int decompress_section(struct section *s, unsigned char **buffer,
+ uint64_t *sz) {
+ GElf_Shdr sh;
+
+ if (gelf_getshdr(s->scn, &sh) == NULL)
+ errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1));
+
+ if (sh.sh_flags & SHF_COMPRESSED) {
+ int ret;
+ GElf_Chdr chdr;
+ Elf64_Xword compressed_size;
+ unsigned char *compressed_data_buffer = NULL;
+ Elf64_Xword inflated_size;
+ unsigned char *uncompressed_data_buffer = NULL;
+ Elf64_Xword uncompressed_size;
+ z_stream strm;
+
+ if (gelf_getchdr(s->scn, &chdr) == NULL)
+ errx(EXIT_FAILURE, "gelf_getchdr() failed: %s", elf_errmsg(-1));
+ if (chdr.ch_type != ELFCOMPRESS_ZLIB)
+ goto fail;
+
+ compressed_data_buffer = *buffer;
+ compressed_size = *sz;
+ inflated_size = 0;
+ uncompressed_size = chdr.ch_size;
+ uncompressed_data_buffer = malloc(uncompressed_size);
+ compressed_data_buffer += sizeof(chdr);
+ compressed_size -= sizeof(chdr);
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = compressed_size;
+ strm.avail_out = uncompressed_size;
+ ret = inflateInit(&strm);
+
+ if (ret != Z_OK)
+ goto fail;
+ /*
+ * The section can contain several compressed buffers,
+ * so decompress in a loop until all data is inflated.
+ */
+ while (inflated_size < compressed_size) {
+ strm.next_in = compressed_data_buffer + inflated_size;
+ strm.next_out = uncompressed_data_buffer + inflated_size;
+ ret = inflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ goto fail;
+ }
+ inflated_size = uncompressed_size - strm.avail_out;
+ ret = inflateReset(&strm);
+ if (ret != Z_OK)
+ goto fail;
+ }
+ if (strm.avail_out != 0) {
+ goto fail;
+ }
+ ret = inflateEnd(&strm);
+ if (ret != Z_OK)
+ goto fail;
+ free(*buffer);
+ *buffer = uncompressed_data_buffer;
+ *sz = uncompressed_size;
+ return (1);
+ fail:
+ free(uncompressed_data_buffer);
+ warnx("decompress_section failed: %s", elf_errmsg(-1));
+ return (0);
+ }
+ return (1);
+}
+
static void
hex_dump(struct readelf *re)
{
@@ -6862,9 +6941,12 @@
s->name);
continue;
}
+ addr = s->addr;
+ if (re->options & RE_Z) {
+ decompress_section(s, (unsigned char **) &d->d_buf, &d->d_size);
+ }
buf = d->d_buf;
sz = d->d_size;
- addr = s->addr;
printf("\nHex dump of section '%s':\n", s->name);
while (sz > 0) {
printf(" 0x%8.8jx ", (uintmax_t)addr);
@@ -6919,9 +7001,12 @@
s->name);
continue;
}
- buf_end = (unsigned char *) d->d_buf + d->d_size;
- start = (unsigned char *) d->d_buf;
found = 0;
+ if (re->options & RE_Z) {
+ decompress_section(s, (unsigned char **) &d->d_buf, &d->d_size);
+ }
+ start = (unsigned char *) d->d_buf;
+ buf_end = start + d->d_size;
printf("\nString dump of section '%s':\n", s->name);
for (;;) {
while (start < buf_end && !isprint(*start))
@@ -7601,7 +7686,7 @@
memset(re, 0, sizeof(*re));
STAILQ_INIT(&re->v_dumpop);
- while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:",
+ while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:z",
longopts, NULL)) != -1) {
switch(opt) {
case '?':
@@ -7698,6 +7783,9 @@
add_dumpop(re, 0, optarg, HEX_DUMP,
DUMP_BY_NAME);
break;
+ case 'z':
+ re->options |= RE_Z;
+ break;
case OPTION_DEBUG_DUMP:
re->options |= RE_W;
parse_dwarf_op_long(re, optarg);
Index: lib/libelf/Makefile
===================================================================
--- lib/libelf/Makefile
+++ lib/libelf/Makefile
@@ -38,6 +38,7 @@
elf_update.c \
elf_version.c \
gelf_cap.c \
+ gelf_chdr.c \
gelf_checksum.c \
gelf_dyn.c \
gelf_ehdr.c \
@@ -57,6 +58,7 @@
libelf_allocate.c \
libelf_ar.c \
libelf_ar_util.c \
+ libelf_chdr.c \
libelf_checksum.c \
libelf_data.c \
libelf_ehdr.c \
Index: usr.bin/readelf/Makefile
===================================================================
--- usr.bin/readelf/Makefile
+++ usr.bin/readelf/Makefile
@@ -10,7 +10,7 @@
PROG= readelf
SRCS= readelf.c
-LIBADD= dwarf elftc elf
+LIBADD= dwarf elftc elf z
.if ${MK_CASPER} != "no"
LIBADD+= casper

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 20, 1:16 AM (10 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23951695
Default Alt Text
D24566.id77994.diff (13 KB)

Event Timeline