summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2009-01-21 19:47:02 -0800
committerRoland McGrath <[email protected]>2009-01-21 19:47:02 -0800
commitf9a5ef258f7acbfee932e59d19c532ea264962bb (patch)
tree3c1e81dfae5b1a79060f4529204efec460d26aac
parent1d0786262b07d603e2a6e0295f8acf2d39cb9c49 (diff)
parent1ea4fdca6f9b2be5a6ad02c18493145d2b669455 (diff)
Merge commit 'origin/master' into dwarf
Conflicts: libdw/ChangeLog src/ChangeLog
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/Makefile.am3
-rw-r--r--libelf/ChangeLog12
-rw-r--r--libelf/elf32_updatefile.c20
-rw-r--r--libelf/note_xlate.h4
-rw-r--r--src/ChangeLog18
-rw-r--r--src/elfcmp.c34
-rw-r--r--src/elflint.c104
-rw-r--r--src/readelf.c13
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]
@@ -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);
}