source: trunk/src/binutils/ld/emultempl/i386aoutemx.em@ 99

Last change on this file since 99 was 99, checked in by bird, 23 years ago

abort() macro clash. Missing prototypes. Wrong function table initialization.

  • Property cvs2svn:cvs-rev set to 1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 14.5 KB
Line 
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3# Derived from generic.em and partialy from emx's ld.c
4cat >e${EMULATION_NAME}.c <<EOF
5/* This file is is generated by a shell script. DO NOT EDIT! */
6
7/* emulate the original gld for the given ${EMULATION_NAME}
8 Copyright (C) 1991, 1993 Free Software Foundation, Inc.
9 Written by Steve Chamberlain [email protected]
10
11This file is part of GLD, the Gnu Linker.
12
13This program is free software; you can redistribute it and/or modify
14it under the terms of the GNU General Public License as published by
15the Free Software Foundation; either version 2 of the License, or
16(at your option) any later version.
17
18This program is distributed in the hope that it will be useful,
19but WITHOUT ANY WARRANTY; without even the implied warranty of
20MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with this program; if not, write to the Free Software
25Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26
27#define TARGET_IS_${EMULATION_NAME}
28
29#include "bfd.h"
30#include "sysdep.h"
31#include "libiberty.h"
32#include "getopt.h"
33#include "obstack.h"
34#include "bfdlink.h"
35
36#include "ld.h"
37#include "ldmain.h"
38#include "ldemul.h"
39#include "ldfile.h"
40#include "ldmisc.h"
41#include "ldexp.h"
42#include "ldlang.h"
43#include "ldctor.h"
44#include "ldgram.h"
45
46static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
47static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
48
49static void
50gld${EMULATION_NAME}_before_parse()
51{
52 ldfile_set_output_arch ("`echo ${ARCH}`");
53 output_filename = "a.out";
54}
55
56static char *
57gld${EMULATION_NAME}_get_script(isfile)
58 int *isfile;
59EOF
60
61if test -n "$COMPILE_IN"
62then
63# Scripts compiled in.
64
65# sed commands to quote an ld script as a C string.
66# bird: stringify.sed is in current directory.
67sc="-f stringify.sed"
68
69#cat >>e${EMULATION_NAME}.c <<EOF
70#{
71# *isfile = 0;
72#
73# if (link_info.relocateable == true && config.build_constructors == true)
74# return
75#EOF
76#sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
77#echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
78#sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
79#echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
80#sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
81#echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
82#sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
83#echo ' ; else return' >> e${EMULATION_NAME}.c
84#sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
85#echo '; }' >> e${EMULATION_NAME}.c
86
87cat >>e${EMULATION_NAME}.c <<EOF
88{
89 *isfile = 0;
90
91EOF
92echo ' if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
93sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
94echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
95sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
96echo ' ; else return' >> e${EMULATION_NAME}.c
97sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
98echo '; }' >> e${EMULATION_NAME}.c
99
100else
101# Scripts read from the filesystem.
102
103cat >>e${EMULATION_NAME}.c <<EOF
104{
105 *isfile = 1;
106
107 if (link_info.relocateable == true && config.build_constructors == true)
108 return "ldscripts/${EMULATION_NAME}.xu";
109 else if (link_info.relocateable == true)
110 return "ldscripts/${EMULATION_NAME}.xr";
111 else if (!config.text_read_only)
112 return "ldscripts/${EMULATION_NAME}.xbn";
113 else if (!config.magic_demand_paged)
114 return "ldscripts/${EMULATION_NAME}.xn";
115 else
116 return "ldscripts/${EMULATION_NAME}.x";
117}
118EOF
119
120fi
121
122cat >>e${EMULATION_NAME}.c <<EOF
123
124extern char *program_name;
125
126/* Report a fatal error.
127 STRING is a printf format string and ARG is one arg for it. */
128
129void
130fatal (string, arg1, arg2)
131 char *string, *arg1, *arg2;
132{
133 fprintf (stderr, "%s: ", program_name);
134 fprintf (stderr, string, arg1, arg2);
135 fprintf (stderr, "\n");
136 xexit (1);
137}
138
139/* Parse the string ARG using scanf format FORMAT, and return the result.
140 If it does not parse, report fatal error
141 generating the error message using format string ERROR and ARG as arg. */
142
143int
144parse (arg, format, error)
145 char *arg, *format;
146 int error;
147{
148 int x;
149 if (1 != sscanf (arg, format, &x))
150 fatal (error, arg);
151 return x;
152}
153
154#define OPT_ZEXE 9990
155#define OPT_ZSTACK 9991
156#define OPT_ZMAP 9992
157#define OPT_ZNODEMANGLE 9993
158#define OPT_ZDEMANGLEPROTO 9994
159#define OPT_ZEMX32 9995
160#define OPT_ZRSX32 9996
161#define OPT_ZWIN32 9997
162
163static struct option longopts[] =
164{
165 {"Zexe", 0, 0, OPT_ZEXE}, /* Create .exe file, touch 'output file' */
166 {"Zstack", 1, 0, OPT_ZSTACK}, /* Set stack size */
167 {"Zmap", 2, 0, OPT_ZMAP}, /* Create .map file */
168 {"Zno-demangle", 0, 0, OPT_ZNODEMANGLE}, /* Don't demangle symbols */
169 {"Zdemangle-proto", 0, 0, OPT_ZDEMANGLEPROTO}, /* Demangle symbols complete */
170 {"Zemx32", 0, 0, OPT_ZEMX32}, /* Create Win32/DOS emx base */
171 {"Zrsx32", 0, 0, OPT_ZRSX32}, /* Create Win32/DOS win32 base */
172 {"Zwin32", 0, 0, OPT_ZWIN32}, /* Create GUI, CUI Win32 */
173 {0, 0, 0, 0}
174};
175
176#include <io.h>
177#include <fcntl.h>
178#include <sys/types.h>
179#include <sys/stat.h>
180/* bird: clash with abort macro in ld should really include this earlier
181 * Quick fix is to undefine the abort macro.
182 */
183#undef abort
184#include <process.h>
185#define abort() ld_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
186/* bird: include headers for alloca and utime too please */
187#include <alloca.h>
188#include <sys/utime.h>
189
190static const char *exe_filename;
191static const char *def_filename = NULL;
192static const char *res_filename = NULL;
193static const char *map_filename = NULL;
194static const char *touch_filename = NULL;
195static int reloc_flag = 0;
196static int dll_flag = 0;
197static int exe_flag = 0;
198static int map_flag = 0;
199static int stack_size = 0;
200static int emxbind_strip = 0;
201enum exe_bind_type
202{
203 EMX_DEFAULT, RSXNT_WIN32, RSXNT_RSX, RSXNT_EMX
204} rsxnt_linked = EMX_DEFAULT;
205
206int gld_${EMULATION_NAME}_parse_args (argc, argv)
207 int argc;
208 char **argv;
209{
210 int longind;
211 int optc;
212 int prevoptind = optind;
213 int prevopterr = opterr;
214
215 opterr = 0;
216 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
217 opterr = prevopterr;
218
219 switch (optc)
220 {
221 default:
222 optind = prevoptind;
223 return 0;
224 case OPT_ZEXE:
225 exe_flag = 1;
226 break;
227 case OPT_ZSTACK:
228 stack_size = parse (optarg, "%i", "invalid argument '%s' to -Zstack");
229 break;
230 case OPT_ZMAP:
231 map_flag = 1;
232 map_filename = optarg;
233 break;
234 case OPT_ZNODEMANGLE:
235 fatal ("-Znodemangle not implemented yet");
236 break;
237 case OPT_ZDEMANGLEPROTO:
238 fatal ("-Zdemangle-proto not implemented yet");
239 break;
240 case OPT_ZEMX32:
241 rsxnt_linked = RSXNT_EMX;
242 break;
243 case OPT_ZRSX32:
244 rsxnt_linked = RSXNT_RSX;
245 break;
246 case OPT_ZWIN32:
247 rsxnt_linked = RSXNT_WIN32;
248 break;
249 }
250 return 1;
251}
252
253/*
254 * This routine is used to post-process command-line options,
255 * since after_parse hook is invoked too late for us (changing
256 * output_filename is not effective).
257 */
258void gld${EMULATION_NAME}_set_symbols ()
259{
260 char *ext, *tmp_dir, *tmp;
261 size_t tmp_dir_len;
262
263 if (rsxnt_linked != EMX_DEFAULT && link_info.strip != strip_none) /* RSXNT */
264 {
265 /* rsxnt can't live without all (even debugging) symbols??? */
266 link_info.strip = strip_none;
267 emxbind_strip = 1;
268 }
269 else if (link_info.strip != strip_none)
270 {
271 /* emxbind cant live without extern defs... */
272 link_info.strip = strip_debugger;
273 emxbind_strip = 1;
274 }
275
276 /* Always generate relocatable output since ld is just the first stage ... */
277 link_info.relocateable = true;
278
279 if (exe_flag)
280 {
281 ext = _getext (output_filename);
282 if ((ext != NULL) && (stricmp (ext, ".exe") == 0))
283 {
284 exe_filename = output_filename;
285 exe_flag = 0;
286 }
287 else
288 {
289 touch_filename = strdup(output_filename);
290 exe_filename = concat (output_filename, ".exe", NULL);
291 }
292 }
293 else
294 {
295 ext = _getext2 (output_filename);
296 if (stricmp (ext, ".dll") == 0)
297 {
298 link_info.relocateable = true;
299 dll_flag = 1;
300 }
301 else if (stricmp (ext, ".exe") != 0)
302 {
303 exe_filename = NULL;
304 return;
305 }
306 exe_filename = output_filename;
307 }
308
309 /* Create a temporary a.out executable file. */
310
311 tmp_dir = getenv ("TMPDIR");
312 if (tmp_dir == NULL) tmp_dir = getenv ("TMP");
313 if (tmp_dir == NULL) tmp_dir = getenv ("TEMP");
314 if (tmp_dir == NULL) tmp_dir = ".";
315 tmp_dir_len = strlen (tmp_dir);
316 output_filename = tmp = xmalloc (tmp_dir_len + 10);
317 memcpy (tmp, tmp_dir, tmp_dir_len);
318 if (tmp_dir_len != 0 && strchr ("\\\\/:", tmp_dir[tmp_dir_len-1]) == NULL)
319 tmp[tmp_dir_len++] = '\\\\';
320 strcpy (tmp + tmp_dir_len, "ldXXXXXX");
321 if (mktemp (tmp) == NULL)
322 fatal ("mktemp(\\"%s\\") failed", output_filename);
323
324 unlink (exe_filename);
325 if (touch_filename != NULL)
326 unlink (touch_filename);
327}
328
329boolean gld_${EMULATION_NAME}_unrecognized_file (entry)
330 lang_input_statement_type *entry;
331{
332 char *ext;
333
334 ext = _getext (entry->filename);
335 if (ext != NULL)
336 {
337 if (stricmp (ext, ".def") == 0)
338 {
339 def_filename = entry->filename;
340 entry->loaded = true;
341 return true;
342 }
343 else if (stricmp (ext, ".res") == 0)
344 {
345 res_filename = entry->filename;
346 entry->loaded = true;
347 return true;
348 }
349 }
350
351 return false;
352}
353
354extern u_int DosCopy (char *pszSource, char *pszTarget, u_int ulOption);
355
356/* Perform final action(s) on output file */
357void gld_${EMULATION_NAME}_finish_link (char *filename)
358{
359 struct stat statbuf;
360 int filemode, mask;
361
362 if (stat (output_filename, &statbuf) < 0)
363 fatal ("cannot query file status for %s\\n", output_filename);
364
365 filemode = statbuf.st_mode;
366
367 mask = umask (0);
368 umask (mask);
369
370 if (rsxnt_linked == EMX_DEFAULT && exe_filename)
371 {
372 char *nargv[11];
373 int i, saved_errno;
374
375 i = 0;
376 nargv[i++] = "emxbind";
377 nargv[i++] = "-bq";
378 if (emxbind_strip)
379 nargv[i++] = "-s";
380 if (def_filename)
381 {
382 nargv[i] = alloca (strlen (def_filename) + 3);
383 strcpy (nargv[i], "-d");
384 strcat (nargv[i], def_filename);
385 i++;
386 }
387 else if (dll_flag)
388 nargv[i++] = "-d";
389
390 if (stack_size != 0)
391 {
392 nargv[i] = alloca (20);
393 sprintf (nargv[i], "-k0x%x", stack_size);
394 i++;
395 }
396
397 if (map_flag)
398 {
399 if (map_filename == NULL)
400 {
401 map_filename = alloca (strlen (exe_filename) + 5);
402 strcpy ((char *)map_filename, exe_filename);
403 _remext ((char *)map_filename);
404 strcat ((char *)map_filename, ".map");
405 }
406 nargv[i] = alloca (strlen (map_filename) + 3);
407 strcpy (nargv[i], "-m");
408 strcat (nargv[i], map_filename);
409 i++;
410 }
411
412 if (res_filename)
413 {
414 nargv[i] = alloca (strlen (res_filename) + 3);
415 strcpy (nargv[i], "-r");
416 strcat (nargv[i], res_filename);
417 i++;
418 }
419
420 nargv[i++] = "-o";
421 nargv[i++] = (char *)exe_filename;
422 nargv[i++] = (char *)output_filename;
423 nargv[i] = NULL;
424 i = spawnvp (P_WAIT, "emxbind", nargv);
425 saved_errno = errno; unlink (output_filename); errno = saved_errno;
426 if (i < 0)
427 fatal ("failed to run emxbind\\n", NULL);
428 else if (i != 0)
429 fatal ("emxbind failed\\n", NULL);
430
431 if (chmod (exe_filename, filemode | (0111 & ~mask)) == -1)
432 fatal ("failed to write file %s\\n", exe_filename);
433
434 if (touch_filename)
435 {
436 char execname[512];
437 _execname(execname, sizeof(execname));
438 strcpy(_getname(execname), "ldstub.bin");
439 /* Copy stub into file */
440 if (DosCopy(execname, (char *)touch_filename, 4))
441 fatal ("cannot copy %s to %s\\n", execname, touch_filename);
442 /* Now touch it */
443 if (utime (touch_filename, NULL))
444 fatal ("cannot touch file %s\\n", touch_filename);
445 }
446 }
447 else if (exe_filename) /* RSXNT */
448 {
449 char *nargv[10];
450 int i, saved_errno;
451
452 i = 0;
453 nargv[i++] = "ntbind";
454 if (emxbind_strip)
455 nargv[i++] = "-s";
456 nargv[i++] = "-o";
457 nargv[i++] = (char *)exe_filename;
458 nargv[i++] = (char *)output_filename;
459
460 if (rsxnt_linked == RSXNT_WIN32)
461 nargv[i++] = (emxbind_strip) ? "dosstub.dos" : "dosstub.dbg";
462 else
463 {
464 nargv[i++] = "dosstub.rsx";
465 if (emxbind_strip)
466 nargv[i++] = "-strip";
467 }
468
469 if (def_filename)
470 {
471 nargv[i++] = "-d";
472 nargv[i] = alloca (strlen (def_filename) + 3);
473 strcpy(nargv[i], def_filename);
474 i++;
475 }
476 nargv[i] = NULL;
477
478 i = spawnvp (P_WAIT, "ntbind", nargv);
479 saved_errno = errno; unlink (output_filename); errno = saved_errno;
480 if (i < 0)
481 fatal ("failed to run ntbind\\n", NULL);
482 else if (i != 0)
483 fatal ("ntbind failed\\n", NULL);
484
485 if (chmod (exe_filename, filemode | (0111 & ~mask)) == -1)
486 fatal ("failed to write file %s\\n", exe_filename);
487
488 if (touch_filename)
489 {
490 i = open (touch_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
491 if (i < 0)
492 fatal ("failed to touch file %s\\n", touch_filename);
493 close (i);
494 }
495 }
496}
497
498/* Create any output sections needed by the target. */
499void gld${EMULATION_NAME}_create_output_section_statements (void)
500{
501 /* Since we enabled relocations LD marked output file as non-pageable */
502 /* However, this is not true for emx: always generate paged output */
503 output_bfd->flags |= D_PAGED;
504}
505
506struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
507{
508 gld${EMULATION_NAME}_before_parse,
509 syslib_default,
510 hll_default,
511 after_parse_default,
512 after_open_default,
513 after_allocation_default,
514 set_output_arch_default,
515 ldemul_default_target,
516 before_allocation_default,
517 gld${EMULATION_NAME}_get_script,
518 "${EMULATION_NAME}",
519 "${OUTPUT_FORMAT}",
520 NULL, /* finish */
521 gld${EMULATION_NAME}_create_output_section_statements, /* create output section statements */
522 NULL, /* open dynamic archive */
523 NULL, /* place orphan */
524 gld${EMULATION_NAME}_set_symbols, /* set symbols */
525 gld_${EMULATION_NAME}_parse_args,
526 gld_${EMULATION_NAME}_unrecognized_file,
527 NULL, /* list_options */
528 NULL, /* recognized_file */
529 NULL, /* find_potential_libraries */
530 gld_${EMULATION_NAME}_finish_link
531};
532EOF
Note: See TracBrowser for help on using the repository browser.