OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elfxx-mips.c] - Diff between revs 163 and 166

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 163 Rev 166
Line 434... Line 434...
 
 
  /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
  /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
     entry is set to the address of __rld_obj_head as in IRIX5.  */
     entry is set to the address of __rld_obj_head as in IRIX5.  */
  bfd_boolean use_rld_obj_head;
  bfd_boolean use_rld_obj_head;
 
 
  /* This is the value of the __rld_map or __rld_obj_head symbol.  */
  /* The  __rld_map or __rld_obj_head symbol. */
  bfd_vma rld_value;
  struct elf_link_hash_entry *rld_symbol;
 
 
  /* This is set if we see any mips16 stub sections.  */
  /* This is set if we see any mips16 stub sections.  */
  bfd_boolean mips16_stubs_seen;
  bfd_boolean mips16_stubs_seen;
 
 
  /* True if we can generate copy relocs and PLTs.  */
  /* True if we can generate copy relocs and PLTs.  */
Line 527... Line 527...
   || r_type == R_MIPS_TLS_GOTTPREL             \
   || r_type == R_MIPS_TLS_GOTTPREL             \
   || r_type == R_MIPS_TLS_TPREL32              \
   || r_type == R_MIPS_TLS_TPREL32              \
   || r_type == R_MIPS_TLS_TPREL64              \
   || r_type == R_MIPS_TLS_TPREL64              \
   || r_type == R_MIPS_TLS_TPREL_HI16           \
   || r_type == R_MIPS_TLS_TPREL_HI16           \
   || r_type == R_MIPS_TLS_TPREL_LO16           \
   || r_type == R_MIPS_TLS_TPREL_LO16           \
 
   || r_type == R_MIPS16_TLS_GD                 \
 
   || r_type == R_MIPS16_TLS_LDM                \
 
   || r_type == R_MIPS16_TLS_DTPREL_HI16        \
 
   || r_type == R_MIPS16_TLS_DTPREL_LO16        \
 
   || r_type == R_MIPS16_TLS_GOTTPREL           \
 
   || r_type == R_MIPS16_TLS_TPREL_HI16         \
 
   || r_type == R_MIPS16_TLS_TPREL_LO16         \
   || r_type == R_MICROMIPS_TLS_GD              \
   || r_type == R_MICROMIPS_TLS_GD              \
   || r_type == R_MICROMIPS_TLS_LDM             \
   || r_type == R_MICROMIPS_TLS_LDM             \
   || r_type == R_MICROMIPS_TLS_DTPREL_HI16     \
   || r_type == R_MICROMIPS_TLS_DTPREL_HI16     \
   || r_type == R_MICROMIPS_TLS_DTPREL_LO16     \
   || r_type == R_MICROMIPS_TLS_DTPREL_LO16     \
   || r_type == R_MICROMIPS_TLS_GOTTPREL        \
   || r_type == R_MICROMIPS_TLS_GOTTPREL        \
Line 766... Line 773...
 
 
/* The size of a GOT entry.  */
/* The size of a GOT entry.  */
#define MIPS_ELF_GOT_SIZE(abfd) \
#define MIPS_ELF_GOT_SIZE(abfd) \
  (get_elf_backend_data (abfd)->s->arch_size / 8)
  (get_elf_backend_data (abfd)->s->arch_size / 8)
 
 
 
/* The size of the .rld_map section. */
 
#define MIPS_ELF_RLD_MAP_SIZE(abfd) \
 
  (get_elf_backend_data (abfd)->s->arch_size / 8)
 
 
/* The size of a symbol-table entry.  */
/* The size of a symbol-table entry.  */
#define MIPS_ELF_SYM_SIZE(abfd) \
#define MIPS_ELF_SYM_SIZE(abfd) \
  (get_elf_backend_data (abfd)->s->sizeof_sym)
  (get_elf_backend_data (abfd)->s->sizeof_sym)
 
 
/* The default alignment for sections, as a power of two.  */
/* The default alignment for sections, as a power of two.  */
Line 915... Line 926...
{
{
  0x3c1c0000,   /* lui $28, %hi(&GOTPLT[0])                             */
  0x3c1c0000,   /* lui $28, %hi(&GOTPLT[0])                             */
  0x8f990000,   /* lw $25, %lo(&GOTPLT[0])($28)                         */
  0x8f990000,   /* lw $25, %lo(&GOTPLT[0])($28)                         */
  0x279c0000,   /* addiu $28, $28, %lo(&GOTPLT[0])                      */
  0x279c0000,   /* addiu $28, $28, %lo(&GOTPLT[0])                      */
  0x031cc023,   /* subu $24, $24, $28                                   */
  0x031cc023,   /* subu $24, $24, $28                                   */
  0x03e07821,   /* move $15, $31                                        */
  0x03e07821,   /* move $15, $31        # 32-bit move (addu)            */
  0x0018c082,   /* srl $24, $24, 2                                      */
  0x0018c082,   /* srl $24, $24, 2                                      */
  0x0320f809,   /* jalr $25                                             */
  0x0320f809,   /* jalr $25                                             */
  0x2718fffe    /* subu $24, $24, 2                                     */
  0x2718fffe    /* subu $24, $24, 2                                     */
};
};
 
 
Line 929... Line 940...
{
{
  0x3c0e0000,   /* lui $14, %hi(&GOTPLT[0])                             */
  0x3c0e0000,   /* lui $14, %hi(&GOTPLT[0])                             */
  0x8dd90000,   /* lw $25, %lo(&GOTPLT[0])($14)                         */
  0x8dd90000,   /* lw $25, %lo(&GOTPLT[0])($14)                         */
  0x25ce0000,   /* addiu $14, $14, %lo(&GOTPLT[0])                      */
  0x25ce0000,   /* addiu $14, $14, %lo(&GOTPLT[0])                      */
  0x030ec023,   /* subu $24, $24, $14                                   */
  0x030ec023,   /* subu $24, $24, $14                                   */
  0x03e07821,   /* move $15, $31                                        */
  0x03e07821,   /* move $15, $31        # 32-bit move (addu)            */
  0x0018c082,   /* srl $24, $24, 2                                      */
  0x0018c082,   /* srl $24, $24, 2                                      */
  0x0320f809,   /* jalr $25                                             */
  0x0320f809,   /* jalr $25                                             */
  0x2718fffe    /* subu $24, $24, 2                                     */
  0x2718fffe    /* subu $24, $24, 2                                     */
};
};
 
 
Line 943... Line 954...
{
{
  0x3c0e0000,   /* lui $14, %hi(&GOTPLT[0])                             */
  0x3c0e0000,   /* lui $14, %hi(&GOTPLT[0])                             */
  0xddd90000,   /* ld $25, %lo(&GOTPLT[0])($14)                         */
  0xddd90000,   /* ld $25, %lo(&GOTPLT[0])($14)                         */
  0x25ce0000,   /* addiu $14, $14, %lo(&GOTPLT[0])                      */
  0x25ce0000,   /* addiu $14, $14, %lo(&GOTPLT[0])                      */
  0x030ec023,   /* subu $24, $24, $14                                   */
  0x030ec023,   /* subu $24, $24, $14                                   */
  0x03e07821,   /* move $15, $31                                        */
  0x03e0782d,   /* move $15, $31        # 64-bit move (daddu)           */
  0x0018c0c2,   /* srl $24, $24, 3                                      */
  0x0018c0c2,   /* srl $24, $24, 3                                      */
  0x0320f809,   /* jalr $25                                             */
  0x0320f809,   /* jalr $25                                             */
  0x2718fffe    /* subu $24, $24, 2                                     */
  0x2718fffe    /* subu $24, $24, 2                                     */
};
};
 
 
Line 1569... Line 1580...
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Return true if H is a locally-defined PIC function, in the sense
/* Return true if H is a locally-defined PIC function, in the sense
   that it might need $25 to be valid on entry.  Note that MIPS16
   that it or its fn_stub might need $25 to be valid on entry.
   functions never need $25 to be valid on entry; they set up $gp
   Note that MIPS16 functions set up $gp using PC-relative instructions,
   using PC-relative instructions instead.  */
   so they themselves never need $25 to be valid.  Only non-MIPS16
 
   entry points are of interest here.  */
 
 
static bfd_boolean
static bfd_boolean
mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
{
{
  return ((h->root.root.type == bfd_link_hash_defined
  return ((h->root.root.type == bfd_link_hash_defined
           || h->root.root.type == bfd_link_hash_defweak)
           || h->root.root.type == bfd_link_hash_defweak)
          && h->root.def_regular
          && h->root.def_regular
          && !bfd_is_abs_section (h->root.root.u.def.section)
          && !bfd_is_abs_section (h->root.root.u.def.section)
          && !ELF_ST_IS_MIPS16 (h->root.other)
          && (!ELF_ST_IS_MIPS16 (h->root.other)
 
              || (h->fn_stub && h->need_fn_stub))
          && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
          && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
              || ELF_ST_IS_MIPS_PIC (h->root.other)));
              || ELF_ST_IS_MIPS_PIC (h->root.other)));
}
}
 
 
 
/* Set *SEC to the input section that contains the target of STUB.
 
   Return the offset of the target from the start of that section.  */
 
 
 
static bfd_vma
 
mips_elf_get_la25_target (struct mips_elf_la25_stub *stub,
 
                          asection **sec)
 
{
 
  if (ELF_ST_IS_MIPS16 (stub->h->root.other))
 
    {
 
      BFD_ASSERT (stub->h->need_fn_stub);
 
      *sec = stub->h->fn_stub;
 
      return 0;
 
    }
 
  else
 
    {
 
      *sec = stub->h->root.root.u.def.section;
 
      return stub->h->root.root.u.def.value;
 
    }
 
}
 
 
/* STUB describes an la25 stub that we have decided to implement
/* STUB describes an la25 stub that we have decided to implement
   by inserting an LUI/ADDIU pair before the target function.
   by inserting an LUI/ADDIU pair before the target function.
   Create the section and redirect the function symbol to it.  */
   Create the section and redirect the function symbol to it.  */
 
 
static bfd_boolean
static bfd_boolean
Line 1609... Line 1642...
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
  sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
 
 
  /* Create the section.  */
  /* Create the section.  */
  input_section = stub->h->root.root.u.def.section;
  mips_elf_get_la25_target (stub, &input_section);
  s = htab->add_stub_section (name, input_section,
  s = htab->add_stub_section (name, input_section,
                              input_section->output_section);
                              input_section->output_section);
  if (s == NULL)
  if (s == NULL)
    return FALSE;
    return FALSE;
 
 
Line 1683... Line 1716...
  bfd_boolean use_trampoline_p;
  bfd_boolean use_trampoline_p;
  asection *s;
  asection *s;
  bfd_vma value;
  bfd_vma value;
  void **slot;
  void **slot;
 
 
  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
 
     of the section and if we would need no more than 2 nops.  */
 
  s = h->root.root.u.def.section;
 
  value = h->root.root.u.def.value;
 
  use_trampoline_p = (value != 0 || s->alignment_power > 4);
 
 
 
  /* Describe the stub we want.  */
  /* Describe the stub we want.  */
  search.stub_section = NULL;
  search.stub_section = NULL;
  search.offset = 0;
  search.offset = 0;
  search.h = h;
  search.h = h;
 
 
Line 1718... Line 1745...
  if (stub == NULL)
  if (stub == NULL)
    return FALSE;
    return FALSE;
  *stub = search;
  *stub = search;
  *slot = stub;
  *slot = stub;
 
 
 
  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
 
     of the section and if we would need no more than 2 nops.  */
 
  value = mips_elf_get_la25_target (stub, &s);
 
  use_trampoline_p = (value != 0 || s->alignment_power > 4);
 
 
  h->la25_stub = stub;
  h->la25_stub = stub;
  return (use_trampoline_p
  return (use_trampoline_p
          ? mips_elf_add_la25_trampoline (stub, info)
          ? mips_elf_add_la25_trampoline (stub, info)
          : mips_elf_add_la25_intro (stub, info));
          : mips_elf_add_la25_intro (stub, info));
}
}
Line 1858... Line 1890...
    case R_MIPS16_GPREL:
    case R_MIPS16_GPREL:
    case R_MIPS16_GOT16:
    case R_MIPS16_GOT16:
    case R_MIPS16_CALL16:
    case R_MIPS16_CALL16:
    case R_MIPS16_HI16:
    case R_MIPS16_HI16:
    case R_MIPS16_LO16:
    case R_MIPS16_LO16:
 
    case R_MIPS16_TLS_GD:
 
    case R_MIPS16_TLS_LDM:
 
    case R_MIPS16_TLS_DTPREL_HI16:
 
    case R_MIPS16_TLS_DTPREL_LO16:
 
    case R_MIPS16_TLS_GOTTPREL:
 
    case R_MIPS16_TLS_TPREL_HI16:
 
    case R_MIPS16_TLS_TPREL_LO16:
      return TRUE;
      return TRUE;
 
 
    default:
    default:
      return FALSE;
      return FALSE;
    }
    }
Line 1985... Line 2024...
}
}
 
 
static inline bfd_boolean
static inline bfd_boolean
tls_gd_reloc_p (unsigned int r_type)
tls_gd_reloc_p (unsigned int r_type)
{
{
  return r_type == R_MIPS_TLS_GD || r_type == R_MICROMIPS_TLS_GD;
  return (r_type == R_MIPS_TLS_GD
 
          || r_type == R_MIPS16_TLS_GD
 
          || r_type == R_MICROMIPS_TLS_GD);
}
}
 
 
static inline bfd_boolean
static inline bfd_boolean
tls_ldm_reloc_p (unsigned int r_type)
tls_ldm_reloc_p (unsigned int r_type)
{
{
  return r_type == R_MIPS_TLS_LDM || r_type == R_MICROMIPS_TLS_LDM;
  return (r_type == R_MIPS_TLS_LDM
 
          || r_type == R_MIPS16_TLS_LDM
 
          || r_type == R_MICROMIPS_TLS_LDM);
}
}
 
 
static inline bfd_boolean
static inline bfd_boolean
tls_gottprel_reloc_p (unsigned int r_type)
tls_gottprel_reloc_p (unsigned int r_type)
{
{
  return r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MICROMIPS_TLS_GOTTPREL;
  return (r_type == R_MIPS_TLS_GOTTPREL
 
          || r_type == R_MIPS16_TLS_GOTTPREL
 
          || r_type == R_MICROMIPS_TLS_GOTTPREL);
}
}
 
 
void
void
_bfd_mips_elf_reloc_unshuffle (bfd *abfd, int r_type,
_bfd_mips_elf_reloc_unshuffle (bfd *abfd, int r_type,
                               bfd_boolean jal_shuffle, bfd_byte *data)
                               bfd_boolean jal_shuffle, bfd_byte *data)
Line 4905... Line 4950...
   require an la25 stub.  See also mips_elf_local_pic_function_p,
   require an la25 stub.  See also mips_elf_local_pic_function_p,
   which determines whether the destination function ever requires a
   which determines whether the destination function ever requires a
   stub.  */
   stub.  */
 
 
static bfd_boolean
static bfd_boolean
mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type,
 
                                     bfd_boolean target_is_16_bit_code_p)
{
{
  /* We specifically ignore branches and jumps from EF_PIC objects,
  /* We specifically ignore branches and jumps from EF_PIC objects,
     where the onus is on the compiler or programmer to perform any
     where the onus is on the compiler or programmer to perform any
     necessary initialization of $25.  Sometimes such initialization
     necessary initialization of $25.  Sometimes such initialization
     is unnecessary; for example, -mno-shared functions do not use
     is unnecessary; for example, -mno-shared functions do not use
Line 4919... Line 4965...
 
 
  switch (r_type)
  switch (r_type)
    {
    {
    case R_MIPS_26:
    case R_MIPS_26:
    case R_MIPS_PC16:
    case R_MIPS_PC16:
    case R_MIPS16_26:
 
    case R_MICROMIPS_26_S1:
    case R_MICROMIPS_26_S1:
    case R_MICROMIPS_PC7_S1:
    case R_MICROMIPS_PC7_S1:
    case R_MICROMIPS_PC10_S1:
    case R_MICROMIPS_PC10_S1:
    case R_MICROMIPS_PC16_S1:
    case R_MICROMIPS_PC16_S1:
    case R_MICROMIPS_PC23_S2:
    case R_MICROMIPS_PC23_S2:
      return TRUE;
      return TRUE;
 
 
 
    case R_MIPS16_26:
 
      return !target_is_16_bit_code_p;
 
 
    default:
    default:
      return FALSE;
      return FALSE;
    }
    }
}
}


Line 5187... Line 5235...
    {
    {
      /* This is a 32- or 64-bit call to a 16-bit function.  We should
      /* This is a 32- or 64-bit call to a 16-bit function.  We should
         have already noticed that we were going to need the
         have already noticed that we were going to need the
         stub.  */
         stub.  */
      if (local_p)
      if (local_p)
 
        {
        sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
        sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
 
          value = 0;
 
        }
      else
      else
        {
        {
          BFD_ASSERT (h->need_fn_stub);
          BFD_ASSERT (h->need_fn_stub);
 
          if (h->la25_stub)
 
            {
 
              /* If a LA25 header for the stub itself exists, point to the
 
                 prepended LUI/ADDIU sequence.  */
 
              sec = h->la25_stub->stub_section;
 
              value = h->la25_stub->offset;
 
            }
 
          else
 
            {
          sec = h->fn_stub;
          sec = h->fn_stub;
 
              value = 0;
 
            }
        }
        }
 
 
      symbol = sec->output_section->vma + sec->output_offset;
      symbol = sec->output_section->vma + sec->output_offset + value;
      /* The target is 16-bit, but the stub isn't.  */
      /* The target is 16-bit, but the stub isn't.  */
      target_is_16_bit_code_p = FALSE;
      target_is_16_bit_code_p = FALSE;
    }
    }
  /* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
  /* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
     need to redirect the call to the stub.  Note that we specifically
     need to redirect the call to the stub.  Note that we specifically
Line 5244... Line 5306...
      symbol = sec->output_section->vma + sec->output_offset;
      symbol = sec->output_section->vma + sec->output_offset;
    }
    }
  /* If this is a direct call to a PIC function, redirect to the
  /* If this is a direct call to a PIC function, redirect to the
     non-PIC stub.  */
     non-PIC stub.  */
  else if (h != NULL && h->la25_stub
  else if (h != NULL && h->la25_stub
           && mips_elf_relocation_needs_la25_stub (input_bfd, r_type))
           && mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
 
                                                   target_is_16_bit_code_p))
    symbol = (h->la25_stub->stub_section->output_section->vma
    symbol = (h->la25_stub->stub_section->output_section->vma
              + h->la25_stub->stub_section->output_offset
              + h->la25_stub->stub_section->output_offset
              + h->la25_stub->offset);
              + h->la25_stub->offset);
 
 
  /* Make sure MIPS16 and microMIPS are not used together.  */
  /* Make sure MIPS16 and microMIPS are not used together.  */
Line 5316... Line 5379...
    case R_MICROMIPS_GOT_LO16:
    case R_MICROMIPS_GOT_LO16:
    case R_MICROMIPS_CALL_LO16:
    case R_MICROMIPS_CALL_LO16:
    case R_MIPS_TLS_GD:
    case R_MIPS_TLS_GD:
    case R_MIPS_TLS_GOTTPREL:
    case R_MIPS_TLS_GOTTPREL:
    case R_MIPS_TLS_LDM:
    case R_MIPS_TLS_LDM:
 
    case R_MIPS16_TLS_GD:
 
    case R_MIPS16_TLS_GOTTPREL:
 
    case R_MIPS16_TLS_LDM:
    case R_MICROMIPS_TLS_GD:
    case R_MICROMIPS_TLS_GD:
    case R_MICROMIPS_TLS_GOTTPREL:
    case R_MICROMIPS_TLS_GOTTPREL:
    case R_MICROMIPS_TLS_LDM:
    case R_MICROMIPS_TLS_LDM:
      /* Find the index into the GOT where this value is located.  */
      /* Find the index into the GOT where this value is located.  */
      if (tls_ldm_reloc_p (r_type))
      if (tls_ldm_reloc_p (r_type))
Line 5485... Line 5551...
        value &= howto->dst_mask;
        value &= howto->dst_mask;
      }
      }
      break;
      break;
 
 
    case R_MIPS_TLS_DTPREL_HI16:
    case R_MIPS_TLS_DTPREL_HI16:
 
    case R_MIPS16_TLS_DTPREL_HI16:
    case R_MICROMIPS_TLS_DTPREL_HI16:
    case R_MICROMIPS_TLS_DTPREL_HI16:
      value = (mips_elf_high (addend + symbol - dtprel_base (info))
      value = (mips_elf_high (addend + symbol - dtprel_base (info))
               & howto->dst_mask);
               & howto->dst_mask);
      break;
      break;
 
 
    case R_MIPS_TLS_DTPREL_LO16:
    case R_MIPS_TLS_DTPREL_LO16:
    case R_MIPS_TLS_DTPREL32:
    case R_MIPS_TLS_DTPREL32:
    case R_MIPS_TLS_DTPREL64:
    case R_MIPS_TLS_DTPREL64:
 
    case R_MIPS16_TLS_DTPREL_LO16:
    case R_MICROMIPS_TLS_DTPREL_LO16:
    case R_MICROMIPS_TLS_DTPREL_LO16:
      value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
      value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
      break;
      break;
 
 
    case R_MIPS_TLS_TPREL_HI16:
    case R_MIPS_TLS_TPREL_HI16:
 
    case R_MIPS16_TLS_TPREL_HI16:
    case R_MICROMIPS_TLS_TPREL_HI16:
    case R_MICROMIPS_TLS_TPREL_HI16:
      value = (mips_elf_high (addend + symbol - tprel_base (info))
      value = (mips_elf_high (addend + symbol - tprel_base (info))
               & howto->dst_mask);
               & howto->dst_mask);
      break;
      break;
 
 
    case R_MIPS_TLS_TPREL_LO16:
    case R_MIPS_TLS_TPREL_LO16:
 
    case R_MIPS_TLS_TPREL32:
 
    case R_MIPS_TLS_TPREL64:
 
    case R_MIPS16_TLS_TPREL_LO16:
    case R_MICROMIPS_TLS_TPREL_LO16:
    case R_MICROMIPS_TLS_TPREL_LO16:
      value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
      value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
      break;
      break;
 
 
    case R_MIPS_HI16:
    case R_MIPS_HI16:
Line 5525... Line 5597...
                4: addiupc $v1,%lo(_gp_disp)
                4: addiupc $v1,%lo(_gp_disp)
                8: sll     $v0,16
                8: sll     $v0,16
               12: addu    $v0,$v1
               12: addu    $v0,$v1
               14: move    $gp,$v0
               14: move    $gp,$v0
             So the offsets of hi and lo relocs are the same, but the
             So the offsets of hi and lo relocs are the same, but the
             $pc is four higher than $t9 would be, so reduce
             base $pc is that used by the ADDIUPC instruction at $t9 + 4.
             both reloc addends by 4. */
             ADDIUPC clears the low two bits of the instruction address,
 
             so the base is ($t9 + 4) & ~3.  */
          if (r_type == R_MIPS16_HI16)
          if (r_type == R_MIPS16_HI16)
            value = mips_elf_high (addend + gp - p - 4);
            value = mips_elf_high (addend + gp - ((p + 4) & ~(bfd_vma) 0x3));
          /* The microMIPS .cpload sequence uses the same assembly
          /* The microMIPS .cpload sequence uses the same assembly
             instructions as the traditional psABI version, but the
             instructions as the traditional psABI version, but the
             incoming $t9 has the low bit set.  */
             incoming $t9 has the low bit set.  */
          else if (r_type == R_MICROMIPS_HI16)
          else if (r_type == R_MICROMIPS_HI16)
            value = mips_elf_high (addend + gp - p - 1);
            value = mips_elf_high (addend + gp - p - 1);
Line 5551... Line 5624...
      else
      else
        {
        {
          /* See the comment for R_MIPS16_HI16 above for the reason
          /* See the comment for R_MIPS16_HI16 above for the reason
             for this conditional.  */
             for this conditional.  */
          if (r_type == R_MIPS16_LO16)
          if (r_type == R_MIPS16_LO16)
            value = addend + gp - p;
            value = addend + gp - (p & ~(bfd_vma) 0x3);
          else if (r_type == R_MICROMIPS_LO16
          else if (r_type == R_MICROMIPS_LO16
                   || r_type == R_MICROMIPS_HI0_LO16)
                   || r_type == R_MICROMIPS_HI0_LO16)
            value = addend + gp - p + 3;
            value = addend + gp - p + 3;
          else
          else
            value = addend + gp - p + 4;
            value = addend + gp - p + 4;
Line 5635... Line 5708...
 
 
    case R_MIPS_TLS_GD:
    case R_MIPS_TLS_GD:
    case R_MIPS_TLS_GOTTPREL:
    case R_MIPS_TLS_GOTTPREL:
    case R_MIPS_TLS_LDM:
    case R_MIPS_TLS_LDM:
    case R_MIPS_GOT_DISP:
    case R_MIPS_GOT_DISP:
 
    case R_MIPS16_TLS_GD:
 
    case R_MIPS16_TLS_GOTTPREL:
 
    case R_MIPS16_TLS_LDM:
    case R_MICROMIPS_TLS_GD:
    case R_MICROMIPS_TLS_GD:
    case R_MICROMIPS_TLS_GOTTPREL:
    case R_MICROMIPS_TLS_GOTTPREL:
    case R_MICROMIPS_TLS_LDM:
    case R_MICROMIPS_TLS_LDM:
    case R_MICROMIPS_GOT_DISP:
    case R_MICROMIPS_GOT_DISP:
      value = g;
      value = g;
Line 6180... Line 6256...
      return bfd_mach_mips_loongson_2f;
      return bfd_mach_mips_loongson_2f;
 
 
    case E_MIPS_MACH_LS3A:
    case E_MIPS_MACH_LS3A:
      return bfd_mach_mips_loongson_3a;
      return bfd_mach_mips_loongson_3a;
 
 
 
    case E_MIPS_MACH_OCTEON2:
 
      return bfd_mach_mips_octeon2;
 
 
    case E_MIPS_MACH_OCTEON:
    case E_MIPS_MACH_OCTEON:
      return bfd_mach_mips_octeon;
      return bfd_mach_mips_octeon;
 
 
    case E_MIPS_MACH_XLR:
    case E_MIPS_MACH_XLR:
      return bfd_mach_mips_xlr;
      return bfd_mach_mips_xlr;
Line 7077... Line 7156...
 
 
      if (! bfd_elf_link_record_dynamic_symbol (info, h))
      if (! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
        return FALSE;
 
 
      mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
      mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
 
      mips_elf_hash_table (info)->rld_symbol = h;
    }
    }
 
 
  /* If this is a mips16 text symbol, add 1 to the value to make it
  /* If this is a mips16 text symbol, add 1 to the value to make it
     odd.  This will cause something like .word SYM to come up with
     odd.  This will cause something like .word SYM to come up with
     the right value when it is loaded into the PC.  */
     the right value when it is loaded into the PC.  */
Line 7262... Line 7342...
          h->def_regular = 1;
          h->def_regular = 1;
          h->type = STT_OBJECT;
          h->type = STT_OBJECT;
 
 
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
            return FALSE;
 
          mips_elf_hash_table (info)->rld_symbol = h;
        }
        }
    }
    }
 
 
  /* Create the .plt, .rel(a).plt, .dynbss and .rel(a).bss sections.
  /* Create the .plt, .rel(a).plt, .dynbss and .rel(a).bss sections.
     Also create the _PROCEDURE_LINKAGE_TABLE symbol.  */
     Also create the _PROCEDURE_LINKAGE_TABLE symbol.  */
Line 7763... Line 7844...
      /* Set CAN_MAKE_DYNAMIC_P to true if we can convert this
      /* Set CAN_MAKE_DYNAMIC_P to true if we can convert this
         relocation into a dynamic one.  */
         relocation into a dynamic one.  */
      can_make_dynamic_p = FALSE;
      can_make_dynamic_p = FALSE;
      switch (r_type)
      switch (r_type)
        {
        {
        case R_MIPS16_GOT16:
 
        case R_MIPS16_CALL16:
 
        case R_MIPS_GOT16:
        case R_MIPS_GOT16:
        case R_MIPS_CALL16:
        case R_MIPS_CALL16:
        case R_MIPS_CALL_HI16:
        case R_MIPS_CALL_HI16:
        case R_MIPS_CALL_LO16:
        case R_MIPS_CALL_LO16:
        case R_MIPS_GOT_HI16:
        case R_MIPS_GOT_HI16:
Line 7777... Line 7856...
        case R_MIPS_GOT_OFST:
        case R_MIPS_GOT_OFST:
        case R_MIPS_GOT_DISP:
        case R_MIPS_GOT_DISP:
        case R_MIPS_TLS_GOTTPREL:
        case R_MIPS_TLS_GOTTPREL:
        case R_MIPS_TLS_GD:
        case R_MIPS_TLS_GD:
        case R_MIPS_TLS_LDM:
        case R_MIPS_TLS_LDM:
 
        case R_MIPS16_GOT16:
 
        case R_MIPS16_CALL16:
 
        case R_MIPS16_TLS_GOTTPREL:
 
        case R_MIPS16_TLS_GD:
 
        case R_MIPS16_TLS_LDM:
        case R_MICROMIPS_GOT16:
        case R_MICROMIPS_GOT16:
        case R_MICROMIPS_CALL16:
        case R_MICROMIPS_CALL16:
        case R_MICROMIPS_CALL_HI16:
        case R_MICROMIPS_CALL_HI16:
        case R_MICROMIPS_CALL_LO16:
        case R_MICROMIPS_CALL_LO16:
        case R_MICROMIPS_GOT_HI16:
        case R_MICROMIPS_GOT_HI16:
Line 7914... Line 7998...
          if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
          if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
                                                 rel->r_addend, info, 0))
                                                 rel->r_addend, info, 0))
            return FALSE;
            return FALSE;
        }
        }
 
 
      if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type))
      if (h != NULL
 
          && mips_elf_relocation_needs_la25_stub (abfd, r_type,
 
                                                  ELF_ST_IS_MIPS16 (h->other)))
        ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
        ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
 
 
      switch (r_type)
      switch (r_type)
        {
        {
        case R_MIPS_CALL16:
        case R_MIPS_CALL16:
Line 8011... Line 8097...
                                                       FALSE, 0))
                                                       FALSE, 0))
            return FALSE;
            return FALSE;
          break;
          break;
 
 
        case R_MIPS_TLS_GOTTPREL:
        case R_MIPS_TLS_GOTTPREL:
 
        case R_MIPS16_TLS_GOTTPREL:
        case R_MICROMIPS_TLS_GOTTPREL:
        case R_MICROMIPS_TLS_GOTTPREL:
          if (info->shared)
          if (info->shared)
            info->flags |= DF_STATIC_TLS;
            info->flags |= DF_STATIC_TLS;
          /* Fall through */
          /* Fall through */
 
 
        case R_MIPS_TLS_LDM:
        case R_MIPS_TLS_LDM:
 
        case R_MIPS16_TLS_LDM:
        case R_MICROMIPS_TLS_LDM:
        case R_MICROMIPS_TLS_LDM:
          if (tls_ldm_reloc_p (r_type))
          if (tls_ldm_reloc_p (r_type))
            {
            {
              r_symndx = STN_UNDEF;
              r_symndx = STN_UNDEF;
              h = NULL;
              h = NULL;
            }
            }
          /* Fall through */
          /* Fall through */
 
 
        case R_MIPS_TLS_GD:
        case R_MIPS_TLS_GD:
 
        case R_MIPS16_TLS_GD:
        case R_MICROMIPS_TLS_GD:
        case R_MICROMIPS_TLS_GD:
          /* This symbol requires a global offset table entry, or two
          /* This symbol requires a global offset table entry, or two
             for TLS GD relocations.  */
             for TLS GD relocations.  */
          {
          {
            unsigned char flag;
            unsigned char flag;
Line 9023... Line 9112...
               && ! mips_elf_hash_table (info)->use_rld_obj_head
               && ! mips_elf_hash_table (info)->use_rld_obj_head
               && CONST_STRNEQ (name, ".rld_map"))
               && CONST_STRNEQ (name, ".rld_map"))
        {
        {
          /* We add a room for __rld_map.  It will be filled in by the
          /* We add a room for __rld_map.  It will be filled in by the
             rtld to contain a pointer to the _r_debug structure.  */
             rtld to contain a pointer to the _r_debug structure.  */
          s->size += 4;
          s->size += MIPS_ELF_RLD_MAP_SIZE (output_bfd);
        }
        }
      else if (SGI_COMPAT (output_bfd)
      else if (SGI_COMPAT (output_bfd)
               && CONST_STRNEQ (name, ".compact_rel"))
               && CONST_STRNEQ (name, ".compact_rel"))
        s->size += mips_elf_hash_table (info)->compact_rel_size;
        s->size += mips_elf_hash_table (info)->compact_rel_size;
      else if (s == htab->splt)
      else if (s == htab->splt)
Line 9611... Line 9700...
 
 
  /* Work out where in the section this stub should go.  */
  /* Work out where in the section this stub should go.  */
  offset = stub->offset;
  offset = stub->offset;
 
 
  /* Work out the target address.  */
  /* Work out the target address.  */
  target = (stub->h->root.root.u.def.section->output_section->vma
  target = mips_elf_get_la25_target (stub, &s);
            + stub->h->root.root.u.def.section->output_offset
  target += s->output_section->vma + s->output_offset;
            + stub->h->root.root.u.def.value);
 
  target_high = ((target + 0x8000) >> 16) & 0xffff;
  target_high = ((target + 0x8000) >> 16) & 0xffff;
  target_low = (target & 0xffff);
  target_low = (target & 0xffff);
 
 
  if (stub->stub_section != htab->strampoline)
  if (stub->stub_section != htab->strampoline)
    {
    {
Line 10026... Line 10115...
 
 
  /* Handle the IRIX6-specific symbols.  */
  /* Handle the IRIX6-specific symbols.  */
  if (IRIX_COMPAT (output_bfd) == ict_irix6)
  if (IRIX_COMPAT (output_bfd) == ict_irix6)
    mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
    mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
 
 
  if (! info->shared)
 
    {
 
      if (! mips_elf_hash_table (info)->use_rld_obj_head
 
          && (strcmp (name, "__rld_map") == 0
 
              || strcmp (name, "__RLD_MAP") == 0))
 
        {
 
          asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
 
          BFD_ASSERT (s != NULL);
 
          sym->st_value = s->output_section->vma + s->output_offset;
 
          bfd_put_32 (output_bfd, 0, s->contents);
 
          if (mips_elf_hash_table (info)->rld_value == 0)
 
            mips_elf_hash_table (info)->rld_value = sym->st_value;
 
        }
 
      else if (mips_elf_hash_table (info)->use_rld_obj_head
 
               && strcmp (name, "__rld_obj_head") == 0)
 
        {
 
          /* IRIX6 does not use a .rld_map section.  */
 
          if (IRIX_COMPAT (output_bfd) == ict_irix5
 
              || IRIX_COMPAT (output_bfd) == ict_none)
 
            BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
 
                        != NULL);
 
          mips_elf_hash_table (info)->rld_value = sym->st_value;
 
        }
 
    }
 
 
 
  /* Keep dynamic MIPS16 symbols odd.  This allows the dynamic linker to
  /* Keep dynamic MIPS16 symbols odd.  This allows the dynamic linker to
     treat MIPS16 symbols like any other.  */
     treat MIPS16 symbols like any other.  */
  if (ELF_ST_IS_MIPS16 (sym->st_other))
  if (ELF_ST_IS_MIPS16 (sym->st_other))
    {
    {
      BFD_ASSERT (sym->st_value & 1);
      BFD_ASSERT (sym->st_value & 1);
Line 10513... Line 10577...
            case DT_MIPS_HIPAGENO:
            case DT_MIPS_HIPAGENO:
              dyn.d_un.d_val = g->local_gotno - htab->reserved_gotno;
              dyn.d_un.d_val = g->local_gotno - htab->reserved_gotno;
              break;
              break;
 
 
            case DT_MIPS_RLD_MAP:
            case DT_MIPS_RLD_MAP:
              dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value;
              {
 
                struct elf_link_hash_entry *h;
 
                h = mips_elf_hash_table (info)->rld_symbol;
 
                if (!h)
 
                  {
 
                    dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
 
                    swap_out_p = FALSE;
 
                    break;
 
                  }
 
                s = h->root.u.def.section;
 
                dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
 
                                  + h->root.u.def.value);
 
              }
              break;
              break;
 
 
            case DT_MIPS_OPTIONS:
            case DT_MIPS_OPTIONS:
              s = (bfd_get_section_by_name
              s = (bfd_get_section_by_name
                   (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
                   (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
Line 10883... Line 10959...
    case bfd_mach_mips_loongson_3a:
    case bfd_mach_mips_loongson_3a:
      val = E_MIPS_ARCH_64 | E_MIPS_MACH_LS3A;
      val = E_MIPS_ARCH_64 | E_MIPS_MACH_LS3A;
      break;
      break;
 
 
    case bfd_mach_mips_octeon:
    case bfd_mach_mips_octeon:
 
    case bfd_mach_mips_octeonp:
      val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON;
      val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON;
      break;
      break;
 
 
    case bfd_mach_mips_xlr:
    case bfd_mach_mips_xlr:
      val = E_MIPS_ARCH_64 | E_MIPS_MACH_XLR;
      val = E_MIPS_ARCH_64 | E_MIPS_MACH_XLR;
      break;
      break;
 
 
 
    case bfd_mach_mips_octeon2:
 
      val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON2;
 
      break;
 
 
    case bfd_mach_mipsisa32:
    case bfd_mach_mipsisa32:
      val = E_MIPS_ARCH_32;
      val = E_MIPS_ARCH_32;
      break;
      break;
 
 
    case bfd_mach_mipsisa64:
    case bfd_mach_mipsisa64:
Line 12791... Line 12872...
    ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
    ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
#endif
#endif
  ret->procedure_count = 0;
  ret->procedure_count = 0;
  ret->compact_rel_size = 0;
  ret->compact_rel_size = 0;
  ret->use_rld_obj_head = FALSE;
  ret->use_rld_obj_head = FALSE;
  ret->rld_value = 0;
  ret->rld_symbol = NULL;
  ret->mips16_stubs_seen = FALSE;
  ret->mips16_stubs_seen = FALSE;
  ret->use_plts_and_copy_relocs = FALSE;
  ret->use_plts_and_copy_relocs = FALSE;
  ret->is_vxworks = FALSE;
  ret->is_vxworks = FALSE;
  ret->small_data_overflow_reported = FALSE;
  ret->small_data_overflow_reported = FALSE;
  ret->srelbss = NULL;
  ret->srelbss = NULL;
Line 13489... Line 13570...
/* An array describing how BFD machines relate to one another.  The entries
/* An array describing how BFD machines relate to one another.  The entries
   are ordered topologically with MIPS I extensions listed last.  */
   are ordered topologically with MIPS I extensions listed last.  */
 
 
static const struct mips_mach_extension mips_mach_extensions[] = {
static const struct mips_mach_extension mips_mach_extensions[] = {
  /* MIPS64r2 extensions.  */
  /* MIPS64r2 extensions.  */
 
  { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
 
  { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
 
 
  /* MIPS64 extensions.  */
  /* MIPS64 extensions.  */
  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.