public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Fwd: Add DW_OP_GNU_encoded_addr]
@ 2008-09-24 23:24 Richard Henderson
  2008-09-25  6:27 ` Matthias Klose
  2008-09-29  8:34 ` Jan Beulich
  0 siblings, 2 replies; 8+ messages in thread
From: Richard Henderson @ 2008-09-24 23:24 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1156 bytes --]

Here's the gas/binutils part of the feature I just posted about
on the gcc list.


r~


-------- Original Message --------
Subject: Add DW_OP_GNU_encoded_addr
Date: Wed, 24 Sep 2008 16:14:18 -0700
From: Richard Henderson <rth@redhat.com>
To: gcc-patches@gcc.gnu.org

This is a new dwarf unwind expression opcode that allows an absolute
address to be put into the .eh_frame section without having to resort
to DW_OP_addr, which would result in runtime relocations in shared
libraries.

This opcode will be generated by a new gas .cfi_val_encoded_addr
directive.  This directive is intended to be used with inline assembly
which actually contains out-of-line code (i.e. in another section).
E.g.

    asm(	"test something
	jnz 1f
	.section text2,\"ax\"
1:	.cfi_startproc simple
	.cfi_def_cfa %%esp, 0
	.cfi_val_encoded_addr %%eip, 0x1b, 11f
	<do-some-stuff>
	jmp 11f
	.cfi_endproc
	.previous
11:");

This is an idiom that shows up several places in glibc and in the
kernel.  In glibc, Jakub currently goes to heroic efforts to
generate the unwind information by hand, but this code is what you
might call write-only i.e. intensely difficult to modify.


r~


[-- Attachment #2: zz.txt --]
[-- Type: text/plain, Size: 13348 bytes --]

include/
        * elf/dwarf2.h (DW_OP_GNU_encoded_addr): New.
binutils/
        * dwarf.c (size_of_encoded_value, get_encoded_value): Move up.
        (decode_location_expression): Add section parameter.  Handle
        DW_OP_GNU_encoded_addr.
        (read_and_display_attr_value): Update decode_location_expression call.
        (display_debug_loc, display_debug_frames): Likewise.
gas/
        * dw2gencfi.c (DWARF2_ADDR_SIZE): Provide default.
        (struct cfi_insn_data): Add ea member.
        (CFI_val_encoded_addr, dot_cfi_val_encoded_addr): New.
        (output_cfi_insn): Handle CFI_val_encoded_addr.
        (select_cie_for_fde): Don't match CFI_val_encoded_addr.
        * doc/as.texinfo (.cfi_val_encoded_addr): Document.

Index: binutils/dwarf.c
===================================================================
RCS file: /cvs/src/src/binutils/dwarf.c,v
retrieving revision 1.39
diff -u -p -r1.39 dwarf.c
--- binutils/dwarf.c	24 Sep 2008 14:37:35 -0000	1.39
+++ binutils/dwarf.c	24 Sep 2008 22:26:32 -0000
@@ -164,6 +164,30 @@ byte_get_signed (unsigned char *field, i
     }
 }
 
+static int
+size_of_encoded_value (int encoding)
+{
+  switch (encoding & 0x7)
+    {
+    default:	/* ??? */
+    case 0:	return eh_addr_size;
+    case 2:	return 2;
+    case 3:	return 4;
+    case 4:	return 8;
+    }
+}
+
+static dwarf_vma
+get_encoded_value (unsigned char *data, int encoding)
+{
+  int size = size_of_encoded_value (encoding);
+
+  if (encoding & DW_EH_PE_signed)
+    return byte_get_signed (data, size);
+  else
+    return byte_get (data, size);
+}
+
 /* Print a dwarf_vma value (typically an address, offset or length) in
    hexadecimal format, followed by a space.  The length of the value (and
    hence the precision displayed) is determined by the byte_size parameter.  */
@@ -651,7 +675,8 @@ static int
 decode_location_expression (unsigned char * data,
 			    unsigned int pointer_size,
 			    unsigned long length,
-			    unsigned long cu_offset)
+			    unsigned long cu_offset,
+			    struct dwarf_section * section)
 {
   unsigned op;
   unsigned int bytes_read;
@@ -989,6 +1014,21 @@ decode_location_expression (unsigned cha
 	  printf ("DW_OP_GNU_uninit");
 	  /* FIXME: Is there data associated with this OP ?  */
 	  break;
+	case DW_OP_GNU_encoded_addr:
+	  {
+	    int encoding;
+	    dwarf_vma addr;
+	
+	    encoding = *data++;
+	    addr = get_encoded_value (data, encoding);
+	    if ((encoding & 0x70) == DW_EH_PE_pcrel)
+	      addr += section->address + (data - section->start);
+	    data += size_of_encoded_value (encoding);
+
+	    printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", encoding);
+	    print_dwarf_vma (addr, pointer_size);
+	  }
+	  break;
 
 	  /* HP extensions.  */
 	case DW_OP_HP_is_value:
@@ -1508,7 +1548,7 @@ read_and_display_attr_value (unsigned lo
 	  need_frame_base = decode_location_expression (block_start,
 							pointer_size,
 							uvalue,
-							cu_offset);
+							cu_offset, section);
 	  printf (")");
 	  if (need_frame_base && !have_frame_base)
 	    printf (_(" [without DW_AT_frame_base]"));
@@ -3186,7 +3226,7 @@ display_debug_loc (struct dwarf_section 
 	      need_frame_base = decode_location_expression (start,
 							    pointer_size,
 							    length,
-							    cu_offset);
+							    cu_offset, section);
 	      putchar (')');
 
 	      if (need_frame_base && !has_frame_base)
@@ -3756,30 +3796,6 @@ frame_display_row (Frame_Chunk *fc, int 
   printf ("\n");
 }
 
-static int
-size_of_encoded_value (int encoding)
-{
-  switch (encoding & 0x7)
-    {
-    default:	/* ??? */
-    case 0:	return eh_addr_size;
-    case 2:	return 2;
-    case 3:	return 4;
-    case 4:	return 8;
-    }
-}
-
-static dwarf_vma
-get_encoded_value (unsigned char *data, int encoding)
-{
-  int size = size_of_encoded_value (encoding);
-
-  if (encoding & DW_EH_PE_signed)
-    return byte_get_signed (data, size);
-  else
-    return byte_get (data, size);
-}
-
 #define GET(N)	byte_get (start, N); start += N
 #define LEB()	read_leb128 (start, & length_return, 0); start += length_return
 #define SLEB()	read_leb128 (start, & length_return, 1); start += length_return
@@ -4379,7 +4395,8 @@ display_debug_frames (struct dwarf_secti
 	      if (! do_debug_frames_interp)
 		{
 		  printf ("  DW_CFA_def_cfa_expression (");
-		  decode_location_expression (start, eh_addr_size, ul, 0);
+		  decode_location_expression (start, eh_addr_size, ul, 0,
+					      section);
 		  printf (")\n");
 		}
 	      fc->cfa_exp = 1;
@@ -4394,7 +4411,7 @@ display_debug_frames (struct dwarf_secti
 		  printf ("  DW_CFA_expression: %s (",
 			  regname (reg, 0));
 		  decode_location_expression (start, eh_addr_size,
-					      ul, 0);
+					      ul, 0, section);
 		  printf (")\n");
 		}
 	      fc->col_type[reg] = DW_CFA_expression;
@@ -4408,7 +4425,8 @@ display_debug_frames (struct dwarf_secti
 		{
 		  printf ("  DW_CFA_val_expression: %s (",
 			  regname (reg, 0));
-		  decode_location_expression (start, eh_addr_size, ul, 0);
+		  decode_location_expression (start, eh_addr_size, ul, 0,
+					      section);
 		  printf (")\n");
 		}
 	      fc->col_type[reg] = DW_CFA_val_expression;
Index: gas/dw2gencfi.c
===================================================================
RCS file: /cvs/src/src/gas/dw2gencfi.c,v
retrieving revision 1.36
diff -u -p -r1.36 dw2gencfi.c
--- gas/dw2gencfi.c	7 Sep 2008 22:54:53 -0000	1.36
+++ gas/dw2gencfi.c	24 Sep 2008 22:26:33 -0000
@@ -58,6 +58,10 @@
 # define tc_cfi_frame_initial_instructions() ((void)0)
 #endif
 
+#ifndef DWARF2_ADDR_SIZE
+# define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
+#endif
+
 
 struct cfi_insn_data
 {
@@ -86,6 +90,11 @@ struct cfi_insn_data
       struct cfi_escape_data *next;
       expressionS exp;
     } *esc;
+
+    struct {
+      unsigned reg, encoding;
+      expressionS exp;
+    } ea;
   } u;
 };
 
@@ -376,6 +385,7 @@ static void dot_cfi_startproc (int);
 static void dot_cfi_endproc (int);
 static void dot_cfi_personality (int);
 static void dot_cfi_lsda (int);
+static void dot_cfi_val_encoded_addr (int);
 
 /* Fake CFI type; outside the byte range of any real CFI insn.  */
 #define CFI_adjust_cfa_offset	0x100
@@ -383,6 +393,7 @@ static void dot_cfi_lsda (int);
 #define CFI_rel_offset		0x102
 #define CFI_escape		0x103
 #define CFI_signal_frame	0x104
+#define CFI_val_encoded_addr	0x105
 
 const pseudo_typeS cfi_pseudo_table[] =
   {
@@ -406,6 +417,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
     { "cfi_personality", dot_cfi_personality, 0 },
     { "cfi_lsda", dot_cfi_lsda, 0 },
+    { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
     { NULL, NULL, 0 }
   };
 
@@ -654,7 +666,7 @@ dot_cfi_personality (int ignored ATTRIBU
     }
 
   fde = frchain_now->frch_cfi_data->cur_fde_data;
-  encoding = get_absolute_expression ();
+  encoding = cfi_parse_const ();
   if (encoding == DW_EH_PE_omit)
     {
       demand_empty_rest_of_line ();
@@ -724,7 +736,7 @@ dot_cfi_lsda (int ignored ATTRIBUTE_UNUS
     }
 
   fde = frchain_now->frch_cfi_data->cur_fde_data;
-  encoding = get_absolute_expression ();
+  encoding = cfi_parse_const ();
   if (encoding == DW_EH_PE_omit)
     {
       demand_empty_rest_of_line ();
@@ -783,6 +795,71 @@ dot_cfi_lsda (int ignored ATTRIBUTE_UNUS
 }
 
 static void
+dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
+{
+  struct cfi_insn_data *insn_ptr;
+  offsetT encoding;
+
+  if (frchain_now->frch_cfi_data == NULL)
+    {
+      as_bad (_("CFI instruction used without previous .cfi_startproc"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  /* If the last address was not at the current PC, advance to current.  */
+  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
+      || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
+	 != frag_now_fix ())
+    cfi_add_advance_loc (symbol_temp_new_now ());
+
+  insn_ptr = alloc_cfi_insn_data ();
+  insn_ptr->insn = CFI_val_encoded_addr;
+  
+  insn_ptr->u.ea.reg = cfi_parse_reg ();
+
+  cfi_parse_separator ();
+  encoding = cfi_parse_const ();
+  if ((encoding & 0xff) != encoding
+      || ((encoding & 0x70) != 0
+#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
+	  && (encoding & 0x70) != DW_EH_PE_pcrel
+#endif
+	  )
+	 /* leb128 can be handled, but does something actually need it?  */
+      || (encoding & 7) == DW_EH_PE_uleb128
+      || (encoding & 7) > DW_EH_PE_udata8)
+    {
+      as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
+      encoding = DW_EH_PE_omit;
+    }
+
+  cfi_parse_separator ();
+  expression_and_evaluate (&insn_ptr->u.ea.exp);
+  switch (insn_ptr->u.ea.exp.X_op)
+    {
+    case O_symbol:
+      break;
+    case O_constant:
+      if ((encoding & 0x70) != DW_EH_PE_pcrel)
+        break;
+    default:
+      encoding = DW_EH_PE_omit;
+      break;
+    }
+
+  insn_ptr->u.ea.encoding = encoding;
+  if (encoding == DW_EH_PE_omit)
+    {
+      as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  demand_empty_rest_of_line ();
+}
+
+static void
 dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
 {
   int simple = 0;
@@ -1028,6 +1105,64 @@ output_cfi_insn (struct cfi_insn_data *i
 	break;
       }
 
+    case CFI_val_encoded_addr:
+      {
+        unsigned encoding = insn->u.ea.encoding;
+        offsetT encoding_size;
+
+	if (encoding == DW_EH_PE_omit)
+	  break;
+	out_one (DW_CFA_val_expression);
+	out_uleb128 (insn->u.ea.reg);
+
+        switch (encoding & 0x7)
+	  {
+	  case DW_EH_PE_absptr:
+	    encoding_size = DWARF2_ADDR_SIZE (stdoutput);
+	    break;
+	  case DW_EH_PE_udata2:
+	    encoding_size = 2;
+	    break;
+	  case DW_EH_PE_udata4:
+	    encoding_size = 4;
+	    break;
+	  case DW_EH_PE_udata8:
+	    encoding_size = 8;
+	    break;
+	  default:
+	    abort ();
+	  }
+
+	/* If the user has requested absolute encoding,
+	   then use the smaller DW_OP_addr encoding.  */
+	if (insn->u.ea.encoding == DW_EH_PE_absptr)
+	  {
+	    out_uleb128 (1 + encoding_size);
+	    out_one (DW_OP_addr);
+	  }
+	else
+	  {
+	    out_uleb128 (1 + 1 + encoding_size);
+	    out_one (DW_OP_GNU_encoded_addr);
+	    out_one (encoding);
+
+	    if ((encoding & 0x70) == DW_EH_PE_pcrel)
+	      {
+#if CFI_DIFF_EXPR_OK
+		insn->u.ea.exp.X_op = O_subtract;
+		insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
+#elif defined (tc_cfi_emit_pcrel_expr)
+		tc_cfi_emit_pcrel_expr (&insn.u.ea.exp, encoding_size);
+		break;
+#else
+		abort ();
+#endif
+	      }
+	  }
+	emit_expr (&insn->u.ea.exp, encoding_size);
+      }
+      break;
+      
     default:
       abort ();
     }
@@ -1292,6 +1427,7 @@ select_cie_for_fde (struct fde_entry *fd
 	      break;
 
 	    case CFI_escape:
+	    case CFI_val_encoded_addr:
 	      /* Don't bother matching these for now.  */
 	      goto fail;
 
@@ -1307,7 +1443,8 @@ select_cie_for_fde (struct fde_entry *fd
 	  && (!j
 	      || j->insn == DW_CFA_advance_loc
 	      || j->insn == DW_CFA_remember_state
-	      || j->insn == CFI_escape))
+	      || j->insn == CFI_escape
+	      || j->insn == CFI_val_encoded_addr))
 	{
 	  *pfirst = j;
 	  return cie;
@@ -1329,7 +1466,8 @@ select_cie_for_fde (struct fde_entry *fd
   for (i = cie->first; i ; i = i->next)
     if (i->insn == DW_CFA_advance_loc
 	|| i->insn == DW_CFA_remember_state
-	|| i->insn == CFI_escape)
+	|| i->insn == CFI_escape
+	|| i->insn == CFI_val_encoded_addr)
       break;
 
   cie->last = i;
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.183
diff -u -p -r1.183 as.texinfo
--- gas/doc/as.texinfo	13 Aug 2008 02:50:41 -0000	1.183
+++ gas/doc/as.texinfo	24 Sep 2008 22:26:37 -0000
@@ -4230,6 +4230,17 @@ Allows the user to add arbitrary bytes t
 might use this to add OS-specific CFI opcodes, or generic CFI
 opcodes that GAS does not yet support.
 
+@section @code{.cfi_val_encoded_addr @var{register}, @var{encoding}, @var{label}}
+The current value of @var{register} is @var{label}.  The value of @var{label}
+will be encoded in the output file according to @var{encoding}; see the
+description of @code{.cfi_personality} for details on this encoding.
+
+The usefulness of equating a register to a fixed label is probably
+limited to the return address register.  Here, it can be useful to
+mark a code segment that has only one return address which is reached
+by a direct branch and no copy of the return address exists in memory
+or another register.
+
 @node LNS directives
 @section @code{.file @var{fileno} @var{filename}}
 @cindex @code{file} directive
Index: include/elf/dwarf2.h
===================================================================
RCS file: /cvs/src/src/include/elf/dwarf2.h,v
retrieving revision 1.23
diff -u -p -r1.23 dwarf2.h
--- include/elf/dwarf2.h	3 Mar 2008 10:19:01 -0000	1.23
+++ include/elf/dwarf2.h	24 Sep 2008 22:26:50 -0000
@@ -544,6 +544,7 @@ enum dwarf_location_atom
     /* GNU extensions.  */
     DW_OP_GNU_push_tls_address = 0xe0,
     DW_OP_GNU_uninit     = 0xf0,
+    DW_OP_GNU_encoded_addr = 0xf1,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-24 23:24 [Fwd: Add DW_OP_GNU_encoded_addr] Richard Henderson
@ 2008-09-25  6:27 ` Matthias Klose
  2008-09-25  6:41   ` Matthias Klose
  2008-09-25 17:05   ` Richard Henderson
  2008-09-29  8:34 ` Jan Beulich
  1 sibling, 2 replies; 8+ messages in thread
From: Matthias Klose @ 2008-09-25  6:27 UTC (permalink / raw)
  To: Richard Henderson; +Cc: binutils

Richard Henderson schrieb:
> Here's the gas/binutils part of the feature I just posted about
> on the gcc list.

this was checked in on the gcc-4_3-branch as well. Is this appropriate for the
binutils 2.19 branch as well?

  Matthias

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-25  6:27 ` Matthias Klose
@ 2008-09-25  6:41   ` Matthias Klose
  2008-09-25 17:05   ` Richard Henderson
  1 sibling, 0 replies; 8+ messages in thread
From: Matthias Klose @ 2008-09-25  6:41 UTC (permalink / raw)
  To: Richard Henderson; +Cc: binutils

Matthias Klose schrieb:
> Richard Henderson schrieb:
>> Here's the gas/binutils part of the feature I just posted about
>> on the gcc list.
> 
> this was checked in on the gcc-4_3-branch as well. Is this appropriate for the
> binutils 2.19 branch as well?

s/this/the corresponding gcc patch/

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-25  6:27 ` Matthias Klose
  2008-09-25  6:41   ` Matthias Klose
@ 2008-09-25 17:05   ` Richard Henderson
  2008-09-26 14:10     ` Daniel Jacobowitz
  1 sibling, 1 reply; 8+ messages in thread
From: Richard Henderson @ 2008-09-25 17:05 UTC (permalink / raw)
  To: Matthias Klose; +Cc: binutils

Matthias Klose wrote:
> Richard Henderson schrieb:
>> Here's the gas/binutils part of the feature I just posted about
>> on the gcc list.
> 
> this was checked in on the gcc-4_3-branch as well. Is this appropriate for the
> binutils 2.19 branch as well?

Yes, I think it is.  I just didn't have the binutils branch handy
yesterday.  Getting this into the 2.19 branch would be nice for
glibc, as they can rev the required assembler version earlier.


r~

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-25 17:05   ` Richard Henderson
@ 2008-09-26 14:10     ` Daniel Jacobowitz
  2008-09-26 15:54       ` Richard Henderson
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2008-09-26 14:10 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Matthias Klose, binutils

On Thu, Sep 25, 2008 at 10:04:49AM -0700, Richard Henderson wrote:
> Yes, I think it is.  I just didn't have the binutils branch handy
> yesterday.  Getting this into the 2.19 branch would be nice for
> glibc, as they can rev the required assembler version earlier.

Thanks.  While we're on the subject, this should have a NEWS entry.
Is this accurate?

-- 
Daniel Jacobowitz
CodeSourcery

2008-09-26  Daniel Jacobowitz  <dan@codesourcery.com>

	* NEWS: Mention .cfi_val_encoded_addr.

Index: NEWS
===================================================================
RCS file: /cvs/src/src/gas/NEWS,v
retrieving revision 1.98
diff -u -p -r1.98 NEWS
--- NEWS	8 Sep 2008 08:56:56 -0000	1.98
+++ NEWS	26 Sep 2008 14:09:16 -0000
@@ -2,6 +2,9 @@
 
 Changes in 2.19:
 
+* New pseudo op .cfi_val_encoded_addr, to record constant addresses in unwind
+  tables without runtime relocation.
+
 * New command line option, -h-tick-hex, for sh, m32c, and h8/300 targets, which
   adds compatibility with H'00 style hex constants.
 

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-26 14:10     ` Daniel Jacobowitz
@ 2008-09-26 15:54       ` Richard Henderson
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2008-09-26 15:54 UTC (permalink / raw)
  To: Richard Henderson, Matthias Klose, binutils

Daniel Jacobowitz wrote:
> Thanks.  While we're on the subject, this should have a NEWS entry.
> Is this accurate?

That looks pretty good, thanks.


r~

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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-24 23:24 [Fwd: Add DW_OP_GNU_encoded_addr] Richard Henderson
  2008-09-25  6:27 ` Matthias Klose
@ 2008-09-29  8:34 ` Jan Beulich
  2008-09-29 16:56   ` Richard Henderson
  1 sibling, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2008-09-29  8:34 UTC (permalink / raw)
  To: Richard Henderson, binutils

Before this gets into wide-spread use, would it be possible to adjust the
operand order of .cfi_val_encoded_addr so that the encoding value would
be last and could hence be made optional (with a default resulting in the
smaller DW_OP_addr encoding)?

While at this, fixing the incorrect reference to .cfi_lsda in one of the new
error messages would also be nice.

Thanks, Jan

>>> Richard Henderson <rth@redhat.com> 25.09.08 01:24 >>>
Here's the gas/binutils part of the feature I just posted about
on the gcc list.


r~


-------- Original Message --------
Subject: Add DW_OP_GNU_encoded_addr
Date: Wed, 24 Sep 2008 16:14:18 -0700
From: Richard Henderson <rth@redhat.com>
To: gcc-patches@gcc.gnu.org 

This is a new dwarf unwind expression opcode that allows an absolute
address to be put into the .eh_frame section without having to resort
to DW_OP_addr, which would result in runtime relocations in shared
libraries.

This opcode will be generated by a new gas .cfi_val_encoded_addr
directive.  This directive is intended to be used with inline assembly
which actually contains out-of-line code (i.e. in another section).
E.g.

    asm(	"test something
	jnz 1f
	.section text2,\"ax\"
1:	.cfi_startproc simple
	.cfi_def_cfa %%esp, 0
	.cfi_val_encoded_addr %%eip, 0x1b, 11f
	<do-some-stuff>
	jmp 11f
	.cfi_endproc
	.previous
11:");

This is an idiom that shows up several places in glibc and in the
kernel.  In glibc, Jakub currently goes to heroic efforts to
generate the unwind information by hand, but this code is what you
might call write-only i.e. intensely difficult to modify.


r~


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

* Re: [Fwd: Add DW_OP_GNU_encoded_addr]
  2008-09-29  8:34 ` Jan Beulich
@ 2008-09-29 16:56   ` Richard Henderson
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2008-09-29 16:56 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

Jan Beulich wrote:
> Before this gets into wide-spread use, would it be possible to adjust the
> operand order of .cfi_val_encoded_addr so that the encoding value would
> be last and could hence be made optional (with a default resulting in the
> smaller DW_OP_addr encoding)?

The encoding already comes first for .cfi_personality and .cfi_lsda;
having it be different for this one seems weird.

If you want DW_OP_addr, you can always use a zero for the encoding...



r~

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

end of thread, other threads:[~2008-09-29 16:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-24 23:24 [Fwd: Add DW_OP_GNU_encoded_addr] Richard Henderson
2008-09-25  6:27 ` Matthias Klose
2008-09-25  6:41   ` Matthias Klose
2008-09-25 17:05   ` Richard Henderson
2008-09-26 14:10     ` Daniel Jacobowitz
2008-09-26 15:54       ` Richard Henderson
2008-09-29  8:34 ` Jan Beulich
2008-09-29 16:56   ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).