* elfxx-mips.c (STUB_LI16): Removed.

(STUB_LUI): New macro.
	(STUB_LI16U): Ditto.
	(STUB_LI16S): Ditto.
	(MIPS_FUNCTION_STUB_SIZE): Rewrote to take info parameter.
	(_bfd_mips_elf_adjust_dynamic_symbol): Pass info parameter to
	MIPS_FUNCTION_STUB_SIZE.
	(_bfd_mips_elf_always_size_sections): Ditto.
	(_bfd_mips_elf_size_dynamic_sections): Ditto.
	(_bfd_mips_elf_finish_dynamic_sections): Ditto.
	(_bfd_mips_elf_finish_dynamic_symbol): Rewrote stub generation
	to allow larger symbol table indexes.
This commit is contained in:
David Daney
2006-06-08 23:51:25 +00:00
parent 99c81228e7
commit 3d6746cad8
2 changed files with 73 additions and 28 deletions

View File

@ -1,3 +1,18 @@
2006-06-08 David Daney <ddaney@avtrex.com>
* elfxx-mips.c (STUB_LI16): Removed.
(STUB_LUI): New macro.
(STUB_LI16U): Ditto.
(STUB_LI16S): Ditto.
(MIPS_FUNCTION_STUB_SIZE): Rewrote to take info parameter.
(_bfd_mips_elf_adjust_dynamic_symbol): Pass info parameter to
MIPS_FUNCTION_STUB_SIZE.
(_bfd_mips_elf_always_size_sections): Ditto.
(_bfd_mips_elf_size_dynamic_sections): Ditto.
(_bfd_mips_elf_finish_dynamic_sections): Ditto.
(_bfd_mips_elf_finish_dynamic_symbol): Rewrote stub generation
to allow larger symbol table indexes.
2006-06-07 Joseph S. Myers <joseph@codesourcery.com> 2006-06-07 Joseph S. Myers <joseph@codesourcery.com>
* po/Make-in (pdf, ps): New dummy targets. * po/Make-in (pdf, ps): New dummy targets.

View File

@ -631,12 +631,18 @@ static bfd *reldyn_sorting_bfd;
((ABI_64_P (abfd) \ ((ABI_64_P (abfd) \
? 0x03e0782d /* daddu t7,ra */ \ ? 0x03e0782d /* daddu t7,ra */ \
: 0x03e07821)) /* addu t7,ra */ : 0x03e07821)) /* addu t7,ra */
#define STUB_LUI(VAL) (0x3c180000 + (VAL)) /* lui t8,VAL */
#define STUB_JALR 0x0320f809 /* jalr t9,ra */ #define STUB_JALR 0x0320f809 /* jalr t9,ra */
#define STUB_LI16(abfd) \ #define STUB_LI16U(VAL) (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned*/
#define STUB_LI16S(abfd, VAL) \
((ABI_64_P (abfd) \ ((ABI_64_P (abfd) \
? 0x64180000 /* daddiu t8,zero,0 */ \ ? (0x64180000 + (VAL)) /* daddiu t8,zero,VAL sign extended */ \
: 0x24180000)) /* addiu t8,zero,0 */ : (0x24180000 + (VAL)))) /* addiu t8,zero,VAL sign extended */
#define MIPS_FUNCTION_STUB_SIZE (16)
#define MIPS_FUNCTION_STUB_SIZE(INFO) \
(elf_hash_table (INFO)->dynsymcount > 65536 ? 20 : 16)
#define MIPS_FUNCTION_STUB_MAX_SIZE 20
/* The name of the dynamic interpreter. This is put in the .interp /* The name of the dynamic interpreter. This is put in the .interp
section. */ section. */
@ -6877,7 +6883,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
h->plt.offset = s->size; h->plt.offset = s->size;
/* Make room for this stub code. */ /* Make room for this stub code. */
s->size += MIPS_FUNCTION_STUB_SIZE; s->size += MIPS_FUNCTION_STUB_SIZE (info);
/* The last half word of the stub will be filled with the index /* The last half word of the stub will be filled with the index
of this symbol in .dynsym section. */ of this symbol in .dynsym section. */
@ -7142,7 +7148,7 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
/* In the worst case, we'll get one stub per dynamic symbol, plus /* In the worst case, we'll get one stub per dynamic symbol, plus
one to account for the dummy entry at the end required by IRIX one to account for the dummy entry at the end required by IRIX
rld. */ rld. */
loadable_size += MIPS_FUNCTION_STUB_SIZE * (i + 1); loadable_size += MIPS_FUNCTION_STUB_SIZE (info) * (i + 1);
if (htab->is_vxworks) if (htab->is_vxworks)
/* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16 /* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
@ -7360,7 +7366,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
{ {
/* IRIX rld assumes that the function stub isn't at the end /* IRIX rld assumes that the function stub isn't at the end
of .text section. So put a dummy. XXX */ of .text section. So put a dummy. XXX */
s->size += MIPS_FUNCTION_STUB_SIZE; s->size += MIPS_FUNCTION_STUB_SIZE (info);
} }
else if (! info->shared else if (! info->shared
&& ! mips_elf_hash_table (info)->use_rld_obj_head && ! mips_elf_hash_table (info)->use_rld_obj_head
@ -7997,13 +8003,14 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
asection *sgot; asection *sgot;
struct mips_got_info *g, *gg; struct mips_got_info *g, *gg;
const char *name; const char *name;
int idx;
dynobj = elf_hash_table (info)->dynobj; dynobj = elf_hash_table (info)->dynobj;
if (h->plt.offset != MINUS_ONE) if (h->plt.offset != MINUS_ONE)
{ {
asection *s; asection *s;
bfd_byte stub[MIPS_FUNCTION_STUB_SIZE]; bfd_byte stub[MIPS_FUNCTION_STUB_MAX_SIZE];
/* This symbol has a stub. Set it up. */ /* This symbol has a stub. Set it up. */
@ -8013,18 +8020,41 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
MIPS_ELF_STUB_SECTION_NAME (dynobj)); MIPS_ELF_STUB_SECTION_NAME (dynobj));
BFD_ASSERT (s != NULL); BFD_ASSERT (s != NULL);
/* FIXME: Can h->dynindx be more than 64K? */ BFD_ASSERT ((MIPS_FUNCTION_STUB_SIZE (info) == 20)
if (h->dynindx & 0xffff0000) || (h->dynindx <= 65536));
/* Values up to 2^31 - 1 are allowed. Larger values would cause
sign extension at runtime in the stub, resulting in a
negative index value. */
if (h->dynindx & 0x80000000)
return FALSE; return FALSE;
/* Fill the stub. */ /* Fill the stub. */
bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub); idx = 0;
bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + 4); bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub + idx);
bfd_put_32 (output_bfd, STUB_JALR, stub + 8); idx += 4;
bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, stub + 12); bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
idx += 4;
if (MIPS_FUNCTION_STUB_SIZE (info) == 20)
{
bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16 ) & 0xffff),
stub + idx);
idx += 4;
}
bfd_put_32 (output_bfd, STUB_JALR, stub + idx);
idx += 4;
/* If a large stub is not required and sign extension is not a
problem, then use legacy code in the stub. */
if ((MIPS_FUNCTION_STUB_SIZE (info) == 20) || (h->dynindx & 0xffff8000))
bfd_put_32 (output_bfd, STUB_LI16U (h->dynindx & 0xffff), stub + idx);
else
bfd_put_32 (output_bfd,
STUB_LI16S (output_bfd, h->dynindx & 0xffff), stub + idx);
BFD_ASSERT (h->plt.offset <= s->size); BFD_ASSERT (h->plt.offset <= s->size);
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE); memcpy (s->contents + h->plt.offset,
stub, MIPS_FUNCTION_STUB_SIZE (info));
/* Mark the symbol as undefined. plt.offset != -1 occurs /* Mark the symbol as undefined. plt.offset != -1 occurs
only for the referenced symbol. */ only for the referenced symbol. */
@ -8827,10 +8857,10 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
{ {
file_ptr dummy_offset; file_ptr dummy_offset;
BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE); BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE (info));
dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE; dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE (info);
memset (s->contents + dummy_offset, 0, memset (s->contents + dummy_offset, 0,
MIPS_FUNCTION_STUB_SIZE); MIPS_FUNCTION_STUB_SIZE (info));
} }
} }
} }