This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC 06/13] Force sign-extend statement addresses on mips64 -msym32
- From: Crestez Dan Leonard <cdleonard at gmail dot com>
- To: systemtap at sourceware dot org
- Date: Thu, 31 Jul 2014 23:21:11 +0300
- Subject: [RFC 06/13] Force sign-extend statement addresses on mips64 -msym32
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
Signed-off-by: Crestez Dan Leonard <cdleonard@gmail.com>
---
dwflpp.cxx | 34 ++++++++++++++++++++++++++++++++++
dwflpp.h | 1 +
tapsets.cxx | 14 ++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/dwflpp.cxx b/dwflpp.cxx
index e53d5f2..dea81b9 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -3054,6 +3054,31 @@ dwflpp::die_location_as_function_string(Dwarf_Addr pc, Dwarf_Die *die)
return locstr;
}
+static bool
+is_elf_mips64(Elf *elf)
+{
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr* ehdr = gelf_getehdr (elf, &ehdr_mem);
+ return ehdr->e_machine == EM_MIPS &&
+ ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+bool
+dwflpp::is_mips64_msym32(Dwarf_Die *die)
+{
+ Dwarf_Addr bias;
+ Elf* elf = (dwarf_getelf (module_dwarf)
+ ?: dwfl_module_getelf (this->module, &bias));
+ if (!::is_elf_mips64(elf)) {
+ return false;
+ }
+
+ Dwarf_Die cu_mem;
+ uint8_t address_size;
+ dwarf_diecu (die, &cu_mem, &address_size, NULL);
+ return (address_size == 4);
+}
+
struct location *
dwflpp::translate_location(struct obstack *pool,
Dwarf_Attribute *attr, Dwarf_Die *die,
@@ -3084,6 +3109,15 @@ dwflpp::translate_location(struct obstack *pool,
to be passed in, but instead should now be zero for the same reason. */
retry:
+ if (is_mips64_msym32(die))
+ {
+ /* Force sign extension */
+ if (sess.verbose > 2)
+ clog << "query_statement truncate pc=" << hex << pc
+ << " to " << hex << (uint32_t)pc
+ << " for lookup on mips64 with 32bit symbols" << endl;
+ pc = (uint32_t)pc;
+ }
switch (dwarf_getlocation_addr (attr, pc /*+ module_bias*/, &expr, &len, 1))
{
case 1: /* Should always happen. */
diff --git a/dwflpp.h b/dwflpp.h
index 2546acf..a411ed4 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -649,6 +649,7 @@ private:
public:
Dwarf_Addr pr15123_retry_addr (Dwarf_Addr pc, Dwarf_Die* var);
+ bool is_mips64_msym32(Dwarf_Die *die);
};
// Template <void> specializations for iterate_over_* functions
diff --git a/tapsets.cxx b/tapsets.cxx
index 3724a96..97d4b7e 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1610,6 +1610,20 @@ query_statement (string const & func,
Dwarf_Addr stmt_addr,
dwarf_query * q)
{
+ if (1)
+ {
+ if (q->dw.is_mips64_msym32(scope_die))
+ {
+ /* Force sign extension */
+ if (q->sess.verbose > 2)
+ clog << "query_statement " << func << "@" << file << ":" << line
+ << " sign-extend stmt_addr " << hex << stmt_addr
+ << " to " << hex << ((int64_t)((int32_t)stmt_addr))
+ << " because were on mips64 with 32bit symbols" << endl;
+ stmt_addr = (int32_t)stmt_addr;
+ }
+ }
+
try
{
q->add_probe_point(func, file ? file : "",