diff options
| author | Roland McGrath <[email protected]> | 2009-01-21 19:47:02 -0800 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2009-01-21 19:47:02 -0800 |
| commit | f9a5ef258f7acbfee932e59d19c532ea264962bb (patch) | |
| tree | 3c1e81dfae5b1a79060f4529204efec460d26aac | |
| parent | 1d0786262b07d603e2a6e0295f8acf2d39cb9c49 (diff) | |
| parent | 1ea4fdca6f9b2be5a6ad02c18493145d2b669455 (diff) | |
Merge commit 'origin/master' into dwarf
Conflicts:
libdw/ChangeLog
src/ChangeLog
| -rw-r--r-- | libdw/ChangeLog | 6 | ||||
| -rw-r--r-- | libdw/Makefile.am | 3 | ||||
| -rw-r--r-- | libelf/ChangeLog | 12 | ||||
| -rw-r--r-- | libelf/elf32_updatefile.c | 20 | ||||
| -rw-r--r-- | libelf/note_xlate.h | 4 | ||||
| -rw-r--r-- | src/ChangeLog | 18 | ||||
| -rw-r--r-- | src/elfcmp.c | 34 | ||||
| -rw-r--r-- | src/elflint.c | 104 | ||||
| -rw-r--r-- | src/readelf.c | 13 |
9 files changed, 173 insertions, 41 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index d915349e..92435ab5 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -3,6 +3,12 @@ * c++/dwarf: New file. * Makefile.am (pkginclude_HEADERS): Add it. +2009-01-21 Roland McGrath <[email protected]> + + * Makefile.am (CLEANFILES): Renamed to ... + (MOSTLYCLEANFILES): ... here. + (CLEANFILES): New variable, add known-dwarf.h. + 2009-01-17 Roland McGrath <[email protected]> * Makefile.am (known-dwarf.h): Target renamed, not in $(srcdir). diff --git a/libdw/Makefile.am b/libdw/Makefile.am index d61a2951..0542f3ad 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -87,6 +87,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_entry_breakpoints.c BUILT_SOURCES = known-dwarf.h +CLEANFILES = known-dwarf.h known-dwarf.h: $(top_srcdir)/config/known-dwarf.awk $(srcdir)/dwarf.h $(AWK) -f $^ > [email protected] mv -f [email protected] $@ @@ -136,4 +137,4 @@ noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h EXTRA_DIST = libdw.map -CLEANFILES = $(am_libdw_pic_a_OBJECTS) *.gcno *.gcda libdw.so.$(VERSION) +MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) *.gcno *.gcda libdw.so.$(VERSION) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 36efd90e..be259e62 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,10 @@ +2009-01-21 Ulrich Drepper <[email protected]> + + * elf32_updatefile.c (elfXX_updatemmap): When skipping non-NOBITS + sections we haven't loaded, update last_position based on scn_start, + not based on old value. Don't run the loop for the dummy section 0. + (elfXX_updatefile): Don't run the loop for the dummy section 0. + 2009-01-10 Ulrich Drepper <[email protected]> * libelfP.h (_): We only have one translation domain, elfutils. @@ -5,6 +12,11 @@ * Makefile.am: Use USE_LOCKS instead of USE_TLS. * elf_error.c: Always use __thread. Remove all !USE_TLS code. +2009-01-04 Roland McGrath <[email protected]> + + * note_xlate.h (elf_cvt_note): Don't examine a size too small to + container a note header. + 2008-12-11 Roland McGrath <[email protected]> * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index e88f4a45..111e1d2b 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -283,6 +283,13 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) for (size_t cnt = 0; cnt < shnum; ++cnt) { Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to make this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + continue; + } ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); @@ -362,9 +369,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) dl = dl->next; } while (dl != NULL); - else if (shdr->sh_type != SHT_NOBITS && scn->index != 0) + else if (shdr->sh_type != SHT_NOBITS) /* We have to trust the existing section header information. */ - last_position += shdr->sh_size; + last_position = scn_start + shdr->sh_size; scn->flags &= ~ELF_F_DIRTY; } @@ -616,6 +623,13 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) for (size_t cnt = 0; cnt < shnum; ++cnt) { Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to make this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + continue; + } ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); @@ -695,7 +709,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) dl = dl->next; } while (dl != NULL); - else if (shdr->sh_type != SHT_NOBITS && scn->index != 0) + else if (shdr->sh_type != SHT_NOBITS) last_offset = scn_start + shdr->sh_size; /* Collect the section header table information. */ diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h index 6e8b78c6..a72fe868 100644 --- a/libelf/note_xlate.h +++ b/libelf/note_xlate.h @@ -1,5 +1,5 @@ /* Conversion functions for notes. - Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007, 2009 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -52,7 +52,7 @@ elf_cvt_note (void *dest, const void *src, size_t len, int encode) { assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); - while (len > 0) + while (len >= sizeof (Elf32_Nhdr)) { (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr), encode); diff --git a/src/ChangeLog b/src/ChangeLog index 0304e7f2..5139781f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -117,8 +117,20 @@ * dwarflint.c: Checking for zero padding and unreferenced bytes. CU size and padding at the end of CU are now checked. +2009-01-21 Ulrich Drepper <[email protected]> + + * elflint.c (check_program_header): Fix typo in .eh_frame_hdr section + test. Handle debuginfo files. + (check_exception_data): First sanity test. + 2009-01-17 Ulrich Drepper <[email protected]> + * readelf.c (print_debug_exception_table): Show target of ar_disp + field. + + * elflint.c (check_program_header): Add most consistency checks for + PT_GNU_EH_FRAME entry. + * addr2line.c: Use ARGP_PROGRAM_VERSION_HOOK_DEF and ARGP_PROGRAM_BUG_ADDRESS_DEF. * ar.c: Likewise. @@ -130,6 +142,7 @@ * objdump.c: Likewise. * ranlib.c: Likewise. * readelf.c: Likewise. + * size.c: Likewise. * strings.c: Likewise. * strip.c: Likewise. @@ -200,6 +213,11 @@ * readelf.c: Implement call frame debug section dumping. +2009-01-05 Roland McGrath <[email protected]> + + * elfcmp.c: Exit with status 2 for errors (like cmp, diff, grep). + Status 1 (aka EXIT_FAILURE) is only for completed OK but not equal. + 2009-01-01 Ulrich Drepper <[email protected]> * addr2line.c: Update copyright year. diff --git a/src/elfcmp.c b/src/elfcmp.c index a1596365..7f871ecf 100644 --- a/src/elfcmp.c +++ b/src/elfcmp.c @@ -165,12 +165,12 @@ main (int argc, char *argv[]) GElf_Ehdr ehdr1_mem; GElf_Ehdr *ehdr1 = gelf_getehdr (elf1, &ehdr1_mem); if (ehdr1 == NULL) - error (EXIT_FAILURE, 0, gettext ("cannot get ELF header of '%s': %s"), + error (2, 0, gettext ("cannot get ELF header of '%s': %s"), fname1, elf_errmsg (-1)); GElf_Ehdr ehdr2_mem; GElf_Ehdr *ehdr2 = gelf_getehdr (elf2, &ehdr2_mem); if (ehdr2 == NULL) - error (EXIT_FAILURE, 0, gettext ("cannot get ELF header of '%s': %s"), + error (2, 0, gettext ("cannot get ELF header of '%s': %s"), fname2, elf_errmsg (-1)); /* Compare the ELF headers. */ @@ -272,13 +272,13 @@ main (int argc, char *argv[]) Elf_Data *data1 = elf_getdata (scn1, NULL); if (data1 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get content of section %zu in '%s': %s"), elf_ndxscn (scn1), fname1, elf_errmsg (-1)); Elf_Data *data2 = elf_getdata (scn2, NULL); if (data2 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get content of section %zu in '%s': %s"), elf_ndxscn (scn2), fname2, elf_errmsg (-1)); @@ -294,13 +294,13 @@ main (int argc, char *argv[]) GElf_Sym sym1_mem; GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem); if (sym1 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get symbol in '%s': %s"), fname1, elf_errmsg (-1)); GElf_Sym sym2_mem; GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem); if (sym2 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get symbol in '%s': %s"), fname2, elf_errmsg (-1)); @@ -427,12 +427,12 @@ main (int argc, char *argv[]) { raw1 = elf_rawfile (elf1, &size1); if (raw1 == NULL ) - error (EXIT_FAILURE, 0, gettext ("cannot load data of '%s': %s"), + error (2, 0, gettext ("cannot load data of '%s': %s"), fname1, elf_errmsg (-1)); raw2 = elf_rawfile (elf2, &size2); if (raw2 == NULL ) - error (EXIT_FAILURE, 0, gettext ("cannot load data of '%s': %s"), + error (2, 0, gettext ("cannot load data of '%s': %s"), fname2, elf_errmsg (-1)); for (size_t cnt = 0; cnt < nregions; ++cnt) @@ -450,13 +450,13 @@ main (int argc, char *argv[]) GElf_Phdr phdr1_mem; GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem); if (ehdr1 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get program header entry %d of '%s': %s"), ndx, fname1, elf_errmsg (-1)); GElf_Phdr phdr2_mem; GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem); if (ehdr2 == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get program header entry %d of '%s': %s"), ndx, fname2, elf_errmsg (-1)); @@ -571,15 +571,15 @@ open_file (const char *fname, int *fdp, Ebl **eblp) { int fd = open (fname, O_RDONLY); if (unlikely (fd == -1)) - error (EXIT_FAILURE, errno, gettext ("cannot open '%s'"), fname); + error (2, errno, gettext ("cannot open '%s'"), fname); Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); if (elf == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot create ELF descriptor for '%s': %s"), fname, elf_errmsg (-1)); Ebl *ebl = ebl_openbackend (elf); if (ebl == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot create EBL descriptor for '%s'"), fname); *fdp = fd; @@ -597,7 +597,7 @@ search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); if (shdr == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get section header of section %zu: %s"), elf_ndxscn (scn), elf_errmsg (-1)); @@ -607,7 +607,7 @@ search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) Elf_Data *data = elf_getdata (scn, NULL); if (data == NULL) - error (EXIT_FAILURE, 0, + error (2, 0, gettext ("cannot get content of section %zu: %s"), elf_ndxscn (scn), elf_errmsg (-1)); @@ -618,7 +618,7 @@ search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) GElf_Rel rel_mem; GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem); if (rel == NULL) - error (EXIT_FAILURE, 0, gettext ("cannot get relocation: %s"), + error (2, 0, gettext ("cannot get relocation: %s"), elf_errmsg (-1)); if ((int) GELF_R_SYM (rel->r_info) == symndx @@ -632,7 +632,7 @@ search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) GElf_Rela rela_mem; GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem); if (rela == NULL) - error (EXIT_FAILURE, 0, gettext ("cannot get relocation: %s"), + error (2, 0, gettext ("cannot get relocation: %s"), elf_errmsg (-1)); if ((int) GELF_R_SYM (rela->r_info) == symndx diff --git a/src/elflint.c b/src/elflint.c index 1c508c47..826d94c3 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -3358,6 +3358,13 @@ static const struct && !memcmp (special_sections[idx].name, string, \ sizeof string - (prefix ? 1 : 0))) + +/* Indeces of some sections we need later. */ +static size_t eh_frame_hdr_scnndx; +static size_t eh_frame_scnndx; +static size_t gcc_except_table_scnndx; + + static void check_sections (Ebl *ebl, GElf_Ehdr *ehdr) { @@ -3554,6 +3561,14 @@ section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n break; } + + /* Remember a few special sections for later. */ + if (strcmp (scnname, ".eh_frame_hdr") == 0) + eh_frame_hdr_scnndx = cnt; + else if (strcmp (scnname, ".eh_frame") == 0) + eh_frame_scnndx = cnt; + else if (strcmp (scnname, ".gcc_except_table") == 0) + gcc_except_table_scnndx = cnt; } if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) @@ -3961,6 +3976,7 @@ section [%2d] '%s': unknown object file note type %" PRIu32 return last_offset; } + static void check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) { @@ -3992,6 +4008,7 @@ phdr[%d]: no note entries defined for the type of file\n"), cnt, phdr->p_filesz - notes_size); } + static void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) { @@ -4023,6 +4040,11 @@ section [%2d] '%s': no note entries defined for the type of file\n"), idx, section_name (ebl, idx), shdr->sh_size - notes_size); } + +/* Index of the PT_GNU_EH_FRAME program eader entry. */ +static int pt_gnu_eh_frame_pndx; + + static void check_program_header (Ebl *ebl, GElf_Ehdr *ehdr) { @@ -4177,35 +4199,71 @@ program header offset in ELF header and PHDR entry do not match")); /* If there is an .eh_frame_hdr section it must be referenced by this program header entry. */ Elf_Scn *scn = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + bool any = false; while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) { - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr != NULL && shdr->sh_type == SHT_PROGBITS + any = true; + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL + && shdr->sh_type == (is_debuginfo + ? SHT_NOBITS : SHT_PROGBITS) && ! strcmp (".eh_frame_hdr", elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) { - if (phdr->p_offset != shdr->sh_offset) - ERROR (gettext ("\ + if (! is_debuginfo) + { + if (phdr->p_offset != shdr->sh_offset) + ERROR (gettext ("\ call frame search table reference in program header has wrong offset\n")); - if (phdr->p_memsz != shdr->sh_size) - ERROR (gettext ("\ + if (phdr->p_memsz != shdr->sh_size) + ERROR (gettext ("\ call frame search table size mismatch in program and section header\n")); + } break; } } - /* The section must be allocated and not be writable and - executable. */ - if ((phdr->p_flags & PF_R) == 0) - ERROR (gettext ("\ + if (scn == NULL) + { + /* If there is no section header table we don't + complain. But if there is one there should be an + entry for .eh_frame_hdr. */ + if (any) + ERROR (gettext ("\ +PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n")); + } + else + { + /* The section must be allocated and not be writable and + executable. */ + if ((phdr->p_flags & PF_R) == 0) + ERROR (gettext ("\ call frame search table must be allocated\n")); - if ((phdr->p_flags & PF_W) != 0) - ERROR (gettext ("\ + else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0) + ERROR (gettext ("\ +section [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr"); + + if ((phdr->p_flags & PF_W) != 0) + ERROR (gettext ("\ call frame search table must not be writable\n")); - if ((phdr->p_flags & PF_X) != 0) - ERROR (gettext ("\ + else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0) + ERROR (gettext ("\ +section [%2zu] '%s' must not be writable\n"), + elf_ndxscn (scn), ".eh_frame_hdr"); + + if ((phdr->p_flags & PF_X) != 0) + ERROR (gettext ("\ call frame search table must not be executable\n")); + else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0) + ERROR (gettext ("\ +section [%2zu] '%s' must not be executable\n"), + elf_ndxscn (scn), ".eh_frame_hdr"); + } + + /* Remember which entry this is. */ + pt_gnu_eh_frame_pndx = cnt; } if (phdr->p_filesz > phdr->p_memsz @@ -4227,6 +4285,17 @@ program header entry %d: file offset and virtual address not module of alignment } +static void +check_exception_data (Ebl *ebl __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused))) +{ + if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) + && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0) + ERROR (gettext ("executable/DSO with .eh_frame_hdr section does not have " + "a PT_GNU_EH_FRAME program header entry")); +} + + /* Process one file. */ static void process_elf_file (Elf *elf, const char *prefix, const char *suffix, @@ -4275,6 +4344,11 @@ process_elf_file (Elf *elf, const char *prefix, const char *suffix, headers at all. */ check_sections (ebl, ehdr); + /* Check the exception handling data, if it exists. */ + if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0 + || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0) + check_exception_data (ebl, ehdr); + /* Report if no relocation section needed the text relocation flag. */ if (textrel && !needed_textrel) ERROR (gettext ("text relocation flag set but not needed\n")); diff --git a/src/readelf.c b/src/readelf.c index a7df58bd..1680fe30 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -5602,9 +5602,16 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), int ar_disp; get_sleb128 (ar_disp, readp); - printf (" [%4u] ar_filter: %d\n" - " ar_disp: %d\n", - u++, ar_filter, ar_disp); + printf (" [%4u] ar_filter: % d\n" + " ar_disp: % -5d", + u, ar_filter, ar_disp); + if (abs (ar_disp) & 1) + printf (" -> [%4u]\n", u + (ar_disp + 1) / 2); + else if (ar_disp != 0) + puts (" -> ???"); + else + putchar_unlocked ('\n'); + ++u; } while (readp < action_table_end); } |
