This is the mail archive of the
frysk@sources.redhat.com
mailing list for the frysk project.
implement backtraces for AMD64
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: frysk at sources dot redhat dot com
- Date: Sun, 17 Sep 2006 04:45:00 -0300
- Subject: implement backtraces for AMD64
- Organization: Red Hat OS Tools Group
This patch adds the missing bits to enable libunwind-based backtraces
on AMD64/EM64T. A few notes:
- The existing IsaEMT64 is misnamed: the correct spelling is EM64T,
not EMT64. We should probably prefer the more neutral X86_64 name (as
in the ELF data structure), or favor AMD64, like I did in the new
RegisterAMD64 class (just trying to set balance ;-)
- I'm not entirely happy with adding libunwind-specific information to
Isa, but Isa doesn't currently provide enough information to enable
some alternate implementation that would keep everything entirely
separate. If we had a method to return the Isa name or the ELF
machine type or some such, then it would be possible to turn that into
a reworked Register* factory/singleton pattern similar to that used
for Isa, all within lib/unwind. It certainly doesn't help that
lib/unwind is in frysk-imports, so it can't use anything in
frysk-core; frysk-core/rt would have to have the glue.
Comments? Any architectural guidance? Or is this ok to install?
for frysk/frysk-imports/lib/unwind/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* RegisterAMD64.java: New class.
for frysk/frysk-core/frysk/proc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* Isa.java (getRegisterNameByUnwindRegnum): New.
* IsaEMT64.java (getRegisterNameByUnwindRegnum): Implement.
* IsaIA32.java (getRegisterNameByUnwindRegnum): Implement.
* IsaPPC.java (getRegisterNameByUnwindRegnum): Add stub.
* IsaPPC64.java (getRegisterNameByUnwindRegnum): Add stub.
for frysk/frysk-core/frysk/rt/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* StackCallbacks.java: Do not import lib.unwind.RegisterX86.
(accessMem): Implement according to Isa-specified word size.
(accessReg, writeReg, accessFpreg, writeFpreg): Do not use
RegisterX86 directly.
Index: frysk/frysk-core/frysk/proc/Isa.java
===================================================================
--- frysk.orig/frysk-core/frysk/proc/Isa.java 2006-09-17 04:31:37.000000000 -0300
+++ frysk/frysk-core/frysk/proc/Isa.java 2006-09-17 04:31:55.000000000 -0300
@@ -52,6 +52,8 @@ public interface Isa
{
Iterator RegisterIterator();
+ String getRegisterNameByUnwindRegnum(long regnum);
+
Register getRegisterByName(String name);
long pc(Task task);
Index: frysk/frysk-core/frysk/proc/IsaEMT64.java
===================================================================
--- frysk.orig/frysk-core/frysk/proc/IsaEMT64.java 2006-09-17 04:31:37.000000000 -0300
+++ frysk/frysk-core/frysk/proc/IsaEMT64.java 2006-09-17 04:31:55.000000000 -0300
@@ -43,6 +43,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import inua.eio.ByteOrder;
+import lib.unwind.RegisterAMD64;
class IsaEMT64 implements Isa
{
@@ -113,6 +114,11 @@ class IsaEMT64 implements Isa
return registerMap.values().iterator();
}
+ public String getRegisterNameByUnwindRegnum(long regnum)
+ {
+ return RegisterAMD64.getUnwindRegister(regnum);
+ }
+
public Register getRegisterByName(String name)
{
return (Register)registerMap.get(name);
Index: frysk/frysk-core/frysk/proc/IsaIA32.java
===================================================================
--- frysk.orig/frysk-core/frysk/proc/IsaIA32.java 2006-09-17 04:31:37.000000000 -0300
+++ frysk/frysk-core/frysk/proc/IsaIA32.java 2006-09-17 04:31:55.000000000 -0300
@@ -43,6 +43,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import inua.eio.ByteOrder;
+import lib.unwind.RegisterX86;
class IsaIA32 implements Isa
{
@@ -120,7 +121,12 @@ class IsaIA32 implements Isa
return registerMap.values().iterator();
}
- public Register getRegisterByName(String name)
+ public String getRegisterNameByUnwindRegnum(long regnum)
+ {
+ return RegisterX86.getUnwindRegister(regnum);
+ }
+
+ public Register getRegisterByName(String name)
{
return (Register)registerMap.get(name);
}
Index: frysk/frysk-core/frysk/proc/IsaPPC.java
===================================================================
--- frysk.orig/frysk-core/frysk/proc/IsaPPC.java 2006-09-17 04:31:37.000000000 -0300
+++ frysk/frysk-core/frysk/proc/IsaPPC.java 2006-09-17 04:31:55.000000000 -0300
@@ -110,6 +110,12 @@ class IsaPPC
return registerMap.values().iterator();
}
+ public String getRegisterNameByUnwindRegnum(long regnum)
+ {
+ /* FIXME: needs implementation. */
+ return null;
+ }
+
public Register getRegisterByName (String name)
{
return (Register)registerMap.get(name);
Index: frysk/frysk-core/frysk/proc/IsaPPC64.java
===================================================================
--- frysk.orig/frysk-core/frysk/proc/IsaPPC64.java 2006-09-17 04:31:37.000000000 -0300
+++ frysk/frysk-core/frysk/proc/IsaPPC64.java 2006-09-17 04:31:55.000000000 -0300
@@ -126,6 +126,12 @@ class IsaPPC64
return registerMap.values().iterator();
}
+ public String getRegisterNameByUnwindRegnum(long regnum)
+ {
+ /* FIXME: needs implementation. */
+ return null;
+ }
+
public Register getRegisterByName (String name)
{
return (Register)registerMap.get(name);
Index: frysk/frysk-imports/lib/unwind/RegisterAMD64.java
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ frysk/frysk-imports/lib/unwind/RegisterAMD64.java 2006-09-17 04:31:55.000000000 -0300
@@ -0,0 +1,65 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2006, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package lib.unwind;
+
+public class RegisterAMD64
+{
+ private static final String[] REG_NAMES = { "rax", "rdx", "rcx", "rbx",
+ "rsi", "rdi", "rbp", "rsp",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "rip",
+
+ /* Other registers may
+ be added here, so we
+ don't make cfa
+ available. */
+
+ /* frame info (read-only) */
+ /* "cfa" */ };
+
+ public static String getUnwindRegister (long val)
+ {
+ if (val > REG_NAMES.length || val < 0)
+ return null;
+
+ return REG_NAMES[(int) val];
+ }
+}
Index: frysk/frysk-core/frysk/rt/StackCallbacks.java
===================================================================
--- frysk.orig/frysk-core/frysk/rt/StackCallbacks.java 2006-09-17 04:31:55.000000000 -0300
+++ frysk/frysk-core/frysk/rt/StackCallbacks.java 2006-09-17 04:31:55.000000000 -0300
@@ -45,7 +45,6 @@ import frysk.proc.Task;
import frysk.proc.TaskException;
import java.util.logging.Level;
import java.util.logging.Logger;
-import lib.unwind.RegisterX86;
import lib.unwind.UnwindCallbacks;
public class StackCallbacks
@@ -68,8 +67,19 @@ public class StackCallbacks
logger.log(Level.FINE, "Libunwind: reading memory at 0x"
+ Long.toHexString(addr) + "\n");
- // XXX: Fixme for 64
- long value = myTask.getMemory().getInt(addr);
+ long value;
+
+ switch (isa.getWordSize())
+ {
+ case 4:
+ value = myTask.getMemory().getInt(addr);
+ break;
+ case 8:
+ value = myTask.getMemory().getLong(addr);
+ break;
+ default:
+ throw new RuntimeException("Not implemented for this word length yet");
+ }
logger.log(Level.FINE, "Libunwind: read value 0x"
+ Long.toHexString(value) + "\n");
@@ -87,7 +97,7 @@ public class StackCallbacks
public long accessReg (long as, long regnum)
{
- String registerName = RegisterX86.getUnwindRegister(regnum);
+ String registerName = isa.getRegisterNameByUnwindRegnum(regnum);
logger.log(Level.FINE, "Libunwind: reading from register "
+ registerName + "\n");
@@ -100,7 +110,7 @@ public class StackCallbacks
public void writeReg (long as, long regnum, long value)
{
- String registerName = RegisterX86.getUnwindRegister(regnum);
+ String registerName = isa.getRegisterNameByUnwindRegnum(regnum);
logger.log(Level.FINE, "Libunwind: writing value 0x"
+ Long.toHexString(value) + " to register "
+ registerName + "\n");
@@ -110,7 +120,9 @@ public class StackCallbacks
public double accessFpreg (long as, long regnum)
{
- String registerName = RegisterX86.getUnwindRegister(regnum);
+ /* This is probably broken, since the numbering for FP regs ought
+ * to be different from that for non-FP reg. */
+ String registerName = isa.getRegisterNameByUnwindRegnum(regnum);
logger.log(Level.FINE, "Libunwind: reading register " + registerName
+ "\n");
@@ -121,7 +133,9 @@ public class StackCallbacks
public void writeFpreg (long as, long regnum, double value)
{
- String registerName = RegisterX86.getUnwindRegister(regnum);
+ /* This is probably broken, since the numbering for FP regs ought
+ * to be different from that for non-FP reg. */
+ String registerName = isa.getRegisterNameByUnwindRegnum(regnum);
logger.log(Level.FINE, "Libunwind: writing value " + value
+ " to register " + registerName + "\n");
throw new RuntimeException("Not implemented in core yet");
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}