From: Ulrich Drepper Date: Tue, 2 Aug 2005 16:07:42 +0000 (+0000) Subject: elflint cleanups. X-Git-Tag: elfutils-0.120~155 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c911c9efe553d9af2d4fb0d420d8b614983e16ac;p=platform%2Fupstream%2Felfutils.git elflint cleanups. Bump release number. --- diff --git a/NEWS b/NEWS index 602514f..02f5e45 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 0.112: + +elfcmp: some more relaxation. + Version 0.111: libdw: now contains all of libdwfl. The latter is not installed anymore. diff --git a/configure.ac b/configure.ac index f995bb7..578ec65 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software Foundation, dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl -AC_INIT([Red Hat elfutils],[0.111],[http://bugzilla.redhat.com/bugzilla/], +AC_INIT([Red Hat elfutils],[0.112],[http://bugzilla.redhat.com/bugzilla/], [elfutils]) AC_CONFIG_AUX_DIR([config]) diff --git a/src/ChangeLog b/src/ChangeLog index bd1d5f2..31a68ae 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2005-08-02 Ulrich Drepper + + * elflint.c (check_reloc_shdr): New function split out from check_rela + and check_rel. + (check_one_reloc): New function. Likewise. + (check_rela): Use check_reloc_shdr and check_one_reloc. + (check_rel): Likewise. + 2005-08-01 Ulrich Drepper * elfcmp.c (main): Ignore section count and section name string table diff --git a/src/elflint.c b/src/elflint.c index 0357237..dca8a79 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -935,7 +935,8 @@ section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segm static bool -is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, int idx, GElf_Shdr *shdr, bool rela) +is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, + bool rela) { /* If this is no executable or DSO it cannot be a .rel.dyn section. */ if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) @@ -987,43 +988,25 @@ section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), } -static void -check_rela (Ebl *ebl, GElf_Ehdr *ehdr, int idx) +static bool +check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, + int idx, int reltype, GElf_Shdr **destshdrp, + GElf_Shdr *destshdr_memp) { - Elf_Scn *scn; - GElf_Shdr shdr_mem; - GElf_Shdr *shdr; - Elf_Data *data; - GElf_Shdr destshdr_mem; - GElf_Shdr *destshdr = NULL; - size_t cnt; bool reldyn = false; - bool known_broken = gnuld; - - scn = elf_getscn (ebl->elf, idx); - shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr == NULL) - return; - data = elf_getdata (scn, NULL); - if (data == NULL) - { - ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), - idx, section_name (ebl, idx)); - return; - } /* Check whether the link to the section we relocate is reasonable. */ if (shdr->sh_info >= shnum) ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), idx, section_name (ebl, idx)); - else + else if (shdr->sh_info != 0) { - destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), - &destshdr_mem); - if (destshdr != NULL) + *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), + destshdr_memp); + if (*destshdrp != NULL) { - if(destshdr->sh_type != SHT_PROGBITS - && destshdr->sh_type != SHT_NOBITS) + if((*destshdrp)->sh_type != SHT_PROGBITS + && (*destshdrp)->sh_type != SHT_NOBITS) { reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); if (!reldyn) @@ -1032,7 +1015,7 @@ section [%2d] '%s': invalid destination section type\n"), idx, section_name (ebl, idx)); else { - /* There is no standard, but we require that .rela.dyn + /* There is no standard, but we require that .rel{,a}.dyn sections have a sh_info value of zero. */ if (shdr->sh_info != 0) ERROR (gettext ("\ @@ -1041,124 +1024,100 @@ section [%2d] '%s': sh_info should be zero\n"), } } - if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) + if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) ERROR (gettext ("\ section [%2d] '%s': no relocations for merge-able sections possible\n"), idx, section_name (ebl, idx)); } } - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT)) - ERROR (gettext ("\ -section [%2d] '%s': section entry size does not match ElfXX_Rela\n"), + if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT)) + ERROR (gettext (reltype == ELF_T_RELA ? "\ +section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ +section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), idx, section_name (ebl, idx)); - Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); - GElf_Shdr symshdr_mem; - GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); - Elf_Data *symdata = elf_getdata (symscn, NULL); + return reldyn; +} - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) - { - GElf_Rela rela_mem; - GElf_Rela *rela; - rela = gelf_getrela (data, cnt, &rela_mem); - if (rela == NULL) - { - ERROR (gettext ("\ -section [%2d] '%s': cannot get relocation %zu: %s\n"), - idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); - continue; - } +static void +check_one_reloc (Ebl *ebl, int idx, size_t cnt, const GElf_Shdr *symshdr, + Elf_Data *symdata, GElf_Addr r_offset, GElf_Xword r_info, + const GElf_Shdr *destshdr, bool reldyn) +{ + bool known_broken = gnuld; - if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rela->r_info))) - ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), - idx, section_name (ebl, idx), cnt); - else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rela->r_info))) - ERROR (gettext ("\ + if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) + ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), + idx, section_name (ebl, idx), cnt); + else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) + ERROR (gettext ("\ section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), - idx, section_name (ebl, idx), cnt); + idx, section_name (ebl, idx), cnt); - if (symshdr != NULL - && ((GELF_R_SYM (rela->r_info) + 1) - * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) - > symshdr->sh_size)) - ERROR (gettext ("\ + if (symshdr != NULL + && ((GELF_R_SYM (r_info) + 1) + * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) + > symshdr->sh_size)) + ERROR (gettext ("\ section [%2d] '%s': relocation %zu: invalid symbol index\n"), - idx, section_name (ebl, idx), cnt); + idx, section_name (ebl, idx), cnt); - if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rela->r_info))) - { - const char *name; - char buf[64]; - GElf_Sym sym_mem; - GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rela->r_info), - &sym_mem); - if (sym != NULL - /* Get the name for the symbol. */ - && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) - && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) - ERROR (gettext ("\ + if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) + { + const char *name; + char buf[64]; + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); + if (sym != NULL + /* Get the name for the symbol. */ + && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) + ERROR (gettext ("\ section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), - idx, section_name (ebl, idx), cnt, - ebl_reloc_type_name (ebl, GELF_R_SYM (rela->r_info), - buf, sizeof (buf))); - } + idx, section_name (ebl, idx), cnt, + ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), + buf, sizeof (buf))); + } - if (reldyn) - { - // XXX TODO Check .rel.dyn section addresses. - } - else if (!known_broken) - { - if (destshdr != NULL - && (rela->r_offset - destshdr->sh_addr) >= destshdr->sh_size) - ERROR (gettext ("\ + if (reldyn) + { + // XXX TODO Check .rel.dyn section addresses. + } + else if (!known_broken) + { + if (destshdr != NULL + && GELF_R_TYPE (r_info) != 0 + && (r_offset - destshdr->sh_addr) >= destshdr->sh_size) + ERROR (gettext ("\ section [%2d] '%s': relocation %zu: offset out of bounds\n"), idx, section_name (ebl, idx), cnt); - } + } - if (symdata != NULL - && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) + if (symdata != NULL && ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))) + { + /* Make sure the referenced symbol is an object or unspecified. */ + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); + if (sym != NULL + && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE + && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) { - /* Make sure the referenced symbol is an object or unspecified. */ - GElf_Sym sym_mem; - GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rela->r_info), - &sym_mem); - if (sym != NULL - && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE - && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) - { - char buf[64]; - ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), - idx, section_name (ebl, idx), cnt, - ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), - buf, sizeof (buf))); - } + char buf[64]; + ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), + idx, section_name (ebl, idx), cnt, + ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), + buf, sizeof (buf))); } } } static void -check_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx) +check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) { - Elf_Scn *scn; - GElf_Shdr shdr_mem; - GElf_Shdr *shdr; - Elf_Data *data; - GElf_Shdr destshdr_mem; - GElf_Shdr *destshdr = NULL; - size_t cnt; - bool reldyn = false; - bool known_broken = gnuld; - - scn = elf_getscn (ebl->elf, idx); - shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr == NULL) - return; - data = elf_getdata (scn, NULL); + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); if (data == NULL) { ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), @@ -1166,58 +1125,61 @@ check_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx) return; } - /* Check whether the link to the section we relocate is reasonable. */ - if (shdr->sh_info >= shnum) - ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), - idx, section_name (ebl, idx)); - else + /* Check the fields of the section header. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = NULL; + bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, + &destshdr_mem); + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + + for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) { - destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), - &destshdr_mem); - if (destshdr != NULL) + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); + if (rela == NULL) { - if (destshdr->sh_type != SHT_PROGBITS - && destshdr->sh_type != SHT_NOBITS) - { - reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, false); - if (!reldyn) - ERROR (gettext ("\ -section [%2d] '%s': invalid destination section type\n"), - idx, section_name (ebl, idx)); - else - { - /* There is no standard, but we require that .rela.dyn - sections have a sh_info value of zero. */ - if (shdr->sh_info != 0) - ERROR (gettext ("\ -section [%2d] '%s': sh_info should be zero\n"), - idx, section_name (ebl, idx)); - } - } - - if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) - ERROR (gettext ("\ -section [%2d] '%s': no relocations for merge-able sections possible\n"), - idx, section_name (ebl, idx)); + ERROR (gettext ("\ +section [%2d] '%s': cannot get relocation %zu: %s\n"), + idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); + continue; } + + check_one_reloc (ebl, idx, cnt, symshdr, symdata, rela->r_offset, + rela->r_info, destshdr, reldyn); } +} - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT)) - ERROR (gettext ("\ -section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), - idx, section_name (ebl, idx)); + +static void +check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + /* Check the fields of the section header. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = NULL; + bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, + &destshdr_mem); Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); GElf_Shdr symshdr_mem; GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); Elf_Data *symdata = elf_getdata (symscn, NULL); - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) + for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) { GElf_Rel rel_mem; - GElf_Rel *rel; - - rel = gelf_getrel (data, cnt, &rel_mem); + GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); if (rel == NULL) { ERROR (gettext ("\ @@ -1226,72 +1188,8 @@ section [%2d] '%s': cannot get relocation %zu: %s\n"), continue; } - if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))) - ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), - idx, section_name (ebl, idx), cnt); - else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rel->r_info))) - ERROR (gettext ("\ -section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), - idx, section_name (ebl, idx), cnt); - - if (symshdr != NULL - && ((GELF_R_SYM (rel->r_info) + 1) - * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) - > symshdr->sh_size)) - ERROR (gettext ("\ -section [%2d] '%s': relocation %zu: invalid symbol index\n"), - idx, section_name (ebl, idx), cnt); - - if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rel->r_info))) - { - const char *name; - char buf[64]; - GElf_Sym sym_mem; - GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rel->r_info), - &sym_mem); - if (sym != NULL - /* Get the name for the symbol. */ - && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) - && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) - ERROR (gettext ("\ -section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), - idx, section_name (ebl, idx), cnt, - ebl_reloc_type_name (ebl, GELF_R_SYM (rel->r_info), - buf, sizeof (buf))); - } - - if (reldyn) - { - // XXX TODO Check .rel.dyn section addresses. - } - else if (!known_broken) - { - if (destshdr != NULL - && GELF_R_TYPE (rel->r_info) != 0 - && (rel->r_offset - destshdr->sh_addr) >= destshdr->sh_size) - ERROR (gettext ("\ -section [%2d] '%s': relocation %zu: offset out of bounds\n"), - idx, section_name (ebl, idx), cnt); - } - - if (symdata != NULL - && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) - { - /* Make sure the referenced symbol is an object or unspecified. */ - GElf_Sym sym_mem; - GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rel->r_info), - &sym_mem); - if (sym != NULL - && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE - && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) - { - char buf[64]; - ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), - idx, section_name (ebl, idx), cnt, - ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), - buf, sizeof (buf))); - } - } + check_one_reloc (ebl, idx, cnt, symshdr, symdata, rel->r_offset, + rel->r_info, destshdr, reldyn); } } @@ -2267,11 +2165,11 @@ section [%2zu] '%s': ELF header says this is the section header string table but break; case SHT_RELA: - check_rela (ebl, ehdr, cnt); + check_rela (ebl, ehdr, shdr, cnt); break; case SHT_REL: - check_rel (ebl, ehdr, cnt); + check_rel (ebl, ehdr, shdr, cnt); break; case SHT_DYNAMIC: