Commit | Line | Data |
---|---|---|
a6152e39 DM |
1 | # This shell script emits a C file. -*- C -*- |
2 | # It does some substitutions. | |
8ddef552 DM |
3 | cat >em_${EMULATION_NAME}.c <<EOF |
4 | /* An emulation for HP PA-RISC OSF/1 linkers. | |
5 | Copyright (C) 1991 Free Software Foundation, Inc. | |
6 | Written by Steve Chamberlain steve@cygnus.com | |
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., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
23 | ||
24 | #include "bfd.h" | |
25 | #include "sysdep.h" | |
26 | ||
27 | ||
28 | #include "ld.h" | |
29 | #include "config.h" | |
30 | #include "ldemul.h" | |
31 | #include "ldfile.h" | |
9d9d72fc | 32 | #include "ldlang.h" |
8ddef552 DM |
33 | #include "ldmisc.h" |
34 | ||
35 | extern boolean lang_float_flag; | |
36 | ||
37 | ||
38 | extern enum bfd_architecture ldfile_output_architecture; | |
39 | extern unsigned long ldfile_output_machine; | |
40 | extern char *ldfile_output_machine_name; | |
41 | ||
42 | extern bfd *output_bfd; | |
43 | ||
8ddef552 DM |
44 | static void hppaosf_before_parse() |
45 | { | |
8ddef552 DM |
46 | ldfile_output_architecture = bfd_arch_hppa; |
47 | } | |
8ddef552 | 48 | |
9d9d72fc JL |
49 | static lang_input_statement_type *stub_file = 0; |
50 | ||
51 | static lang_input_section_type *stub_input_section = NULL; | |
52 | ||
53 | extern lang_statement_list_type *stat_ptr; | |
54 | /* List of statements needed to handle constructors */ | |
55 | extern lang_statement_list_type constructor_list; | |
56 | ||
57 | static void | |
58 | hppaosf_search_for_padding_statements(s,prev) | |
59 | lang_statement_union_type *s; | |
60 | lang_statement_union_type **prev; | |
61 | { | |
62 | lang_statement_union_type *sprev = NULL; | |
63 | for (; s != (lang_statement_union_type *) NULL; s = s->next) | |
64 | { | |
65 | switch (s->header.type) | |
66 | { | |
67 | case lang_constructors_statement_enum: | |
68 | hppaosf_search_for_padding_statements (constructor_list.head,&constructor_list.head); | |
69 | break; | |
70 | case lang_output_section_statement_enum: | |
71 | hppaosf_search_for_padding_statements | |
72 | (s->output_section_statement.children.head,&s->output_section_statement.children.head); | |
73 | break; | |
74 | case lang_wild_statement_enum: | |
75 | hppaosf_search_for_padding_statements | |
76 | (s->wild_statement.children.head,&s->wild_statement.children.head); | |
77 | break; | |
78 | case lang_data_statement_enum: | |
79 | case lang_object_symbols_statement_enum: | |
80 | case lang_output_statement_enum: | |
81 | case lang_target_statement_enum: | |
82 | case lang_input_section_enum: | |
83 | case lang_input_statement_enum: | |
84 | case lang_assignment_statement_enum: | |
85 | case lang_address_statement_enum: | |
86 | break; | |
87 | case lang_padding_statement_enum: | |
88 | if ( sprev ) | |
89 | { | |
90 | sprev->header.next = s->header.next; | |
91 | } | |
92 | else | |
93 | { | |
94 | **prev = *s; | |
95 | } | |
96 | break; | |
97 | default: | |
98 | FAIL (); | |
99 | break; | |
100 | } | |
101 | sprev = s; | |
102 | } | |
103 | } | |
104 | ||
105 | static void | |
106 | hppaosf_finish() | |
107 | { | |
108 | extern asymbol *hppa_look_for_stubs_in_section(); | |
109 | extern ld_config_type config; | |
110 | ||
111 | if (config.relocateable_output == false) | |
112 | { | |
113 | /* check for needed stubs */ | |
114 | LANG_FOR_EACH_INPUT_SECTION | |
115 | (statement, abfd, section, | |
116 | ( | |
117 | { | |
118 | int new_sym_cnt = 0; | |
119 | int i,j; | |
120 | asymbol *syms = hppa_look_for_stubs_in_section (stub_file->the_bfd, | |
121 | abfd, | |
122 | output_bfd, | |
123 | section, | |
124 | statement->asymbols, | |
125 | &new_sym_cnt); | |
126 | ||
127 | if ( (new_sym_cnt > 0) && syms ) | |
128 | { | |
129 | struct symbol_cache_entry **old_asymbols = stub_file->asymbols; | |
130 | ||
131 | stub_file->asymbols = ldmalloc((stub_file->symbol_count + new_sym_cnt) * sizeof(asymbol *)); | |
132 | ||
133 | for ( j = 0; j < stub_file->symbol_count; j++ ) | |
134 | stub_file->asymbols[j] = old_asymbols[j]; | |
135 | ||
136 | for ( j = 0, i = stub_file->symbol_count; j < new_sym_cnt; j++, i++ ) | |
137 | stub_file->asymbols[i] = &syms[j]; | |
138 | ||
139 | stub_file->symbol_count += new_sym_cnt; | |
140 | /* Now, attach the contents of the new linker stub(s) */ | |
141 | /* to the linker stub input section. */ | |
142 | ||
143 | ||
144 | } | |
145 | } | |
146 | ) | |
147 | ) | |
148 | /* Add a statement to get the linker stubs included in the output */ | |
149 | lang_add_wild(".hppa_linker_stubs",NULL); | |
150 | ||
151 | /* If we've added stubs,remove the padding_statements because */ | |
152 | /* they are no longer valid */ | |
153 | hppaosf_search_for_padding_statements(stat_ptr->head,&(stat_ptr->head)); | |
154 | } | |
155 | } | |
156 | ||
157 | static void | |
158 | hppaosf_create_output_section_statements() | |
159 | { | |
160 | asection *stub_sec; | |
161 | asection *output_text_sec = bfd_make_section_old_way(output_bfd,".text"); | |
162 | lang_input_section_type *new_input_sec; | |
163 | ||
164 | stub_file = lang_add_input_file ("linker stubs", | |
165 | lang_input_file_is_fake_enum, | |
166 | (char *) NULL); | |
167 | stub_file->the_bfd = bfd_create ("linker stubs", output_bfd); | |
168 | stub_file->symbol_count = 0; | |
169 | stub_file->the_bfd->sections = 0; | |
170 | ||
171 | stub_sec = bfd_make_section_old_way(stub_file->the_bfd,".hppa_linker_stubs"); | |
172 | stub_sec->output_section = output_text_sec; | |
173 | bfd_set_section_flags(stub_file->the_bfd, stub_sec, SEC_HAS_CONTENTS | SEC_ALLOC | SEC_CODE | SEC_RELOC ); | |
174 | ||
175 | /* The user data of a bfd points to the input statement attached */ | |
176 | stub_file->the_bfd->usrdata = (void *)stub_file; | |
177 | stub_file->common_section = | |
178 | bfd_make_section(stub_file->the_bfd,"COMMON"); | |
179 | ||
180 | new_input_sec = (lang_input_section_type *)stat_alloc(sizeof(lang_input_section_type)); | |
181 | if ( new_input_sec ) | |
182 | { | |
183 | lang_output_section_statement_type *text_output_sec; | |
184 | lang_statement_union_type *stmt; | |
185 | lang_wild_statement_type *stub_statement; | |
186 | new_input_sec->section = stub_sec; | |
187 | new_input_sec->ifile = stub_file; | |
188 | new_input_sec->header.type = lang_input_section_enum; | |
189 | new_input_sec->header.next = NULL; | |
190 | ||
191 | stub_input_section = new_input_sec; | |
192 | ||
193 | /* Find the output_section_statement for .text, */ | |
194 | /* then find the wild_statement for .hppa_linker_stubs */ | |
195 | ||
196 | text_output_sec = lang_output_section_find(".text"); | |
197 | ||
198 | stmt = text_output_sec->children.head; | |
199 | ||
200 | while (stmt && stmt->header.type != lang_wild_statement_enum) | |
201 | { | |
202 | stmt = stmt->header.next; | |
203 | } | |
204 | ||
205 | if ( stmt ) | |
206 | { | |
207 | lang_wild_statement_type *wstmt = (lang_wild_statement_type *)stmt; | |
208 | lang_list_init(&wstmt->children); | |
209 | lang_statement_append(&wstmt->children, | |
210 | (lang_statement_union_type *)new_input_sec, | |
211 | &new_input_sec->header.next); | |
212 | } | |
213 | } | |
214 | } | |
215 | ||
8ddef552 DM |
216 | static void |
217 | hppaosf_set_output_arch() | |
218 | { | |
219 | /* Set the output architecture and machine if possible */ | |
220 | unsigned long machine = 0; | |
221 | bfd_set_arch_mach(output_bfd, ldfile_output_architecture, machine); | |
222 | } | |
223 | ||
a6152e39 DM |
224 | static char * |
225 | hppaosf_get_script(isfile) | |
226 | int *isfile; | |
227 | EOF | |
8ddef552 | 228 | |
d59e5a47 | 229 | if test -n "$COMPILE_IN" |
a6152e39 DM |
230 | then |
231 | # Scripts compiled in. | |
232 | ||
233 | # sed commands to quote an ld script as a C string. | |
234 | sc='s/["\\]/\\&/g | |
235 | s/$/\\n\\/ | |
236 | 1s/^/"{/ | |
237 | $s/$/n}"/ | |
238 | ' | |
239 | ||
240 | cat >>em_${EMULATION_NAME}.c <<EOF | |
241 | { | |
242 | extern ld_config_type config; | |
243 | ||
244 | *isfile = 0; | |
245 | ||
246 | if (config.relocateable_output == true && config.build_constructors == true) | |
247 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; | |
248 | else if (config.relocateable_output == true) | |
249 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; | |
250 | else if (!config.text_read_only) | |
251 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; | |
252 | else if (!config.magic_demand_paged) | |
253 | return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; | |
254 | else | |
255 | return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; | |
256 | } | |
257 | EOF | |
8ddef552 | 258 | |
a6152e39 DM |
259 | else |
260 | # Scripts read from the filesystem. | |
261 | ||
262 | cat >>em_${EMULATION_NAME}.c <<EOF | |
263 | { | |
264 | extern ld_config_type config; | |
265 | ||
266 | *isfile = 1; | |
267 | ||
268 | if (config.relocateable_output == true && config.build_constructors == true) | |
269 | return "ldscripts/${EMULATION_NAME}.xu"; | |
270 | else if (config.relocateable_output == true) | |
271 | return "ldscripts/${EMULATION_NAME}.xr"; | |
272 | else if (!config.text_read_only) | |
273 | return "ldscripts/${EMULATION_NAME}.xbn"; | |
274 | else if (!config.magic_demand_paged) | |
275 | return "ldscripts/${EMULATION_NAME}.xn"; | |
276 | else | |
277 | return "ldscripts/${EMULATION_NAME}.x"; | |
278 | } | |
279 | EOF | |
8ddef552 | 280 | |
a6152e39 | 281 | fi |
8ddef552 | 282 | |
a6152e39 | 283 | cat >>em_${EMULATION_NAME}.c <<EOF |
8ddef552 DM |
284 | |
285 | struct ld_emulation_xfer_struct ld_hppaosf_emulation = | |
286 | { | |
287 | hppaosf_before_parse, | |
288 | syslib_default, | |
289 | hll_default, | |
290 | after_parse_default, | |
291 | after_allocation_default, | |
292 | hppaosf_set_output_arch, | |
293 | ldemul_default_target, | |
294 | before_allocation_default, | |
295 | hppaosf_get_script, | |
296 | "hppaosf", | |
9d9d72fc JL |
297 | "elf32-hppa", |
298 | hppaosf_finish, | |
299 | hppaosf_create_output_section_statements | |
8ddef552 DM |
300 | }; |
301 | EOF |