aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/m68kelf.em
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-05-21 12:01:37 +0000
committerNick Clifton <nickc@redhat.com>2008-05-21 12:01:37 +0000
commit7fb9f789e396b4653bba0ff56d786f5470a870c9 (patch)
treebb01440a6b01700909481064c73ebfa0ee9be648 /ld/emultempl/m68kelf.em
parent90b5b1a5e42372c0fde6186d08235aa4746d9707 (diff)
downloadfsf-binutils-gdb-7fb9f789e396b4653bba0ff56d786f5470a870c9.zip
fsf-binutils-gdb-7fb9f789e396b4653bba0ff56d786f5470a870c9.tar.gz
fsf-binutils-gdb-7fb9f789e396b4653bba0ff56d786f5470a870c9.tar.bz2
Multi-GOT support for m68k.
bfd/ * elf32-m68k.c (struct elf_m68k_link_hash_entry: got_entry_key, glist): New fields. (struct elf_m68k_got_entry_key, struct elf_m68k_got_entry, struct elf_m68k_got, struct elf_m68k_bfd2got_entry, struct elf_m68k_multi_got): New data structures. (struct elf_m68k_link_hash_table: local_gp_p, use_neg_got_offsets_p, allow_multigot_p, multi_got_): New fields. (elf_m68k_multi_got): New macro. (elf_m68k_link_hash_newfunc): Initialize new fields of struct elf_m68k_link_hash_entry. (elf_m68k_link_hash_table_create): Initialize new fields of struct elf_m68k_link_hash_table. (elf_m68k_link_hash_table_free): New static function implementing hook. (elf_m68k_init_got, elf_m68k_clear_got, elf_m68k_create_empty_got): New static functions for struct elf_m68k_got. (elf_m68k_init_got_entry_key, elf_m68k_got_entry_hash, elf_m68k_got_entry_eq): New static functions for struct elf_m68k_got_entry. (ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT, ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT): New macros. (enum elf_m68k_get_entry_howto): New enum. (elf_m68k_get_got_entry, elf_m68k_update_got_entry_type, elf_m68k_remove_got_entry_type): New static functions for struct elf_m68k_got_entry. (elf_m68k_add_entry_to_got): New static function. (elf_m68k_bfd2got_entry_hash, elf_m68k_bfd2got_entry_eq, elf_m68k_bfd2got_entry_del, elf_m68k_get_bfd2got_entry): New static functions for struct elf_m68k_bfd2got_entry. (struct elf_m68k_can_merge_gots_arg, elf_m68k_can_merge_gots_1, elf_m68k_can_merge_gots): New traversal. (struct elf_m68k_merge_gots_arg, elf_m68k_merge_gots_1, elf_m68k_merge_gots): Ditto. (struct elf_m68k_finalize_got_offsets_arg, elf_m68k_finalize_got_offsets_1, elf_m68k_finalize_got_offsets): Ditto. (struct elf_m68k_partition_multi_got_arg, elf_m68k_partition_multi_got_1, elf_m68k_init_symndx2h_1, elf_m68k_partition_multi_got): Ditto. (elf_m68k_find_got_entry_ptr, elf_m68k_remove_got_entry): New static functions. (elf_m68k_copy_indirect_symbol): New static function implementing a hook. (elf_m68k_check_relocs): Update to add entries to multi-GOT. (elf_m68k_gc_sweep_hook): Update to remove entries from multi-GOT. (elf_m68k_always_size_sections): Assign BFDs to GOTs. (elf_m68k_relocate_section): Update to properly handle GOT relocations. (elf_m68k_finish_dynamic_symbol): Update to traverse all GOT entries of a global symbol. (bfd_elf_m68k_set_target_options): New function. (bfd_elf32_bfd_link_hash_table_free): Define hook. (bfd_elf32_bfd_final_link): Change expansion to bfd_elf_final_link to skip generic calculation of GOT offsets. (elf_backend_copy_indirect_symbol): Define hook. * bfd-in.h (bfd_elf_m68k_set_target_options): Declare function. * bfd-in2.h: Regenerate. ld/ * configure.in (--enable-got): New option. Handle it. * configure: Regenerate. * config.in: Regenerate. * emultempl/m68kelf.em: (got_handling_target_default): New shell variable. (GOT_HANDLING_TARGET_DEFAULT): New macro. (GOT_HANDLING_DEFAULT): New macro. Initialize it from configure option if one was given. (got_handling): New static variable. (elf_m68k_create_output_section_statements): New static function implementing hook. (PARSE_AND_LIST_PROLOGUE): Define shell variable. (OPTION_GOT): New macro. (PARSE_AND_LIST_LONGOPTS): Define shell variable. Specify --got option. (got): New linker option. (PARSE_AND_LIST_OPTIONS): Define shell variable. Print help string for --got option. (PARSE_AND_LIST_ARGS_CASES): Define shell variable. Handle --got option. * ld.texinfo: Document --got=<type> option. * gen-doc.texi: Add M68K. * NEWS: Mention the new feature. ld/testsuite/ * ld-m68k/got-12.s: New file. * ld-m68k/got-13.s: New file. * ld-m68k/got-14.s: New file. * ld-m68k/got-15.s: New file. * ld-m68k/got-34.s: New file. * ld-m68k/got-35.s: New file. * ld-m68k/got-single-12-ok.d: New dump test. * ld-m68k/got-single-13-er.d: New dump test. * ld-m68k/got-negative-14-ok.d: New dump test. * ld-m68k/got-negative-15-er.d: New dump test. * ld-m68k/got-negative-12-13-14-34-ok.d: New dump test. * ld-m68k/got-negative-12-13-14-35-er.d: New dump test. * ld-m68k/got-multigot-14-ok.d: New dump test. * ld-m68k/got-multigot-15-er.d: New dump test. * ld-m68k/got-multigot-12-13-14-34-35-ok.d: New dump test. * ld-m68k/xgot-15.s: New source. * ld-m68k/got-xgot-15-ok.d: New test. * ld-m68k/got-xgot-12-13-14-15-34-35-ok.d: New test. * ld-m68k/m68k.exp: Run new tests.
Diffstat (limited to 'ld/emultempl/m68kelf.em')
-rw-r--r--ld/emultempl/m68kelf.em62
1 files changed, 61 insertions, 1 deletions
diff --git a/ld/emultempl/m68kelf.em b/ld/emultempl/m68kelf.em
index d6a1d8a..57a8f1d 100644
--- a/ld/emultempl/m68kelf.em
+++ b/ld/emultempl/m68kelf.em
@@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*-
-# Copyright 2000, 2001, 2003, 2007 Free Software Foundation, Inc.
+# Copyright 2000, 2001, 2003, 2007, 2008 Free Software Foundation, Inc.
# Written by Michael Sokolov <msokolov@ivan.Harhan.ORG>, based on armelf.em
#
# This file is part of the GNU Binutils.
@@ -31,8 +31,28 @@ case ${target} in
;;
esac
+case ${target} in
+ *-linux*)
+# Don't use multi-GOT by default due to glibc linker's assumption
+# that GOT pointer points to GOT[0].
+# got_handling_target_default=GOT_HANDLING_MULTIGOT
+ got_handling_target_default=GOT_HANDLING_SINGLE
+ ;;
+ *)
+ got_handling_target_default=GOT_HANDLING_SINGLE
+ ;;
+esac
+
fragment <<EOF
+#define GOT_HANDLING_SINGLE (0)
+#define GOT_HANDLING_NEGATIVE (1)
+#define GOT_HANDLING_MULTIGOT (2)
+#define GOT_HANDLING_TARGET_DEFAULT ${got_handling_target_default}
+
+/* How to generate GOT. */
+static int got_handling = GOT_HANDLING_DEFAULT;
+
#ifdef SUPPORT_EMBEDDED_RELOCS
static void check_sections (bfd *, asection *, void *);
#endif
@@ -182,9 +202,49 @@ m68k_elf_after_allocation (void)
#endif /* SUPPORT_EMBEDDED_RELOCS */
}
+/* This is a convenient point to tell BFD about target specific flags.
+ After the output has been created, but before inputs are read. */
+
+static void
+elf_m68k_create_output_section_statements (void)
+{
+ bfd_elf_m68k_set_target_options (&link_info, got_handling);
+}
+
EOF
+# Define some shell vars to insert bits of code into the standard elf
+# parse_args and list_options functions.
+#
+PARSE_AND_LIST_PROLOGUE='
+#define OPTION_GOT 301
+'
+
+PARSE_AND_LIST_LONGOPTS='
+ { "got", required_argument, NULL, OPTION_GOT},
+'
+
+PARSE_AND_LIST_OPTIONS='
+ fprintf (file, _(" --got=<type> Specify GOT handling scheme\n"));
+'
+
+PARSE_AND_LIST_ARGS_CASES='
+ case OPTION_GOT:
+ if (strcmp (optarg, "target") == 0)
+ got_handling = GOT_HANDLING_TARGET_DEFAULT;
+ else if (strcmp (optarg, "single") == 0)
+ got_handling = 0;
+ else if (strcmp (optarg, "negative") == 0)
+ got_handling = 1;
+ else if (strcmp (optarg, "multigot") == 0)
+ got_handling = 2;
+ else
+ einfo (_("Unrecognized --got argument '\''%s'\''.\n"), optarg);
+ break;
+'
+
# We have our own after_open and after_allocation functions, but they call
# the standard routines, so give them a different name.
LDEMUL_AFTER_OPEN=m68k_elf_after_open
LDEMUL_AFTER_ALLOCATION=m68k_elf_after_allocation
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=elf_m68k_create_output_section_statements