Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] Use compilation unit's address size in dwarf2expr.c and  dwarf2loc.c
@ 2008-03-14 22:15 Kevin Buettner
  2008-03-15 19:36 ` Jim Blandy
  0 siblings, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2008-03-14 22:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jim Blandy

The patch below is a re-work of a patch that Jim Blandy wrote in 2005
and posted in 2006.  Jim's 2006 posting may be found here:

    http://sourceware.org/ml/gdb-patches/2006-05/msg00226.html

This patch fixes problems identified by Fred Fish and Michael Snyder.
See:

    http://sourceware.org/ml/gdb-patches/2006-05/msg00198.html

and:

    http://sourceware.org/ml/gdb-patches/2006-05/msg00484.html

I've tested this patch against i686-pc-linux-gnu (native) and mipsisa64-elf
(cross).  I see no regressions for i686-pc-linux.  For mipsisa64-elf, the
failure count for gdb.base/*.exp is reduced from 882 to 447.

I've tried to preserve the structure of Jim's ChangeLog comments as
much as possible to make comparisons between this and the original
work easier.

Comments?

	Include a pointer to the partial symbol table in the symbol
	batons, not to the objfile.
	* dwarf2loc.h (sturct dwarf2_locexpr_baton, struct
	dwarf2_loclist_baton): New member `psymtab', replacing `objfile'.
	* dwarf2loc.c (dwarf2_evaluate_loc_desc): Expect a psymtab, not
	an objfile.  Store the psymtab's objfile in baton.
	(locexpr_read_variable, loclist_read_variable): Pass
	baton->psymtab to dwarf2_evaluate_loc_desc, not baton->objfile.
	(locexpr_describe_location): Get the file name for thread-local
	storage blocks from dlbaton->psymtab->objfile, instead of
	dlbaton->objfile.
	* dwarf2read.c (dwarf2_symbol_mark_computed): Store the cu's psymtab
	in the batons we create for location expressions and location lists.

	Allow dwarf2loc.c to find a compilation unit's address size, given
	the psymtab for that compilation unit.
	* dwarf2loc.h (dwarf_psymtab_address_size): New function.
	* dwarf2read.c (struct dwarf2_per_cu_data): Add `address_size'
	member.
	(load_full_comp_unit): Store the cu's address size in it.
	(dwarf_psymtab_address_size): New function.

	Use the correct address size when parsing Dwarf 2 location lists,
	and evaluation of DW_OP_deref and DW_OP_deref_size opcodes.
	* dwarf2loc.h (struct dwarf_expr_context): New member
	`address_size'.
	(dwarf2_read_address): Adjust prototype; see next change.
	* dwarf2expr.c (dwarf2_read_address): Take the address size as an
	argument, rather than returning the address size via a reference
	parameter.
	(unsigned_address_type, signed_address_type): Take an address size
	as an argument.
	(execute_stack_op): Pass CTX's address size to dwarf2_read_address.
	Use it as the pointer size for DW_OP_deref and DW_OP_deref_size.
	Pass CTX to pass the address size to unsigned_address_type and
	signed_address_type.
	* dwarf2loc.h (dwarf_psymtab_address_size): New prototype.
	* dwarf2loc.c (find_location_expression): Use baton->psymtab's
	address size.
	(dwarf2_evaluate_loc_desc): Store PSYMTAB's address size in the
	context we're creating.
	(dwarf2_loc_desc_needs_frame): Likewise.
	(locexpr_read_needs_frame): Pass the psymtab to
	dwarf2_loc_desc_needs_frame.
	(locexpr_describe_location): Use dlbaton's psymtab's address size
	to read DW_OP_GNU_push_tls_address's operand.
	* dwarf2-frame.c (size_of_encoded_value): Add forward declaration.
	(execute_stack_op, execute_cfa_program): Use
	size_of_encoded_value (DW_EH_PE_absptr) as the address size.

Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.79
diff -u -p -r1.79 dwarf2-frame.c
--- dwarf2-frame.c	1 Jan 2008 22:53:09 -0000	1.79
+++ dwarf2-frame.c	14 Mar 2008 20:56:35 -0000
@@ -227,6 +227,8 @@ dwarf2_frame_state_free (void *p)
 
 /* Helper functions for execute_stack_op.  */
 
+static unsigned int size_of_encoded_value (gdb_byte encoding);
+
 static CORE_ADDR
 read_reg (void *baton, int reg)
 {
@@ -312,6 +314,11 @@ execute_stack_op (gdb_byte *exp, ULONGES
   ctx->get_frame_base = no_get_frame_base;
   ctx->get_tls_address = no_get_tls_address;
 
+  /* This isn't really right, but the Dwarf spec doesn't say what
+     address size is correct to use for CFI, so this is a reasonable
+     guess.  */
+  ctx->address_size = size_of_encoded_value (DW_EH_PE_absptr);
+
   dwarf_expr_push (ctx, initial);
   dwarf_expr_eval (ctx, exp, len);
   result = dwarf_expr_fetch (ctx, 0);
@@ -331,7 +338,6 @@ execute_cfa_program (gdb_byte *insn_ptr,
 		     struct dwarf2_frame_state *fs, int eh_frame_p)
 {
   CORE_ADDR pc = frame_pc_unwind (next_frame);
-  int bytes_read;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
 
   while (insn_ptr < insn_end && fs->pc <= pc)
@@ -362,8 +368,14 @@ execute_cfa_program (gdb_byte *insn_ptr,
 	  switch (insn)
 	    {
 	    case DW_CFA_set_loc:
-	      fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
-	      insn_ptr += bytes_read;
+	      /* This isn't really the right address size to use, but
+		 the Dwarf spec doesn't say what address size is
+		 correct to use for CFI, so this is a reasonable
+		 guess.  */
+	      fs->pc =
+		dwarf2_read_address (insn_ptr, insn_end,
+				     size_of_encoded_value (DW_EH_PE_absptr));
+	      insn_ptr += size_of_encoded_value (DW_EH_PE_absptr);
 	      break;
 
 	    case DW_CFA_advance_loc1:
Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.24
diff -u -p -r1.24 dwarf2expr.c
--- dwarf2expr.c	1 Jan 2008 22:53:09 -0000	1.24
+++ dwarf2expr.c	14 Mar 2008 20:56:35 -0000
@@ -32,7 +32,7 @@
 
 static void execute_stack_op (struct dwarf_expr_context *,
 			      gdb_byte *, gdb_byte *);
-static struct type *unsigned_address_type (void);
+static struct type *unsigned_address_type (CORE_ADDR address_size);
 
 /* Create a new context for the expression evaluator.  */
 
@@ -192,20 +192,17 @@ read_sleb128 (gdb_byte *buf, gdb_byte *b
   return buf;
 }
 
-/* Read an address from BUF, and verify that it doesn't extend past
-   BUF_END.  The address is returned, and *BYTES_READ is set to the
-   number of bytes read from BUF.  */
+/* Read and return an ADDRESS_SIZE-byte address from BUF, and verify
+   that it doesn't extend past BUF_END.  */
 
 CORE_ADDR
-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
+dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, CORE_ADDR address_size)
 {
   CORE_ADDR result;
 
-  if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  if (buf_end - buf < address_size)
     error (_("dwarf2_read_address: Corrupted DWARF expression."));
 
-  *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
-
   /* For most architectures, calling extract_unsigned_integer() alone
      is sufficient for extracting an address.  However, some
      architectures (e.g. MIPS) use signed addresses and using
@@ -229,11 +226,9 @@ dwarf2_read_address (gdb_byte *buf, gdb_
      address being returned.  */
 
   result = value_as_address (value_from_longest 
-			      (unsigned_address_type (),
+			      (unsigned_address_type (address_size),
 			       extract_unsigned_integer 
-				 (buf,
-				  gdbarch_addr_bit (current_gdbarch)
-				    / TARGET_CHAR_BIT)));
+				 (buf, address_size)));
 
   return result;
 }
@@ -241,9 +236,9 @@ dwarf2_read_address (gdb_byte *buf, gdb_
 /* Return the type of an address, for unsigned arithmetic.  */
 
 static struct type *
-unsigned_address_type (void)
+unsigned_address_type (CORE_ADDR address_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (address_size)
     {
     case 2:
       return builtin_type_uint16;
@@ -260,9 +255,9 @@ unsigned_address_type (void)
 /* Return the type of an address, for signed arithmetic.  */
 
 static struct type *
-signed_address_type (void)
+signed_address_type (CORE_ADDR address_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (address_size)
     {
     case 2:
       return builtin_type_int16;
@@ -332,8 +327,8 @@ execute_stack_op (struct dwarf_expr_cont
 	  break;
 
 	case DW_OP_addr:
-	  result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
-	  op_ptr += bytes_read;
+	  result = dwarf2_read_address (op_ptr, op_end, ctx->address_size);
+	  op_ptr += ctx->address_size;
 	  break;
 
 	case DW_OP_const1u:
@@ -550,34 +545,23 @@ execute_stack_op (struct dwarf_expr_cont
 	    {
 	    case DW_OP_deref:
 	      {
-		gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch)
-					  / TARGET_CHAR_BIT);
-		int bytes_read;
+		gdb_byte *buf = alloca (ctx->address_size);
 
-		(ctx->read_mem) (ctx->baton, buf, result,
-				 gdbarch_addr_bit (current_gdbarch)
-				   / TARGET_CHAR_BIT);
-		result = dwarf2_read_address (buf,
-					      buf + (gdbarch_addr_bit
-						       (current_gdbarch)
-						     / TARGET_CHAR_BIT),
-					      &bytes_read);
+		(ctx->read_mem) (ctx->baton, buf, result, ctx->address_size);
+		result = dwarf2_read_address (buf, buf + ctx->address_size,
+					      ctx->address_size);
 	      }
 	      break;
 
 	    case DW_OP_deref_size:
 	      {
 		gdb_byte *buf
-		   = alloca (gdbarch_addr_bit (current_gdbarch)
-			      / TARGET_CHAR_BIT);
+		   = alloca (ctx->address_size);
 		int bytes_read;
 
 		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
-		result = dwarf2_read_address (buf,
-					      buf + (gdbarch_addr_bit
-						      (current_gdbarch)
-						     / TARGET_CHAR_BIT),
-					      &bytes_read);
+		result = dwarf2_read_address (buf, buf + ctx->address_size,
+					      ctx->address_size);
 	      }
 	      break;
 
@@ -628,8 +612,8 @@ execute_stack_op (struct dwarf_expr_cont
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
-	    val1 = value_from_longest (unsigned_address_type (), first);
-	    val2 = value_from_longest (unsigned_address_type (), second);
+	    val1 = value_from_longest (unsigned_address_type (ctx->address_size), first);
+	    val2 = value_from_longest (unsigned_address_type (ctx->address_size), second);
 
 	    switch (op)
 	      {
@@ -662,7 +646,7 @@ execute_stack_op (struct dwarf_expr_cont
                 break;
 	      case DW_OP_shra:
 		binop = BINOP_RSH;
-		val1 = value_from_longest (signed_address_type (), first);
+		val1 = value_from_longest (signed_address_type (ctx->address_size), first);
 		break;
 	      case DW_OP_xor:
 		binop = BINOP_BITWISE_XOR;
Index: dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.12
diff -u -p -r1.12 dwarf2expr.h
--- dwarf2expr.h	1 Jan 2008 22:53:09 -0000	1.12
+++ dwarf2expr.h	14 Mar 2008 20:56:35 -0000
@@ -34,6 +34,11 @@ struct dwarf_expr_context
      number of elements allocated to the stack.  */
   int stack_len, stack_allocated;
 
+  /* The size of an address, in bytes.  For use with operations like
+     DW_OP_addr and DW_OP_deref, and for properly masking arguments to
+     division-like operators.  */
+  CORE_ADDR address_size;
+
   /* An opaque argument provided by the caller, which will be passed
      to all of the callback functions.  */
   void *baton;
@@ -136,6 +141,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf
 gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r);
 gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r);
 CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
-			       int *bytes_read);
+                               CORE_ADDR address_size);
 
 #endif /* dwarf2expr.h */
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.48
diff -u -p -r1.48 dwarf2loc.c
--- dwarf2loc.c	1 Jan 2008 22:53:09 -0000	1.48
+++ dwarf2loc.c	14 Mar 2008 20:56:35 -0000
@@ -54,11 +54,11 @@ find_location_expression (struct dwarf2_
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+  unsigned int addr_size = dwarf_psymtab_address_size (baton->psymtab);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
-				    SECT_OFF_TEXT (baton->objfile));
+  CORE_ADDR base_offset = ANOFFSET (baton->psymtab->objfile->section_offsets,
+				    SECT_OFF_TEXT (baton->psymtab->objfile));
   CORE_ADDR base_address = baton->base_address + base_offset;
 
   loc_ptr = baton->data;
@@ -66,10 +66,10 @@ find_location_expression (struct dwarf2_
 
   while (1)
     {
-      low = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
-      high = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
+      low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
+      high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
       if (low == 0 && high == 0)
@@ -185,11 +185,12 @@ dwarf_expr_tls_address (void *baton, COR
 
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable VAR in the context
-   of FRAME.  */
+   of FRAME.  PSYMTAB is the partial symtab for the compilation unit
+   defining VAR.  */
 static struct value *
 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
 			  gdb_byte *data, unsigned short size,
-			  struct objfile *objfile)
+			  struct partial_symtab *psymtab)
 {
   struct gdbarch *arch = get_frame_arch (frame);
   struct value *retval;
@@ -205,9 +206,10 @@ dwarf2_evaluate_loc_desc (struct symbol 
     }
 
   baton.frame = frame;
-  baton.objfile = objfile;
+  baton.objfile = psymtab->objfile;
 
   ctx = new_dwarf_expr_context ();
+  ctx->address_size = dwarf_psymtab_address_size (psymtab);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
@@ -318,7 +320,8 @@ needs_frame_tls_address (void *baton, CO
    requires a frame to evaluate.  */
 
 static int
-dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
+dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
+                             struct partial_symtab *psymtab)
 {
   struct needs_frame_baton baton;
   struct dwarf_expr_context *ctx;
@@ -327,6 +330,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  ctx->address_size = dwarf_psymtab_address_size (psymtab);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
@@ -429,7 +433,7 @@ locexpr_read_variable (struct symbol *sy
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
   struct value *val;
   val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
-				  dlbaton->objfile);
+				  dlbaton->psymtab);
 
   return val;
 }
@@ -439,7 +443,8 @@ static int
 locexpr_read_needs_frame (struct symbol *symbol)
 {
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
-  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
+  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
+                                      dlbaton->psymtab);
 }
 
 /* Print a natural-language description of SYMBOL to STREAM.  */
@@ -477,14 +482,14 @@ locexpr_describe_location (struct symbol
       && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
     if (dlbaton->data[0] == DW_OP_addr)
       {
-	int bytes_read;
+	int address_size = dwarf_psymtab_address_size (dlbaton->psymtab);
 	CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
 						&dlbaton->data[dlbaton->size - 1],
-						&bytes_read);
+						address_size);
 	fprintf_filtered (stream, 
 			  "a thread-local variable at offset %s in the "
 			  "thread-local storage for `%s'",
-			  paddr_nz (offset), dlbaton->objfile->name);
+			  paddr_nz (offset), dlbaton->psymtab->objfile->name);
 	return 1;
       }
   
@@ -546,7 +551,7 @@ loclist_read_variable (struct symbol *sy
     }
   else
     val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
-				    dlbaton->objfile);
+				    dlbaton->psymtab);
 
   return val;
 }
Index: dwarf2loc.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.h,v
retrieving revision 1.10
diff -u -p -r1.10 dwarf2loc.h
--- dwarf2loc.h	1 Jan 2008 22:53:09 -0000	1.10
+++ dwarf2loc.h	14 Mar 2008 20:56:35 -0000
@@ -25,6 +25,10 @@ struct symbol_ops;
 /* This header is private to the DWARF-2 reader.  It is shared between
    dwarf2read.c and dwarf2loc.c.  */
 
+/* Return the address size given in the compilation unit header for
+   PSYMTAB.  */
+CORE_ADDR dwarf_psymtab_address_size (struct partial_symtab *psymtab);
+
 /* The symbol location baton types used by the DWARF-2 reader (i.e.
    SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol).  "struct
    dwarf2_locexpr_baton" is for a symbol with a single location
@@ -39,8 +43,12 @@ struct dwarf2_locexpr_baton
   /* Length of the location expression.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  struct objfile *objfile;
+  /* The partial symtab structure for the compilation unit containing
+     the symbol whose location we're computing.  Passing the psymtab
+     instead of the objfile gives us access to compilation-unit-
+     specific information like Dwarf address size, and the psymtab
+     also points to the objfile.  */
+  struct partial_symtab *psymtab;
 };
 
 struct dwarf2_loclist_baton
@@ -55,12 +63,12 @@ struct dwarf2_loclist_baton
   /* Length of the location list.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  /* Used (only???) by thread local variables.  The objfile in which
-     this symbol is defined.  To find a thread-local variable (e.g., a
-     variable declared with the `__thread' storage class), we may need
-     to know which object file it's in.  */
-  struct objfile *objfile;
+  /* The partial symtab structure for the compilation unit containing
+     the symbol whose location we're computing.  Passing the psymtab
+     instead of the objfile gives us access to compilation-unit-
+     specific information like Dwarf address size, and the psymtab
+     also points to the objfile.  */
+  struct partial_symtab *psymtab;
 };
 
 extern const struct symbol_ops dwarf2_locexpr_funcs;
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.252
diff -u -p -r1.252 dwarf2read.c
--- dwarf2read.c	10 Mar 2008 14:01:56 -0000	1.252
+++ dwarf2read.c	14 Mar 2008 20:56:36 -0000
@@ -378,6 +378,10 @@ struct dwarf2_per_cu_data
      or NULL for partial units (which do not have an associated
      symtab).  */
   struct partial_symtab *psymtab;
+
+  /* Size of the addresses in this compilation unit -- from the
+     compilation unit header.  */
+  CORE_ADDR address_size;
 };
 
 /* The line number information for a compilation unit (found in the
@@ -2548,6 +2552,9 @@ load_full_comp_unit (struct dwarf2_per_c
 
   /* read in the comp_unit header  */
   info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
+  
+  /* Save the address size in the per-cu data.  */
+  per_cu->address_size = cu->header.addr_size;
 
   /* Read the abbrevs for this compilation unit  */
   dwarf2_read_abbrevs (abfd, cu);
@@ -2657,6 +2664,14 @@ process_full_comp_unit (struct dwarf2_pe
   do_cleanups (back_to);
 }
 
+CORE_ADDR
+dwarf_psymtab_address_size (struct partial_symtab *psymtab)
+{
+  struct dwarf2_per_cu_data *this_cu 
+    = (struct dwarf2_per_cu_data *) psymtab->read_symtab_private;
+  return this_cu->address_size;
+}
+
 /* Process a die and its children.  */
 
 static void
@@ -9835,7 +9850,7 @@ dwarf2_symbol_mark_computed (struct attr
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
 			     sizeof (struct dwarf2_loclist_baton));
-      baton->objfile = objfile;
+      baton->psymtab = cu->per_cu->psymtab;
 
       /* We don't know how long the location list is, but make sure we
 	 don't run off the edge of the section.  */
@@ -9855,7 +9870,7 @@ dwarf2_symbol_mark_computed (struct attr
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
 			     sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = objfile;
+      baton->psymtab = cu->per_cu->psymtab;
 
       if (attr_form_is_block (attr))
 	{


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c
  2008-03-14 22:15 [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c Kevin Buettner
@ 2008-03-15 19:36 ` Jim Blandy
  2008-03-15 19:38   ` Jim Blandy
  0 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2008-03-15 19:36 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches, Jim Blandy

Didn't Uli W. update that patch already?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c
  2008-03-15 19:36 ` Jim Blandy
@ 2008-03-15 19:38   ` Jim Blandy
  2008-03-16  1:39     ` Kevin Buettner
  0 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2008-03-15 19:38 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches, Jim Blandy

On Sat, Mar 15, 2008 at 12:36 PM, Jim Blandy <jimb@red-bean.com> wrote:
> Didn't Uli W. update that patch already?

I don't mean to be cryptic.  I have a strong recollection of Ulrich
Weigand starting with that patch and bringing it up to date with the
current sources.  I can't remember whether the conversation ended with
a commit, or stalled.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and  dwarf2loc.c
  2008-03-15 19:38   ` Jim Blandy
@ 2008-03-16  1:39     ` Kevin Buettner
  2008-03-17 13:35       ` Ulrich Weigand
  0 siblings, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2008-03-16  1:39 UTC (permalink / raw)
  To: gdb-patches

On Sat, 15 Mar 2008 12:38:08 -0700
"Jim Blandy" <jimb@red-bean.com> wrote:

> On Sat, Mar 15, 2008 at 12:36 PM, Jim Blandy <jimb@red-bean.com> wrote:
> > Didn't Uli W. update that patch already?
> 
> I don't mean to be cryptic.  I have a strong recollection of Ulrich
> Weigand starting with that patch and bringing it up to date with the
> current sources.  I can't remember whether the conversation ended with
> a commit, or stalled.

Apparently it stalled.  (It's certainly not in the present sources.)

The patch and and subsequent thread begins here:

    http://sourceware.org/ml/gdb-patches/2008-01/msg00329.html

Kevin


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and  dwarf2loc.c
  2008-03-16  1:39     ` Kevin Buettner
@ 2008-03-17 13:35       ` Ulrich Weigand
  2008-03-17 18:07         ` Kevin Buettner
  2008-03-17 19:15         ` Daniel Jacobowitz
  0 siblings, 2 replies; 10+ messages in thread
From: Ulrich Weigand @ 2008-03-17 13:35 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

Kevin Buettner wrote:
> On Sat, 15 Mar 2008 12:38:08 -0700
> "Jim Blandy" <jimb@red-bean.com> wrote:
> > I don't mean to be cryptic.  I have a strong recollection of Ulrich
> > Weigand starting with that patch and bringing it up to date with the
> > current sources.  I can't remember whether the conversation ended with
> > a commit, or stalled.
> 
> Apparently it stalled.  (It's certainly not in the present sources.)
> 
> The patch and and subsequent thread begins here:
> 
>     http://sourceware.org/ml/gdb-patches/2008-01/msg00329.html

Sorry for not following up on this earlier.

Here is my current patch, based on Jim Blandy's orignal patch and on
Dan Jacobowitz' patch to fix DW_CFA_set_loc.  With the exception of
the one FIXME in decode_frame_entry_1, this patch fixes all issues
related to dwarf address size handling that I'm aware of ...

Tested on i386-linux, s390-linux, and s390x-linux.

Does this look OK?

Bye,
Ulrich


2008-03-17  Ulrich Weigand  <uweigand@de.ibm.com>
	    Jim Blandy  <jimb@codesourcery.com>
	    Daniel Jacobowitz  <drow@false.org>

	* dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member.
	(dwarf2_read_address): Update prototype.

	* dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter.
	(signed_address_type): Likewise.
	(dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE.
	(execute_stack_op): Update calls to unsigned_address_type,
	signed_address_type and dwarf2_read_address.  Fix implementation
	of DW_OP_deref_size.

	* dwarfloc.h (dwarf2_per_cu_objfile): Add prototype.
	(dwarf2_per_cu_addr_size): Likewise.
	(struct dwarf2_locexpr_baton): Replace OBJFILE with PER_CU.
	(struct dwarf2_loclist_baton): Likewise.

	* dwarf2loc.c (find_location_expression): Update calls to
	dwarf2_read_address.  Use dwarf2_per_cu_objfile and
	dwarf2_per_cu_addr_size to retrieve PER_CU parameters.
	(locexpr_describe_location): Likewise.
	(dwarf2_evaluate_loc_desc): Replace OBJFILE with PER_CU parameter.
	Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu).
	(dwarf2_loc_desc_needs_frame): Add PER_CU parameter.  Set ctx->addr_size
	to dwarf2_per_cu_addr_size (per_cu).
	(locexpr_read_variable): Update dwarf2_evaluate_loc_desc call.
	(loclist_read_variable): Likewise.
	(locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call.

	* dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->per_cu
	instead of baton->objfile.
	(dwarf2_per_cu_obfile): New function.
	(dwarf2_per_cu_addr_size): Likewise.

	* dwarf2-frame.c (struct comp_unit): Move higher.
	(struct dwarf2_cie): Add UNIT and ADDR_SIZE members.
	(execute_stack_op): Add ADDR_SIZE parameter; set ctx->addr_size.
	(execute_cfa_program): Add FDE parameter.  Replace EH_FRAME_P
	parameter by using fde->eh_frame_p.  Use read_encoded_value
	to implement DW_CFA_set_loc.
	(struct dwarf2_frame_cache): Add ADDR_SIZE member.
	(dwarf2_frame_cache): Set cache->addr_size.  Update calls to
	execute_stack_op and execute_cfa_program.
	(dwarf2_frame_prev_register): Update calls to execute_stack_op.
	(size_of_encoded_value): Remove.
	(read_encoded_value): Add PTR_LEN and FUNC_BASE parameters.
	Remove call to size_of_encoded_value.  Implement DW_EH_PE_funcrel.
	(add_cie): Set cie->unit backlink.
	(decode_frame_entry_1): Set cie->addr_size.  Update calls to
	read_encoded_value.
	(dwarf2_build_frame_info): Allocate UNIT on objfile obstack.



diff -urNp gdb-orig/gdb/dwarf2expr.c gdb-head/gdb/dwarf2expr.c
--- gdb-orig/gdb/dwarf2expr.c	2008-02-06 18:20:35.000000000 +0100
+++ gdb-head/gdb/dwarf2expr.c	2008-03-17 14:01:44.000000000 +0100
@@ -32,7 +32,7 @@
 
 static void execute_stack_op (struct dwarf_expr_context *,
 			      gdb_byte *, gdb_byte *);
-static struct type *unsigned_address_type (void);
+static struct type *unsigned_address_type (int);
 
 /* Create a new context for the expression evaluator.  */
 
@@ -192,20 +192,17 @@ read_sleb128 (gdb_byte *buf, gdb_byte *b
   return buf;
 }
 
-/* Read an address from BUF, and verify that it doesn't extend past
-   BUF_END.  The address is returned, and *BYTES_READ is set to the
-   number of bytes read from BUF.  */
+/* Read an address of size ADDR_SIZE from BUF, and verify that it
+   doesn't extend past BUF_END.  */
 
 CORE_ADDR
-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
+dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size)
 {
   CORE_ADDR result;
 
-  if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  if (buf_end - buf < addr_size)
     error (_("dwarf2_read_address: Corrupted DWARF expression."));
 
-  *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
-
   /* For most architectures, calling extract_unsigned_integer() alone
      is sufficient for extracting an address.  However, some
      architectures (e.g. MIPS) use signed addresses and using
@@ -229,21 +226,18 @@ dwarf2_read_address (gdb_byte *buf, gdb_
      address being returned.  */
 
   result = value_as_address (value_from_longest 
-			      (unsigned_address_type (),
-			       extract_unsigned_integer 
-				 (buf,
-				  gdbarch_addr_bit (current_gdbarch)
-				    / TARGET_CHAR_BIT)));
-
+			      (unsigned_address_type (addr_size),
+			       extract_unsigned_integer (buf, addr_size)));
   return result;
 }
 
-/* Return the type of an address, for unsigned arithmetic.  */
+/* Return the type of an address of size ADDR_SIZE,
+   for unsigned arithmetic.  */
 
 static struct type *
-unsigned_address_type (void)
+unsigned_address_type (int addr_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (addr_size)
     {
     case 2:
       return builtin_type_uint16;
@@ -257,12 +251,13 @@ unsigned_address_type (void)
     }
 }
 
-/* Return the type of an address, for signed arithmetic.  */
+/* Return the type of an address of size ADDR_SIZE,
+   for signed arithmetic.  */
 
 static struct type *
-signed_address_type (void)
+signed_address_type (int addr_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (addr_size)
     {
     case 2:
       return builtin_type_int16;
@@ -292,7 +287,6 @@ execute_stack_op (struct dwarf_expr_cont
       CORE_ADDR result;
       ULONGEST uoffset, reg;
       LONGEST offset;
-      int bytes_read;
 
       switch (op)
 	{
@@ -332,8 +326,8 @@ execute_stack_op (struct dwarf_expr_cont
 	  break;
 
 	case DW_OP_addr:
-	  result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
-	  op_ptr += bytes_read;
+	  result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size);
+	  op_ptr += ctx->addr_size;
 	  break;
 
 	case DW_OP_const1u:
@@ -550,34 +544,20 @@ execute_stack_op (struct dwarf_expr_cont
 	    {
 	    case DW_OP_deref:
 	      {
-		gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch)
-					  / TARGET_CHAR_BIT);
-		int bytes_read;
-
-		(ctx->read_mem) (ctx->baton, buf, result,
-				 gdbarch_addr_bit (current_gdbarch)
-				   / TARGET_CHAR_BIT);
-		result = dwarf2_read_address (buf,
-					      buf + (gdbarch_addr_bit
-						       (current_gdbarch)
-						     / TARGET_CHAR_BIT),
-					      &bytes_read);
+		gdb_byte *buf = alloca (ctx->addr_size);
+		(ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
+		result = dwarf2_read_address (buf, buf + ctx->addr_size,
+					      ctx->addr_size);
 	      }
 	      break;
 
 	    case DW_OP_deref_size:
 	      {
-		gdb_byte *buf
-		   = alloca (gdbarch_addr_bit (current_gdbarch)
-			      / TARGET_CHAR_BIT);
-		int bytes_read;
-
-		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
-		result = dwarf2_read_address (buf,
-					      buf + (gdbarch_addr_bit
-						      (current_gdbarch)
-						     / TARGET_CHAR_BIT),
-					      &bytes_read);
+		int addr_size = *op_ptr++;
+		gdb_byte *buf = alloca (addr_size);
+		(ctx->read_mem) (ctx->baton, buf, result, addr_size);
+		result = dwarf2_read_address (buf, buf + addr_size,
+					      addr_size);
 	      }
 	      break;
 
@@ -628,8 +608,10 @@ execute_stack_op (struct dwarf_expr_cont
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
-	    val1 = value_from_longest (unsigned_address_type (), first);
-	    val2 = value_from_longest (unsigned_address_type (), second);
+	    val1 = value_from_longest
+		     (unsigned_address_type (ctx->addr_size), first);
+	    val2 = value_from_longest
+		     (unsigned_address_type (ctx->addr_size), second);
 
 	    switch (op)
 	      {
@@ -662,7 +644,8 @@ execute_stack_op (struct dwarf_expr_cont
                 break;
 	      case DW_OP_shra:
 		binop = BINOP_RSH;
-		val1 = value_from_longest (signed_address_type (), first);
+		val1 = value_from_longest
+			 (signed_address_type (ctx->addr_size), first);
 		break;
 	      case DW_OP_xor:
 		binop = BINOP_BITWISE_XOR;
diff -urNp gdb-orig/gdb/dwarf2expr.h gdb-head/gdb/dwarf2expr.h
--- gdb-orig/gdb/dwarf2expr.h	2008-02-06 18:20:35.000000000 +0100
+++ gdb-head/gdb/dwarf2expr.h	2008-03-17 14:01:44.000000000 +0100
@@ -34,6 +34,9 @@ struct dwarf_expr_context
      number of elements allocated to the stack.  */
   int stack_len, stack_allocated;
 
+  /* Target address size in bytes.  */
+  int addr_size;
+
   /* An opaque argument provided by the caller, which will be passed
      to all of the callback functions.  */
   void *baton;
@@ -136,6 +139,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf
 gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r);
 gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r);
 CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
-			       int *bytes_read);
+			       int addr_size);
 
 #endif /* dwarf2expr.h */
diff -urNp gdb-orig/gdb/dwarf2-frame.c gdb-head/gdb/dwarf2-frame.c
--- gdb-orig/gdb/dwarf2-frame.c	2008-02-06 18:20:35.000000000 +0100
+++ gdb-head/gdb/dwarf2-frame.c	2008-03-17 14:05:04.000000000 +0100
@@ -38,12 +38,17 @@
 #include "complaints.h"
 #include "dwarf2-frame.h"
 
+struct comp_unit;
+
 /* Call Frame Information (CFI).  */
 
 /* Common Information Entry (CIE).  */
 
 struct dwarf2_cie
 {
+  /* Computation Unit for this CIE.  */
+  struct comp_unit *unit;
+
   /* Offset into the .debug_frame section where this CIE was found.
      Used to identify this CIE.  */
   ULONGEST cie_pointer;
@@ -68,6 +73,9 @@ struct dwarf2_cie
   /* Encoding of addresses.  */
   gdb_byte encoding;
 
+  /* Target address size in bytes.  */
+  int addr_size;
+
   /* True if a 'z' augmentation existed.  */
   unsigned char saw_z_augmentation;
 
@@ -104,10 +112,44 @@ struct dwarf2_fde
   struct dwarf2_fde *next;
 };
 
+/* A minimal decoding of DWARF2 compilation units.  We only decode
+   what's needed to get to the call frame information.  */
+
+struct comp_unit
+{
+  /* Keep the bfd convenient.  */
+  bfd *abfd;
+
+  struct objfile *objfile;
+
+  /* Linked list of CIEs for this object.  */
+  struct dwarf2_cie *cie;
+
+  /* Pointer to the .debug_frame section loaded into memory.  */
+  gdb_byte *dwarf_frame_buffer;
+
+  /* Length of the loaded .debug_frame section.  */
+  unsigned long dwarf_frame_size;
+
+  /* Pointer to the .debug_frame section.  */
+  asection *dwarf_frame_section;
+
+  /* Base for DW_EH_PE_datarel encodings.  */
+  bfd_vma dbase;
+
+  /* Base for DW_EH_PE_textrel encodings.  */
+  bfd_vma tbase;
+};
+
 static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc);
 
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
 				       int eh_frame_p);
+
+static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
+				     int ptr_len, gdb_byte *buf,
+				     unsigned int *bytes_read_ptr,
+				     CORE_ADDR func_base);
 \f
 
 /* Structure describing a frame state.  */
@@ -299,13 +341,14 @@ register %s (#%d) at 0x%s"),
 }
 
 static CORE_ADDR
-execute_stack_op (gdb_byte *exp, ULONGEST len,
+execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
 		  struct frame_info *next_frame, CORE_ADDR initial)
 {
   struct dwarf_expr_context *ctx;
   CORE_ADDR result;
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = addr_size;
   ctx->baton = next_frame;
   ctx->read_reg = read_reg;
   ctx->read_mem = read_mem;
@@ -326,10 +369,11 @@ execute_stack_op (gdb_byte *exp, ULONGES
 \f
 
 static void
-execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end,
-		     struct frame_info *next_frame,
-		     struct dwarf2_frame_state *fs, int eh_frame_p)
+execute_cfa_program (struct dwarf2_fde *fde, gdb_byte *insn_ptr,
+		     gdb_byte *insn_end, struct frame_info *next_frame,
+		     struct dwarf2_frame_state *fs)
 {
+  int eh_frame_p = fde->eh_frame_p;
   CORE_ADDR pc = frame_pc_unwind (next_frame);
   int bytes_read;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -362,7 +406,12 @@ execute_cfa_program (gdb_byte *insn_ptr,
 	  switch (insn)
 	    {
 	    case DW_CFA_set_loc:
-	      fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
+	      fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
+					   fde->cie->addr_size, insn_ptr,
+					   &bytes_read, fde->initial_location);
+	      /* Apply the objfile offset for relocatable objects.  */
+	      fs->pc += ANOFFSET (fde->cie->unit->objfile->section_offsets,
+				  SECT_OFF_TEXT (fde->cie->unit->objfile));
 	      insn_ptr += bytes_read;
 	      break;
 
@@ -813,6 +862,9 @@ struct dwarf2_frame_cache
 
   /* Return address register.  */
   struct dwarf2_frame_state_reg retaddr_reg;
+
+  /* Target address size in bytes.  */
+  int addr_size;
 };
 
 static struct dwarf2_frame_cache *
@@ -863,21 +915,21 @@ dwarf2_frame_cache (struct frame_info *n
   fs->data_align = fde->cie->data_alignment_factor;
   fs->code_align = fde->cie->code_alignment_factor;
   fs->retaddr_column = fde->cie->return_address_register;
+  cache->addr_size = fde->cie->addr_size;
 
   /* Check for "quirks" - known bugs in producers.  */
   dwarf2_frame_find_quirks (fs, fde);
 
   /* First decode all the insns in the CIE.  */
-  execute_cfa_program (fde->cie->initial_instructions,
-		       fde->cie->end, next_frame, fs, fde->eh_frame_p);
+  execute_cfa_program (fde, fde->cie->initial_instructions,
+		       fde->cie->end, next_frame, fs);
 
   /* Save the initialized register set.  */
   fs->initial = fs->regs;
   fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs);
 
   /* Then decode the insns in the FDE up to our target PC.  */
-  execute_cfa_program (fde->instructions, fde->end, next_frame, fs,
-		       fde->eh_frame_p);
+  execute_cfa_program (fde, fde->instructions, fde->end, next_frame, fs);
 
   /* Caclulate the CFA.  */
   switch (fs->cfa_how)
@@ -892,7 +944,8 @@ dwarf2_frame_cache (struct frame_info *n
 
     case CFA_EXP:
       cache->cfa =
-	execute_stack_op (fs->cfa_exp, fs->cfa_exp_len, next_frame, 0);
+	execute_stack_op (fs->cfa_exp, fs->cfa_exp_len,
+			  cache->addr_size, next_frame, 0);
       break;
 
     default:
@@ -1089,7 +1142,7 @@ dwarf2_frame_prev_register (struct frame
       *lvalp = lval_memory;
       *addrp = execute_stack_op (cache->reg[regnum].loc.exp,
 				 cache->reg[regnum].exp_len,
-				 next_frame, cache->cfa);
+				 cache->addr_size, next_frame, cache->cfa);
       *realnump = -1;
       if (valuep)
 	{
@@ -1117,7 +1170,8 @@ dwarf2_frame_prev_register (struct frame
 	store_unsigned_integer (valuep, register_size (gdbarch, regnum),
 				execute_stack_op (cache->reg[regnum].loc.exp,
 						  cache->reg[regnum].exp_len,
-						  next_frame, cache->cfa));
+						  cache->addr_size, next_frame,
+						  cache->cfa));
       break;
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
@@ -1261,35 +1315,6 @@ dwarf2_frame_base_sniffer (struct frame_
   return NULL;
 }
 \f
-/* A minimal decoding of DWARF2 compilation units.  We only decode
-   what's needed to get to the call frame information.  */
-
-struct comp_unit
-{
-  /* Keep the bfd convenient.  */
-  bfd *abfd;
-
-  struct objfile *objfile;
-
-  /* Linked list of CIEs for this object.  */
-  struct dwarf2_cie *cie;
-
-  /* Pointer to the .debug_frame section loaded into memory.  */
-  gdb_byte *dwarf_frame_buffer;
-
-  /* Length of the loaded .debug_frame section.  */
-  unsigned long dwarf_frame_size;
-
-  /* Pointer to the .debug_frame section.  */
-  asection *dwarf_frame_section;
-
-  /* Base for DW_EH_PE_datarel encodings.  */
-  bfd_vma dbase;
-
-  /* Base for DW_EH_PE_textrel encodings.  */
-  bfd_vma tbase;
-};
-
 const struct objfile_data *dwarf2_frame_objfile_data;
 
 static unsigned int
@@ -1417,32 +1442,11 @@ encoding_for_size (unsigned int size)
     }
 }
 
-static unsigned int
-size_of_encoded_value (gdb_byte encoding)
-{
-  if (encoding == DW_EH_PE_omit)
-    return 0;
-
-  switch (encoding & 0x07)
-    {
-    case DW_EH_PE_absptr:
-      return TYPE_LENGTH (builtin_type_void_data_ptr);
-    case DW_EH_PE_udata2:
-      return 2;
-    case DW_EH_PE_udata4:
-      return 4;
-    case DW_EH_PE_udata8:
-      return 8;
-    default:
-      internal_error (__FILE__, __LINE__, _("Invalid or unsupported encoding"));
-    }
-}
-
 static CORE_ADDR
 read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
-		    gdb_byte *buf, unsigned int *bytes_read_ptr)
+		    int ptr_len, gdb_byte *buf, unsigned int *bytes_read_ptr,
+		    CORE_ADDR func_base)
 {
-  int ptr_len = size_of_encoded_value (DW_EH_PE_absptr);
   ptrdiff_t offset;
   CORE_ADDR base;
 
@@ -1470,12 +1474,7 @@ read_encoded_value (struct comp_unit *un
       base = unit->tbase;
       break;
     case DW_EH_PE_funcrel:
-      /* FIXME: kettenis/20040501: For now just pretend
-         DW_EH_PE_funcrel is equivalent to DW_EH_PE_absptr.  For
-         reading the initial location of an FDE it should be treated
-         as such, and currently that's the only place where this code
-         is used.  */
-      base = 0;
+      base = func_base;
       break;
     case DW_EH_PE_aligned:
       base = 0;
@@ -1561,6 +1560,7 @@ add_cie (struct comp_unit *unit, struct 
 {
   cie->next = unit->cie;
   unit->cie = cie;
+  cie->unit = unit;
 }
 
 /* Find the FDE for *PC.  Return a pointer to the FDE, and store the
@@ -1685,6 +1685,13 @@ decode_frame_entry_1 (struct comp_unit *
          depends on the target address size.  */
       cie->encoding = DW_EH_PE_absptr;
 
+      /* The target address size.  For .eh_frame FDEs this is considered
+	 equal to the size of a target pointer.  For .dwarf_frame FDEs, 
+	 this is supposed to be the target address size from the associated
+	 CU header.  FIXME: We do not have a good way to determine the 
+	 latter.  Always use the target pointer size for now.  */
+      cie->addr_size = gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+
       /* We'll determine the final value later, but we need to
 	 initialize it conservatively.  */
       cie->signal_frame = 0;
@@ -1773,7 +1780,8 @@ decode_frame_entry_1 (struct comp_unit *
 	    {
 	      /* Skip.  Avoid indirection since we throw away the result.  */
 	      gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
-	      read_encoded_value (unit, encoding, buf, &bytes_read);
+	      read_encoded_value (unit, encoding, cie->addr_size,
+				  buf, &bytes_read, 0);
 	      buf += bytes_read;
 	      augmentation++;
 	    }
@@ -1837,11 +1845,13 @@ decode_frame_entry_1 (struct comp_unit *
       gdb_assert (fde->cie != NULL);
 
       fde->initial_location =
-	read_encoded_value (unit, fde->cie->encoding, buf, &bytes_read);
+	read_encoded_value (unit, fde->cie->encoding, fde->cie->addr_size,
+			    buf, &bytes_read, 0);
       buf += bytes_read;
 
       fde->address_range =
-	read_encoded_value (unit, fde->cie->encoding & 0x0f, buf, &bytes_read);
+	read_encoded_value (unit, fde->cie->encoding & 0x0f,
+			    fde->cie->addr_size, buf, &bytes_read, 0);
       buf += bytes_read;
 
       /* A 'z' augmentation in the CIE implies the presence of an
@@ -1975,14 +1985,16 @@ extern gdb_byte *dwarf2_read_section (st
 void
 dwarf2_build_frame_info (struct objfile *objfile)
 {
-  struct comp_unit unit;
+  struct comp_unit *unit;
   gdb_byte *frame_ptr;
 
   /* Build a minimal decoding of the DWARF2 compilation unit.  */
-  unit.abfd = objfile->obfd;
-  unit.objfile = objfile;
-  unit.dbase = 0;
-  unit.tbase = 0;
+  unit = (struct comp_unit *) obstack_alloc (&objfile->objfile_obstack,
+					     sizeof (struct comp_unit));
+  unit->abfd = objfile->obfd;
+  unit->objfile = objfile;
+  unit->dbase = 0;
+  unit->tbase = 0;
 
   /* First add the information from the .eh_frame section.  That way,
      the FDEs from that section are searched last.  */
@@ -1990,43 +2002,43 @@ dwarf2_build_frame_info (struct objfile 
     {
       asection *got, *txt;
 
-      unit.cie = NULL;
-      unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
-						     dwarf_eh_frame_section);
+      unit->cie = NULL;
+      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
+						      dwarf_eh_frame_section);
 
-      unit.dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
-      unit.dwarf_frame_section = dwarf_eh_frame_section;
+      unit->dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
+      unit->dwarf_frame_section = dwarf_eh_frame_section;
 
       /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
 	 that is used for the i386/amd64 target, which currently is
 	 the only target in GCC that supports/uses the
 	 DW_EH_PE_datarel encoding.  */
-      got = bfd_get_section_by_name (unit.abfd, ".got");
+      got = bfd_get_section_by_name (unit->abfd, ".got");
       if (got)
-	unit.dbase = got->vma;
+	unit->dbase = got->vma;
 
       /* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64
          so far.  */
-      txt = bfd_get_section_by_name (unit.abfd, ".text");
+      txt = bfd_get_section_by_name (unit->abfd, ".text");
       if (txt)
-	unit.tbase = txt->vma;
+	unit->tbase = txt->vma;
 
-      frame_ptr = unit.dwarf_frame_buffer;
-      while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
-	frame_ptr = decode_frame_entry (&unit, frame_ptr, 1);
+      frame_ptr = unit->dwarf_frame_buffer;
+      while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
+	frame_ptr = decode_frame_entry (unit, frame_ptr, 1);
     }
 
   if (dwarf_frame_section)
     {
-      unit.cie = NULL;
-      unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
-						     dwarf_frame_section);
-      unit.dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
-      unit.dwarf_frame_section = dwarf_frame_section;
-
-      frame_ptr = unit.dwarf_frame_buffer;
-      while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
-	frame_ptr = decode_frame_entry (&unit, frame_ptr, 0);
+      unit->cie = NULL;
+      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
+						      dwarf_frame_section);
+      unit->dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
+      unit->dwarf_frame_section = dwarf_frame_section;
+
+      frame_ptr = unit->dwarf_frame_buffer;
+      while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
+	frame_ptr = decode_frame_entry (unit, frame_ptr, 0);
     }
 }
 
diff -urNp gdb-orig/gdb/dwarf2loc.c gdb-head/gdb/dwarf2loc.c
--- gdb-orig/gdb/dwarf2loc.c	2008-02-06 18:20:35.000000000 +0100
+++ gdb-head/gdb/dwarf2loc.c	2008-03-17 14:01:44.000000000 +0100
@@ -54,11 +54,12 @@ find_location_expression (struct dwarf2_
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
+  unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
-				    SECT_OFF_TEXT (baton->objfile));
+  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
+				    SECT_OFF_TEXT (objfile));
   CORE_ADDR base_address = baton->base_address + base_offset;
 
   loc_ptr = baton->data;
@@ -66,10 +67,10 @@ find_location_expression (struct dwarf2_
 
   while (1)
     {
-      low = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
-      high = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
+      low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
+      high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
       if (low == 0 && high == 0)
@@ -189,7 +190,7 @@ dwarf_expr_tls_address (void *baton, COR
 static struct value *
 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
 			  gdb_byte *data, unsigned short size,
-			  struct objfile *objfile)
+			  struct dwarf2_per_cu_data *per_cu)
 {
   struct gdbarch *arch = get_frame_arch (frame);
   struct value *retval;
@@ -205,9 +206,10 @@ dwarf2_evaluate_loc_desc (struct symbol 
     }
 
   baton.frame = frame;
-  baton.objfile = objfile;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
@@ -318,7 +320,8 @@ needs_frame_tls_address (void *baton, CO
    requires a frame to evaluate.  */
 
 static int
-dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
+dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
+			     struct dwarf2_per_cu_data *per_cu)
 {
   struct needs_frame_baton baton;
   struct dwarf_expr_context *ctx;
@@ -327,6 +330,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
@@ -429,7 +433,7 @@ locexpr_read_variable (struct symbol *sy
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
   struct value *val;
   val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
-				  dlbaton->objfile);
+				  dlbaton->per_cu);
 
   return val;
 }
@@ -439,7 +443,8 @@ static int
 locexpr_read_needs_frame (struct symbol *symbol)
 {
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
-  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
+  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
+				      dlbaton->per_cu);
 }
 
 /* Print a natural-language description of SYMBOL to STREAM.  */
@@ -448,6 +453,7 @@ locexpr_describe_location (struct symbol
 {
   /* FIXME: be more extensive.  */
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+  int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
 
   if (dlbaton->size == 1
       && dlbaton->data[0] >= DW_OP_reg0
@@ -477,14 +483,14 @@ locexpr_describe_location (struct symbol
       && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
     if (dlbaton->data[0] == DW_OP_addr)
       {
-	int bytes_read;
+	struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
 	CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
 						&dlbaton->data[dlbaton->size - 1],
-						&bytes_read);
+						addr_size);
 	fprintf_filtered (stream, 
 			  "a thread-local variable at offset %s in the "
 			  "thread-local storage for `%s'",
-			  paddr_nz (offset), dlbaton->objfile->name);
+			  paddr_nz (offset), objfile->name);
 	return 1;
       }
   
@@ -546,7 +552,7 @@ loclist_read_variable (struct symbol *sy
     }
   else
     val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
-				    dlbaton->objfile);
+				    dlbaton->per_cu);
 
   return val;
 }
diff -urNp gdb-orig/gdb/dwarf2loc.h gdb-head/gdb/dwarf2loc.h
--- gdb-orig/gdb/dwarf2loc.h	2008-02-06 18:20:35.000000000 +0100
+++ gdb-head/gdb/dwarf2loc.h	2008-03-17 14:01:44.000000000 +0100
@@ -21,10 +21,18 @@
 #define DWARF2LOC_H
 
 struct symbol_ops;
+struct objfile;
+struct dwarf2_per_cu_data;
 
 /* This header is private to the DWARF-2 reader.  It is shared between
    dwarf2read.c and dwarf2loc.c.  */
 
+/* Return the OBJFILE associated with the compilation unit CU.  */
+struct objfile *dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *cu);
+
+/* Return the address size given in the compilation unit header for CU.  */
+CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu);
+
 /* The symbol location baton types used by the DWARF-2 reader (i.e.
    SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol).  "struct
    dwarf2_locexpr_baton" is for a symbol with a single location
@@ -39,8 +47,9 @@ struct dwarf2_locexpr_baton
   /* Length of the location expression.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  struct objfile *objfile;
+  /* The compilation unit containing the symbol whose location
+     we're computing.  */
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 struct dwarf2_loclist_baton
@@ -55,12 +64,9 @@ struct dwarf2_loclist_baton
   /* Length of the location list.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  /* Used (only???) by thread local variables.  The objfile in which
-     this symbol is defined.  To find a thread-local variable (e.g., a
-     variable declared with the `__thread' storage class), we may need
-     to know which object file it's in.  */
-  struct objfile *objfile;
+  /* The compilation unit containing the symbol whose location
+     we're computing.  */
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 extern const struct symbol_ops dwarf2_locexpr_funcs;
diff -urNp gdb-orig/gdb/dwarf2read.c gdb-head/gdb/dwarf2read.c
--- gdb-orig/gdb/dwarf2read.c	2008-03-17 12:53:31.000000000 +0100
+++ gdb-head/gdb/dwarf2read.c	2008-03-17 14:01:44.000000000 +0100
@@ -9818,13 +9818,6 @@ static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 			     struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
-
-  /* Save the master objfile, so that we can report and look up the
-     correct file containing this variable.  */
-  if (objfile->separate_debug_objfile_backlink)
-    objfile = objfile->separate_debug_objfile_backlink;
-
   if (attr_form_is_section_offset (attr)
       /* ".debug_loc" may not exist at all, or the offset may be outside
 	 the section.  If so, fall through to the complaint in the
@@ -9835,7 +9828,8 @@ dwarf2_symbol_mark_computed (struct attr
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
 			     sizeof (struct dwarf2_loclist_baton));
-      baton->objfile = objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       /* We don't know how long the location list is, but make sure we
 	 don't run off the edge of the section.  */
@@ -9855,7 +9849,8 @@ dwarf2_symbol_mark_computed (struct attr
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
 			     sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       if (attr_form_is_block (attr))
 	{
@@ -9880,6 +9875,43 @@ dwarf2_symbol_mark_computed (struct attr
     }
 }
 
+/* Return the OBJFILE associated with the compilation unit CU.  */
+
+struct objfile *
+dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+{
+  struct objfile *objfile = per_cu->psymtab->objfile;
+
+  /* Return the master objfile, so that we can report and look up the
+     correct file containing this variable.  */
+  if (objfile->separate_debug_objfile_backlink)
+    objfile = objfile->separate_debug_objfile_backlink;
+
+  return objfile;
+}
+
+/* Return the address size given in the compilation unit header for CU.  */
+
+CORE_ADDR
+dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+  if (per_cu->cu)
+    return per_cu->cu->header.addr_size;
+  else
+    {
+      /* If the CU is not currently read in, we re-read its header.  */
+      struct objfile *objfile = per_cu->psymtab->objfile;
+      struct dwarf2_per_objfile *per_objfile
+	= objfile_data (objfile, dwarf2_objfile_data_key);
+      gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
+
+      struct comp_unit_head cu_header;
+      memset (&cu_header, 0, sizeof cu_header);
+      read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+      return cu_header.addr_size;
+    }
+}
+
 /* Locate the compilation unit from CU's objfile which contains the
    DIE at OFFSET.  Raises an error on failure.  */
 

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and   dwarf2loc.c
  2008-03-17 13:35       ` Ulrich Weigand
@ 2008-03-17 18:07         ` Kevin Buettner
  2008-03-17 19:10           ` Ulrich Weigand
  2008-03-17 19:15         ` Daniel Jacobowitz
  1 sibling, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2008-03-17 18:07 UTC (permalink / raw)
  To: gdb-patches

On Mon, 17 Mar 2008 14:35:03 +0100 (CET)
"Ulrich Weigand" <uweigand@de.ibm.com> wrote:

> Here is my current patch, based on Jim Blandy's orignal patch and on
> Dan Jacobowitz' patch to fix DW_CFA_set_loc.  With the exception of
> the one FIXME in decode_frame_entry_1, this patch fixes all issues
> related to dwarf address size handling that I'm aware of ...
> 
> Tested on i386-linux, s390-linux, and s390x-linux.
> 
> Does this look OK?

I've tested your patch against the mips target upon which I was
seeing address size related problems.  The results are comparable
to those obtained using the patch that I posted.

So, as far as I'm concerned, your patch is okay to commit.

Kevin


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and   dwarf2loc.c
  2008-03-17 18:07         ` Kevin Buettner
@ 2008-03-17 19:10           ` Ulrich Weigand
  0 siblings, 0 replies; 10+ messages in thread
From: Ulrich Weigand @ 2008-03-17 19:10 UTC (permalink / raw)
  To: Kevin Buettner, drow, jimb; +Cc: gdb-patches

Kevin Buettner wrote:
> On Mon, 17 Mar 2008 14:35:03 +0100 (CET)
> "Ulrich Weigand" <uweigand@de.ibm.com> wrote:
> 
> > Here is my current patch, based on Jim Blandy's orignal patch and on
> > Dan Jacobowitz' patch to fix DW_CFA_set_loc.  With the exception of
> > the one FIXME in decode_frame_entry_1, this patch fixes all issues
> > related to dwarf address size handling that I'm aware of ...
> > 
> > Tested on i386-linux, s390-linux, and s390x-linux.
> > 
> > Does this look OK?
> 
> I've tested your patch against the mips target upon which I was
> seeing address size related problems.  The results are comparable
> to those obtained using the patch that I posted.
> 
> So, as far as I'm concerned, your patch is okay to commit.

Thanks for testing!

Dan, Jim, if this is OK with you I'll go ahead and commit this
version of the patch ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and  dwarf2loc.c
  2008-03-17 13:35       ` Ulrich Weigand
  2008-03-17 18:07         ` Kevin Buettner
@ 2008-03-17 19:15         ` Daniel Jacobowitz
  2008-03-18  5:28           ` Jim Blandy
  1 sibling, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2008-03-17 19:15 UTC (permalink / raw)
  To: gdb-patches

On Mon, Mar 17, 2008 at 02:35:03PM +0100, Ulrich Weigand wrote:
> Sorry for not following up on this earlier.

Me too; I see that I had the ball on the set_loc parts and I dropped
it.

> Does this look OK?

It does to me.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c
  2008-03-17 19:15         ` Daniel Jacobowitz
@ 2008-03-18  5:28           ` Jim Blandy
  2008-03-18 19:42             ` Ulrich Weigand
  0 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2008-03-18  5:28 UTC (permalink / raw)
  To: gdb-patches

It looks fine to me.  Should be 'dwarf2loc.h' in the ChangeLog entry, though.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c
  2008-03-18  5:28           ` Jim Blandy
@ 2008-03-18 19:42             ` Ulrich Weigand
  0 siblings, 0 replies; 10+ messages in thread
From: Ulrich Weigand @ 2008-03-18 19:42 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches

Jim Blandy wrote:
> It looks fine to me.  Should be 'dwarf2loc.h' in the ChangeLog entry, though.

Good catch, thanks!

I've checked the patch in now.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-03-18 19:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-14 22:15 [RFC] Use compilation unit's address size in dwarf2expr.c and dwarf2loc.c Kevin Buettner
2008-03-15 19:36 ` Jim Blandy
2008-03-15 19:38   ` Jim Blandy
2008-03-16  1:39     ` Kevin Buettner
2008-03-17 13:35       ` Ulrich Weigand
2008-03-17 18:07         ` Kevin Buettner
2008-03-17 19:10           ` Ulrich Weigand
2008-03-17 19:15         ` Daniel Jacobowitz
2008-03-18  5:28           ` Jim Blandy
2008-03-18 19:42             ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox