mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
* xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Look through the
members of an archive for dynamic objects with no symbols, and pass them directly to check_archive_element. (xcoff_link_check_ar_symbols): Pass dynamic objects to xcoff_link_check_dynamic_ar_symbols. (xcoff_link_check_dynamic_ar_symbols): New static function. The above is for PR 9520. * coff-rs6000.c (rs6000coff_vec): Change BFD_JUMP_TABLE_DYNAMIC from _bfd_nodynamic to _bfd_xcoff. * libcoff-in.h (_bfd_xcoff_get_dynamic_symtab_upper_bound): Declare. (_bfd_xcoff_canonicalize_dynamic_symtab): Declare. (_bfd_xcoff_get_dynamic_reloc_upper_bound): Declare. (_bfd_xcoff_canonicalize_dynamic_reloc): Declare. * libcoff.h: Rebuild. * xcofflink.c (xcoff_swap_ldrel_in): New static function. (xcoff_get_section_contents): New static function. (_bfd_xcoff_get_dynamic_symtab_upper_bound): New function. (_bfd_xcoff_canonicalize_dynamic_symtab): New function. (_bfd_xcoff_get_dynamic_reloc_upper_bound): New function. (xcoff_dynamic_reloc): New static variable. (_bfd_xcoff_canonicalize_dynamic_reloc): New function. (xcoff_link_add_dynamic_symbols): Use xcoff_get_section_contents.
This commit is contained in:
parent
116bf30f41
commit
f5d6548535
@ -1,3 +1,35 @@
|
||||
Wed Apr 24 14:04:07 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Look through the
|
||||
members of an archive for dynamic objects with no symbols, and
|
||||
pass them directly to check_archive_element.
|
||||
(xcoff_link_check_ar_symbols): Pass dynamic objects to
|
||||
xcoff_link_check_dynamic_ar_symbols.
|
||||
(xcoff_link_check_dynamic_ar_symbols): New static function.
|
||||
|
||||
* coff-rs6000.c (rs6000coff_vec): Change BFD_JUMP_TABLE_DYNAMIC
|
||||
from _bfd_nodynamic to _bfd_xcoff.
|
||||
* libcoff-in.h (_bfd_xcoff_get_dynamic_symtab_upper_bound):
|
||||
Declare.
|
||||
(_bfd_xcoff_canonicalize_dynamic_symtab): Declare.
|
||||
(_bfd_xcoff_get_dynamic_reloc_upper_bound): Declare.
|
||||
(_bfd_xcoff_canonicalize_dynamic_reloc): Declare.
|
||||
* libcoff.h: Rebuild.
|
||||
* xcofflink.c (xcoff_swap_ldrel_in): New static function.
|
||||
(xcoff_get_section_contents): New static function.
|
||||
(_bfd_xcoff_get_dynamic_symtab_upper_bound): New function.
|
||||
(_bfd_xcoff_canonicalize_dynamic_symtab): New function.
|
||||
(_bfd_xcoff_get_dynamic_reloc_upper_bound): New function.
|
||||
(xcoff_dynamic_reloc): New static variable.
|
||||
(_bfd_xcoff_canonicalize_dynamic_reloc): New function.
|
||||
(xcoff_link_add_dynamic_symbols): Use xcoff_get_section_contents.
|
||||
|
||||
Tue Apr 23 12:48:42 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* coff-sparc.c (bfd_coff_generic_reloc): Return bfd_reloc_ok even
|
||||
if reloc_entry->addend is not 0.
|
||||
(CALC_ADDEND): Just set the addend to reloc.r_offset.
|
||||
|
||||
Mon Apr 22 18:29:01 1996 Doug Evans <dje@canuck.cygnus.com>
|
||||
|
||||
* elf32-sparc.c (_bfd_sparc_elf_howto_table): Fix spelling of
|
||||
|
@ -177,6 +177,8 @@ struct coff_section_tdata
|
||||
unsigned int i;
|
||||
const char *function;
|
||||
int line_base;
|
||||
/* A pointer used for .stab linking optimizations. */
|
||||
PTR stab_info;
|
||||
/* Available for individual backends. */
|
||||
PTR tdata;
|
||||
};
|
||||
@ -236,6 +238,8 @@ struct coff_link_hash_entry
|
||||
struct coff_link_hash_table
|
||||
{
|
||||
struct bfd_link_hash_table root;
|
||||
/* A pointer to information used to link stabs in sections. */
|
||||
PTR stab_info;
|
||||
};
|
||||
|
||||
/* Look up an entry in a COFF linker hash table. */
|
||||
@ -473,6 +477,12 @@ extern boolean _bfd_coff_reloc_link_order
|
||||
|
||||
/* Functions in xcofflink.c. */
|
||||
|
||||
extern long _bfd_xcoff_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
|
||||
extern long _bfd_xcoff_canonicalize_dynamic_symtab
|
||||
PARAMS ((bfd *, asymbol **));
|
||||
extern long _bfd_xcoff_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
|
||||
extern long _bfd_xcoff_canonicalize_dynamic_reloc
|
||||
PARAMS ((bfd *, arelent **, asymbol **));
|
||||
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
|
||||
PARAMS ((bfd *));
|
||||
extern boolean _bfd_xcoff_bfd_link_add_symbols
|
||||
|
@ -177,6 +177,8 @@ struct coff_section_tdata
|
||||
unsigned int i;
|
||||
const char *function;
|
||||
int line_base;
|
||||
/* A pointer used for .stab linking optimizations. */
|
||||
PTR stab_info;
|
||||
/* Available for individual backends. */
|
||||
PTR tdata;
|
||||
};
|
||||
@ -236,6 +238,8 @@ struct coff_link_hash_entry
|
||||
struct coff_link_hash_table
|
||||
{
|
||||
struct bfd_link_hash_table root;
|
||||
/* A pointer to information used to link stabs in sections. */
|
||||
PTR stab_info;
|
||||
};
|
||||
|
||||
/* Look up an entry in a COFF linker hash table. */
|
||||
@ -473,6 +477,12 @@ extern boolean _bfd_coff_reloc_link_order
|
||||
|
||||
/* Functions in xcofflink.c. */
|
||||
|
||||
extern long _bfd_xcoff_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
|
||||
extern long _bfd_xcoff_canonicalize_dynamic_symtab
|
||||
PARAMS ((bfd *, asymbol **));
|
||||
extern long _bfd_xcoff_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
|
||||
extern long _bfd_xcoff_canonicalize_dynamic_reloc
|
||||
PARAMS ((bfd *, arelent **, asymbol **));
|
||||
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
|
||||
PARAMS ((bfd *));
|
||||
extern boolean _bfd_xcoff_bfd_link_add_symbols
|
||||
|
478
bfd/xcofflink.c
478
bfd/xcofflink.c
@ -435,6 +435,8 @@ static void xcoff_swap_ldsym_in
|
||||
PARAMS ((bfd *, const struct external_ldsym *, struct internal_ldsym *));
|
||||
static void xcoff_swap_ldsym_out
|
||||
PARAMS ((bfd *, const struct internal_ldsym *, struct external_ldsym *));
|
||||
static void xcoff_swap_ldrel_in
|
||||
PARAMS ((bfd *, const struct external_ldrel *, struct internal_ldrel *));
|
||||
static void xcoff_swap_ldrel_out
|
||||
PARAMS ((bfd *, const struct internal_ldrel *, struct external_ldrel *));
|
||||
static struct bfd_hash_entry *xcoff_link_hash_newfunc
|
||||
@ -448,6 +450,8 @@ static boolean xcoff_link_check_archive_element
|
||||
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
||||
static boolean xcoff_link_check_ar_symbols
|
||||
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
||||
static boolean xcoff_link_check_dynamic_ar_symbols
|
||||
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
||||
static bfd_size_type xcoff_find_reloc
|
||||
PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma));
|
||||
static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
|
||||
@ -553,7 +557,19 @@ xcoff_swap_ldsym_out (abfd, src, dst)
|
||||
bfd_put_32 (abfd, src->l_parm, dst->l_parm);
|
||||
}
|
||||
|
||||
/* As it happens, we never need to swap in the ldrel structure. */
|
||||
/* Swap in the ldrel structure. */
|
||||
|
||||
static void
|
||||
xcoff_swap_ldrel_in (abfd, src, dst)
|
||||
bfd *abfd;
|
||||
const struct external_ldrel *src;
|
||||
struct internal_ldrel *dst;
|
||||
{
|
||||
dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
|
||||
dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
|
||||
dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
|
||||
dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
|
||||
}
|
||||
|
||||
/* Swap out the ldrel structure. */
|
||||
|
||||
@ -569,6 +585,316 @@ xcoff_swap_ldrel_out (abfd, src, dst)
|
||||
bfd_put_16 (abfd, src->l_rsecnm, dst->l_rsecnm);
|
||||
}
|
||||
|
||||
/* Routines to read XCOFF dynamic information. This don't really
|
||||
belong here, but we already have the ldsym manipulation routines
|
||||
here. */
|
||||
|
||||
/* Read the contents of a section. */
|
||||
|
||||
static boolean
|
||||
xcoff_get_section_contents (abfd, sec)
|
||||
bfd *abfd;
|
||||
asection *sec;
|
||||
{
|
||||
if (coff_section_data (abfd, sec) == NULL)
|
||||
{
|
||||
sec->used_by_bfd = bfd_zalloc (abfd,
|
||||
sizeof (struct coff_section_tdata));
|
||||
if (sec->used_by_bfd == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (coff_section_data (abfd, sec)->contents == NULL)
|
||||
{
|
||||
coff_section_data (abfd, sec)->contents = bfd_malloc (sec->_raw_size);
|
||||
if (coff_section_data (abfd, sec)->contents == NULL)
|
||||
return false;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, sec,
|
||||
coff_section_data (abfd, sec)->contents,
|
||||
(file_ptr) 0, sec->_raw_size))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Get the size required to hold the dynamic symbols. */
|
||||
|
||||
long
|
||||
_bfd_xcoff_get_dynamic_symtab_upper_bound (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *contents;
|
||||
struct internal_ldhdr ldhdr;
|
||||
|
||||
if ((abfd->flags & DYNAMIC) == 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lsec = bfd_get_section_by_name (abfd, ".loader");
|
||||
if (lsec == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_symbols);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return -1;
|
||||
contents = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
|
||||
|
||||
return (ldhdr.l_nsyms + 1) * sizeof (asymbol *);
|
||||
}
|
||||
|
||||
/* Get the dynamic symbols. */
|
||||
|
||||
long
|
||||
_bfd_xcoff_canonicalize_dynamic_symtab (abfd, psyms)
|
||||
bfd *abfd;
|
||||
asymbol **psyms;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *contents;
|
||||
struct internal_ldhdr ldhdr;
|
||||
const char *strings;
|
||||
struct external_ldsym *elsym, *elsymend;
|
||||
coff_symbol_type *symbuf;
|
||||
|
||||
if ((abfd->flags & DYNAMIC) == 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lsec = bfd_get_section_by_name (abfd, ".loader");
|
||||
if (lsec == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_symbols);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return -1;
|
||||
contents = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
coff_section_data (abfd, lsec)->keep_contents = true;
|
||||
|
||||
xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
|
||||
|
||||
strings = (char *) contents + ldhdr.l_stoff;
|
||||
|
||||
symbuf = ((coff_symbol_type *)
|
||||
bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (coff_symbol_type)));
|
||||
if (symbuf == NULL)
|
||||
return -1;
|
||||
|
||||
elsym = (struct external_ldsym *) (contents + LDHDRSZ);
|
||||
elsymend = elsym + ldhdr.l_nsyms;
|
||||
for (; elsym < elsymend; elsym++, symbuf++, psyms++)
|
||||
{
|
||||
struct internal_ldsym ldsym;
|
||||
|
||||
xcoff_swap_ldsym_in (abfd, elsym, &ldsym);
|
||||
|
||||
symbuf->symbol.the_bfd = abfd;
|
||||
|
||||
if (ldsym._l._l_l._l_zeroes == 0)
|
||||
symbuf->symbol.name = strings + ldsym._l._l_l._l_offset;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SYMNMLEN; i++)
|
||||
if (ldsym._l._l_name[i] == '\0')
|
||||
break;
|
||||
if (i < SYMNMLEN)
|
||||
symbuf->symbol.name = elsym->_l._l_name;
|
||||
else
|
||||
{
|
||||
char *c;
|
||||
|
||||
c = bfd_alloc (abfd, SYMNMLEN + 1);
|
||||
if (c == NULL)
|
||||
return -1;
|
||||
memcpy (c, ldsym._l._l_name, SYMNMLEN);
|
||||
c[SYMNMLEN] = '\0';
|
||||
symbuf->symbol.name = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (ldsym.l_smclas == XMC_XO)
|
||||
symbuf->symbol.section = bfd_abs_section_ptr;
|
||||
else
|
||||
symbuf->symbol.section = coff_section_from_bfd_index (abfd,
|
||||
ldsym.l_scnum);
|
||||
symbuf->symbol.value = ldsym.l_value - symbuf->symbol.section->vma;
|
||||
|
||||
symbuf->symbol.flags = BSF_NO_FLAGS;
|
||||
if ((ldsym.l_smtype & L_EXPORT) != 0)
|
||||
symbuf->symbol.flags |= BSF_GLOBAL;
|
||||
|
||||
/* FIXME: We have no way to record the other information stored
|
||||
with the loader symbol. */
|
||||
|
||||
*psyms = (asymbol *) symbuf;
|
||||
}
|
||||
|
||||
*psyms = NULL;
|
||||
|
||||
return ldhdr.l_nsyms;
|
||||
}
|
||||
|
||||
/* Get the size required to hold the dynamic relocs. */
|
||||
|
||||
long
|
||||
_bfd_xcoff_get_dynamic_reloc_upper_bound (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *contents;
|
||||
struct internal_ldhdr ldhdr;
|
||||
|
||||
if ((abfd->flags & DYNAMIC) == 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lsec = bfd_get_section_by_name (abfd, ".loader");
|
||||
if (lsec == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_symbols);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return -1;
|
||||
contents = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
|
||||
|
||||
return (ldhdr.l_nreloc + 1) * sizeof (arelent *);
|
||||
}
|
||||
|
||||
/* The typical dynamic reloc. */
|
||||
|
||||
static reloc_howto_type xcoff_dynamic_reloc =
|
||||
HOWTO (0, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
0, /* special_function */
|
||||
"R_POS", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false); /* pcrel_offset */
|
||||
|
||||
/* Get the dynamic relocs. */
|
||||
|
||||
long
|
||||
_bfd_xcoff_canonicalize_dynamic_reloc (abfd, prelocs, syms)
|
||||
bfd *abfd;
|
||||
arelent **prelocs;
|
||||
asymbol **syms;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *contents;
|
||||
struct internal_ldhdr ldhdr;
|
||||
arelent *relbuf;
|
||||
struct external_ldrel *elrel, *elrelend;
|
||||
|
||||
if ((abfd->flags & DYNAMIC) == 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lsec = bfd_get_section_by_name (abfd, ".loader");
|
||||
if (lsec == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_symbols);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return -1;
|
||||
contents = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
|
||||
|
||||
relbuf = (arelent *) bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent));
|
||||
if (relbuf == NULL)
|
||||
return -1;
|
||||
|
||||
elrel = ((struct external_ldrel *)
|
||||
(contents + LDHDRSZ + ldhdr.l_nsyms * LDSYMSZ));
|
||||
elrelend = elrel + ldhdr.l_nreloc;
|
||||
for (; elrel < elrelend; elrel++, relbuf++, prelocs++)
|
||||
{
|
||||
struct internal_ldrel ldrel;
|
||||
|
||||
xcoff_swap_ldrel_in (abfd, elrel, &ldrel);
|
||||
|
||||
if (ldrel.l_symndx >= 3)
|
||||
relbuf->sym_ptr_ptr = syms + (ldrel.l_symndx - 3);
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
asection *sec;
|
||||
|
||||
switch (ldrel.l_symndx)
|
||||
{
|
||||
case 0:
|
||||
name = ".text";
|
||||
break;
|
||||
case 1:
|
||||
name = ".data";
|
||||
break;
|
||||
case 2:
|
||||
name = ".bss";
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
|
||||
sec = bfd_get_section_by_name (abfd, name);
|
||||
if (sec == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
relbuf->sym_ptr_ptr = sec->symbol_ptr_ptr;
|
||||
}
|
||||
|
||||
relbuf->address = ldrel.l_vaddr;
|
||||
relbuf->addend = 0;
|
||||
|
||||
/* Most dynamic relocs have the same type. FIXME: This is only
|
||||
correct if ldrel.l_rtype == 0. In other cases, we should use
|
||||
a different howto. */
|
||||
relbuf->howto = &xcoff_dynamic_reloc;
|
||||
|
||||
/* FIXME: We have no way to record the l_rsecnm field. */
|
||||
|
||||
*prelocs = relbuf;
|
||||
}
|
||||
|
||||
*prelocs = NULL;
|
||||
|
||||
return ldhdr.l_nreloc;
|
||||
}
|
||||
|
||||
/* Routine to create an entry in an XCOFF link hash table. */
|
||||
|
||||
static struct bfd_hash_entry *
|
||||
@ -736,8 +1062,34 @@ _bfd_xcoff_bfd_link_add_symbols (abfd, info)
|
||||
case bfd_object:
|
||||
return xcoff_link_add_object_symbols (abfd, info);
|
||||
case bfd_archive:
|
||||
return (_bfd_generic_link_add_archive_symbols
|
||||
(abfd, info, xcoff_link_check_archive_element));
|
||||
/* We need to look through the archive for stripped dynamic
|
||||
objects, because they will not appear in the archive map even
|
||||
though they should, perhaps, be included. */
|
||||
{
|
||||
bfd *member;
|
||||
|
||||
member = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
|
||||
while (member != NULL)
|
||||
{
|
||||
if (bfd_check_format (member, bfd_object)
|
||||
&& (member->flags & DYNAMIC) != 0
|
||||
&& (member->flags & HAS_SYMS) == 0)
|
||||
{
|
||||
boolean needed;
|
||||
|
||||
if (! xcoff_link_check_archive_element (member, info, &needed))
|
||||
return false;
|
||||
if (needed)
|
||||
member->archive_pass = -1;
|
||||
}
|
||||
member = bfd_openr_next_archived_file (abfd, member);
|
||||
}
|
||||
|
||||
/* Now do the usual search. */
|
||||
return (_bfd_generic_link_add_archive_symbols
|
||||
(abfd, info, xcoff_link_check_archive_element));
|
||||
}
|
||||
|
||||
default:
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return false;
|
||||
@ -810,6 +1162,11 @@ xcoff_link_check_ar_symbols (abfd, info, pneeded)
|
||||
|
||||
*pneeded = false;
|
||||
|
||||
if ((abfd->flags & DYNAMIC) != 0
|
||||
&& ! info->static_link
|
||||
&& info->hash->creator == abfd->xvec)
|
||||
return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded);
|
||||
|
||||
symesz = bfd_coff_symesz (abfd);
|
||||
esym = (bfd_byte *) obj_coff_external_syms (abfd);
|
||||
esym_end = esym + obj_raw_syment_count (abfd) * symesz;
|
||||
@ -855,6 +1212,87 @@ xcoff_link_check_ar_symbols (abfd, info, pneeded)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Look through the loader symbols to see if this dynamic object
|
||||
should be included in the link. The native linker uses the loader
|
||||
symbols, not the normal symbol table, so we do too. */
|
||||
|
||||
static boolean
|
||||
xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
boolean *pneeded;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *buf;
|
||||
struct internal_ldhdr ldhdr;
|
||||
const char *strings;
|
||||
struct external_ldsym *elsym, *elsymend;
|
||||
|
||||
*pneeded = false;
|
||||
|
||||
lsec = bfd_get_section_by_name (abfd, ".loader");
|
||||
if (lsec == NULL)
|
||||
{
|
||||
/* There are no symbols, so don't try to include it. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return false;
|
||||
buf = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) buf, &ldhdr);
|
||||
|
||||
strings = (char *) buf + ldhdr.l_stoff;
|
||||
|
||||
elsym = (struct external_ldsym *) (buf + LDHDRSZ);
|
||||
elsymend = elsym + ldhdr.l_nsyms;
|
||||
for (; elsym < elsymend; elsym++)
|
||||
{
|
||||
struct internal_ldsym ldsym;
|
||||
char nambuf[SYMNMLEN + 1];
|
||||
const char *name;
|
||||
struct bfd_link_hash_entry *h;
|
||||
|
||||
xcoff_swap_ldsym_in (abfd, elsym, &ldsym);
|
||||
|
||||
/* We are only interested in exported symbols. */
|
||||
if ((ldsym.l_smtype & L_EXPORT) == 0)
|
||||
continue;
|
||||
|
||||
if (ldsym._l._l_l._l_zeroes == 0)
|
||||
name = strings + ldsym._l._l_l._l_offset;
|
||||
else
|
||||
{
|
||||
memcpy (nambuf, ldsym._l._l_name, SYMNMLEN);
|
||||
nambuf[SYMNMLEN] = '\0';
|
||||
name = nambuf;
|
||||
}
|
||||
|
||||
h = bfd_link_hash_lookup (info->hash, name, false, false, true);
|
||||
|
||||
/* We are only interested in symbols that are currently
|
||||
undefined. */
|
||||
if (h != NULL && h->type == bfd_link_hash_undefined)
|
||||
{
|
||||
if (! (*info->callbacks->add_archive_element) (info, abfd, name))
|
||||
return false;
|
||||
*pneeded = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* We do not need this shared object. */
|
||||
|
||||
if (buf != NULL && ! coff_section_data (abfd, lsec)->keep_contents)
|
||||
{
|
||||
free (coff_section_data (abfd, lsec)->contents);
|
||||
coff_section_data (abfd, lsec)->contents = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns the index of reloc in RELOCS with the least address greater
|
||||
than or equal to ADDRESS. The relocs are sorted by address. */
|
||||
|
||||
@ -1903,7 +2341,7 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
asection *lsec;
|
||||
bfd_byte *buf = NULL;
|
||||
bfd_byte *buf;
|
||||
struct internal_ldhdr ldhdr;
|
||||
const char *strings;
|
||||
struct external_ldsym *elsym, *elsymend;
|
||||
@ -1922,7 +2360,7 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
("%s: XCOFF shared object when not producing XCOFF output",
|
||||
bfd_get_filename (abfd));
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
goto error_return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The symbols we use from a dynamic object are not the symbols in
|
||||
@ -1943,16 +2381,12 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
("%s: dynamic object with no .loader section",
|
||||
bfd_get_filename (abfd));
|
||||
bfd_set_error (bfd_error_no_symbols);
|
||||
goto error_return;
|
||||
return false;
|
||||
}
|
||||
|
||||
buf = (bfd_byte *) bfd_malloc (lsec->_raw_size);
|
||||
if (buf == NULL && lsec->_raw_size > 0)
|
||||
goto error_return;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, lsec, (PTR) buf, (file_ptr) 0,
|
||||
lsec->_raw_size))
|
||||
goto error_return;
|
||||
if (! xcoff_get_section_contents (abfd, lsec))
|
||||
return false;
|
||||
buf = coff_section_data (abfd, lsec)->contents;
|
||||
|
||||
/* Remove the sections from this object, so that they do not get
|
||||
included in the link. */
|
||||
@ -1995,7 +2429,7 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true,
|
||||
true, true);
|
||||
if (h == NULL)
|
||||
goto error_return;
|
||||
return false;
|
||||
|
||||
h->flags |= XCOFF_DEF_DYNAMIC;
|
||||
|
||||
@ -2036,10 +2470,10 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
if (buf != NULL)
|
||||
if (buf != NULL && ! coff_section_data (abfd, lsec)->keep_contents)
|
||||
{
|
||||
free (buf);
|
||||
buf = NULL;
|
||||
free (coff_section_data (abfd, lsec)->contents);
|
||||
coff_section_data (abfd, lsec)->contents = NULL;
|
||||
}
|
||||
|
||||
/* Record this file in the import files. */
|
||||
@ -2047,7 +2481,7 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
n = ((struct xcoff_import_file *)
|
||||
bfd_alloc (abfd, sizeof (struct xcoff_import_file)));
|
||||
if (n == NULL)
|
||||
goto error_return;
|
||||
return false;
|
||||
n->next = NULL;
|
||||
|
||||
/* For some reason, the path entry in the import file list for a
|
||||
@ -2081,11 +2515,6 @@ xcoff_link_add_dynamic_symbols (abfd, info)
|
||||
xcoff_data (abfd)->import_file_id = c;
|
||||
|
||||
return true;
|
||||
|
||||
error_return:
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Routines that are called after all the input files have been
|
||||
@ -4350,7 +4779,8 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||
|
||||
if (ISFCN (isymp->n_type)
|
||||
|| ISTAG (isymp->n_sclass)
|
||||
|| isymp->n_sclass == C_BLOCK)
|
||||
|| isymp->n_sclass == C_BLOCK
|
||||
|| isymp->n_sclass == C_FCN)
|
||||
{
|
||||
indx = aux.x_sym.x_fcnary.x_fcn.x_endndx.l;
|
||||
if (indx > 0
|
||||
|
Loading…
Reference in New Issue
Block a user