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