This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
oops, powerpc .plt
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Wed, 8 May 2002 14:42:05 +0930
- Subject: oops, powerpc .plt
Some time ago, I changed _bfd_elf_create_dynamic_sections to not
set SEC_CODE for .plt when plt_not_loaded. This is wrong for
ppc32. Additionally, .got should really be marked executable too,
as it contains a "blrl" instruction that is used to find the
.got section.
* elf32-ppc.c (ppc_elf_create_got): New function.
(ppc_elf_create_dynamic_sections): Call ppc_elf_create_got before
_bfd_elf_create_dynamic_sections. Correct .plt flags.
(ppc_elf_check_relocs): Use ppc_elf_create_got in place of
_bfd_elf_create_got_section.
Committing to mainline, and in a few days to the branch if no one objects.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.43
diff -c -p -r1.43 elf32-ppc.c
*** bfd/elf32-ppc.c 7 May 2002 00:16:51 -0000 1.43
--- bfd/elf32-ppc.c 8 May 2002 04:57:03 -0000
*************** static boolean ppc_elf_merge_private_bfd
*** 49,54 ****
--- 49,56 ----
static int ppc_elf_additional_program_headers PARAMS ((bfd *));
static boolean ppc_elf_modify_segment_map PARAMS ((bfd *));
+ static asection *ppc_elf_create_got
+ PARAMS ((bfd *, struct bfd_link_info *));
static boolean ppc_elf_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
*************** ppc_elf_modify_segment_map (abfd)
*** 1632,1637 ****
--- 1634,1663 ----
return true;
}
+ /* The powerpc .got has a blrl instruction in it. Mark it executable. */
+
+ static asection *
+ ppc_elf_create_got (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ {
+ register asection *s;
+ flagword flags;
+
+ if (!_bfd_elf_create_got_section (abfd, info))
+ return NULL;
+
+ s = bfd_get_section_by_name (abfd, ".got");
+ if (s == NULL)
+ abort ();
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ if (!bfd_set_section_flags (abfd, s, flags))
+ return NULL;
+ return s;
+ }
+
/* We have to create .dynsbss and .rela.sbss here so that they get mapped
to output sections (just like _bfd_elf_create_dynamic_sections has
to create .dynbss and .rela.bss). */
*************** ppc_elf_create_dynamic_sections (abfd, i
*** 1644,1649 ****
--- 1670,1678 ----
register asection *s;
flagword flags;
+ if (!ppc_elf_create_got (abfd, info))
+ return false;
+
if (!_bfd_elf_create_dynamic_sections (abfd, info))
return false;
*************** ppc_elf_create_dynamic_sections (abfd, i
*** 1663,1669 ****
|| ! bfd_set_section_alignment (abfd, s, 2))
return false;
}
! return true;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
--- 1692,1704 ----
|| ! bfd_set_section_alignment (abfd, s, 2))
return false;
}
!
! s = bfd_get_section_by_name (abfd, ".plt");
! if (s == NULL)
! abort ();
!
! flags = SEC_ALLOC | SEC_CODE | SEC_IN_MEMORY | SEC_LINKER_CREATED;
! return bfd_set_section_flags (abfd, s, flags);
}
/* Adjust a symbol defined by a dynamic object and referenced by a
*************** ppc_elf_check_relocs (abfd, info, sec, r
*** 2119,2128 ****
{
if (dynobj == NULL)
elf_hash_table (info)->dynobj = dynobj = abfd;
! if (! _bfd_elf_create_got_section (dynobj, info))
return false;
- sgot = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (sgot != NULL);
}
}
--- 2154,2162 ----
{
if (dynobj == NULL)
elf_hash_table (info)->dynobj = dynobj = abfd;
! sgot = ppc_elf_create_got (dynobj, info);
! if (sgot == NULL)
return false;
}
}
*************** ppc_elf_check_relocs (abfd, info, sec, r
*** 2139,2148 ****
{
if (dynobj == NULL)
elf_hash_table (info)->dynobj = dynobj = abfd;
! if (! _bfd_elf_create_got_section (dynobj, info))
return false;
- sgot = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (sgot != NULL);
}
if (srelgot == NULL
--- 2173,2181 ----
{
if (dynobj == NULL)
elf_hash_table (info)->dynobj = dynobj = abfd;
! sgot = ppc_elf_create_got (dynobj, info);
! if (sgot == NULL)
return false;
}
if (srelgot == NULL
--
Alan Modra
IBM OzLabs - Linux Technology Centre