2 /* Parser for linker scripts.
3 Copyright (C) 2001-2011 Red Hat, Inc.
4 This file is part of Red Hat elfutils.
5 Written by Ulrich Drepper <drepper@redhat.com>, 2001.
7 Red Hat elfutils is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by the
9 Free Software Foundation; version 2 of the License.
11 Red Hat elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with Red Hat elfutils; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
20 Red Hat elfutils is an included package of the Open Invention Network.
21 An included package of the Open Invention Network is a package for which
22 Open Invention Network licensees cross-license their patents. No patent
23 license is granted, either expressly or impliedly, by designation as an
24 included package. Should you wish to participate in the Open Invention
25 Network licensing program, please visit www.openinventionnetwork.com
26 <http://www.openinventionnetwork.com>. */
44 /* The error handler. */
45 static void yyerror (const char *s);
47 /* Some helper functions we need to construct the data structures
48 describing information from the file. */
49 static struct expression *new_expr (int tag);
50 static struct input_section_name *new_input_section_name (const char *name,
52 static struct input_rule *new_input_rule (int tag);
53 static struct output_rule *new_output_rule (int tag);
54 static struct assignment *new_assignment (const char *variable,
55 struct expression *expression,
57 static void new_segment (int mode, struct output_rule *output_rule);
58 static struct filename_list *new_filename_listelem (const char *string);
59 static void add_inputfiles (struct filename_list *fnames);
60 static struct id_list *new_id_listelem (const char *str);
61 static struct filename_list *mark_as_needed (struct filename_list *listp);
62 static struct version *new_version (struct id_list *local,
63 struct id_list *global);
64 static struct version *merge_versions (struct version *one,
66 static void add_versions (struct version *versions);
68 extern int yylex (void);
73 enum expression_tag op;
75 struct expression *expr;
76 struct input_section_name *sectionname;
77 struct filemask_section_name *filemask_section_name;
78 struct input_rule *input_rule;
79 struct output_rule *output_rule;
80 struct assignment *assignment;
81 struct filename_list *filename_list;
82 struct version *version;
83 struct id_list *id_list;
91 %token <str> kFILENAME
102 %token kOUTPUT_FORMAT
107 %token kSIZEOF_HEADERS
110 %token kVERSION_SCRIPT
119 %type <str> filename_id
120 %type <str> filename_id_star
121 %type <str> exclude_opt
123 %type <sectionname> sort_opt_name
124 %type <filemask_section_name> sectionname
125 %type <input_rule> inputsection
126 %type <input_rule> inputsections
127 %type <output_rule> outputsection
128 %type <output_rule> outputsections
129 %type <assignment> assignment
130 %type <filename_list> filename_id_list
131 %type <filename_list> filename_id_listelem
132 %type <version> versionlist
133 %type <version> version
134 %type <version> version_stmt_list
135 %type <version> version_stmt
136 %type <id_list> filename_id_star_list
144 | kVERSION_SCRIPT versionlist
145 { add_versions ($2); }
152 content: kENTRY '(' kID ')' ';'
154 if (likely (ld_state.entry == NULL))
157 | kSEARCH_DIR '(' filename_id ')' ';'
159 ld_new_searchdir ($3);
161 | kPAGESIZE '(' kNUM ')' ';'
163 if (likely (ld_state.pagesize == 0))
164 ld_state.pagesize = $3;
166 | kINTERP '(' filename_id ')' ';'
168 if (likely (ld_state.interp == NULL)
169 && ld_state.file_type != dso_file_type)
170 ld_state.interp = $3;
172 | kSEGMENT kMODE '{' outputsections '}'
174 new_segment ($2, $4);
176 | kSEGMENT error '{' outputsections '}'
178 fputs_unlocked (gettext ("mode for segment invalid\n"),
182 | kGROUP '(' filename_id_list ')'
184 /* First little optimization. If there is only one
185 file in the group don't do anything. */
188 $3->next->group_start = 1;
193 | kINPUT '(' filename_id_list ')'
194 { add_inputfiles ($3); }
195 | kAS_NEEDED '(' filename_id_list ')'
196 { add_inputfiles (mark_as_needed ($3)); }
197 | kVERSION '{' versionlist '}'
198 { add_versions ($3); }
199 | kOUTPUT_FORMAT '(' filename_id ')'
203 outputsections: outputsections outputsection
212 outputsection: assignment ';'
214 $$ = new_output_rule (output_assignment);
215 $$->val.assignment = $1;
217 | kID '{' inputsections '}'
219 $$ = new_output_rule (output_section);
220 $$->val.section.name = $1;
221 $$->val.section.input = $3->next;
222 if (ld_state.strip == strip_debug
223 && ebl_debugscn_p (ld_state.ebl, $1))
224 $$->val.section.ignored = true;
226 $$->val.section.ignored = false;
231 /* This is a short cut for "ID { *(ID) }". */
232 $$ = new_output_rule (output_section);
233 $$->val.section.name = $1;
234 $$->val.section.input = new_input_rule (input_section);
235 $$->val.section.input->next = NULL;
236 $$->val.section.input->val.section =
237 (struct filemask_section_name *)
238 obstack_alloc (&ld_state.smem,
239 sizeof (struct filemask_section_name));
240 $$->val.section.input->val.section->filemask = NULL;
241 $$->val.section.input->val.section->excludemask = NULL;
242 $$->val.section.input->val.section->section_name =
243 new_input_section_name ($1, false);
244 $$->val.section.input->val.section->keep_flag = false;
245 if (ld_state.strip == strip_debug
246 && ebl_debugscn_p (ld_state.ebl, $1))
247 $$->val.section.ignored = true;
249 $$->val.section.ignored = false;
253 assignment: kID '=' expr
254 { $$ = new_assignment ($1, $3, false); }
255 | kPROVIDE '(' kID '=' expr ')'
256 { $$ = new_assignment ($3, $5, true); }
259 inputsections: inputsections inputsection
268 inputsection: sectionname
270 $$ = new_input_rule (input_section);
271 $$->val.section = $1;
273 | kKEEP '(' sectionname ')'
275 $3->keep_flag = true;
277 $$ = new_input_rule (input_section);
278 $$->val.section = $3;
282 $$ = new_input_rule (input_assignment);
283 $$->val.assignment = $1;
287 sectionname: filename_id_star '(' exclude_opt sort_opt_name ')'
289 $$ = (struct filemask_section_name *)
290 obstack_alloc (&ld_state.smem, sizeof (*$$));
292 $$->excludemask = $3;
293 $$->section_name = $4;
294 $$->keep_flag = false;
299 { $$ = new_input_section_name ($1, false); }
301 { $$ = new_input_section_name ($3, true); }
304 exclude_opt: kEXCLUDE_FILE '(' filename_id ')'
310 expr: kALIGN '(' expr ')'
312 $$ = new_expr (exp_align);
319 $$ = new_expr (exp_mult);
320 $$->val.binary.left = $1;
321 $$->val.binary.right = $3;
326 $$->val.binary.left = $1;
327 $$->val.binary.right = $3;
332 $$->val.binary.left = $1;
333 $$->val.binary.right = $3;
337 $$ = new_expr (exp_and);
338 $$->val.binary.left = $1;
339 $$->val.binary.right = $3;
343 $$ = new_expr (exp_or);
344 $$->val.binary.left = $1;
345 $$->val.binary.right = $3;
349 $$ = new_expr (exp_num);
354 $$ = new_expr (exp_id);
358 { $$ = new_expr (exp_sizeof_headers); }
360 { $$ = new_expr (exp_pagesize); }
363 filename_id_list: filename_id_list comma_opt filename_id_listelem
368 | filename_id_listelem
376 filename_id_listelem: kGROUP '(' filename_id_list ')'
378 /* First little optimization. If there is only one
379 file in the group don't do anything. */
382 $3->next->group_start = 1;
387 | kAS_NEEDED '(' filename_id_list ')'
388 { $$ = mark_as_needed ($3); }
390 { $$ = new_filename_listelem ($1); }
394 versionlist: versionlist version
403 version: '{' version_stmt_list '}' ';'
405 $2->versionname = "";
406 $2->parentname = NULL;
409 | filename_id '{' version_stmt_list '}' ';'
411 $3->versionname = $1;
412 $3->parentname = NULL;
415 | filename_id '{' version_stmt_list '}' filename_id ';'
417 $3->versionname = $1;
424 version_stmt_list version_stmt
425 { $$ = merge_versions ($1, $2); }
430 version_stmt: kGLOBAL filename_id_star_list
431 { $$ = new_version (NULL, $2); }
432 | kLOCAL filename_id_star_list
433 { $$ = new_version ($2, NULL); }
436 filename_id_star_list:
437 filename_id_star_list filename_id_star ';'
439 struct id_list *newp = new_id_listelem ($2);
440 newp->next = $1->next;
441 $$ = $1->next = newp;
443 | filename_id_star ';'
444 { $$ = new_id_listelem ($1); }
447 filename_id: kFILENAME
453 filename_id_star: filename_id
462 yyerror (const char *s)
464 error (0, 0, (ld_scan_version_script
465 ? gettext ("while reading version script '%s': %s at line %d")
466 : gettext ("while reading linker script '%s': %s at line %d")),
467 ldin_fname, gettext (s), ldlineno);
471 static struct expression *
474 struct expression *newp = (struct expression *)
475 obstack_alloc (&ld_state.smem, sizeof (*newp));
482 static struct input_section_name *
483 new_input_section_name (const char *name, bool sort_flag)
485 struct input_section_name *newp = (struct input_section_name *)
486 obstack_alloc (&ld_state.smem, sizeof (*newp));
489 newp->sort_flag = sort_flag;
494 static struct input_rule *
495 new_input_rule (int tag)
497 struct input_rule *newp = (struct input_rule *)
498 obstack_alloc (&ld_state.smem, sizeof (*newp));
506 static struct output_rule *
507 new_output_rule (int tag)
509 struct output_rule *newp = (struct output_rule *)
510 memset (obstack_alloc (&ld_state.smem, sizeof (*newp)),
511 '\0', sizeof (*newp));
519 static struct assignment *
520 new_assignment (const char *variable, struct expression *expression,
523 struct assignment *newp = (struct assignment *)
524 obstack_alloc (&ld_state.smem, sizeof (*newp));
526 newp->variable = variable;
527 newp->expression = expression;
529 newp->provide_flag = provide_flag;
531 /* Insert the symbol into a hash table. We will later have to matc*/
537 new_segment (int mode, struct output_rule *output_rule)
539 struct output_segment *newp;
542 = (struct output_segment *) obstack_alloc (&ld_state.smem, sizeof (*newp));
546 newp->output_rules = output_rule->next;
547 output_rule->next = NULL;
549 /* Enqueue the output segment description. */
550 if (ld_state.output_segments == NULL)
551 ld_state.output_segments = newp;
554 newp->next = ld_state.output_segments->next;
555 ld_state.output_segments = ld_state.output_segments->next = newp;
558 /* If the output file should be stripped of all symbol set the flag
559 in the structures of all output sections. */
560 if (mode == 0 && ld_state.strip == strip_all)
562 struct output_rule *runp;
564 for (runp = newp->output_rules; runp != NULL; runp = runp->next)
565 if (runp->tag == output_section)
566 runp->val.section.ignored = true;
571 static struct filename_list *
572 new_filename_listelem (const char *string)
574 struct filename_list *newp;
576 /* We use calloc and not the obstack since this object can be freed soon. */
577 newp = (struct filename_list *) xcalloc (1, sizeof (*newp));
584 static struct filename_list *
585 mark_as_needed (struct filename_list *listp)
587 struct filename_list *runp = listp;
590 runp->as_needed = true;
593 while (runp != listp);
600 add_inputfiles (struct filename_list *fnames)
602 assert (fnames != NULL);
604 if (ld_state.srcfiles == NULL)
605 ld_state.srcfiles = fnames;
608 struct filename_list *first = ld_state.srcfiles->next;
610 ld_state.srcfiles->next = fnames->next;
611 fnames->next = first;
612 ld_state.srcfiles->next = fnames;
618 special_char_p (const char *str)
622 if (__builtin_expect (*str == '*', 0)
623 || __builtin_expect (*str == '?', 0)
624 || __builtin_expect (*str == '[', 0))
634 static struct id_list *
635 new_id_listelem (const char *str)
637 struct id_list *newp;
639 newp = (struct id_list *) obstack_alloc (&ld_state.smem, sizeof (*newp));
641 newp->u.id_type = id_all;
642 else if (__builtin_expect (special_char_p (str), false))
643 newp->u.id_type = id_wild;
645 newp->u.id_type = id_str;
653 static struct version *
654 new_version (struct id_list *local, struct id_list *global)
656 struct version *newp;
658 newp = (struct version *) obstack_alloc (&ld_state.smem, sizeof (*newp));
660 newp->local_names = local;
661 newp->global_names = global;
662 newp->versionname = NULL;
663 newp->parentname = NULL;
669 static struct version *
670 merge_versions (struct version *one, struct version *two)
672 assert (two->local_names == NULL || two->global_names == NULL);
674 if (two->local_names != NULL)
676 if (one->local_names == NULL)
677 one->local_names = two->local_names;
680 two->local_names->next = one->local_names->next;
681 one->local_names = one->local_names->next = two->local_names;
686 if (one->global_names == NULL)
687 one->global_names = two->global_names;
690 two->global_names->next = one->global_names->next;
691 one->global_names = one->global_names->next = two->global_names;
700 add_id_list (const char *versionname, struct id_list *runp, _Bool local)
702 struct id_list *lastp = runp;
708 /* Convert into a simple single-linked list. */
710 assert (runp != NULL);
714 if (runp->u.id_type == id_str)
716 struct id_list *curp;
717 struct id_list *defp;
718 unsigned long int hval = elf_hash (runp->id);
723 defp = ld_version_str_tab_find (&ld_state.version_str_tab, hval, curp);
726 /* There is already a version definition for this symbol. */
727 while (strcmp (defp->u.s.versionname, versionname) != 0)
729 if (defp->next == NULL)
731 /* No version like this so far. */
733 curp->u.s.local = local;
734 curp->u.s.versionname = versionname;
743 if (defp != NULL && defp->u.s.local != local)
744 error (EXIT_FAILURE, 0, versionname[0] == '\0'
746 symbol '%s' is declared both local and global for unnamed version")
748 symbol '%s' is declared both local and global for version '%s'"),
749 runp->id, versionname);
753 /* This is the first version definition for this symbol. */
754 ld_version_str_tab_insert (&ld_state.version_str_tab, hval, curp);
756 curp->u.s.local = local;
757 curp->u.s.versionname = versionname;
761 else if (runp->u.id_type == id_all)
765 if (ld_state.default_bind_global)
766 error (EXIT_FAILURE, 0,
767 gettext ("default visibility set as local and global"));
768 ld_state.default_bind_local = true;
772 if (ld_state.default_bind_local)
773 error (EXIT_FAILURE, 0,
774 gettext ("default visibility set as local and global"));
775 ld_state.default_bind_global = true;
782 assert (runp->u.id_type == id_wild);
786 while (runp != NULL);
791 add_versions (struct version *versions)
793 struct version *lastp = versions;
795 if (versions == NULL)
798 /* Convert into a simple single-linked list. */
799 versions = versions->next;
800 assert (versions != NULL);
805 add_id_list (versions->versionname, versions->local_names, true);
806 add_id_list (versions->versionname, versions->global_names, false);
808 versions = versions->next;
810 while (versions != NULL);