| 1 | # This shell script emits a C file. -*- C -*- |
| 2 | # Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
| 3 | # Free Software Foundation, Inc. |
| 4 | # |
| 5 | # This file is part of the GNU Binutils. |
| 6 | # |
| 7 | # This program is free software; you can redistribute it and/or modify |
| 8 | # it under the terms of the GNU General Public License as published by |
| 9 | # the Free Software Foundation; either version 3 of the License, or |
| 10 | # (at your option) any later version. |
| 11 | # |
| 12 | # This program is distributed in the hope that it will be useful, |
| 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | # GNU General Public License for more details. |
| 16 | # |
| 17 | # You should have received a copy of the GNU General Public License |
| 18 | # along with this program; if not, write to the Free Software |
| 19 | # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| 20 | # MA 02110-1301, USA. |
| 21 | # |
| 22 | |
| 23 | # This file is sourced from generic.em. |
| 24 | |
| 25 | fragment <<EOF |
| 26 | /* Need to have this macro defined before mmix-elfnmmo, which uses the |
| 27 | name for the before_allocation function, defined in ldemul.c (for |
| 28 | the mmo "emulation") or in elf32.em (for the elf64mmix |
| 29 | "emulation"). */ |
| 30 | #define gldmmo_before_allocation before_allocation_default |
| 31 | |
| 32 | /* We include this header *not* because we expect to handle ELF here |
| 33 | but because we re-use the map_segments function in elf-generic.em, |
| 34 | a file which is rightly somewhat ELF-centric. But this is only to |
| 35 | get a weird testcase right; ld-mmix/bpo-22, forcing ELF to be |
| 36 | output from the mmo emulation: -m mmo --oformat elf64-mmix! */ |
| 37 | #include "elf-bfd.h" |
| 38 | |
| 39 | static void gld${EMULATION_NAME}_after_allocation (void); |
| 40 | EOF |
| 41 | |
| 42 | source_em ${srcdir}/emultempl/elf-generic.em |
| 43 | source_em ${srcdir}/emultempl/mmix-elfnmmo.em |
| 44 | |
| 45 | fragment <<EOF |
| 46 | |
| 47 | /* Place an orphan section. We use this to put random SEC_CODE or |
| 48 | SEC_READONLY sections right after MMO_TEXT_SECTION_NAME. Much borrowed |
| 49 | from elf32.em. */ |
| 50 | |
| 51 | static lang_output_section_statement_type * |
| 52 | mmo_place_orphan (asection *s, |
| 53 | const char *secname, |
| 54 | int constraint ATTRIBUTE_UNUSED) |
| 55 | { |
| 56 | static struct orphan_save hold_text = |
| 57 | { |
| 58 | MMO_TEXT_SECTION_NAME, |
| 59 | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE, |
| 60 | 0, 0, 0, 0 |
| 61 | }; |
| 62 | struct orphan_save *place; |
| 63 | lang_output_section_statement_type *after; |
| 64 | lang_output_section_statement_type *os; |
| 65 | |
| 66 | /* We have nothing to say for anything other than a final link. */ |
| 67 | if (link_info.relocatable |
| 68 | || (s->flags & (SEC_EXCLUDE | SEC_LOAD)) != SEC_LOAD) |
| 69 | return NULL; |
| 70 | |
| 71 | /* Only care for sections we're going to load. */ |
| 72 | os = lang_output_section_find (secname); |
| 73 | |
| 74 | /* We have an output section by this name. Place the section inside it |
| 75 | (regardless of whether the linker script lists it as input). */ |
| 76 | if (os != NULL) |
| 77 | { |
| 78 | lang_add_section (&os->children, s, os); |
| 79 | return os; |
| 80 | } |
| 81 | |
| 82 | /* If this section does not have .text-type section flags or there's no |
| 83 | MMO_TEXT_SECTION_NAME, we don't have anything to say. */ |
| 84 | if ((s->flags & (SEC_CODE | SEC_READONLY)) == 0) |
| 85 | return NULL; |
| 86 | |
| 87 | if (hold_text.os == NULL) |
| 88 | hold_text.os = lang_output_section_find (hold_text.name); |
| 89 | |
| 90 | place = &hold_text; |
| 91 | if (hold_text.os != NULL) |
| 92 | after = hold_text.os; |
| 93 | else |
| 94 | after = &lang_output_section_statement.head->output_section_statement; |
| 95 | |
| 96 | /* If there's an output section by this name, we'll use it, regardless |
| 97 | of section flags, in contrast to what's done in elf32.em. */ |
| 98 | os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL); |
| 99 | |
| 100 | /* We need an output section for .text as a root, so if there was none |
| 101 | (might happen with a peculiar linker script such as in "map |
| 102 | addresses", map-address.exp), we grab the output section created |
| 103 | above. */ |
| 104 | if (hold_text.os == NULL) |
| 105 | hold_text.os = os; |
| 106 | |
| 107 | return os; |
| 108 | } |
| 109 | |
| 110 | /* Remove the spurious settings of SEC_RELOC that make it to the output at |
| 111 | link time. We are as confused as elflink.h:elf_bfd_final_link, and |
| 112 | paper over the bug similarly. */ |
| 113 | |
| 114 | static void |
| 115 | mmo_wipe_sec_reloc_flag (bfd *abfd, asection *sec, void *ptr ATTRIBUTE_UNUSED) |
| 116 | { |
| 117 | bfd_set_section_flags (abfd, sec, |
| 118 | bfd_get_section_flags (abfd, sec) & ~SEC_RELOC); |
| 119 | } |
| 120 | |
| 121 | /* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */ |
| 122 | |
| 123 | static void |
| 124 | gld${EMULATION_NAME}_after_allocation (void) |
| 125 | { |
| 126 | bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL); |
| 127 | gld${EMULATION_NAME}_map_segments (FALSE); |
| 128 | } |
| 129 | \f |
| 130 | /* To get on-demand global register allocation right, we need to parse the |
| 131 | relocs, like what happens when linking to ELF. It needs to be done |
| 132 | before all input sections are supposed to be present. When linking to |
| 133 | ELF, it's done when reading symbols. When linking to mmo, we do it |
| 134 | when all input files are seen, which is equivalent. */ |
| 135 | |
| 136 | static void |
| 137 | mmo_after_open (void) |
| 138 | { |
| 139 | /* When there's a mismatch between the output format and the emulation |
| 140 | (using weird combinations like "-m mmo --oformat elf64-mmix" for |
| 141 | example), we'd count relocs twice because they'd also be counted |
| 142 | along the usual route for ELF-only linking, which would lead to an |
| 143 | internal accounting error. */ |
| 144 | if (bfd_get_flavour (link_info.output_bfd) != bfd_target_elf_flavour) |
| 145 | { |
| 146 | LANG_FOR_EACH_INPUT_STATEMENT (is) |
| 147 | { |
| 148 | if (bfd_get_flavour (is->the_bfd) == bfd_target_elf_flavour |
| 149 | && !_bfd_mmix_check_all_relocs (is->the_bfd, &link_info)) |
| 150 | einfo ("%X%P: Internal problems scanning %B after opening it", |
| 151 | is->the_bfd); |
| 152 | } |
| 153 | } |
| 154 | } |
| 155 | EOF |
| 156 | |
| 157 | LDEMUL_PLACE_ORPHAN=mmo_place_orphan |
| 158 | LDEMUL_AFTER_OPEN=mmo_after_open |