You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02110-1301, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "bfd.h"
#include "sysdep.h"
flags = bed->dynamic_sec_flags;
- s = bfd_make_section (abfd, ".got");
+ s = bfd_make_section_with_flags (abfd, ".got", flags);
if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags)
|| !bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (bed->want_got_plt)
{
- s = bfd_make_section (abfd, ".got.plt");
+ s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags)
|| !bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
}
bh = NULL;
if (!(_bfd_generic_link_add_one_symbol
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
- bed->got_symbol_offset, NULL, FALSE, bed->collect, &bh)))
+ 0, NULL, FALSE, bed->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
h->def_regular = 1;
}
/* The first bit of the global offset table is the header. */
- s->size += bed->got_header_size + bed->got_symbol_offset;
+ s->size += bed->got_header_size;
return TRUE;
}
shared library does not. */
if (info->executable)
{
- s = bfd_make_section (abfd, ".interp");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
+ s = bfd_make_section_with_flags (abfd, ".interp",
+ flags | SEC_READONLY);
+ if (s == NULL)
return FALSE;
}
if (! info->traditional_format)
{
- s = bfd_make_section (abfd, ".eh_frame_hdr");
+ s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, 2))
return FALSE;
elf_hash_table (info)->eh_info.hdr_sec = s;
/* Create sections to hold version informations. These are removed
if they are not needed. */
- s = bfd_make_section (abfd, ".gnu.version_d");
+ s = bfd_make_section_with_flags (abfd, ".gnu.version_d",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
- s = bfd_make_section (abfd, ".gnu.version");
+ s = bfd_make_section_with_flags (abfd, ".gnu.version",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, 1))
return FALSE;
- s = bfd_make_section (abfd, ".gnu.version_r");
+ s = bfd_make_section_with_flags (abfd, ".gnu.version_r",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
- s = bfd_make_section (abfd, ".dynsym");
+ s = bfd_make_section_with_flags (abfd, ".dynsym",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
- s = bfd_make_section (abfd, ".dynstr");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
+ s = bfd_make_section_with_flags (abfd, ".dynstr",
+ flags | SEC_READONLY);
+ if (s == NULL)
return FALSE;
- s = bfd_make_section (abfd, ".dynamic");
+ s = bfd_make_section_with_flags (abfd, ".dynamic", flags);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
- s = bfd_make_section (abfd, ".hash");
+ s = bfd_make_section_with_flags (abfd, ".hash",
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
- s = bfd_make_section (abfd, ".plt");
+ s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, pltflags)
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
return FALSE;
}
- s = bfd_make_section (abfd,
- bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
+ s = bfd_make_section_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
image and use a R_*_COPY reloc to tell the dynamic linker to
initialize them at run time. The linker script puts the .dynbss
section into the .bss section of the final image. */
- s = bfd_make_section (abfd, ".dynbss");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
+ s = bfd_make_section_with_flags (abfd, ".dynbss",
+ (SEC_ALLOC
+ | SEC_LINKER_CREATED));
+ if (s == NULL)
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
copy relocs. */
if (! info->shared)
{
- s = bfd_make_section (abfd,
- (bed->default_use_rela_p
- ? ".rela.bss" : ".rel.bss"));
+ s = bfd_make_section_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
}
this in case some dynamic object refers to this symbol. */
bfd_boolean
-bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info,
+bfd_elf_record_link_assignment (struct bfd_link_info *info,
const char *name,
bfd_boolean provide)
{
if (h->type == STT_TLS)
{
- ntbfd = abfd;
+ ntbfd = abfd;
ntsec = sec;
ntdef = newdef;
tbfd = oldbfd;
/* Handle the special case of an old common symbol merging with a
new symbol which looks like a common symbol in a shared object.
We change *PSEC and *PVALUE to make the new symbol look like a
- common symbol, and let _bfd_generic_link_add_one_symbol will do
- the right thing. */
+ common symbol, and let _bfd_generic_link_add_one_symbol do the
+ right thing. */
if (newdyncommon
&& h->root.type == bfd_link_hash_common)
d = (*t->match) (&t->locals, NULL, alc);
if (d != NULL
&& h->dynindx != -1
- && info->shared
&& ! info->export_dynamic)
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
}
{
h->verinfo.vertree = local_ver;
if (h->dynindx != -1
- && info->shared
&& ! info->export_dynamic)
{
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
_bfd_elf_link_output_relocs (bfd *output_bfd,
asection *input_section,
Elf_Internal_Shdr *input_rel_hdr,
- Elf_Internal_Rela *internal_relocs)
+ Elf_Internal_Rela *internal_relocs,
+ struct elf_link_hash_entry **rel_hash
+ ATTRIBUTE_UNUSED)
{
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
if (h->root.type == bfd_link_hash_warning)
{
- h->plt = elf_hash_table (eif->info)->init_offset;
- h->got = elf_hash_table (eif->info)->init_offset;
+ h->got = elf_hash_table (eif->info)->init_got_offset;
+ h->plt = elf_hash_table (eif->info)->init_plt_offset;
/* When warning symbols are created, they **replace** the "real"
entry in the hash table, thus we never get to see the real
|| (!h->ref_regular
&& (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1))))
{
- h->plt = elf_hash_table (eif->info)->init_offset;
+ h->plt = elf_hash_table (eif->info)->init_plt_offset;
return TRUE;
}
else if (sec->kept_section)
{
/* Symbols from discarded section are undefined, and have
- default visibility. */
+ default visibility. */
sec = bfd_und_section_ptr;
isym->st_shndx = SHN_UNDEF;
isym->st_other = STV_DEFAULT
if (tcomm == NULL)
{
- tcomm = bfd_make_section (abfd, ".tcommon");
- if (tcomm == NULL
- || !bfd_set_section_flags (abfd, tcomm, (SEC_ALLOC
- | SEC_IS_COMMON
- | SEC_LINKER_CREATED
- | SEC_THREAD_LOCAL)))
+ tcomm = bfd_make_section_with_flags (abfd, ".tcommon",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED
+ | SEC_THREAD_LOCAL));
+ if (tcomm == NULL)
goto error_free_vers;
}
sec = tcomm;
/* If this is a hidden symbol, or if it is not version
1, we append the version name to the symbol name.
- However, we do not modify a non-hidden absolute
- symbol, because it might be the version symbol
- itself. FIXME: What if it isn't? */
+ However, we do not modify a non-hidden absolute symbol
+ if it is not a function, because it might be the version
+ symbol itself. FIXME: What if it isn't? */
if ((iver.vs_vers & VERSYM_HIDDEN) != 0
- || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ || (vernum > 1 && (! bfd_is_abs_section (sec)
+ || ELF_ST_TYPE (isym->st_info) == STT_FUNC)))
{
const char *verstr;
size_t namelen, verlen, newlen;
/* Any syms created from now on start with -1 in
got.refcount/offset and plt.refcount/offset. */
- elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset;
+ elf_hash_table (info)->init_got_refcount
+ = elf_hash_table (info)->init_got_offset;
+ elf_hash_table (info)->init_plt_refcount
+ = elf_hash_table (info)->init_plt_offset;
/* The backend may have to create some sections regardless of whether
we're dynamic or not. */
{
bfd_size_type indx;
- name = basename (output_bfd->filename);
+ name = lbasename (output_bfd->filename);
def.vd_hash = bfd_elf_hash (name);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
name, FALSE);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
elf_dt_name (t->vn_bfd) != NULL
? elf_dt_name (t->vn_bfd)
- : basename (t->vn_bfd->filename),
+ : lbasename (t->vn_bfd->filename),
FALSE);
if (indx == (bfd_size_type) -1)
return FALSE;
{
(*_bfd_error_handler)
(_("%B: %s symbol `%s' in %B is referenced by DSO"),
- finfo->output_bfd, h->root.u.def.section->owner,
+ finfo->output_bfd,
+ h->root.u.def.section == bfd_abs_section_ptr
+ ? finfo->output_bfd : h->root.u.def.section->owner,
ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
? "internal"
: ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
return TRUE;
emit_relocs = (finfo->info->relocatable
- || finfo->info->emitrelocations
- || bed->elf_backend_emit_relocs);
+ || finfo->info->emitrelocations);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (elf_bad_symtab (input_bfd))
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
-
+
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
{
BFD_ASSERT (r_symndx != 0);
if (action & COMPLAIN)
- {
- (*_bfd_error_handler)
- (_("`%s' referenced in section `%A' of %B: "
- "defined in discarded section `%A' of %B"),
- o, input_bfd, sec, sec->owner, sym_name);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
+ (*finfo->info->callbacks->einfo)
+ (_("%X`%s' referenced in section `%A' of %B: "
+ "defined in discarded section `%A' of %B"),
+ sym_name, o, input_bfd, sec, sec->owner);
/* Try to do the best we can to support buggy old
versions of gcc. If we've warned, or this is
Elf_Internal_Rela *irelaend;
bfd_vma last_offset;
struct elf_link_hash_entry **rel_hash;
+ struct elf_link_hash_entry **rel_hash_list;
Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
unsigned int next_erel;
- bfd_boolean (*reloc_emitter)
- (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *);
bfd_boolean rela_normal;
input_rel_hdr = &elf_section_data (o)->rel_hdr;
rel_hash = (elf_section_data (o->output_section)->rel_hashes
+ elf_section_data (o->output_section)->rel_count
+ elf_section_data (o->output_section)->rel_count2);
+ rel_hash_list = rel_hash;
last_offset = o->output_offset;
if (!finfo->info->relocatable)
last_offset += o->output_section->vma;
}
/* Swap out the relocs. */
- if (bed->elf_backend_emit_relocs
- && !(finfo->info->relocatable
- || finfo->info->emitrelocations))
- reloc_emitter = bed->elf_backend_emit_relocs;
- else
- reloc_emitter = _bfd_elf_link_output_relocs;
-
if (input_rel_hdr->sh_size != 0
- && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
- internal_relocs))
+ && !bed->elf_backend_emit_relocs (output_bfd, o,
+ input_rel_hdr,
+ internal_relocs,
+ rel_hash_list))
return FALSE;
input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
{
internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel);
- if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2,
- internal_relocs))
+ rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
+ if (!bed->elf_backend_emit_relocs (output_bfd, o,
+ input_rel_hdr2,
+ internal_relocs,
+ rel_hash_list))
return FALSE;
}
}
struct bfd_link_order **sections;
asection *s;
bfd_vma offset;
-
+
seen_other = 0;
seen_linkorder = 0;
for (p = o->map_head.link_order; p != NULL; p = p->next)
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
-
+
sections = (struct bfd_link_order **)
xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
seen_linkorder = 0;
-
+
for (p = o->map_head.link_order; p != NULL; p = p->next)
{
sections[seen_linkorder++] = p;
gc_mark_hook_fn gc_mark_hook)
{
bfd_boolean ret;
+ bfd_boolean is_eh;
asection *group_sec;
sec->gc_mark = 1;
/* Look through the section relocs. */
ret = TRUE;
+ is_eh = strcmp (sec->name, ".eh_frame") == 0;
if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
{
Elf_Internal_Rela *relstart, *rel, *relend;
{
if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
rsec->gc_mark = 1;
+ else if (is_eh)
+ rsec->gc_mark_from_eh = 1;
else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
{
ret = FALSE;
if (o->gc_mark)
continue;
+ /* Keep .gcc_except_table.* if the associated .text.* is
+ marked. This isn't very nice, but the proper solution,
+ splitting .eh_frame up and using comdat doesn't pan out
+ easily due to needing special relocs to handle the
+ difference of two symbols in separate sections.
+ Don't keep code sections referenced by .eh_frame. */
+ if (o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
+ {
+ if (strncmp (o->name, ".gcc_except_table.", 18) == 0)
+ {
+ unsigned long len;
+ char *fn_name;
+ asection *fn_text;
+
+ len = strlen (o->name + 18) + 1;
+ fn_name = bfd_malloc (len + 6);
+ if (fn_name == NULL)
+ return FALSE;
+ memcpy (fn_name, ".text.", 6);
+ memcpy (fn_name + 6, o->name + 18, len);
+ fn_text = bfd_get_section_by_name (sub, fn_name);
+ free (fn_name);
+ if (fn_text != NULL && fn_text->gc_mark)
+ o->gc_mark = 1;
+ }
+
+ /* If not using specially named exception table section,
+ then keep whatever we are using. */
+ else
+ o->gc_mark = 1;
+
+ if (o->gc_mark)
+ continue;
+ }
+
/* Skip sweeping sections already excluded. */
if (o->flags & SEC_EXCLUDE)
continue;
/* But we also have to update some of the relocation
info we collected before. */
if (gc_sweep_hook
- && (o->flags & SEC_RELOC) && o->reloc_count > 0)
+ && (o->flags & SEC_RELOC) != 0
+ && o->reloc_count > 0
+ && !bfd_is_abs_section (o->output_section))
{
Elf_Internal_Rela *internal_relocs;
bfd_boolean r;
return TRUE;
}
-
-/* Mark sections containing global symbols. This is called through
- elf_link_hash_traverse. */
-static bfd_boolean
-elf_mark_used_section (struct elf_link_hash_entry *h,
- void *data ATTRIBUTE_UNUSED)
-{
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- if (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- {
- asection *s = h->root.u.def.section;
- if (s != NULL && s->output_section != NULL)
- s->output_section->flags |= SEC_KEEP;
- }
-
- return TRUE;
-}
-
/* Do mark and sweep of unused sections. */
bfd_boolean
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *h, Elf_Internal_Sym *);
- if (!info->gc_sections)
- {
- /* If we are called when info->gc_sections is 0, we will mark
- all sections containing global symbols for non-relocatable
- link. */
- if (!info->relocatable)
- elf_link_hash_traverse (elf_hash_table (info),
- elf_mark_used_section, NULL);
- return TRUE;
- }
-
if (!get_elf_backend_data (abfd)->can_gc_sections
|| info->relocatable
|| info->emitrelocations
continue;
for (o = sub->sections; o != NULL; o = o->next)
- {
- if (o->flags & SEC_KEEP)
- {
- /* _bfd_elf_discard_section_eh_frame knows how to discard
- orphaned FDEs so don't mark sections referenced by the
- EH frame section. */
- if (strcmp (o->name, ".eh_frame") == 0)
- o->gc_mark = 1;
- else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
- return FALSE;
- }
- }
+ if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark)
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
}
/* ... and mark SEC_EXCLUDE for those that go. */
which we are really going to use. */
sec->output_section = bfd_abs_section_ptr;
sec->kept_section = l->sec;
-
+
if (flags & SEC_GROUP)
{
asection *first = elf_next_in_group (sec);
}
static void
-bfd_elf_set_symbol (struct elf_link_hash_entry *h, bfd_vma val)
+bfd_elf_set_symbol (struct elf_link_hash_entry *h, bfd_vma val,
+ struct bfd_section *s)
{
h->root.type = bfd_link_hash_defined;
- h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.section = s ? s : bfd_abs_section_ptr;
h->root.u.def.value = val;
h->def_regular = 1;
h->type = STT_OBJECT;
h->forced_local = 1;
}
-/* Set NAME to VAL if the symbol exists and is undefined. */
+/* Set NAME to VAL if the symbol exists and is not defined in a regular
+ object file. If S is NULL it is an absolute symbol, otherwise it is
+ relative to that section. */
void
_bfd_elf_provide_symbol (struct bfd_link_info *info, const char *name,
- bfd_vma val)
+ bfd_vma val, struct bfd_section *s)
{
struct elf_link_hash_entry *h;
- h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE,
- FALSE);
- if (h != NULL && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak))
- bfd_elf_set_symbol (h, val);
+ bfd_elf_record_link_assignment (info, name, TRUE);
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+ if (h != NULL
+ && !(h->root.type == bfd_link_hash_defined
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section != h->root.u.def.section->output_section))
+ bfd_elf_set_symbol (h, val, s);
}
-/* Set START and END to boundaries of SEC if they exist and are
- undefined. */
+/* Set START and END to boundaries of SEC if they exist and are not
+ defined in regular object files. */
void
_bfd_elf_provide_section_bound_symbols (struct bfd_link_info *info,
const char *start,
const char *end)
{
- struct elf_link_hash_entry *hs, *he;
- bfd_vma start_val, end_val;
- bfd_boolean do_start, do_end;
-
- /* Check if we need them or not first. */
- hs = elf_link_hash_lookup (elf_hash_table (info), start, FALSE,
- FALSE, FALSE);
- do_start = (hs != NULL
- && (hs->root.type == bfd_link_hash_undefined
- || hs->root.type == bfd_link_hash_undefweak));
-
- he = elf_link_hash_lookup (elf_hash_table (info), end, FALSE,
- FALSE, FALSE);
- do_end = (he != NULL
- && (he->root.type == bfd_link_hash_undefined
- || he->root.type == bfd_link_hash_undefweak));
-
- if (!do_start && !do_end)
- return;
-
+ bfd_vma val = 0;
+ _bfd_elf_provide_symbol (info, start, val, sec);
if (sec != NULL)
+ val = sec->size;
+ _bfd_elf_provide_symbol (info, end, val, sec);
+}
+
+/* Convert symbols in excluded output sections to absolute. */
+
+static bfd_boolean
+fix_syms (struct bfd_link_hash_entry *h, void *data)
+{
+ bfd *obfd = (bfd *) data;
+
+ if (h->type == bfd_link_hash_warning)
+ h = h->u.i.link;
+
+ if (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
{
- start_val = sec->vma;
- end_val = start_val + sec->size;
- }
- else
- {
- /* We have to choose those values very carefully. Some targets,
- like alpha, may have relocation overflow with 0. "_edata"
- should be defined in all cases. */
- struct elf_link_hash_entry *h
- = elf_link_hash_lookup (elf_hash_table (info), "_edata",
- FALSE, FALSE, FALSE);
- if (h != NULL && h->root.type == bfd_link_hash_defined)
- start_val = h->root.u.def.value;
- else
- start_val = 0;
- end_val = start_val;
+ asection *s = h->u.def.section;
+ if (s != NULL
+ && s == s->output_section
+ && bfd_section_removed_from_list (obfd, s))
+ {
+ h->u.def.value += s->vma;
+ h->u.def.section = bfd_abs_section_ptr;
+ }
}
- if (do_start)
- bfd_elf_set_symbol (hs, start_val);
+ return TRUE;
+}
- if (do_end)
- bfd_elf_set_symbol (he, end_val);
+void
+_bfd_elf_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
+{
+ bfd_link_hash_traverse (info->hash, fix_syms, obfd);
}