]>
Commit | Line | Data |
---|---|---|
252b5132 RH |
1 | # This shell script emits a C file. -*- C -*- |
2 | # It does some substitutions. | |
3 | cat >e${EMULATION_NAME}.c <<EOF | |
4 | /* An emulation for HP PA-RISC ELF linkers. | |
5 | Copyright (C) 1991, 93, 94, 95, 1997 Free Software Foundation, Inc. | |
6 | Written by Steve Chamberlain [email protected] | |
7 | ||
8 | This file is part of GLD, the Gnu Linker. | |
9 | ||
10 | This program is free software; you can redistribute it and/or modify | |
11 | it under the terms of the GNU General Public License as published by | |
12 | the Free Software Foundation; either version 2 of the License, or | |
13 | (at your option) any later version. | |
14 | ||
15 | This program is distributed in the hope that it will be useful, | |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | GNU General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU General Public License | |
21 | along with this program; if not, write to the Free Software | |
22 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
23 | ||
24 | #include "bfd.h" | |
25 | #include "sysdep.h" | |
26 | #include "bfdlink.h" | |
27 | ||
28 | #include "ld.h" | |
29 | #include "ldemul.h" | |
30 | #include "ldfile.h" | |
31 | #include "ldexp.h" | |
32 | #include "ldlang.h" | |
33 | #include "ldmisc.h" | |
34 | #include "ldmain.h" | |
35 | #include "ldctor.h" | |
36 | ||
37 | /* Section in which we build stubs. */ | |
38 | static asection *stub_sec; | |
39 | static lang_input_statement_type *stub_file; | |
40 | ||
41 | ||
42 | /* FIXME. This doesn't belong here. */ | |
43 | extern lang_statement_list_type file_chain; | |
44 | ||
45 | /* Perform some emulation specific initialization. For PA ELF we set | |
46 | up the local label prefix and the output architecture. */ | |
47 | ||
48 | static void | |
49 | hppaelf_before_parse () | |
50 | { | |
51 | ldfile_output_architecture = bfd_arch_hppa; | |
52 | } | |
53 | ||
54 | /* Set the output architecture and machine. */ | |
55 | ||
56 | static void | |
57 | hppaelf_set_output_arch() | |
58 | { | |
59 | unsigned long machine = 0; | |
60 | ||
61 | bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine); | |
62 | } | |
63 | ||
64 | /* This is called before the input files are opened. We create a new | |
65 | fake input file to hold the stub section. */ | |
66 | ||
67 | static void | |
68 | hppaelf_create_output_section_statements () | |
69 | { | |
70 | stub_file = lang_add_input_file ("linker stubs", | |
71 | lang_input_file_is_fake_enum, | |
72 | NULL); | |
73 | stub_file->the_bfd = bfd_create ("linker stubs", output_bfd); | |
74 | if (stub_file->the_bfd == NULL | |
75 | || ! bfd_set_arch_mach (stub_file->the_bfd, | |
76 | bfd_get_arch (output_bfd), | |
77 | bfd_get_mach (output_bfd))) | |
78 | { | |
79 | einfo ("%X%P: can not create BFD %E\n"); | |
80 | return; | |
81 | } | |
82 | ||
83 | stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text"); | |
84 | /* Don't set SEC_RELOC until we actually have relocations in this | |
85 | section. */ | |
86 | if (stub_sec == NULL | |
87 | || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec, | |
88 | (SEC_HAS_CONTENTS | |
89 | | SEC_ALLOC | |
90 | | SEC_LOAD | |
91 | | SEC_CODE | |
92 | | SEC_IN_MEMORY))) | |
93 | { | |
94 | einfo ("%X%P: can not create stub section: %E\n"); | |
95 | return; | |
96 | } | |
97 | ||
98 | ldlang_add_file (stub_file); | |
99 | } | |
100 | ||
101 | /* Walk all the lang statements splicing out any padding statements from | |
102 | the list. */ | |
103 | ||
104 | static void | |
105 | hppaelf_delete_padding_statements (s, prev) | |
106 | lang_statement_union_type *s; | |
107 | lang_statement_union_type **prev; | |
108 | { | |
109 | lang_statement_union_type *sprev = NULL; | |
110 | for (; s != NULL; s = s->next) | |
111 | { | |
112 | switch (s->header.type) | |
113 | { | |
114 | ||
115 | /* We want recursively walk these sections. */ | |
116 | case lang_constructors_statement_enum: | |
117 | hppaelf_delete_padding_statements (constructor_list.head, | |
118 | &constructor_list.head); | |
119 | break; | |
120 | ||
121 | case lang_output_section_statement_enum: | |
122 | hppaelf_delete_padding_statements (s->output_section_statement. | |
123 | children.head, | |
124 | &s->output_section_statement. | |
125 | children.head); | |
126 | break; | |
127 | ||
128 | /* Huh? What is a lang_wild_statement? */ | |
129 | case lang_wild_statement_enum: | |
130 | hppaelf_delete_padding_statements (s->wild_statement. | |
131 | children.head, | |
132 | &s->wild_statement. | |
133 | children.head); | |
134 | break; | |
135 | ||
136 | /* Here's what we are really looking for. Splice these out of | |
137 | the list. */ | |
138 | case lang_padding_statement_enum: | |
139 | if (sprev) | |
140 | sprev->header.next = s->header.next; | |
141 | else | |
142 | **prev = *s; | |
143 | break; | |
144 | ||
145 | /* We don't care about these cases. */ | |
146 | case lang_data_statement_enum: | |
147 | case lang_object_symbols_statement_enum: | |
148 | case lang_output_statement_enum: | |
149 | case lang_target_statement_enum: | |
150 | case lang_input_section_enum: | |
151 | case lang_input_statement_enum: | |
152 | case lang_assignment_statement_enum: | |
153 | case lang_address_statement_enum: | |
154 | break; | |
155 | ||
156 | default: | |
157 | abort (); | |
158 | break; | |
159 | } | |
160 | sprev = s; | |
161 | } | |
162 | } | |
163 | ||
164 | /* Final emulation specific call. For the PA we use this opportunity | |
165 | to build linker stubs. */ | |
166 | ||
167 | static void | |
168 | hppaelf_finish () | |
169 | { | |
170 | /* Call into the BFD backend to do the real work. */ | |
171 | if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info) | |
172 | == false) | |
173 | { | |
174 | einfo ("%X%P: can not size stub section: %E\n"); | |
175 | return; | |
176 | } | |
177 | ||
178 | /* If the size of the stub section is nonzero, then we need | |
179 | to resize the sections, recompute the assignments, and finally | |
180 | build the stubs. */ | |
181 | if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0) | |
182 | { | |
183 | /* Delete all the padding statements, they're no longer valid. */ | |
184 | hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head); | |
185 | ||
186 | /* Resize the sections. */ | |
187 | lang_size_sections (stat_ptr->head, abs_output_section, | |
188 | &stat_ptr->head, 0, (bfd_vma) 0, false); | |
189 | ||
190 | /* Redo special stuff. */ | |
191 | ldemul_after_allocation (); | |
192 | ||
193 | /* Do the assignments again. */ | |
194 | lang_do_assignments (stat_ptr->head, | |
195 | abs_output_section, | |
196 | (fill_type) 0, (bfd_vma) 0); | |
197 | ||
198 | /* Now build the linker stubs. */ | |
199 | if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false) | |
200 | { | |
201 | einfo ("%X%P: can not build stubs: %E\n"); | |
202 | return; | |
203 | } | |
204 | } | |
205 | } | |
206 | ||
207 | /* The script itself gets inserted here. */ | |
208 | ||
209 | static char * | |
210 | hppaelf_get_script(isfile) | |
211 | int *isfile; | |
212 | EOF | |
213 | ||
214 | if test -n "$COMPILE_IN" | |
215 | then | |
216 | # Scripts compiled in. | |
217 | ||
218 | # sed commands to quote an ld script as a C string. | |
219 | sc='s/["\\]/\\&/g | |
220 | s/$/\\n\\/ | |
221 | 1s/^/"/ | |
222 | $s/$/n"/ | |
223 | ' | |
224 | ||
225 | cat >>e${EMULATION_NAME}.c <<EOF | |
226 | { | |
227 | *isfile = 0; | |
228 | ||
229 | if (link_info.relocateable == true && config.build_constructors == true) | |
230 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; | |
231 | else if (link_info.relocateable == true) | |
232 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; | |
233 | else if (!config.text_read_only) | |
234 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; | |
235 | else if (!config.magic_demand_paged) | |
236 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; | |
237 | else | |
238 | return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; | |
239 | } | |
240 | EOF | |
241 | ||
242 | else | |
243 | # Scripts read from the filesystem. | |
244 | ||
245 | cat >>e${EMULATION_NAME}.c <<EOF | |
246 | { | |
247 | *isfile = 1; | |
248 | ||
249 | if (link_info.relocateable == true && config.build_constructors == true) | |
250 | return "ldscripts/${EMULATION_NAME}.xu"; | |
251 | else if (link_info.relocateable == true) | |
252 | return "ldscripts/${EMULATION_NAME}.xr"; | |
253 | else if (!config.text_read_only) | |
254 | return "ldscripts/${EMULATION_NAME}.xbn"; | |
255 | else if (!config.magic_demand_paged) | |
256 | return "ldscripts/${EMULATION_NAME}.xn"; | |
257 | else | |
258 | return "ldscripts/${EMULATION_NAME}.x"; | |
259 | } | |
260 | EOF | |
261 | ||
262 | fi | |
263 | ||
264 | cat >>e${EMULATION_NAME}.c <<EOF | |
265 | ||
266 | struct ld_emulation_xfer_struct ld_hppaelf_emulation = | |
267 | { | |
268 | hppaelf_before_parse, | |
269 | syslib_default, | |
270 | hll_default, | |
271 | after_parse_default, | |
272 | after_open_default, | |
273 | after_allocation_default, | |
274 | hppaelf_set_output_arch, | |
275 | ldemul_default_target, | |
276 | before_allocation_default, | |
277 | hppaelf_get_script, | |
278 | "hppaelf", | |
279 | "elf32-hppa", | |
280 | hppaelf_finish, | |
281 | hppaelf_create_output_section_statements, | |
282 | }; | |
283 | EOF |