summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChih-hung Hsieh <chh@google.com>2015-10-09 18:39:18 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-10-09 18:39:18 +0000
commit495820301403545dee86eadbc2198d63765d06a3 (patch)
tree40ae3959ffe2abac7ce87f49186787648dee3101
parent5e22dcc417102da5c05f8c5b98b9b617cdbf7b20 (diff)
parent322dc30a675af1bf85103c43d48368af0be38927 (diff)
downloadandroid_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.tar.gz
android_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.tar.bz2
android_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.zip
Merge "Merge upstream commit '86ed7f7'."
-rw-r--r--ChangeLog5
-rw-r--r--backends/ChangeLog10
-rw-r--r--backends/Makefile.am6
-rw-r--r--backends/sparc_attrs.c75
-rw-r--r--backends/sparc_init.c1
-rw-r--r--config/ChangeLog9
-rw-r--r--config/eu.am4
-rw-r--r--configure.ac2
-rw-r--r--lib/ChangeLog5
-rw-r--r--lib/Makefile.am2
-rw-r--r--libasm/ChangeLog4
-rw-r--r--libasm/Makefile.am4
-rw-r--r--libcpu/ChangeLog11
-rw-r--r--libcpu/Makefile.am12
-rw-r--r--libdw/ChangeLog9
-rw-r--r--libdw/Makefile.am6
-rw-r--r--libdwfl/ChangeLog20
-rw-r--r--libdwfl/dwfl_module_getdwarf.c63
-rw-r--r--libdwfl/dwfl_segment_report_module.c70
-rw-r--r--libdwfl/elf-from-memory.c49
-rw-r--r--libdwfl/link_map.c87
-rw-r--r--libebl/ChangeLog5
-rw-r--r--libebl/Makefile.am2
-rw-r--r--libelf/ChangeLog14
-rw-r--r--libelf/Makefile.am6
-rw-r--r--libelf/elf_getarsym.c14
-rw-r--r--src/ChangeLog20
-rw-r--r--src/Makefile.am10
-rw-r--r--src/readelf.c26
-rw-r--r--src/unstrip.c25
-rw-r--r--tests/ChangeLog4
-rw-r--r--tests/Makefile.am2
32 files changed, 388 insertions, 194 deletions
diff --git a/ChangeLog b/ChangeLog
index afa5905a..b7e69e09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * configure.ac: Use -fPIC instead of -fpic to avoid relocation
+ overflows in some platforms.
+
2015-07-11 Pino Toscano <toscano.pino@tiscali.it>
* .gitignore: Add more generated files, and anchor some of the
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 60c6b72f..e6f37633 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,13 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (libebl_%.so): Add AM_V_at and AM_V_CCLD silencers.
+
+2015-10-06 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * sparc_attrs.c: New file.
+ * Makefile.am (sparc_SRCS): Added sparc_attrs.c
+ * sparc_init.c (sparc_init): Hook sparc_check_object_attribute.
+
2015-10-02 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc_init.c (RELOC_TYPE_ID): Defined.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 21d7bd24..f7002fb5 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -84,7 +84,7 @@ libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS)
am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os)
sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c \
- sparc_corenote.c sparc64_corenote.c sparc_auxv.c
+ sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c
libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
@@ -114,9 +114,9 @@ am_libebl_tilegx_pic_a_OBJECTS = $(tilegx_SRCS:.c=.os)
libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
@rm -f $(@:.so=.map)
- echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
+ $(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
> $(@:.so=.map)
- $(LINK) -shared -o $(@:.map=.so) \
+ $(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-Wl,--version-script,$(@:.so=.map) \
-Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
diff --git a/backends/sparc_attrs.c b/backends/sparc_attrs.c
new file mode 100644
index 00000000..e95b577b
--- /dev/null
+++ b/backends/sparc_attrs.c
@@ -0,0 +1,75 @@
+/* Object attribute tags for SPARC.
+ Copyright (C) 2015 Oracle, 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 <string.h>
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+bool
+sparc_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+ const char *vendor, int tag, uint64_t value,
+ const char **tag_name, const char **value_name)
+{
+ if (!strcmp (vendor, "gnu"))
+ switch (tag)
+ {
+ case 4:
+ *tag_name = "GNU_Sparc_HWCAPS";
+ static const char *hwcaps[30] =
+ {
+ "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
+ "asi_blk_init", "fmaf", NULL, "vis3", "hpc", "random", "trans", "fjfmau",
+ "ima", "asi_cache_sparing", "aes", "des", "kasumi", "camellia",
+ "md5", "sha1", "sha256", "sha512", "mpmul", "mont", "pause",
+ "cbcond", "crc32c"
+ };
+ if (value < 30 && hwcaps[value] != NULL)
+ *value_name = hwcaps[value];
+ return true;
+
+ case 8:
+ *tag_name = "GNU_Sparc_HWCAPS2";
+ static const char *hwcaps2[11] =
+ {
+ "fjathplus", "vis3b", "adp", "sparc5", "mwait", "xmpmul",
+ "xmont", "nsec", "fjathhpc", "fjdes", "fjaes"
+ };
+ if (value < 11)
+ *value_name = hwcaps2[value];
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/backends/sparc_init.c b/backends/sparc_init.c
index 229a9b08..f8a7cfbd 100644
--- a/backends/sparc_init.c
+++ b/backends/sparc_init.c
@@ -75,6 +75,7 @@ sparc_init (Elf *elf __attribute__ ((unused)),
HOOK (eh, auxv_info);
HOOK (eh, register_info);
HOOK (eh, return_value_location);
+ HOOK (eh, check_object_attribute);
return MODVERSION;
}
diff --git a/config/ChangeLog b/config/ChangeLog
index 067af115..ba5cb387 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,12 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * eu.am (%.os): Add AM_V_CC silencers.
+
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * eu.am (%.os): Use -fPIC instead of -fpic to avoid relocation
+ overflows in some platforms.
+
2015-09-22 Mark Wielaard <mjw@redhat.com>
* eu.am (AM_CFLAGS): Add -Wold-style-definition -Wstrict-prototypes.
diff --git a/config/eu.am b/config/eu.am
index 441b68dd..6ad8f822 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -55,14 +55,14 @@ endif
%.os: %.c %.o
if AMDEP
- if $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) -MT $@ -MD -MP \
+ $(AM_V_CC)if $(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) -MT $@ -MD -MP \
-MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
rm -f "$(DEPDIR)/$*.Tpo"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
else
- $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) $<
+ $(AM_V_CC)$(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) $<
endif
CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index 9c47a688..fe2795e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,7 +111,7 @@ AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl
# Some old compiler/linker/libc combinations fail some ways and not others.
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
-CFLAGS="-fpic $CFLAGS"
+CFLAGS="-fPIC $CFLAGS"
LDFLAGS="-shared -Wl,-z,defs,-z,relro $LDFLAGS"
AC_LINK_IFELSE([dnl
AC_LANG_PROGRAM([[#include <stdlib.h>
diff --git a/lib/ChangeLog b/lib/ChangeLog
index d1bdc7bc..76b5753d 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid relocation
+ overflows in some platforms.
+
2015-09-22 Mark Wielaard <mjw@redhat.com>
* dynamicsizehash.c: Remove old-style function definitions.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 97f295eb..2219eaa4 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -28,7 +28,7 @@
## not, see <http://www.gnu.org/licenses/>.
##
include $(top_srcdir)/config/eu.am
-AM_CFLAGS += -fpic
+AM_CFLAGS += -fPIC
AM_CPPFLAGS += -I$(srcdir)/../libelf
noinst_LIBRARIES = libeu.a
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 7433cb72..beb6211c 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (libasm.so): Add AM_V_CCLD and AM_V_at silencers.
+
2015-09-23 Mark Wielaard <mjw@redhat.com>
* asm_align.c (__libasm_ensure_section_space): Mark as
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 6ea2a8e8..a4bf293a 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -62,12 +62,12 @@ endif
libasm_so_SOURCES =
libasm.so$(EXEEXT): libasm_pic.a libasm.map
- $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+ $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
-Wl,--soname,$@.$(VERSION) \
../libebl/libebl.a ../libelf/libelf.so $(libasm_so_LDLIBS)
@$(textrel_check)
- ln -fs $@ $@.$(VERSION)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
install: install-am libasm.so
$(mkinstalldirs) $(DESTDIR)$(libdir)
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index a20f4407..c953c7b3 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,3 +1,14 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (%_defs): Add AM_V_GEN and AM_V_at silencers.
+ ($(srcdir)/%_dis.h): Ditto.
+ (%.mnemonics): Add AM_V_GEN silencer.
+
+2014-10-29 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+ relocation overflows in some platforms.
+
2014-04-13 Mark Wielaard <mjw@redhat.com>
* Makefile.am (i386_gendis_LDADD): Remove libmudflap.
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index 3beccf34..f0caaea6 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -30,7 +30,7 @@
include $(top_srcdir)/config/eu.am
AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
-I$(srcdir)/../libdw -I$(srcdir)/../libasm
-AM_CFLAGS += -fpic -fdollars-in-identifiers
+AM_CFLAGS += -fPIC -fdollars-in-identifiers
LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$(<F:lex.l=)
LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
AM_YFLAGS = -p$(<F:parse.y=)
@@ -46,8 +46,8 @@ i386_disasm.o: i386.mnemonics $(srcdir)/i386_dis.h
x86_64_disasm.o: x86_64.mnemonics $(srcdir)/x86_64_dis.h
%_defs: $(srcdir)/defs/i386
- m4 -D$* -DDISASSEMBLER $< > $@T
- mv -f $@T $@
+ $(AM_V_GEN)m4 -D$* -DDISASSEMBLER $< > $@T
+ $(AM_V_at)mv -f $@T $@
if MAINTAINER_MODE
noinst_HEADERS = memory-access.h i386_parse.h i386_data.h
@@ -55,8 +55,8 @@ noinst_HEADERS = memory-access.h i386_parse.h i386_data.h
noinst_PROGRAMS = i386_gendis
$(srcdir)/%_dis.h: %_defs i386_gendis
- ./i386_gendis $< > $@T
- mv -f $@T $@
+ $(AM_V_GEN)./i386_gendis $< > $@T
+ $(AM_V_at)mv -f $@T $@
else
@@ -67,7 +67,7 @@ $(srcdir)/%_dis.h:
endif
%.mnemonics: %_defs
- sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \
+ $(AM_V_GEN)sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \
$< | sort -u > $@
i386_lex_no_Werror = yes
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 5a026d87..efe6ccb8 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (libdw.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+ relocation overflows in some platforms.
+
2015-09-23 Mark Wielaard <mjw@redhat.com>
* dwarf_error.c (__libdw_seterrno): Mark as internal_function.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 2299b2fa..2da0db67 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -29,7 +29,7 @@
##
include $(top_srcdir)/config/eu.am
if BUILD_STATIC
-AM_CFLAGS += -fpic
+AM_CFLAGS += -fPIC
endif
AM_CPPFLAGS += -I$(srcdir)/../libelf
VERSION = 1
@@ -108,13 +108,13 @@ libdw.so$(EXEEXT): $(srcdir)/libdw.map libdw_pic.a ../libdwelf/libdwelf_pic.a \
../libelf/libelf.so
# The rpath is necessary for libebl because its $ORIGIN use will
# not fly in a setuid executable that links in libdw.
- $(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+ $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
-ldl $(argp_LDADD) $(zip_LIBS)
@$(textrel_check)
- ln -fs $@ $@.$(VERSION)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
install: install-am libdw.so
$(mkinstalldirs) $(DESTDIR)$(libdir)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ed1156ef..ee41405e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,23 @@
+2015-10-07 Mark Wielaard <mjw@redhat.com>
+
+ * dwfl_module_getdwarf.c (MAX): Removed.
+ (find_prelink_address_sync): Allocate exact amount of bytes for
+ phdrs and shdrs.
+ * dwfl_segment_report_module.c (dwfl_segment_report_module):
+ Likewise for phdrs.
+ * elf-from-memory.c (MAX): Removed.
+ (elf_from_remote_memory): Allocate exact amount of bytes for phdrs.
+
+2015-10-05 Chih-Hung Hsieh <chh@google.com>
+
+ * dwfl_module_getdwarf.c (find_prelink_address_sync): Do not use
+ union of variable length arrays.
+ * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise.
+ * elf-from-memory.c (elf_from_remote_memory): Likewise.
+ * link_map.c (auxv_format_probe): Likewise.
+ * link_map.c (report_r_debug): Likewise.
+ * link_map.c (dwfl_link_map_report): Likewise.
+
2015-09-18 Chih-Hung Hsieh <chh@google.com>
* relocate.c (relocate_section): Move nested function "relocate"
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index dba9d664..a3590577 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -367,38 +367,40 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
src.d_size = phnum * phentsize;
GElf_Addr undo_interp = 0;
+ bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
{
- typedef union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdr;
- phdr *phdrs = malloc (sizeof (phdr));
+ size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+ if (unlikely (phnum > SIZE_MAX / phdr_size))
+ return DWFL_E_NOMEM;
+ const size_t phdrs_bytes = phnum * phdr_size;
+ void *phdrs = malloc (phdrs_bytes);
if (unlikely (phdrs == NULL))
return DWFL_E_NOMEM;
dst.d_buf = phdrs;
- dst.d_size = sizeof (phdr);
+ dst.d_size = phdrs_bytes;
if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
ehdr.e32.e_ident[EI_DATA]) == NULL))
{
free (phdrs);
return DWFL_E_LIBELF;
}
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+ if (class32)
{
+ Elf32_Phdr (*p32)[phnum] = phdrs;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_INTERP)
+ if ((*p32)[i].p_type == PT_INTERP)
{
- undo_interp = phdrs->p32[i].p_vaddr;
+ undo_interp = (*p32)[i].p_vaddr;
break;
}
}
else
{
+ Elf64_Phdr (*p64)[phnum] = phdrs;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_INTERP)
+ if ((*p64)[i].p_type == PT_INTERP)
{
- undo_interp = phdrs->p64[i].p_vaddr;
+ undo_interp = (*p64)[i].p_vaddr;
break;
}
}
@@ -412,16 +414,15 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
src.d_type = ELF_T_SHDR;
src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
- typedef union
- {
- Elf32_Shdr s32[shnum - 1];
- Elf64_Shdr s64[shnum - 1];
- } shdr;
- shdr *shdrs = malloc (sizeof (shdr));
+ size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
+ if (unlikely (shnum - 1 > SIZE_MAX / shdr_size))
+ return DWFL_E_NOMEM;
+ const size_t shdrs_bytes = (shnum - 1) * shdr_size;
+ void *shdrs = malloc (shdrs_bytes);
if (unlikely (shdrs == NULL))
return DWFL_E_NOMEM;
dst.d_buf = shdrs;
- dst.d_size = sizeof (shdr);
+ dst.d_size = shdrs_bytes;
if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
ehdr.e32.e_ident[EI_DATA]) == NULL))
{
@@ -482,16 +483,22 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
mod->main.address_sync = highest;
highest = 0;
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
- for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdrs->s32[i].sh_type,
- shdrs->s32[i].sh_flags, shdrs->s32[i].sh_addr,
- shdrs->s32[i].sh_size);
+ if (class32)
+ {
+ Elf32_Shdr (*s32)[shnum - 1] = shdrs;
+ for (size_t i = 0; i < shnum - 1; ++i)
+ consider_shdr (undo_interp, (*s32)[i].sh_type,
+ (*s32)[i].sh_flags, (*s32)[i].sh_addr,
+ (*s32)[i].sh_size);
+ }
else
- for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdrs->s64[i].sh_type,
- shdrs->s64[i].sh_flags, shdrs->s64[i].sh_addr,
- shdrs->s64[i].sh_size);
+ {
+ Elf64_Shdr (*s64)[shnum - 1] = shdrs;
+ for (size_t i = 0; i < shnum - 1; ++i)
+ consider_shdr (undo_interp, (*s64)[i].sh_type,
+ (*s64)[i].sh_flags, (*s64)[i].sh_addr,
+ (*s64)[i].sh_size);
+ }
if (highest > file->vaddr)
file->address_sync = highest;
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index a0f07ada..ca86c311 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -53,6 +53,10 @@
# define MY_ELFDATA ELFDATA2MSB
#endif
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
/* Return user segment index closest to ADDR but not above it.
If NEXT, return the closest to ADDR but not below it. */
@@ -404,19 +408,17 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
xlatefrom.d_buf = ph_buffer;
- typedef union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrsn;
-
- phdrsp = malloc (sizeof (phdrsn));
+ bool class32 = ei_class == ELFCLASS32;
+ size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+ if (unlikely (phnum > SIZE_MAX / phdr_size))
+ return finish ();
+ const size_t phdrsp_bytes = phnum * phdr_size;
+ phdrsp = malloc (phdrsp_bytes);
if (unlikely (phdrsp == NULL))
return finish ();
- phdrsn *phdrs = (phdrsn *) phdrsp;
- xlateto.d_buf = phdrs;
- xlateto.d_size = sizeof (phdrsn);
+ xlateto.d_buf = phdrsp;
+ xlateto.d_size = phdrsp_bytes;
/* Track the bounds of the file visible in memory. */
GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
@@ -573,16 +575,19 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
break;
}
}
+
+ Elf32_Phdr (*p32)[phnum] = phdrsp;
+ Elf64_Phdr (*p64)[phnum] = phdrsp;
if (ei_class == ELFCLASS32)
{
if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
found_bias = false; /* Trigger error check. */
else
for (uint_fast16_t i = 0; i < phnum; ++i)
- consider_phdr (phdrs->p32[i].p_type,
- phdrs->p32[i].p_vaddr, phdrs->p32[i].p_memsz,
- phdrs->p32[i].p_offset, phdrs->p32[i].p_filesz,
- phdrs->p32[i].p_align);
+ consider_phdr ((*p32)[i].p_type,
+ (*p32)[i].p_vaddr, (*p32)[i].p_memsz,
+ (*p32)[i].p_offset, (*p32)[i].p_filesz,
+ (*p32)[i].p_align);
}
else
{
@@ -590,10 +595,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
found_bias = false; /* Trigger error check. */
else
for (uint_fast16_t i = 0; i < phnum; ++i)
- consider_phdr (phdrs->p64[i].p_type,
- phdrs->p64[i].p_vaddr, phdrs->p64[i].p_memsz,
- phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz,
- phdrs->p64[i].p_align);
+ consider_phdr ((*p64)[i].p_type,
+ (*p64)[i].p_vaddr, (*p64)[i].p_memsz,
+ (*p64)[i].p_offset, (*p64)[i].p_filesz,
+ (*p64)[i].p_align);
}
finish_portion (&ph_buffer, &ph_buffer_size);
@@ -749,44 +754,39 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
const size_t dyn_entsize = (ei_class == ELFCLASS32
? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
- void *dyns = NULL;
void *dyn_data = NULL;
size_t dyn_data_size = 0;
if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
&& ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
{
- typedef union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } dynn;
- dyns = malloc (sizeof (dynn));
+ void *dyns = malloc (dyn_filesz);
+ Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
+ Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
if (unlikely (dyns == NULL))
return finish ();
- dynn *dyn = (dynn *) dyns;
xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
xlatefrom.d_buf = (void *) dyn_data;
xlatefrom.d_size = dyn_filesz;
- xlateto.d_buf = dyn;
- xlateto.d_size = sizeof (dynn);
+ xlateto.d_buf = dyns;
+ xlateto.d_size = dyn_filesz;
if (ei_class == ELFCLASS32)
{
if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
- if (consider_dyn (dyn->d32[i].d_tag, dyn->d32[i].d_un.d_val))
+ if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val))
break;
}
else
{
if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
- if (consider_dyn (dyn->d64[i].d_tag, dyn->d64[i].d_un.d_val))
+ if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val))
break;
}
+ free (dyns);
}
- free (dyns);
finish_portion (&dyn_data, &dyn_data_size);
/* We'll use the name passed in or a stupid default if not DT_SONAME. */
@@ -901,12 +901,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
if (ei_class == ELFCLASS32)
for (uint_fast16_t i = 0; i < phnum; ++i)
- read_phdr (phdrs->p32[i].p_type, phdrs->p32[i].p_vaddr,
- phdrs->p32[i].p_offset, phdrs->p32[i].p_filesz);
+ read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr,
+ (*p32)[i].p_offset, (*p32)[i].p_filesz);
else
for (uint_fast16_t i = 0; i < phnum; ++i)
- read_phdr (phdrs->p64[i].p_type, phdrs->p64[i].p_vaddr,
- phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz);
+ read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr,
+ (*p64)[i].p_offset, (*p64)[i].p_filesz);
}
else
{
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index ed8f6e92..dd42e954 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -191,22 +191,23 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
xlatefrom.d_buf = buffer;
}
- typedef union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrsn;
-
- phdrsp = malloc (sizeof (phdrsn));
+ bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+ size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+ if (unlikely (phnum > SIZE_MAX / phdr_size))
+ {
+ free (buffer);
+ goto no_memory;
+ }
+ const size_t phdrsp_bytes = phnum * phdr_size;
+ phdrsp = malloc (phdrsp_bytes);
if (unlikely (phdrsp == NULL))
{
free (buffer);
goto no_memory;
}
- phdrsn *phdrs = (phdrsn *) phdrsp;
- xlateto.d_buf = phdrs;
- xlateto.d_size = sizeof (phdrsn);
+ xlateto.d_buf = phdrsp;
+ xlateto.d_size = phdrsp_bytes;
/* Scan for PT_LOAD segments to find the total size of the file image. */
size_t contents_size = 0;
@@ -214,6 +215,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
GElf_Off segments_end_mem = 0;
GElf_Addr loadbase = ehdr_vma;
bool found_base = false;
+ Elf32_Phdr (*p32)[phnum] = phdrsp;
+ Elf64_Phdr (*p64)[phnum] = phdrsp;
switch (ehdr.e32.e_ident[EI_CLASS])
{
/* Sanity checks segments and calculates segment_end,
@@ -249,9 +252,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e32.e_ident[EI_DATA]) == NULL)
goto libelf_error;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p32[i].p_vaddr, phdrs->p32[i].p_offset,
- phdrs->p32[i].p_filesz, phdrs->p32[i].p_memsz))
+ if ((*p32)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+ (*p32)[i].p_filesz, (*p32)[i].p_memsz))
goto bad_elf;
break;
@@ -260,9 +263,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e64.e_ident[EI_DATA]) == NULL)
goto libelf_error;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p64[i].p_vaddr, phdrs->p64[i].p_offset,
- phdrs->p64[i].p_filesz, phdrs->p64[i].p_memsz))
+ if ((*p64)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+ (*p64)[i].p_filesz, (*p64)[i].p_memsz))
goto bad_elf;
break;
@@ -315,9 +318,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS32:
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p32[i].p_vaddr, phdrs->p32[i].p_offset,
- phdrs->p32[i].p_filesz))
+ if ((*p32)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+ (*p32)[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -342,9 +345,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS64:
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p64[i].p_vaddr, phdrs->p64[i].p_offset,
- phdrs->p64[i].p_filesz))
+ if ((*p64)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+ (*p64)[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -373,7 +376,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
}
free (phdrsp);
- phdrs = phdrsp = NULL;
+ phdrsp = NULL;
/* Now we have the image. Open libelf on it. */
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 030c6002..9f0b4a2c 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -48,20 +48,16 @@ static bool
auxv_format_probe (const void *auxv, size_t size,
uint_fast8_t *elfclass, uint_fast8_t *elfdata)
{
- const union
- {
- char buf[size];
- Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
- Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
- } *u = auxv;
+ const Elf32_auxv_t (*a32)[size / sizeof (Elf32_auxv_t)] = (void *) auxv;
+ const Elf64_auxv_t (*a64)[size / sizeof (Elf64_auxv_t)] = (void *) auxv;
inline bool check64 (size_t i)
{
/* The AUXV pointer might not even be naturally aligned for 64-bit
data, because note payloads in a core file are not aligned. */
- uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
- uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);
+ uint64_t type = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_type);
+ uint64_t val = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_un.a_val);
if (type == BE64 (PROBE_TYPE)
&& val == BE64 (PROBE_VAL64))
@@ -85,8 +81,8 @@ auxv_format_probe (const void *auxv, size_t size,
/* The AUXV pointer might not even be naturally aligned for 32-bit
data, because note payloads in a core file are not aligned. */
- uint32_t type = read_4ubyte_unaligned_noncvt (&u->a32[i].a_type);
- uint32_t val = read_4ubyte_unaligned_noncvt (&u->a32[i].a_un.a_val);
+ uint32_t type = read_4ubyte_unaligned_noncvt (&(*a32)[i].a_type);
+ uint32_t val = read_4ubyte_unaligned_noncvt (&(*a32)[i].a_un.a_val);
if (type == BE32 (PROBE_TYPE)
&& val == BE32 (PROBE_VAL32))
@@ -280,29 +276,26 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
return true;
}
- const union
- {
- Elf32_Addr a32[n];
- Elf64_Addr a64[n];
- } *in = vaddr - read_vaddr + buffer;
+ Elf32_Addr (*a32)[n] = vaddr - read_vaddr + buffer;
+ Elf64_Addr (*a64)[n] = (void *) a32;
if (elfclass == ELFCLASS32)
{
if (elfdata == ELFDATA2MSB)
for (size_t i = 0; i < n; ++i)
- addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&in->a32[i]));
+ addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
else
for (size_t i = 0; i < n; ++i)
- addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&in->a32[i]));
+ addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
}
else
{
if (elfdata == ELFDATA2MSB)
for (size_t i = 0; i < n; ++i)
- addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&in->a64[i]));
+ addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
else
for (size_t i = 0; i < n; ++i)
- addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&in->a64[i]));
+ addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
}
return false;
@@ -861,13 +854,15 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
}
if (in_ok)
{
- typedef union
- {
- Elf32_Phdr p32;
- Elf64_Phdr p64;
- char data[phnum * phent];
- } data_buf;
- data_buf *buf = malloc (sizeof (data_buf));
+ if (unlikely (phnum > SIZE_MAX / phent))
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return false;
+ }
+ size_t nbytes = phnum * phent;
+ void *buf = malloc (nbytes);
+ Elf32_Phdr (*p32)[phnum] = buf;
+ Elf64_Phdr (*p64)[phnum] = buf;
if (unlikely (buf == NULL))
{
__libdwfl_seterrno (DWFL_E_NOMEM);
@@ -886,25 +881,20 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
(&out, &in, elfdata) != NULL))
{
/* We are looking for PT_DYNAMIC. */
- const union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } *u = (void *) buf;
if (elfclass == ELFCLASS32)
{
for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p32[i].p_type,
- u->p32[i].p_vaddr,
- u->p32[i].p_filesz))
+ if (consider_phdr ((*p32)[i].p_type,
+ (*p32)[i].p_vaddr,
+ (*p32)[i].p_filesz))
break;
}
else
{
for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p64[i].p_type,
- u->p64[i].p_vaddr,
- u->p64[i].p_filesz))
+ if (consider_phdr ((*p64)[i].p_type,
+ (*p64)[i].p_vaddr,
+ (*p64)[i].p_filesz))
break;
}
}
@@ -955,13 +945,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
dyn_vaddr, dyn_filesz, memory_callback_arg))
{
- typedef union
- {
- Elf32_Dyn d32;
- Elf64_Dyn d64;
- char data[dyn_filesz];
- } data_buf;
- data_buf *buf = malloc (sizeof (data_buf));
+ void *buf = malloc (dyn_filesz);
+ Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = buf;
+ Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = buf;
if (unlikely (buf == NULL))
{
__libdwfl_seterrno (DWFL_E_NOMEM);
@@ -980,18 +966,13 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
(&out, &in, elfdata) != NULL))
{
/* We are looking for DT_DEBUG. */
- const union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } *u = (void *) buf;
if (elfclass == ELFCLASS32)
{
size_t n = dyn_filesz / sizeof (Elf32_Dyn);
for (size_t i = 0; i < n; ++i)
- if (u->d32[i].d_tag == DT_DEBUG)
+ if ((*d32)[i].d_tag == DT_DEBUG)
{
- r_debug_vaddr = u->d32[i].d_un.d_val;
+ r_debug_vaddr = (*d32)[i].d_un.d_val;
break;
}
}
@@ -999,9 +980,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
{
size_t n = dyn_filesz / sizeof (Elf64_Dyn);
for (size_t i = 0; i < n; ++i)
- if (u->d64[i].d_tag == DT_DEBUG)
+ if ((*d64)[i].d_tag == DT_DEBUG)
{
- r_debug_vaddr = u->d64[i].d_un.d_val;
+ r_debug_vaddr = (*d64)[i].d_un.d_val;
break;
}
}
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 4ea6d498..d040c08f 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+ relocation overflows in some platforms.
+
2015-09-22 Mark Wielaard <mjw@redhat.com>
* *.c: Remove old-style function definitions.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index ec4477b7..6b41a3e1 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -28,7 +28,7 @@
## not, see <http://www.gnu.org/licenses/>.
##
include $(top_srcdir)/config/eu.am
-AM_CFLAGS += -fpic
+AM_CFLAGS += -fPIC
AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
VERSION = 1
LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 0609b37d..0b9ddf2b 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,17 @@
+2015-10-05 Chih-Hung Hsieh <chh@google.com>
+
+ * elf_getarsym.c (elf_getarsym): Do not use
+ union of variable length arrays.
+
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (libelf.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+ relocation overflows in some platforms.
+
2015-09-29 Mark Wielaard <mjw@redhat.com>
* elf32_updatenull.c (default_ehdr): Set e_version when EV_NONE.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index afcb2aa5..91a7d073 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -29,7 +29,7 @@
##
include $(top_srcdir)/config/eu.am
if BUILD_STATIC
-AM_CFLAGS += -fpic
+AM_CFLAGS += -fPIC
endif
GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
VERSION = 1
@@ -100,11 +100,11 @@ endif
libelf_so_SOURCES =
libelf.so$(EXEEXT): libelf_pic.a libelf.map
- $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+ $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \
-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS)
@$(textrel_check)
- ln -fs $@ $@.$(VERSION)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
install: install-am libelf.so
$(mkinstalldirs) $(DESTDIR)$(libdir)
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
index 1ab94ca8..65c67cc8 100644
--- a/libelf/elf_getarsym.c
+++ b/libelf/elf_getarsym.c
@@ -201,11 +201,7 @@ elf_getarsym (Elf *elf, size_t *ptr)
elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
if (elf->state.ar.ar_sym != NULL)
{
- union
- {
- uint32_t u32[n];
- uint64_t u64[n];
- } *file_data;
+ void *file_data; /* unit32_t[n] or uint64_t[n] */
char *str_data;
size_t sz = n * w;
@@ -267,12 +263,14 @@ elf_getarsym (Elf *elf, size_t *ptr)
/* Now we can build the data structure. */
Elf_Arsym *arsym = elf->state.ar.ar_sym;
+ uint64_t (*u64)[n] = file_data;
+ uint32_t (*u32)[n] = file_data;
for (size_t cnt = 0; cnt < n; ++cnt)
{
arsym[cnt].as_name = str_data;
if (index64_p)
{
- uint64_t tmp = file_data->u64[cnt];
+ uint64_t tmp = (*u64)[cnt];
if (__BYTE_ORDER == __LITTLE_ENDIAN)
tmp = bswap_64 (tmp);
@@ -294,9 +292,9 @@ elf_getarsym (Elf *elf, size_t *ptr)
}
}
else if (__BYTE_ORDER == __LITTLE_ENDIAN)
- arsym[cnt].as_off = bswap_32 (file_data->u32[cnt]);
+ arsym[cnt].as_off = bswap_32 ((*u32)[cnt]);
else
- arsym[cnt].as_off = file_data->u32[cnt];
+ arsym[cnt].as_off = (*u32)[cnt];
arsym[cnt].as_hash = _dl_elf_hash (str_data);
str_data = rawmemchr (str_data, '\0') + 1;
diff --git a/src/ChangeLog b/src/ChangeLog
index 411c70bf..f5778856 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,23 @@
+2015-10-07 Mark Wielaard <mjw@redhat.com>
+
+ * unstrip.c (MAX): Removed.
+ (find_alloc_sections_prelink): Allocate exact amount of bytes for
+ shdrs.
+
+2015-10-05 Chih-Hung Hsieh <chh@google.com>
+
+ * unstrip.c (find_alloc_sections_prelink): Do not allocate
+ on stack union types with variable length arrays; use xmalloc
+ for such dynamic sized objects.
+ * readelf.c (handle_core_item): Likewise, but use alloca
+ for small variable size data object and add assert(count < 128).
+
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (libld_elf_i386.so): Add AM_V_CCLD silencer.
+ (.deps/none_ld.Po): Always silence the dummy command.
+ (make-debug-archive): Add AM_V_GEN and AM_V_at silencers.
+
2015-10-02 Mark Wielaard <mjw@redhat.com>
* unstrip.c (copy_elided_sections): Use SH_INFO_LINK_P, not just
diff --git a/src/Makefile.am b/src/Makefile.am
index cd2755b0..afb38fc0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -138,7 +138,7 @@ am_libld_elf_i386_pic_a_OBJECTS = i386_ld.os
libld_elf_i386_so_SOURCES =
libld_elf_i386.so: libld_elf_i386_pic.a libld_elf_i386.map
- $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+ $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
$(libelf) $(libeu) \
-Wl,--version-script,$(srcdir)/libld_elf_i386.map
@$(textrel_check)
@@ -147,7 +147,7 @@ endif
# Special rule to make it possible to define libld_elf_a_SOURCES as we do.
# Otherwise make would complain.
.deps/none_ld.Po: none_ld.os
- -:
+ @-:
installcheck-binPROGRAMS: $(bin_PROGRAMS)
@@ -172,11 +172,11 @@ MAINTAINERCLEANFILES = ldlex.c ldscript.c ldscript.h
make-debug-archive: $(srcdir)/make-debug-archive.in
- UNSTRIP=$(bindir)/`echo unstrip | sed '$(transform)'`; \
+ $(AM_V_GEN)UNSTRIP=$(bindir)/`echo unstrip | sed '$(transform)'`; \
AR=$(bindir)/`echo ar | sed '$(transform)'`; \
sed -e "s,[@]UNSTRIP[@],$$UNSTRIP,g" -e "s,[@]AR[@],$$AR,g" \
-e "s%[@]PACKAGE_NAME[@]%$(PACKAGE_NAME)%g" \
-e "s%[@]PACKAGE_VERSION[@]%$(PACKAGE_VERSION)%g" \
$(srcdir)/make-debug-archive.in > $@.new
- chmod +x $@.new
- mv -f $@.new $@
+ $(AM_V_at)chmod +x $@.new
+ $(AM_V_at)mv -f $@.new $@
diff --git a/src/readelf.c b/src/readelf.c
index 33274f35..fe7bc392 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8370,6 +8370,9 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
unsigned int colno, size_t *repeated_size)
{
uint_fast16_t count = item->count ?: 1;
+ /* Ebl_Core_Item count is always a small number.
+ Make sure the backend didn't put in some large bogus value. */
+ assert (count < 128);
#define TYPES \
DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
@@ -8379,11 +8382,16 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
-#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
- union { TYPES; } value;
+#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
+ typedef union { TYPES; } value_t;
+ void *data = alloca (count * sizeof (value_t));
+#undef DO_TYPE
+
+#define DO_TYPE(NAME, Name, hex, dec) \
+ GElf_##Name *value_##Name __attribute__((unused)) = data
+ TYPES;
#undef DO_TYPE
- void *data = &value;
size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
size_t convsize = size;
if (repeated_size != NULL)
@@ -8414,7 +8422,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
colno = print_core_item (colno, ',', WRAP_COLUMN, \
- 0, item->name, dec, value.Name[0]); \
+ 0, item->name, dec, value_##Name[0]); \
break
TYPES;
#undef DO_TYPE
@@ -8430,7 +8438,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
colno = print_core_item (colno, ',', WRAP_COLUMN, \
- 0, item->name, hex, value.Name[0]); \
+ 0, item->name, hex, value_##Name[0]); \
break
TYPES;
#undef DO_TYPE
@@ -8520,8 +8528,8 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
{
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
- sec = value.Name[0]; \
- usec = value.Name[1]; \
+ sec = value_##Name[0]; \
+ usec = value_##Name[1]; \
break
TYPES;
#undef DO_TYPE
@@ -8551,12 +8559,12 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
case 'c':
assert (count == 1);
colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
- "%c", value.Byte[0]);
+ "%c", value_Byte[0]);
break;
case 's':
colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
- "%.*s", (int) count, value.Byte);
+ "%.*s", (int) count, value_Byte);
break;
case '\n':
diff --git a/src/unstrip.c b/src/unstrip.c
index d193708a..b725987c 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1013,13 +1013,15 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
".gnu.prelink_undo");
- union
- {
- Elf32_Shdr s32[shnum - 1];
- Elf64_Shdr s64[shnum - 1];
- } shdr;
- dst.d_buf = &shdr;
- dst.d_size = sizeof shdr;
+ bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+ size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
+ if (unlikely ((shnum - 1) > SIZE_MAX / shsize))
+ error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
+ (size_t) shnum, ".gnu.prelink_undo");
+ const size_t shdr_bytes = (shnum - 1) * shsize;
+ void *shdr = xmalloc (shdr_bytes);
+ dst.d_buf = shdr;
+ dst.d_size = shdr_bytes;
ELF_CHECK (gelf_xlatetom (main, &dst, &src,
main_ehdr->e_ident[EI_DATA]) != NULL,
_("cannot read '.gnu.prelink_undo' section: %s"));
@@ -1028,9 +1030,11 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
for (size_t i = 0; i < shnum - 1; ++i)
{
struct section *sec = &undo_sections[undo_nalloc];
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+ Elf32_Shdr (*s32)[shnum - 1] = shdr;
+ Elf64_Shdr (*s64)[shnum - 1] = shdr;
+ if (class32)
{
-#define COPY(field) sec->shdr.field = shdr.s32[i].field
+#define COPY(field) sec->shdr.field = (*s32)[i].field
COPY (sh_name);
COPY (sh_type);
COPY (sh_flags);
@@ -1044,7 +1048,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
#undef COPY
}
else
- sec->shdr = shdr.s64[i];
+ sec->shdr = (*s64)[i];
if (sec->shdr.sh_flags & SHF_ALLOC)
{
sec->shdr.sh_addr += bias;
@@ -1057,6 +1061,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
}
qsort (undo_sections, undo_nalloc,
sizeof undo_sections[0], compare_sections_nonrel);
+ free (shdr);
}
bool fail = false;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9d079123..66781d0c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2015-10-05 Josh Stone <jistone@redhat.com>
+
+ * Makefile.am (backtrace-child-biarch): Add AM_V_CC silencer.
+
2015-10-02 Mark Wielaard <mjw@redhat.com>
* elfstrmerge.c: New check program.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4ff48e64..fc9b648d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -63,7 +63,7 @@ endif
# Substitute $(COMPILE).
backtrace-child-biarch$(EXEEXT): backtrace-child.c
- $(CC_BIARCH) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_V_CC)$(CC_BIARCH) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS) $(backtrace_child_CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) $(backtrace_child_LDFLAGS) \