* ld.h (lang_phase_type): Move to..
[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
AM
209 if (expld.phase != lang_first_phase_enum)
210 {
211 make_abs ();
212 new_rel_from_abs (align_n (expld.dot, expld.result.value));
213 }
0ae1cf52 214 else
e9ee469a 215 expld.result.valid_p = FALSE;
0ae1cf52
AM
216 break;
217
218 case ABSOLUTE:
e9ee469a 219 make_abs ();
0ae1cf52
AM
220 break;
221
222 case '~':
e9ee469a
AM
223 make_abs ();
224 expld.result.value = ~expld.result.value;
0ae1cf52
AM
225 break;
226
227 case '!':
e9ee469a
AM
228 make_abs ();
229 expld.result.value = !expld.result.value;
0ae1cf52
AM
230 break;
231
232 case '-':
e9ee469a
AM
233 make_abs ();
234 expld.result.value = -expld.result.value;
0ae1cf52
AM
235 break;
236
237 case NEXT:
238 /* Return next place aligned to value. */
e9ee469a 239 if (expld.phase != lang_first_phase_enum)
0ae1cf52 240 {
e9ee469a
AM
241 make_abs ();
242 expld.result.value = align_n (expld.dot, expld.result.value);
0ae1cf52
AM
243 }
244 else
e9ee469a 245 expld.result.valid_p = FALSE;
0ae1cf52
AM
246 break;
247
248 case DATA_SEGMENT_END:
e9ee469a
AM
249 if (expld.phase != lang_first_phase_enum
250 && expld.section == bfd_abs_section_ptr
251 && (expld.dataseg.phase == exp_dataseg_align_seen
252 || expld.dataseg.phase == exp_dataseg_relro_seen
253 || expld.dataseg.phase == exp_dataseg_adjust
254 || expld.dataseg.phase == exp_dataseg_relro_adjust
255 || expld.phase == lang_final_phase_enum))
0ae1cf52 256 {
e9ee469a
AM
257 if (expld.dataseg.phase == exp_dataseg_align_seen
258 || expld.dataseg.phase == exp_dataseg_relro_seen)
0ae1cf52 259 {
e9ee469a
AM
260 expld.dataseg.phase = exp_dataseg_end_seen;
261 expld.dataseg.end = expld.result.value;
0ae1cf52
AM
262 }
263 }
264 else
e9ee469a 265 expld.result.valid_p = FALSE;
0ae1cf52
AM
266 break;
267
268 default:
269 FAIL ();
270 break;
271 }
272 }
0ae1cf52
AM
273}
274
e9ee469a
AM
275static void
276fold_binary (etree_type *tree)
252b5132 277{
e9ee469a 278 exp_fold_tree_1 (tree->binary.lhs);
ba916c8a
MM
279
280 /* The SEGMENT_START operator is special because its first
281 operand is a string, not the name of a symbol. */
e9ee469a 282 if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
ba916c8a
MM
283 {
284 const char *segment_name;
285 segment_type *seg;
286 /* Check to see if the user has overridden the default
287 value. */
288 segment_name = tree->binary.rhs->name.name;
289 for (seg = segments; seg; seg = seg->next)
290 if (strcmp (seg->name, segment_name) == 0)
291 {
292 seg->used = TRUE;
e9ee469a
AM
293 expld.result.value = seg->value;
294 expld.result.str = NULL;
295 expld.result.section = NULL;
ba916c8a
MM
296 break;
297 }
298 }
e9ee469a 299 else if (expld.result.valid_p)
252b5132 300 {
e9ee469a 301 etree_value_type lhs = expld.result;
252b5132 302
e9ee469a
AM
303 exp_fold_tree_1 (tree->binary.rhs);
304 if (expld.result.valid_p)
252b5132
RH
305 {
306 /* If the values are from different sections, or this is an
307 absolute expression, make both the source arguments
308 absolute. However, adding or subtracting an absolute
309 value from a relative value is meaningful, and is an
310 exception. */
e9ee469a
AM
311 if (expld.section != bfd_abs_section_ptr
312 && lhs.section == bfd_abs_section_ptr
313 && tree->type.node_code == '+')
314 {
315 /* Keep the section of the rhs term. */
316 expld.result.value = lhs.value + expld.result.value;
317 return;
318 }
319 else if (expld.section != bfd_abs_section_ptr
320 && expld.result.section == bfd_abs_section_ptr
252b5132
RH
321 && (tree->type.node_code == '+'
322 || tree->type.node_code == '-'))
323 {
e9ee469a
AM
324 /* Keep the section of the lhs term. */
325 expld.result.section = lhs.section;
252b5132 326 }
e9ee469a
AM
327 else if (expld.result.section != lhs.section
328 || expld.section == bfd_abs_section_ptr)
252b5132 329 {
e9ee469a
AM
330 make_abs ();
331 lhs.value += lhs.section->vma;
252b5132
RH
332 }
333
4de2d33d 334 switch (tree->type.node_code)
252b5132
RH
335 {
336 case '%':
e9ee469a
AM
337 if (expld.result.value != 0)
338 expld.result.value = ((bfd_signed_vma) lhs.value
339 % (bfd_signed_vma) expld.result.value);
340 else if (expld.phase != lang_mark_phase_enum)
252b5132 341 einfo (_("%F%S %% by zero\n"));
252b5132
RH
342 break;
343
344 case '/':
e9ee469a
AM
345 if (expld.result.value != 0)
346 expld.result.value = ((bfd_signed_vma) lhs.value
347 / (bfd_signed_vma) expld.result.value);
348 else if (expld.phase != lang_mark_phase_enum)
252b5132 349 einfo (_("%F%S / by zero\n"));
252b5132
RH
350 break;
351
e9ee469a
AM
352#define BOP(x, y) \
353 case x: \
354 expld.result.value = lhs.value y expld.result.value; \
355 break;
356
8c95a62e
KH
357 BOP ('+', +);
358 BOP ('*', *);
359 BOP ('-', -);
360 BOP (LSHIFT, <<);
361 BOP (RSHIFT, >>);
362 BOP (EQ, ==);
363 BOP (NE, !=);
364 BOP ('<', <);
365 BOP ('>', >);
366 BOP (LE, <=);
367 BOP (GE, >=);
368 BOP ('&', &);
369 BOP ('^', ^);
370 BOP ('|', |);
371 BOP (ANDAND, &&);
372 BOP (OROR, ||);
252b5132
RH
373
374 case MAX_K:
e9ee469a
AM
375 if (lhs.value > expld.result.value)
376 expld.result.value = lhs.value;
252b5132
RH
377 break;
378
379 case MIN_K:
e9ee469a
AM
380 if (lhs.value < expld.result.value)
381 expld.result.value = lhs.value;
252b5132
RH
382 break;
383
876f4090 384 case ALIGN_K:
e9ee469a 385 expld.result.value = align_n (lhs.value, expld.result.value);
876f4090 386 break;
c468c8bc 387
2d20f7bf 388 case DATA_SEGMENT_ALIGN:
e9ee469a
AM
389 if (expld.phase != lang_first_phase_enum
390 && expld.section == bfd_abs_section_ptr
391 && (expld.dataseg.phase == exp_dataseg_none
392 || expld.dataseg.phase == exp_dataseg_adjust
393 || expld.dataseg.phase == exp_dataseg_relro_adjust
394 || expld.phase == lang_final_phase_enum))
2d20f7bf 395 {
e9ee469a
AM
396 bfd_vma maxpage = lhs.value;
397 bfd_vma commonpage = expld.result.value;
2d20f7bf 398
e9ee469a
AM
399 expld.result.value = align_n (expld.dot, maxpage);
400 if (expld.dataseg.phase == exp_dataseg_relro_adjust)
401 expld.result.value = expld.dataseg.base;
402 else if (expld.dataseg.phase != exp_dataseg_adjust)
2d20f7bf 403 {
e9ee469a
AM
404 expld.result.value += expld.dot & (maxpage - 1);
405 if (expld.phase == lang_allocating_phase_enum)
2d20f7bf 406 {
e9ee469a
AM
407 expld.dataseg.phase = exp_dataseg_align_seen;
408 expld.dataseg.min_base = align_n (expld.dot, maxpage);
409 expld.dataseg.base = expld.result.value;
410 expld.dataseg.pagesize = commonpage;
411 expld.dataseg.maxpagesize = maxpage;
412 expld.dataseg.relro_end = 0;
2d20f7bf
JJ
413 }
414 }
e9ee469a
AM
415 else if (commonpage < maxpage)
416 expld.result.value += ((expld.dot + commonpage - 1)
417 & (maxpage - commonpage));
2d20f7bf
JJ
418 }
419 else
e9ee469a 420 expld.result.valid_p = FALSE;
2d20f7bf
JJ
421 break;
422
a4f5ad88 423 case DATA_SEGMENT_RELRO_END:
e9ee469a
AM
424 if (expld.phase != lang_first_phase_enum
425 && (expld.dataseg.phase == exp_dataseg_align_seen
426 || expld.dataseg.phase == exp_dataseg_adjust
427 || expld.dataseg.phase == exp_dataseg_relro_adjust
428 || expld.phase == lang_final_phase_enum))
a4f5ad88 429 {
e9ee469a
AM
430 if (expld.dataseg.phase == exp_dataseg_align_seen
431 || expld.dataseg.phase == exp_dataseg_relro_adjust)
432 expld.dataseg.relro_end = lhs.value + expld.result.value;
433
434 if (expld.dataseg.phase == exp_dataseg_relro_adjust
435 && (expld.dataseg.relro_end
436 & (expld.dataseg.pagesize - 1)))
a4f5ad88 437 {
e9ee469a
AM
438 expld.dataseg.relro_end += expld.dataseg.pagesize - 1;
439 expld.dataseg.relro_end &= ~(expld.dataseg.pagesize - 1);
440 expld.result.value = (expld.dataseg.relro_end
441 - expld.result.value);
a4f5ad88 442 }
e9ee469a
AM
443 else
444 expld.result.value = lhs.value;
445
446 if (expld.dataseg.phase == exp_dataseg_align_seen)
447 expld.dataseg.phase = exp_dataseg_relro_seen;
a4f5ad88
JJ
448 }
449 else
e9ee469a 450 expld.result.valid_p = FALSE;
a4f5ad88
JJ
451 break;
452
252b5132 453 default:
8c95a62e 454 FAIL ();
252b5132
RH
455 }
456 }
457 else
e9ee469a 458 expld.result.valid_p = FALSE;
252b5132 459 }
252b5132
RH
460}
461
e9ee469a
AM
462static void
463fold_trinary (etree_type *tree)
0ae1cf52 464{
e9ee469a
AM
465 exp_fold_tree_1 (tree->trinary.cond);
466 if (expld.result.valid_p)
467 exp_fold_tree_1 (expld.result.value
468 ? tree->trinary.lhs
469 : tree->trinary.rhs);
0ae1cf52
AM
470}
471
e9ee469a
AM
472static void
473fold_name (etree_type *tree)
252b5132 474{
e9ee469a 475 memset (&expld.result, 0, sizeof (expld.result));
c468c8bc 476
4de2d33d 477 switch (tree->type.node_code)
8c95a62e
KH
478 {
479 case SIZEOF_HEADERS:
e9ee469a
AM
480 if (expld.phase != lang_first_phase_enum)
481 {
482 bfd_vma hdr_size = 0;
483 /* Don't find the real header size if only marking sections;
484 The bfd function may cache incorrect data. */
485 if (expld.phase != lang_mark_phase_enum)
486 hdr_size = bfd_sizeof_headers (output_bfd, link_info.relocatable);
487 new_abs (hdr_size);
488 }
8c95a62e
KH
489 break;
490 case DEFINED:
e9ee469a 491 if (expld.phase == lang_first_phase_enum)
1b493742 492 lang_track_definedness (tree->name.name);
8c95a62e
KH
493 else
494 {
495 struct bfd_link_hash_entry *h;
420e579c
HPN
496 int def_iteration
497 = lang_symbol_definition_iteration (tree->name.name);
8c95a62e
KH
498
499 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
500 tree->name.name,
b34976b6 501 FALSE, FALSE, TRUE);
e9ee469a
AM
502 expld.result.value = (h != NULL
503 && (h->type == bfd_link_hash_defined
504 || h->type == bfd_link_hash_defweak
505 || h->type == bfd_link_hash_common)
506 && (def_iteration == lang_statement_iteration
507 || def_iteration == -1));
508 expld.result.section = bfd_abs_section_ptr;
509 expld.result.valid_p = TRUE;
8c95a62e
KH
510 }
511 break;
512 case NAME:
e9ee469a
AM
513 if (expld.phase == lang_first_phase_enum)
514 ;
515 else if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
516 new_rel_from_abs (expld.dot);
517 else
8c95a62e
KH
518 {
519 struct bfd_link_hash_entry *h;
520
521 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
522 tree->name.name,
1b493742
NS
523 TRUE, FALSE, TRUE);
524 if (!h)
525 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
526 else if (h->type == bfd_link_hash_defined
527 || h->type == bfd_link_hash_defweak)
8c95a62e
KH
528 {
529 if (bfd_is_abs_section (h->u.def.section))
e9ee469a
AM
530 new_abs (h->u.def.value);
531 else
8c95a62e
KH
532 {
533 asection *output_section;
534
535 output_section = h->u.def.section->output_section;
536 if (output_section == NULL)
8c95a62e 537 {
e9ee469a
AM
538 if (expld.phase != lang_mark_phase_enum)
539 einfo (_("%X%S: unresolvable symbol `%s'"
540 " referenced in expression\n"),
541 tree->name.name);
8c95a62e 542 }
e9ee469a
AM
543 else
544 new_rel (h->u.def.value + h->u.def.section->output_offset,
545 NULL, output_section);
8c95a62e
KH
546 }
547 }
e9ee469a
AM
548 else if (expld.phase == lang_final_phase_enum
549 || expld.assigning_to_dot)
8c95a62e
KH
550 einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
551 tree->name.name);
1b493742
NS
552 else if (h->type == bfd_link_hash_new)
553 {
554 h->type = bfd_link_hash_undefined;
555 h->u.undef.abfd = NULL;
3eda52aa 556 if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
a010d60f 557 bfd_link_add_undef (link_info.hash, h);
1b493742 558 }
8c95a62e
KH
559 }
560 break;
561
562 case ADDR:
e9ee469a 563 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
564 {
565 lang_output_section_statement_type *os;
566
567 os = lang_output_section_find (tree->name.name);
e9ee469a
AM
568 if (os != NULL && os->processed > 0)
569 new_rel (0, NULL, os->bfd_section);
8c95a62e 570 }
8c95a62e
KH
571 break;
572
573 case LOADADDR:
e9ee469a 574 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
575 {
576 lang_output_section_statement_type *os;
577
578 os = lang_output_section_find (tree->name.name);
e9ee469a 579 if (os != NULL && os->processed > 0)
1b493742 580 {
e9ee469a
AM
581 if (os->load_base == NULL)
582 new_rel (0, NULL, os->bfd_section);
583 else
584 exp_fold_tree_1 (os->load_base);
1b493742 585 }
8c95a62e 586 }
8c95a62e
KH
587 break;
588
589 case SIZEOF:
e9ee469a 590 if (expld.phase != lang_first_phase_enum)
8c95a62e
KH
591 {
592 int opb = bfd_octets_per_byte (output_bfd);
593 lang_output_section_statement_type *os;
594
595 os = lang_output_section_find (tree->name.name);
e9ee469a
AM
596 if (os != NULL && os->processed > 0)
597 new_abs (os->bfd_section->size / opb);
8c95a62e 598 }
8c95a62e
KH
599 break;
600
3ec57632
NC
601 case LENGTH:
602 {
603 lang_memory_region_type *mem;
604
605 mem = lang_memory_region_lookup (tree->name.name, FALSE);
606 if (mem != NULL)
e9ee469a 607 new_abs (mem->length);
3ec57632 608 else
e9ee469a
AM
609 einfo (_("%F%S: undefined MEMORY region `%s'"
610 " referenced in expression\n"), tree->name.name);
3ec57632
NC
611 }
612 break;
613
614 case ORIGIN:
615 {
616 lang_memory_region_type *mem;
617
618 mem = lang_memory_region_lookup (tree->name.name, FALSE);
619 if (mem != NULL)
e9ee469a 620 new_abs (mem->origin);
3ec57632 621 else
e9ee469a
AM
622 einfo (_("%F%S: undefined MEMORY region `%s'"
623 " referenced in expression\n"), tree->name.name);
3ec57632
NC
624 }
625 break;
626
8c95a62e
KH
627 default:
628 FAIL ();
629 break;
630 }
252b5132 631}
8c95a62e 632
e9ee469a
AM
633static void
634exp_fold_tree_1 (etree_type *tree)
252b5132 635{
252b5132
RH
636 if (tree == NULL)
637 {
e9ee469a
AM
638 memset (&expld.result, 0, sizeof (expld.result));
639 return;
252b5132
RH
640 }
641
4de2d33d 642 switch (tree->type.node_class)
252b5132
RH
643 {
644 case etree_value:
e9ee469a 645 new_rel (tree->value.value, tree->value.str, expld.section);
252b5132
RH
646 break;
647
648 case etree_rel:
e9ee469a
AM
649 if (expld.phase != lang_first_phase_enum)
650 {
651 asection *output_section = tree->rel.section->output_section;
652 new_rel (tree->rel.value + tree->rel.section->output_offset,
653 NULL, output_section);
654 }
252b5132 655 else
e9ee469a 656 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
657 break;
658
659 case etree_assert:
e9ee469a
AM
660 exp_fold_tree_1 (tree->assert_s.child);
661 if (expld.result.valid_p)
75ff4589 662 {
e9ee469a 663 if (expld.phase == lang_mark_phase_enum)
75ff4589
L
664 /* We don't care if assert fails or not when we are just
665 marking if a section is used or not. */
e9ee469a
AM
666 expld.result.value = 1;
667 else if (!expld.result.value)
75ff4589
L
668 einfo ("%X%P: %s\n", tree->assert_s.message);
669 }
252b5132
RH
670 break;
671
672 case etree_unary:
e9ee469a 673 fold_unary (tree);
252b5132
RH
674 break;
675
676 case etree_binary:
e9ee469a 677 fold_binary (tree);
252b5132 678 break;
0ae1cf52
AM
679
680 case etree_trinary:
e9ee469a 681 fold_trinary (tree);
0ae1cf52 682 break;
252b5132
RH
683
684 case etree_assign:
685 case etree_provide:
b46a87b1 686 case etree_provided:
252b5132
RH
687 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
688 {
c7d701b0 689 /* Assignment to dot can only be done during allocation. */
b46a87b1 690 if (tree->type.node_class != etree_assign)
252b5132 691 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
e9ee469a
AM
692 if (expld.phase == lang_mark_phase_enum
693 || expld.phase == lang_allocating_phase_enum
694 || (expld.phase == lang_final_phase_enum
695 && expld.section == bfd_abs_section_ptr))
252b5132 696 {
fbbb9ac5 697 /* Notify the folder that this is an assignment to dot. */
e9ee469a
AM
698 expld.assigning_to_dot = TRUE;
699 exp_fold_tree_1 (tree->assign.src);
700 expld.assigning_to_dot = FALSE;
701
702 if (!expld.result.valid_p)
703 {
704 if (expld.phase != lang_mark_phase_enum)
705 einfo (_("%F%S invalid assignment to location counter\n"));
706 }
707 else if (expld.dotp == NULL)
708 einfo (_("%F%S assignment to location counter"
709 " invalid outside of SECTION\n"));
252b5132
RH
710 else
711 {
e9ee469a
AM
712 bfd_vma nextdot;
713
714 nextdot = expld.result.value + expld.section->vma;
715 if (nextdot < expld.dot
716 && expld.section != bfd_abs_section_ptr)
717 einfo (_("%F%S cannot move location counter backwards"
718 " (from %V to %V)\n"), expld.dot, nextdot);
252b5132
RH
719 else
720 {
e9ee469a
AM
721 expld.dot = nextdot;
722 *expld.dotp = nextdot;
252b5132
RH
723 }
724 }
725 }
8b3d8fa8 726 else
e9ee469a 727 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
728 }
729 else
730 {
e9ee469a 731 struct bfd_link_hash_entry *h = NULL;
252b5132 732
e9ee469a
AM
733 if (tree->type.node_class == etree_provide)
734 {
252b5132 735 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
e9ee469a
AM
736 FALSE, FALSE, TRUE);
737 if (h == NULL
738 || (h->type != bfd_link_hash_new
739 && h->type != bfd_link_hash_undefined
740 && h->type != bfd_link_hash_common))
741 {
742 /* Do nothing. The symbol was never referenced, or was
743 defined by some object. */
744 break;
745 }
746 }
747
748 exp_fold_tree_1 (tree->assign.src);
749 if (expld.result.valid_p)
750 {
1579bae1 751 if (h == NULL)
67010b46 752 {
e9ee469a
AM
753 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
754 TRUE, FALSE, TRUE);
755 if (h == NULL)
67010b46
NC
756 einfo (_("%P%F:%s: hash creation failed\n"),
757 tree->assign.dst);
758 }
e9ee469a
AM
759
760 /* FIXME: Should we worry if the symbol is already
761 defined? */
762 lang_update_definedness (tree->assign.dst, h);
763 h->type = bfd_link_hash_defined;
764 h->u.def.value = expld.result.value;
765 h->u.def.section = expld.result.section;
766 if (tree->type.node_class == etree_provide)
767 tree->type.node_class = etree_provided;
252b5132
RH
768 }
769 }
770 break;
771
772 case etree_name:
e9ee469a 773 fold_name (tree);
252b5132
RH
774 break;
775
776 default:
777 FAIL ();
e9ee469a 778 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
779 break;
780 }
252b5132
RH
781}
782
e9ee469a
AM
783void
784exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
75ff4589 785{
e9ee469a
AM
786 expld.dot = *dotp;
787 expld.dotp = dotp;
788 expld.section = current_section;
789 exp_fold_tree_1 (tree);
75ff4589
L
790}
791
e9ee469a
AM
792static void
793exp_fold_tree_no_dot (etree_type *tree)
252b5132 794{
e9ee469a
AM
795 expld.dot = 0;
796 expld.dotp = NULL;
797 expld.section = bfd_abs_section_ptr;
798 exp_fold_tree_1 (tree);
252b5132
RH
799}
800
801etree_type *
1579bae1 802exp_binop (int code, etree_type *lhs, etree_type *rhs)
252b5132
RH
803{
804 etree_type value, *new;
252b5132
RH
805
806 value.type.node_code = code;
807 value.binary.lhs = lhs;
808 value.binary.rhs = rhs;
809 value.type.node_class = etree_binary;
e9ee469a
AM
810 exp_fold_tree_no_dot (&value);
811 if (expld.result.valid_p)
812 return exp_intop (expld.result.value);
813
1579bae1
AM
814 new = stat_alloc (sizeof (new->binary));
815 memcpy (new, &value, sizeof (new->binary));
252b5132
RH
816 return new;
817}
818
819etree_type *
1579bae1 820exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
252b5132
RH
821{
822 etree_type value, *new;
e9ee469a 823
252b5132
RH
824 value.type.node_code = code;
825 value.trinary.lhs = lhs;
826 value.trinary.cond = cond;
827 value.trinary.rhs = rhs;
828 value.type.node_class = etree_trinary;
e9ee469a
AM
829 exp_fold_tree_no_dot (&value);
830 if (expld.result.valid_p)
831 return exp_intop (expld.result.value);
c7d701b0 832
1579bae1
AM
833 new = stat_alloc (sizeof (new->trinary));
834 memcpy (new, &value, sizeof (new->trinary));
252b5132
RH
835 return new;
836}
837
252b5132 838etree_type *
1579bae1 839exp_unop (int code, etree_type *child)
252b5132
RH
840{
841 etree_type value, *new;
842
252b5132
RH
843 value.unary.type.node_code = code;
844 value.unary.child = child;
845 value.unary.type.node_class = etree_unary;
e9ee469a
AM
846 exp_fold_tree_no_dot (&value);
847 if (expld.result.valid_p)
848 return exp_intop (expld.result.value);
c7d701b0 849
1579bae1
AM
850 new = stat_alloc (sizeof (new->unary));
851 memcpy (new, &value, sizeof (new->unary));
252b5132
RH
852 return new;
853}
854
252b5132 855etree_type *
1579bae1 856exp_nameop (int code, const char *name)
252b5132
RH
857{
858 etree_type value, *new;
e9ee469a 859
252b5132
RH
860 value.name.type.node_code = code;
861 value.name.name = name;
862 value.name.type.node_class = etree_name;
863
e9ee469a
AM
864 exp_fold_tree_no_dot (&value);
865 if (expld.result.valid_p)
866 return exp_intop (expld.result.value);
c7d701b0 867
1579bae1
AM
868 new = stat_alloc (sizeof (new->name));
869 memcpy (new, &value, sizeof (new->name));
252b5132
RH
870 return new;
871
872}
873
252b5132 874etree_type *
1579bae1 875exp_assop (int code, const char *dst, etree_type *src)
252b5132 876{
e9ee469a 877 etree_type *new;
252b5132 878
1579bae1 879 new = stat_alloc (sizeof (new->assign));
e9ee469a
AM
880 new->type.node_code = code;
881 new->type.node_class = etree_assign;
882 new->assign.src = src;
883 new->assign.dst = dst;
252b5132
RH
884 return new;
885}
886
887/* Handle PROVIDE. */
888
889etree_type *
1579bae1 890exp_provide (const char *dst, etree_type *src)
252b5132
RH
891{
892 etree_type *n;
893
1579bae1 894 n = stat_alloc (sizeof (n->assign));
252b5132
RH
895 n->assign.type.node_code = '=';
896 n->assign.type.node_class = etree_provide;
897 n->assign.src = src;
898 n->assign.dst = dst;
899 return n;
900}
901
902/* Handle ASSERT. */
903
904etree_type *
1579bae1 905exp_assert (etree_type *exp, const char *message)
252b5132
RH
906{
907 etree_type *n;
908
1579bae1 909 n = stat_alloc (sizeof (n->assert_s));
252b5132
RH
910 n->assert_s.type.node_code = '!';
911 n->assert_s.type.node_class = etree_assert;
912 n->assert_s.child = exp;
913 n->assert_s.message = message;
914 return n;
915}
916
4de2d33d 917void
1579bae1 918exp_print_tree (etree_type *tree)
252b5132 919{
c7d701b0
NC
920 if (config.map_file == NULL)
921 config.map_file = stderr;
b7a26f91 922
c7d701b0
NC
923 if (tree == NULL)
924 {
925 minfo ("NULL TREE\n");
926 return;
927 }
b7a26f91 928
8c95a62e
KH
929 switch (tree->type.node_class)
930 {
931 case etree_value:
932 minfo ("0x%v", tree->value.value);
933 return;
934 case etree_rel:
935 if (tree->rel.section->owner != NULL)
936 minfo ("%B:", tree->rel.section->owner);
937 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
938 return;
939 case etree_assign:
8c95a62e 940 fprintf (config.map_file, "%s", tree->assign.dst);
b34976b6 941 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
942 exp_print_tree (tree->assign.src);
943 break;
944 case etree_provide:
b46a87b1 945 case etree_provided:
8c95a62e
KH
946 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
947 exp_print_tree (tree->assign.src);
948 fprintf (config.map_file, ")");
949 break;
950 case etree_binary:
951 fprintf (config.map_file, "(");
952 exp_print_tree (tree->binary.lhs);
b34976b6 953 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
954 exp_print_tree (tree->binary.rhs);
955 fprintf (config.map_file, ")");
956 break;
957 case etree_trinary:
958 exp_print_tree (tree->trinary.cond);
959 fprintf (config.map_file, "?");
960 exp_print_tree (tree->trinary.lhs);
961 fprintf (config.map_file, ":");
962 exp_print_tree (tree->trinary.rhs);
963 break;
964 case etree_unary:
b34976b6 965 exp_print_token (tree->unary.type.node_code, FALSE);
8c95a62e
KH
966 if (tree->unary.child)
967 {
7b17f854 968 fprintf (config.map_file, " (");
8c95a62e
KH
969 exp_print_tree (tree->unary.child);
970 fprintf (config.map_file, ")");
971 }
972 break;
973
974 case etree_assert:
975 fprintf (config.map_file, "ASSERT (");
976 exp_print_tree (tree->assert_s.child);
977 fprintf (config.map_file, ", %s)", tree->assert_s.message);
978 break;
979
8c95a62e
KH
980 case etree_name:
981 if (tree->type.node_code == NAME)
982 {
983 fprintf (config.map_file, "%s", tree->name.name);
984 }
985 else
986 {
b34976b6 987 exp_print_token (tree->type.node_code, FALSE);
8c95a62e 988 if (tree->name.name)
7b17f854 989 fprintf (config.map_file, " (%s)", tree->name.name);
8c95a62e
KH
990 }
991 break;
992 default:
993 FAIL ();
994 break;
252b5132 995 }
252b5132
RH
996}
997
998bfd_vma
e9ee469a 999exp_get_vma (etree_type *tree, bfd_vma def, char *name)
252b5132 1000{
252b5132
RH
1001 if (tree != NULL)
1002 {
e9ee469a
AM
1003 exp_fold_tree_no_dot (tree);
1004 if (expld.result.valid_p)
1005 return expld.result.value;
1006 else if (name != NULL && expld.phase != lang_mark_phase_enum)
252b5132 1007 einfo (_("%F%S nonconstant expression for %s\n"), name);
252b5132 1008 }
e9ee469a 1009 return def;
252b5132
RH
1010}
1011
4de2d33d 1012int
e9ee469a 1013exp_get_value_int (etree_type *tree, int def, char *name)
252b5132 1014{
e9ee469a 1015 return exp_get_vma (tree, def, name);
252b5132
RH
1016}
1017
2c382fb6 1018fill_type *
e9ee469a 1019exp_get_fill (etree_type *tree, fill_type *def, char *name)
2c382fb6
AM
1020{
1021 fill_type *fill;
2c382fb6
AM
1022 size_t len;
1023 unsigned int val;
1024
1025 if (tree == NULL)
1026 return def;
1027
e9ee469a
AM
1028 exp_fold_tree_no_dot (tree);
1029 if (!expld.result.valid_p)
1030 {
1031 if (name != NULL && expld.phase != lang_mark_phase_enum)
1032 einfo (_("%F%S nonconstant expression for %s\n"), name);
1033 return def;
1034 }
2c382fb6 1035
e9ee469a 1036 if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0)
2c382fb6
AM
1037 {
1038 unsigned char *dst;
1039 unsigned char *s;
1579bae1 1040 fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
2c382fb6
AM
1041 fill->size = (len + 1) / 2;
1042 dst = fill->data;
e9ee469a 1043 s = (unsigned char *) expld.result.str;
2c382fb6
AM
1044 val = 0;
1045 do
1046 {
1047 unsigned int digit;
1048
1049 digit = *s++ - '0';
1050 if (digit > 9)
1051 digit = (digit - 'A' + '0' + 10) & 0xf;
1052 val <<= 4;
1053 val += digit;
1054 --len;
1055 if ((len & 1) == 0)
1056 {
1057 *dst++ = val;
1058 val = 0;
1059 }
1060 }
1061 while (len != 0);
1062 }
1063 else
1064 {
1579bae1 1065 fill = xmalloc (4 + sizeof (*fill) - 1);
e9ee469a 1066 val = expld.result.value;
2c382fb6
AM
1067 fill->data[0] = (val >> 24) & 0xff;
1068 fill->data[1] = (val >> 16) & 0xff;
1069 fill->data[2] = (val >> 8) & 0xff;
1070 fill->data[3] = (val >> 0) & 0xff;
1071 fill->size = 4;
1072 }
1073 return fill;
1074}
1075
252b5132 1076bfd_vma
e9ee469a 1077exp_get_abs_int (etree_type *tree, int def, char *name)
252b5132 1078{
e9ee469a
AM
1079 if (tree != NULL)
1080 {
1081 exp_fold_tree_no_dot (tree);
c7d701b0 1082
e9ee469a
AM
1083 if (expld.result.valid_p)
1084 {
1085 expld.result.value += expld.result.section->vma;
1086 return expld.result.value;
1087 }
1088 else if (name != NULL && expld.phase != lang_mark_phase_enum)
1089 einfo (_("%F%S non constant expression for %s\n"), name);
1090 }
1091 return def;
252b5132 1092}
c553bb91 1093
e5caa5e0
AM
1094static bfd_vma
1095align_n (bfd_vma value, bfd_vma align)
c553bb91
AM
1096{
1097 if (align <= 1)
1098 return value;
1099
1100 value = (value + align - 1) / align;
1101 return value * align;
1102}
This page took 0.386216 seconds and 4 git commands to generate.