From 7b6021f1972b04daee9d9afd467be3e1782c2158 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 16 Jun 2009 01:52:13 +0000 Subject: bfd/ * elf32-vax.c (elf_vax_check_relocs): Handle the visibility attribute. (elf_vax_relocate_section): Likewise. gas/ * config/tc-vax.c (md_estimate_size_before_relax): Accept indirect symbol references in the PIC mode and emit a PC-relative relocation instead of a GOT/PLT one. Likewise for symbols known to be hidden at this point. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-vax.c | 31 ++++++++++++++++++++++++------- gas/ChangeLog | 7 +++++++ gas/config/tc-vax.c | 29 +++++++++++++---------------- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4d4469b..f9dbef7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2009-06-16 Maciej W. Rozycki + + * elf32-vax.c (elf_vax_check_relocs): Handle the visibility + attribute. + (elf_vax_relocate_section): Likewise. + 2009-06-15 H.J. Lu * elf32-i386.c (elf_i386_allocate_dynrelocs): Update comments. diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 9caa47d..93cb1cb 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -605,6 +605,11 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, || h == elf_hash_table (info)->hplt) break; + /* If this is a local symbol, we resolve it directly without + creating a global offset table entry. */ + if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + break; + /* This symbol requires a global offset table entry. */ if (dynobj == NULL) @@ -677,7 +682,7 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* If this is a local symbol, we resolve it directly without creating a procedure linkage table entry. */ BFD_ASSERT (h != NULL); - if (h->forced_local) + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local) break; h->needs_plt = 1; @@ -706,7 +711,9 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, && (!info->symbolic || !h->def_regular))) { - if (h != NULL && !h->forced_local) + if (h != NULL + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !h->forced_local) { /* Make sure a plt entry is created for this symbol if it turns out to be a function defined by a dynamic @@ -718,14 +725,17 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, } break; } - if (h != NULL && h->forced_local) + /* If this is a local symbol, we can resolve it directly. */ + if (h != NULL + && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || h->forced_local)) break; /* Fall through. */ case R_VAX_8: case R_VAX_16: case R_VAX_32: - if (h != NULL) + if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) { /* Make sure a plt entry is created for this symbol if it turns out to be a function defined by a dynamic object. */ @@ -1465,7 +1475,10 @@ elf_vax_relocate_section (bfd *output_bfd, case R_VAX_GOT32: /* Relocation is to the address of the entry for this symbol in the global offset table. */ - if (h == NULL || h->got.offset == (bfd_vma) -1 || h->forced_local) + if (h == NULL + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || h->got.offset == (bfd_vma) -1 + || h->forced_local) break; /* Relocation is the offset of the entry for this symbol in @@ -1527,7 +1540,9 @@ elf_vax_relocate_section (bfd *output_bfd, /* Resolve a PLTxx reloc against a local symbol directly, without using the procedure linkage table. */ - if (h == NULL || h->forced_local) + if (h == NULL + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || h->forced_local) break; if (h->plt.offset == (bfd_vma) -1 @@ -1581,7 +1596,9 @@ elf_vax_relocate_section (bfd *output_bfd, case R_VAX_PC8: case R_VAX_PC16: case R_VAX_PC32: - if (h == NULL || h->forced_local) + if (h == NULL + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || h->forced_local) break; /* Fall through. */ case R_VAX_8: diff --git a/gas/ChangeLog b/gas/ChangeLog index 04e73ad..ed478c6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2009-06-16 Maciej W. Rozycki + + * config/tc-vax.c (md_estimate_size_before_relax): Accept + indirect symbol references in the PIC mode and emit a + PC-relative relocation instead of a GOT/PLT one. Likewise + for symbols known to be hidden at this point. + 2009-06-15 Nick Clifton PR 10186 diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index db2055e..ec83657 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -396,23 +396,20 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) || S_IS_WEAK (fragP->fr_symbol) || S_IS_EXTERNAL (fragP->fr_symbol))) { - if (p[0] & 0x10) - { - if (flag_want_pic) - as_fatal ("PIC reference to %s is indirect.\n", - S_GET_NAME (fragP->fr_symbol)); - } + /* Indirect references cannot go through the GOT or PLT, + let's hope they'll become local in the final link. */ + if ((ELF_ST_VISIBILITY (S_GET_OTHER (fragP->fr_symbol)) + != STV_DEFAULT) + || (p[0] & 0x10)) + reloc_type = BFD_RELOC_32_PCREL; + else if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP + || S_IS_FUNCTION (fragP->fr_symbol)) + reloc_type = BFD_RELOC_32_PLT_PCREL; else - { - if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS - || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG - || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB - || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP - || S_IS_FUNCTION (fragP->fr_symbol)) - reloc_type = BFD_RELOC_32_PLT_PCREL; - else - reloc_type = BFD_RELOC_32_GOT_PCREL; - } + reloc_type = BFD_RELOC_32_GOT_PCREL; } #endif switch (RELAX_STATE (fragP->fr_subtype)) -- cgit v1.1