This is the mail archive of the frysk@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

implement backtraces for AMD64


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}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]