summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libelf/ChangeLog28
-rw-r--r--libelf/Makefile.am8
-rw-r--r--libelf/abstract.h20
-rw-r--r--libelf/chdr_xlate.h33
-rw-r--r--libelf/elf32_getchdr.c83
-rw-r--r--libelf/elf64_getchdr.c30
-rw-r--r--libelf/elf_error.c20
-rw-r--r--libelf/elf_getdata.c20
-rw-r--r--libelf/exttypes.h4
-rw-r--r--libelf/gelf.h8
-rw-r--r--libelf/gelf_fsize.c1
-rw-r--r--libelf/gelf_getchdr.c69
-rw-r--r--libelf/gelf_xlate.c4
-rw-r--r--libelf/gelf_xlate.h1
-rw-r--r--libelf/libelf.h8
-rw-r--r--libelf/libelf.map7
-rw-r--r--libelf/libelfP.h5
-rw-r--r--tests/ChangeLog17
-rw-r--r--tests/Makefile.am11
-rw-r--r--tests/elfgetchdr.c124
-rw-r--r--tests/msg_tst.c5
-rwxr-xr-xtests/run-elfgetchdr.sh188
-rwxr-xr-xtests/testfile-zgabi32.bz2bin0 -> 767 bytes
-rwxr-xr-xtests/testfile-zgabi32be.bz2bin0 -> 769 bytes
-rwxr-xr-xtests/testfile-zgabi64.bz2bin0 -> 795 bytes
-rwxr-xr-xtests/testfile-zgabi64be.bz2bin0 -> 780 bytes
26 files changed, 676 insertions, 18 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index fbe8e3ae..2ed4a674 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,31 @@
+2015-11-19 Mark Wielaard <[email protected]>
+
+ * Makefile.am (libelf_a_SOURCES): Add elf32_getchdr.c,
+ elf64_getchdr.c and gelf_getchdr.c.
+ (noinst_HEADERS): Add chdr_xlate.h.
+ * abstract.h: Define Chdr32 and Chdr64.
+ * chdr_xlate.h: New file.
+ * elf32_getchdr.c: New file.
+ * elf64_getchdr.c: New file.
+ * elf_error.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+ and ELF_E_INVALID_SECTION_FLAGS.
+ * elf_getdata.c (__libelf_set_rawdata_wrlock): Set d_type to
+ ELF_T_CHDR for SHF_COMPRESSED sections.
+ * exttypes.h: Add Chdr32 and Chdr64.
+ * gelf.h (GElf_Chdr): New typedef.
+ (gelf_getchdr): New function definition.
+ * gelf_fsize.c (__libelf_type_sizes): Add ELF_T_CHDR.
+ * gelf_getchdr.c: New file.
+ * gelf_xlate.c (__elf_xfctstom): Add ELF_T_CHDR cvt_chdr.
+ * gelf_xlate.h: Add Chdr.
+ * libelf.h (Elf_Type): Add ELF_T_CHDR.
+ (elf32_getchdr): New function definition.
+ (elf64_getchdr): Likewise.
+ * libelf.map (ELFUTILS_1.7): New sections add elf32_getchdr,
+ elf64_getchdr and gelf_getchdr.
+ * libelfP.h: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+ and ELF_E_INVALID_SECTION_FLAGS.
+
2015-10-16 Mark Wielaard <[email protected]>
* Makefile.am (libelf_so_LDLIBS): Add -lz.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 4a4131c1..8a678b84 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
-## Copyright (C) 1996-2010 Red Hat, Inc.
+## Copyright (C) 1996-2010, 2015 Red Hat, Inc.
## This file is part of elfutils.
##
## This file is free software; you can redistribute it and/or modify
@@ -88,7 +88,8 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
elf32_offscn.c elf64_offscn.c gelf_offscn.c \
elf_getaroff.c \
elf_gnu_hash.c \
- elf_scnshndx.c
+ elf_scnshndx.c \
+ elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c
libelf_pic_a_SOURCES =
am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
@@ -118,7 +119,8 @@ uninstall: uninstall-am
rm -f $(DESTDIR)$(libdir)/libelf.so
noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
- version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h
+ version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h \
+ chdr_xlate.h
EXTRA_DIST = libelf.map
CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so.$(VERSION)
diff --git a/libelf/abstract.h b/libelf/abstract.h
index 53713eec..d4515f27 100644
--- a/libelf/abstract.h
+++ b/libelf/abstract.h
@@ -1,5 +1,5 @@
/* Abstract description of component ELF types.
- Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007, 2015 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 1998.
@@ -310,3 +310,21 @@ START (64, auxv_t, Ext##auxv_t) \
TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);) \
TYPE_EXTRA (} a_un;) \
END (64, Ext##auxv_t)
+
+/* Note that there is actual compression data right after the Chdr.
+ So we also have a separate conversion function for the whole
+ section. */
+#define Chdr32(Ext) \
+START (32, Chdr, Ext##Chdr) \
+ TYPE_NAME (ElfW2(32, Ext##Word), ch_type) \
+ TYPE_NAME (ElfW2(32, Ext##Word), ch_size) \
+ TYPE_NAME (ElfW2(32, Ext##Word), ch_addralign) \
+END (32, Ext##Chdr)
+
+#define Chdr64(Ext) \
+START (64, Chdr, Ext##Chdr) \
+ TYPE_NAME (ElfW2(64, Ext##Word), ch_type) \
+ TYPE_NAME (ElfW2(64, Ext##Word), ch_reserved) \
+ TYPE_NAME (ElfW2(64, Ext##Xword), ch_size) \
+ TYPE_NAME (ElfW2(64, Ext##Xword), ch_addralign) \
+END (64, Ext##Chdr)
diff --git a/libelf/chdr_xlate.h b/libelf/chdr_xlate.h
new file mode 100644
index 00000000..70782b43
--- /dev/null
+++ b/libelf/chdr_xlate.h
@@ -0,0 +1,33 @@
+#include "common.h"
+
+/* These functions convert a while section, one Chdr plus compression data. */
+
+static void
+Elf32_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+ if (len == 0)
+ return;
+
+ /* Move everything over, if necessary, we only need to xlate the
+ header, not the compressed data following it. */
+ if (dest != src)
+ memmove (dest, src, len);
+
+ if (len >= sizeof (Elf32_Chdr))
+ Elf32_cvt_Chdr (dest, src, sizeof (Elf32_Chdr), encode);
+}
+
+static void
+Elf64_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+ if (len == 0)
+ return;
+
+ /* Move everything over, if necessary, we only need to xlate the
+ header, not the compressed data following it. */
+ if (dest != src)
+ memmove (dest, src, len);
+
+ if (len >= sizeof (Elf64_Chdr))
+ Elf64_cvt_Chdr (dest, src, sizeof (Elf64_Chdr), encode);
+}
diff --git a/libelf/elf32_getchdr.c b/libelf/elf32_getchdr.c
new file mode 100644
index 00000000..982a614c
--- /dev/null
+++ b/libelf/elf32_getchdr.c
@@ -0,0 +1,83 @@
+/* Return section compression header.
+ Copyright (C) 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Chdr) *
+elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn)
+{
+ ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn);
+ if (shdr == NULL)
+ return NULL;
+
+ /* Must have SHF_COMPRESSED flag set. Allocated or no bits sections
+ can never be compressed. */
+ if ((shdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+ return NULL;
+ }
+
+ if (shdr->sh_type == SHT_NULL
+ || shdr->sh_type == SHT_NOBITS)
+ {
+ __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+ return NULL;
+ }
+
+ if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+ {
+ __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+ return NULL;
+ }
+
+ /* This makes sure the data is in the correct format, so we don't
+ need to swap fields. */
+ Elf_Data *d = elf_getdata (scn, NULL);
+ if (d == NULL)
+ return NULL;
+
+ if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL)
+ {
+ __libelf_seterrno (ELF_E_INVALID_DATA);
+ return NULL;
+ }
+
+ return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf;
+}
diff --git a/libelf/elf64_getchdr.c b/libelf/elf64_getchdr.c
new file mode 100644
index 00000000..6588b791
--- /dev/null
+++ b/libelf/elf64_getchdr.c
@@ -0,0 +1,30 @@
+/* Return section compression header.
+ Copyright (C) 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_getchdr.c"
diff --git a/libelf/elf_error.c b/libelf/elf_error.c
index d6bdaab0..d97e3bd6 100644
--- a/libelf/elf_error.c
+++ b/libelf/elf_error.c
@@ -230,6 +230,21 @@ core files")
(ELF_E_NO_PHDR_IDX \
+ sizeof "file has no program header")
N_("invalid offset")
+ "\0"
+#define ELF_E_INVALID_SECTION_TYPE_IDX \
+ (ELF_E_INVALID_OFFSET_IDX \
+ + sizeof "invalid offset")
+ N_("invalid section type")
+ "\0"
+#define ELF_E_INVALID_SECTION_FLAGS_IDX \
+ (ELF_E_INVALID_SECTION_TYPE_IDX \
+ + sizeof "invalid section type")
+ N_("invalid section flags")
+ "\0"
+#define ELF_E_NOT_COMPRESSED_IDX \
+ (ELF_E_INVALID_SECTION_FLAGS_IDX \
+ + sizeof "invalid section flags")
+ N_("section does not contain compressed data")
};
@@ -277,7 +292,10 @@ static const uint_fast16_t msgidx[ELF_E_NUM] =
[ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX,
[ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX,
[ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX,
- [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX
+ [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX,
+ [ELF_E_INVALID_SECTION_TYPE] = ELF_E_INVALID_SECTION_TYPE_IDX,
+ [ELF_E_INVALID_SECTION_FLAGS] = ELF_E_INVALID_SECTION_FLAGS_IDX,
+ [ELF_E_NOT_COMPRESSED] = ELF_E_NOT_COMPRESSED_IDX
};
#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 9a567e51..bd1f0682 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -106,6 +106,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
[ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \
[ELF_T_GNUHASH] = __alignof__ (Elf32_Word), \
[ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \
+ [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)), \
}
[EV_CURRENT - 1] =
{
@@ -204,6 +205,7 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
Elf64_Off offset;
Elf64_Xword size;
Elf64_Xword align;
+ Elf64_Xword flags;
int type;
Elf *elf = scn->elf;
@@ -220,6 +222,7 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
size = shdr->sh_size;
type = shdr->sh_type;
align = shdr->sh_addralign;
+ flags = shdr->sh_flags;
}
else
{
@@ -234,6 +237,7 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
size = shdr->sh_size;
type = shdr->sh_type;
align = shdr->sh_addralign;
+ flags = shdr->sh_flags;
}
/* If the section has no data (for whatever reason), leave the `d_buf'
@@ -243,7 +247,10 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
/* First a test whether the section is valid at all. */
size_t entsize;
- if (type == SHT_HASH)
+ /* Compressed data has a header, but then compressed data. */
+ if ((flags & SHF_COMPRESSED) != 0)
+ entsize = 1;
+ else if (type == SHT_HASH)
{
GElf_Ehdr ehdr_mem;
GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
@@ -320,10 +327,15 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
}
scn->rawdata.d.d_size = size;
- /* Some broken ELF ABI for 64-bit machines use the wrong hash table
- entry size. See elf-knowledge.h for more information. */
- if (type == SHT_HASH && elf->class == ELFCLASS64)
+
+ /* Compressed data always has type ELF_T_CHDR regardless of the
+ section type. */
+ if ((flags & SHF_COMPRESSED) != 0)
+ scn->rawdata.d.d_type = ELF_T_CHDR;
+ else if (type == SHT_HASH && elf->class == ELFCLASS64)
{
+ /* Some broken ELF ABI for 64-bit machines use the wrong hash table
+ entry size. See elf-knowledge.h for more information. */
GElf_Ehdr ehdr_mem;
GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
scn->rawdata.d.d_type
diff --git a/libelf/exttypes.h b/libelf/exttypes.h
index 8cb2aaec..7bacd654 100644
--- a/libelf/exttypes.h
+++ b/libelf/exttypes.h
@@ -1,5 +1,5 @@
/* External ELF types.
- Copyright (C) 1998-2010 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2015 Red Hat, Inc.
This file is part of elfutils.
Contributed by Ulrich Drepper <[email protected]>, 1998.
@@ -75,6 +75,7 @@ Syminfo32 (Ext_);
Move32 (Ext_);
Lib32 (Ext_);
auxv_t32 (Ext_);
+Chdr32 (Ext_);
Ehdr64 (Ext_);
Phdr64 (Ext_);
@@ -92,6 +93,7 @@ Syminfo64 (Ext_);
Move64 (Ext_);
Lib64 (Ext_);
auxv_t64 (Ext_);
+Chdr64 (Ext_);
#undef START
#undef END
diff --git a/libelf/gelf.h b/libelf/gelf.h
index e3f07404..1bc7ee72 100644
--- a/libelf/gelf.h
+++ b/libelf/gelf.h
@@ -1,5 +1,5 @@
/* This file defines generic ELF types, structures, and macros.
- Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007 Red Hat, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -85,6 +85,9 @@ typedef Elf64_Rela GElf_Rela;
/* Program segment header. */
typedef Elf64_Phdr GElf_Phdr;
+/* Header of a compressed section. */
+typedef Elf64_Chdr GElf_Chdr;
+
/* Dynamic section entry. */
typedef Elf64_Dyn GElf_Dyn;
@@ -183,6 +186,9 @@ extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src);
/* Create new program header with PHNUM entries. */
extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum);
+/* Get compression header of section if any. Returns NULL and sets
+ elf_errno if the section isn't compressed or an error occurred. */
+extern GElf_Chdr *gelf_getchdr (Elf_Scn *__scn, GElf_Chdr *__dst);
/* Convert data structure from the representation in the file represented
by ELF to their memory representation. */
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index a124fa84..0c509265 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -68,6 +68,7 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
[ELF_T_MOVE] = sizeof (ElfW2(LIBELFBITS, Ext_Move)), \
[ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \
[ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \
+ [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \
[ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD)
TYPE_SIZES (32)
},
diff --git a/libelf/gelf_getchdr.c b/libelf/gelf_getchdr.c
new file mode 100644
index 00000000..394bf4b3
--- /dev/null
+++ b/libelf/gelf_getchdr.c
@@ -0,0 +1,69 @@
+/* Return section compression header.
+ Copyright (C) 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+#include <gelf.h>
+#include <stddef.h>
+
+
+GElf_Chdr *
+gelf_getchdr (Elf_Scn *scn, GElf_Chdr *dest)
+{
+ if (scn == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ __libelf_seterrno (ELF_E_INVALID_OPERAND);
+ return NULL;
+ }
+
+ if (scn->elf->class == ELFCLASS32)
+ {
+ Elf32_Chdr *chdr = elf32_getchdr (scn);
+ if (chdr == NULL)
+ return NULL;
+ dest->ch_type = chdr->ch_type;
+ dest->ch_size = chdr->ch_size;
+ dest->ch_addralign = chdr->ch_addralign;
+ }
+ else
+ {
+ Elf64_Chdr *chdr = elf64_getchdr (scn);
+ if (chdr == NULL)
+ return NULL;
+ *dest = *chdr;
+ }
+
+ return dest;
+}
+INTDEF(gelf_getchdr)
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
index c5805e73..f3d3b7a0 100644
--- a/libelf/gelf_xlate.c
+++ b/libelf/gelf_xlate.c
@@ -166,6 +166,7 @@ union unaligned
#include "version_xlate.h"
#include "gnuhash_xlate.h"
#include "note_xlate.h"
+#include "chdr_xlate.h"
/* Now the externally visible table with the function pointers. */
@@ -198,7 +199,8 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo), \
[ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \
[ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \
- [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t)
+ [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t), \
+ [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr)
define_xfcts (32),
[ELF_T_GNUHASH] = Elf32_cvt_Word
},
diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h
index f11eb90b..3c0e4bf6 100644
--- a/libelf/gelf_xlate.h
+++ b/libelf/gelf_xlate.h
@@ -50,6 +50,7 @@ TYPE (Syminfo, LIBELFBITS)
TYPE (Move, LIBELFBITS)
TYPE (Lib, LIBELFBITS)
TYPE (auxv_t, LIBELFBITS)
+TYPE (Chdr, LIBELFBITS)
/* Prepare for the next round. */
diff --git a/libelf/libelf.h b/libelf/libelf.h
index 54f7c29b..49234c8a 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -1,5 +1,5 @@
/* Interface for libelf.
- Copyright (C) 1998-2010 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -64,6 +64,7 @@ typedef enum
ELF_T_LIB, /* Elf32_Lib, Elf64_Lib, ... */
ELF_T_GNUHASH, /* GNU-style hash section. */
ELF_T_AUXV, /* Elf32_auxv_t, Elf64_auxv_t, ... */
+ ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
/* Keep this the last entry. */
ELF_T_NUM
} Elf_Type;
@@ -267,6 +268,11 @@ extern Elf32_Shdr *elf32_getshdr (Elf_Scn *__scn);
/* Similar for ELFCLASS64. */
extern Elf64_Shdr *elf64_getshdr (Elf_Scn *__scn);
+/* Returns compression header for a section if section data is
+ compressed. Returns NULL and sets elf_errno if the section isn't
+ compressed or an error occurred. */
+extern Elf32_Chdr *elf32_getchdr (Elf_Scn *__scn);
+extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn);
/* Set or clear flags for ELF file. */
extern unsigned int elf_flagelf (Elf *__elf, Elf_Cmd __cmd,
diff --git a/libelf/libelf.map b/libelf/libelf.map
index de6d912a..d402ccc0 100644
--- a/libelf/libelf.map
+++ b/libelf/libelf.map
@@ -138,3 +138,10 @@ ELFUTILS_1.6 {
global:
elf_getphdrnum;
} ELFUTILS_1.5;
+
+ELFUTILS_1.7 {
+ global:
+ elf32_getchdr;
+ elf64_getchdr;
+ gelf_getchdr;
+} ELFUTILS_1.6; \ No newline at end of file
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 993c6556..8ff8478c 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998-2010 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2015 Red Hat, Inc.
This file is part of elfutils.
Contributed by Ulrich Drepper <[email protected]>, 1998.
@@ -138,6 +138,9 @@ enum
ELF_E_INVALID_PHDR,
ELF_E_NO_PHDR,
ELF_E_INVALID_OFFSET,
+ ELF_E_INVALID_SECTION_TYPE,
+ ELF_E_INVALID_SECTION_FLAGS,
+ ELF_E_NOT_COMPRESSED,
/* Keep this as the last entry. */
ELF_E_NUM
};
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 5afe4bd2..7096f9f9 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,22 @@
2015-10-28 Mark Wielaard <[email protected]>
+ * elfgetchdr.c: New file.
+ * run-elfgetchdr.sh: New test.
+ * testfile-zgabi32.bz2: New testfile.
+ * testfile-zgabi32be.bz2: Likewise.
+ * testfile-zgabi64.bz2: Likewise.
+ * testfile-zgabi64be.bz2: Likewise.
+ * Makefile.am (check_PROGRAMS): Add elfgetchdr.
+ (TESTS): Add run-elfgetchdr.sh.
+ (EXTRA_DIST): Add run-elfgetchdr.sh, testfile-zgabi32.bz2,
+ testfile-zgabi32be.bz2, testfile-zgabi64.bz2, testfile-zgabi64be.bz2.
+ (welfgetchdr_LDADD): New variable.
+ * msg_tst.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+ and ELF_E_INVALID_SECTION_FLAGS,
+
+
+2015-10-28 Mark Wielaard <[email protected]>
+
* dwelfgnucompressed.c: New file.
* run-dwelfgnucompressed.sh: New test.
* testfile-zgnu32.bz2: New testfile.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8e2f2833..2528e1c0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -52,7 +52,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
backtrace-data backtrace-dwarf debuglink debugaltlink \
buildid deleted deleted-lib.so aggregate_size vdsosyms \
getsrc_die strptr newdata elfstrtab dwfl-proc-attach \
- elfshphehdr elfstrmerge dwelfgnucompressed
+ elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr
asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -120,7 +120,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh \
run-linkmap-cut.sh run-aggregate-size.sh vdsosyms run-readelf-A.sh \
run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \
- elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh
+ elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh \
+ run-elfgetchdr.sh
if !BIARCH
export ELFUTILS_DISABLE_BIARCH = 1
@@ -309,7 +310,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-lfs-symbols.sh lfs-symbols testfile-nolfs.bz2 \
testfile-zgnu32.bz2 testfile-zgnu64.bz2 \
testfile-zgnu32be.bz2 testfile-zgnu64be.bz2 \
- run-dwelfgnucompressed.sh
+ run-dwelfgnucompressed.sh \
+ testfile-zgabi32.bz2 testfile-zgabi64.bz2 \
+ testfile-zgabi32be.bz2 testfile-zgabi64be.bz2 \
+ run-elfgetchdr.sh
if USE_VALGRIND
valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
@@ -459,6 +463,7 @@ dwfl_proc_attach_LDFLAGS = -pthread $(AM_LDFLAGS)
elfshphehdr_LDADD =$(libelf)
elfstrmerge_LDADD = $(libebl) $(libelf)
dwelfgnucompressed_LDADD = $(libelf) $(libdw)
+elfgetchdr_LDADD = $(libelf) $(libdw)
if GCOV
check: check-am coverage
diff --git a/tests/elfgetchdr.c b/tests/elfgetchdr.c
new file mode 100644
index 00000000..44ba1789
--- /dev/null
+++ b/tests/elfgetchdr.c
@@ -0,0 +1,124 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include ELFUTILS_HEADER(elf)
+#include ELFUTILS_HEADER(dwelf)
+#include <gelf.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ int result = 0;
+ int cnt;
+
+ elf_version (EV_CURRENT);
+
+ for (cnt = 1; cnt < argc; ++cnt)
+ {
+ int fd = open (argv[cnt], O_RDONLY);
+
+ Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+ if (elf == NULL)
+ {
+ printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
+ result = 1;
+ close (fd);
+ continue;
+ }
+
+ size_t shdrstrndx;
+ if (elf_getshdrstrndx (elf, &shdrstrndx) == -1)
+ {
+ printf ("elf_getshdrstrnd failed %s\n", elf_errmsg (-1));
+ result = 1;
+ close (fd);
+ continue;
+ }
+
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ int idx = elf_ndxscn (scn);
+ GElf_Shdr shdr;
+ if (gelf_getshdr (scn, &shdr) == NULL)
+ {
+ printf ("gelf_getshdr failed: %s\n", elf_errmsg (-1));
+ result = 1;
+ break;
+ }
+
+ if ((shdr.sh_flags & SHF_COMPRESSED) != 0)
+ {
+ GElf_Chdr chdr;
+ if (gelf_getchdr (scn, &chdr) == NULL)
+ {
+ printf ("gelf_getchdr failed: %s\n", elf_errmsg (-1));
+ result = 1;
+ break;
+ }
+
+ printf ("section %d: ELF Compressed ch_type: %" PRId32
+ ", ch_size: %" PRIx64 ", ch_addralign: %" PRIx64 "\n",
+ idx, chdr.ch_type, chdr.ch_size, chdr.ch_addralign);
+ }
+ else
+ {
+ const char *sname = elf_strptr (elf, shdrstrndx, shdr.sh_name);
+ if (sname == NULL)
+ {
+ printf ("couldn't get section name: %s\n", elf_errmsg (-1));
+ result = 1;
+ break;
+ }
+
+ /* This duplicates what the dwelfgnucompressed testcase does. */
+ if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
+ {
+ ssize_t size;
+ if ((size = dwelf_scn_gnu_compressed_size (scn)) == -1)
+ {
+ printf ("dwelf_scn_gnu_compressed_size failed: %s\n",
+ elf_errmsg (-1));
+ result = 1;
+ break;
+ }
+ printf ("section %d: GNU Compressed size: %zx\n", idx, size);
+ }
+ else
+ printf ("section %d: NOT Compressed\n", idx);
+ }
+ }
+
+ elf_end (elf);
+ close (fd);
+ }
+
+ return result;
+}
diff --git a/tests/msg_tst.c b/tests/msg_tst.c
index 10ff0f73..539c5ddb 100644
--- a/tests/msg_tst.c
+++ b/tests/msg_tst.c
@@ -74,7 +74,10 @@ static struct
"program header only allowed in executables, shared objects, \
and core files" },
{ ELF_E_NO_PHDR, "file has no program header" },
- { ELF_E_INVALID_OFFSET, "invalid offset" }
+ { ELF_E_INVALID_OFFSET, "invalid offset" },
+ { ELF_E_INVALID_SECTION_TYPE , "invalid section type" },
+ { ELF_E_INVALID_SECTION_FLAGS , "invalid section flags" },
+ { ELF_E_NOT_COMPRESSED, "section does not contain compressed data" }
};
diff --git a/tests/run-elfgetchdr.sh b/tests/run-elfgetchdr.sh
new file mode 100755
index 00000000..7a422f39
--- /dev/null
+++ b/tests/run-elfgetchdr.sh
@@ -0,0 +1,188 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# = funcs.s =
+# .globl testfunc
+# testfunc:
+# nop
+# ret
+# .type testfunc, @function
+# .size testfunc, .-testfunc
+#
+# .globl testfunc2
+# testfunc2:
+# call testfunc
+# nop
+# nop
+# ret
+# .type testfunc2, @function
+# .size testfunc2, .-testfunc2
+#
+# .globl functest3
+# functest3:
+# jmp local
+# nop
+# nop
+# local:
+# call testfunc2
+# ret
+# .type functest3, @function
+# .size functest3, .-functest3
+
+# = start.s =
+# .global _start
+# _start:
+# call functest3
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# nop
+# ret
+# .type _start, @function
+# .size _start, .-_start
+
+# gas --compress-debug-sections=zlib-gnu -32 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -32 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -melf_i386 -g -o zgnu32 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gnu -64 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -64 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -g -o zgnu64 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gabi -32 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gabi -32 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gabi -melf_i386 -g -o zgabi32 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gabi -64 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gabi -64 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gabi -g -o zgabi64 funcs.o start.o
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu64 <<\EOF
+section 1: NOT Compressed
+section 2: GNU Compressed size: 60
+section 3: GNU Compressed size: aa
+section 4: NOT Compressed
+section 5: GNU Compressed size: 8d
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgabi64
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi64 <<\EOF
+section 1: NOT Compressed
+section 2: ELF Compressed ch_type: 1, ch_size: 60, ch_addralign: 10
+section 3: ELF Compressed ch_type: 1, ch_size: aa, ch_addralign: 1
+section 4: NOT Compressed
+section 5: ELF Compressed ch_type: 1, ch_size: 8d, ch_addralign: 1
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu32 <<\EOF
+section 1: NOT Compressed
+section 2: GNU Compressed size: 40
+section 3: GNU Compressed size: 9a
+section 4: NOT Compressed
+section 5: GNU Compressed size: 85
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgabi32
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi32 <<\EOF
+section 1: NOT Compressed
+section 2: ELF Compressed ch_type: 1, ch_size: 40, ch_addralign: 8
+section 3: ELF Compressed ch_type: 1, ch_size: 9a, ch_addralign: 1
+section 4: NOT Compressed
+section 5: ELF Compressed ch_type: 1, ch_size: 85, ch_addralign: 1
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgnu64be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu64be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: GNU Compressed size: 60
+section 4: GNU Compressed size: 7e
+section 5: NOT Compressed
+section 6: GNU Compressed size: 8d
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgabi64be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi64be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: ELF Compressed ch_type: 1, ch_size: 60, ch_addralign: 10
+section 4: ELF Compressed ch_type: 1, ch_size: 7e, ch_addralign: 1
+section 5: NOT Compressed
+section 6: ELF Compressed ch_type: 1, ch_size: 8d, ch_addralign: 1
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgnu32be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu32be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: GNU Compressed size: 40
+section 4: GNU Compressed size: 6e
+section 5: NOT Compressed
+section 6: GNU Compressed size: 85
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgabi32be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi32be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: ELF Compressed ch_type: 1, ch_size: 40, ch_addralign: 8
+section 4: ELF Compressed ch_type: 1, ch_size: 6e, ch_addralign: 1
+section 5: NOT Compressed
+section 6: ELF Compressed ch_type: 1, ch_size: 85, ch_addralign: 1
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+exit 0
diff --git a/tests/testfile-zgabi32.bz2 b/tests/testfile-zgabi32.bz2
new file mode 100755
index 00000000..6159dbce
--- /dev/null
+++ b/tests/testfile-zgabi32.bz2
Binary files differ
diff --git a/tests/testfile-zgabi32be.bz2 b/tests/testfile-zgabi32be.bz2
new file mode 100755
index 00000000..f1f5eb5c
--- /dev/null
+++ b/tests/testfile-zgabi32be.bz2
Binary files differ
diff --git a/tests/testfile-zgabi64.bz2 b/tests/testfile-zgabi64.bz2
new file mode 100755
index 00000000..3b44f089
--- /dev/null
+++ b/tests/testfile-zgabi64.bz2
Binary files differ
diff --git a/tests/testfile-zgabi64be.bz2 b/tests/testfile-zgabi64be.bz2
new file mode 100755
index 00000000..d819ae3d
--- /dev/null
+++ b/tests/testfile-zgabi64be.bz2
Binary files differ