is_unwind_section_name (name)
const char *name;
{
- size_t len1, len2;
+ size_t len1, len2, len3;
len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
- return (strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
- && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0);
+ len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
+ return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
+ && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
+ || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
}
/* Handle an IA-64 specific section when reading an object file. This
/* .IA_64.unwindFOO -> FOO */
text_sect = bfd_get_section_by_name (abfd, sname);
}
+ else if (sname
+ && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
+ strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
+ {
+ /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
+ size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
+ char *once_name = alloca (len2 + strlen (sname) - len + 1);
+
+ memcpy (once_name, ".gnu.linkonce.t.", len2);
+ strcpy (once_name + len2, sname + len);
+ text_sect = bfd_get_section_by_name (abfd, once_name);
+ }
else
/* last resort: fall back on .text */
text_sect = bfd_get_section_by_name (abfd, ".text");
{
if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
{
- /* Define __GLOB_DATA_PTR. This is expected to be a linker-defined
- symbol by the Aix C runtime startup code. Define the symbol
- when it is encountered. IBM sez no one else should use it b/c it is
- undocumented. */
+ /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
+ be a linker-defined symbol by the Aix C runtime startup code. IBM sez
+ no one else should use it b/c it is undocumented. */
struct elf_link_hash_entry *h;
h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, *namep, false, false, false);
ia64_info = elfNN_ia64_hash_table (info);
if (!(_bfd_generic_link_add_one_symbol
- (info, abfd, *namep, BSF_GLOBAL, ia64_info->got_sec,
+ (info, abfd, *namep, BSF_GLOBAL,
+ bfd_get_section_by_name (abfd, ".bss"),
bed->got_symbol_offset, (const char *) NULL, false,
bed->collect, (struct bfd_link_hash_entry **) &h)))
return false;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
h->type = STT_OBJECT;
- if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h))
return false;
}
{
int i;
- /* SHN_MONTEREY_SYSCALL (Description from IBM):
- Special symbols on AIX; if the value is non-zero, the value
- should be put in the gp member of the function descriptor. the
- function address member should be set to the address of the entry
- point of the user-space portion of the system call (epc insn in a
- priviledged page). If the symbol value is zero, look in the special
- table for extended system calls. The number for extended system
- calls will come from that table. The index is set when the linker
- sees an export file that contains the syscall attribute after an
- exported symbol. Kernel extensions indicate extended system calls
- they define by having STO_MONTEREY_SYSCALL in their st_other symbol
- table member. This is used by the system loader to add extended
- system calls to its table, which is subsequently provided to the
- runtime linker at each process startup. */
+ /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
+ is only relevant when compiling code for extended system calls.
+ Replace the "special" section with .text, if possible.
+ Note that these symbols are always assumed to be in .text. */
for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++)
{
asection * sec = bfd_section_from_elf_index (abfd, i);
}
}
- /* FIXME need to determine the proper section instead of defaulting to
- .text. */
if (*secp == NULL)
*secp = bfd_abs_section_ptr;
h = (struct elfNN_ia64_link_hash_entry *)xh;
h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
- h->root.dynindx = -1;
+ if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+ h->root.dynindx = -1;
for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
dyn_i->want_plt2 = 0;
case R_IA64_FPTR32LSB:
case R_IA64_FPTR64MSB:
case R_IA64_FPTR64LSB:
- if (elfNN_ia64_aix_vec (abfd->xvec))
- need_entry = NEED_FPTR | NEED_DYNREL;
- else if (info->shared || h)
+ if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
need_entry = NEED_FPTR | NEED_DYNREL;
else
need_entry = NEED_FPTR;
case R_IA64_DIR64LSB:
/* Shared objects will always need at least a REL relocation. */
if (info->shared || maybe_dynamic
- /* On AIX, we always need a relocation, but make sure
- __GLOB_DATA_PTR doesn't get an entry. */
|| (elfNN_ia64_aix_vec (abfd->xvec)
- && (!h || strcmp (h->root.root.string,
+ && (!h || strcmp (h->root.root.string,
"__GLOB_DATA_PTR") != 0)))
need_entry = NEED_DYNREL;
dynrel_type = R_IA64_DIR64LSB;
if (dyn_i->want_got
&& ! dyn_i->want_fptr
&& (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
- || elfNN_ia64_aix_vec (x->info->hash->creator)))
+ || (elfNN_ia64_aix_vec (x->info->hash->creator)
+ && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
+ "__GLOB_DATA_PTR") != 0))))
{
dyn_i->got_offset = x->ofs;
x->ofs += 8;
ia64_info = elfNN_ia64_hash_table (x->info);
dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
- || elfNN_ia64_aix_vec (x->info->hash->creator);
+ || (elfNN_ia64_aix_vec (x->info->hash->creator)
+ /* Don't allocate an entry for __GLOB_DATA_PTR */
+ && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
+ "__GLOB_DATA_PTR") != 0));
shared = x->info->shared;
/* Take care of the normal data relocations. */
/* Install a dynamic relocation for this reloc. */
if ((dynamic_symbol_p || info->shared
|| (elfNN_ia64_aix_vec (info->hash->creator)
- /* We want REL relocation for _GLOB_DATA_PTR, which would
- otherwise be an IMM64, which isn't handled below. The
- symbol comes from the C runtime. */
- && (!h ||
- strcmp (h->root.root.string, "__GLOB_DATA_PTR") != 0)))
+ /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
+ && (!h || strcmp (h->root.root.string,
+ "__GLOB_DATA_PTR") != 0)))
&& (input_section->flags & SEC_ALLOC) != 0)
{
unsigned int dyn_r_type;