1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "libiberty.h"
24 #include "safe-ctype.h"
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
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
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
62 #define yy_yys def_yys
63 #define yystate def_state
66 #define yy_yyv def_yyv
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined. */
70 #define yytoks def_toks /* With YYDEBUG defined. */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
81 static void def_description
(const char *);
82 static void def_exports
(const char *, const char *, int, int);
83 static void def_heapsize
(int, int);
84 static void def_import
(const char *, const char *, const char *, const char *,
86 static void def_image_name
(const char *, int, int);
87 static void def_section
(const char *, int);
88 static void def_section_alt
(const char *, const char *);
89 static void def_stacksize
(int, int);
90 static void def_version
(int, int);
91 static void def_directive
(char *);
92 static int def_parse
(void);
93 static int def_error
(const char *);
94 static int def_lex
(void);
96 static int lex_forced_token
= 0;
97 static const char *lex_parse_string
= 0;
98 static const char *lex_parse_string_end
= 0;
107 %token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL
108 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
109 %token PRIVATEU PRIVATEL
110 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
112 %token
<number
> NUMBER
113 %type
<number
> opt_base opt_ordinal
114 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
115 %type
<id
> opt_name opt_equal_name dot_name
124 NAME opt_name opt_base
{ def_image_name
($2, $3, 0); }
125 | LIBRARY opt_name opt_base
{ def_image_name
($2, $3, 1); }
126 | DESCRIPTION ID
{ def_description
($2);}
127 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
128 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
129 | CODE attr_list
{ def_section
("CODE", $2);}
130 | DATAU attr_list
{ def_section
("DATA", $2);}
134 | VERSIONK NUMBER
{ def_version
($2, 0);}
135 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
136 | DIRECTIVE ID
{ def_directive
($2);}
147 /* The opt_comma is necessary to support both the usual
148 DEF file syntax as well as .drectve syntax which
149 mandates <expsym>,<expoptlist>. */
150 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
151 { def_exports
($1, $2, $3, $5); }
154 /* The opt_comma is necessary to support both the usual
155 DEF file syntax as well as .drectve syntax which
156 allows for comma separated opt list. */
157 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
162 | NONAMEL
{ $$
= 1; }
163 | CONSTANTU
{ $$
= 2; }
164 | CONSTANTL
{ $$
= 2; }
167 | PRIVATEU
{ $$
= 8; }
168 | PRIVATEL
{ $$
= 8; }
176 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
177 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
178 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
179 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
180 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
181 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
190 ID attr_list
{ def_section
($1, $2);}
191 | ID ID
{ def_section_alt
($1, $2);}
195 attr_list opt_comma attr
{ $$
= $1 |
$3; }
203 opt_number: ',' NUMBER
{ $$
=$2;}
214 opt_name: ID
{ $$
= $1; }
217 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
218 sprintf
(name
, "%s.%s", $1, $3);
225 '@' NUMBER
{ $$
= $2;}
230 '=' dot_name
{ $$
= $2; }
234 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
238 dot_name: ID
{ $$
= $1; }
241 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
242 sprintf
(name
, "%s.%s", $1, $3);
250 /*****************************************************************************
252 *****************************************************************************/
254 static FILE *the_file
;
255 static const char *def_filename
;
256 static int linenumber
;
257 static def_file
*def
;
258 static int saw_newline
;
262 struct directive
*next
;
267 static struct directive
*directives
= 0;
270 def_file_empty
(void)
272 def_file
*rv
= xmalloc
(sizeof
(def_file
));
273 memset
(rv
, 0, sizeof
(def_file
));
275 rv
->base_address
= (bfd_vma
) -1;
276 rv
->stack_reserve
= rv
->stack_commit
= -1;
277 rv
->heap_reserve
= rv
->heap_commit
= -1;
278 rv
->version_major
= rv
->version_minor
= -1;
283 def_file_parse
(const char *filename
, def_file
*add_to
)
287 the_file
= fopen
(filename
, "r");
288 def_filename
= filename
;
301 def
= def_file_empty
();
314 for
(d
= directives
; d
; d
= d
->next
)
317 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
319 def_file_add_directive
(def
, d
->name
, d
->len
);
326 def_file_free
(def_file
*def
)
334 if
(def
->description
)
335 free
(def
->description
);
337 if
(def
->section_defs
)
339 for
(i
= 0; i
< def
->num_section_defs
; i
++)
341 if
(def
->section_defs
[i
].name
)
342 free
(def
->section_defs
[i
].name
);
343 if
(def
->section_defs
[i
].class
)
344 free
(def
->section_defs
[i
].class
);
346 free
(def
->section_defs
);
351 for
(i
= 0; i
< def
->num_exports
; i
++)
353 if
(def
->exports
[i
].internal_name
354 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
355 free
(def
->exports
[i
].internal_name
);
356 if
(def
->exports
[i
].name
)
357 free
(def
->exports
[i
].name
);
364 for
(i
= 0; i
< def
->num_imports
; i
++)
366 if
(def
->imports
[i
].internal_name
367 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
368 free
(def
->imports
[i
].internal_name
);
369 if
(def
->imports
[i
].name
)
370 free
(def
->imports
[i
].name
);
377 def_file_module
*m
= def
->modules
;
378 def
->modules
= def
->modules
->next
;
385 #ifdef DEF_FILE_PRINT
387 def_file_print
(FILE *file
, def_file
*def
)
391 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
393 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
394 if
(def
->is_dll
!= -1)
395 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
396 if
(def
->base_address
!= (bfd_vma
) -1)
397 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
398 if
(def
->description
)
399 fprintf
(file
, " description: `%s'\n", def
->description
);
400 if
(def
->stack_reserve
!= -1)
401 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
402 if
(def
->stack_commit
!= -1)
403 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
404 if
(def
->heap_reserve
!= -1)
405 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
406 if
(def
->heap_commit
!= -1)
407 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
409 if
(def
->num_section_defs
> 0)
411 fprintf
(file
, " section defs:\n");
413 for
(i
= 0; i
< def
->num_section_defs
; i
++)
415 fprintf
(file
, " name: `%s', class: `%s', flags:",
416 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
417 if
(def
->section_defs
[i
].flag_read
)
418 fprintf
(file
, " R");
419 if
(def
->section_defs
[i
].flag_write
)
420 fprintf
(file
, " W");
421 if
(def
->section_defs
[i
].flag_execute
)
422 fprintf
(file
, " X");
423 if
(def
->section_defs
[i
].flag_shared
)
424 fprintf
(file
, " S");
425 fprintf
(file
, "\n");
429 if
(def
->num_exports
> 0)
431 fprintf
(file
, " exports:\n");
433 for
(i
= 0; i
< def
->num_exports
; i
++)
435 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
436 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
437 def
->exports
[i
].ordinal
);
438 if
(def
->exports
[i
].flag_private
)
439 fprintf
(file
, " P");
440 if
(def
->exports
[i
].flag_constant
)
441 fprintf
(file
, " C");
442 if
(def
->exports
[i
].flag_noname
)
443 fprintf
(file
, " N");
444 if
(def
->exports
[i
].flag_data
)
445 fprintf
(file
, " D");
446 fprintf
(file
, "\n");
450 if
(def
->num_imports
> 0)
452 fprintf
(file
, " imports:\n");
454 for
(i
= 0; i
< def
->num_imports
; i
++)
456 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
457 def
->imports
[i
].internal_name
,
458 def
->imports
[i
].module
,
459 def
->imports
[i
].name
,
460 def
->imports
[i
].ordinal
);
464 if
(def
->version_major
!= -1)
465 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
467 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
472 def_file_add_export
(def_file
*def
,
473 const char *external_name
,
474 const char *internal_name
,
478 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
480 if
(def
->num_exports
>= max_exports
)
482 max_exports
= ROUND_UP
(def
->num_exports
+ 1, 32);
484 def
->exports
= xrealloc
(def
->exports
,
485 max_exports
* sizeof
(def_file_export
));
487 def
->exports
= xmalloc
(max_exports
* sizeof
(def_file_export
));
489 e
= def
->exports
+ def
->num_exports
;
490 memset
(e
, 0, sizeof
(def_file_export
));
491 if
(internal_name
&& !external_name
)
492 external_name
= internal_name
;
493 if
(external_name
&& !internal_name
)
494 internal_name
= external_name
;
495 e
->name
= xstrdup
(external_name
);
496 e
->internal_name
= xstrdup
(internal_name
);
497 e
->ordinal
= ordinal
;
503 def_get_module
(def_file
*def
, const char *name
)
507 for
(s
= def
->modules
; s
; s
= s
->next
)
508 if
(strcmp
(s
->name
, name
) == 0)
514 static def_file_module
*
515 def_stash_module
(def_file
*def
, const char *name
)
519 if
((s
= def_get_module
(def
, name
)) != NULL
)
521 s
= xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
522 s
->next
= def
->modules
;
525 strcpy
(s
->name
, name
);
530 def_file_add_import
(def_file
*def
,
534 const char *internal_name
)
537 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
539 if
(def
->num_imports
>= max_imports
)
541 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
544 def
->imports
= xrealloc
(def
->imports
,
545 max_imports
* sizeof
(def_file_import
));
547 def
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
549 i
= def
->imports
+ def
->num_imports
;
550 memset
(i
, 0, sizeof
(def_file_import
));
552 i
->name
= xstrdup
(name
);
554 i
->module
= def_stash_module
(def
, module
);
555 i
->ordinal
= ordinal
;
557 i
->internal_name
= xstrdup
(internal_name
);
559 i
->internal_name
= i
->name
;
572 { "-heap", HEAPSIZE
},
573 { "-stack", STACKSIZE
},
574 { "-attr", SECTIONS
},
575 { "-export", EXPORTS
},
580 def_file_add_directive
(def_file
*my_def
, const char *param
, int len
)
582 def_file
*save_def
= def
;
583 const char *pend
= param
+ len
;
584 char * tend
= (char *) param
;
592 && (ISSPACE
(*param
) ||
*param
== '\n' ||
*param
== 0))
598 /* Scan forward until we encounter any of:
599 - the end of the buffer
600 - the start of a new option
601 - a newline seperating options
602 - a NUL seperating options. */
603 for
(tend
= (char *) (param
+ 1);
605 && !(ISSPACE
(tend
[-1]) && *tend
== '-')
606 && *tend
!= '\n' && *tend
!= 0);
610 for
(i
= 0; diropts
[i
].param
; i
++)
612 int len
= strlen
(diropts
[i
].param
);
614 if
(tend
- param
>= len
615 && strncmp
(param
, diropts
[i
].param
, len
) == 0
616 && (param
[len
] == ':' || param
[len
] == ' '))
618 lex_parse_string_end
= tend
;
619 lex_parse_string
= param
+ len
+ 1;
620 lex_forced_token
= diropts
[i
].token
;
628 if
(!diropts
[i
].param
)
634 /* xgettext:c-format */
635 einfo
(_
("Warning: .drectve `%s' unrecognized\n"), param
);
639 lex_parse_string
= 0;
646 /* Parser Callbacks. */
649 def_image_name
(const char *name
, int base
, int is_dll
)
651 const char* image_name
= lbasename
(name
);
652 if
(image_name
!= name
)
653 einfo
("%s:%d: Warning: path components stripped from %s, '%s'\n",
654 def_filename
, linenumber
, is_dll ?
"LIBRARY" : "NAME", name
);
657 /* Append the default suffix, if none specified. */
658 if
(strchr
(image_name
, '.') == 0)
660 const char * suffix
= is_dll ?
".dll" : ".exe";
662 def
->name
= xmalloc
(strlen
(image_name
) + strlen
(suffix
) + 1);
663 sprintf
(def
->name
, "%s%s", image_name
, suffix
);
666 def
->name
= xstrdup
(image_name
);
667 def
->base_address
= base
;
668 def
->is_dll
= is_dll
;
672 def_description
(const char *text
)
674 int len
= def
->description ? strlen
(def
->description
) : 0;
676 len
+= strlen
(text
) + 1;
677 if
(def
->description
)
679 def
->description
= xrealloc
(def
->description
, len
);
680 strcat
(def
->description
, text
);
684 def
->description
= xmalloc
(len
);
685 strcpy
(def
->description
, text
);
690 def_stacksize
(int reserve
, int commit
)
692 def
->stack_reserve
= reserve
;
693 def
->stack_commit
= commit
;
697 def_heapsize
(int reserve
, int commit
)
699 def
->heap_reserve
= reserve
;
700 def
->heap_commit
= commit
;
704 def_section
(const char *name
, int attr
)
707 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
709 if
(def
->num_section_defs
>= max_sections
)
711 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
713 if
(def
->section_defs
)
714 def
->section_defs
= xrealloc
(def
->section_defs
,
715 max_sections
* sizeof
(def_file_import
));
717 def
->section_defs
= xmalloc
(max_sections
* sizeof
(def_file_import
));
719 s
= def
->section_defs
+ def
->num_section_defs
;
720 memset
(s
, 0, sizeof
(def_file_section
));
721 s
->name
= xstrdup
(name
);
731 def
->num_section_defs
++;
735 def_section_alt
(const char *name
, const char *attr
)
739 for
(; *attr
; attr
++)
761 def_section
(name
, aval
);
765 def_exports
(const char *external_name
,
766 const char *internal_name
,
770 def_file_export
*dfe
;
772 if
(!internal_name
&& external_name
)
773 internal_name
= external_name
;
775 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
778 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
780 dfe
->flag_noname
= 1;
782 dfe
->flag_constant
= 1;
786 dfe
->flag_private
= 1;
790 def_import
(const char *internal_name
,
797 const char *ext
= dllext ? dllext
: "dll";
799 buf
= xmalloc
(strlen
(module
) + strlen
(ext
) + 2);
800 sprintf
(buf
, "%s.%s", module
, ext
);
803 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
809 def_version
(int major
, int minor
)
811 def
->version_major
= major
;
812 def
->version_minor
= minor
;
816 def_directive
(char *str
)
818 struct directive
*d
= xmalloc
(sizeof
(struct directive
));
820 d
->next
= directives
;
822 d
->name
= xstrdup
(str
);
823 d
->len
= strlen
(str
);
827 def_error
(const char *err
)
829 einfo
("%P: %s:%d: %s\n",
830 def_filename ? def_filename
: "<unknown-file>", linenumber
, err
);
835 /* Lexical Scanner. */
840 /* Never freed, but always reused as needed, so no real leak. */
841 static char *buffer
= 0;
842 static int buflen
= 0;
843 static int bufptr
= 0;
848 if
(bufptr
== buflen
)
850 buflen
+= 50; /* overly reasonable, eh? */
852 buffer
= xrealloc
(buffer
, buflen
+ 1);
854 buffer
= xmalloc
(buflen
+ 1);
856 buffer
[bufptr
++] = c
;
857 buffer
[bufptr
] = 0; /* not optimal, but very convenient. */
869 { "CONSTANT", CONSTANTU
},
870 { "constant", CONSTANTL
},
873 { "DESCRIPTION", DESCRIPTION
},
874 { "DIRECTIVE", DIRECTIVE
},
875 { "EXECUTE", EXECUTE
},
876 { "EXPORTS", EXPORTS
},
877 { "HEAPSIZE", HEAPSIZE
},
878 { "IMPORTS", IMPORTS
},
879 { "LIBRARY", LIBRARY
},
881 { "NONAME", NONAMEU
},
882 { "noname", NONAMEL
},
883 { "PRIVATE", PRIVATEU
},
884 { "private", PRIVATEL
},
886 { "SECTIONS", SECTIONS
},
887 { "SEGMENTS", SECTIONS
},
888 { "SHARED", SHARED
},
889 { "STACKSIZE", STACKSIZE
},
890 { "VERSION", VERSIONK
},
900 if
(lex_parse_string
)
902 if
(lex_parse_string
>= lex_parse_string_end
)
905 rv
= *lex_parse_string
++;
909 rv
= fgetc
(the_file
);
919 if
(lex_parse_string
)
925 return ungetc
(c
, the_file
);
933 if
(lex_forced_token
)
935 i
= lex_forced_token
;
936 lex_forced_token
= 0;
938 printf
("lex: forcing token %d\n", i
);
945 /* Trim leading whitespace. */
946 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
952 printf
("lex: EOF\n");
957 if
(saw_newline
&& c
== ';')
963 while
(c
!= EOF
&& c
!= '\n');
969 /* Must be something else. */
975 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
982 yylval.number
= strtoul
(buffer
, 0, 0);
984 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
989 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
998 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
1000 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
1006 printf
("lex: @ returns itself\n");
1010 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@", c
)))
1017 if
(ISALPHA
(q
)) /* Check for tokens. */
1019 for
(i
= 0; tokens
[i
].name
; i
++)
1020 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1023 printf
("lex: `%s' is a string token\n", buffer
);
1025 return tokens
[i
].token
;
1029 printf
("lex: `%s' returns ID\n", buffer
);
1031 yylval.id
= xstrdup
(buffer
);
1035 if
(c
== '\'' || c
== '"')
1041 while
(c
!= EOF
&& c
!= q
)
1046 yylval.id
= xstrdup
(buffer
);
1048 printf
("lex: `%s' returns ID\n", buffer
);
1053 if
(c
== '=' || c
== '.' || c
== ',')
1056 printf
("lex: `%c' returns itself\n", c
);
1067 /*printf ("lex: 0x%02x ignored\n", c); */