More PowerPC64 ELFv2 --just-symbols fixes
authorAlan Modra <amodra@gmail.com>
Tue, 3 Dec 2013 07:18:31 +0000 (17:48 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 3 Dec 2013 07:32:44 +0000 (18:02 +1030)
I don't know what I was thinking here to omit the save of r2.
Possibly I was looking at -msave-toc-indirect code at the time, where
r2 is saved in the function prologue.

* elf64-ppc.c (ppc_build_one_stub <ppc_stub_plt_branch_r2off>):
Don't omit saving of r2 for ELFv2.  Don't addi 2,2,0.
(ppc_size_one_stub <ppc_stub_plt_branch_r2off>): Adjust to suit.

bfd/ChangeLog
bfd/elf64-ppc.c

index e213a15107882dfd8239150ada352d446b930b51..a9420cd96a48afff5594ad5dfb83776bdfcc769c 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-03  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (ppc_build_one_stub <ppc_stub_plt_branch_r2off>):
+       Don't omit saving of r2 for ELFv2.  Don't addi 2,2,0.
+       (ppc_size_one_stub <ppc_stub_plt_branch_r2off>): Adjust to suit.
+
 2013-12-03  Alan Modra  <amodra@gmail.com>
 
        * elf64-ppc.c (ppc64_elf_link_just_syms): Remove .got check.
index 4bbb70f93ff1af1f2cec46c1a968cdb0d5af6ef6..f30c009b5c3a512c250c36f7d6e321fee1a0f055 100644 (file)
@@ -10597,8 +10597,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          r[0].r_offset = loc - stub_entry->stub_sec->contents;
          if (bfd_big_endian (info->output_bfd))
            r[0].r_offset += 2;
-         if (stub_entry->stub_type == ppc_stub_plt_branch_r2off
-             && htab->opd_abi)
+         if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
            r[0].r_offset += 4;
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
          r[0].r_addend = dest;
@@ -10611,8 +10610,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
            }
        }
 
-      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
-         || !htab->opd_abi)
+      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
        {
          if (PPC_HA (off) != 0)
            {
@@ -10631,7 +10629,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
        {
          bfd_vma r2off = get_r2off (info, stub_entry);
 
-         if (r2off == 0)
+         if (r2off == 0 && htab->opd_abi)
            {
              htab->stub_error = TRUE;
              return FALSE;
@@ -10639,28 +10637,29 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 
          bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
          loc += 4;
-         size = 20;
+         size = 16;
          if (PPC_HA (off) != 0)
            {
              size += 4;
              bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
              loc += 4;
              bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
-             loc += 4;
            }
          else
-           {
-             bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
-             loc += 4;
-           }
+           bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
 
          if (PPC_HA (r2off) != 0)
            {
              size += 4;
+             loc += 4;
              bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
+           }
+         if (PPC_LO (r2off) != 0)
+           {
+             size += 4;
              loc += 4;
+             bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
            }
-         bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
        }
       loc += 4;
       bfd_put_32 (htab->stub_bfd, MTCTR_R12, loc);
@@ -10954,8 +10953,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              stub_entry->stub_sec->flags |= SEC_RELOC;
            }
 
-         if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
-             || !htab->opd_abi)
+         if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
            {
              size = 12;
              if (PPC_HA (off) != 0)
@@ -10963,12 +10961,14 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
            }
          else
            {
-             size = 20;
+             size = 16;
              if (PPC_HA (off) != 0)
                size += 4;
 
              if (PPC_HA (r2off) != 0)
                size += 4;
+             if (PPC_LO (r2off) != 0)
+               size += 4;
            }
        }
       else if (info->emitrelocations)