1 Upstream-Status: Backport
 
   3 From 26e802720ccd055d70addadbc39f4119716f8573 Mon Sep 17 00:00:00 2001
 
   5 Date: Mon, 19 Dec 2011 10:39:27 +0000
 
   6 Subject: [PATCH 036/262] 2011-12-19  Chung-Lin Tang 
 
   7  <cltang@codesourcery.com>
 
   9         Backport from mainline:
 
  11         2011-12-19  Chung-Lin Tang  <cltang@codesourcery.com>
 
  12                     Catherine Moore  <clm@codesourcery.com>
 
  13                     Sandra Loosemore  <sandra@codesourcery.com>
 
  14                     Richard Sandiford  <rdsandiford@googlemail.com>
 
  16         * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when
 
  17         H is a MIPS16 function with a kept 32-bit stub. Update comments.
 
  18         (mips_elf_get_la25_target): New function.
 
  19         (mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target().
 
  20         (mips_elf_add_la25_stub): Move compute of use_trampoline_p down,
 
  21         change to use mips_elf_get_la25_target().
 
  22         (mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p
 
  23         parameter, add switch case for R_MIPS16_26.
 
  24         (mips_elf_calculate_relocation): Redirect relocation to point to the
 
  25         LA25 stub if it exists, instead of the MIPS16 stub. Update arguments
 
  26         of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub
 
  27         for mips16->mips16 calls.
 
  28         (_bfd_mips_elf_check_relocs): Update arguments of call to
 
  29         mips_elf_relocation_needs_la25_stub().
 
  30         (mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target().
 
  32 diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
 
  33 index 3939183..9f3833b 100644
 
  34 --- a/bfd/elfxx-mips.c
 
  35 +++ b/bfd/elfxx-mips.c
 
  36 @@ -1575,9 +1575,10 @@ _bfd_mips_elf_init_stubs (struct bfd_link_info *info,
 
  39  /* Return true if H is a locally-defined PIC function, in the sense
 
  40 -   that it might need $25 to be valid on entry.  Note that MIPS16
 
  41 -   functions never need $25 to be valid on entry; they set up $gp
 
  42 -   using PC-relative instructions instead.  */
 
  43 +   that it or its fn_stub might need $25 to be valid on entry.
 
  44 +   Note that MIPS16 functions set up $gp using PC-relative instructions,
 
  45 +   so they themselves never need $25 to be valid.  Only non-MIPS16
 
  46 +   entry points are of interest here.  */
 
  49  mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
 
  50 @@ -1586,11 +1587,32 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
 
  51            || h->root.root.type == bfd_link_hash_defweak)
 
  52           && h->root.def_regular
 
  53           && !bfd_is_abs_section (h->root.root.u.def.section)
 
  54 -         && !ELF_ST_IS_MIPS16 (h->root.other)
 
  55 +         && (!ELF_ST_IS_MIPS16 (h->root.other)
 
  56 +             || (h->fn_stub && h->need_fn_stub))
 
  57           && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
 
  58               || ELF_ST_IS_MIPS_PIC (h->root.other)));
 
  61 +/* Set *SEC to the input section that contains the target of STUB.
 
  62 +   Return the offset of the target from the start of that section.  */
 
  65 +mips_elf_get_la25_target (struct mips_elf_la25_stub *stub,
 
  68 +  if (ELF_ST_IS_MIPS16 (stub->h->root.other))
 
  70 +      BFD_ASSERT (stub->h->need_fn_stub);
 
  71 +      *sec = stub->h->fn_stub;
 
  76 +      *sec = stub->h->root.root.u.def.section;
 
  77 +      return stub->h->root.root.u.def.value;
 
  81  /* STUB describes an la25 stub that we have decided to implement
 
  82     by inserting an LUI/ADDIU pair before the target function.
 
  83     Create the section and redirect the function symbol to it.  */
 
  84 @@ -1615,7 +1637,7 @@ mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub,
 
  85    sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
 
  87    /* Create the section.  */
 
  88 -  input_section = stub->h->root.root.u.def.section;
 
  89 +  mips_elf_get_la25_target (stub, &input_section);
 
  90    s = htab->add_stub_section (name, input_section,
 
  91                               input_section->output_section);
 
  93 @@ -1689,12 +1711,6 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
 
  97 -  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
 
  98 -     of the section and if we would need no more than 2 nops.  */
 
  99 -  s = h->root.root.u.def.section;
 
 100 -  value = h->root.root.u.def.value;
 
 101 -  use_trampoline_p = (value != 0 || s->alignment_power > 4);
 
 103    /* Describe the stub we want.  */
 
 104    search.stub_section = NULL;
 
 106 @@ -1724,6 +1740,11 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
 
 110 +  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
 
 111 +     of the section and if we would need no more than 2 nops.  */
 
 112 +  value = mips_elf_get_la25_target (stub, &s);
 
 113 +  use_trampoline_p = (value != 0 || s->alignment_power > 4);
 
 116    return (use_trampoline_p
 
 117           ? mips_elf_add_la25_trampoline (stub, info)
 
 118 @@ -4911,7 +4932,8 @@ is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
 
 122 -mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
 
 123 +mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type,
 
 124 +                                    bfd_boolean target_is_16_bit_code_p)
 
 126    /* We specifically ignore branches and jumps from EF_PIC objects,
 
 127       where the onus is on the compiler or programmer to perform any
 
 128 @@ -4925,7 +4947,6 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
 
 133      case R_MICROMIPS_26_S1:
 
 134      case R_MICROMIPS_PC7_S1:
 
 135      case R_MICROMIPS_PC10_S1:
 
 136 @@ -4933,6 +4954,9 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
 
 137      case R_MICROMIPS_PC23_S2:
 
 141 +      return !target_is_16_bit_code_p;
 
 146 @@ -5193,14 +5217,28 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 
 147          have already noticed that we were going to need the
 
 150 -       sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
 
 152 +         sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
 
 157           BFD_ASSERT (h->need_fn_stub);
 
 161 +             /* If a LA25 header for the stub itself exists, point to the
 
 162 +                prepended LUI/ADDIU sequence.  */
 
 163 +             sec = h->la25_stub->stub_section;
 
 164 +             value = h->la25_stub->offset;
 
 173 -      symbol = sec->output_section->vma + sec->output_offset;
 
 174 +      symbol = sec->output_section->vma + sec->output_offset + value;
 
 175        /* The target is 16-bit, but the stub isn't.  */
 
 176        target_is_16_bit_code_p = FALSE;
 
 178 @@ -5250,7 +5288,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 
 179    /* If this is a direct call to a PIC function, redirect to the
 
 181    else if (h != NULL && h->la25_stub
 
 182 -          && mips_elf_relocation_needs_la25_stub (input_bfd, r_type))
 
 183 +          && mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
 
 184 +                                                  target_is_16_bit_code_p))
 
 185      symbol = (h->la25_stub->stub_section->output_section->vma
 
 186               + h->la25_stub->stub_section->output_offset
 
 187               + h->la25_stub->offset);
 
 188 @@ -7925,7 +7964,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 192 -      if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type))
 
 194 +         && mips_elf_relocation_needs_la25_stub (abfd, r_type,
 
 195 +                                                 ELF_ST_IS_MIPS16 (h->other)))
 
 196         ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
 
 199 @@ -9622,9 +9663,9 @@ mips_elf_create_la25_stub (void **slot, void *data)
 
 200    offset = stub->offset;
 
 202    /* Work out the target address.  */
 
 203 -  target = (stub->h->root.root.u.def.section->output_section->vma
 
 204 -           + stub->h->root.root.u.def.section->output_offset
 
 205 -           + stub->h->root.root.u.def.value);
 
 206 +  target = mips_elf_get_la25_target (stub, &s);
 
 207 +  target += s->output_section->vma + s->output_offset;
 
 209    target_high = ((target + 0x8000) >> 16) & 0xffff;
 
 210    target_low = (target & 0xffff);