forked from Imagelibrary/binutils-gdb
PowerPC64 --no-pcrel-optimize
This new option effectively ignores R_PPC64_PCREL_OPT, disabling the optimization of instructions marked by that relocation. The patch also disables GOT indirect to GOT/TOC pointer relative code editing when --no-toc-optimize. bfd/ * elf64-ppc.h (struct ppc64_elf_params): Add no_pcrel_opt. * elf64-ppc.c (ppc64_elf_relocate_section): Disable GOT reloc optimizations when --no-toc-optimize. Disable R_PPC64_PCREL_OPT optimization when --no-pcrel-optimize. ld/ * emultempl/ppc64elf.em (params): Init new field. (enum ppc64_opt): Add OPTION_NO_PCREL_OPT. (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS), (PARSE_AND_LIST_ARGS_CASES): Support --no-pcrel-optimize.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
2020-08-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.h (struct ppc64_elf_params): Add no_pcrel_opt.
|
||||||
|
* elf64-ppc.c (ppc64_elf_relocate_section): Disable GOT reloc
|
||||||
|
optimizations when --no-toc-optimize. Disable R_PPC64_PCREL_OPT
|
||||||
|
optimization when --no-pcrel-optimize.
|
||||||
|
|
||||||
2020-08-13 Alan Modra <amodra@gmail.com>
|
2020-08-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 26348
|
PR 26348
|
||||||
|
|||||||
@@ -15903,7 +15903,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_GOT16_DS:
|
case R_PPC64_GOT16_DS:
|
||||||
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
|
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
|
||||||
|
|| !htab->do_toc_opt)
|
||||||
break;
|
break;
|
||||||
from = TOCstart + htab->sec_info[input_section->id].toc_off;
|
from = TOCstart + htab->sec_info[input_section->id].toc_off;
|
||||||
if (relocation + addend - from + 0x8000 < 0x10000
|
if (relocation + addend - from + 0x8000 < 0x10000
|
||||||
@@ -15922,7 +15923,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
case R_PPC64_GOT16_LO_DS:
|
case R_PPC64_GOT16_LO_DS:
|
||||||
case R_PPC64_GOT16_HA:
|
case R_PPC64_GOT16_HA:
|
||||||
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
|
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
|
||||||
|
|| !htab->do_toc_opt)
|
||||||
break;
|
break;
|
||||||
from = TOCstart + htab->sec_info[input_section->id].toc_off;
|
from = TOCstart + htab->sec_info[input_section->id].toc_off;
|
||||||
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
|
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
|
||||||
@@ -15945,34 +15947,38 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_GOT_PCREL34:
|
case R_PPC64_GOT_PCREL34:
|
||||||
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
|
if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
|
||||||
|
|| !htab->do_toc_opt)
|
||||||
break;
|
break;
|
||||||
from = (rel->r_offset
|
from = (rel->r_offset
|
||||||
+ input_section->output_section->vma
|
+ input_section->output_section->vma
|
||||||
+ input_section->output_offset);
|
+ input_section->output_offset);
|
||||||
if (relocation - from + (1ULL << 33) < 1ULL << 34
|
if (!(relocation - from + (1ULL << 33) < 1ULL << 34
|
||||||
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
|
||||||
{
|
break;
|
||||||
|
|
||||||
offset = rel->r_offset;
|
offset = rel->r_offset;
|
||||||
pinsn = bfd_get_32 (input_bfd, contents + offset);
|
pinsn = bfd_get_32 (input_bfd, contents + offset);
|
||||||
pinsn <<= 32;
|
pinsn <<= 32;
|
||||||
pinsn |= bfd_get_32 (input_bfd, contents + offset + 4);
|
pinsn |= bfd_get_32 (input_bfd, contents + offset + 4);
|
||||||
if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
|
if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
|
||||||
== ((1ULL << 58) | (1ULL << 52) | (57ULL << 26) /* pld */))
|
!= ((1ULL << 58) | (1ULL << 52) | (57ULL << 26) /* pld */))
|
||||||
{
|
break;
|
||||||
|
|
||||||
/* Replace with paddi. */
|
/* Replace with paddi. */
|
||||||
pinsn += (2ULL << 56) + (14ULL << 26) - (57ULL << 26);
|
pinsn += (2ULL << 56) + (14ULL << 26) - (57ULL << 26);
|
||||||
r_type = R_PPC64_PCREL34;
|
r_type = R_PPC64_PCREL34;
|
||||||
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
||||||
bfd_put_32 (input_bfd, pinsn >> 32, contents + offset);
|
bfd_put_32 (input_bfd, pinsn >> 32, contents + offset);
|
||||||
bfd_put_32 (input_bfd, pinsn, contents + offset + 4);
|
bfd_put_32 (input_bfd, pinsn, contents + offset + 4);
|
||||||
goto pcrelopt;
|
/* Fall through. */
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_PPC64_PCREL34:
|
case R_PPC64_PCREL34:
|
||||||
if (SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
if (!htab->params->no_pcrel_opt
|
||||||
|
&& rel + 1 < relend
|
||||||
|
&& rel[1].r_offset == rel->r_offset
|
||||||
|
&& rel[1].r_info == ELF64_R_INFO (0, R_PPC64_PCREL_OPT)
|
||||||
|
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
||||||
{
|
{
|
||||||
offset = rel->r_offset;
|
offset = rel->r_offset;
|
||||||
pinsn = bfd_get_32 (input_bfd, contents + offset);
|
pinsn = bfd_get_32 (input_bfd, contents + offset);
|
||||||
@@ -15981,11 +15987,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
|
if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
|
||||||
== ((1ULL << 58) | (2ULL << 56) | (1ULL << 52)
|
== ((1ULL << 58) | (2ULL << 56) | (1ULL << 52)
|
||||||
| (14ULL << 26) /* paddi */))
|
| (14ULL << 26) /* paddi */))
|
||||||
{
|
|
||||||
pcrelopt:
|
|
||||||
if (rel + 1 < relend
|
|
||||||
&& rel[1].r_offset == offset
|
|
||||||
&& rel[1].r_info == ELF64_R_INFO (0, R_PPC64_PCREL_OPT))
|
|
||||||
{
|
{
|
||||||
bfd_vma off2 = rel[1].r_addend;
|
bfd_vma off2 = rel[1].r_addend;
|
||||||
if (off2 == 0)
|
if (off2 == 0)
|
||||||
@@ -16022,7 +16023,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ struct ppc64_elf_params
|
|||||||
/* Whether to use power10 instructions in linkage stubs. */
|
/* Whether to use power10 instructions in linkage stubs. */
|
||||||
int power10_stubs;
|
int power10_stubs;
|
||||||
|
|
||||||
|
/* Whether R_PPC64_PCREL_OPT should be ignored. */
|
||||||
|
int no_pcrel_opt;
|
||||||
|
|
||||||
/* Whether to canonicalize .opd so that there are no overlapping
|
/* Whether to canonicalize .opd so that there are no overlapping
|
||||||
.opd entries. */
|
.opd entries. */
|
||||||
int non_overlapping_opd;
|
int non_overlapping_opd;
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
2020-08-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* emultempl/ppc64elf.em (params): Init new field.
|
||||||
|
(enum ppc64_opt): Add OPTION_NO_PCREL_OPT.
|
||||||
|
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS),
|
||||||
|
(PARSE_AND_LIST_ARGS_CASES): Support --no-pcrel-optimize.
|
||||||
|
|
||||||
2020-08-10 Nick Clifton <nickc@redhat.com>
|
2020-08-10 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR ld/21351
|
PR ld/21351
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ static struct ppc64_elf_params params = { NULL,
|
|||||||
&ppc_layout_sections_again,
|
&ppc_layout_sections_again,
|
||||||
1, -1, -1, 0,
|
1, -1, -1, 0,
|
||||||
${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
|
${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
|
||||||
-1, -1, 0, -1, -1, 0};
|
-1, -1, 0, 0, -1, -1, 0};
|
||||||
|
|
||||||
/* Fake input file for stubs. */
|
/* Fake input file for stubs. */
|
||||||
static lang_input_statement_type *stub_file;
|
static lang_input_statement_type *stub_file;
|
||||||
@@ -686,6 +686,7 @@ enum ppc64_opt
|
|||||||
OPTION_NO_PLT_LOCALENTRY,
|
OPTION_NO_PLT_LOCALENTRY,
|
||||||
OPTION_POWER10_STUBS,
|
OPTION_POWER10_STUBS,
|
||||||
OPTION_NO_POWER10_STUBS,
|
OPTION_NO_POWER10_STUBS,
|
||||||
|
OPTION_NO_PCREL_OPT,
|
||||||
OPTION_STUBSYMS,
|
OPTION_STUBSYMS,
|
||||||
OPTION_NO_STUBSYMS,
|
OPTION_NO_STUBSYMS,
|
||||||
OPTION_SAVRES,
|
OPTION_SAVRES,
|
||||||
@@ -717,6 +718,7 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
|
|||||||
{ "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
|
{ "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
|
||||||
{ "no-plt-localentry", no_argument, NULL, OPTION_NO_PLT_LOCALENTRY },
|
{ "no-plt-localentry", no_argument, NULL, OPTION_NO_PLT_LOCALENTRY },
|
||||||
{ "power10-stubs", optional_argument, NULL, OPTION_POWER10_STUBS },
|
{ "power10-stubs", optional_argument, NULL, OPTION_POWER10_STUBS },
|
||||||
|
{ "no-pcrel-optimize", no_argument, NULL, OPTION_NO_PCREL_OPT },
|
||||||
{ "no-power10-stubs", no_argument, NULL, OPTION_NO_POWER10_STUBS },
|
{ "no-power10-stubs", no_argument, NULL, OPTION_NO_POWER10_STUBS },
|
||||||
{ "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
|
{ "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
|
||||||
{ "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
|
{ "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
|
||||||
@@ -776,6 +778,9 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
|
|||||||
--power10-stubs [=auto] Use Power10 PLT call stubs (default auto)\n"
|
--power10-stubs [=auto] Use Power10 PLT call stubs (default auto)\n"
|
||||||
));
|
));
|
||||||
fprintf (file, _("\
|
fprintf (file, _("\
|
||||||
|
--no-pcrel-optimize Don'\''t perform R_PPC64_PCREL_OPT optimization\n"
|
||||||
|
));
|
||||||
|
fprintf (file, _("\
|
||||||
--no-power10-stubs Don'\''t use Power10 PLT call stubs\n"
|
--no-power10-stubs Don'\''t use Power10 PLT call stubs\n"
|
||||||
));
|
));
|
||||||
fprintf (file, _("\
|
fprintf (file, _("\
|
||||||
@@ -909,6 +914,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
|
|||||||
params.power10_stubs = 0;
|
params.power10_stubs = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPTION_NO_PCREL_OPT:
|
||||||
|
params.no_pcrel_opt = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case OPTION_STUBSYMS:
|
case OPTION_STUBSYMS:
|
||||||
params.emit_stub_syms = 1;
|
params.emit_stub_syms = 1;
|
||||||
break;
|
break;
|
||||||
@@ -985,6 +994,7 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
|
|||||||
params.no_multi_toc = 1;
|
params.no_multi_toc = 1;
|
||||||
no_toc_sort = 1;
|
no_toc_sort = 1;
|
||||||
params.plt_static_chain = 1;
|
params.plt_static_chain = 1;
|
||||||
|
params.no_pcrel_opt = 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user