bfd/
* elf64-ppc.c (struct ppc_link_hash_table): Add no_multi_toc and multi_toc_needed. (has_toc_reloc, makes_toc_func_call, call_check_in_progress): Define. (ppc64_elf_check_relocs): Update references to has_gp_reloc. (ppc64_elf_setup_section_lists): Add no_multi_toc parm, set htab bit. (ppc64_elf_next_toc_section): Heed no_multi_toc. (ppc64_elf_reinit_toc): Set multi_toc_needed. (toc_adjusting_stub_needed): Rewrite. (ppc64_elf_next_input_section): Use multi_toc_needed to shortcut toc tests. Adjust for toc_adjusting_stub_needed changes. (ppc64_elf_size_stubs): Update references to has_gp_reloc. * elf64-ppc.h (ppc64_elf_setup_section_lists): Update prototype. * section.c: Expand comment on backend bits. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. ld/ * emultempl/ppc64elf.em (no_multi_toc): New var. (gld${EMULATION_NAME}_finish): Pass to ppc64_elf_setup_section_lists. (OPTION_NO_MULTI_TOC): Define. (PARSE_AND_LIST_LONGOPTS): Add --no-multi-toc support. (PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise.
This commit is contained in:
parent
f03d65b413
commit
4c52953f84
8 changed files with 267 additions and 63 deletions
|
@ -1,3 +1,21 @@
|
|||
2005-01-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (struct ppc_link_hash_table): Add no_multi_toc and
|
||||
multi_toc_needed.
|
||||
(has_toc_reloc, makes_toc_func_call, call_check_in_progress): Define.
|
||||
(ppc64_elf_check_relocs): Update references to has_gp_reloc.
|
||||
(ppc64_elf_setup_section_lists): Add no_multi_toc parm, set htab bit.
|
||||
(ppc64_elf_next_toc_section): Heed no_multi_toc.
|
||||
(ppc64_elf_reinit_toc): Set multi_toc_needed.
|
||||
(toc_adjusting_stub_needed): Rewrite.
|
||||
(ppc64_elf_next_input_section): Use multi_toc_needed to shortcut
|
||||
toc tests. Adjust for toc_adjusting_stub_needed changes.
|
||||
(ppc64_elf_size_stubs): Update references to has_gp_reloc.
|
||||
* elf64-ppc.h (ppc64_elf_setup_section_lists): Update prototype.
|
||||
* section.c: Expand comment on backend bits.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* libbfd.h: Regenerate.
|
||||
|
||||
2005-01-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (ppc64_elf_size_stubs): When determining need for
|
||||
|
@ -36,7 +54,7 @@
|
|||
Add 'base' argument for constructing register sections. Reformat.
|
||||
(elfcore_grok_nto_note): Call elfcore_grok_nto_regs for both
|
||||
gp and fp regs. Reformat.
|
||||
|
||||
|
||||
2004-12-22 Klaus Rudolph <lts-rudolph@gmx.de>
|
||||
|
||||
* reloc.c: Add new relocs R_AVR_LDI, R_AVR_6, R_AVR_6_ADIW.
|
||||
|
|
|
@ -1269,7 +1269,8 @@ typedef struct bfd_section
|
|||
/* Nonzero if this section uses RELA relocations, rather than REL. */
|
||||
unsigned int use_rela_p:1;
|
||||
|
||||
/* Bits used by various backends. */
|
||||
/* Bits used by various backends. The generic code doesn't touch
|
||||
these fields. */
|
||||
|
||||
/* Nonzero if this section has TLS related relocations. */
|
||||
unsigned int has_tls_reloc:1;
|
||||
|
|
270
bfd/elf64-ppc.c
270
bfd/elf64-ppc.c
|
@ -3301,6 +3301,10 @@ struct ppc_link_hash_table
|
|||
/* Set if we should emit symbols for stubs. */
|
||||
unsigned int emit_stub_syms:1;
|
||||
|
||||
/* Support for multiple toc sections. */
|
||||
unsigned int no_multi_toc:1;
|
||||
unsigned int multi_toc_needed:1;
|
||||
|
||||
/* Set on error. */
|
||||
unsigned int stub_error:1;
|
||||
|
||||
|
@ -3318,6 +3322,12 @@ struct ppc_link_hash_table
|
|||
struct sym_sec_cache sym_sec;
|
||||
};
|
||||
|
||||
/* Rename some of the generic section flags to better document how they
|
||||
are used here. */
|
||||
#define has_toc_reloc has_gp_reloc
|
||||
#define makes_toc_func_call need_finalize_relax
|
||||
#define call_check_in_progress reloc_done
|
||||
|
||||
/* Get the ppc64 ELF linker hash table from a link_info structure. */
|
||||
|
||||
#define ppc_hash_table(p) \
|
||||
|
@ -4285,7 +4295,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
case R_PPC64_GOT16_LO:
|
||||
case R_PPC64_GOT16_LO_DS:
|
||||
/* This symbol requires a global offset table entry. */
|
||||
sec->has_gp_reloc = 1;
|
||||
sec->has_toc_reloc = 1;
|
||||
if (ppc64_elf_tdata (abfd)->got == NULL
|
||||
&& !create_got_section (abfd, info))
|
||||
return FALSE;
|
||||
|
@ -4375,7 +4385,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
case R_PPC64_TOC16_HA:
|
||||
case R_PPC64_TOC16_DS:
|
||||
case R_PPC64_TOC16_LO_DS:
|
||||
sec->has_gp_reloc = 1;
|
||||
sec->has_toc_reloc = 1;
|
||||
break;
|
||||
|
||||
/* This relocation describes the C++ object vtable hierarchy.
|
||||
|
@ -8131,7 +8141,9 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||
0 when no stubs will be needed, and 1 on success. */
|
||||
|
||||
int
|
||||
ppc64_elf_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
|
||||
ppc64_elf_setup_section_lists (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
int no_multi_toc)
|
||||
{
|
||||
bfd *input_bfd;
|
||||
int top_id, top_index, id;
|
||||
|
@ -8140,6 +8152,8 @@ ppc64_elf_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
|
|||
bfd_size_type amt;
|
||||
struct ppc_link_hash_table *htab = ppc_hash_table (info);
|
||||
|
||||
htab->no_multi_toc = no_multi_toc;
|
||||
|
||||
if (htab->brlt == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -8199,25 +8213,30 @@ void
|
|||
ppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
|
||||
{
|
||||
struct ppc_link_hash_table *htab = ppc_hash_table (info);
|
||||
bfd_vma addr = isec->output_offset + isec->output_section->vma;
|
||||
bfd_vma off = addr - htab->toc_curr;
|
||||
|
||||
if (off + isec->size > 0x10000)
|
||||
htab->toc_curr = addr;
|
||||
if (!htab->no_multi_toc)
|
||||
{
|
||||
bfd_vma addr = isec->output_offset + isec->output_section->vma;
|
||||
bfd_vma off = addr - htab->toc_curr;
|
||||
|
||||
elf_gp (isec->owner) = (htab->toc_curr
|
||||
- elf_gp (isec->output_section->owner)
|
||||
+ TOC_BASE_OFF);
|
||||
if (off + isec->size > 0x10000)
|
||||
htab->toc_curr = addr;
|
||||
|
||||
elf_gp (isec->owner) = (htab->toc_curr
|
||||
- elf_gp (isec->output_section->owner)
|
||||
+ TOC_BASE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called after the last call to the above function. */
|
||||
|
||||
void
|
||||
ppc64_elf_reinit_toc (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info *info)
|
||||
ppc64_elf_reinit_toc (bfd *output_bfd, struct bfd_link_info *info)
|
||||
{
|
||||
struct ppc_link_hash_table *htab = ppc_hash_table (info);
|
||||
|
||||
htab->multi_toc_needed = htab->toc_curr != elf_gp (output_bfd);
|
||||
|
||||
/* toc_curr tracks the TOC offset used for code sections below in
|
||||
ppc64_elf_next_input_section. Start off at 0x8000. */
|
||||
htab->toc_curr = TOC_BASE_OFF;
|
||||
|
@ -8226,15 +8245,18 @@ ppc64_elf_reinit_toc (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||
/* No toc references were found in ISEC. If the code in ISEC makes no
|
||||
calls, then there's no need to use toc adjusting stubs when branching
|
||||
into ISEC. Actually, indirect calls from ISEC are OK as they will
|
||||
load r2. */
|
||||
load r2. Returns -1 on error, 0 for no stub needed, 1 for stub
|
||||
needed, and 2 if a cyclical call-graph was found but no other reason
|
||||
for a stub was detected. If called from the top level, a return of
|
||||
2 means the same as a return of 0. */
|
||||
|
||||
static int
|
||||
toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
|
||||
{
|
||||
bfd_byte *contents;
|
||||
bfd_size_type i;
|
||||
Elf_Internal_Rela *relstart, *rel;
|
||||
Elf_Internal_Sym *local_syms;
|
||||
int ret;
|
||||
int branch_ok;
|
||||
struct ppc_link_hash_table *htab;
|
||||
|
||||
/* We know none of our code bearing sections will need toc stubs. */
|
||||
if ((isec->flags & SEC_LINKER_CREATED) != 0)
|
||||
|
@ -8243,44 +8265,175 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
|
|||
if (isec->size == 0)
|
||||
return 0;
|
||||
|
||||
if (isec->output_section == NULL)
|
||||
return 0;
|
||||
|
||||
/* Hack for linux kernel. .fixup contains branches, but only back to
|
||||
the function that hit an exception. */
|
||||
branch_ok = strcmp (isec->name, ".fixup") == 0;
|
||||
if (strcmp (isec->name, ".fixup") == 0)
|
||||
return 0;
|
||||
|
||||
contents = elf_section_data (isec)->this_hdr.contents;
|
||||
if (contents == NULL)
|
||||
{
|
||||
if (!bfd_malloc_and_get_section (isec->owner, isec, &contents))
|
||||
{
|
||||
if (contents != NULL)
|
||||
free (contents);
|
||||
return -1;
|
||||
}
|
||||
if (info->keep_memory)
|
||||
elf_section_data (isec)->this_hdr.contents = contents;
|
||||
}
|
||||
if (isec->reloc_count == 0)
|
||||
return 0;
|
||||
|
||||
/* Code scan, because we don't necessarily have relocs on calls to
|
||||
static functions. */
|
||||
relstart = _bfd_elf_link_read_relocs (isec->owner, isec, NULL, NULL,
|
||||
info->keep_memory);
|
||||
if (relstart == NULL)
|
||||
return -1;
|
||||
|
||||
/* Look for branches to outside of this section. */
|
||||
local_syms = NULL;
|
||||
ret = 0;
|
||||
for (i = 0; i < isec->size; i += 4)
|
||||
htab = ppc_hash_table (info);
|
||||
for (rel = relstart; rel < relstart + isec->reloc_count; ++rel)
|
||||
{
|
||||
unsigned long insn = bfd_get_32 (isec->owner, contents + i);
|
||||
/* Is this a branch? */
|
||||
if ((insn & (0x3f << 26)) == (18 << 26)
|
||||
/* If branch and link, it's a function call. */
|
||||
&& ((insn & 1) != 0
|
||||
/* Sibling calls use a plain branch. I don't know a way
|
||||
of deciding whether a branch is really a sibling call. */
|
||||
|| !branch_ok))
|
||||
enum elf_ppc64_reloc_type r_type;
|
||||
unsigned long r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
asection *sym_sec;
|
||||
long *opd_adjust;
|
||||
bfd_vma sym_value;
|
||||
bfd_vma dest;
|
||||
|
||||
r_type = ELF64_R_TYPE (rel->r_info);
|
||||
if (r_type != R_PPC64_REL24
|
||||
&& r_type != R_PPC64_REL14
|
||||
&& r_type != R_PPC64_REL14_BRTAKEN
|
||||
&& r_type != R_PPC64_REL14_BRNTAKEN)
|
||||
continue;
|
||||
|
||||
r_symndx = ELF64_R_SYM (rel->r_info);
|
||||
if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms, r_symndx,
|
||||
isec->owner))
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ignore branches to undefined syms. */
|
||||
if (sym_sec == NULL)
|
||||
continue;
|
||||
|
||||
/* Calls to dynamic lib functions go through a plt call stub
|
||||
that uses r2. Assume branches to other sections not included
|
||||
in the link need stubs too, to cover -R and absolute syms. */
|
||||
if (sym_sec->output_section == NULL)
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (h == NULL)
|
||||
sym_value = sym->st_value;
|
||||
else
|
||||
{
|
||||
if (h->root.type != bfd_link_hash_defined
|
||||
&& h->root.type != bfd_link_hash_defweak)
|
||||
abort ();
|
||||
sym_value = h->root.u.def.value;
|
||||
}
|
||||
sym_value += rel->r_addend;
|
||||
|
||||
/* If this branch reloc uses an opd sym, find the code section. */
|
||||
opd_adjust = get_opd_info (sym_sec);
|
||||
if (opd_adjust != NULL)
|
||||
{
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
long adjust;
|
||||
|
||||
adjust = opd_adjust[sym->st_value / 8];
|
||||
if (adjust == -1)
|
||||
/* Assume deleted functions won't ever be called. */
|
||||
continue;
|
||||
sym_value += adjust;
|
||||
}
|
||||
|
||||
dest = opd_entry_value (sym_sec, sym_value, &sym_sec, NULL);
|
||||
if (dest == (bfd_vma) -1)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
dest = (sym_value
|
||||
+ sym_sec->output_offset
|
||||
+ sym_sec->output_section->vma);
|
||||
|
||||
/* Ignore branch to self. */
|
||||
if (sym_sec == isec)
|
||||
continue;
|
||||
|
||||
/* If the called function uses the toc, we need a stub. */
|
||||
if (sym_sec->has_toc_reloc
|
||||
|| sym_sec->makes_toc_func_call)
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assume any branch that needs a long branch stub might in fact
|
||||
need a plt_branch stub. A plt_branch stub uses r2. */
|
||||
else if (dest - (isec->output_offset
|
||||
+ isec->output_section->vma
|
||||
+ rel->r_offset) + (1 << 25) >= (2 << 25))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If calling back to a section in the process of being tested, we
|
||||
can't say for sure that no toc adjusting stubs are needed, so
|
||||
don't return zero. */
|
||||
else if (sym_sec->call_check_in_progress)
|
||||
ret = 2;
|
||||
|
||||
/* Branches to another section that itself doesn't have any TOC
|
||||
references are OK. Recursively call ourselves to check. */
|
||||
else if (sym_sec->id <= htab->top_id
|
||||
&& htab->stub_group[sym_sec->id].toc_off == 0)
|
||||
{
|
||||
int recur;
|
||||
|
||||
/* Mark current section as indeterminate, so that other
|
||||
sections that call back to current won't be marked as
|
||||
known. */
|
||||
isec->call_check_in_progress = 1;
|
||||
recur = toc_adjusting_stub_needed (info, sym_sec);
|
||||
isec->call_check_in_progress = 0;
|
||||
|
||||
if (recur < 0)
|
||||
{
|
||||
/* An error. Exit. */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
else if (recur <= 1)
|
||||
{
|
||||
/* Known result. Mark as checked and set section flag. */
|
||||
htab->stub_group[sym_sec->id].toc_off = 1;
|
||||
if (recur != 0)
|
||||
{
|
||||
sym_sec->makes_toc_func_call = 1;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown result. Continue checking. */
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_section_data (isec)->this_hdr.contents != contents)
|
||||
free (contents);
|
||||
if (local_syms != NULL
|
||||
&& (elf_tdata (isec->owner)->symtab_hdr.contents
|
||||
!= (unsigned char *) local_syms))
|
||||
free (local_syms);
|
||||
if (elf_section_data (isec)->relocs != relstart)
|
||||
free (relstart);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -8293,7 +8446,6 @@ bfd_boolean
|
|||
ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
|
||||
{
|
||||
struct ppc_link_hash_table *htab = ppc_hash_table (info);
|
||||
int ret;
|
||||
|
||||
if ((isec->output_section->flags & SEC_CODE) != 0
|
||||
&& isec->output_section->index <= htab->top_index)
|
||||
|
@ -8307,19 +8459,26 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
|
|||
*list = isec;
|
||||
}
|
||||
|
||||
/* If a code section has a function that uses the TOC then we need
|
||||
to use the right TOC (obviously). Also, make sure that .opd gets
|
||||
the correct TOC value for R_PPC64_TOC relocs that don't have or
|
||||
can't find their function symbol (shouldn't ever happen now). */
|
||||
if (isec->has_gp_reloc || (isec->flags & SEC_CODE) == 0)
|
||||
if (htab->multi_toc_needed)
|
||||
{
|
||||
if (elf_gp (isec->owner) != 0)
|
||||
htab->toc_curr = elf_gp (isec->owner);
|
||||
/* If a code section has a function that uses the TOC then we need
|
||||
to use the right TOC (obviously). Also, make sure that .opd gets
|
||||
the correct TOC value for R_PPC64_TOC relocs that don't have or
|
||||
can't find their function symbol (shouldn't ever happen now). */
|
||||
if (isec->has_toc_reloc || (isec->flags & SEC_CODE) == 0)
|
||||
{
|
||||
if (elf_gp (isec->owner) != 0)
|
||||
htab->toc_curr = elf_gp (isec->owner);
|
||||
}
|
||||
else if (htab->stub_group[isec->id].toc_off == 0)
|
||||
{
|
||||
int ret = toc_adjusting_stub_needed (info, isec);
|
||||
if (ret < 0)
|
||||
return FALSE;
|
||||
else
|
||||
isec->makes_toc_func_call = ret & 1;
|
||||
}
|
||||
}
|
||||
else if ((ret = toc_adjusting_stub_needed (info, isec)) < 0)
|
||||
return FALSE;
|
||||
else
|
||||
isec->has_gp_reloc = ret;
|
||||
|
||||
/* Functions that don't use the TOC can belong in any TOC group.
|
||||
Use the last TOC base. This happens to make _init and _fini
|
||||
|
@ -8643,7 +8802,8 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
&& code_sec->output_section != NULL
|
||||
&& (htab->stub_group[code_sec->id].toc_off
|
||||
!= htab->stub_group[section->id].toc_off)
|
||||
&& code_sec->has_gp_reloc)
|
||||
&& (code_sec->has_toc_reloc
|
||||
|| code_sec->makes_toc_func_call))
|
||||
stub_type = ppc_stub_long_branch_r2off;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ bfd_boolean ppc64_elf_edit_toc
|
|||
bfd_vma ppc64_elf_toc
|
||||
(bfd *);
|
||||
int ppc64_elf_setup_section_lists
|
||||
(bfd *, struct bfd_link_info *);
|
||||
(bfd *, struct bfd_link_info *, int);
|
||||
void ppc64_elf_next_toc_section
|
||||
(struct bfd_link_info *, asection *);
|
||||
void ppc64_elf_reinit_toc
|
||||
|
|
|
@ -1362,6 +1362,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||
"BFD_RELOC_AVR_HI8_LDI_PM_NEG",
|
||||
"BFD_RELOC_AVR_HH8_LDI_PM_NEG",
|
||||
"BFD_RELOC_AVR_CALL",
|
||||
"BFD_RELOC_AVR_LDI",
|
||||
"BFD_RELOC_AVR_6",
|
||||
"BFD_RELOC_AVR_6_ADIW",
|
||||
"BFD_RELOC_390_12",
|
||||
"BFD_RELOC_390_GOT12",
|
||||
"BFD_RELOC_390_PLT32",
|
||||
|
|
|
@ -373,7 +373,8 @@ CODE_FRAGMENT
|
|||
. {* Nonzero if this section uses RELA relocations, rather than REL. *}
|
||||
. unsigned int use_rela_p:1;
|
||||
.
|
||||
. {* Bits used by various backends. *}
|
||||
. {* Bits used by various backends. The generic code doesn't touch
|
||||
. these fields. *}
|
||||
.
|
||||
. {* Nonzero if this section has TLS related relocations. *}
|
||||
. unsigned int has_tls_reloc:1;
|
||||
|
|
12
ld/ChangeLog
12
ld/ChangeLog
|
@ -1,8 +1,16 @@
|
|||
2005-01-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* emultempl/ppc64elf.em (no_multi_toc): New var.
|
||||
(gld${EMULATION_NAME}_finish): Pass to ppc64_elf_setup_section_lists.
|
||||
(OPTION_NO_MULTI_TOC): Define.
|
||||
(PARSE_AND_LIST_LONGOPTS): Add --no-multi-toc support.
|
||||
(PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise.
|
||||
|
||||
2005-01-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/614
|
||||
* ldmisc.c (vfinfo): Alter output to conform to the GNU Coding
|
||||
Standard's specification for parsable error messages.
|
||||
Standard's specification for parsable error messages.
|
||||
|
||||
2005-01-04 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
|
@ -89,7 +97,7 @@
|
|||
|
||||
* ld/ldlex.l: Allow ORIGIN and LENGTH in EXPRESSION.
|
||||
* ld/ldgram.y: Add ORIGIN and LENGTH expressions.
|
||||
* ld/ldexp.c (fold_name): Implement LENGTH() and ORIGIN() functions
|
||||
* ld/ldexp.c (fold_name): Implement LENGTH() and ORIGIN() functions
|
||||
which return the length and origin of a memory.
|
||||
* ld/ld.texinfo: Document LENGTH() and ORIGIN() functions.
|
||||
* NEWS: Mention support for ORIGIN and LENGTH operators.
|
||||
|
|
|
@ -52,6 +52,9 @@ static int no_opd_opt = 0;
|
|||
/* Whether to run toc optimization. */
|
||||
static int no_toc_opt = 0;
|
||||
|
||||
/* Whether to allow multiple toc sections. */
|
||||
static int no_multi_toc = 0;
|
||||
|
||||
/* Whether to emit symbols for stubs. */
|
||||
static int emit_stub_syms = 0;
|
||||
|
||||
|
@ -337,7 +340,8 @@ gld${EMULATION_NAME}_finish (void)
|
|||
stubs. */
|
||||
if (stub_file != NULL && !link_info.relocatable)
|
||||
{
|
||||
int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
|
||||
int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info,
|
||||
no_multi_toc);
|
||||
if (ret != 0)
|
||||
{
|
||||
if (ret < 0)
|
||||
|
@ -484,7 +488,8 @@ PARSE_AND_LIST_PROLOGUE='
|
|||
#define OPTION_NO_TLS_OPT (OPTION_NO_DOTSYMS + 1)
|
||||
#define OPTION_NO_OPD_OPT (OPTION_NO_TLS_OPT + 1)
|
||||
#define OPTION_NO_TOC_OPT (OPTION_NO_OPD_OPT + 1)
|
||||
#define OPTION_NON_OVERLAPPING_OPD (OPTION_NO_TOC_OPT + 1)
|
||||
#define OPTION_NO_MULTI_TOC (OPTION_NO_TOC_OPT + 1)
|
||||
#define OPTION_NON_OVERLAPPING_OPD (OPTION_NO_MULTI_TOC + 1)
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_LONGOPTS='
|
||||
|
@ -495,6 +500,7 @@ PARSE_AND_LIST_LONGOPTS='
|
|||
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
|
||||
{ "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
|
||||
{ "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
|
||||
{ "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
|
||||
{ "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
|
||||
'
|
||||
|
||||
|
@ -530,6 +536,9 @@ PARSE_AND_LIST_OPTIONS='
|
|||
--no-toc-optimize Don'\''t optimize the TOC section.\n"
|
||||
));
|
||||
fprintf (file, _("\
|
||||
--no-multi-toc Disallow automatic multiple toc sections.\n"
|
||||
));
|
||||
fprintf (file, _("\
|
||||
--non-overlapping-opd Canonicalize .opd, so that there are no overlapping\n\
|
||||
.opd entries.\n"
|
||||
));
|
||||
|
@ -569,6 +578,10 @@ PARSE_AND_LIST_ARGS_CASES='
|
|||
no_toc_opt = 1;
|
||||
break;
|
||||
|
||||
case OPTION_NO_MULTI_TOC:
|
||||
no_multi_toc = 1;
|
||||
break;
|
||||
|
||||
case OPTION_NON_OVERLAPPING_OPD:
|
||||
non_overlapping_opd = 1;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue