"fix" dw2gencfi pc-relative reloc

Richard Henderson rth@twiddle.net
Sat May 31 21:58:00 GMT 2003


As the comment said, I have no idea the existing code wasn't working.
But as you can see from the elf-reloc-8.d diff, the addends were in
fact all wrong.  Though it appears from that test case that it is always
off by -8, that was not the case with every asm file I looked at.  
Though it did in fact seem to be related to the .text and/or .eh_frame
offset.

Didn't notice until I started poking at things in gdb...  :-(


r~


        * dw2gencfi.c (output_fde): Use fix_new to emit pc-relative reloc.
        (cfi_finish): Set flag_traditional_format around .eh_frame data.

        * gas/alpha/elf-reloc-8.d: Correct .eh_frame relocs.
        * gas/cfi/cfi-alpha-2.d: New.
        * gas/cfi/cfi-alpha-2.s: New.
        * gas/cfi/cfi.exp: Run it.

Index: dw2gencfi.c
===================================================================
RCS file: /cvs/src/src/gas/dw2gencfi.c,v
retrieving revision 1.5
diff -c -p -d -u -r1.5 dw2gencfi.c
--- dw2gencfi.c	27 May 2003 16:52:46 -0000	1.5
+++ dw2gencfi.c	31 May 2003 19:33:08 -0000
@@ -666,9 +666,17 @@ output_fde (struct fde_entry *fde, struc
   exp.X_op_symbol = cie->start_address;
   emit_expr (&exp, 4);				/* CIE offset */
   
+  /* ??? Unsure why this works and the following doesn't.  
+     Symptom was incorrect addends to the relocation.  */
+#if 1
+  memset (frag_more (4), 0, 4);			/* Code offset */
+  fix_new (frag_now, frag_now_fix () - 4, 4,
+	   fde->start_address, 0, 1, BFD_RELOC_32);
+#else
   exp.X_add_symbol = fde->start_address;
   exp.X_op_symbol = symbol_temp_new_now ();
-  emit_expr (&exp, 4);				/* Code offset */
+  emit_expr (&exp, 4);
+#endif
 
   exp.X_add_symbol = fde->end_address;
   exp.X_op_symbol = fde->start_address;		/* Code length */
@@ -770,6 +778,7 @@ cfi_finish (void)
 {
   segT cfi_seg;
   struct fde_entry *fde;
+  int save_flag_traditional_format;
 
   if (cur_fde_data)
     {
@@ -789,6 +798,10 @@ cfi_finish (void)
   subseg_set (cfi_seg, 0);
   record_alignment (cfi_seg, 2);
 
+  /* Make sure check_eh_frame doesn't do anything with our output.  */
+  save_flag_traditional_format = flag_traditional_format;
+  flag_traditional_format = 1;
+
   for (fde = all_fde_data; fde ; fde = fde->next)
     {
       struct cfi_insn_data *first;
@@ -797,4 +810,6 @@ cfi_finish (void)
       cie = select_cie_for_fde (fde, &first);
       output_fde (fde, cie, first);
     }
+
+  flag_traditional_format = save_flag_traditional_format;
 }
Index: testsuite/gas/alpha/elf-reloc-8.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/alpha/elf-reloc-8.d,v
retrieving revision 1.2
diff -c -p -d -u -r1.2 elf-reloc-8.d
--- testsuite/gas/alpha/elf-reloc-8.d	30 May 2003 03:01:11 -0000	1.2
+++ testsuite/gas/alpha/elf-reloc-8.d	31 May 2003 19:33:09 -0000
@@ -311,20 +311,20 @@ OFFSET *TYPE *VALUE 
 
 RELOCATION RECORDS FOR \[\.eh_frame\]:
 OFFSET *TYPE *VALUE 
-0*000001c SREL32            \.init\.text\+0xf*ffffff8
-0*0000034 SREL32            \.init\.text\+0x0*0000048
-0*0000048 SREL32            \.init\.text\+0x0*0000078
-0*000005c SREL32            \.init\.text\+0x0*00000a8
-0*0000080 SREL32            \.init\.text\+0x0*00002b8
-0*00000a0 SREL32            \.init\.text\+0x0*0000598
-0*00000b8 SREL32            \.init\.text\+0x0*00005e8
-0*00000cc SREL32            \.init\.text\+0x0*0000608
-0*00000e0 SREL32            \.init\.text\+0x0*0000628
-0*00000fc SREL32            \.init\.text\+0x0*0000748
-0*0000120 SREL32            \.init\.text\+0x0*0000988
-0*000013c SREL32            \.init\.text\+0x0*0000a08
-0*0000150 SREL32            \.init\.text\+0x0*0000a18
-0*0000164 SREL32            \.init\.text\+0x0*0000a38
-0*000017c SREL32            \.init\.text\+0x0*0000a88
-0*0000190 SREL32            \.init\.text\+0x0*0000a98
-0*00001a4 SREL32            \.text\+0xf*ffffff8
+0*000001c SREL32            \.init\.text
+0*0000034 SREL32            \.init\.text\+0x0*0000050
+0*0000048 SREL32            \.init\.text\+0x0*0000080
+0*000005c SREL32            \.init\.text\+0x0*00000b0
+0*0000080 SREL32            \.init\.text\+0x0*00002c0
+0*00000a0 SREL32            \.init\.text\+0x0*00005a0
+0*00000b8 SREL32            \.init\.text\+0x0*00005f0
+0*00000cc SREL32            \.init\.text\+0x0*0000610
+0*00000e0 SREL32            \.init\.text\+0x0*0000630
+0*00000fc SREL32            \.init\.text\+0x0*0000750
+0*0000120 SREL32            \.init\.text\+0x0*0000990
+0*000013c SREL32            \.init\.text\+0x0*0000a10
+0*0000150 SREL32            \.init\.text\+0x0*0000a20
+0*0000164 SREL32            \.init\.text\+0x0*0000a40
+0*000017c SREL32            \.init\.text\+0x0*0000a90
+0*0000190 SREL32            \.init\.text\+0x0*0000aa0
+0*00001a4 SREL32            \.text
Index: testsuite/gas/cfi/cfi-alpha-2.d
===================================================================
RCS file: testsuite/gas/cfi/cfi-alpha-2.d
diff -N testsuite/gas/cfi/cfi-alpha-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/cfi/cfi-alpha-2.d	31 May 2003 19:33:09 -0000
@@ -0,0 +1,9 @@
+#objdump: -r -j .eh_frame
+#name: CFI on alpha, 2
+
+.*:     file format elf64-alpha
+
+RELOCATION RECORDS FOR \[\.eh_frame\]:
+OFFSET           TYPE              VALUE 
+0*000001c SREL32            \.text
+0*0000030 SREL32            \.text\+0x0*0000004
Index: testsuite/gas/cfi/cfi-alpha-2.s
===================================================================
RCS file: testsuite/gas/cfi/cfi-alpha-2.s
diff -N testsuite/gas/cfi/cfi-alpha-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/cfi/cfi-alpha-2.s	31 May 2003 19:33:09 -0000
@@ -0,0 +1,14 @@
+	.text
+	.ent foo
+foo:
+	.frame $30, 0, $26, 0
+	.prologue 1
+	ret
+	.end foo
+
+	.ent bar
+bar:
+	.frame $30, 0, $26, 0
+	.prologue 1
+	ret
+	.end bar
Index: testsuite/gas/cfi/cfi.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/cfi/cfi.exp,v
retrieving revision 1.2
diff -c -p -d -u -r1.2 cfi.exp
--- testsuite/gas/cfi/cfi.exp	30 May 2003 03:01:12 -0000	1.2
+++ testsuite/gas/cfi/cfi.exp	31 May 2003 19:33:09 -0000
@@ -15,5 +15,6 @@ if { [istarget alpha*-*-*] } then {
 
     if $elf {
 	run_dump_test "cfi-alpha-1"
+	run_dump_test "cfi-alpha-2"
     }
 }



More information about the Binutils mailing list