On Mon, 2014-05-19 at 00:43 +0200, Mark Wielaard wrote: > And on armv7hl with one FAIL. > > We added elflint checks against .o ET_REL files which produce on arm: > section [ 8] '.rel.ARM.exidx': invalid destination section type > > On RHEL5 ia64 elflint also failed with two issues: > > section [13] '.rela.IA_64.unwind': invalid destination section type > Again in an ET_REL file, so it looks like the armv7hl failure above.
They were indeed related. Both architectures add a special section type which is the target of a relocation. elflint didn't know about the special section type. The attached patch fixes it by introducing a new ebl hook with implementations for arm and ia64 that elflint then calls. > section [ 2] '.dynsym': symbol 1: symbol in dynamic symbol table with > non-default visibility This looks like a real bug caused by a really ancient binutils. The .dynsym contains symbols with STV_HIDDEN. Which really is just wrong. I don't want to add a workaround for this one. I'll merge the attached patch and do a release tomorrow. Cheers, Mark
>From 028d0ab0cc1cb5f96ee48feef966b7d8d56c6a8e Mon Sep 17 00:00:00 2001 From: Mark Wielaard <m...@redhat.com> Date: Mon, 19 May 2014 16:52:56 +0200 Subject: [PATCH] backends: Add ebl_check_reloc_target_type. And implement for arm and ia64. Both have special section types that are valid targets for a reloc. Both refer to unwind data. elflint now just calls ebl_check_reloc_target_type instead of hard coding the expected section types. Signed-off-by: Mark Wielaard <m...@redhat.com> --- backends/ChangeLog | 7 +++ backends/arm_init.c | 1 + backends/arm_symbol.c | 9 ++++- backends/ia64_init.c | 3 +- backends/ia64_symbol.c | 9 ++++- libebl/ChangeLog | 10 +++++ libebl/Makefile.am | 2 +- libebl/ebl-hooks.h | 5 ++- .../eblcheckreloctargettype.c | 40 +++++--------------- libebl/eblopenbackend.c | 11 +++++- libebl/libebl.h | 3 + src/ChangeLog | 4 ++ src/elflint.c | 3 +- 13 files changed, 69 insertions(+), 38 deletions(-) copy backends/ia64_init.c => libebl/eblcheckreloctargettype.c (50%) diff --git a/backends/ChangeLog b/backends/ChangeLog index 748d0a0..bc5b843 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,10 @@ +2014-05-19 Mark Wielaard <m...@redhat.com> + + * arm_init.c (arm_init): Hook check_reloc_target_type. + * arm_symbol.c (arm_check_reloc_target_type): New function. + * ia64_init.c (ia64_init): Hook check_reloc_target_type. + * ia64_symbol.c (ia64_check_reloc_target_type): New function. + 2014-04-22 Kurt Roeckx <k...@roeckx.be> * i386_initreg.c: Make Linux only. diff --git a/backends/arm_init.c b/backends/arm_init.c index 14b2635..92e6cd5 100644 --- a/backends/arm_init.c +++ b/backends/arm_init.c @@ -63,6 +63,7 @@ arm_init (elf, machine, eh, ehlen) HOOK (eh, check_object_attribute); HOOK (eh, return_value_location); HOOK (eh, abi_cfi); + HOOK (eh, check_reloc_target_type); /* We only unwind the core integer registers. */ eh->frame_nregs = 16; diff --git a/backends/arm_symbol.c b/backends/arm_symbol.c index e41ce34..cd467ff 100644 --- a/backends/arm_symbol.c +++ b/backends/arm_symbol.c @@ -1,5 +1,5 @@ /* Arm specific symbolic name handling. - Copyright (C) 2002-2009 Red Hat, Inc. + Copyright (C) 2002-2009, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -122,3 +122,10 @@ arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type) return ELF_T_NUM; } } + +/* The SHT_ARM_EXIDX section type is a valid target for relocation. */ +bool +arm_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type) +{ + return sh_type == SHT_ARM_EXIDX; +} diff --git a/backends/ia64_init.c b/backends/ia64_init.c index ed56efa..91da748 100644 --- a/backends/ia64_init.c +++ b/backends/ia64_init.c @@ -1,5 +1,5 @@ /* Initialization of IA-64 specific backend library. - Copyright (C) 2002, 2003, 2005, 2006, 2007 Red Hat, Inc. + Copyright (C) 2002, 2003, 2005, 2006, 2007, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drep...@redhat.com>, 2002. @@ -61,6 +61,7 @@ ia64_init (elf, machine, eh, ehlen) HOOK (eh, machine_section_flag_check); HOOK (eh, register_info); HOOK (eh, return_value_location); + HOOK (eh, check_reloc_target_type); return MODVERSION; } diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c index 8d806b0..f928b0b 100644 --- a/backends/ia64_symbol.c +++ b/backends/ia64_symbol.c @@ -1,5 +1,5 @@ /* IA-64 specific symbolic name handling. - Copyright (C) 2002-2009 Red Hat, Inc. + Copyright (C) 2002-2009, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drep...@redhat.com>, 2002. @@ -148,3 +148,10 @@ ia64_reloc_simple_type (Ebl *ebl, int type) return ELF_T_NUM; } + +/* The SHT_IA_64_UNWIND section type is a valid target for relocation. */ +bool +ia64_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type) +{ + return sh_type == SHT_IA_64_UNWIND; +} diff --git a/libebl/ChangeLog b/libebl/ChangeLog index fc6bdd5..7198d5e 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,13 @@ +2014-05-19 Mark Wielaard <m...@redhat.com> + + * Makefile.am (gen_SOURCES): Add eblcheckreloctargettype.c. + * eblcheckreloctargettype.c: New file. + * ebl-hooks.h (check_reloc_target_type): New hook. + * eblopenbackend.c (default_check_reloc_target_type): New function. + (fill_defaults): Assign default_check_reloc_target_type to + check_reloc_target_type. + * libebl.h (ebl_check_reloc_target_type): New function definition. + 2013-12-18 Mark Wielaard <m...@redhat.com> * Makefile.am (gen_SOURCES): Add eblresolvesym.c. diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 916af72..ec4477b 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -55,7 +55,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \ ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \ eblstother.c eblinitreg.c ebldwarftoregno.c eblnormalizepc.c \ - eblunwind.c eblresolvesym.c + eblunwind.c eblresolvesym.c eblcheckreloctargettype.c libebl_a_SOURCES = $(gen_SOURCES) diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index bfb7f4a..65c62ec 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -1,5 +1,5 @@ /* Backend hook signatures internal interface for libebl. - Copyright (C) 2000-2011, 2013 Red Hat, Inc. + Copyright (C) 2000-2011, 2013, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -105,6 +105,9 @@ bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *); bool EBLHOOK(check_object_attribute) (Ebl *, const char *, int, uint64_t, const char **, const char **); +/* Check reloc target section type. */ +bool EBLHOOK(check_reloc_target_type) (Ebl *, Elf64_Word); + /* Describe auxv element type. */ int EBLHOOK(auxv_info) (GElf_Xword, const char **, const char **); diff --git a/backends/ia64_init.c b/libebl/eblcheckreloctargettype.c similarity index 50% copy from backends/ia64_init.c copy to libebl/eblcheckreloctargettype.c index ed56efa..e135f8a 100644 --- a/backends/ia64_init.c +++ b/libebl/eblcheckreloctargettype.c @@ -1,7 +1,6 @@ -/* Initialization of IA-64 specific backend library. - Copyright (C) 2002, 2003, 2005, 2006, 2007 Red Hat, Inc. +/* Check whether a section type is a valid target for relocation. + Copyright (C) 2014 Red Hat, Inc. This file is part of elfutils. - Written by Ulrich Drepper <drep...@redhat.com>, 2002. This file is free software; you can redistribute it and/or modify it under the terms of either @@ -31,36 +30,17 @@ # include <config.h> #endif -#define BACKEND ia64_ -#define RELOC_PREFIX R_IA64_ -#include "libebl_CPU.h" +#include <libeblP.h> -/* This defines the common reloc hooks based on ia64_reloc.def. */ -#include "common-reloc.c" -const char * -ia64_init (elf, machine, eh, ehlen) - Elf *elf __attribute__ ((unused)); - GElf_Half machine __attribute__ ((unused)); - Ebl *eh; - size_t ehlen; +bool +ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type) { - /* Check whether the Elf_BH object has a sufficent size. */ - if (ehlen < sizeof (Ebl)) - return NULL; + if (ebl->check_reloc_target_type (ebl, sh_type)) + return true; - /* We handle it. */ - eh->name = "Intel IA-64"; - ia64_init_reloc (eh); - HOOK (eh, reloc_simple_type); - HOOK (eh, segment_type_name); - HOOK (eh, section_type_name); - HOOK (eh, dynamic_tag_name); - HOOK (eh, dynamic_tag_check); - HOOK (eh, machine_flag_check); - HOOK (eh, machine_section_flag_check); - HOOK (eh, register_info); - HOOK (eh, return_value_location); + if (sh_type == SHT_PROGBITS || sh_type == SHT_NOBITS) + return true; - return MODVERSION; + return false; } diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index c19ae1b..bd94759 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -1,5 +1,5 @@ /* Generate ELF backend handle. - Copyright (C) 2000-2013 Red Hat, Inc. + Copyright (C) 2000-2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -200,6 +200,7 @@ static bool default_check_object_attribute (Ebl *ebl, const char *vendor, int tag, uint64_t value, const char **tag_name, const char **value_name); +static bool default_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type); static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info); @@ -241,6 +242,7 @@ fill_defaults (Ebl *result) result->register_info = default_register_info; result->syscall_abi = default_syscall_abi; result->check_object_attribute = default_check_object_attribute; + result->check_reloc_target_type = default_check_reloc_target_type; result->disasm = NULL; result->abi_cfi = default_abi_cfi; result->destr = default_destr; @@ -747,6 +749,13 @@ default_check_object_attribute (Ebl *ebl __attribute__ ((unused)), return false; } +static bool +default_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), + Elf64_Word sh_type __attribute__ ((unused))) +{ + return false; +} + static int default_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info __attribute__ ((unused))) diff --git a/libebl/libebl.h b/libebl/libebl.h index 50d6baa..d05751f 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -179,6 +179,9 @@ extern bool ebl_check_object_attribute (Ebl *ebl, const char *vendor, const char **tag_name, const char **value_name); +/* Check whether a section type is a valid reloc target. */ +extern bool ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type); + /* Check section name for being that of a debug informatino section. */ extern bool ebl_debugscn_p (Ebl *ebl, const char *name); diff --git a/src/ChangeLog b/src/ChangeLog index 341787d..4197ccd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2014-05-19 Mark Wielaard <m...@redhat.com> + + * elflint.c (check_reloc_shdr): Check ebl_check_reloc_target_type. + 2014-05-01 Mark Wielaard <m...@redhat.com> * readelf.c (find_no_debuginfo): Call dwfl_standard_find_debuginfo diff --git a/src/elflint.c b/src/elflint.c index 5a500b7..bf6d044 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -1216,8 +1216,7 @@ check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, destshdr_memp); if (*destshdrp != NULL) { - if((*destshdrp)->sh_type != SHT_PROGBITS - && (*destshdrp)->sh_type != SHT_NOBITS) + if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type)) { reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); if (!reldyn) -- 1.7.1