From: Frank Ch. Eigler Date: Thu, 28 May 2020 16:45:06 +0000 (-0400) Subject: PR14013: don't reject DW_OP_GNU_push_tls_address DWARF location operator X-Git-Tag: release-4.3~32 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=f29f23213cc9668fb6c54a34c815257b7cbeaf5c;p=systemtap.git PR14013: don't reject DW_OP_GNU_push_tls_address DWARF location operator Subject DWARF OP is used for accessing TLS variables in GCC-compiled C code. In all but the simplest cases, we must emulate libthread_db logic for resolving TLS addresses. Step 1 is to map this operator to a tapset function call __push_tls_address, which will implement the architecture-specific lookup functionality. We also tweak systemtap_session::print_error to ensure even isolated little error messages seen only once do get printed. See also: https://infinitynotes.org/wiki/Glibc --- diff --git a/elaborate.cxx b/elaborate.cxx index e90f97e8b..6cbc85038 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -2941,7 +2941,8 @@ symresolution_info::visit_functioncall (functioncall* e) else { string sugs = levenshtein_suggest(e->function, collect_functions(), 5); // print 5 funcs - throw SEMANTIC_ERROR(_F("unresolved function%s", + throw SEMANTIC_ERROR(_F("unresolved function %s%s", + string(e->function).c_str(), sugs.empty() ? "" : (_(" (similar: ") + sugs + ")").c_str()), e->tok); } diff --git a/loc2stap.cxx b/loc2stap.cxx index d4fd05182..6e6069dcf 100644 --- a/loc2stap.cxx +++ b/loc2stap.cxx @@ -690,6 +690,18 @@ location_context::translate (const Dwarf_Op *expr, const size_t len, } break; + case DW_OP_GNU_push_tls_address: + { + POP(addr); + functioncall *fc = new functioncall; + fc->tok = e->tok; + fc->function = std::string("__push_tls_address"); + fc->synthetic = true; + fc->args.push_back(addr); + PUSH(fc); + } + break; + default: DIE ("unhandled DW_OP operation"); break; diff --git a/session.cxx b/session.cxx index 1304570cd..d0959f018 100644 --- a/session.cxx +++ b/session.cxx @@ -2382,6 +2382,7 @@ systemtap_session::print_error (const semantic_error& se) if (verbose > 0 || seen_errors[se.errsrc_chain()] < 1) { seen_errors[se.errsrc_chain()]++; + cerr << build_error_msg(se); for (const semantic_error *e = &se; e != NULL; e = e->get_chain()) if (verbose > 1 || seen_errors[e->errsrc] < 1) // dupe-eliminate chained errors too {