public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* ld corrupting .cfi_label uses
@ 2017-02-24 14:03 Jan Beulich
  2017-02-26 23:42 ` Alan Modra
  0 siblings, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-02-24 14:03 UTC (permalink / raw)
  To: binutils

Hello,

at first, after realizing that the problem starts with an "ld -r" invocation,
I thought the PR 17467 was at fault here, but I then realized that if
that was reverted, the same issue would occur during final link. The
problem is the re-writing of .eh_frame section contents by the linker:
This can only lead to problems, as these labels don't get moved
together with the section contents being changed.

I've been looking around for a couple of hours to find at least a
workaround, but other than emitting something into the section
_bfd_elf_parse_eh_frame() doesn't understand (which then would
be at risk of breaking again with a future linker version) I can't
seem to find anything:
- no command line option to keep the linker from touching the
  section
- no per-section flag indicating whether the section is the
  target of some (non-discarded) relocation
- no other apparent mechanism

While the proper solution would be to have
_bfd_elf_write_section_eh_frame() update the relocation (and,
if present, symbol) offsets, I would already be happy to at least
have a way to suppress this unwanted fiddling with the section.
Suggestions?

This raises more general concerns though:

1) Is it unreasonable to expect "ld -r" with a single input and no
other options to produce output matching its input, at least as
far as the results of linking either object into a final binary go?

2) With gas emitting 4-byte aligned/padded .eh_frame entries
for x86-64, what's the point of ld padding them to 8-byte
boundaries?

Thanks, Jan

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

* Re: ld corrupting .cfi_label uses
  2017-02-24 14:03 ld corrupting .cfi_label uses Jan Beulich
@ 2017-02-26 23:42 ` Alan Modra
  2017-02-27  8:28   ` Jan Beulich
  2017-03-03  8:37   ` Jan Beulich
  0 siblings, 2 replies; 18+ messages in thread
From: Alan Modra @ 2017-02-26 23:42 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Fri, Feb 24, 2017 at 07:03:35AM -0700, Jan Beulich wrote:
> Hello,
> 
> at first, after realizing that the problem starts with an "ld -r" invocation,
> I thought the PR 17467 was at fault here, but I then realized that if
> that was reverted, the same issue would occur during final link. The
> problem is the re-writing of .eh_frame section contents by the linker:
> This can only lead to problems, as these labels don't get moved
> together with the section contents being changed.
> 
> I've been looking around for a couple of hours to find at least a
> workaround, but other than emitting something into the section
> _bfd_elf_parse_eh_frame() doesn't understand (which then would
> be at risk of breaking again with a future linker version) I can't
> seem to find anything:
> - no command line option to keep the linker from touching the
>   section
> - no per-section flag indicating whether the section is the
>   target of some (non-discarded) relocation
> - no other apparent mechanism
> 
> While the proper solution would be to have
> _bfd_elf_write_section_eh_frame() update the relocation (and,
> if present, symbol) offsets, I would already be happy to at least
> have a way to suppress this unwanted fiddling with the section.

Since gcc does not emit separate sections for debug or eh_frame when
there are comdat section groups, I think the linker needs to always
trim FDEs corresponding to removed groups.

So, ld needs to do something about adjusting the .cfi_label
references.

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-02-26 23:42 ` Alan Modra
@ 2017-02-27  8:28   ` Jan Beulich
  2017-03-01  2:42     ` Alan Modra
  2017-03-03  8:37   ` Jan Beulich
  1 sibling, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-02-27  8:28 UTC (permalink / raw)
  To: amodra; +Cc: binutils

>>> Alan Modra <amodra@gmail.com> 02/27/17 12:42 AM >>>
>On Fri, Feb 24, 2017 at 07:03:35AM -0700, Jan Beulich wrote:
>> at first, after realizing that the problem starts with an "ld -r" invocation,
>> I thought the PR 17467 was at fault here, but I then realized that if
>> that was reverted, the same issue would occur during final link. The
>> problem is the re-writing of .eh_frame section contents by the linker:
>> This can only lead to problems, as these labels don't get moved
>> together with the section contents being changed.
>> 
>> I've been looking around for a couple of hours to find at least a
>> workaround, but other than emitting something into the section
>> _bfd_elf_parse_eh_frame() doesn't understand (which then would
>> be at risk of breaking again with a future linker version) I can't
>> seem to find anything:
>> - no command line option to keep the linker from touching the
>>   section
>> - no per-section flag indicating whether the section is the
>>   target of some (non-discarded) relocation
>> - no other apparent mechanism
>> 
>> While the proper solution would be to have
>> _bfd_elf_write_section_eh_frame() update the relocation (and,
>> if present, symbol) offsets, I would already be happy to at least
>> have a way to suppress this unwanted fiddling with the section.
>
>Since gcc does not emit separate sections for debug or eh_frame when
>there are comdat section groups, I think the linker needs to always
>trim FDEs corresponding to removed groups.
>
>So, ld needs to do something about adjusting the .cfi_label
>references.

As said, I agree this ought to be the proper final solution, yet while there's
no real magic needed here, it'll likely be not exactly a non-intrusive change.
Still in the case at hand (Linux kernel) there aren't any section groups
involved, and I think the linker ought to leave the contents of .eh_frame
untouched unless it actually has a need to remove anything from it. Afaict
it is solely the padding to a multiple of 8 bytes which actually gets in the
way in my case. But obviously that's hard to verify without suppressing that
adjustment first, which didn't look safe to do in a straightforward manner as
(a) there's a later assertion to that effect and (b) there's no explanation why
the adjustment is being done in the first place, and hence it's not clear
under what conditions it may need retaining.

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-02-27  8:28   ` Jan Beulich
@ 2017-03-01  2:42     ` Alan Modra
  2017-03-01  7:46       ` Jan Beulich
  2017-03-02 16:30       ` Jan Beulich
  0 siblings, 2 replies; 18+ messages in thread
From: Alan Modra @ 2017-03-01  2:42 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Mon, Feb 27, 2017 at 01:28:25AM -0700, Jan Beulich wrote:
> As said, I agree this ought to be the proper final solution, yet while there's
> no real magic needed here, it'll likely be not exactly a non-intrusive change.
> Still in the case at hand (Linux kernel) there aren't any section groups
> involved, and I think the linker ought to leave the contents of .eh_frame
> untouched unless it actually has a need to remove anything from it. Afaict
> it is solely the padding to a multiple of 8 bytes which actually gets in the
> way in my case. But obviously that's hard to verify without suppressing that
> adjustment first, which didn't look safe to do in a straightforward manner as
> (a) there's a later assertion to that effect and (b) there's no explanation why
> the adjustment is being done in the first place, and hence it's not clear
> under what conditions it may need retaining.

Yeah, I've run into the padding issue myself.  It is a pain to deal
with.  If one input .eh_frame has larger alignment than other
.eh_frame sections for whatever reason, then padding placed before
that section will be seen as a zero terminator.

I suspect that is why ld ensures FDEs are a multiple of eight in size
(it would be better to look at the output section alignment) because
gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
pad with NOPs *inside* an FDE or CIE, not outside.

The following implements my suggestion re. output section alignment.
That may well cure your complaint.

bfd/
	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Align
	FDEs and CIEs to output section alignment, not ptr_size.
	(_bfd_elf_write_section_eh_frame): Likewise.
ld/
	* testsuite/ld-elf/eh3.d: Adjust to suit alignment change.

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 1b03b9b..31c9cd4 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -1326,7 +1326,7 @@ _bfd_elf_discard_section_eh_frame
   struct eh_cie_fde *ent;
   struct eh_frame_sec_info *sec_info;
   struct eh_frame_hdr_info *hdr_info;
-  unsigned int ptr_size, offset;
+  unsigned int ptr_size, offset, eh_alignment;
 
   if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
     return FALSE;
@@ -1406,12 +1406,13 @@ _bfd_elf_discard_section_eh_frame
       sec_info->cies = NULL;
     }
 
+  eh_alignment = 1 << sec->output_section->alignment_power;
   offset = 0;
   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
     if (!ent->removed)
       {
 	ent->new_offset = offset;
-	offset += size_of_output_cie_fde (ent, ptr_size);
+	offset += size_of_output_cie_fde (ent, eh_alignment);
       }
 
   sec->rawsize = sec->size;
@@ -1731,7 +1732,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
   struct eh_frame_sec_info *sec_info;
   struct elf_link_hash_table *htab;
   struct eh_frame_hdr_info *hdr_info;
-  unsigned int ptr_size;
+  unsigned int ptr_size, eh_alignment;
   struct eh_cie_fde *ent;
   bfd_size_type sec_size;
 
@@ -1771,6 +1772,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
     if (!ent->removed && ent->new_offset < ent->offset)
       memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
 
+  eh_alignment = 1 << sec->output_section->alignment_power;
   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
     {
       unsigned char *buf, *end;
@@ -1788,7 +1790,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
 
       buf = contents + ent->new_offset;
       end = buf + ent->size;
-      new_size = size_of_output_cie_fde (ent, ptr_size);
+      new_size = size_of_output_cie_fde (ent, eh_alignment);
 
       /* Update the size.  It may be shrinked.  */
       bfd_put_32 (abfd, new_size - 4, buf);
@@ -2062,13 +2064,13 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
   /* We don't align the section to its section alignment since the
      runtime library only expects all CIE/FDE records aligned at
      the pointer size. _bfd_elf_discard_section_eh_frame should
-     have padded CIE/FDE records to multiple of pointer size with
+     have padded CIE/FDE records to multiple of eh_alignment with
      size_of_output_cie_fde.  */
   sec_size = sec->size;
   if (sec_info->count != 0
       && sec_info->entry[sec_info->count - 1].size == 4)
     sec_size -= 4;
-  if ((sec_size % ptr_size) != 0)
+  if ((sec_size % eh_alignment) != 0)
     abort ();
 
   /* FIXME: octets_per_byte.  */
diff --git a/ld/testsuite/ld-elf/eh3.d b/ld/testsuite/ld-elf/eh3.d
index 6ac584a..2228c72 100644
--- a/ld/testsuite/ld-elf/eh3.d
+++ b/ld/testsuite/ld-elf/eh3.d
@@ -7,7 +7,7 @@
 
 Contents of the .eh_frame section:
 
-0+0000 0+0014 0+0000 CIE
+0+0000 0+001c 0+0000 CIE
   Version:               1
   Augmentation:          ""
   Code alignment factor: 1
@@ -22,13 +22,21 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
 
-0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
+0+0020 0+001c 0+0024 FDE cie=0+0000 pc=0+400078\.\.0+400090
   DW_CFA_advance_loc: 8 to 0+400080
   DW_CFA_def_cfa_offset: 16
   DW_CFA_offset: r6 \(rbp\) at cfa-16
   DW_CFA_advance_loc: 8 to 0+400088
   DW_CFA_def_cfa_register: r6 \(rbp\)
 
-0+0038 ZERO terminator
+0+0040 ZERO terminator
 #pass

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-01  2:42     ` Alan Modra
@ 2017-03-01  7:46       ` Jan Beulich
  2017-03-02 16:30       ` Jan Beulich
  1 sibling, 0 replies; 18+ messages in thread
From: Jan Beulich @ 2017-03-01  7:46 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 01.03.17 at 03:42, <amodra@gmail.com> wrote:
> On Mon, Feb 27, 2017 at 01:28:25AM -0700, Jan Beulich wrote:
>> As said, I agree this ought to be the proper final solution, yet while there's
>> no real magic needed here, it'll likely be not exactly a non-intrusive change.
>> Still in the case at hand (Linux kernel) there aren't any section groups
>> involved, and I think the linker ought to leave the contents of .eh_frame
>> untouched unless it actually has a need to remove anything from it. Afaict
>> it is solely the padding to a multiple of 8 bytes which actually gets in the
>> way in my case. But obviously that's hard to verify without suppressing that
>> adjustment first, which didn't look safe to do in a straightforward manner as
>> (a) there's a later assertion to that effect and (b) there's no explanation why
>> the adjustment is being done in the first place, and hence it's not clear
>> under what conditions it may need retaining.
> 
> Yeah, I've run into the padding issue myself.  It is a pain to deal
> with.  If one input .eh_frame has larger alignment than other
> .eh_frame sections for whatever reason, then padding placed before
> that section will be seen as a zero terminator.
> 
> I suspect that is why ld ensures FDEs are a multiple of eight in size
> (it would be better to look at the output section alignment) because
> gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
> pad with NOPs *inside* an FDE or CIE, not outside.
> 
> The following implements my suggestion re. output section alignment.
> That may well cure your complaint.

Oh, thanks! I'll see to give this a try, maybe not today, but hopefully
later this week.

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-01  2:42     ` Alan Modra
  2017-03-01  7:46       ` Jan Beulich
@ 2017-03-02 16:30       ` Jan Beulich
  2017-03-02 21:34         ` Alan Modra
  1 sibling, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-03-02 16:30 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 01.03.17 at 03:42, <amodra@gmail.com> wrote:
> On Mon, Feb 27, 2017 at 01:28:25AM -0700, Jan Beulich wrote:
>> As said, I agree this ought to be the proper final solution, yet while there's
>> no real magic needed here, it'll likely be not exactly a non-intrusive change.
>> Still in the case at hand (Linux kernel) there aren't any section groups
>> involved, and I think the linker ought to leave the contents of .eh_frame
>> untouched unless it actually has a need to remove anything from it. Afaict
>> it is solely the padding to a multiple of 8 bytes which actually gets in the
>> way in my case. But obviously that's hard to verify without suppressing that
>> adjustment first, which didn't look safe to do in a straightforward manner as
>> (a) there's a later assertion to that effect and (b) there's no explanation why
>> the adjustment is being done in the first place, and hence it's not clear
>> under what conditions it may need retaining.
> 
> Yeah, I've run into the padding issue myself.  It is a pain to deal
> with.  If one input .eh_frame has larger alignment than other
> .eh_frame sections for whatever reason, then padding placed before
> that section will be seen as a zero terminator.
> 
> I suspect that is why ld ensures FDEs are a multiple of eight in size
> (it would be better to look at the output section alignment) because
> gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
> pad with NOPs *inside* an FDE or CIE, not outside.
> 
> The following implements my suggestion re. output section alignment.
> That may well cure your complaint.

For .eh_frame with 4-byte alignment this indeed helps at least for the
ld -r case. I haven't got to the final link part yet, as I have to fiddle
with the object files in order to make the alignment such - even gas
emits 8-byte alignment by default. And I can't seem to spot an
objcopy option to alter the alignment of a section. I'll see if I can spot
why gas behaves this way, and if I may possibly change it.

Jan

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-02 16:30       ` Jan Beulich
@ 2017-03-02 21:34         ` Alan Modra
  2017-03-03  7:28           ` Jan Beulich
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Modra @ 2017-03-02 21:34 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Thu, Mar 02, 2017 at 09:30:52AM -0700, Jan Beulich wrote:
> >>> On 01.03.17 at 03:42, <amodra@gmail.com> wrote:
> > Yeah, I've run into the padding issue myself.  It is a pain to deal
> > with.  If one input .eh_frame has larger alignment than other
> > .eh_frame sections for whatever reason, then padding placed before
> > that section will be seen as a zero terminator.
> > 
> > I suspect that is why ld ensures FDEs are a multiple of eight in size
> > (it would be better to look at the output section alignment) because
> > gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
> > pad with NOPs *inside* an FDE or CIE, not outside.
> > 
> > The following implements my suggestion re. output section alignment.
> > That may well cure your complaint.
> 
> For .eh_frame with 4-byte alignment this indeed helps at least for the
> ld -r case. I haven't got to the final link part yet, as I have to fiddle
> with the object files in order to make the alignment such - even gas
> emits 8-byte alignment by default. And I can't seem to spot an
> objcopy option to alter the alignment of a section. I'll see if I can spot
> why gas behaves this way, and if I may possibly change it.

Good.  I'm not going to commit the patch as is, because it breaks
powerpc64.  From elf64-ppc.c:

  /* Note that the glink_eh_frame check here is not only testing that
     the generated size matched the calculated size but also that
     bfd_elf_discard_info didn't make any changes to the section.  */

So I have some further patches for powerpc64, and am modifying
elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
range start and size naturally aligned.

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-02 21:34         ` Alan Modra
@ 2017-03-03  7:28           ` Jan Beulich
  2017-03-03  9:43             ` Alan Modra
  0 siblings, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-03-03  7:28 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 02.03.17 at 22:34, <amodra@gmail.com> wrote:
> On Thu, Mar 02, 2017 at 09:30:52AM -0700, Jan Beulich wrote:
>> >>> On 01.03.17 at 03:42, <amodra@gmail.com> wrote:
>> > Yeah, I've run into the padding issue myself.  It is a pain to deal
>> > with.  If one input .eh_frame has larger alignment than other
>> > .eh_frame sections for whatever reason, then padding placed before
>> > that section will be seen as a zero terminator.
>> > 
>> > I suspect that is why ld ensures FDEs are a multiple of eight in size
>> > (it would be better to look at the output section alignment) because
>> > gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
>> > pad with NOPs *inside* an FDE or CIE, not outside.
>> > 
>> > The following implements my suggestion re. output section alignment.
>> > That may well cure your complaint.
>> 
>> For .eh_frame with 4-byte alignment this indeed helps at least for the
>> ld -r case. I haven't got to the final link part yet, as I have to fiddle
>> with the object files in order to make the alignment such - even gas
>> emits 8-byte alignment by default. And I can't seem to spot an
>> objcopy option to alter the alignment of a section. I'll see if I can spot
>> why gas behaves this way, and if I may possibly change it.
> 
> Good.  I'm not going to commit the patch as is, because it breaks
> powerpc64.  From elf64-ppc.c:
> 
>   /* Note that the glink_eh_frame check here is not only testing that
>      the generated size matched the calculated size but also that
>      bfd_elf_discard_info didn't make any changes to the section.  */

I don't think I understand the connection here (the wording
suggests to me that ppc64 expects .eh_frame contents to not
be changed at all, which would seem to imply that there is a
way to suppress changes being made, which in turn is contrary
to my findings so far). After all your patch, aiui, reduces the
chance of changes being made. But then again I know next to
nothing about ppc specifics anyway.

> So I have some further patches for powerpc64, and am modifying
> elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
> the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
> range start and size naturally aligned.

That was one of my thoughts too, but would seem to collide with
the dwarf2_format_64bit case: That emits 32 bits of all ones
followed by two 64-bit quantities. DWARF2_FDE_RELOC_SIZE
being larger than 4 would the still mean misaligned fields (as much
as the two mentioned 64-bit ones already appear to be).

What I'll give a try next is overriding EH_FRAME_ALIGNMENT just
for x86-64, and only for the .eh_frame case (i.e. leave the
Dwarf side alone to minimize impact).

Speaking of DWARF2_FDE_RELOC_SIZE - the reloc handling in
output_fde() looks rather suspicious in this regard: Shouldn't, at
the very least, the three literal 4-s be DWARF2_FDE_RELOC_SIZE?
Or even more correctly, shouldn't these numbers be determined
based on the chosen reloc, and then also be used to set addr_size?

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-02-26 23:42 ` Alan Modra
  2017-02-27  8:28   ` Jan Beulich
@ 2017-03-03  8:37   ` Jan Beulich
  2017-03-08 14:12     ` Alan Modra
  1 sibling, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-03-03  8:37 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 27.02.17 at 00:42, <amodra@gmail.com> wrote:
> On Fri, Feb 24, 2017 at 07:03:35AM -0700, Jan Beulich wrote:
>> at first, after realizing that the problem starts with an "ld -r" invocation,
>> I thought the PR 17467 was at fault here, but I then realized that if
>> that was reverted, the same issue would occur during final link. The
>> problem is the re-writing of .eh_frame section contents by the linker:
>> This can only lead to problems, as these labels don't get moved
>> together with the section contents being changed.
>> 
>> I've been looking around for a couple of hours to find at least a
>> workaround, but other than emitting something into the section
>> _bfd_elf_parse_eh_frame() doesn't understand (which then would
>> be at risk of breaking again with a future linker version) I can't
>> seem to find anything:
>> - no command line option to keep the linker from touching the
>>   section
>> - no per-section flag indicating whether the section is the
>>   target of some (non-discarded) relocation
>> - no other apparent mechanism
>> 
>> While the proper solution would be to have
>> _bfd_elf_write_section_eh_frame() update the relocation (and,
>> if present, symbol) offsets, I would already be happy to at least
>> have a way to suppress this unwanted fiddling with the section.
> 
> Since gcc does not emit separate sections for debug or eh_frame when
> there are comdat section groups, I think the linker needs to always
> trim FDEs corresponding to removed groups.
> 
> So, ld needs to do something about adjusting the .cfi_label
> references.

Well, .cfi_label uses are only a special case. Hand-generated
.eh_frame sections may have labels point anywhere, including
at the boundary between one CIE/FDE and another. In such
a case you can't tell whether the label marks the end of one or
the beginning of the other. So I think CIEs/FDEs with symbols
or relocations pointing into them need to be left alone, even
in the comdat case (the exception being normal linkonce
processing of course, where the entire section may still be
discarded).

My problem here is that I don't see any way to know whether
there are symbols (including local ones, but excluding the
section one) or relocations referring to a particular section
(other than going through the raw object file of course), for
easy checking in _bfd_elf_write_section_eh_frame(), or
even better already in _bfd_elf_parse_eh_frame_entry().

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-03  7:28           ` Jan Beulich
@ 2017-03-03  9:43             ` Alan Modra
  2017-03-03 10:24               ` Jan Beulich
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Modra @ 2017-03-03  9:43 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Fri, Mar 03, 2017 at 12:28:46AM -0700, Jan Beulich wrote:
> >>> On 02.03.17 at 22:34, <amodra@gmail.com> wrote:
> > On Thu, Mar 02, 2017 at 09:30:52AM -0700, Jan Beulich wrote:
> >> >>> On 01.03.17 at 03:42, <amodra@gmail.com> wrote:
> >> > Yeah, I've run into the padding issue myself.  It is a pain to deal
> >> > with.  If one input .eh_frame has larger alignment than other
> >> > .eh_frame sections for whatever reason, then padding placed before
> >> > that section will be seen as a zero terminator.
> >> > 
> >> > I suspect that is why ld ensures FDEs are a multiple of eight in size
> >> > (it would be better to look at the output section alignment) because
> >> > gcc emits .eh_frame aligned to eight bytes on 64-bit targets.  You can
> >> > pad with NOPs *inside* an FDE or CIE, not outside.
> >> > 
> >> > The following implements my suggestion re. output section alignment.
> >> > That may well cure your complaint.
> >> 
> >> For .eh_frame with 4-byte alignment this indeed helps at least for the
> >> ld -r case. I haven't got to the final link part yet, as I have to fiddle
> >> with the object files in order to make the alignment such - even gas
> >> emits 8-byte alignment by default. And I can't seem to spot an
> >> objcopy option to alter the alignment of a section. I'll see if I can spot
> >> why gas behaves this way, and if I may possibly change it.
> > 
> > Good.  I'm not going to commit the patch as is, because it breaks
> > powerpc64.  From elf64-ppc.c:
> > 
> >   /* Note that the glink_eh_frame check here is not only testing that
> >      the generated size matched the calculated size but also that
> >      bfd_elf_discard_info didn't make any changes to the section.  */
> 
> I don't think I understand the connection here (the wording
> suggests to me that ppc64 expects .eh_frame contents to not
> be changed at all, which would seem to imply that there is a
> way to suppress changes being made, which in turn is contrary
> to my findings so far). After all your patch, aiui, reduces the
> chance of changes being made. But then again I know next to
> nothing about ppc specifics anyway.

The problem for ppc64 is that sizing and initial eh_frame contents
describing linker generated stubs needs to be done early, before final
layout of sections.  Offsets from eh_frame to the stubs are written
later.  The eh_frame editing done by bfd_elf_discard_info comes beteen
these two steps.  So we need to make sure the eh_frame editing doesn't
change anything before writing the offsets.  I suppose we could parse
the CIEs and FDEs in elf64-ppc.c, but what I do at the moment is make
sure they are generated in a way that won't be changed by the eh_frame
editing.  This is possible due to CIE merging keeping the earliest CIE
seen, and ppc64 arranging to put the linker generated eh_frame first.

> > So I have some further patches for powerpc64, and am modifying
> > elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
> > the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
> > range start and size naturally aligned.
> 
> That was one of my thoughts too, but would seem to collide with
> the dwarf2_format_64bit case: That emits 32 bits of all ones
> followed by two 64-bit quantities. DWARF2_FDE_RELOC_SIZE
> being larger than 4 would the still mean misaligned fields (as much
> as the two mentioned 64-bit ones already appear to be).

gas doesn't generate a 64-bit eh_frame, and elf-eh-frame.c doesn't
support 64-bit eh_frame.  So not a problem.

> What I'll give a try next is overriding EH_FRAME_ALIGNMENT just
> for x86-64, and only for the .eh_frame case (i.e. leave the
> Dwarf side alone to minimize impact).
> 
> Speaking of DWARF2_FDE_RELOC_SIZE - the reloc handling in
> output_fde() looks rather suspicious in this regard: Shouldn't, at
> the very least, the three literal 4-s be DWARF2_FDE_RELOC_SIZE?
> Or even more correctly, shouldn't these numbers be determined
> based on the chosen reloc, and then also be used to set addr_size?

The 4-s after the tc_cfi_reloc_for_encoding call?  That's all fairly
new code only used by mips at the moment, where the reloc size is
always 4 bytes.  Yes, it would be better to generalize the code but
I'm not going to rush to do that..

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-03  9:43             ` Alan Modra
@ 2017-03-03 10:24               ` Jan Beulich
  2017-03-05  4:21                 ` Alan Modra
  0 siblings, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-03-03 10:24 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 03.03.17 at 10:43, <amodra@gmail.com> wrote:
> On Fri, Mar 03, 2017 at 12:28:46AM -0700, Jan Beulich wrote:
>> >>> On 02.03.17 at 22:34, <amodra@gmail.com> wrote:
>> > So I have some further patches for powerpc64, and am modifying
>> > elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
>> > the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
>> > range start and size naturally aligned.
>> 
>> That was one of my thoughts too, but would seem to collide with
>> the dwarf2_format_64bit case: That emits 32 bits of all ones
>> followed by two 64-bit quantities. DWARF2_FDE_RELOC_SIZE
>> being larger than 4 would the still mean misaligned fields (as much
>> as the two mentioned 64-bit ones already appear to be).
> 
> gas doesn't generate a 64-bit eh_frame, and elf-eh-frame.c doesn't
> support 64-bit eh_frame.  So not a problem.

Oh, so you do what you said above only in the .eh_frame case,
but not in the Dwarf one? (I've run the testsuite on ppc64 over
your original patch, without there being any issue. Nevertheless
I would of course appreciate to get to see the further
adjustments you've made. Or perhaps you mean to commit them
soon anyway?)

As to all of the changes so far (including reducing the alignment
on x86-64) helping - no, sadly not. There are still some CIEs and/or
FDEs folded during final link, so labels still point to the wrong place.
It's just not as far off anymore.

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-03 10:24               ` Jan Beulich
@ 2017-03-05  4:21                 ` Alan Modra
  2017-03-06  9:38                   ` Jan Beulich
  2017-03-06 11:45                   ` Jan Beulich
  0 siblings, 2 replies; 18+ messages in thread
From: Alan Modra @ 2017-03-05  4:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Fri, Mar 03, 2017 at 03:24:13AM -0700, Jan Beulich wrote:
> >>> On 03.03.17 at 10:43, <amodra@gmail.com> wrote:
> > On Fri, Mar 03, 2017 at 12:28:46AM -0700, Jan Beulich wrote:
> >> >>> On 02.03.17 at 22:34, <amodra@gmail.com> wrote:
> >> > So I have some further patches for powerpc64, and am modifying
> >> > elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
> >> > the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
> >> > range start and size naturally aligned.
> >> 
> >> That was one of my thoughts too, but would seem to collide with
> >> the dwarf2_format_64bit case: That emits 32 bits of all ones
> >> followed by two 64-bit quantities. DWARF2_FDE_RELOC_SIZE
> >> being larger than 4 would the still mean misaligned fields (as much
> >> as the two mentioned 64-bit ones already appear to be).
> > 
> > gas doesn't generate a 64-bit eh_frame, and elf-eh-frame.c doesn't
> > support 64-bit eh_frame.  So not a problem.
> 
> Oh, so you do what you said above only in the .eh_frame case,

Yes.

> but not in the Dwarf one? (I've run the testsuite on ppc64 over
> your original patch, without there being any issue. Nevertheless
> I would of course appreciate to get to see the further
> adjustments you've made. Or perhaps you mean to commit them
> soon anyway?)
> 
> As to all of the changes so far (including reducing the alignment
> on x86-64) helping - no, sadly not. There are still some CIEs and/or
> FDEs folded during final link, so labels still point to the wrong place.
> It's just not as far off anymore.

BTW, --traditional-format should turn off eh_frame editing.

Here's what I'm about to commit.  If we can teach gas to align
.eh_frame sections using the same logic as the loop in
_bfd_elf_discard_section_eh_frame, then we'll see even more
DW_CFA_nops disappear.  There is one testcase that adds nops, eh3, due
to the output section being aligned to 16 bytes and the zero
terminator being 8 bytes rather than 4.  I decided it wasn't worth
optimizing for that odd case.

bfd/
	* elf-bfd.h (struct eh_cie_fde): Add u.cie.per_encoding_aligned8.
	* elf-eh-frame.c (size_of_output_cie_fde): Don't align here.
	(next_cie_fde_offset): New function.
	(_bfd_elf_parse_eh_frame): Set u.cie.per_encoding_aligned8.
	(_bfd_elf_discard_section_eh_frame): Align zero terminator to
	four bytes.  Align CIEs to four or eight bytes depending on
	per_encoding_aligned8.  Align FDEs according to their encoding.
	Pad last FDE to output section alignment.
	(_bfd_elf_write_section_eh_frame): Adjust to suit.  Remove
	assertion.
	* elf64-ppc.c (glink_eh_frame_cie): Delete padding.
	(ppc64_elf_size_stubs): Pad glink eh_frame as per elf-eh-frame.c.
	(ppc64_elf_finish_dynamic_sections): Adjust to suit.
ld/
	* testsuite/ld-elf/eh3.d: Adjust for eh_frame alignment change.
	* testsuite/ld-elf/eh6.d: Likewise.
	* testsuite/ld-alpha/tlsbin.dd: Likewise.
	* testsuite/ld-alpha/tlsbin.td: Likewise.
	* testsuite/ld-alpha/tlsbinr.dd: Likewise.
	* testsuite/ld-alpha/tlspic.dd: Likewise.
	* testsuite/ld-alpha/tlspic.rd: Likewise.
	* testsuite/ld-alpha/tlspic.sd: Likewise.
	* testsuite/ld-alpha/tlspic.td: Likewise.
	* testsuite/ld-mips-elf/eh-frame1-n64.d: Likewise.
	* testsuite/ld-mips-elf/eh-frame2-n64.d: Likewise.
	* testsuite/ld-mips-elf/eh-frame3.d: Likewise.
	* testsuite/ld-x86-64/pr20830a.d: Likewise.
	* testsuite/ld-x86-64/pr21038a.d: Likewise.
	* testsuite/ld-x86-64/pr21038b.d: Likewise.
	* testsuite/ld-x86-64/pr21038c.d: Likewise.

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index f5a8d75..9e3d6f5 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -342,6 +342,10 @@ struct eh_cie_fde
 	 make_per_encoding_relative is.  */
       unsigned int per_encoding_relative : 1;
 
+      /* True if the CIE contains personality data aligned to a
+	 multiple of eight bytes.  */
+      unsigned int per_encoding_aligned8 : 1;
+
       /* True if we need to add an 'R' (FDE encoding) entry to the
 	 CIE's augmentation data.  */
       unsigned int add_fde_encoding : 1;
@@ -350,7 +354,7 @@ struct eh_cie_fde
       unsigned int merged : 1;
 
       /* Unused bits.  */
-      unsigned int pad1 : 18;
+      unsigned int pad1 : 17;
     } cie;
   } u;
   unsigned int reloc_index;
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 1b03b9b..6967f37 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -309,11 +309,10 @@ extra_augmentation_data_bytes (struct eh_cie_fde *entry)
   return size;
 }
 
-/* Return the size that ENTRY will have in the output.  ALIGNMENT is the
-   required alignment of ENTRY in bytes.  */
+/* Return the size that ENTRY will have in the output.  */
 
 static unsigned int
-size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
+size_of_output_cie_fde (struct eh_cie_fde *entry)
 {
   if (entry->removed)
     return 0;
@@ -321,8 +320,22 @@ size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
     return 4;
   return (entry->size
 	  + extra_augmentation_string_bytes (entry)
-	  + extra_augmentation_data_bytes (entry)
-	  + alignment - 1) & -alignment;
+	  + extra_augmentation_data_bytes (entry));
+}
+
+/* Return the offset of the FDE or CIE after ENT.  */
+
+static unsigned int
+next_cie_fde_offset (struct eh_cie_fde *ent,
+		     struct eh_cie_fde *last,
+		     asection *sec)
+{
+  while (++ent < last)
+    {
+      if (!ent->removed)
+	return ent->new_offset;
+    }
+  return sec->size;
 }
 
 /* Assume that the bytes between *ITER and END are CFA instructions.
@@ -811,6 +824,8 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 			{
 			  length = -(buf - ehbuf) & (per_width - 1);
 			  REQUIRE (skip_bytes (&buf, end, length));
+			  if (per_width == 8)
+			    this_inf->u.cie.per_encoding_aligned8 = 1;
 			}
 		      this_inf->u.cie.personality_offset = buf - start;
 		      ENSURE_NO_RELOCS (buf);
@@ -1326,7 +1341,7 @@ _bfd_elf_discard_section_eh_frame
   struct eh_cie_fde *ent;
   struct eh_frame_sec_info *sec_info;
   struct eh_frame_hdr_info *hdr_info;
-  unsigned int ptr_size, offset;
+  unsigned int ptr_size, offset, eh_alignment;
 
   if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
     return FALSE;
@@ -1406,14 +1421,46 @@ _bfd_elf_discard_section_eh_frame
       sec_info->cies = NULL;
     }
 
+  /* It may be that some .eh_frame input section has greater alignment
+     than other .eh_frame sections.  In that case we run the risk of
+     padding with zeros before that section, which would be seen as a
+     zero terminator.  Alignment padding must be added *inside* the
+     last FDE instead.  For other FDEs we align according to their
+     encoding, in order to align FDE address range entries naturally.  */
   offset = 0;
   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
     if (!ent->removed)
       {
+	eh_alignment = 4;
+	if (ent->size == 4)
+	  ;
+	else if (ent->cie)
+	  {
+	    if (ent->u.cie.per_encoding_aligned8)
+	      eh_alignment = 8;
+	  }
+	else
+	  {
+	    eh_alignment = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
+	    if (eh_alignment < 4)
+	      eh_alignment = 4;
+	  }
+	offset = (offset + eh_alignment - 1) & -eh_alignment;
 	ent->new_offset = offset;
-	offset += size_of_output_cie_fde (ent, ptr_size);
+	offset += size_of_output_cie_fde (ent);
       }
 
+  /* Pad the last FDE out to the output section alignment if there are
+     following sections, in order to ensure no padding between this
+     section and the next.  (Relies on the output section alignment
+     being the maximum of all input sections alignments, which is the
+     case unless someone is overriding alignment via scripts.)  */
+  eh_alignment = 4;
+  if (sec->map_head.s != NULL
+      && (sec->map_head.s->size != 4
+	  || sec->map_head.s->map_head.s != NULL))
+    eh_alignment = 1 << sec->output_section->alignment_power;
+  offset = (offset + eh_alignment - 1) & -eh_alignment;
   sec->rawsize = sec->size;
   sec->size = offset;
   return offset != sec->rawsize;
@@ -1732,8 +1779,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
   struct elf_link_hash_table *htab;
   struct eh_frame_hdr_info *hdr_info;
   unsigned int ptr_size;
-  struct eh_cie_fde *ent;
-  bfd_size_type sec_size;
+  struct eh_cie_fde *ent, *last_ent;
 
   if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
     /* FIXME: octets_per_byte.  */
@@ -1771,7 +1817,8 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
     if (!ent->removed && ent->new_offset < ent->offset)
       memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
 
-  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+  last_ent = sec_info->entry + sec_info->count;
+  for (ent = sec_info->entry; ent < last_ent; ++ent)
     {
       unsigned char *buf, *end;
       unsigned int new_size;
@@ -1782,13 +1829,13 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
       if (ent->size == 4)
 	{
 	  /* Any terminating FDE must be at the end of the section.  */
-	  BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
+	  BFD_ASSERT (ent == last_ent - 1);
 	  continue;
 	}
 
       buf = contents + ent->new_offset;
       end = buf + ent->size;
-      new_size = size_of_output_cie_fde (ent, ptr_size);
+      new_size = next_cie_fde_offset (ent, last_ent, sec) - ent->new_offset;
 
       /* Update the size.  It may be shrinked.  */
       bfd_put_32 (abfd, new_size - 4, buf);
@@ -2059,18 +2106,6 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
 	}
     }
 
-  /* We don't align the section to its section alignment since the
-     runtime library only expects all CIE/FDE records aligned at
-     the pointer size. _bfd_elf_discard_section_eh_frame should
-     have padded CIE/FDE records to multiple of pointer size with
-     size_of_output_cie_fde.  */
-  sec_size = sec->size;
-  if (sec_info->count != 0
-      && sec_info->entry[sec_info->count - 1].size == 4)
-    sec_size -= 4;
-  if ((sec_size % ptr_size) != 0)
-    abort ();
-
   /* FIXME: octets_per_byte.  */
   return bfd_set_section_contents (abfd, sec->output_section,
 				   contents, (file_ptr) sec->output_offset,
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5ecd1a3..84cb214 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -12232,8 +12232,7 @@ static const unsigned char glink_eh_frame_cie[] =
   65,					/* RA reg.  */
   1,					/* Augmentation size.  */
   DW_EH_PE_pcrel | DW_EH_PE_sdata4,	/* FDE encoding.  */
-  DW_CFA_def_cfa, 1, 0,			/* def_cfa: r1 offset 0.  */
-  0, 0, 0, 0
+  DW_CFA_def_cfa, 1, 0			/* def_cfa: r1 offset 0.  */
 };
 
 /* Stripping output sections is normally done before dynamic section
@@ -12686,21 +12685,19 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 	  && !bfd_is_abs_section (htab->glink_eh_frame->output_section)
 	  && htab->glink_eh_frame->output_section->size != 0)
 	{
-	  size_t size = 0, align;
+	  size_t size = 0, align = 4;
 
 	  for (stub_sec = htab->params->stub_bfd->sections;
 	       stub_sec != NULL;
 	       stub_sec = stub_sec->next)
 	    if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-	      size += 24;
+	      size += (17 + align - 1) & -align;
 	  if (htab->glink != NULL && htab->glink->size != 0)
-	    size += 24;
+	    size += (24 + align - 1) & -align;
 	  if (size != 0)
-	    size += sizeof (glink_eh_frame_cie);
-	  align = 1;
-	  align <<= htab->glink_eh_frame->output_section->alignment_power;
-	  align -= 1;
-	  size = (size + align) & ~align;
+	    size += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
+	  align = 1ul << htab->glink_eh_frame->output_section->alignment_power;
+	  size = (size + align - 1) & -align;
 	  htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
 	  htab->glink_eh_frame->size = size;
 	}
@@ -12745,12 +12742,13 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 	return FALSE;
       htab->glink_eh_frame->contents = p;
       last_fde = p;
+      align = 4;
 
       memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
       /* CIE length (rewrite in case little-endian).  */
-      last_fde_len = sizeof (glink_eh_frame_cie) - 4;
+      last_fde_len = ((sizeof (glink_eh_frame_cie) + align - 1) & -align) - 4;
       bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
-      p += sizeof (glink_eh_frame_cie);
+      p += last_fde_len + 4;
 
       for (stub_sec = htab->params->stub_bfd->sections;
 	   stub_sec != NULL;
@@ -12758,9 +12756,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 	if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
 	  {
 	    last_fde = p;
-	    last_fde_len = 20;
+	    last_fde_len = ((17 + align - 1) & -align) - 4;
 	    /* FDE length.  */
-	    bfd_put_32 (htab->elf.dynobj, 20, p);
+	    bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
 	    p += 4;
 	    /* CIE pointer.  */
 	    val = p - htab->glink_eh_frame->contents;
@@ -12774,14 +12772,14 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 	    /* Augmentation.  */
 	    p += 1;
 	    /* Pad.  */
-	    p += 7;
+	    p += ((17 + align - 1) & -align) - 17;
 	  }
       if (htab->glink != NULL && htab->glink->size != 0)
 	{
 	  last_fde = p;
-	  last_fde_len = 20;
+	  last_fde_len = ((24 + align - 1) & -align) - 4;
 	  /* FDE length.  */
-	  bfd_put_32 (htab->elf.dynobj, 20, p);
+	  bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
 	  p += 4;
 	  /* CIE pointer.  */
 	  val = p - htab->glink_eh_frame->contents;
@@ -12802,15 +12800,14 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 	  *p++ = DW_CFA_advance_loc + 4;
 	  *p++ = DW_CFA_restore_extended;
 	  *p++ = 65;
+	  p += ((24 + align - 1) & -align) - 24;
 	}
       /* Subsume any padding into the last FDE if user .eh_frame
 	 sections are aligned more than glink_eh_frame.  Otherwise any
 	 zero padding will be seen as a terminator.  */
+      align = 1ul << htab->glink_eh_frame->output_section->alignment_power;
       size = p - htab->glink_eh_frame->contents;
-      align = 1;
-      align <<= htab->glink_eh_frame->output_section->alignment_power;
-      align -= 1;
-      pad = ((size + align) & ~align) - size;
+      pad = ((size + align - 1) & -align) - size;
       htab->glink_eh_frame->size = size + pad;
       bfd_put_32 (htab->elf.dynobj, last_fde_len + pad, last_fde);
     }
@@ -15667,8 +15664,10 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
       bfd_vma val;
       bfd_byte *p;
       asection *stub_sec;
+      size_t align = 4;
 
-      p = htab->glink_eh_frame->contents + sizeof (glink_eh_frame_cie);
+      p = htab->glink_eh_frame->contents;
+      p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
       for (stub_sec = htab->params->stub_bfd->sections;
 	   stub_sec != NULL;
 	   stub_sec = stub_sec->next)
@@ -15698,7 +15697,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 	    /* Augmentation.  */
 	    p += 1;
 	    /* Pad.  */
-	    p += 7;
+	    p += ((17 + align - 1) & -align) - 17;
 	  }
       if (htab->glink != NULL && htab->glink->size != 0)
 	{
@@ -15728,6 +15727,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 	  p += 1;
 	  /* Ops.  */
 	  p += 7;
+	  p += ((24 + align - 1) & -align) - 24;
 	}
 
       if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
diff --git a/ld/testsuite/ld-alpha/tlsbin.dd b/ld/testsuite/ld-alpha/tlsbin.dd
index 26f1797..eab2fcd 100644
--- a/ld/testsuite/ld-alpha/tlsbin.dd
+++ b/ld/testsuite/ld-alpha/tlsbin.dd
@@ -12,30 +12,30 @@ Disassembly of section \.text:
 
 0+120001000 <fn2>:
    120001000:	02 00 bb 27 	ldah	gp,2\(t12\)
-   120001004:	b0 82 bd 23 	lda	gp,-32080\(gp\)
+   120001004:	a8 82 bd 23 	lda	gp,-32088\(gp\)
    120001008:	3e 15 c2 43 	subq	sp,0x10,sp
    12000100c:	00 00 5e b7 	stq	ra,0\(sp\)
    120001010:	18 80 1d 22 	lda	a0,-32744\(gp\)
    120001014:	08 80 7d a7 	ldq	t12,-32760\(gp\)
    120001018:	00 40 5b 6b 	jsr	ra,\(t12\),12000101c <.*>
    12000101c:	02 00 ba 27 	ldah	gp,2\(ra\)
-   120001020:	94 82 bd 23 	lda	gp,-32108\(gp\)
+   120001020:	8c 82 bd 23 	lda	gp,-32116\(gp\)
    120001024:	38 80 1d 22 	lda	a0,-32712\(gp\)
    120001028:	08 80 7d a7 	ldq	t12,-32760\(gp\)
    12000102c:	00 40 5b 6b 	jsr	ra,\(t12\),120001030 <.*>
    120001030:	02 00 ba 27 	ldah	gp,2\(ra\)
-   120001034:	80 82 bd 23 	lda	gp,-32128\(gp\)
+   120001034:	78 82 bd 23 	lda	gp,-32136\(gp\)
    120001038:	28 80 1d 22 	lda	a0,-32728\(gp\)
    12000103c:	08 80 7d a7 	ldq	t12,-32760\(gp\)
    120001040:	00 40 5b 6b 	jsr	ra,\(t12\),120001044 <.*>
    120001044:	02 00 ba 27 	ldah	gp,2\(ra\)
-   120001048:	6c 82 bd 23 	lda	gp,-32148\(gp\)
+   120001048:	64 82 bd 23 	lda	gp,-32156\(gp\)
    12000104c:	21 00 20 20 	lda	t0,33\(v0\)
    120001050:	28 80 1d 22 	lda	a0,-32728\(gp\)
    120001054:	08 80 7d a7 	ldq	t12,-32760\(gp\)
    120001058:	00 40 5b 6b 	jsr	ra,\(t12\),12000105c <.*>
    12000105c:	02 00 ba 27 	ldah	gp,2\(ra\)
-   120001060:	54 82 bd 23 	lda	gp,-32172\(gp\)
+   120001060:	4c 82 bd 23 	lda	gp,-32180\(gp\)
    120001064:	40 00 20 20 	lda	t0,64\(v0\)
    120001068:	46 00 20 20 	lda	t0,70\(v0\)
    12000106c:	00 00 20 24 	ldah	t0,0\(v0\)
diff --git a/ld/testsuite/ld-alpha/tlsbin.td b/ld/testsuite/ld-alpha/tlsbin.td
index 8bd7a6c..b577239 100644
--- a/ld/testsuite/ld-alpha/tlsbin.td
+++ b/ld/testsuite/ld-alpha/tlsbin.td
@@ -9,9 +9,9 @@
 .*: +file format elf64-alpha
 
 Contents of section .tdata:
- 1?200110f0 11000000 12000000 13000000 14000000  .*
- 1?20011100 15000000 16000000 17000000 18000000  .*
- 1?20011110 41000000 42000000 43000000 44000000  .*
- 1?20011120 45000000 46000000 47000000 48000000  .*
- 1?20011130 01010000 02010000 03010000 04010000  .*
- 1?20011140 05010000 06010000 07010000 08010000  .*
+ 1?200110e8 11000000 12000000 13000000 14000000  .*
+ 1?200110f8 15000000 16000000 17000000 18000000  .*
+ 1?20011108 41000000 42000000 43000000 44000000  .*
+ 1?20011118 45000000 46000000 47000000 48000000  .*
+ 1?20011128 01010000 02010000 03010000 04010000  .*
+ 1?20011138 05010000 06010000 07010000 08010000  .*
diff --git a/ld/testsuite/ld-alpha/tlsbinr.dd b/ld/testsuite/ld-alpha/tlsbinr.dd
index ee55fa9..44b5059 100644
--- a/ld/testsuite/ld-alpha/tlsbinr.dd
+++ b/ld/testsuite/ld-alpha/tlsbinr.dd
@@ -12,7 +12,7 @@ Disassembly of section \.text:
 
 0+120001000 <fn2>:
    120001000:	02 00 bb 27 	ldah	gp,2\(t12\)
-   120001004:	a0 82 bd 23 	lda	gp,-32096\(gp\)
+   120001004:	98 82 bd 23 	lda	gp,-32104\(gp\)
    120001008:	3e 15 c2 43 	subq	sp,0x10,sp
    12000100c:	00 00 5e b7 	stq	ra,0\(sp\)
    120001010:	08 80 1d a6 	ldq	a0,-32760\(gp\)
diff --git a/ld/testsuite/ld-alpha/tlspic.dd b/ld/testsuite/ld-alpha/tlspic.dd
index 4bd040c..bf645a4 100644
--- a/ld/testsuite/ld-alpha/tlspic.dd
+++ b/ld/testsuite/ld-alpha/tlspic.dd
@@ -12,7 +12,7 @@ Disassembly of section .text:
 
 0+1000 <fn1>:
     1000:	02 00 bb 27 	ldah	gp,2\(t12\)
-    1004:	90 82 bd 23 	lda	gp,-32112\(gp\)
+    1004:	88 82 bd 23 	lda	gp,-32120\(gp\)
     1008:	3e 15 c2 43 	subq	sp,0x10,sp
     100c:	00 00 5e b7 	stq	ra,0\(sp\)
     1010:	08 00 3e b5 	stq	s0,8\(sp\)
@@ -22,23 +22,23 @@ Disassembly of section .text:
     1020:	00 80 7d a7 	ldq	t12,-32768\(gp\)
     1024:	00 40 5b 6b 	jsr	ra,\(t12\),1028 <.*>
     1028:	02 00 ba 27 	ldah	gp,2\(ra\)
-    102c:	68 82 bd 23 	lda	gp,-32152\(gp\)
+    102c:	60 82 bd 23 	lda	gp,-32160\(gp\)
     1030:	30 80 1d 22 	lda	a0,-32720\(gp\)
     1034:	00 80 7d a7 	ldq	t12,-32768\(gp\)
     1038:	00 40 5b 6b 	jsr	ra,\(t12\),103c <.*>
     103c:	02 00 ba 27 	ldah	gp,2\(ra\)
-    1040:	54 82 bd 23 	lda	gp,-32172\(gp\)
+    1040:	4c 82 bd 23 	lda	gp,-32180\(gp\)
     1044:	40 80 1d 22 	lda	a0,-32704\(gp\)
     1048:	00 80 7d a7 	ldq	t12,-32768\(gp\)
     104c:	00 40 5b 6b 	jsr	ra,\(t12\),1050 <.*>
     1050:	02 00 ba 27 	ldah	gp,2\(ra\)
-    1054:	40 82 bd 23 	lda	gp,-32192\(gp\)
+    1054:	38 82 bd 23 	lda	gp,-32200\(gp\)
     1058:	21 00 20 20 	lda	t0,33\(v0\)
     105c:	40 80 1d 22 	lda	a0,-32704\(gp\)
     1060:	00 80 7d a7 	ldq	t12,-32768\(gp\)
     1064:	00 40 5b 6b 	jsr	ra,\(t12\),1068 <.*>
     1068:	02 00 ba 27 	ldah	gp,2\(ra\)
-    106c:	28 82 bd 23 	lda	gp,-32216\(gp\)
+    106c:	20 82 bd 23 	lda	gp,-32224\(gp\)
     1070:	40 00 20 20 	lda	t0,64\(v0\)
     1074:	62 00 20 20 	lda	t0,98\(v0\)
     1078:	00 00 20 24 	ldah	t0,0\(v0\)
diff --git a/ld/testsuite/ld-alpha/tlspic.rd b/ld/testsuite/ld-alpha/tlspic.rd
index f1fb974..4aeb5e3 100644
--- a/ld/testsuite/ld-alpha/tlspic.rd
+++ b/ld/testsuite/ld-alpha/tlspic.rd
@@ -37,7 +37,7 @@ Program Headers:
  +LOAD +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x10000
  +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ RW  0x10000
  +DYNAMIC +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ RW +0x8
- +TLS +0x0+10e0 0x0+110e0 0x0+110e0 0x0+60 0x0+80 R +0x4
+ +TLS +0x0+10d8 0x0+110d8 0x0+110d8 0x0+60 0x0+80 R +0x4
 #...
 
 Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 7 entries:
diff --git a/ld/testsuite/ld-alpha/tlspic.sd b/ld/testsuite/ld-alpha/tlspic.sd
index 573bc3d..7d02cf1 100644
--- a/ld/testsuite/ld-alpha/tlspic.sd
+++ b/ld/testsuite/ld-alpha/tlspic.sd
@@ -9,10 +9,10 @@
 .*: +file format elf64-alpha
 
 Contents of section .got:
- 11280 00000000 00000000 00000000 00000000  .*
- 11290 44040000 00000000 00000000 00000000  .*
- 112a0 00000000 00000000 71000000 00000000  .*
- 112b0 00000000 00000000 00000000 00000000  .*
- 112c0 00000000 00000000 44000000 00000000  .*
- 112d0 00000000 00000000 00000000 00000000  .*
- 112e0 00000000 00000000                    .*
+ 11278 00000000 00000000 00000000 00000000  .*
+ 11288 44040000 00000000 00000000 00000000  .*
+ 11298 00000000 00000000 71000000 00000000  .*
+ 112a8 00000000 00000000 00000000 00000000  .*
+ 112b8 00000000 00000000 44000000 00000000  .*
+ 112c8 00000000 00000000 00000000 00000000  .*
+ 112d8 00000000 00000000                    .*
diff --git a/ld/testsuite/ld-alpha/tlspic.td b/ld/testsuite/ld-alpha/tlspic.td
index cd09609..8ef7f3d 100644
--- a/ld/testsuite/ld-alpha/tlspic.td
+++ b/ld/testsuite/ld-alpha/tlspic.td
@@ -9,9 +9,9 @@
 .*: +file format elf64-alpha
 
 Contents of section .tdata:
- 110e0 11000000 12000000 13000000 14000000  .*
- 110f0 15000000 16000000 17000000 18000000  .*
- 11100 41000000 42000000 43000000 44000000  .*
- 11110 45000000 46000000 47000000 48000000  .*
- 11120 01010000 02010000 03010000 04010000  .*
- 11130 05010000 06010000 07010000 08010000  .*
+ 110d8 11000000 12000000 13000000 14000000  .*
+ 110e8 15000000 16000000 17000000 18000000  .*
+ 110f8 41000000 42000000 43000000 44000000  .*
+ 11108 45000000 46000000 47000000 48000000  .*
+ 11118 01010000 02010000 03010000 04010000  .*
+ 11128 05010000 06010000 07010000 08010000  .*
diff --git a/ld/testsuite/ld-elf/eh3.d b/ld/testsuite/ld-elf/eh3.d
index 6ac584a..3811341 100644
--- a/ld/testsuite/ld-elf/eh3.d
+++ b/ld/testsuite/ld-elf/eh3.d
@@ -23,12 +23,20 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
+0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
   DW_CFA_advance_loc: 8 to 0+400080
   DW_CFA_def_cfa_offset: 16
   DW_CFA_offset: r6 \(rbp\) at cfa-16
   DW_CFA_advance_loc: 8 to 0+400088
   DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
 
-0+0038 ZERO terminator
+0+0040 ZERO terminator
 #pass
diff --git a/ld/testsuite/ld-elf/eh6.d b/ld/testsuite/ld-elf/eh6.d
index 475b2a7..69c4c85 100644
--- a/ld/testsuite/ld-elf/eh6.d
+++ b/ld/testsuite/ld-elf/eh6.d
@@ -8,7 +8,7 @@
 #...
 Contents of the .eh_frame section:
 
-0+0000 0+001[4c] 0+0000 CIE
+0+0000 0+001[48] 0+0000 CIE
   Version:               1
   Augmentation:          "zPR"
   Code alignment factor: 1
diff --git a/ld/testsuite/ld-mips-elf/eh-frame1-n64.d b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
index cdc43bc..3802277 100644
--- a/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
+++ b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
@@ -12,25 +12,25 @@ Relocation section '\.rel\.dyn' .*:
  *Type2: R_MIPS_NONE *
  *Type3: R_MIPS_NONE *
 # Initial PCs for the FDEs attached to CIE 0x120
-0+00030148  [0-9a-f]+ R_MIPS_REL32 *
+0+00030140  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030168  [0-9a-f]+ R_MIPS_REL32 *
+0+00030160  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030308  [0-9a-f]+ R_MIPS_REL32 *
+0+00030300  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030328  [0-9a-f]+ R_MIPS_REL32 *
+0+00030320  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+000300cb  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
+0+000300c7  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030138  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
+0+00030130  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030192  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
+0+0003018a  [0-9a-f]+ R_MIPS_REL32      0+00+00+00 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
 Contents of the \.eh_frame section:
@@ -90,16 +90,12 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
 
 # basic4 removed
-0+0098 0+001c 0+009c FDE cie=0+0000 pc=0+0200a0..0+0200f0
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0098 0+0018 0+009c FDE cie=0+0000 pc=0+0200a0..0+0200f0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
 
-0+00b8 0+0024 0+0000 CIE
+0+00b4 0+0020 0+0000 CIE
   Version:               1
   Augmentation:          "zRP"
   Code alignment factor: 1
@@ -116,12 +112,8 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+0000
   DW_CFA_nop
   DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
 
-0+00e0 0+001c 0+002c FDE cie=0+00b8 pc=0+0200f0..0+020100
+0+00d8 0+001c 0+0028 FDE cie=0+00b4 pc=0+0200f0..0+020100
   DW_CFA_advance_loc: 0 to 0+0200f0
   DW_CFA_advance_loc: 0 to 0+0200f0
   DW_CFA_advance_loc: 0 to 0+0200f0
@@ -130,7 +122,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+0200f0
   DW_CFA_advance_loc: 0 to 0+0200f0
 
-0+0100 0+001c 0+004c FDE cie=0+00b8 pc=0+020100..0+020120
+0+00f8 0+001c 0+0048 FDE cie=0+00b4 pc=0+020100..0+020120
   DW_CFA_advance_loc: 0 to 0+020100
   DW_CFA_advance_loc: 0 to 0+020100
   DW_CFA_advance_loc: 0 to 0+020100
@@ -139,7 +131,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020100
   DW_CFA_advance_loc: 0 to 0+020100
 
-0+0120 0+001c 0+0000 CIE
+0+0118 0+001c 0+0000 CIE
   Version:               1
   Augmentation:          "zP"
   Code alignment factor: 1
@@ -148,7 +140,7 @@ Contents of the \.eh_frame section:
   Augmentation data:     50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
 
-0+0140 0+001c 0+0024 FDE cie=0+0120 pc=0+020120..0+020130
+0+0138 0+001c 0+0024 FDE cie=0+0118 pc=0+020120..0+020130
   DW_CFA_advance_loc: 0 to 0+020120
   DW_CFA_advance_loc: 0 to 0+020120
   DW_CFA_advance_loc: 0 to 0+020120
@@ -157,7 +149,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020120
   DW_CFA_advance_loc: 0 to 0+020120
 
-0+0160 0+001c 0+0044 FDE cie=0+0120 pc=0+020130..0+020150
+0+0158 0+001c 0+0044 FDE cie=0+0118 pc=0+020130..0+020150
   DW_CFA_advance_loc: 0 to 0+020130
   DW_CFA_advance_loc: 0 to 0+020130
   DW_CFA_advance_loc: 0 to 0+020130
@@ -166,7 +158,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020130
   DW_CFA_advance_loc: 0 to 0+020130
 
-0+0180 0+001c 0+0000 CIE
+0+0178 0+001c 0+0000 CIE
   Version:               1
   Augmentation:          "zPR"
   Code alignment factor: 1
@@ -180,7 +172,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+0000
   DW_CFA_advance_loc: 0 to 0+0000
 
-0+01a0 0+001c 0+0024 FDE cie=0+0180 pc=0+020150..0+020160
+0+0198 0+001c 0+0024 FDE cie=0+0178 pc=0+020150..0+020160
   DW_CFA_advance_loc: 0 to 0+020150
   DW_CFA_advance_loc: 0 to 0+020150
   DW_CFA_advance_loc: 0 to 0+020150
@@ -191,7 +183,7 @@ Contents of the \.eh_frame section:
 
 # FDE for .discard removed
 # zPR2 removed
-0+01c0 0+001c 0+0044 FDE cie=0+0180 pc=0+020160..0+020190
+0+01b8 0+001c 0+0044 FDE cie=0+0178 pc=0+020160..0+020190
   DW_CFA_advance_loc: 0 to 0+020160
   DW_CFA_advance_loc: 0 to 0+020160
   DW_CFA_advance_loc: 0 to 0+020160
@@ -200,7 +192,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020160
   DW_CFA_advance_loc: 0 to 0+020160
 
-0+01e0 0+001c 0+0064 FDE cie=0+0180 pc=0+020190..0+0201d0
+0+01d8 0+001c 0+0064 FDE cie=0+0178 pc=0+020190..0+0201d0
   DW_CFA_advance_loc: 0 to 0+020190
   DW_CFA_advance_loc: 0 to 0+020190
   DW_CFA_advance_loc: 0 to 0+020190
@@ -209,7 +201,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020190
   DW_CFA_advance_loc: 0 to 0+020190
 
-0+0200 0+001c 0+0204 FDE cie=0+0000 pc=0+0201d0..0+0201e0
+0+01f8 0+001c 0+01fc FDE cie=0+0000 pc=0+0201d0..0+0201e0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -219,7 +211,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
 
 # basic1 removed, followed by repeat of above
-0+0220 0+001c 0+0224 FDE cie=0+0000 pc=0+0201e0..0+0201f0
+0+0218 0+001c 0+021c FDE cie=0+0000 pc=0+0201e0..0+0201f0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -228,7 +220,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0240 0+001c 0+0244 FDE cie=0+0000 pc=0+0201f0..0+020210
+0+0238 0+001c 0+023c FDE cie=0+0000 pc=0+0201f0..0+020210
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -237,7 +229,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0260 0+001c 0+0264 FDE cie=0+0000 pc=0+020210..0+020240
+0+0258 0+001c 0+025c FDE cie=0+0000 pc=0+020210..0+020240
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -246,7 +238,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0280 0+001c 0+0284 FDE cie=0+0000 pc=0+020240..0+020280
+0+0278 0+001c 0+027c FDE cie=0+0000 pc=0+020240..0+020280
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -255,7 +247,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02a0 0+001c 0+02a4 FDE cie=0+0000 pc=0+020280..0+0202d0
+0+0298 0+001c 0+029c FDE cie=0+0000 pc=0+020280..0+0202d0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -264,7 +256,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02c0 0+001c 0+020c FDE cie=0+00b8 pc=0+0202d0..0+0202e0
+0+02b8 0+001c 0+0208 FDE cie=0+00b4 pc=0+0202d0..0+0202e0
   DW_CFA_advance_loc: 0 to 0+0202d0
   DW_CFA_advance_loc: 0 to 0+0202d0
   DW_CFA_advance_loc: 0 to 0+0202d0
@@ -273,7 +265,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+0202d0
   DW_CFA_advance_loc: 0 to 0+0202d0
 
-0+02e0 0+001c 0+022c FDE cie=0+00b8 pc=0+0202e0..0+020300
+0+02d8 0+001c 0+0228 FDE cie=0+00b4 pc=0+0202e0..0+020300
   DW_CFA_advance_loc: 0 to 0+0202e0
   DW_CFA_advance_loc: 0 to 0+0202e0
   DW_CFA_advance_loc: 0 to 0+0202e0
@@ -282,7 +274,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+0202e0
   DW_CFA_advance_loc: 0 to 0+0202e0
 
-0+0300 0+001c 0+01e4 FDE cie=0+0120 pc=0+020300..0+020310
+0+02f8 0+001c 0+01e4 FDE cie=0+0118 pc=0+020300..0+020310
   DW_CFA_advance_loc: 0 to 0+020300
   DW_CFA_advance_loc: 0 to 0+020300
   DW_CFA_advance_loc: 0 to 0+020300
@@ -291,7 +283,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020300
   DW_CFA_advance_loc: 0 to 0+020300
 
-0+0320 0+001c 0+0204 FDE cie=0+0120 pc=0+020310..0+020330
+0+0318 0+001c 0+0204 FDE cie=0+0118 pc=0+020310..0+020330
   DW_CFA_advance_loc: 0 to 0+020310
   DW_CFA_advance_loc: 0 to 0+020310
   DW_CFA_advance_loc: 0 to 0+020310
@@ -300,7 +292,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020310
   DW_CFA_advance_loc: 0 to 0+020310
 
-0+0340 0+001c 0+01c4 FDE cie=0+0180 pc=0+020330..0+020340
+0+0338 0+001c 0+01c4 FDE cie=0+0178 pc=0+020330..0+020340
   DW_CFA_advance_loc: 0 to 0+020330
   DW_CFA_advance_loc: 0 to 0+020330
   DW_CFA_advance_loc: 0 to 0+020330
@@ -309,7 +301,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020330
   DW_CFA_advance_loc: 0 to 0+020330
 
-0+0360 0+001c 0+01e4 FDE cie=0+0180 pc=0+020340..0+020370
+0+0358 0+001c 0+01e4 FDE cie=0+0178 pc=0+020340..0+020370
   DW_CFA_advance_loc: 0 to 0+020340
   DW_CFA_advance_loc: 0 to 0+020340
   DW_CFA_advance_loc: 0 to 0+020340
@@ -318,7 +310,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020340
   DW_CFA_advance_loc: 0 to 0+020340
 
-0+0380 0+001c 0+0204 FDE cie=0+0180 pc=0+020370..0+0203b0
+0+0378 0+001c 0+0204 FDE cie=0+0178 pc=0+020370..0+0203b0
   DW_CFA_advance_loc: 0 to 0+020370
   DW_CFA_advance_loc: 0 to 0+020370
   DW_CFA_advance_loc: 0 to 0+020370
@@ -327,11 +319,7 @@ Contents of the \.eh_frame section:
   DW_CFA_advance_loc: 0 to 0+020370
   DW_CFA_advance_loc: 0 to 0+020370
 
-0+03a0 0+001c 0+03a4 FDE cie=0+0000 pc=0+0203b0..0+0203c0
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0398 0+0018 0+039c FDE cie=0+0000 pc=0+0203b0..0+0203c0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-mips-elf/eh-frame2-n64.d b/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
index add403e..505e6db 100644
--- a/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
+++ b/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
@@ -12,25 +12,25 @@ Relocation section '\.rel\.dyn' .*:
  *Type2: R_MIPS_NONE *
  *Type3: R_MIPS_NONE *
 # Initial PCs for the FDEs attached to CIE 0x118
-0+00030140  [0-9a-f]+ R_MIPS_REL32 *
+0+00030138  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030160  [0-9a-f]+ R_MIPS_REL32 *
+0+00030158  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030300  [0-9a-f]+ R_MIPS_REL32 *
+0+000302f0  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030320  [0-9a-f]+ R_MIPS_REL32 *
+0+00030310  [0-9a-f]+ R_MIPS_REL32 *
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+000300cb  [0-9a-f]+ R_MIPS_REL32      0+000 foo
+0+000300c7  [0-9a-f]+ R_MIPS_REL32      0+000 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+00030130  [0-9a-f]+ R_MIPS_REL32      0+000 foo
+0+00030128  [0-9a-f]+ R_MIPS_REL32      0+000 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
-0+0003018a  [0-9a-f]+ R_MIPS_REL32      0+000 foo
+0+0003017e  [0-9a-f]+ R_MIPS_REL32      0+000 foo
  *Type2: R_MIPS_64 *
  *Type3: R_MIPS_NONE *
 Contents of the \.eh_frame section:
@@ -90,16 +90,12 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
 
 # basic4 removed
-0+0098 0+001c 0+009c FDE cie=0+0000 pc=0+0200a0..0+0200f0
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0098 0+0018 0+009c FDE cie=0+0000 pc=0+0200a0..0+0200f0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
 
-0+00b8 0+001c 0+0000 CIE
+0+00b4 0+0018 0+0000 CIE
   Version:               1
   Augmentation:          "zRP"
   Code alignment factor: 1
@@ -108,12 +104,8 @@ Contents of the \.eh_frame section:
   Augmentation data:     1c 00 00 00 00 00 00 00 00 00
 
   DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
 
-0+00d8 0+001c 0+0024 FDE cie=0+00b8 pc=0+0200f0..0+020100
+0+00d0 0+001c 0+0020 FDE cie=0+00b4 pc=0+0200f0..0+020100
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -122,7 +114,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+00f8 0+001c 0+0044 FDE cie=0+00b8 pc=0+020100..0+020120
+0+00f0 0+001c 0+0040 FDE cie=0+00b4 pc=0+020100..0+020120
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -131,7 +123,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0118 0+001c 0+0000 CIE
+0+0110 0+001c 0+0000 CIE
   Version:               1
   Augmentation:          "zP"
   Code alignment factor: 1
@@ -140,7 +132,7 @@ Contents of the \.eh_frame section:
   Augmentation data:     50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
 
-0+0138 0+001c 0+0024 FDE cie=0+0118 pc=0+020120..0+020130
+0+0130 0+001c 0+0024 FDE cie=0+0110 pc=0+020120..0+020130
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -149,16 +141,12 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0158 0+001c 0+0044 FDE cie=0+0118 pc=0+020130..0+020150
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0150 0+0018 0+0044 FDE cie=0+0110 pc=0+020130..0+020150
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
 
-0+0178 0+001c 0+0000 CIE
+0+016c 0+0018 0+0000 CIE
   Version:               1
   Augmentation:          "zPR"
   Code alignment factor: 1
@@ -167,12 +155,8 @@ Contents of the \.eh_frame section:
   Augmentation data:     00 00 00 00 00 00 00 00 00 1c
 
   DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
 
-0+0198 0+001c 0+0024 FDE cie=0+0178 pc=0+020150..0+020160
+0+0188 0+001c 0+0020 FDE cie=0+016c pc=0+020150..0+020160
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -183,7 +167,7 @@ Contents of the \.eh_frame section:
 
 # FDE for .discard removed
 # zPR2 removed
-0+01b8 0+001c 0+0044 FDE cie=0+0178 pc=0+020160..0+020190
+0+01a8 0+001c 0+0040 FDE cie=0+016c pc=0+020160..0+020190
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -192,7 +176,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+01d8 0+001c 0+0064 FDE cie=0+0178 pc=0+020190..0+0201d0
+0+01c8 0+001c 0+0060 FDE cie=0+016c pc=0+020190..0+0201d0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -201,7 +185,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+01f8 0+001c 0+01fc FDE cie=0+0000 pc=0+0201d0..0+0201e0
+0+01e8 0+001c 0+01ec FDE cie=0+0000 pc=0+0201d0..0+0201e0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -211,7 +195,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
 
 # basic1 removed, followed by repeat of above
-0+0218 0+001c 0+021c FDE cie=0+0000 pc=0+0201e0..0+0201f0
+0+0208 0+001c 0+020c FDE cie=0+0000 pc=0+0201e0..0+0201f0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -220,7 +204,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0238 0+001c 0+023c FDE cie=0+0000 pc=0+0201f0..0+020210
+0+0228 0+001c 0+022c FDE cie=0+0000 pc=0+0201f0..0+020210
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -229,7 +213,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0258 0+001c 0+025c FDE cie=0+0000 pc=0+020210..0+020240
+0+0248 0+001c 0+024c FDE cie=0+0000 pc=0+020210..0+020240
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -238,7 +222,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0278 0+001c 0+027c FDE cie=0+0000 pc=0+020240..0+020280
+0+0268 0+001c 0+026c FDE cie=0+0000 pc=0+020240..0+020280
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -247,7 +231,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0298 0+001c 0+029c FDE cie=0+0000 pc=0+020280..0+0202d0
+0+0288 0+001c 0+028c FDE cie=0+0000 pc=0+020280..0+0202d0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -256,7 +240,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02b8 0+001c 0+0204 FDE cie=0+00b8 pc=0+0202d0..0+0202e0
+0+02a8 0+001c 0+01f8 FDE cie=0+00b4 pc=0+0202d0..0+0202e0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -265,7 +249,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02d8 0+001c 0+0224 FDE cie=0+00b8 pc=0+0202e0..0+020300
+0+02c8 0+001c 0+0218 FDE cie=0+00b4 pc=0+0202e0..0+020300
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -274,7 +258,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02f8 0+001c 0+01e4 FDE cie=0+0118 pc=0+020300..0+020310
+0+02e8 0+001c 0+01dc FDE cie=0+0110 pc=0+020300..0+020310
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -283,7 +267,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0318 0+001c 0+0204 FDE cie=0+0118 pc=0+020310..0+020330
+0+0308 0+001c 0+01fc FDE cie=0+0110 pc=0+020310..0+020330
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -292,7 +276,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0338 0+001c 0+01c4 FDE cie=0+0178 pc=0+020330..0+020340
+0+0328 0+001c 0+01c0 FDE cie=0+016c pc=0+020330..0+020340
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -301,7 +285,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0358 0+001c 0+01e4 FDE cie=0+0178 pc=0+020340..0+020370
+0+0348 0+001c 0+01e0 FDE cie=0+016c pc=0+020340..0+020370
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -310,7 +294,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0378 0+001c 0+0204 FDE cie=0+0178 pc=0+020370..0+0203b0
+0+0368 0+001c 0+0200 FDE cie=0+016c pc=0+020370..0+0203b0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -319,11 +303,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0398 0+001c 0+039c FDE cie=0+0000 pc=0+0203b0..0+0203c0
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0388 0+0018 0+038c FDE cie=0+0000 pc=0+0203b0..0+0203c0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-mips-elf/eh-frame3.d b/ld/testsuite/ld-mips-elf/eh-frame3.d
index 10d0cd8..ad6270c 100644
--- a/ld/testsuite/ld-mips-elf/eh-frame3.d
+++ b/ld/testsuite/ld-mips-elf/eh-frame3.d
@@ -87,16 +87,12 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0128 0+001c 0+0044 FDE cie=0+00e8 pc=0+020130..0+020150
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+0128 0+0018 0+0044 FDE cie=0+00e8 pc=0+020130..0+020150
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
 
-0+0148 0+001c 0+0000 CIE
+0+0144 0+0018 0+0000 CIE
   Version:               1
   Augmentation:          "zPR"
   Code alignment factor: 1
@@ -105,12 +101,8 @@ Contents of the \.eh_frame section:
   Augmentation data:     00 00 00 00 00 50 60 70 80 00
 
   DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
 
-0+0168 0+001c 0+0024 FDE cie=0+0148 pc=0+020150..0+020160
+0+0160 0+001c 0+0020 FDE cie=0+0144 pc=0+020150..0+020160
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -121,7 +113,7 @@ Contents of the \.eh_frame section:
 
 # FDE for .discard removed
 # zPR2 removed
-0+0188 0+001c 0+0044 FDE cie=0+0148 pc=0+020160..0+020190
+0+0180 0+001c 0+0040 FDE cie=0+0144 pc=0+020160..0+020190
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -130,7 +122,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+01a8 0+001c 0+0064 FDE cie=0+0148 pc=0+020190..0+0201d0
+0+01a0 0+001c 0+0060 FDE cie=0+0144 pc=0+020190..0+0201d0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -139,20 +131,20 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+01c8 0+0014 0+01cc FDE cie=0+0000 pc=0+0201d0..0+0201e0
+0+01c0 0+0014 0+01c4 FDE cie=0+0000 pc=0+0201d0..0+0201e0
 
 # basic1 removed, followed by repeat of above
-0+01e0 0+0014 0+01e4 FDE cie=0+0000 pc=0+0201e0..0+0201f0
+0+01d8 0+0014 0+01dc FDE cie=0+0000 pc=0+0201e0..0+0201f0
 
-0+01f8 0+0014 0+01fc FDE cie=0+0000 pc=0+0201f0..0+020210
+0+01f0 0+0014 0+01f4 FDE cie=0+0000 pc=0+0201f0..0+020210
 
-0+0210 0+0014 0+0214 FDE cie=0+0000 pc=0+020210..0+020240
+0+0208 0+0014 0+020c FDE cie=0+0000 pc=0+020210..0+020240
 
-0+0228 0+0014 0+022c FDE cie=0+0000 pc=0+020240..0+020280
+0+0220 0+0014 0+0224 FDE cie=0+0000 pc=0+020240..0+020280
 
-0+0240 0+0014 0+0244 FDE cie=0+0000 pc=0+020280..0+0202d0
+0+0238 0+0014 0+023c FDE cie=0+0000 pc=0+020280..0+0202d0
 
-0+0258 0+001c 0+01d4 FDE cie=0+0088 pc=0+0202d0..0+0202e0
+0+0250 0+001c 0+01cc FDE cie=0+0088 pc=0+0202d0..0+0202e0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -161,7 +153,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0278 0+001c 0+01f4 FDE cie=0+0088 pc=0+0202e0..0+020300
+0+0270 0+001c 0+01ec FDE cie=0+0088 pc=0+0202e0..0+020300
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -170,7 +162,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0298 0+001c 0+01b4 FDE cie=0+00e8 pc=0+020300..0+020310
+0+0290 0+001c 0+01ac FDE cie=0+00e8 pc=0+020300..0+020310
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -179,7 +171,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02b8 0+001c 0+01d4 FDE cie=0+00e8 pc=0+020310..0+020330
+0+02b0 0+001c 0+01cc FDE cie=0+00e8 pc=0+020310..0+020330
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -188,7 +180,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+02d8 0+001c 0+0194 FDE cie=0+0148 pc=0+020330..0+020340
+0+02d0 0+001c 0+0190 FDE cie=0+0144 pc=0+020330..0+020340
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -199,7 +191,7 @@ Contents of the \.eh_frame section:
 
 # FDE for .discard removed
 # zPR2 removed
-0+02f8 0+001c 0+01b4 FDE cie=0+0148 pc=0+020340..0+020370
+0+02f0 0+001c 0+01b0 FDE cie=0+0144 pc=0+020340..0+020370
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -208,7 +200,7 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0318 0+001c 0+01d4 FDE cie=0+0148 pc=0+020370..0+0203b0
+0+0310 0+001c 0+01d0 FDE cie=0+0144 pc=0+020370..0+0203b0
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -217,4 +209,4 @@ Contents of the \.eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0338 0+0014 0+033c FDE cie=0+0000 pc=0+0203b0..0+0203c0
+0+0330 0+0014 0+0334 FDE cie=0+0000 pc=0+0203b0..0+0203c0
diff --git a/ld/testsuite/ld-x86-64/pr20830a.d b/ld/testsuite/ld-x86-64/pr20830a.d
index 87ea25d..caa4fe8 100644
--- a/ld/testsuite/ld-x86-64/pr20830a.d
+++ b/ld/testsuite/ld-x86-64/pr20830a.d
@@ -41,11 +41,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-x86-64/pr21038a.d b/ld/testsuite/ld-x86-64/pr21038a.d
index f2f88eb..e6829d5 100644
--- a/ld/testsuite/ld-x86-64/pr21038a.d
+++ b/ld/testsuite/ld-x86-64/pr21038a.d
@@ -40,11 +40,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-x86-64/pr21038b.d b/ld/testsuite/ld-x86-64/pr21038b.d
index 053d908..69b5c65 100644
--- a/ld/testsuite/ld-x86-64/pr21038b.d
+++ b/ld/testsuite/ld-x86-64/pr21038b.d
@@ -40,11 +40,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000240..0000000000000248
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000240..0000000000000248
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-x86-64/pr21038c.d b/ld/testsuite/ld-x86-64/pr21038c.d
index 33ff4ed..5b6c22f 100644
--- a/ld/testsuite/ld-x86-64/pr21038c.d
+++ b/ld/testsuite/ld-x86-64/pr21038c.d
@@ -49,11 +49,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+70 0000000000000014 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+70 0000000000000010 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop


-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-05  4:21                 ` Alan Modra
@ 2017-03-06  9:38                   ` Jan Beulich
  2017-03-06 11:45                   ` Jan Beulich
  1 sibling, 0 replies; 18+ messages in thread
From: Jan Beulich @ 2017-03-06  9:38 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 05.03.17 at 05:21, <amodra@gmail.com> wrote:
> On Fri, Mar 03, 2017 at 03:24:13AM -0700, Jan Beulich wrote:
>> >>> On 03.03.17 at 10:43, <amodra@gmail.com> wrote:
>> > On Fri, Mar 03, 2017 at 12:28:46AM -0700, Jan Beulich wrote:
>> >> >>> On 02.03.17 at 22:34, <amodra@gmail.com> wrote:
>> >> > So I have some further patches for powerpc64, and am modifying
>> >> > elf-eh-frame.c to align CIEs and FDEs ideally.  Current patch looks at
>> >> > the FDE encoding to choose 4 or 8 byte alignment in order to make FDE
>> >> > range start and size naturally aligned.
>> >> 
>> >> That was one of my thoughts too, but would seem to collide with
>> >> the dwarf2_format_64bit case: That emits 32 bits of all ones
>> >> followed by two 64-bit quantities. DWARF2_FDE_RELOC_SIZE
>> >> being larger than 4 would the still mean misaligned fields (as much
>> >> as the two mentioned 64-bit ones already appear to be).
>> > 
>> > gas doesn't generate a 64-bit eh_frame, and elf-eh-frame.c doesn't
>> > support 64-bit eh_frame.  So not a problem.
>> 
>> Oh, so you do what you said above only in the .eh_frame case,
> 
> Yes.
> 
>> but not in the Dwarf one? (I've run the testsuite on ppc64 over
>> your original patch, without there being any issue. Nevertheless
>> I would of course appreciate to get to see the further
>> adjustments you've made. Or perhaps you mean to commit them
>> soon anyway?)
>> 
>> As to all of the changes so far (including reducing the alignment
>> on x86-64) helping - no, sadly not. There are still some CIEs and/or
>> FDEs folded during final link, so labels still point to the wrong place.
>> It's just not as far off anymore.
> 
> BTW, --traditional-format should turn off eh_frame editing.

Ah, thanks for the hint. It looks like the main other effect of passing
the flag would be .stabs related, which is of no interest for the Linux
kernel, so it may well be suitable as a temporary workaround - I'll
give this a try.

> Here's what I'm about to commit.

Thanks, for doing this, even if it is only part of what's needed to
fully cope with .cfi_label. I'm getting the impression though that my
change to force .eh_frame alignment to just 4 on x86-64 will have
the same (or actually marginally wider) effect than this larger (but
of course architecture independent) change.

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-05  4:21                 ` Alan Modra
  2017-03-06  9:38                   ` Jan Beulich
@ 2017-03-06 11:45                   ` Jan Beulich
  1 sibling, 0 replies; 18+ messages in thread
From: Jan Beulich @ 2017-03-06 11:45 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 05.03.17 at 05:21, <amodra@gmail.com> wrote:
> On Fri, Mar 03, 2017 at 03:24:13AM -0700, Jan Beulich wrote:
>> As to all of the changes so far (including reducing the alignment
>> on x86-64) helping - no, sadly not. There are still some CIEs and/or
>> FDEs folded during final link, so labels still point to the wrong place.
>> It's just not as far off anymore.
> 
> BTW, --traditional-format should turn off eh_frame editing.

Thanks, this indeed makes things work. A sad consequence though
is that I don't get any .eh_frame_hdr section produced anymore.

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-03  8:37   ` Jan Beulich
@ 2017-03-08 14:12     ` Alan Modra
  2017-03-08 14:33       ` Jan Beulich
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Modra @ 2017-03-08 14:12 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Fri, Mar 03, 2017 at 01:37:17AM -0700, Jan Beulich wrote:
> My problem here is that I don't see any way to know whether
> there are symbols (including local ones, but excluding the
> section one) or relocations referring to a particular section
> (other than going through the raw object file of course), for
> easy checking in _bfd_elf_write_section_eh_frame(), or
> even better already in _bfd_elf_parse_eh_frame_entry().

Here's a prototype patch.  It hasn't had much testing, and needs a few
testcases added, particularly for labels in odd parts of a CIE or FDE.
If you could run with this, that would be good.

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 9e3d6f5..ad97c61 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -326,6 +326,12 @@ struct eh_cie_fde
 	 or 0 if the CIE doesn't have any.  */
       unsigned int personality_offset : 8;
 
+      /* Length of augmentation.  aug_str_len is the length of the
+	 string including null terminator.  aug_data_len is the length
+	 of the rest up to the initial insns.  */
+      unsigned int aug_str_len : 3;
+      unsigned int aug_data_len : 5;
+
       /* True if we have marked relocations associated with this CIE.  */
       unsigned int gc_mark : 1;
 
@@ -354,7 +360,7 @@ struct eh_cie_fde
       unsigned int merged : 1;
 
       /* Unused bits.  */
-      unsigned int pad1 : 17;
+      unsigned int pad1 : 9;
     } cie;
   } u;
   unsigned int reloc_index;
@@ -2123,6 +2129,8 @@ extern bfd_boolean _bfd_elf_end_eh_frame_parsing
 extern bfd_boolean _bfd_elf_discard_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *,
    bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
+extern bfd_boolean _bfd_elf_adjust_eh_frame_global_symbol
+  (struct elf_link_hash_entry *, void *);
 extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr
   (bfd *, struct bfd_link_info *);
 extern bfd_vma _bfd_elf_eh_frame_section_offset
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 6967f37..719b7c1 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -757,6 +757,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 
 	  strcpy (cie->augmentation, (char *) buf);
 	  buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
+	  this_inf->u.cie.aug_str_len = buf - start - 1;
 	  ENSURE_NO_RELOCS (buf);
 	  if (buf[0] == 'e' && buf[1] == 'h')
 	    {
@@ -845,6 +846,8 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 		    goto free_no_table;
 		  }
 	    }
+	  this_inf->u.cie.aug_data_len
+	    = buf - start - 1 - this_inf->u.cie.aug_str_len;
 
 	  /* For shared libraries, try to get rid of as many RELATIVE relocs
 	     as possible.  */
@@ -1327,6 +1330,143 @@ find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
   return new_cie->cie_inf;
 }
 
+/* For a given OFFSET in SEC, return the delta to the new location
+   after .eh_frame editing.  */
+
+static bfd_signed_vma
+offset_adjust (bfd_vma offset, asection *sec)
+{
+  struct eh_frame_sec_info *sec_info
+    = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+  unsigned int lo, hi, mid;
+  struct eh_cie_fde *ent;
+  bfd_signed_vma delta;
+
+  lo = 0;
+  hi = sec_info->count;
+  if (hi == 0)
+    return 0;
+
+  while (lo < hi)
+    {
+      mid = (lo + hi) / 2;
+      ent = &sec_info->entry[mid];
+      if (offset < ent->offset)
+	hi = mid;
+      else if (mid + 1 >= hi)
+	break;
+      else if (offset >= ent[1].offset)
+	lo = mid + 1;
+      else
+	break;
+    }
+
+  if (!ent->removed)
+    delta = (bfd_vma) ent->new_offset - (bfd_vma) ent->offset;
+  else if (ent->cie && ent->u.cie.merged)
+    {
+      struct eh_cie_fde *cie = ent->u.cie.u.merged_with;
+      delta = ((bfd_vma) cie->new_offset + cie->u.cie.u.sec->output_offset
+	       - (bfd_vma) ent->offset - sec->output_offset);
+    }
+  else
+    {
+      /* Is putting the symbol on the next entry best for a deleted
+	 CIE/FDE?  */
+      struct eh_cie_fde *last = sec_info->entry + sec_info->count;
+      delta = ((bfd_vma) next_cie_fde_offset (ent, last, sec)
+	       - (bfd_vma) ent->offset);
+      return delta;
+    }
+
+  /* Account for editing within this CIE/FDE.  */
+  offset -= ent->offset;
+  if (ent->cie)
+    {
+      unsigned int extra
+	= ent->add_augmentation_size + ent->u.cie.add_fde_encoding;
+      if (extra == 0
+	  || offset <= 9u + ent->u.cie.aug_str_len)
+	return delta;
+      delta += extra;
+      if (offset <= 9u + ent->u.cie.aug_str_len + ent->u.cie.aug_data_len)
+	return delta;
+      delta += extra;
+    }
+  else
+    {
+      unsigned int ptr_size, width, extra = ent->add_augmentation_size;
+      if (offset <= 12 || extra == 0)
+	return delta;
+      ptr_size = (get_elf_backend_data (sec->owner)
+		  ->elf_backend_eh_frame_address_size (sec->owner, sec));
+      width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
+      if (offset <= 8 + 2 * width)
+	return delta;
+      delta += extra;
+    }
+
+  return delta;
+}
+
+/* Adjust a global symbol defined in .eh_frame, so that it stays
+   relative to its original CIE/FDE.  It is assumed that a symbol
+   defined at the beginning of a CIE/FDE belongs to that CIE/FDE
+   rather than marking the end of the previous CIE/FDE.  This matters
+   when a CIE is merged with a previous CIE, since the symbol is
+   moved to the merged CIE.  */
+
+bfd_boolean
+_bfd_elf_adjust_eh_frame_global_symbol (struct elf_link_hash_entry *h,
+					void *arg ATTRIBUTE_UNUSED)
+{
+  asection *sym_sec;
+  bfd_signed_vma delta;
+
+  if (h->root.type != bfd_link_hash_defined
+      && h->root.type != bfd_link_hash_defweak)
+    return TRUE;
+
+  sym_sec = h->root.u.def.section;
+  if (sym_sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME
+      || elf_section_data (sym_sec)->sec_info == NULL)
+    return TRUE;
+
+  delta = offset_adjust (h->root.u.def.value, sym_sec);
+  h->root.u.def.value += delta;
+
+  return TRUE;
+}
+
+/* The same for all local symbols defined in .eh_frame.  Returns true
+   if any symbol was changed.  */
+
+static int
+adjust_eh_frame_local_symbols (asection *sec,
+			       struct elf_reloc_cookie *cookie)
+{
+  unsigned int shndx;
+  Elf_Internal_Sym *sym;
+  Elf_Internal_Sym *end_sym;
+  int adjusted = 0;
+
+  shndx = elf_section_data (sec)->this_idx;
+  end_sym = cookie->locsyms + cookie->locsymcount;
+  for (sym = cookie->locsyms + 1; sym < end_sym; ++sym)
+    if (sym->st_info <= ELF_ST_INFO (STB_LOCAL, STT_OBJECT)
+	&& sym->st_shndx == shndx)
+      {
+	bfd_signed_vma delta = offset_adjust (sym->st_value, sec);
+
+	if (delta != 0)
+	  {
+	    adjusted = 1;
+	    sym->st_value += delta;
+	  }
+      }
+  return adjusted;
+}
+
 /* This function is called for each input file before the .eh_frame
    section is relocated.  It discards duplicate CIEs and FDEs for discarded
    functions.  The function returns TRUE iff any entries have been
@@ -1342,6 +1482,7 @@ _bfd_elf_discard_section_eh_frame
   struct eh_frame_sec_info *sec_info;
   struct eh_frame_hdr_info *hdr_info;
   unsigned int ptr_size, offset, eh_alignment;
+  int changed;
 
   if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
     return FALSE;
@@ -1428,6 +1569,7 @@ _bfd_elf_discard_section_eh_frame
      last FDE instead.  For other FDEs we align according to their
      encoding, in order to align FDE address range entries naturally.  */
   offset = 0;
+  changed = 0;
   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
     if (!ent->removed)
       {
@@ -1447,6 +1589,8 @@ _bfd_elf_discard_section_eh_frame
 	  }
 	offset = (offset + eh_alignment - 1) & -eh_alignment;
 	ent->new_offset = offset;
+	if (ent->new_offset != ent->offset)
+	  changed = 1;
 	offset += size_of_output_cie_fde (ent);
       }
 
@@ -1463,7 +1607,15 @@ _bfd_elf_discard_section_eh_frame
   offset = (offset + eh_alignment - 1) & -eh_alignment;
   sec->rawsize = sec->size;
   sec->size = offset;
-  return offset != sec->rawsize;
+  if (sec->size != sec->rawsize)
+    changed = 1;
+
+  if (changed && adjust_eh_frame_local_symbols (sec, cookie))
+    {
+      Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+      symtab_hdr->contents = (unsigned char *) cookie->locsyms;
+    }
+  return changed;
 }
 
 /* This function is called for .eh_frame_hdr section after
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 776357f..f7bbfdb 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13738,6 +13738,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
   if (o != NULL)
     {
       asection *i;
+      int eh_changed = 0;
 
       for (i = o->map_head.s; i != NULL; i = i->map_head.s)
 	{
@@ -13755,10 +13756,17 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 	  if (_bfd_elf_discard_section_eh_frame (abfd, info, i,
 						 bfd_elf_reloc_symbol_deleted_p,
 						 &cookie))
-	    changed = 1;
+	    {
+	      eh_changed = 1;
+	      if (i->size != i->rawsize)
+		changed = 1;
+	    }
 
 	  fini_reloc_cookie_for_section (&cookie, i);
 	}
+      if (eh_changed)
+	elf_link_hash_traverse (elf_hash_table (info),
+				_bfd_elf_adjust_eh_frame_global_symbol, NULL);
     }
 
   for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
diff --git a/gas/symbols.c b/gas/symbols.c
index d4f09fc..a54e469 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -2092,12 +2092,18 @@ int
 S_FORCE_RELOC (symbolS *s, int strict)
 {
   if (LOCAL_SYMBOL_CHECK (s))
-    return ((struct local_symbol *) s)->lsy_section == undefined_section;
+    return (((struct local_symbol *) s)->lsy_section == undefined_section
+	    || (IS_ELF
+		&& strict
+		&& strcmp (((struct local_symbol *) s)->lsy_section->name,
+			   ".eh_frame") == 0));
 
   return ((strict
 	   && ((s->bsym->flags & BSF_WEAK) != 0
 	       || (EXTERN_FORCE_RELOC
-		   && (s->bsym->flags & BSF_GLOBAL) != 0)))
+		   && (s->bsym->flags & BSF_GLOBAL) != 0)
+	       || (IS_ELF
+		   && strcmp (s->bsym->section->name, ".eh_frame") == 0)))
 	  || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0
 	  || s->bsym->section == undefined_section
 	  || bfd_is_com_section (s->bsym->section));
diff --git a/ld/testsuite/ld-elf/eh5a.s b/ld/testsuite/ld-elf/eh5a.s
index a74b2cc..5c4966a 100644
--- a/ld/testsuite/ld-elf/eh5a.s
+++ b/ld/testsuite/ld-elf/eh5a.s
@@ -15,11 +15,16 @@
 	.long 0
 	.cfi_endproc
 
+	.global G1, G2, G3, G4
 	.cfi_startproc simple
+	.cfi_label G1
 	.cfi_personality 3, my_personality_v1
+	.cfi_label G2
 	.cfi_lsda 12, 0xdeadbeef
 	.long 0
+	.cfi_label G3
 	.cfi_def_cfa 0, 16
+	.cfi_label G4
 	.cfi_endproc
 
 	.globl my_personality_v1
diff --git a/ld/testsuite/ld-elf/eh5b.s b/ld/testsuite/ld-elf/eh5b.s
index fa27edd..a7d81b5 100644
--- a/ld/testsuite/ld-elf/eh5b.s
+++ b/ld/testsuite/ld-elf/eh5b.s
@@ -18,10 +18,14 @@
 	.cfi_endproc
 
 	.cfi_startproc simple
+	.cfi_label L1
 	.cfi_personality 3, my_personality_v0
+	.cfi_label L2
 	.cfi_lsda 12, 0xdeadbeef
 	.long 0
+	.cfi_label L3
 	.cfi_def_cfa 0, 16
+	.cfi_label L4
 	.cfi_endproc
 
 	.globl main
@@ -32,4 +36,5 @@ main:
 start:
 _start:
 __start:
-	.long 0
+	.dc.a G1, G2, G3, G4
+	.dc.a L1, L2, L3, L4

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-08 14:12     ` Alan Modra
@ 2017-03-08 14:33       ` Jan Beulich
  2017-03-08 21:53         ` Alan Modra
  0 siblings, 1 reply; 18+ messages in thread
From: Jan Beulich @ 2017-03-08 14:33 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 08.03.17 at 15:12, <amodra@gmail.com> wrote:
> On Fri, Mar 03, 2017 at 01:37:17AM -0700, Jan Beulich wrote:
>> My problem here is that I don't see any way to know whether
>> there are symbols (including local ones, but excluding the
>> section one) or relocations referring to a particular section
>> (other than going through the raw object file of course), for
>> easy checking in _bfd_elf_write_section_eh_frame(), or
>> even better already in _bfd_elf_parse_eh_frame_entry().
> 
> Here's a prototype patch.  It hasn't had much testing, and needs a few
> testcases added, particularly for labels in odd parts of a CIE or FDE.
> If you could run with this, that would be good.

Thanks for doing this, but going over the patch I can't seem to spot
where (generally section symbol relative) relocations are being
taken care of. Am I simply overlooking something? I ask because
that's the main problem for my use case, whereas symbols don't
really matter for the moment (I simply didn't have a need to create
any so far).

And then, for the ld test case source adjustments, how do these do
anything useful with no test case output adjustments being needed?

Jan

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

* Re: ld corrupting .cfi_label uses
  2017-03-08 14:33       ` Jan Beulich
@ 2017-03-08 21:53         ` Alan Modra
  2017-03-28  9:28           ` Jan Beulich
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Modra @ 2017-03-08 21:53 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Wed, Mar 08, 2017 at 07:33:07AM -0700, Jan Beulich wrote:
> >>> On 08.03.17 at 15:12, <amodra@gmail.com> wrote:
> > On Fri, Mar 03, 2017 at 01:37:17AM -0700, Jan Beulich wrote:
> >> My problem here is that I don't see any way to know whether
> >> there are symbols (including local ones, but excluding the
> >> section one) or relocations referring to a particular section
> >> (other than going through the raw object file of course), for
> >> easy checking in _bfd_elf_write_section_eh_frame(), or
> >> even better already in _bfd_elf_parse_eh_frame_entry().
> > 
> > Here's a prototype patch.  It hasn't had much testing, and needs a few
> > testcases added, particularly for labels in odd parts of a CIE or FDE.
> > If you could run with this, that would be good.
> 
> Thanks for doing this, but going over the patch I can't seem to spot
> where (generally section symbol relative) relocations are being
> taken care of. Am I simply overlooking something? I ask because
> that's the main problem for my use case, whereas symbols don't
> really matter for the moment (I simply didn't have a need to create
> any so far).

The S_FORCE_RELOC change will result in relocations against local
symbols not being converted to relocations against a section symbol,
and it should also result in a reloc beins emitted even for references
within .eh_frame.  (The latter is one of the things I haven't tested.
There will be a reloc if the reference crosses a frag, I'm not so sure
if within the same frag.  Also, the section test may need to be
!strict.)

> And then, for the ld test case source adjustments, how do these do
> anything useful with no test case output adjustments being needed?

That's another of the unfinished details.  I was using that testcase
and inspecting the result by running readelf and objdump by hand.

Incidentally, trying to use .cfi_label outside of .cfi_startproc
.cfi_endproc results in a gas segfault, and there's no documentation
saying that .cfi_label is only meant to be used in the insn part of a
CIE or FDE.

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: ld corrupting .cfi_label uses
  2017-03-08 21:53         ` Alan Modra
@ 2017-03-28  9:28           ` Jan Beulich
  0 siblings, 0 replies; 18+ messages in thread
From: Jan Beulich @ 2017-03-28  9:28 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

>>> On 08.03.17 at 22:52, <amodra@gmail.com> wrote:
> On Wed, Mar 08, 2017 at 07:33:07AM -0700, Jan Beulich wrote:
>> >>> On 08.03.17 at 15:12, <amodra@gmail.com> wrote:
>> > On Fri, Mar 03, 2017 at 01:37:17AM -0700, Jan Beulich wrote:
>> >> My problem here is that I don't see any way to know whether
>> >> there are symbols (including local ones, but excluding the
>> >> section one) or relocations referring to a particular section
>> >> (other than going through the raw object file of course), for
>> >> easy checking in _bfd_elf_write_section_eh_frame(), or
>> >> even better already in _bfd_elf_parse_eh_frame_entry().
>> > 
>> > Here's a prototype patch.  It hasn't had much testing, and needs a few
>> > testcases added, particularly for labels in odd parts of a CIE or FDE.
>> > If you could run with this, that would be good.
>> 
>> Thanks for doing this, but going over the patch I can't seem to spot
>> where (generally section symbol relative) relocations are being
>> taken care of. Am I simply overlooking something? I ask because
>> that's the main problem for my use case, whereas symbols don't
>> really matter for the moment (I simply didn't have a need to create
>> any so far).
> 
> The S_FORCE_RELOC change will result in relocations against local
> symbols not being converted to relocations against a section symbol,
> and it should also result in a reloc beins emitted even for references
> within .eh_frame.  (The latter is one of the things I haven't tested.
> There will be a reloc if the reference crosses a frag, I'm not so sure
> if within the same frag.  Also, the section test may need to be
> !strict.)

I'm sorry for not having got back to you on this so far. The issue
I've run into here is in a sideband project of mine, and for now I
can't really predict when I'll be able to spend some more time on
this.

Jan

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

end of thread, other threads:[~2017-03-28  9:28 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-24 14:03 ld corrupting .cfi_label uses Jan Beulich
2017-02-26 23:42 ` Alan Modra
2017-02-27  8:28   ` Jan Beulich
2017-03-01  2:42     ` Alan Modra
2017-03-01  7:46       ` Jan Beulich
2017-03-02 16:30       ` Jan Beulich
2017-03-02 21:34         ` Alan Modra
2017-03-03  7:28           ` Jan Beulich
2017-03-03  9:43             ` Alan Modra
2017-03-03 10:24               ` Jan Beulich
2017-03-05  4:21                 ` Alan Modra
2017-03-06  9:38                   ` Jan Beulich
2017-03-06 11:45                   ` Jan Beulich
2017-03-03  8:37   ` Jan Beulich
2017-03-08 14:12     ` Alan Modra
2017-03-08 14:33       ` Jan Beulich
2017-03-08 21:53         ` Alan Modra
2017-03-28  9:28           ` Jan Beulich

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).