2005-07-24 Paolo Bonzini <bonzini@gnu.org>
[deliverable/binutils-gdb.git] / ld / ldexp.c
CommitLineData
252b5132 1/* This module handles expression trees.
a2b64bed 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
20c2cbe3 3 2001, 2002, 2003, 2004, 2005
87f2a346 4 Free Software Foundation, Inc.
8c95a62e 5 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
252b5132 6
3ec57632 7 This file is part of GLD, the Gnu Linker.
252b5132 8
3ec57632
NC
9 GLD is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
252b5132 13
3ec57632
NC
14 GLD is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
252b5132 18
3ec57632
NC
19 You should have received a copy of the GNU General Public License
20 along with GLD; see the file COPYING. If not, write to the Free
75be928b
NC
21 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23
8c95a62e 24/* This module is in charge of working out the contents of expressions.
252b5132 25
8c95a62e
KH
26 It has to keep track of the relative/absness of a symbol etc. This
27 is done by keeping all values in a struct (an etree_value_type)
28 which contains a value, a section to which it is relative and a
29 valid bit. */
252b5132 30
252b5132
RH
31#include "bfd.h"
32#include "sysdep.h"
33#include "bfdlink.h"
34
35#include "ld.h"
36#include "ldmain.h"
37#include "ldmisc.h"
38#include "ldexp.h"
df2a7313 39#include <ldgram.h>
252b5132 40#include "ldlang.h"
c7d701b0 41#include "libiberty.h"
2c382fb6 42#include "safe-ctype.h"
252b5132 43
e9ee469a
AM
44static void exp_fold_tree_1 (etree_type *);
45static void exp_fold_tree_no_dot (etree_type *);
46static bfd_vma align_n (bfd_vma, bfd_vma);
2d20f7bf 47
ba916c8a
MM
48segment_type *segments;
49
e9ee469a 50struct ldexp_control expld;
fbbb9ac5 51
7b17f854 52/* Print the string representation of the given token. Surround it
b34976b6 53 with spaces if INFIX_P is TRUE. */
7b17f854 54
252b5132 55static void
1579bae1 56exp_print_token (token_code_type code, int infix_p)
252b5132 57{
4da711b1 58 static const struct
c7d701b0 59 {
8c95a62e 60 token_code_type code;
c7d701b0
NC
61 char * name;
62 }
63 table[] =
64 {
8c95a62e 65 { INT, "int" },
8c95a62e
KH
66 { NAME, "NAME" },
67 { PLUSEQ, "+=" },
68 { MINUSEQ, "-=" },
69 { MULTEQ, "*=" },
70 { DIVEQ, "/=" },
71 { LSHIFTEQ, "<<=" },
72 { RSHIFTEQ, ">>=" },
73 { ANDEQ, "&=" },
74 { OREQ, "|=" },
75 { OROR, "||" },
76 { ANDAND, "&&" },
77 { EQ, "==" },
78 { NE, "!=" },
79 { LE, "<=" },
80 { GE, ">=" },
81 { LSHIFT, "<<" },
7cecdbff 82 { RSHIFT, ">>" },
8c95a62e
KH
83 { ALIGN_K, "ALIGN" },
84 { BLOCK, "BLOCK" },
c7d701b0
NC
85 { QUAD, "QUAD" },
86 { SQUAD, "SQUAD" },
87 { LONG, "LONG" },
88 { SHORT, "SHORT" },
89 { BYTE, "BYTE" },
8c95a62e
KH
90 { SECTIONS, "SECTIONS" },
91 { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
8c95a62e
KH
92 { MEMORY, "MEMORY" },
93 { DEFINED, "DEFINED" },
94 { TARGET_K, "TARGET" },
95 { SEARCH_DIR, "SEARCH_DIR" },
96 { MAP, "MAP" },
8c95a62e 97 { ENTRY, "ENTRY" },
c7d701b0
NC
98 { NEXT, "NEXT" },
99 { SIZEOF, "SIZEOF" },
100 { ADDR, "ADDR" },
101 { LOADADDR, "LOADADDR" },
102 { MAX_K, "MAX_K" },
1049f94e 103 { REL, "relocatable" },
2d20f7bf 104 { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
8c37241b 105 { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
ba916c8a 106 { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
3ec57632
NC
107 { ORIGIN, "ORIGIN" },
108 { LENGTH, "LENGTH" },
ba916c8a 109 { SEGMENT_START, "SEGMENT_START" }
8c95a62e 110 };
252b5132
RH
111 unsigned int idx;
112
7b17f854
RS
113 for (idx = 0; idx < ARRAY_SIZE (table); idx++)
114 if (table[idx].code == code)
115 break;
c7d701b0 116
7b17f854
RS
117 if (infix_p)
118 fputc (' ', config.map_file);
119
120 if (idx < ARRAY_SIZE (table))
121 fputs (table[idx].name, config.map_file);
122 else if (code < 127)
123 fputc (code, config.map_file);
c7d701b0 124 else
7b17f854
RS
125 fprintf (config.map_file, "<code %d>", code);
126
127 if (infix_p)
128 fputc (' ', config.map_file);
252b5132
RH
129}
130
4de2d33d 131static void
e9ee469a 132make_abs (void)
252b5132 133{
e9ee469a
AM
134 expld.result.value += expld.result.section->vma;
135 expld.result.section = bfd_abs_section_ptr;
252b5132
RH
136}
137
e9ee469a 138static void
1579bae1 139new_abs (bfd_vma value)
252b5132 140{
e9ee469a
AM
141 expld.result.valid_p = TRUE;
142 expld.result.section = bfd_abs_section_ptr;
143 expld.result.value = value;
144 expld.result.str = NULL;
252b5132
RH
145}
146
252b5132 147etree_type *
1579bae1 148exp_intop (bfd_vma value)
252b5132 149{
1579bae1 150 etree_type *new = stat_alloc (sizeof (new->value));
252b5132
RH
151 new->type.node_code = INT;
152 new->value.value = value;
2c382fb6 153 new->value.str = NULL;
252b5132
RH
154 new->type.node_class = etree_value;
155 return new;
2c382fb6 156}
252b5132 157
2c382fb6 158etree_type *
1579bae1 159exp_bigintop (bfd_vma value, char *str)
2c382fb6 160{
1579bae1 161 etree_type *new = stat_alloc (sizeof (new->value));
2c382fb6
AM
162 new->type.node_code = INT;
163 new->value.value = value;
164 new->value.str = str;
165 new->type.node_class = etree_value;
166 return new;
252b5132
RH
167}
168
1049f94e 169/* Build an expression representing an unnamed relocatable value. */
252b5132
RH
170
171etree_type *
1579bae1 172exp_relop (asection *section, bfd_vma value)
252b5132 173{
1579bae1 174 etree_type *new = stat_alloc (sizeof (new->rel));
252b5132
RH
175 new->type.node_code = REL;
176 new->type.node_class = etree_rel;
177 new->rel.section = section;
178 new->rel.value = value;
179 return new;
180}
181
e9ee469a
AM
182static void
183new_rel (bfd_vma value, char *str, asection *section)
252b5132 184{
e9ee469a
AM
185 expld.result.valid_p = TRUE;
186 expld.result.value = value;
187 expld.result.str = str;
188 expld.result.section = section;
252b5132
RH
189}
190
e9ee469a
AM
191static void
192new_rel_from_abs (bfd_vma value)
252b5132 193{
e9ee469a
AM
194 expld.result.valid_p = TRUE;
195 expld.result.value = value - expld.section->vma;
196 expld.result.str = NULL;
197 expld.result.section = expld.section;
252b5132
RH
198}
199
e9ee469a
AM
200static void
201fold_unary (etree_type *tree)
0ae1cf52 202{
e9ee469a
AM
203 exp_fold_tree_1 (tree->unary.child);
204 if (expld.result.valid_p)
0ae1cf52
AM
205 {
206 switch (tree->type.node_code)
207 {
208 case ALIGN_K:
e9ee469a 209 if (expld.phase != lang_first_phase_enum)
dea2f0a8 210 new_rel_from_abs (align_n (expld.dot, expld.result.value));
0ae1cf52 211 else
e9ee469a 212 expld.result.valid_p = FALSE;
0ae1cf52
AM
213 break;
214
215 case ABSOLUTE:
e9ee469a 216 make_abs ();
0ae1cf52
AM
217 break;
218
219 case '~':
e9ee469a
AM
220 make_abs ();
221 expld.result.value = ~expld.result.value;
0ae1cf52
AM
222 break;
223
224 case '!':
e9ee469a
AM
225 make_abs ();
226 expld.result.value = !expld.result.value;
0ae1cf52
AM
227 break;
228
229 case '-':
e9ee469a
AM
230 make_abs ();
231 expld.result.value = -expld.result.value;
0ae1cf52
AM
232 break;
233
234 case NEXT:
235 /* Return next place aligned to value. */
e9ee469a 236 if (expld.phase != lang_first_phase_enum)
0ae1cf52 237 {
e9ee469a
AM
238 make_abs ();
239 expld.result.value = align_n (expld.dot, expld.result.value);
0ae1cf52
AM
240 }
241 else
e9ee469a 242 expld.result.valid_p = FALSE;
0ae1cf52
AM
243 break;
244
245 case DATA_SEGMENT_END:
e9ee469a
AM
246 if (expld.phase != lang_first_phase_enum
247 && expld.section == bfd_abs_section_ptr
248 && (expld.dataseg.phase == exp_dataseg_align_seen
249 || expld.dataseg.phase == exp_dataseg_relro_seen
250 || expld.dataseg.phase == exp_dataseg_adjust
251 || expld.dataseg.phase == exp_dataseg_relro_adjust
252 || expld.phase == lang_final_phase_enum))
0ae1cf52 253 {
e9ee469a
AM
254 if (expld.dataseg.phase == exp_dataseg_align_seen
255 || expld.dataseg.phase == exp_dataseg_relro_seen)
0ae1cf52 256 {
e9ee469a
AM
257 expld.dataseg.phase = exp_dataseg_end_seen;
258 expld.dataseg.end = expld.result.value;
0ae1cf52
AM
259 }
260 }
261 else
e9ee469a 262 expld.result.valid_p = FALSE;
0ae1cf52
AM
263 break;
264
265 default:
266 FAIL ();
267 break;
268 }
269 }
0ae1cf52
AM
270}
271
e9ee469a
AM
272static void
273fold_binary (etree_type *tree)
252b5132 274{
e9ee469a 275 exp_fold_tree_1 (tree->binary.lhs);
ba916c8a
MM
276
277 /* The SEGMENT_START operator is special because its first
278 operand is a string, not the name of a symbol. */
e9ee469a 279 if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
ba916c8a
MM
280 {
281 const char *segment_name;
282 segment_type *seg;
283 /* Check to see if the user has overridden the default
284 value. */
285 segment_name = tree->binary.rhs->name.name;
286 for (seg = segments; seg; seg = seg->next)
287 if (strcmp (seg->name, segment_name) == 0)
288 {
289 seg->used = TRUE;
e9ee469a
AM
290 expld.result.value = seg->value;
291 expld.result.str = NULL;
292 expld.result.section = NULL;
ba916c8a
MM
293 break;
294 }
295 }
e9ee469a 296 else if (expld.result.valid_p)
252b5132 297 {
e9ee469a 298 etree_value_type lhs = expld.result;
252b5132 299
e9ee469a
AM
300 exp_fold_tree_1 (tree->binary.rhs);
301 if (expld.result.valid_p)
252b5132
RH
302 {
303 /* If the values are from different sections, or this is an
304 absolute expression, make both the source arguments
305 absolute. However, adding or subtracting an absolute
306 value from a relative value is meaningful, and is an
307 exception. */
e9ee469a
AM
308 if (expld.section != bfd_abs_section_ptr
309 && lhs.section == bfd_abs_section_ptr
310 && tree->type.node_code == '+')
311 {
312 /* Keep the section of the rhs term. */
313 expld.result.value = lhs.value + expld.result.value;
314 return;
315 }
316 else if (expld.section != bfd_abs_section_ptr
317 && expld.result.section == bfd_abs_section_ptr
252b5132
RH
318 && (tree->type.node_code == '+'
319 || tree->type.node_code == '-'))
320 {
e9ee469a
AM
321 /* Keep the section of the lhs term. */
322 expld.result.section = lhs.section;
252b5132 323 }
e9ee469a
AM
324 else if (expld.result.section != lhs.section
325 || expld.section == bfd_abs_section_ptr)
252b5132 326 {
e9ee469a
AM
327 make_abs ();
328 lhs.value += lhs.section->vma;
252b5132
RH
329 }
330
4de2d33d 331 switch (tree->type.node_code)
252b5132
RH
332 {
333 case '%':
e9ee469a
AM
334 if (expld.result.value != 0)
335 expld.result.value = ((bfd_signed_vma) lhs.value
336 % (bfd_signed_vma) expld.result.value);
337 else if (expld.phase != lang_mark_phase_enum)
252b5132 338 einfo (_("%F%S %% by zero\n"));
252b5132
RH
339 break;
340
341 case '/':
e9ee469a
AM
342 if (expld.result.value != 0)
343 expld.result.value = ((bfd_signed_vma) lhs.value
344 / (bfd_signed_vma) expld.result.value);
345 else if (expld.phase != lang_mark_phase_enum)
252b5132 346 einfo (_("%F%S / by zero\n"));
252b5132
RH
347 break;
348
e9ee469a
AM
349#define BOP(x, y) \
350 case x: \
351 expld.result.value = lhs.value y expld.result.value; \
352 break;
353
8c95a62e
KH
354 BOP ('+', +);
355 BOP ('*', *);
356 BOP ('-', -);
357 BOP (LSHIFT, <<);
358 BOP (RSHIFT, >>);
359 BOP (EQ, ==);
360 BOP (NE, !=);
361 BOP ('<', <);
362 BOP ('>', >);
363 BOP (LE, <=);
364 BOP (GE, >=);
365 BOP ('&', &);
366 BOP ('^', ^);
367 BOP ('|', |);
368 BOP (ANDAND, &&);
369 BOP (OROR, ||);
252b5132
RH
370
371 case MAX_K:
e9ee469a
AM
372 if (lhs.value > expld.result.value)
373 expld.result.value = lhs.value;
252b5132
RH
374 break;
375
376 case MIN_K:
e9ee469a
AM
377 if (lhs.value < expld.result.value)
378 expld.result.value = lhs.value;
252b5132
RH
379 break;
380
876f4090 381 case ALIGN_K:
e9ee469a 382 expld.result.value = align_n (lhs.value, expld.result.value);
876f4090 383 break;
c468c8bc 384
2d20f7bf 385 case DATA_SEGMENT_ALIGN:
e9ee469a
AM
386 if (expld.phase != lang_first_phase_enum
387 && expld.section == bfd_abs_section_ptr
388 && (expld.dataseg.phase == exp_dataseg_none
389 || expld.dataseg.phase == exp_dataseg_adjust
390 || expld.dataseg.phase == exp_dataseg_relro_adjust
391 || expld.phase == lang_final_phase_enum))
2d20f7bf 392 {
e9ee469a
AM
393 bfd_vma maxpage = lhs.value;
394 bfd_vma commonpage = expld.result.value;
2d20f7bf 395
e9ee469a
AM
396 expld.result.value = align_n (expld.dot, maxpage);
397 if (expld.dataseg.phase == exp_dataseg_relro_adjust)
398 expld.result.value = expld.dataseg.base;
399 else if (expld.dataseg.phase != exp_dataseg_adjust)
2d20f7bf 400 {
e9ee469a
AM
401 expld.result.value += expld.dot & (maxpage - 1);
402 if (expld.phase == lang_allocating_phase_enum)
2d20f7bf 403 {
e9ee469a
AM
404 expld.dataseg.phase = exp_dataseg_align_seen;
405 expld.dataseg.min_base = align_n (expld.dot, maxpage);
406 expld.dataseg.base = expld.result.value;
407 expld.dataseg.pagesize = commonpage;
408 expld.dataseg.maxpagesize = maxpage;
409 expld.dataseg.relro_end = 0;
2d20f7bf
JJ
410 }
411 }
e9ee469a
AM
412 else if (commonpage < maxpage)
413 expld.result.value += ((expld.dot + commonpage - 1)
414 & (maxpage - commonpage));
2d20f7bf
JJ
415 }
416 else
e9ee469a 417 expld.result.valid_p = FALSE;
2d20f7bf
JJ
418 break;
419
a4f5ad88 420 case DATA_SEGMENT_RELRO_END:
e9ee469a
AM
421 if (expld.phase != lang_first_phase_enum
422 && (expld.dataseg.phase == exp_dataseg_align_seen
423 || expld.dataseg.phase == exp_dataseg_adjust
424 || expld.dataseg.phase == exp_dataseg_relro_adjust
425 || expld.phase == lang_final_phase_enum))
a4f5ad88 426 {
e9ee469a
AM
427 if (expld.dataseg.phase == exp_dataseg_align_seen
428 || expld.dataseg.phase == exp_dataseg_relro_adjust)
429 expld.dataseg.relro_end = lhs.value + expld.result.value;
430
431 if (expld.dataseg.phase == exp_dataseg_relro_adjust
432 && (expld.dataseg.relro_end
433 & (expld.dataseg.pagesize - 1)))
a4f5ad88 434 {
e9ee469a
AM
435 expld.dataseg.relro_end += expld.dataseg.pagesize - 1;
436 expld.dataseg.relro_end &= ~(expld.dataseg.pagesize - 1);
437 expld.result.value = (expld.dataseg.relro_end
438 - expld.result.value);
a4f5ad88 439 }
e9ee469a
AM
440 else
441 expld.result.value = lhs.value;
442
443 if (expld.dataseg.phase == exp_dataseg_align_seen)
444 expld.dataseg.phase = exp_dataseg_relro_seen;
a4f5ad88
JJ
445 }
446 else
e9ee469a 447 expld.result.valid_p = FALSE;
a4f5ad88
JJ
448 break;
449
252b5132 450 default:
8c95a62e 451 FAIL ();
252b5132
RH
452 }
453 }
454 else
e9ee469a 455 expld.result.valid_p = FALSE;
252b5132 456 }
252b5132
RH
457}
458
e9ee469a
AM
459static void
460fold_trinary (etree_type *tree)
0ae1cf52 461{
e9ee469a
AM
462 exp_fold_tree_1 (tree->trinary.cond);
463 if (expld.result.valid_p)
464 exp_fold_tree_1 (expld.result.value
465 ? tree->trinary.lhs
466 : tree->trinary.rhs);
0ae1cf52
AM
467}
468
e9ee469a
AM
469static void
470fold_name (etree_type *tree)
252b5132 471{
e9ee469a 472 memset (&expld.result, 0, sizeof (expld.result));
c468c8bc 473
4de2d33d 474 switch (tree->type.node_code)
8c95a62e
KH
475 {
476 case SIZEOF_HEADERS:
e9ee469a
AM
477 if (expld.phase != lang_first_phase_enum)
478 {
479 bfd_vma hdr_size = 0;
480 /* Don't find the real header size if only marking sections;
481 The bfd function may cache incorrect data. */
482 if (expld.phase != lang_mark_phase_enum)
483 hdr_size = bfd_sizeof_headers (output_bfd, link_info.relocatable);
484 new_abs (hdr_size);
485 }
8c95a62e
KH
486 break;
487 case DEFINED:
e9ee469a 488 if (expld.phase == lang_first_phase_enum)
1b493742 489 lang_track_definedness (tree->name.name);
8c95a62e
KH
490 else
491 {
492 struct bfd_link_hash_entry *h;
420e579c
HPN
493 int def_iteration
494 = lang_symbol_definition_iteration (tree->name.name);
8c95a62e
KH
495
496 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
497 tree->name.name,
b34976b6 498 FALSE, FALSE, TRUE);
e9ee469a
AM
499 expld.result.value = (h != NULL
500 && (h->type == bfd_link_hash_defined
501 || h->type == bfd_link_hash_defweak
502 || h->type == bfd_link_hash_common)
503 && (def_iteration == lang_statement_iteration
504 || def_iteration == -1));
505 expld.result.section = bfd_abs_section_ptr;
506 expld.result.valid_p = TRUE;
8c95a62e
KH
507 }
508 break;
509 case NAME:
e9ee469a
AM
510 if (expld.phase == lang_first_phase_enum)
511 ;
512 else if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
513 new_rel_from_abs (expld.dot);
514 else
8c95a62e
KH
515 {
516 struct bfd_link_hash_entry *h;
517
518 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
519 tree->name.name,
1b493742
NS
520 TRUE, FALSE, TRUE);
521 if (!h)
522 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
523 else if (h->type == bfd_link_hash_defined
524 || h->type == bfd_link_hash_defweak)
8c95a62e
KH
525 {
526 if (bfd_is_abs_section (h->u.def.section))
e9ee469a
AM
527 new_abs (h->u.def.value);
528 else
8c95a62e
KH
529 {
530 asection *output_section;
531
532 output_section = h->u.def.section->output_section;
533 if (output_section == NULL)
8c95a62e 534 {
e9ee469a
AM
535 if (expld.phase != lang_mark_phase_enum)
536 einfo (_("%X%S: unresolvable symbol `%s'"
537 " referenced in expression\n"),
538 tree->name.name);
8c95a62e 539 }
e9ee469a
AM
540 else
541 new_rel (h->u.def.value + h->u.def.section->output_offset,
542 NULL, output_section);
8c95a62e
KH
543 }
544 }
e9ee469a
AM
545 else if (expld.phase == lang_final_phase_enum
546 || expld.assigning_to_dot)
8c95a62e
KH
547 einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
548 tree->name.name);
1b493742
NS
549 else if (h->type == bfd_link_hash_new)
550 {
551 h->type = bfd_link_hash_undefined;
552 h->u.undef.abfd = NULL;
3eda52aa 553 if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
a010d60f 554 bfd_link_add_undef (link_info.hash, h);
1b493742 555 }
8c95a62e
KH
556 }
557 break;
558
559 case ADDR:
e9ee469a 560 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
561 {
562 lang_output_section_statement_type *os;
563
564 os = lang_output_section_find (tree->name.name);
e9ee469a
AM
565 if (os != NULL && os->processed > 0)
566 new_rel (0, NULL, os->bfd_section);
8c95a62e 567 }
8c95a62e
KH
568 break;
569
570 case LOADADDR:
e9ee469a 571 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
572 {
573 lang_output_section_statement_type *os;
574
575 os = lang_output_section_find (tree->name.name);
e9ee469a 576 if (os != NULL && os->processed > 0)
1b493742 577 {
e9ee469a
AM
578 if (os->load_base == NULL)
579 new_rel (0, NULL, os->bfd_section);
580 else
581 exp_fold_tree_1 (os->load_base);
1b493742 582 }
8c95a62e 583 }
8c95a62e
KH
584 break;
585
586 case SIZEOF:
e9ee469a 587 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
588 {
589 int opb = bfd_octets_per_byte (output_bfd);
590 lang_output_section_statement_type *os;
591
592 os = lang_output_section_find (tree->name.name);
e9ee469a
AM
593 if (os != NULL && os->processed > 0)
594 new_abs (os->bfd_section->size / opb);
8c95a62e 595 }
8c95a62e
KH
596 break;
597
3ec57632
NC
598 case LENGTH:
599 {
600 lang_memory_region_type *mem;
601
602 mem = lang_memory_region_lookup (tree->name.name, FALSE);
603 if (mem != NULL)
e9ee469a 604 new_abs (mem->length);
3ec57632 605 else
e9ee469a
AM
606 einfo (_("%F%S: undefined MEMORY region `%s'"
607 " referenced in expression\n"), tree->name.name);
3ec57632
NC
608 }
609 break;
610
611 case ORIGIN:
612 {
613 lang_memory_region_type *mem;
614
615 mem = lang_memory_region_lookup (tree->name.name, FALSE);
616 if (mem != NULL)
e9ee469a 617 new_abs (mem->origin);
3ec57632 618 else
e9ee469a
AM
619 einfo (_("%F%S: undefined MEMORY region `%s'"
620 " referenced in expression\n"), tree->name.name);
3ec57632
NC
621 }
622 break;
623
8c95a62e
KH
624 default:
625 FAIL ();
626 break;
627 }
252b5132 628}
8c95a62e 629
e9ee469a
AM
630static void
631exp_fold_tree_1 (etree_type *tree)
252b5132 632{
252b5132
RH
633 if (tree == NULL)
634 {
e9ee469a
AM
635 memset (&expld.result, 0, sizeof (expld.result));
636 return;
252b5132
RH
637 }
638
4de2d33d 639 switch (tree->type.node_class)
252b5132
RH
640 {
641 case etree_value:
e9ee469a 642 new_rel (tree->value.value, tree->value.str, expld.section);
252b5132
RH
643 break;
644
645 case etree_rel:
e9ee469a
AM
646 if (expld.phase != lang_first_phase_enum)
647 {
648 asection *output_section = tree->rel.section->output_section;
649 new_rel (tree->rel.value + tree->rel.section->output_offset,
650 NULL, output_section);
651 }
252b5132 652 else
e9ee469a 653 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
654 break;
655
656 case etree_assert:
e9ee469a
AM
657 exp_fold_tree_1 (tree->assert_s.child);
658 if (expld.result.valid_p)
75ff4589 659 {
e9ee469a 660 if (expld.phase == lang_mark_phase_enum)
75ff4589
L
661 /* We don't care if assert fails or not when we are just
662 marking if a section is used or not. */
e9ee469a
AM
663 expld.result.value = 1;
664 else if (!expld.result.value)
75ff4589
L
665 einfo ("%X%P: %s\n", tree->assert_s.message);
666 }
252b5132
RH
667 break;
668
669 case etree_unary:
e9ee469a 670 fold_unary (tree);
252b5132
RH
671 break;
672
673 case etree_binary:
e9ee469a 674 fold_binary (tree);
252b5132 675 break;
0ae1cf52
AM
676
677 case etree_trinary:
e9ee469a 678 fold_trinary (tree);
0ae1cf52 679 break;
252b5132
RH
680
681 case etree_assign:
682 case etree_provide:
b46a87b1 683 case etree_provided:
252b5132
RH
684 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
685 {
c7d701b0 686 /* Assignment to dot can only be done during allocation. */
b46a87b1 687 if (tree->type.node_class != etree_assign)
252b5132 688 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
e9ee469a
AM
689 if (expld.phase == lang_mark_phase_enum
690 || expld.phase == lang_allocating_phase_enum
691 || (expld.phase == lang_final_phase_enum
692 && expld.section == bfd_abs_section_ptr))
252b5132 693 {
fbbb9ac5 694 /* Notify the folder that this is an assignment to dot. */
e9ee469a
AM
695 expld.assigning_to_dot = TRUE;
696 exp_fold_tree_1 (tree->assign.src);
697 expld.assigning_to_dot = FALSE;
698
699 if (!expld.result.valid_p)
700 {
701 if (expld.phase != lang_mark_phase_enum)
702 einfo (_("%F%S invalid assignment to location counter\n"));
703 }
704 else if (expld.dotp == NULL)
705 einfo (_("%F%S assignment to location counter"
706 " invalid outside of SECTION\n"));
252b5132
RH
707 else
708 {
e9ee469a
AM
709 bfd_vma nextdot;
710
711 nextdot = expld.result.value + expld.section->vma;
712 if (nextdot < expld.dot
713 && expld.section != bfd_abs_section_ptr)
714 einfo (_("%F%S cannot move location counter backwards"
715 " (from %V to %V)\n"), expld.dot, nextdot);
252b5132
RH
716 else
717 {
e9ee469a
AM
718 expld.dot = nextdot;
719 *expld.dotp = nextdot;
252b5132
RH
720 }
721 }
722 }
8b3d8fa8 723 else
e9ee469a 724 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
725 }
726 else
727 {
e9ee469a 728 struct bfd_link_hash_entry *h = NULL;
252b5132 729
e9ee469a
AM
730 if (tree->type.node_class == etree_provide)
731 {
252b5132 732 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
e9ee469a
AM
733 FALSE, FALSE, TRUE);
734 if (h == NULL
735 || (h->type != bfd_link_hash_new
736 && h->type != bfd_link_hash_undefined
737 && h->type != bfd_link_hash_common))
738 {
739 /* Do nothing. The symbol was never referenced, or was
740 defined by some object. */
741 break;
742 }
743 }
744
745 exp_fold_tree_1 (tree->assign.src);
746 if (expld.result.valid_p)
747 {
1579bae1 748 if (h == NULL)
67010b46 749 {
e9ee469a
AM
750 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
751 TRUE, FALSE, TRUE);
752 if (h == NULL)
67010b46
NC
753 einfo (_("%P%F:%s: hash creation failed\n"),
754 tree->assign.dst);
755 }
e9ee469a
AM
756
757 /* FIXME: Should we worry if the symbol is already
758 defined? */
759 lang_update_definedness (tree->assign.dst, h);
760 h->type = bfd_link_hash_defined;
761 h->u.def.value = expld.result.value;
762 h->u.def.section = expld.result.section;
763 if (tree->type.node_class == etree_provide)
764 tree->type.node_class = etree_provided;
252b5132
RH
765 }
766 }
767 break;
768
769 case etree_name:
e9ee469a 770 fold_name (tree);
252b5132
RH
771 break;
772
773 default:
774 FAIL ();
e9ee469a 775 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
776 break;
777 }
252b5132
RH
778}
779
e9ee469a
AM
780void
781exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
75ff4589 782{
e9ee469a
AM
783 expld.dot = *dotp;
784 expld.dotp = dotp;
785 expld.section = current_section;
786 exp_fold_tree_1 (tree);
75ff4589
L
787}
788
e9ee469a
AM
789static void
790exp_fold_tree_no_dot (etree_type *tree)
252b5132 791{
e9ee469a
AM
792 expld.dot = 0;
793 expld.dotp = NULL;
794 expld.section = bfd_abs_section_ptr;
795 exp_fold_tree_1 (tree);
252b5132
RH
796}
797
798etree_type *
1579bae1 799exp_binop (int code, etree_type *lhs, etree_type *rhs)
252b5132
RH
800{
801 etree_type value, *new;
252b5132
RH
802
803 value.type.node_code = code;
804 value.binary.lhs = lhs;
805 value.binary.rhs = rhs;
806 value.type.node_class = etree_binary;
e9ee469a
AM
807 exp_fold_tree_no_dot (&value);
808 if (expld.result.valid_p)
809 return exp_intop (expld.result.value);
810
1579bae1
AM
811 new = stat_alloc (sizeof (new->binary));
812 memcpy (new, &value, sizeof (new->binary));
252b5132
RH
813 return new;
814}
815
816etree_type *
1579bae1 817exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
252b5132
RH
818{
819 etree_type value, *new;
e9ee469a 820
252b5132
RH
821 value.type.node_code = code;
822 value.trinary.lhs = lhs;
823 value.trinary.cond = cond;
824 value.trinary.rhs = rhs;
825 value.type.node_class = etree_trinary;
e9ee469a
AM
826 exp_fold_tree_no_dot (&value);
827 if (expld.result.valid_p)
828 return exp_intop (expld.result.value);
c7d701b0 829
1579bae1
AM
830 new = stat_alloc (sizeof (new->trinary));
831 memcpy (new, &value, sizeof (new->trinary));
252b5132
RH
832 return new;
833}
834
252b5132 835etree_type *
1579bae1 836exp_unop (int code, etree_type *child)
252b5132
RH
837{
838 etree_type value, *new;
839
252b5132
RH
840 value.unary.type.node_code = code;
841 value.unary.child = child;
842 value.unary.type.node_class = etree_unary;
e9ee469a
AM
843 exp_fold_tree_no_dot (&value);
844 if (expld.result.valid_p)
845 return exp_intop (expld.result.value);
c7d701b0 846
1579bae1
AM
847 new = stat_alloc (sizeof (new->unary));
848 memcpy (new, &value, sizeof (new->unary));
252b5132
RH
849 return new;
850}
851
252b5132 852etree_type *
1579bae1 853exp_nameop (int code, const char *name)
252b5132
RH
854{
855 etree_type value, *new;
e9ee469a 856
252b5132
RH
857 value.name.type.node_code = code;
858 value.name.name = name;
859 value.name.type.node_class = etree_name;
860
e9ee469a
AM
861 exp_fold_tree_no_dot (&value);
862 if (expld.result.valid_p)
863 return exp_intop (expld.result.value);
c7d701b0 864
1579bae1
AM
865 new = stat_alloc (sizeof (new->name));
866 memcpy (new, &value, sizeof (new->name));
252b5132
RH
867 return new;
868
869}
870
252b5132 871etree_type *
1579bae1 872exp_assop (int code, const char *dst, etree_type *src)
252b5132 873{
e9ee469a 874 etree_type *new;
252b5132 875
1579bae1 876 new = stat_alloc (sizeof (new->assign));
e9ee469a
AM
877 new->type.node_code = code;
878 new->type.node_class = etree_assign;
879 new->assign.src = src;
880 new->assign.dst = dst;
252b5132
RH
881 return new;
882}
883
884/* Handle PROVIDE. */
885
886etree_type *
1579bae1 887exp_provide (const char *dst, etree_type *src)
252b5132
RH
888{
889 etree_type *n;
890
1579bae1 891 n = stat_alloc (sizeof (n->assign));
252b5132
RH
892 n->assign.type.node_code = '=';
893 n->assign.type.node_class = etree_provide;
894 n->assign.src = src;
895 n->assign.dst = dst;
896 return n;
897}
898
899/* Handle ASSERT. */
900
901etree_type *
1579bae1 902exp_assert (etree_type *exp, const char *message)
252b5132
RH
903{
904 etree_type *n;
905
1579bae1 906 n = stat_alloc (sizeof (n->assert_s));
252b5132
RH
907 n->assert_s.type.node_code = '!';
908 n->assert_s.type.node_class = etree_assert;
909 n->assert_s.child = exp;
910 n->assert_s.message = message;
911 return n;
912}
913
4de2d33d 914void
1579bae1 915exp_print_tree (etree_type *tree)
252b5132 916{
c7d701b0
NC
917 if (config.map_file == NULL)
918 config.map_file = stderr;
b7a26f91 919
c7d701b0
NC
920 if (tree == NULL)
921 {
922 minfo ("NULL TREE\n");
923 return;
924 }
b7a26f91 925
8c95a62e
KH
926 switch (tree->type.node_class)
927 {
928 case etree_value:
929 minfo ("0x%v", tree->value.value);
930 return;
931 case etree_rel:
932 if (tree->rel.section->owner != NULL)
933 minfo ("%B:", tree->rel.section->owner);
934 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
935 return;
936 case etree_assign:
8c95a62e 937 fprintf (config.map_file, "%s", tree->assign.dst);
b34976b6 938 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
939 exp_print_tree (tree->assign.src);
940 break;
941 case etree_provide:
b46a87b1 942 case etree_provided:
8c95a62e
KH
943 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
944 exp_print_tree (tree->assign.src);
945 fprintf (config.map_file, ")");
946 break;
947 case etree_binary:
948 fprintf (config.map_file, "(");
949 exp_print_tree (tree->binary.lhs);
b34976b6 950 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
951 exp_print_tree (tree->binary.rhs);
952 fprintf (config.map_file, ")");
953 break;
954 case etree_trinary:
955 exp_print_tree (tree->trinary.cond);
956 fprintf (config.map_file, "?");
957 exp_print_tree (tree->trinary.lhs);
958 fprintf (config.map_file, ":");
959 exp_print_tree (tree->trinary.rhs);
960 break;
961 case etree_unary:
b34976b6 962 exp_print_token (tree->unary.type.node_code, FALSE);
8c95a62e
KH
963 if (tree->unary.child)
964 {
7b17f854 965 fprintf (config.map_file, " (");
8c95a62e
KH
966 exp_print_tree (tree->unary.child);
967 fprintf (config.map_file, ")");
968 }
969 break;
970
971 case etree_assert:
972 fprintf (config.map_file, "ASSERT (");
973 exp_print_tree (tree->assert_s.child);
974 fprintf (config.map_file, ", %s)", tree->assert_s.message);
975 break;
976
8c95a62e
KH
977 case etree_name:
978 if (tree->type.node_code == NAME)
979 {
980 fprintf (config.map_file, "%s", tree->name.name);
981 }
982 else
983 {
b34976b6 984 exp_print_token (tree->type.node_code, FALSE);
8c95a62e 985 if (tree->name.name)
7b17f854 986 fprintf (config.map_file, " (%s)", tree->name.name);
8c95a62e
KH
987 }
988 break;
989 default:
990 FAIL ();
991 break;
252b5132 992 }
252b5132
RH
993}
994
995bfd_vma
e9ee469a 996exp_get_vma (etree_type *tree, bfd_vma def, char *name)
252b5132 997{
252b5132
RH
998 if (tree != NULL)
999 {
e9ee469a
AM
1000 exp_fold_tree_no_dot (tree);
1001 if (expld.result.valid_p)
1002 return expld.result.value;
1003 else if (name != NULL && expld.phase != lang_mark_phase_enum)
252b5132 1004 einfo (_("%F%S nonconstant expression for %s\n"), name);
252b5132 1005 }
e9ee469a 1006 return def;
252b5132
RH
1007}
1008
4de2d33d 1009int
e9ee469a 1010exp_get_value_int (etree_type *tree, int def, char *name)
252b5132 1011{
e9ee469a 1012 return exp_get_vma (tree, def, name);
252b5132
RH
1013}
1014
2c382fb6 1015fill_type *
e9ee469a 1016exp_get_fill (etree_type *tree, fill_type *def, char *name)
2c382fb6
AM
1017{
1018 fill_type *fill;
2c382fb6
AM
1019 size_t len;
1020 unsigned int val;
1021
1022 if (tree == NULL)
1023 return def;
1024
e9ee469a
AM
1025 exp_fold_tree_no_dot (tree);
1026 if (!expld.result.valid_p)
1027 {
1028 if (name != NULL && expld.phase != lang_mark_phase_enum)
1029 einfo (_("%F%S nonconstant expression for %s\n"), name);
1030 return def;
1031 }
2c382fb6 1032
e9ee469a 1033 if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0)
2c382fb6
AM
1034 {
1035 unsigned char *dst;
1036 unsigned char *s;
1579bae1 1037 fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
2c382fb6
AM
1038 fill->size = (len + 1) / 2;
1039 dst = fill->data;
e9ee469a 1040 s = (unsigned char *) expld.result.str;
2c382fb6
AM
1041 val = 0;
1042 do
1043 {
1044 unsigned int digit;
1045
1046 digit = *s++ - '0';
1047 if (digit > 9)
1048 digit = (digit - 'A' + '0' + 10) & 0xf;
1049 val <<= 4;
1050 val += digit;
1051 --len;
1052 if ((len & 1) == 0)
1053 {
1054 *dst++ = val;
1055 val = 0;
1056 }
1057 }
1058 while (len != 0);
1059 }
1060 else
1061 {
1579bae1 1062 fill = xmalloc (4 + sizeof (*fill) - 1);
e9ee469a 1063 val = expld.result.value;
2c382fb6
AM
1064 fill->data[0] = (val >> 24) & 0xff;
1065 fill->data[1] = (val >> 16) & 0xff;
1066 fill->data[2] = (val >> 8) & 0xff;
1067 fill->data[3] = (val >> 0) & 0xff;
1068 fill->size = 4;
1069 }
1070 return fill;
1071}
1072
252b5132 1073bfd_vma
e9ee469a 1074exp_get_abs_int (etree_type *tree, int def, char *name)
252b5132 1075{
e9ee469a
AM
1076 if (tree != NULL)
1077 {
1078 exp_fold_tree_no_dot (tree);
c7d701b0 1079
e9ee469a
AM
1080 if (expld.result.valid_p)
1081 {
1082 expld.result.value += expld.result.section->vma;
1083 return expld.result.value;
1084 }
1085 else if (name != NULL && expld.phase != lang_mark_phase_enum)
1086 einfo (_("%F%S non constant expression for %s\n"), name);
1087 }
1088 return def;
252b5132 1089}
c553bb91 1090
e5caa5e0
AM
1091static bfd_vma
1092align_n (bfd_vma value, bfd_vma align)
c553bb91
AM
1093{
1094 if (align <= 1)
1095 return value;
1096
1097 value = (value + align - 1) / align;
1098 return value * align;
1099}
This page took 0.345472 seconds and 4 git commands to generate.