ldexp.c revision 33965
115920Speter/* This module handles expression trees. 215920SpeterCopyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. 315920SpeterWritten by Steve Chamberlain of Cygnus Support (sac@cygnus.com). 415920Speter 515920SpeterThis file is part of GLD, the Gnu Linker. 615920Speter 715920SpeterGLD is free software; you can redistribute it and/or modify 815920Speterit under the terms of the GNU General Public License as published by 915920Speterthe Free Software Foundation; either version 2, or (at your option) 1015920Speterany later version. 1115920Speter 1215920SpeterGLD is distributed in the hope that it will be useful, 1315920Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1415920SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1515920SpeterGNU General Public License for more details. 1615920Speter 1715920SpeterYou should have received a copy of the GNU General Public License 1815920Speteralong with GLD; see the file COPYING. If not, write to 1915920Speterthe Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2015920Speter 2115920Speter/* 2215920SpeterThis module is in charge of working out the contents of expressions. 2315920Speter 2415920SpeterIt has to keep track of the relative/absness of a symbol etc. This is 2515920Speterdone by keeping all values in a struct (an etree_value_type) which 2615920Spetercontains a value, a section to which it is relative and a valid bit. 2715920Speter 2815920Speter*/ 2915920Speter 3015920Speter 3115920Speter#include "bfd.h" 3215920Speter#include "sysdep.h" 3315920Speter#include "bfdlink.h" 3415920Speter 3515920Speter#include "ld.h" 3615920Speter#include "ldmain.h" 3715920Speter#include "ldmisc.h" 3850471Speter#include "ldexp.h" 3915920Speter#include "ldgram.h" 4015920Speter#include "ldlang.h" 4115920Speter 4215920Speterstatic void exp_print_token PARAMS ((token_code_type code)); 4315920Speterstatic void make_abs PARAMS ((etree_value_type *ptr)); 4415920Speterstatic etree_value_type new_abs PARAMS ((bfd_vma value)); 4515920Speterstatic void check PARAMS ((lang_output_section_statement_type *os, 4615920Speter const char *name, const char *op)); 4715920Speterstatic etree_value_type new_rel 4815920Speter PARAMS ((bfd_vma value, lang_output_section_statement_type *section)); 4915920Speterstatic etree_value_type new_rel_from_section 5015920Speter PARAMS ((bfd_vma value, lang_output_section_statement_type *section)); 5115920Speterstatic etree_value_type fold_binary 5215920Speter PARAMS ((etree_type *tree, 5315920Speter lang_output_section_statement_type *current_section, 5415920Speter lang_phase_type allocation_done, 5515920Speter bfd_vma dot, bfd_vma *dotp)); 5615920Speterstatic etree_value_type fold_name 5715920Speter PARAMS ((etree_type *tree, 5815920Speter lang_output_section_statement_type *current_section, 5915920Speter lang_phase_type allocation_done, 6015920Speter bfd_vma dot)); 6115920Speterstatic etree_value_type exp_fold_tree_no_dot 6215920Speter PARAMS ((etree_type *tree, 6315920Speter lang_output_section_statement_type *current_section, 6415920Speter lang_phase_type allocation_done)); 6515920Speter 6615920Speterstatic void 6715920Speterexp_print_token (code) 6815920Speter token_code_type code; 6915920Speter{ 7015920Speter static CONST struct 7115920Speter { 7215920Speter token_code_type code; 7315920Speter char *name; 7415920Speter } table[] = 7515920Speter { 7618614Speter { INT, "int" }, 7715920Speter { REL, "relocateable" }, 7815920Speter { NAME,"NAME" }, 7915920Speter { PLUSEQ,"+=" }, 8015920Speter { MINUSEQ,"-=" }, 8115920Speter { MULTEQ,"*=" }, 8215920Speter { DIVEQ,"/=" }, 8315920Speter { LSHIFTEQ,"<<=" }, 8415920Speter { RSHIFTEQ,">>=" }, 8525235Ssteve { ANDEQ,"&=" }, 8615920Speter { OREQ,"|=" }, 8715920Speter { OROR,"||" }, 8815920Speter { ANDAND,"&&" }, 8915920Speter { EQ,"==" }, 9015920Speter { NE,"!=" }, 9115920Speter { LE,"<=" }, 9215920Speter { GE,">=" }, 93 { LSHIFT,"<<" }, 94 { RSHIFT,">>=" }, 95 { ALIGN_K,"ALIGN" }, 96 { BLOCK,"BLOCK" }, 97 { SECTIONS,"SECTIONS" }, 98 { SIZEOF_HEADERS,"SIZEOF_HEADERS" }, 99 { NEXT,"NEXT" }, 100 { SIZEOF,"SIZEOF" }, 101 { ADDR,"ADDR" }, 102 { LOADADDR,"LOADADDR" }, 103 { MEMORY,"MEMORY" }, 104 { DEFINED,"DEFINED" }, 105 { TARGET_K,"TARGET" }, 106 { SEARCH_DIR,"SEARCH_DIR" }, 107 { MAP,"MAP" }, 108 { QUAD,"QUAD" }, 109 { LONG,"LONG" }, 110 { SHORT,"SHORT" }, 111 { BYTE,"BYTE" }, 112 { ENTRY,"ENTRY" }, 113 { 0,(char *)NULL } 114 }; 115 unsigned int idx; 116 117 for (idx = 0; table[idx].name != (char*)NULL; idx++) { 118 if (table[idx].code == code) { 119 fprintf(config.map_file, "%s", table[idx].name); 120 return; 121 } 122 } 123 /* Not in table, just print it alone */ 124 fprintf(config.map_file, "%c",code); 125} 126 127static void 128make_abs (ptr) 129 etree_value_type *ptr; 130{ 131 asection *s = ptr->section->bfd_section; 132 ptr->value += s->vma; 133 ptr->section = abs_output_section; 134} 135 136static etree_value_type 137new_abs (value) 138 bfd_vma value; 139{ 140 etree_value_type new; 141 new.valid = true; 142 new.section = abs_output_section; 143 new.value = value; 144 return new; 145} 146 147static void 148check (os, name, op) 149 lang_output_section_statement_type *os; 150 const char *name; 151 const char *op; 152{ 153 if (os == NULL) 154 einfo ("%F%P: %s uses undefined section %s\n", op, name); 155 if (! os->processed) 156 einfo ("%F%P: %s forward reference of section %s\n", op, name); 157} 158 159etree_type * 160exp_intop (value) 161 bfd_vma value; 162{ 163 etree_type *new = (etree_type *) stat_alloc(sizeof(new->value)); 164 new->type.node_code = INT; 165 new->value.value = value; 166 new->type.node_class = etree_value; 167 return new; 168 169} 170 171/* Build an expression representing an unnamed relocateable value. */ 172 173etree_type * 174exp_relop (section, value) 175 asection *section; 176 bfd_vma value; 177{ 178 etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel)); 179 new->type.node_code = REL; 180 new->type.node_class = etree_rel; 181 new->rel.section = section; 182 new->rel.value = value; 183 return new; 184} 185 186static etree_value_type 187new_rel (value, section) 188 bfd_vma value; 189 lang_output_section_statement_type *section; 190{ 191 etree_value_type new; 192 new.valid = true; 193 new.value = value; 194 new.section = section; 195 return new; 196} 197 198static etree_value_type 199new_rel_from_section (value, section) 200 bfd_vma value; 201 lang_output_section_statement_type *section; 202{ 203 etree_value_type new; 204 new.valid = true; 205 new.value = value; 206 new.section = section; 207 208 new.value -= section->bfd_section->vma; 209 210 return new; 211} 212 213static etree_value_type 214fold_binary (tree, current_section, allocation_done, dot, dotp) 215 etree_type *tree; 216 lang_output_section_statement_type *current_section; 217 lang_phase_type allocation_done; 218 bfd_vma dot; 219 bfd_vma *dotp; 220{ 221 etree_value_type result; 222 223 result = exp_fold_tree (tree->binary.lhs, current_section, 224 allocation_done, dot, dotp); 225 if (result.valid) 226 { 227 etree_value_type other; 228 229 other = exp_fold_tree (tree->binary.rhs, 230 current_section, 231 allocation_done, dot,dotp) ; 232 if (other.valid) 233 { 234 /* If the values are from different sections, or this is an 235 absolute expression, make both the source arguments 236 absolute. However, adding or subtracting an absolute 237 value from a relative value is meaningful, and is an 238 exception. */ 239 if (current_section != abs_output_section 240 && (other.section == abs_output_section 241 || (result.section == abs_output_section 242 && tree->type.node_code == '+')) 243 && (tree->type.node_code == '+' 244 || tree->type.node_code == '-')) 245 { 246 etree_value_type hold; 247 248 /* If there is only one absolute term, make sure it is the 249 second one. */ 250 if (other.section != abs_output_section) 251 { 252 hold = result; 253 result = other; 254 other = hold; 255 } 256 } 257 else if (result.section != other.section 258 || current_section == abs_output_section) 259 { 260 make_abs(&result); 261 make_abs(&other); 262 } 263 264 switch (tree->type.node_code) 265 { 266 case '%': 267 if (other.value == 0) 268 einfo ("%F%S %% by zero\n"); 269 result.value = ((bfd_signed_vma) result.value 270 % (bfd_signed_vma) other.value); 271 break; 272 273 case '/': 274 if (other.value == 0) 275 einfo ("%F%S / by zero\n"); 276 result.value = ((bfd_signed_vma) result.value 277 / (bfd_signed_vma) other.value); 278 break; 279 280#define BOP(x,y) case x : result.value = result.value y other.value; break; 281 BOP('+',+); 282 BOP('*',*); 283 BOP('-',-); 284 BOP(LSHIFT,<<); 285 BOP(RSHIFT,>>); 286 BOP(EQ,==); 287 BOP(NE,!=); 288 BOP('<',<); 289 BOP('>',>); 290 BOP(LE,<=); 291 BOP(GE,>=); 292 BOP('&',&); 293 BOP('^',^); 294 BOP('|',|); 295 BOP(ANDAND,&&); 296 BOP(OROR,||); 297 298 case MAX: 299 if (result.value < other.value) 300 result = other; 301 break; 302 303 case MIN: 304 if (result.value > other.value) 305 result = other; 306 break; 307 308 default: 309 FAIL(); 310 } 311 } 312 else 313 { 314 result.valid = false; 315 } 316 } 317 318 return result; 319} 320 321etree_value_type 322invalid () 323{ 324 etree_value_type new; 325 new.valid = false; 326 return new; 327} 328 329static etree_value_type 330fold_name (tree, current_section, allocation_done, dot) 331 etree_type *tree; 332 lang_output_section_statement_type *current_section; 333 lang_phase_type allocation_done; 334 bfd_vma dot; 335{ 336 etree_value_type result; 337 switch (tree->type.node_code) 338 { 339 case SIZEOF_HEADERS: 340 if (allocation_done != lang_first_phase_enum) 341 { 342 result = new_abs ((bfd_vma) 343 bfd_sizeof_headers (output_bfd, 344 link_info.relocateable)); 345 } 346 else 347 { 348 result.valid = false; 349 } 350 break; 351 case DEFINED: 352 if (allocation_done == lang_first_phase_enum) 353 result.valid = false; 354 else 355 { 356 struct bfd_link_hash_entry *h; 357 358 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, 359 tree->name.name, 360 false, false, true); 361 result.value = (h != (struct bfd_link_hash_entry *) NULL 362 && (h->type == bfd_link_hash_defined 363 || h->type == bfd_link_hash_defweak 364 || h->type == bfd_link_hash_common)); 365 result.section = 0; 366 result.valid = true; 367 } 368 break; 369 case NAME: 370 result.valid = false; 371 if (tree->name.name[0] == '.' && tree->name.name[1] == 0) 372 { 373 if (allocation_done != lang_first_phase_enum) 374 result = new_rel_from_section(dot, current_section); 375 else 376 result = invalid(); 377 } 378 else if (allocation_done != lang_first_phase_enum) 379 { 380 struct bfd_link_hash_entry *h; 381 382 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, 383 tree->name.name, 384 false, false, true); 385 if (h != NULL 386 && (h->type == bfd_link_hash_defined 387 || h->type == bfd_link_hash_defweak)) 388 { 389 if (bfd_is_abs_section (h->u.def.section)) 390 result = new_abs (h->u.def.value); 391 else if (allocation_done == lang_final_phase_enum 392 || allocation_done == lang_allocating_phase_enum) 393 { 394 lang_output_section_statement_type *os; 395 396 os = (lang_output_section_statement_lookup 397 (h->u.def.section->output_section->name)); 398 399 /* FIXME: Is this correct if this section is being 400 linked with -R? */ 401 result = new_rel ((h->u.def.value 402 + h->u.def.section->output_offset), 403 os); 404 } 405 } 406 else if (allocation_done == lang_final_phase_enum) 407 einfo ("%F%S: undefined symbol `%s' referenced in expression\n", 408 tree->name.name); 409 } 410 break; 411 412 case ADDR: 413 if (allocation_done != lang_first_phase_enum) 414 { 415 lang_output_section_statement_type *os; 416 417 os = lang_output_section_find (tree->name.name); 418 check (os, tree->name.name, "ADDR"); 419 result = new_rel (0, os); 420 } 421 else 422 result = invalid (); 423 break; 424 425 case LOADADDR: 426 if (allocation_done != lang_first_phase_enum) 427 { 428 lang_output_section_statement_type *os; 429 430 os = lang_output_section_find (tree->name.name); 431 check (os, tree->name.name, "LOADADDR"); 432 if (os->load_base == NULL) 433 result = new_rel (0, os); 434 else 435 result = exp_fold_tree_no_dot (os->load_base, 436 abs_output_section, 437 allocation_done); 438 } 439 else 440 result = invalid (); 441 break; 442 443 case SIZEOF: 444 if (allocation_done != lang_first_phase_enum) 445 { 446 lang_output_section_statement_type *os; 447 448 os = lang_output_section_find (tree->name.name); 449 check (os, tree->name.name, "SIZEOF"); 450 result = new_abs (os->bfd_section->_raw_size); 451 } 452 else 453 result = invalid (); 454 break; 455 456 default: 457 FAIL(); 458 break; 459 } 460 461 return result; 462} 463etree_value_type 464exp_fold_tree (tree, current_section, allocation_done, dot, dotp) 465 etree_type *tree; 466 lang_output_section_statement_type *current_section; 467 lang_phase_type allocation_done; 468 bfd_vma dot; 469 bfd_vma *dotp; 470{ 471 etree_value_type result; 472 473 if (tree == NULL) 474 { 475 result.valid = false; 476 return result; 477 } 478 479 switch (tree->type.node_class) 480 { 481 case etree_value: 482 result = new_rel (tree->value.value, current_section); 483 break; 484 485 case etree_rel: 486 if (allocation_done != lang_final_phase_enum) 487 result.valid = false; 488 else 489 result = new_rel ((tree->rel.value 490 + tree->rel.section->output_section->vma 491 + tree->rel.section->output_offset), 492 current_section); 493 break; 494 495 case etree_unary: 496 result = exp_fold_tree (tree->unary.child, 497 current_section, 498 allocation_done, dot, dotp); 499 if (result.valid) 500 { 501 switch (tree->type.node_code) 502 { 503 case ALIGN_K: 504 if (allocation_done != lang_first_phase_enum) 505 result = new_rel_from_section (ALIGN_N (dot, result.value), 506 current_section); 507 else 508 result.valid = false; 509 break; 510 511 case ABSOLUTE: 512 if (allocation_done != lang_first_phase_enum && result.valid) 513 { 514 result.value += result.section->bfd_section->vma; 515 result.section = abs_output_section; 516 } 517 else 518 result.valid = false; 519 break; 520 521 case '~': 522 make_abs (&result); 523 result.value = ~result.value; 524 break; 525 526 case '!': 527 make_abs (&result); 528 result.value = !result.value; 529 break; 530 531 case '-': 532 make_abs (&result); 533 result.value = -result.value; 534 break; 535 536 case NEXT: 537 /* Return next place aligned to value. */ 538 if (allocation_done == lang_allocating_phase_enum) 539 { 540 make_abs (&result); 541 result.value = ALIGN_N (dot, result.value); 542 } 543 else 544 result.valid = false; 545 break; 546 547 default: 548 FAIL (); 549 break; 550 } 551 } 552 break; 553 554 case etree_trinary: 555 result = exp_fold_tree (tree->trinary.cond, current_section, 556 allocation_done, dot, dotp); 557 if (result.valid) 558 result = exp_fold_tree ((result.value 559 ? tree->trinary.lhs 560 : tree->trinary.rhs), 561 current_section, 562 allocation_done, dot, dotp); 563 break; 564 565 case etree_binary: 566 result = fold_binary (tree, current_section, allocation_done, 567 dot, dotp); 568 break; 569 570 case etree_assign: 571 case etree_provide: 572 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) 573 { 574 /* Assignment to dot can only be done during allocation */ 575 if (tree->type.node_class == etree_provide) 576 einfo ("%F%S can not PROVIDE assignment to location counter\n"); 577 if (allocation_done == lang_allocating_phase_enum 578 || (allocation_done == lang_final_phase_enum 579 && current_section == abs_output_section)) 580 { 581 result = exp_fold_tree (tree->assign.src, 582 current_section, 583 lang_allocating_phase_enum, dot, 584 dotp); 585 if (! result.valid) 586 einfo ("%F%S invalid assignment to location counter\n"); 587 else 588 { 589 if (current_section == NULL) 590 einfo ("%F%S assignment to location counter invalid outside of SECTION\n"); 591 else 592 { 593 bfd_vma nextdot; 594 595 nextdot = (result.value 596 + current_section->bfd_section->vma); 597 if (nextdot < dot 598 && current_section != abs_output_section) 599 { 600 einfo ("%F%S cannot move location counter backwards (from %V to %V)\n", 601 dot, nextdot); 602 } 603 else 604 *dotp = nextdot; 605 } 606 } 607 } 608 } 609 else 610 { 611 result = exp_fold_tree (tree->assign.src, 612 current_section, allocation_done, 613 dot, dotp); 614 if (result.valid) 615 { 616 boolean create; 617 struct bfd_link_hash_entry *h; 618 619 if (tree->type.node_class == etree_assign) 620 create = true; 621 else 622 create = false; 623 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, 624 create, false, false); 625 if (h == (struct bfd_link_hash_entry *) NULL) 626 { 627 if (tree->type.node_class == etree_assign) 628 einfo ("%P%F:%s: hash creation failed\n", 629 tree->assign.dst); 630 } 631 else if (tree->type.node_class == etree_provide 632 && h->type != bfd_link_hash_undefined 633 && h->type != bfd_link_hash_common) 634 { 635 /* Do nothing. The symbol was defined by some 636 object. */ 637 } 638 else 639 { 640 /* FIXME: Should we worry if the symbol is already 641 defined? */ 642 h->type = bfd_link_hash_defined; 643 h->u.def.value = result.value; 644 h->u.def.section = result.section->bfd_section; 645 } 646 } 647 } 648 break; 649 650 case etree_name: 651 result = fold_name (tree, current_section, allocation_done, dot); 652 break; 653 654 default: 655 FAIL (); 656 break; 657 } 658 659 return result; 660} 661 662static etree_value_type 663exp_fold_tree_no_dot (tree, current_section, allocation_done) 664 etree_type *tree; 665 lang_output_section_statement_type *current_section; 666 lang_phase_type allocation_done; 667{ 668return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma) 669 0, (bfd_vma *)NULL); 670} 671 672etree_type * 673exp_binop (code, lhs, rhs) 674 int code; 675 etree_type *lhs; 676 etree_type *rhs; 677{ 678 etree_type value, *new; 679 etree_value_type r; 680 681 value.type.node_code = code; 682 value.binary.lhs = lhs; 683 value.binary.rhs = rhs; 684 value.type.node_class = etree_binary; 685 r = exp_fold_tree_no_dot(&value, 686 abs_output_section, 687 lang_first_phase_enum ); 688 if (r.valid) 689 { 690 return exp_intop(r.value); 691 } 692 new = (etree_type *) stat_alloc (sizeof (new->binary)); 693 memcpy((char *)new, (char *)&value, sizeof(new->binary)); 694 return new; 695} 696 697etree_type * 698exp_trinop (code, cond, lhs, rhs) 699 int code; 700 etree_type *cond; 701 etree_type *lhs; 702 etree_type *rhs; 703{ 704 etree_type value, *new; 705 etree_value_type r; 706 value.type.node_code = code; 707 value.trinary.lhs = lhs; 708 value.trinary.cond = cond; 709 value.trinary.rhs = rhs; 710 value.type.node_class = etree_trinary; 711 r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type 712 *)NULL,lang_first_phase_enum); 713 if (r.valid) { 714 return exp_intop(r.value); 715 } 716 new = (etree_type *) stat_alloc (sizeof (new->trinary)); 717 memcpy((char *)new,(char *) &value, sizeof(new->trinary)); 718 return new; 719} 720 721 722etree_type * 723exp_unop (code, child) 724 int code; 725 etree_type *child; 726{ 727 etree_type value, *new; 728 729 etree_value_type r; 730 value.unary.type.node_code = code; 731 value.unary.child = child; 732 value.unary.type.node_class = etree_unary; 733 r = exp_fold_tree_no_dot(&value,abs_output_section, 734 lang_first_phase_enum); 735 if (r.valid) { 736 return exp_intop(r.value); 737 } 738 new = (etree_type *) stat_alloc (sizeof (new->unary)); 739 memcpy((char *)new, (char *)&value, sizeof(new->unary)); 740 return new; 741} 742 743 744etree_type * 745exp_nameop (code, name) 746 int code; 747 CONST char *name; 748{ 749 etree_type value, *new; 750 etree_value_type r; 751 value.name.type.node_code = code; 752 value.name.name = name; 753 value.name.type.node_class = etree_name; 754 755 756 r = exp_fold_tree_no_dot(&value, 757 (lang_output_section_statement_type *)NULL, 758 lang_first_phase_enum); 759 if (r.valid) { 760 return exp_intop(r.value); 761 } 762 new = (etree_type *) stat_alloc (sizeof (new->name)); 763 memcpy((char *)new, (char *)&value, sizeof(new->name)); 764 return new; 765 766} 767 768 769 770 771etree_type * 772exp_assop (code, dst, src) 773 int code; 774 CONST char *dst; 775 etree_type *src; 776{ 777 etree_type value, *new; 778 779 value.assign.type.node_code = code; 780 781 782 value.assign.src = src; 783 value.assign.dst = dst; 784 value.assign.type.node_class = etree_assign; 785 786#if 0 787 if (exp_fold_tree_no_dot(&value, &result)) { 788 return exp_intop(result); 789 } 790#endif 791 new = (etree_type*) stat_alloc (sizeof (new->assign)); 792 memcpy((char *)new, (char *)&value, sizeof(new->assign)); 793 return new; 794} 795 796/* Handle PROVIDE. */ 797 798etree_type * 799exp_provide (dst, src) 800 const char *dst; 801 etree_type *src; 802{ 803 etree_type *n; 804 805 n = (etree_type *) stat_alloc (sizeof (n->assign)); 806 n->assign.type.node_code = '='; 807 n->assign.type.node_class = etree_provide; 808 n->assign.src = src; 809 n->assign.dst = dst; 810 return n; 811} 812 813void 814exp_print_tree (tree) 815 etree_type *tree; 816{ 817 switch (tree->type.node_class) { 818 case etree_value: 819 minfo ("0x%v", tree->value.value); 820 return; 821 case etree_rel: 822 if (tree->rel.section->owner != NULL) 823 minfo ("%B:", tree->rel.section->owner); 824 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value); 825 return; 826 case etree_assign: 827#if 0 828 if (tree->assign.dst->sdefs != (asymbol *)NULL){ 829 fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name, 830 tree->assign.dst->sdefs->value); 831 } 832 else { 833 fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name); 834 } 835#endif 836 fprintf(config.map_file,"%s",tree->assign.dst); 837 exp_print_token(tree->type.node_code); 838 exp_print_tree(tree->assign.src); 839 break; 840 case etree_provide: 841 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst); 842 exp_print_tree (tree->assign.src); 843 fprintf (config.map_file, ")"); 844 break; 845 case etree_binary: 846 fprintf(config.map_file,"("); 847 exp_print_tree(tree->binary.lhs); 848 exp_print_token(tree->type.node_code); 849 exp_print_tree(tree->binary.rhs); 850 fprintf(config.map_file,")"); 851 break; 852 case etree_trinary: 853 exp_print_tree(tree->trinary.cond); 854 fprintf(config.map_file,"?"); 855 exp_print_tree(tree->trinary.lhs); 856 fprintf(config.map_file,":"); 857 exp_print_tree(tree->trinary.rhs); 858 break; 859 case etree_unary: 860 exp_print_token(tree->unary.type.node_code); 861 if (tree->unary.child) 862 { 863 864 fprintf(config.map_file,"("); 865 exp_print_tree(tree->unary.child); 866 fprintf(config.map_file,")"); 867 } 868 869 break; 870 case etree_undef: 871 fprintf(config.map_file,"????????"); 872 break; 873 case etree_name: 874 if (tree->type.node_code == NAME) { 875 fprintf(config.map_file,"%s", tree->name.name); 876 } 877 else { 878 exp_print_token(tree->type.node_code); 879 if (tree->name.name) 880 fprintf(config.map_file,"(%s)", tree->name.name); 881 } 882 break; 883 default: 884 FAIL(); 885 break; 886 } 887} 888 889bfd_vma 890exp_get_vma (tree, def, name, allocation_done) 891 etree_type *tree; 892 bfd_vma def; 893 char *name; 894 lang_phase_type allocation_done; 895{ 896 etree_value_type r; 897 898 if (tree != NULL) 899 { 900 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); 901 if (! r.valid && name != NULL) 902 einfo ("%F%S nonconstant expression for %s\n", name); 903 return r.value; 904 } 905 else 906 return def; 907} 908 909int 910exp_get_value_int (tree,def,name, allocation_done) 911 etree_type *tree; 912 int def; 913 char *name; 914 lang_phase_type allocation_done; 915{ 916 return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done); 917} 918 919 920bfd_vma 921exp_get_abs_int (tree, def, name, allocation_done) 922 etree_type *tree; 923 int def; 924 char *name; 925 lang_phase_type allocation_done; 926{ 927 etree_value_type res; 928 res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); 929 930 if (res.valid) 931 { 932 res.value += res.section->bfd_section->vma; 933 } 934 else { 935 einfo ("%F%S non constant expression for %s\n",name); 936 } 937 return res.value; 938} 939