diff options
-rw-r--r-- | bfd/ChangeLog | 32 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 2 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 2 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 2 | ||||
-rw-r--r-- | bfd/elf32-sparc.c | 2 | ||||
-rw-r--r-- | bfd/elf64-alpha.c | 2 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 2 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 2 | ||||
-rw-r--r-- | bfd/elf64-sparc.c | 2 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 2 | ||||
-rw-r--r-- | bfd/elfxx-ia64.c | 126 | ||||
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/emulparams/elf64_ia64.sh | 9 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 7 |
14 files changed, 162 insertions, 38 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 712976c..49c49c2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,35 @@ +2003-07-04 Jakub Jelinek <jakub@redhat.com> + + * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add rel_fptr_sec. + (elfNN_ia64_dynamic_symbol_p): Change info->shared into + !info->executable. + (get_fptr): For -pie create .opd as writable section and create + .rela.opd as well. + (elfNN_ia64_check_relocs): Change info->shared into + !info->executable. + (allocate_fptr): Likewise. + (allocate_dynrel_entries): Account for a relative reloc for -pie + @fptr(). Don't account for a relative reloc if -pie want_ltoff_fptr + for undefweak symbol. Account for an IPLT reloc in .rela.opd + section if -pie. + (set_got_entry): Don't create a relative reloc if -pie + want_ltoff_fptr for undefweak symbol. + (set_fptr_entry): Emit an IPLT reloc in .rela.opd for -pie. + (elfNN_ia64_relocate_section): Emit a relative reloc for -pie + @fptr(). + + * elfxx-ia64.c (elfNN_ia64_relocate_section): Issue undefined_symbol + even if -pie. + * elf32-i386.c (elf_i386_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elf64-sparc.c (sparc64_elf_relocate_section): Likewise. + * elf64-s390.c (elf_s390_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_relocate_section): Likewise. + * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + 2003-07-04 Paul <paulc@senet.com.au> * elf32-h8300.c (R_H8_DIR32A16): Fix name field. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 3c7bbd9..0ddd507 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2177,7 +2177,7 @@ elf_i386_relocate_section (bfd *output_bfd, } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index f2b987c..68d83e3 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -4628,7 +4628,7 @@ ppc_elf_relocate_section (bfd *output_bfd, } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 55690bd..5312cbb 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2356,7 +2356,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index ac10184..c18edda 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -2209,7 +2209,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 767d89c..ca3aa19 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -4504,7 +4504,7 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.root.type == bfd_link_hash_undefweak) undef_weak_ref = TRUE; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) ; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index f499adf..ab2f45a3 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -7195,7 +7195,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 1b86cb0..4b89712 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2326,7 +2326,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index dbaa954..13f6a55 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -2097,7 +2097,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 7286627..542f83f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1852,7 +1852,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; - else if (info->shared + else if (!info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 2098f6f..35f3611 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -143,6 +143,7 @@ struct elfNN_ia64_link_hash_table asection *got_sec; /* the linkage table section (or NULL) */ asection *rel_got_sec; /* dynamic relocation section for same */ asection *fptr_sec; /* function descriptor table (or NULL) */ + asection *rel_fptr_sec; /* dynamic relocation section for same */ asection *plt_sec; /* the primary plt section (or NULL) */ asection *pltoff_sec; /* private descriptors for plt (or NULL) */ asection *rel_pltoff_sec; /* dynamic relocation section for same */ @@ -1652,7 +1653,7 @@ elfNN_ia64_dynamic_symbol_p (h, info) || h->root.type == bfd_link_hash_defweak) return TRUE; - if ((info->shared && (!info->symbolic || info->allow_shlib_undefined)) + if ((!info->executable && (!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))) @@ -2063,7 +2064,7 @@ get_got (abfd, info, ia64_info) static asection * get_fptr (abfd, info, ia64_info) bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; + struct bfd_link_info *info; struct elfNN_ia64_link_hash_table *ia64_info; { asection *fptr; @@ -2083,7 +2084,7 @@ get_fptr (abfd, info, ia64_info) | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY + | (info->pie ? 0 : SEC_READONLY) | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, fptr, 4)) { @@ -2092,6 +2093,26 @@ get_fptr (abfd, info, ia64_info) } ia64_info->fptr_sec = fptr; + + if (info->pie) + { + asection *fptr_rel; + fptr_rel = bfd_make_section(abfd, ".rela.opd"); + if (fptr_rel == NULL + || !bfd_set_section_flags (abfd, fptr_rel, + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED + | SEC_READONLY)) + || !bfd_set_section_alignment (abfd, fptr_rel, 3)) + { + BFD_ASSERT (0); + return NULL; + } + + ia64_info->rel_fptr_sec = fptr_rel; + } } return fptr; @@ -2278,7 +2299,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) 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 + if (h && ((!info->executable && (!info->symbolic || info->allow_shlib_undefined)) || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) || h->root.type == bfd_link_hash_defweak @@ -2638,7 +2659,7 @@ allocate_fptr (dyn_i, data) || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - if ((x->info->shared + if ((!x->info->executable && (!h || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak)) @@ -2788,10 +2809,11 @@ allocate_dynrel_entries (dyn_i, data) switch (rent->type) { case R_IA64_FPTR64LSB: - /* Allocate one iff !want_fptr, which by this point will - be true only if we're actually allocating one statically - in the main executable. */ - if (dyn_i->want_fptr) + /* Allocate one iff !want_fptr and not PIE, which by this point + will be true only if we're actually allocating one statically + in the main executable. Position independent executables + need a relative reloc. */ + if (dyn_i->want_fptr && !x->info->pie) continue; break; case R_IA64_PCREL64LSB: @@ -2828,13 +2850,24 @@ allocate_dynrel_entries (dyn_i, data) || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1)) - ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); + { + if (!dyn_i->want_ltoff_fptr + || !x->info->pie + || dyn_i->h == NULL + || dyn_i->h->root.type != bfd_link_hash_undefweak) + ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); + } if ((dynamic_symbol || shared) && dyn_i->want_tprel) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); if (dynamic_symbol && dyn_i->want_dtpmod) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); if (dynamic_symbol && dyn_i->want_dtprel) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); + if (ia64_info->rel_fptr_sec && dyn_i->want_fptr) + { + if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak) + ia64_info->rel_fptr_sec->_raw_size += sizeof (ElfNN_External_Rela); + } if (!resolved_zero && dyn_i->want_pltoff) { @@ -3444,14 +3477,18 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type) bfd_put_64 (abfd, value, got_sec->contents + got_offset); /* Install a dynamic relocation if needed. */ - if ((info->shared - && (!dyn_i->h - || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT - || dyn_i->h->root.type != bfd_link_hash_undefweak) - && dyn_r_type != R_IA64_DTPREL64LSB) - || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info) - || elfNN_ia64_aix_vec (abfd->xvec) - || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) + if (((info->shared + && (!dyn_i->h + || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT + || dyn_i->h->root.type != bfd_link_hash_undefweak) + && dyn_r_type != R_IA64_DTPREL64LSB) + || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info) + || elfNN_ia64_aix_vec (abfd->xvec) + || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) + && (!dyn_i->want_ltoff_fptr + || !info->pie + || !dyn_i->h + || dyn_i->h->root.type != bfd_link_hash_undefweak)) { if (dynindx == -1 && dyn_r_type != R_IA64_TPREL64LSB @@ -3530,6 +3567,24 @@ set_fptr_entry (abfd, info, dyn_i, value) bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset); bfd_put_64 (abfd, _bfd_get_gp_value (abfd), fptr_sec->contents + dyn_i->fptr_offset + 8); + if (ia64_info->rel_fptr_sec) + { + Elf_Internal_Rela outrel; + bfd_byte *loc; + + if (bfd_little_endian (abfd)) + outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB); + else + outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB); + outrel.r_addend = value; + outrel.r_offset = (fptr_sec->output_section->vma + + fptr_sec->output_offset + + dyn_i->fptr_offset); + loc = ia64_info->rel_fptr_sec->contents; + loc += ia64_info->rel_fptr_sec->reloc_count++ + * sizeof (ElfNN_External_Rela); + bfd_elfNN_swap_reloca_out (abfd, &outrel, loc); + } } /* Return the descriptor's address. */ @@ -3986,7 +4041,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, } else if (h->root.type == bfd_link_hash_undefweak) undef_weak_ref = TRUE; - else if (info->shared + else if (! info->executable && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; @@ -4146,14 +4201,36 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, if (!undef_weak_ref) value = set_fptr_entry (output_bfd, info, dyn_i, value); } - else + if (!dyn_i->want_fptr || info->pie) { long dynindx; + unsigned int dyn_r_type = r_type; + bfd_vma addend = rel->r_addend; /* Otherwise, we expect the dynamic linker to create the entry. */ - if (h) + if (dyn_i->want_fptr) + { + if (r_type == R_IA64_FPTR64I) + { + /* We can't represent this without a dynamic symbol. + Adjust the relocation to be against an output + section symbol, which are always present in the + dynamic symbol table. */ + /* ??? People shouldn't be doing non-pic code in + shared libraries. Hork. */ + (*_bfd_error_handler) + (_("%s: linking non-pic code in a position independent executable"), + bfd_archive_filename (input_bfd)); + ret_val = FALSE; + continue; + } + dynindx = 0; + addend = value; + dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB; + } + else if (h) { if (h->dynindx != -1) dynindx = h->dynindx; @@ -4161,17 +4238,18 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, dynindx = (_bfd_elf_link_lookup_local_dynindx (info, h->root.u.def.section->owner, global_sym_index (h))); + value = 0; } else { dynindx = (_bfd_elf_link_lookup_local_dynindx (info, input_bfd, (long) r_symndx)); + value = 0; } elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section, - srel, rel->r_offset, r_type, - dynindx, rel->r_addend); - value = 0; + srel, rel->r_offset, dyn_r_type, + dynindx, addend); } r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type); diff --git a/ld/ChangeLog b/ld/ChangeLog index b8b160e..e0ccf8b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2003-07-02 Jakub Jelinek <jakub@redhat.com> + + * emulparams/elf64_ia64.sh (OTHER_READONLY_SECTIONS): Don't include + .opd if -pie. + (OTHER_READWRITE_SECTIONS): Include .opd if -pie. + * scripttempl/elf.sc: Use SHLIB_DATA_ADDR instead of DATA_ADDR + if -pie. + 2003-06-28 Alan Modra <amodra@bigpond.net.au> * ld.h: Convert to C90, remove unnecessary prototypes and casts. diff --git a/ld/emulparams/elf64_ia64.sh b/ld/emulparams/elf64_ia64.sh index 85ffe61..d9c7f6a 100644 --- a/ld/emulparams/elf64_ia64.sh +++ b/ld/emulparams/elf64_ia64.sh @@ -22,7 +22,12 @@ OTHER_GOT_SECTIONS=" .IA_64.pltoff ${RELOCATING-0} : { *(.IA_64.pltoff) }" OTHER_PLT_RELOC_SECTIONS=" .rela.IA_64.pltoff ${RELOCATING-0} : { *(.rela.IA_64.pltoff) }" -OTHER_READONLY_SECTIONS=" - .opd ${RELOCATING-0} : { *(.opd) } +OTHER_READONLY_SECTIONS= +OTHER_READWRITE_SECTIONS= +test -z "$CREATE_PIE" && OTHER_READONLY_SECTIONS=" + .opd ${RELOCATING-0} : { *(.opd) }" +test -n "$CREATE_PIE" && OTHER_READWRITE_SECTIONS=" + .opd ${RELOCATING-0} : { *(.opd) }" +OTHER_READONLY_SECTIONS="${OTHER_READONLY_SECTIONS} .IA_64.unwind_info ${RELOCATING-0} : { *(.IA_64.unwind_info${RELOCATING+* .gnu.linkonce.ia64unwi.*}) } .IA_64.unwind ${RELOCATING-0} : { *(.IA_64.unwind${RELOCATING+* .gnu.linkonce.ia64unw.*}) }" diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 97b100e..0c1f5c6 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -72,8 +72,8 @@ if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHI test -z "${ELFSIZE}" && ELFSIZE=32 test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8" test "$LD_FLAG" = "N" && DATA_ADDR=. -test -n "$CREATE_SHLIB" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE="" -test -z "$CREATE_SHLIB" && test -n "$DATA_ADDR" && COMMONPAGESIZE="" +test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE="" +test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE="" DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))" DATA_SEGMENT_END="" if test -n "${COMMONPAGESIZE}"; then @@ -285,8 +285,9 @@ cat <<EOF /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ - ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}} + ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}} ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}} + ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}} /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but |