Changeset 609 for branches/GNU/src/binutils/ld/ldexp.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/ld/ldexp.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* This module handles expression trees. 2 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3 2001 3 2001, 2002 4 4 Free Software Foundation, Inc. 5 5 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. … … 37 37 #include "ldmisc.h" 38 38 #include "ldexp.h" 39 #include "ldgram.h"39 #include <ldgram.h> 40 40 #include "ldlang.h" 41 42 static void exp_print_token PARAMS ((token_code_type code)); 43 static void make_abs PARAMS ((etree_value_type *ptr)); 44 static etree_value_type new_abs PARAMS ((bfd_vma value)); 45 static void check PARAMS ((lang_output_section_statement_type *os, 46 const char *name, const char *op)); 41 #include "libiberty.h" 42 #include "safe-ctype.h" 43 44 static void exp_print_token 45 PARAMS ((token_code_type code, int infix_p)); 46 static void make_abs 47 PARAMS ((etree_value_type *ptr)); 48 static etree_value_type new_abs 49 PARAMS ((bfd_vma value)); 50 static void check 51 PARAMS ((lang_output_section_statement_type *os, const char *name, 52 const char *op)); 47 53 static etree_value_type new_rel 48 PARAMS ((bfd_vma value, lang_output_section_statement_type *section));54 PARAMS ((bfd_vma, char *, lang_output_section_statement_type *section)); 49 55 static etree_value_type new_rel_from_section 50 56 PARAMS ((bfd_vma value, lang_output_section_statement_type *section)); 57 static etree_value_type fold_unary 58 PARAMS ((etree_type *tree, 59 lang_output_section_statement_type *current_section, 60 lang_phase_type allocation_done, 61 bfd_vma dot, bfd_vma *dotp)); 51 62 static etree_value_type fold_binary 63 PARAMS ((etree_type *tree, 64 lang_output_section_statement_type *current_section, 65 lang_phase_type allocation_done, 66 bfd_vma dot, bfd_vma *dotp)); 67 static etree_value_type fold_trinary 52 68 PARAMS ((etree_type *tree, 53 69 lang_output_section_statement_type *current_section, … … 64 80 lang_phase_type allocation_done)); 65 81 82 struct exp_data_seg exp_data_seg; 83 84 /* Print the string representation of the given token. Surround it 85 with spaces if INFIX_P is TRUE. */ 86 66 87 static void 67 exp_print_token (code )88 exp_print_token (code, infix_p) 68 89 token_code_type code; 69 { 70 static CONST struct { 90 int infix_p; 91 { 92 static const struct 93 { 71 94 token_code_type code; 72 char *name; 73 } table[] = { 95 char * name; 96 } 97 table[] = 98 { 74 99 { INT, "int" }, 75 { REL, "relocateable" },76 100 { NAME, "NAME" }, 77 101 { PLUSEQ, "+=" }, … … 90 114 { GE, ">=" }, 91 115 { LSHIFT, "<<" }, 92 { RSHIFT, ">> =" },116 { RSHIFT, ">>" }, 93 117 { ALIGN_K, "ALIGN" }, 94 118 { BLOCK, "BLOCK" }, 119 { QUAD, "QUAD" }, 120 { SQUAD, "SQUAD" }, 121 { LONG, "LONG" }, 122 { SHORT, "SHORT" }, 123 { BYTE, "BYTE" }, 95 124 { SECTIONS, "SECTIONS" }, 96 125 { SIZEOF_HEADERS, "SIZEOF_HEADERS" }, 97 { NEXT, "NEXT" },98 { SIZEOF, "SIZEOF" },99 { ADDR, "ADDR" },100 { LOADADDR, "LOADADDR" },101 126 { MEMORY, "MEMORY" }, 102 127 { DEFINED, "DEFINED" }, … … 104 129 { SEARCH_DIR, "SEARCH_DIR" }, 105 130 { MAP, "MAP" }, 106 { QUAD, "QUAD" },107 { SQUAD, "SQUAD" },108 { LONG, "LONG" },109 { SHORT, "SHORT" },110 { BYTE, "BYTE" },111 131 { ENTRY, "ENTRY" }, 112 { 0, (char *) NULL } 132 { NEXT, "NEXT" }, 133 { SIZEOF, "SIZEOF" }, 134 { ADDR, "ADDR" }, 135 { LOADADDR, "LOADADDR" }, 136 { MAX_K, "MAX_K" }, 137 { REL, "relocateable" }, 138 { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" }, 139 { DATA_SEGMENT_END, "DATA_SEGMENT_END" } 113 140 }; 114 141 unsigned int idx; 115 142 116 for (idx = 0; table[idx].name != (char *) NULL; idx++) 117 { 118 if (table[idx].code == code) 119 { 120 fprintf (config.map_file, "%s", table[idx].name); 121 return; 122 } 123 } 124 /* Not in table, just print it alone */ 125 fprintf (config.map_file, "%c", code); 143 for (idx = 0; idx < ARRAY_SIZE (table); idx++) 144 if (table[idx].code == code) 145 break; 146 147 if (infix_p) 148 fputc (' ', config.map_file); 149 150 if (idx < ARRAY_SIZE (table)) 151 fputs (table[idx].name, config.map_file); 152 else if (code < 127) 153 fputc (code, config.map_file); 154 else 155 fprintf (config.map_file, "<code %d>", code); 156 157 if (infix_p) 158 fputc (' ', config.map_file); 126 159 } 127 160 … … 140 173 { 141 174 etree_value_type new; 142 new.valid_p = true;175 new.valid_p = TRUE; 143 176 new.section = abs_output_section; 144 177 new.value = value; … … 165 198 new->type.node_code = INT; 166 199 new->value.value = value; 200 new->value.str = NULL; 167 201 new->type.node_class = etree_value; 168 202 return new; 169 203 } 204 205 etree_type * 206 exp_bigintop (value, str) 207 bfd_vma value; 208 char *str; 209 { 210 etree_type *new = (etree_type *) stat_alloc (sizeof (new->value)); 211 new->type.node_code = INT; 212 new->value.value = value; 213 new->value.str = str; 214 new->type.node_class = etree_value; 215 return new; 170 216 } 171 217 … … 186 232 187 233 static etree_value_type 188 new_rel (value, s ection)234 new_rel (value, str, section) 189 235 bfd_vma value; 236 char *str; 190 237 lang_output_section_statement_type *section; 191 238 { 192 239 etree_value_type new; 193 new.valid_p = true;240 new.valid_p = TRUE; 194 241 new.value = value; 242 new.str = str; 195 243 new.section = section; 196 244 return new; … … 203 251 { 204 252 etree_value_type new; 205 new.valid_p = true;253 new.valid_p = TRUE; 206 254 new.value = value; 255 new.str = NULL; 207 256 new.section = section; 208 257 … … 210 259 211 260 return new; 261 } 262 263 static etree_value_type 264 fold_unary (tree, current_section, allocation_done, dot, dotp) 265 etree_type *tree; 266 lang_output_section_statement_type *current_section; 267 lang_phase_type allocation_done; 268 bfd_vma dot; 269 bfd_vma *dotp; 270 { 271 etree_value_type result; 272 273 result = exp_fold_tree (tree->unary.child, 274 current_section, 275 allocation_done, dot, dotp); 276 if (result.valid_p) 277 { 278 switch (tree->type.node_code) 279 { 280 case ALIGN_K: 281 if (allocation_done != lang_first_phase_enum) 282 result = new_rel_from_section (align_n (dot, result.value), 283 current_section); 284 else 285 result.valid_p = FALSE; 286 break; 287 288 case ABSOLUTE: 289 if (allocation_done != lang_first_phase_enum) 290 { 291 result.value += result.section->bfd_section->vma; 292 result.section = abs_output_section; 293 } 294 else 295 result.valid_p = FALSE; 296 break; 297 298 case '~': 299 make_abs (&result); 300 result.value = ~result.value; 301 break; 302 303 case '!': 304 make_abs (&result); 305 result.value = !result.value; 306 break; 307 308 case '-': 309 make_abs (&result); 310 result.value = -result.value; 311 break; 312 313 case NEXT: 314 /* Return next place aligned to value. */ 315 if (allocation_done == lang_allocating_phase_enum) 316 { 317 make_abs (&result); 318 result.value = align_n (dot, result.value); 319 } 320 else 321 result.valid_p = FALSE; 322 break; 323 324 case DATA_SEGMENT_END: 325 if (allocation_done != lang_first_phase_enum 326 && current_section == abs_output_section 327 && (exp_data_seg.phase == exp_dataseg_align_seen 328 || exp_data_seg.phase == exp_dataseg_adjust 329 || allocation_done != lang_allocating_phase_enum)) 330 { 331 if (exp_data_seg.phase == exp_dataseg_align_seen) 332 { 333 exp_data_seg.phase = exp_dataseg_end_seen; 334 exp_data_seg.end = result.value; 335 } 336 } 337 else 338 result.valid_p = FALSE; 339 break; 340 341 default: 342 FAIL (); 343 break; 344 } 345 } 346 347 return result; 212 348 } 213 349 … … 245 381 || tree->type.node_code == '-')) 246 382 { 247 etree_value_type hold;248 249 /* If there is only one absolute term, make sure it is the250 second one. */251 383 if (other.section != abs_output_section) 252 384 { 253 hold = result; 254 result = other; 255 other = hold; 385 /* Keep the section of the other term. */ 386 if (tree->type.node_code == '+') 387 other.value = result.value + other.value; 388 else 389 other.value = result.value - other.value; 390 return other; 256 391 } 257 392 } … … 307 442 break; 308 443 444 case DATA_SEGMENT_ALIGN: 445 if (allocation_done != lang_first_phase_enum 446 && current_section == abs_output_section 447 && (exp_data_seg.phase == exp_dataseg_none 448 || exp_data_seg.phase == exp_dataseg_adjust 449 || allocation_done != lang_allocating_phase_enum)) 450 { 451 bfd_vma maxpage = result.value; 452 453 result.value = align_n (dot, maxpage); 454 if (exp_data_seg.phase != exp_dataseg_adjust) 455 { 456 result.value += dot & (maxpage - 1); 457 if (allocation_done == lang_allocating_phase_enum) 458 { 459 exp_data_seg.phase = exp_dataseg_align_seen; 460 exp_data_seg.base = result.value; 461 exp_data_seg.pagesize = other.value; 462 } 463 } 464 else if (other.value < maxpage) 465 result.value += (dot + other.value - 1) 466 & (maxpage - other.value); 467 } 468 else 469 result.valid_p = FALSE; 470 break; 471 309 472 default: 310 473 FAIL (); … … 313 476 else 314 477 { 315 result.valid_p = false;478 result.valid_p = FALSE; 316 479 } 317 480 } 481 482 return result; 483 } 484 485 static etree_value_type 486 fold_trinary (tree, current_section, allocation_done, dot, dotp) 487 etree_type *tree; 488 lang_output_section_statement_type *current_section; 489 lang_phase_type allocation_done; 490 bfd_vma dot; 491 bfd_vma *dotp; 492 { 493 etree_value_type result; 494 495 result = exp_fold_tree (tree->trinary.cond, current_section, 496 allocation_done, dot, dotp); 497 if (result.valid_p) 498 result = exp_fold_tree ((result.value 499 ? tree->trinary.lhs 500 : tree->trinary.rhs), 501 current_section, 502 allocation_done, dot, dotp); 318 503 319 504 return result; … … 324 509 { 325 510 etree_value_type new; 326 new.valid_p = false;511 new.valid_p = FALSE; 327 512 return new; 328 513 } … … 336 521 { 337 522 etree_value_type result; 523 338 524 switch (tree->type.node_code) 339 525 { … … 347 533 else 348 534 { 349 result.valid_p = false;535 result.valid_p = FALSE; 350 536 } 351 537 break; 352 538 case DEFINED: 353 539 if (allocation_done == lang_first_phase_enum) 354 result.valid_p = false;540 result.valid_p = FALSE; 355 541 else 356 542 { … … 359 545 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, 360 546 tree->name.name, 361 false, false, true);547 FALSE, FALSE, TRUE); 362 548 result.value = (h != (struct bfd_link_hash_entry *) NULL 363 549 && (h->type == bfd_link_hash_defined … … 365 551 || h->type == bfd_link_hash_common)); 366 552 result.section = 0; 367 result.valid_p = true;553 result.valid_p = TRUE; 368 554 } 369 555 break; 370 556 case NAME: 371 result.valid_p = false;557 result.valid_p = FALSE; 372 558 if (tree->name.name[0] == '.' && tree->name.name[1] == 0) 373 559 { … … 383 569 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, 384 570 tree->name.name, 385 false, false, true);571 FALSE, FALSE, TRUE); 386 572 if (h != NULL 387 573 && (h->type == bfd_link_hash_defined … … 411 597 result = new_rel ((h->u.def.value 412 598 + h->u.def.section->output_offset), 599 NULL, 413 600 os); 414 601 } … … 428 615 os = lang_output_section_find (tree->name.name); 429 616 check (os, tree->name.name, "ADDR"); 430 result = new_rel (0, os);617 result = new_rel (0, NULL, os); 431 618 } 432 619 else … … 442 629 check (os, tree->name.name, "LOADADDR"); 443 630 if (os->load_base == NULL) 444 result = new_rel (0, os);631 result = new_rel (0, NULL, os); 445 632 else 446 633 result = exp_fold_tree_no_dot (os->load_base, … … 486 673 if (tree == NULL) 487 674 { 488 result.valid_p = false;675 result.valid_p = FALSE; 489 676 return result; 490 677 } … … 493 680 { 494 681 case etree_value: 495 result = new_rel (tree->value.value, current_section);682 result = new_rel (tree->value.value, tree->value.str, current_section); 496 683 break; 497 684 498 685 case etree_rel: 499 686 if (allocation_done != lang_final_phase_enum) 500 result.valid_p = false;687 result.valid_p = FALSE; 501 688 else 502 689 result = new_rel ((tree->rel.value 503 690 + tree->rel.section->output_section->vma 504 691 + tree->rel.section->output_offset), 692 NULL, 505 693 current_section); 506 694 break; … … 519 707 520 708 case etree_unary: 521 result = exp_fold_tree (tree->unary.child, 522 current_section, 523 allocation_done, dot, dotp); 524 if (result.valid_p) 525 { 526 switch (tree->type.node_code) 527 { 528 case ALIGN_K: 529 if (allocation_done != lang_first_phase_enum) 530 result = new_rel_from_section (ALIGN_N (dot, result.value), 531 current_section); 532 else 533 result.valid_p = false; 534 break; 535 536 case ABSOLUTE: 537 if (allocation_done != lang_first_phase_enum && result.valid_p) 538 { 539 result.value += result.section->bfd_section->vma; 540 result.section = abs_output_section; 541 } 542 else 543 result.valid_p = false; 544 break; 545 546 case '~': 547 make_abs (&result); 548 result.value = ~result.value; 549 break; 550 551 case '!': 552 make_abs (&result); 553 result.value = !result.value; 554 break; 555 556 case '-': 557 make_abs (&result); 558 result.value = -result.value; 559 break; 560 561 case NEXT: 562 /* Return next place aligned to value. */ 563 if (allocation_done == lang_allocating_phase_enum) 564 { 565 make_abs (&result); 566 result.value = ALIGN_N (dot, result.value); 567 } 568 else 569 result.valid_p = false; 570 break; 571 572 default: 573 FAIL (); 574 break; 575 } 576 } 577 break; 578 579 case etree_trinary: 580 result = exp_fold_tree (tree->trinary.cond, current_section, 581 allocation_done, dot, dotp); 582 if (result.valid_p) 583 result = exp_fold_tree ((result.value 584 ? tree->trinary.lhs 585 : tree->trinary.rhs), 586 current_section, 587 allocation_done, dot, dotp); 709 result = fold_unary (tree, current_section, allocation_done, 710 dot, dotp); 588 711 break; 589 712 … … 591 714 result = fold_binary (tree, current_section, allocation_done, 592 715 dot, dotp); 716 break; 717 718 case etree_trinary: 719 result = fold_trinary (tree, current_section, allocation_done, 720 dot, dotp); 593 721 break; 594 722 … … 598 726 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) 599 727 { 600 /* Assignment to dot can only be done during allocation */728 /* Assignment to dot can only be done during allocation. */ 601 729 if (tree->type.node_class != etree_assign) 602 730 einfo (_("%F%S can not PROVIDE assignment to location counter\n")); … … 607 735 result = exp_fold_tree (tree->assign.src, 608 736 current_section, 609 lang_allocating_phase_enum, dot,737 allocation_done, dot, 610 738 dotp); 611 739 if (! result.valid_p) … … 623 751 if (nextdot < dot 624 752 && current_section != abs_output_section) 625 { 626 einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"), 627 dot, nextdot); 628 } 753 einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"), 754 dot, nextdot); 629 755 else 630 756 *dotp = nextdot; … … 640 766 if (result.valid_p) 641 767 { 642 b oolean create;768 bfd_boolean create; 643 769 struct bfd_link_hash_entry *h; 644 770 645 771 if (tree->type.node_class == etree_assign) 646 create = true;772 create = TRUE; 647 773 else 648 create = false;774 create = FALSE; 649 775 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, 650 create, false, false);776 create, FALSE, FALSE); 651 777 if (h == (struct bfd_link_hash_entry *) NULL) 652 778 { … … 741 867 lang_first_phase_enum); 742 868 if (r.valid_p) 743 { 744 return exp_intop (r.value); 745 } 869 return exp_intop (r.value); 870 746 871 new = (etree_type *) stat_alloc (sizeof (new->trinary)); 747 872 memcpy ((char *) new, (char *) &value, sizeof (new->trinary)); … … 763 888 lang_first_phase_enum); 764 889 if (r.valid_p) 765 { 766 return exp_intop (r.value); 767 } 890 return exp_intop (r.value); 891 768 892 new = (etree_type *) stat_alloc (sizeof (new->unary)); 769 893 memcpy ((char *) new, (char *) &value, sizeof (new->unary)); … … 774 898 exp_nameop (code, name) 775 899 int code; 776 CONSTchar *name;900 const char *name; 777 901 { 778 902 etree_type value, *new; … … 786 910 lang_first_phase_enum); 787 911 if (r.valid_p) 788 { 789 return exp_intop (r.value); 790 } 912 return exp_intop (r.value); 913 791 914 new = (etree_type *) stat_alloc (sizeof (new->name)); 792 915 memcpy ((char *) new, (char *) &value, sizeof (new->name)); … … 798 921 exp_assop (code, dst, src) 799 922 int code; 800 CONSTchar *dst;923 const char *dst; 801 924 etree_type *src; 802 925 { … … 811 934 #if 0 812 935 if (exp_fold_tree_no_dot (&value, &result)) 813 { 814 return exp_intop (result); 815 } 936 return exp_intop (result); 816 937 #endif 817 938 new = (etree_type *) stat_alloc (sizeof (new->assign)); … … 858 979 etree_type *tree; 859 980 { 981 if (config.map_file == NULL) 982 config.map_file = stderr; 983 984 if (tree == NULL) 985 { 986 minfo ("NULL TREE\n"); 987 return; 988 } 989 860 990 switch (tree->type.node_class) 861 991 { … … 871 1001 #if 0 872 1002 if (tree->assign.dst->sdefs != (asymbol *) NULL) 873 { 874 fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name, 875 tree->assign.dst->sdefs->value); 876 } 1003 fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name, 1004 tree->assign.dst->sdefs->value); 877 1005 else 878 { 879 fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name); 880 } 1006 fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name); 881 1007 #endif 882 1008 fprintf (config.map_file, "%s", tree->assign.dst); 883 exp_print_token (tree->type.node_code );1009 exp_print_token (tree->type.node_code, TRUE); 884 1010 exp_print_tree (tree->assign.src); 885 1011 break; … … 893 1019 fprintf (config.map_file, "("); 894 1020 exp_print_tree (tree->binary.lhs); 895 exp_print_token (tree->type.node_code );1021 exp_print_token (tree->type.node_code, TRUE); 896 1022 exp_print_tree (tree->binary.rhs); 897 1023 fprintf (config.map_file, ")"); … … 905 1031 break; 906 1032 case etree_unary: 907 exp_print_token (tree->unary.type.node_code );1033 exp_print_token (tree->unary.type.node_code, FALSE); 908 1034 if (tree->unary.child) 909 1035 { 910 fprintf (config.map_file, " (");1036 fprintf (config.map_file, " ("); 911 1037 exp_print_tree (tree->unary.child); 912 1038 fprintf (config.map_file, ")"); … … 930 1056 else 931 1057 { 932 exp_print_token (tree->type.node_code );1058 exp_print_token (tree->type.node_code, FALSE); 933 1059 if (tree->name.name) 934 fprintf (config.map_file, " (%s)", tree->name.name);1060 fprintf (config.map_file, " (%s)", tree->name.name); 935 1061 } 936 1062 break; … … 971 1097 } 972 1098 1099 fill_type * 1100 exp_get_fill (tree, def, name, allocation_done) 1101 etree_type *tree; 1102 fill_type *def; 1103 char *name; 1104 lang_phase_type allocation_done; 1105 { 1106 fill_type *fill; 1107 etree_value_type r; 1108 size_t len; 1109 unsigned int val; 1110 1111 if (tree == NULL) 1112 return def; 1113 1114 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); 1115 if (! r.valid_p && name != NULL) 1116 einfo (_("%F%S nonconstant expression for %s\n"), name); 1117 1118 if (r.str != NULL && (len = strlen (r.str)) != 0) 1119 { 1120 unsigned char *dst; 1121 unsigned char *s; 1122 fill = (fill_type *) xmalloc ((len + 1) / 2 + sizeof (*fill) - 1); 1123 fill->size = (len + 1) / 2; 1124 dst = fill->data; 1125 s = r.str; 1126 val = 0; 1127 do 1128 { 1129 unsigned int digit; 1130 1131 digit = *s++ - '0'; 1132 if (digit > 9) 1133 digit = (digit - 'A' + '0' + 10) & 0xf; 1134 val <<= 4; 1135 val += digit; 1136 --len; 1137 if ((len & 1) == 0) 1138 { 1139 *dst++ = val; 1140 val = 0; 1141 } 1142 } 1143 while (len != 0); 1144 } 1145 else 1146 { 1147 fill = (fill_type *) xmalloc (4 + sizeof (*fill) - 1); 1148 val = r.value; 1149 fill->data[0] = (val >> 24) & 0xff; 1150 fill->data[1] = (val >> 16) & 0xff; 1151 fill->data[2] = (val >> 8) & 0xff; 1152 fill->data[3] = (val >> 0) & 0xff; 1153 fill->size = 4; 1154 } 1155 return fill; 1156 } 1157 973 1158 bfd_vma 974 1159 exp_get_abs_int (tree, def, name, allocation_done) … … 982 1167 983 1168 if (res.valid_p) 984 { 985 res.value += res.section->bfd_section->vma; 986 } 1169 res.value += res.section->bfd_section->vma; 987 1170 else 988 { 989 einfo (_("%F%S non constant expression for %s\n"), name); 990 } 1171 einfo (_("%F%S non constant expression for %s\n"), name); 1172 991 1173 return res.value; 992 1174 } 1175 1176 bfd_vma align_n (value, align) 1177 bfd_vma value; 1178 bfd_vma align; 1179 { 1180 if (align <= 1) 1181 return value; 1182 1183 value = (value + align - 1) / align; 1184 return value * align; 1185 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.