* elf32-mips.c (mips_elf_local_relocation_p): New static

function.
	(mips_elf_next_lo16_addend): Call bfd_set_error on failure.
	(mips_elf_calculate_relocation): Use mips_elf_local_relocation_p.
	Always set *require_jalxp.
	(mips_elf_stub_section_p): Mark abfd parameter as unused.
	(_bfd_mips_elf_relocate_section): Only look for LO16 following
	GOT16 if the GOT16 is against a local symbol.  Don't return false
	for an undefined symbol.  If there is an overflow, assert that we
	have a name.
This commit is contained in:
Ian Lance Taylor
1999-07-16 19:09:22 +00:00
parent b4cac588ae
commit 6387d6028b
2 changed files with 68 additions and 21 deletions

View File

@ -1,3 +1,16 @@
1999-07-16 Ian Lance Taylor <ian@zembu.com>
* elf32-mips.c (mips_elf_local_relocation_p): New static
function.
(mips_elf_next_lo16_addend): Call bfd_set_error on failure.
(mips_elf_calculate_relocation): Use mips_elf_local_relocation_p.
Always set *require_jalxp.
(mips_elf_stub_section_p): Mark abfd parameter as unused.
(_bfd_mips_elf_relocate_section): Only look for LO16 following
GOT16 if the GOT16 is against a local symbol. Don't return false
for an undefined symbol. If there is an overflow, assert that we
have a name.
1999-07-16 Andreas Schwab <schwab@suse.de> 1999-07-16 Andreas Schwab <schwab@suse.de>
* elflink.h (elf_link_record_local_dynamic_symbol): Remove unused * elflink.h (elf_link_record_local_dynamic_symbol): Remove unused

View File

@ -184,6 +184,8 @@ static boolean mips_elf_sort_hash_table
static asection * mips_elf_got_section PARAMS ((bfd *)); static asection * mips_elf_got_section PARAMS ((bfd *));
static struct mips_got_info *mips_elf_got_info static struct mips_got_info *mips_elf_got_info
PARAMS ((bfd *, asection **)); PARAMS ((bfd *, asection **));
static boolean mips_elf_local_relocation_p
PARAMS ((bfd *, const Elf_Internal_Rela *, asection **));
static bfd_vma mips_elf_create_local_got_entry static bfd_vma mips_elf_create_local_got_entry
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma)); PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
static bfd_vma mips_elf_got16_entry static bfd_vma mips_elf_got16_entry
@ -5150,6 +5152,29 @@ mips_elf_got_info (abfd, sgotp)
return g; return g;
} }
/* Return whether a relocation is against a local symbol. */
static boolean
mips_elf_local_relocation_p (input_bfd, relocation, local_sections)
bfd *input_bfd;
const Elf_Internal_Rela *relocation;
asection **local_sections;
{
unsigned long r_symndx;
Elf_Internal_Shdr *symtab_hdr;
r_symndx = ELF32_R_SYM (relocation->r_info);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (! elf_bad_symtab (input_bfd))
return r_symndx < symtab_hdr->sh_info;
else
{
/* The symbol table does not follow the rule that local symbols
must come before globals. */
return local_sections[r_symndx] != NULL;
}
}
/* Sign-extend VALUE, which has the indicated number of BITS. */ /* Sign-extend VALUE, which has the indicated number of BITS. */
static bfd_vma static bfd_vma
@ -5554,6 +5579,7 @@ mips_elf_next_lo16_addend (relocation, relend, addendp)
} }
/* We didn't find it. */ /* We didn't find it. */
bfd_set_error (bfd_error_bad_value);
return false; return false;
} }
@ -5754,19 +5780,18 @@ mips_elf_calculate_relocation (abfd,
/* Assume that there will be no overflow. */ /* Assume that there will be no overflow. */
overflowed_p = false; overflowed_p = false;
/* Figure out whether or not the symbol is local. */ /* Figure out whether or not the symbol is local, and get the offset
used in the array of hash table entries. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (elf_bad_symtab (input_bfd)) local_p = mips_elf_local_relocation_p (input_bfd, relocation,
local_sections);
if (! elf_bad_symtab (input_bfd))
extsymoff = symtab_hdr->sh_info;
else
{ {
/* The symbol table does not follow the rule that local symbols /* The symbol table does not follow the rule that local symbols
must come before globals. */ must come before globals. */
extsymoff = 0; extsymoff = 0;
local_p = local_sections[r_symndx] != NULL;
}
else
{
extsymoff = symtab_hdr->sh_info;
local_p = r_symndx < extsymoff;
} }
/* Figure out the value of the symbol. */ /* Figure out the value of the symbol. */
@ -5905,9 +5930,8 @@ mips_elf_calculate_relocation (abfd,
/* Calls from 16-bit code to 32-bit code and vice versa require the /* Calls from 16-bit code to 32-bit code and vice versa require the
special jalx instruction. */ special jalx instruction. */
if (!info->relocateable *require_jalxp = (!info->relocateable
&& ((r_type == R_MIPS16_26) != target_is_16_bit_code_p)) && ((r_type == R_MIPS16_26) != target_is_16_bit_code_p));
*require_jalxp = true;
/* If we haven't already determined the GOT offset, or the GP value, /* If we haven't already determined the GOT offset, or the GP value,
and we're going to need it, get it now. */ and we're going to need it, get it now. */
@ -6381,7 +6405,7 @@ mips_elf_perform_relocation (info, howto, relocation, value,
static boolean static boolean
mips_elf_stub_section_p (abfd, section) mips_elf_stub_section_p (abfd, section)
bfd *abfd; bfd *abfd ATTRIBUTE_UNUSED;
asection *section; asection *section;
{ {
const char *name = bfd_get_section_name (abfd, section); const char *name = bfd_get_section_name (abfd, section);
@ -6463,7 +6487,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
/* For some kinds of relocations, the ADDEND is a /* For some kinds of relocations, the ADDEND is a
combination of the addend stored in two different combination of the addend stored in two different
relocations. */ relocations. */
if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16) if (r_type == R_MIPS_HI16
|| (r_type == R_MIPS_GOT16
&& mips_elf_local_relocation_p (input_bfd, rel,
local_sections)))
{ {
/* Scan ahead to find a matching R_MIPS_LO16 /* Scan ahead to find a matching R_MIPS_LO16
relocation. */ relocation. */
@ -6486,7 +6513,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
{ {
/* Used the saved HI16 addend. */ /* Used the saved HI16 addend. */
if (!last_hi16_addend_valid_p) if (!last_hi16_addend_valid_p)
return false; {
bfd_set_error (bfd_error_bad_value);
return false;
}
addend |= last_hi16_addend; addend |= last_hi16_addend;
} }
else if (r_type == R_MIPS16_GPREL) else if (r_type == R_MIPS16_GPREL)
@ -6533,7 +6563,9 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
continue; continue;
case bfd_reloc_undefined: case bfd_reloc_undefined:
return false; /* mips_elf_calculate_relocation already called the
undefined_symbol callback. */
break;
case bfd_reloc_notsupported: case bfd_reloc_notsupported:
abort (); abort ();
@ -6544,12 +6576,14 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
/* Ignore overflow until we reach the last relocation for /* Ignore overflow until we reach the last relocation for
a given location. */ a given location. */
; ;
else if (!name else
|| ! ((*info->callbacks->reloc_overflow) {
(info, name, howto->name, (bfd_vma) 0, BFD_ASSERT (name != NULL);
input_bfd, input_section, rel->r_offset))) if (! ((*info->callbacks->reloc_overflow)
return false; (info, name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset)))
return false;
}
break; break;
case bfd_reloc_ok: case bfd_reloc_ok: