diff options
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | libdw/ChangeLog | 15 | ||||
-rw-r--r-- | libdw/dwarf_getattrs.c | 33 | ||||
-rw-r--r-- | libdw/dwarf_getsrclines.c | 6 | ||||
-rw-r--r-- | libdw/dwarf_ranges.c | 11 | ||||
-rw-r--r-- | libdw/libdwP.h | 41 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 5 | ||||
-rw-r--r-- | libdwfl/dwfl_report_elf.c | 3 | ||||
-rw-r--r-- | m4/ChangeLog | 4 | ||||
-rw-r--r-- | m4/zip.m4 | 7 | ||||
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/readelf.c | 52 |
12 files changed, 146 insertions, 49 deletions
@@ -1,7 +1,7 @@ ToDo list for elfutils -*-outline-*- ---------------------- -Time-stamp: <2009-01-26 13:07:11 drepper> +Time-stamp: <2009-02-05 22:08:01 drepper> * mkinstalldirs @@ -110,6 +110,13 @@ Time-stamp: <2009-01-26 13:07:11 drepper> Not implemented at all in the moment except for recognition of the option itself. +** variables with aliases in executables + + When linking an executable with a references against a variable in a + DSO, create symbol table entries for all the aliases of the variable + in the DSO and create a relocation for one of them (a non-weak + definition) + * elflint ** additional checks diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 6ee143f7..d66f34b0 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,18 @@ +2009-01-28 Roland McGrath <roland@redhat.com> + + * libdwP.h (struct Dwarf_Line_s): Move out of struct Dwarf_Lines_s + defn so C++ doesn't scope the name to not match the Dwarf_Line typedef. + + * libdwP.h (struct Dwarf_Files_s): Replace dbg field with cu field. + +2009-01-26 Roland McGrath <roland@redhat.com> + + * dwarf_ranges.c: Return 0 when no ranges or *_pc attrs at all. + +2009-01-25 Roland McGrath <roland@redhat.com> + + * dwarf_getattrs.c: Correctly skip attribute values when restarting. + 2009-01-23 Roland McGrath <roland@redhat.com> * Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back. diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c index 42f25ca0..051dc25f 100644 --- a/libdw/dwarf_getattrs.c +++ b/libdw/dwarf_getattrs.c @@ -1,5 +1,5 @@ /* Get attributes of the DIE. - Copyright (C) 2004, 2005, 2008 Red Hat, Inc. + Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -62,6 +62,9 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), if (die == NULL) return -1l; + if (unlikely (offset == 1)) + return 1; + const unsigned char *die_addr = die->addr; /* Get the abbreviation code. */ @@ -80,7 +83,8 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), } /* This is where the attributes start. */ - const unsigned char *attrp = die->abbrev->attrp + offset; + const unsigned char *attrp = die->abbrev->attrp; + const unsigned char *const offset_attrp = die->abbrev->attrp + offset; /* Go over the list of attributes. */ Dwarf *dbg = die->cu->dbg; @@ -108,16 +112,21 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), offset of an attribute. */ return 1l; - /* Fill in the rest. */ - attr.valp = (unsigned char *) die_addr; - attr.cu = die->cu; - - /* Now call the callback function. */ - if (callback (&attr, arg) != DWARF_CB_OK) - /* Return the offset of the start of the attribute, so that - dwarf_getattrs() can be restarted from this point if the - caller so desires. */ - return remembered_attrp - die->abbrev->attrp; + /* If we are not to OFFSET_ATTRP yet, we just have to skip + the values of the intervening attributes. */ + if (remembered_attrp >= offset_attrp) + { + /* Fill in the rest. */ + attr.valp = (unsigned char *) die_addr; + attr.cu = die->cu; + + /* Now call the callback function. */ + if (callback (&attr, arg) != DWARF_CB_OK) + /* Return the offset of the start of the attribute, so that + dwarf_getattrs() can be restarted from this point if the + caller so desires. */ + return remembered_attrp - die->abbrev->attrp; + } /* Skip over the rest of this attribute (if there is any). */ if (attr.form != 0) diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 9b3c97af..fe0e67d6 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -1,5 +1,5 @@ /* Return line number information of CU. - Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc. + Copyright (C) 2004-2009 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -634,8 +634,8 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) dirs[i] = dirarray[i]->dir; dirs[ndirlist] = NULL; - /* Remember the debugging descriptor. */ - files->dbg = dbg; + /* Remember the referring CU. */ + files->cu = cu; /* Make the file data structure available through the CU. */ cu->files = files; diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c index 89da0af4..1eef617b 100644 --- a/libdw/dwarf_ranges.c +++ b/libdw/dwarf_ranges.c @@ -1,5 +1,5 @@ /* Enumerate the PC ranges covered by a DIE. - Copyright (C) 2005, 2007 Red Hat, Inc. + Copyright (C) 2005, 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 @@ -78,8 +78,9 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, /* We have to look for a noncontiguous range. */ const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges]; - if (d == NULL) + if (d == NULL && offset != 0) { + no_ranges: __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES); return -1; } @@ -90,13 +91,17 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges, &attr_mem); if (attr == NULL) - return -1; + /* No PC attributes in this DIE at all, so an empty range list. */ + return 0; /* Must have the form data4 or data8 which act as an offset. */ Dwarf_Word start_offset; if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0) return -1; + if (d == NULL) + goto no_ranges; + offset = start_offset; assert ((Dwarf_Word) offset == start_offset); diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 867ad89b..1d5a9b27 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -1,5 +1,5 @@ /* Internal definitions for libdwarf. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. + Copyright (C) 2002-2009 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -208,7 +208,7 @@ struct Dwarf_Abbrev /* Files in line information records. */ struct Dwarf_Files_s { - Dwarf *dbg; + struct Dwarf_CU *cu; unsigned int ndirs; unsigned int nfiles; struct Dwarf_Fileinfo_s @@ -223,26 +223,27 @@ typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; /* Representation of a row in the line table. */ -struct Dwarf_Lines_s - { - size_t nlines; - struct Dwarf_Line_s - { - Dwarf_Addr addr; - unsigned int file; - int line; - unsigned short int column; - unsigned int is_stmt:1; - unsigned int basic_block:1; - unsigned int end_sequence:1; - unsigned int prologue_end:1; - unsigned int epilogue_begin:1; - - Dwarf_Files *files; - } info[0]; - }; +struct Dwarf_Line_s +{ + Dwarf_Addr addr; + unsigned int file; + int line; + unsigned short int column; + unsigned int is_stmt:1; + unsigned int basic_block:1; + unsigned int end_sequence:1; + unsigned int prologue_end:1; + unsigned int epilogue_begin:1; + Dwarf_Files *files; +}; + +struct Dwarf_Lines_s +{ + size_t nlines; + struct Dwarf_Line_s info[0]; +}; /* Representation of address ranges. */ struct Dwarf_Aranges_s diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 5490f5f0..aafa1c92 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,8 @@ +2009-01-27 Roland McGrath <roland@redhat.com> + + * dwfl_report_elf.c (__libdwfl_report_elf): Ignore trailing PT_LOAD + with zero vaddr and memsz. + 2009-01-22 Roland McGrath <roland@redhat.com> * open.c (decompress): Move BUFFER, SIZE decls outside #if. diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c index 3482a229..9fc156fe 100644 --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@ -208,7 +208,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem); if (unlikely (ph == NULL)) goto elf_error; - if (ph->p_type == PT_LOAD) + if (ph->p_type == PT_LOAD + && ph->p_vaddr + ph->p_memsz > 0) { end = base + (ph->p_vaddr + ph->p_memsz); break; diff --git a/m4/ChangeLog b/m4/ChangeLog index eea78ff0..25675634 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2009-02-01 Roland McGrath <roland@redhat.com> + + * zip.m4: Fix --with/--without argument handling. + 2009-01-08 Roland McGrath <roland@redhat.com> * zip.am: New file. @@ -1,10 +1,11 @@ -dnl Test for either zlib or bzlib. +dnl -*- Autoconf -*- test for either zlib or bzlib. dnl Defines --with-$1lib argument, $2LIB automake conditional, dnl and sets AC_DEFINE(USE_$2LIB) and LIBS. -AC_DEFUN([eu_ZIPLIB], [with_[$1]lib=default +AC_DEFUN([eu_ZIPLIB], [dnl AC_ARG_WITH([[$1]lib], -AC_HELP_STRING([--with-[$1]lib], [support g[$1]ip compression in libdwfl])) +AC_HELP_STRING([--with-[$1]lib], [support g[$1]ip compression in libdwfl]),, + [with_[$1]lib=default]) if test $with_[$1]lib != no; then AC_SEARCH_LIBS([$4], [$3], [with_[$1]lib=yes], [test $with_[$1]lib = default || diff --git a/src/ChangeLog b/src/ChangeLog index 71a6da2f..287ead38 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -19,6 +19,15 @@ * objdump.c (parse_opt): Likewise. * readelf.c (parse_opt): Likewise. +2009-01-27 Roland McGrath <roland@redhat.com> + + * readelf.c (print_ops): Notice short length, don't overrun buffer + (still need to fix LEB128). + + * readelf.c (print_ops): Fix DW_OP_call[24] decoding. + + * readelf.c (print_ops): Print (empty)\n when LEN == 0. + 2009-01-24 Ulrich Drepper <drepper@redhat.com> * readelf.c (print_debug_frame_section): Fix computation of vma_base diff --git a/src/readelf.c b/src/readelf.c index 51ce144d..c9f18896 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3785,6 +3785,14 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, [DW_OP_bit_piece] = "bit_piece", }; + if (len == 0) + { + printf ("%*s(empty)\n", indent, ""); + return; + } + +#define NEED(n) if (len < n) goto invalid; + Dwarf_Word offset = 0; while (len-- > 0) { @@ -3796,6 +3804,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_addr:; /* Address operand. */ Dwarf_Word addr; + NEED (addrsize); if (addrsize == 4) addr = read_4ubyte_unaligned (dbg, data); else @@ -3825,6 +3834,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_pick: case DW_OP_const1u: // XXX value might be modified by relocation + NEED (1); printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", indent, "", (uintmax_t) offset, known[op], *((uint8_t *) data)); @@ -3834,6 +3844,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const2u: + NEED (2); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", indent, "", (uintmax_t) offset, @@ -3844,6 +3855,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const4u: + NEED (4); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", indent, "", (uintmax_t) offset, @@ -3854,6 +3866,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const8u: + NEED (8); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", indent, "", (uintmax_t) offset, @@ -3864,6 +3877,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const1s: + NEED (1); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", indent, "", (uintmax_t) offset, @@ -3874,6 +3888,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const2s: + NEED (2); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", indent, "", (uintmax_t) offset, @@ -3884,6 +3899,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const4s: + NEED (4); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n", indent, "", (uintmax_t) offset, @@ -3894,6 +3910,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_const8s: + NEED (8); // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", indent, "", (uintmax_t) offset, @@ -3909,7 +3926,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_constu:; const unsigned char *start = data; unsigned int uleb; - get_uleb128 (uleb, data); + get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %u\n", indent, "", (uintmax_t) offset, known[op], uleb); len -= data - start; @@ -3919,8 +3936,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_bit_piece: start = data; unsigned int uleb2; - get_uleb128 (uleb, data); - get_uleb128 (uleb2, data); + get_uleb128 (uleb, data); /* XXX check overrun */ + get_uleb128 (uleb2, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %u, %u\n", indent, "", (uintmax_t) offset, known[op], uleb, uleb2); len -= data - start; @@ -3932,7 +3949,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_consts: start = data; unsigned int sleb; - get_sleb128 (sleb, data); + get_sleb128 (sleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %d\n", indent, "", (uintmax_t) offset, known[op], sleb); len -= data - start; @@ -3941,8 +3958,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_bregx: start = data; - get_uleb128 (uleb, data); - get_sleb128 (sleb, data); + get_uleb128 (uleb, data); /* XXX check overrun */ + get_sleb128 (sleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %u %d\n", indent, "", (uintmax_t) offset, known[op], uleb, sleb); len -= data - start; @@ -3950,9 +3967,26 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, break; case DW_OP_call2: + NEED (2); + printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", + indent, "", (uintmax_t) offset, known[op], + read_2ubyte_unaligned (dbg, data)); + len -= 2; + offset += 3; + break; + case DW_OP_call4: + NEED (4); + printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", + indent, "", (uintmax_t) offset, known[op], + read_4ubyte_unaligned (dbg, data)); + len -= 4; + offset += 5; + break; + case DW_OP_skip: case DW_OP_bra: + NEED (2); printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n", indent, "", (uintmax_t) offset, known[op], (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data))); @@ -3974,6 +4008,12 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, } indent = indentrest; + continue; + + invalid: + printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"), + indent, "", (uintmax_t) offset, known[op]); + break; } } |