diff options
author | Alan Modra <amodra@gmail.com> | 2014-01-30 08:26:02 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-02-03 20:24:20 +1030 |
commit | 5446cbdf82892a800ed7eef563a795e75223ec52 (patch) | |
tree | 5abcadcfcfd715515d8c13b7905a03626004ef2c /bfd/elf32-ppc.h | |
parent | 8effdc96dc110ef0bcd256bdc026d56d373c2e11 (diff) | |
download | gdb-5446cbdf82892a800ed7eef563a795e75223ec52.zip gdb-5446cbdf82892a800ed7eef563a795e75223ec52.tar.gz gdb-5446cbdf82892a800ed7eef563a795e75223ec52.tar.bz2 |
ppc476 icache bug workaround
This implements a work-around for an icache bug on 476 that can cause
execution of stale instructions when control falls through from one
page to the next. The idea is to prevent such fall-through by
replacing the last instruction on a page with a branch to a patch
area containing the instruction, then branch to the next page.
The patch also fixes a number of bugs in the existing support for long
branch trampolines.
bfd/
* elf32-ppc.c (struct ppc_elf_link_hash_table): Add params.
Delete emit_stub_syms, no_tls_get_addr_opt. Update all uses.
(ppc_elf_link_params): New function.
(ppc_elf_create_glink): Align .glink to 64 bytes for ppc476
workaround.
(ppc_elf_select_plt_layout): Remove plt_style and emit_stub_syms
parameters. Use htab->params instead.
(ppc_elf_tls_setup): Remove no_tls_get_addr_opt parameter.
(ppc_elf_size_dynamic_sections): Align __glink_PLTresolve to
64 bytes for ppc476 workaround.
(struct ppc_elf_relax_info): New.
(ppc_elf_relax_section): Exclude linker created sections and
those too small to hold one instruction. Don't add another
branch around trampolines on later relax passes. Don't
generate trampolines for undefined symbols when !relocatable,
nor for plugin symbols. Allocate space for ppc476 workaround
patch area. Free fixups on error return path.
(ppc_elf_relocate_section): Handle ppc476 workaround patching.
* elf32-ppc.h (struct ppc_elf_params): New.
(ppc_elf_select_plt_layout, ppc_elf_tls_setup): Update prototype.
(ppc_elf_link_params): Declare.
* section.c (SEC_INFO_TYPE_TARGET): Define.
* bfd-in2.h: Regenerate.
ld/
* emultempl/ppc32elf.em (no_tls_get_addr_opt, emit_stub_syms)
plt_style): Delete. Adjust all refs to instead use..
(params): ..this. New variable.
(ppc_after_open_output): New function. Tweak params and pass to
ppc_elf_link_params.
(ppc_after_open): Adjust ppc_elf_select_plt_layout call.
(ppc_before_allocation): Adjust ppc_elf_tls_setup call. Enable
relaxation for ppc476 workaround.
(PARSE_AND_LIST_*): Add --{no-,}ppc476-workaround support.
(LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS): Define.
Diffstat (limited to 'bfd/elf32-ppc.h')
-rw-r--r-- | bfd/elf32-ppc.h | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/bfd/elf32-ppc.h b/bfd/elf32-ppc.h index 0bf973c..0909245 100644 --- a/bfd/elf32-ppc.h +++ b/bfd/elf32-ppc.h @@ -26,9 +26,29 @@ enum ppc_elf_plt_type PLT_VXWORKS }; -int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, - enum ppc_elf_plt_type, int); -asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *, int); +/* Various options passed from the linker to bfd backend. */ +struct ppc_elf_params +{ + /* Chooses the type of .plt. */ + enum ppc_elf_plt_type plt_style; + + /* Whether to emit symbols for stubs. */ + int emit_stub_syms; + + /* Whether to emit special stub for __tls_get_addr calls. */ + int no_tls_get_addr_opt; + + /* Insert trampolines for branches that won't reach their destination. */ + int branch_trampolines; + + /* Avoid execution falling into new page. */ + int ppc476_workaround; + int pagesize; +}; + +void ppc_elf_link_params (struct bfd_link_info *, struct ppc_elf_params *); +int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *); +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 *); extern bfd_boolean ppc_elf_modify_segment_map (bfd *, |