This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFC: Using DW_EH_PE_sdata* when converting absolute encodings to PC-relative form
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Cc: rth at redhat dot com
- Date: Sun, 20 Sep 2009 11:56:44 +0100
- Subject: RFC: Using DW_EH_PE_sdata* when converting absolute encodings to PC-relative form
Thw MIPS linker testsuite has some tests to make sure that absolute
.eh_frame addresses can be converted into PC-relative form. Two of
the n32 ones fail on 64-bit hosts because:
(a) the linker converts DW_EH_PE_absptr into DW_EH_PE_pcrel
| DW_EH_PE_absptr;
(b) binutils/dwarf.c treats that as an unsigned encoding; and
(c) binutils/dwarf.c doesn't restrict the printed pointers to
the target address size.
The upshot is that we read negative DW_EH_PE_pcrel | DW_EH_PE_absptr
offsets as "ff......", and so print the resolved addess as "100......"
instead of "00......".
(c) is probably a bug, but before I fix it, I was wondering
whether it was worth changing (a) to use an explicit signed
encoding, like most GCC ports do from the beginning.
I.e. whether the patch below was an improvement or not?
I realise it shouldn't matter in practice, but which is
theoretically better?
Richard
bfd/
* elf-eh-frame.c (make_pc_relative): New function.
(_bfd_elf_write_section_eh_frame): Use it.
ld/testsuite/
* ld-mips-elf/eh-frame1-n32.d: Expect PC-relative encodings
to include DW_EH_PE_sdata4.
* ld-mips-elf/eh-frame2-n32.d: Likewise.
* ld-mips-elf/eh-frame1-n64.d: Expect PC-relative encodings
to include DW_EH_PE_sdata8.
* ld-mips-elf/eh-frame2-n64.d: Likewise.
Index: bfd/elf-eh-frame.c
===================================================================
--- bfd/elf-eh-frame.c 2009-09-20 11:39:55.000000000 +0100
+++ bfd/elf-eh-frame.c 2009-09-20 11:53:25.000000000 +0100
@@ -423,6 +423,28 @@ skip_non_nops (bfd_byte *buf, bfd_byte *
return last;
}
+/* Convert absolute encoding ENCODING into PC-relative form.
+ SIZE is the size of a pointer. */
+
+static unsigned char
+make_pc_relative (unsigned char encoding, unsigned int ptr_size)
+{
+ if ((encoding & 0x7f) == DW_EH_PE_absptr)
+ switch (ptr_size)
+ {
+ case 2:
+ encoding |= DW_EH_PE_sdata2;
+ break;
+ case 4:
+ encoding |= DW_EH_PE_sdata4;
+ break;
+ case 8:
+ encoding |= DW_EH_PE_sdata8;
+ break;
+ }
+ return encoding | DW_EH_PE_pcrel;
+}
+
/* Called before calling _bfd_elf_parse_eh_frame on every input bfd's
.eh_frame section. */
@@ -1454,7 +1476,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
{
BFD_ASSERT (action & 1);
*aug++ = 'R';
- *buf++ = DW_EH_PE_pcrel;
+ *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size);
action &= ~1;
}
@@ -1465,7 +1487,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
if (action & 2)
{
BFD_ASSERT (*buf == ent->lsda_encoding);
- *buf |= DW_EH_PE_pcrel;
+ *buf = make_pc_relative (*buf, ptr_size);
action &= ~2;
}
buf++;
@@ -1506,7 +1528,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
if (action & 1)
{
BFD_ASSERT (*buf == ent->fde_encoding);
- *buf |= DW_EH_PE_pcrel;
+ *buf = make_pc_relative (*buf, ptr_size);
action &= ~1;
}
buf++;
Index: ld/testsuite/ld-mips-elf/eh-frame1-n32.d
===================================================================
--- ld/testsuite/ld-mips-elf/eh-frame1-n32.d 2009-09-20 11:39:55.000000000 +0100
+++ ld/testsuite/ld-mips-elf/eh-frame1-n32.d 2009-09-20 11:39:58.000000000 +0100
@@ -25,7 +25,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10
+ Augmentation data: 1b
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
@@ -65,7 +65,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10 00 00 00 00 00
+ Augmentation data: 1b 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
@@ -108,7 +108,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 00 00 00 00 00 10
+ Augmentation data: 00 00 00 00 00 1b
DW_CFA_advance_loc: 0 to 00000000
Index: ld/testsuite/ld-mips-elf/eh-frame2-n32.d
===================================================================
--- ld/testsuite/ld-mips-elf/eh-frame2-n32.d 2009-09-20 11:39:56.000000000 +0100
+++ ld/testsuite/ld-mips-elf/eh-frame2-n32.d 2009-09-20 11:39:58.000000000 +0100
@@ -25,7 +25,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10
+ Augmentation data: 1b
DW_CFA_nop
DW_CFA_nop
@@ -65,7 +65,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10 00 00 00 00 00
+ Augmentation data: 1b 00 00 00 00 00
DW_CFA_nop
@@ -104,7 +104,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 00 00 00 00 00 10
+ Augmentation data: 00 00 00 00 00 1b
DW_CFA_nop
Index: ld/testsuite/ld-mips-elf/eh-frame1-n64.d
===================================================================
--- ld/testsuite/ld-mips-elf/eh-frame1-n64.d 2009-09-20 11:39:55.000000000 +0100
+++ ld/testsuite/ld-mips-elf/eh-frame1-n64.d 2009-09-20 11:39:58.000000000 +0100
@@ -41,7 +41,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10
+ Augmentation data: 1c
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
@@ -105,7 +105,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10 00 00 00 00 00 00 00 00 00
+ Augmentation data: 1c 00 00 00 00 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
@@ -172,7 +172,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 00 00 00 00 00 00 00 00 00 10
+ Augmentation data: 00 00 00 00 00 00 00 00 00 1c
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
Index: ld/testsuite/ld-mips-elf/eh-frame2-n64.d
===================================================================
--- ld/testsuite/ld-mips-elf/eh-frame2-n64.d 2009-09-20 11:39:56.000000000 +0100
+++ ld/testsuite/ld-mips-elf/eh-frame2-n64.d 2009-09-20 11:39:58.000000000 +0100
@@ -41,7 +41,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10
+ Augmentation data: 1c
DW_CFA_nop
DW_CFA_nop
@@ -105,7 +105,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 10 00 00 00 00 00 00 00 00 00
+ Augmentation data: 1c 00 00 00 00 00 00 00 00 00
DW_CFA_nop
DW_CFA_nop
@@ -164,7 +164,7 @@ Contents of the \.eh_frame section:
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
- Augmentation data: 00 00 00 00 00 00 00 00 00 10
+ Augmentation data: 00 00 00 00 00 00 00 00 00 1c
DW_CFA_nop
DW_CFA_nop