diff options
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | config/elfutils.spec.in | 6 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | libdw/ChangeLog | 21 | ||||
-rw-r--r-- | libdw/cfi.c | 47 | ||||
-rw-r--r-- | libdw/cfi.h | 9 | ||||
-rw-r--r-- | libdw/dwarf_frame_cfa.c | 7 | ||||
-rw-r--r-- | libdw/dwarf_frame_register.c | 4 | ||||
-rw-r--r-- | libdw/dwarf_getlocation.c | 21 | ||||
-rw-r--r-- | libdw/libdwP.h | 4 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 6 | ||||
-rw-r--r-- | libdwfl/relocate.c | 11 | ||||
-rw-r--r-- | po/de.po | 2 | ||||
-rw-r--r-- | po/es.po | 2 | ||||
-rw-r--r-- | po/ja.po | 2 | ||||
-rw-r--r-- | po/pl.po | 2 | ||||
-rw-r--r-- | po/uk.po | 2 | ||||
-rw-r--r-- | tests/ChangeLog | 5 | ||||
-rw-r--r-- | tests/addrcfi.c | 4 |
19 files changed, 123 insertions, 42 deletions
@@ -1,3 +1,9 @@ +Version 0.147: + +libdw: Fixes in CFI handling, best possible handling of bogus CFA ops. + +libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r bugs. + Version 0.146: libdwfl: New function dwfl_core_file_report. diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in index 9dab9906..102d723f 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -183,6 +183,12 @@ rm -rf ${RPM_BUILD_ROOT} %{_libdir}/libelf.a %changelog +* Mon May 3 2010 Ulrich Drepper <drepper@redhat.com> 0.147-1 +- libdw: Fixes in CFI handling, best possible handling of bogus CFA + ops. +- libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r + bugs. + * Wed Apr 21 2010 <drepper@redhat.com> 0.146-1 - libdwfl: New function dwfl_core_file_report. diff --git a/configure.ac b/configure.ac index 80087873..53cd8c05 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. dnl Configure input file for elfutils. -*-autoconf-*- dnl -dnl Copyright (C) 1996-2009, 2010 Red Hat, Inc. +dnl Copyright (C) 1996-2010 Red Hat, Inc. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by @@ -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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. dnl -AC_INIT([Red Hat elfutils],[0.146],[http://bugzilla.redhat.com/bugzilla/],[elfutils]) +AC_INIT([Red Hat elfutils],[0.147],[http://bugzilla.redhat.com/bugzilla/],[elfutils]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_FILES([config/Makefile]) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index bda46082..c16e91d5 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,24 @@ +2010-04-26 Roland McGrath <roland@redhat.com> + + * cfi.h (struct Dwarf_Frame_s): Add cfa_invalid alternative in cfa_rule. + * cfi.c (execute_cfi): Set that instead of doing cfi_assert for + DW_CFA_def_cfa_{offset*,register} when a non-offset rule is in force. + * dwarf_frame_cfa.c (dwarf_frame_cfa): Handle cfa_invalid. + + * dwarf_getlocation.c (__libdw_intern_expression): Take new arg CFAP. + Prepend DW_OP_call_frame_cfa if true. + (getlocation): Update caller. + * dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise. + * dwarf_frame_register.c (dwarf_frame_register): Likewise. + * libdwP.h: Update decl. + +2010-04-22 Roland McGrath <roland@redhat.com> + + * cfi.c (execute_cfi): Never return without cleanup. + Free FS on failure. + (cie_cache_initial_state): Adjust caller to expect that free. + (__libdw_frame_at_address): Likewise. + 2010-03-10 Roland McGrath <roland@redhat.com> * libdw.map (ELFUTILS_0.146): New set. Add dwfl_core_file_report. diff --git a/libdw/cfi.c b/libdw/cfi.c index ac197833..3cb378b6 100644 --- a/libdw/cfi.c +++ b/libdw/cfi.c @@ -1,5 +1,5 @@ /* CFI program execution. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -76,7 +76,8 @@ duplicate_frame_state (const Dwarf_Frame *original, return copy; } -/* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI. */ +/* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI. + Frees *STATE on failure. */ static int execute_cfi (Dwarf_CFI *cache, const struct dwarf_cie *cie, @@ -116,6 +117,12 @@ execute_cfi (Dwarf_CFI *cache, return true; } + inline void require_cfa_offset (void) + { + if (unlikely (fs->cfa_rule != cfa_offset)) + fs->cfa_rule = cfa_invalid; + } + #define register_rule(regno, r_rule, r_value) do { \ if (unlikely (! enough_registers (regno))) \ goto out; \ @@ -152,10 +159,11 @@ execute_cfi (Dwarf_CFI *cache, goto advance_loc; case DW_CFA_set_loc: - if (unlikely (read_encoded_value (cache, cie->fde_encoding, &program, - &loc))) - return INTUSE(dwarf_errno) (); - break; + if (likely (!read_encoded_value (cache, cie->fde_encoding, + &program, &loc))) + break; + result = INTUSE(dwarf_errno) (); + goto out; /* Now all following cases affect this row, but do not touch LOC. These cases end with 'continue'. We only get out of the @@ -175,7 +183,7 @@ execute_cfi (Dwarf_CFI *cache, case DW_CFA_def_cfa_register: get_uleb128 (regno, program); - cfi_assert (fs->cfa_rule == cfa_offset); + require_cfa_offset (); fs->cfa_val_reg = regno; continue; @@ -188,7 +196,7 @@ execute_cfi (Dwarf_CFI *cache, case DW_CFA_def_cfa_offset: get_uleb128 (offset, program); def_cfa_offset: - cfi_assert (fs->cfa_rule == cfa_offset); + require_cfa_offset (); fs->cfa_val_offset = offset; continue; @@ -323,8 +331,8 @@ execute_cfi (Dwarf_CFI *cache, cfi_assert (prev != NULL); free (fs); fs = prev; + continue; } - continue; case DW_CFA_nop: continue; @@ -395,8 +403,10 @@ execute_cfi (Dwarf_CFI *cache, free (prev); } - if (result == DWARF_E_NOERROR) + if (likely (result == DWARF_E_NOERROR)) *state = fs; + else + free (fs); return result; } @@ -458,17 +468,14 @@ cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie) cie->initial_instructions_end, false, 0, (Dwarf_Addr) -1l); - if (unlikely (result != DWARF_E_NOERROR)) + if (likely (result == DWARF_E_NOERROR)) { - free (cie_fs); - return result; + /* Now we have the initial state of things that all + FDEs using this CIE will start from. */ + cie_fs->cache = cache; + cie->initial_state = cie_fs; } - /* Now we have the initial state of things that all - FDEs using this CIE will start from. */ - cie_fs->cache = cache; - cie->initial_state = cie_fs; - return result; } @@ -491,9 +498,7 @@ __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, result = execute_cfi (cache, fde->cie, &fs, fde->instructions, fde->instructions_end, false, fde->start, address); - if (unlikely (result != DWARF_E_NOERROR)) - free (fs); - else + if (likely (result == DWARF_E_NOERROR)) *frame = fs; } return result; diff --git a/libdw/cfi.h b/libdw/cfi.h index 64f3f157..e04e76dd 100644 --- a/libdw/cfi.h +++ b/libdw/cfi.h @@ -1,5 +1,5 @@ /* Internal definitions for libdw CFI interpreter. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -191,8 +191,11 @@ struct Dwarf_Frame_s which has the return_address_register and signal_frame flag. */ struct dwarf_fde *fde; - /* The CFA is unknown, is R+N, or is computed by a DWARF expression. */ - enum { cfa_undefined, cfa_offset, cfa_expr } cfa_rule; + /* The CFA is unknown, is R+N, or is computed by a DWARF expression. + A bogon in the CFI can indicate an invalid/incalculable rule. + We store that as cfa_invalid rather than barfing when processing it, + so callers can ignore the bogon unless they really need that CFA. */ + enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule; union { Dwarf_Op offset; diff --git a/libdw/dwarf_frame_cfa.c b/libdw/dwarf_frame_cfa.c index d1c57108..0ba26b2f 100644 --- a/libdw/dwarf_frame_cfa.c +++ b/libdw/dwarf_frame_cfa.c @@ -84,10 +84,15 @@ dwarf_frame_cfa (fs, ops, nops) result = __libdw_intern_expression (NULL, fs->cache->other_byte_order, fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8, - &fs->cache->expr_tree, &fs->cfa_data.expr, false, + &fs->cache->expr_tree, &fs->cfa_data.expr, false, false, ops, nops, IDX_debug_frame); break; + case cfa_invalid: + __libdw_seterrno (DWARF_E_INVALID_CFI); + result = -1; + break; + default: abort (); } diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c index 3d232e95..e42b76bf 100644 --- a/libdw/dwarf_frame_register.c +++ b/libdw/dwarf_frame_register.c @@ -1,5 +1,5 @@ /* Get register location expression for frame. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -131,7 +131,7 @@ dwarf_frame_register (fs, regno, ops_mem, ops, nops) fs->cache->other_byte_order, address_size, &fs->cache->expr_tree, &block, - reg->rule == reg_val_expression, + true, reg->rule == reg_val_expression, ops, nops, IDX_debug_frame) < 0) return -1; break; diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 720b20f4..f362fe22 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -1,5 +1,5 @@ /* Return location expression list. - Copyright (C) 2000-2009 Red Hat, Inc. + Copyright (C) 2000-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -221,7 +221,8 @@ int internal_function __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, unsigned int address_size, - void **cache, const Dwarf_Block *block, bool valuep, + void **cache, const Dwarf_Block *block, + bool cfap, bool valuep, Dwarf_Op **llbuf, size_t *listlen, int sec_index) { /* Check whether we already looked at this list. */ @@ -444,6 +445,9 @@ __libdw_intern_expression (Dwarf *dbg, ++n; } + if (cfap) + ++n; + /* Allocate the array. */ Dwarf_Op *result; if (dbg != NULL) @@ -463,6 +467,16 @@ __libdw_intern_expression (Dwarf *dbg, *llbuf = result; *listlen = n; + if (cfap) + { + /* Synthesize the operation to push the CFA before the expression. */ + --n; + result[0].atom = DW_OP_call_frame_cfa; + result[0].number = 0; + result[0].number2 = 0; + result[0].offset = -1; + } + do { /* We populate the array from the back since the list is backwards. */ @@ -507,7 +521,8 @@ getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, Dwarf_Op **llbuf, size_t *listlen, int sec_index) { return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, - cu->address_size, &cu->locs, block, false, + cu->address_size, &cu->locs, block, + false, false, llbuf, listlen, sec_index); } diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 99f53680..7a3a360a 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -440,10 +440,10 @@ extern int __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, unsigned int address_size, void **cache, const Dwarf_Block *block, - bool valuep, + bool cfap, bool valuep, Dwarf_Op **llbuf, size_t *listlen, int sec_index) - __nonnull_attribute__ (4, 5, 7, 8) internal_function; + __nonnull_attribute__ (4, 5, 8, 9) internal_function; /* Return error code of last failing function call. This value is kept diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 54ac53fa..a9f36d96 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2010-04-26 Roland McGrath <roland@redhat.com> + + * relocate.c (relocate_section): Treat R_*_NONE reloc as no reloc. + Works around probably-wrong ld -r behavior for case of a DWARF address + constant that refers to a discarded SHF_ALLOC section. + 2010-04-14 Roland McGrath <roland@redhat.com> * link_map.c (report_r_debug): Limit iterations on the l_next chain to diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c index 121a481b..0075c7f9 100644 --- a/libdwfl/relocate.c +++ b/libdwfl/relocate.c @@ -1,5 +1,5 @@ /* Relocate debug information. - Copyright (C) 2005-2009 Red Hat, Inc. + Copyright (C) 2005-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -325,6 +325,15 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr, { /* First see if this is a reloc we can handle. If we are skipping it, don't bother resolving the symbol. */ + + if (unlikely (rtype == 0)) + /* In some odd situations, the linker can leave R_*_NONE relocs + behind. This is probably bogus ld -r behavior, but the only + cases it's known to appear in are harmless: DWARF data + referring to addresses in a section that has been discarded. + So we just pretend it's OK without further relocation. */ + return DWFL_E_NOERROR; + Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype); if (unlikely (type == ELF_T_NUM)) return DWFL_E_BADRELTYPE; @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: elfutils VERSION\n" "Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n" -"POT-Creation-Date: 2010-04-21 07:41-0700\n" +"POT-Creation-Date: 2010-05-03 14:14-0700\n" "PO-Revision-Date: 2009-06-29 15:15+0200\n" "Last-Translator: Michael Münch <micm@fedoraproject.org>\n" "Language-Team: German\n" @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: elfutils.master.es\n" "Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n" -"POT-Creation-Date: 2010-04-21 07:41-0700\n" +"POT-Creation-Date: 2010-05-03 14:14-0700\n" "PO-Revision-Date: 2010-04-19 10:51-0300\n" "Last-Translator: Héctor Daniel Cabrera <logan@fedoraproject.org>\n" "Language-Team: Fedora Spanish <trans-es@lists.fedoraproject.org>\n" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ja\n" "Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n" -"POT-Creation-Date: 2010-04-21 07:41-0700\n" +"POT-Creation-Date: 2010-05-03 14:14-0700\n" "PO-Revision-Date: 2009-09-20 15:32+0900\n" "Last-Translator: Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>\n" "Language-Team: Japanese <jp@li.org>\n" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: pl\n" "Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n" -"POT-Creation-Date: 2010-04-21 07:41-0700\n" +"POT-Creation-Date: 2010-05-03 14:14-0700\n" "PO-Revision-Date: 2007-03-16 20:10+0100\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n" @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n" -"POT-Creation-Date: 2010-04-21 07:41-0700\n" +"POT-Creation-Date: 2010-05-03 14:14-0700\n" "PO-Revision-Date: 2010-04-15 07:24+0300\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <kde-i18n-doc@kde.org>\n" diff --git a/tests/ChangeLog b/tests/ChangeLog index 83b4b747..e2fe66f2 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2010-04-22 Roland McGrath <roland@redhat.com> + + * addrcfi.c (handle_cfi): Fix function name in error message. + Use dwarf_errmsg, not dwfl_errmsg, after dwarf_cfi_addrframe. + 2010-04-14 Roland McGrath <roland@redhat.com> * Makefile.am (EXTRA_DIST): Add run-test-flag-nobits.sh here too. diff --git a/tests/addrcfi.c b/tests/addrcfi.c index 2a3db05c..4e042418 100644 --- a/tests/addrcfi.c +++ b/tests/addrcfi.c @@ -1,5 +1,5 @@ /* Test program for CFI handling. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -100,7 +100,7 @@ handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi, int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame); if (result != 0) { - error (0, 0, "dwarf_addrframe (%s): %s", which, dwfl_errmsg (-1)); + error (0, 0, "dwarf_cfi_addrframe (%s): %s", which, dwarf_errmsg (-1)); return 1; } |