X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldexp.c;h=02c76f8b33c22dd6235aec8ef49aac68d299267f;hb=969168ce6f6a769ff87eae63d2680d6ae0d99790;hp=4b9676ecbab6cef813aa0ed92d682a9a46bdd76a;hpb=a000f8817b32eadd4aeadf9185634350a59e6649;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldexp.c b/ld/ldexp.c index 4b9676ecba..02c76f8b33 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -1,5 +1,5 @@ /* This module handles expression trees. - Copyright (C) 1991-2018 Free Software Foundation, Inc. + Copyright (C) 1991-2021 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support . This file is part of the GNU Binutils. @@ -30,6 +30,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" @@ -160,14 +161,14 @@ make_log2ceil (void) { bfd_vma value = expld.result.value; bfd_vma result = -1; - bfd_boolean round_up = FALSE; + bool round_up = false; do { result++; /* If more than one bit is set in the value we will need to round up. */ if ((value > 1) && (value & 1)) - round_up = TRUE; + round_up = true; } while (value >>= 1); @@ -183,13 +184,13 @@ make_abs (void) if (expld.result.section != NULL) expld.result.value += expld.result.section->vma; expld.result.section = bfd_abs_section_ptr; - expld.rel_from_abs = FALSE; + expld.rel_from_abs = false; } static void new_abs (bfd_vma value) { - expld.result.valid_p = TRUE; + expld.result.valid_p = true; expld.result.section = bfd_abs_section_ptr; expld.result.value = value; expld.result.str = NULL; @@ -198,7 +199,7 @@ new_abs (bfd_vma value) etree_type * exp_intop (bfd_vma value) { - etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->value)); + etree_type *new_e = stat_alloc (sizeof (new_e->value)); new_e->type.node_code = INT; new_e->type.filename = ldlex_filename (); new_e->type.lineno = lineno; @@ -211,7 +212,7 @@ exp_intop (bfd_vma value) etree_type * exp_bigintop (bfd_vma value, char *str) { - etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->value)); + etree_type *new_e = stat_alloc (sizeof (new_e->value)); new_e->type.node_code = INT; new_e->type.filename = ldlex_filename (); new_e->type.lineno = lineno; @@ -226,7 +227,7 @@ exp_bigintop (bfd_vma value, char *str) etree_type * exp_relop (asection *section, bfd_vma value) { - etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->rel)); + etree_type *new_e = stat_alloc (sizeof (new_e->rel)); new_e->type.node_code = REL; new_e->type.filename = ldlex_filename (); new_e->type.lineno = lineno; @@ -239,7 +240,7 @@ exp_relop (asection *section, bfd_vma value) static void new_number (bfd_vma value) { - expld.result.valid_p = TRUE; + expld.result.valid_p = true; expld.result.value = value; expld.result.str = NULL; expld.result.section = NULL; @@ -248,7 +249,7 @@ new_number (bfd_vma value) static void new_rel (bfd_vma value, asection *section) { - expld.result.valid_p = TRUE; + expld.result.valid_p = true; expld.result.value = value; expld.result.str = NULL; expld.result.section = section; @@ -259,8 +260,8 @@ new_rel_from_abs (bfd_vma value) { asection *s = expld.section; - expld.rel_from_abs = TRUE; - expld.result.valid_p = TRUE; + expld.rel_from_abs = true; + expld.result.valid_p = true; expld.result.value = value - s->vma; expld.result.str = NULL; expld.result.section = s; @@ -296,26 +297,26 @@ static struct definedness_hash_entry * symbol_defined (const char *name) { return ((struct definedness_hash_entry *) - bfd_hash_lookup (&definedness_table, name, FALSE, FALSE)); + bfd_hash_lookup (&definedness_table, name, false, false)); } /* Update the definedness state of NAME. Return FALSE if script symbol is multiply defining a strong symbol in an object. */ -static bfd_boolean +static bool update_definedness (const char *name, struct bfd_link_hash_entry *h) { - bfd_boolean ret; + bool ret; struct definedness_hash_entry *defentry = (struct definedness_hash_entry *) - bfd_hash_lookup (&definedness_table, name, TRUE, FALSE); + bfd_hash_lookup (&definedness_table, name, true, false); if (defentry == NULL) einfo (_("%F%P: bfd_hash_lookup failed creating symbol %s\n"), name); /* If the symbol was already defined, and not by a script, then it must be defined by an object file or by the linker target code. */ - ret = TRUE; + ret = true; if (!h->ldscript_def && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak @@ -324,8 +325,9 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h) defentry->by_object = 1; if (h->type == bfd_link_hash_defined && h->u.def.section->output_section != NULL + && !bfd_is_abs_section (h->u.def.section) && !h->linker_def) - ret = FALSE; + ret = false; } defentry->iteration = lang_statement_iteration; @@ -343,7 +345,7 @@ fold_segment_end (seg_align_type *seg) if (expld.phase == lang_first_phase_enum || expld.section != bfd_abs_section_ptr) { - expld.result.valid_p = FALSE; + expld.result.valid_p = false; } else if (seg->phase == exp_seg_align_seen || seg->phase == exp_seg_relro_seen) @@ -358,7 +360,7 @@ fold_segment_end (seg_align_type *seg) /* OK. */ } else - expld.result.valid_p = FALSE; + expld.result.valid_p = false; } static void @@ -373,7 +375,7 @@ fold_unary (etree_type *tree) if (expld.phase != lang_first_phase_enum) new_rel_from_abs (align_n (expld.dot, expld.result.value)); else - expld.result.valid_p = FALSE; + expld.result.valid_p = false; break; case ABSOLUTE: @@ -404,7 +406,7 @@ fold_unary (etree_type *tree) expld.result.value = align_n (expld.dot, expld.result.value); } else - expld.result.valid_p = FALSE; + expld.result.valid_p = false; break; case DATA_SEGMENT_END: @@ -450,7 +452,7 @@ fold_segment_align (seg_align_type *seg, etree_value_type *lhs) seg->relro = exp_seg_relro_start; if (expld.phase == lang_first_phase_enum || expld.section != bfd_abs_section_ptr) - expld.result.valid_p = FALSE; + expld.result.valid_p = false; else { bfd_vma maxpage = lhs->value; @@ -481,7 +483,7 @@ fold_segment_align (seg_align_type *seg, etree_value_type *lhs) seg->relro_end = 0; } else - expld.result.valid_p = FALSE; + expld.result.valid_p = false; } } } @@ -495,7 +497,7 @@ fold_segment_relro_end (seg_align_type *seg, etree_value_type *lhs) seg->relro_offset = expld.result.value; if (expld.phase == lang_first_phase_enum || expld.section != bfd_abs_section_ptr) - expld.result.valid_p = FALSE; + expld.result.valid_p = false; else if (seg->phase == exp_seg_align_seen || seg->phase == exp_seg_adjust || seg->phase == exp_seg_relro_adjust @@ -519,7 +521,7 @@ fold_segment_relro_end (seg_align_type *seg, etree_value_type *lhs) seg->phase = exp_seg_relro_seen; } else - expld.result.valid_p = FALSE; + expld.result.valid_p = false; } static void @@ -534,6 +536,7 @@ fold_binary (etree_type *tree) operand, binary.rhs is first operand. */ if (expld.result.valid_p && tree->type.node_code == SEGMENT_START) { + bfd_vma value = expld.result.value; const char *segment_name; segment_type *seg; @@ -545,15 +548,16 @@ fold_binary (etree_type *tree) { if (!seg->used && config.magic_demand_paged - && config.maxpagesize != 0 - && (seg->value % config.maxpagesize) != 0) + && link_info.maxpagesize != 0 + && (seg->value % link_info.maxpagesize) != 0) einfo (_("%P: warning: address of `%s' " "isn't multiple of maximum page size\n"), segment_name); - seg->used = TRUE; - new_rel_from_abs (seg->value); + seg->used = true; + value = seg->value; break; } + new_rel_from_abs (value); return; } @@ -690,13 +694,15 @@ fold_name (etree_type *tree) switch (tree->type.node_code) { case SIZEOF_HEADERS: + link_info.load_phdrs = 1; if (expld.phase != lang_first_phase_enum) { bfd_vma hdr_size = 0; /* Don't find the real header size if only marking sections; The bfd function may cache incorrect data. */ if (expld.phase != lang_mark_phase_enum) - hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info); + hdr_size = (bfd_sizeof_headers (link_info.output_bfd, &link_info) + / bfd_octets_per_byte (link_info.output_bfd, NULL)); new_number (hdr_size); } break; @@ -705,7 +711,7 @@ fold_name (etree_type *tree) h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info, tree->name.name, - FALSE, FALSE, TRUE); + false, false, true); new_number (h != NULL && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak @@ -717,23 +723,6 @@ fold_name (etree_type *tree) break; case NAME: - if (expld.assign_name != NULL - && strcmp (expld.assign_name, tree->name.name) == 0) - { - /* Self-assignment is only allowed for absolute symbols - defined in a linker script. */ - h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, - &link_info, - tree->name.name, - FALSE, FALSE, TRUE); - if (!(h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) - && h->u.def.section == bfd_abs_section_ptr - && (def = symbol_defined (tree->name.name)) != NULL - && def->iteration == (lang_statement_iteration & 255))) - expld.assign_name = NULL; - } if (tree->name.name[0] == '.' && tree->name.name[1] == 0) new_rel_from_abs (expld.dot); else @@ -741,9 +730,12 @@ fold_name (etree_type *tree) h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info, tree->name.name, - TRUE, FALSE, TRUE); + true, false, true); if (!h) - einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n")); + { + if (expld.phase != lang_first_phase_enum) + einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n")); + } else if (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak) { @@ -784,6 +776,18 @@ fold_name (etree_type *tree) expld.assign_src = h; else expld.assign_src = (struct bfd_link_hash_entry *) - 1; + + /* Self-assignment is only allowed for absolute symbols + defined in a linker script. */ + if (expld.assign_name != NULL + && strcmp (expld.assign_name, tree->name.name) == 0 + && !(h != NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && h->u.def.section == bfd_abs_section_ptr + && (def = symbol_defined (tree->name.name)) != NULL + && def->iteration == (lang_statement_iteration & 255))) + expld.assign_name = NULL; } break; @@ -853,7 +857,8 @@ fold_name (etree_type *tree) if (tree->type.node_code == SIZEOF) val = (os->bfd_section->size - / bfd_octets_per_byte (link_info.output_bfd)); + / bfd_octets_per_byte (link_info.output_bfd, + os->bfd_section)); else val = (bfd_vma)1 << os->bfd_section->alignment_power; @@ -866,41 +871,37 @@ fold_name (etree_type *tree) case LENGTH: { - if (expld.phase != lang_first_phase_enum) - { - lang_memory_region_type *mem; - - mem = lang_memory_region_lookup (tree->name.name, FALSE); - if (mem != NULL) - new_number (mem->length); - else - einfo (_("%F%P:%pS: undefined MEMORY region `%s'" - " referenced in expression\n"), - tree, tree->name.name); - } + lang_memory_region_type *mem; + + mem = lang_memory_region_lookup (tree->name.name, false); + if (mem != NULL) + new_number (mem->length); + else + einfo (_("%F%P:%pS: undefined MEMORY region `%s'" + " referenced in expression\n"), + tree, tree->name.name); } break; case ORIGIN: - if (expld.phase != lang_first_phase_enum) - { - lang_memory_region_type *mem; - - mem = lang_memory_region_lookup (tree->name.name, FALSE); - if (mem != NULL) - new_rel_from_abs (mem->origin); - else - einfo (_("%F%P:%pS: undefined MEMORY region `%s'" - " referenced in expression\n"), - tree, tree->name.name); - } + { + lang_memory_region_type *mem; + + mem = lang_memory_region_lookup (tree->name.name, false); + if (mem != NULL) + new_rel_from_abs (mem->origin); + else + einfo (_("%F%P:%pS: undefined MEMORY region `%s'" + " referenced in expression\n"), + tree, tree->name.name); + } break; case CONSTANT: if (strcmp (tree->name.name, "MAXPAGESIZE") == 0) - new_number (config.maxpagesize); + new_number (link_info.maxpagesize); else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0) - new_number (config.commonpagesize); + new_number (link_info.commonpagesize); else einfo (_("%F%P:%pS: unknown constant `%s' referenced in expression\n"), tree, tree->name.name); @@ -914,7 +915,7 @@ fold_name (etree_type *tree) /* Return true if TREE is '.'. */ -static bfd_boolean +static bool is_dot (const etree_type *tree) { return (tree->type.node_class == etree_name @@ -925,7 +926,7 @@ is_dot (const etree_type *tree) /* Return true if TREE is a constant equal to VAL. */ -static bfd_boolean +static bool is_value (const etree_type *tree, bfd_vma val) { return (tree->type.node_class == etree_value @@ -935,7 +936,7 @@ is_value (const etree_type *tree, bfd_vma val) /* Return true if TREE is an absolute symbol equal to VAL defined in a linker script. */ -static bfd_boolean +static bool is_sym_value (const etree_type *tree, bfd_vma val) { struct bfd_link_hash_entry *h; @@ -948,7 +949,7 @@ is_sym_value (const etree_type *tree, bfd_vma val) && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info, tree->name.name, - FALSE, FALSE, TRUE)) != NULL + false, false, true)) != NULL && h->ldscript_def && h->type == bfd_link_hash_defined && h->u.def.section == bfd_abs_section_ptr @@ -957,7 +958,7 @@ is_sym_value (const etree_type *tree, bfd_vma val) /* Return true if TREE is ". != 0". */ -static bfd_boolean +static bool is_dot_ne_0 (const etree_type *tree) { return (tree->type.node_class == etree_binary @@ -969,7 +970,7 @@ is_dot_ne_0 (const etree_type *tree) /* Return true if TREE is ". = . + 0" or ". = . + sym" where sym is an absolute constant with value 0 defined in a linker script. */ -static bfd_boolean +static bool is_dot_plus_0 (const etree_type *tree) { return (tree->type.node_class == etree_binary @@ -981,7 +982,7 @@ is_dot_plus_0 (const etree_type *tree) /* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)". */ -static bfd_boolean +static bool is_align_conditional (const etree_type *tree) { if (tree->type.node_class == etree_unary @@ -992,7 +993,7 @@ is_align_conditional (const etree_type *tree) && is_dot_ne_0 (tree->trinary.cond) && is_value (tree->trinary.rhs, 1)); } - return FALSE; + return false; } static void @@ -1055,9 +1056,9 @@ exp_fold_tree_1 (etree_type *tree) if (expld.phase != lang_first_phase_enum) { /* Notify the folder that this is an assignment to dot. */ - expld.assigning_to_dot = TRUE; + expld.assigning_to_dot = true; exp_fold_tree_1 (tree->assign.src); - expld.assigning_to_dot = FALSE; + expld.assigning_to_dot = false; /* If we are assigning to dot inside an output section arrange to keep the section, except for certain @@ -1126,7 +1127,7 @@ exp_fold_tree_1 (etree_type *tree) if (tree->type.node_class == etree_provide) { h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, - FALSE, FALSE, TRUE); + false, false, true); if (h == NULL || !(h->type == bfd_link_hash_new || h->type == bfd_link_hash_undefined @@ -1155,7 +1156,8 @@ exp_fold_tree_1 (etree_type *tree) converted to absolute values, as is required by many expressions, until final section sizing is complete. */ if (expld.phase == lang_final_phase_enum - || expld.assign_name != NULL) + || expld.phase == lang_fixed_phase_enum + || expld.assign_name != NULL) { if (tree->type.node_class == etree_provide) tree->type.node_class = etree_provided; @@ -1163,7 +1165,7 @@ exp_fold_tree_1 (etree_type *tree) if (h == NULL) { h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, - TRUE, FALSE, TRUE); + true, false, true); if (h == NULL) einfo (_("%F%P:%s: hash creation failed\n"), tree->assign.dst); @@ -1178,46 +1180,65 @@ exp_fold_tree_1 (etree_type *tree) { expld.result.value = 0; expld.result.section = NULL; - expld.result.valid_p = TRUE; + expld.result.valid_p = true; } if (expld.result.valid_p) { if (expld.result.section == NULL) expld.result.section = expld.section; - if (!update_definedness (tree->assign.dst, h) && 0) + if (!update_definedness (tree->assign.dst, h) + && expld.assign_name != NULL) { - /* Symbol was already defined. For now this error - is disabled because it causes failures in the ld - testsuite: ld-elf/var1, ld-scripts/defined5, and - ld-scripts/pr14962. Some of these no doubt - reflect scripts used in the wild. */ + /* Symbol was already defined, and the script isn't + modifying the symbol value for some reason as in + ld-elf/var1 and ld-scripts/pr14962. + For now this is only a warning. */ + unsigned int warn = link_info.warn_multiple_definition; + link_info.warn_multiple_definition = 1; (*link_info.callbacks->multiple_definition) (&link_info, h, link_info.output_bfd, expld.result.section, expld.result.value); + link_info.warn_multiple_definition = warn; + } + if (expld.phase == lang_fixed_phase_enum) + { + if (h->type == bfd_link_hash_defined) + { + expld.result.value = h->u.def.value; + expld.result.section = h->u.def.section; + } + } + else + { + h->type = bfd_link_hash_defined; + h->u.def.value = expld.result.value; + h->u.def.section = expld.result.section; + h->linker_def = ! tree->assign.type.lineno; + h->ldscript_def = 1; + h->rel_from_abs = expld.rel_from_abs; + if (tree->assign.hidden) + bfd_link_hide_symbol (link_info.output_bfd, + &link_info, h); + + /* Copy the symbol type and set non_ir_ref_regular + on the source if this is an expression only + referencing a single symbol. (If the expression + contains ternary conditions, ignoring symbols on + false branches.) */ + if (expld.assign_src != NULL + && (expld.assign_src + != (struct bfd_link_hash_entry *) -1)) + { + bfd_copy_link_hash_symbol_type (link_info.output_bfd, + h, expld.assign_src); + expld.assign_src->non_ir_ref_regular = true; + } } - h->type = bfd_link_hash_defined; - h->u.def.value = expld.result.value; - h->u.def.section = expld.result.section; - h->linker_def = ! tree->assign.type.lineno; - h->ldscript_def = 1; - h->rel_from_abs = expld.rel_from_abs; - if (tree->assign.hidden) - bfd_link_hide_symbol (link_info.output_bfd, - &link_info, h); - - /* Copy the symbol type if this is an expression only - referencing a single symbol. (If the expression - contains ternary conditions, ignoring symbols on - false branches.) */ - if (expld.assign_src != NULL - && (expld.assign_src - != (struct bfd_link_hash_entry *) -1)) - bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, - expld.assign_src); } } - expld.assign_name = NULL; + if (expld.phase != lang_fixed_phase_enum) + expld.assign_name = NULL; } break; @@ -1235,7 +1256,7 @@ exp_fold_tree_1 (etree_type *tree) void exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) { - expld.rel_from_abs = FALSE; + expld.rel_from_abs = false; expld.dot = *dotp; expld.dotp = dotp; expld.section = current_section; @@ -1245,7 +1266,7 @@ exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) void exp_fold_tree_no_dot (etree_type *tree) { - expld.rel_from_abs = FALSE; + expld.rel_from_abs = false; expld.dot = 0; expld.dotp = NULL; expld.section = bfd_abs_section_ptr; @@ -1270,8 +1291,8 @@ exp_value_fold (etree_type *tree) etree_type * exp_binop (int code, etree_type *lhs, etree_type *rhs) { - etree_type *new_e = (etree_type *) stat_alloc (MAX (sizeof (new_e->binary), - sizeof (new_e->value))); + etree_type *new_e = stat_alloc (MAX (sizeof (new_e->binary), + sizeof (new_e->value))); new_e->type.node_code = code; new_e->type.filename = lhs->type.filename; new_e->type.lineno = lhs->type.lineno; @@ -1290,8 +1311,8 @@ exp_binop (int code, etree_type *lhs, etree_type *rhs) etree_type * exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs) { - etree_type *new_e = (etree_type *) stat_alloc (MAX (sizeof (new_e->trinary), - sizeof (new_e->value))); + etree_type *new_e = stat_alloc (MAX (sizeof (new_e->trinary), + sizeof (new_e->value))); new_e->type.node_code = code; new_e->type.filename = cond->type.filename; new_e->type.lineno = cond->type.lineno; @@ -1309,8 +1330,8 @@ exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs) etree_type * exp_unop (int code, etree_type *child) { - etree_type *new_e = (etree_type *) stat_alloc (MAX (sizeof (new_e->unary), - sizeof (new_e->value))); + etree_type *new_e = stat_alloc (MAX (sizeof (new_e->unary), + sizeof (new_e->value))); new_e->unary.type.node_code = code; new_e->unary.type.filename = child->type.filename; new_e->unary.type.lineno = child->type.lineno; @@ -1328,7 +1349,7 @@ exp_unop (int code, etree_type *child) etree_type * exp_nameop (int code, const char *name) { - etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->name)); + etree_type *new_e = stat_alloc (sizeof (new_e->name)); new_e->name.type.node_code = code; new_e->name.type.filename = ldlex_filename (); @@ -1343,11 +1364,11 @@ static etree_type * exp_assop (const char *dst, etree_type *src, enum node_tree_enum class, - bfd_boolean hidden) + bool hidden) { etree_type *n; - n = (etree_type *) stat_alloc (sizeof (n->assign)); + n = stat_alloc (sizeof (n->assign)); n->assign.type.node_code = '='; n->assign.type.filename = src->type.filename; n->assign.type.lineno = src->type.lineno; @@ -1361,7 +1382,7 @@ exp_assop (const char *dst, /* Handle linker script assignments and HIDDEN. */ etree_type * -exp_assign (const char *dst, etree_type *src, bfd_boolean hidden) +exp_assign (const char *dst, etree_type *src, bool hidden) { return exp_assop (dst, src, etree_assign, hidden); } @@ -1371,13 +1392,13 @@ exp_assign (const char *dst, etree_type *src, bfd_boolean hidden) etree_type * exp_defsym (const char *dst, etree_type *src) { - return exp_assop (dst, src, etree_assign, FALSE); + return exp_assop (dst, src, etree_assign, false); } /* Handle PROVIDE. */ etree_type * -exp_provide (const char *dst, etree_type *src, bfd_boolean hidden) +exp_provide (const char *dst, etree_type *src, bool hidden) { return exp_assop (dst, src, etree_provide, hidden); } @@ -1389,7 +1410,7 @@ exp_assert (etree_type *exp, const char *message) { etree_type *n; - n = (etree_type *) stat_alloc (sizeof (n->assert_s)); + n = stat_alloc (sizeof (n->assert_s)); n->assert_s.type.node_code = '!'; n->assert_s.type.filename = exp->type.filename; n->assert_s.type.lineno = exp->type.lineno; @@ -1402,7 +1423,7 @@ exp_assert (etree_type *exp, const char *message) void exp_print_tree (etree_type *tree) { - bfd_boolean function_like; + bool function_like; if (config.map_file == NULL) config.map_file = stderr; @@ -1425,7 +1446,7 @@ exp_print_tree (etree_type *tree) return; case etree_assign: fputs (tree->assign.dst, config.map_file); - exp_print_token (tree->type.node_code, TRUE); + exp_print_token (tree->type.node_code, true); exp_print_tree (tree->assign.src); break; case etree_provide: @@ -1435,7 +1456,7 @@ exp_print_tree (etree_type *tree) fputc (')', config.map_file); break; case etree_binary: - function_like = FALSE; + function_like = false; switch (tree->type.node_code) { case MAX_K: @@ -1443,12 +1464,12 @@ exp_print_tree (etree_type *tree) case ALIGN_K: case DATA_SEGMENT_ALIGN: case DATA_SEGMENT_RELRO_END: - function_like = TRUE; + function_like = true; break; case SEGMENT_START: /* Special handling because arguments are in reverse order and the segment name is quoted. */ - exp_print_token (tree->type.node_code, FALSE); + exp_print_token (tree->type.node_code, false); fputs (" (\"", config.map_file); exp_print_tree (tree->binary.rhs); fputs ("\", ", config.map_file); @@ -1458,7 +1479,7 @@ exp_print_tree (etree_type *tree) } if (function_like) { - exp_print_token (tree->type.node_code, FALSE); + exp_print_token (tree->type.node_code, false); fputc (' ', config.map_file); } fputc ('(', config.map_file); @@ -1466,7 +1487,7 @@ exp_print_tree (etree_type *tree) if (function_like) fprintf (config.map_file, ", "); else - exp_print_token (tree->type.node_code, TRUE); + exp_print_token (tree->type.node_code, true); exp_print_tree (tree->binary.rhs); fputc (')', config.map_file); break; @@ -1478,7 +1499,7 @@ exp_print_tree (etree_type *tree) exp_print_tree (tree->trinary.rhs); break; case etree_unary: - exp_print_token (tree->unary.type.node_code, FALSE); + exp_print_token (tree->unary.type.node_code, false); if (tree->unary.child) { fprintf (config.map_file, " ("); @@ -1498,7 +1519,7 @@ exp_print_tree (etree_type *tree) fputs (tree->name.name, config.map_file); else { - exp_print_token (tree->type.node_code, FALSE); + exp_print_token (tree->type.node_code, false); if (tree->name.name) fprintf (config.map_file, " (%s)", tree->name.name); } @@ -1653,7 +1674,7 @@ ldexp_init (void) SEGMENT_START or ORIGIN) outside of an output section statement, to section relative. */ -static bfd_boolean +static bool set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) { struct definedness_hash_entry *def = (struct definedness_hash_entry *) bh; @@ -1661,7 +1682,7 @@ set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) { struct bfd_link_hash_entry *h; h = bfd_link_hash_lookup (link_info.hash, bh->string, - FALSE, FALSE, TRUE); + false, false, true); if (h != NULL && h->type == bfd_link_hash_defined && h->u.def.section == bfd_abs_section_ptr) @@ -1670,7 +1691,7 @@ set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) h->u.def.section = def->final_sec; } } - return TRUE; + return true; } void @@ -1679,6 +1700,28 @@ ldexp_finalize_syms (void) bfd_hash_traverse (&definedness_table, set_sym_sections, NULL); } +/* Determine whether a symbol is going to remain absolute even after + ldexp_finalize_syms() has run. */ + +bool +ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *h) +{ + if (h->type == bfd_link_hash_defined + && h->u.def.section == bfd_abs_section_ptr) + { + const struct definedness_hash_entry *def; + + if (!h->ldscript_def) + return true; + + def = symbol_defined (h->root.string); + if (def != NULL) + return def->final_sec == bfd_abs_section_ptr; + } + + return false; +} + void ldexp_finish (void) {