diff options
author | Chih-hung Hsieh <chh@google.com> | 2015-10-09 18:39:18 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-10-09 18:39:18 +0000 |
commit | 495820301403545dee86eadbc2198d63765d06a3 (patch) | |
tree | 40ae3959ffe2abac7ce87f49186787648dee3101 | |
parent | 5e22dcc417102da5c05f8c5b98b9b617cdbf7b20 (diff) | |
parent | 322dc30a675af1bf85103c43d48368af0be38927 (diff) | |
download | android_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.tar.gz android_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.tar.bz2 android_external_elfutils-495820301403545dee86eadbc2198d63765d06a3.zip |
Merge "Merge upstream commit '86ed7f7'."
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | backends/ChangeLog | 10 | ||||
-rw-r--r-- | backends/Makefile.am | 6 | ||||
-rw-r--r-- | backends/sparc_attrs.c | 75 | ||||
-rw-r--r-- | backends/sparc_init.c | 1 | ||||
-rw-r--r-- | config/ChangeLog | 9 | ||||
-rw-r--r-- | config/eu.am | 4 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/ChangeLog | 5 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | libasm/ChangeLog | 4 | ||||
-rw-r--r-- | libasm/Makefile.am | 4 | ||||
-rw-r--r-- | libcpu/ChangeLog | 11 | ||||
-rw-r--r-- | libcpu/Makefile.am | 12 | ||||
-rw-r--r-- | libdw/ChangeLog | 9 | ||||
-rw-r--r-- | libdw/Makefile.am | 6 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 20 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 63 | ||||
-rw-r--r-- | libdwfl/dwfl_segment_report_module.c | 70 | ||||
-rw-r--r-- | libdwfl/elf-from-memory.c | 49 | ||||
-rw-r--r-- | libdwfl/link_map.c | 87 | ||||
-rw-r--r-- | libebl/ChangeLog | 5 | ||||
-rw-r--r-- | libebl/Makefile.am | 2 | ||||
-rw-r--r-- | libelf/ChangeLog | 14 | ||||
-rw-r--r-- | libelf/Makefile.am | 6 | ||||
-rw-r--r-- | libelf/elf_getarsym.c | 14 | ||||
-rw-r--r-- | src/ChangeLog | 20 | ||||
-rw-r--r-- | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/readelf.c | 26 | ||||
-rw-r--r-- | src/unstrip.c | 25 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 2 |
32 files changed, 388 insertions, 194 deletions
@@ -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) \ |