URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [emultempl/] [hppaelf.em] - Rev 145
Compare with Previous | Blame | View Log
# This shell script emits a C file. -*- C -*-# Copyright 1991, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003, 2004,# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.## This file is part of the GNU Binutils.## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 3 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,# MA 02110-1301, USA.## This file is sourced from elf32.em, and defines extra hppa-elf# specific routines.#fragment <<EOF#include "ldctor.h"#include "elf32-hppa.h"/* Fake input file for stubs. */static lang_input_statement_type *stub_file;/* Type of import/export stubs to build. For a single sub-space model,we can build smaller import stubs and there is no need for exportstubs. */static int multi_subspace = 0;/* Whether we need to call hppa_layout_sections_again. */static int need_laying_out = 0;/* Maximum size of a group of input sections that can be handled byone stub section. A value of +/-1 indicates the bfd back-endshould use a suitable default size. */static bfd_signed_vma group_size = 1;/* Stops the linker merging .text sections on a relocatable link,and adds millicode library to the list of input files. */static voidhppaelf_after_parse (void){if (link_info.relocatable)lang_add_unique (".text");/* Enable this once we split millicode stuff from libgcc:lang_add_input_file ("milli",lang_input_file_is_l_enum,NULL);*/after_parse_default ();}/* This is called before the input files are opened. We create a newfake input file to hold the stub sections. */static voidhppaelf_create_output_section_statements (void){if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour&& (elf_object_id (link_info.output_bfd) == HPPA32_ELF_DATA|| elf_object_id (link_info.output_bfd) == HPPA64_ELF_DATA)))return;stub_file = lang_add_input_file ("linker stubs",lang_input_file_is_fake_enum,NULL);stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);if (stub_file->the_bfd == NULL|| ! bfd_set_arch_mach (stub_file->the_bfd,bfd_get_arch (link_info.output_bfd),bfd_get_mach (link_info.output_bfd))){einfo ("%X%P: can not create BFD %E\n");return;}stub_file->the_bfd->flags |= BFD_LINKER_CREATED;ldlang_add_file (stub_file);}struct hook_stub_info{lang_statement_list_type add;asection *input_section;};/* Traverse the linker tree to find the spot where the stub goes. */static bfd_booleanhook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp){lang_statement_union_type *l;bfd_boolean ret;for (; (l = *lp) != NULL; lp = &l->header.next){switch (l->header.type){case lang_constructors_statement_enum:ret = hook_in_stub (info, &constructor_list.head);if (ret)return ret;break;case lang_output_section_statement_enum:ret = hook_in_stub (info,&l->output_section_statement.children.head);if (ret)return ret;break;case lang_wild_statement_enum:ret = hook_in_stub (info, &l->wild_statement.children.head);if (ret)return ret;break;case lang_group_statement_enum:ret = hook_in_stub (info, &l->group_statement.children.head);if (ret)return ret;break;case lang_input_section_enum:if (l->input_section.section == info->input_section){/* We've found our section. Insert the stub immediatelybefore its associated input section. */*lp = info->add.head;*(info->add.tail) = l;return TRUE;}break;case lang_data_statement_enum:case lang_reloc_statement_enum:case lang_object_symbols_statement_enum:case lang_output_statement_enum:case lang_target_statement_enum:case lang_input_statement_enum:case lang_assignment_statement_enum:case lang_padding_statement_enum:case lang_address_statement_enum:case lang_fill_statement_enum:break;default:FAIL ();break;}}return FALSE;}/* Call-back for elf32_hppa_size_stubs. *//* Create a new stub section, and arrange for it to be linkedimmediately before INPUT_SECTION. */static asection *hppaelf_add_stub_section (const char *stub_sec_name, asection *input_section){asection *stub_sec;flagword flags;asection *output_section;const char *secname;lang_output_section_statement_type *os;struct hook_stub_info info;flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE| SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,stub_sec_name, flags);if (stub_sec == NULL)goto err_ret;output_section = input_section->output_section;secname = bfd_get_section_name (output_section->owner, output_section);os = lang_output_section_find (secname);info.input_section = input_section;lang_list_init (&info.add);lang_add_section (&info.add, stub_sec, os);if (info.add.head == NULL)goto err_ret;if (hook_in_stub (&info, &os->children.head))return stub_sec;err_ret:einfo ("%X%P: can not make stub section: %E\n");return NULL;}/* Another call-back for elf32_hppa_size_stubs. */static voidhppaelf_layout_sections_again (void){/* If we have changed sizes of the stub sections, then we needto recalculate all the section offsets. This may mean we need toadd even more stubs. */gld${EMULATION_NAME}_map_segments (TRUE);need_laying_out = -1;}static voidbuild_section_lists (lang_statement_union_type *statement){if (statement->header.type == lang_input_section_enum){asection *i = statement->input_section.section;if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag&& (i->flags & SEC_EXCLUDE) == 0&& i->output_section != NULL&& i->output_section->owner == link_info.output_bfd){elf32_hppa_next_input_section (&link_info, i);}}}/* For the PA we use this opportunity to size and build linker stubs. */static voidgld${EMULATION_NAME}_after_allocation (void){/* bfd_elf_discard_info just plays with data and debugging sections,ie. doesn't affect code size, so we can delay resizing thesections. It's likely we'll resize everything in the process ofadding stubs. */if (bfd_elf_discard_info (link_info.output_bfd, &link_info))need_laying_out = 1;/* If generating a relocatable output file, then we don'thave to examine the relocs. */if (stub_file != NULL && !link_info.relocatable){int ret = elf32_hppa_setup_section_lists (link_info.output_bfd,&link_info);if (ret != 0){if (ret < 0){einfo ("%X%P: can not size stub section: %E\n");return;}lang_for_each_statement (build_section_lists);/* Call into the BFD backend to do the real work. */if (! elf32_hppa_size_stubs (link_info.output_bfd,stub_file->the_bfd,&link_info,multi_subspace,group_size,&hppaelf_add_stub_section,&hppaelf_layout_sections_again)){einfo ("%X%P: can not size stub section: %E\n");return;}}}if (need_laying_out != -1)gld${EMULATION_NAME}_map_segments (need_laying_out);if (! link_info.relocatable){/* Set the global data pointer. */if (! elf32_hppa_set_gp (link_info.output_bfd, &link_info)){einfo ("%X%P: can not set gp\n");return;}/* Now build the linker stubs. */if (stub_file != NULL && stub_file->the_bfd->sections != NULL){if (! elf32_hppa_build_stubs (&link_info))einfo ("%X%P: can not build stubs: %E\n");}}}/* Avoid processing the fake stub_file in vercheck, stat_needed andcheck_needed routines. */static void (*real_func) (lang_input_statement_type *);static void hppa_for_each_input_file_wrapper (lang_input_statement_type *l){if (l != stub_file)(*real_func) (l);}static voidhppa_lang_for_each_input_file (void (*func) (lang_input_statement_type *)){real_func = func;lang_for_each_input_file (&hppa_for_each_input_file_wrapper);}#define lang_for_each_input_file hppa_lang_for_each_input_fileEOF# 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_MULTI_SUBSPACE 301#define OPTION_STUBGROUP_SIZE (OPTION_MULTI_SUBSPACE + 1)'PARSE_AND_LIST_LONGOPTS='{ "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE },{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },'PARSE_AND_LIST_OPTIONS='fprintf (file, _("\--multi-subspace Generate import and export stubs to support\n\multiple sub-space shared libraries\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\value locates all stubs before their branches\n\(with a group size of -N), while a positive\n\value allows two groups of input sections, one\n\before, and one after each stub section.\n\Values of +/-1 indicate the linker should\n\choose suitable defaults.\n"));'PARSE_AND_LIST_ARGS_CASES='case OPTION_MULTI_SUBSPACE:multi_subspace = 1;break;case OPTION_STUBGROUP_SIZE:{const char *end;group_size = bfd_scan_vma (optarg, &end, 0);if (*end)einfo (_("%P%F: invalid number `%s'\''\n"), optarg);}break;'# Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation#LDEMUL_AFTER_PARSE=hppaelf_after_parseLDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocationLDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements
