1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_library
(const char *, int);
87 static void def_name
(const char *, int);
88 static void def_section
(const char *, int);
89 static void def_section_alt
(const char *, const char *);
90 static void def_stacksize
(int, int);
91 static void def_version
(int, int);
92 static void def_directive
(char *);
93 static int def_parse
(void);
94 static int def_error
(const char *);
95 static int def_lex
(void);
97 static int lex_forced_token
= 0;
98 static const char *lex_parse_string
= 0;
99 static const char *lex_parse_string_end
= 0;
108 %token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL
109 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
110 %token PRIVATEU PRIVATEL
111 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
113 %token
<number
> NUMBER
114 %type
<number
> opt_base opt_ordinal
115 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
116 %type
<id
> opt_name opt_equal_name dot_name
125 NAME opt_name opt_base
{ def_name
($2, $3); }
126 | LIBRARY opt_name opt_base
{ def_library
($2, $3); }
127 | DESCRIPTION ID
{ def_description
($2);}
128 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
129 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
130 | CODE attr_list
{ def_section
("CODE", $2);}
131 | DATAU attr_list
{ def_section
("DATA", $2);}
135 | VERSIONK NUMBER
{ def_version
($2, 0);}
136 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
137 | DIRECTIVE ID
{ def_directive
($2);}
148 /* The opt_comma is necessary to support both the usual
149 DEF file syntax as well as .drectve syntax which
150 mandates <expsym>,<expoptlist>. */
151 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
152 { def_exports
($1, $2, $3, $5); }
155 /* The opt_comma is necessary to support both the usual
156 DEF file syntax as well as .drectve syntax which
157 allows for comma separated opt list. */
158 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
163 | NONAMEL
{ $$
= 1; }
164 | CONSTANTU
{ $$
= 2; }
165 | CONSTANTL
{ $$
= 2; }
168 | PRIVATEU
{ $$
= 8; }
169 | PRIVATEL
{ $$
= 8; }
177 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
178 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
179 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
180 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
181 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
182 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
191 ID attr_list
{ def_section
($1, $2);}
192 | ID ID
{ def_section_alt
($1, $2);}
196 attr_list opt_comma attr
{ $$
= $1 |
$3; }
204 opt_number: ',' NUMBER
{ $$
=$2;}
215 opt_name: ID
{ $$
= $1; }
218 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
219 sprintf
(name
, "%s.%s", $1, $3);
226 '@' NUMBER
{ $$
= $2;}
231 '=' dot_name
{ $$
= $2; }
235 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
239 dot_name: ID
{ $$
= $1; }
242 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
243 sprintf
(name
, "%s.%s", $1, $3);
251 /*****************************************************************************
253 *****************************************************************************/
255 static FILE *the_file
;
256 static const char *def_filename
;
257 static int linenumber
;
258 static def_file
*def
;
259 static int saw_newline
;
263 struct directive
*next
;
268 static struct directive
*directives
= 0;
271 def_file_empty
(void)
273 def_file
*rv
= xmalloc
(sizeof
(def_file
));
274 memset
(rv
, 0, sizeof
(def_file
));
276 rv
->base_address
= (bfd_vma
) -1;
277 rv
->stack_reserve
= rv
->stack_commit
= -1;
278 rv
->heap_reserve
= rv
->heap_commit
= -1;
279 rv
->version_major
= rv
->version_minor
= -1;
284 def_file_parse
(const char *filename
, def_file
*add_to
)
288 the_file
= fopen
(filename
, "r");
289 def_filename
= filename
;
302 def
= def_file_empty
();
315 for
(d
= directives
; d
; d
= d
->next
)
318 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
320 def_file_add_directive
(def
, d
->name
, d
->len
);
327 def_file_free
(def_file
*def
)
335 if
(def
->description
)
336 free
(def
->description
);
338 if
(def
->section_defs
)
340 for
(i
= 0; i
< def
->num_section_defs
; i
++)
342 if
(def
->section_defs
[i
].name
)
343 free
(def
->section_defs
[i
].name
);
344 if
(def
->section_defs
[i
].class
)
345 free
(def
->section_defs
[i
].class
);
347 free
(def
->section_defs
);
352 for
(i
= 0; i
< def
->num_exports
; i
++)
354 if
(def
->exports
[i
].internal_name
355 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
356 free
(def
->exports
[i
].internal_name
);
357 if
(def
->exports
[i
].name
)
358 free
(def
->exports
[i
].name
);
365 for
(i
= 0; i
< def
->num_imports
; i
++)
367 if
(def
->imports
[i
].internal_name
368 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
369 free
(def
->imports
[i
].internal_name
);
370 if
(def
->imports
[i
].name
)
371 free
(def
->imports
[i
].name
);
378 def_file_module
*m
= def
->modules
;
379 def
->modules
= def
->modules
->next
;
386 #ifdef DEF_FILE_PRINT
388 def_file_print
(FILE *file
, def_file
*def
)
392 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
394 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
395 if
(def
->is_dll
!= -1)
396 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
397 if
(def
->base_address
!= (bfd_vma
) -1)
398 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
399 if
(def
->description
)
400 fprintf
(file
, " description: `%s'\n", def
->description
);
401 if
(def
->stack_reserve
!= -1)
402 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
403 if
(def
->stack_commit
!= -1)
404 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
405 if
(def
->heap_reserve
!= -1)
406 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
407 if
(def
->heap_commit
!= -1)
408 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
410 if
(def
->num_section_defs
> 0)
412 fprintf
(file
, " section defs:\n");
414 for
(i
= 0; i
< def
->num_section_defs
; i
++)
416 fprintf
(file
, " name: `%s', class: `%s', flags:",
417 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
418 if
(def
->section_defs
[i
].flag_read
)
419 fprintf
(file
, " R");
420 if
(def
->section_defs
[i
].flag_write
)
421 fprintf
(file
, " W");
422 if
(def
->section_defs
[i
].flag_execute
)
423 fprintf
(file
, " X");
424 if
(def
->section_defs
[i
].flag_shared
)
425 fprintf
(file
, " S");
426 fprintf
(file
, "\n");
430 if
(def
->num_exports
> 0)
432 fprintf
(file
, " exports:\n");
434 for
(i
= 0; i
< def
->num_exports
; i
++)
436 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
437 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
438 def
->exports
[i
].ordinal
);
439 if
(def
->exports
[i
].flag_private
)
440 fprintf
(file
, " P");
441 if
(def
->exports
[i
].flag_constant
)
442 fprintf
(file
, " C");
443 if
(def
->exports
[i
].flag_noname
)
444 fprintf
(file
, " N");
445 if
(def
->exports
[i
].flag_data
)
446 fprintf
(file
, " D");
447 fprintf
(file
, "\n");
451 if
(def
->num_imports
> 0)
453 fprintf
(file
, " imports:\n");
455 for
(i
= 0; i
< def
->num_imports
; i
++)
457 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
458 def
->imports
[i
].internal_name
,
459 def
->imports
[i
].module
,
460 def
->imports
[i
].name
,
461 def
->imports
[i
].ordinal
);
465 if
(def
->version_major
!= -1)
466 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
468 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
473 def_file_add_export
(def_file
*def
,
474 const char *external_name
,
475 const char *internal_name
,
479 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
481 if
(def
->num_exports
>= max_exports
)
483 max_exports
= ROUND_UP
(def
->num_exports
+ 1, 32);
485 def
->exports
= xrealloc
(def
->exports
,
486 max_exports
* sizeof
(def_file_export
));
488 def
->exports
= xmalloc
(max_exports
* sizeof
(def_file_export
));
490 e
= def
->exports
+ def
->num_exports
;
491 memset
(e
, 0, sizeof
(def_file_export
));
492 if
(internal_name
&& !external_name
)
493 external_name
= internal_name
;
494 if
(external_name
&& !internal_name
)
495 internal_name
= external_name
;
496 e
->name
= xstrdup
(external_name
);
497 e
->internal_name
= xstrdup
(internal_name
);
498 e
->ordinal
= ordinal
;
504 def_get_module
(def_file
*def
, const char *name
)
508 for
(s
= def
->modules
; s
; s
= s
->next
)
509 if
(strcmp
(s
->name
, name
) == 0)
515 static def_file_module
*
516 def_stash_module
(def_file
*def
, const char *name
)
520 if
((s
= def_get_module
(def
, name
)) != NULL
)
522 s
= xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
523 s
->next
= def
->modules
;
526 strcpy
(s
->name
, name
);
531 def_file_add_import
(def_file
*def
,
535 const char *internal_name
)
538 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
540 if
(def
->num_imports
>= max_imports
)
542 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
545 def
->imports
= xrealloc
(def
->imports
,
546 max_imports
* sizeof
(def_file_import
));
548 def
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
550 i
= def
->imports
+ def
->num_imports
;
551 memset
(i
, 0, sizeof
(def_file_import
));
553 i
->name
= xstrdup
(name
);
555 i
->module
= def_stash_module
(def
, module
);
556 i
->ordinal
= ordinal
;
558 i
->internal_name
= xstrdup
(internal_name
);
560 i
->internal_name
= i
->name
;
573 { "-heap", HEAPSIZE
},
574 { "-stack", STACKSIZE
},
575 { "-attr", SECTIONS
},
576 { "-export", EXPORTS
},
581 def_file_add_directive
(def_file
*my_def
, const char *param
, int len
)
583 def_file
*save_def
= def
;
584 const char *pend
= param
+ len
;
585 char * tend
= (char *) param
;
593 && (ISSPACE
(*param
) ||
*param
== '\n' ||
*param
== 0))
599 /* Scan forward until we encounter any of:
600 - the end of the buffer
601 - the start of a new option
602 - a newline seperating options
603 - a NUL seperating options. */
604 for
(tend
= (char *) (param
+ 1);
606 && !(ISSPACE
(tend
[-1]) && *tend
== '-')
607 && *tend
!= '\n' && *tend
!= 0);
611 for
(i
= 0; diropts
[i
].param
; i
++)
613 int len
= strlen
(diropts
[i
].param
);
615 if
(tend
- param
>= len
616 && strncmp
(param
, diropts
[i
].param
, len
) == 0
617 && (param
[len
] == ':' || param
[len
] == ' '))
619 lex_parse_string_end
= tend
;
620 lex_parse_string
= param
+ len
+ 1;
621 lex_forced_token
= diropts
[i
].token
;
629 if
(!diropts
[i
].param
)
635 /* xgettext:c-format */
636 einfo
(_
("Warning: .drectve `%s' unrecognized\n"), param
);
640 lex_parse_string
= 0;
647 /* Parser Callbacks. */
650 def_name
(const char *name
, int base
)
654 def
->name
= xstrdup
(name
);
655 def
->base_address
= base
;
660 def_library
(const char *name
, int base
)
664 def
->name
= xstrdup
(name
);
665 def
->base_address
= base
;
670 def_description
(const char *text
)
672 int len
= def
->description ? strlen
(def
->description
) : 0;
674 len
+= strlen
(text
) + 1;
675 if
(def
->description
)
677 def
->description
= xrealloc
(def
->description
, len
);
678 strcat
(def
->description
, text
);
682 def
->description
= xmalloc
(len
);
683 strcpy
(def
->description
, text
);
688 def_stacksize
(int reserve
, int commit
)
690 def
->stack_reserve
= reserve
;
691 def
->stack_commit
= commit
;
695 def_heapsize
(int reserve
, int commit
)
697 def
->heap_reserve
= reserve
;
698 def
->heap_commit
= commit
;
702 def_section
(const char *name
, int attr
)
705 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
707 if
(def
->num_section_defs
>= max_sections
)
709 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
711 if
(def
->section_defs
)
712 def
->section_defs
= xrealloc
(def
->section_defs
,
713 max_sections
* sizeof
(def_file_import
));
715 def
->section_defs
= xmalloc
(max_sections
* sizeof
(def_file_import
));
717 s
= def
->section_defs
+ def
->num_section_defs
;
718 memset
(s
, 0, sizeof
(def_file_section
));
719 s
->name
= xstrdup
(name
);
729 def
->num_section_defs
++;
733 def_section_alt
(const char *name
, const char *attr
)
737 for
(; *attr
; attr
++)
759 def_section
(name
, aval
);
763 def_exports
(const char *external_name
,
764 const char *internal_name
,
768 def_file_export
*dfe
;
770 if
(!internal_name
&& external_name
)
771 internal_name
= external_name
;
773 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
776 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
778 dfe
->flag_noname
= 1;
780 dfe
->flag_constant
= 1;
784 dfe
->flag_private
= 1;
788 def_import
(const char *internal_name
,
795 const char *ext
= dllext ? dllext
: "dll";
797 buf
= xmalloc
(strlen
(module
) + strlen
(ext
) + 2);
798 sprintf
(buf
, "%s.%s", module
, ext
);
801 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
807 def_version
(int major
, int minor
)
809 def
->version_major
= major
;
810 def
->version_minor
= minor
;
814 def_directive
(char *str
)
816 struct directive
*d
= xmalloc
(sizeof
(struct directive
));
818 d
->next
= directives
;
820 d
->name
= xstrdup
(str
);
821 d
->len
= strlen
(str
);
825 def_error
(const char *err
)
827 einfo
("%P: %s:%d: %s\n",
828 def_filename ? def_filename
: "<unknown-file>", linenumber
, err
);
833 /* Lexical Scanner. */
838 /* Never freed, but always reused as needed, so no real leak. */
839 static char *buffer
= 0;
840 static int buflen
= 0;
841 static int bufptr
= 0;
846 if
(bufptr
== buflen
)
848 buflen
+= 50; /* overly reasonable, eh? */
850 buffer
= xrealloc
(buffer
, buflen
+ 1);
852 buffer
= xmalloc
(buflen
+ 1);
854 buffer
[bufptr
++] = c
;
855 buffer
[bufptr
] = 0; /* not optimal, but very convenient. */
867 { "CONSTANT", CONSTANTU
},
868 { "constant", CONSTANTL
},
871 { "DESCRIPTION", DESCRIPTION
},
872 { "DIRECTIVE", DIRECTIVE
},
873 { "EXECUTE", EXECUTE
},
874 { "EXPORTS", EXPORTS
},
875 { "HEAPSIZE", HEAPSIZE
},
876 { "IMPORTS", IMPORTS
},
877 { "LIBRARY", LIBRARY
},
879 { "NONAME", NONAMEU
},
880 { "noname", NONAMEL
},
881 { "PRIVATE", PRIVATEU
},
882 { "private", PRIVATEL
},
884 { "SECTIONS", SECTIONS
},
885 { "SEGMENTS", SECTIONS
},
886 { "SHARED", SHARED
},
887 { "STACKSIZE", STACKSIZE
},
888 { "VERSION", VERSIONK
},
898 if
(lex_parse_string
)
900 if
(lex_parse_string
>= lex_parse_string_end
)
903 rv
= *lex_parse_string
++;
907 rv
= fgetc
(the_file
);
917 if
(lex_parse_string
)
923 return ungetc
(c
, the_file
);
931 if
(lex_forced_token
)
933 i
= lex_forced_token
;
934 lex_forced_token
= 0;
936 printf
("lex: forcing token %d\n", i
);
943 /* Trim leading whitespace. */
944 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
950 printf
("lex: EOF\n");
955 if
(saw_newline
&& c
== ';')
961 while
(c
!= EOF
&& c
!= '\n');
967 /* Must be something else. */
973 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
980 yylval.number
= strtoul
(buffer
, 0, 0);
982 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
987 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
996 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
998 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
1004 printf
("lex: @ returns itself\n");
1008 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@", c
)))
1015 if
(ISALPHA
(q
)) /* Check for tokens. */
1017 for
(i
= 0; tokens
[i
].name
; i
++)
1018 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1021 printf
("lex: `%s' is a string token\n", buffer
);
1023 return tokens
[i
].token
;
1027 printf
("lex: `%s' returns ID\n", buffer
);
1029 yylval.id
= xstrdup
(buffer
);
1033 if
(c
== '\'' || c
== '"')
1039 while
(c
!= EOF
&& c
!= q
)
1044 yylval.id
= xstrdup
(buffer
);
1046 printf
("lex: `%s' returns ID\n", buffer
);
1051 if
(c
== '=' || c
== '.' || c
== ',')
1054 printf
("lex: `%c' returns itself\n", c
);
1065 /*printf ("lex: 0x%02x ignored\n", c); */