diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 17 | ||||
-rw-r--r-- | ld/ld.h | 5 | ||||
-rw-r--r-- | ld/ldlang.c | 68 |
4 files changed, 58 insertions, 40 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 7996b23..66b9762 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2012-11-21 Roland McGrath <mcgrathr@google.com> + + * ld.h (ld_config_type): New flag member separate_code. + * emultempl/elf32.em + (gld${EMULATION_NAME}_before_parse): Set it based on $SEPARATE_CODE. + * ldlang.c (ldlang_override_segment_assignment): If it's set, then + always return TRUE when SEC_CODE differs between the sections. + 2012-11-20 H.J. Lu <hongjiu.lu@intel.com> * ld.texinfo: Document "-z global". diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index acb01e5..6c84b82 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -104,6 +104,7 @@ gld${EMULATION_NAME}_before_parse (void) ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`); input_flags.dynamic = ${DYNAMIC_LINK-TRUE}; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; + config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; } EOF @@ -140,7 +141,7 @@ gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry) return FALSE; bfd_elf_set_dyn_lib_class (entry->the_bfd, - (enum dynamic_lib_link_class) link_class); + (enum dynamic_lib_link_class) link_class); /* Continue on with normal load_symbols processing. */ return FALSE; @@ -1104,7 +1105,7 @@ gld${EMULATION_NAME}_after_open (void) { struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd); struct build_id_info *b = - (struct build_id_info *) xmalloc (sizeof *b); + (struct build_id_info *) xmalloc (sizeof *b); b->style = link_info.emit_note_gnu_build_id; b->sec = s; @@ -1439,7 +1440,7 @@ if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; fragment <<EOF /* used by before_allocation and handle_option. */ -static void +static void gld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg) { if (*to == NULL) @@ -1507,7 +1508,7 @@ gld${EMULATION_NAME}_before_allocation (void) { const char *audit_libs = elf_dt_audit (abfd); - /* If the input bfd contains an audit entry, we need to add it as + /* If the input bfd contains an audit entry, we need to add it as a dep audit entry. */ if (audit_libs && *audit_libs != '\0') { @@ -2204,7 +2205,7 @@ EOF if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then fragment <<EOF case OPTION_AUDIT: - gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg); + gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg); break; case 'P': @@ -2393,7 +2394,7 @@ if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then fragment <<EOF fprintf (file, _("\ -P AUDITLIB, --depaudit=AUDITLIB\n" "\ - Specify a library to use for auditing dependencies\n")); + Specify a library to use for auditing dependencies\n")); fprintf (file, _("\ --disable-new-dtags Disable new dynamic tags\n")); fprintf (file, _("\ @@ -2422,7 +2423,7 @@ if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then fragment <<EOF fprintf (file, _("\ -z global Make symbols in DSO available for subsequently\n\ - loaded objects\n")); + loaded objects\n")); fprintf (file, _("\ -z initfirst Mark DSO to be initialized first at runtime\n")); fprintf (file, _("\ @@ -2469,7 +2470,7 @@ fragment <<EOF -z now Mark object non-lazy runtime binding\n")); fprintf (file, _("\ -z origin Mark object requiring immediate \$ORIGIN\n\ - processing at runtime\n")); + processing at runtime\n")); fprintf (file, _("\ -z relro Create RELRO program header\n")); fprintf (file, _("\ @@ -82,7 +82,7 @@ typedef struct name_list { name_list; typedef enum {sort_none, sort_ascending, sort_descending} sort_order; - + /* A wildcard specification. */ typedef enum { @@ -274,6 +274,9 @@ typedef struct { numbers everywhere. */ bfd_boolean sane_expr; + /* If set, code and non-code sections should never be in one segment. */ + bfd_boolean separate_code; + /* The rpath separation character. Usually ':'. */ char rpath_separator; diff --git a/ld/ldlang.c b/ld/ldlang.c index 6802211..750711c 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -878,8 +878,8 @@ walk_wild_file (lang_wild_statement_type *s, if (member->usrdata != NULL) { walk_wild_section (s, - (lang_input_statement_type *) member->usrdata, - callback, data); + (lang_input_statement_type *) member->usrdata, + callback, data); } member = bfd_openr_next_archived_file (f->the_bfd, member); @@ -1050,7 +1050,7 @@ new_afile (const char *name, else { p = (lang_input_statement_type *) - stat_alloc (sizeof (lang_input_statement_type)); + stat_alloc (sizeof (lang_input_statement_type)); p->header.type = lang_input_statement_enum; p->header.next = NULL; } @@ -1148,7 +1148,7 @@ output_section_statement_newfunc (struct bfd_hash_entry *entry, if (entry == NULL) { entry = (struct bfd_hash_entry *) bfd_hash_allocate (table, - sizeof (*ret)); + sizeof (*ret)); if (entry == NULL) return entry; } @@ -1283,12 +1283,12 @@ lang_memory_region_lookup (const char *const name, bfd_boolean create) for (r = lang_memory_region_list; r != NULL; r = r->next) for (n = &r->name_list; n != NULL; n = n->next) if (strcmp (n->name, name) == 0) - { - if (create) - einfo (_("%P:%S: warning: redeclaration of memory region `%s'\n"), - NULL, name); - return r; - } + { + if (create) + einfo (_("%P:%S: warning: redeclaration of memory region `%s'\n"), + NULL, name); + return r; + } if (!create && strcmp (name, DEFAULT_MEMORY_REGION)) einfo (_("%P:%S: warning: memory region `%s' not declared\n"), @@ -1334,19 +1334,19 @@ lang_memory_region_alias (const char * alias, const char * region_name) for (r = lang_memory_region_list; r != NULL; r = r->next) for (n = &r->name_list; n != NULL; n = n->next) { - if (region == NULL && strcmp (n->name, region_name) == 0) - region = r; - if (strcmp (n->name, alias) == 0) - einfo (_("%F%P:%S: error: redefinition of memory region " - "alias `%s'\n"), - NULL, alias); + if (region == NULL && strcmp (n->name, region_name) == 0) + region = r; + if (strcmp (n->name, alias) == 0) + einfo (_("%F%P:%S: error: redefinition of memory region " + "alias `%s'\n"), + NULL, alias); } /* Check if the target region exists. */ if (region == NULL) einfo (_("%F%P:%S: error: memory region `%s' " - "for alias `%s' does not exist\n"), - NULL, region_name, alias); + "for alias `%s' does not exist\n"), + NULL, region_name, alias); /* Add alias to region name list. */ n = (lang_memory_region_name *) stat_alloc (sizeof (lang_memory_region_name)); @@ -1777,7 +1777,7 @@ lang_insert_orphan (asection *s, os_tail = ((lang_output_section_statement_type **) lang_output_section_statement.tail); os = lang_enter_output_section_statement (secname, address, normal_section, - NULL, NULL, NULL, constraint); + NULL, NULL, NULL, constraint); ps = NULL; if (config.build_constructors && *os_tail == os) @@ -2080,14 +2080,14 @@ sort_def_symbol (struct bfd_link_hash_entry *hash_entry, struct map_symbol_def *def; ud = (struct fat_user_section_struct *) - get_userdata (hash_entry->u.def.section); + get_userdata (hash_entry->u.def.section); if (! ud) { /* ??? What do we have to do to initialize this beforehand? */ /* The first time we get here is bfd_abs_section... */ init_map_userdata (0, hash_entry->u.def.section, 0); ud = (struct fat_user_section_struct *) - get_userdata (hash_entry->u.def.section); + get_userdata (hash_entry->u.def.section); } else if (!ud->map_symbol_def_tail) ud->map_symbol_def_tail = &ud->map_symbol_def_head; @@ -2125,7 +2125,7 @@ init_os (lang_output_section_statement_type *s, flagword flags) if (!link_info.reduce_memory_overheads) { fat_section_userdata_type *new_userdata = (fat_section_userdata_type *) - stat_alloc (sizeof (fat_section_userdata_type)); + stat_alloc (sizeof (fat_section_userdata_type)); memset (new_userdata, 0, sizeof (fat_section_userdata_type)); get_userdata (s->bfd_section) = new_userdata; } @@ -2264,7 +2264,7 @@ lang_add_section (lang_statement_list_type *ptr, keep = bfd_lookup_section_flags (&link_info, sflag_info, section); if (!keep) - return; + return; } if (section->output_section != NULL) @@ -4151,7 +4151,7 @@ print_all_symbols (asection *sec) entries[i] = def->entry; qsort (entries, ud->map_symbol_def_count, sizeof (*entries), - hash_entry_addr_cmp); + hash_entry_addr_cmp); /* Print the symbols. */ for (i = 0; i < ud->map_symbol_def_count; i++) @@ -4583,7 +4583,7 @@ insert_pad (lang_statement_union_type **ptr, { /* Make a new padding statement, linked into existing chain. */ pad = (lang_statement_union_type *) - stat_alloc (sizeof (lang_padding_statement_type)); + stat_alloc (sizeof (lang_padding_statement_type)); pad->header.next = *ptr; *ptr = pad; pad->header.type = lang_padding_statement_enum; @@ -5361,6 +5361,12 @@ ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED if (current_section == NULL || previous_section == NULL) return new_segment; + /* If this flag is set, the target never wants code and non-code + sections comingled in the same segment. */ + if (config.separate_code + && ((current_section->flags ^ previous_section->flags) & SEC_CODE)) + return TRUE; + /* Find the memory regions associated with the two sections. We call lang_output_section_find() here rather than scanning the list of output sections looking for a matching section pointer because if @@ -7237,7 +7243,7 @@ lang_record_phdrs (void) { alc *= 2; secs = (asection **) xrealloc (secs, - alc * sizeof (asection *)); + alc * sizeof (asection *)); } secs[c] = os->bfd_section; ++c; @@ -7539,7 +7545,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head, { e.pattern = c_sym; expr = (struct bfd_elf_version_expr *) - htab_find ((htab_t) head->htab, &e); + htab_find ((htab_t) head->htab, &e); while (expr && strcmp (expr->pattern, c_sym) == 0) if (expr->mask == BFD_ELF_VERSION_C_TYPE) goto out_ret; @@ -7552,7 +7558,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head, { e.pattern = cxx_sym; expr = (struct bfd_elf_version_expr *) - htab_find ((htab_t) head->htab, &e); + htab_find ((htab_t) head->htab, &e); while (expr && strcmp (expr->pattern, cxx_sym) == 0) if (expr->mask == BFD_ELF_VERSION_CXX_TYPE) goto out_ret; @@ -7565,7 +7571,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head, { e.pattern = java_sym; expr = (struct bfd_elf_version_expr *) - htab_find ((htab_t) head->htab, &e); + htab_find ((htab_t) head->htab, &e); while (expr && strcmp (expr->pattern, java_sym) == 0) if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE) goto out_ret; @@ -7862,7 +7868,7 @@ lang_register_vers_node (const char *name, if (t->locals.htab && e1->literal) { e2 = (struct bfd_elf_version_expr *) - htab_find ((htab_t) t->locals.htab, e1); + htab_find ((htab_t) t->locals.htab, e1); while (e2 && strcmp (e1->pattern, e2->pattern) == 0) { if (e1->mask == e2->mask) @@ -7889,7 +7895,7 @@ lang_register_vers_node (const char *name, if (t->globals.htab && e1->literal) { e2 = (struct bfd_elf_version_expr *) - htab_find ((htab_t) t->globals.htab, e1); + htab_find ((htab_t) t->globals.htab, e1); while (e2 && strcmp (e1->pattern, e2->pattern) == 0) { if (e1->mask == e2->mask) |