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? */
struct elfNN_ia64_local_hash_table loc_hash_table;
};
PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
const char **namep, flagword *flagsp, asection **secp,
bfd_vma *valp));
-static boolean elfNN_ia64_aix_vec
+static boolean elfNN_ia64_aix_vec
PARAMS ((const bfd_target *vec));
static boolean elfNN_ia64_aix_add_symbol_hook
PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
const Elf_Internal_Rela *relocs));
static boolean elfNN_ia64_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
-static unsigned long global_sym_index
+static long global_sym_index
PARAMS ((struct elf_link_hash_entry *h));
static boolean allocate_fptr
PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
PARAMS ((bfd *ibfd, bfd *obfd));
static boolean elfNN_ia64_print_private_bfd_data
PARAMS ((bfd *abfd, PTR ptr));
+static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
+ PARAMS ((const Elf_Internal_Rela *));
\f
/* ia64-specific relocation */
arelent *bfd_reloc;
ElfNN_Internal_Rela *elf_reloc;
{
- bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
+ bfd_reloc->howto
+ = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
}
\f
#define PLT_HEADER_SIZE (3 * 16)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ || (bfd_bread (extsyms, symtab_hdr->sh_size, abfd)
!= symtab_hdr->sh_size))
goto error_return;
}
Elf_Internal_Sym isym;
asection *tsec;
struct one_fixup *f;
+ bfd_size_type amt;
if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
continue;
roff = irel->r_offset;
reladdr = (sec->output_section->vma
+ sec->output_offset
- + roff) & -4;
+ + roff) & (bfd_vma) -4;
/* If the branch is in range, no need to do anything. */
if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
make a copy of the FULL_PLT entry. Otherwise, we'll have
to use a `brl' insn to get where we're going. */
- int size;
+ size_t size;
if (tsec == ia64_info->plt_sec)
size = sizeof (plt_full_entry);
}
/* Resize the current section to make room for the new branch. */
- trampoff = (sec->_cooked_size + 15) & -16;
- contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
+ trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
+ amt = trampoff + size;
+ contents = (bfd_byte *) bfd_realloc (contents, amt);
if (contents == NULL)
goto error_return;
- sec->_cooked_size = trampoff + size;
+ sec->_cooked_size = amt;
if (tsec == ia64_info->plt_sec)
{
}
/* Record the fixup so we don't do it again this section. */
- f = (struct one_fixup *) bfd_malloc (sizeof (*f));
+ f = (struct one_fixup *) bfd_malloc ((bfd_size_type) sizeof (*f));
f->next = fixups;
f->tsec = tsec;
f->toff = toff;
/* Fix up the existing branch to hit the trampoline. Hope like
hell this doesn't overflow too. */
if (elfNN_ia64_install_value (abfd, contents + roff,
- f->trampoff - (roff & -4),
+ f->trampoff - (roff & (bfd_vma) -4),
R_IA64_PCREL21B) != bfd_reloc_ok)
goto error_return;
extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
- return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
+ return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
|| vec == & bfd_elfNN_ia64_aix_big_vec);
}
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);
- if (h == NULL)
+ h = elf_link_hash_lookup (elf_hash_table (info), *namep,
+ false, false, false);
+ if (h == NULL)
{
struct elf_backend_data *bed;
struct elfNN_ia64_link_hash_table *ia64_info;
bed = get_elf_backend_data (abfd);
ia64_info = elfNN_ia64_hash_table (info);
-
+
if (!(_bfd_generic_link_add_one_symbol
- (info, abfd, *namep, BSF_GLOBAL,
+ (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 (! _bfd_elf_link_record_dynamic_symbol (info, h))
return false;
}
else if (sym->st_shndx == SHN_LOOS)
{
int i;
-
+
/* 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.
+ 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);
-
+ asection * sec = bfd_section_from_elf_index (abfd, (unsigned) i);
+
if (sec && strcmp (sec->name, ".text") == 0)
{
*secp = sec;
if (*secp == NULL)
*secp = bfd_abs_section_ptr;
-
+
*valp = sym->st_size;
-
+
return true;
}
- else
+ else
{
- return elfNN_ia64_add_symbol_hook (abfd, info, sym,
+ return elfNN_ia64_add_symbol_hook (abfd, info, sym,
namep, flagsp, secp, valp);
}
}
break;
if (m == NULL)
{
- m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
if (m == NULL)
return false;
if (m == NULL)
{
- m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
if (m == NULL)
return false;
|| h->root.type == bfd_link_hash_defweak)
return true;
- if ((info->shared && !info->symbolic)
+ if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
|| ((h->elf_link_hash_flags
& (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
== (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
{
struct elfNN_ia64_link_hash_entry *dir, *ind;
- dir = (struct elfNN_ia64_link_hash_entry *)xdir;
- ind = (struct elfNN_ia64_link_hash_entry *)xind;
+ dir = (struct elfNN_ia64_link_hash_entry *) xdir;
+ ind = (struct elfNN_ia64_link_hash_entry *) xind;
/* Copy down any references that we may have already seen to the
symbol which just became indirect. */
| ELF_LINK_HASH_REF_REGULAR
| ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+ if (ind->root.root.type != bfd_link_hash_indirect)
+ return;
+
/* Copy over the got and plt data. This would have been done
by check_relocs. */
{
struct elfNN_ia64_link_hash_table *ret;
- ret = bfd_alloc (abfd, sizeof (*ret));
+ ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
if (!ret)
return 0;
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
if (dyn_i == NULL && create)
{
- dyn_i = (struct elfNN_ia64_dyn_sym_info *)
- bfd_zalloc (abfd, sizeof *dyn_i);
+ dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
*pp = dyn_i;
dyn_i->addend = addend;
}
return NULL;
}
+ if (sec->flags & SEC_READONLY)
+ ia64_info->reltext = 1;
+
return srel;
}
if (!rent)
{
- rent = (struct elfNN_ia64_dyn_reloc_entry *)
- bfd_alloc (abfd, sizeof (*rent));
+ rent = ((struct elfNN_ia64_dyn_reloc_entry *)
+ bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
if (!rent)
return false;
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = false;
- if (h && ((info->shared && ! info->symbolic)
+ if (h && ((info->shared
+ && (!info->symbolic || info->allow_shlib_undefined))
|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
|| h->root.type == bfd_link_hash_defweak
|| elfNN_ia64_aix_vec (abfd->xvec)))
{
(*info->callbacks->warning)
(info, _("@pltoff reloc against local symbol"), 0,
- abfd, 0, 0);
+ abfd, 0, (bfd_vma) 0);
}
break;
{
(*info->callbacks->warning)
(info, _("non-zero addend in @fptr reloc"), 0,
- abfd, 0, 0);
+ abfd, 0, (bfd_vma) 0);
}
dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
|| elfNN_ia64_aix_vec (abfd->xvec)))
{
if (! (_bfd_elfNN_link_record_local_dynamic_symbol
- (info, abfd, r_symndx)))
+ (info, abfd, (long) r_symndx)))
return false;
}
/* Search for the index of a global symbol in it's defining object file. */
-static unsigned long
+static long
global_sym_index (h)
struct elf_link_hash_entry *h;
{
struct elfNN_ia64_link_hash_table *ia64_info;
asection *sec;
bfd *dynobj;
- boolean reltext = false;
boolean relplt = false;
dynobj = elf_hash_table(info)->dynobj;
}
/* Align the pointer for the plt2 entries. */
- data.ofs = (data.ofs + 31) & -32;
+ data.ofs = (data.ofs + 31) & (bfd_vma) -32;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
if (data.ofs != 0)
{
if (!strip)
{
- const char *outname;
- asection *target;
-
- /* If this relocation section applies to a read only
- section, then we probably need a DT_TEXTREL entry. */
- outname = bfd_get_section_name (output_bfd,
- sec->output_section);
- if (outname[4] == 'a')
- outname += 5;
- else
- outname += 4;
-
- target = bfd_get_section_by_name (output_bfd, outname);
- if (target != NULL
- && (target->flags & SEC_READONLY) != 0
- && (target->flags & SEC_ALLOC) != 0)
- reltext = true;
-
/* We use the reloc_count field as a counter if we need to
copy relocs into the output file. */
sec->reloc_count = 0;
else
{
/* Allocate memory for the section contents. */
- sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
+ sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
if (sec->contents == NULL && sec->_raw_size != 0)
return false;
}
{
/* The DT_DEBUG entry is filled in by the dynamic linker and used
by the debugger. */
- if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
+#define add_dynamic_entry(TAG, VAL) \
+ bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+
+ if (!add_dynamic_entry (DT_DEBUG, 0))
return false;
}
- if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
+ if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
return false;
- if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
+ if (!add_dynamic_entry (DT_PLTGOT, 0))
return false;
if (relplt)
{
- if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
return false;
}
- if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
- sizeof (ElfNN_External_Rela)))
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
return false;
- if (reltext)
+ if (ia64_info->reltext)
{
- if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
return false;
info->flags |= DF_TEXTREL;
}
}
static bfd_reloc_status_type
-elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
+elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
bfd *abfd;
bfd_byte *hit_addr;
- bfd_vma val;
+ bfd_vma v;
unsigned int r_type;
{
const struct ia64_operand *op;
enum ia64_opnd opnd;
const char *err;
size_t size = 8;
+#ifdef BFD_HOST_U_64_BIT
+ BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
+#else
+ bfd_vma val = v;
+#endif
opnd = IA64_OPND_NIL;
switch (r_type)
insn = (dword >> shift) & 0x1ffffffffffLL;
op = elf64_ia64_operands + opnd;
- err = (*op->insert) (op, val, &insn);
+ err = (*op->insert) (op, val, (ia64_insn *)& insn);
if (err)
return bfd_reloc_overflow;
if (unwind_output_sec)
{
elfNN_ia64_unwind_entry_compare_bfd = abfd;
- qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
- 24, elfNN_ia64_unwind_entry_compare);
+ qsort (unwind_output_sec->contents,
+ (size_t) (unwind_output_sec->_raw_size / 24),
+ 24,
+ elfNN_ia64_unwind_entry_compare);
if (! bfd_set_section_contents (abfd, unwind_output_sec,
- unwind_output_sec->contents, 0,
+ unwind_output_sec->contents, (bfd_vma) 0,
unwind_output_sec->_raw_size))
return false;
}
{
(*_bfd_error_handler)
(_("%s: unknown relocation type %d"),
- bfd_get_filename (input_bfd), (int)r_type);
+ bfd_archive_filename (input_bfd), (int)r_type);
bfd_set_error (bfd_error_bad_value);
ret_val = false;
continue;
}
else if (h->root.type == bfd_link_hash_undefweak)
undef_weak_ref = true;
- else if (info->shared && !info->symbolic
+ else if (info->shared
+ && (!info->symbolic || info->allow_shlib_undefined)
&& !info->no_undefined
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
;
if ((dynamic_symbol_p || info->shared
|| (elfNN_ia64_aix_vec (info->hash->creator)
/* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
- && (!h || strcmp (h->root.root.string,
+ && (!h || strcmp (h->root.root.string,
"__GLOB_DATA_PTR") != 0)))
&& (input_section->flags & SEC_ALLOC) != 0)
{
shared libraries. Hork. */
(*_bfd_error_handler)
(_("%s: linking non-pic code in a shared library"),
- bfd_get_filename (input_bfd));
+ bfd_archive_filename (input_bfd));
ret_val = false;
continue;
}
{
(*_bfd_error_handler)
(_("%s: @gprel relocation against dynamic symbol %s"),
- bfd_get_filename (input_bfd), h->root.root.string);
+ bfd_archive_filename (input_bfd), h->root.root.string);
ret_val = false;
continue;
}
else
{
dynindx = (_bfd_elf_link_lookup_local_dynindx
- (info, input_bfd, r_symndx));
+ (info, input_bfd, (long) r_symndx));
}
elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
}
else
dynindx = (_bfd_elf_link_lookup_local_dynindx
- (info, input_bfd, r_symndx));
+ (info, input_bfd, (long) r_symndx));
value = 0;
}
{
(*_bfd_error_handler)
(_("%s: dynamic relocation against speculation fixup"),
- bfd_get_filename (input_bfd));
+ bfd_archive_filename (input_bfd));
ret_val = false;
continue;
}
{
(*_bfd_error_handler)
(_("%s: speculation fixup against undefined weak symbol"),
- bfd_get_filename (input_bfd));
+ bfd_archive_filename (input_bfd));
ret_val = false;
continue;
}
name = bfd_section_name (input_bfd, input_section);
}
if (!(*info->callbacks->reloc_overflow) (info, name,
- howto->name, 0,
+ howto->name,
+ (bfd_vma) 0,
input_bfd,
input_section,
rel->r_offset))
{
(*_bfd_error_handler)
(_("%s: linking trap-on-NULL-dereference with non-trapping files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
bfd_set_error (bfd_error_bad_value);
ok = false;
{
(*_bfd_error_handler)
(_("%s: linking big-endian files with little-endian files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
bfd_set_error (bfd_error_bad_value);
ok = false;
{
(*_bfd_error_handler)
(_("%s: linking 64-bit files with 32-bit files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
bfd_set_error (bfd_error_bad_value);
ok = false;
{
(*_bfd_error_handler)
(_("%s: linking constant-gp files with non-constant-gp files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
bfd_set_error (bfd_error_bad_value);
ok = false;
{
(*_bfd_error_handler)
(_("%s: linking auto-pic files with non-auto-pic files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
bfd_set_error (bfd_error_bad_value);
ok = false;
_bfd_elf_print_private_bfd_data (abfd, ptr);
return true;
}
+
+static enum elf_reloc_type_class
+elfNN_ia64_reloc_type_class (rela)
+ const Elf_Internal_Rela *rela;
+{
+ switch ((int) ELFNN_R_TYPE (rela->r_info))
+ {
+ case R_IA64_REL32MSB:
+ case R_IA64_REL32LSB:
+ case R_IA64_REL64MSB:
+ case R_IA64_REL64LSB:
+ return reloc_class_relative;
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ return reloc_class_plt;
+ case R_IA64_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
\f
#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
#define TARGET_LITTLE_NAME "elfNN-ia64-little"
#define elf_backend_want_dynbss 0
#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
+#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
#include "elfNN-target.h"