* elfcode.h (elf_fake_sections): Permit .scommon or COMMON sections as random

SHT_NOBITS sections, in case a linker script is strange.
This commit is contained in:
Ken Raeburn
1995-06-08 20:12:25 +00:00
parent 0cd2755006
commit 0ef449dfad
2 changed files with 250 additions and 78 deletions

View File

@ -1,3 +1,26 @@
Wed Jun 7 19:01:30 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
* elfcode.h (elf_fake_sections): Permit .scommon or COMMON
sections as random SHT_NOBITS sections, in case a linker script is
strange.
Tue Jun 6 17:29:32 1995 Steve Chamberlain <sac@slash.cygnus.com>
* bfd-in.h (NT_subsystem, NT_stack_heap): Moved from pe.h
* coff-i386.c (coff_i386_rtype_to_howto): Get PE relocs right.
* coffcode.h (coff_mkobject): Set pe tdata bit when using PE.
* cofflink.c (COFF_WITH_PE code): Test on obj_pe bit rather
than conditional compile.
* configure.in: Fix PE dependencies.
* libcoff-in.h (obj_pe): New.
(coff_tdata): Added pe entry.
* libcoff.h: Regenerated.
Mon Jun 5 09:07:13 1995 Steve Chamberlain <sac@slash.cygnus.com>
* coff-a29k.c (coff_a29k_adjust_symndx): Completely parenthesize
macro. (pr ld/7127)
Mon Jun 5 02:15:20 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com> Mon Jun 5 02:15:20 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
Linker support for m68k-elf from Andreas Schwab Linker support for m68k-elf from Andreas Schwab

View File

@ -111,7 +111,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) #define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto)
#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) #define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel)
#define elf_new_section_hook NAME(bfd_elf,new_section_hook) #define elf_new_section_hook NAME(bfd_elf,new_section_hook)
#define write_relocs NAME(bfd_elf,_write_relocs)
#define elf_find_section NAME(bfd_elf,find_section) #define elf_find_section NAME(bfd_elf,find_section)
#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) #define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols)
#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) #define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry)
@ -155,6 +154,7 @@ static int elf_symbol_from_bfd_symbol PARAMS ((bfd *,
static boolean elf_compute_section_file_positions static boolean elf_compute_section_file_positions
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *));
static boolean prep_headers PARAMS ((bfd *)); static boolean prep_headers PARAMS ((bfd *));
static void write_relocs PARAMS ((bfd *, asection *, PTR));
static void elf_fake_sections PARAMS ((bfd *, asection *, PTR)); static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
static boolean assign_section_numbers PARAMS ((bfd *)); static boolean assign_section_numbers PARAMS ((bfd *));
static file_ptr align_file_position PARAMS ((file_ptr)); static file_ptr align_file_position PARAMS ((file_ptr));
@ -179,6 +179,7 @@ static boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex));
#ifdef DEBUG #ifdef DEBUG
static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *)); static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));
static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *)); static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *));
static char *elf_symbol_flags PARAMS ((flagword));
#endif #endif
#define elf_string_from_elf_strtab(abfd,strindex) \ #define elf_string_from_elf_strtab(abfd,strindex) \
@ -1000,12 +1001,13 @@ elf_symbol_from (ignore_abfd, symbol)
return (elf_symbol_type *) symbol; return (elf_symbol_type *) symbol;
} }
void static void
write_relocs (abfd, sec, xxx) write_relocs (abfd, sec, data)
bfd *abfd; bfd *abfd;
asection *sec; asection *sec;
PTR xxx; PTR data;
{ {
boolean *failedp = (boolean *) data;
Elf_Internal_Shdr *rela_hdr; Elf_Internal_Shdr *rela_hdr;
Elf_External_Rela *outbound_relocas; Elf_External_Rela *outbound_relocas;
Elf_External_Rel *outbound_relocs; Elf_External_Rel *outbound_relocs;
@ -1014,6 +1016,10 @@ write_relocs (abfd, sec, xxx)
asymbol *last_sym = 0; asymbol *last_sym = 0;
int last_sym_idx = 9999999; /* should always be written before use */ int last_sym_idx = 9999999; /* should always be written before use */
/* If we have already failed, don't do anything. */
if (*failedp)
return;
if ((sec->flags & SEC_RELOC) == 0) if ((sec->flags & SEC_RELOC) == 0)
return; return;
@ -1027,11 +1033,12 @@ write_relocs (abfd, sec, xxx)
rela_hdr = &elf_section_data (sec)->rel_hdr; rela_hdr = &elf_section_data (sec)->rel_hdr;
rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
rela_hdr->contents = (void *) bfd_alloc (abfd, rela_hdr->sh_size); rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
if (!rela_hdr->contents) if (rela_hdr->contents == NULL)
{ {
bfd_set_error (bfd_error_no_memory); bfd_set_error (bfd_error_no_memory);
abort (); /* FIXME */ *failedp = true;
return;
} }
/* orelocation has the data, reloc_count has the count... */ /* orelocation has the data, reloc_count has the count... */
@ -1198,7 +1205,9 @@ elf_fake_sections (abfd, asect, failedptrarg)
&& ((asect->flags & SEC_LOAD) == 0)) && ((asect->flags & SEC_LOAD) == 0))
{ {
BFD_ASSERT (strcmp (asect->name, ".bss") == 0 BFD_ASSERT (strcmp (asect->name, ".bss") == 0
|| strcmp (asect->name, ".sbss") == 0); || strcmp (asect->name, ".sbss") == 0
|| strcmp (asect->name, ".scommon") == 0
|| strcmp (asect->name, "COMMON") == 0);
this_hdr->sh_type = SHT_NOBITS; this_hdr->sh_type = SHT_NOBITS;
} }
else else
@ -1440,26 +1449,9 @@ sym_is_global (abfd, sym)
return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global) return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global)
(abfd, sym)); (abfd, sym));
if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
{ || bfd_is_und_section (bfd_get_section (sym))
if (sym->flags & BSF_LOCAL) || bfd_is_com_section (bfd_get_section (sym)));
abort ();
return 1;
}
if (sym->section == 0)
{
/* Is this valid? */
abort ();
return 1;
}
if (bfd_is_und_section (sym->section))
return 1;
if (bfd_is_com_section (sym->section))
return 1;
if (sym->flags & (BSF_LOCAL | BSF_SECTION_SYM | BSF_FILE))
return 0;
return 0;
} }
static boolean static boolean
@ -2053,7 +2045,15 @@ map_program_segments (abfd, off, first, sorted_hdrs, phdr_size)
what we computed here. Actually, it's OK if we allocated too what we computed here. Actually, it's OK if we allocated too
much space in the program header. */ much space in the program header. */
if (phdr_count > phdr_size / sizeof (Elf_External_Phdr)) if (phdr_count > phdr_size / sizeof (Elf_External_Phdr))
abort (); {
((*_bfd_error_handler)
("%s: Not enough room for program headers (allocated %lu, need %u)",
bfd_get_filename (abfd),
(unsigned long) (phdr_size / sizeof (Elf_External_Phdr)),
phdr_count));
bfd_set_error (bfd_error_bad_value);
return (file_ptr) -1;
}
/* Set up program header information. */ /* Set up program header information. */
i_ehdrp = elf_elfheader (abfd); i_ehdrp = elf_elfheader (abfd);
@ -2476,8 +2476,9 @@ swap_out_syms (abfd, sttp)
Elf_Internal_Sym sym; Elf_Internal_Sym sym;
bfd_vma value = syms[idx]->value; bfd_vma value = syms[idx]->value;
elf_symbol_type *type_ptr; elf_symbol_type *type_ptr;
flagword flags = syms[idx]->flags;
if (syms[idx]->flags & BSF_SECTION_SYM) if (flags & BSF_SECTION_SYM)
/* Section symbols have no names. */ /* Section symbols have no names. */
sym.st_name = 0; sym.st_name = 0;
else else
@ -2538,19 +2539,20 @@ swap_out_syms (abfd, sttp)
if (bfd_is_com_section (syms[idx]->section)) if (bfd_is_com_section (syms[idx]->section))
sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT); sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
else if (bfd_is_und_section (syms[idx]->section)) else if (bfd_is_und_section (syms[idx]->section))
sym.st_info = ELF_ST_INFO (STB_GLOBAL, sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
((syms[idx]->flags & BSF_FUNCTION) ? STB_WEAK
: STB_GLOBAL),
((flags & BSF_FUNCTION)
? STT_FUNC ? STT_FUNC
: STT_NOTYPE)); : STT_NOTYPE));
else if (syms[idx]->flags & BSF_SECTION_SYM) else if (flags & BSF_SECTION_SYM)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
else if (syms[idx]->flags & BSF_FILE) else if (flags & BSF_FILE)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
else else
{ {
int bind = STB_LOCAL; int bind = STB_LOCAL;
int type = STT_OBJECT; int type = STT_OBJECT;
unsigned int flags = syms[idx]->flags;
if (flags & BSF_LOCAL) if (flags & BSF_LOCAL)
bind = STB_LOCAL; bind = STB_LOCAL;
@ -2670,6 +2672,7 @@ NAME(bfd_elf,write_object_contents) (abfd)
struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_backend_data *bed = get_elf_backend_data (abfd);
Elf_Internal_Ehdr *i_ehdrp; Elf_Internal_Ehdr *i_ehdrp;
Elf_Internal_Shdr **i_shdrp; Elf_Internal_Shdr **i_shdrp;
boolean failed;
unsigned int count; unsigned int count;
if (! abfd->output_has_begun if (! abfd->output_has_begun
@ -2680,7 +2683,10 @@ NAME(bfd_elf,write_object_contents) (abfd)
i_shdrp = elf_elfsections (abfd); i_shdrp = elf_elfsections (abfd);
i_ehdrp = elf_elfheader (abfd); i_ehdrp = elf_elfheader (abfd);
bfd_map_over_sections (abfd, write_relocs, (PTR) 0); failed = false;
bfd_map_over_sections (abfd, write_relocs, &failed);
if (failed)
return false;
assign_file_positions_for_relocs (abfd); assign_file_positions_for_relocs (abfd);
/* After writing the headers, we need to write the sections too... */ /* After writing the headers, we need to write the sections too... */
@ -2797,14 +2803,13 @@ elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr)
} }
idx = asym_ptr->udata.i; idx = asym_ptr->udata.i;
if (idx == 0) BFD_ASSERT (idx != 0);
abort ();
#if DEBUG & 4 #if DEBUG & 4
{ {
fprintf (stderr, fprintf (stderr,
"elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx %s\n", "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n",
(long) asym_ptr, asym_ptr->name, idx, flags, elf_symbol_flags (flags)); (long) asym_ptr, asym_ptr->name, idx, flags, elf_symbol_flags (flags));
fflush (stderr); fflush (stderr);
} }
@ -3169,7 +3174,7 @@ elf_debug_section (num, hdr)
Elf_Internal_Shdr *hdr; Elf_Internal_Shdr *hdr;
{ {
fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,
hdr->bfd_section != NULL ? hfd->bfd_section->name : "", hdr->bfd_section != NULL ? hdr->bfd_section->name : "",
(long) hdr); (long) hdr);
fprintf (stderr, fprintf (stderr,
"sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n",
@ -3203,6 +3208,78 @@ elf_debug_file (ehdrp)
fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum);
fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize);
} }
static char *
elf_symbol_flags (flags)
flagword flags;
{
static char buffer[1024];
buffer[0] = '\0';
if (flags & BSF_LOCAL)
strcat (buffer, " local");
if (flags & BSF_GLOBAL)
strcat (buffer, " global");
if (flags & BSF_DEBUGGING)
strcat (buffer, " debug");
if (flags & BSF_FUNCTION)
strcat (buffer, " function");
if (flags & BSF_KEEP)
strcat (buffer, " keep");
if (flags & BSF_KEEP_G)
strcat (buffer, " keep_g");
if (flags & BSF_WEAK)
strcat (buffer, " weak");
if (flags & BSF_SECTION_SYM)
strcat (buffer, " section-sym");
if (flags & BSF_OLD_COMMON)
strcat (buffer, " old-common");
if (flags & BSF_NOT_AT_END)
strcat (buffer, " not-at-end");
if (flags & BSF_CONSTRUCTOR)
strcat (buffer, " constructor");
if (flags & BSF_WARNING)
strcat (buffer, " warning");
if (flags & BSF_INDIRECT)
strcat (buffer, " indirect");
if (flags & BSF_FILE)
strcat (buffer, " file");
if (flags & DYNAMIC)
strcat (buffer, " dynamic");
if (flags & ~(BSF_LOCAL
| BSF_GLOBAL
| BSF_DEBUGGING
| BSF_FUNCTION
| BSF_KEEP
| BSF_KEEP_G
| BSF_WEAK
| BSF_SECTION_SYM
| BSF_OLD_COMMON
| BSF_NOT_AT_END
| BSF_CONSTRUCTOR
| BSF_WARNING
| BSF_INDIRECT
| BSF_FILE
| BSF_DYNAMIC))
strcat (buffer, " unknown-bits");
return buffer;
}
#endif #endif
/* Canonicalize the relocs. */ /* Canonicalize the relocs. */
@ -3544,7 +3621,7 @@ elf_core_file_matches_executable_p (core_bfd, exec_bfd)
if (core_prpsinfo (core_bfd)) if (core_prpsinfo (core_bfd))
{ {
corename = (((struct prpsinfo *) core_prpsinfo (core_bfd))->pr_fname); corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
} }
else else
{ {
@ -3865,6 +3942,15 @@ static boolean elf_export_symbol
static boolean elf_adjust_dynamic_symbol static boolean elf_adjust_dynamic_symbol
PARAMS ((struct elf_link_hash_entry *, PTR)); PARAMS ((struct elf_link_hash_entry *, PTR));
/* This struct is used to pass information to routines called via
elf_link_hash_traverse which must return failure. */
struct elf_info_failed
{
boolean failed;
struct bfd_link_info *info;
};
/* Given an ELF BFD, add symbols to the global hash table as /* Given an ELF BFD, add symbols to the global hash table as
appropriate. */ appropriate. */
@ -3882,7 +3968,10 @@ elf_bfd_link_add_symbols (abfd, info)
case bfd_archive: case bfd_archive:
first = bfd_openr_next_archived_file (abfd, (bfd *) NULL); first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
if (first == NULL) if (first == NULL)
return false; {
/* It's OK to have an empty archive. */
return true;
}
if (! bfd_check_format (first, bfd_object)) if (! bfd_check_format (first, bfd_object))
return false; return false;
if (bfd_get_flavour (first) != bfd_target_elf_flavour) if (bfd_get_flavour (first) != bfd_target_elf_flavour)
@ -4204,6 +4293,7 @@ elf_link_add_object_symbols (abfd, info)
{ {
asection *s; asection *s;
const char *name; const char *name;
bfd_size_type oldsize;
bfd_size_type strindex; bfd_size_type strindex;
dynamic = true; dynamic = true;
@ -4290,10 +4380,43 @@ elf_link_add_object_symbols (abfd, info)
} }
/* Add a DT_NEEDED entry for this dynamic object. */ /* Add a DT_NEEDED entry for this dynamic object. */
oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name, strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name,
true, false); true, false);
if (strindex == (bfd_size_type) -1) if (strindex == (bfd_size_type) -1)
goto error_return; goto error_return;
if (oldsize == _bfd_stringtab_size (elf_hash_table (info)->dynstr))
{
asection *sdyn;
Elf_External_Dyn *dyncon, *dynconend;
/* The hash table size did not change, which means that the
dynamic object name was already entered. If we have
already included this dynamic object in the link, just
ignore it. There is no reason to include a particular
dynamic object more than once. */
sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
".dynamic");
BFD_ASSERT (sdyn != NULL);
dyncon = (Elf_External_Dyn *) sdyn->contents;
dynconend = (Elf_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
elf_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon, &dyn);
if (dyn.d_tag == DT_NEEDED
&& dyn.d_un.d_val == strindex)
{
if (buf != NULL)
free (buf);
return true;
}
}
}
if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex)) if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
goto error_return; goto error_return;
} }
@ -4582,7 +4705,7 @@ elf_link_add_object_symbols (abfd, info)
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
h = *hpp; h = *hpp;
if (h != hlook if (h != NULL && h != hlook
&& (h->root.type == bfd_link_hash_defined && (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak) || h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section == slook && h->root.u.def.section == slook
@ -5008,10 +5131,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
asection **sinterpptr; asection **sinterpptr;
{ {
bfd *dynobj; bfd *dynobj;
asection *s;
Elf_Internal_Sym isym;
size_t i;
size_t bucketcount;
struct elf_backend_data *bed; struct elf_backend_data *bed;
*sinterpptr = NULL; *sinterpptr = NULL;
@ -5029,11 +5148,20 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
/* If we are supposed to export all symbols into the dynamic symbol /* If we are supposed to export all symbols into the dynamic symbol
table (this is not the normal case), then do so. */ table (this is not the normal case), then do so. */
if (export_dynamic) if (export_dynamic)
elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol, {
(PTR) info); struct elf_info_failed eif;
eif.failed = false;
eif.info = info;
elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol,
(PTR) &eif);
if (eif.failed)
return false;
}
if (elf_hash_table (info)->dynamic_sections_created) if (elf_hash_table (info)->dynamic_sections_created)
{ {
struct elf_info_failed eif;
bfd_size_type strsize; bfd_size_type strsize;
*sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
@ -5063,9 +5191,13 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
/* Find all symbols which were defined in a dynamic object and make /* Find all symbols which were defined in a dynamic object and make
the backend pick a reasonable value for them. */ the backend pick a reasonable value for them. */
eif.failed = false;
eif.info = info;
elf_link_hash_traverse (elf_hash_table (info), elf_link_hash_traverse (elf_hash_table (info),
elf_adjust_dynamic_symbol, elf_adjust_dynamic_symbol,
(PTR) info); (PTR) &eif);
if (eif.failed)
return false;
/* Add some entries to the .dynamic section. We fill in some of the /* Add some entries to the .dynamic section. We fill in some of the
values later, in elf_bfd_final_link, but we must add the entries values later, in elf_bfd_final_link, but we must add the entries
@ -5101,6 +5233,10 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (elf_hash_table (info)->dynamic_sections_created) if (elf_hash_table (info)->dynamic_sections_created)
{ {
size_t dynsymcount; size_t dynsymcount;
asection *s;
size_t i;
size_t bucketcount;
Elf_Internal_Sym isym;
/* Set the size of the .dynsym and .hash sections. We counted /* Set the size of the .dynsym and .hash sections. We counted
the number of dynamic symbols in elf_link_add_object_symbols. the number of dynamic symbols in elf_link_add_object_symbols.
@ -5171,16 +5307,16 @@ elf_export_symbol (h, data)
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
PTR data; PTR data;
{ {
struct bfd_link_info *info = (struct bfd_link_info *) data; struct elf_info_failed *eif = (struct elf_info_failed *) data;
if (h->dynindx == -1 if (h->dynindx == -1
&& (h->elf_link_hash_flags && (h->elf_link_hash_flags
& (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0) & (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0)
{ {
if (! elf_link_record_dynamic_symbol (info, h)) if (! elf_link_record_dynamic_symbol (eif->info, h))
{ {
/* FIXME: No way to report error. */ eif->failed = true;
abort (); return false;
} }
} }
@ -5196,7 +5332,7 @@ elf_adjust_dynamic_symbol (h, data)
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
PTR data; PTR data;
{ {
struct bfd_link_info *info = (struct bfd_link_info *) data; struct elf_info_failed *eif = (struct elf_info_failed *) data;
bfd *dynobj; bfd *dynobj;
struct elf_backend_data *bed; struct elf_backend_data *bed;
@ -5272,17 +5408,17 @@ elf_adjust_dynamic_symbol (h, data)
/* There is an implicit reference by a regular object file /* There is an implicit reference by a regular object file
via the weak symbol. */ via the weak symbol. */
weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
if (! elf_adjust_dynamic_symbol (weakdef, (PTR) info)) if (! elf_adjust_dynamic_symbol (weakdef, (PTR) eif))
return false; return false;
} }
} }
dynobj = elf_hash_table (info)->dynobj; dynobj = elf_hash_table (eif->info)->dynobj;
bed = get_elf_backend_data (dynobj); bed = get_elf_backend_data (dynobj);
if (! (*bed->elf_backend_adjust_dynamic_symbol) (info, h)) if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
{ {
/* FIXME: No way to return error. */ eif->failed = true;
abort (); return false;
} }
return true; return true;
@ -5343,6 +5479,15 @@ static boolean elf_reloc_link_order
PARAMS ((bfd *, struct bfd_link_info *, asection *, PARAMS ((bfd *, struct bfd_link_info *, asection *,
struct bfd_link_order *)); struct bfd_link_order *));
/* This struct is used to pass information to routines called via
elf_link_hash_traverse which must return failure. */
struct elf_finfo_failed
{
boolean failed;
struct elf_final_link_info *finfo;
};
/* Do the final step of an ELF link. */ /* Do the final step of an ELF link. */
boolean boolean
@ -5366,6 +5511,7 @@ elf_bfd_final_link (abfd, info)
Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *symstrtab_hdr; Elf_Internal_Shdr *symstrtab_hdr;
struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_finfo_failed eif;
if (info->shared) if (info->shared)
abfd->flags |= DYNAMIC; abfd->flags |= DYNAMIC;
@ -5387,9 +5533,7 @@ elf_bfd_final_link (abfd, info)
{ {
finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym");
finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
if (finfo.dynsym_sec == NULL BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL);
|| finfo.hash_sec == NULL)
abort ();
} }
finfo.contents = NULL; finfo.contents = NULL;
finfo.external_relocs = NULL; finfo.external_relocs = NULL;
@ -5702,8 +5846,12 @@ elf_bfd_final_link (abfd, info)
elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1; elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1;
/* We get the global symbols from the hash table. */ /* We get the global symbols from the hash table. */
eif.failed = false;
eif.finfo = &finfo;
elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
(PTR) &finfo); (PTR) &eif);
if (eif.failed)
return false;
/* Flush all symbols to the file. */ /* Flush all symbols to the file. */
if (! elf_link_flush_output_syms (&finfo)) if (! elf_link_flush_output_syms (&finfo))
@ -5832,7 +5980,9 @@ elf_bfd_final_link (abfd, info)
dyn.d_un.d_val += (o->output_section->vma dyn.d_un.d_val += (o->output_section->vma
+ o->output_offset); + o->output_offset);
else else
dyn.d_un.d_val += o->vma; /* The symbol is imported from another shared
library and does not apply to this one. */
dyn.d_un.d_val = 0;
} }
elf_swap_dyn_out (dynobj, &dyn, dyncon); elf_swap_dyn_out (dynobj, &dyn, dyncon);
} }
@ -6068,7 +6218,8 @@ elf_link_output_extsym (h, data)
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
PTR data; PTR data;
{ {
struct elf_final_link_info *finfo = (struct elf_final_link_info *) data; struct elf_finfo_failed *eif = (struct elf_finfo_failed *) data;
struct elf_final_link_info *finfo = eif->finfo;
boolean strip; boolean strip;
Elf_Internal_Sym sym; Elf_Internal_Sym sym;
asection *input_sec; asection *input_sec;
@ -6099,8 +6250,8 @@ elf_link_output_extsym (h, data)
(finfo->info, h->root.root.string, h->root.u.undef.abfd, (finfo->info, h->root.root.string, h->root.u.undef.abfd,
(asection *) NULL, 0))) (asection *) NULL, 0)))
{ {
/* FIXME: No way to return error. */ eif->failed = true;
abort (); return false;
} }
} }
@ -6166,8 +6317,8 @@ elf_link_output_extsym (h, data)
input_sec->output_section); input_sec->output_section);
if (sym.st_shndx == (unsigned short) -1) if (sym.st_shndx == (unsigned short) -1)
{ {
/* FIXME: No way to handle errors. */ eif->failed = true;
abort (); return false;
} }
/* ELF symbols in relocateable files are section relative, /* ELF symbols in relocateable files are section relative,
@ -6221,8 +6372,8 @@ elf_link_output_extsym (h, data)
if (! ((*bed->elf_backend_finish_dynamic_symbol) if (! ((*bed->elf_backend_finish_dynamic_symbol)
(finfo->output_bfd, finfo->info, h, &sym))) (finfo->output_bfd, finfo->info, h, &sym)))
{ {
/* FIXME: No way to return error. */ eif->failed = true;
abort (); return false;
} }
elf_swap_symbol_out (finfo->output_bfd, &sym, elf_swap_symbol_out (finfo->output_bfd, &sym,
@ -6250,8 +6401,8 @@ elf_link_output_extsym (h, data)
if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec)) if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec))
{ {
/* FIXME: No way to return error. */ eif->failed = true;
abort (); return false;
} }
return true; return true;
@ -6549,8 +6700,7 @@ elf_link_input_bfd (finfo, input_bfd)
else else
{ {
r_symndx = sec->output_section->target_index; r_symndx = sec->output_section->target_index;
if (r_symndx == 0) BFD_ASSERT (r_symndx != 0);
abort ();
} }
} }
else else
@ -6732,8 +6882,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
if (link_order->type == bfd_section_reloc_link_order) if (link_order->type == bfd_section_reloc_link_order)
{ {
indx = link_order->u.reloc.p->u.section->target_index; indx = link_order->u.reloc.p->u.section->target_index;
if (indx == 0) BFD_ASSERT (indx != 0);
abort ();
*rel_hash_ptr = NULL; *rel_hash_ptr = NULL;
} }
else else