Rev 5199 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5199 | serge | 1 | /* This module handles expression trees. |
6324 | serge | 2 | Copyright (C) 1991-2015 Free Software Foundation, Inc. |
5199 | serge | 3 | Written by Steve Chamberlain of Cygnus Support |
4 | |||
5 | This file is part of the GNU Binutils. |
||
6 | |||
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. |
||
11 | |||
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. |
||
16 | |||
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. */ |
||
21 | |||
22 | |||
23 | /* This module is in charge of working out the contents of expressions. |
||
24 | |||
25 | It has to keep track of the relative/absness of a symbol etc. This |
||
26 | is done by keeping all values in a struct (an etree_value_type) |
||
27 | which contains a value, a section to which it is relative and a |
||
28 | valid bit. */ |
||
29 | |||
30 | #include "sysdep.h" |
||
31 | #include "bfd.h" |
||
32 | #include "bfdlink.h" |
||
33 | |||
34 | #include "ld.h" |
||
35 | #include "ldmain.h" |
||
36 | #include "ldmisc.h" |
||
37 | #include "ldexp.h" |
||
38 | #include "ldlex.h" |
||
39 | #include |
||
40 | #include "ldlang.h" |
||
41 | #include "libiberty.h" |
||
42 | #include "safe-ctype.h" |
||
43 | |||
44 | static void exp_fold_tree_1 (etree_type *); |
||
45 | static bfd_vma align_n (bfd_vma, bfd_vma); |
||
46 | |||
47 | segment_type *segments; |
||
48 | |||
49 | struct ldexp_control expld; |
||
50 | |||
6324 | serge | 51 | /* This structure records symbols for which we need to keep track of |
52 | definedness for use in the DEFINED () test. It is also used in |
||
53 | making absolute symbols section relative late in the link. */ |
||
54 | |||
55 | struct definedness_hash_entry |
||
56 | { |
||
57 | struct bfd_hash_entry root; |
||
58 | |||
59 | /* If this symbol was assigned from "dot" outside of an output |
||
60 | section statement, the section we'd like it relative to. */ |
||
61 | asection *final_sec; |
||
62 | |||
63 | /* Symbol was defined by an object file. */ |
||
64 | unsigned int by_object : 1; |
||
65 | |||
66 | /* Symbols was defined by a script. */ |
||
67 | unsigned int by_script : 1; |
||
68 | |||
69 | /* Low bit of iteration count. Symbols with matching iteration have |
||
70 | been defined in this pass over the script. */ |
||
71 | unsigned int iteration : 1; |
||
72 | }; |
||
73 | |||
74 | static struct bfd_hash_table definedness_table; |
||
75 | |||
5199 | serge | 76 | /* Print the string representation of the given token. Surround it |
77 | with spaces if INFIX_P is TRUE. */ |
||
78 | |||
79 | static void |
||
80 | exp_print_token (token_code_type code, int infix_p) |
||
81 | { |
||
82 | static const struct |
||
83 | { |
||
84 | token_code_type code; |
||
85 | const char * name; |
||
86 | } |
||
87 | table[] = |
||
88 | { |
||
89 | { INT, "int" }, |
||
90 | { NAME, "NAME" }, |
||
91 | { PLUSEQ, "+=" }, |
||
92 | { MINUSEQ, "-=" }, |
||
93 | { MULTEQ, "*=" }, |
||
94 | { DIVEQ, "/=" }, |
||
95 | { LSHIFTEQ, "<<=" }, |
||
96 | { RSHIFTEQ, ">>=" }, |
||
97 | { ANDEQ, "&=" }, |
||
98 | { OREQ, "|=" }, |
||
99 | { OROR, "||" }, |
||
100 | { ANDAND, "&&" }, |
||
101 | { EQ, "==" }, |
||
102 | { NE, "!=" }, |
||
103 | { LE, "<=" }, |
||
104 | { GE, ">=" }, |
||
105 | { LSHIFT, "<<" }, |
||
106 | { RSHIFT, ">>" }, |
||
107 | { LOG2CEIL, "LOG2CEIL" }, |
||
108 | { ALIGN_K, "ALIGN" }, |
||
109 | { BLOCK, "BLOCK" }, |
||
110 | { QUAD, "QUAD" }, |
||
111 | { SQUAD, "SQUAD" }, |
||
112 | { LONG, "LONG" }, |
||
113 | { SHORT, "SHORT" }, |
||
114 | { BYTE, "BYTE" }, |
||
115 | { SECTIONS, "SECTIONS" }, |
||
116 | { SIZEOF_HEADERS, "SIZEOF_HEADERS" }, |
||
117 | { MEMORY, "MEMORY" }, |
||
118 | { DEFINED, "DEFINED" }, |
||
119 | { TARGET_K, "TARGET" }, |
||
120 | { SEARCH_DIR, "SEARCH_DIR" }, |
||
121 | { MAP, "MAP" }, |
||
122 | { ENTRY, "ENTRY" }, |
||
123 | { NEXT, "NEXT" }, |
||
124 | { ALIGNOF, "ALIGNOF" }, |
||
125 | { SIZEOF, "SIZEOF" }, |
||
126 | { ADDR, "ADDR" }, |
||
127 | { LOADADDR, "LOADADDR" }, |
||
128 | { CONSTANT, "CONSTANT" }, |
||
129 | { ABSOLUTE, "ABSOLUTE" }, |
||
130 | { MAX_K, "MAX" }, |
||
131 | { MIN_K, "MIN" }, |
||
132 | { ASSERT_K, "ASSERT" }, |
||
133 | { REL, "relocatable" }, |
||
134 | { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" }, |
||
135 | { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" }, |
||
136 | { DATA_SEGMENT_END, "DATA_SEGMENT_END" }, |
||
137 | { ORIGIN, "ORIGIN" }, |
||
138 | { LENGTH, "LENGTH" }, |
||
139 | { SEGMENT_START, "SEGMENT_START" } |
||
140 | }; |
||
141 | unsigned int idx; |
||
142 | |||
143 | for (idx = 0; idx < ARRAY_SIZE (table); idx++) |
||
144 | if (table[idx].code == code) |
||
145 | break; |
||
146 | |||
147 | if (infix_p) |
||
148 | fputc (' ', config.map_file); |
||
149 | |||
150 | if (idx < ARRAY_SIZE (table)) |
||
151 | fputs (table[idx].name, config.map_file); |
||
152 | else if (code < 127) |
||
153 | fputc (code, config.map_file); |
||
154 | else |
||
155 | fprintf (config.map_file, " |
||
156 | |||
157 | if (infix_p) |
||
158 | fputc (' ', config.map_file); |
||
159 | } |
||
160 | |||
161 | static void |
||
162 | make_log2ceil (void) |
||
163 | { |
||
164 | bfd_vma value = expld.result.value; |
||
165 | bfd_vma result = -1; |
||
166 | bfd_boolean round_up = FALSE; |
||
167 | |||
168 | do |
||
169 | { |
||
170 | result++; |
||
171 | /* If more than one bit is set in the value we will need to round up. */ |
||
172 | if ((value > 1) && (value & 1)) |
||
173 | round_up = TRUE; |
||
174 | } |
||
175 | while (value >>= 1); |
||
176 | |||
177 | if (round_up) |
||
178 | result += 1; |
||
179 | expld.result.section = NULL; |
||
180 | expld.result.value = result; |
||
181 | } |
||
182 | |||
183 | static void |
||
184 | make_abs (void) |
||
185 | { |
||
186 | if (expld.result.section != NULL) |
||
187 | expld.result.value += expld.result.section->vma; |
||
188 | expld.result.section = bfd_abs_section_ptr; |
||
6324 | serge | 189 | expld.rel_from_abs = FALSE; |
5199 | serge | 190 | } |
191 | |||
192 | static void |
||
193 | new_abs (bfd_vma value) |
||
194 | { |
||
195 | expld.result.valid_p = TRUE; |
||
196 | expld.result.section = bfd_abs_section_ptr; |
||
197 | expld.result.value = value; |
||
198 | expld.result.str = NULL; |
||
199 | } |
||
200 | |||
201 | etree_type * |
||
202 | exp_intop (bfd_vma value) |
||
203 | { |
||
204 | etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->value)); |
||
205 | new_e->type.node_code = INT; |
||
206 | new_e->type.filename = ldlex_filename (); |
||
207 | new_e->type.lineno = lineno; |
||
208 | new_e->value.value = value; |
||
209 | new_e->value.str = NULL; |
||
210 | new_e->type.node_class = etree_value; |
||
211 | return new_e; |
||
212 | } |
||
213 | |||
214 | etree_type * |
||
215 | exp_bigintop (bfd_vma value, char *str) |
||
216 | { |
||
217 | etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->value)); |
||
218 | new_e->type.node_code = INT; |
||
219 | new_e->type.filename = ldlex_filename (); |
||
220 | new_e->type.lineno = lineno; |
||
221 | new_e->value.value = value; |
||
222 | new_e->value.str = str; |
||
223 | new_e->type.node_class = etree_value; |
||
224 | return new_e; |
||
225 | } |
||
226 | |||
227 | /* Build an expression representing an unnamed relocatable value. */ |
||
228 | |||
229 | etree_type * |
||
230 | exp_relop (asection *section, bfd_vma value) |
||
231 | { |
||
232 | etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->rel)); |
||
233 | new_e->type.node_code = REL; |
||
234 | new_e->type.filename = ldlex_filename (); |
||
235 | new_e->type.lineno = lineno; |
||
236 | new_e->type.node_class = etree_rel; |
||
237 | new_e->rel.section = section; |
||
238 | new_e->rel.value = value; |
||
239 | return new_e; |
||
240 | } |
||
241 | |||
242 | static void |
||
243 | new_number (bfd_vma value) |
||
244 | { |
||
245 | expld.result.valid_p = TRUE; |
||
246 | expld.result.value = value; |
||
247 | expld.result.str = NULL; |
||
248 | expld.result.section = NULL; |
||
249 | } |
||
250 | |||
251 | static void |
||
252 | new_rel (bfd_vma value, asection *section) |
||
253 | { |
||
254 | expld.result.valid_p = TRUE; |
||
255 | expld.result.value = value; |
||
256 | expld.result.str = NULL; |
||
257 | expld.result.section = section; |
||
258 | } |
||
259 | |||
260 | static void |
||
261 | new_rel_from_abs (bfd_vma value) |
||
262 | { |
||
263 | asection *s = expld.section; |
||
264 | |||
6324 | serge | 265 | expld.rel_from_abs = TRUE; |
5199 | serge | 266 | expld.result.valid_p = TRUE; |
267 | expld.result.value = value - s->vma; |
||
268 | expld.result.str = NULL; |
||
269 | expld.result.section = s; |
||
270 | } |
||
271 | |||
6324 | serge | 272 | /* New-function for the definedness hash table. */ |
273 | |||
274 | static struct bfd_hash_entry * |
||
275 | definedness_newfunc (struct bfd_hash_entry *entry, |
||
276 | struct bfd_hash_table *table ATTRIBUTE_UNUSED, |
||
277 | const char *name ATTRIBUTE_UNUSED) |
||
278 | { |
||
279 | struct definedness_hash_entry *ret = (struct definedness_hash_entry *) entry; |
||
280 | |||
281 | if (ret == NULL) |
||
282 | ret = (struct definedness_hash_entry *) |
||
283 | bfd_hash_allocate (table, sizeof (struct definedness_hash_entry)); |
||
284 | |||
285 | if (ret == NULL) |
||
286 | einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name); |
||
287 | |||
288 | ret->by_object = 0; |
||
289 | ret->by_script = 0; |
||
290 | ret->iteration = 0; |
||
291 | return &ret->root; |
||
292 | } |
||
293 | |||
294 | /* Called during processing of linker script script expressions. |
||
295 | For symbols assigned in a linker script, return a struct describing |
||
296 | where the symbol is defined relative to the current expression, |
||
297 | otherwise return NULL. */ |
||
298 | |||
299 | static struct definedness_hash_entry * |
||
300 | symbol_defined (const char *name) |
||
301 | { |
||
302 | return ((struct definedness_hash_entry *) |
||
303 | bfd_hash_lookup (&definedness_table, name, FALSE, FALSE)); |
||
304 | } |
||
305 | |||
306 | /* Update the definedness state of NAME. Return FALSE if script symbol |
||
307 | is multiply defining a strong symbol in an object. */ |
||
308 | |||
309 | static bfd_boolean |
||
310 | update_definedness (const char *name, struct bfd_link_hash_entry *h) |
||
311 | { |
||
312 | bfd_boolean ret; |
||
313 | struct definedness_hash_entry *defentry |
||
314 | = (struct definedness_hash_entry *) |
||
315 | bfd_hash_lookup (&definedness_table, name, TRUE, FALSE); |
||
316 | |||
317 | if (defentry == NULL) |
||
318 | einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name); |
||
319 | |||
320 | /* If the symbol was already defined, and not by a script, then it |
||
321 | must be defined by an object file or by the linker target code. */ |
||
322 | ret = TRUE; |
||
323 | if (!defentry->by_script |
||
324 | && (h->type == bfd_link_hash_defined |
||
325 | || h->type == bfd_link_hash_defweak |
||
326 | || h->type == bfd_link_hash_common)) |
||
327 | { |
||
328 | defentry->by_object = 1; |
||
329 | if (h->type == bfd_link_hash_defined |
||
330 | && h->u.def.section->output_section != NULL |
||
331 | && !h->linker_def) |
||
332 | ret = FALSE; |
||
333 | } |
||
334 | |||
335 | defentry->by_script = 1; |
||
336 | defentry->iteration = lang_statement_iteration; |
||
337 | defentry->final_sec = bfd_abs_section_ptr; |
||
338 | if (expld.phase == lang_final_phase_enum |
||
339 | && expld.rel_from_abs |
||
340 | && expld.result.section == bfd_abs_section_ptr) |
||
341 | defentry->final_sec = section_for_dot (); |
||
342 | return ret; |
||
343 | } |
||
344 | |||
5199 | serge | 345 | static void |
346 | fold_unary (etree_type *tree) |
||
347 | { |
||
348 | exp_fold_tree_1 (tree->unary.child); |
||
349 | if (expld.result.valid_p) |
||
350 | { |
||
351 | switch (tree->type.node_code) |
||
352 | { |
||
353 | case ALIGN_K: |
||
354 | if (expld.phase != lang_first_phase_enum) |
||
355 | new_rel_from_abs (align_n (expld.dot, expld.result.value)); |
||
356 | else |
||
357 | expld.result.valid_p = FALSE; |
||
358 | break; |
||
359 | |||
360 | case ABSOLUTE: |
||
361 | make_abs (); |
||
362 | break; |
||
363 | |||
364 | case LOG2CEIL: |
||
365 | make_log2ceil (); |
||
366 | break; |
||
367 | |||
368 | case '~': |
||
369 | expld.result.value = ~expld.result.value; |
||
370 | break; |
||
371 | |||
372 | case '!': |
||
373 | expld.result.value = !expld.result.value; |
||
374 | break; |
||
375 | |||
376 | case '-': |
||
377 | expld.result.value = -expld.result.value; |
||
378 | break; |
||
379 | |||
380 | case NEXT: |
||
381 | /* Return next place aligned to value. */ |
||
382 | if (expld.phase != lang_first_phase_enum) |
||
383 | { |
||
384 | make_abs (); |
||
385 | expld.result.value = align_n (expld.dot, expld.result.value); |
||
386 | } |
||
387 | else |
||
388 | expld.result.valid_p = FALSE; |
||
389 | break; |
||
390 | |||
391 | case DATA_SEGMENT_END: |
||
392 | if (expld.phase == lang_first_phase_enum |
||
393 | || expld.section != bfd_abs_section_ptr) |
||
394 | { |
||
395 | expld.result.valid_p = FALSE; |
||
396 | } |
||
397 | else if (expld.dataseg.phase == exp_dataseg_align_seen |
||
398 | || expld.dataseg.phase == exp_dataseg_relro_seen) |
||
399 | { |
||
400 | expld.dataseg.phase = exp_dataseg_end_seen; |
||
401 | expld.dataseg.end = expld.result.value; |
||
402 | } |
||
403 | else if (expld.dataseg.phase == exp_dataseg_done |
||
404 | || expld.dataseg.phase == exp_dataseg_adjust |
||
405 | || expld.dataseg.phase == exp_dataseg_relro_adjust) |
||
406 | { |
||
407 | /* OK. */ |
||
408 | } |
||
409 | else |
||
410 | expld.result.valid_p = FALSE; |
||
411 | break; |
||
412 | |||
413 | default: |
||
414 | FAIL (); |
||
415 | break; |
||
416 | } |
||
417 | } |
||
418 | } |
||
419 | |||
420 | static void |
||
421 | fold_binary (etree_type *tree) |
||
422 | { |
||
423 | etree_value_type lhs; |
||
424 | exp_fold_tree_1 (tree->binary.lhs); |
||
425 | |||
426 | /* The SEGMENT_START operator is special because its first |
||
427 | operand is a string, not the name of a symbol. Note that the |
||
428 | operands have been swapped, so binary.lhs is second (default) |
||
429 | operand, binary.rhs is first operand. */ |
||
430 | if (expld.result.valid_p && tree->type.node_code == SEGMENT_START) |
||
431 | { |
||
432 | const char *segment_name; |
||
433 | segment_type *seg; |
||
434 | |||
435 | /* Check to see if the user has overridden the default |
||
436 | value. */ |
||
437 | segment_name = tree->binary.rhs->name.name; |
||
438 | for (seg = segments; seg; seg = seg->next) |
||
439 | if (strcmp (seg->name, segment_name) == 0) |
||
440 | { |
||
441 | if (!seg->used |
||
442 | && config.magic_demand_paged |
||
443 | && (seg->value % config.maxpagesize) != 0) |
||
444 | einfo (_("%P: warning: address of `%s' isn't multiple of maximum page size\n"), |
||
445 | segment_name); |
||
446 | seg->used = TRUE; |
||
447 | new_rel_from_abs (seg->value); |
||
448 | break; |
||
449 | } |
||
450 | return; |
||
451 | } |
||
452 | |||
453 | lhs = expld.result; |
||
454 | exp_fold_tree_1 (tree->binary.rhs); |
||
455 | expld.result.valid_p &= lhs.valid_p; |
||
456 | |||
457 | if (expld.result.valid_p) |
||
458 | { |
||
459 | if (lhs.section != expld.result.section) |
||
460 | { |
||
461 | /* If the values are from different sections, and neither is |
||
462 | just a number, make both the source arguments absolute. */ |
||
463 | if (expld.result.section != NULL |
||
464 | && lhs.section != NULL) |
||
465 | { |
||
466 | make_abs (); |
||
467 | lhs.value += lhs.section->vma; |
||
468 | lhs.section = bfd_abs_section_ptr; |
||
469 | } |
||
470 | |||
471 | /* If the rhs is just a number, keep the lhs section. */ |
||
472 | else if (expld.result.section == NULL) |
||
473 | { |
||
474 | expld.result.section = lhs.section; |
||
475 | /* Make this NULL so that we know one of the operands |
||
476 | was just a number, for later tests. */ |
||
477 | lhs.section = NULL; |
||
478 | } |
||
479 | } |
||
480 | /* At this point we know that both operands have the same |
||
481 | section, or at least one of them is a plain number. */ |
||
482 | |||
483 | switch (tree->type.node_code) |
||
484 | { |
||
485 | /* Arithmetic operators, bitwise AND, bitwise OR and XOR |
||
486 | keep the section of one of their operands only when the |
||
487 | other operand is a plain number. Losing the section when |
||
488 | operating on two symbols, ie. a result of a plain number, |
||
489 | is required for subtraction and XOR. It's justifiable |
||
490 | for the other operations on the grounds that adding, |
||
491 | multiplying etc. two section relative values does not |
||
492 | really make sense unless they are just treated as |
||
493 | numbers. |
||
494 | The same argument could be made for many expressions |
||
495 | involving one symbol and a number. For example, |
||
496 | "1 << x" and "100 / x" probably should not be given the |
||
497 | section of x. The trouble is that if we fuss about such |
||
498 | things the rules become complex and it is onerous to |
||
499 | document ld expression evaluation. */ |
||
500 | #define BOP(x, y) \ |
||
501 | case x: \ |
||
502 | expld.result.value = lhs.value y expld.result.value; \ |
||
503 | if (expld.result.section == lhs.section) \ |
||
504 | expld.result.section = NULL; \ |
||
505 | break; |
||
506 | |||
507 | /* Comparison operators, logical AND, and logical OR always |
||
508 | return a plain number. */ |
||
509 | #define BOPN(x, y) \ |
||
510 | case x: \ |
||
511 | expld.result.value = lhs.value y expld.result.value; \ |
||
512 | expld.result.section = NULL; \ |
||
513 | break; |
||
514 | |||
515 | BOP ('+', +); |
||
516 | BOP ('*', *); |
||
517 | BOP ('-', -); |
||
518 | BOP (LSHIFT, <<); |
||
519 | BOP (RSHIFT, >>); |
||
520 | BOP ('&', &); |
||
521 | BOP ('^', ^); |
||
522 | BOP ('|', |); |
||
523 | BOPN (EQ, ==); |
||
524 | BOPN (NE, !=); |
||
525 | BOPN ('<', <); |
||
526 | BOPN ('>', >); |
||
527 | BOPN (LE, <=); |
||
528 | BOPN (GE, >=); |
||
529 | BOPN (ANDAND, &&); |
||
530 | BOPN (OROR, ||); |
||
531 | |||
532 | case '%': |
||
533 | if (expld.result.value != 0) |
||
534 | expld.result.value = ((bfd_signed_vma) lhs.value |
||
535 | % (bfd_signed_vma) expld.result.value); |
||
536 | else if (expld.phase != lang_mark_phase_enum) |
||
537 | einfo (_("%F%S %% by zero\n"), tree->binary.rhs); |
||
538 | if (expld.result.section == lhs.section) |
||
539 | expld.result.section = NULL; |
||
540 | break; |
||
541 | |||
542 | case '/': |
||
543 | if (expld.result.value != 0) |
||
544 | expld.result.value = ((bfd_signed_vma) lhs.value |
||
545 | / (bfd_signed_vma) expld.result.value); |
||
546 | else if (expld.phase != lang_mark_phase_enum) |
||
547 | einfo (_("%F%S / by zero\n"), tree->binary.rhs); |
||
548 | if (expld.result.section == lhs.section) |
||
549 | expld.result.section = NULL; |
||
550 | break; |
||
551 | |||
552 | case MAX_K: |
||
553 | if (lhs.value > expld.result.value) |
||
554 | expld.result.value = lhs.value; |
||
555 | break; |
||
556 | |||
557 | case MIN_K: |
||
558 | if (lhs.value < expld.result.value) |
||
559 | expld.result.value = lhs.value; |
||
560 | break; |
||
561 | |||
562 | case ALIGN_K: |
||
563 | expld.result.value = align_n (lhs.value, expld.result.value); |
||
564 | break; |
||
565 | |||
566 | case DATA_SEGMENT_ALIGN: |
||
567 | expld.dataseg.relro = exp_dataseg_relro_start; |
||
568 | if (expld.phase == lang_first_phase_enum |
||
569 | || expld.section != bfd_abs_section_ptr) |
||
570 | expld.result.valid_p = FALSE; |
||
571 | else |
||
572 | { |
||
573 | bfd_vma maxpage = lhs.value; |
||
574 | bfd_vma commonpage = expld.result.value; |
||
575 | |||
576 | expld.result.value = align_n (expld.dot, maxpage); |
||
577 | if (expld.dataseg.phase == exp_dataseg_relro_adjust) |
||
578 | expld.result.value = expld.dataseg.base; |
||
579 | else if (expld.dataseg.phase == exp_dataseg_adjust) |
||
580 | { |
||
581 | if (commonpage < maxpage) |
||
582 | expld.result.value += ((expld.dot + commonpage - 1) |
||
583 | & (maxpage - commonpage)); |
||
584 | } |
||
585 | else |
||
586 | { |
||
587 | expld.result.value += expld.dot & (maxpage - 1); |
||
588 | if (expld.dataseg.phase == exp_dataseg_done) |
||
589 | { |
||
590 | /* OK. */ |
||
591 | } |
||
592 | else if (expld.dataseg.phase == exp_dataseg_none) |
||
593 | { |
||
594 | expld.dataseg.phase = exp_dataseg_align_seen; |
||
595 | expld.dataseg.base = expld.result.value; |
||
596 | expld.dataseg.pagesize = commonpage; |
||
597 | expld.dataseg.maxpagesize = maxpage; |
||
598 | expld.dataseg.relro_end = 0; |
||
599 | } |
||
600 | else |
||
601 | expld.result.valid_p = FALSE; |
||
602 | } |
||
603 | } |
||
604 | break; |
||
605 | |||
606 | case DATA_SEGMENT_RELRO_END: |
||
6324 | serge | 607 | /* Operands swapped! DATA_SEGMENT_RELRO_END(offset,exp) |
608 | has offset in expld.result and exp in lhs. */ |
||
5199 | serge | 609 | expld.dataseg.relro = exp_dataseg_relro_end; |
6324 | serge | 610 | expld.dataseg.relro_offset = expld.result.value; |
5199 | serge | 611 | if (expld.phase == lang_first_phase_enum |
612 | || expld.section != bfd_abs_section_ptr) |
||
613 | expld.result.valid_p = FALSE; |
||
614 | else if (expld.dataseg.phase == exp_dataseg_align_seen |
||
615 | || expld.dataseg.phase == exp_dataseg_adjust |
||
616 | || expld.dataseg.phase == exp_dataseg_relro_adjust |
||
617 | || expld.dataseg.phase == exp_dataseg_done) |
||
618 | { |
||
619 | if (expld.dataseg.phase == exp_dataseg_align_seen |
||
620 | || expld.dataseg.phase == exp_dataseg_relro_adjust) |
||
621 | expld.dataseg.relro_end = lhs.value + expld.result.value; |
||
622 | |||
623 | if (expld.dataseg.phase == exp_dataseg_relro_adjust |
||
624 | && (expld.dataseg.relro_end |
||
625 | & (expld.dataseg.pagesize - 1))) |
||
626 | { |
||
627 | expld.dataseg.relro_end += expld.dataseg.pagesize - 1; |
||
628 | expld.dataseg.relro_end &= ~(expld.dataseg.pagesize - 1); |
||
629 | expld.result.value = (expld.dataseg.relro_end |
||
630 | - expld.result.value); |
||
631 | } |
||
632 | else |
||
633 | expld.result.value = lhs.value; |
||
634 | |||
635 | if (expld.dataseg.phase == exp_dataseg_align_seen) |
||
636 | expld.dataseg.phase = exp_dataseg_relro_seen; |
||
637 | } |
||
638 | else |
||
639 | expld.result.valid_p = FALSE; |
||
640 | break; |
||
641 | |||
642 | default: |
||
643 | FAIL (); |
||
644 | } |
||
645 | } |
||
646 | } |
||
647 | |||
648 | static void |
||
649 | fold_trinary (etree_type *tree) |
||
650 | { |
||
651 | exp_fold_tree_1 (tree->trinary.cond); |
||
652 | if (expld.result.valid_p) |
||
653 | exp_fold_tree_1 (expld.result.value |
||
654 | ? tree->trinary.lhs |
||
655 | : tree->trinary.rhs); |
||
656 | } |
||
657 | |||
658 | static void |
||
659 | fold_name (etree_type *tree) |
||
660 | { |
||
661 | memset (&expld.result, 0, sizeof (expld.result)); |
||
662 | |||
663 | switch (tree->type.node_code) |
||
664 | { |
||
665 | case SIZEOF_HEADERS: |
||
666 | if (expld.phase != lang_first_phase_enum) |
||
667 | { |
||
668 | bfd_vma hdr_size = 0; |
||
669 | /* Don't find the real header size if only marking sections; |
||
670 | The bfd function may cache incorrect data. */ |
||
671 | if (expld.phase != lang_mark_phase_enum) |
||
672 | hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info); |
||
673 | new_number (hdr_size); |
||
674 | } |
||
675 | break; |
||
676 | |||
677 | case DEFINED: |
||
6324 | serge | 678 | if (expld.phase != lang_first_phase_enum) |
5199 | serge | 679 | { |
680 | struct bfd_link_hash_entry *h; |
||
6324 | serge | 681 | struct definedness_hash_entry *def; |
5199 | serge | 682 | |
683 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
||
684 | &link_info, |
||
685 | tree->name.name, |
||
686 | FALSE, FALSE, TRUE); |
||
687 | new_number (h != NULL |
||
688 | && (h->type == bfd_link_hash_defined |
||
689 | || h->type == bfd_link_hash_defweak |
||
690 | || h->type == bfd_link_hash_common) |
||
6324 | serge | 691 | && ((def = symbol_defined (tree->name.name)) == NULL |
692 | || def->by_object |
||
693 | || def->iteration == (lang_statement_iteration & 1))); |
||
5199 | serge | 694 | } |
695 | break; |
||
696 | |||
697 | case NAME: |
||
698 | if (expld.assign_name != NULL |
||
699 | && strcmp (expld.assign_name, tree->name.name) == 0) |
||
6324 | serge | 700 | { |
701 | /* Self-assignment is only allowed for absolute symbols |
||
702 | defined in a linker script. */ |
||
703 | struct bfd_link_hash_entry *h; |
||
704 | struct definedness_hash_entry *def; |
||
705 | |||
706 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
||
707 | &link_info, |
||
708 | tree->name.name, |
||
709 | FALSE, FALSE, TRUE); |
||
710 | if (!(h != NULL |
||
711 | && (h->type == bfd_link_hash_defined |
||
712 | || h->type == bfd_link_hash_defweak) |
||
713 | && h->u.def.section == bfd_abs_section_ptr |
||
714 | && (def = symbol_defined (tree->name.name)) != NULL |
||
715 | && def->iteration == (lang_statement_iteration & 1))) |
||
5199 | serge | 716 | expld.assign_name = NULL; |
6324 | serge | 717 | } |
5199 | serge | 718 | if (expld.phase == lang_first_phase_enum) |
719 | ; |
||
720 | else if (tree->name.name[0] == '.' && tree->name.name[1] == 0) |
||
721 | new_rel_from_abs (expld.dot); |
||
722 | else |
||
723 | { |
||
724 | struct bfd_link_hash_entry *h; |
||
725 | |||
726 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
||
727 | &link_info, |
||
728 | tree->name.name, |
||
729 | TRUE, FALSE, TRUE); |
||
730 | if (!h) |
||
731 | einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); |
||
732 | else if (h->type == bfd_link_hash_defined |
||
733 | || h->type == bfd_link_hash_defweak) |
||
734 | { |
||
735 | asection *output_section; |
||
736 | |||
737 | output_section = h->u.def.section->output_section; |
||
738 | if (output_section == NULL) |
||
739 | { |
||
740 | if (expld.phase == lang_mark_phase_enum) |
||
741 | new_rel (h->u.def.value, h->u.def.section); |
||
742 | else |
||
743 | einfo (_("%X%S: unresolvable symbol `%s'" |
||
744 | " referenced in expression\n"), |
||
745 | tree, tree->name.name); |
||
746 | } |
||
747 | else if (output_section == bfd_abs_section_ptr |
||
748 | && (expld.section != bfd_abs_section_ptr |
||
749 | || config.sane_expr)) |
||
750 | new_number (h->u.def.value + h->u.def.section->output_offset); |
||
751 | else |
||
752 | new_rel (h->u.def.value + h->u.def.section->output_offset, |
||
753 | output_section); |
||
754 | } |
||
755 | else if (expld.phase == lang_final_phase_enum |
||
756 | || (expld.phase != lang_mark_phase_enum |
||
757 | && expld.assigning_to_dot)) |
||
758 | einfo (_("%F%S: undefined symbol `%s'" |
||
759 | " referenced in expression\n"), |
||
760 | tree, tree->name.name); |
||
761 | else if (h->type == bfd_link_hash_new) |
||
762 | { |
||
763 | h->type = bfd_link_hash_undefined; |
||
764 | h->u.undef.abfd = NULL; |
||
765 | if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail) |
||
766 | bfd_link_add_undef (link_info.hash, h); |
||
767 | } |
||
768 | } |
||
769 | break; |
||
770 | |||
771 | case ADDR: |
||
772 | if (expld.phase != lang_first_phase_enum) |
||
773 | { |
||
774 | lang_output_section_statement_type *os; |
||
775 | |||
776 | os = lang_output_section_find (tree->name.name); |
||
777 | if (os == NULL) |
||
778 | { |
||
779 | if (expld.phase == lang_final_phase_enum) |
||
780 | einfo (_("%F%S: undefined section `%s'" |
||
781 | " referenced in expression\n"), |
||
782 | tree, tree->name.name); |
||
783 | } |
||
784 | else if (os->processed_vma) |
||
785 | new_rel (0, os->bfd_section); |
||
786 | } |
||
787 | break; |
||
788 | |||
789 | case LOADADDR: |
||
790 | if (expld.phase != lang_first_phase_enum) |
||
791 | { |
||
792 | lang_output_section_statement_type *os; |
||
793 | |||
794 | os = lang_output_section_find (tree->name.name); |
||
795 | if (os == NULL) |
||
796 | { |
||
797 | if (expld.phase == lang_final_phase_enum) |
||
798 | einfo (_("%F%S: undefined section `%s'" |
||
799 | " referenced in expression\n"), |
||
800 | tree, tree->name.name); |
||
801 | } |
||
802 | else if (os->processed_lma) |
||
803 | { |
||
804 | if (os->load_base == NULL) |
||
805 | new_abs (os->bfd_section->lma); |
||
806 | else |
||
807 | { |
||
808 | exp_fold_tree_1 (os->load_base); |
||
809 | if (expld.result.valid_p) |
||
810 | make_abs (); |
||
811 | } |
||
812 | } |
||
813 | } |
||
814 | break; |
||
815 | |||
816 | case SIZEOF: |
||
817 | case ALIGNOF: |
||
818 | if (expld.phase != lang_first_phase_enum) |
||
819 | { |
||
820 | lang_output_section_statement_type *os; |
||
821 | |||
822 | os = lang_output_section_find (tree->name.name); |
||
823 | if (os == NULL) |
||
824 | { |
||
825 | if (expld.phase == lang_final_phase_enum) |
||
826 | einfo (_("%F%S: undefined section `%s'" |
||
827 | " referenced in expression\n"), |
||
828 | tree, tree->name.name); |
||
829 | new_number (0); |
||
830 | } |
||
831 | else if (os->bfd_section != NULL) |
||
832 | { |
||
833 | bfd_vma val; |
||
834 | |||
835 | if (tree->type.node_code == SIZEOF) |
||
836 | val = (os->bfd_section->size |
||
837 | / bfd_octets_per_byte (link_info.output_bfd)); |
||
838 | else |
||
839 | val = (bfd_vma)1 << os->bfd_section->alignment_power; |
||
840 | |||
841 | new_number (val); |
||
842 | } |
||
843 | else |
||
844 | new_number (0); |
||
845 | } |
||
846 | break; |
||
847 | |||
848 | case LENGTH: |
||
849 | { |
||
6324 | serge | 850 | if (expld.phase != lang_first_phase_enum) |
851 | { |
||
5199 | serge | 852 | lang_memory_region_type *mem; |
853 | |||
854 | mem = lang_memory_region_lookup (tree->name.name, FALSE); |
||
855 | if (mem != NULL) |
||
856 | new_number (mem->length); |
||
857 | else |
||
858 | einfo (_("%F%S: undefined MEMORY region `%s'" |
||
859 | " referenced in expression\n"), |
||
860 | tree, tree->name.name); |
||
861 | } |
||
6324 | serge | 862 | } |
5199 | serge | 863 | break; |
864 | |||
865 | case ORIGIN: |
||
866 | if (expld.phase != lang_first_phase_enum) |
||
867 | { |
||
868 | lang_memory_region_type *mem; |
||
869 | |||
870 | mem = lang_memory_region_lookup (tree->name.name, FALSE); |
||
871 | if (mem != NULL) |
||
872 | new_rel_from_abs (mem->origin); |
||
873 | else |
||
874 | einfo (_("%F%S: undefined MEMORY region `%s'" |
||
875 | " referenced in expression\n"), |
||
876 | tree, tree->name.name); |
||
877 | } |
||
878 | break; |
||
879 | |||
880 | case CONSTANT: |
||
881 | if (strcmp (tree->name.name, "MAXPAGESIZE") == 0) |
||
882 | new_number (config.maxpagesize); |
||
883 | else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0) |
||
884 | new_number (config.commonpagesize); |
||
885 | else |
||
886 | einfo (_("%F%S: unknown constant `%s' referenced in expression\n"), |
||
887 | tree, tree->name.name); |
||
888 | break; |
||
889 | |||
890 | default: |
||
891 | FAIL (); |
||
892 | break; |
||
893 | } |
||
894 | } |
||
895 | |||
6324 | serge | 896 | /* Return true if TREE is '.'. */ |
897 | |||
898 | static bfd_boolean |
||
899 | is_dot (const etree_type *tree) |
||
900 | { |
||
901 | return (tree->type.node_class == etree_name |
||
902 | && tree->type.node_code == NAME |
||
903 | && tree->name.name[0] == '.' |
||
904 | && tree->name.name[1] == 0); |
||
905 | } |
||
906 | |||
907 | /* Return true if TREE is a constant equal to VAL. */ |
||
908 | |||
909 | static bfd_boolean |
||
910 | is_value (const etree_type *tree, bfd_vma val) |
||
911 | { |
||
912 | return (tree->type.node_class == etree_value |
||
913 | && tree->value.value == val); |
||
914 | } |
||
915 | |||
916 | /* Return true if TREE is an absolute symbol equal to VAL defined in |
||
917 | a linker script. */ |
||
918 | |||
919 | static bfd_boolean |
||
920 | is_sym_value (const etree_type *tree, bfd_vma val) |
||
921 | { |
||
922 | struct bfd_link_hash_entry *h; |
||
923 | struct definedness_hash_entry *def; |
||
924 | |||
925 | return (tree->type.node_class == etree_name |
||
926 | && tree->type.node_code == NAME |
||
927 | && (def = symbol_defined (tree->name.name)) != NULL |
||
928 | && def->by_script |
||
929 | && def->iteration == (lang_statement_iteration & 1) |
||
930 | && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
||
931 | &link_info, |
||
932 | tree->name.name, |
||
933 | FALSE, FALSE, TRUE)) != NULL |
||
934 | && h->type == bfd_link_hash_defined |
||
935 | && h->u.def.section == bfd_abs_section_ptr |
||
936 | && h->u.def.value == val); |
||
937 | } |
||
938 | |||
939 | /* Return true if TREE is ". != 0". */ |
||
940 | |||
941 | static bfd_boolean |
||
942 | is_dot_ne_0 (const etree_type *tree) |
||
943 | { |
||
944 | return (tree->type.node_class == etree_binary |
||
945 | && tree->type.node_code == NE |
||
946 | && is_dot (tree->binary.lhs) |
||
947 | && is_value (tree->binary.rhs, 0)); |
||
948 | } |
||
949 | |||
950 | /* Return true if TREE is ". = . + 0" or ". = . + sym" where sym is an |
||
951 | absolute constant with value 0 defined in a linker script. */ |
||
952 | |||
953 | static bfd_boolean |
||
954 | is_dot_plus_0 (const etree_type *tree) |
||
955 | { |
||
956 | return (tree->type.node_class == etree_binary |
||
957 | && tree->type.node_code == '+' |
||
958 | && is_dot (tree->binary.lhs) |
||
959 | && (is_value (tree->binary.rhs, 0) |
||
960 | || is_sym_value (tree->binary.rhs, 0))); |
||
961 | } |
||
962 | |||
963 | /* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)". */ |
||
964 | |||
965 | static bfd_boolean |
||
966 | is_align_conditional (const etree_type *tree) |
||
967 | { |
||
968 | if (tree->type.node_class == etree_unary |
||
969 | && tree->type.node_code == ALIGN_K) |
||
970 | { |
||
971 | tree = tree->unary.child; |
||
972 | return (tree->type.node_class == etree_trinary |
||
973 | && is_dot_ne_0 (tree->trinary.cond) |
||
974 | && is_value (tree->trinary.rhs, 1)); |
||
975 | } |
||
976 | return FALSE; |
||
977 | } |
||
978 | |||
979 | /* Subroutine of exp_fold_tree_1 for copying a symbol type. */ |
||
980 | |||
5199 | serge | 981 | static void |
6324 | serge | 982 | try_copy_symbol_type (struct bfd_link_hash_entry * h, etree_type *src) |
983 | { |
||
984 | if (src->type.node_class == etree_name) |
||
985 | { |
||
986 | struct bfd_link_hash_entry *hsrc; |
||
987 | |||
988 | hsrc = bfd_link_hash_lookup (link_info.hash, src->name.name, |
||
989 | FALSE, FALSE, TRUE); |
||
990 | if (hsrc) |
||
991 | bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, |
||
992 | hsrc); |
||
993 | } |
||
994 | } |
||
995 | |||
996 | static void |
||
5199 | serge | 997 | exp_fold_tree_1 (etree_type *tree) |
998 | { |
||
999 | if (tree == NULL) |
||
1000 | { |
||
1001 | memset (&expld.result, 0, sizeof (expld.result)); |
||
1002 | return; |
||
1003 | } |
||
1004 | |||
1005 | switch (tree->type.node_class) |
||
1006 | { |
||
1007 | case etree_value: |
||
1008 | if (expld.section == bfd_abs_section_ptr |
||
1009 | && !config.sane_expr) |
||
1010 | new_abs (tree->value.value); |
||
1011 | else |
||
1012 | new_number (tree->value.value); |
||
1013 | expld.result.str = tree->value.str; |
||
1014 | break; |
||
1015 | |||
1016 | case etree_rel: |
||
1017 | if (expld.phase != lang_first_phase_enum) |
||
1018 | { |
||
1019 | asection *output_section = tree->rel.section->output_section; |
||
1020 | new_rel (tree->rel.value + tree->rel.section->output_offset, |
||
1021 | output_section); |
||
1022 | } |
||
1023 | else |
||
1024 | memset (&expld.result, 0, sizeof (expld.result)); |
||
1025 | break; |
||
1026 | |||
1027 | case etree_assert: |
||
1028 | exp_fold_tree_1 (tree->assert_s.child); |
||
1029 | if (expld.phase == lang_final_phase_enum && !expld.result.value) |
||
1030 | einfo ("%X%P: %s\n", tree->assert_s.message); |
||
1031 | break; |
||
1032 | |||
1033 | case etree_unary: |
||
1034 | fold_unary (tree); |
||
1035 | break; |
||
1036 | |||
1037 | case etree_binary: |
||
1038 | fold_binary (tree); |
||
1039 | break; |
||
1040 | |||
1041 | case etree_trinary: |
||
1042 | fold_trinary (tree); |
||
1043 | break; |
||
1044 | |||
1045 | case etree_assign: |
||
1046 | case etree_provide: |
||
1047 | case etree_provided: |
||
1048 | if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) |
||
1049 | { |
||
1050 | if (tree->type.node_class != etree_assign) |
||
1051 | einfo (_("%F%S can not PROVIDE assignment to" |
||
1052 | " location counter\n"), tree); |
||
1053 | if (expld.phase != lang_first_phase_enum) |
||
1054 | { |
||
1055 | /* Notify the folder that this is an assignment to dot. */ |
||
1056 | expld.assigning_to_dot = TRUE; |
||
1057 | exp_fold_tree_1 (tree->assign.src); |
||
1058 | expld.assigning_to_dot = FALSE; |
||
1059 | |||
6324 | serge | 1060 | /* If we are assigning to dot inside an output section |
1061 | arrange to keep the section, except for certain |
||
1062 | expressions that evaluate to zero. We ignore . = 0, |
||
1063 | . = . + 0, and . = ALIGN (. != 0 ? expr : 1). |
||
1064 | We can't ignore all expressions that evaluate to zero |
||
1065 | because an otherwise empty section might have padding |
||
1066 | added by an alignment expression that changes with |
||
1067 | relaxation. Such a section might have zero size |
||
1068 | before relaxation and so be stripped incorrectly. */ |
||
1069 | if (expld.phase == lang_mark_phase_enum |
||
1070 | && expld.section != bfd_abs_section_ptr |
||
1071 | && !(expld.result.valid_p |
||
1072 | && expld.result.value == 0 |
||
1073 | && (is_value (tree->assign.src, 0) |
||
1074 | || is_sym_value (tree->assign.src, 0) |
||
1075 | || is_dot_plus_0 (tree->assign.src) |
||
1076 | || is_align_conditional (tree->assign.src)))) |
||
1077 | expld.section->flags |= SEC_KEEP; |
||
1078 | |||
5199 | serge | 1079 | if (!expld.result.valid_p) |
1080 | { |
||
1081 | if (expld.phase != lang_mark_phase_enum) |
||
1082 | einfo (_("%F%S invalid assignment to" |
||
1083 | " location counter\n"), tree); |
||
1084 | } |
||
1085 | else if (expld.dotp == NULL) |
||
1086 | einfo (_("%F%S assignment to location counter" |
||
1087 | " invalid outside of SECTIONS\n"), tree); |
||
1088 | |||
1089 | /* After allocation, assignment to dot should not be |
||
1090 | done inside an output section since allocation adds a |
||
1091 | padding statement that effectively duplicates the |
||
1092 | assignment. */ |
||
1093 | else if (expld.phase <= lang_allocating_phase_enum |
||
1094 | || expld.section == bfd_abs_section_ptr) |
||
1095 | { |
||
1096 | bfd_vma nextdot; |
||
1097 | |||
1098 | nextdot = expld.result.value; |
||
1099 | if (expld.result.section != NULL) |
||
1100 | nextdot += expld.result.section->vma; |
||
1101 | else |
||
1102 | nextdot += expld.section->vma; |
||
1103 | if (nextdot < expld.dot |
||
1104 | && expld.section != bfd_abs_section_ptr) |
||
1105 | einfo (_("%F%S cannot move location counter backwards" |
||
1106 | " (from %V to %V)\n"), |
||
1107 | tree, expld.dot, nextdot); |
||
1108 | else |
||
1109 | { |
||
1110 | expld.dot = nextdot; |
||
1111 | *expld.dotp = nextdot; |
||
1112 | } |
||
1113 | } |
||
1114 | } |
||
1115 | else |
||
1116 | memset (&expld.result, 0, sizeof (expld.result)); |
||
1117 | } |
||
1118 | else |
||
1119 | { |
||
1120 | struct bfd_link_hash_entry *h = NULL; |
||
1121 | |||
1122 | if (tree->type.node_class == etree_provide) |
||
1123 | { |
||
1124 | h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, |
||
1125 | FALSE, FALSE, TRUE); |
||
1126 | if (h == NULL |
||
6324 | serge | 1127 | || !(h->type == bfd_link_hash_new |
1128 | || h->type == bfd_link_hash_undefined |
||
1129 | || h->type == bfd_link_hash_undefweak |
||
1130 | || h->linker_def)) |
||
5199 | serge | 1131 | { |
6324 | serge | 1132 | /* Do nothing. The symbol was never referenced, or |
1133 | was defined in some object file. Note that |
||
1134 | undefweak symbols are defined by PROVIDE. This |
||
1135 | is to support glibc use of __rela_iplt_start and |
||
1136 | similar weak references. */ |
||
5199 | serge | 1137 | break; |
1138 | } |
||
1139 | } |
||
1140 | |||
1141 | expld.assign_name = tree->assign.dst; |
||
1142 | exp_fold_tree_1 (tree->assign.src); |
||
1143 | /* expld.assign_name remaining equal to tree->assign.dst |
||
1144 | below indicates the evaluation of tree->assign.src did |
||
1145 | not use the value of tree->assign.dst. We don't allow |
||
1146 | self assignment until the final phase for two reasons: |
||
1147 | 1) Expressions are evaluated multiple times. With |
||
1148 | relaxation, the number of times may vary. |
||
1149 | 2) Section relative symbol values cannot be correctly |
||
1150 | converted to absolute values, as is required by many |
||
1151 | expressions, until final section sizing is complete. */ |
||
1152 | if ((expld.result.valid_p |
||
1153 | && (expld.phase == lang_final_phase_enum |
||
1154 | || expld.assign_name != NULL)) |
||
1155 | || (expld.phase <= lang_mark_phase_enum |
||
1156 | && tree->type.node_class == etree_assign |
||
1157 | && tree->assign.defsym)) |
||
1158 | { |
||
1159 | if (h == NULL) |
||
1160 | { |
||
1161 | h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, |
||
1162 | TRUE, FALSE, TRUE); |
||
1163 | if (h == NULL) |
||
1164 | einfo (_("%P%F:%s: hash creation failed\n"), |
||
1165 | tree->assign.dst); |
||
1166 | } |
||
1167 | |||
6324 | serge | 1168 | if (expld.result.section == NULL) |
1169 | expld.result.section = expld.section; |
||
1170 | if (!update_definedness (tree->assign.dst, h) && 0) |
||
1171 | { |
||
1172 | /* Symbol was already defined. For now this error |
||
1173 | is disabled because it causes failures in the ld |
||
1174 | testsuite: ld-elf/var1, ld-scripts/defined5, and |
||
1175 | ld-scripts/pr14962. Some of these no doubt |
||
1176 | reflect scripts used in the wild. */ |
||
1177 | (*link_info.callbacks->multiple_definition) |
||
1178 | (&link_info, h, link_info.output_bfd, |
||
1179 | expld.result.section, expld.result.value); |
||
1180 | } |
||
5199 | serge | 1181 | h->type = bfd_link_hash_defined; |
1182 | h->u.def.value = expld.result.value; |
||
1183 | h->u.def.section = expld.result.section; |
||
6324 | serge | 1184 | h->linker_def = 0; |
5199 | serge | 1185 | if (tree->type.node_class == etree_provide) |
1186 | tree->type.node_class = etree_provided; |
||
1187 | |||
1188 | /* Copy the symbol type if this is a simple assignment of |
||
6324 | serge | 1189 | one symbol to another. Also, handle the case of a foldable |
1190 | ternary conditional with names on either side. */ |
||
5199 | serge | 1191 | if (tree->assign.src->type.node_class == etree_name) |
6324 | serge | 1192 | try_copy_symbol_type (h, tree->assign.src); |
1193 | else if (tree->assign.src->type.node_class == etree_trinary) |
||
5199 | serge | 1194 | { |
6324 | serge | 1195 | exp_fold_tree_1 (tree->assign.src->trinary.cond); |
1196 | if (expld.result.valid_p) |
||
1197 | { |
||
1198 | if (expld.result.value |
||
1199 | && tree->assign.src->trinary.lhs->type.node_class |
||
1200 | == etree_name) |
||
1201 | try_copy_symbol_type (h, tree->assign.src->trinary.lhs); |
||
5199 | serge | 1202 | |
6324 | serge | 1203 | if (!expld.result.value |
1204 | && tree->assign.src->trinary.rhs->type.node_class |
||
1205 | == etree_name) |
||
1206 | try_copy_symbol_type (h, tree->assign.src->trinary.rhs); |
||
1207 | } |
||
5199 | serge | 1208 | } |
1209 | } |
||
1210 | else if (expld.phase == lang_final_phase_enum) |
||
1211 | { |
||
1212 | h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, |
||
1213 | FALSE, FALSE, TRUE); |
||
1214 | if (h != NULL |
||
1215 | && h->type == bfd_link_hash_new) |
||
1216 | h->type = bfd_link_hash_undefined; |
||
1217 | } |
||
1218 | expld.assign_name = NULL; |
||
1219 | } |
||
1220 | break; |
||
1221 | |||
1222 | case etree_name: |
||
1223 | fold_name (tree); |
||
1224 | break; |
||
1225 | |||
1226 | default: |
||
1227 | FAIL (); |
||
1228 | memset (&expld.result, 0, sizeof (expld.result)); |
||
1229 | break; |
||
1230 | } |
||
1231 | } |
||
1232 | |||
1233 | void |
||
1234 | exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) |
||
1235 | { |
||
6324 | serge | 1236 | expld.rel_from_abs = FALSE; |
5199 | serge | 1237 | expld.dot = *dotp; |
1238 | expld.dotp = dotp; |
||
1239 | expld.section = current_section; |
||
1240 | exp_fold_tree_1 (tree); |
||
1241 | } |
||
1242 | |||
1243 | void |
||
1244 | exp_fold_tree_no_dot (etree_type *tree) |
||
1245 | { |
||
6324 | serge | 1246 | expld.rel_from_abs = FALSE; |
5199 | serge | 1247 | expld.dot = 0; |
1248 | expld.dotp = NULL; |
||
1249 | expld.section = bfd_abs_section_ptr; |
||
1250 | exp_fold_tree_1 (tree); |
||
1251 | } |
||
1252 | |||
1253 | etree_type * |
||
1254 | exp_binop (int code, etree_type *lhs, etree_type *rhs) |
||
1255 | { |
||
1256 | etree_type value, *new_e; |
||
1257 | |||
1258 | value.type.node_code = code; |
||
1259 | value.type.filename = lhs->type.filename; |
||
1260 | value.type.lineno = lhs->type.lineno; |
||
1261 | value.binary.lhs = lhs; |
||
1262 | value.binary.rhs = rhs; |
||
1263 | value.type.node_class = etree_binary; |
||
1264 | exp_fold_tree_no_dot (&value); |
||
1265 | if (expld.result.valid_p) |
||
1266 | return exp_intop (expld.result.value); |
||
1267 | |||
1268 | new_e = (etree_type *) stat_alloc (sizeof (new_e->binary)); |
||
1269 | memcpy (new_e, &value, sizeof (new_e->binary)); |
||
1270 | return new_e; |
||
1271 | } |
||
1272 | |||
1273 | etree_type * |
||
1274 | exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs) |
||
1275 | { |
||
1276 | etree_type value, *new_e; |
||
1277 | |||
1278 | value.type.node_code = code; |
||
1279 | value.type.filename = cond->type.filename; |
||
1280 | value.type.lineno = cond->type.lineno; |
||
1281 | value.trinary.lhs = lhs; |
||
1282 | value.trinary.cond = cond; |
||
1283 | value.trinary.rhs = rhs; |
||
1284 | value.type.node_class = etree_trinary; |
||
1285 | exp_fold_tree_no_dot (&value); |
||
1286 | if (expld.result.valid_p) |
||
1287 | return exp_intop (expld.result.value); |
||
1288 | |||
1289 | new_e = (etree_type *) stat_alloc (sizeof (new_e->trinary)); |
||
1290 | memcpy (new_e, &value, sizeof (new_e->trinary)); |
||
1291 | return new_e; |
||
1292 | } |
||
1293 | |||
1294 | etree_type * |
||
1295 | exp_unop (int code, etree_type *child) |
||
1296 | { |
||
1297 | etree_type value, *new_e; |
||
1298 | |||
1299 | value.unary.type.node_code = code; |
||
1300 | value.unary.type.filename = child->type.filename; |
||
1301 | value.unary.type.lineno = child->type.lineno; |
||
1302 | value.unary.child = child; |
||
1303 | value.unary.type.node_class = etree_unary; |
||
1304 | exp_fold_tree_no_dot (&value); |
||
1305 | if (expld.result.valid_p) |
||
1306 | return exp_intop (expld.result.value); |
||
1307 | |||
1308 | new_e = (etree_type *) stat_alloc (sizeof (new_e->unary)); |
||
1309 | memcpy (new_e, &value, sizeof (new_e->unary)); |
||
1310 | return new_e; |
||
1311 | } |
||
1312 | |||
1313 | etree_type * |
||
1314 | exp_nameop (int code, const char *name) |
||
1315 | { |
||
1316 | etree_type value, *new_e; |
||
1317 | |||
1318 | value.name.type.node_code = code; |
||
1319 | value.name.type.filename = ldlex_filename (); |
||
1320 | value.name.type.lineno = lineno; |
||
1321 | value.name.name = name; |
||
1322 | value.name.type.node_class = etree_name; |
||
1323 | |||
1324 | exp_fold_tree_no_dot (&value); |
||
1325 | if (expld.result.valid_p) |
||
1326 | return exp_intop (expld.result.value); |
||
1327 | |||
1328 | new_e = (etree_type *) stat_alloc (sizeof (new_e->name)); |
||
1329 | memcpy (new_e, &value, sizeof (new_e->name)); |
||
1330 | return new_e; |
||
1331 | |||
1332 | } |
||
1333 | |||
1334 | static etree_type * |
||
1335 | exp_assop (const char *dst, |
||
1336 | etree_type *src, |
||
1337 | enum node_tree_enum class, |
||
1338 | bfd_boolean defsym, |
||
1339 | bfd_boolean hidden) |
||
1340 | { |
||
1341 | etree_type *n; |
||
1342 | |||
1343 | n = (etree_type *) stat_alloc (sizeof (n->assign)); |
||
1344 | n->assign.type.node_code = '='; |
||
1345 | n->assign.type.filename = src->type.filename; |
||
1346 | n->assign.type.lineno = src->type.lineno; |
||
1347 | n->assign.type.node_class = class; |
||
1348 | n->assign.src = src; |
||
1349 | n->assign.dst = dst; |
||
1350 | n->assign.defsym = defsym; |
||
1351 | n->assign.hidden = hidden; |
||
1352 | return n; |
||
1353 | } |
||
1354 | |||
1355 | /* Handle linker script assignments and HIDDEN. */ |
||
1356 | |||
1357 | etree_type * |
||
1358 | exp_assign (const char *dst, etree_type *src, bfd_boolean hidden) |
||
1359 | { |
||
1360 | return exp_assop (dst, src, etree_assign, FALSE, hidden); |
||
1361 | } |
||
1362 | |||
1363 | /* Handle --defsym command-line option. */ |
||
1364 | |||
1365 | etree_type * |
||
1366 | exp_defsym (const char *dst, etree_type *src) |
||
1367 | { |
||
1368 | return exp_assop (dst, src, etree_assign, TRUE, FALSE); |
||
1369 | } |
||
1370 | |||
1371 | /* Handle PROVIDE. */ |
||
1372 | |||
1373 | etree_type * |
||
1374 | exp_provide (const char *dst, etree_type *src, bfd_boolean hidden) |
||
1375 | { |
||
1376 | return exp_assop (dst, src, etree_provide, FALSE, hidden); |
||
1377 | } |
||
1378 | |||
1379 | /* Handle ASSERT. */ |
||
1380 | |||
1381 | etree_type * |
||
1382 | exp_assert (etree_type *exp, const char *message) |
||
1383 | { |
||
1384 | etree_type *n; |
||
1385 | |||
1386 | n = (etree_type *) stat_alloc (sizeof (n->assert_s)); |
||
1387 | n->assert_s.type.node_code = '!'; |
||
1388 | n->assert_s.type.filename = exp->type.filename; |
||
1389 | n->assert_s.type.lineno = exp->type.lineno; |
||
1390 | n->assert_s.type.node_class = etree_assert; |
||
1391 | n->assert_s.child = exp; |
||
1392 | n->assert_s.message = message; |
||
1393 | return n; |
||
1394 | } |
||
1395 | |||
1396 | void |
||
1397 | exp_print_tree (etree_type *tree) |
||
1398 | { |
||
1399 | bfd_boolean function_like; |
||
1400 | |||
1401 | if (config.map_file == NULL) |
||
1402 | config.map_file = stderr; |
||
1403 | |||
1404 | if (tree == NULL) |
||
1405 | { |
||
1406 | minfo ("NULL TREE\n"); |
||
1407 | return; |
||
1408 | } |
||
1409 | |||
1410 | switch (tree->type.node_class) |
||
1411 | { |
||
1412 | case etree_value: |
||
1413 | minfo ("0x%v", tree->value.value); |
||
1414 | return; |
||
1415 | case etree_rel: |
||
1416 | if (tree->rel.section->owner != NULL) |
||
1417 | minfo ("%B:", tree->rel.section->owner); |
||
1418 | minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value); |
||
1419 | return; |
||
1420 | case etree_assign: |
||
1421 | fputs (tree->assign.dst, config.map_file); |
||
1422 | exp_print_token (tree->type.node_code, TRUE); |
||
1423 | exp_print_tree (tree->assign.src); |
||
1424 | break; |
||
1425 | case etree_provide: |
||
1426 | case etree_provided: |
||
1427 | fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst); |
||
1428 | exp_print_tree (tree->assign.src); |
||
1429 | fputc (')', config.map_file); |
||
1430 | break; |
||
1431 | case etree_binary: |
||
1432 | function_like = FALSE; |
||
1433 | switch (tree->type.node_code) |
||
1434 | { |
||
1435 | case MAX_K: |
||
1436 | case MIN_K: |
||
1437 | case ALIGN_K: |
||
1438 | case DATA_SEGMENT_ALIGN: |
||
1439 | case DATA_SEGMENT_RELRO_END: |
||
1440 | function_like = TRUE; |
||
1441 | break; |
||
1442 | case SEGMENT_START: |
||
1443 | /* Special handling because arguments are in reverse order and |
||
1444 | the segment name is quoted. */ |
||
1445 | exp_print_token (tree->type.node_code, FALSE); |
||
1446 | fputs (" (\"", config.map_file); |
||
1447 | exp_print_tree (tree->binary.rhs); |
||
1448 | fputs ("\", ", config.map_file); |
||
1449 | exp_print_tree (tree->binary.lhs); |
||
1450 | fputc (')', config.map_file); |
||
1451 | return; |
||
1452 | } |
||
1453 | if (function_like) |
||
1454 | { |
||
1455 | exp_print_token (tree->type.node_code, FALSE); |
||
1456 | fputc (' ', config.map_file); |
||
1457 | } |
||
1458 | fputc ('(', config.map_file); |
||
1459 | exp_print_tree (tree->binary.lhs); |
||
1460 | if (function_like) |
||
1461 | fprintf (config.map_file, ", "); |
||
1462 | else |
||
1463 | exp_print_token (tree->type.node_code, TRUE); |
||
1464 | exp_print_tree (tree->binary.rhs); |
||
1465 | fputc (')', config.map_file); |
||
1466 | break; |
||
1467 | case etree_trinary: |
||
1468 | exp_print_tree (tree->trinary.cond); |
||
1469 | fputc ('?', config.map_file); |
||
1470 | exp_print_tree (tree->trinary.lhs); |
||
1471 | fputc (':', config.map_file); |
||
1472 | exp_print_tree (tree->trinary.rhs); |
||
1473 | break; |
||
1474 | case etree_unary: |
||
1475 | exp_print_token (tree->unary.type.node_code, FALSE); |
||
1476 | if (tree->unary.child) |
||
1477 | { |
||
1478 | fprintf (config.map_file, " ("); |
||
1479 | exp_print_tree (tree->unary.child); |
||
1480 | fputc (')', config.map_file); |
||
1481 | } |
||
1482 | break; |
||
1483 | |||
1484 | case etree_assert: |
||
1485 | fprintf (config.map_file, "ASSERT ("); |
||
1486 | exp_print_tree (tree->assert_s.child); |
||
1487 | fprintf (config.map_file, ", %s)", tree->assert_s.message); |
||
1488 | break; |
||
1489 | |||
1490 | case etree_name: |
||
1491 | if (tree->type.node_code == NAME) |
||
1492 | fputs (tree->name.name, config.map_file); |
||
1493 | else |
||
1494 | { |
||
1495 | exp_print_token (tree->type.node_code, FALSE); |
||
1496 | if (tree->name.name) |
||
1497 | fprintf (config.map_file, " (%s)", tree->name.name); |
||
1498 | } |
||
1499 | break; |
||
1500 | default: |
||
1501 | FAIL (); |
||
1502 | break; |
||
1503 | } |
||
1504 | } |
||
1505 | |||
1506 | bfd_vma |
||
1507 | exp_get_vma (etree_type *tree, bfd_vma def, char *name) |
||
1508 | { |
||
1509 | if (tree != NULL) |
||
1510 | { |
||
1511 | exp_fold_tree_no_dot (tree); |
||
1512 | if (expld.result.valid_p) |
||
1513 | return expld.result.value; |
||
1514 | else if (name != NULL && expld.phase != lang_mark_phase_enum) |
||
1515 | einfo (_("%F%S: nonconstant expression for %s\n"), |
||
1516 | tree, name); |
||
1517 | } |
||
1518 | return def; |
||
1519 | } |
||
1520 | |||
1521 | int |
||
1522 | exp_get_value_int (etree_type *tree, int def, char *name) |
||
1523 | { |
||
1524 | return exp_get_vma (tree, def, name); |
||
1525 | } |
||
1526 | |||
1527 | fill_type * |
||
1528 | exp_get_fill (etree_type *tree, fill_type *def, char *name) |
||
1529 | { |
||
1530 | fill_type *fill; |
||
1531 | size_t len; |
||
1532 | unsigned int val; |
||
1533 | |||
1534 | if (tree == NULL) |
||
1535 | return def; |
||
1536 | |||
1537 | exp_fold_tree_no_dot (tree); |
||
1538 | if (!expld.result.valid_p) |
||
1539 | { |
||
1540 | if (name != NULL && expld.phase != lang_mark_phase_enum) |
||
1541 | einfo (_("%F%S: nonconstant expression for %s\n"), |
||
1542 | tree, name); |
||
1543 | return def; |
||
1544 | } |
||
1545 | |||
1546 | if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0) |
||
1547 | { |
||
1548 | unsigned char *dst; |
||
1549 | unsigned char *s; |
||
1550 | fill = (fill_type *) xmalloc ((len + 1) / 2 + sizeof (*fill) - 1); |
||
1551 | fill->size = (len + 1) / 2; |
||
1552 | dst = fill->data; |
||
1553 | s = (unsigned char *) expld.result.str; |
||
1554 | val = 0; |
||
1555 | do |
||
1556 | { |
||
1557 | unsigned int digit; |
||
1558 | |||
1559 | digit = *s++ - '0'; |
||
1560 | if (digit > 9) |
||
1561 | digit = (digit - 'A' + '0' + 10) & 0xf; |
||
1562 | val <<= 4; |
||
1563 | val += digit; |
||
1564 | --len; |
||
1565 | if ((len & 1) == 0) |
||
1566 | { |
||
1567 | *dst++ = val; |
||
1568 | val = 0; |
||
1569 | } |
||
1570 | } |
||
1571 | while (len != 0); |
||
1572 | } |
||
1573 | else |
||
1574 | { |
||
1575 | fill = (fill_type *) xmalloc (4 + sizeof (*fill) - 1); |
||
1576 | val = expld.result.value; |
||
1577 | fill->data[0] = (val >> 24) & 0xff; |
||
1578 | fill->data[1] = (val >> 16) & 0xff; |
||
1579 | fill->data[2] = (val >> 8) & 0xff; |
||
1580 | fill->data[3] = (val >> 0) & 0xff; |
||
1581 | fill->size = 4; |
||
1582 | } |
||
1583 | return fill; |
||
1584 | } |
||
1585 | |||
1586 | bfd_vma |
||
1587 | exp_get_abs_int (etree_type *tree, int def, char *name) |
||
1588 | { |
||
1589 | if (tree != NULL) |
||
1590 | { |
||
1591 | exp_fold_tree_no_dot (tree); |
||
1592 | |||
1593 | if (expld.result.valid_p) |
||
1594 | { |
||
1595 | if (expld.result.section != NULL) |
||
1596 | expld.result.value += expld.result.section->vma; |
||
1597 | return expld.result.value; |
||
1598 | } |
||
1599 | else if (name != NULL && expld.phase != lang_mark_phase_enum) |
||
1600 | { |
||
1601 | einfo (_("%F%S: nonconstant expression for %s\n"), |
||
1602 | tree, name); |
||
1603 | } |
||
1604 | } |
||
1605 | return def; |
||
1606 | } |
||
1607 | |||
1608 | static bfd_vma |
||
1609 | align_n (bfd_vma value, bfd_vma align) |
||
1610 | { |
||
1611 | if (align <= 1) |
||
1612 | return value; |
||
1613 | |||
1614 | value = (value + align - 1) / align; |
||
1615 | return value * align; |
||
1616 | } |
||
6324 | serge | 1617 | |
1618 | void |
||
1619 | ldexp_init (void) |
||
1620 | { |
||
1621 | /* The value "13" is ad-hoc, somewhat related to the expected number of |
||
1622 | assignments in a linker script. */ |
||
1623 | if (!bfd_hash_table_init_n (&definedness_table, |
||
1624 | definedness_newfunc, |
||
1625 | sizeof (struct definedness_hash_entry), |
||
1626 | 13)) |
||
1627 | einfo (_("%P%F: can not create hash table: %E\n")); |
||
1628 | } |
||
1629 | |||
1630 | /* Convert absolute symbols defined by a script from "dot" (also |
||
1631 | SEGMENT_START or ORIGIN) outside of an output section statement, |
||
1632 | to section relative. */ |
||
1633 | |||
1634 | static bfd_boolean |
||
1635 | set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) |
||
1636 | { |
||
1637 | struct definedness_hash_entry *def = (struct definedness_hash_entry *) bh; |
||
1638 | if (def->final_sec != bfd_abs_section_ptr) |
||
1639 | { |
||
1640 | struct bfd_link_hash_entry *h; |
||
1641 | h = bfd_link_hash_lookup (link_info.hash, bh->string, |
||
1642 | FALSE, FALSE, TRUE); |
||
1643 | if (h != NULL |
||
1644 | && h->type == bfd_link_hash_defined |
||
1645 | && h->u.def.section == bfd_abs_section_ptr) |
||
1646 | { |
||
1647 | h->u.def.value -= def->final_sec->vma; |
||
1648 | h->u.def.section = def->final_sec; |
||
1649 | } |
||
1650 | } |
||
1651 | return TRUE; |
||
1652 | } |
||
1653 | |||
1654 | void |
||
1655 | ldexp_finalize_syms (void) |
||
1656 | { |
||
1657 | bfd_hash_traverse (&definedness_table, set_sym_sections, NULL); |
||
1658 | } |
||
1659 | |||
1660 | void |
||
1661 | ldexp_finish (void) |
||
1662 | { |
||
1663 | bfd_hash_table_free (&definedness_table); |
||
1664 | }=>=><=>=>>=>><>>>=); |