This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: linker stub symbols for ELF32 secured ABI
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Yaakov Yaari <YAARI at il dot ibm dot com>
- Cc: Steve Munroe <sjmunroe at us dot ibm dot com>, binutils at sources dot redhat dot com
- Date: Mon, 5 Dec 2005 23:56:49 +1030
- Subject: Re: linker stub symbols for ELF32 secured ABI
- References: <OF36E9ABBE.BF7B75B6-ONC22570CD.0049BCBC-C22570CD.004A499D@il.ibm.com>
On Sun, Dec 04, 2005 at 03:31:25PM +0200, Yaakov Yaari wrote:
> Hi Alan,
> A while ago I asked you to add linker stub symbols for ELF64. The form of
> such symbols is <address>.<linker stub type>.<target func name>
> This was implemented in the linker that came with RHEL4.
> >From looking at the code generated by the 20050923 tool chain it seems this
> is not implemented for ELF32 secured ABI.
> Can you fix that?
Sure. Let me know if the names I chose here are bad for some reason.
If OK, I'll commit this patch.
bfd/
* elf32-ppc.c (struct ppc_elf_link_hash_table): Add emit_stub_syms.
(ppc_elf_select_plt_layout): Add emit_stub_syms param, save to htab.
(add_stub_sym): New function.
(allocate_dynrelocs): Call add_stub_sym.
(ppc_elf_size_dynamic_sections): Emit __glink and __glink_PLTresolve
when emit_stub_syms.
* elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
ld/
* emultempl/ppc32elf.em (emit_stub_syms): New var.
(ppc_after_open): Pass it to ppc_elf_select_plt_layout.
(PARSE_AND_LIST_PROLOGUE <OPTION_STUBSYMS>): Define.
(PARSE_AND_LIST_LONGOPTS): Add emit-stub-syms.
(PARSE_AND_LIST_OPTIONS): Describe emit-stub-syms.
(PARSE_AND_LIST_OPTIONS): Handle it.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.183
diff -u -p -r1.183 elf32-ppc.c
--- bfd/elf32-ppc.c 25 Oct 2005 16:19:06 -0000 1.183
+++ bfd/elf32-ppc.c 5 Dec 2005 13:17:49 -0000
@@ -2353,6 +2353,9 @@ struct ppc_elf_link_hash_table
unsigned int new_plt:1;
unsigned int old_plt:1;
+ /* Set if we should emit symbols for stubs. */
+ unsigned int emit_stub_syms:1;
+
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
@@ -3593,7 +3596,8 @@ ppc_elf_merge_private_bfd_data (bfd *ibf
int
ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
- int force_old_plt)
+ int force_old_plt,
+ int emit_stub_syms)
{
struct ppc_elf_link_hash_table *htab;
flagword flags;
@@ -3602,6 +3606,8 @@ ppc_elf_select_plt_layout (bfd *output_b
if (force_old_plt || !htab->new_plt)
htab->old_plt = 1;
+ htab->emit_stub_syms = emit_stub_syms;
+
if (htab->is_vxworks)
{
/* The VxWorks PLT is a loaded section with contents. */
@@ -4207,6 +4213,51 @@ ppc_elf_adjust_dynamic_symbol (struct bf
return TRUE;
}
+/* Generate a symbol to mark plt call stubs, of the form
+ xxxxxxxx_plt_call_<callee> where xxxxxxxx is a hex number, usually 0,
+ specifying the addend on the plt relocation, or for -fPIC,
+ xxxxxxxx.got2_plt_call_<callee>. */
+
+static bfd_boolean
+add_stub_sym (struct plt_entry *ent,
+ struct elf_link_hash_entry *h,
+ struct ppc_elf_link_hash_table *htab)
+{
+ struct elf_link_hash_entry *sh;
+ size_t len1, len2, len3;
+ char *name;
+
+ len1 = strlen (h->root.root.string);
+ len2 = sizeof ("plt_call_") - 1;
+ len3 = 0;
+ if (ent->sec)
+ len3 = strlen (ent->sec->name);
+ name = bfd_malloc (len1 + len2 + len3 + 10);
+ if (name == NULL)
+ return FALSE;
+ sprintf (name, "%08x", (unsigned) ent->addend & 0xffffffff);
+ if (ent->sec)
+ memcpy (name + 8, ent->sec->name, len3);
+ name[len3 + 8] = '_';
+ memcpy (name + len3 + 9, "plt_call_", len2);
+ memcpy (name + len3 + 9 + len2, h->root.root.string, len1 + 1);
+ sh = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = ent->glink_offset;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ return TRUE;
+}
+
/* Allocate NEED contiguous space in .got, and return the offset.
Handles allocation of the got header when crossing 32k. */
@@ -4308,6 +4359,10 @@ allocate_dynrelocs (struct elf_link_hash
h->root.u.def.value = glink_offset;
}
ent->glink_offset = glink_offset;
+
+ if (htab->emit_stub_syms
+ && !add_stub_sym (ent, h, htab))
+ return FALSE;
}
else
{
@@ -4747,6 +4802,41 @@ ppc_elf_size_dynamic_sections (bfd *outp
/* Pad out to align the start of PLTresolve. */
htab->glink->size += -htab->glink->size & 15;
htab->glink->size += GLINK_PLTRESOLVE;
+
+ if (htab->emit_stub_syms)
+ {
+ struct elf_link_hash_entry *sh;
+ sh = elf_link_hash_lookup (&htab->elf, "__glink",
+ TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = htab->glink_pltresolve;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
+ TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = htab->glink->size - GLINK_PLTRESOLVE;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ }
}
/* We've now determined the sizes of the various dynamic sections.
Index: bfd/elf32-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.h,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-ppc.h
--- bfd/elf32-ppc.h 16 Jul 2005 03:30:23 -0000 1.8
+++ bfd/elf32-ppc.h 5 Dec 2005 13:17:49 -0000
@@ -17,7 +17,7 @@ You should have received a copy of the G
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
-int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, int);
+int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, int, int);
asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);
Index: ld/emultempl/ppc32elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc32elf.em,v
retrieving revision 1.10
diff -u -p -r1.10 ppc32elf.em
--- ld/emultempl/ppc32elf.em 4 Aug 2005 06:22:13 -0000 1.10
+++ ld/emultempl/ppc32elf.em 5 Dec 2005 13:17:49 -0000
@@ -41,6 +41,9 @@ is_ppc_elf32_vec(const bfd_target * vec)
/* Whether to run tls optimization. */
static int notlsopt = 0;
+/* Whether to emit symbols for stubs. */
+static int emit_stub_syms = 0;
+
/* Chooses the correct place for .plt and .got. */
static int old_plt = 0;
static int old_got = 0;
@@ -58,7 +61,9 @@ ppc_after_open (void)
lang_output_section_statement_type *plt_os[2];
lang_output_section_statement_type *got_os[2];
- new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt);
+ emit_stub_syms |= link_info.emitrelocations;
+ new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt,
+ emit_stub_syms);
if (new_plt < 0)
einfo ("%X%P: select_plt_layout problem %E\n");
@@ -126,9 +131,11 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_TLS_OPT 301
#define OPTION_OLD_PLT 302
#define OPTION_OLD_GOT 303
+#define OPTION_STUBSYMS 304
'
PARSE_AND_LIST_LONGOPTS='
+ { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
@@ -136,6 +143,7 @@ PARSE_AND_LIST_LONGOPTS='
PARSE_AND_LIST_OPTIONS='
fprintf (file, _("\
+ --emit-stub-syms Label linker stubs with a symbol.\n\
--no-tls-optimize Don'\''t try to optimize TLS accesses.\n\
--bss-plt Force old-style BSS PLT.\n\
--sdata-got Force GOT location just before .sdata.\n"
@@ -143,6 +151,10 @@ PARSE_AND_LIST_OPTIONS='
'
PARSE_AND_LIST_ARGS_CASES='
+ case OPTION_STUBSYMS:
+ emit_stub_syms = 1;
+ break;
+
case OPTION_NO_TLS_OPT:
notlsopt = 1;
break;
--
Alan Modra
IBM OzLabs - Linux Technology Centre