/* POWER/PowerPC XCOFF linker support.
- Copyright 1995 Free Software Foundation, Inc.
+ Copyright 1995, 1996 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
ret = ((struct xcoff_link_hash_entry *)
bfd_hash_allocate (table, sizeof (struct xcoff_link_hash_entry)));
if (ret == (struct xcoff_link_hash_entry *) NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return (struct bfd_hash_entry *) ret;
- }
+ return (struct bfd_hash_entry *) ret;
/* Call the allocation method of the superclass. */
ret = ((struct xcoff_link_hash_entry *)
ret = ((struct xcoff_link_hash_table *)
bfd_alloc (abfd, sizeof (struct xcoff_link_hash_table)));
if (ret == (struct xcoff_link_hash_table *) NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return (struct bfd_link_hash_table *) NULL;
- }
+ return (struct bfd_link_hash_table *) NULL;
if (! _bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc))
{
bfd_release (abfd, ret);
if ((abfd->flags & DYNAMIC) != 0
&& ! info->static_link)
- return xcoff_link_add_dynamic_symbols (abfd, info);
-
- n_tmask = coff_data (abfd)->local_n_tmask;
- n_btshft = coff_data (abfd)->local_n_btshft;
-
- /* Define macros so that ISFCN, et. al., macros work correctly. */
-#define N_TMASK n_tmask
-#define N_BTSHFT n_btshft
+ {
+ if (! xcoff_link_add_dynamic_symbols (abfd, info))
+ return false;
+ }
/* We need to build a .loader section, so we do it here. This won't
- work if we're producing an XCOFF output file with no non dynamic
- XCOFF input files. FIXME. */
+ work if we're producing an XCOFF output file with no XCOFF input
+ files. FIXME. */
if (xcoff_hash_table (info)->loader_section == NULL)
{
asection *lsec;
dsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY;
}
+ if ((abfd->flags & DYNAMIC) != 0
+ && ! info->static_link)
+ return true;
+
+ n_tmask = coff_data (abfd)->local_n_tmask;
+ n_btshft = coff_data (abfd)->local_n_btshft;
+
+ /* Define macros so that ISFCN, et. al., macros work correctly. */
+#define N_TMASK n_tmask
+#define N_BTSHFT n_btshft
+
if (info->keep_memory)
default_copy = false;
else
(symcount
* sizeof (struct xcoff_link_hash_entry *))));
if (sym_hash == NULL && symcount != 0)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash;
memset (sym_hash, 0,
(size_t) symcount * sizeof (struct xcoff_link_hash_entry *));
csect_cache = ((asection **)
bfd_alloc (abfd, symcount * sizeof (asection *)));
if (csect_cache == NULL && symcount != 0)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
xcoff_data (abfd)->csects = csect_cache;
memset (csect_cache, 0, (size_t) symcount * sizeof (asection *));
scanning along the relocs as we process the csects. We index
into reloc_info using the section target_index. */
reloc_info = ((struct reloc_info_struct *)
- malloc ((abfd->section_count + 1)
- * sizeof (struct reloc_info_struct)));
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct reloc_info_struct)));
if (reloc_info == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
memset ((PTR) reloc_info, 0,
(abfd->section_count + 1) * sizeof (struct reloc_info_struct));
xcoff_read_internal_relocs (abfd, o, true, (bfd_byte *) NULL,
false, (struct internal_reloc *) NULL);
reloc_info[o->target_index].csects =
- (asection **) malloc (o->reloc_count * sizeof (asection *));
+ (asection **) bfd_malloc (o->reloc_count * sizeof (asection *));
if (reloc_info[o->target_index].csects == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
memset (reloc_info[o->target_index].csects, 0,
o->reloc_count * sizeof (asection *));
}
{
bfd_byte *linenos;
- linenos = (bfd_byte *) malloc (o->lineno_count * linesz);
+ linenos = (bfd_byte *) bfd_malloc (o->lineno_count * linesz);
if (linenos == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
reloc_info[o->target_index].linenos = linenos;
if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0
|| (bfd_read (linenos, linesz, o->lineno_count, abfd)
((struct coff_section_tdata *)
bfd_zalloc (abfd, sizeof (struct coff_section_tdata)));
if (csect->used_by_bfd == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
coff_section_data (abfd, csect)->tdata =
bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata));
if (coff_section_data (abfd, csect)->tdata == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
xcoff_section_data (abfd, csect)->enclosing = enclosing;
xcoff_section_data (abfd, csect)->lineno_count =
enclosing->lineno_count;
((struct coff_section_tdata *)
bfd_zalloc (abfd, sizeof (struct coff_section_tdata)));
if (csect->used_by_bfd == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
coff_section_data (abfd, csect)->tdata =
bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata));
if (coff_section_data (abfd, csect)->tdata == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
xcoff_section_data (abfd, csect)->first_symndx = csect_index;
if (first_csect == NULL)
goto error_return;
}
- buf = (bfd_byte *) malloc (lsec->_raw_size);
+ buf = (bfd_byte *) bfd_malloc (lsec->_raw_size);
if (buf == NULL && lsec->_raw_size > 0)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
if (! bfd_get_section_contents (abfd, lsec, (PTR) buf, (file_ptr) 0,
lsec->_raw_size))
n = ((struct xcoff_import_file *)
bfd_alloc (abfd, sizeof (struct xcoff_import_file)));
if (n == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
n->next = NULL;
/* For some reason, the path entry in the import file list for a
n = ((struct xcoff_link_size_list *)
bfd_alloc (output_bfd, sizeof (struct xcoff_link_size_list)));
if (n == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
n->next = xcoff_hash_table (info)->size_list;
n->h = h;
n->size = size;
h->ldsym = ((struct internal_ldsym *)
bfd_zalloc (output_bfd, sizeof (struct internal_ldsym)));
if (h->ldsym == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
}
if (imppath == NULL)
n = ((struct xcoff_import_file *)
bfd_alloc (output_bfd, sizeof (struct xcoff_import_file)));
if (n == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
n->next = NULL;
n->path = imppath;
n->file = impfile;
char *fnname;
struct xcoff_link_hash_entry *hfn;
- fnname = (char *) malloc (strlen (h->root.root.string) + 2);
+ fnname = (char *) bfd_malloc (strlen (h->root.root.string) + 2);
if (fnname == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
fnname[0] = '.';
strcpy (fnname + 1, h->root.root.string);
hfn = xcoff_link_hash_lookup (xcoff_hash_table (info),
bfd *output_bfd;
/* Link information structure. */
struct bfd_link_info *info;
+ /* Whether all defined symbols should be exported. */
+ boolean export_defineds;
/* Number of ldsym structures. */
size_t ldsym_count;
/* Size of string table. */
.loader section before the linker lays out the output file.
LIBPATH is the library path to search for shared objects; this is
normally built from the -L arguments passed to the linker. ENTRY
- is the name of the entry point symbol. */
+ is the name of the entry point symbol (the -e linker option).
+ FILE_ALIGN is the alignment to use for sections within the file
+ (the -H linker option). MAXSTACK is the maximum stack size (the
+ -bmaxstack linker option). MAXDATA is the maximum data size (the
+ -bmaxdata linker option). GC is whether to do garbage collection
+ (the -bgc linker option). MODTYPE is the module type (the
+ -bmodtype linker option). TEXTRO is whether the text section must
+ be read only (the -btextro linker option). EXPORT_DEFINEDS is
+ whether all defined symbols should be exported (the -unix linker
+ option). SPECIAL_SECTIONS is set by this routine to csects with
+ magic names like _end. */
boolean
bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
file_align, maxstack, maxdata, gc,
- modtype, textro, special_sections)
+ modtype, textro, export_defineds,
+ special_sections)
bfd *output_bfd;
struct bfd_link_info *info;
const char *libpath;
boolean gc;
int modtype;
boolean textro;
+ boolean export_defineds;
asection **special_sections;
{
struct xcoff_link_hash_entry *hentry;
ldinfo.failed = false;
ldinfo.output_bfd = output_bfd;
ldinfo.info = info;
+ ldinfo.export_defineds = export_defineds;
ldinfo.ldsym_count = 0;
ldinfo.string_size = 0;
ldinfo.strings = NULL;
lsec->_raw_size = stoff + ldhdr->l_stlen;
lsec->contents = (bfd_byte *) bfd_zalloc (output_bfd, lsec->_raw_size);
if (lsec->contents == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
/* Set up the header. */
xcoff_swap_ldhdr_out (output_bfd, ldhdr,
{
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
if (sec->contents == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
}
sec = xcoff_hash_table (info)->toc_section;
if (sec->_raw_size > 0)
{
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
if (sec->contents == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
}
sec = xcoff_hash_table (info)->descriptor_section;
if (sec->_raw_size > 0)
{
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
if (sec->contents == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
}
/* Now that we've done garbage collection, figure out the contents
debug_index = ((unsigned long *)
bfd_zalloc (sub, symcount * sizeof (unsigned long)));
if (debug_index == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
xcoff_data (sub)->debug_indices = debug_index;
/* Grab the contents of the .debug section. We use malloc and
bfd_alloc, because I expect that, when linking many files
together, many of the strings will be the same. Storing the
strings in the hash table should save space in this case. */
- debug_contents = (bfd_byte *) malloc (subdeb->_raw_size);
+ debug_contents = (bfd_byte *) bfd_malloc (subdeb->_raw_size);
if (debug_contents == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
if (! bfd_get_section_contents (sub, subdeb, (PTR) debug_contents,
(file_ptr) 0, subdeb->_raw_size))
goto error_return;
struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
size_t len;
+ /* If all defined symbols should be exported, mark them now. */
+ if (ldinfo->export_defineds
+ && (h->flags & XCOFF_DEF_REGULAR) != 0)
+ h->flags |= XCOFF_EXPORT;
+
/* We don't want to garbage collect symbols which are not defined in
XCOFF files. This is a convenient place to mark them. */
if (xcoff_hash_table (ldinfo->info)->gc
if (h->ldsym == NULL)
{
ldinfo->failed = true;
- bfd_set_error (bfd_error_no_memory);
return false;
}
}
while (ldinfo->string_size + len + 3 > newalc)
newalc *= 2;
- if (ldinfo->strings == NULL)
- newstrings = (bfd_byte *) malloc (newalc);
- else
- newstrings = ((bfd_byte *)
- realloc ((PTR) ldinfo->strings, newalc));
+ newstrings = ((bfd_byte *)
+ bfd_realloc ((PTR) ldinfo->strings, newalc));
if (newstrings == NULL)
{
ldinfo->failed = true;
- bfd_set_error (bfd_error_no_memory);
return false;
}
ldinfo->string_alc = newalc;
/* We use section_count + 1, rather than section_count, because
the target_index fields are 1 based. */
- finfo.section_info = ((struct xcoff_link_section_info *)
- malloc ((abfd->section_count + 1)
- * sizeof (struct xcoff_link_section_info)));
+ finfo.section_info =
+ ((struct xcoff_link_section_info *)
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct xcoff_link_section_info)));
if (finfo.section_info == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
for (i = 0; i <= abfd->section_count; i++)
{
finfo.section_info[i].relocs = NULL;
would be slow. */
finfo.section_info[o->target_index].relocs =
((struct internal_reloc *)
- malloc (o->reloc_count * sizeof (struct internal_reloc)));
+ bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
finfo.section_info[o->target_index].rel_hashes =
((struct xcoff_link_hash_entry **)
- malloc (o->reloc_count
+ bfd_malloc (o->reloc_count
* sizeof (struct xcoff_link_hash_entry *)));
if (finfo.section_info[o->target_index].relocs == NULL
|| finfo.section_info[o->target_index].rel_hashes == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
if (o->reloc_count > max_output_reloc_count)
max_output_reloc_count = o->reloc_count;
/* Allocate some buffers used while linking. */
finfo.internal_syms = ((struct internal_syment *)
- malloc (max_sym_count
- * sizeof (struct internal_syment)));
- finfo.sym_indices = (long *) malloc (max_sym_count * sizeof (long));
+ bfd_malloc (max_sym_count
+ * sizeof (struct internal_syment)));
+ finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
finfo.outsyms = ((bfd_byte *)
- malloc ((size_t) ((max_sym_count + 1) * symesz)));
- finfo.linenos = (bfd_byte *) malloc (max_lineno_count
- * bfd_coff_linesz (abfd));
- finfo.contents = (bfd_byte *) malloc (max_contents_size);
- finfo.external_relocs = (bfd_byte *) malloc (max_reloc_count * relsz);
+ bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
+ finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
+ * bfd_coff_linesz (abfd));
+ finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
if ((finfo.internal_syms == NULL && max_sym_count > 0)
|| (finfo.sym_indices == NULL && max_sym_count > 0)
|| finfo.outsyms == NULL
|| (finfo.linenos == NULL && max_lineno_count > 0)
|| (finfo.contents == NULL && max_contents_size > 0)
|| (finfo.external_relocs == NULL && max_reloc_count > 0))
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
obj_raw_syment_count (abfd) = 0;
xcoff_data (abfd)->toc = (bfd_vma) -1;
bfd_alloc (finfo->output_bfd,
sizeof (struct xcoff_toc_rel_hash)));
if (n == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
si = finfo->section_info + target_index;
n->next = si->toc_rel_hashes;
n->h = h;
size = bfd_get_reloc_size (howto);
buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
switch (rstat)