2010-11-23 Phil Muldoon <pmuldoon@redhat.com>
[deliverable/binutils-gdb.git] / ld / deffilep.y
CommitLineData
252b5132
RH
1%{ /* deffilep.y - parser for .def files */
2
aa820537
AM
3/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
252b5132 5
a35bc64f 6 This file is part of GNU Binutils.
252b5132 7
a35bc64f
NC
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
f96b4a7b 10 the Free Software Foundation; either version 3 of the License, or
a35bc64f 11 (at your option) any later version.
252b5132 12
a35bc64f
NC
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.
252b5132 17
a35bc64f
NC
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
f96b4a7b
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
3db64b00 23#include "sysdep.h"
252b5132 24#include "libiberty.h"
3882b010 25#include "safe-ctype.h"
252b5132 26#include "bfd.h"
252b5132
RH
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
a35bc64f 40 generators need to be fixed instead of adding those names to this list. */
252b5132
RH
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
a35bc64f
NC
69#define yyreds def_reds /* With YYDEBUG defined. */
70#define yytoks def_toks /* With YYDEBUG defined. */
252b5132
RH
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
1579bae1 81static void def_description (const char *);
7fcab871 82static void def_exports (const char *, const char *, int, int, const char *);
1579bae1
AM
83static void def_heapsize (int, int);
84static void def_import (const char *, const char *, const char *, const char *,
7fcab871 85 int, const char *);
a880c748 86static void def_image_name (const char *, int, int);
1579bae1
AM
87static void def_section (const char *, int);
88static void def_section_alt (const char *, const char *);
89static void def_stacksize (int, int);
90static void def_version (int, int);
91static void def_directive (char *);
c1711530 92static void def_aligncomm (char *str, int align);
1579bae1
AM
93static int def_parse (void);
94static int def_error (const char *);
95static int def_lex (void);
252b5132
RH
96
97static int lex_forced_token = 0;
98static const char *lex_parse_string = 0;
99static const char *lex_parse_string_end = 0;
100
101%}
102
103%union {
104 char *id;
105 int number;
05056a8d 106 char *digits;
252b5132
RH
107};
108
8e58566f 109%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
655f76a2 110%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
c1711530 111%token PRIVATEU PRIVATEL ALIGNCOMM
7fcab871 112%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
252b5132 113%token <id> ID
05056a8d
DK
114%token <digits> DIGITS
115%type <number> NUMBER
116%type <digits> opt_digits
252b5132
RH
117%type <number> opt_base opt_ordinal
118%type <number> attr attr_list opt_number exp_opt_list exp_opt
05056a8d 119%type <id> opt_name opt_equal_name dot_name anylang_id opt_id
7fcab871 120%type <id> opt_equalequal_name
252b5132
RH
121
122%%
123
124start: start command
125 | command
126 ;
127
128command:
a880c748
DS
129 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
130 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
252b5132 131 | DESCRIPTION ID { def_description ($2);}
8e58566f 132 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
252b5132
RH
133 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
134 | CODE attr_list { def_section ("CODE", $2);}
7c9e78f8 135 | DATAU attr_list { def_section ("DATA", $2);}
252b5132
RH
136 | SECTIONS seclist
137 | EXPORTS explist
138 | IMPORTS implist
139 | VERSIONK NUMBER { def_version ($2, 0);}
140 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
141 | DIRECTIVE ID { def_directive ($2);}
05056a8d 142 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
252b5132
RH
143 ;
144
145
146explist:
147 /* EMPTY */
148 | expline
149 | explist expline
150 ;
151
152expline:
7c9e78f8
DD
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 mandates <expsym>,<expoptlist>. */
7fcab871
KT
156 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
157 { def_exports ($1, $2, $3, $5, $7); }
252b5132
RH
158 ;
159exp_opt_list:
7c9e78f8
DD
160 /* The opt_comma is necessary to support both the usual
161 DEF file syntax as well as .drectve syntax which
162 allows for comma separated opt list. */
163 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
252b5132
RH
164 | { $$ = 0; }
165 ;
166exp_opt:
7c9e78f8
DD
167 NONAMEU { $$ = 1; }
168 | NONAMEL { $$ = 1; }
169 | CONSTANTU { $$ = 2; }
170 | CONSTANTL { $$ = 2; }
171 | DATAU { $$ = 4; }
172 | DATAL { $$ = 4; }
173 | PRIVATEU { $$ = 8; }
174 | PRIVATEL { $$ = 8; }
252b5132
RH
175 ;
176implist:
177 implist impline
178 | impline
179 ;
180
181impline:
7fcab871
KT
182 ID '=' ID '.' ID '.' ID opt_equalequal_name
183 { def_import ($1, $3, $5, $7, -1, $8); }
184 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
185 { def_import ($1, $3, $5, 0, $7, $8); }
186 | ID '=' ID '.' ID opt_equalequal_name
187 { def_import ($1, $3, 0, $5, -1, $6); }
188 | ID '=' ID '.' NUMBER opt_equalequal_name
189 { def_import ($1, $3, 0, 0, $5, $6); }
190 | ID '.' ID '.' ID opt_equalequal_name
191 { def_import( 0, $1, $3, $5, -1, $6); }
192 | ID '.' ID opt_equalequal_name
193 { def_import ( 0, $1, 0, $3, -1, $4); }
252b5132
RH
194;
195
196seclist:
197 seclist secline
198 | secline
199 ;
200
201secline:
202 ID attr_list { def_section ($1, $2);}
203 | ID ID { def_section_alt ($1, $2);}
204 ;
205
206attr_list:
207 attr_list opt_comma attr { $$ = $1 | $3; }
208 | attr { $$ = $1; }
209 ;
210
211opt_comma:
212 ','
213 |
214 ;
215opt_number: ',' NUMBER { $$=$2;}
216 | { $$=-1;}
217 ;
218
219attr:
220 READ { $$ = 1;}
221 | WRITE { $$ = 2;}
222 | EXECUTE { $$=4;}
223 | SHARED { $$=8;}
224 ;
225
226opt_name: ID { $$ = $1; }
770c040b
KT
227 | '.' ID
228 {
229 char *name = xmalloc (strlen ($2) + 2);
230 sprintf (name, ".%s", $2);
231 $$ = name;
232 }
5aaace27
NC
233 | ID '.' ID
234 {
1579bae1 235 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
5aaace27
NC
236 sprintf (name, "%s.%s", $1, $3);
237 $$ = name;
238 }
239 | { $$ = ""; }
252b5132
RH
240 ;
241
7fcab871
KT
242opt_equalequal_name: EQUAL ID { $$ = $2; }
243 | { $$ = 0; }
244 ;
245
252b5132
RH
246opt_ordinal:
247 '@' NUMBER { $$ = $2;}
248 | { $$ = -1;}
249 ;
250
251opt_equal_name:
053c44e1 252 '=' dot_name { $$ = $2; }
252b5132
RH
253 | { $$ = 0; }
254 ;
255
256opt_base: BASE '=' NUMBER { $$ = $3;}
4064c856 257 | { $$ = -1;}
252b5132
RH
258 ;
259
053c44e1 260dot_name: ID { $$ = $1; }
770c040b
KT
261 | '.' ID
262 {
263 char *name = xmalloc (strlen ($2) + 2);
264 sprintf (name, ".%s", $2);
265 $$ = name;
266 }
053c44e1
DS
267 | dot_name '.' ID
268 {
1579bae1 269 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
053c44e1
DS
270 sprintf (name, "%s.%s", $1, $3);
271 $$ = name;
272 }
273 ;
05056a8d
DK
274
275anylang_id: ID { $$ = $1; }
770c040b
KT
276 | '.' ID
277 {
278 char *id = xmalloc (strlen ($2) + 2);
279 sprintf (id, ".%s", $2);
280 $$ = id;
281 }
05056a8d
DK
282 | anylang_id '.' opt_digits opt_id
283 {
284 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
285 sprintf (id, "%s.%s%s", $1, $3, $4);
286 $$ = id;
287 }
288 ;
289
290opt_digits: DIGITS { $$ = $1; }
291 | { $$ = ""; }
292 ;
293
294opt_id: ID { $$ = $1; }
295 | { $$ = ""; }
296 ;
297
298NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
252b5132
RH
299
300%%
301
302/*****************************************************************************
303 API
304 *****************************************************************************/
305
306static FILE *the_file;
307static const char *def_filename;
308static int linenumber;
309static def_file *def;
310static int saw_newline;
311
312struct directive
313 {
314 struct directive *next;
315 char *name;
316 int len;
317 };
318
319static struct directive *directives = 0;
320
321def_file *
1579bae1 322def_file_empty (void)
252b5132 323{
1579bae1 324 def_file *rv = xmalloc (sizeof (def_file));
252b5132
RH
325 memset (rv, 0, sizeof (def_file));
326 rv->is_dll = -1;
1579bae1 327 rv->base_address = (bfd_vma) -1;
252b5132
RH
328 rv->stack_reserve = rv->stack_commit = -1;
329 rv->heap_reserve = rv->heap_commit = -1;
330 rv->version_major = rv->version_minor = -1;
331 return rv;
332}
333
334def_file *
1579bae1 335def_file_parse (const char *filename, def_file *add_to)
252b5132
RH
336{
337 struct directive *d;
338
339 the_file = fopen (filename, "r");
340 def_filename = filename;
341 linenumber = 1;
342 if (!the_file)
343 {
344 perror (filename);
345 return 0;
346 }
347 if (add_to)
348 {
349 def = add_to;
350 }
351 else
352 {
353 def = def_file_empty ();
354 }
355
356 saw_newline = 1;
357 if (def_parse ())
358 {
359 def_file_free (def);
360 fclose (the_file);
361 return 0;
362 }
363
364 fclose (the_file);
365
366 for (d = directives; d; d = d->next)
367 {
368#if TRACE
369 printf ("Adding directive %08x `%s'\n", d->name, d->name);
370#endif
371 def_file_add_directive (def, d->name, d->len);
372 }
373
374 return def;
375}
376
377void
91d6fa6a 378def_file_free (def_file *fdef)
252b5132
RH
379{
380 int i;
a35bc64f 381
91d6fa6a 382 if (!fdef)
252b5132 383 return;
91d6fa6a
NC
384 if (fdef->name)
385 free (fdef->name);
386 if (fdef->description)
387 free (fdef->description);
252b5132 388
91d6fa6a 389 if (fdef->section_defs)
252b5132 390 {
91d6fa6a 391 for (i = 0; i < fdef->num_section_defs; i++)
252b5132 392 {
91d6fa6a
NC
393 if (fdef->section_defs[i].name)
394 free (fdef->section_defs[i].name);
395 if (fdef->section_defs[i].class)
396 free (fdef->section_defs[i].class);
252b5132 397 }
91d6fa6a 398 free (fdef->section_defs);
252b5132
RH
399 }
400
91d6fa6a 401 if (fdef->exports)
252b5132 402 {
b41d91a7 403 for (i = 0; i < fdef->num_exports; i++)
252b5132 404 {
91d6fa6a
NC
405 if (fdef->exports[i].internal_name
406 && fdef->exports[i].internal_name != fdef->exports[i].name)
407 free (fdef->exports[i].internal_name);
408 if (fdef->exports[i].name)
409 free (fdef->exports[i].name);
410 if (fdef->exports[i].its_name)
411 free (fdef->exports[i].its_name);
252b5132 412 }
91d6fa6a 413 free (fdef->exports);
252b5132
RH
414 }
415
91d6fa6a 416 if (fdef->imports)
252b5132 417 {
91d6fa6a 418 for (i = 0; i < fdef->num_imports; i++)
252b5132 419 {
91d6fa6a
NC
420 if (fdef->imports[i].internal_name
421 && fdef->imports[i].internal_name != fdef->imports[i].name)
422 free (fdef->imports[i].internal_name);
423 if (fdef->imports[i].name)
424 free (fdef->imports[i].name);
425 if (fdef->imports[i].its_name)
426 free (fdef->imports[i].its_name);
252b5132 427 }
91d6fa6a 428 free (fdef->imports);
252b5132
RH
429 }
430
91d6fa6a 431 while (fdef->modules)
252b5132 432 {
91d6fa6a
NC
433 def_file_module *m = fdef->modules;
434
435 fdef->modules = fdef->modules->next;
252b5132
RH
436 free (m);
437 }
438
91d6fa6a 439 while (fdef->aligncomms)
c1711530 440 {
91d6fa6a
NC
441 def_file_aligncomm *c = fdef->aligncomms;
442
443 fdef->aligncomms = fdef->aligncomms->next;
c1711530
DK
444 free (c->symbol_name);
445 free (c);
446 }
447
91d6fa6a 448 free (fdef);
252b5132
RH
449}
450
451#ifdef DEF_FILE_PRINT
452void
91d6fa6a 453def_file_print (FILE *file, def_file *fdef)
252b5132
RH
454{
455 int i;
a35bc64f 456
91d6fa6a
NC
457 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
458 if (fdef->name)
459 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
460 if (fdef->is_dll != -1)
461 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
462 if (fdef->base_address != (bfd_vma) -1)
463 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
464 if (fdef->description)
465 fprintf (file, " description: `%s'\n", fdef->description);
466 if (fdef->stack_reserve != -1)
467 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
468 if (fdef->stack_commit != -1)
469 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
470 if (fdef->heap_reserve != -1)
471 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
472 if (fdef->heap_commit != -1)
473 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
474
475 if (fdef->num_section_defs > 0)
252b5132
RH
476 {
477 fprintf (file, " section defs:\n");
a35bc64f 478
91d6fa6a 479 for (i = 0; i < fdef->num_section_defs; i++)
252b5132
RH
480 {
481 fprintf (file, " name: `%s', class: `%s', flags:",
91d6fa6a
NC
482 fdef->section_defs[i].name, fdef->section_defs[i].class);
483 if (fdef->section_defs[i].flag_read)
252b5132 484 fprintf (file, " R");
91d6fa6a 485 if (fdef->section_defs[i].flag_write)
252b5132 486 fprintf (file, " W");
91d6fa6a 487 if (fdef->section_defs[i].flag_execute)
252b5132 488 fprintf (file, " X");
91d6fa6a 489 if (fdef->section_defs[i].flag_shared)
252b5132
RH
490 fprintf (file, " S");
491 fprintf (file, "\n");
492 }
493 }
494
91d6fa6a 495 if (fdef->num_exports > 0)
252b5132
RH
496 {
497 fprintf (file, " exports:\n");
a35bc64f 498
91d6fa6a 499 for (i = 0; i < fdef->num_exports; i++)
252b5132
RH
500 {
501 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
91d6fa6a
NC
502 fdef->exports[i].name, fdef->exports[i].internal_name,
503 fdef->exports[i].ordinal);
504 if (fdef->exports[i].flag_private)
252b5132 505 fprintf (file, " P");
91d6fa6a 506 if (fdef->exports[i].flag_constant)
252b5132 507 fprintf (file, " C");
91d6fa6a 508 if (fdef->exports[i].flag_noname)
252b5132 509 fprintf (file, " N");
91d6fa6a 510 if (fdef->exports[i].flag_data)
252b5132
RH
511 fprintf (file, " D");
512 fprintf (file, "\n");
513 }
514 }
515
91d6fa6a 516 if (fdef->num_imports > 0)
252b5132
RH
517 {
518 fprintf (file, " imports:\n");
a35bc64f 519
91d6fa6a 520 for (i = 0; i < fdef->num_imports; i++)
252b5132
RH
521 {
522 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
91d6fa6a
NC
523 fdef->imports[i].internal_name,
524 fdef->imports[i].module,
525 fdef->imports[i].name,
526 fdef->imports[i].ordinal);
252b5132
RH
527 }
528 }
a35bc64f 529
91d6fa6a
NC
530 if (fdef->version_major != -1)
531 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
a35bc64f 532
b41d91a7 533 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
252b5132
RH
534}
535#endif
536
537def_file_export *
91d6fa6a 538def_file_add_export (def_file *fdef,
1579bae1
AM
539 const char *external_name,
540 const char *internal_name,
7fcab871
KT
541 int ordinal,
542 const char *its_name)
252b5132
RH
543{
544 def_file_export *e;
91d6fa6a 545 int max_exports = ROUND_UP(fdef->num_exports, 32);
a35bc64f 546
91d6fa6a 547 if (fdef->num_exports >= max_exports)
252b5132 548 {
91d6fa6a
NC
549 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
550 if (fdef->exports)
551 fdef->exports = xrealloc (fdef->exports,
1579bae1 552 max_exports * sizeof (def_file_export));
252b5132 553 else
91d6fa6a 554 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
252b5132 555 }
91d6fa6a 556 e = fdef->exports + fdef->num_exports;
252b5132
RH
557 memset (e, 0, sizeof (def_file_export));
558 if (internal_name && !external_name)
559 external_name = internal_name;
560 if (external_name && !internal_name)
561 internal_name = external_name;
562 e->name = xstrdup (external_name);
563 e->internal_name = xstrdup (internal_name);
7fcab871 564 e->its_name = (its_name ? xstrdup (its_name) : NULL);
252b5132 565 e->ordinal = ordinal;
91d6fa6a 566 fdef->num_exports++;
252b5132
RH
567 return e;
568}
569
a35bc64f 570def_file_module *
91d6fa6a 571def_get_module (def_file *fdef, const char *name)
a35bc64f
NC
572{
573 def_file_module *s;
574
91d6fa6a 575 for (s = fdef->modules; s; s = s->next)
a35bc64f
NC
576 if (strcmp (s->name, name) == 0)
577 return s;
578
1579bae1 579 return NULL;
a35bc64f
NC
580}
581
252b5132 582static def_file_module *
91d6fa6a 583def_stash_module (def_file *fdef, const char *name)
252b5132
RH
584{
585 def_file_module *s;
a35bc64f 586
91d6fa6a 587 if ((s = def_get_module (fdef, name)) != NULL)
252b5132 588 return s;
1579bae1 589 s = xmalloc (sizeof (def_file_module) + strlen (name));
b41d91a7 590 s->next = fdef->modules;
91d6fa6a 591 fdef->modules = s;
252b5132
RH
592 s->user_data = 0;
593 strcpy (s->name, name);
594 return s;
595}
596
597def_file_import *
91d6fa6a 598def_file_add_import (def_file *fdef,
1579bae1
AM
599 const char *name,
600 const char *module,
601 int ordinal,
7fcab871
KT
602 const char *internal_name,
603 const char *its_name)
252b5132
RH
604{
605 def_file_import *i;
91d6fa6a 606 int max_imports = ROUND_UP (fdef->num_imports, 16);
a35bc64f 607
91d6fa6a 608 if (fdef->num_imports >= max_imports)
252b5132 609 {
91d6fa6a 610 max_imports = ROUND_UP (fdef->num_imports+1, 16);
a35bc64f 611
91d6fa6a
NC
612 if (fdef->imports)
613 fdef->imports = xrealloc (fdef->imports,
1579bae1 614 max_imports * sizeof (def_file_import));
252b5132 615 else
91d6fa6a 616 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
252b5132 617 }
91d6fa6a 618 i = fdef->imports + fdef->num_imports;
252b5132
RH
619 memset (i, 0, sizeof (def_file_import));
620 if (name)
621 i->name = xstrdup (name);
622 if (module)
b41d91a7 623 i->module = def_stash_module (fdef, module);
252b5132
RH
624 i->ordinal = ordinal;
625 if (internal_name)
626 i->internal_name = xstrdup (internal_name);
627 else
628 i->internal_name = i->name;
7fcab871 629 i->its_name = (its_name ? xstrdup (its_name) : NULL);
91d6fa6a 630 fdef->num_imports++;
a35bc64f 631
252b5132
RH
632 return i;
633}
634
635struct
636{
637 char *param;
638 int token;
639}
640diropts[] =
641{
642 { "-heap", HEAPSIZE },
8e58566f 643 { "-stack", STACKSIZE_K },
252b5132
RH
644 { "-attr", SECTIONS },
645 { "-export", EXPORTS },
c1711530 646 { "-aligncomm", ALIGNCOMM },
252b5132
RH
647 { 0, 0 }
648};
649
650void
1579bae1 651def_file_add_directive (def_file *my_def, const char *param, int len)
252b5132
RH
652{
653 def_file *save_def = def;
654 const char *pend = param + len;
dc17f155 655 char * tend = (char *) param;
252b5132
RH
656 int i;
657
658 def = my_def;
659
660 while (param < pend)
661 {
1579bae1
AM
662 while (param < pend
663 && (ISSPACE (*param) || *param == '\n' || *param == 0))
252b5132 664 param++;
a35bc64f 665
dc17f155
NC
666 if (param == pend)
667 break;
668
669 /* Scan forward until we encounter any of:
670 - the end of the buffer
671 - the start of a new option
672 - a newline seperating options
673 - a NUL seperating options. */
674 for (tend = (char *) (param + 1);
1579bae1
AM
675 (tend < pend
676 && !(ISSPACE (tend[-1]) && *tend == '-')
677 && *tend != '\n' && *tend != 0);
a35bc64f
NC
678 tend++)
679 ;
252b5132
RH
680
681 for (i = 0; diropts[i].param; i++)
682 {
91d6fa6a 683 len = strlen (diropts[i].param);
a35bc64f 684
252b5132
RH
685 if (tend - param >= len
686 && strncmp (param, diropts[i].param, len) == 0
687 && (param[len] == ':' || param[len] == ' '))
688 {
689 lex_parse_string_end = tend;
690 lex_parse_string = param + len + 1;
691 lex_forced_token = diropts[i].token;
692 saw_newline = 0;
dc17f155
NC
693 if (def_parse ())
694 continue;
252b5132
RH
695 break;
696 }
697 }
698
699 if (!diropts[i].param)
dc17f155
NC
700 {
701 char saved;
702
703 saved = * tend;
704 * tend = 0;
705 /* xgettext:c-format */
706 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
707 * tend = saved;
708 }
a35bc64f 709
252b5132
RH
710 lex_parse_string = 0;
711 param = tend;
712 }
713
714 def = save_def;
715}
716
a35bc64f 717/* Parser Callbacks. */
252b5132
RH
718
719static void
a880c748 720def_image_name (const char *name, int base, int is_dll)
252b5132 721{
a2877985
DS
722 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
723 to do here. We retain the output filename specified on command line. */
724 if (*name)
725 {
726 const char* image_name = lbasename (name);
91d6fa6a 727
a2877985
DS
728 if (image_name != name)
729 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
730 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
731 name);
732 if (def->name)
733 free (def->name);
734 /* Append the default suffix, if none specified. */
735 if (strchr (image_name, '.') == 0)
736 {
737 const char * suffix = is_dll ? ".dll" : ".exe";
738
739 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
740 sprintf (def->name, "%s%s", image_name, suffix);
741 }
742 else
743 def->name = xstrdup (image_name);
744 }
745
746 /* Honor a BASE address statement, even if LIBRARY string is empty. */
252b5132 747 def->base_address = base;
a880c748 748 def->is_dll = is_dll;
252b5132
RH
749}
750
751static void
1579bae1 752def_description (const char *text)
252b5132
RH
753{
754 int len = def->description ? strlen (def->description) : 0;
a35bc64f 755
252b5132
RH
756 len += strlen (text) + 1;
757 if (def->description)
758 {
1579bae1 759 def->description = xrealloc (def->description, len);
252b5132
RH
760 strcat (def->description, text);
761 }
762 else
763 {
1579bae1 764 def->description = xmalloc (len);
252b5132
RH
765 strcpy (def->description, text);
766 }
767}
768
769static void
1579bae1 770def_stacksize (int reserve, int commit)
252b5132
RH
771{
772 def->stack_reserve = reserve;
773 def->stack_commit = commit;
774}
775
776static void
1579bae1 777def_heapsize (int reserve, int commit)
252b5132
RH
778{
779 def->heap_reserve = reserve;
780 def->heap_commit = commit;
781}
782
783static void
1579bae1 784def_section (const char *name, int attr)
252b5132
RH
785{
786 def_file_section *s;
1579bae1 787 int max_sections = ROUND_UP (def->num_section_defs, 4);
a35bc64f 788
252b5132
RH
789 if (def->num_section_defs >= max_sections)
790 {
1579bae1 791 max_sections = ROUND_UP (def->num_section_defs+1, 4);
a35bc64f 792
252b5132 793 if (def->section_defs)
1579bae1
AM
794 def->section_defs = xrealloc (def->section_defs,
795 max_sections * sizeof (def_file_import));
252b5132 796 else
1579bae1 797 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
252b5132
RH
798 }
799 s = def->section_defs + def->num_section_defs;
800 memset (s, 0, sizeof (def_file_section));
801 s->name = xstrdup (name);
802 if (attr & 1)
803 s->flag_read = 1;
804 if (attr & 2)
805 s->flag_write = 1;
806 if (attr & 4)
807 s->flag_execute = 1;
808 if (attr & 8)
809 s->flag_shared = 1;
810
811 def->num_section_defs++;
812}
813
814static void
1579bae1 815def_section_alt (const char *name, const char *attr)
252b5132
RH
816{
817 int aval = 0;
a35bc64f 818
252b5132
RH
819 for (; *attr; attr++)
820 {
821 switch (*attr)
822 {
823 case 'R':
824 case 'r':
825 aval |= 1;
826 break;
827 case 'W':
828 case 'w':
829 aval |= 2;
830 break;
831 case 'X':
832 case 'x':
833 aval |= 4;
834 break;
835 case 'S':
836 case 's':
837 aval |= 8;
838 break;
839 }
840 }
841 def_section (name, aval);
842}
843
844static void
1579bae1
AM
845def_exports (const char *external_name,
846 const char *internal_name,
847 int ordinal,
7fcab871
KT
848 int flags,
849 const char *its_name)
252b5132
RH
850{
851 def_file_export *dfe;
852
853 if (!internal_name && external_name)
854 internal_name = external_name;
855#if TRACE
856 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
857#endif
858
7fcab871
KT
859 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
860 its_name);
252b5132
RH
861 if (flags & 1)
862 dfe->flag_noname = 1;
863 if (flags & 2)
864 dfe->flag_constant = 1;
865 if (flags & 4)
866 dfe->flag_data = 1;
867 if (flags & 8)
868 dfe->flag_private = 1;
869}
870
871static void
1579bae1
AM
872def_import (const char *internal_name,
873 const char *module,
874 const char *dllext,
875 const char *name,
7fcab871
KT
876 int ordinal,
877 const char *its_name)
252b5132
RH
878{
879 char *buf = 0;
053c44e1
DS
880 const char *ext = dllext ? dllext : "dll";
881
1579bae1 882 buf = xmalloc (strlen (module) + strlen (ext) + 2);
053c44e1
DS
883 sprintf (buf, "%s.%s", module, ext);
884 module = buf;
252b5132 885
7fcab871 886 def_file_add_import (def, name, module, ordinal, internal_name, its_name);
252b5132
RH
887 if (buf)
888 free (buf);
889}
890
891static void
1579bae1 892def_version (int major, int minor)
252b5132
RH
893{
894 def->version_major = major;
895 def->version_minor = minor;
896}
897
898static void
1579bae1 899def_directive (char *str)
252b5132 900{
1579bae1 901 struct directive *d = xmalloc (sizeof (struct directive));
a35bc64f 902
252b5132
RH
903 d->next = directives;
904 directives = d;
905 d->name = xstrdup (str);
906 d->len = strlen (str);
907}
908
c1711530
DK
909static void
910def_aligncomm (char *str, int align)
911{
912 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
913
914 c->symbol_name = xstrdup (str);
915 c->alignment = (unsigned int) align;
916
917 c->next = def->aligncomms;
918 def->aligncomms = c;
919}
920
252b5132 921static int
1579bae1 922def_error (const char *err)
252b5132 923{
1579bae1
AM
924 einfo ("%P: %s:%d: %s\n",
925 def_filename ? def_filename : "<unknown-file>", linenumber, err);
252b5132
RH
926 return 0;
927}
928
929
a35bc64f 930/* Lexical Scanner. */
252b5132
RH
931
932#undef TRACE
933#define TRACE 0
934
a35bc64f 935/* Never freed, but always reused as needed, so no real leak. */
252b5132
RH
936static char *buffer = 0;
937static int buflen = 0;
938static int bufptr = 0;
939
940static void
1579bae1 941put_buf (char c)
252b5132
RH
942{
943 if (bufptr == buflen)
944 {
a35bc64f 945 buflen += 50; /* overly reasonable, eh? */
252b5132 946 if (buffer)
1579bae1 947 buffer = xrealloc (buffer, buflen + 1);
252b5132 948 else
1579bae1 949 buffer = xmalloc (buflen + 1);
252b5132
RH
950 }
951 buffer[bufptr++] = c;
a35bc64f 952 buffer[bufptr] = 0; /* not optimal, but very convenient. */
252b5132
RH
953}
954
955static struct
956{
957 char *name;
958 int token;
959}
960tokens[] =
961{
962 { "BASE", BASE },
963 { "CODE", CODE },
7c9e78f8
DD
964 { "CONSTANT", CONSTANTU },
965 { "constant", CONSTANTL },
966 { "DATA", DATAU },
967 { "data", DATAL },
252b5132
RH
968 { "DESCRIPTION", DESCRIPTION },
969 { "DIRECTIVE", DIRECTIVE },
970 { "EXECUTE", EXECUTE },
971 { "EXPORTS", EXPORTS },
972 { "HEAPSIZE", HEAPSIZE },
973 { "IMPORTS", IMPORTS },
974 { "LIBRARY", LIBRARY },
975 { "NAME", NAME },
7c9e78f8
DD
976 { "NONAME", NONAMEU },
977 { "noname", NONAMEL },
978 { "PRIVATE", PRIVATEU },
979 { "private", PRIVATEL },
252b5132
RH
980 { "READ", READ },
981 { "SECTIONS", SECTIONS },
982 { "SEGMENTS", SECTIONS },
983 { "SHARED", SHARED },
8e58566f 984 { "STACKSIZE", STACKSIZE_K },
252b5132
RH
985 { "VERSION", VERSIONK },
986 { "WRITE", WRITE },
987 { 0, 0 }
988};
989
990static int
1579bae1 991def_getc (void)
252b5132
RH
992{
993 int rv;
a35bc64f 994
252b5132
RH
995 if (lex_parse_string)
996 {
997 if (lex_parse_string >= lex_parse_string_end)
998 rv = EOF;
999 else
1000 rv = *lex_parse_string++;
1001 }
1002 else
1003 {
1004 rv = fgetc (the_file);
1005 }
1006 if (rv == '\n')
1007 saw_newline = 1;
1008 return rv;
1009}
1010
1011static int
1579bae1 1012def_ungetc (int c)
252b5132
RH
1013{
1014 if (lex_parse_string)
1015 {
1016 lex_parse_string--;
1017 return c;
1018 }
1019 else
1020 return ungetc (c, the_file);
1021}
1022
1023static int
1579bae1 1024def_lex (void)
252b5132
RH
1025{
1026 int c, i, q;
1027
1028 if (lex_forced_token)
1029 {
1030 i = lex_forced_token;
1031 lex_forced_token = 0;
1032#if TRACE
1033 printf ("lex: forcing token %d\n", i);
1034#endif
1035 return i;
1036 }
1037
1038 c = def_getc ();
1039
a35bc64f 1040 /* Trim leading whitespace. */
252b5132
RH
1041 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1042 c = def_getc ();
1043
1044 if (c == EOF)
1045 {
1046#if TRACE
1047 printf ("lex: EOF\n");
1048#endif
1049 return 0;
1050 }
1051
1052 if (saw_newline && c == ';')
1053 {
1054 do
1055 {
1056 c = def_getc ();
1057 }
1058 while (c != EOF && c != '\n');
1059 if (c == '\n')
1060 return def_lex ();
1061 return 0;
1062 }
a35bc64f
NC
1063
1064 /* Must be something else. */
252b5132
RH
1065 saw_newline = 0;
1066
3882b010 1067 if (ISDIGIT (c))
252b5132
RH
1068 {
1069 bufptr = 0;
3882b010 1070 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
1071 {
1072 put_buf (c);
1073 c = def_getc ();
1074 }
1075 if (c != EOF)
1076 def_ungetc (c);
05056a8d 1077 yylval.digits = xstrdup (buffer);
252b5132 1078#if TRACE
05056a8d 1079 printf ("lex: `%s' returns DIGITS\n", buffer);
252b5132 1080#endif
05056a8d 1081 return DIGITS;
252b5132
RH
1082 }
1083
c9e38879 1084 if (ISALPHA (c) || strchr ("$:-_?@", c))
252b5132
RH
1085 {
1086 bufptr = 0;
c9e38879
NC
1087 q = c;
1088 put_buf (c);
1089 c = def_getc ();
1090
1091 if (q == '@')
1092 {
1093 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1094 return (q);
1095 else if (ISDIGIT (c)) /* '@' followed by digit. */
1096 {
1097 def_ungetc (c);
1098 return (q);
1099 }
1100#if TRACE
1101 printf ("lex: @ returns itself\n");
1102#endif
1103 }
1104
424908eb 1105 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
252b5132
RH
1106 {
1107 put_buf (c);
1108 c = def_getc ();
1109 }
1110 if (c != EOF)
1111 def_ungetc (c);
c9e38879
NC
1112 if (ISALPHA (q)) /* Check for tokens. */
1113 {
1114 for (i = 0; tokens[i].name; i++)
1115 if (strcmp (tokens[i].name, buffer) == 0)
1116 {
252b5132 1117#if TRACE
c9e38879 1118 printf ("lex: `%s' is a string token\n", buffer);
252b5132 1119#endif
c9e38879
NC
1120 return tokens[i].token;
1121 }
1122 }
252b5132
RH
1123#if TRACE
1124 printf ("lex: `%s' returns ID\n", buffer);
1125#endif
1126 yylval.id = xstrdup (buffer);
1127 return ID;
1128 }
1129
1130 if (c == '\'' || c == '"')
1131 {
1132 q = c;
1133 c = def_getc ();
1134 bufptr = 0;
a35bc64f 1135
252b5132
RH
1136 while (c != EOF && c != q)
1137 {
1138 put_buf (c);
1139 c = def_getc ();
1140 }
1141 yylval.id = xstrdup (buffer);
1142#if TRACE
1143 printf ("lex: `%s' returns ID\n", buffer);
1144#endif
1145 return ID;
1146 }
1147
7fcab871
KT
1148 if ( c == '=')
1149 {
1150 c = def_getc ();
1151 if (c == '=')
1152 {
1153#if TRACE
1154 printf ("lex: `==' returns EQUAL\n");
1155#endif
1156 return EQUAL;
1157 }
1158 def_ungetc (c);
1159#if TRACE
1160 printf ("lex: `=' returns itself\n");
1161#endif
1162 return '=';
1163 }
1164 if (c == '.' || c == ',')
252b5132
RH
1165 {
1166#if TRACE
1167 printf ("lex: `%c' returns itself\n", c);
1168#endif
1169 return c;
1170 }
1171
1172 if (c == '\n')
1173 {
1174 linenumber++;
1175 saw_newline = 1;
1176 }
1177
1178 /*printf ("lex: 0x%02x ignored\n", c); */
1179 return def_lex ();
1180}
This page took 0.558082 seconds and 4 git commands to generate.