diff --git a/frysk-core/frysk/stack/LibunwindFrame.java b/frysk-core/frysk/stack/LibunwindFrame.java index 080df12..64e9c28 100644 --- a/frysk-core/frysk/stack/LibunwindFrame.java +++ b/frysk-core/frysk/stack/LibunwindFrame.java @@ -44,7 +44,6 @@ import frysk.isa.Register; import java.util.logging.Logger; import lib.unwind.Cursor; import lib.unwind.ProcInfo; -import lib.unwind.ProcName; import frysk.isa.ISA; import frysk.proc.Task; import frysk.symtab.Symbol; @@ -92,13 +91,7 @@ class LibunwindFrame extends Frame * Returns the current program counter of this Frame. */ public long getAddress() { - ProcInfo myInfo = cursor.getProcInfo(); - ProcName myName = cursor.getProcName(0); - - if (myInfo.getError() != 0 || myName.getError() != 0) - return 0; - - return myInfo.getStartIP() + myName.getOffset(); + return cursor.getIP(); } /** diff --git a/frysk-imports/libunwind/src/mi/Gget_reg.c b/frysk-imports/libunwind/src/mi/Gget_reg.c index 23b72be..5179a88 100644 --- a/frysk-imports/libunwind/src/mi/Gget_reg.c +++ b/frysk-imports/libunwind/src/mi/Gget_reg.c @@ -30,5 +30,12 @@ unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp) { struct cursor *c = (struct cursor *) cursor; + // No need to go look up the IP value since it is cached in the cursor. + if (regnum == UNW_REG_IP) + { + *valp = c->dwarf.ip; + return 0; + } + return tdep_access_reg (c, regnum, valp, 0); } diff --git a/frysk-sys/lib/unwind/Cursor.java b/frysk-sys/lib/unwind/Cursor.java index 190e315..6433ace 100644 --- a/frysk-sys/lib/unwind/Cursor.java +++ b/frysk-sys/lib/unwind/Cursor.java @@ -81,6 +81,10 @@ public class Cursor bytes, start); } + public long getIP() { + return unwinder.getIP(cursor); + } + public long getSP() { return unwinder.getSP(cursor); } @@ -110,8 +114,8 @@ public class Cursor public Cursor unwind() { logger.log(Level.FINE, "{0}, unwind\n", this); - //XXX: Don't unwind if no more frames. - if (step == 0) + //XXX: Don't unwind if no more, or unknown frames. + if (step == 0 || getIP() == 0) return null; Cursor newCursor = new Cursor(addressSpace, diff --git a/frysk-sys/lib/unwind/Unwind.java b/frysk-sys/lib/unwind/Unwind.java index 23181ec..8e9d3d3 100644 --- a/frysk-sys/lib/unwind/Unwind.java +++ b/frysk-sys/lib/unwind/Unwind.java @@ -70,6 +70,7 @@ public abstract class Unwind abstract void setRegister(RawDataManaged cursor, int regNum, long offset, int length, byte[] word, int start); + public abstract long getIP(RawDataManaged cursor); public abstract long getSP(RawDataManaged cursor); abstract RawDataManaged copyCursor(RawDataManaged cursor); diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx index c13576c..f48494e 100644 --- a/frysk-sys/lib/unwind/cni/UnwindH.hxx +++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx @@ -402,6 +402,17 @@ lib::unwind::TARGET::getSP(gnu::gcj::RawDataManaged* cursor) return sp; } +jlong +lib::unwind::TARGET::getIP(gnu::gcj::RawDataManaged* cursor) +{ + unw_word_t ip; + int status = unw_get_reg((::unw_cursor_t *) cursor, UNW_REG_IP, &ip); + if (status < 0) + return 0; // bottom of stack. + else + return ip; +} + jint lib::unwind::TARGET::getContext(gnu::gcj::RawDataManaged* context) @@ -445,6 +456,9 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre jboolean needUnwindInfo, lib::unwind::ElfImage* elfImage) { + if (elfImage == NULL) + return new lib::unwind::ProcInfo(UNW_ENOINFO); + unw_proc_info_t *procInfo = (::unw_proc_info_t *) JvAllocBytes(sizeof (::unw_proc_info_t));