1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2020 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 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 typedef
struct def_pool_str
{
82 struct def_pool_str
*next
;
86 static def_pool_str
*pool_strs
= NULL
;
88 static char *def_pool_alloc
(size_t sz
);
89 static char *def_pool_strdup
(const char *str
);
90 static void def_pool_free
(void);
92 static void def_description
(const char *);
93 static void def_exports
(const char *, const char *, int, int, const char *);
94 static void def_heapsize
(int, int);
95 static void def_import
(const char *, const char *, const char *, const char *,
97 static void def_image_name
(const char *, bfd_vma
, int);
98 static void def_section
(const char *, int);
99 static void def_section_alt
(const char *, const char *);
100 static void def_stacksize
(int, int);
101 static void def_version
(int, int);
102 static void def_directive
(char *);
103 static void def_aligncomm
(char *str
, int align
);
104 static int def_parse
(void);
105 static int def_error
(const char *);
106 static int def_lex
(void);
108 static int lex_forced_token
= 0;
109 static const char *lex_parse_string
= 0;
110 static const char *lex_parse_string_end
= 0;
116 const char *id_const
;
122 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
123 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
124 %token PRIVATEU PRIVATEL ALIGNCOMM
125 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
127 %token
<digits
> DIGITS
128 %type
<number
> NUMBER
129 %type
<vma
> VMA opt_base
130 %type
<digits
> opt_digits
131 %type
<number
> opt_ordinal
132 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
133 %type
<id
> opt_name opt_name2 opt_equal_name anylang_id opt_id
134 %type
<id
> opt_equalequal_name
135 %type
<id_const
> keyword_as_name
144 NAME opt_name opt_base
{ def_image_name
($2, $3, 0); }
145 | LIBRARY opt_name opt_base
{ def_image_name
($2, $3, 1); }
146 | DESCRIPTION ID
{ def_description
($2);}
147 | STACKSIZE_K NUMBER opt_number
{ def_stacksize
($2, $3);}
148 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
149 | CODE attr_list
{ def_section
("CODE", $2);}
150 | DATAU attr_list
{ def_section
("DATA", $2);}
154 | VERSIONK NUMBER
{ def_version
($2, 0);}
155 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
156 | DIRECTIVE ID
{ def_directive
($2);}
157 | ALIGNCOMM anylang_id
',' NUMBER
{ def_aligncomm
($2, $4);}
168 /* The opt_comma is necessary to support both the usual
169 DEF file syntax as well as .drectve syntax which
170 mandates <expsym>,<expoptlist>. */
171 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
172 { def_exports
($1, $2, $3, $5, $7); }
175 /* The opt_comma is necessary to support both the usual
176 DEF file syntax as well as .drectve syntax which
177 allows for comma separated opt list. */
178 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
183 | NONAMEL
{ $$
= 1; }
184 | CONSTANTU
{ $$
= 2; }
185 | CONSTANTL
{ $$
= 2; }
188 | PRIVATEU
{ $$
= 8; }
189 | PRIVATEL
{ $$
= 8; }
197 ID
'=' ID
'.' ID
'.' ID opt_equalequal_name
198 { def_import
($1, $3, $5, $7, -1, $8); }
199 | ID
'=' ID
'.' ID
'.' NUMBER opt_equalequal_name
200 { def_import
($1, $3, $5, 0, $7, $8); }
201 | ID
'=' ID
'.' ID opt_equalequal_name
202 { def_import
($1, $3, 0, $5, -1, $6); }
203 | ID
'=' ID
'.' NUMBER opt_equalequal_name
204 { def_import
($1, $3, 0, 0, $5, $6); }
205 | ID
'.' ID
'.' ID opt_equalequal_name
206 { def_import
( 0, $1, $3, $5, -1, $6); }
207 | ID
'.' ID opt_equalequal_name
208 { def_import
( 0, $1, 0, $3, -1, $4); }
217 ID attr_list
{ def_section
($1, $2);}
218 | ID ID
{ def_section_alt
($1, $2);}
222 attr_list opt_comma attr
{ $$
= $1 |
$3; }
230 opt_number: ',' NUMBER
{ $$
=$2;}
242 keyword_as_name: BASE
{ $$
= "BASE"; }
243 | CODE
{ $$
= "CODE"; }
244 | CONSTANTU
{ $$
= "CONSTANT"; }
245 | CONSTANTL
{ $$
= "constant"; }
246 | DATAU
{ $$
= "DATA"; }
247 | DATAL
{ $$
= "data"; }
248 | DESCRIPTION
{ $$
= "DESCRIPTION"; }
249 | DIRECTIVE
{ $$
= "DIRECTIVE"; }
250 | EXECUTE
{ $$
= "EXECUTE"; }
251 | EXPORTS
{ $$
= "EXPORTS"; }
252 | HEAPSIZE
{ $$
= "HEAPSIZE"; }
253 | IMPORTS
{ $$
= "IMPORTS"; }
254 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
255 for libtool, which places this command after EXPORTS command.
256 This behavior is illegal by specification, but sadly required by
257 by compatibility reasons.
258 See PR binutils/13710
259 | LIBRARY { $$ = "LIBRARY"; } */
260 | NAME
{ $$
= "NAME"; }
261 | NONAMEU
{ $$
= "NONAME"; }
262 | NONAMEL
{ $$
= "noname"; }
263 | PRIVATEU
{ $$
= "PRIVATE"; }
264 | PRIVATEL
{ $$
= "private"; }
265 | READ
{ $$
= "READ"; }
266 | SHARED
{ $$
= "SHARED"; }
267 | STACKSIZE_K
{ $$
= "STACKSIZE"; }
268 | VERSIONK
{ $$
= "VERSION"; }
269 | WRITE
{ $$
= "WRITE"; }
272 opt_name2: ID
{ $$
= $1; }
273 |
'.' keyword_as_name
275 char *name
= xmalloc
(strlen
($2) + 2);
276 sprintf
(name
, ".%s", $2);
281 char *name
= def_pool_alloc
(strlen
($2) + 2);
282 sprintf
(name
, ".%s", $2);
285 | keyword_as_name
'.' opt_name2
287 char *name
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + 1);
288 sprintf
(name
, "%s.%s", $1, $3);
293 char *name
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + 1);
294 sprintf
(name
, "%s.%s", $1, $3);
299 opt_name: opt_name2
{ $$
= $1; }
303 opt_equalequal_name: EQUAL ID
{ $$
= $2; }
308 '@' NUMBER
{ $$
= $2;}
313 '=' opt_name2
{ $$
= $2; }
317 opt_base: BASE
'=' VMA
{ $$
= $3;}
318 |
{ $$
= (bfd_vma
) -1;}
321 anylang_id: ID
{ $$
= $1; }
324 char *id
= def_pool_alloc
(strlen
($2) + 2);
325 sprintf
(id
, ".%s", $2);
328 | anylang_id
'.' opt_digits opt_id
330 char *id
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + strlen
($4) + 1);
331 sprintf
(id
, "%s.%s%s", $1, $3, $4);
336 opt_digits: DIGITS
{ $$
= $1; }
340 opt_id: ID
{ $$
= $1; }
344 NUMBER: DIGITS
{ $$
= strtoul
($1, 0, 0); }
346 VMA: DIGITS
{ $$
= (bfd_vma
) strtoull
($1, 0, 0); }
350 /*****************************************************************************
352 *****************************************************************************/
354 static FILE *the_file
;
355 static const char *def_filename
;
356 static int linenumber
;
357 static def_file
*def
;
358 static int saw_newline
;
362 struct directive
*next
;
367 static struct directive
*directives
= 0;
370 def_file_empty
(void)
372 def_file
*rv
= xmalloc
(sizeof
(def_file
));
373 memset
(rv
, 0, sizeof
(def_file
));
375 rv
->base_address
= (bfd_vma
) -1;
376 rv
->stack_reserve
= rv
->stack_commit
= -1;
377 rv
->heap_reserve
= rv
->heap_commit
= -1;
378 rv
->version_major
= rv
->version_minor
= -1;
383 def_file_parse
(const char *filename
, def_file
*add_to
)
387 the_file
= fopen
(filename
, "r");
388 def_filename
= filename
;
401 def
= def_file_empty
();
415 while
((d
= directives
) != NULL
)
418 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
420 def_file_add_directive
(def
, d
->name
, d
->len
);
421 directives
= d
->next
;
431 def_file_free
(def_file
*fdef
)
438 free
(fdef
->description
);
440 if
(fdef
->section_defs
)
442 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
444 free
(fdef
->section_defs
[i
].name
);
445 free
(fdef
->section_defs
[i
].class
);
447 free
(fdef
->section_defs
);
452 for
(i
= 0; i
< fdef
->num_exports
; i
++)
454 if
(fdef
->exports
[i
].internal_name
!= fdef
->exports
[i
].name
)
455 free
(fdef
->exports
[i
].internal_name
);
456 free
(fdef
->exports
[i
].name
);
457 free
(fdef
->exports
[i
].its_name
);
459 free
(fdef
->exports
);
464 for
(i
= 0; i
< fdef
->num_imports
; i
++)
466 if
(fdef
->imports
[i
].internal_name
!= fdef
->imports
[i
].name
)
467 free
(fdef
->imports
[i
].internal_name
);
468 free
(fdef
->imports
[i
].name
);
469 free
(fdef
->imports
[i
].its_name
);
471 free
(fdef
->imports
);
474 while
(fdef
->modules
)
476 def_file_module
*m
= fdef
->modules
;
478 fdef
->modules
= fdef
->modules
->next
;
482 while
(fdef
->aligncomms
)
484 def_file_aligncomm
*c
= fdef
->aligncomms
;
486 fdef
->aligncomms
= fdef
->aligncomms
->next
;
487 free
(c
->symbol_name
);
494 #ifdef DEF_FILE_PRINT
496 def_file_print
(FILE *file
, def_file
*fdef
)
500 fprintf
(file
, ">>>> def_file at 0x%08x\n", fdef
);
502 fprintf
(file
, " name: %s\n", fdef
->name ? fdef
->name
: "(unspecified)");
503 if
(fdef
->is_dll
!= -1)
504 fprintf
(file
, " is dll: %s\n", fdef
->is_dll ?
"yes" : "no");
505 if
(fdef
->base_address
!= (bfd_vma
) -1)
507 fprintf
(file
, " base address: 0x");
508 fprintf_vma
(file
, fdef
->base_address
);
509 fprintf
(file
, "\n");
511 if
(fdef
->description
)
512 fprintf
(file
, " description: `%s'\n", fdef
->description
);
513 if
(fdef
->stack_reserve
!= -1)
514 fprintf
(file
, " stack reserve: 0x%08x\n", fdef
->stack_reserve
);
515 if
(fdef
->stack_commit
!= -1)
516 fprintf
(file
, " stack commit: 0x%08x\n", fdef
->stack_commit
);
517 if
(fdef
->heap_reserve
!= -1)
518 fprintf
(file
, " heap reserve: 0x%08x\n", fdef
->heap_reserve
);
519 if
(fdef
->heap_commit
!= -1)
520 fprintf
(file
, " heap commit: 0x%08x\n", fdef
->heap_commit
);
522 if
(fdef
->num_section_defs
> 0)
524 fprintf
(file
, " section defs:\n");
526 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
528 fprintf
(file
, " name: `%s', class: `%s', flags:",
529 fdef
->section_defs
[i
].name
, fdef
->section_defs
[i
].class
);
530 if
(fdef
->section_defs
[i
].flag_read
)
531 fprintf
(file
, " R");
532 if
(fdef
->section_defs
[i
].flag_write
)
533 fprintf
(file
, " W");
534 if
(fdef
->section_defs
[i
].flag_execute
)
535 fprintf
(file
, " X");
536 if
(fdef
->section_defs
[i
].flag_shared
)
537 fprintf
(file
, " S");
538 fprintf
(file
, "\n");
542 if
(fdef
->num_exports
> 0)
544 fprintf
(file
, " exports:\n");
546 for
(i
= 0; i
< fdef
->num_exports
; i
++)
548 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
549 fdef
->exports
[i
].name
, fdef
->exports
[i
].internal_name
,
550 fdef
->exports
[i
].ordinal
);
551 if
(fdef
->exports
[i
].flag_private
)
552 fprintf
(file
, " P");
553 if
(fdef
->exports
[i
].flag_constant
)
554 fprintf
(file
, " C");
555 if
(fdef
->exports
[i
].flag_noname
)
556 fprintf
(file
, " N");
557 if
(fdef
->exports
[i
].flag_data
)
558 fprintf
(file
, " D");
559 fprintf
(file
, "\n");
563 if
(fdef
->num_imports
> 0)
565 fprintf
(file
, " imports:\n");
567 for
(i
= 0; i
< fdef
->num_imports
; i
++)
569 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
570 fdef
->imports
[i
].internal_name
,
571 fdef
->imports
[i
].module
,
572 fdef
->imports
[i
].name
,
573 fdef
->imports
[i
].ordinal
);
577 if
(fdef
->version_major
!= -1)
578 fprintf
(file
, " version: %d.%d\n", fdef
->version_major
, fdef
->version_minor
);
580 fprintf
(file
, "<<<< def_file at 0x%08x\n", fdef
);
584 /* Helper routine to check for identity of string pointers,
585 which might be NULL. */
588 are_names_equal
(const char *s1
, const char *s2
)
593 return
(!s1 ?
-1 : 1);
594 return strcmp
(s1
, s2
);
598 cmp_export_elem
(const def_file_export
*e
, const char *ex_name
,
599 const char *in_name
, const char *its_name
,
604 if
((r
= are_names_equal
(ex_name
, e
->name
)) != 0)
606 if
((r
= are_names_equal
(in_name
, e
->internal_name
)) != 0)
608 if
((r
= are_names_equal
(its_name
, e
->its_name
)) != 0)
610 return
(ord
- e
->ordinal
);
613 /* Search the position of the identical element, or returns the position
614 of the next higher element. If last valid element is smaller, then MAX
618 find_export_in_list
(def_file_export
*b
, int max
,
619 const char *ex_name
, const char *in_name
,
620 const char *its_name
, int ord
, int *is_ident
)
627 if
((e
= cmp_export_elem
(b
, ex_name
, in_name
, its_name
, ord
)) <= 0)
635 if
((e
= cmp_export_elem
(b
+ (max
- 1), ex_name
, in_name
, its_name
, ord
)) > 0)
637 else if
(!e || max
== 2)
647 e
= cmp_export_elem
(b
+ p
, ex_name
, in_name
, its_name
, ord
);
658 if
((e
= cmp_export_elem
(b
+ l
, ex_name
, in_name
, its_name
, ord
)) > 0)
666 def_file_add_export
(def_file
*fdef
,
667 const char *external_name
,
668 const char *internal_name
,
670 const char *its_name
,
675 int max_exports
= ROUND_UP
(fdef
->num_exports
, 32);
677 if
(internal_name
&& !external_name
)
678 external_name
= internal_name
;
679 if
(external_name
&& !internal_name
)
680 internal_name
= external_name
;
682 /* We need to avoid duplicates. */
684 pos
= find_export_in_list
(fdef
->exports
, fdef
->num_exports
,
685 external_name
, internal_name
,
686 its_name
, ordinal
, is_dup
);
689 return
(fdef
->exports
+ pos
);
691 if
(fdef
->num_exports
>= max_exports
)
693 max_exports
= ROUND_UP
(fdef
->num_exports
+ 1, 32);
695 fdef
->exports
= xrealloc
(fdef
->exports
,
696 max_exports
* sizeof
(def_file_export
));
698 fdef
->exports
= xmalloc
(max_exports
* sizeof
(def_file_export
));
701 e
= fdef
->exports
+ pos
;
702 if
(pos
!= fdef
->num_exports
)
703 memmove
(&e
[1], e
, (sizeof
(def_file_export
) * (fdef
->num_exports
- pos
)));
704 memset
(e
, 0, sizeof
(def_file_export
));
705 e
->name
= xstrdup
(external_name
);
706 e
->internal_name
= xstrdup
(internal_name
);
707 e
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
708 e
->ordinal
= ordinal
;
714 def_get_module
(def_file
*fdef
, const char *name
)
718 for
(s
= fdef
->modules
; s
; s
= s
->next
)
719 if
(strcmp
(s
->name
, name
) == 0)
725 static def_file_module
*
726 def_stash_module
(def_file
*fdef
, const char *name
)
730 if
((s
= def_get_module
(fdef
, name
)) != NULL
)
732 s
= xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
733 s
->next
= fdef
->modules
;
736 strcpy
(s
->name
, name
);
741 cmp_import_elem
(const def_file_import
*e
, const char *ex_name
,
742 const char *in_name
, const char *module
,
747 if
((r
= are_names_equal
(module
, (e
->module ? e
->module
->name
: NULL
))))
749 if
((r
= are_names_equal
(ex_name
, e
->name
)) != 0)
751 if
((r
= are_names_equal
(in_name
, e
->internal_name
)) != 0)
753 if
(ord
!= e
->ordinal
)
754 return
(ord
< e
->ordinal ?
-1 : 1);
758 /* Search the position of the identical element, or returns the position
759 of the next higher element. If last valid element is smaller, then MAX
763 find_import_in_list
(def_file_import
*b
, int max
,
764 const char *ex_name
, const char *in_name
,
765 const char *module
, int ord
, int *is_ident
)
772 if
((e
= cmp_import_elem
(b
, ex_name
, in_name
, module
, ord
)) <= 0)
780 if
((e
= cmp_import_elem
(b
+ (max
- 1), ex_name
, in_name
, module
, ord
)) > 0)
782 else if
(!e || max
== 2)
792 e
= cmp_import_elem
(b
+ p
, ex_name
, in_name
, module
, ord
);
803 if
((e
= cmp_import_elem
(b
+ l
, ex_name
, in_name
, module
, ord
)) > 0)
811 fill_in_import
(def_file_import
*i
,
813 def_file_module
*module
,
815 const char *internal_name
,
816 const char *its_name
)
818 memset
(i
, 0, sizeof
(def_file_import
));
820 i
->name
= xstrdup
(name
);
822 i
->ordinal
= ordinal
;
824 i
->internal_name
= xstrdup
(internal_name
);
826 i
->internal_name
= i
->name
;
827 i
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
831 def_file_add_import
(def_file
*fdef
,
835 const char *internal_name
,
836 const char *its_name
,
841 int max_imports
= ROUND_UP
(fdef
->num_imports
, 16);
843 /* We need to avoid here duplicates. */
845 pos
= find_import_in_list
(fdef
->imports
, fdef
->num_imports
,
847 (!internal_name ? name
: internal_name
),
848 module
, ordinal
, is_dup
);
850 return fdef
->imports
+ pos
;
852 if
(fdef
->num_imports
>= max_imports
)
854 max_imports
= ROUND_UP
(fdef
->num_imports
+1, 16);
857 fdef
->imports
= xrealloc
(fdef
->imports
,
858 max_imports
* sizeof
(def_file_import
));
860 fdef
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
862 i
= fdef
->imports
+ pos
;
863 if
(pos
!= fdef
->num_imports
)
864 memmove
(i
+ 1, i
, sizeof
(def_file_import
) * (fdef
->num_imports
- pos
));
866 fill_in_import
(i
, name
, def_stash_module
(fdef
, module
), ordinal
,
867 internal_name
, its_name
);
874 def_file_add_import_from
(def_file
*fdef
,
879 const char *internal_name
,
880 const char *its_name ATTRIBUTE_UNUSED
)
885 int max_imports
= ROUND_UP
(fdef
->num_imports
, 16);
887 /* We need to avoid here duplicates. */
889 pos
= find_import_in_list
(fdef
->imports
, fdef
->num_imports
,
890 name
, internal_name ? internal_name
: name
,
891 module
, ordinal
, &is_dup
);
894 if
(fdef
->imports
&& pos
!= fdef
->num_imports
)
896 i
= fdef
->imports
+ pos
;
897 if
(i
->module
&& strcmp
(i
->module
->name
, module
) == 0)
901 if
(fdef
->num_imports
+ num_imports
- 1 >= max_imports
)
903 max_imports
= ROUND_UP
(fdef
->num_imports
+ num_imports
, 16);
906 fdef
->imports
= xrealloc
(fdef
->imports
,
907 max_imports
* sizeof
(def_file_import
));
909 fdef
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
911 i
= fdef
->imports
+ pos
;
912 if
(pos
!= fdef
->num_imports
)
913 memmove
(i
+ num_imports
, i
,
914 sizeof
(def_file_import
) * (fdef
->num_imports
- pos
));
920 def_file_add_import_at
(def_file
*fdef
,
925 const char *internal_name
,
926 const char *its_name
)
928 def_file_import
*i
= fdef
->imports
+ pos
;
930 fill_in_import
(i
, name
, def_stash_module
(fdef
, module
), ordinal
,
931 internal_name
, its_name
);
944 { "-heap", HEAPSIZE
},
945 { "-stack", STACKSIZE_K
},
946 { "-attr", SECTIONS
},
947 { "-export", EXPORTS
},
948 { "-aligncomm", ALIGNCOMM
},
953 def_file_add_directive
(def_file
*my_def
, const char *param
, int len
)
955 def_file
*save_def
= def
;
956 const char *pend
= param
+ len
;
957 char * tend
= (char *) param
;
965 && (ISSPACE
(*param
) ||
*param
== '\n' ||
*param
== 0))
971 /* Scan forward until we encounter any of:
972 - the end of the buffer
973 - the start of a new option
974 - a newline separating options
975 - a NUL separating options. */
976 for
(tend
= (char *) (param
+ 1);
978 && !(ISSPACE
(tend
[-1]) && *tend
== '-')
979 && *tend
!= '\n' && *tend
!= 0);
983 for
(i
= 0; diropts
[i
].param
; i
++)
985 len
= strlen
(diropts
[i
].param
);
987 if
(tend
- param
>= len
988 && strncmp
(param
, diropts
[i
].param
, len
) == 0
989 && (param
[len
] == ':' || param
[len
] == ' '))
991 lex_parse_string_end
= tend
;
992 lex_parse_string
= param
+ len
+ 1;
993 lex_forced_token
= diropts
[i
].token
;
1001 if
(!diropts
[i
].param
)
1009 /* xgettext:c-format */
1010 einfo
(_
("Warning: .drectve `%s' unrecognized\n"), param
);
1015 einfo
(_
("Warning: corrupt .drectve at end of def file\n"));
1019 lex_parse_string
= 0;
1027 /* Parser Callbacks. */
1030 def_image_name
(const char *name
, bfd_vma base
, int is_dll
)
1032 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1033 to do here. We retain the output filename specified on command line. */
1036 const char* image_name
= lbasename
(name
);
1038 if
(image_name
!= name
)
1039 einfo
("%s:%d: Warning: path components stripped from %s, '%s'\n",
1040 def_filename
, linenumber
, is_dll ?
"LIBRARY" : "NAME",
1043 /* Append the default suffix, if none specified. */
1044 if
(strchr
(image_name
, '.') == 0)
1046 const char * suffix
= is_dll ?
".dll" : ".exe";
1048 def
->name
= xmalloc
(strlen
(image_name
) + strlen
(suffix
) + 1);
1049 sprintf
(def
->name
, "%s%s", image_name
, suffix
);
1052 def
->name
= xstrdup
(image_name
);
1055 /* Honor a BASE address statement, even if LIBRARY string is empty. */
1056 def
->base_address
= base
;
1057 def
->is_dll
= is_dll
;
1061 def_description
(const char *text
)
1063 int len
= def
->description ? strlen
(def
->description
) : 0;
1065 len
+= strlen
(text
) + 1;
1066 if
(def
->description
)
1068 def
->description
= xrealloc
(def
->description
, len
);
1069 strcat
(def
->description
, text
);
1073 def
->description
= xmalloc
(len
);
1074 strcpy
(def
->description
, text
);
1079 def_stacksize
(int reserve
, int commit
)
1081 def
->stack_reserve
= reserve
;
1082 def
->stack_commit
= commit
;
1086 def_heapsize
(int reserve
, int commit
)
1088 def
->heap_reserve
= reserve
;
1089 def
->heap_commit
= commit
;
1093 def_section
(const char *name
, int attr
)
1095 def_file_section
*s
;
1096 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
1098 if
(def
->num_section_defs
>= max_sections
)
1100 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
1102 if
(def
->section_defs
)
1103 def
->section_defs
= xrealloc
(def
->section_defs
,
1104 max_sections
* sizeof
(def_file_import
));
1106 def
->section_defs
= xmalloc
(max_sections
* sizeof
(def_file_import
));
1108 s
= def
->section_defs
+ def
->num_section_defs
;
1109 memset
(s
, 0, sizeof
(def_file_section
));
1110 s
->name
= xstrdup
(name
);
1116 s
->flag_execute
= 1;
1120 def
->num_section_defs
++;
1124 def_section_alt
(const char *name
, const char *attr
)
1128 for
(; *attr
; attr
++)
1150 def_section
(name
, aval
);
1154 def_exports
(const char *external_name
,
1155 const char *internal_name
,
1158 const char *its_name
)
1160 def_file_export
*dfe
;
1163 if
(!internal_name
&& external_name
)
1164 internal_name
= external_name
;
1166 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
1169 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
,
1172 /* We might check here for flag redefinition and warn. For now we
1173 ignore duplicates silently. */
1178 dfe
->flag_noname
= 1;
1180 dfe
->flag_constant
= 1;
1184 dfe
->flag_private
= 1;
1188 def_import
(const char *internal_name
,
1193 const char *its_name
)
1196 const char *ext
= dllext ? dllext
: "dll";
1199 buf
= xmalloc
(strlen
(module
) + strlen
(ext
) + 2);
1200 sprintf
(buf
, "%s.%s", module
, ext
);
1203 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
, its_name
,
1209 def_version
(int major
, int minor
)
1211 def
->version_major
= major
;
1212 def
->version_minor
= minor
;
1216 def_directive
(char *str
)
1218 struct directive
*d
= xmalloc
(sizeof
(struct directive
));
1220 d
->next
= directives
;
1222 d
->name
= xstrdup
(str
);
1223 d
->len
= strlen
(str
);
1227 def_aligncomm
(char *str
, int align
)
1229 def_file_aligncomm
*c
, *p
;
1232 c
= def
->aligncomms
;
1235 int e
= strcmp
(c
->symbol_name
, str
);
1238 /* Not sure if we want to allow here duplicates with
1239 different alignments, but for now we keep them. */
1240 e
= (int) c
->alignment
- align
;
1249 c
= xmalloc
(sizeof
(def_file_aligncomm
));
1250 c
->symbol_name
= xstrdup
(str
);
1251 c
->alignment
= (unsigned int) align
;
1254 c
->next
= def
->aligncomms
;
1255 def
->aligncomms
= c
;
1265 def_error
(const char *err
)
1267 einfo
("%P: %s:%d: %s\n",
1268 def_filename ? def_filename
: "<unknown-file>", linenumber
, err
);
1273 /* Lexical Scanner. */
1278 /* Never freed, but always reused as needed, so no real leak. */
1279 static char *buffer
= 0;
1280 static int buflen
= 0;
1281 static int bufptr
= 0;
1286 if
(bufptr
== buflen
)
1288 buflen
+= 50; /* overly reasonable, eh? */
1290 buffer
= xrealloc
(buffer
, buflen
+ 1);
1292 buffer
= xmalloc
(buflen
+ 1);
1294 buffer
[bufptr
++] = c
;
1295 buffer
[bufptr
] = 0; /* not optimal, but very convenient. */
1307 { "CONSTANT", CONSTANTU
},
1308 { "constant", CONSTANTL
},
1311 { "DESCRIPTION", DESCRIPTION
},
1312 { "DIRECTIVE", DIRECTIVE
},
1313 { "EXECUTE", EXECUTE
},
1314 { "EXPORTS", EXPORTS
},
1315 { "HEAPSIZE", HEAPSIZE
},
1316 { "IMPORTS", IMPORTS
},
1317 { "LIBRARY", LIBRARY
},
1319 { "NONAME", NONAMEU
},
1320 { "noname", NONAMEL
},
1321 { "PRIVATE", PRIVATEU
},
1322 { "private", PRIVATEL
},
1324 { "SECTIONS", SECTIONS
},
1325 { "SEGMENTS", SECTIONS
},
1326 { "SHARED", SHARED
},
1327 { "STACKSIZE", STACKSIZE_K
},
1328 { "VERSION", VERSIONK
},
1338 if
(lex_parse_string
)
1340 if
(lex_parse_string
>= lex_parse_string_end
)
1343 rv
= *lex_parse_string
++;
1347 rv
= fgetc
(the_file
);
1357 if
(lex_parse_string
)
1363 return ungetc
(c
, the_file
);
1371 if
(lex_forced_token
)
1373 i
= lex_forced_token
;
1374 lex_forced_token
= 0;
1376 printf
("lex: forcing token %d\n", i
);
1383 /* Trim leading whitespace. */
1384 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
1390 printf
("lex: EOF\n");
1395 if
(saw_newline
&& c
== ';')
1401 while
(c
!= EOF
&& c
!= '\n');
1407 /* Must be something else. */
1413 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
1420 yylval.digits
= def_pool_strdup
(buffer
);
1422 printf
("lex: `%s' returns DIGITS\n", buffer
);
1427 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
1436 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
1438 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
1444 printf
("lex: @ returns itself\n");
1448 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@<>", c
)))
1455 if
(ISALPHA
(q
)) /* Check for tokens. */
1457 for
(i
= 0; tokens
[i
].name
; i
++)
1458 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1461 printf
("lex: `%s' is a string token\n", buffer
);
1463 return tokens
[i
].token
;
1467 printf
("lex: `%s' returns ID\n", buffer
);
1469 yylval.id
= def_pool_strdup
(buffer
);
1473 if
(c
== '\'' || c
== '"')
1479 while
(c
!= EOF
&& c
!= q
)
1484 yylval.id
= def_pool_strdup
(buffer
);
1486 printf
("lex: `%s' returns ID\n", buffer
);
1497 printf
("lex: `==' returns EQUAL\n");
1503 printf
("lex: `=' returns itself\n");
1507 if
(c
== '.' || c
== ',')
1510 printf
("lex: `%c' returns itself\n", c
);
1521 /*printf ("lex: 0x%02x ignored\n", c); */
1526 def_pool_alloc
(size_t sz
)
1530 e
= (def_pool_str
*) xmalloc
(sizeof
(def_pool_str
) + sz
);
1531 e
->next
= pool_strs
;
1537 def_pool_strdup
(const char *str
)
1543 len
= strlen
(str
) + 1;
1544 s
= def_pool_alloc
(len
);
1545 memcpy
(s
, str
, len
);
1550 def_pool_free
(void)
1553 while
((p
= pool_strs
) != NULL
)
1555 pool_strs
= p
->next
;