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