This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] (version 2) Change MIPS linker stubs to allow for more than 2^15 symbols.
- From: Thiemo Seufer <ths at networkno dot de>
- To: David Daney <ddaney at avtrex dot com>, binutils at sourceware dot org, Daniel Jacobowitz <drow at false dot org>, richard at codesourcery dot com
- Date: Fri, 9 Jun 2006 16:46:20 +0100
- Subject: Re: [PATCH] (version 2) Change MIPS linker stubs to allow for more than 2^15 symbols.
- References: <4488A29D.5040100@avtrex.com> <87hd2ukeb2.fsf@talisman.home>
Richard Sandiford wrote:
> David Daney <ddaney@avtrex.com> writes:
> > ! #define MIPS_FUNCTION_STUB_SIZE(INFO) \
> > ! (elf_hash_table (INFO)->dynsymcount > 65536 ? 20 : 16)
>
> Sorry to be a pain, but as I said earlier, I really do think we should
> cache the chosen stub size in mips_elf_link_hash_table (and get rid of
> this macro entirely). That will emphasise that always_size_dynamic_sections
> is the place that makes the decision, and that it's only safe to use this
> value once that function has been called. I think that will be more robust
> and easier to understand in future.
>
> Apart from that, and from Thiemo's and Daniel's comments, this looks
> really good to me. Thanks a lot for doing this!
Does this followup patch look ok?
Thiemo
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.171
diff -u -p -r1.171 elfxx-mips.c
--- bfd/elfxx-mips.c 9 Jun 2006 13:47:41 -0000 1.171
+++ bfd/elfxx-mips.c 9 Jun 2006 15:42:47 -0000
@@ -335,6 +335,8 @@ struct mips_elf_link_hash_table
bfd_vma plt_header_size;
/* The size of a PLT entry in bytes (VxWorks only). */
bfd_vma plt_entry_size;
+ /* The size of a function stub entry in bytes. */
+ bfd_vma function_stub_size;
};
#define TLS_RELOC_P(r_type) \
@@ -633,16 +635,14 @@ static bfd *reldyn_sorting_bfd;
: 0x03e07821)) /* addu t7,ra */
#define STUB_LUI(VAL) (0x3c180000 + (VAL)) /* lui t8,VAL */
#define STUB_JALR 0x0320f809 /* jalr t9,ra */
-#define STUB_LI16U(VAL) (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned*/
+#define STUB_LI16U(VAL) (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned */
#define STUB_LI16S(abfd, VAL) \
((ABI_64_P (abfd) \
? (0x64180000 + (VAL)) /* daddiu t8,zero,VAL sign extended */ \
: (0x24180000 + (VAL)))) /* addiu t8,zero,VAL sign extended */
-#define MIPS_FUNCTION_STUB_SIZE(INFO) \
- (elf_hash_table (INFO)->dynsymcount > 65536 ? 20 : 16)
-
-#define MIPS_FUNCTION_STUB_MAX_SIZE 20
+#define MIPS_FUNCTION_STUB_NORMAL_SIZE 16
+#define MIPS_FUNCTION_STUB_BIG_SIZE 20
/* The name of the dynamic interpreter. This is put in the .interp
section. */
@@ -5930,6 +5930,9 @@ _bfd_mips_elf_create_dynamic_sections (b
|| ! bfd_set_section_alignment (abfd, s,
MIPS_ELF_LOG_FILE_ALIGN (abfd)))
return FALSE;
+ htab->function_stub_size = (elf_hash_table (info)->dynsymcount > 0xffff
+ ? MIPS_FUNCTION_STUB_BIG_SIZE
+ : MIPS_FUNCTION_STUB_NORMAL_SIZE);
}
if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
@@ -6832,7 +6835,9 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
bfd *dynobj;
struct mips_elf_link_hash_entry *hmips;
asection *s;
+ struct mips_elf_link_hash_table *htab;
+ htab = mips_elf_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
/* Make sure we know what is going on here. */
@@ -6885,7 +6890,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
h->plt.offset = s->size;
/* Make room for this stub code. */
- s->size += MIPS_FUNCTION_STUB_SIZE (info);
+ s->size += htab->function_stub_size;
/* The last half word of the stub will be filled with the index
of this symbol in .dynsym section. */
@@ -7150,7 +7155,7 @@ _bfd_mips_elf_always_size_sections (bfd
/* 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
rld. */
- loadable_size += MIPS_FUNCTION_STUB_SIZE (info) * (i + 1);
+ loadable_size += htab->function_stub_size * (i + 1);
if (htab->is_vxworks)
/* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
@@ -7367,14 +7372,14 @@ _bfd_mips_elf_size_dynamic_sections (bfd
else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
{
/* IRIX rld assumes that the function stub isn't at the end
- of .text section. So put a dummy. XXX */
- s->size += MIPS_FUNCTION_STUB_SIZE (info);
+ of .text section. So put a dummy. XXX */
+ s->size += htab->function_stub_size;
}
else if (! info->shared
&& ! mips_elf_hash_table (info)->use_rld_obj_head
&& strncmp (name, ".rld_map", 8) == 0)
{
- /* 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. */
s->size += 4;
}
@@ -8006,13 +8011,15 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
struct mips_got_info *g, *gg;
const char *name;
int idx;
+ struct mips_elf_link_hash_table *htab;
+ htab = mips_elf_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
if (h->plt.offset != MINUS_ONE)
{
asection *s;
- bfd_byte stub[MIPS_FUNCTION_STUB_MAX_SIZE];
+ bfd_byte stub[MIPS_FUNCTION_STUB_BIG_SIZE];
/* This symbol has a stub. Set it up. */
@@ -8022,13 +8029,13 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
MIPS_ELF_STUB_SECTION_NAME (dynobj));
BFD_ASSERT (s != NULL);
- BFD_ASSERT ((MIPS_FUNCTION_STUB_SIZE (info) == 20)
- || (h->dynindx <= 65536));
+ BFD_ASSERT ((htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
+ || (h->dynindx <= 0xffff));
/* 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)
+ sign extension at runtime in the stub, resulting in a negative
+ index value. */
+ if (h->dynindx & ~0x7fffffff)
return FALSE;
/* Fill the stub. */
@@ -8037,9 +8044,9 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
idx += 4;
bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
idx += 4;
- if (MIPS_FUNCTION_STUB_SIZE (info) == 20)
+ if (htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
{
- bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16 ) & 0xffff),
+ bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16) & 0x7fff),
stub + idx);
idx += 4;
}
@@ -8048,15 +8055,15 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
/* 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))
+ if ((htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
+ || (h->dynindx & ~0x7fff))
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_put_32 (output_bfd, STUB_LI16S (output_bfd, h->dynindx),
+ stub + idx);
+
BFD_ASSERT (h->plt.offset <= s->size);
- memcpy (s->contents + h->plt.offset,
- stub, MIPS_FUNCTION_STUB_SIZE (info));
+ memcpy (s->contents + h->plt.offset, stub, htab->function_stub_size);
/* Mark the symbol as undefined. plt.offset != -1 occurs
only for the referenced symbol. */
@@ -8859,10 +8866,10 @@ _bfd_mips_elf_finish_dynamic_sections (b
{
file_ptr dummy_offset;
- BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE (info));
- dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE (info);
+ BFD_ASSERT (s->size >= htab->function_stub_size);
+ dummy_offset = s->size - htab->function_stub_size;
memset (s->contents + dummy_offset, 0,
- MIPS_FUNCTION_STUB_SIZE (info));
+ htab->function_stub_size);
}
}
}
@@ -9974,6 +9981,7 @@ _bfd_mips_elf_link_hash_table_create (bf
ret->splt = NULL;
ret->plt_header_size = 0;
ret->plt_entry_size = 0;
+ ret->function_stub_size = 0;
return &ret->root.root;
}