2005-05-04 H.J. Lu <hongjiu.lu@intel.com>

* elfxx-ia64.c (ARCH_SIZE): New.
	(LOG_SECTION_ALIGN): Likewise.
	(elfNN_ia64_create_dynamic_sections): Use LOG_SECTION_ALIGN to
	align relocation sections.
	(get_fptr): Likewise.
	(get_reloc_section): Likewise.
	(elfNN_ia64_tprel_base): Likewise.
	(elfNN_ia64_check_relocs): Support 32bit relocations.
	(allocate_global_fptr_got): Likewise.
	(allocate_dynrel_entries): Likewise.
	(set_got_entry): Likewise.
	(set_pltoff_entry): Likewise.
	(elfNN_ia64_relocate_section): Likewise.
This commit is contained in:
H.J. Lu 2005-05-04 22:20:25 +00:00
parent be5cacdb6d
commit 5a260b6644
2 changed files with 82 additions and 20 deletions

View File

@ -1,3 +1,27 @@
2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-ia64.c (ARCH_SIZE): New.
(LOG_SECTION_ALIGN): Likewise.
(elfNN_ia64_create_dynamic_sections): Use LOG_SECTION_ALIGN to
align relocation sections.
(get_fptr): Likewise.
(get_reloc_section): Likewise.
(elfNN_ia64_tprel_base): Likewise.
(elfNN_ia64_check_relocs): Support 32bit relocations.
(allocate_global_fptr_got): Likewise.
(allocate_dynrel_entries): Likewise.
(set_got_entry): Likewise.
(set_pltoff_entry): Likewise.
(elfNN_ia64_relocate_section): Likewise.
2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
* configure.in: Add AC_CHECK_DECLS(stpcpy).
* configure: Regenerate.
* config.in: Likewise.
* sysdep.h (stpcpy): New.
2005-05-04 Nick Clifton <nickc@redhat.com> 2005-05-04 Nick Clifton <nickc@redhat.com>
* Update the address and phone number of the FSF organization in * Update the address and phone number of the FSF organization in

View File

@ -28,6 +28,16 @@
#include "objalloc.h" #include "objalloc.h"
#include "hashtab.h" #include "hashtab.h"
#define ARCH_SIZE NN
#if ARCH_SIZE == 64
#define LOG_SECTION_ALIGN 3
#endif
#if ARCH_SIZE == 32
#define LOG_SECTION_ALIGN 2
#endif
/* THE RULES for all the stuff the linker creates -- /* THE RULES for all the stuff the linker creates --
GOT Entries created in response to LTOFF or LTOFF_FPTR GOT Entries created in response to LTOFF or LTOFF_FPTR
@ -1871,7 +1881,7 @@ elfNN_ia64_create_dynamic_sections (abfd, info)
| SEC_IN_MEMORY | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_LINKER_CREATED
| SEC_READONLY)) | SEC_READONLY))
|| !bfd_set_section_alignment (abfd, s, 3)) || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
return FALSE; return FALSE;
ia64_info->rel_pltoff_sec = s; ia64_info->rel_pltoff_sec = s;
@ -1882,7 +1892,7 @@ elfNN_ia64_create_dynamic_sections (abfd, info)
| SEC_IN_MEMORY | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_LINKER_CREATED
| SEC_READONLY)) | SEC_READONLY))
|| !bfd_set_section_alignment (abfd, s, 3)) || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
return FALSE; return FALSE;
ia64_info->rel_got_sec = s; ia64_info->rel_got_sec = s;
@ -2056,7 +2066,8 @@ get_fptr (abfd, info, ia64_info)
| SEC_IN_MEMORY | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_LINKER_CREATED
| SEC_READONLY)) | SEC_READONLY))
|| !bfd_set_section_alignment (abfd, fptr_rel, 3)) || !bfd_set_section_alignment (abfd, fptr_rel,
LOG_SECTION_ALIGN))
{ {
BFD_ASSERT (0); BFD_ASSERT (0);
return NULL; return NULL;
@ -2146,7 +2157,8 @@ get_reloc_section (abfd, ia64_info, sec, create)
| SEC_IN_MEMORY | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_LINKER_CREATED
| SEC_READONLY)) | SEC_READONLY))
|| !bfd_set_section_alignment (dynobj, srel, 3)) || !bfd_set_section_alignment (dynobj, srel,
LOG_SECTION_ALIGN))
return NULL; return NULL;
} }
@ -2270,11 +2282,13 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
info->flags |= DF_STATIC_TLS; info->flags |= DF_STATIC_TLS;
break; break;
case R_IA64_DTPREL32MSB:
case R_IA64_DTPREL32LSB:
case R_IA64_DTPREL64MSB: case R_IA64_DTPREL64MSB:
case R_IA64_DTPREL64LSB: case R_IA64_DTPREL64LSB:
if (info->shared || maybe_dynamic) if (info->shared || maybe_dynamic)
need_entry = NEED_DYNREL; need_entry = NEED_DYNREL;
dynrel_type = R_IA64_DTPREL64LSB; dynrel_type = R_IA64_DTPRELNNLSB;
break; break;
case R_IA64_LTOFF_DTPREL22: case R_IA64_LTOFF_DTPREL22:
@ -2310,7 +2324,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
need_entry = NEED_FPTR | NEED_DYNREL; need_entry = NEED_FPTR | NEED_DYNREL;
else else
need_entry = NEED_FPTR; need_entry = NEED_FPTR;
dynrel_type = R_IA64_FPTR64LSB; dynrel_type = R_IA64_FPTRNNLSB;
break; break;
case R_IA64_LTOFF22: case R_IA64_LTOFF22:
@ -2360,7 +2374,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
/* Shared objects will always need at least a REL relocation. */ /* Shared objects will always need at least a REL relocation. */
if (info->shared || maybe_dynamic) if (info->shared || maybe_dynamic)
need_entry = NEED_DYNREL; need_entry = NEED_DYNREL;
dynrel_type = R_IA64_DIR64LSB; dynrel_type = R_IA64_DIRNNLSB;
break; break;
case R_IA64_IPLTMSB: case R_IA64_IPLTMSB:
@ -2379,7 +2393,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
case R_IA64_PCREL64LSB: case R_IA64_PCREL64LSB:
if (maybe_dynamic) if (maybe_dynamic)
need_entry = NEED_DYNREL; need_entry = NEED_DYNREL;
dynrel_type = R_IA64_PCREL64LSB; dynrel_type = R_IA64_PCRELNNLSB;
break; break;
} }
@ -2543,7 +2557,7 @@ allocate_global_fptr_got (dyn_i, data)
if (dyn_i->want_got if (dyn_i->want_got
&& dyn_i->want_fptr && dyn_i->want_fptr
&& elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB)) && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
{ {
dyn_i->got_offset = x->ofs; dyn_i->got_offset = x->ofs;
x->ofs += 8; x->ofs += 8;
@ -2750,6 +2764,7 @@ allocate_dynrel_entries (dyn_i, data)
switch (rent->type) switch (rent->type)
{ {
case R_IA64_FPTR32LSB:
case R_IA64_FPTR64LSB: case R_IA64_FPTR64LSB:
/* Allocate one iff !want_fptr and not PIE, which by this point /* Allocate one iff !want_fptr and not PIE, which by this point
will be true only if we're actually allocating one statically will be true only if we're actually allocating one statically
@ -2758,10 +2773,12 @@ allocate_dynrel_entries (dyn_i, data)
if (dyn_i->want_fptr && !x->info->pie) if (dyn_i->want_fptr && !x->info->pie)
continue; continue;
break; break;
case R_IA64_PCREL32LSB:
case R_IA64_PCREL64LSB: case R_IA64_PCREL64LSB:
if (!dynamic_symbol) if (!dynamic_symbol)
continue; continue;
break; break;
case R_IA64_DIR32LSB:
case R_IA64_DIR64LSB: case R_IA64_DIR64LSB:
if (!dynamic_symbol && !shared) if (!dynamic_symbol && !shared)
continue; continue;
@ -2774,6 +2791,7 @@ allocate_dynrel_entries (dyn_i, data)
if (!dynamic_symbol) if (!dynamic_symbol)
count *= 2; count *= 2;
break; break;
case R_IA64_DTPREL32LSB:
case R_IA64_TPREL64LSB: case R_IA64_TPREL64LSB:
case R_IA64_DTPREL64LSB: case R_IA64_DTPREL64LSB:
case R_IA64_DTPMOD64LSB: case R_IA64_DTPMOD64LSB:
@ -3413,6 +3431,7 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
} }
got_offset = dyn_i->dtpmod_offset; got_offset = dyn_i->dtpmod_offset;
break; break;
case R_IA64_DTPREL32LSB:
case R_IA64_DTPREL64LSB: case R_IA64_DTPREL64LSB:
done = dyn_i->dtprel_done; done = dyn_i->dtprel_done;
dyn_i->dtprel_done = TRUE; dyn_i->dtprel_done = TRUE;
@ -3437,9 +3456,12 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
&& (!dyn_i->h && (!dyn_i->h
|| ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
|| dyn_i->h->root.type != bfd_link_hash_undefweak) || dyn_i->h->root.type != bfd_link_hash_undefweak)
&& dyn_r_type != R_IA64_DTPREL32LSB
&& dyn_r_type != R_IA64_DTPREL64LSB) && dyn_r_type != R_IA64_DTPREL64LSB)
|| elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type) || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
|| (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) || (dynindx != -1
&& (dyn_r_type == R_IA64_FPTR32LSB
|| dyn_r_type == R_IA64_FPTR64LSB)))
&& (!dyn_i->want_ltoff_fptr && (!dyn_i->want_ltoff_fptr
|| !info->pie || !info->pie
|| !dyn_i->h || !dyn_i->h
@ -3448,9 +3470,10 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
if (dynindx == -1 if (dynindx == -1
&& dyn_r_type != R_IA64_TPREL64LSB && dyn_r_type != R_IA64_TPREL64LSB
&& dyn_r_type != R_IA64_DTPMOD64LSB && dyn_r_type != R_IA64_DTPMOD64LSB
&& dyn_r_type != R_IA64_DTPREL32LSB
&& dyn_r_type != R_IA64_DTPREL64LSB) && dyn_r_type != R_IA64_DTPREL64LSB)
{ {
dyn_r_type = R_IA64_REL64LSB; dyn_r_type = R_IA64_RELNNLSB;
dynindx = 0; dynindx = 0;
addend = value; addend = value;
} }
@ -3459,6 +3482,18 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
{ {
switch (dyn_r_type) switch (dyn_r_type)
{ {
case R_IA64_REL32LSB:
dyn_r_type = R_IA64_REL32MSB;
break;
case R_IA64_DIR32LSB:
dyn_r_type = R_IA64_DIR32MSB;
break;
case R_IA64_FPTR32LSB:
dyn_r_type = R_IA64_FPTR32MSB;
break;
case R_IA64_DTPREL32LSB:
dyn_r_type = R_IA64_DTPREL32MSB;
break;
case R_IA64_REL64LSB: case R_IA64_REL64LSB:
dyn_r_type = R_IA64_REL64MSB; dyn_r_type = R_IA64_REL64MSB;
break; break;
@ -3588,9 +3623,9 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
unsigned int dyn_r_type; unsigned int dyn_r_type;
if (bfd_big_endian (abfd)) if (bfd_big_endian (abfd))
dyn_r_type = R_IA64_REL64MSB; dyn_r_type = R_IA64_RELNNMSB;
else else
dyn_r_type = R_IA64_REL64LSB; dyn_r_type = R_IA64_RELNNLSB;
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec, elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec, ia64_info->rel_pltoff_sec,
@ -3598,7 +3633,7 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
dyn_r_type, 0, value); dyn_r_type, 0, value);
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec, elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec, ia64_info->rel_pltoff_sec,
dyn_i->pltoff_offset + 8, dyn_i->pltoff_offset + ARCH_SIZE / 8,
dyn_r_type, 0, gp); dyn_r_type, 0, gp);
} }
@ -3616,7 +3651,7 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
/* Return the base VMA address which should be subtracted from real addresses /* Return the base VMA address which should be subtracted from real addresses
when resolving @tprel() relocation. when resolving @tprel() relocation.
Main program TLS (whose template starts at PT_TLS p_vaddr) Main program TLS (whose template starts at PT_TLS p_vaddr)
is assigned offset round(16, PT_TLS p_align). */ is assigned offset round(2 * size of pointer, PT_TLS p_align). */
static bfd_vma static bfd_vma
elfNN_ia64_tprel_base (info) elfNN_ia64_tprel_base (info)
@ -3625,7 +3660,8 @@ elfNN_ia64_tprel_base (info)
asection *tls_sec = elf_hash_table (info)->tls_sec; asection *tls_sec = elf_hash_table (info)->tls_sec;
BFD_ASSERT (tls_sec != NULL); BFD_ASSERT (tls_sec != NULL);
return tls_sec->vma - align_power ((bfd_vma) 16, tls_sec->alignment_power); return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
tls_sec->alignment_power);
} }
/* Return the base VMA address which should be subtracted from real addresses /* Return the base VMA address which should be subtracted from real addresses
@ -4096,7 +4132,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
case R_IA64_LTOFF64I: case R_IA64_LTOFF64I:
dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE); dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1), value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
rel->r_addend, value, R_IA64_DIR64LSB); rel->r_addend, value, R_IA64_DIRNNLSB);
value -= gp_val; value -= gp_val;
r = elfNN_ia64_install_value (hit_addr, value, r_type); r = elfNN_ia64_install_value (hit_addr, value, r_type);
break; break;
@ -4149,7 +4185,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
} }
dynindx = 0; dynindx = 0;
addend = value; addend = value;
dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB; dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
} }
else if (h) else if (h)
{ {
@ -4213,7 +4249,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
} }
value = set_got_entry (output_bfd, info, dyn_i, dynindx, value = set_got_entry (output_bfd, info, dyn_i, dynindx,
rel->r_addend, value, R_IA64_FPTR64LSB); rel->r_addend, value, R_IA64_FPTRNNLSB);
value -= gp_val; value -= gp_val;
r = elfNN_ia64_install_value (hit_addr, value, r_type); r = elfNN_ia64_install_value (hit_addr, value, r_type);
} }
@ -4412,6 +4448,8 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
case R_IA64_DTPREL14: case R_IA64_DTPREL14:
case R_IA64_DTPREL22: case R_IA64_DTPREL22:
case R_IA64_DTPREL64I: case R_IA64_DTPREL64I:
case R_IA64_DTPREL32LSB:
case R_IA64_DTPREL32MSB:
case R_IA64_DTPREL64LSB: case R_IA64_DTPREL64LSB:
case R_IA64_DTPREL64MSB: case R_IA64_DTPREL64MSB:
value -= elfNN_ia64_dtprel_base (info); value -= elfNN_ia64_dtprel_base (info);
@ -4450,7 +4488,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
case R_IA64_LTOFF_DTPREL22: case R_IA64_LTOFF_DTPREL22:
if (!dynamic_symbol_p) if (!dynamic_symbol_p)
value -= elfNN_ia64_dtprel_base (info); value -= elfNN_ia64_dtprel_base (info);
got_r_type = R_IA64_DTPREL64LSB; got_r_type = R_IA64_DTPRELNNLSB;
break; break;
} }
dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE); dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);