public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: PowerPC64 .branch_lt address
@ 2022-07-25  1:54 Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2022-07-25  1:54 UTC (permalink / raw)
  To: binutils

On seeing PR29369 my suspicion was naturally on a recent powerpc64
change, commit 0ab80031430e.  Without a reproducer, I spent time
wondering what could have gone wrong, and while I doubt this patch
would have fixed the PR, there are some improvements that can be made
to cater for user silliness.

I also noticed that when -z relro -z now sections are created out of
order, with .got before .plt in the section headers but .got is laid
out at a higher address.  That's due to the address expression for
.branch_lt referencing SIZEOF(.got) and so calling init_os (which
creates a bfd section) for .got before the .plt section is created.
Fix that by ignoring SIZEOF in exp_init_os.  Unlike ADDR and LOADADDR
which need to reference section vma and lma respectively, SIZEOF can
and does cope with a missing bfd section by returning zero for its
size, which of course is correct.

	PR 29369
	* ldlang.c (exp_init_os): Don't create a bfd section for SIZEOF.
	* emulparams/elf64ppc.sh (OTHER_RELRO_SECTIONS_2): Revise
	.branch_lt address to take into account possible user sections
	with alignment larger than 8 bytes.

diff --git a/ld/emulparams/elf64ppc.sh b/ld/emulparams/elf64ppc.sh
index 59132fa06fa..668606e7c18 100644
--- a/ld/emulparams/elf64ppc.sh
+++ b/ld/emulparams/elf64ppc.sh
@@ -34,10 +34,30 @@ OTHER_GOT_RELOC_SECTIONS="
   .rela.toc1	${RELOCATING-0} : { *(.rela.toc1) }
   .rela.tocbss	${RELOCATING-0} : { *(.rela.tocbss) }
   .rela.branch_lt	${RELOCATING-0} : { *(.rela.branch_lt) }"
+# The idea behind setting .branch_lt address as we do below is to put
+# it up against .got which is 256 byte aligned, so that the offset
+# from .TOC. to an entry in .branch_lt remains fixed after stub
+# sizing.  (.eh_frame is edited late.)  When -z relro -z now, we have
+# .branch_lt, .plt, .iplt, then .got, so in that case we move
+# .branch_lt so that the end of .iplt is against .got.  All of these
+# sections are linker generated, with alignment eight and size a
+# multiple of eight, but a user playing games with their own
+# .branch_lt, .plt or .iplt sections can result in unexpected
+# alignment or size.  Cope with that anyway.  Note that if user
+# alignment of .branch_lt is 256 or more then nothing special need be
+# done.
+#
+# To understand what is going on here consider that the end address
+# of .iplt should be 0 mod 256, so the start of .iplt should be
+# -sizeof(.iplt) mod 256.  But the start is constrained by alignment,
+# so goes down to (-alignof(.iplt) & -sizeof(.iplt)) mod 256.  Repeat
+# that calculation for .plt and .branch_lt to find the start of
+# .branch_lt then subtract . mod 256 to find the padding.  Of course
+# just one mod 256 suffices, which is done by anding with 255.
 OTHER_RELRO_SECTIONS_2="
   .opd		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { KEEP (*(.opd)) }
   .toc1		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc1) }
-  .branch_lt	${RELOCATING-0}${RELOCATING+(SIZEOF(.got) != 0 ? . + 255 - (255 & (. - 1 + ALIGN(SIZEOF(.branch_lt),8)${RELRO_NOW+ + ALIGN(SIZEOF(.plt),8) + ALIGN(SIZEOF(.iplt),8)})) : ALIGN(8))} : { *(.branch_lt) }"
+  .branch_lt	${RELOCATING-0}${RELOCATING+ALIGNOF(.branch_lt) < 256 && SIZEOF(.got) != 0 ? . + (((-MAX(ALIGNOF(.branch_lt),8) & (-SIZEOF(.branch_lt)${RELRO_NOW+ + (-MAX(ALIGNOF(.plt),8) & (-SIZEOF(.plt) + (-MAX(ALIGNOF(.iplt),8) & -SIZEOF(.iplt))))})) - .) & 255) : ALIGN(MAX(ALIGNOF(.branch_lt), SIZEOF(.got) != 0 ? 256 : 8))} : { *(.branch_lt) }"
 INITIAL_READWRITE_SECTIONS="
   .toc		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc) }"
 # Put .got before .data
diff --git a/ld/ldlang.c b/ld/ldlang.c
index e640380e901..f12c09633a7 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2458,7 +2458,6 @@ exp_init_os (etree_type *exp)
 	{
 	case ADDR:
 	case LOADADDR:
-	case SIZEOF:
 	  {
 	    lang_output_section_statement_type *os;
 

-- 
Alan Modra
Australia Development Lab, IBM

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

* PowerPC64 .branch_lt address
@ 2022-06-27  3:25 Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2022-06-27  3:25 UTC (permalink / raw)
  To: binutils

.branch_lt is really an extension of .plt, as is .iplt.  We'd like all
of the PLT sections to be fixed relative to .TOC. after stub sizing,
because changes in offset to PLT entries might mean a change in stub
sizes.  When -z relro, the relro layout does this by laying out
sections from the end of the relro segment.  So for example, a change
in .eh_frame (which happens after stub sizing) will keep the same GOT
to PLT offset when -z relro.  Not so when -z norelro, because then the
usual forward layout of section is done and .got is more aligned than
.branch_lt.

	* emulparams/elf64ppc.sh: Set .branch_lt address fixed relative
	to .got.
	* testsuite/ld-powerpc/elfv2exe.d: Adjust to suit.

diff --git a/ld/emulparams/elf64ppc.sh b/ld/emulparams/elf64ppc.sh
index a18393b7202..59132fa06fa 100644
--- a/ld/emulparams/elf64ppc.sh
+++ b/ld/emulparams/elf64ppc.sh
@@ -37,7 +37,7 @@ OTHER_GOT_RELOC_SECTIONS="
 OTHER_RELRO_SECTIONS_2="
   .opd		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { KEEP (*(.opd)) }
   .toc1		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc1) }
-  .branch_lt	${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.branch_lt) }"
+  .branch_lt	${RELOCATING-0}${RELOCATING+(SIZEOF(.got) != 0 ? . + 255 - (255 & (. - 1 + ALIGN(SIZEOF(.branch_lt),8)${RELRO_NOW+ + ALIGN(SIZEOF(.plt),8) + ALIGN(SIZEOF(.iplt),8)})) : ALIGN(8))} : { *(.branch_lt) }"
 INITIAL_READWRITE_SECTIONS="
   .toc		${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc) }"
 # Put .got before .data
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
index 0ccfcbf345a..586264d449b 100644
--- a/ld/testsuite/ld-powerpc/elfv2exe.d
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
@@ -9,13 +9,13 @@ Disassembly of section \.text:
 
 0+100000c0 <.*\.plt_branch\.f4>:
 .*:	(3d 82 ff ff|ff ff 82 3d) 	addis   r12,r2,-1
-.*:	(e9 8c 7f 58|58 7f 8c e9) 	ld      r12,32600\(r12\)
+.*:	(e9 8c 7f f0|f0 7f 8c e9) 	ld      r12,32752\(r12\)
 .*:	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
 .*:	(4e 80 04 20|20 04 80 4e) 	bctr
 
 0+100000d0 <.*\.plt_branch\.f2>:
 .*:	(3d 82 ff ff|ff ff 82 3d) 	addis   r12,r2,-1
-.*:	(e9 8c 7f 60|60 7f 8c e9) 	ld      r12,32608\(r12\)
+.*:	(e9 8c 7f f8|f8 7f 8c e9) 	ld      r12,32760\(r12\)
 .*:	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
 .*:	(4e 80 04 20|20 04 80 4e) 	bctr
 

-- 
Alan Modra
Australia Development Lab, IBM

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

end of thread, other threads:[~2022-07-25  1:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-25  1:54 PowerPC64 .branch_lt address Alan Modra
  -- strict thread matches above, loose matches on Subject: below --
2022-06-27  3:25 Alan Modra

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