From be4079e3f2e0ff20a265a31adca71ed9280b92a8 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 15 Feb 2010 15:12:10 +0000 Subject: [PATCH] - Add systemtap-1.1-cfi-cfa_ops-fixes.patch - Resolves RHBZ #564429 --- systemtap-1.1-cfi-cfa_ops-fixes.patch | 283 ++++++++++++++++++++++++++ systemtap.spec | 10 +- 2 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 systemtap-1.1-cfi-cfa_ops-fixes.patch diff --git a/systemtap-1.1-cfi-cfa_ops-fixes.patch b/systemtap-1.1-cfi-cfa_ops-fixes.patch new file mode 100644 index 0000000..ed22ea0 --- /dev/null +++ b/systemtap-1.1-cfi-cfa_ops-fixes.patch @@ -0,0 +1,283 @@ +commit 08d1d520616557f6ff7dd023e260ad6577e9e0e8 +Author: Mark Wielaard +Date: Mon Jan 18 09:13:30 2010 +0100 + + PR11173 Markers get a bad address in prelinked libraries. + + Our literal_addr_to_sym_addr() function was just wrong. To compensate for + raw addresses read from elf (either given by the user or through a mark + transformation) we need to know what the elf_bias is (as returned by + dwfl_module_getelf) before feeding them to any libdwfl functions. + + * tapsets.cxx (query_module_dwarf): Always add elf_bias to raw function or + statement addresses before calling query_addr(). + (query_addr): Don't call literal_addr_to_sym_addr(). + * dwflpp.h (literal_addr_to_sym_addr): Removed. + * dwflpp.cxx (literal_addr_to_sym_addr): Likewise. + +diff --git a/dwflpp.cxx b/dwflpp.cxx +index 7dd31d0..e6fe017 100644 +--- a/dwflpp.cxx ++++ b/dwflpp.cxx +@@ -2771,45 +2771,6 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, string& reloc_section) + return reloc_addr; + } + +-/* Converts a "global" literal address to the module symbol address +- * space. If necessary (not for kernel and executables using absolute +- * addresses), this adjust the address for the current module symbol +- * bias. Literal addresses are provided by the user (or contained on +- * the .probes section) based on the "on disk" layout of the module. +- */ +-Dwarf_Addr +-dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) +-{ +- if (sess.verbose > 2) +- clog << "literal_addr_to_sym_addr 0x" << hex << lit_addr << dec << endl; +- +- // Assume the address came from the symbol list. +- // If we cannot get the symbol bias fall back on the dw bias. +- // The kernel (and other absolute executable modules) is special though. +- if (module_name != TOK_KERNEL +- && dwfl_module_relocations (module) > 0) +- { +- Dwarf_Addr symbias = ~0; +- if (dwfl_module_getsymtab (module) != -1) +- dwfl_module_info (module, NULL, NULL, NULL, NULL, +- &symbias, NULL, NULL); +- +- if (sess.verbose > 3) +- clog << "symbias 0x" << hex << symbias << dec +- << ", dwbias 0x" << hex << module_bias << dec << endl; +- +- if (symbias == (Dwarf_Addr) ~0) +- symbias = module_bias; +- +- lit_addr += symbias; +- } +- +- if (sess.verbose > 2) +- clog << "literal_addr_to_sym_addr ret 0x" << hex << lit_addr << dec << endl; +- +- return lit_addr; +-} +- + /* Returns the call frame address operations for the given program counter + * in the libdw address space. + */ +diff --git a/dwflpp.h b/dwflpp.h +index cdc6ad9..523dd88 100644 +--- a/dwflpp.h ++++ b/dwflpp.h +@@ -284,8 +284,6 @@ struct dwflpp + + Dwarf_Addr relocate_address(Dwarf_Addr addr, std::string& reloc_section); + +- Dwarf_Addr literal_addr_to_sym_addr(Dwarf_Addr lit_addr); +- + + private: + DwflPtr dwfl_ptr; +diff --git a/tapsets.cxx b/tapsets.cxx +index 071f92d..d5c6b25 100644 +--- a/tapsets.cxx ++++ b/tapsets.cxx +@@ -761,6 +761,13 @@ dwarf_query::query_module_dwarf() + // number plus the module's bias. + Dwarf_Addr addr = has_function_num ? + function_num_val : statement_num_val; ++ ++ // These are raw addresses, we need to know what the elf_bias ++ // is to feed it to libdwfl based functions. ++ Dwarf_Addr elf_bias; ++ Elf *elf = dwfl_module_getelf (dw.module, &elf_bias); ++ assert(elf); ++ addr += elf_bias; + query_addr(addr, this); + } + else +@@ -1168,8 +1175,8 @@ query_addr(Dwarf_Addr addr, dwarf_query *q) + { + dwflpp &dw = q->dw; + +- // Translate to and actual sumbol address. +- addr = dw.literal_addr_to_sym_addr(addr); ++ if (q->sess.verbose > 2) ++ clog << "query_addr 0x" << hex << addr << dec << endl; + + // First pick which CU contains this address + Dwarf_Die* cudie = dw.query_cu_containing_address(addr); + +commit 87748e2b87e574d3c83866ccd0d83678c3c68d93 +Author: Mark Wielaard +Date: Tue Feb 2 13:47:19 2010 +0100 + + Make sure cfa_ops are always retrieved through dwfl global address. + + dwflpp::translate_location() works on the dw address space, but + get_cfa_ops() starts out with dwfl calls (only dwarf_cfi_addrframe() + needs to be adjusted for bias). + + * dwflpp.cxx (translate_location): Pass pc plus module bias through to + get_cfa_ops. + (get_cfa_ops): Adjust for bias when calling dwarf_cfi_addrframe(), + add frame start/end address when found if verbose logging. + * testsuite/systemtap.exelib/lib.stp: Add $foo and $bar variables to + process.function probes. + * testsuite/systemtap.exelib/libmarkunamestack.stp: Likewise. + * testsuite/systemtap.exelib/lib.tcl: Expect correct values for + process.function probe variables. + * testsuite/systemtap.exelib/libmarkunamestack.tcl: Likewise. + +diff --git a/dwflpp.cxx b/dwflpp.cxx +index e6fe017..d16411c 100644 +--- a/dwflpp.cxx ++++ b/dwflpp.cxx +@@ -1726,9 +1726,10 @@ dwflpp::translate_location(struct obstack *pool, + e->tok); + } + +- // pc is relative to current module, which is what get_cfa_ops +- // and c_translate_location expects. +- Dwarf_Op *cfa_ops = get_cfa_ops (pc); ++ // pc is in the dw address space of the current module, which is what ++ // c_translate_location expects. get_cfa_ops wants the global dwfl address. ++ Dwarf_Addr addr = pc + module_bias; ++ Dwarf_Op *cfa_ops = get_cfa_ops (addr); + return c_translate_location (pool, &loc2c_error, this, + &loc2c_emit_address, + 1, 0 /* PR9768 */, +@@ -2783,17 +2784,17 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) + clog << "get_cfa_ops @0x" << hex << pc << dec + << ", module_start @0x" << hex << module_start << dec << endl; + +-#if _ELFUTILS_PREREQ(0,142) + // Try debug_frame first, then fall back on eh_frame. +- size_t cfa_nops; +- Dwarf_Addr bias; ++ size_t cfa_nops = 0; ++ Dwarf_Addr bias = 0; ++ Dwarf_Frame *frame = NULL; ++#if _ELFUTILS_PREREQ(0,142) + Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); + if (cfi != NULL) + { + if (sess.verbose > 3) + clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl; +- Dwarf_Frame *frame = NULL; +- if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) ++ if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); + else if (sess.verbose > 3) + clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; +@@ -2809,7 +2810,7 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) + if (sess.verbose > 3) + clog << "got eh cfi bias: 0x" << hex << bias << dec << endl; + Dwarf_Frame *frame = NULL; +- if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) ++ if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); + else if (sess.verbose > 3) + clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; +@@ -2821,7 +2822,20 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) + #endif + + if (sess.verbose > 2) +- clog << (cfa_ops == NULL ? "not " : " ") << "found cfa" << endl; ++ { ++ if (cfa_ops == NULL) ++ clog << "not found cfa" << endl; ++ else ++ { ++ Dwarf_Addr frame_start, frame_end; ++ bool frame_signalp; ++ int info = dwarf_frame_info (frame, &frame_start, &frame_end, ++ &frame_signalp); ++ clog << "found cfa, info:" << info << " [start: 0x" << hex ++ << frame_start << dec << ", end: 0x" << hex << frame_end ++ << dec << "), nops: " << cfa_nops << endl; ++ } ++ } + + return cfa_ops; + } +diff --git a/testsuite/systemtap.exelib/lib.stp b/testsuite/systemtap.exelib/lib.stp +index 0151282..3fdc6db 100644 +--- a/testsuite/systemtap.exelib/lib.stp ++++ b/testsuite/systemtap.exelib/lib.stp +@@ -6,7 +6,7 @@ probe process(@1).function("main") { + } + + probe process(@1).function("main_func") { +- printf("main_func\n"); ++ printf("main_func %d\n", $foo); + } + + probe process(@2).function("lib_main") { +@@ -14,5 +14,5 @@ probe process(@2).function("lib_main") { + } + + probe process(@2).function("lib_func") { +- printf("lib_func\n"); ++ printf("lib_func %d\n", $bar); + } +diff --git a/testsuite/systemtap.exelib/lib.tcl b/testsuite/systemtap.exelib/lib.tcl +index c5b7402..a33290b 100644 +--- a/testsuite/systemtap.exelib/lib.tcl ++++ b/testsuite/systemtap.exelib/lib.tcl +@@ -1,11 +1,11 @@ + set ::result_string {main +-main_func +-main_func +-main_func ++main_func 3 ++main_func 2 ++main_func 1 + lib_main +-lib_func +-lib_func +-lib_func} ++lib_func 3 ++lib_func 2 ++lib_func 1} + + # Only run on make installcheck + if {! [installtest_p]} { untested "lib-$testname"; return } +diff --git a/testsuite/systemtap.exelib/libmarkunamestack.stp b/testsuite/systemtap.exelib/libmarkunamestack.stp +index 0efbae0..5ee229d 100644 +--- a/testsuite/systemtap.exelib/libmarkunamestack.stp ++++ b/testsuite/systemtap.exelib/libmarkunamestack.stp +@@ -7,7 +7,7 @@ probe process(@1).function("main") { + } + + probe process(@1).function("main_func") { +- printf("main_func\n"); ++ printf("main_func: %d\n", $foo); + } + + probe process(@2).function("lib_main") { +@@ -15,7 +15,7 @@ probe process(@2).function("lib_main") { + } + + probe process(@2).function("lib_func") { +- printf("lib_func\n"); ++ printf("lib_func: %d\n", $bar); + } + + #mark +diff --git a/testsuite/systemtap.exelib/libmarkunamestack.tcl b/testsuite/systemtap.exelib/libmarkunamestack.tcl +index 55dc10e..20111b3 100644 +--- a/testsuite/systemtap.exelib/libmarkunamestack.tcl ++++ b/testsuite/systemtap.exelib/libmarkunamestack.tcl +@@ -47,9 +47,9 @@ expect { + + # lib + -re {^main\r\n} {incr lib; exp_continue} +- -re {^main_func\r\n} {incr lib; exp_continue} ++ -re {^main_func: [1-3]\r\n} {incr lib; exp_continue} + -re {^lib_main\r\n} {incr lib; exp_continue} +- -re {^lib_func\r\n} {incr lib; exp_continue} ++ -re {^lib_func: [1-3]\r\n} {incr lib; exp_continue} + + # mark + -re {^main_count: [1-3]\r\n} {incr mark; exp_continue} diff --git a/systemtap.spec b/systemtap.spec index 3a0a120..3ddd7c2 100644 --- a/systemtap.spec +++ b/systemtap.spec @@ -12,7 +12,7 @@ Name: systemtap Version: 1.1 -Release: 1%{?dist} +Release: 2%{?dist} # for version, see also configure.ac Summary: Instrumentation System Group: Development/System @@ -56,6 +56,8 @@ BuildRequires: elfutils-devel >= %{elfutils_version} Requires: crash %endif +Patch10: systemtap-1.1-cfi-cfa_ops-fixes.patch + %if %{with_docs} BuildRequires: /usr/bin/latex /usr/bin/dvips /usr/bin/ps2pdf latex2html # On F10, xmlto's pdf support was broken off into a sub-package, @@ -189,6 +191,8 @@ find . \( -name configure -o -name config.h.in \) -print | xargs touch cd .. %endif +%patch10 -p1 + %build %if %{with_bundled_elfutils} @@ -492,6 +496,10 @@ exit 0 %changelog +* Mon Feb 15 2010 Mark Wielaard - 1.1-2 +- Add systemtap-1.1-cfi-cfa_ops-fixes.patch +- Resolves RHBZ #564429 + * Mon Dec 21 2009 David Smith - 1.1-1 - Upstream release.