XCOFF64 fixes. For setting arch/mach and for R_BR relocations.
[deliverable/binutils-gdb.git] / ld / emultempl / aix.em
CommitLineData
252b5132
RH
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
86af25fe
L
3if [ -z "$MACHINE" ]; then
4 OUTPUT_ARCH=${ARCH}
5else
6 OUTPUT_ARCH=${ARCH}:${MACHINE}
7fi
252b5132
RH
8cat >e${EMULATION_NAME}.c <<EOF
9/* This file is is generated by a shell script. DO NOT EDIT! */
10
11/* AIX emulation code for ${EMULATION_NAME}
8529105a
AM
12 Copyright 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001
13 Free Software Foundation, Inc.
252b5132
RH
14 Written by Steve Chamberlain <sac@cygnus.com>
15 AIX support by Ian Lance Taylor <ian@cygnus.com>
3b1b01cf 16 AIX 64 bit support by Tom Rix <trix@redhat.com>
252b5132
RH
17
18This file is part of GLD, the Gnu Linker.
19
20This program is free software; you can redistribute it and/or modify
21it under the terms of the GNU General Public License as published by
22the Free Software Foundation; either version 2 of the License, or
23(at your option) any later version.
24
25This program is distributed in the hope that it will be useful,
26but WITHOUT ANY WARRANTY; without even the implied warranty of
27MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28GNU General Public License for more details.
29
30You should have received a copy of the GNU General Public License
31along with this program; if not, write to the Free Software
32Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
33
34#define TARGET_IS_${EMULATION_NAME}
35
36#include "bfd.h"
37#include "sysdep.h"
38#include "libiberty.h"
3882b010 39#include "safe-ctype.h"
252b5132
RH
40#include "getopt.h"
41#include "obstack.h"
42#include "bfdlink.h"
43
252b5132
RH
44#include "ld.h"
45#include "ldmain.h"
252b5132
RH
46#include "ldmisc.h"
47#include "ldexp.h"
48#include "ldlang.h"
20713691
AM
49#include "ldfile.h"
50#include "ldemul.h"
252b5132
RH
51#include "ldctor.h"
52#include "ldgram.h"
53
3b1b01cf
TR
54#include "coff/internal.h"
55#include "coff/xcoff.h"
f1f0d9ab
TR
56#include "libcoff.h"
57#include "libxcoff.h"
3b1b01cf 58
252b5132
RH
59static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
60static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
61static void gld${EMULATION_NAME}_after_open PARAMS ((void));
f1f0d9ab 62static char *gld${EMULATION_NAME}_choose_target PARAMS ((int, char **));
252b5132
RH
63static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
64static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean));
65static void gld${EMULATION_NAME}_free PARAMS ((PTR));
249172c3
TR
66static void gld${EMULATION_NAME}_find_relocs
67PARAMS ((lang_statement_union_type *));
252b5132
RH
68static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
69static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
48f6162b
AJ
70static boolean gld${EMULATION_NAME}_unrecognized_file
71 PARAMS ((lang_input_statement_type *));
9a4c7f16 72static void gld${EMULATION_NAME}_create_output_section_statements
f1f0d9ab
TR
73 PARAMS ((void));
74static void gld${EMULATION_NAME}_set_output_arch PARAMS ((void));
75
249172c3
TR
76static int is_syscall PARAMS ((char *, unsigned int *));
77static int change_symbol_mode PARAMS ((char *));
252b5132
RH
78
79/* The file alignment required for each section. */
80static unsigned long file_align;
81
82/* The maximum size the stack is permitted to grow. This is stored in
83 the a.out header. */
84static unsigned long maxstack;
85
86/* The maximum data size. This is stored in the a.out header. */
87static unsigned long maxdata;
88
89/* Whether to perform garbage collection. */
90static int gc = 1;
91
92/* The module type to use. */
93static unsigned short modtype = ('1' << 8) | 'L';
94
95/* Whether the .text section must be read-only (i.e., no relocs
96 permitted). */
97static int textro;
98
99/* Whether to implement Unix like linker semantics. */
100static int unix_ld;
101
102/* Structure used to hold import file list. */
103
104struct filelist
105{
106 struct filelist *next;
107 const char *name;
108};
109
110/* List of import files. */
111static struct filelist *import_files;
112
113/* List of export symbols read from the export files. */
114
115struct export_symbol_list
116{
117 struct export_symbol_list *next;
118 const char *name;
252b5132
RH
119};
120
121static struct export_symbol_list *export_symbols;
122
3b1b01cf
TR
123/* Maintains the 32 or 64 bit mode state of import file */
124static unsigned int symbol_mode = 0x04;
125
742aeb63
TR
126/* Which symbol modes are valid */
127static unsigned int symbol_mode_mask = 0x0d;
128
129/* Whether this is a 64 bit link */
130static int is_64bit = 0;
131
132/* Which syscalls from import file are valid */
133static unsigned int syscall_mask = 0x77;
134
9a4c7f16
TR
135/* fake file for -binitfini support */
136static lang_input_statement_type *initfini_file;
69f284c7
TR
137
138/* Whether to do run time linking */
f1f0d9ab 139static int rtld;
69f284c7 140
aa67bccf
TR
141/* Explicit command line library path, -blibpath */
142static char *command_line_blibpath = NULL;
143
252b5132
RH
144/* This routine is called before anything else is done. */
145
146static void
fab80407 147gld${EMULATION_NAME}_before_parse ()
252b5132 148{
f1f0d9ab 149
252b5132 150 config.has_shared = true;
3b1b01cf 151
9a4c7f16
TR
152 /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
153 Override them here so we can use the link_info.init_function as a
154 state flag that lets the backend know that -binitfini has been done. */
155
3b1b01cf
TR
156 link_info.init_function = NULL;
157 link_info.fini_function = NULL;
252b5132
RH
158}
159
160/* Handle AIX specific options. */
161
162static int
163gld${EMULATION_NAME}_parse_args (argc, argv)
164 int argc;
165 char **argv;
166{
167 int prevoptind = optind;
168 int prevopterr = opterr;
169 int indx;
170 int longind;
171 int optc;
3b1b01cf 172 bfd_signed_vma val;
252b5132
RH
173 char *end;
174
249172c3
TR
175 enum
176 {
3b1b01cf 177 OPTION_IGNORE = 300,
fab80407
AM
178 OPTION_AUTOIMP,
179 OPTION_ERNOTOK,
180 OPTION_EROK,
181 OPTION_EXPORT,
182 OPTION_IMPORT,
183 OPTION_INITFINI,
184 OPTION_LOADMAP,
185 OPTION_MAXDATA,
186 OPTION_MAXSTACK,
187 OPTION_MODTYPE,
188 OPTION_NOAUTOIMP,
189 OPTION_NOSTRCMPCT,
190 OPTION_PD,
191 OPTION_PT,
192 OPTION_STRCMPCT,
742aeb63
TR
193 OPTION_UNIX,
194 OPTION_32,
195 OPTION_64,
aa67bccf
TR
196 OPTION_LIBPATH,
197 OPTION_NOLIBPATH,
3b1b01cf
TR
198 };
199
9a4c7f16
TR
200 /* -binitfini has special handling in the linker backend. The native linker
201 uses the arguemnts to generate a table of init and fini functions for
202 the executable. The important use for this option is to support aix 4.2+
203 c++ constructors and destructors. This is tied into gcc via collect2.c.
204
205 The function table is accessed by the runtime linker/loader by checking if
206 the first symbol in the loader symbol table is __rtinit. The gnu linker
207 generates this symbol and makes it the first loader symbol. */
3b1b01cf
TR
208
209 static const struct option longopts[] = {
252b5132
RH
210 {"basis", no_argument, NULL, OPTION_IGNORE},
211 {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
212 {"bcomprld", no_argument, NULL, OPTION_IGNORE},
213 {"bcrld", no_argument, NULL, OPTION_IGNORE},
214 {"bcror31", no_argument, NULL, OPTION_IGNORE},
215 {"bD", required_argument, NULL, OPTION_MAXDATA},
216 {"bE", required_argument, NULL, OPTION_EXPORT},
217 {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
218 {"berok", no_argument, NULL, OPTION_EROK},
219 {"berrmsg", no_argument, NULL, OPTION_IGNORE},
220 {"bexport", required_argument, NULL, OPTION_EXPORT},
221 {"bf", no_argument, NULL, OPTION_ERNOTOK},
222 {"bgc", no_argument, &gc, 1},
223 {"bh", required_argument, NULL, OPTION_IGNORE},
224 {"bhalt", required_argument, NULL, OPTION_IGNORE},
225 {"bI", required_argument, NULL, OPTION_IMPORT},
226 {"bimport", required_argument, NULL, OPTION_IMPORT},
3b1b01cf 227 {"binitfini", required_argument, NULL, OPTION_INITFINI},
252b5132
RH
228 {"bl", required_argument, NULL, OPTION_LOADMAP},
229 {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
230 {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
231 {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
232 {"bM", required_argument, NULL, OPTION_MODTYPE},
233 {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
234 {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
235 {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
236 {"bnoentry", no_argument, NULL, OPTION_IGNORE},
237 {"bnogc", no_argument, &gc, 0},
238 {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
239 {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
240 {"bnotextro", no_argument, &textro, 0},
241 {"bnro", no_argument, &textro, 0},
242 {"bpD", required_argument, NULL, OPTION_PD},
243 {"bpT", required_argument, NULL, OPTION_PT},
244 {"bro", no_argument, &textro, 1},
69f284c7 245 {"brtl", no_argument, &rtld, 1},
252b5132
RH
246 {"bS", required_argument, NULL, OPTION_MAXSTACK},
247 {"bso", no_argument, NULL, OPTION_AUTOIMP},
248 {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
249 {"btextro", no_argument, &textro, 1},
742aeb63
TR
250 {"b32", no_argument, NULL, OPTION_32},
251 {"b64", no_argument, NULL, OPTION_64},
252b5132
RH
252 {"static", no_argument, NULL, OPTION_NOAUTOIMP},
253 {"unix", no_argument, NULL, OPTION_UNIX},
aa67bccf
TR
254 {"blibpath", required_argument, NULL, OPTION_LIBPATH},
255 {"bnolibpath", required_argument, NULL, OPTION_NOLIBPATH},
252b5132
RH
256 {NULL, no_argument, NULL, 0}
257 };
258
259 /* Options supported by the AIX linker which we do not support: -f,
260 -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
261 -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
262 -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
263 -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
264 -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
265 -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
266 -bx, -bX, -bxref. */
267
268 /* If the current option starts with -b, change the first : to an =.
269 The AIX linker uses : to separate the option from the argument;
270 changing it to = lets us treat it as a getopt option. */
271 indx = optind;
fab80407 272 if (indx == 0)
249172c3 273 indx = 1;
fab80407
AM
274
275 if (indx < argc && strncmp (argv[indx], "-b", 2) == 0)
276 {
277 char *s;
278
279 for (s = argv[indx]; *s != '\0'; s++)
280 {
281 if (*s == ':')
282 {
283 *s = '=';
284 break;
285 }
286 }
252b5132 287 }
3b1b01cf 288
252b5132
RH
289
290 /* We add s and u so to the short options list so that -s and -u on
291 the command line do not match -static and -unix. */
292
293 opterr = 0;
294 optc = getopt_long_only (argc, argv, "-D:H:KT:zsu", longopts, &longind);
295 opterr = prevopterr;
296
297 switch (optc)
298 {
299 case 's':
300 case 'u':
301 default:
302 optind = prevoptind;
303 return 0;
304
305 case 0:
306 /* Long option which just sets a flag. */
307 break;
308
309 case 'D':
3b1b01cf 310 val = strtoll (optarg, &end, 0);
252b5132
RH
311 if (*end != '\0')
312 einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
313 else if (val != -1)
314 lang_section_start (".data", exp_intop (val));
315 break;
316
317 case 'H':
318 val = strtoul (optarg, &end, 0);
249172c3 319 if (*end != '\0' || (val & (val - 1)) != 0)
252b5132
RH
320 einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
321 else
322 file_align = val;
323 break;
324
325 case 'K':
326 case 'z':
327 /* FIXME: This should use the page size for the target system. */
328 file_align = 4096;
329 break;
330
331 case 'T':
332 /* On AIX this is the same as GNU ld -Ttext. When we see -T
333 number, we assume the AIX option is intended. Otherwise, we
334 assume the usual GNU ld -T option is intended. We can't just
335 ignore the AIX option, because gcc passes it to the linker. */
3b1b01cf 336 val = strtoull (optarg, &end, 0);
252b5132
RH
337 if (*end != '\0')
338 {
339 optind = prevoptind;
340 return 0;
341 }
342 lang_section_start (".text", exp_intop (val));
343 break;
344
345 case OPTION_IGNORE:
346 break;
347
fab80407
AM
348 case OPTION_INITFINI:
349 {
350 /*
351 * The aix linker init fini has the format :
352 *
353 * -binitfini:[ Initial][:Termination][:Priority]
354 *
355 * it allows the Termination and Priority to be optional.
356 *
357 * Since we support only one init/fini pair, we ignore the Priority.
358 *
359 * Define the special symbol __rtinit.
360 *
361 * strtok does not correctly handle the case of -binitfini::fini: so
362 * do it by hand
363 */
364 char *t, *i, *f;
365
366 i = t = optarg;
367 while (*t && ':' != *t)
368 t++;
369 if (*t)
370 *t++ = 0;
371
372 if (0 != strlen (i))
249172c3 373 link_info.init_function = i;
3b1b01cf 374
fab80407
AM
375 f = t;
376 while (*t && ':' != *t)
377 t++;
378 *t = 0;
3b1b01cf 379
fab80407 380 if (0 != strlen (f))
249172c3 381 link_info.fini_function = f;
3b1b01cf 382 }
249172c3
TR
383 break;
384
252b5132
RH
385 case OPTION_AUTOIMP:
386 link_info.static_link = false;
387 break;
388
389 case OPTION_ERNOTOK:
390 force_make_executable = false;
391 break;
392
393 case OPTION_EROK:
394 force_make_executable = true;
395 break;
396
397 case OPTION_EXPORT:
398 gld${EMULATION_NAME}_read_file (optarg, false);
399 break;
400
401 case OPTION_IMPORT:
402 {
403 struct filelist *n;
404 struct filelist **flpp;
405
406 n = (struct filelist *) xmalloc (sizeof (struct filelist));
407 n->next = NULL;
408 n->name = optarg;
409 flpp = &import_files;
410 while (*flpp != NULL)
411 flpp = &(*flpp)->next;
412 *flpp = n;
413 }
414 break;
415
416 case OPTION_LOADMAP:
417 config.map_filename = optarg;
418 break;
419
420 case OPTION_MAXDATA:
3b1b01cf 421 val = strtoull (optarg, &end, 0);
252b5132 422 if (*end != '\0')
fab80407 423 einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", optarg);
252b5132
RH
424 else
425 maxdata = val;
426 break;
427
428 case OPTION_MAXSTACK:
3b1b01cf 429 val = strtoull (optarg, &end, 0);
252b5132 430 if (*end != '\0')
249172c3
TR
431 einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
432 optarg);
252b5132
RH
433 else
434 maxstack = val;
435 break;
436
437 case OPTION_MODTYPE:
438 if (*optarg == 'S')
439 {
440 link_info.shared = true;
441 ++optarg;
442 }
443 if (*optarg == '\0' || optarg[1] == '\0')
444 einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
445 else
446 modtype = (*optarg << 8) | optarg[1];
447 break;
448
449 case OPTION_NOAUTOIMP:
450 link_info.static_link = true;
451 break;
452
453 case OPTION_NOSTRCMPCT:
454 link_info.traditional_format = true;
455 break;
456
457 case OPTION_PD:
458 /* This sets the page that the .data section is supposed to
459 start on. The offset within the page should still be the
460 offset within the file, so we need to build an appropriate
461 expression. */
3b1b01cf 462 val = strtoull (optarg, &end, 0);
252b5132
RH
463 if (*end != '\0')
464 einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
465 else
466 {
467 etree_type *t;
468
469 t = exp_binop ('+',
470 exp_intop (val),
471 exp_binop ('&',
472 exp_nameop (NAME, "."),
473 exp_intop (0xfff)));
474 t = exp_binop ('&',
475 exp_binop ('+', t, exp_intop (31)),
249172c3 476 exp_intop (~(bfd_vma) 31));
252b5132
RH
477 lang_section_start (".data", t);
478 }
479 break;
480
481 case OPTION_PT:
482 /* This set the page that the .text section is supposed to start
483 on. The offset within the page should still be the offset
484 within the file. */
3b1b01cf 485 val = strtoull (optarg, &end, 0);
252b5132
RH
486 if (*end != '\0')
487 einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
488 else
489 {
490 etree_type *t;
491
492 t = exp_binop ('+',
493 exp_intop (val),
494 exp_nameop (SIZEOF_HEADERS, NULL));
495 t = exp_binop ('&',
496 exp_binop ('+', t, exp_intop (31)),
249172c3 497 exp_intop (~(bfd_vma) 31));
252b5132
RH
498 lang_section_start (".text", t);
499 }
500 break;
501
502 case OPTION_STRCMPCT:
503 link_info.traditional_format = false;
504 break;
505
506 case OPTION_UNIX:
507 unix_ld = true;
508 break;
742aeb63
TR
509
510 case OPTION_32:
511 is_64bit = 0;
512 syscall_mask = 0x77;
513 symbol_mode_mask = 0x0d;
514 break;
515
516 case OPTION_64:
517 is_64bit = 1;
518 syscall_mask = 0xcc;
519 symbol_mode_mask = 0x0e;
520 break;
521
aa67bccf 522 case OPTION_LIBPATH:
cc7e59b2 523 command_line_blibpath = optarg;
aa67bccf
TR
524 break;
525
526 case OPTION_NOLIBPATH:
cc7e59b2 527 command_line_blibpath = NULL;
aa67bccf
TR
528 break;
529
252b5132
RH
530 }
531
532 return 1;
533}
534
535/* This is called when an input file can not be recognized as a BFD
536 object or an archive. If the file starts with #!, we must treat it
537 as an import file. This is for AIX compatibility. */
538
539static boolean
540gld${EMULATION_NAME}_unrecognized_file (entry)
541 lang_input_statement_type *entry;
542{
543 FILE *e;
544 boolean ret;
545
546 e = fopen (entry->filename, FOPEN_RT);
547 if (e == NULL)
548 return false;
549
550 ret = false;
551
552 if (getc (e) == '#' && getc (e) == '!')
553 {
554 struct filelist *n;
555 struct filelist **flpp;
556
557 n = (struct filelist *) xmalloc (sizeof (struct filelist));
558 n->next = NULL;
559 n->name = entry->filename;
560 flpp = &import_files;
561 while (*flpp != NULL)
562 flpp = &(*flpp)->next;
563 *flpp = n;
564
565 ret = true;
566 entry->loaded = true;
567 }
568
569 fclose (e);
570
571 return ret;
572}
573
574/* This is called after the input files have been opened. */
575
576static void
577gld${EMULATION_NAME}_after_open ()
578{
579 boolean r;
580 struct set_info *p;
581
582 /* Call ldctor_build_sets, after pretending that this is a
583 relocateable link. We do this because AIX requires relocation
584 entries for all references to symbols, even in a final
585 executable. Of course, we only want to do this if we are
586 producing an XCOFF output file. */
587 r = link_info.relocateable;
588 if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL)
589 link_info.relocateable = true;
590 ldctor_build_sets ();
591 link_info.relocateable = r;
592
593 /* For each set, record the size, so that the XCOFF backend can
594 output the correct csect length. */
595 for (p = sets; p != (struct set_info *) NULL; p = p->next)
596 {
597 bfd_size_type size;
598
599 /* If the symbol is defined, we may have been invoked from
249172c3
TR
600 collect, and the sets may already have been built, so we do
601 not do anything. */
252b5132
RH
602 if (p->h->type == bfd_link_hash_defined
603 || p->h->type == bfd_link_hash_defweak)
604 continue;
605
606 if (p->reloc != BFD_RELOC_CTOR)
607 {
608 /* Handle this if we need to. */
609 abort ();
610 }
611
612 size = (p->count + 2) * 4;
249172c3 613 if (!bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
252b5132
RH
614 einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
615 }
616}
617
618/* This is called after the sections have been attached to output
619 sections, but before any sizes or addresses have been set. */
620
621static void
622gld${EMULATION_NAME}_before_allocation ()
623{
624 struct filelist *fl;
625 struct export_symbol_list *el;
626 char *libpath;
3b1b01cf 627 asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS];
252b5132
RH
628 int i;
629
630 /* Handle the import and export files, if any. */
631 for (fl = import_files; fl != NULL; fl = fl->next)
632 gld${EMULATION_NAME}_read_file (fl->name, true);
fab80407
AM
633 for (el = export_symbols; el != NULL; el = el->next)
634 {
635 struct bfd_link_hash_entry *h;
636
637 h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false);
638 if (h == NULL)
639 einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
249172c3 640 if (!bfd_xcoff_export_symbol (output_bfd, &link_info, h))
fab80407
AM
641 einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
642 }
252b5132
RH
643
644 /* Track down all relocations called for by the linker script (these
645 are typically constructor/destructor entries created by
646 CONSTRUCTORS) and let the backend know it will need to create
647 .loader relocs for them. */
648 lang_for_each_statement (gld${EMULATION_NAME}_find_relocs);
649
aa67bccf
TR
650 /* Precedence of LIBPATH
651 -blibpath: native support always first
652 -rpath: gnu extension
653 -L build from command line -L's */
654 if (command_line_blibpath != NULL)
655 libpath = command_line_blibpath;
656 else if (command_line.rpath != NULL)
252b5132
RH
657 libpath = command_line.rpath;
658 else if (search_head == NULL)
659 libpath = (char *) "";
660 else
661 {
662 size_t len;
663 search_dirs_type *search;
664
665 len = strlen (search_head->name);
666 libpath = xmalloc (len + 1);
667 strcpy (libpath, search_head->name);
668 for (search = search_head->next; search != NULL; search = search->next)
669 {
670 size_t nlen;
671
672 nlen = strlen (search->name);
673 libpath = xrealloc (libpath, len + nlen + 2);
674 libpath[len] = ':';
675 strcpy (libpath + len + 1, search->name);
676 len += nlen + 1;
677 }
678 }
679
680 /* Let the XCOFF backend set up the .loader section. */
69f284c7
TR
681 if (!bfd_xcoff_size_dynamic_sections
682 (output_bfd, &link_info, libpath, entry_symbol, file_align,
683 maxstack, maxdata, gc && !unix_ld ? true : false,
f1f0d9ab
TR
684 modtype, textro ? true : false, unix_ld, special_sections,
685 rtld ? true : false))
252b5132
RH
686 einfo ("%P%F: failed to set dynamic section sizes: %E\n");
687
688 /* Look through the special sections, and put them in the right
689 place in the link ordering. This is especially magic. */
fab80407
AM
690 for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
691 {
692 asection *sec;
693 lang_output_section_statement_type *os;
694 lang_statement_union_type **pls;
695 lang_input_section_type *is;
696 const char *oname;
697 boolean start;
698
699 sec = special_sections[i];
700 if (sec == NULL)
701 continue;
3b1b01cf 702
fab80407 703 /* Remove this section from the list of the output section.
249172c3 704 This assumes we know what the script looks like. */
fab80407
AM
705 is = NULL;
706 os = lang_output_section_find (sec->output_section->name);
249172c3 707 if (os == NULL)
fab80407
AM
708 einfo ("%P%F: can't find output section %s\n",
709 sec->output_section->name);
fab80407
AM
710
711 for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
712 {
249172c3
TR
713 if ((*pls)->header.type == lang_input_section_enum
714 && (*pls)->input_section.section == sec)
fab80407 715 {
249172c3 716 is = (lang_input_section_type *) * pls;
fab80407 717 *pls = (*pls)->header.next;
252b5132 718 break;
fab80407
AM
719 }
720
721 if ((*pls)->header.type == lang_wild_statement_enum)
722 {
723 lang_statement_union_type **pwls;
724
725 for (pwls = &(*pls)->wild_statement.children.head;
249172c3 726 *pwls != NULL; pwls = &(*pwls)->header.next)
fab80407
AM
727 {
728
249172c3
TR
729 if ((*pwls)->header.type == lang_input_section_enum
730 && (*pwls)->input_section.section == sec)
fab80407 731 {
249172c3 732 is = (lang_input_section_type *) * pwls;
fab80407
AM
733 *pwls = (*pwls)->header.next;
734 break;
735 }
736 }
737
738 if (is != NULL)
739 break;
740 }
741 }
742
743 if (is == NULL)
744 {
745 einfo ("%P%F: can't find %s in output section\n",
746 bfd_get_section_name (sec->owner, sec));
3b1b01cf 747 }
fab80407
AM
748
749 /* Now figure out where the section should go. */
750 switch (i)
751 {
752
249172c3 753 default: /* to avoid warnings */
fab80407
AM
754 case XCOFF_SPECIAL_SECTION_TEXT:
755 /* _text */
756 oname = ".text";
757 start = true;
3b1b01cf 758 break;
252b5132 759
fab80407
AM
760 case XCOFF_SPECIAL_SECTION_ETEXT:
761 /* _etext */
762 oname = ".text";
763 start = false;
764 break;
252b5132 765
fab80407
AM
766 case XCOFF_SPECIAL_SECTION_DATA:
767 /* _data */
768 oname = ".data";
769 start = true;
770 break;
252b5132 771
fab80407
AM
772 case XCOFF_SPECIAL_SECTION_EDATA:
773 /* _edata */
774 oname = ".data";
775 start = false;
776 break;
777
778 case XCOFF_SPECIAL_SECTION_END:
779 case XCOFF_SPECIAL_SECTION_END2:
780 /* _end and end */
781 oname = ".bss";
782 start = false;
783 break;
784 }
252b5132 785
fab80407 786 os = lang_output_section_find (oname);
252b5132 787
fab80407
AM
788 if (start)
789 {
790 is->header.next = os->children.head;
791 os->children.head = (lang_statement_union_type *) is;
792 }
793 else
794 {
795 is->header.next = NULL;
796 lang_statement_append (&os->children,
797 (lang_statement_union_type *) is,
798 &is->header.next);
799 }
3b1b01cf 800 }
3b1b01cf
TR
801}
802
742aeb63 803static char *
f1f0d9ab 804gld${EMULATION_NAME}_choose_target (argc, argv)
742aeb63
TR
805 int argc;
806 char **argv;
807{
808 int i, j, jmax;
809 static char *from_outside;
810 static char *from_inside;
249172c3
TR
811 static char *argv_to_target[][2] = {
812 {NULL, "${OUTPUT_FORMAT}"},
eb1e0e80
NC
813 {"-b32", "${OUTPUT_FORMAT_32BIT}"},
814 {"-b64", "${OUTPUT_FORMAT_64BIT}"},
249172c3 815 };
742aeb63
TR
816
817 jmax = 3;
818
819 from_outside = getenv (TARGET_ENVIRON);
249172c3 820 if (from_outside != (char *) NULL)
742aeb63
TR
821 return from_outside;
822
823 /* Set to default. */
824 from_inside = argv_to_target[0][1];
825 for (i = 1; i < argc; i++)
826 {
827 for (j = 1; j < jmax; j++)
828 {
829 if (0 == strcmp (argv[i], argv_to_target[j][0]))
830 from_inside = argv_to_target[j][1];
831 }
832 }
249172c3 833
742aeb63
TR
834 return from_inside;
835}
836
249172c3
TR
837/* Returns
838 1 : state changed
839 0 : no change */
840static int
841change_symbol_mode (input)
842 char *input;
3b1b01cf 843{
3b1b01cf 844 char *symbol_mode_string[] = {
249172c3
TR
845 "# 32", /* 0x01 */
846 "# 64", /* 0x02 */
847 "# no32", /* 0x04 */
848 "# no64", /* 0x08 */
3b1b01cf
TR
849 NULL,
850 };
249172c3 851
3b1b01cf
TR
852 unsigned int bit;
853 char *string;
854
249172c3 855 for (bit = 0;; bit++)
fab80407
AM
856 {
857 string = symbol_mode_string[bit];
249172c3 858 if (string == NULL)
fab80407
AM
859 return 0;
860
861 if (0 == strcmp (input, string))
862 {
863 symbol_mode = (1 << bit);
864 return 1;
865 }
3b1b01cf 866 }
3b1b01cf
TR
867 /* should not be here */
868 return 0;
869}
870
249172c3
TR
871/* Returns
872 1 : yes
873 0 : ignore
874 -1 : error, try something else */
875static int
876is_syscall (input, flag)
877 char *input;
878 unsigned int *flag;
3b1b01cf 879{
3b1b01cf
TR
880 unsigned int bit;
881 char *string;
1fdf0249
TR
882
883 struct sc {
884 char *syscall_string;
885 unsigned int flag;
886 } s [] = {
887 { "svc" /* 0x01 */, XCOFF_SYSCALL32 },
888 { "svc32" /* 0x02 */, XCOFF_SYSCALL32 },
889 { "svc3264" /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
890 { "svc64" /* 0x08 */, XCOFF_SYSCALL64 },
891 { "syscall" /* 0x10 */, XCOFF_SYSCALL32 },
892 { "syscall32" /* 0x20 */, XCOFF_SYSCALL32 },
893 { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
894 { "syscall64" /* 0x80 */, XCOFF_SYSCALL64 },
895 { NULL, 0 },
3b1b01cf
TR
896 };
897
1fdf0249 898 *flag = 0;
3b1b01cf 899
249172c3
TR
900 for (bit = 0;; bit++)
901 {
902 string = s[bit].syscall_string;
903 if (string == NULL)
904 return -1;
fab80407 905
249172c3
TR
906 if (0 == strcmp (input, string))
907 {
908 if (1 << bit & syscall_mask)
909 {
910 *flag = s[bit].flag;
911 return 1;
912 }
913 else
914 {
915 return 0;
916 }
917 }
252b5132 918 }
3b1b01cf
TR
919 /* should not be here */
920 return -1;
252b5132
RH
921}
922
923/* Read an import or export file. For an import file, this is called
924 by the before_allocation emulation routine. For an export file,
925 this is called by the parse_args emulation routine. */
926
927static void
928gld${EMULATION_NAME}_read_file (filename, import)
929 const char *filename;
930 boolean import;
931{
932 struct obstack *o;
933 FILE *f;
934 int lineno;
935 int c;
936 boolean keep;
937 const char *imppath;
938 const char *impfile;
939 const char *impmember;
940
941 o = (struct obstack *) xmalloc (sizeof (struct obstack));
942 obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
943
944 f = fopen (filename, FOPEN_RT);
945 if (f == NULL)
946 {
947 bfd_set_error (bfd_error_system_call);
948 einfo ("%F%s: %E\n", filename);
949 }
950
951 keep = false;
952
953 imppath = NULL;
954 impfile = NULL;
955 impmember = NULL;
956
957 lineno = 0;
3b1b01cf 958
69f284c7
TR
959 /* Default to 32 and 64 bit mode
960 symbols at top of /lib/syscalls.exp do not have a mode modifier and they
961 are not repeated, assume 64 bit routines also want to use them.
962 See the routine change_symbol_mode for more information. */
963
3b1b01cf
TR
964 symbol_mode = 0x04;
965
252b5132
RH
966 while ((c = getc (f)) != EOF)
967 {
968 char *s;
969 char *symname;
1fdf0249 970 unsigned int syscall_flag = 0;
252b5132
RH
971 bfd_vma address;
972 struct bfd_link_hash_entry *h;
973
974 if (c != '\n')
975 {
976 obstack_1grow (o, c);
977 continue;
978 }
979
980 obstack_1grow (o, '\0');
981 ++lineno;
982
983 s = (char *) obstack_base (o);
3882b010 984 while (ISSPACE (*s))
252b5132 985 ++s;
fab80407
AM
986 if (*s == '\0'
987 || *s == '*'
988 || change_symbol_mode (s)
989 || (*s == '#' && s[1] == ' ')
249172c3 990 || (!import && *s == '#' && s[1] == '!'))
252b5132
RH
991 {
992 obstack_free (o, obstack_base (o));
993 continue;
994 }
995
996 if (*s == '#' && s[1] == '!')
997 {
998 s += 2;
3882b010 999 while (ISSPACE (*s))
252b5132
RH
1000 ++s;
1001 if (*s == '\0')
1002 {
1003 imppath = NULL;
1004 impfile = NULL;
1005 impmember = NULL;
1006 obstack_free (o, obstack_base (o));
1007 }
1008 else if (*s == '(')
1009 einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
1010 filename, lineno);
1011 else
1012 {
1013 char cs;
1014 char *file;
1015
1016 (void) obstack_finish (o);
1017 keep = true;
1018 imppath = s;
1019 file = NULL;
249172c3 1020 while (!ISSPACE (*s) && *s != '(' && *s != '\0')
252b5132
RH
1021 {
1022 if (*s == '/')
1023 file = s + 1;
1024 ++s;
1025 }
1026 if (file != NULL)
1027 {
1028 file[-1] = '\0';
1029 impfile = file;
1030 if (imppath == file - 1)
1031 imppath = "/";
1032 }
1033 else
1034 {
1035 impfile = imppath;
1036 imppath = "";
1037 }
1038 cs = *s;
1039 *s = '\0';
3882b010 1040 while (ISSPACE (cs))
252b5132
RH
1041 {
1042 ++s;
1043 cs = *s;
1044 }
1045 if (cs != '(')
1046 {
1047 impmember = "";
1048 if (cs != '\0')
1049 einfo ("%s:%d: warning: syntax error in import file\n",
1050 filename, lineno);
1051 }
1052 else
1053 {
1054 ++s;
1055 impmember = s;
1056 while (*s != ')' && *s != '\0')
1057 ++s;
1058 if (*s == ')')
1059 *s = '\0';
1060 else
1061 einfo ("%s:%d: warning: syntax error in import file\n",
1062 filename, lineno);
1063 }
1064 }
1065
1066 continue;
1067 }
1068
742aeb63 1069 if (symbol_mode & symbol_mode_mask)
fab80407
AM
1070 {
1071 /* This is a symbol to be imported or exported. */
1072 symname = s;
1fdf0249 1073 syscall_flag = 0;
fab80407
AM
1074 address = (bfd_vma) -1;
1075
249172c3 1076 while (!ISSPACE (*s) && *s != '\0')
fab80407
AM
1077 ++s;
1078 if (*s != '\0')
1079 {
1080 char *se;
3b1b01cf 1081
fab80407 1082 *s++ = '\0';
3b1b01cf 1083
3882b010 1084 while (ISSPACE (*s))
fab80407
AM
1085 ++s;
1086
1087 se = s;
249172c3 1088 while (!ISSPACE (*se) && *se != '\0')
fab80407
AM
1089 ++se;
1090 if (*se != '\0')
1091 {
1092 *se++ = '\0';
3882b010 1093 while (ISSPACE (*se))
fab80407
AM
1094 ++se;
1095 if (*se != '\0')
1096 einfo ("%s%d: warning: syntax error in import/export file\n",
1097 filename, lineno);
1098 }
1099
1100 if (s != se)
1101 {
1102 int status;
1103 char *end;
1104
249172c3 1105 status = is_syscall (s, &syscall_flag);
1fdf0249 1106
249172c3
TR
1107 if (0 > status)
1108 {
1109 /* not a system call, check for address */
1110 address = strtoul (s, &end, 0);
1111 if (*end != '\0')
1112 {
1113 einfo ("%s:%d: warning: syntax error in import/export file\n",
1114 filename, lineno);
1115
1116 }
1117 }
3b1b01cf 1118 }
252b5132 1119 }
3b1b01cf 1120
249172c3 1121 if (!import)
fab80407
AM
1122 {
1123 struct export_symbol_list *n;
1124
1125 ldlang_add_undef (symname);
1126 n = ((struct export_symbol_list *)
1127 xmalloc (sizeof (struct export_symbol_list)));
1128 n->next = export_symbols;
1129 n->name = xstrdup (symname);
fab80407
AM
1130 export_symbols = n;
1131 }
1132 else
1133 {
1134 h = bfd_link_hash_lookup (link_info.hash, symname, false, false,
1135 true);
1136 if (h == NULL || h->type == bfd_link_hash_new)
1137 {
1138 /* We can just ignore attempts to import an unreferenced
1139 symbol. */
1140 }
1141 else
1142 {
249172c3
TR
1143 if (!bfd_xcoff_import_symbol (output_bfd, &link_info, h,
1144 address, imppath, impfile,
1145 impmember, syscall_flag))
fab80407
AM
1146 einfo ("%X%s:%d: failed to import symbol %s: %E\n",
1147 filename, lineno, symname);
1148 }
1149 }
1150 }
252b5132
RH
1151 obstack_free (o, obstack_base (o));
1152 }
fab80407 1153
252b5132
RH
1154 if (obstack_object_size (o) > 0)
1155 {
fab80407
AM
1156 einfo ("%s:%d: warning: ignoring unterminated last line\n",
1157 filename, lineno);
1158 obstack_free (o, obstack_base (o));
1159 }
252b5132 1160
249172c3 1161 if (!keep)
fab80407
AM
1162 {
1163 obstack_free (o, NULL);
1164 free (o);
252b5132 1165 }
fab80407 1166}
252b5132
RH
1167
1168/* This routine saves us from worrying about declaring free. */
1169
1170static void
1171gld${EMULATION_NAME}_free (p)
1172 PTR p;
1173{
1174 free (p);
1175}
1176
1177/* This is called by the before_allocation routine via
1178 lang_for_each_statement. It looks for relocations and assignments
1179 to symbols. */
1180
1181static void
1182gld${EMULATION_NAME}_find_relocs (s)
1183 lang_statement_union_type *s;
1184{
1185 if (s->header.type == lang_reloc_statement_enum)
1186 {
1187 lang_reloc_statement_type *rs;
1188
1189 rs = &s->reloc_statement;
1190 if (rs->name == NULL)
1191 einfo ("%F%P: only relocations against symbols are permitted\n");
249172c3 1192 if (!bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name))
252b5132
RH
1193 einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
1194 }
1195
1196 if (s->header.type == lang_assignment_statement_enum)
1197 gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
1198}
1199
1200/* Look through an expression for an assignment statement. */
1201
1202static void
1203gld${EMULATION_NAME}_find_exp_assignment (exp)
1204 etree_type *exp;
1205{
1206 struct bfd_link_hash_entry *h;
1207
1208 switch (exp->type.node_class)
1209 {
1210 case etree_provide:
1211 h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
1212 false, false, false);
1213 if (h == NULL)
1214 break;
1215 /* Fall through. */
1216 case etree_assign:
1217 if (strcmp (exp->assign.dst, ".") != 0)
1218 {
249172c3
TR
1219 if (!bfd_xcoff_record_link_assignment (output_bfd, &link_info,
1220 exp->assign.dst))
252b5132
RH
1221 einfo ("%P%F: failed to record assignment to %s: %E\n",
1222 exp->assign.dst);
1223 }
1224 gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
1225 break;
1226
1227 case etree_binary:
1228 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
1229 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
1230 break;
1231
1232 case etree_trinary:
1233 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
1234 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
1235 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
1236 break;
1237
1238 case etree_unary:
1239 gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
1240 break;
1241
1242 default:
1243 break;
1244 }
1245}
1246
1247static char *
fab80407 1248gld${EMULATION_NAME}_get_script (isfile)
252b5132
RH
1249 int *isfile;
1250EOF
1251
1252if test -n "$COMPILE_IN"
1253then
1254# Scripts compiled in.
1255
1256# sed commands to quote an ld script as a C string.
5f642101 1257sc="-f ${srcdir}/emultempl/ostring.sed"
252b5132
RH
1258
1259cat >>e${EMULATION_NAME}.c <<EOF
fab80407 1260{
252b5132
RH
1261 *isfile = 0;
1262
1263 if (link_info.relocateable == true && config.build_constructors == true)
1264 return
1265EOF
1266sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
1267echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
1268sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
1269echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
1270sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
1271echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
1272sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
1273echo ' ; else return' >> e${EMULATION_NAME}.c
1274sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
1275echo '; }' >> e${EMULATION_NAME}.c
1276
1277else
1278# Scripts read from the filesystem.
1279
1280cat >>e${EMULATION_NAME}.c <<EOF
fab80407 1281{
252b5132
RH
1282 *isfile = 1;
1283
1284 if (link_info.relocateable == true && config.build_constructors == true)
1285 return "ldscripts/${EMULATION_NAME}.xu";
1286 else if (link_info.relocateable == true)
1287 return "ldscripts/${EMULATION_NAME}.xr";
1288 else if (!config.text_read_only)
1289 return "ldscripts/${EMULATION_NAME}.xbn";
1290 else if (!config.magic_demand_paged)
1291 return "ldscripts/${EMULATION_NAME}.xn";
1292 else
1293 return "ldscripts/${EMULATION_NAME}.x";
1294}
1295EOF
1296
1297fi
1298
1299cat >>e${EMULATION_NAME}.c <<EOF
1300
9a4c7f16 1301static void
f1f0d9ab 1302gld${EMULATION_NAME}_create_output_section_statements ()
9a4c7f16
TR
1303{
1304 /* __rtinit */
1305 if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
69f284c7
TR
1306 && (link_info.init_function != NULL
1307 || link_info.fini_function != NULL
1308 || rtld == true))
9a4c7f16 1309 {
9a4c7f16
TR
1310 initfini_file = lang_add_input_file ("initfini",
1311 lang_input_file_is_file_enum,
1312 NULL);
1313
1314 initfini_file->the_bfd = bfd_create ("initfini", output_bfd);
1315 if (initfini_file->the_bfd == NULL
1316 || ! bfd_set_arch_mach (initfini_file->the_bfd,
1317 bfd_get_arch (output_bfd),
1318 bfd_get_mach (output_bfd)))
1319 {
1320 einfo ("%X%P: can not create BFD %E\n");
1321 return;
1322 }
1323
1324 /* Call backend to fill in the rest */
1325 if (false == bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd,
1326 link_info.init_function,
69f284c7
TR
1327 link_info.fini_function,
1328 rtld))
9a4c7f16
TR
1329 {
1330 einfo ("%X%P: can not create BFD %E\n");
1331 return;
1332 }
69f284c7
TR
1333
1334 /* __rtld defined in /lib/librtl.a */
1335 if (true == rtld)
1336 lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL);
9a4c7f16
TR
1337 }
1338}
1339
f1f0d9ab
TR
1340static void
1341gld${EMULATION_NAME}_set_output_arch ()
1342{
1343 bfd_set_arch_mach (output_bfd,
1344 bfd_xcoff_architecture (output_bfd),
1345 bfd_xcoff_machine (output_bfd));
1346
1347 ldfile_output_architecture = bfd_get_arch (output_bfd);
1348 ldfile_output_machine = bfd_get_mach (output_bfd);
1349 ldfile_output_machine_name = bfd_printable_name (output_bfd);
1350}
1351
249172c3 1352struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
252b5132
RH
1353 gld${EMULATION_NAME}_before_parse,
1354 syslib_default,
1355 hll_default,
1356 after_parse_default,
1357 gld${EMULATION_NAME}_after_open,
1358 after_allocation_default,
f1f0d9ab
TR
1359 gld${EMULATION_NAME}_set_output_arch,
1360 gld${EMULATION_NAME}_choose_target,
252b5132
RH
1361 gld${EMULATION_NAME}_before_allocation,
1362 gld${EMULATION_NAME}_get_script,
1363 "${EMULATION_NAME}",
1364 "${OUTPUT_FORMAT}",
249172c3 1365 0, /* finish */
9a4c7f16 1366 gld${EMULATION_NAME}_create_output_section_statements,
249172c3
TR
1367 0, /* open_dynamic_archive */
1368 0, /* place_orphan */
1369 0, /* set_symbols */
252b5132 1370 gld${EMULATION_NAME}_parse_args,
40d109bf 1371 gld${EMULATION_NAME}_unrecognized_file,
249172c3
TR
1372 NULL, /* list_options */
1373 NULL, /* recognized_file */
1374 NULL, /* find potential_libraries */
252b5132
RH
1375};
1376EOF
This page took 0.178567 seconds and 4 git commands to generate.