/* BFD back-end for PDP-11 a.out binaries.
- Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
-static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, bfd_boolean *);
+static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, bfd_boolean *);
static bfd_boolean aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
static bfd_boolean aout_link_add_symbols (bfd *, struct bfd_link_info *);
static bfd_boolean aout_link_write_symbols (struct aout_final_link_info *, bfd *);
if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0
|| !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
|| bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0
- || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
return FALSE;
}
bfd_boolean
NAME (aout, find_nearest_line) (bfd *abfd,
- asection *section,
asymbol **symbols,
+ asection *section,
bfd_vma offset,
const char **filename_ptr,
const char **functionname_ptr,
- unsigned int *line_ptr)
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
{
/* Run down the file looking for the filename, function and linenumber. */
asymbol **p;
*filename_ptr = abfd->filename;
*functionname_ptr = 0;
*line_ptr = 0;
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
if (symbols != NULL)
{
struct aout_link_hash_table *ret;
bfd_size_type amt = sizeof (struct aout_link_hash_table);
- ret = bfd_alloc (abfd, amt);
+ ret = bfd_malloc (amt);
if (ret == NULL)
return NULL;
if (! NAME (aout, link_hash_table_init) (ret, abfd,
static bfd_boolean
aout_link_check_archive_element (bfd *abfd,
struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
bfd_boolean *pneeded)
{
bfd *oldbfd;
aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
{
struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
- struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
+ struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
bfd *output_bfd;
int type;
bfd_vma val;
return TRUE;
}
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
{
if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
- (output_bfd, finfo->info, h)))
+ (output_bfd, flaginfo->info, h)))
{
/* FIXME: No way to handle errors. */
abort ();
/* An indx of -2 means the symbol must be written. */
if (h->indx != -2
- && (finfo->info->strip == strip_all
- || (finfo->info->strip == strip_some
- && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
FALSE, FALSE) == NULL)))
return TRUE;
}
H_PUT_8 (output_bfd, type, outsym.e_type);
- indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
+ indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
FALSE);
if (indx == (bfd_size_type) -1)
/* FIXME: No way to handle errors. */
PUT_WORD (output_bfd, val, outsym.e_value);
amt = EXTERNAL_NLIST_SIZE;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
|| bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
/* FIXME: No way to handle errors. */
abort ();
- finfo->symoff += amt;
+ flaginfo->symoff += amt;
h->indx = obj_aout_external_sym_count (output_bfd);
++obj_aout_external_sym_count (output_bfd);
/* Handle a link order which is supposed to generate a reloc. */
static bfd_boolean
-aout_link_reloc_link_order (struct aout_final_link_info *finfo,
+aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
asection *o,
struct bfd_link_order *p)
{
r_index = N_ABS | N_EXT;
else
{
- BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
+ BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
r_index = pr->u.section->target_index;
}
}
BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
r_extern = 1;
h = ((struct aout_link_hash_entry *)
- bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
+ bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
pr->u.name, FALSE, FALSE, TRUE));
if (h != NULL
&& h->indx >= 0)
symbol. */
h->indx = -2;
h->written = FALSE;
- if (!aout_link_write_other_symbol (&h->root.root, finfo))
+ if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
return FALSE;
r_index = h->indx;
}
else
{
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
return FALSE;
r_index = 0;
}
}
- howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
+ howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
if (howto == 0)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
- if (o == obj_textsec (finfo->output_bfd))
- reloff_ptr = &finfo->treloff;
- else if (o == obj_datasec (finfo->output_bfd))
- reloff_ptr = &finfo->dreloff;
+ if (o == obj_textsec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->treloff;
+ else if (o == obj_datasec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->dreloff;
else
abort ();
#ifdef MY_put_reloc
- MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
+ MY_put_reloc(flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
&srel);
#else
{
r_relative = (howto->type & 32) != 0;
r_length = howto->size;
- PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
- if (bfd_header_big_endian (finfo->output_bfd))
+ PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (flaginfo->output_bfd))
{
srel.r_index[0] = r_index >> 16;
srel.r_index[1] = r_index >> 8;
buf = bfd_zmalloc (size);
if (buf == NULL)
return FALSE;
- r = MY_relocate_contents (howto, finfo->output_bfd,
+ r = MY_relocate_contents (howto, flaginfo->output_bfd,
pr->addend, buf);
switch (r)
{
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, NULL,
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
(p->type == bfd_section_reloc_link_order
- ? bfd_section_name (finfo->output_bfd,
+ ? bfd_section_name (flaginfo->output_bfd,
pr->u.section)
: pr->u.name),
howto->name, pr->addend, NULL,
}
break;
}
- ok = bfd_set_section_contents (finfo->output_bfd, o,
+ ok = bfd_set_section_contents (flaginfo->output_bfd, o,
(void *) buf,
(file_ptr) p->offset,
size);
return FALSE;
}
- rel_size = obj_reloc_entry_size (finfo->output_bfd);
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
- || bfd_bwrite (rel_ptr, rel_size, finfo->output_bfd) != rel_size)
+ rel_size = obj_reloc_entry_size (flaginfo->output_bfd);
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || bfd_bwrite (rel_ptr, rel_size, flaginfo->output_bfd) != rel_size)
return FALSE;
*reloff_ptr += rel_size;
/* Assert that the relocs have not run into the symbols, and that n
the text relocs have not run into the data relocs. */
- BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
- && (reloff_ptr != &finfo->treloff
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
return TRUE;
}
}
static bfd_boolean
-pdp11_aout_link_input_section (struct aout_final_link_info *finfo,
+pdp11_aout_link_input_section (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
bfd_byte *relocs,
bfd_byte *rel;
bfd_byte *rel_end;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder
== output_bfd->xvec->header_byteorder);
- relocatable = finfo->info->relocatable;
+ relocatable = flaginfo->info->relocatable;
syms = obj_aout_external_syms (input_bfd);
strings = obj_aout_external_strings (input_bfd);
sym_hashes = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
rel = relocs;
rel_end = rel + rel_size;
h->indx = -2;
h->written = FALSE;
if (!aout_link_write_other_symbol (&h->root.root,
- finfo))
+ flaginfo))
return FALSE;
}
r_index = h->indx;
name = strings + GET_WORD (input_bfd,
syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr)))
return FALSE;
r_index = 0;
bfd_boolean skip;
if (! ((*check_dynamic_reloc)
- (finfo->info, input_bfd, input_section, h,
+ (flaginfo->info, input_bfd, input_section, h,
(void *) rel, contents, &skip, &relocation)))
return FALSE;
if (skip)
/* Now warn if a global symbol is undefined. We could not
do this earlier, because check_dynamic_reloc might want
to skip this reloc. */
- if (hundef && ! finfo->info->shared)
+ if (hundef && ! flaginfo->info->shared)
{
const char *name;
name = h->root.root.string;
else
name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->undefined_symbol)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr, TRUE)))
return FALSE;
}
s = aout_reloc_type_to_section (input_bfd, r_type);
name = bfd_section_name (input_bfd, s);
}
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, (h ? &h->root : NULL), name,
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name,
howto->name, (bfd_vma) 0, input_bfd,
input_section, r_addr)))
return FALSE;
/* Link an a.out section into the output file. */
static bfd_boolean
-aout_link_input_section (struct aout_final_link_info *finfo,
+aout_link_input_section (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
file_ptr *reloff_ptr,
/* Get the section contents. */
input_size = input_section->size;
if (! bfd_get_section_contents (input_bfd, input_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) 0, input_size))
return FALSE;
relocs = aout_section_data (input_section)->relocs;
else
{
- relocs = finfo->relocs;
+ relocs = flaginfo->relocs;
if (rel_size > 0)
{
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
}
/* Relocate the section contents. */
- if (! pdp11_aout_link_input_section (finfo, input_bfd, input_section,
+ if (! pdp11_aout_link_input_section (flaginfo, input_bfd, input_section,
(bfd_byte *) relocs,
- rel_size, finfo->contents))
+ rel_size, flaginfo->contents))
return FALSE;
/* Write out the section contents. */
- if (! bfd_set_section_contents (finfo->output_bfd,
+ if (! bfd_set_section_contents (flaginfo->output_bfd,
input_section->output_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) input_section->output_offset,
input_size))
return FALSE;
/* If we are producing relocatable output, the relocs were
modified, and we now write them out. */
- if (finfo->info->relocatable && rel_size > 0)
+ if (flaginfo->info->relocatable && rel_size > 0)
{
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
return FALSE;
- if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
+ if (bfd_bwrite (relocs, rel_size, flaginfo->output_bfd) != rel_size)
return FALSE;
*reloff_ptr += rel_size;
/* Assert that the relocs have not run into the symbols, and
that if these are the text relocs they have not run into the
data relocs. */
- BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
- && (reloff_ptr != &finfo->treloff
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
}
return TRUE;
/* Link an a.out input BFD into the output file. */
static bfd_boolean
-aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
if ((input_bfd->flags & DYNAMIC) != 0
&& aout_backend_info (input_bfd)->link_dynamic_object != NULL)
return ((*aout_backend_info (input_bfd)->link_dynamic_object)
- (finfo->info, input_bfd));
+ (flaginfo->info, input_bfd));
/* Get the symbols. We probably have them already, unless
- finfo->info->keep_memory is FALSE. */
+ flaginfo->info->keep_memory is FALSE. */
if (! aout_get_external_symbols (input_bfd))
return FALSE;
/* Write out the symbols and get a map of the new indices. The map
- is placed into finfo->symbol_map. */
- if (! aout_link_write_symbols (finfo, input_bfd))
+ is placed into flaginfo->symbol_map. */
+ if (! aout_link_write_symbols (flaginfo, input_bfd))
return FALSE;
/* Relocate and write out the sections. These functions use the
link, which will normally be the case. */
if (obj_textsec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_textsec (input_bfd),
- &finfo->treloff,
+ &flaginfo->treloff,
exec_hdr (input_bfd)->a_trsize))
return FALSE;
}
if (obj_datasec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_datasec (input_bfd),
- &finfo->dreloff,
+ &flaginfo->dreloff,
exec_hdr (input_bfd)->a_drsize))
return FALSE;
}
/* If we are not keeping memory, we don't need the symbols any
longer. We still need them if we are keeping memory, because the
strings in the hash table point into them. */
- if (! finfo->info->keep_memory)
+ if (! flaginfo->info->keep_memory)
{
if (! aout_link_free_symbols (input_bfd))
return FALSE;
/* Do the final link step. This is called on the output BFD. The
INFO structure should point to a list of BFDs linked through the
- link_next field which can be used to find each BFD which takes part
+ link.next field which can be used to find each BFD which takes part
in the output. Also, each section in ABFD should point to a list
of bfd_link_order structures which list all the input sections for
the output section. */
max_contents_size = 0;
max_relocs_size = 0;
max_sym_count = 0;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
size_t sz;
We use the output_has_begun field of the input BFDs to see
whether we have already handled it. */
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
sub->output_has_begun = FALSE;
/* Mark all sections which are to be included in the link. This
symbol indices into a symbol_map. */
static bfd_boolean
-aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
bfd *output_bfd;
bfd_size_type sym_count;
bfd_boolean pass;
bfd_boolean skip_next;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
sym_count = obj_aout_external_sym_count (input_bfd);
strings = obj_aout_external_strings (input_bfd);
- strip = finfo->info->strip;
- discard = finfo->info->discard;
- outsym = finfo->output_syms;
+ strip = flaginfo->info->strip;
+ discard = flaginfo->info->discard;
+ outsym = flaginfo->output_syms;
/* First write out a symbol for this object file, unless we are
discarding such symbols. */
if (strip != strip_all
&& (strip != strip_some
- || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
+ || bfd_hash_lookup (flaginfo->info->keep_hash, input_bfd->filename,
FALSE, FALSE) != NULL)
&& discard != discard_all)
{
H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
input_bfd->filename, FALSE);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
sym = obj_aout_external_syms (input_bfd);
sym_end = sym + sym_count;
sym_hash = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
{
skip = TRUE;
break;
case strip_some:
- if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
+ if (bfd_hash_lookup (flaginfo->info->keep_hash, name, FALSE, FALSE)
== NULL)
skip = TRUE;
break;
/* If we have already included a header file with the
same value, then replace this one with an N_EXCL
symbol. */
- copy = ! finfo->info->keep_memory;
- incl_entry = aout_link_includes_lookup (&finfo->includes,
+ copy = ! flaginfo->info->keep_memory;
+ incl_entry = aout_link_includes_lookup (&flaginfo->includes,
name, TRUE, copy);
if (incl_entry == NULL)
return FALSE;
{
/* This is the first time we have seen this header
file with this set of stabs strings. */
- t = bfd_hash_allocate (&finfo->includes.root,
+ t = bfd_hash_allocate (&flaginfo->includes.root,
sizeof *t);
if (t == NULL)
return FALSE;
write out. */
H_PUT_8 (output_bfd, type, outsym->e_type);
copy = FALSE;
- if (! finfo->info->keep_memory)
+ if (! flaginfo->info->keep_memory)
{
/* name points into a string table which we are going to
free. If there is a hash table entry, use that string.
else
copy = TRUE;
}
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
name, copy);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
}
/* Write out the output symbols we have just constructed. */
- if (outsym > finfo->output_syms)
+ if (outsym > flaginfo->output_syms)
{
bfd_size_type size;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
return FALSE;
- size = outsym - finfo->output_syms;
+ size = outsym - flaginfo->output_syms;
size *= EXTERNAL_NLIST_SIZE;
- if (bfd_bwrite ((void *) finfo->output_syms, size, output_bfd) != size)
+ if (bfd_bwrite ((void *) flaginfo->output_syms, size, output_bfd) != size)
return FALSE;
- finfo->symoff += size;
+ flaginfo->symoff += size;
}
return TRUE;