/* IA-64 support for 64-bit ELF
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2009 Free Software Foundation, Inc.
+ 2008, 2009, 2010 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of BFD, the Binary File Descriptor library.
#include "elf/ia64.h"
#include "objalloc.h"
#include "hashtab.h"
+#include "bfd_stdint.h"
#define ARCH_SIZE NN
MIN_PLT Created by PLTOFF entries against dynamic symbols. This
does not require dynamic relocations. */
+/* Only add code for vms when the vms target is enabled. This is required
+ because it depends on vms-lib.c for its archive format and we don't want
+ to compile that code if it is not used. */
+#if ARCH_SIZE == 64 && \
+ (defined (HAVE_bfd_elf64_ia64_vms_vec) || defined (HAVE_all_vecs))
+#define INCLUDE_IA64_VMS
+#endif
+
+
#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
typedef struct bfd_hash_entry *(*new_hash_entry_func)
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
/* In dynamically (linker-) created sections, we generally need to keep track
of the place a symbol or expression got allocated to. This is done via hash
/* The main hash table. */
struct elf_link_hash_table root;
- asection *fptr_sec; /* function descriptor table (or NULL) */
- asection *rel_fptr_sec; /* dynamic relocation section for same */
- asection *pltoff_sec; /* private descriptors for plt (or NULL) */
- asection *rel_pltoff_sec; /* dynamic relocation section for same */
-
- bfd_size_type minplt_entries; /* number of minplt entries */
- unsigned reltext : 1; /* are there relocs against readonly sections? */
- unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
- bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
+ asection *fptr_sec; /* Function descriptor table (or NULL). */
+ asection *rel_fptr_sec; /* Dynamic relocation section for same. */
+ asection *pltoff_sec; /* Private descriptors for plt (or NULL). */
+ asection *rel_pltoff_sec; /* Dynamic relocation section for same. */
+
+ bfd_size_type minplt_entries; /* Number of minplt entries. */
+ unsigned reltext : 1; /* Are there relocs against readonly sections? */
+ unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished? */
+ bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry. */
+ /* There are maybe R_IA64_GPREL22 relocations, including those
+ optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
+ sections. We need to record those sections so that we can choose
+ a proper GP to cover all R_IA64_GPREL22 relocations. */
+ asection *max_short_sec; /* Maximum short output section. */
+ bfd_vma max_short_offset; /* Maximum short offset. */
+ asection *min_short_sec; /* Minimum short output section. */
+ bfd_vma min_short_offset; /* Minimum short offset. */
htab_t loc_hash_table;
void *loc_hash_memory;
};
#define elfNN_ia64_hash_table(p) \
- ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
(struct elfNN_ia64_link_hash_table *ia64_info,
static bfd_boolean
elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
{
- unsigned int template, mlx;
+ unsigned int template_val, mlx;
bfd_vma t0, t1, s0, s1, s2, br_code;
long br_slot;
bfd_byte *hit_addr;
hit_addr = (bfd_byte *) (contents + off);
- br_slot = (long) hit_addr & 0x3;
+ br_slot = (intptr_t) hit_addr & 0x3;
hit_addr -= br_slot;
t0 = bfd_getl64 (hit_addr + 0);
t1 = bfd_getl64 (hit_addr + 8);
/* Check if we can turn br into brl. A label is always at the start
of the bundle. Even if there are predicates on NOPs, we still
perform this optimization. */
- template = t0 & 0x1e;
+ template_val = t0 & 0x1e;
s0 = (t0 >> 5) & 0x1ffffffffffLL;
s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
s2 = (t1 >> 23) & 0x1ffffffffffLL;
case 1:
/* Check if slot 2 is NOP. Possible templates are MBB and BBB.
For BBB, slot 0 also has to be nop.b. */
- if (!((template == 0x12 /* MBB */
+ if (!((template_val == 0x12 /* MBB */
&& IS_NOP_B (s2))
- || (template == 0x16 /* BBB */
+ || (template_val == 0x16 /* BBB */
&& IS_NOP_B (s0)
&& IS_NOP_B (s2))))
return FALSE;
case 2:
/* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
MMB and MFB. For BBB, slot 0 also has to be nop.b. */
- if (!((template == 0x10 /* MIB */
+ if (!((template_val == 0x10 /* MIB */
&& IS_NOP_I (s1))
- || (template == 0x12 /* MBB */
+ || (template_val == 0x12 /* MBB */
&& IS_NOP_B (s1))
- || (template == 0x16 /* BBB */
+ || (template_val == 0x16 /* BBB */
&& IS_NOP_B (s0)
&& IS_NOP_B (s1))
- || (template == 0x18 /* MMB */
+ || (template_val == 0x18 /* MMB */
&& IS_NOP_M (s1))
- || (template == 0x1c /* MFB */
+ || (template_val == 0x1c /* MFB */
&& IS_NOP_F (s1))))
return FALSE;
br_code = s2;
else
mlx = 0x4;
- if (template == 0x16)
+ if (template_val == 0x16)
{
/* For BBB, we need to put nop.m in slot 0. We keep the original
predicate only if slot 0 isn't br. */
static void
elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
{
- int template;
+ int template_val;
bfd_byte *hit_addr;
bfd_vma t0, t1, i0, i1, i2;
hit_addr = (bfd_byte *) (contents + off);
- hit_addr -= (long) hit_addr & 0x3;
+ hit_addr -= (intptr_t) hit_addr & 0x3;
t0 = bfd_getl64 (hit_addr);
t1 = bfd_getl64 (hit_addr + 8);
/* Turn a MLX bundle into a MBB bundle with the same stop-bit
variety. */
if (t0 & 0x1)
- template = 0x13;
+ template_val = 0x13;
else
- template = 0x12;
- t0 = (i1 << 46) | (i0 << 5) | template;
+ template_val = 0x12;
+ t0 = (i1 << 46) | (i0 << 5) | template_val;
t1 = (i2 << 23) | (i1 >> 18);
bfd_putl64 (t0, hit_addr);
/* Rename some of the generic section flags to better document how they
are used here. */
-#define skip_relax_pass_0 need_finalize_relax
-#define skip_relax_pass_1 has_gp_reloc
+#define skip_relax_pass_0 sec_flg0
+#define skip_relax_pass_1 sec_flg1
\f
/* These functions do relaxation for IA-64 ELF. */
+static void
+elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
+ struct elfNN_ia64_link_hash_table *ia64_info)
+{
+ /* Skip ABS and SHF_IA_64_SHORT sections. */
+ if (sec == bfd_abs_section_ptr
+ || (sec->flags & SEC_SMALL_DATA) != 0)
+ return;
+
+ if (!ia64_info->min_short_sec)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+ else if (sec == ia64_info->max_short_sec
+ && offset > ia64_info->max_short_offset)
+ ia64_info->max_short_offset = offset;
+ else if (sec == ia64_info->min_short_sec
+ && offset < ia64_info->min_short_offset)
+ ia64_info->min_short_offset = offset;
+ else if (sec->output_section->vma
+ > ia64_info->max_short_sec->vma)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ }
+ else if (sec->output_section->vma
+ < ia64_info->min_short_sec->vma)
+ {
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+}
+
static bfd_boolean
elfNN_ia64_relax_section (bfd *abfd, asection *sec,
struct bfd_link_info *link_info,
|| (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
return TRUE;
+ ia64_info = elfNN_ia64_hash_table (link_info);
+ if (ia64_info == NULL)
+ return FALSE;
+
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Load the relocations for this section. */
internal_relocs = (_bfd_elf_link_read_relocs
- (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
return FALSE;
- ia64_info = elfNN_ia64_hash_table (link_info);
irelend = internal_relocs + sec->reloc_count;
/* Get the section contents. */
is_branch = TRUE;
break;
+ case R_IA64_GPREL22:
+ /* Update max_short_sec/min_short_sec. */
+
case R_IA64_LTOFF22X:
case R_IA64_LDXMOV:
/* We can't relax ldx/mov in pass 0 since br relaxations will
||(bfd_signed_vma) (symaddr - gp) < -0x200000)
continue;
- if (r_type == R_IA64_LTOFF22X)
+ if (r_type == R_IA64_GPREL22)
+ elfNN_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
+ else if (r_type == R_IA64_LTOFF22X)
{
irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
R_IA64_GPREL22);
dyn_i->want_gotx = 0;
changed_got |= !dyn_i->want_got;
}
+
+ elfNN_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
}
else
{
const char *name,
int shindex)
{
- asection *newsect;
-
/* There ought to be a place to keep ELF backend specific flags, but
at the moment there isn't one. We just keep track of the
sections by their name, instead. Fortunately, the ABI gives
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
return FALSE;
- newsect = hdr->bfd_section;
return TRUE;
}
elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
asection *sec)
{
- register const char *name;
+ const char *name;
name = bfd_get_section_name (abfd, sec);
struct elfNN_ia64_local_hash_entry *entry
= (struct elfNN_ia64_local_hash_entry *) ptr;
- return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
- ^ entry->r_sym ^ (entry->id >> 16);
+ return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
}
/* Compare local hash entries. */
derived hash table to keep information specific to the IA-64 ElF
linker (without using static variables). */
-static struct bfd_link_hash_table*
+static struct bfd_link_hash_table *
elfNN_ia64_hash_table_create (bfd *abfd)
{
struct elfNN_ia64_link_hash_table *ret;
ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
if (!ret)
- return 0;
+ return NULL;
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
elfNN_ia64_new_elf_hash_entry,
- sizeof (struct elfNN_ia64_link_hash_entry)))
+ sizeof (struct elfNN_ia64_link_hash_entry),
+ IA64_ELF_DATA))
{
free (ret);
- return 0;
+ return NULL;
}
ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
- return 0;
+ return NULL;
}
return &ret->root.root;
return FALSE;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
{
flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
{
struct elfNN_ia64_local_hash_entry e, *ret;
asection *sec = abfd->sections;
- hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
- ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ ELFNN_R_SYM (rel->r_info));
void **slot;
e.id = sec->id;
unsigned int count)
{
bfd_vma curr, prev, got_offset;
- unsigned int i, kept, dup, diff, dest, src, len;
+ unsigned int i, kept, dupes, diff, dest, src, len;
qsort (info, count, sizeof (*info), addend_compare);
/* Find the next duplicate. SRC will be kept. */
prev = info [src].addend;
got_offset = info [src].got_offset;
- for (dup = src + 1; dup < count; dup++)
+ for (dupes = src + 1; dupes < count; dupes ++)
{
- curr = info [dup].addend;
+ curr = info [dupes].addend;
if (curr == prev)
{
/* Make sure that got_offset is valid. */
if (got_offset == (bfd_vma) -1)
- got_offset = info [dup].got_offset;
+ got_offset = info [dupes].got_offset;
/* For duplicates, make sure that the kept one has
a valid got_offset. */
if (got_offset != (bfd_vma) -1)
- info [dup - 1].got_offset = got_offset;
+ info [dupes - 1].got_offset = got_offset;
break;
}
- got_offset = info [dup].got_offset;
+ got_offset = info [dupes].got_offset;
prev = curr;
}
/* How much to move. */
- len = dup - src;
- i = dup + 1;
+ len = dupes - src;
+ i = dupes + 1;
- if (len == 1 && dup < count)
+ if (len == 1 && dupes < count)
{
/* If we only move 1 element, we combine it with the next
one. There must be at least a duplicate. Find the
next different one. */
- for (diff = dup + 1, src++; diff < count; diff++, src++)
+ for (diff = dupes + 1, src++; diff < count; diff++, src++)
{
if (info [diff].addend != curr)
break;
offset. */
prev = info [diff].addend;
got_offset = info [diff].got_offset;
- for (dup = diff + 1; dup < count; dup++)
+ for (dupes = diff + 1; dupes < count; dupes ++)
{
- curr = info [dup].addend;
+ curr = info [dupes].addend;
if (curr == prev)
{
/* For duplicates, make sure that GOT_OFFSET
is valid. */
if (got_offset == (bfd_vma) -1)
- got_offset = info [dup].got_offset;
+ got_offset = info [dupes].got_offset;
break;
}
- got_offset = info [dup].got_offset;
+ got_offset = info [dupes].got_offset;
prev = curr;
diff++;
}
srel_name = (bfd_elf_string_from_elf_section
(abfd, elf_elfheader(abfd)->e_shstrndx,
- elf_section_data(sec)->rel_hdr.sh_name));
+ _bfd_elf_single_rel_hdr (sec)->sh_name));
if (srel_name == NULL)
return NULL;
- BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
- && strcmp (bfd_get_section_name (abfd, sec),
- srel_name+5) == 0)
- || (CONST_STRNEQ (srel_name, ".rel")
- && strcmp (bfd_get_section_name (abfd, sec),
- srel_name+4) == 0));
-
dynobj = ia64_info->root.dynobj;
if (!dynobj)
ia64_info->root.dynobj = dynobj = abfd;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
got = fptr = srel = pltoff = NULL;
static bfd_boolean
allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
- PTR data)
+ void * data)
{
struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
struct elfNN_ia64_link_hash_table *ia64_info;
ia64_info = elfNN_ia64_hash_table (x->info);
+ if (ia64_info == NULL)
+ return FALSE;
+
if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
{
ia64_info->self_dtpmod_offset = x->ofs;
static bfd_boolean
allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
- PTR data)
+ void * data)
{
struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
bfd_boolean dynamic_symbol, shared, resolved_zero;
ia64_info = elfNN_ia64_hash_table (x->info);
+ if (ia64_info == NULL)
+ return FALSE;
/* Note that this can't be used in relation to FPTR relocs below. */
dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
dynobj = elf_hash_table(info)->dynobj;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
ia64_info->self_dtpmod_offset = (bfd_vma) -1;
BFD_ASSERT(dynobj != NULL);
data.info = info;
switch (opnd)
{
case IA64_OPND_IMMU64:
- hit_addr -= (long) hit_addr & 0x3;
+ hit_addr -= (intptr_t) hit_addr & 0x3;
t0 = bfd_getl64 (hit_addr);
t1 = bfd_getl64 (hit_addr + 8);
break;
case IA64_OPND_TGT64:
- hit_addr -= (long) hit_addr & 0x3;
+ hit_addr -= (intptr_t) hit_addr & 0x3;
t0 = bfd_getl64 (hit_addr);
t1 = bfd_getl64 (hit_addr + 8);
break;
default:
- switch ((long) hit_addr & 0x3)
+ switch ((intptr_t) hit_addr & 0x3)
{
case 0: shift = 5; break;
case 1: shift = 14; hit_addr += 3; break;
bfd_vma got_offset;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
got_sec = ia64_info->root.sgot;
switch (dyn_r_type)
asection *fptr_sec;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
fptr_sec = ia64_info->fptr_sec;
if (!dyn_i->fptr_done)
asection *pltoff_sec;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
pltoff_sec = ia64_info->pltoff_sec;
/* Don't do anything if this symbol uses a real PLT entry. In
struct elfNN_ia64_link_hash_table *ia64_info;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
/* Find the min and max vma of all sections marked short. Also collect
min and max vma of any type, for use in selecting a nice gp. */
}
}
+ if (ia64_info->min_short_sec)
+ {
+ if (min_short_vma
+ > (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset))
+ min_short_vma = (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset);
+ if (max_short_vma
+ < (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset))
+ max_short_vma = (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset);
+ }
+
/* See if the user wants to force a value. */
gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
FALSE, FALSE);
{
/* Pick a sensible value. */
- asection *got_sec = ia64_info->root.sgot;
+ if (ia64_info->min_short_sec)
+ {
+ bfd_vma short_range = max_short_vma - min_short_vma;
- /* Start with just the address of the .got. */
- if (got_sec)
- gp_val = got_sec->output_section->vma;
- else if (max_short_vma != 0)
- gp_val = min_short_vma;
- else if (max_vma - min_vma < 0x200000)
- gp_val = min_vma;
+ /* If min_short_sec is set, pick one in the middle bewteen
+ min_short_vma and max_short_vma. */
+ if (short_range >= 0x400000)
+ goto overflow;
+ gp_val = min_short_vma + short_range / 2;
+ }
else
- gp_val = max_vma - 0x200000 + 8;
+ {
+ asection *got_sec = ia64_info->root.sgot;
+
+ /* Start with just the address of the .got. */
+ if (got_sec)
+ gp_val = got_sec->output_section->vma;
+ else if (max_short_vma != 0)
+ gp_val = min_short_vma;
+ else if (max_vma - min_vma < 0x200000)
+ gp_val = min_vma;
+ else
+ gp_val = max_vma - 0x200000 + 8;
+ }
/* If it is possible to address the entire image, but we
don't with the choice above, adjust. */
{
if (max_short_vma - min_short_vma >= 0x400000)
{
+overflow:
(*_bfd_error_handler)
(_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
bfd_get_filename (abfd),
asection *unwind_output_sec;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
/* Make sure we've got ourselves a nice fat __gp value. */
if (!info->relocatable)
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
/* Infect various flags from the input section to the output section. */
if (info->relocatable)
continue;
}
- /* For relocs against symbols from removed linkonce sections,
- or sections discarded by a linker script, we just want the
- section contents zeroed. Avoid any special processing. */
if (sym_sec != NULL && elf_discarded_section (sym_sec))
- {
- _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
- rel->r_info = 0;
- rel->r_addend = 0;
- continue;
- }
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
if (info->relocatable)
continue;
case R_IA64_DIR64LSB:
/* Install a dynamic relocation for this reloc. */
if ((dynamic_symbol_p || info->shared)
- && r_symndx != 0
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0)
{
unsigned int dyn_r_type;
case R_IA64_PCREL64MSB:
case R_IA64_PCREL64LSB:
/* Install a dynamic relocation for this reloc. */
- if (dynamic_symbol_p && r_symndx != 0)
+ if (dynamic_symbol_p && r_symndx != STN_UNDEF)
{
BFD_ASSERT (srel != NULL);
struct elfNN_ia64_dyn_sym_info *dyn_i;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
/* Fill in the PLT data, if required. */
Elf_Internal_Rela outrel;
bfd_byte *loc;
asection *plt_sec;
- bfd_vma plt_addr, pltoff_addr, gp_val, index;
+ bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
gp_val = _bfd_get_gp_value (output_bfd);
/* Initialize the minimal PLT entry. */
- index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
+ plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
plt_sec = ia64_info->root.splt;
loc = plt_sec->contents + dyn_i->plt_offset;
memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
- elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
+ elfNN_ia64_install_value (loc, plt_index, R_IA64_IMM22);
elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
plt_addr = (plt_sec->output_section->vma
PLT relocations. */
loc = ia64_info->rel_pltoff_sec->contents;
- loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
+ loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
* sizeof (ElfNN_External_Rela));
bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
}
bfd *dynobj;
ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
dynobj = ia64_info->root.dynobj;
if (elf_hash_table (info)->dynamic_sections_created)
}
}
+#ifdef INCLUDE_IA64_VMS
+
static bfd_boolean
elfNN_vms_section_from_shdr (bfd *abfd,
Elf_Internal_Shdr *hdr,
const char *name,
int shindex)
{
- asection *newsect;
-
switch (hdr->sh_type)
{
case SHT_IA_64_VMS_TRACE:
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
return FALSE;
- newsect = hdr->bfd_section;
return TRUE;
}
return _bfd_generic_close_and_cleanup (abfd);
}
+#endif /* INCLUDE_IA64_VMS */
\f
#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
#define TARGET_LITTLE_NAME "elfNN-ia64-little"
#define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
#define TARGET_BIG_NAME "elfNN-ia64-big"
#define ELF_ARCH bfd_arch_ia64
+#define ELF_TARGET_ID IA64_ELF_DATA
#define ELF_MACHINE_CODE EM_IA_64
#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
#include "elfNN-target.h"
/* VMS-specific vectors. */
+#ifdef INCLUDE_IA64_VMS
#undef TARGET_LITTLE_SYM
#define TARGET_LITTLE_SYM bfd_elfNN_ia64_vms_vec
#undef elf_backend_want_p_paddr_set_to_zero
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_OPENVMS
+
#undef ELF_MAXPAGESIZE
#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
#undef elfNN_bed
#define elfNN_bed elfNN_ia64_vms_bed
+/* Use VMS-style archives (in particular, don't use the standard coff
+ archive format). */
+#define bfd_elfNN_archive_functions
+
+#undef bfd_elfNN_archive_p
+#define bfd_elfNN_archive_p _bfd_vms_lib_ia64_archive_p
+#undef bfd_elfNN_write_archive_contents
+#define bfd_elfNN_write_archive_contents _bfd_vms_lib_write_archive_contents
+#undef bfd_elfNN_mkarchive
+#define bfd_elfNN_mkarchive _bfd_vms_lib_ia64_mkarchive
+
+#define bfd_elfNN_archive_slurp_armap \
+ _bfd_vms_lib_slurp_armap
+#define bfd_elfNN_archive_slurp_extended_name_table \
+ _bfd_vms_lib_slurp_extended_name_table
+#define bfd_elfNN_archive_construct_extended_name_table \
+ _bfd_vms_lib_construct_extended_name_table
+#define bfd_elfNN_archive_truncate_arname \
+ _bfd_vms_lib_truncate_arname
+#define bfd_elfNN_archive_write_armap \
+ _bfd_vms_lib_write_armap
+#define bfd_elfNN_archive_read_ar_hdr \
+ _bfd_vms_lib_read_ar_hdr
+#define bfd_elfNN_archive_write_ar_hdr \
+ _bfd_vms_lib_write_ar_hdr
+#define bfd_elfNN_archive_openr_next_archived_file \
+ _bfd_vms_lib_openr_next_archived_file
+#define bfd_elfNN_archive_get_elt_at_index \
+ _bfd_vms_lib_get_elt_at_index
+#define bfd_elfNN_archive_generic_stat_arch_elt \
+ _bfd_vms_lib_generic_stat_arch_elt
+#define bfd_elfNN_archive_update_armap_timestamp \
+ _bfd_vms_lib_update_armap_timestamp
+
#include "elfNN-target.h"
+
+#endif /* INCLUDE_IA64_VMS */