source: trunk/binutils/ld/emultempl/i386aoutemx.em@ 2912

Last change on this file since 2912 was 625, checked in by bird, 22 years ago

#597: Corrected struct initialization and fixed some compiler warnings.

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