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]

dwarf support for expressions


Here is what I have thus far for dwarf support just to get feedback as
to the general direction. There are still some rough edges.
Example:
% cat /home/scox/accu/src/loop.c 
int j = 7;
bar ()
{
  int i = 8;
  while (i)
    {
    }
}
foo ()
{
  bar ();
}
main ()
{
  foo ();
}
% (hpd) attach /home/scox/accu/src/loop.x 31826
(hpd) what j
int j
(hpd) what i
int i
(hpd) print j
7
(hpd) print i
# No DW_AT_frame_base support so value is wrong
0
(hpd) assign j 9
9
(hpd) print j
# Need to actually put the value with ptrace
7
(hpd) quit


Changes:

0. Add frysk-core/frysk/cli/hpd/hpd.java
   (Command line interface to CLI.java, makes testing easier)
1. frysk-core/frysk/cli/hpd/CLI.java
   Add attach/detach to attach to a process
2. Move PrintHandler.java to SymTab.java
3. SymTab
   A. class symTab callback to frysk-core/frysk/expr
      - put not fully implemented but will be similar to get
      - get implemented for static int
	Need: DW_AT_frame_base support for local variables
	Need: Complex addressing support
	Need: add types other than int
   B.  class SymTab 
      - 'what' gives variable type
	Need: Expand for more complex types
      - 'print' interfaces to expr, no changes
4. frysk-core/frysk/lang/Endian.java
   A. Remove and change all callers to use inua/eio/ByteOrder.java
   B. Add CppSymTab interface for 3-A above
   (This is independent of everything else)
5. frysk-imports/lib/dw/DwarfDie.java
   A. Add getScopesVar to return dwarf scoping info
   B. Add getAddr to return the address of a variable
      Possibly need to refactor this to accomodate more complex address
modes 
   C. getType to return the type of a variable
   D. fbregVariable to say if a variable is local off of frame ptr
6. frysk-imports/lib/dw/cni/DwarfDie.cxx
   For 5 above

Index: frysk-core/frysk/cli/hpd/CLI.java
===================================================================
diff -u -p -r1.12 CLI.java
--- frysk-core/frysk/cli/hpd/CLI.java	14 Jul 2006 22:24:56 -0000	1.12
+++ frysk-core/frysk/cli/hpd/CLI.java	5 Sep 2006 16:33:48 -0000
@@ -48,5 +48,11 @@ import java.util.Iterator;
 public class CLI 
 {
+    private Dwfl dwfl;
+    Proc proc;
+    Task task;
+    int pid = 0;
+    SymTab symtab;
+
 	/*
 	 * Command handlers
 	 */
@@ -255,6 +277,55 @@ public class CLI 
 		}
 	}
 
+    class AttachHandler implements CommandHandler
+    {
+        public void handle(Command cmd) throws ParseException
+        {
+          Vector params = cmd.getParameters();
+          String executable = "";
+
+          if (params.size() != 2)
+            {
+              cmd.getOut().println ("Usage " + cmd.getAction() +
"Executable PID");
+              return;
+            }
+          Manager.eventLoop.runPolling (5 * 1000);
+
+          executable = ((String)params.elementAt(0));
+          pid = Integer.parseInt((String)params.elementAt(1));
+
+          try {
+            Ptrace.attach(pid);
+          }
+          catch (Errno errno) {
+            addMessage(new Message("No such process.",
Message.TYPE_ERROR));
+          }
+            
+          Manager.host.requestRefreshXXX (true);
+          Manager.eventLoop.runPending ();
+          proc = Manager.host.getProc (new ProcId (pid));
+          task = proc.getMainTask();
+          SymTab symtab = new SymTab(pid, proc, task);
+        }
+    }
+
+    class DetachHandler implements CommandHandler
+    {
+        public void handle(Command cmd) throws ParseException
+        {
+          Vector params = cmd.getParameters();
+          String sInput =
cmd.getFullCommand().substring(cmd.getAction().length()).trim();
+
+          if (params.size() > 0)
+            {
+              cmd.getOut().println ("Usage " + cmd.getAction());
+              return;
+            }
+
+          Manager.eventLoop.requestStop();
+        }
+    }
+    
 	class UnaliasHandler implements CommandHandler
 	{
 		public void handle(Command cmd)  throws ParseException

Index: frysk-core/frysk/cli/hpd/SymTab.java
===================================================================
// This file is part of the program FRYSK.
// ...
import ...

class symTab implements CppSymTab
{
  static Map symTab = new HashMap();
  public void put(String s, Variable v)
  { symTab.put(s, v);}
  public Variable get(String s)
  {
    Dwfl dwfl;
    long address;
    try
    {
      address = SymTab.task.getIsa().pc(SymTab.task) - 1;
    }
    catch (TaskException tte)
    {
      throw new RuntimeException(tte);
    }
    
    dwfl = new Dwfl(SymTab.pid);
    DwflLine line = null;
    DwflDieBias bias = dwfl.getDie(address);
    DwarfDie die = bias.die;
    DwarfDie[] allDies = die.getScopes(die.getLowPC() - bias.bias);

    String sInput = s;
    DwarfDie varDie = die.getScopesVar(allDies, sInput);
    long addr = varDie.getAddr();
    if (varDie.fbregVariable())
      {
        long regval = 0;
        try
        {
          if (MachineType.getMachineType() == MachineType.X8664)
            regval = SymTab.task.getIsa().getRegisterByName("rbp").get
(SymTab.task);
          else if (MachineType.getMachineType() == MachineType.IA32)
            regval = SymTab.task.getIsa().getRegisterByName("ebp").get
(SymTab.task);
        }
        catch (TaskException tte)
        {
          throw new RuntimeException(tte);
        }
        // Need to use DW_AT_frame_base here
        addr += regval;
      }
      

    ByteBuffer buffer;
    buffer = new PtraceByteBuffer(SymTab.pid,
PtraceByteBuffer.Area.DATA,
                                  0xffffffffl);
    try
    {
      buffer = buffer.order(SymTab.task.getIsa().getByteOrder());
    }
    catch (TaskException tte)
    {
      throw new RuntimeException(tte);
    }

    if (varDie.getType().compareTo("int") == 0)
      {
      int intVal;
      intVal = buffer.getInt(addr);
    
      Variable v;
      try
      {
        IntegerType intType = new
IntegerType(SymTab.task.getIsa().getWordSize(),

SymTab.task.getIsa().getByteOrder());
        v = IntegerType.newIntegerVariable(intType, intVal); 
      }
      catch (TaskException tte)
      {
        throw new RuntimeException(tte);
      }
      return v; 
      }
    return null;
  }
}

public class SymTab
{
    static Proc proc;
    static Task task;
    static int pid;
    static symTab hpdsymTab = new symTab();

    public SymTab (int pid_p, Proc proc_p, Task task_p)
    {
      pid = pid_p;
      proc = proc_p;
      task = task_p;
    }
    static public void what(Command cmd) throws ParseException
    {
      long address;
      Dwfl dwfl;
      try
      {
        address = task.getIsa().pc(task) - 1;
      }
      catch (TaskException tte)
      {
        throw new RuntimeException(tte);
      }

      dwfl = new Dwfl(pid);
      DwflLine line = null;
      DwflDieBias bias = dwfl.getDie(address);
      DwarfDie die = bias.die;
      DwarfDie[] allDies = die.getScopes(die.getLowPC() - bias.bias);

      String sInput = cmd.getFullCommand().substring(4).trim();
      DwarfDie varDie = die.getScopesVar(allDies, sInput);
      if (varDie == null)
        {
          System.out.println(sInput + " not found in scope.");
          return;
        }
      long addr = varDie.getAddr();
      String type = varDie.getType();
      System.out.println(type + " " + varDie.getName());
      
    }
    
    private static final int DECIMAL = 10;
    private static final int HEX = 16;
    private static final int OCTAL = 8;
    
    static public void print(Command cmd) throws ParseException
    {
...Moved from PrintHandler otherwise mostly unchanged
    }
}


Index: frysk-imports/lib/dw/DwarfDie.java
===================================================================
diff -u -p -r1.4 DwarfDie.java
@@ -94,10 +94,43 @@ public class DwarfDie
     return dies;
   }
   
+  public DwarfDie getScopesVar (DwarfDie[] scopes, String variable)
+  {
+    long[] vals = new long[scopes.length];
+    for(int i = 0; i < scopes.length; i++)
+	vals[i] = scopes[i].getPointer();
+
+    DwarfDie die = null;
+    long val = get_scopesvar(vals, scopes.length, variable);
+    if (val != 0)
+      die = new DwarfDie(val, this.parent);
+    return die;
+  }
+    
+  
+  public long getAddr ()
+  {
+    return get_addr(this.getPointer());
+  }
+
+  public String getType ()
+  {
+    return get_type(this.getPointer());
+  }
+  
   protected long getPointer ()
   {
     return this.pointer;
   }
+  
+  public boolean fbregVariable ()
+  {
+    long is_fb = fbreg_variable (this.getPointer());
+    if (is_fb == 1)
+      return true;
+    else
+      return false;
+  }
 
   // protected native long dwarf_diecu();
   private native long get_lowpc ();
@@ -107,4 +140,12 @@ public class DwarfDie
   private native String get_diename ();
   
   private native long[] get_scopes (long addr);
+
+  private native long get_scopesvar (long[] scopes, long nscopes,
String variable);
+  
+  private native long get_addr (long addr);
+  
+  private native String get_type (long addr);
+  
+  private native long fbreg_variable (long addr);
 }
Index: frysk-imports/lib/dw/cni/DwarfDie.cxx
===================================================================
diff -u -p -r1.3 DwarfDie.cxx
@@ -78,3 +82,96 @@ lib::dw::DwarfDie::get_scopes(jlong addr
 		
 	return longs;
 }
+
+Dwarf_Die *var_die;
+
+jlong
+lib::dw::DwarfDie::get_scopesvar (jlongArray scopes, jlong nscopes,
+				  jstring variable)
+{
+  // alloc this in java
+  var_die = (Dwarf_Die*)malloc(sizeof(Dwarf_Die));
+
+  Dwarf_Die *dies[nscopes];
+  jlong* scopesp = elements(scopes);
+
+  for(int i = 0; i < nscopes; i++)
+    {
+      jlong dieptr = scopesp[i];
+      dies[i] = (Dwarf_Die*)dieptr;
+    }
+  
+  // have this return int declaring_scope
+  int code = dwarf_getscopevar (*dies, nscopes,
+				(const char*)JvGetStringChars(variable),
+				0, NULL, 0, 0, var_die);
+  if (code >= 0)
+    return (jlong)var_die;
+  else
+    return 0;
+}
+
+jlong
+lib::dw::DwarfDie::get_addr (jlong var_die)
+{
+  Dwarf_Die *die = (Dwarf_Die*) var_die;
+  Dwarf_Block block;
+  Dwarf_Attribute loc_attr;
+  Dwarf_Op *fb_expr;
+  size_t fb_len;
+  
+  if (dwarf_attr_integrate (die, DW_AT_location, &loc_attr))
+    {
+      dwarf_formblock (&loc_attr, &block);
+      dwarf_getlocation (&loc_attr, &fb_expr, &fb_len);
+      FILE *f = fopen ("/tmp/,dwarfdie", "w");
+      fprintf (f, "fb_len %d atom %x operand %d offset %d\n",
(int)fb_len, (int)fb_expr[0].atom, (int)fb_expr[0].number,
(int)fb_expr[0].offset);
+      fclose (f);
+      return fb_expr[0].number;
+    }
+  else
+    return 0;
+}
+
+jstring
+lib::dw::DwarfDie::get_type (jlong var_die)
+{
+  Dwarf_Die *die = (Dwarf_Die*) var_die;
+  Dwarf_Die *type_die, type_mem_die;
+  Dwarf_Attribute type_attr;
+  
+  if (dwarf_attr_integrate (die, DW_AT_type, &type_attr))
+    {
+      type_die = dwarf_formref_die (&type_attr, &type_mem_die);
+      if (dwarf_tag (type_die) == DW_TAG_base_type)
+	{
+	  return JvNewStringLatin1
+	    (dwarf_formstring (dwarf_attr_integrate
+			       (type_die, DW_AT_name, &type_attr)));
+	}
+    }
+  return 0;
+}
+
+jlong
+lib::dw::DwarfDie::fbreg_variable (jlong var_die)
+{
+  Dwarf_Die *die = (Dwarf_Die*) var_die;
+  Dwarf_Block block;
+  Dwarf_Attribute loc_attr;
+  Dwarf_Op *fb_expr;
+  size_t fb_len;
+  
+  if (dwarf_attr_integrate (die, DW_AT_location, &loc_attr))
+    {
+      dwarf_formblock (&loc_attr, &block);
+      dwarf_getlocation (&loc_attr, &fb_expr, &fb_len);
+      FILE *f = fopen ("/tmp/,dwarfdie", "w");
+      fprintf (f, "fb_len %d atom %x operand %d offset %d\n",
(int)fb_len, (int)fb_expr[0].atom, (int)fb_expr[0].number,
(int)fb_expr[0].offset);
+      fclose (f);
+      if (fb_expr[0].atom == DW_OP_fbreg)
+	return 1;
+    }
+  return 0;
+}
+



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