* ld.texino: Describe double-quoted string syntax for version
[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);
f68d3f78 565 if (os != NULL && os->processed)
e9ee469a 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);
f68d3f78 576 if (os != NULL && os->processed)
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);
5397b1fe
AM
593 if (os == NULL)
594 new_abs (0);
f68d3f78 595 else if (os->processed)
e9ee469a 596 new_abs (os->bfd_section->size / opb);
8c95a62e 597 }
8c95a62e
KH
598 break;
599
3ec57632
NC
600 case LENGTH:
601 {
602 lang_memory_region_type *mem;
603
604 mem = lang_memory_region_lookup (tree->name.name, FALSE);
605 if (mem != NULL)
e9ee469a 606 new_abs (mem->length);
3ec57632 607 else
e9ee469a
AM
608 einfo (_("%F%S: undefined MEMORY region `%s'"
609 " referenced in expression\n"), tree->name.name);
3ec57632
NC
610 }
611 break;
612
613 case ORIGIN:
614 {
615 lang_memory_region_type *mem;
616
617 mem = lang_memory_region_lookup (tree->name.name, FALSE);
618 if (mem != NULL)
e9ee469a 619 new_abs (mem->origin);
3ec57632 620 else
e9ee469a
AM
621 einfo (_("%F%S: undefined MEMORY region `%s'"
622 " referenced in expression\n"), tree->name.name);
3ec57632
NC
623 }
624 break;
625
8c95a62e
KH
626 default:
627 FAIL ();
628 break;
629 }
252b5132 630}
8c95a62e 631
e9ee469a
AM
632static void
633exp_fold_tree_1 (etree_type *tree)
252b5132 634{
252b5132
RH
635 if (tree == NULL)
636 {
e9ee469a
AM
637 memset (&expld.result, 0, sizeof (expld.result));
638 return;
252b5132
RH
639 }
640
4de2d33d 641 switch (tree->type.node_class)
252b5132
RH
642 {
643 case etree_value:
e9ee469a 644 new_rel (tree->value.value, tree->value.str, expld.section);
252b5132
RH
645 break;
646
647 case etree_rel:
e9ee469a
AM
648 if (expld.phase != lang_first_phase_enum)
649 {
650 asection *output_section = tree->rel.section->output_section;
651 new_rel (tree->rel.value + tree->rel.section->output_offset,
652 NULL, output_section);
653 }
252b5132 654 else
e9ee469a 655 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
656 break;
657
658 case etree_assert:
e9ee469a 659 exp_fold_tree_1 (tree->assert_s.child);
5397b1fe
AM
660 if (expld.phase == lang_final_phase_enum && !expld.result.value)
661 einfo ("%X%P: %s\n", tree->assert_s.message);
252b5132
RH
662 break;
663
664 case etree_unary:
e9ee469a 665 fold_unary (tree);
252b5132
RH
666 break;
667
668 case etree_binary:
e9ee469a 669 fold_binary (tree);
252b5132 670 break;
0ae1cf52
AM
671
672 case etree_trinary:
e9ee469a 673 fold_trinary (tree);
0ae1cf52 674 break;
252b5132
RH
675
676 case etree_assign:
677 case etree_provide:
b46a87b1 678 case etree_provided:
252b5132
RH
679 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
680 {
c7d701b0 681 /* Assignment to dot can only be done during allocation. */
b46a87b1 682 if (tree->type.node_class != etree_assign)
252b5132 683 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
e9ee469a
AM
684 if (expld.phase == lang_mark_phase_enum
685 || expld.phase == lang_allocating_phase_enum
686 || (expld.phase == lang_final_phase_enum
687 && expld.section == bfd_abs_section_ptr))
252b5132 688 {
fbbb9ac5 689 /* Notify the folder that this is an assignment to dot. */
e9ee469a
AM
690 expld.assigning_to_dot = TRUE;
691 exp_fold_tree_1 (tree->assign.src);
692 expld.assigning_to_dot = FALSE;
693
694 if (!expld.result.valid_p)
695 {
696 if (expld.phase != lang_mark_phase_enum)
697 einfo (_("%F%S invalid assignment to location counter\n"));
698 }
699 else if (expld.dotp == NULL)
700 einfo (_("%F%S assignment to location counter"
701 " invalid outside of SECTION\n"));
252b5132
RH
702 else
703 {
e9ee469a
AM
704 bfd_vma nextdot;
705
706 nextdot = expld.result.value + expld.section->vma;
707 if (nextdot < expld.dot
708 && expld.section != bfd_abs_section_ptr)
709 einfo (_("%F%S cannot move location counter backwards"
710 " (from %V to %V)\n"), expld.dot, nextdot);
252b5132
RH
711 else
712 {
e9ee469a
AM
713 expld.dot = nextdot;
714 *expld.dotp = nextdot;
252b5132
RH
715 }
716 }
717 }
8b3d8fa8 718 else
e9ee469a 719 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
720 }
721 else
722 {
e9ee469a 723 struct bfd_link_hash_entry *h = NULL;
252b5132 724
e9ee469a
AM
725 if (tree->type.node_class == etree_provide)
726 {
252b5132 727 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
e9ee469a
AM
728 FALSE, FALSE, TRUE);
729 if (h == NULL
730 || (h->type != bfd_link_hash_new
731 && h->type != bfd_link_hash_undefined
732 && h->type != bfd_link_hash_common))
733 {
734 /* Do nothing. The symbol was never referenced, or was
735 defined by some object. */
736 break;
737 }
7af8e998
L
738 if (tree->assign.hidden)
739 bfd_hide_symbol (output_bfd, &link_info, h, TRUE);
e9ee469a
AM
740 }
741
742 exp_fold_tree_1 (tree->assign.src);
743 if (expld.result.valid_p)
744 {
1579bae1 745 if (h == NULL)
67010b46 746 {
e9ee469a
AM
747 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
748 TRUE, FALSE, TRUE);
749 if (h == NULL)
67010b46
NC
750 einfo (_("%P%F:%s: hash creation failed\n"),
751 tree->assign.dst);
752 }
e9ee469a
AM
753
754 /* FIXME: Should we worry if the symbol is already
755 defined? */
756 lang_update_definedness (tree->assign.dst, h);
757 h->type = bfd_link_hash_defined;
758 h->u.def.value = expld.result.value;
759 h->u.def.section = expld.result.section;
760 if (tree->type.node_class == etree_provide)
761 tree->type.node_class = etree_provided;
252b5132
RH
762 }
763 }
764 break;
765
766 case etree_name:
e9ee469a 767 fold_name (tree);
252b5132
RH
768 break;
769
770 default:
771 FAIL ();
e9ee469a 772 memset (&expld.result, 0, sizeof (expld.result));
252b5132
RH
773 break;
774 }
252b5132
RH
775}
776
e9ee469a
AM
777void
778exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
75ff4589 779{
e9ee469a
AM
780 expld.dot = *dotp;
781 expld.dotp = dotp;
782 expld.section = current_section;
783 exp_fold_tree_1 (tree);
75ff4589
L
784}
785
e9ee469a
AM
786static void
787exp_fold_tree_no_dot (etree_type *tree)
252b5132 788{
e9ee469a
AM
789 expld.dot = 0;
790 expld.dotp = NULL;
791 expld.section = bfd_abs_section_ptr;
792 exp_fold_tree_1 (tree);
252b5132
RH
793}
794
795etree_type *
1579bae1 796exp_binop (int code, etree_type *lhs, etree_type *rhs)
252b5132
RH
797{
798 etree_type value, *new;
252b5132
RH
799
800 value.type.node_code = code;
801 value.binary.lhs = lhs;
802 value.binary.rhs = rhs;
803 value.type.node_class = etree_binary;
e9ee469a
AM
804 exp_fold_tree_no_dot (&value);
805 if (expld.result.valid_p)
806 return exp_intop (expld.result.value);
807
1579bae1
AM
808 new = stat_alloc (sizeof (new->binary));
809 memcpy (new, &value, sizeof (new->binary));
252b5132
RH
810 return new;
811}
812
813etree_type *
1579bae1 814exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
252b5132
RH
815{
816 etree_type value, *new;
e9ee469a 817
252b5132
RH
818 value.type.node_code = code;
819 value.trinary.lhs = lhs;
820 value.trinary.cond = cond;
821 value.trinary.rhs = rhs;
822 value.type.node_class = etree_trinary;
e9ee469a
AM
823 exp_fold_tree_no_dot (&value);
824 if (expld.result.valid_p)
825 return exp_intop (expld.result.value);
c7d701b0 826
1579bae1
AM
827 new = stat_alloc (sizeof (new->trinary));
828 memcpy (new, &value, sizeof (new->trinary));
252b5132
RH
829 return new;
830}
831
252b5132 832etree_type *
1579bae1 833exp_unop (int code, etree_type *child)
252b5132
RH
834{
835 etree_type value, *new;
836
252b5132
RH
837 value.unary.type.node_code = code;
838 value.unary.child = child;
839 value.unary.type.node_class = etree_unary;
e9ee469a
AM
840 exp_fold_tree_no_dot (&value);
841 if (expld.result.valid_p)
842 return exp_intop (expld.result.value);
c7d701b0 843
1579bae1
AM
844 new = stat_alloc (sizeof (new->unary));
845 memcpy (new, &value, sizeof (new->unary));
252b5132
RH
846 return new;
847}
848
252b5132 849etree_type *
1579bae1 850exp_nameop (int code, const char *name)
252b5132
RH
851{
852 etree_type value, *new;
e9ee469a 853
252b5132
RH
854 value.name.type.node_code = code;
855 value.name.name = name;
856 value.name.type.node_class = etree_name;
857
e9ee469a
AM
858 exp_fold_tree_no_dot (&value);
859 if (expld.result.valid_p)
860 return exp_intop (expld.result.value);
c7d701b0 861
1579bae1
AM
862 new = stat_alloc (sizeof (new->name));
863 memcpy (new, &value, sizeof (new->name));
252b5132
RH
864 return new;
865
866}
867
252b5132 868etree_type *
1579bae1 869exp_assop (int code, const char *dst, etree_type *src)
252b5132 870{
e9ee469a 871 etree_type *new;
252b5132 872
1579bae1 873 new = stat_alloc (sizeof (new->assign));
e9ee469a
AM
874 new->type.node_code = code;
875 new->type.node_class = etree_assign;
876 new->assign.src = src;
877 new->assign.dst = dst;
252b5132
RH
878 return new;
879}
880
881/* Handle PROVIDE. */
882
883etree_type *
7af8e998 884exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
252b5132
RH
885{
886 etree_type *n;
887
1579bae1 888 n = stat_alloc (sizeof (n->assign));
252b5132
RH
889 n->assign.type.node_code = '=';
890 n->assign.type.node_class = etree_provide;
891 n->assign.src = src;
892 n->assign.dst = dst;
7af8e998 893 n->assign.hidden = hidden;
252b5132
RH
894 return n;
895}
896
897/* Handle ASSERT. */
898
899etree_type *
1579bae1 900exp_assert (etree_type *exp, const char *message)
252b5132
RH
901{
902 etree_type *n;
903
1579bae1 904 n = stat_alloc (sizeof (n->assert_s));
252b5132
RH
905 n->assert_s.type.node_code = '!';
906 n->assert_s.type.node_class = etree_assert;
907 n->assert_s.child = exp;
908 n->assert_s.message = message;
909 return n;
910}
911
4de2d33d 912void
1579bae1 913exp_print_tree (etree_type *tree)
252b5132 914{
c7d701b0
NC
915 if (config.map_file == NULL)
916 config.map_file = stderr;
b7a26f91 917
c7d701b0
NC
918 if (tree == NULL)
919 {
920 minfo ("NULL TREE\n");
921 return;
922 }
b7a26f91 923
8c95a62e
KH
924 switch (tree->type.node_class)
925 {
926 case etree_value:
927 minfo ("0x%v", tree->value.value);
928 return;
929 case etree_rel:
930 if (tree->rel.section->owner != NULL)
931 minfo ("%B:", tree->rel.section->owner);
932 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
933 return;
934 case etree_assign:
8c95a62e 935 fprintf (config.map_file, "%s", tree->assign.dst);
b34976b6 936 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
937 exp_print_tree (tree->assign.src);
938 break;
939 case etree_provide:
b46a87b1 940 case etree_provided:
8c95a62e
KH
941 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
942 exp_print_tree (tree->assign.src);
943 fprintf (config.map_file, ")");
944 break;
945 case etree_binary:
946 fprintf (config.map_file, "(");
947 exp_print_tree (tree->binary.lhs);
b34976b6 948 exp_print_token (tree->type.node_code, TRUE);
8c95a62e
KH
949 exp_print_tree (tree->binary.rhs);
950 fprintf (config.map_file, ")");
951 break;
952 case etree_trinary:
953 exp_print_tree (tree->trinary.cond);
954 fprintf (config.map_file, "?");
955 exp_print_tree (tree->trinary.lhs);
956 fprintf (config.map_file, ":");
957 exp_print_tree (tree->trinary.rhs);
958 break;
959 case etree_unary:
b34976b6 960 exp_print_token (tree->unary.type.node_code, FALSE);
8c95a62e
KH
961 if (tree->unary.child)
962 {
7b17f854 963 fprintf (config.map_file, " (");
8c95a62e
KH
964 exp_print_tree (tree->unary.child);
965 fprintf (config.map_file, ")");
966 }
967 break;
968
969 case etree_assert:
970 fprintf (config.map_file, "ASSERT (");
971 exp_print_tree (tree->assert_s.child);
972 fprintf (config.map_file, ", %s)", tree->assert_s.message);
973 break;
974
8c95a62e
KH
975 case etree_name:
976 if (tree->type.node_code == NAME)
977 {
978 fprintf (config.map_file, "%s", tree->name.name);
979 }
980 else
981 {
b34976b6 982 exp_print_token (tree->type.node_code, FALSE);
8c95a62e 983 if (tree->name.name)
7b17f854 984 fprintf (config.map_file, " (%s)", tree->name.name);
8c95a62e
KH
985 }
986 break;
987 default:
988 FAIL ();
989 break;
252b5132 990 }
252b5132
RH
991}
992
993bfd_vma
e9ee469a 994exp_get_vma (etree_type *tree, bfd_vma def, char *name)
252b5132 995{
252b5132
RH
996 if (tree != NULL)
997 {
e9ee469a
AM
998 exp_fold_tree_no_dot (tree);
999 if (expld.result.valid_p)
1000 return expld.result.value;
1001 else if (name != NULL && expld.phase != lang_mark_phase_enum)
252b5132 1002 einfo (_("%F%S nonconstant expression for %s\n"), name);
252b5132 1003 }
e9ee469a 1004 return def;
252b5132
RH
1005}
1006
4de2d33d 1007int
e9ee469a 1008exp_get_value_int (etree_type *tree, int def, char *name)
252b5132 1009{
e9ee469a 1010 return exp_get_vma (tree, def, name);
252b5132
RH
1011}
1012
2c382fb6 1013fill_type *
e9ee469a 1014exp_get_fill (etree_type *tree, fill_type *def, char *name)
2c382fb6
AM
1015{
1016 fill_type *fill;
2c382fb6
AM
1017 size_t len;
1018 unsigned int val;
1019
1020 if (tree == NULL)
1021 return def;
1022
e9ee469a
AM
1023 exp_fold_tree_no_dot (tree);
1024 if (!expld.result.valid_p)
1025 {
1026 if (name != NULL && expld.phase != lang_mark_phase_enum)
1027 einfo (_("%F%S nonconstant expression for %s\n"), name);
1028 return def;
1029 }
2c382fb6 1030
e9ee469a 1031 if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0)
2c382fb6
AM
1032 {
1033 unsigned char *dst;
1034 unsigned char *s;
1579bae1 1035 fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
2c382fb6
AM
1036 fill->size = (len + 1) / 2;
1037 dst = fill->data;
e9ee469a 1038 s = (unsigned char *) expld.result.str;
2c382fb6
AM
1039 val = 0;
1040 do
1041 {
1042 unsigned int digit;
1043
1044 digit = *s++ - '0';
1045 if (digit > 9)
1046 digit = (digit - 'A' + '0' + 10) & 0xf;
1047 val <<= 4;
1048 val += digit;
1049 --len;
1050 if ((len & 1) == 0)
1051 {
1052 *dst++ = val;
1053 val = 0;
1054 }
1055 }
1056 while (len != 0);
1057 }
1058 else
1059 {
1579bae1 1060 fill = xmalloc (4 + sizeof (*fill) - 1);
e9ee469a 1061 val = expld.result.value;
2c382fb6
AM
1062 fill->data[0] = (val >> 24) & 0xff;
1063 fill->data[1] = (val >> 16) & 0xff;
1064 fill->data[2] = (val >> 8) & 0xff;
1065 fill->data[3] = (val >> 0) & 0xff;
1066 fill->size = 4;
1067 }
1068 return fill;
1069}
1070
252b5132 1071bfd_vma
e9ee469a 1072exp_get_abs_int (etree_type *tree, int def, char *name)
252b5132 1073{
e9ee469a
AM
1074 if (tree != NULL)
1075 {
1076 exp_fold_tree_no_dot (tree);
c7d701b0 1077
e9ee469a
AM
1078 if (expld.result.valid_p)
1079 {
1080 expld.result.value += expld.result.section->vma;
1081 return expld.result.value;
1082 }
1083 else if (name != NULL && expld.phase != lang_mark_phase_enum)
1084 einfo (_("%F%S non constant expression for %s\n"), name);
1085 }
1086 return def;
252b5132 1087}
c553bb91 1088
e5caa5e0
AM
1089static bfd_vma
1090align_n (bfd_vma value, bfd_vma align)
c553bb91
AM
1091{
1092 if (align <= 1)
1093 return value;
1094
1095 value = (value + align - 1) / align;
1096 return value * align;
1097}
This page took 0.394747 seconds and 4 git commands to generate.