Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "opcode/ia64.h"
#include "elf/ia64.h"
-/*
- * THE RULES for all the stuff the linker creates --
- *
- * GOT Entries created in response to LTOFF or LTOFF_FPTR
- * relocations. Dynamic relocs created for dynamic
- * symbols in an application; REL relocs for locals
- * in a shared library.
- *
- * FPTR The canonical function descriptor. Created for local
- * symbols in applications. Descriptors for dynamic symbols
- * and local symbols in shared libraries are created by
- * ld.so. Thus there are no dynamic relocs against these
- * objects. The FPTR relocs for such _are_ passed through
- * to the dynamic relocation tables.
- *
- * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
- * Requires the creation of a PLTOFF entry. This does not
- * require any dynamic relocations.
- *
- * PLTOFF Created by PLTOFF relocations. For local symbols, this
- * is an alternate function descriptor, and in shared libraries
- * requires two REL relocations. Note that this cannot be
- * transformed into an FPTR relocation, since it must be in
- * range of the GP. For dynamic symbols, this is a function
- * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
- *
- * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
- * does not reqire dynamic relocations.
- */
-
-#define USE_RELA /* we want RELA relocs, not REL */
+/* THE RULES for all the stuff the linker creates --
+
+ GOT Entries created in response to LTOFF or LTOFF_FPTR
+ relocations. Dynamic relocs created for dynamic
+ symbols in an application; REL relocs for locals
+ in a shared library.
+
+ FPTR The canonical function descriptor. Created for local
+ symbols in applications. Descriptors for dynamic symbols
+ and local symbols in shared libraries are created by
+ ld.so. Thus there are no dynamic relocs against these
+ objects. The FPTR relocs for such _are_ passed through
+ to the dynamic relocation tables.
+
+ FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
+ Requires the creation of a PLTOFF entry. This does not
+ require any dynamic relocations.
+
+ PLTOFF Created by PLTOFF relocations. For local symbols, this
+ is an alternate function descriptor, and in shared libraries
+ requires two REL relocations. Note that this cannot be
+ transformed into an FPTR relocation, since it must be in
+ range of the GP. For dynamic symbols, this is a function
+ descriptor for a MIN_PLT entry, and requires one IPLT reloc.
+
+ MIN_PLT Created by PLTOFF entries against dynamic symbols. This
+ does not reqire dynamic relocations. */
#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
struct elfNN_ia64_link_hash_table
{
- /* The main hash table */
+ /* The main hash table. */
struct elf_link_hash_table root;
asection *got_sec; /* the linkage table section (or NULL) */
PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
const char *string));
static void elfNN_ia64_hash_copy_indirect
- PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+ PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *));
static void elfNN_ia64_hash_hide_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
boolean elfNN_hpux_backend_section_from_bfd_section
PARAMS ((bfd *abfd, asection *sec, int *retval));
\f
-/* ia64-specific relocation */
+/* ia64-specific relocation. */
/* Perform a relocation. Not much to do here as all the hard work is
done in elfNN_ia64_final_link_relocate. */
/* Given a BFD reloc type, return the matching HOWTO structure. */
-static reloc_howto_type*
+static reloc_howto_type *
lookup_howto (rtype)
unsigned int rtype;
{
not support brl, and so it gets emulated by the kernel. */
#undef USE_BRL
+#ifdef USE_BRL
static const bfd_byte oor_brl[16] =
{
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
0x00, 0x00, 0x00, 0xc0
};
-
+#else
static const bfd_byte oor_ip[48] =
{
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
0x60, 0x00, 0x80, 0x00 /* br b6;; */
};
+#endif
\f
/* These functions do relaxation for IA-64 ELF.
irelend = internal_relocs + sec->reloc_count;
for (irel = internal_relocs; irel < irelend; irel++)
- if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
+ if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B
+ || ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21M
+ || ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21F)
break;
/* No branch-type relocations. */
struct one_fixup *f;
bfd_size_type amt;
- if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
+ if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B
+ && ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21M
+ && ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21F)
continue;
/* Get the value of the symbol referred to by the reloc. */
else if (strcmp (name, ".HP.opt_annot") == 0)
hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
else if (strcmp (name, ".reloc") == 0)
- /*
- * This is an ugly, but unfortunately necessary hack that is
- * needed when producing EFI binaries on IA-64. It tells
- * elf.c:elf_fake_sections() not to consider ".reloc" as a section
- * containing ELF relocation info. We need this hack in order to
- * be able to generate ELF binaries that can be translated into
- * EFI applications (which are essentially COFF objects). Those
- * files contain a COFF ".reloc" section inside an ELFNN object,
- * which would normally cause BFD to segfault because it would
- * attempt to interpret this section as containing relocation
- * entries for section "oc". With this hack enabled, ".reloc"
- * will be treated as a normal data section, which will avoid the
- * segfault. However, you won't be able to create an ELFNN binary
- * with a section named "oc" that needs relocations, but that's
- * the kind of ugly side-effects you get when detecting section
- * types based on their names... In practice, this limitation is
- * unlikely to bite.
- */
+ /* This is an ugly, but unfortunately necessary hack that is
+ needed when producing EFI binaries on IA-64. It tells
+ elf.c:elf_fake_sections() not to consider ".reloc" as a section
+ containing ELF relocation info. We need this hack in order to
+ be able to generate ELF binaries that can be translated into
+ EFI applications (which are essentially COFF objects). Those
+ files contain a COFF ".reloc" section inside an ELFNN object,
+ which would normally cause BFD to segfault because it would
+ attempt to interpret this section as containing relocation
+ entries for section "oc". With this hack enabled, ".reloc"
+ will be treated as a normal data section, which will avoid the
+ segfault. However, you won't be able to create an ELFNN binary
+ with a section named "oc" that needs relocations, but that's
+ the kind of ugly side-effects you get when detecting section
+ types based on their names... In practice, this limitation is
+ unlikely to bite. */
hdr->sh_type = SHT_PROGBITS;
if (sec->flags & SEC_SMALL_DATA)
break;
}
}
+
+ if (! elf_flags_init (abfd))
+ {
+ unsigned long flags = 0;
+
+ if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
+ flags |= EF_IA_64_BE;
+ if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
+ flags |= EF_IA_64_ABI64;
+
+ elf_elfheader(abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ }
}
/* Hook called by the linker routine which adds symbols from an object
{
struct elf_backend_data *bed;
struct elfNN_ia64_link_hash_table *ia64_info;
+ struct bfd_link_hash_entry *bh = NULL;
bed = get_elf_backend_data (abfd);
ia64_info = elfNN_ia64_hash_table (info);
(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)))
+ bed->collect, &bh)))
return false;
+ h = (struct elf_link_hash_entry *) bh;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
h->type = STT_OBJECT;
struct elf_segment_map *m, **pm;
Elf_Internal_Shdr *hdr;
asection *s;
- boolean unwind_found;
- asection *unwind_sec;
/* If we need a PT_IA_64_ARCHEXT segment, it must come before
all PT_LOAD segments. */
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
if (m->p_type == PT_IA_64_UNWIND)
{
+ int i;
+
/* Look through all sections in the unwind segment
for a match since there may be multiple sections
to a segment. */
+ for (i = m->count - 1; i >= 0; --i)
+ if (m->sections[i] == s)
+ break;
- unwind_sec = m->sections[0];
- unwind_found = false;
- while (unwind_sec != NULL && !unwind_found)
- {
- if (unwind_sec == s)
- unwind_found = true;
- else
- unwind_sec = unwind_sec -> next;
- }
- if (unwind_found)
+ if (i >= 0)
break;
}
case STV_INTERNAL:
case STV_HIDDEN:
return false;
+ default:
+ break;
}
if (h->root.type == bfd_link_hash_undefweak
}
static void
-elfNN_ia64_hash_copy_indirect (xdir, xind)
+elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
+ struct elf_backend_data *bed ATTRIBUTE_UNUSED;
struct elf_link_hash_entry *xdir, *xind;
{
struct elfNN_ia64_link_hash_entry *dir, *ind;
{
Elf_Internal_Rela outrel;
- offset += sec->output_section->vma + sec->output_offset;
-
BFD_ASSERT (dynindx != -1);
outrel.r_info = ELFNN_R_INFO (dynindx, type);
outrel.r_addend = addend;
outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
- if ((outrel.r_offset | 1) == (bfd_vma) -1)
+ if (outrel.r_offset >= (bfd_vma) -2)
{
/* Run for the hills. We shouldn't be outputting a relocation
for this. So do what everyone else does and output a no-op. */
outrel.r_addend = 0;
outrel.r_offset = 0;
}
+ else
+ outrel.r_offset += sec->output_section->vma + sec->output_offset;
bfd_elfNN_swap_reloca_out (abfd, &outrel,
((ElfNN_External_Rela *) srel->contents
#undef elf_backend_section_from_bfd_section
#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
+#undef elf_backend_want_p_paddr_set_to_zero
+#define elf_backend_want_p_paddr_set_to_zero 1
+
#undef ELF_MAXPAGESIZE
#define ELF_MAXPAGESIZE 0x1000 /* 1K */
#define elfNN_bed elfNN_ia64_hpux_bed
#include "elfNN-target.h"
+
+#undef elf_backend_want_p_paddr_set_to_zero