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