00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "bfd.h"
00036 #include "sysdep.h"
00037 #include "bfdlink.h"
00038
00039 #include "ld.h"
00040 #include "ldmain.h"
00041 #include "ldmisc.h"
00042 #include "ldexp.h"
00043 #include <ldgram.h>
00044 #include "ldlang.h"
00045 #include "libiberty.h"
00046 #include "safe-ctype.h"
00047
00048 static etree_value_type exp_fold_tree_no_dot
00049 (etree_type *, lang_output_section_statement_type *, lang_phase_type);
00050 static bfd_vma align_n
00051 (bfd_vma, bfd_vma);
00052
00053 struct exp_data_seg exp_data_seg;
00054
00055 segment_type *segments;
00056
00057
00058 static bfd_boolean assigning_to_dot = FALSE;
00059
00060
00061
00062
00063 static void
00064 exp_print_token (token_code_type code, int infix_p)
00065 {
00066 static const struct
00067 {
00068 token_code_type code;
00069 char * name;
00070 }
00071 table[] =
00072 {
00073 { INT, "int" },
00074 { NAME, "NAME" },
00075 { PLUSEQ, "+=" },
00076 { MINUSEQ, "-=" },
00077 { MULTEQ, "*=" },
00078 { DIVEQ, "/=" },
00079 { LSHIFTEQ, "<<=" },
00080 { RSHIFTEQ, ">>=" },
00081 { ANDEQ, "&=" },
00082 { OREQ, "|=" },
00083 { OROR, "||" },
00084 { ANDAND, "&&" },
00085 { EQ, "==" },
00086 { NE, "!=" },
00087 { LE, "<=" },
00088 { GE, ">=" },
00089 { LSHIFT, "<<" },
00090 { RSHIFT, ">>" },
00091 { ALIGN_K, "ALIGN" },
00092 { BLOCK, "BLOCK" },
00093 { QUAD, "QUAD" },
00094 { SQUAD, "SQUAD" },
00095 { LONG, "LONG" },
00096 { SHORT, "SHORT" },
00097 { BYTE, "BYTE" },
00098 { SECTIONS, "SECTIONS" },
00099 { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
00100 { MEMORY, "MEMORY" },
00101 { DEFINED, "DEFINED" },
00102 { TARGET_K, "TARGET" },
00103 { SEARCH_DIR, "SEARCH_DIR" },
00104 { MAP, "MAP" },
00105 { ENTRY, "ENTRY" },
00106 { NEXT, "NEXT" },
00107 { SIZEOF, "SIZEOF" },
00108 { ADDR, "ADDR" },
00109 { LOADADDR, "LOADADDR" },
00110 { MAX_K, "MAX_K" },
00111 { REL, "relocatable" },
00112 { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
00113 { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
00114 { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
00115 { ORIGIN, "ORIGIN" },
00116 { LENGTH, "LENGTH" },
00117 { SEGMENT_START, "SEGMENT_START" }
00118 };
00119 unsigned int idx;
00120
00121 for (idx = 0; idx < ARRAY_SIZE (table); idx++)
00122 if (table[idx].code == code)
00123 break;
00124
00125 if (infix_p)
00126 fputc (' ', config.map_file);
00127
00128 if (idx < ARRAY_SIZE (table))
00129 fputs (table[idx].name, config.map_file);
00130 else if (code < 127)
00131 fputc (code, config.map_file);
00132 else
00133 fprintf (config.map_file, "<code %d>", code);
00134
00135 if (infix_p)
00136 fputc (' ', config.map_file);
00137 }
00138
00139 static void
00140 make_abs (etree_value_type *ptr)
00141 {
00142 asection *s = ptr->section->bfd_section;
00143 ptr->value += s->vma;
00144 ptr->section = abs_output_section;
00145 }
00146
00147 static etree_value_type
00148 new_abs (bfd_vma value)
00149 {
00150 etree_value_type new;
00151 new.valid_p = TRUE;
00152 new.section = abs_output_section;
00153 new.value = value;
00154 new.str = NULL;
00155 return new;
00156 }
00157
00158 etree_type *
00159 exp_intop (bfd_vma value)
00160 {
00161 etree_type *new = stat_alloc (sizeof (new->value));
00162 new->type.node_code = INT;
00163 new->value.value = value;
00164 new->value.str = NULL;
00165 new->type.node_class = etree_value;
00166 return new;
00167 }
00168
00169 etree_type *
00170 exp_bigintop (bfd_vma value, char *str)
00171 {
00172 etree_type *new = stat_alloc (sizeof (new->value));
00173 new->type.node_code = INT;
00174 new->value.value = value;
00175 new->value.str = str;
00176 new->type.node_class = etree_value;
00177 return new;
00178 }
00179
00180
00181
00182 etree_type *
00183 exp_relop (asection *section, bfd_vma value)
00184 {
00185 etree_type *new = stat_alloc (sizeof (new->rel));
00186 new->type.node_code = REL;
00187 new->type.node_class = etree_rel;
00188 new->rel.section = section;
00189 new->rel.value = value;
00190 return new;
00191 }
00192
00193 static etree_value_type
00194 new_rel (bfd_vma value,
00195 char *str,
00196 lang_output_section_statement_type *section)
00197 {
00198 etree_value_type new;
00199 new.valid_p = TRUE;
00200 new.value = value;
00201 new.str = str;
00202 new.section = section;
00203 return new;
00204 }
00205
00206 static etree_value_type
00207 new_rel_from_section (bfd_vma value,
00208 lang_output_section_statement_type *section)
00209 {
00210 etree_value_type new;
00211 new.valid_p = TRUE;
00212 new.value = value;
00213 new.str = NULL;
00214 new.section = section;
00215
00216 new.value -= section->bfd_section->vma;
00217
00218 return new;
00219 }
00220
00221 static etree_value_type
00222 fold_unary (etree_type *tree,
00223 lang_output_section_statement_type *current_section,
00224 lang_phase_type allocation_done,
00225 bfd_vma dot,
00226 bfd_vma *dotp)
00227 {
00228 etree_value_type result;
00229
00230 result = exp_fold_tree (tree->unary.child,
00231 current_section,
00232 allocation_done, dot, dotp);
00233 if (result.valid_p)
00234 {
00235 switch (tree->type.node_code)
00236 {
00237 case ALIGN_K:
00238 if (allocation_done != lang_first_phase_enum)
00239 result = new_rel_from_section (align_n (dot, result.value),
00240 current_section);
00241 else
00242 result.valid_p = FALSE;
00243 break;
00244
00245 case ABSOLUTE:
00246 if (allocation_done != lang_first_phase_enum)
00247 {
00248 result.value += result.section->bfd_section->vma;
00249 result.section = abs_output_section;
00250 }
00251 else
00252 result.valid_p = FALSE;
00253 break;
00254
00255 case '~':
00256 make_abs (&result);
00257 result.value = ~result.value;
00258 break;
00259
00260 case '!':
00261 make_abs (&result);
00262 result.value = !result.value;
00263 break;
00264
00265 case '-':
00266 make_abs (&result);
00267 result.value = -result.value;
00268 break;
00269
00270 case NEXT:
00271
00272 if (allocation_done == lang_allocating_phase_enum)
00273 {
00274 make_abs (&result);
00275 result.value = align_n (dot, result.value);
00276 }
00277 else
00278 result.valid_p = FALSE;
00279 break;
00280
00281 case DATA_SEGMENT_END:
00282 if (allocation_done != lang_first_phase_enum
00283 && current_section == abs_output_section
00284 && (exp_data_seg.phase == exp_dataseg_align_seen
00285 || exp_data_seg.phase == exp_dataseg_relro_seen
00286 || exp_data_seg.phase == exp_dataseg_adjust
00287 || exp_data_seg.phase == exp_dataseg_relro_adjust
00288 || allocation_done != lang_allocating_phase_enum))
00289 {
00290 if (exp_data_seg.phase == exp_dataseg_align_seen
00291 || exp_data_seg.phase == exp_dataseg_relro_seen)
00292 {
00293 exp_data_seg.phase = exp_dataseg_end_seen;
00294 exp_data_seg.end = result.value;
00295 }
00296 }
00297 else
00298 result.valid_p = FALSE;
00299 break;
00300
00301 default:
00302 FAIL ();
00303 break;
00304 }
00305 }
00306
00307 return result;
00308 }
00309
00310 static etree_value_type
00311 fold_binary (etree_type *tree,
00312 lang_output_section_statement_type *current_section,
00313 lang_phase_type allocation_done,
00314 bfd_vma dot,
00315 bfd_vma *dotp)
00316 {
00317 etree_value_type result;
00318
00319 result = exp_fold_tree (tree->binary.lhs, current_section,
00320 allocation_done, dot, dotp);
00321
00322
00323
00324 if (result.valid_p && tree->type.node_code == SEGMENT_START)
00325 {
00326 const char *segment_name;
00327 segment_type *seg;
00328
00329
00330 segment_name = tree->binary.rhs->name.name;
00331 for (seg = segments; seg; seg = seg->next)
00332 if (strcmp (seg->name, segment_name) == 0)
00333 {
00334 seg->used = TRUE;
00335 result.value = seg->value;
00336 result.str = NULL;
00337 result.section = NULL;
00338 break;
00339 }
00340 }
00341 else if (result.valid_p)
00342 {
00343 etree_value_type other;
00344
00345 other = exp_fold_tree (tree->binary.rhs,
00346 current_section,
00347 allocation_done, dot, dotp);
00348 if (other.valid_p)
00349 {
00350
00351
00352
00353
00354
00355 if (current_section != abs_output_section
00356 && (other.section == abs_output_section
00357 || (result.section == abs_output_section
00358 && tree->type.node_code == '+'))
00359 && (tree->type.node_code == '+'
00360 || tree->type.node_code == '-'))
00361 {
00362 if (other.section != abs_output_section)
00363 {
00364
00365 if (tree->type.node_code == '+')
00366 other.value = result.value + other.value;
00367 else
00368 other.value = result.value - other.value;
00369 return other;
00370 }
00371 }
00372 else if (result.section != other.section
00373 || current_section == abs_output_section)
00374 {
00375 make_abs (&result);
00376 make_abs (&other);
00377 }
00378
00379 switch (tree->type.node_code)
00380 {
00381 case '%':
00382 if (other.value == 0)
00383 einfo (_("%F%S %% by zero\n"));
00384 result.value = ((bfd_signed_vma) result.value
00385 % (bfd_signed_vma) other.value);
00386 break;
00387
00388 case '/':
00389 if (other.value == 0)
00390 einfo (_("%F%S / by zero\n"));
00391 result.value = ((bfd_signed_vma) result.value
00392 / (bfd_signed_vma) other.value);
00393 break;
00394
00395 #define BOP(x,y) case x : result.value = result.value y other.value; break;
00396 BOP ('+', +);
00397 BOP ('*', *);
00398 BOP ('-', -);
00399 BOP (LSHIFT, <<);
00400 BOP (RSHIFT, >>);
00401 BOP (EQ, ==);
00402 BOP (NE, !=);
00403 BOP ('<', <);
00404 BOP ('>', >);
00405 BOP (LE, <=);
00406 BOP (GE, >=);
00407 BOP ('&', &);
00408 BOP ('^', ^);
00409 BOP ('|', |);
00410 BOP (ANDAND, &&);
00411 BOP (OROR, ||);
00412
00413 case MAX_K:
00414 if (result.value < other.value)
00415 result = other;
00416 break;
00417
00418 case MIN_K:
00419 if (result.value > other.value)
00420 result = other;
00421 break;
00422
00423 case ALIGN_K:
00424 result.value = align_n (result.value, other.value);
00425 break;
00426
00427 case DATA_SEGMENT_ALIGN:
00428 if (allocation_done != lang_first_phase_enum
00429 && current_section == abs_output_section
00430 && (exp_data_seg.phase == exp_dataseg_none
00431 || exp_data_seg.phase == exp_dataseg_adjust
00432 || exp_data_seg.phase == exp_dataseg_relro_adjust
00433 || allocation_done != lang_allocating_phase_enum))
00434 {
00435 bfd_vma maxpage = result.value;
00436
00437 result.value = align_n (dot, maxpage);
00438 if (exp_data_seg.phase == exp_dataseg_relro_adjust)
00439 result.value = exp_data_seg.base;
00440 else if (exp_data_seg.phase != exp_dataseg_adjust)
00441 {
00442 result.value += dot & (maxpage - 1);
00443 if (allocation_done == lang_allocating_phase_enum)
00444 {
00445 exp_data_seg.phase = exp_dataseg_align_seen;
00446 exp_data_seg.min_base = align_n (dot, maxpage);
00447 exp_data_seg.base = result.value;
00448 exp_data_seg.pagesize = other.value;
00449 exp_data_seg.maxpagesize = maxpage;
00450 exp_data_seg.relro_end = 0;
00451 }
00452 }
00453 else if (other.value < maxpage)
00454 result.value += (dot + other.value - 1)
00455 & (maxpage - other.value);
00456 }
00457 else
00458 result.valid_p = FALSE;
00459 break;
00460
00461 case DATA_SEGMENT_RELRO_END:
00462 if (allocation_done != lang_first_phase_enum
00463 && (exp_data_seg.phase == exp_dataseg_align_seen
00464 || exp_data_seg.phase == exp_dataseg_adjust
00465 || exp_data_seg.phase == exp_dataseg_relro_adjust
00466 || allocation_done != lang_allocating_phase_enum))
00467 {
00468 if (exp_data_seg.phase == exp_dataseg_align_seen
00469 || exp_data_seg.phase == exp_dataseg_relro_adjust)
00470 exp_data_seg.relro_end
00471 = result.value + other.value;
00472 if (exp_data_seg.phase == exp_dataseg_relro_adjust
00473 && (exp_data_seg.relro_end
00474 & (exp_data_seg.pagesize - 1)))
00475 {
00476 exp_data_seg.relro_end += exp_data_seg.pagesize - 1;
00477 exp_data_seg.relro_end &= ~(exp_data_seg.pagesize - 1);
00478 result.value = exp_data_seg.relro_end - other.value;
00479 }
00480 if (exp_data_seg.phase == exp_dataseg_align_seen)
00481 exp_data_seg.phase = exp_dataseg_relro_seen;
00482 }
00483 else
00484 result.valid_p = FALSE;
00485 break;
00486
00487 default:
00488 FAIL ();
00489 }
00490 }
00491 else
00492 {
00493 result.valid_p = FALSE;
00494 }
00495 }
00496
00497 return result;
00498 }
00499
00500 static etree_value_type
00501 fold_trinary (etree_type *tree,
00502 lang_output_section_statement_type *current_section,
00503 lang_phase_type allocation_done,
00504 bfd_vma dot,
00505 bfd_vma *dotp)
00506 {
00507 etree_value_type result;
00508
00509 result = exp_fold_tree (tree->trinary.cond, current_section,
00510 allocation_done, dot, dotp);
00511 if (result.valid_p)
00512 result = exp_fold_tree ((result.value
00513 ? tree->trinary.lhs
00514 : tree->trinary.rhs),
00515 current_section,
00516 allocation_done, dot, dotp);
00517
00518 return result;
00519 }
00520
00521 static etree_value_type
00522 fold_name (etree_type *tree,
00523 lang_output_section_statement_type *current_section,
00524 lang_phase_type allocation_done,
00525 bfd_vma dot)
00526 {
00527 etree_value_type result;
00528
00529 result.valid_p = FALSE;
00530
00531 switch (tree->type.node_code)
00532 {
00533 case SIZEOF_HEADERS:
00534 if (allocation_done != lang_first_phase_enum)
00535 result = new_abs (bfd_sizeof_headers (output_bfd,
00536 link_info.relocatable));
00537 break;
00538 case DEFINED:
00539 if (allocation_done == lang_first_phase_enum)
00540 lang_track_definedness (tree->name.name);
00541 else
00542 {
00543 struct bfd_link_hash_entry *h;
00544 int def_iteration
00545 = lang_symbol_definition_iteration (tree->name.name);
00546
00547 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
00548 tree->name.name,
00549 FALSE, FALSE, TRUE);
00550 result.value = (h != NULL
00551 && (h->type == bfd_link_hash_defined
00552 || h->type == bfd_link_hash_defweak
00553 || h->type == bfd_link_hash_common)
00554 && (def_iteration == lang_statement_iteration
00555 || def_iteration == -1));
00556 result.section = abs_output_section;
00557 result.valid_p = TRUE;
00558 }
00559 break;
00560 case NAME:
00561 if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
00562 {
00563 if (allocation_done != lang_first_phase_enum)
00564 result = new_rel_from_section (dot, current_section);
00565 }
00566 else if (allocation_done != lang_first_phase_enum)
00567 {
00568 struct bfd_link_hash_entry *h;
00569
00570 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
00571 tree->name.name,
00572 TRUE, FALSE, TRUE);
00573 if (!h)
00574 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
00575 else if (h->type == bfd_link_hash_defined
00576 || h->type == bfd_link_hash_defweak)
00577 {
00578 if (bfd_is_abs_section (h->u.def.section))
00579 result = new_abs (h->u.def.value);
00580 else if (allocation_done == lang_final_phase_enum
00581 || allocation_done == lang_allocating_phase_enum)
00582 {
00583 asection *output_section;
00584
00585 output_section = h->u.def.section->output_section;
00586 if (output_section == NULL)
00587 einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
00588 tree->name.name);
00589 else
00590 {
00591 lang_output_section_statement_type *os;
00592
00593 os = (lang_output_section_statement_lookup
00594 (bfd_get_section_name (output_bfd,
00595 output_section)));
00596
00597
00598
00599 result = new_rel ((h->u.def.value
00600 + h->u.def.section->output_offset),
00601 NULL,
00602 os);
00603 }
00604 }
00605 }
00606 else if (allocation_done == lang_final_phase_enum
00607 || assigning_to_dot)
00608 einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
00609 tree->name.name);
00610 else if (h->type == bfd_link_hash_new)
00611 {
00612 h->type = bfd_link_hash_undefined;
00613 h->u.undef.abfd = NULL;
00614 if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
00615 bfd_link_add_undef (link_info.hash, h);
00616 }
00617 }
00618 break;
00619
00620 case ADDR:
00621 if (allocation_done != lang_first_phase_enum)
00622 {
00623 lang_output_section_statement_type *os;
00624
00625 os = lang_output_section_find (tree->name.name);
00626 if (os && os->processed > 0)
00627 result = new_rel (0, NULL, os);
00628 }
00629 break;
00630
00631 case LOADADDR:
00632 if (allocation_done != lang_first_phase_enum)
00633 {
00634 lang_output_section_statement_type *os;
00635
00636 os = lang_output_section_find (tree->name.name);
00637 if (os && os->processed != 0)
00638 {
00639 if (os->load_base == NULL)
00640 result = new_rel (0, NULL, os);
00641 else
00642 result = exp_fold_tree_no_dot (os->load_base,
00643 abs_output_section,
00644 allocation_done);
00645 }
00646 }
00647 break;
00648
00649 case SIZEOF:
00650 if (allocation_done != lang_first_phase_enum)
00651 {
00652 int opb = bfd_octets_per_byte (output_bfd);
00653 lang_output_section_statement_type *os;
00654
00655 os = lang_output_section_find (tree->name.name);
00656 if (os && os->processed > 0)
00657 result = new_abs (os->bfd_section->size / opb);
00658 }
00659 break;
00660
00661 case LENGTH:
00662 {
00663 lang_memory_region_type *mem;
00664
00665 mem = lang_memory_region_lookup (tree->name.name, FALSE);
00666 if (mem != NULL)
00667 result = new_abs (mem->length);
00668 else
00669 einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
00670 tree->name.name);
00671 }
00672 break;
00673
00674 case ORIGIN:
00675 {
00676 lang_memory_region_type *mem;
00677
00678 mem = lang_memory_region_lookup (tree->name.name, FALSE);
00679 if (mem != NULL)
00680 result = new_abs (mem->origin);
00681 else
00682 einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
00683 tree->name.name);
00684 }
00685 break;
00686
00687 default:
00688 FAIL ();
00689 break;
00690 }
00691
00692 return result;
00693 }
00694
00695 etree_value_type
00696 exp_fold_tree (etree_type *tree,
00697 lang_output_section_statement_type *current_section,
00698 lang_phase_type allocation_done,
00699 bfd_vma dot,
00700 bfd_vma *dotp)
00701 {
00702 etree_value_type result;
00703
00704 if (tree == NULL)
00705 {
00706 memset (&result, 0, sizeof (result));
00707 return result;
00708 }
00709
00710 switch (tree->type.node_class)
00711 {
00712 case etree_value:
00713 result = new_rel (tree->value.value, tree->value.str, current_section);
00714 break;
00715
00716 case etree_rel:
00717 if (allocation_done != lang_final_phase_enum)
00718 memset (&result, 0, sizeof (result));
00719 else
00720 result = new_rel ((tree->rel.value
00721 + tree->rel.section->output_section->vma
00722 + tree->rel.section->output_offset),
00723 NULL,
00724 current_section);
00725 break;
00726
00727 case etree_assert:
00728 result = exp_fold_tree (tree->assert_s.child,
00729 current_section,
00730 allocation_done, dot, dotp);
00731 if (result.valid_p && !result.value)
00732 einfo ("%X%P: %s\n", tree->assert_s.message);
00733 break;
00734
00735 case etree_unary:
00736 result = fold_unary (tree, current_section, allocation_done,
00737 dot, dotp);
00738 break;
00739
00740 case etree_binary:
00741 result = fold_binary (tree, current_section, allocation_done,
00742 dot, dotp);
00743 break;
00744
00745 case etree_trinary:
00746 result = fold_trinary (tree, current_section, allocation_done,
00747 dot, dotp);
00748 break;
00749
00750 case etree_assign:
00751 case etree_provide:
00752 case etree_provided:
00753 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
00754 {
00755
00756 if (tree->type.node_class != etree_assign)
00757 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
00758 if (allocation_done == lang_allocating_phase_enum
00759 || (allocation_done == lang_final_phase_enum
00760 && current_section == abs_output_section))
00761 {
00762
00763 assigning_to_dot = TRUE;
00764 result = exp_fold_tree (tree->assign.src,
00765 current_section,
00766 allocation_done, dot, dotp);
00767 assigning_to_dot = FALSE;
00768
00769 if (! result.valid_p)
00770 einfo (_("%F%S invalid assignment to location counter\n"));
00771 else
00772 {
00773 if (current_section == NULL)
00774 einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
00775 else
00776 {
00777 bfd_vma nextdot;
00778
00779 nextdot = (result.value
00780 + current_section->bfd_section->vma);
00781 if (nextdot < dot
00782 && current_section != abs_output_section)
00783 einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
00784 dot, nextdot);
00785 else
00786 *dotp = nextdot;
00787 }
00788 }
00789 }
00790 else
00791 memset (&result, 0, sizeof (result));
00792 }
00793 else
00794 {
00795 result = exp_fold_tree (tree->assign.src,
00796 current_section, allocation_done,
00797 dot, dotp);
00798 if (result.valid_p)
00799 {
00800 bfd_boolean create;
00801 struct bfd_link_hash_entry *h;
00802
00803 if (tree->type.node_class == etree_assign)
00804 create = TRUE;
00805 else
00806 create = FALSE;
00807 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
00808 create, FALSE, TRUE);
00809 if (h == NULL)
00810 {
00811 if (create)
00812 einfo (_("%P%F:%s: hash creation failed\n"),
00813 tree->assign.dst);
00814 }
00815 else if (tree->type.node_class == etree_provide
00816 && h->type != bfd_link_hash_new
00817 && h->type != bfd_link_hash_undefined
00818 && h->type != bfd_link_hash_common)
00819 {
00820
00821
00822 }
00823 else
00824 {
00825
00826
00827 lang_update_definedness (tree->assign.dst, h);
00828 h->type = bfd_link_hash_defined;
00829 h->u.def.value = result.value;
00830 h->u.def.section = result.section->bfd_section;
00831 if (tree->type.node_class == etree_provide)
00832 tree->type.node_class = etree_provided;
00833 }
00834 }
00835 }
00836 break;
00837
00838 case etree_name:
00839 result = fold_name (tree, current_section, allocation_done, dot);
00840 break;
00841
00842 default:
00843 FAIL ();
00844 memset (&result, 0, sizeof (result));
00845 break;
00846 }
00847
00848 return result;
00849 }
00850
00851 static etree_value_type
00852 exp_fold_tree_no_dot (etree_type *tree,
00853 lang_output_section_statement_type *current_section,
00854 lang_phase_type allocation_done)
00855 {
00856 return exp_fold_tree (tree, current_section, allocation_done, 0, NULL);
00857 }
00858
00859 etree_type *
00860 exp_binop (int code, etree_type *lhs, etree_type *rhs)
00861 {
00862 etree_type value, *new;
00863 etree_value_type r;
00864
00865 value.type.node_code = code;
00866 value.binary.lhs = lhs;
00867 value.binary.rhs = rhs;
00868 value.type.node_class = etree_binary;
00869 r = exp_fold_tree_no_dot (&value,
00870 abs_output_section,
00871 lang_first_phase_enum);
00872 if (r.valid_p)
00873 {
00874 return exp_intop (r.value);
00875 }
00876 new = stat_alloc (sizeof (new->binary));
00877 memcpy (new, &value, sizeof (new->binary));
00878 return new;
00879 }
00880
00881 etree_type *
00882 exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
00883 {
00884 etree_type value, *new;
00885 etree_value_type r;
00886 value.type.node_code = code;
00887 value.trinary.lhs = lhs;
00888 value.trinary.cond = cond;
00889 value.trinary.rhs = rhs;
00890 value.type.node_class = etree_trinary;
00891 r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum);
00892 if (r.valid_p)
00893 return exp_intop (r.value);
00894
00895 new = stat_alloc (sizeof (new->trinary));
00896 memcpy (new, &value, sizeof (new->trinary));
00897 return new;
00898 }
00899
00900 etree_type *
00901 exp_unop (int code, etree_type *child)
00902 {
00903 etree_type value, *new;
00904
00905 etree_value_type r;
00906 value.unary.type.node_code = code;
00907 value.unary.child = child;
00908 value.unary.type.node_class = etree_unary;
00909 r = exp_fold_tree_no_dot (&value, abs_output_section,
00910 lang_first_phase_enum);
00911 if (r.valid_p)
00912 return exp_intop (r.value);
00913
00914 new = stat_alloc (sizeof (new->unary));
00915 memcpy (new, &value, sizeof (new->unary));
00916 return new;
00917 }
00918
00919 etree_type *
00920 exp_nameop (int code, const char *name)
00921 {
00922 etree_type value, *new;
00923 etree_value_type r;
00924 value.name.type.node_code = code;
00925 value.name.name = name;
00926 value.name.type.node_class = etree_name;
00927
00928 r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum);
00929 if (r.valid_p)
00930 return exp_intop (r.value);
00931
00932 new = stat_alloc (sizeof (new->name));
00933 memcpy (new, &value, sizeof (new->name));
00934 return new;
00935
00936 }
00937
00938 etree_type *
00939 exp_assop (int code, const char *dst, etree_type *src)
00940 {
00941 etree_type value, *new;
00942
00943 value.assign.type.node_code = code;
00944
00945 value.assign.src = src;
00946 value.assign.dst = dst;
00947 value.assign.type.node_class = etree_assign;
00948
00949 new = stat_alloc (sizeof (new->assign));
00950 memcpy (new, &value, sizeof (new->assign));
00951 return new;
00952 }
00953
00954
00955
00956 etree_type *
00957 exp_provide (const char *dst, etree_type *src)
00958 {
00959 etree_type *n;
00960
00961 n = stat_alloc (sizeof (n->assign));
00962 n->assign.type.node_code = '=';
00963 n->assign.type.node_class = etree_provide;
00964 n->assign.src = src;
00965 n->assign.dst = dst;
00966 return n;
00967 }
00968
00969
00970
00971 etree_type *
00972 exp_assert (etree_type *exp, const char *message)
00973 {
00974 etree_type *n;
00975
00976 n = stat_alloc (sizeof (n->assert_s));
00977 n->assert_s.type.node_code = '!';
00978 n->assert_s.type.node_class = etree_assert;
00979 n->assert_s.child = exp;
00980 n->assert_s.message = message;
00981 return n;
00982 }
00983
00984 void
00985 exp_print_tree (etree_type *tree)
00986 {
00987 if (config.map_file == NULL)
00988 config.map_file = stderr;
00989
00990 if (tree == NULL)
00991 {
00992 minfo ("NULL TREE\n");
00993 return;
00994 }
00995
00996 switch (tree->type.node_class)
00997 {
00998 case etree_value:
00999 minfo ("0x%v", tree->value.value);
01000 return;
01001 case etree_rel:
01002 if (tree->rel.section->owner != NULL)
01003 minfo ("%B:", tree->rel.section->owner);
01004 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
01005 return;
01006 case etree_assign:
01007 fprintf (config.map_file, "%s", tree->assign.dst);
01008 exp_print_token (tree->type.node_code, TRUE);
01009 exp_print_tree (tree->assign.src);
01010 break;
01011 case etree_provide:
01012 case etree_provided:
01013 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
01014 exp_print_tree (tree->assign.src);
01015 fprintf (config.map_file, ")");
01016 break;
01017 case etree_binary:
01018 fprintf (config.map_file, "(");
01019 exp_print_tree (tree->binary.lhs);
01020 exp_print_token (tree->type.node_code, TRUE);
01021 exp_print_tree (tree->binary.rhs);
01022 fprintf (config.map_file, ")");
01023 break;
01024 case etree_trinary:
01025 exp_print_tree (tree->trinary.cond);
01026 fprintf (config.map_file, "?");
01027 exp_print_tree (tree->trinary.lhs);
01028 fprintf (config.map_file, ":");
01029 exp_print_tree (tree->trinary.rhs);
01030 break;
01031 case etree_unary:
01032 exp_print_token (tree->unary.type.node_code, FALSE);
01033 if (tree->unary.child)
01034 {
01035 fprintf (config.map_file, " (");
01036 exp_print_tree (tree->unary.child);
01037 fprintf (config.map_file, ")");
01038 }
01039 break;
01040
01041 case etree_assert:
01042 fprintf (config.map_file, "ASSERT (");
01043 exp_print_tree (tree->assert_s.child);
01044 fprintf (config.map_file, ", %s)", tree->assert_s.message);
01045 break;
01046
01047 case etree_undef:
01048 fprintf (config.map_file, "????????");
01049 break;
01050 case etree_name:
01051 if (tree->type.node_code == NAME)
01052 {
01053 fprintf (config.map_file, "%s", tree->name.name);
01054 }
01055 else
01056 {
01057 exp_print_token (tree->type.node_code, FALSE);
01058 if (tree->name.name)
01059 fprintf (config.map_file, " (%s)", tree->name.name);
01060 }
01061 break;
01062 default:
01063 FAIL ();
01064 break;
01065 }
01066 }
01067
01068 bfd_vma
01069 exp_get_vma (etree_type *tree,
01070 bfd_vma def,
01071 char *name,
01072 lang_phase_type allocation_done)
01073 {
01074 etree_value_type r;
01075
01076 if (tree != NULL)
01077 {
01078 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
01079 if (! r.valid_p && name != NULL)
01080 einfo (_("%F%S nonconstant expression for %s\n"), name);
01081 return r.value;
01082 }
01083 else
01084 return def;
01085 }
01086
01087 int
01088 exp_get_value_int (etree_type *tree,
01089 int def,
01090 char *name,
01091 lang_phase_type allocation_done)
01092 {
01093 return exp_get_vma (tree, def, name, allocation_done);
01094 }
01095
01096 fill_type *
01097 exp_get_fill (etree_type *tree,
01098 fill_type *def,
01099 char *name,
01100 lang_phase_type allocation_done)
01101 {
01102 fill_type *fill;
01103 etree_value_type r;
01104 size_t len;
01105 unsigned int val;
01106
01107 if (tree == NULL)
01108 return def;
01109
01110 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
01111 if (! r.valid_p && name != NULL)
01112 einfo (_("%F%S nonconstant expression for %s\n"), name);
01113
01114 if (r.str != NULL && (len = strlen (r.str)) != 0)
01115 {
01116 unsigned char *dst;
01117 unsigned char *s;
01118 fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
01119 fill->size = (len + 1) / 2;
01120 dst = fill->data;
01121 s = (unsigned char *) r.str;
01122 val = 0;
01123 do
01124 {
01125 unsigned int digit;
01126
01127 digit = *s++ - '0';
01128 if (digit > 9)
01129 digit = (digit - 'A' + '0' + 10) & 0xf;
01130 val <<= 4;
01131 val += digit;
01132 --len;
01133 if ((len & 1) == 0)
01134 {
01135 *dst++ = val;
01136 val = 0;
01137 }
01138 }
01139 while (len != 0);
01140 }
01141 else
01142 {
01143 fill = xmalloc (4 + sizeof (*fill) - 1);
01144 val = r.value;
01145 fill->data[0] = (val >> 24) & 0xff;
01146 fill->data[1] = (val >> 16) & 0xff;
01147 fill->data[2] = (val >> 8) & 0xff;
01148 fill->data[3] = (val >> 0) & 0xff;
01149 fill->size = 4;
01150 }
01151 return fill;
01152 }
01153
01154 bfd_vma
01155 exp_get_abs_int (etree_type *tree,
01156 int def ATTRIBUTE_UNUSED,
01157 char *name,
01158 lang_phase_type allocation_done)
01159 {
01160 etree_value_type res;
01161 res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
01162
01163 if (res.valid_p)
01164 res.value += res.section->bfd_section->vma;
01165 else
01166 einfo (_("%F%S non constant expression for %s\n"), name);
01167
01168 return res.value;
01169 }
01170
01171 static bfd_vma
01172 align_n (bfd_vma value, bfd_vma align)
01173 {
01174 if (align <= 1)
01175 return value;
01176
01177 value = (value + align - 1) / align;
01178 return value * align;
01179 }