Elf_Internal_Sym *));
static boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
-static enum elf_reloc_type_class ppc_elf_reloc_type_class PARAMS ((int));
+static enum elf_reloc_type_class ppc_elf_reloc_type_class
+ PARAMS ((const Elf_Internal_Rela *));
+static boolean ppc_elf_grok_prstatus
+ PARAMS ((bfd *abfd, Elf_Internal_Note *note));
+static boolean ppc_elf_grok_psinfo
+ PARAMS ((bfd *abfd, Elf_Internal_Note *note));
#define BRANCH_PREDICT_BIT 0x200000 /* branch prediction bit for branch taken relocs */
#define RA_REGISTER_MASK 0x001f0000 /* mask to set RA in memory instructions */
if (isec->reloc_count)
{
unsigned n;
+ bfd_size_type amt;
/* Get a copy of the native relocations. */
internal_relocs = _bfd_elf32_link_read_relocs (
free_relocs = internal_relocs;
/* Setup a faster access method for the reloc info we need. */
- rela_comb = (Elf_Internal_Rela**)
- bfd_malloc (isec->reloc_count*sizeof (Elf_Internal_Rela*));
+ amt = isec->reloc_count;
+ amt *= sizeof (Elf_Internal_Rela*);
+ rela_comb = (Elf_Internal_Rela**) bfd_malloc (amt);
if (rela_comb == NULL)
goto error_return;
for (n = 0; n < isec->reloc_count; ++n)
#undef BO4
if (modified)
{
- bfd_put_32 (abfd, insn, contents + isec_offset);
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + isec_offset);
section_modified = true;
}
}
error = true;
(*_bfd_error_handler)
(_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
}
else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
&& (old_flags & EF_PPC_RELOCATABLE) != 0)
error = true;
(*_bfd_error_handler)
(_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
}
/* The output is -mrelocatable-lib iff both the input files are. */
error = true;
(*_bfd_error_handler)
(_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
- bfd_get_filename (ibfd), (long) new_flags, (long) old_flags);
+ bfd_archive_filename (ibfd), (long) new_flags, (long) old_flags);
}
if (error)
return true;
}
+ else
+ h->plt.offset = (bfd_vma) -1;
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
must add the entries now so that we get the correct size for
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
- if (! info->shared)
+#define add_dynamic_entry(TAG, VAL) \
+ bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+
+ if (!info->shared)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!add_dynamic_entry (DT_DEBUG, 0))
return false;
}
if (plt)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
return false;
}
if (relocs)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf32_External_Rela)))
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
return false;
}
if ((info->flags & DF_TEXTREL) != 0)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
return false;
info->flags |= DF_TEXTREL;
}
}
+#undef add_dynamic_entry
return true;
}
#ifdef DEBUG
fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
bfd_get_section_name (abfd, sec),
- bfd_get_filename (abfd));
+ bfd_archive_filename (abfd));
#endif
/* Create the linker generated sections all the time so that the
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
sgot->_raw_size += 4;
/* Allocate relocation space. */
srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
- h->got.refcount = 1;
}
- else
- h->got.refcount++;
+ h->got.refcount++;
}
else
{
/* This is a global offset table entry for a local symbol. */
if (local_got_refcounts == NULL)
{
- size_t size;
+ bfd_size_type size;
- size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);
- local_got_refcounts = (bfd_signed_vma *)
- bfd_alloc (abfd, size);
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts
+ = (bfd_signed_vma *) bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
sgot->_raw_size += 4;
dynamic linker can adjust this GOT entry. */
if (info->shared)
srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
- local_got_refcounts[r_symndx] = 1;
}
- else
- local_got_refcounts[r_symndx]++;
+ local_got_refcounts[r_symndx]++;
}
break;
{
((*_bfd_error_handler)
(_("%s: relocation %s cannot be used when making a shared object"),
- bfd_get_filename (abfd), "R_PPC_EMB_SDAI16"));
+ bfd_archive_filename (abfd), "R_PPC_EMB_SDAI16"));
return false;
}
{
((*_bfd_error_handler)
(_("%s: relocation %s cannot be used when making a shared object"),
- bfd_get_filename (abfd), "R_PPC_EMB_SDA2I16"));
+ bfd_archive_filename (abfd), "R_PPC_EMB_SDA2I16"));
return false;
}
{
((*_bfd_error_handler)
(_("%s: relocation %s cannot be used when making a shared object"),
- bfd_get_filename (abfd),
+ bfd_archive_filename (abfd),
ppc_elf_howto_table[(int) ELF32_R_TYPE (rel->r_info)]->name));
return false;
}
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
}
- if (h->plt.refcount == -1)
- {
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- h->plt.refcount = 1;
- }
- else
- h->plt.refcount++;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount++;
break;
/* The following relocations don't need to propagate the
if (!sdata->bss_section)
{
+ bfd_size_type amt;
+
/* We don't go through bfd_make_section, because we don't
want to attach this common section to DYNOBJ. The linker
will move the symbols to the appropriate output section
when it defines common symbols. */
- sdata->bss_section = ((asection *)
- bfd_zalloc (abfd, sizeof (asection)));
+ amt = sizeof (asection);
+ sdata->bss_section = (asection *) bfd_zalloc (abfd, amt);
if (sdata->bss_section == NULL)
return false;
sdata->bss_section->name = sdata->bss_name;
sdata->bss_section->flags = SEC_IS_COMMON;
sdata->bss_section->output_section = sdata->bss_section;
- sdata->bss_section->symbol =
- (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ amt = sizeof (asymbol);
+ sdata->bss_section->symbol = (asymbol *) bfd_zalloc (abfd, amt);
+ amt = sizeof (asymbol *);
sdata->bss_section->symbol_ptr_ptr =
- (asymbol **) bfd_zalloc (abfd, sizeof (asymbol *));
+ (asymbol **) bfd_zalloc (abfd, amt);
if (sdata->bss_section->symbol == NULL
|| sdata->bss_section->symbol_ptr_ptr == NULL)
return false;
rela.r_offset = (sgot->output_section->vma
+ sgot->output_offset
- + (h->got.offset &~ 1));
+ + (h->got.offset &~ (bfd_vma) 1));
/* If this is a -Bsymbolic link, and the symbol is defined
locally, we just want to emit a RELATIVE reloc. The entry in
if (sgot)
{
unsigned char *contents = sgot->contents;
- bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x4e800021 /* blrl */, contents);
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
#ifdef DEBUG
fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
bfd_section_name(input_bfd, input_section),
(long) input_section->reloc_count,
(info->relocateable) ? " (relocatable)" : "");
|| !ppc_elf_howto_table[(int) r_type])
{
(*_bfd_error_handler) (_("%s: unknown relocation type %d"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
(int) r_type);
bfd_set_error (bfd_error_bad_value);
sec = local_sections[r_symndx];
sym_name = "<local symbol>";
- relocation = (sec->output_section->vma
- + sec->output_offset
- + sym->st_value);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+ addend = rel->r_addend;
/* Relocs to local symbols are always resolved. */
will_become_local = 1;
}
{
(*_bfd_error_handler)
(_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
- bfd_get_filename (input_bfd), h->root.root.string,
+ bfd_archive_filename (input_bfd), h->root.root.string,
bfd_get_section_name (input_bfd, input_section));
relocation = 0;
}
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (info->shared && !info->symbolic && !info->no_undefined
+ else if (info->shared
+ && (!info->symbolic || info->allow_shlib_undefined)
+ && !info->no_undefined
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
{
default:
(*_bfd_error_handler) (_("%s: unknown relocation type %d for symbol %s"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
(int) r_type, sym_name);
bfd_set_error (bfd_error_bad_value);
ret = false;
continue;
+ case (int) R_PPC_NONE:
+ continue;
+
/* Relocations that need no special processing. */
case (int) R_PPC_LOCAL24PC:
/* It makes no sense to point a local relocation
/* Relocations that always need to be propagated if this is a shared
object. */
- case (int) R_PPC_NONE:
case (int) R_PPC_ADDR32:
case (int) R_PPC_ADDR24:
case (int) R_PPC_ADDR16:
case (int) R_PPC_ADDR14:
case (int) R_PPC_UADDR32:
case (int) R_PPC_UADDR16:
- if (info->shared)
+ if (info->shared && r_symndx != 0)
{
Elf_Internal_Rela outrel;
boolean skip;
skip = false;
- if (elf_section_data (input_section)->stab_info == NULL)
- outrel.r_offset = rel->r_offset;
- else
- {
- bfd_vma off;
-
- off = (_bfd_stab_section_offset
- (output_bfd, &elf_hash_table (info)->stab_info,
- input_section,
- &elf_section_data (input_section)->stab_info,
- rel->r_offset));
- if (off == (bfd_vma) -1)
- skip = true;
- outrel.r_offset = off;
- }
-
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = true;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
insn &= ~BRANCH_PREDICT_BIT;
else
insn |= BRANCH_PREDICT_BIT;
- bfd_put_32 (output_bfd, insn, contents + offset);
+ bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
break;
/* branch not taken predicition relocations */
insn |= BRANCH_PREDICT_BIT;
else
insn &= ~BRANCH_PREDICT_BIT;
- bfd_put_32 (output_bfd, insn, contents + offset);
+ bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
break;
/* GOT16 relocations */
&& strcmp (name, ".sbss") != 0)
{
(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
sym_name,
ppc_elf_howto_table[(int) r_type]->name,
name);
if (strcmp (name, ".sdata2") != 0 && strcmp (name, ".sbss2") != 0)
{
(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
sym_name,
ppc_elf_howto_table[(int) r_type]->name,
name);
else
{
(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
sym_name,
ppc_elf_howto_table[(int) r_type]->name,
name);
{ /* fill in register field */
insn = bfd_get_32 (output_bfd, contents + offset);
insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
- bfd_put_32 (output_bfd, insn, contents + offset);
+ bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
}
}
break;
case (int) R_PPC_EMB_RELST_HA:
case (int) R_PPC_EMB_BIT_FLD:
(*_bfd_error_handler) (_("%s: Relocation %s is not yet supported for symbol %s."),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
ppc_elf_howto_table[(int) r_type]->name,
sym_name);
}
static enum elf_reloc_type_class
-ppc_elf_reloc_type_class (type)
- int type;
+ppc_elf_reloc_type_class (rela)
+ const Elf_Internal_Rela *rela;
{
- switch (type)
+ switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_PPC_RELATIVE:
return reloc_class_relative;
Elf_Internal_Note *note;
{
int offset;
- int raw_size;
+ unsigned int raw_size;
switch (note->descsz)
{
#define elf_backend_plt_not_loaded 1
#define elf_backend_got_symbol_offset 4
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_got_header_size 12
#define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE