bfd/
* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when the signature symbol is global. * elflink.c (elf_link_input_bfd): Ensure group signature symbol is output when ld -r. Set group sh_info when local. * linker.c (default_indirect_link_order): Handle group sections specially. ld/ * ldemul.c (ldemul_place_orphan): Add "name" param. * ldemul.h (ldemul_place_orphan): Update prototype. (struct ld_emulation_xfer_struct <place_orphan>): Likewise. * ldlang.c (lang_place_orphans): Generate unique section names here.. * emultempl/elf32.em (place_orphan): ..rather than here. Don't directly use an existing output section statement that has no bfd section. * emultempl/pe.em (place_orphan): Likewise. * emultempl/pep.em (place_orphan): Likewise. * emultempl/beos.em (place_orphan): Adjust. * emultempl/spuelf.em (spu_place_special_section): Adjust place_orphan call. * emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function. (LDEMUL_AFTER_OPEN): Define.
This commit is contained in:
parent
81ab4297b7
commit
bcacc0f587
@ -1,3 +1,12 @@
|
||||
2008-10-03 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when
|
||||
the signature symbol is global.
|
||||
* elflink.c (elf_link_input_bfd): Ensure group signature symbol
|
||||
is output when ld -r. Set group sh_info when local.
|
||||
* linker.c (default_indirect_link_order): Handle group sections
|
||||
specially.
|
||||
|
||||
2008-09-30 Wesley W. Terpstra <wesley@terpstra.ca>
|
||||
Nick Clifton <nickc@redhat.com>
|
||||
|
||||
|
59
bfd/elf.c
59
bfd/elf.c
@ -2681,13 +2681,15 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
|
||||
*failedptr = TRUE;
|
||||
}
|
||||
|
||||
/* Fill in the contents of a SHT_GROUP section. */
|
||||
/* Fill in the contents of a SHT_GROUP section. Called from
|
||||
_bfd_elf_compute_section_file_positions for gas, objcopy, and
|
||||
when ELF targets use the generic linker, ld. Called for ld -r
|
||||
from bfd_elf_final_link. */
|
||||
|
||||
void
|
||||
bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
|
||||
{
|
||||
bfd_boolean *failedptr = failedptrarg;
|
||||
unsigned long symindx;
|
||||
asection *elt, *first;
|
||||
unsigned char *loc;
|
||||
bfd_boolean gas;
|
||||
@ -2698,20 +2700,49 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
|
||||
|| *failedptr)
|
||||
return;
|
||||
|
||||
symindx = 0;
|
||||
if (elf_group_id (sec) != NULL)
|
||||
symindx = elf_group_id (sec)->udata.i;
|
||||
|
||||
if (symindx == 0)
|
||||
if (elf_section_data (sec)->this_hdr.sh_info == 0)
|
||||
{
|
||||
/* If called from the assembler, swap_out_syms will have set up
|
||||
elf_section_syms; If called for "ld -r", use target_index. */
|
||||
if (elf_section_syms (abfd) != NULL)
|
||||
symindx = elf_section_syms (abfd)[sec->index]->udata.i;
|
||||
else
|
||||
symindx = sec->target_index;
|
||||
unsigned long symindx = 0;
|
||||
|
||||
/* elf_group_id will have been set up by objcopy and the
|
||||
generic linker. */
|
||||
if (elf_group_id (sec) != NULL)
|
||||
symindx = elf_group_id (sec)->udata.i;
|
||||
|
||||
if (symindx == 0)
|
||||
{
|
||||
/* If called from the assembler, swap_out_syms will have set up
|
||||
elf_section_syms. */
|
||||
BFD_ASSERT (elf_section_syms (abfd) != NULL);
|
||||
symindx = elf_section_syms (abfd)[sec->index]->udata.i;
|
||||
}
|
||||
elf_section_data (sec)->this_hdr.sh_info = symindx;
|
||||
}
|
||||
else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
|
||||
{
|
||||
/* The ELF backend linker sets sh_info to -2 when the group
|
||||
signature symbol is global, and thus the index can't be
|
||||
set until all local symbols are output. */
|
||||
asection *igroup = elf_sec_group (elf_next_in_group (sec));
|
||||
struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
|
||||
unsigned long symndx = sec_data->this_hdr.sh_info;
|
||||
unsigned long extsymoff = 0;
|
||||
struct elf_link_hash_entry *h;
|
||||
|
||||
if (!elf_bad_symtab (igroup->owner))
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
|
||||
symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
|
||||
extsymoff = symtab_hdr->sh_info;
|
||||
}
|
||||
h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
|
||||
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;
|
||||
|
||||
elf_section_data (sec)->this_hdr.sh_info = h->indx;
|
||||
}
|
||||
elf_section_data (sec)->this_hdr.sh_info = symindx;
|
||||
|
||||
/* The contents won't be allocated for "ld -r" or objcopy. */
|
||||
gas = TRUE;
|
||||
|
@ -9062,6 +9062,63 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (finfo->info->relocatable
|
||||
&& (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP)
|
||||
{
|
||||
/* Deal with the group signature symbol. */
|
||||
struct bfd_elf_section_data *sec_data = elf_section_data (o);
|
||||
unsigned long symndx = sec_data->this_hdr.sh_info;
|
||||
asection *osec = o->output_section;
|
||||
|
||||
if (symndx >= locsymcount
|
||||
|| (elf_bad_symtab (input_bfd)
|
||||
&& finfo->sections[symndx] == NULL))
|
||||
{
|
||||
struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff];
|
||||
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;
|
||||
/* Arrange for symbol to be output. */
|
||||
h->indx = -2;
|
||||
elf_section_data (osec)->this_hdr.sh_info = -2;
|
||||
}
|
||||
else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION)
|
||||
{
|
||||
/* We'll use the output section target_index. */
|
||||
asection *sec = finfo->sections[symndx]->output_section;
|
||||
elf_section_data (osec)->this_hdr.sh_info = sec->target_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (finfo->indices[symndx] == -1)
|
||||
{
|
||||
/* Otherwise output the local symbol now. */
|
||||
Elf_Internal_Sym sym = isymbuf[symndx];
|
||||
asection *sec = finfo->sections[symndx]->output_section;
|
||||
const char *name;
|
||||
|
||||
name = bfd_elf_string_from_elf_section (input_bfd,
|
||||
symtab_hdr->sh_link,
|
||||
sym.st_name);
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
|
||||
sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
|
||||
sec);
|
||||
if (sym.st_shndx == SHN_BAD)
|
||||
return FALSE;
|
||||
|
||||
sym.st_value += o->output_offset;
|
||||
|
||||
finfo->indices[symndx] = bfd_get_symcount (output_bfd);
|
||||
if (! elf_link_output_sym (finfo, name, &sym, o, NULL))
|
||||
return FALSE;
|
||||
}
|
||||
elf_section_data (osec)->this_hdr.sh_info
|
||||
= finfo->indices[symndx];
|
||||
}
|
||||
}
|
||||
|
||||
if ((o->flags & SEC_HAS_CONTENTS) == 0
|
||||
|| (o->size == 0 && (o->flags & SEC_RELOC) == 0))
|
||||
continue;
|
||||
|
42
bfd/linker.c
42
bfd/linker.c
@ -2796,18 +2796,36 @@ default_indirect_link_order (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
/* Get and relocate the section contents. */
|
||||
sec_size = (input_section->rawsize > input_section->size
|
||||
? input_section->rawsize
|
||||
: input_section->size);
|
||||
contents = bfd_malloc (sec_size);
|
||||
if (contents == NULL && sec_size != 0)
|
||||
goto error_return;
|
||||
new_contents = (bfd_get_relocated_section_contents
|
||||
(output_bfd, info, link_order, contents, info->relocatable,
|
||||
_bfd_generic_link_get_symbols (input_bfd)));
|
||||
if (!new_contents)
|
||||
goto error_return;
|
||||
if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP
|
||||
&& input_section->size != 0)
|
||||
{
|
||||
/* Group section contents are set by bfd_elf_set_group_contents. */
|
||||
if (!output_bfd->output_has_begun)
|
||||
{
|
||||
/* FIXME: This hack ensures bfd_elf_set_group_contents is called. */
|
||||
if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1))
|
||||
goto error_return;
|
||||
}
|
||||
new_contents = output_section->contents;
|
||||
BFD_ASSERT (new_contents != NULL);
|
||||
BFD_ASSERT (input_section->output_offset == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get and relocate the section contents. */
|
||||
sec_size = (input_section->rawsize > input_section->size
|
||||
? input_section->rawsize
|
||||
: input_section->size);
|
||||
contents = bfd_malloc (sec_size);
|
||||
if (contents == NULL && sec_size != 0)
|
||||
goto error_return;
|
||||
new_contents = (bfd_get_relocated_section_contents
|
||||
(output_bfd, info, link_order, contents,
|
||||
info->relocatable,
|
||||
_bfd_generic_link_get_symbols (input_bfd)));
|
||||
if (!new_contents)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Output the section contents. */
|
||||
loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
|
||||
|
17
ld/ChangeLog
17
ld/ChangeLog
@ -1,3 +1,20 @@
|
||||
2008-10-03 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ldemul.c (ldemul_place_orphan): Add "name" param.
|
||||
* ldemul.h (ldemul_place_orphan): Update prototype.
|
||||
(struct ld_emulation_xfer_struct <place_orphan>): Likewise.
|
||||
* ldlang.c (lang_place_orphans): Generate unique section names here..
|
||||
* emultempl/elf32.em (place_orphan): ..rather than here. Don't
|
||||
directly use an existing output section statement that has no
|
||||
bfd section.
|
||||
* emultempl/pe.em (place_orphan): Likewise.
|
||||
* emultempl/pep.em (place_orphan): Likewise.
|
||||
* emultempl/beos.em (place_orphan): Adjust.
|
||||
* emultempl/spuelf.em (spu_place_special_section): Adjust
|
||||
place_orphan call.
|
||||
* emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function.
|
||||
(LDEMUL_AFTER_OPEN): Define.
|
||||
|
||||
2008-09-30 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* emulparams/elf64ppc.sh (OTHER_GOT_RELOC_SECTIONS): Add .rela.opd
|
||||
|
@ -665,9 +665,8 @@ gld_${EMULATION_NAME}_before_allocation (void)
|
||||
which are not mentioned in the linker script. */
|
||||
|
||||
static bfd_boolean
|
||||
gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
|
||||
{
|
||||
const char *secname;
|
||||
char *output_secname, *ps;
|
||||
lang_output_section_statement_type *os;
|
||||
lang_statement_union_type *l;
|
||||
@ -682,8 +681,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
if (link_info.relocatable)
|
||||
return FALSE;
|
||||
|
||||
secname = bfd_get_section_name (s->owner, s);
|
||||
|
||||
/* Everything from the '\$' on gets deleted so don't allow '\$' as the
|
||||
first character. */
|
||||
if (*secname == '\$')
|
||||
|
@ -62,7 +62,7 @@ fragment <<EOF
|
||||
static void gld${EMULATION_NAME}_before_parse (void);
|
||||
static void gld${EMULATION_NAME}_after_open (void);
|
||||
static void gld${EMULATION_NAME}_before_allocation (void);
|
||||
static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s);
|
||||
static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *, const char *);
|
||||
static void gld${EMULATION_NAME}_finish (void);
|
||||
|
||||
EOF
|
||||
@ -1635,7 +1635,7 @@ output_rel_find (asection *sec, int isdyn)
|
||||
sections in the right segment. */
|
||||
|
||||
static bfd_boolean
|
||||
gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
|
||||
{
|
||||
static struct orphan_save hold[] =
|
||||
{
|
||||
@ -1673,15 +1673,12 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
};
|
||||
static int orphan_init_done = 0;
|
||||
struct orphan_save *place;
|
||||
const char *secname;
|
||||
lang_output_section_statement_type *after;
|
||||
lang_output_section_statement_type *os;
|
||||
int isdyn = 0;
|
||||
int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
|
||||
unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
|
||||
|
||||
secname = bfd_get_section_name (s->owner, s);
|
||||
|
||||
if (! link_info.relocatable
|
||||
&& link_info.combreloc
|
||||
&& (s->flags & SEC_ALLOC))
|
||||
@ -1707,28 +1704,24 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
|
||||
{
|
||||
/* Look through the script to see where to place this section. */
|
||||
os = lang_output_section_find (secname);
|
||||
/* Look through the script to see where to place this section. */
|
||||
os = lang_output_section_find (secname);
|
||||
|
||||
if (os != NULL
|
||||
&& (os->bfd_section == NULL
|
||||
|| os->bfd_section->flags == 0
|
||||
|| (_bfd_elf_match_sections_by_type (link_info.output_bfd,
|
||||
os->bfd_section,
|
||||
s->owner, s)
|
||||
&& ((s->flags ^ os->bfd_section->flags)
|
||||
& (SEC_LOAD | SEC_ALLOC)) == 0)))
|
||||
{
|
||||
/* We already have an output section statement with this
|
||||
name, and its bfd section, if any, has compatible flags.
|
||||
If the section already exists but does not have any flags
|
||||
set, then it has been created by the linker, probably as a
|
||||
result of a --section-start command line switch. */
|
||||
lang_add_section (&os->children, s, os);
|
||||
return TRUE;
|
||||
}
|
||||
if (os != NULL
|
||||
&& os->bfd_section != NULL
|
||||
&& (os->bfd_section->flags == 0
|
||||
|| (_bfd_elf_match_sections_by_type (link_info.output_bfd,
|
||||
os->bfd_section, s->owner, s)
|
||||
&& ((s->flags ^ os->bfd_section->flags)
|
||||
& (SEC_LOAD | SEC_ALLOC)) == 0)))
|
||||
{
|
||||
/* We already have an output section statement with this
|
||||
name, and its bfd section has compatible flags.
|
||||
If the section already exists but does not have any flags
|
||||
set, then it has been created by the linker, probably as a
|
||||
result of a --section-start command line switch. */
|
||||
lang_add_section (&os->children, s, os);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!orphan_init_done)
|
||||
@ -1748,7 +1741,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
sections into the .text section to get them out of the way. */
|
||||
if (link_info.executable
|
||||
&& ! link_info.relocatable
|
||||
&& CONST_STRNEQ (secname, ".gnu.warning.")
|
||||
&& CONST_STRNEQ (s->name, ".gnu.warning.")
|
||||
&& hold[orphan_text].os != NULL)
|
||||
{
|
||||
lang_add_section (&hold[orphan_text].os->children, s,
|
||||
@ -1803,18 +1796,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
|
||||
after = &lang_output_section_statement.head->output_section_statement;
|
||||
}
|
||||
|
||||
/* Choose a unique name for the section. This will be needed if the
|
||||
same section name appears in the input file with different
|
||||
loadable or allocatable characteristics. */
|
||||
if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
|
||||
{
|
||||
static int count = 1;
|
||||
secname = bfd_get_unique_section_name (link_info.output_bfd,
|
||||
secname, &count);
|
||||
if (secname == NULL)
|
||||
einfo ("%F%P: place_orphan failed: %E\n");
|
||||
}
|
||||
|
||||
lang_insert_orphan (s, secname, after, place, NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
|
@ -34,7 +34,27 @@ gld${EMULATION_NAME}_finish (void)
|
||||
gld${EMULATION_NAME}_map_segments (FALSE);
|
||||
finish_default ();
|
||||
}
|
||||
|
||||
static void
|
||||
gld${EMULATION_NAME}_after_open (void)
|
||||
{
|
||||
bfd *ibfd;
|
||||
asection *sec;
|
||||
asymbol **syms;
|
||||
|
||||
if (link_info.relocatable)
|
||||
for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||
if ((syms = bfd_get_outsymbols (ibfd)) != NULL
|
||||
&& bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
|
||||
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
|
||||
if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP)
|
||||
{
|
||||
struct bfd_elf_section_data *sec_data = elf_section_data (sec);
|
||||
elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1];
|
||||
}
|
||||
}
|
||||
EOF
|
||||
# Put these extra routines in ld_${EMULATION_NAME}_emulation
|
||||
#
|
||||
LDEMUL_FINISH=gld${EMULATION_NAME}_finish
|
||||
LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
|
||||
|
@ -1613,24 +1613,20 @@ gld_${EMULATION_NAME}_finish (void)
|
||||
sort_sections. */
|
||||
|
||||
static bfd_boolean
|
||||
gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
|
||||
{
|
||||
const char *secname;
|
||||
const char *orig_secname;
|
||||
const char *orig_secname = secname;
|
||||
char *dollar = NULL;
|
||||
lang_output_section_statement_type *os;
|
||||
lang_statement_list_type add_child;
|
||||
|
||||
secname = bfd_get_section_name (s->owner, s);
|
||||
|
||||
/* Look through the script to see where to place this section. */
|
||||
orig_secname = secname;
|
||||
if (!link_info.relocatable
|
||||
&& (dollar = strchr (secname, '$')) != NULL)
|
||||
{
|
||||
size_t len = dollar - orig_secname;
|
||||
size_t len = dollar - secname;
|
||||
char *newname = xmalloc (len + 1);
|
||||
memcpy (newname, orig_secname, len);
|
||||
memcpy (newname, secname, len);
|
||||
newname[len] = '\0';
|
||||
secname = newname;
|
||||
}
|
||||
@ -1640,13 +1636,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
lang_list_init (&add_child);
|
||||
|
||||
if (os != NULL
|
||||
&& (os->bfd_section == NULL
|
||||
|| os->bfd_section->flags == 0
|
||||
&& os->bfd_section != NULL
|
||||
&& (os->bfd_section->flags == 0
|
||||
|| ((s->flags ^ os->bfd_section->flags)
|
||||
& (SEC_LOAD | SEC_ALLOC)) == 0))
|
||||
{
|
||||
/* We already have an output section statement with this
|
||||
name, and its bfd section, if any, has compatible flags.
|
||||
name, and its bfd section has compatible flags.
|
||||
If the section already exists but does not have any flags set,
|
||||
then it has been created by the linker, probably as a result of
|
||||
a --section-start command line switch. */
|
||||
@ -1723,18 +1719,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
->output_section_statement);
|
||||
}
|
||||
|
||||
/* Choose a unique name for the section. This will be needed if the
|
||||
same section name appears in the input file with different
|
||||
loadable or allocatable characteristics. */
|
||||
if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
|
||||
{
|
||||
static int count = 1;
|
||||
secname = bfd_get_unique_section_name (link_info.output_bfd,
|
||||
secname, &count);
|
||||
if (secname == NULL)
|
||||
einfo ("%F%P: place_orphan failed: %E\n");
|
||||
}
|
||||
|
||||
/* All sections in an executable must be aligned to a page boundary. */
|
||||
address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
|
||||
os = lang_insert_orphan (s, secname, after, place, address, &add_child);
|
||||
|
@ -1372,24 +1372,20 @@ gld_${EMULATION_NAME}_finish (void)
|
||||
sort_sections. */
|
||||
|
||||
static bfd_boolean
|
||||
gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
|
||||
{
|
||||
const char *secname;
|
||||
const char *orig_secname;
|
||||
const char *orig_secname = secname;
|
||||
char *dollar = NULL;
|
||||
lang_output_section_statement_type *os;
|
||||
lang_statement_list_type add_child;
|
||||
|
||||
secname = bfd_get_section_name (s->owner, s);
|
||||
|
||||
/* Look through the script to see where to place this section. */
|
||||
orig_secname = secname;
|
||||
if (!link_info.relocatable
|
||||
&& (dollar = strchr (secname, '$')) != NULL)
|
||||
{
|
||||
size_t len = dollar - orig_secname;
|
||||
size_t len = dollar - secname;
|
||||
char *newname = xmalloc (len + 1);
|
||||
memcpy (newname, orig_secname, len);
|
||||
memcpy (newname, secname, len);
|
||||
newname[len] = '\0';
|
||||
secname = newname;
|
||||
}
|
||||
@ -1399,13 +1395,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
lang_list_init (&add_child);
|
||||
|
||||
if (os != NULL
|
||||
&& (os->bfd_section == NULL
|
||||
|| os->bfd_section->flags == 0
|
||||
&& os->bfd_section != NULL
|
||||
&& (os->bfd_section->flags == 0
|
||||
|| ((s->flags ^ os->bfd_section->flags)
|
||||
& (SEC_LOAD | SEC_ALLOC)) == 0))
|
||||
{
|
||||
/* We already have an output section statement with this
|
||||
name, and its bfd section, if any, has compatible flags.
|
||||
name, and its bfd section has compatible flags.
|
||||
If the section already exists but does not have any flags set,
|
||||
then it has been created by the linker, probably as a result of
|
||||
a --section-start command line switch. */
|
||||
@ -1482,18 +1478,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
|
||||
->output_section_statement);
|
||||
}
|
||||
|
||||
/* Choose a unique name for the section. This will be needed if the
|
||||
same section name appears in the input file with different
|
||||
loadable or allocatable characteristics. */
|
||||
if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
|
||||
{
|
||||
static int count = 1;
|
||||
secname = bfd_get_unique_section_name (link_info.output_bfd,
|
||||
secname, &count);
|
||||
if (secname == NULL)
|
||||
einfo ("%F%P: place_orphan failed: %E\n");
|
||||
}
|
||||
|
||||
/* All sections in an executable must be aligned to a page boundary. */
|
||||
address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
|
||||
os = lang_insert_orphan (s, secname, after, place, address, &add_child);
|
||||
|
@ -114,12 +114,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name)
|
||||
|
||||
os = lang_output_section_find (o != NULL ? o->name : output_name);
|
||||
if (os == NULL)
|
||||
{
|
||||
const char *save = s->name;
|
||||
s->name = output_name;
|
||||
gld${EMULATION_NAME}_place_orphan (s);
|
||||
s->name = save;
|
||||
}
|
||||
gld${EMULATION_NAME}_place_orphan (s, output_name);
|
||||
else if (o != NULL && os->children.head != NULL)
|
||||
{
|
||||
lang_statement_list_type add;
|
||||
|
@ -120,10 +120,10 @@ ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search,
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
ldemul_place_orphan (asection *s)
|
||||
ldemul_place_orphan (asection *s, const char *name)
|
||||
{
|
||||
if (ld_emulation->place_orphan)
|
||||
return (*ld_emulation->place_orphan) (s);
|
||||
return (*ld_emulation->place_orphan) (s, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ extern void ldemul_set_symbols
|
||||
extern void ldemul_create_output_section_statements
|
||||
(void);
|
||||
extern bfd_boolean ldemul_place_orphan
|
||||
(asection *);
|
||||
(asection *, const char *);
|
||||
extern bfd_boolean ldemul_parse_args
|
||||
(int, char **);
|
||||
extern void ldemul_add_options
|
||||
@ -152,7 +152,7 @@ typedef struct ld_emulation_xfer_struct {
|
||||
the default action should be taken. This field may be NULL, in
|
||||
which case the default action will always be taken. */
|
||||
bfd_boolean (*place_orphan)
|
||||
(asection *);
|
||||
(asection *, const char *);
|
||||
|
||||
/* Run after assigning parsing with the args, but before
|
||||
reading the script. Used to initialize symbols used in the script. */
|
||||
|
25
ld/ldlang.c
25
ld/ldlang.c
@ -5652,14 +5652,29 @@ lang_place_orphans (void)
|
||||
default_common_section);
|
||||
}
|
||||
}
|
||||
else if (ldemul_place_orphan (s))
|
||||
;
|
||||
else
|
||||
{
|
||||
lang_output_section_statement_type *os;
|
||||
const char *name = s->name;
|
||||
|
||||
os = lang_output_section_statement_lookup (s->name, 0, TRUE);
|
||||
lang_add_section (&os->children, s, os);
|
||||
if ((config.unique_orphan_sections
|
||||
|| unique_section_p (s))
|
||||
&& bfd_get_section_by_name (link_info.output_bfd,
|
||||
name) != NULL)
|
||||
{
|
||||
static int count = 1;
|
||||
name = bfd_get_unique_section_name (link_info.output_bfd,
|
||||
name, &count);
|
||||
if (name == NULL)
|
||||
einfo ("%F%P: place_orphan failed: %E\n");
|
||||
}
|
||||
|
||||
if (!ldemul_place_orphan (s, name))
|
||||
{
|
||||
lang_output_section_statement_type *os;
|
||||
os = lang_output_section_statement_lookup (name, 0,
|
||||
TRUE);
|
||||
lang_add_section (&os->children, s, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user