/* Linker command language support.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-static const char *startup_file;
static const char *entry_symbol_default = "start";
static bfd_boolean placed_commons = FALSE;
static bfd_boolean stripped_excluded_sections = FALSE;
sprintf (symname + (symname[0] != 0), "__start_%s", secname);
e_align = exp_unop (ALIGN_K,
exp_intop ((bfd_vma) 1 << s->alignment_power));
- lang_add_assignment (exp_assop ('=', ".", e_align));
+ lang_add_assignment (exp_assign (".", e_align));
lang_add_assignment (exp_provide (symname,
exp_unop (ABSOLUTE,
exp_nameop (NAME, ".")),
sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
void *info ATTRIBUTE_UNUSED)
{
+ if (hash_entry->type == bfd_link_hash_warning)
+ hash_entry = (struct bfd_link_hash_entry *) hash_entry->u.i.link;
+
if (hash_entry->type == bfd_link_hash_defined
|| hash_entry->type == bfd_link_hash_defweak)
{
}
}
break;
+ case lang_assignment_statement_enum:
+ if (s->assignment_statement.exp->assign.hidden)
+ /* This is from a --defsym on the command line. */
+ exp_fold_tree_no_dot (s->assignment_statement.exp);
+ break;
default:
break;
}
insert_undefined (ptr->name);
}
-typedef struct bfd_sym_chain ldlang_def_chain_list_type;
-
-static ldlang_def_chain_list_type ldlang_def_chain_list_head;
-
-/* Insert NAME as defined in the symbol table. */
-
-static void
-insert_defined (const char *name)
-{
- struct bfd_link_hash_entry *h;
-
- h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE);
- if (h == NULL)
- einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
- if (h->type == bfd_link_hash_new
- || h->type == bfd_link_hash_undefined
- || h->type == bfd_link_hash_undefweak)
- {
- h->type = bfd_link_hash_defined;
- h->u.def.section = bfd_abs_section_ptr;
- h->u.def.value = 0;
- }
-}
-
-/* Like lang_add_undef, but this time for symbols defined on the
- command line. */
-
-static void
-ldlang_add_def (const char *const name)
-{
- if (link_info.output_bfd != NULL)
- insert_defined (xstrdup (name));
- else
- {
- ldlang_def_chain_list_type *new_def;
-
- new_def = (ldlang_def_chain_list_type *) stat_alloc (sizeof (*new_def));
- new_def->next = ldlang_def_chain_list_head.next;
- ldlang_def_chain_list_head.next = new_def;
-
- new_def->name = xstrdup (name);
- }
-}
-
-/* Run through the list of defineds created above and place them
- into the linker hash table as defined symbols belonging to the
- script file. */
-
-static void
-lang_place_defineds (void)
-{
- ldlang_def_chain_list_type *ptr;
-
- for (ptr = ldlang_def_chain_list_head.next;
- ptr != NULL;
- ptr = ptr->next)
- insert_defined (ptr->name);
-}
-
/* Check for all readonly or some readwrite sections. */
static void
switch (rhs->type.node_class)
{
case etree_binary:
- return scan_for_self_assignment (dst, rhs->binary.lhs)
- || scan_for_self_assignment (dst, rhs->binary.rhs);
+ return (scan_for_self_assignment (dst, rhs->binary.lhs)
+ || scan_for_self_assignment (dst, rhs->binary.rhs));
case etree_trinary:
- return scan_for_self_assignment (dst, rhs->trinary.lhs)
- || scan_for_self_assignment (dst, rhs->trinary.rhs);
+ return (scan_for_self_assignment (dst, rhs->trinary.lhs)
+ || scan_for_self_assignment (dst, rhs->trinary.rhs));
case etree_assign:
case etree_provided:
is_dot = (dst[0] == '.' && dst[1] == 0);
tree = assignment->exp->assign.src;
- computation_is_valid = is_dot || (scan_for_self_assignment (dst, tree) == FALSE);
+ computation_is_valid = is_dot || !scan_for_self_assignment (dst, tree);
}
osec = output_section->bfd_section;
lang_reset_memory_regions ();
one_lang_size_sections_pass (relax, check_regions);
}
+ else
+ expld.dataseg.phase = exp_dataseg_done;
}
-
- expld.phase = lang_final_phase_enum;
+ else
+ expld.dataseg.phase = exp_dataseg_done;
}
/* Worker function for lang_do_assignments. Recursiveness goes here. */
/* Add to the hash table all undefineds on the command line. */
lang_place_undefineds ();
- lang_place_defineds ();
if (!bfd_section_already_linked_table_init ())
einfo (_("%P%F: Failed to create hash table\n"));
/* Run through the contours of the script and attach input sections
to the correct output sections. */
+ lang_statement_iteration++;
map_input_to_output_sections (statement_list.head, NULL, NULL);
process_insert_statements ();
/* Do all the assignments, now that we know the final resting places
of all the symbols. */
-
+ expld.phase = lang_final_phase_enum;
lang_do_assignments ();
ldemul_finish ();
{
lang_assignment_statement_type *new_stmt;
- extern int parsing_defsym;
- if (parsing_defsym)
- ldlang_add_def (exp->assign.dst);
-
new_stmt = new_stat (lang_assignment_statement, stat_ptr);
new_stmt->exp = exp;
return new_stmt;
void
lang_startup (const char *name)
{
- if (startup_file != NULL)
+ if (first_file->filename != NULL)
{
einfo (_("%P%F: multiple STARTUP files\n"));
}
first_file->filename = name;
first_file->local_sym_name = name;
first_file->real = TRUE;
-
- startup_file = name;
}
void
overlay region. */
if (overlay_list != NULL)
overlay_list->os->update_dot_tree
- = exp_assop ('=', ".", exp_binop ('+', overlay_vma, overlay_max));
+ = exp_assign (".", exp_binop ('+', overlay_vma, overlay_max));
l = overlay_list;
while (l != NULL)
struct bfd_elf_version_expr *prev,
const char *sym)
{
+ const char *c_sym;
const char *cxx_sym = sym;
const char *java_sym = sym;
struct bfd_elf_version_expr *expr = NULL;
+ enum demangling_styles curr_style;
+
+ curr_style = CURRENT_DEMANGLING_STYLE;
+ cplus_demangle_set_style (no_demangling);
+ c_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_NO_OPTS);
+ if (!c_sym)
+ c_sym = sym;
+ cplus_demangle_set_style (curr_style);
if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
{
- cxx_sym = cplus_demangle (sym, DMGL_PARAMS | DMGL_ANSI);
+ cxx_sym = bfd_demangle (link_info.output_bfd, sym,
+ DMGL_PARAMS | DMGL_ANSI);
if (!cxx_sym)
cxx_sym = sym;
}
if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
{
- java_sym = cplus_demangle (sym, DMGL_JAVA);
+ java_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_JAVA);
if (!java_sym)
java_sym = sym;
}
case 0:
if (head->mask & BFD_ELF_VERSION_C_TYPE)
{
- e.pattern = sym;
+ e.pattern = c_sym;
expr = (struct bfd_elf_version_expr *)
htab_find ((htab_t) head->htab, &e);
- while (expr && strcmp (expr->pattern, sym) == 0)
+ while (expr && strcmp (expr->pattern, c_sym) == 0)
if (expr->mask == BFD_ELF_VERSION_C_TYPE)
goto out_ret;
else
else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
s = cxx_sym;
else
- s = sym;
+ s = c_sym;
if (fnmatch (expr->pattern, s, 0) == 0)
break;
}
out_ret:
+ if (c_sym != sym)
+ free ((char *) c_sym);
if (cxx_sym != sym)
free ((char *) cxx_sym);
if (java_sym != sym)
lang_append_dynamic_list (dynamic);
}
+
+/* Scan a space and/or comma separated string of features. */
+
+void
+lang_ld_feature (char *str)
+{
+ char *p, *q;
+
+ p = str;
+ while (*p)
+ {
+ char sep;
+ while (*p == ',' || ISSPACE (*p))
+ ++p;
+ if (!*p)
+ break;
+ q = p + 1;
+ while (*q && *q != ',' && !ISSPACE (*q))
+ ++q;
+ sep = *q;
+ *q = 0;
+ if (strcasecmp (p, "SANE_EXPR") == 0)
+ config.sane_expr = TRUE;
+ else
+ einfo (_("%X%P: unknown feature `%s'\n"), p);
+ *q = sep;
+ p = q;
+ }
+}