From 30af59626b24a4f41e0d9adc224617b8eec0a9d5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 21 Sep 2009 18:55:08 +0000 Subject: 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. --- bfd/ChangeLog | 5 +++++ bfd/elf-eh-frame.c | 28 +++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9900119f37..a5fe823aeb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2009-09-21 Richard Sandiford + + * elf-eh-frame.c (make_pc_relative): New function. + (_bfd_elf_write_section_eh_frame): Use it. + 2009-09-21 Alan Modra * elf32-ppc.c (TLS_GET_ADDR_GLINK_SIZE): Define. diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 4ea9627342..995dac04ee 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -423,6 +423,28 @@ skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width, 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 *abfd, { 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 *abfd, 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 *abfd, if (action & 1) { BFD_ASSERT (*buf == ent->fde_encoding); - *buf |= DW_EH_PE_pcrel; + *buf = make_pc_relative (*buf, ptr_size); action &= ~1; } buf++; -- cgit v1.2.1