/* PowerPC-specific support for 32-bit ELF
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
/* This reloc does nothing. */
HOWTO (R_PPC_NONE, /* type */
0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 3, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
+ unsigned int r_type;
+
/* Initialize howto table if not already done. */
if (!ppc_elf_howto_table[R_PPC_ADDR32])
ppc_elf_howto_init ();
- BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
- cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
+ r_type = ELF32_R_TYPE (dst->r_info);
+ if (r_type >= R_PPC_max)
+ {
+ (*_bfd_error_handler) (_("%B: unrecognised PPC reloc number: %d"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ r_type = R_PPC_NONE;
+ }
+ cache_ptr->howto = ppc_elf_howto_table[r_type];
/* Just because the above assert didn't trigger doesn't mean that
ELF32_R_TYPE (dst->r_info) is necessarily a valid relocation. */
if (!cache_ptr->howto)
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
- abfd, ELF32_R_TYPE (dst->r_info));
+ abfd, r_type);
bfd_set_error (bfd_error_bad_value);
cache_ptr->howto = ppc_elf_howto_table[R_PPC_NONE];
return bfd_reloc_ok;
}
- if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
- return bfd_reloc_outofrange;
-
if (bfd_is_com_section (symbol->section))
relocation = 0;
else
*valp = sym->st_size;
}
- if ((abfd->flags & DYNAMIC) == 0
- && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
- || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
\f
/* Generate a symbol to mark plt call stubs. For non-PIC code the sym is
sh->ref_regular_nonweak = 1;
sh->forced_local = 1;
sh->non_elf = 0;
+ sh->root.linker_def = 1;
}
return TRUE;
}
sh->ref_regular_nonweak = 1;
sh->forced_local = 1;
sh->non_elf = 0;
+ sh->root.linker_def = 1;
}
sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
TRUE, FALSE, FALSE);
sh->ref_regular_nonweak = 1;
sh->forced_local = 1;
sh->non_elf = 0;
+ sh->root.linker_def = 1;
}
}
}
bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
addr = isec->output_section->vma + isec->output_offset;
- end_addr = addr + trampoff - 1;
+ end_addr = addr + trampoff;
addr &= -pagesize;
crossings = ((end_addr & -pagesize) - addr) >> htab->params->pagesize_p2;
if (crossings != 0)
/* Keep space aligned, to ensure the patch code itself does
not cross a page. Don't decrease size calculated on a
previous pass as otherwise we might never settle on a layout. */
- newsize = 15 - (end_addr & 15);
+ newsize = 15 - ((end_addr - 1) & 15);
newsize += crossings * 16;
if (relax_info->workaround_size < newsize)
{
+ R_PPC_GOT_TPREL16);
else
{
- bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
rel->r_offset -= d_offset;
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
r_type = R_PPC_NONE;
}
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
&& branch_reloc_hash_match (input_bfd, rel + 1,
htab->tls_get_addr))
offset = rel[1].r_offset;
+ /* We read the low GOT_TLS insn because we need to keep
+ the destination reg. It may be something other than
+ the usual r3, and moved to r3 before the call by
+ intervening code. */
+ insn1 = bfd_get_32 (output_bfd,
+ contents + rel->r_offset - d_offset);
if ((tls_mask & tls_gd) != 0)
{
/* IE */
- insn1 = bfd_get_32 (output_bfd,
- contents + rel->r_offset - d_offset);
- insn1 &= (1 << 26) - 1;
+ insn1 &= (0x1f << 21) | (0x1f << 16);
insn1 |= 32 << 26; /* lwz */
if (offset != (bfd_vma) -1)
{
else
{
/* LE */
- insn1 = 0x3c620000; /* addis 3,2,0 */
+ insn1 &= 0x1f << 21;
+ insn1 |= 0x3c020000; /* addis r,2,0 */
if (tls_gd == 0)
{
/* Was an LD reloc. */
{
outrel.r_addend += relocation;
if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
- outrel.r_addend -= htab->elf.tls_sec->vma;
+ {
+ if (htab->elf.tls_sec == NULL)
+ outrel.r_addend = 0;
+ else
+ outrel.r_addend -= htab->elf.tls_sec->vma;
+ }
}
loc = rsec->contents;
loc += (rsec->reloc_count++
value = 1;
else if (tls_ty != 0)
{
- value -= htab->elf.tls_sec->vma + DTP_OFFSET;
- if (tls_ty == (TLS_TLS | TLS_TPREL))
- value += DTP_OFFSET - TP_OFFSET;
+ if (htab->elf.tls_sec == NULL)
+ value = 0;
+ else
+ {
+ value -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (tls_ty == (TLS_TLS | TLS_TPREL))
+ value += DTP_OFFSET - TP_OFFSET;
+ }
if (tls_ty == (TLS_TLS | TLS_GD))
{
case R_PPC_DTPREL16_LO:
case R_PPC_DTPREL16_HI:
case R_PPC_DTPREL16_HA:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
break;
/* Relocations that may need to be propagated if this is a shared
bfd_put_32 (output_bfd, insn, p);
break;
}
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
/* The TPREL16 relocs shouldn't really be used in shared
libs as they will result in DT_TEXTREL being set, but
support them anyway. */
goto dodyn;
case R_PPC_TPREL32:
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
goto dodyn;
case R_PPC_DTPREL32:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
goto dodyn;
case R_PPC_DTPMOD32:
#define ELF_MACHINE_CODE EM_PPC
#ifdef __QNXTARGET__
#define ELF_MAXPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
#else
#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
#endif
#define ELF_MINPAGESIZE 0x1000
-#define ELF_COMMONPAGESIZE 0x1000
#define elf_info_to_howto ppc_elf_info_to_howto
#ifdef EM_CYGNUS_POWERPC