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