Browse Source

bfd/

* elflink.c (elf_section_ignore_discarded_relocs): Revert last
	change.  Comment.
	(elf_section_complain_discarded): New function.  Handle
	.gcc_except_table too.
	(elf_link_input_bfd): Rewrite handling of relocs against symbols
	in discarded sections.
	* elf-bfd.h (elf_discarded_section): Protect macro arg.
ld/testsuite/
	* ld-discard/extern.d: Update.
	* ld-discard/start.d: Update.
	* ld-discard/static.d: Update.
jimb-rda-nptl-branch
Alan Modra 22 years ago
parent
commit
cdd3575c22
  1. 10
      bfd/ChangeLog
  2. 4
      bfd/elf-bfd.h
  3. 164
      bfd/elflink.c
  4. 6
      ld/testsuite/ChangeLog
  5. 2
      ld/testsuite/ld-discard/extern.d
  6. 2
      ld/testsuite/ld-discard/start.d
  7. 2
      ld/testsuite/ld-discard/static.d

10
bfd/ChangeLog

@ -1,3 +1,13 @@
2004-07-01 Alan Modra <amodra@bigpond.net.au>
* elflink.c (elf_section_ignore_discarded_relocs): Revert last
change. Comment.
(elf_section_complain_discarded): New function. Handle
.gcc_except_table too.
(elf_link_input_bfd): Rewrite handling of relocs against symbols
in discarded sections.
* elf-bfd.h (elf_discarded_section): Protect macro arg.
2004-06-30 James E Wilson <wilson@specifixinc.com>
* elfxx-ia64.c (elfNN_ia64_check_relocs): New local pltoff. Initialize

4
bfd/elf-bfd.h

@ -1067,8 +1067,8 @@ struct bfd_elf_section_data
#define elf_discarded_section(sec) \
(!bfd_is_abs_section (sec) \
&& bfd_is_abs_section ((sec)->output_section) \
&& sec->sec_info_type != ELF_INFO_TYPE_MERGE \
&& sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
&& (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \
&& (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
#define get_elf_backend_data(abfd) \
((const struct elf_backend_data *) (abfd)->xvec->backend_data)

164
bfd/elflink.c

@ -6258,18 +6258,22 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
return TRUE;
}
/* Return TRUE if special handling is done for relocs in SEC against
symbols defined in discarded sections. */
static bfd_boolean
elf_section_ignore_discarded_relocs (asection *sec)
{
const struct elf_backend_data *bed;
if (strncmp (".stab", sec->name, 5) == 0
&& (!sec->name[5] ||
(sec->name[5] == '.' && ISDIGIT (sec->name[6]))))
return TRUE;
if (strcmp (".eh_frame", sec->name) == 0)
return TRUE;
switch (sec->sec_info_type)
{
case ELF_INFO_TYPE_STABS:
case ELF_INFO_TYPE_EH_FRAME:
return TRUE;
default:
break;
}
bed = get_elf_backend_data (sec->owner);
if (bed->elf_backend_ignore_discarded_relocs != NULL
@ -6279,6 +6283,26 @@ elf_section_ignore_discarded_relocs (asection *sec)
return FALSE;
}
/* Return TRUE if we should complain about a reloc in SEC against a
symbol defined in a discarded section. */
static bfd_boolean
elf_section_complain_discarded (asection *sec)
{
if (strncmp (".stab", sec->name, 5) == 0
&& (!sec->name[5] ||
(sec->name[5] == '.' && ISDIGIT (sec->name[6]))))
return FALSE;
if (strcmp (".eh_frame", sec->name) == 0)
return FALSE;
if (strcmp (".gcc_except_table", sec->name) == 0)
return FALSE;
return TRUE;
}
/* Link an input file into the linker output file. This function
handles all the sections and relocations of the input file at once.
This is so that we only have to read the local symbols once, and
@ -6551,99 +6575,87 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
if (!elf_section_ignore_discarded_relocs (o))
{
Elf_Internal_Rela *rel, *relend;
bfd_boolean complain = elf_section_complain_discarded (o);
rel = internal_relocs;
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
for ( ; rel < relend; rel++)
{
unsigned long r_symndx = rel->r_info >> r_sym_shift;
asection *sec;
asection **ps, *sec;
struct elf_link_hash_entry *h = NULL;
const char *sym_name;
if (r_symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
&& finfo->sections[r_symndx] == NULL))
{
struct elf_link_hash_entry *h;
h = sym_hashes[r_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;
/* Complain if the definition comes from a
discarded section. */
sec = h->root.u.def.section;
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& elf_discarded_section (sec))
{
if ((o->flags & SEC_DEBUGGING) != 0)
{
BFD_ASSERT (r_symndx != 0);
/* Try to preserve debug information. */
if (sec->kept_section != NULL
&& sec->size == sec->kept_section->size)
h->root.u.def.section
= sec->kept_section;
else
memset (rel, 0, sizeof (*rel));
}
else
{
char *r_name
= xstrdup (bfd_archive_filename (o->owner));
finfo->info->callbacks->error_handler
(LD_DEFINITION_IN_DISCARDED_SECTION,
_("`%T' referenced in section `%s' from %s: discarded in section `%s' from %s\n"),
h->root.root.string,
h->root.root.string,
o->name, r_name,
h->root.u.def.section->name,
bfd_archive_filename (h->root.u.def.section->owner));
if (r_name)
free (r_name);
}
}
if (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
continue;
ps = &h->root.u.def.section;
sym_name = h->root.root.string;
}
else
{
sec = finfo->sections[r_symndx];
Elf_Internal_Sym *sym = isymbuf + r_symndx;
ps = &finfo->sections[r_symndx];
sym_name = bfd_elf_local_sym_name (input_bfd, sym);
}
if (sec != NULL && elf_discarded_section (sec))
/* Complain if the definition comes from a
discarded section. */
if ((sec = *ps) != NULL && elf_discarded_section (sec))
{
if ((o->flags & SEC_DEBUGGING) != 0)
{
if ((o->flags & SEC_DEBUGGING) != 0)
{
BFD_ASSERT (r_symndx != 0);
/* Try to preserve debug information. */
if (sec->kept_section != NULL
&& sec->size == sec->kept_section->size)
finfo->sections[r_symndx]
= sec->kept_section;
else
{
rel->r_info &= r_type_mask;
rel->r_addend = 0;
}
}
else
BFD_ASSERT (r_symndx != 0);
/* Try to preserve debug information.
FIXME: This is quite broken. Modifying
the symbol here means we will be changing
all uses of the symbol, not just those in
debug sections. The only thing that makes
this half reasonable is that debug sections
tend to come after other sections. Of
course, that doesn't help with globals.
??? All link-once sections of the same name
ought to define the same set of symbols, so
it would seem that globals ought to always
be defined in the kept section. */
if (sec->kept_section != NULL
&& sec->size == sec->kept_section->size)
{
static int count;
int ok;
char *buf;
ok = asprintf (&buf, "local symbol %d",
count++);
if (ok <= 0)
buf = (char *) "local symbol";
finfo->info->callbacks->error_handler
(LD_DEFINITION_IN_DISCARDED_SECTION,
_("`%T' referenced in section `%s': discarded in section `%s' from %s\n"),
buf, buf, o->name, sec->name,
bfd_archive_filename (input_bfd));
if (ok != -1)
free (buf);
*ps = sec->kept_section;
continue;
}
}
else if (complain)
{
finfo->info->callbacks->error_handler
(LD_DEFINITION_IN_DISCARDED_SECTION,
_("`%T' referenced in section `%s' of %B: "
"defined in discarded section `%s' of %B\n"),
sym_name,
sym_name, o->name, input_bfd,
sec->name, sec->owner);
}
/* Remove the symbol reference from the reloc, but
don't kill the reloc completely. This is so that
a zero value will be written into the section,
which may have non-zero contents put there by the
assembler. Zero in things like an eh_frame fde
pc_begin allows stack unwinders to recognize the
fde as bogus. */
rel->r_info &= r_type_mask;
rel->r_addend = 0;
}
}
}

6
ld/testsuite/ChangeLog

@ -1,3 +1,9 @@
2004-07-01 Alan Modra <amodra@bigpond.net.au>
* ld-discard/extern.d: Update.
* ld-discard/start.d: Update.
* ld-discard/static.d: Update.
2004-06-30 H.J. Lu <hongjiu.lu@intel.com>
PR 233

2
ld/testsuite/ld-discard/extern.d

@ -1,3 +1,3 @@
#source: extern.s
#ld: -T discard.ld
#error: `data' referenced in section `\.text' from tmpdir/dump0.o: discarded in section `\.data\.exit' from tmpdir/dump0.o
#error: `data' referenced in section `\.text' of tmpdir/dump0.o: defined in discarded section `\.data\.exit' of tmpdir/dump0.o

2
ld/testsuite/ld-discard/start.d

@ -1,4 +1,4 @@
#source: start.s
#source: exit.s
#ld: -T discard.ld
#error: `data' referenced in section `\.text' from tmpdir/dump0.o: discarded in section `\.data\.exit' from tmpdir/dump1.o
#error: `data' referenced in section `\.text' of tmpdir/dump0.o: defined in discarded section `\.data\.exit' of tmpdir/dump1.o

2
ld/testsuite/ld-discard/static.d

@ -1,3 +1,3 @@
#source: static.s
#ld: -T discard.ld
#error: `local symbol 0' referenced in section `\.text': discarded in section `\.data\.exit' from tmpdir/dump0.o
#error: `\.data\.exit' referenced in section `\.text' of tmpdir/dump0.o: defined in discarded section `\.data\.exit' of tmpdir/dump0.o

Loading…
Cancel
Save