Remove trailing white spaces in ld
[deliverable/binutils-gdb.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "libiberty.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "deffile.h"
30
31 #define TRACE 0
32
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
41
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
44 #define yylex def_lex
45 #define yyerror def_error
46 #define yylval def_lval
47 #define yychar def_char
48 #define yydebug def_debug
49 #define yypact def_pact
50 #define yyr1 def_r1
51 #define yyr2 def_r2
52 #define yydef def_def
53 #define yychk def_chk
54 #define yypgo def_pgo
55 #define yyact def_act
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
59 #define yyps def_ps
60 #define yypv def_pv
61 #define yys def_s
62 #define yy_yys def_yys
63 #define yystate def_state
64 #define yytmp def_tmp
65 #define yyv def_v
66 #define yy_yyv def_yyv
67 #define yyval def_val
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined. */
70 #define yytoks def_toks /* With YYDEBUG defined. */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
80
81 typedef struct def_pool_str {
82 struct def_pool_str *next;
83 char data[1];
84 } def_pool_str;
85
86 static def_pool_str *pool_strs = NULL;
87
88 static char *def_pool_alloc (size_t sz);
89 static char *def_pool_strdup (const char *str);
90 static void def_pool_free (void);
91
92 static void def_description (const char *);
93 static void def_exports (const char *, const char *, int, int, const char *);
94 static void def_heapsize (int, int);
95 static void def_import (const char *, const char *, const char *, const char *,
96 int, const char *);
97 static void def_image_name (const char *, int, int);
98 static void def_section (const char *, int);
99 static void def_section_alt (const char *, const char *);
100 static void def_stacksize (int, int);
101 static void def_version (int, int);
102 static void def_directive (char *);
103 static void def_aligncomm (char *str, int align);
104 static int def_parse (void);
105 static int def_error (const char *);
106 static int def_lex (void);
107
108 static int lex_forced_token = 0;
109 static const char *lex_parse_string = 0;
110 static const char *lex_parse_string_end = 0;
111
112 %}
113
114 %union {
115 char *id;
116 const char *id_const;
117 int number;
118 char *digits;
119 };
120
121 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
122 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
123 %token PRIVATEU PRIVATEL ALIGNCOMM
124 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
125 %token <id> ID
126 %token <digits> DIGITS
127 %type <number> NUMBER
128 %type <digits> opt_digits
129 %type <number> opt_base opt_ordinal
130 %type <number> attr attr_list opt_number exp_opt_list exp_opt
131 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
132 %type <id> opt_equalequal_name
133 %type <id_const> keyword_as_name
134
135 %%
136
137 start: start command
138 | command
139 ;
140
141 command:
142 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
143 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
144 | DESCRIPTION ID { def_description ($2);}
145 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
146 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
147 | CODE attr_list { def_section ("CODE", $2);}
148 | DATAU attr_list { def_section ("DATA", $2);}
149 | SECTIONS seclist
150 | EXPORTS explist
151 | IMPORTS implist
152 | VERSIONK NUMBER { def_version ($2, 0);}
153 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
154 | DIRECTIVE ID { def_directive ($2);}
155 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
156 ;
157
158
159 explist:
160 /* EMPTY */
161 | expline
162 | explist expline
163 ;
164
165 expline:
166 /* The opt_comma is necessary to support both the usual
167 DEF file syntax as well as .drectve syntax which
168 mandates <expsym>,<expoptlist>. */
169 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
170 { def_exports ($1, $2, $3, $5, $7); }
171 ;
172 exp_opt_list:
173 /* The opt_comma is necessary to support both the usual
174 DEF file syntax as well as .drectve syntax which
175 allows for comma separated opt list. */
176 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
177 | { $$ = 0; }
178 ;
179 exp_opt:
180 NONAMEU { $$ = 1; }
181 | NONAMEL { $$ = 1; }
182 | CONSTANTU { $$ = 2; }
183 | CONSTANTL { $$ = 2; }
184 | DATAU { $$ = 4; }
185 | DATAL { $$ = 4; }
186 | PRIVATEU { $$ = 8; }
187 | PRIVATEL { $$ = 8; }
188 ;
189 implist:
190 implist impline
191 | impline
192 ;
193
194 impline:
195 ID '=' ID '.' ID '.' ID opt_equalequal_name
196 { def_import ($1, $3, $5, $7, -1, $8); }
197 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
198 { def_import ($1, $3, $5, 0, $7, $8); }
199 | ID '=' ID '.' ID opt_equalequal_name
200 { def_import ($1, $3, 0, $5, -1, $6); }
201 | ID '=' ID '.' NUMBER opt_equalequal_name
202 { def_import ($1, $3, 0, 0, $5, $6); }
203 | ID '.' ID '.' ID opt_equalequal_name
204 { def_import( 0, $1, $3, $5, -1, $6); }
205 | ID '.' ID opt_equalequal_name
206 { def_import ( 0, $1, 0, $3, -1, $4); }
207 ;
208
209 seclist:
210 seclist secline
211 | secline
212 ;
213
214 secline:
215 ID attr_list { def_section ($1, $2);}
216 | ID ID { def_section_alt ($1, $2);}
217 ;
218
219 attr_list:
220 attr_list opt_comma attr { $$ = $1 | $3; }
221 | attr { $$ = $1; }
222 ;
223
224 opt_comma:
225 ','
226 |
227 ;
228 opt_number: ',' NUMBER { $$=$2;}
229 | { $$=-1;}
230 ;
231
232 attr:
233 READ { $$ = 1;}
234 | WRITE { $$ = 2;}
235 | EXECUTE { $$=4;}
236 | SHARED { $$=8;}
237 ;
238
239
240 keyword_as_name: BASE { $$ = "BASE"; }
241 | CODE { $$ = "CODE"; }
242 | CONSTANTU { $$ = "CONSTANT"; }
243 | CONSTANTL { $$ = "constant"; }
244 | DATAU { $$ = "DATA"; }
245 | DATAL { $$ = "data"; }
246 | DESCRIPTION { $$ = "DESCRIPTION"; }
247 | DIRECTIVE { $$ = "DIRECTIVE"; }
248 | EXECUTE { $$ = "EXECUTE"; }
249 | EXPORTS { $$ = "EXPORTS"; }
250 | HEAPSIZE { $$ = "HEAPSIZE"; }
251 | IMPORTS { $$ = "IMPORTS"; }
252 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
253 for libtool, which places this command after EXPORTS command.
254 This behavior is illegal by specification, but sadly required by
255 by compatibility reasons.
256 See PR binutils/13710
257 | LIBRARY { $$ = "LIBRARY"; } */
258 | NAME { $$ = "NAME"; }
259 | NONAMEU { $$ = "NONAME"; }
260 | NONAMEL { $$ = "noname"; }
261 | PRIVATEU { $$ = "PRIVATE"; }
262 | PRIVATEL { $$ = "private"; }
263 | READ { $$ = "READ"; }
264 | SHARED { $$ = "SHARED"; }
265 | STACKSIZE_K { $$ = "STACKSIZE"; }
266 | VERSIONK { $$ = "VERSION"; }
267 | WRITE { $$ = "WRITE"; }
268 ;
269
270 opt_name2: ID { $$ = $1; }
271 | '.' keyword_as_name
272 {
273 char *name = xmalloc (strlen ($2) + 2);
274 sprintf (name, ".%s", $2);
275 $$ = name;
276 }
277 | '.' opt_name2
278 {
279 char *name = def_pool_alloc (strlen ($2) + 2);
280 sprintf (name, ".%s", $2);
281 $$ = name;
282 }
283 | keyword_as_name '.' opt_name2
284 {
285 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
286 sprintf (name, "%s.%s", $1, $3);
287 $$ = name;
288 }
289 | ID '.' opt_name2
290 {
291 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
292 sprintf (name, "%s.%s", $1, $3);
293 $$ = name;
294 }
295 ;
296
297 opt_name: opt_name2 { $$ = $1; }
298 | { $$ = ""; }
299 ;
300
301 opt_equalequal_name: EQUAL ID { $$ = $2; }
302 | { $$ = 0; }
303 ;
304
305 opt_ordinal:
306 '@' NUMBER { $$ = $2;}
307 | { $$ = -1;}
308 ;
309
310 opt_equal_name:
311 '=' opt_name2 { $$ = $2; }
312 | { $$ = 0; }
313 ;
314
315 opt_base: BASE '=' NUMBER { $$ = $3;}
316 | { $$ = -1;}
317 ;
318
319 anylang_id: ID { $$ = $1; }
320 | '.' ID
321 {
322 char *id = def_pool_alloc (strlen ($2) + 2);
323 sprintf (id, ".%s", $2);
324 $$ = id;
325 }
326 | anylang_id '.' opt_digits opt_id
327 {
328 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
329 sprintf (id, "%s.%s%s", $1, $3, $4);
330 $$ = id;
331 }
332 ;
333
334 opt_digits: DIGITS { $$ = $1; }
335 | { $$ = ""; }
336 ;
337
338 opt_id: ID { $$ = $1; }
339 | { $$ = ""; }
340 ;
341
342 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
343
344 %%
345
346 /*****************************************************************************
347 API
348 *****************************************************************************/
349
350 static FILE *the_file;
351 static const char *def_filename;
352 static int linenumber;
353 static def_file *def;
354 static int saw_newline;
355
356 struct directive
357 {
358 struct directive *next;
359 char *name;
360 int len;
361 };
362
363 static struct directive *directives = 0;
364
365 def_file *
366 def_file_empty (void)
367 {
368 def_file *rv = xmalloc (sizeof (def_file));
369 memset (rv, 0, sizeof (def_file));
370 rv->is_dll = -1;
371 rv->base_address = (bfd_vma) -1;
372 rv->stack_reserve = rv->stack_commit = -1;
373 rv->heap_reserve = rv->heap_commit = -1;
374 rv->version_major = rv->version_minor = -1;
375 return rv;
376 }
377
378 def_file *
379 def_file_parse (const char *filename, def_file *add_to)
380 {
381 struct directive *d;
382
383 the_file = fopen (filename, "r");
384 def_filename = filename;
385 linenumber = 1;
386 if (!the_file)
387 {
388 perror (filename);
389 return 0;
390 }
391 if (add_to)
392 {
393 def = add_to;
394 }
395 else
396 {
397 def = def_file_empty ();
398 }
399
400 saw_newline = 1;
401 if (def_parse ())
402 {
403 def_file_free (def);
404 fclose (the_file);
405 def_pool_free ();
406 return 0;
407 }
408
409 fclose (the_file);
410
411 while ((d = directives) != NULL)
412 {
413 #if TRACE
414 printf ("Adding directive %08x `%s'\n", d->name, d->name);
415 #endif
416 def_file_add_directive (def, d->name, d->len);
417 directives = d->next;
418 free (d->name);
419 free (d);
420 }
421 def_pool_free ();
422
423 return def;
424 }
425
426 void
427 def_file_free (def_file *fdef)
428 {
429 int i;
430
431 if (!fdef)
432 return;
433 if (fdef->name)
434 free (fdef->name);
435 if (fdef->description)
436 free (fdef->description);
437
438 if (fdef->section_defs)
439 {
440 for (i = 0; i < fdef->num_section_defs; i++)
441 {
442 if (fdef->section_defs[i].name)
443 free (fdef->section_defs[i].name);
444 if (fdef->section_defs[i].class)
445 free (fdef->section_defs[i].class);
446 }
447 free (fdef->section_defs);
448 }
449
450 if (fdef->exports)
451 {
452 for (i = 0; i < fdef->num_exports; i++)
453 {
454 if (fdef->exports[i].internal_name
455 && fdef->exports[i].internal_name != fdef->exports[i].name)
456 free (fdef->exports[i].internal_name);
457 if (fdef->exports[i].name)
458 free (fdef->exports[i].name);
459 if (fdef->exports[i].its_name)
460 free (fdef->exports[i].its_name);
461 }
462 free (fdef->exports);
463 }
464
465 if (fdef->imports)
466 {
467 for (i = 0; i < fdef->num_imports; i++)
468 {
469 if (fdef->imports[i].internal_name
470 && fdef->imports[i].internal_name != fdef->imports[i].name)
471 free (fdef->imports[i].internal_name);
472 if (fdef->imports[i].name)
473 free (fdef->imports[i].name);
474 if (fdef->imports[i].its_name)
475 free (fdef->imports[i].its_name);
476 }
477 free (fdef->imports);
478 }
479
480 while (fdef->modules)
481 {
482 def_file_module *m = fdef->modules;
483
484 fdef->modules = fdef->modules->next;
485 free (m);
486 }
487
488 while (fdef->aligncomms)
489 {
490 def_file_aligncomm *c = fdef->aligncomms;
491
492 fdef->aligncomms = fdef->aligncomms->next;
493 free (c->symbol_name);
494 free (c);
495 }
496
497 free (fdef);
498 }
499
500 #ifdef DEF_FILE_PRINT
501 void
502 def_file_print (FILE *file, def_file *fdef)
503 {
504 int i;
505
506 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
507 if (fdef->name)
508 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
509 if (fdef->is_dll != -1)
510 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
511 if (fdef->base_address != (bfd_vma) -1)
512 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
513 if (fdef->description)
514 fprintf (file, " description: `%s'\n", fdef->description);
515 if (fdef->stack_reserve != -1)
516 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
517 if (fdef->stack_commit != -1)
518 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
519 if (fdef->heap_reserve != -1)
520 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
521 if (fdef->heap_commit != -1)
522 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
523
524 if (fdef->num_section_defs > 0)
525 {
526 fprintf (file, " section defs:\n");
527
528 for (i = 0; i < fdef->num_section_defs; i++)
529 {
530 fprintf (file, " name: `%s', class: `%s', flags:",
531 fdef->section_defs[i].name, fdef->section_defs[i].class);
532 if (fdef->section_defs[i].flag_read)
533 fprintf (file, " R");
534 if (fdef->section_defs[i].flag_write)
535 fprintf (file, " W");
536 if (fdef->section_defs[i].flag_execute)
537 fprintf (file, " X");
538 if (fdef->section_defs[i].flag_shared)
539 fprintf (file, " S");
540 fprintf (file, "\n");
541 }
542 }
543
544 if (fdef->num_exports > 0)
545 {
546 fprintf (file, " exports:\n");
547
548 for (i = 0; i < fdef->num_exports; i++)
549 {
550 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
551 fdef->exports[i].name, fdef->exports[i].internal_name,
552 fdef->exports[i].ordinal);
553 if (fdef->exports[i].flag_private)
554 fprintf (file, " P");
555 if (fdef->exports[i].flag_constant)
556 fprintf (file, " C");
557 if (fdef->exports[i].flag_noname)
558 fprintf (file, " N");
559 if (fdef->exports[i].flag_data)
560 fprintf (file, " D");
561 fprintf (file, "\n");
562 }
563 }
564
565 if (fdef->num_imports > 0)
566 {
567 fprintf (file, " imports:\n");
568
569 for (i = 0; i < fdef->num_imports; i++)
570 {
571 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
572 fdef->imports[i].internal_name,
573 fdef->imports[i].module,
574 fdef->imports[i].name,
575 fdef->imports[i].ordinal);
576 }
577 }
578
579 if (fdef->version_major != -1)
580 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
581
582 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
583 }
584 #endif
585
586 /* Helper routine to check for identity of string pointers,
587 which might be NULL. */
588
589 static int
590 are_names_equal (const char *s1, const char *s2)
591 {
592 if (!s1 && !s2)
593 return 0;
594 if (!s1 || !s2)
595 return (!s1 ? -1 : 1);
596 return strcmp (s1, s2);
597 }
598
599 static int
600 cmp_export_elem (const def_file_export *e, const char *ex_name,
601 const char *in_name, const char *its_name,
602 int ord)
603 {
604 int r;
605
606 if ((r = are_names_equal (ex_name, e->name)) != 0)
607 return r;
608 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
609 return r;
610 if ((r = are_names_equal (its_name, e->its_name)) != 0)
611 return r;
612 return (ord - e->ordinal);
613 }
614
615 /* Search the position of the identical element, or returns the position
616 of the next higher element. If last valid element is smaller, then MAX
617 is returned. */
618
619 static int
620 find_export_in_list (def_file_export *b, int max,
621 const char *ex_name, const char *in_name,
622 const char *its_name, int ord, int *is_ident)
623 {
624 int e, l, r, p;
625
626 *is_ident = 0;
627 if (!max)
628 return 0;
629 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
630 {
631 if (!e)
632 *is_ident = 1;
633 return 0;
634 }
635 if (max == 1)
636 return 1;
637 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
638 return max;
639 else if (!e || max == 2)
640 {
641 if (!e)
642 *is_ident = 1;
643 return max - 1;
644 }
645 l = 0; r = max - 1;
646 while (l < r)
647 {
648 p = (l + r) / 2;
649 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
650 if (!e)
651 {
652 *is_ident = 1;
653 return p;
654 }
655 else if (e < 0)
656 r = p - 1;
657 else if (e > 0)
658 l = p + 1;
659 }
660 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
661 ++l;
662 else if (!e)
663 *is_ident = 1;
664 return l;
665 }
666
667 def_file_export *
668 def_file_add_export (def_file *fdef,
669 const char *external_name,
670 const char *internal_name,
671 int ordinal,
672 const char *its_name,
673 int *is_dup)
674 {
675 def_file_export *e;
676 int pos;
677 int max_exports = ROUND_UP(fdef->num_exports, 32);
678
679 if (internal_name && !external_name)
680 external_name = internal_name;
681 if (external_name && !internal_name)
682 internal_name = external_name;
683
684 /* We need to avoid duplicates. */
685 *is_dup = 0;
686 pos = find_export_in_list (fdef->exports, fdef->num_exports,
687 external_name, internal_name,
688 its_name, ordinal, is_dup);
689
690 if (*is_dup != 0)
691 return (fdef->exports + pos);
692
693 if (fdef->num_exports >= max_exports)
694 {
695 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
696 if (fdef->exports)
697 fdef->exports = xrealloc (fdef->exports,
698 max_exports * sizeof (def_file_export));
699 else
700 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
701 }
702
703 e = fdef->exports + pos;
704 if (pos != fdef->num_exports)
705 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
706 memset (e, 0, sizeof (def_file_export));
707 e->name = xstrdup (external_name);
708 e->internal_name = xstrdup (internal_name);
709 e->its_name = (its_name ? xstrdup (its_name) : NULL);
710 e->ordinal = ordinal;
711 fdef->num_exports++;
712 return e;
713 }
714
715 def_file_module *
716 def_get_module (def_file *fdef, const char *name)
717 {
718 def_file_module *s;
719
720 for (s = fdef->modules; s; s = s->next)
721 if (strcmp (s->name, name) == 0)
722 return s;
723
724 return NULL;
725 }
726
727 static def_file_module *
728 def_stash_module (def_file *fdef, const char *name)
729 {
730 def_file_module *s;
731
732 if ((s = def_get_module (fdef, name)) != NULL)
733 return s;
734 s = xmalloc (sizeof (def_file_module) + strlen (name));
735 s->next = fdef->modules;
736 fdef->modules = s;
737 s->user_data = 0;
738 strcpy (s->name, name);
739 return s;
740 }
741
742 static int
743 cmp_import_elem (const def_file_import *e, const char *ex_name,
744 const char *in_name, const char *module,
745 int ord)
746 {
747 int r;
748
749 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
750 return r;
751 if ((r = are_names_equal (ex_name, e->name)) != 0)
752 return r;
753 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
754 return r;
755 if (ord != e->ordinal)
756 return (ord < e->ordinal ? -1 : 1);
757 return 0;
758 }
759
760 /* Search the position of the identical element, or returns the position
761 of the next higher element. If last valid element is smaller, then MAX
762 is returned. */
763
764 static int
765 find_import_in_list (def_file_import *b, int max,
766 const char *ex_name, const char *in_name,
767 const char *module, int ord, int *is_ident)
768 {
769 int e, l, r, p;
770
771 *is_ident = 0;
772 if (!max)
773 return 0;
774 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
775 {
776 if (!e)
777 *is_ident = 1;
778 return 0;
779 }
780 if (max == 1)
781 return 1;
782 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
783 return max;
784 else if (!e || max == 2)
785 {
786 if (!e)
787 *is_ident = 1;
788 return max - 1;
789 }
790 l = 0; r = max - 1;
791 while (l < r)
792 {
793 p = (l + r) / 2;
794 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
795 if (!e)
796 {
797 *is_ident = 1;
798 return p;
799 }
800 else if (e < 0)
801 r = p - 1;
802 else if (e > 0)
803 l = p + 1;
804 }
805 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
806 ++l;
807 else if (!e)
808 *is_ident = 1;
809 return l;
810 }
811
812 def_file_import *
813 def_file_add_import (def_file *fdef,
814 const char *name,
815 const char *module,
816 int ordinal,
817 const char *internal_name,
818 const char *its_name,
819 int *is_dup)
820 {
821 def_file_import *i;
822 int pos;
823 int max_imports = ROUND_UP (fdef->num_imports, 16);
824
825 /* We need to avoid here duplicates. */
826 *is_dup = 0;
827 pos = find_import_in_list (fdef->imports, fdef->num_imports,
828 name,
829 (!internal_name ? name : internal_name),
830 module, ordinal, is_dup);
831 if (*is_dup != 0)
832 return fdef->imports + pos;
833
834 if (fdef->num_imports >= max_imports)
835 {
836 max_imports = ROUND_UP (fdef->num_imports+1, 16);
837
838 if (fdef->imports)
839 fdef->imports = xrealloc (fdef->imports,
840 max_imports * sizeof (def_file_import));
841 else
842 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
843 }
844 i = fdef->imports + pos;
845 if (pos != fdef->num_imports)
846 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
847 memset (i, 0, sizeof (def_file_import));
848 if (name)
849 i->name = xstrdup (name);
850 if (module)
851 i->module = def_stash_module (fdef, module);
852 i->ordinal = ordinal;
853 if (internal_name)
854 i->internal_name = xstrdup (internal_name);
855 else
856 i->internal_name = i->name;
857 i->its_name = (its_name ? xstrdup (its_name) : NULL);
858 fdef->num_imports++;
859
860 return i;
861 }
862
863 struct
864 {
865 char *param;
866 int token;
867 }
868 diropts[] =
869 {
870 { "-heap", HEAPSIZE },
871 { "-stack", STACKSIZE_K },
872 { "-attr", SECTIONS },
873 { "-export", EXPORTS },
874 { "-aligncomm", ALIGNCOMM },
875 { 0, 0 }
876 };
877
878 void
879 def_file_add_directive (def_file *my_def, const char *param, int len)
880 {
881 def_file *save_def = def;
882 const char *pend = param + len;
883 char * tend = (char *) param;
884 int i;
885
886 def = my_def;
887
888 while (param < pend)
889 {
890 while (param < pend
891 && (ISSPACE (*param) || *param == '\n' || *param == 0))
892 param++;
893
894 if (param == pend)
895 break;
896
897 /* Scan forward until we encounter any of:
898 - the end of the buffer
899 - the start of a new option
900 - a newline seperating options
901 - a NUL seperating options. */
902 for (tend = (char *) (param + 1);
903 (tend < pend
904 && !(ISSPACE (tend[-1]) && *tend == '-')
905 && *tend != '\n' && *tend != 0);
906 tend++)
907 ;
908
909 for (i = 0; diropts[i].param; i++)
910 {
911 len = strlen (diropts[i].param);
912
913 if (tend - param >= len
914 && strncmp (param, diropts[i].param, len) == 0
915 && (param[len] == ':' || param[len] == ' '))
916 {
917 lex_parse_string_end = tend;
918 lex_parse_string = param + len + 1;
919 lex_forced_token = diropts[i].token;
920 saw_newline = 0;
921 if (def_parse ())
922 continue;
923 break;
924 }
925 }
926
927 if (!diropts[i].param)
928 {
929 char saved;
930
931 saved = * tend;
932 * tend = 0;
933 /* xgettext:c-format */
934 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
935 * tend = saved;
936 }
937
938 lex_parse_string = 0;
939 param = tend;
940 }
941
942 def = save_def;
943 def_pool_free ();
944 }
945
946 /* Parser Callbacks. */
947
948 static void
949 def_image_name (const char *name, int base, int is_dll)
950 {
951 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
952 to do here. We retain the output filename specified on command line. */
953 if (*name)
954 {
955 const char* image_name = lbasename (name);
956
957 if (image_name != name)
958 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
959 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
960 name);
961 if (def->name)
962 free (def->name);
963 /* Append the default suffix, if none specified. */
964 if (strchr (image_name, '.') == 0)
965 {
966 const char * suffix = is_dll ? ".dll" : ".exe";
967
968 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
969 sprintf (def->name, "%s%s", image_name, suffix);
970 }
971 else
972 def->name = xstrdup (image_name);
973 }
974
975 /* Honor a BASE address statement, even if LIBRARY string is empty. */
976 def->base_address = base;
977 def->is_dll = is_dll;
978 }
979
980 static void
981 def_description (const char *text)
982 {
983 int len = def->description ? strlen (def->description) : 0;
984
985 len += strlen (text) + 1;
986 if (def->description)
987 {
988 def->description = xrealloc (def->description, len);
989 strcat (def->description, text);
990 }
991 else
992 {
993 def->description = xmalloc (len);
994 strcpy (def->description, text);
995 }
996 }
997
998 static void
999 def_stacksize (int reserve, int commit)
1000 {
1001 def->stack_reserve = reserve;
1002 def->stack_commit = commit;
1003 }
1004
1005 static void
1006 def_heapsize (int reserve, int commit)
1007 {
1008 def->heap_reserve = reserve;
1009 def->heap_commit = commit;
1010 }
1011
1012 static void
1013 def_section (const char *name, int attr)
1014 {
1015 def_file_section *s;
1016 int max_sections = ROUND_UP (def->num_section_defs, 4);
1017
1018 if (def->num_section_defs >= max_sections)
1019 {
1020 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1021
1022 if (def->section_defs)
1023 def->section_defs = xrealloc (def->section_defs,
1024 max_sections * sizeof (def_file_import));
1025 else
1026 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1027 }
1028 s = def->section_defs + def->num_section_defs;
1029 memset (s, 0, sizeof (def_file_section));
1030 s->name = xstrdup (name);
1031 if (attr & 1)
1032 s->flag_read = 1;
1033 if (attr & 2)
1034 s->flag_write = 1;
1035 if (attr & 4)
1036 s->flag_execute = 1;
1037 if (attr & 8)
1038 s->flag_shared = 1;
1039
1040 def->num_section_defs++;
1041 }
1042
1043 static void
1044 def_section_alt (const char *name, const char *attr)
1045 {
1046 int aval = 0;
1047
1048 for (; *attr; attr++)
1049 {
1050 switch (*attr)
1051 {
1052 case 'R':
1053 case 'r':
1054 aval |= 1;
1055 break;
1056 case 'W':
1057 case 'w':
1058 aval |= 2;
1059 break;
1060 case 'X':
1061 case 'x':
1062 aval |= 4;
1063 break;
1064 case 'S':
1065 case 's':
1066 aval |= 8;
1067 break;
1068 }
1069 }
1070 def_section (name, aval);
1071 }
1072
1073 static void
1074 def_exports (const char *external_name,
1075 const char *internal_name,
1076 int ordinal,
1077 int flags,
1078 const char *its_name)
1079 {
1080 def_file_export *dfe;
1081 int is_dup = 0;
1082
1083 if (!internal_name && external_name)
1084 internal_name = external_name;
1085 #if TRACE
1086 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1087 #endif
1088
1089 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1090 its_name, &is_dup);
1091
1092 /* We might check here for flag redefinition and warn. For now we
1093 ignore duplicates silently. */
1094 if (is_dup)
1095 return;
1096
1097 if (flags & 1)
1098 dfe->flag_noname = 1;
1099 if (flags & 2)
1100 dfe->flag_constant = 1;
1101 if (flags & 4)
1102 dfe->flag_data = 1;
1103 if (flags & 8)
1104 dfe->flag_private = 1;
1105 }
1106
1107 static void
1108 def_import (const char *internal_name,
1109 const char *module,
1110 const char *dllext,
1111 const char *name,
1112 int ordinal,
1113 const char *its_name)
1114 {
1115 char *buf = 0;
1116 const char *ext = dllext ? dllext : "dll";
1117 int is_dup = 0;
1118
1119 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1120 sprintf (buf, "%s.%s", module, ext);
1121 module = buf;
1122
1123 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1124 &is_dup);
1125 free (buf);
1126 }
1127
1128 static void
1129 def_version (int major, int minor)
1130 {
1131 def->version_major = major;
1132 def->version_minor = minor;
1133 }
1134
1135 static void
1136 def_directive (char *str)
1137 {
1138 struct directive *d = xmalloc (sizeof (struct directive));
1139
1140 d->next = directives;
1141 directives = d;
1142 d->name = xstrdup (str);
1143 d->len = strlen (str);
1144 }
1145
1146 static void
1147 def_aligncomm (char *str, int align)
1148 {
1149 def_file_aligncomm *c, *p;
1150
1151 p = NULL;
1152 c = def->aligncomms;
1153 while (c != NULL)
1154 {
1155 int e = strcmp (c->symbol_name, str);
1156 if (!e)
1157 {
1158 /* Not sure if we want to allow here duplicates with
1159 different alignments, but for now we keep them. */
1160 e = (int) c->alignment - align;
1161 if (!e)
1162 return;
1163 }
1164 if (e > 0)
1165 break;
1166 c = (p = c)->next;
1167 }
1168
1169 c = xmalloc (sizeof (def_file_aligncomm));
1170 c->symbol_name = xstrdup (str);
1171 c->alignment = (unsigned int) align;
1172 if (!p)
1173 {
1174 c->next = def->aligncomms;
1175 def->aligncomms = c;
1176 }
1177 else
1178 {
1179 c->next = p->next;
1180 p->next = c;
1181 }
1182 }
1183
1184 static int
1185 def_error (const char *err)
1186 {
1187 einfo ("%P: %s:%d: %s\n",
1188 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1189 return 0;
1190 }
1191
1192
1193 /* Lexical Scanner. */
1194
1195 #undef TRACE
1196 #define TRACE 0
1197
1198 /* Never freed, but always reused as needed, so no real leak. */
1199 static char *buffer = 0;
1200 static int buflen = 0;
1201 static int bufptr = 0;
1202
1203 static void
1204 put_buf (char c)
1205 {
1206 if (bufptr == buflen)
1207 {
1208 buflen += 50; /* overly reasonable, eh? */
1209 if (buffer)
1210 buffer = xrealloc (buffer, buflen + 1);
1211 else
1212 buffer = xmalloc (buflen + 1);
1213 }
1214 buffer[bufptr++] = c;
1215 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1216 }
1217
1218 static struct
1219 {
1220 char *name;
1221 int token;
1222 }
1223 tokens[] =
1224 {
1225 { "BASE", BASE },
1226 { "CODE", CODE },
1227 { "CONSTANT", CONSTANTU },
1228 { "constant", CONSTANTL },
1229 { "DATA", DATAU },
1230 { "data", DATAL },
1231 { "DESCRIPTION", DESCRIPTION },
1232 { "DIRECTIVE", DIRECTIVE },
1233 { "EXECUTE", EXECUTE },
1234 { "EXPORTS", EXPORTS },
1235 { "HEAPSIZE", HEAPSIZE },
1236 { "IMPORTS", IMPORTS },
1237 { "LIBRARY", LIBRARY },
1238 { "NAME", NAME },
1239 { "NONAME", NONAMEU },
1240 { "noname", NONAMEL },
1241 { "PRIVATE", PRIVATEU },
1242 { "private", PRIVATEL },
1243 { "READ", READ },
1244 { "SECTIONS", SECTIONS },
1245 { "SEGMENTS", SECTIONS },
1246 { "SHARED", SHARED },
1247 { "STACKSIZE", STACKSIZE_K },
1248 { "VERSION", VERSIONK },
1249 { "WRITE", WRITE },
1250 { 0, 0 }
1251 };
1252
1253 static int
1254 def_getc (void)
1255 {
1256 int rv;
1257
1258 if (lex_parse_string)
1259 {
1260 if (lex_parse_string >= lex_parse_string_end)
1261 rv = EOF;
1262 else
1263 rv = *lex_parse_string++;
1264 }
1265 else
1266 {
1267 rv = fgetc (the_file);
1268 }
1269 if (rv == '\n')
1270 saw_newline = 1;
1271 return rv;
1272 }
1273
1274 static int
1275 def_ungetc (int c)
1276 {
1277 if (lex_parse_string)
1278 {
1279 lex_parse_string--;
1280 return c;
1281 }
1282 else
1283 return ungetc (c, the_file);
1284 }
1285
1286 static int
1287 def_lex (void)
1288 {
1289 int c, i, q;
1290
1291 if (lex_forced_token)
1292 {
1293 i = lex_forced_token;
1294 lex_forced_token = 0;
1295 #if TRACE
1296 printf ("lex: forcing token %d\n", i);
1297 #endif
1298 return i;
1299 }
1300
1301 c = def_getc ();
1302
1303 /* Trim leading whitespace. */
1304 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1305 c = def_getc ();
1306
1307 if (c == EOF)
1308 {
1309 #if TRACE
1310 printf ("lex: EOF\n");
1311 #endif
1312 return 0;
1313 }
1314
1315 if (saw_newline && c == ';')
1316 {
1317 do
1318 {
1319 c = def_getc ();
1320 }
1321 while (c != EOF && c != '\n');
1322 if (c == '\n')
1323 return def_lex ();
1324 return 0;
1325 }
1326
1327 /* Must be something else. */
1328 saw_newline = 0;
1329
1330 if (ISDIGIT (c))
1331 {
1332 bufptr = 0;
1333 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1334 {
1335 put_buf (c);
1336 c = def_getc ();
1337 }
1338 if (c != EOF)
1339 def_ungetc (c);
1340 yylval.digits = def_pool_strdup (buffer);
1341 #if TRACE
1342 printf ("lex: `%s' returns DIGITS\n", buffer);
1343 #endif
1344 return DIGITS;
1345 }
1346
1347 if (ISALPHA (c) || strchr ("$:-_?@", c))
1348 {
1349 bufptr = 0;
1350 q = c;
1351 put_buf (c);
1352 c = def_getc ();
1353
1354 if (q == '@')
1355 {
1356 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1357 return (q);
1358 else if (ISDIGIT (c)) /* '@' followed by digit. */
1359 {
1360 def_ungetc (c);
1361 return (q);
1362 }
1363 #if TRACE
1364 printf ("lex: @ returns itself\n");
1365 #endif
1366 }
1367
1368 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1369 {
1370 put_buf (c);
1371 c = def_getc ();
1372 }
1373 if (c != EOF)
1374 def_ungetc (c);
1375 if (ISALPHA (q)) /* Check for tokens. */
1376 {
1377 for (i = 0; tokens[i].name; i++)
1378 if (strcmp (tokens[i].name, buffer) == 0)
1379 {
1380 #if TRACE
1381 printf ("lex: `%s' is a string token\n", buffer);
1382 #endif
1383 return tokens[i].token;
1384 }
1385 }
1386 #if TRACE
1387 printf ("lex: `%s' returns ID\n", buffer);
1388 #endif
1389 yylval.id = def_pool_strdup (buffer);
1390 return ID;
1391 }
1392
1393 if (c == '\'' || c == '"')
1394 {
1395 q = c;
1396 c = def_getc ();
1397 bufptr = 0;
1398
1399 while (c != EOF && c != q)
1400 {
1401 put_buf (c);
1402 c = def_getc ();
1403 }
1404 yylval.id = def_pool_strdup (buffer);
1405 #if TRACE
1406 printf ("lex: `%s' returns ID\n", buffer);
1407 #endif
1408 return ID;
1409 }
1410
1411 if ( c == '=')
1412 {
1413 c = def_getc ();
1414 if (c == '=')
1415 {
1416 #if TRACE
1417 printf ("lex: `==' returns EQUAL\n");
1418 #endif
1419 return EQUAL;
1420 }
1421 def_ungetc (c);
1422 #if TRACE
1423 printf ("lex: `=' returns itself\n");
1424 #endif
1425 return '=';
1426 }
1427 if (c == '.' || c == ',')
1428 {
1429 #if TRACE
1430 printf ("lex: `%c' returns itself\n", c);
1431 #endif
1432 return c;
1433 }
1434
1435 if (c == '\n')
1436 {
1437 linenumber++;
1438 saw_newline = 1;
1439 }
1440
1441 /*printf ("lex: 0x%02x ignored\n", c); */
1442 return def_lex ();
1443 }
1444
1445 static char *
1446 def_pool_alloc (size_t sz)
1447 {
1448 def_pool_str *e;
1449
1450 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1451 e->next = pool_strs;
1452 pool_strs = e;
1453 return e->data;
1454 }
1455
1456 static char *
1457 def_pool_strdup (const char *str)
1458 {
1459 char *s;
1460 size_t len;
1461 if (!str)
1462 return NULL;
1463 len = strlen (str) + 1;
1464 s = def_pool_alloc (len);
1465 memcpy (s, str, len);
1466 return s;
1467 }
1468
1469 static void
1470 def_pool_free (void)
1471 {
1472 def_pool_str *p;
1473 while ((p = pool_strs) != NULL)
1474 {
1475 pool_strs = p->next;
1476 free (p);
1477 }
1478 }
This page took 0.063254 seconds and 5 git commands to generate.