From: Alan Modra <amodra@bigpond.net.au>
To: binutils@sources.redhat.com
Subject: Re: powerpc new PLT and GOT
Date: Thu, 12 May 2005 16:10:00 -0000 [thread overview]
Message-ID: <20050512152354.GC12174@bubble.grove.modra.org> (raw)
In-Reply-To: <20050512083650.GH29302@bubble.grove.modra.org>
A bug fix for new .got section flags, and the smaller plt call stubs
without a load-with-update instruction.
* elf32-ppc.c (LWZU_0_X_11): Delete.
(B, LWZ_11_X_11, LWZ_11_X_30, MTCTR_11): Define.
(ppc_elf_select_plt_layout): Set .got flags too. Formatting.
(ppc_elf_size_dynamic_sections): Allocate space for .glink branch
table.
(ppc_elf_finish_dynamic_symbol): Point .plt entries into the branch
table.
(ppc_elf_finish_dynamic_sections): Adjust DT_PPC_GLINK value.
Generate .glink branch table and updated stubs.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.156
diff -u -p -r1.156 elf32-ppc.c
--- bfd/elf32-ppc.c 11 May 2005 14:09:42 -0000 1.156
+++ bfd/elf32-ppc.c 12 May 2005 14:51:46 -0000
@@ -67,6 +67,7 @@ static bfd_reloc_status_type ppc_elf_unh
/* Some instructions. */
#define NOP 0x60000000
+#define B 0x48000000
#define ADDIS_11_11 0x3d6b0000
#define ADDI_11_11 0x396b0000
#define SUB_11_11_30 0x7d7e5850
@@ -77,7 +78,9 @@ static bfd_reloc_status_type ppc_elf_unh
#define LWZ_12_8_30 0x819e0008
#define BCTR 0x4e800420
#define ADDIS_11_30 0x3d7e0000
-#define LWZU_0_X_11 0x840b0000
+#define LWZ_11_X_11 0x816b0000
+#define LWZ_11_X_30 0x817e0000
+#define MTCTR_11 0x7d6903a6
/* Offset of tp and dtp pointers from start of TLS block. */
#define TP_OFFSET 0x7000
@@ -3280,24 +3283,25 @@ ppc_elf_select_plt_layout (bfd *output_b
if (!htab->old_plt)
{
- /* The new PLT is a loaded section. Fix its flags. */
- if (htab->plt != NULL)
- {
- flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- if (!bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
- return -1;
- }
+ /* The new PLT is a loaded section. */
+ if (htab->plt != NULL
+ && !bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
+ return -1;
+
+ /* The new GOT is not executable. */
+ if (htab->got != NULL
+ && !bfd_set_section_flags (htab->elf.dynobj, htab->got, flags))
+ return -1;
}
else
{
/* Stop an unused .glink section from affecting .text alignment. */
- if (htab->glink != NULL)
- {
- if (!bfd_set_section_alignment (htab->elf.dynobj, htab->glink, 0))
- return -1;
- }
+ if (htab->glink != NULL
+ && !bfd_set_section_alignment (htab->elf.dynobj, htab->glink, 0))
+ return -1;
}
return !htab->old_plt;
}
@@ -4302,6 +4306,10 @@ ppc_elf_size_dynamic_sections (bfd *outp
if (htab->glink != NULL && htab->glink->size != 0)
{
htab->glink_pltresolve = htab->glink->size;
+ /* Space for the branch table. */
+ htab->glink->size += htab->glink->size / (GLINK_ENTRY_SIZE / 4) - 4;
+ /* Pad out to align the start of PLTresolve. */
+ htab->glink->size += -htab->glink->size & 15;
htab->glink->size += GLINK_PLTRESOLVE;
}
@@ -6197,6 +6205,7 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
else
{
bfd_vma val = (htab->glink_pltresolve
+ + h->plt.offset
+ htab->glink->output_section->vma
+ htab->glink->output_offset);
bfd_put_32 (output_bfd, val, htab->plt->contents + h->plt.offset);
@@ -6345,7 +6354,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
case DT_PPC_GLINK:
s = htab->glink;
- dyn.d_un.d_ptr = (htab->glink_pltresolve
+ dyn.d_un.d_ptr = (s->size - GLINK_PLTRESOLVE
+ s->output_section->vma + s->output_offset);
break;
@@ -6380,7 +6389,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
{
unsigned char *p;
unsigned char *endp;
- bfd_vma pltgot;
+ bfd_vma got, pltgot;
unsigned int i;
static const unsigned int plt_resolve[] =
{
@@ -6400,17 +6409,67 @@ ppc_elf_finish_dynamic_sections (bfd *ou
#define PPC_HI(v) (((v) >> 16) & 0xffff)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+ got = (htab->elf.hgot->root.u.def.value
+ + htab->elf.hgot->root.u.def.section->output_section->vma
+ + htab->elf.hgot->root.u.def.section->output_offset);
+
pltgot = (htab->plt->output_section->vma
+ htab->plt->output_offset
- - htab->elf.hgot->root.u.def.value
- - htab->elf.hgot->root.u.def.section->output_section->vma
- - htab->elf.hgot->root.u.def.section->output_offset);
+ - got);
+ /* Write the plt call stubs. */
p = htab->glink->contents;
- p += htab->glink_pltresolve;
- bfd_put_32 (output_bfd, ADDIS_11_11 + PPC_HA (-pltgot), p);
+ endp = p + htab->glink_pltresolve;
+ while (p < endp)
+ {
+ if (pltgot < 0x8000)
+ {
+ bfd_put_32 (output_bfd, LWZ_11_X_30 + pltgot, p);
+ p += 4;
+ bfd_put_32 (output_bfd, MTCTR_11, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BCTR, p);
+ p += 4;
+ bfd_put_32 (output_bfd, NOP, p);
+ p += 4;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (pltgot), p);
+ p += 4;
+ bfd_put_32 (output_bfd, LWZ_11_X_11 + PPC_LO (pltgot), p);
+ p += 4;
+ bfd_put_32 (output_bfd, MTCTR_11, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BCTR, p);
+ p += 4;
+ }
+ pltgot += 4;
+ }
+
+ /* Now build the branch table, one for each plt entry (less one),
+ and perhaps some padding. */
+ endp = htab->glink->contents;
+ endp += htab->glink->size - GLINK_PLTRESOLVE;
+ while (p < endp - 8 * 4)
+ {
+ bfd_put_32 (output_bfd, B + endp - p, p);
+ p += 4;
+ }
+ while (p < endp)
+ {
+ bfd_put_32 (output_bfd, NOP, p);
+ p += 4;
+ }
+
+ got -= (htab->glink_pltresolve
+ + htab->glink->output_section->vma
+ + htab->glink->output_offset);
+
+ /* Last comes the PLTresolve stub. */
+ bfd_put_32 (output_bfd, ADDIS_11_11 + PPC_HA (got), p);
p += 4;
- bfd_put_32 (output_bfd, ADDI_11_11 + PPC_LO (-pltgot), p);
+ bfd_put_32 (output_bfd, ADDI_11_11 + PPC_LO (got), p);
p += 4;
for (i = 0; i < ARRAY_SIZE (plt_resolve); i++)
@@ -6420,21 +6479,6 @@ ppc_elf_finish_dynamic_sections (bfd *ou
}
if (ARRAY_SIZE (plt_resolve) + 2 != GLINK_PLTRESOLVE / 4)
abort ();
-
- p = htab->glink->contents;
- endp = p + htab->glink_pltresolve;
- while (p < endp)
- {
- bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (pltgot), p);
- p += 4;
- bfd_put_32 (output_bfd, LWZU_0_X_11 + PPC_LO (pltgot), p);
- p += 4;
- bfd_put_32 (output_bfd, MTCTR_0, p);
- p += 4;
- bfd_put_32 (output_bfd, BCTR, p);
- p += 4;
- pltgot += 4;
- }
}
return TRUE;
--
Alan Modra
IBM OzLabs - Linux Technology Centre
next prev parent reply other threads:[~2005-05-12 15:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-05-11 14:22 Alan Modra
2005-05-11 14:29 ` Daniel Jacobowitz
2005-05-11 14:59 ` Alan Modra
2005-05-11 15:10 ` Andreas Schwab
2005-05-11 15:39 ` Alan Modra
2005-05-11 15:16 ` Daniel Jacobowitz
2005-05-11 16:37 ` Richard Earnshaw
2005-05-11 14:45 ` Andreas Schwab
2005-05-12 6:08 ` Richard Henderson
2005-05-12 6:13 ` Alan Modra
2005-05-12 7:47 ` Richard Henderson
2005-05-12 9:02 ` Alan Modra
2005-05-12 16:10 ` Alan Modra [this message]
2005-05-12 18:07 ` Richard Henderson
2005-05-14 5:57 ` Alan Modra
2005-05-17 14:16 ` Alan Modra
2005-05-19 8:32 ` Alan Modra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050512152354.GC12174@bubble.grove.modra.org \
--to=amodra@bigpond.net.au \
--cc=binutils@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).