This patch adds support for ARM PLT entries that support a full 32-bit offset range.
Enabled via the use of a new linker command line option: --long-plt. * bfd-in.h: Add export of bfd_elf32_arm_use_long_plt. * bfd-in2.h: Regenerate. * elf32-arm.c (elf32_arm_plt_entry_long): New array. (elf32_arm_link_hash_table_create): Set plt_entry_size to 16 if using long PLT entries. (bfd_elf32_arm_use_long_plt): New function. (elf32_arm_populate_plt_entry): Add support for long PLT entries. * emultempl/armelf.em (OPTION_LONG_PLT): Define. (PARSE_AND_LIST_LONGOPTS): Add long-plt. (PARSE_AND_LIST_OPTIONS): Likewise. (PARSE_AND_LIST_ARGS_CASES): Handle long-plt. * ld.texinfo: Document --long-plt. * ld-arm/long-plt-format.s: New test case. * ld-arm/long-plt-format.d: Expected disassembly. * ld-arm/arm-elf.exp: Run the new test.
This commit is contained in:
parent
fa96cb382c
commit
1db37fe627
11 changed files with 164 additions and 48 deletions
|
@ -1,3 +1,13 @@
|
|||
2014-02-27 Yuri Gribov <y.gribov@samsung.com>
|
||||
|
||||
* bfd-in.h: Add export of bfd_elf32_arm_use_long_plt.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* elf32-arm.c (elf32_arm_plt_entry_long): New array.
|
||||
(elf32_arm_link_hash_table_create): Set plt_entry_size to 16 if
|
||||
using long PLT entries.
|
||||
(bfd_elf32_arm_use_long_plt): New function.
|
||||
(elf32_arm_populate_plt_entry): Add support for long PLT entries.
|
||||
|
||||
2014-02-27 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf32-ppc.c (ppc_elf_link_hash_table_create): Provide default
|
||||
|
|
14
bfd/bfd-in.h
14
bfd/bfd-in.h
|
@ -1,6 +1,6 @@
|
|||
/* Main header file for the bfd library -- portable access to object files.
|
||||
|
||||
Copyright 1990-2013 Free Software Foundation, Inc.
|
||||
Copyright 1990-2014 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support.
|
||||
|
||||
|
@ -877,15 +877,19 @@ extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
|||
extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
|
||||
(bfd *, struct bfd_link_info *);
|
||||
|
||||
/* ELF ARM mapping symbol support */
|
||||
/* ELF ARM mapping symbol support. */
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_MAP (1 << 0)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_TAG (1 << 1)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_OTHER (1 << 2)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_ANY (~0)
|
||||
extern bfd_boolean bfd_is_arm_special_symbol_name
|
||||
(const char * name, int type);
|
||||
|
||||
extern void bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *, int);
|
||||
extern bfd_boolean bfd_is_arm_special_symbol_name
|
||||
(const char *, int);
|
||||
|
||||
extern void bfd_elf32_arm_set_byteswap_code
|
||||
(struct bfd_link_info *, int);
|
||||
|
||||
extern void bfd_elf32_arm_use_long_plt (void);
|
||||
|
||||
/* ARM Note section processing. */
|
||||
extern bfd_boolean bfd_arm_merge_machines
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
/* Main header file for the bfd library -- portable access to object files.
|
||||
|
||||
Copyright 1990-2013 Free Software Foundation, Inc.
|
||||
Copyright 1990-2014 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support.
|
||||
|
||||
|
@ -884,15 +884,19 @@ extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
|||
extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
|
||||
(bfd *, struct bfd_link_info *);
|
||||
|
||||
/* ELF ARM mapping symbol support */
|
||||
/* ELF ARM mapping symbol support. */
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_MAP (1 << 0)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_TAG (1 << 1)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_OTHER (1 << 2)
|
||||
#define BFD_ARM_SPECIAL_SYM_TYPE_ANY (~0)
|
||||
extern bfd_boolean bfd_is_arm_special_symbol_name
|
||||
(const char * name, int type);
|
||||
|
||||
extern void bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *, int);
|
||||
extern bfd_boolean bfd_is_arm_special_symbol_name
|
||||
(const char *, int);
|
||||
|
||||
extern void bfd_elf32_arm_set_byteswap_code
|
||||
(struct bfd_link_info *, int);
|
||||
|
||||
extern void bfd_elf32_arm_use_long_plt (void);
|
||||
|
||||
/* ARM Note section processing. */
|
||||
extern bfd_boolean bfd_arm_merge_machines
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* 32-bit ELF support for ARM
|
||||
Copyright 1998-2013 Free Software Foundation, Inc.
|
||||
Copyright 1998-2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
|
@ -2140,15 +2140,27 @@ static const bfd_vma elf32_arm_plt0_entry [] =
|
|||
0x00000000, /* &GOT[0] - . */
|
||||
};
|
||||
|
||||
/* Subsequent entries in a procedure linkage table look like
|
||||
this. */
|
||||
static const bfd_vma elf32_arm_plt_entry [] =
|
||||
/* By default subsequent entries in a procedure linkage table look like
|
||||
this. Offsets that don't fit into 28 bits will cause link error. */
|
||||
static const bfd_vma elf32_arm_plt_entry_short [] =
|
||||
{
|
||||
0xe28fc600, /* add ip, pc, #0xNN00000 */
|
||||
0xe28cca00, /* add ip, ip, #0xNN000 */
|
||||
0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */
|
||||
};
|
||||
|
||||
/* When explicitly asked, we'll use this "long" entry format
|
||||
which can cope with arbitrary displacements. */
|
||||
static const bfd_vma elf32_arm_plt_entry_long [] =
|
||||
{
|
||||
0xe28fc200, /* add ip, pc, #0xN0000000 */
|
||||
0xe28cc600, /* add ip, ip, #0xNN00000 */
|
||||
0xe28cca00, /* add ip, ip, #0xNN000 */
|
||||
0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */
|
||||
};
|
||||
|
||||
static bfd_boolean elf32_arm_use_long_plt_entry = FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
/* The format of the first entry in the procedure linkage table
|
||||
|
@ -3464,7 +3476,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
|
|||
ret->plt_entry_size = 16;
|
||||
#else
|
||||
ret->plt_header_size = 20;
|
||||
ret->plt_entry_size = 12;
|
||||
ret->plt_entry_size = elf32_arm_use_long_plt_entry ? 16 : 12;
|
||||
#endif
|
||||
ret->use_rel = 1;
|
||||
ret->obfd = abfd;
|
||||
|
@ -6027,6 +6039,15 @@ arm_make_glue_section (bfd * abfd, const char * name)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Set size of .plt entries. This function is called from the
|
||||
linker scripts in ld/emultempl/{armelf}.em. */
|
||||
|
||||
void
|
||||
bfd_elf32_arm_use_long_plt (void)
|
||||
{
|
||||
elf32_arm_use_long_plt_entry = TRUE;
|
||||
}
|
||||
|
||||
/* Add the glue sections to ABFD. This function is called from the
|
||||
linker scripts in ld/emultempl/{armelf}.em. */
|
||||
|
||||
|
@ -7705,8 +7726,6 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
|
|||
of the PLT stub. */
|
||||
got_displacement = got_address - (plt_address + 8);
|
||||
|
||||
BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
|
||||
|
||||
if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
|
||||
{
|
||||
put_thumb_insn (htab, output_bfd,
|
||||
|
@ -7715,21 +7734,45 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
|
|||
elf32_arm_plt_thumb_stub[1], ptr - 2);
|
||||
}
|
||||
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry[0]
|
||||
| ((got_displacement & 0x0ff00000) >> 20),
|
||||
ptr + 0);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry[1]
|
||||
| ((got_displacement & 0x000ff000) >> 12),
|
||||
ptr+ 4);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry[2]
|
||||
| (got_displacement & 0x00000fff),
|
||||
ptr + 8);
|
||||
if (!elf32_arm_use_long_plt_entry)
|
||||
{
|
||||
BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
|
||||
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_short[0]
|
||||
| ((got_displacement & 0x0ff00000) >> 20),
|
||||
ptr + 0);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_short[1]
|
||||
| ((got_displacement & 0x000ff000) >> 12),
|
||||
ptr+ 4);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_short[2]
|
||||
| (got_displacement & 0x00000fff),
|
||||
ptr + 8);
|
||||
#ifdef FOUR_WORD_PLT
|
||||
bfd_put_32 (output_bfd, elf32_arm_plt_entry[3], ptr + 12);
|
||||
bfd_put_32 (output_bfd, elf32_arm_plt_entry_short[3], ptr + 12);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_long[0]
|
||||
| ((got_displacement & 0xf0000000) >> 28),
|
||||
ptr + 0);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_long[1]
|
||||
| ((got_displacement & 0x0ff00000) >> 20),
|
||||
ptr + 4);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_long[2]
|
||||
| ((got_displacement & 0x000ff000) >> 12),
|
||||
ptr+ 8);
|
||||
put_arm_insn (htab, output_bfd,
|
||||
elf32_arm_plt_entry_long[3]
|
||||
| (got_displacement & 0x00000fff),
|
||||
ptr + 12);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the entry in the .rel(a).(i)plt section. */
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2014-02-27 Yuri Gribov <y.gribov@samsung.com>
|
||||
|
||||
* emultempl/armelf.em (OPTION_LONG_PLT): Define.
|
||||
(PARSE_AND_LIST_LONGOPTS): Add long-plt.
|
||||
(PARSE_AND_LIST_OPTIONS): Likewise.
|
||||
(PARSE_AND_LIST_ARGS_CASES): Handle long-plt.
|
||||
* ld.texinfo: Document --long-plt.
|
||||
|
||||
2014-02-27 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* emulparams/elf32ppcvxworks.sh: Source plt_unwind.sh and
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# This shell script emits a C file. -*- C -*-
|
||||
# Copyright 1991-2013 Free Software Foundation, Inc.
|
||||
# Copyright 1991-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of the GNU Binutils.
|
||||
#
|
||||
|
@ -28,10 +28,10 @@ fragment <<EOF
|
|||
#include "ldctor.h"
|
||||
#include "elf/arm.h"
|
||||
|
||||
static char *thumb_entry_symbol = NULL;
|
||||
static char * thumb_entry_symbol = NULL;
|
||||
static int byteswap_code = 0;
|
||||
static int target1_is_rel = 0${TARGET1_IS_REL};
|
||||
static char *target2_type = "${TARGET2_TYPE}";
|
||||
static char * target2_type = "${TARGET2_TYPE}";
|
||||
static int fix_v4bx = 0;
|
||||
static int use_blx = 0;
|
||||
static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT;
|
||||
|
@ -531,6 +531,7 @@ PARSE_AND_LIST_PROLOGUE='
|
|||
#define OPTION_NO_MERGE_EXIDX_ENTRIES 316
|
||||
#define OPTION_FIX_ARM1176 317
|
||||
#define OPTION_NO_FIX_ARM1176 318
|
||||
#define OPTION_LONG_PLT 319
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_SHORTOPTS=p
|
||||
|
@ -555,6 +556,7 @@ PARSE_AND_LIST_LONGOPTS='
|
|||
{ "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
|
||||
{ "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
|
||||
{ "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
|
||||
{ "long-plt", no_argument, NULL, OPTION_LONG_PLT },
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_OPTIONS='
|
||||
|
@ -572,6 +574,8 @@ PARSE_AND_LIST_OPTIONS='
|
|||
fprintf (file, _(" --no-wchar-size-warning Don'\''t warn about objects with incompatible\n"
|
||||
" wchar_t sizes\n"));
|
||||
fprintf (file, _(" --pic-veneer Always generate PIC interworking veneers\n"));
|
||||
fprintf (file, _(" --long-plt Generate long .plt entries\n"
|
||||
" to handle large .plt/.got displacements\n"));
|
||||
fprintf (file, _("\
|
||||
--stub-group-size=N Maximum size of a group of input sections that\n\
|
||||
can be handled by one stub section. A negative\n\
|
||||
|
@ -675,6 +679,10 @@ PARSE_AND_LIST_ARGS_CASES='
|
|||
case OPTION_NO_FIX_ARM1176:
|
||||
fix_arm1176 = 0;
|
||||
break;
|
||||
|
||||
case OPTION_LONG_PLT:
|
||||
bfd_elf32_arm_use_long_plt ();
|
||||
break;
|
||||
'
|
||||
|
||||
# We have our own before_allocation etc. functions, but they call
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
\input texinfo
|
||||
@setfilename ld.info
|
||||
@c Copyright 1991-2013 Free Software Foundation, Inc.
|
||||
@c Copyright 1991-2014 Free Software Foundation, Inc.
|
||||
@syncodeindex ky cp
|
||||
@c man begin INCLUDE
|
||||
@include configdoc.texi
|
||||
|
@ -55,7 +55,7 @@ This file documents the @sc{gnu} linker LD
|
|||
@end ifset
|
||||
version @value{VERSION}.
|
||||
|
||||
Copyright @copyright{} 1991-2013 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1991-2014 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
|
@ -92,7 +92,7 @@ section entitled ``GNU Free Documentation License''.
|
|||
|
||||
@vskip 0pt plus 1filll
|
||||
@c man begin COPYRIGHT
|
||||
Copyright @copyright{} 1991-2013 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1991-2014 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
|
@ -6257,17 +6257,6 @@ instructions into @code{bal} instructions when it determines that the
|
|||
target subroutine is a leaf routine (that is, the target subroutine does
|
||||
not itself call any subroutines).
|
||||
|
||||
@cindex Cortex-A8 erratum workaround
|
||||
@kindex --fix-cortex-a8
|
||||
@kindex --no-fix-cortex-a8
|
||||
The @samp{--fix-cortex-a8} switch enables a link-time workaround for an erratum in certain Cortex-A8 processors. The workaround is enabled by default if you are targeting the ARM v7-A architecture profile. It can be enabled otherwise by specifying @samp{--fix-cortex-a8}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a8}.
|
||||
|
||||
The erratum only affects Thumb-2 code. Please contact ARM for further details.
|
||||
|
||||
@kindex --merge-exidx-entries
|
||||
@kindex --no-merge-exidx-entries
|
||||
The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent exidx entries in debuginfo.
|
||||
|
||||
@ifclear GENERIC
|
||||
@lowersections
|
||||
@end ifclear
|
||||
|
@ -6526,6 +6515,24 @@ Farcalls stubs insertion is fully supported for the ARM-EABI target
|
|||
only, because it relies on object files properties not present
|
||||
otherwise.
|
||||
|
||||
@cindex Cortex-A8 erratum workaround
|
||||
@kindex --fix-cortex-a8
|
||||
@kindex --no-fix-cortex-a8
|
||||
The @samp{--fix-cortex-a8} switch enables a link-time workaround for an erratum in certain Cortex-A8 processors. The workaround is enabled by default if you are targeting the ARM v7-A architecture profile. It can be enabled otherwise by specifying @samp{--fix-cortex-a8}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a8}.
|
||||
|
||||
The erratum only affects Thumb-2 code. Please contact ARM for further details.
|
||||
|
||||
@kindex --merge-exidx-entries
|
||||
@kindex --no-merge-exidx-entries
|
||||
@cindex Merging exidx entries
|
||||
The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent exidx entries in debuginfo.
|
||||
|
||||
@kindex --long-plt
|
||||
@cindex 32-bit PLT entries
|
||||
The @samp{--long-plt} option enables the use of 16 byte PLT entries
|
||||
which support up to 4Gb of code. The default is to use 12 byte PLT
|
||||
entries which only support 512Mb of code.
|
||||
|
||||
@ifclear GENERIC
|
||||
@lowersections
|
||||
@end ifclear
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2014-02-27 Yuri Gribov <y.gribov@samsung.com>
|
||||
|
||||
* ld-arm/long-plt-format.s: New test case.
|
||||
* ld-arm/long-plt-format.d: Expected disassembly.
|
||||
* ld-arm/arm-elf.exp: Run the new test.
|
||||
|
||||
2014-02-27 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* ld-pe/longsecn-1.d: Allow for extra sections.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Expect script for various ARM ELF tests.
|
||||
# Copyright 2002-2013 Free Software Foundation, Inc.
|
||||
# Copyright 2002-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of the GNU Binutils.
|
||||
#
|
||||
|
@ -188,6 +188,10 @@ set armelftests_common {
|
|||
"" {exec-got-1b.s}
|
||||
{{readelf --relocs exec-got-1.d}}
|
||||
"exec-got-1"}
|
||||
{"Long PLT entries in executables" "--long-plt -shared --section-start=.plt=0x200 --section-start=.got=0xf0000300" ""
|
||||
"" {long-plt-format.s}
|
||||
{{objdump "-d -j .plt" long-plt-format.d}}
|
||||
"long-plt-format"}
|
||||
{"abs call" "-T arm.ld" "" "" {abs-call-1.s}
|
||||
{{objdump -d abs-call-1.d}}
|
||||
"abs-call-1"}
|
||||
|
|
15
ld/testsuite/ld-arm/long-plt-format.d
Normal file
15
ld/testsuite/ld-arm/long-plt-format.d
Normal file
|
@ -0,0 +1,15 @@
|
|||
.*: file format elf32-.*
|
||||
|
||||
|
||||
Disassembly of section .plt:
|
||||
|
||||
00000200 <.plt>:
|
||||
200: .*
|
||||
204: .*
|
||||
208: .*
|
||||
20c: .*
|
||||
210: .* .word .*
|
||||
214: .* add ip, pc, #-268435456 ; 0xf0000000
|
||||
218: .* add ip, ip, #0, 12
|
||||
21c: .* add ip, ip, #0, 20
|
||||
220: .* ldr pc, [ip, #[0-9]*]! ; 0x.*
|
7
ld/testsuite/ld-arm/long-plt-format.s
Normal file
7
ld/testsuite/ld-arm/long-plt-format.s
Normal file
|
@ -0,0 +1,7 @@
|
|||
.globl _start
|
||||
.type _start,%function
|
||||
.globl foo
|
||||
_start:
|
||||
bl foo(PLT)
|
||||
.size _start,.-_start
|
||||
|
Loading…
Reference in a new issue