* reloc.c (BFD_RELOC_MIPS16_GOT16, BFD_RELOC_MIPS16_CALL16): Declare.
	* libbfd.h, bfd-in2.h: Regenerate.
	* elf32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
	R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
	(mips16_reloc_map): Add mappings.
	* elf64-mips.c (mips16_elf64_howto_table_rel): Fill in reserved
	R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
	(mips16_elf64_howto_table_rela): Likewise.
	(mips16_reloc_map): Add mappings.
	* elfn32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
	R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
	(elf_mips16_howto_table_rela): Likewise.
	(mips16_reloc_map): Add mappings.
	* elfxx-mips.c (mips_elf_create_shadow_symbol): New function.
	(section_allows_mips16_refs_p): Likewise.
	(mips16_stub_symndx): Likewise.
	(mips_elf_check_mips16_stubs): Treat the data argument as a
	bfd_link_info.  Mark every dynamic symbol as needing MIPS16 stubs
	and create a "shadow" symbol for the original MIPS16 definition.
	(mips16_reloc_p, got16_reloc_p, call16_reloc_p, hi16_reloc_p)
	(lo16_reloc_p, mips16_call_reloc_p): New functions.
	(_bfd_mips16_elf_reloc_unshuffle): Use mips16_reloc_p to generalize
	relocation checks.
	(_bfd_mips16_elf_reloc_shuffle): Likewise.
	(_bfd_mips_elf_lo16_reloc): Handle R_MIPS16_GOT16.
	(mips_elf_got16_entry): Add comment.
	(mips_elf_calculate_relocation): Use hi16_reloc_p,
	lo16_reloc_p, mips16_call_reloc_p, call16_reloc_p and got16_reloc_p
	to generalize relocation checks.  Use section_allows_mips16_refs_p
	instead of mips16_stub_section_p.   Handle R_MIPS16_CALL16 and
	R_MIPS16_GOT16, allowing the former to refer directly to a
	MIPS16 function if its stub is not needed.
	(mips16_stub_section_p): Delete.
	(_bfd_mips_elf_symbol_processing): Convert odd-valued function
	symbols into even MIPS16 symbols.
	(mips_elf_add_lo16_rel_addend): Use mips16_reloc_p to generalize
	a relocation check.
	(_bfd_mips_elf_check_relocs): Calculate "bed" and "rel_end"
	earlier in the function.  Use mips16_stub_symndx to identify
	the target function.  Avoid out-of-bounds accesses when the
	stub has no relocations; report an error instead.  Use
	section_allows_mips16_refs_p instead of mips16_stub_section_p.
	Use mips16_call_reloc_p and got16_reloc_p to generalize relocation
	checks.  Handle R_MIPS16_CALL16 and R_MIPS16_GOT16.  Don't create
	dynamic relocations for absolute references to __gnu_local_gp.
	(_bfd_mips_elf_always_size_sections): Pass a bfd_link_info as
	the argument to mips_elf_check_mips16_stubs.  Generalize comment.
	(_bfd_mips_elf_relocate_section): Use hi16_reloc_p and got16_reloc_p
	to generalize relocation checks.
	(_bfd_mips_elf_finish_dynamic_symbol): If a dynamic MIPS16 function
	symbol has a non-MIPS16 stub, redirect the symbol to the stub.
	Fix an overly long line.  Don't give dynamic symbols type STO_MIPS16.
	(_bfd_mips_elf_gc_sweep_hook): Handle R_MIPS16_CALL16 and
	R_MIPS16_GOT16.

gas/
	* config/tc-mips.c (mips16_reloc_p, got16_reloc_p, hi16_reloc_p)
	(lo16_reloc_p): New functions.
	(reloc_needs_lo_p): Use hi16_reloc_p and got16_reloc_p to
	generalize relocation checks.
	(matching_lo_reloc): New function.
	(fixup_has_matching_lo_p): Use it.
	(mips16_mark_labels): Don't clobber a symbol's visibility.
	(append_insn): Use hi16_reloc_p and lo16_reloc_p.
	(mips16_ip): Handle BFD_RELOC_MIPS16_GOT16 and BFD_RELOC_MIPS16_CALL16.
	(md_apply_fix): Likewise.
	(mips16_percent_op): Add %got and %call16.
	(mips_frob_file): Use got16_reloc_p to generalize relocation checks.
	Use matching_lo_reloc.
	(mips_force_relocation): Use hi16_reloc_p and lo16_reloc_p to
	generalize relocation checks.
	(mips_fix_adjustable): Use lo16_reloc_p to generalize relocation
	checks.

gas/testsuite/
	* gas/mips/elf-rel8-mips16.d, gas/mips/elf-rel8-mips16.s,
	* gas/mips/elf-rel9-mips16.d, gas/mips/elf-rel9-mips16.s,
	* gas/mips/elf-rel13-mips16.d, gas/mips/elf-rel13-mips16.s: New tests.
	* gas/mips/mips.exp: Run them.

ld/testsuite/
	* ld-mips-elf/mips16-local-stubs-1.d: Remove stub_for_h3,
	which was only referenced by the .pdr section, and was not
	actually needed by code.
	* ld-mips-elf/mips16-intermix.d: Remove unused static function stubs.
	* ld-mips-elf/mips16-pic-1a.s,
	ld-mips-elf/mips16-pic-1b.s,
	ld-mips-elf/mips16-pic-1-dummy.s,
	ld-mips-elf/mips16-pic-1.dd,
	ld-mips-elf/mips16-pic-1.gd,
	ld-mips-elf/mips16-pic-1.inc,
	ld-mips-elf/mips16-pic-1.ld,
	ld-mips-elf/mips16-pic-2a.s,
	ld-mips-elf/mips16-pic-2b.s,
	ld-mips-elf/mips16-pic-2.ad,
	ld-mips-elf/mips16-pic-2.dd,
	ld-mips-elf/mips16-pic-2.gd,
	ld-mips-elf/mips16-pic-2.nd,
	ld-mips-elf/mips16-pic-2.rd: New tests.
	* ld-mips-elf/mips-elf.exp: Run them.
This commit is contained in:
Richard Sandiford 2008-08-06 19:44:47 +00:00
parent d57a3c85f6
commit 738e53487d
36 changed files with 2862 additions and 145 deletions

View file

@ -1,3 +1,60 @@
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
* reloc.c (BFD_RELOC_MIPS16_GOT16, BFD_RELOC_MIPS16_CALL16): Declare.
* libbfd.h, bfd-in2.h: Regenerate.
* elf32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
(mips16_reloc_map): Add mappings.
* elf64-mips.c (mips16_elf64_howto_table_rel): Fill in reserved
R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
(mips16_elf64_howto_table_rela): Likewise.
(mips16_reloc_map): Add mappings.
* elfn32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
(elf_mips16_howto_table_rela): Likewise.
(mips16_reloc_map): Add mappings.
* elfxx-mips.c (mips_elf_create_shadow_symbol): New function.
(section_allows_mips16_refs_p): Likewise.
(mips16_stub_symndx): Likewise.
(mips_elf_check_mips16_stubs): Treat the data argument as a
bfd_link_info. Mark every dynamic symbol as needing MIPS16 stubs
and create a "shadow" symbol for the original MIPS16 definition.
(mips16_reloc_p, got16_reloc_p, call16_reloc_p, hi16_reloc_p)
(lo16_reloc_p, mips16_call_reloc_p): New functions.
(_bfd_mips16_elf_reloc_unshuffle): Use mips16_reloc_p to generalize
relocation checks.
(_bfd_mips16_elf_reloc_shuffle): Likewise.
(_bfd_mips_elf_lo16_reloc): Handle R_MIPS16_GOT16.
(mips_elf_got16_entry): Add comment.
(mips_elf_calculate_relocation): Use hi16_reloc_p,
lo16_reloc_p, mips16_call_reloc_p, call16_reloc_p and got16_reloc_p
to generalize relocation checks. Use section_allows_mips16_refs_p
instead of mips16_stub_section_p. Handle R_MIPS16_CALL16 and
R_MIPS16_GOT16, allowing the former to refer directly to a
MIPS16 function if its stub is not needed.
(mips16_stub_section_p): Delete.
(_bfd_mips_elf_symbol_processing): Convert odd-valued function
symbols into even MIPS16 symbols.
(mips_elf_add_lo16_rel_addend): Use mips16_reloc_p to generalize
a relocation check.
(_bfd_mips_elf_check_relocs): Calculate "bed" and "rel_end"
earlier in the function. Use mips16_stub_symndx to identify
the target function. Avoid out-of-bounds accesses when the
stub has no relocations; report an error instead. Use
section_allows_mips16_refs_p instead of mips16_stub_section_p.
Use mips16_call_reloc_p and got16_reloc_p to generalize relocation
checks. Handle R_MIPS16_CALL16 and R_MIPS16_GOT16. Don't create
dynamic relocations for absolute references to __gnu_local_gp.
(_bfd_mips_elf_always_size_sections): Pass a bfd_link_info as
the argument to mips_elf_check_mips16_stubs. Generalize comment.
(_bfd_mips_elf_relocate_section): Use hi16_reloc_p and got16_reloc_p
to generalize relocation checks.
(_bfd_mips_elf_finish_dynamic_symbol): If a dynamic MIPS16 function
symbol has a non-MIPS16 stub, redirect the symbol to the stub.
Fix an overly long line. Don't give dynamic symbols type STO_MIPS16.
(_bfd_mips_elf_gc_sweep_hook): Handle R_MIPS16_CALL16 and
R_MIPS16_GOT16.
2008-08-06 Alan Modra <amodra@bigpond.net.au>
* elf32-ppc.c (ppc_elf_relax_section): Clear R_PPC_PLTREL24 addend.

View file

@ -2604,6 +2604,11 @@ to compensate for the borrow when the low bits are added. */
/* Low 16 bits of pc-relative value */
BFD_RELOC_LO16_PCREL,
/* Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
16-bit immediate fields */
BFD_RELOC_MIPS16_GOT16,
BFD_RELOC_MIPS16_CALL16,
/* MIPS16 high 16 bits of 32-bit value. */
BFD_RELOC_MIPS16_HI16,

View file

@ -771,11 +771,35 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 reference to global offset table. */
EMPTY_HOWTO (R_MIPS16_GOT16),
/* A MIPS16 reference to the global offset table. */
HOWTO (R_MIPS16_GOT16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS16_GOT16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 16 bit call through global offset table. */
EMPTY_HOWTO (R_MIPS16_CALL16),
/* A MIPS16 call through the global offset table. */
HOWTO (R_MIPS16_CALL16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_CALL16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* MIPS16 high 16 bits of symbol value. */
HOWTO (R_MIPS16_HI16, /* type */
@ -1224,6 +1248,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
{
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
};

View file

@ -1503,11 +1503,35 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 reference to global offset table. */
EMPTY_HOWTO (R_MIPS16_GOT16),
/* A MIPS16 reference to the global offset table. */
HOWTO (R_MIPS16_GOT16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS16_GOT16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 16 bit call through global offset table. */
EMPTY_HOWTO (R_MIPS16_CALL16),
/* A MIPS16 call through the global offset table. */
HOWTO (R_MIPS16_CALL16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_CALL16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* MIPS16 high 16 bits of symbol value. */
HOWTO (R_MIPS16_HI16, /* type */
@ -1575,11 +1599,35 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 reference to global offset table. */
EMPTY_HOWTO (R_MIPS16_GOT16),
/* A MIPS16 reference to the global offset table. */
HOWTO (R_MIPS16_GOT16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS16_GOT16", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 16 bit call through global offset table. */
EMPTY_HOWTO (R_MIPS16_CALL16),
/* A MIPS16 call through the global offset table. */
HOWTO (R_MIPS16_CALL16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_CALL16", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* MIPS16 high 16 bits of symbol value. */
HOWTO (R_MIPS16_HI16, /* type */
@ -2197,6 +2245,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
{
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
};

View file

@ -1496,11 +1496,35 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 reference to global offset table. */
EMPTY_HOWTO (R_MIPS16_GOT16),
/* A MIPS16 reference to the global offset table. */
HOWTO (R_MIPS16_GOT16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS16_GOT16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 16 bit call through global offset table. */
EMPTY_HOWTO (R_MIPS16_CALL16),
/* A MIPS16 call through the global offset table. */
HOWTO (R_MIPS16_CALL16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_CALL16", /* name */
TRUE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* MIPS16 high 16 bits of symbol value. */
HOWTO (R_MIPS16_HI16, /* type */
@ -1568,11 +1592,35 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 reference to global offset table. */
EMPTY_HOWTO (R_MIPS16_GOT16),
/* A MIPS16 reference to the global offset table. */
HOWTO (R_MIPS16_GOT16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS16_GOT16", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A placeholder for MIPS16 16 bit call through global offset table. */
EMPTY_HOWTO (R_MIPS16_CALL16),
/* A MIPS16 call through the global offset table. */
HOWTO (R_MIPS16_CALL16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_CALL16", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* MIPS16 high 16 bits of symbol value. */
HOWTO (R_MIPS16_HI16, /* type */
@ -2041,6 +2089,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
{
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
{ BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
{ BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
};

View file

@ -525,8 +525,6 @@ static bfd_boolean mips_elf_sort_hash_table_f
(struct mips_elf_link_hash_entry *, void *);
static bfd_vma mips_elf_high
(bfd_vma);
static bfd_boolean mips16_stub_section_p
(bfd *, asection *);
static bfd_boolean mips_elf_create_dynamic_relocation
(bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
struct mips_elf_link_hash_entry *, asection *, bfd_vma,
@ -1148,17 +1146,104 @@ mips_elf_create_procedure_table (void *handle, bfd *abfd,
free (sv);
return FALSE;
}
/* We're about to redefine H. Create a symbol to represent H's
current value and size, to help make the disassembly easier
to read. */
static bfd_boolean
mips_elf_create_shadow_symbol (struct bfd_link_info *info,
struct mips_elf_link_hash_entry *h,
const char *prefix)
{
struct bfd_link_hash_entry *bh;
struct elf_link_hash_entry *elfh;
const char *name;
asection *s;
bfd_vma value;
/* Read the symbol's value. */
BFD_ASSERT (h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak);
s = h->root.root.u.def.section;
value = h->root.root.u.def.value;
/* Create a new symbol. */
name = ACONCAT ((prefix, h->root.root.root.string, NULL));
bh = NULL;
if (!_bfd_generic_link_add_one_symbol (info, s->owner, name,
BSF_LOCAL, s, value, NULL,
TRUE, FALSE, &bh))
return FALSE;
/* Make it local and copy the other attributes from H. */
elfh = (struct elf_link_hash_entry *) bh;
elfh->type = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (h->root.type));
elfh->other = h->root.other;
elfh->size = h->root.size;
elfh->forced_local = 1;
return TRUE;
}
/* Return TRUE if relocations in SECTION can refer directly to a MIPS16
function rather than to a hard-float stub. */
static bfd_boolean
section_allows_mips16_refs_p (asection *section)
{
const char *name;
name = bfd_get_section_name (section->owner, section);
return (FN_STUB_P (name)
|| CALL_STUB_P (name)
|| CALL_FP_STUB_P (name)
|| strcmp (name, ".pdr") == 0);
}
/* [RELOCS, RELEND) are the relocations against SEC, which is a MIPS16
stub section of some kind. Return the R_SYMNDX of the target
function, or 0 if we can't decide which function that is. */
static unsigned long
mips16_stub_symndx (asection *sec, const Elf_Internal_Rela *relocs,
const Elf_Internal_Rela *relend)
{
const Elf_Internal_Rela *rel;
/* Trust the first R_MIPS_NONE relocation, if any. */
for (rel = relocs; rel < relend; rel++)
if (ELF_R_TYPE (sec->owner, rel->r_info) == R_MIPS_NONE)
return ELF_R_SYM (sec->owner, rel->r_info);
/* Otherwise trust the first relocation, whatever its kind. This is
the traditional behavior. */
if (relocs < relend)
return ELF_R_SYM (sec->owner, relocs->r_info);
return 0;
}
/* Check the mips16 stubs for a particular symbol, and see if we can
discard them. */
static bfd_boolean
mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
void *data ATTRIBUTE_UNUSED)
mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h, void *data)
{
struct bfd_link_info *info;
info = (struct bfd_link_info *) data;
if (h->root.root.type == bfd_link_hash_warning)
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
/* Dynamic symbols must use the standard call interface, in case other
objects try to call them. */
if (h->fn_stub != NULL
&& h->root.dynindx != -1)
{
mips_elf_create_shadow_symbol (info, h, ".mips16.");
h->need_fn_stub = TRUE;
}
if (h->fn_stub != NULL
&& ! h->need_fn_stub)
{
@ -1257,8 +1342,18 @@ mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff)
R_MIPS16_GPREL is used for GP-relative addressing in mips16
mode. A typical instruction will have a format like this:
The table below lists the other MIPS16 instruction relocations.
Each one is calculated in the same way as the non-MIPS16 relocation
given on the right, but using the extended MIPS16 layout of 16-bit
immediate fields:
R_MIPS16_GPREL R_MIPS_GPREL16
R_MIPS16_GOT16 R_MIPS_GOT16
R_MIPS16_CALL16 R_MIPS_CALL16
R_MIPS16_HI16 R_MIPS_HI16
R_MIPS16_LO16 R_MIPS_LO16
A typical instruction will have a format like this:
+--------------+--------------------------------+
| EXTEND | Imm 10:5 | Imm 15:11 |
@ -1269,28 +1364,65 @@ mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
EXTEND is the five bit value 11110. Major is the instruction
opcode.
This is handled exactly like R_MIPS_GPREL16, except that the
addend is retrieved and stored as shown in this diagram; that
is, the Imm fields above replace the V-rel16 field.
All we need to do here is shuffle the bits appropriately.
As above, the two 16-bit halves must be swapped on a
little-endian system. */
All we need to do here is shuffle the bits appropriately. As
above, the two 16-bit halves must be swapped on a
little-endian system.
static inline bfd_boolean
mips16_reloc_p (int r_type)
{
switch (r_type)
{
case R_MIPS16_26:
case R_MIPS16_GPREL:
case R_MIPS16_GOT16:
case R_MIPS16_CALL16:
case R_MIPS16_HI16:
case R_MIPS16_LO16:
return TRUE;
default:
return FALSE;
}
}
static inline bfd_boolean
got16_reloc_p (int r_type)
{
return r_type == R_MIPS_GOT16 || r_type == R_MIPS16_GOT16;
}
static inline bfd_boolean
call16_reloc_p (int r_type)
{
return r_type == R_MIPS_CALL16 || r_type == R_MIPS16_CALL16;
}
static inline bfd_boolean
hi16_reloc_p (int r_type)
{
return r_type == R_MIPS_HI16 || r_type == R_MIPS16_HI16;
}
static inline bfd_boolean
lo16_reloc_p (int r_type)
{
return r_type == R_MIPS_LO16 || r_type == R_MIPS16_LO16;
}
static inline bfd_boolean
mips16_call_reloc_p (int r_type)
{
return r_type == R_MIPS16_26 || r_type == R_MIPS16_CALL16;
}
R_MIPS16_HI16 and R_MIPS16_LO16 are used in mips16 mode to
access data when neither GP-relative nor PC-relative addressing
can be used. They are handled like R_MIPS_HI16 and R_MIPS_LO16,
except that the addend is retrieved and stored as shown above
for R_MIPS16_GPREL.
*/
void
_bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type,
bfd_boolean jal_shuffle, bfd_byte *data)
{
bfd_vma extend, insn, val;
if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
if (!mips16_reloc_p (r_type))
return;
/* Pick up the mips16 extend instruction and the real instruction. */
@ -1316,8 +1448,7 @@ _bfd_mips16_elf_reloc_shuffle (bfd *abfd, int r_type,
{
bfd_vma extend, insn, val;
if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
if (!mips16_reloc_p (r_type))
return;
val = bfd_get_32 (abfd, data);
@ -1446,7 +1577,7 @@ _bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
return bfd_reloc_ok;
}
/* A howto special_function for REL R_MIPS_GOT16 relocations. This is just
/* A howto special_function for REL R_MIPS*_GOT16 relocations. This is just
like any other 16-bit relocation when applied to global symbols, but is
treated in the same as R_MIPS_HI16 when applied to local symbols. */
@ -1495,13 +1626,15 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
hi = mips_hi16_list;
/* R_MIPS_GOT16 relocations are something of a special case. We
want to install the addend in the same way as for a R_MIPS_HI16
/* R_MIPS*_GOT16 relocations are something of a special case. We
want to install the addend in the same way as for a R_MIPS*_HI16
relocation (with a rightshift of 16). However, since GOT16
relocations can also be used with global symbols, their howto
has a rightshift of 0. */
if (hi->rel.howto->type == R_MIPS_GOT16)
hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);
else if (hi->rel.howto->type == R_MIPS16_GOT16)
hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS16_HI16, FALSE);
/* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any
carry or borrow will induce a change of +1 or -1 in the high part. */
@ -2620,7 +2753,7 @@ mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
return index;
}
/* Find a local GOT entry for an R_MIPS_GOT16 relocation against VALUE.
/* Find a local GOT entry for an R_MIPS*_GOT16 relocation against VALUE.
EXTERNAL is true if the relocation was against a global symbol
that has been forced local. */
@ -2641,6 +2774,9 @@ mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
/* It doesn't matter whether the original relocation was R_MIPS_GOT16,
R_MIPS16_GOT16, R_MIPS_CALL16, etc. The format of the entry is the
same in all cases. */
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
value, 0, NULL, R_MIPS_GOT16);
if (entry)
@ -4216,8 +4352,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
{
/* Relocations against _gp_disp are permitted only with
R_MIPS_HI16 and R_MIPS_LO16 relocations. */
if (r_type != R_MIPS_HI16 && r_type != R_MIPS_LO16
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
if (!hi16_reloc_p (r_type) && !lo16_reloc_p (r_type))
return bfd_reloc_notsupported;
gp_disp_p = TRUE;
@ -4291,15 +4426,24 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
}
/* If this is a 32- or 64-bit call to a 16-bit function with a stub, we
need to redirect the call to the stub, unless we're already *in*
a stub. */
if (r_type != R_MIPS16_26 && !info->relocatable
&& ((h != NULL && h->fn_stub != NULL)
/* If this is a reference to a 16-bit function with a stub, we need
to redirect the relocation to the stub unless:
(a) the relocation is for a MIPS16 JAL;
(b) the relocation is for a MIPS16 PIC call, and there are no
non-MIPS16 uses of the GOT slot; or
(c) the section allows direct references to MIPS16 functions. */
if (r_type != R_MIPS16_26
&& !info->relocatable
&& ((h != NULL
&& h->fn_stub != NULL
&& (r_type != R_MIPS16_CALL16 || h->need_fn_stub))
|| (local_p
&& elf_tdata (input_bfd)->local_stubs != NULL
&& elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
&& !mips16_stub_section_p (input_bfd, input_section))
&& !section_allows_mips16_refs_p (input_section))
{
/* This is a 32- or 64-bit call to a 16-bit function. We should
have already noticed that we were going to need the
@ -4317,7 +4461,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
target_is_16_bit_code_p = FALSE;
}
/* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
need to redirect the call to the stub. */
need to redirect the call to the stub. Note that we specifically
exclude R_MIPS16_CALL16 from this behavior; indirect calls should
use an indirect stub instead. */
else if (r_type == R_MIPS16_26 && !info->relocatable
&& ((h != NULL && (h->call_stub != NULL || h->call_fp_stub != NULL))
|| (local_p
@ -4389,6 +4535,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
break;
/* Fall through. */
case R_MIPS16_CALL16:
case R_MIPS16_GOT16:
case R_MIPS_CALL16:
case R_MIPS_GOT16:
case R_MIPS_GOT_DISP:
@ -4414,7 +4562,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
if (htab->is_vxworks
&& (r_type == R_MIPS_CALL_HI16
|| r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_CALL16))
|| call16_reloc_p (r_type)))
{
BFD_ASSERT (addend == 0);
BFD_ASSERT (h->root.needs_plt);
@ -4444,7 +4592,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
}
}
else if (!htab->is_vxworks
&& (r_type == R_MIPS_CALL16 || (r_type == R_MIPS_GOT16)))
&& (call16_reloc_p (r_type) || got16_reloc_p (r_type)))
/* The calculation below does not involve "g". */
break;
else
@ -4674,10 +4822,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
overflowed_p = mips_elf_overflow_p (value, 16);
break;
case R_MIPS16_GOT16:
case R_MIPS16_CALL16:
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* VxWorks does not have separate local and global semantics for
R_MIPS_GOT16; every relocation evaluates to "G". */
R_MIPS*_GOT16; every relocation evaluates to "G". */
if (!htab->is_vxworks && local_p)
{
bfd_boolean forced;
@ -4921,16 +5071,6 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
return TRUE;
}
/* Returns TRUE if SECTION is a MIPS16 stub section. */
static bfd_boolean
mips16_stub_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
{
const char *name = bfd_get_section_name (abfd, section);
return FN_STUB_P (name) || CALL_STUB_P (name) || CALL_FP_STUB_P (name);
}
/* Add room for N relocations to the .rel(a).dyn section in ABFD. */
@ -5312,14 +5452,14 @@ static asection mips_elf_acom_section;
static asymbol mips_elf_acom_symbol;
static asymbol *mips_elf_acom_symbol_ptr;
/* Handle the special MIPS section numbers that a symbol may use.
This is used for both the 32-bit and the 64-bit ABI. */
/* This is used for both the 32-bit and the 64-bit ABI. */
void
_bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
{
elf_symbol_type *elfsym;
/* Handle the special MIPS section numbers that a symbol may use. */
elfsym = (elf_symbol_type *) asym;
switch (elfsym->internal_elf_sym.st_shndx)
{
@ -5407,6 +5547,15 @@ _bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
}
break;
}
/* If this is an odd-valued function symbol, assume it's a MIPS16 one. */
if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_FUNC
&& (asym->value & 1) != 0)
{
asym->value--;
elfsym->internal_elf_sym.st_other
= ELF_ST_SET_MIPS16 (elfsym->internal_elf_sym.st_other);
}
}
/* Implement elf_backend_eh_frame_address_size. This differs from
@ -6401,7 +6550,7 @@ mips_elf_add_lo16_rel_addend (bfd *abfd,
bfd_vma l;
r_type = ELF_R_TYPE (abfd, rel->r_info);
if (r_type == R_MIPS16_HI16)
if (mips16_reloc_p (r_type))
lo16_type = R_MIPS16_LO16;
else
lo16_type = R_MIPS_LO16;
@ -6491,6 +6640,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
sym_hashes = elf_sym_hashes (abfd);
extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
bed = get_elf_backend_data (abfd);
rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
/* Check for the mips16 stub sections. */
name = bfd_get_section_name (abfd, sec);
@ -6501,7 +6653,16 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* Look at the relocation information to figure out which symbol
this is for. */
r_symndx = ELF_R_SYM (abfd, relocs->r_info);
r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
if (r_symndx == 0)
{
(*_bfd_error_handler)
(_("%B: Warning: cannot determine the target function for"
" stub section `%s'"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if (r_symndx < extsymoff
|| sym_hashes[r_symndx - extsymoff] == NULL)
@ -6519,7 +6680,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* We can ignore stub sections when looking for relocs. */
if ((o->flags & SEC_RELOC) == 0
|| o->reloc_count == 0
|| mips16_stub_section_p (abfd, o))
|| section_allows_mips16_refs_p (o))
continue;
sec_relocs
@ -6531,7 +6692,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
rend = sec_relocs + o->reloc_count;
for (r = sec_relocs; r < rend; r++)
if (ELF_R_SYM (abfd, r->r_info) == r_symndx
&& ELF_R_TYPE (abfd, r->r_info) != R_MIPS16_26)
&& !mips16_call_reloc_p (ELF_R_TYPE (abfd, r->r_info)))
break;
if (elf_section_data (o)->relocs != sec_relocs)
@ -6617,7 +6778,16 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* Look at the relocation information to figure out which symbol
this is for. */
r_symndx = ELF_R_SYM (abfd, relocs->r_info);
r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
if (r_symndx == 0)
{
(*_bfd_error_handler)
(_("%B: Warning: cannot determine the target function for"
" stub section `%s'"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if (r_symndx < extsymoff
|| sym_hashes[r_symndx - extsymoff] == NULL)
@ -6635,7 +6805,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* We can ignore stub sections when looking for relocs. */
if ((o->flags & SEC_RELOC) == 0
|| o->reloc_count == 0
|| mips16_stub_section_p (abfd, o))
|| section_allows_mips16_refs_p (o))
continue;
sec_relocs
@ -6743,8 +6913,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
}
sreloc = NULL;
bed = get_elf_backend_data (abfd);
rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
contents = NULL;
for (rel = relocs; rel < rel_end; ++rel)
{
@ -6782,6 +6950,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
{
switch (r_type)
{
case R_MIPS16_GOT16:
case R_MIPS16_CALL16:
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_CALL_HI16:
@ -6851,13 +7021,13 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
else if (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
|| r_type == R_MIPS_GOT_DISP
|| (r_type == R_MIPS_GOT16 && htab->is_vxworks))
|| (got16_reloc_p (r_type) && htab->is_vxworks))
{
/* We may need a local GOT entry for this relocation. We
don't count R_MIPS_GOT_PAGE because we can estimate the
maximum number of pages needed by looking at the size of
the segment. Similar comments apply to R_MIPS_GOT16 and
R_MIPS_CALL16, except on VxWorks, where GOT relocations
the segment. Similar comments apply to R_MIPS*_GOT16 and
R_MIPS*_CALL16, except on VxWorks, where GOT relocations
always evaluate to "G". We don't count R_MIPS_GOT_HI16, or
R_MIPS_CALL_HI16 because these are always followed by an
R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. */
@ -6869,6 +7039,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
switch (r_type)
{
case R_MIPS_CALL16:
case R_MIPS16_CALL16:
if (h == NULL)
{
(*_bfd_error_handler)
@ -6919,6 +7090,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
}
/* Fall through. */
case R_MIPS16_GOT16:
case R_MIPS_GOT16:
case R_MIPS_GOT_HI16:
case R_MIPS_GOT_LO16:
@ -7003,6 +7175,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
are handled using copy relocs or PLT stubs, so there's
no need to add a .rela.dyn entry for this relocation. */
if ((info->shared || (h != NULL && !htab->is_vxworks))
&& !(h && strcmp (h->root.root.string, "__gnu_local_gp") == 0)
&& (sec->flags & SEC_ALLOC) != 0)
{
if (sreloc == NULL)
@ -7116,6 +7289,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
default:
((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE;
break;
case R_MIPS16_CALL16:
case R_MIPS_CALL16:
case R_MIPS_CALL_HI16:
case R_MIPS_CALL_LO16:
@ -7123,12 +7297,13 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
}
/* If this reloc is not a 16 bit call, and it has a global
symbol, then we will need the fn_stub if there is one.
References from a stub section do not count. */
/* See if this reloc would need to refer to a MIPS16 hard-float stub,
if there is one. We only need to handle global symbols here;
we decide whether to keep or delete stubs for local symbols
when processing the stub's relocations. */
if (h != NULL
&& r_type != R_MIPS16_26
&& !mips16_stub_section_p (abfd, sec))
&& !mips16_call_reloc_p (r_type)
&& !section_allows_mips16_refs_p (sec))
{
struct mips_elf_link_hash_entry *mh;
@ -7638,7 +7813,7 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
if (! (info->relocatable
|| ! mips_elf_hash_table (info)->mips16_stubs_seen))
mips_elf_link_hash_traverse (mips_elf_hash_table (info),
mips_elf_check_mips16_stubs, NULL);
mips_elf_check_mips16_stubs, info);
dynobj = elf_hash_table (info)->dynobj;
if (dynobj == NULL)
@ -7700,7 +7875,7 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
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
/* There's no need to allocate page entries for VxWorks; R_MIPS*_GOT16
relocations against local symbols evaluate to "G", and the EABI does
not include R_MIPS_GOT_PAGE. */
page_gotno = 0;
@ -8248,9 +8423,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
rela_relocation_p = FALSE;
addend = mips_elf_read_rel_addend (input_bfd, rel,
howto, contents);
if (r_type == R_MIPS_HI16
|| r_type == R_MIPS16_HI16
|| (r_type == R_MIPS_GOT16
if (hi16_reloc_p (r_type)
|| (got16_reloc_p (r_type)
&& mips_elf_local_relocation_p (input_bfd, rel,
local_sections, FALSE)))
{
@ -8289,8 +8463,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (!rela_relocation_p && rel->r_addend)
{
addend += rel->r_addend;
if (r_type == R_MIPS_HI16
|| r_type == R_MIPS_GOT16)
if (hi16_reloc_p (r_type) || got16_reloc_p (r_type))
addend = mips_elf_high (addend);
else if (r_type == R_MIPS_HIGHER)
addend = mips_elf_higher (addend);
@ -8555,9 +8728,11 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
const char *name;
int idx;
struct mips_elf_link_hash_table *htab;
struct mips_elf_link_hash_entry *hmips;
htab = mips_elf_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
hmips = (struct mips_elf_link_hash_entry *) h;
if (h->plt.offset != MINUS_ONE)
{
@ -8620,6 +8795,18 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
+ h->plt.offset);
}
/* If we have a MIPS16 function with a stub, the dynamic symbol must
refer to the stub, since only the stub uses the standard calling
conventions. */
if (h->dynindx != -1 && hmips->fn_stub != NULL)
{
BFD_ASSERT (hmips->need_fn_stub);
sym->st_value = (hmips->fn_stub->output_section->vma
+ hmips->fn_stub->output_offset);
sym->st_size = hmips->fn_stub->size;
sym->st_other = ELF_ST_VISIBILITY (sym->st_other);
}
BFD_ASSERT (h->dynindx != -1
|| h->forced_local);
@ -8638,7 +8825,8 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_vma value;
value = sym->st_value;
offset = mips_elf_global_got_index (dynobj, output_bfd, h, R_MIPS_GOT16, info);
offset = mips_elf_global_got_index (dynobj, output_bfd, h,
R_MIPS_GOT16, info);
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
}
@ -8652,7 +8840,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
e.abfd = output_bfd;
e.symndx = -1;
e.d.h = (struct mips_elf_link_hash_entry *)h;
e.d.h = hmips;
e.tls_type = 0;
for (g = g->next; g->next != gg; g = g->next)
@ -8768,9 +8956,13 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
}
}
/* If this is a mips16 symbol, force the value to be even. */
/* Keep dynamic MIPS16 symbols odd. This allows the dynamic linker to
treat MIPS16 symbols like any other. */
if (ELF_ST_IS_MIPS16 (sym->st_other))
sym->st_value &= ~1;
{
BFD_ASSERT (sym->st_value & 1);
sym->st_other -= STO_MIPS16;
}
return TRUE;
}
@ -9998,6 +10190,8 @@ _bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
for (rel = relocs; rel < relend; rel++)
switch (ELF_R_TYPE (abfd, rel->r_info))
{
case R_MIPS16_GOT16:
case R_MIPS16_CALL16:
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_CALL_HI16:

View file

@ -964,6 +964,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_HI16_PCREL",
"BFD_RELOC_HI16_S_PCREL",
"BFD_RELOC_LO16_PCREL",
"BFD_RELOC_MIPS16_GOT16",
"BFD_RELOC_MIPS16_CALL16",
"BFD_RELOC_MIPS16_HI16",
"BFD_RELOC_MIPS16_HI16_S",
"BFD_RELOC_MIPS16_LO16",

View file

@ -2153,6 +2153,13 @@ ENUM
ENUMDOC
Low 16 bits of pc-relative value
ENUM
BFD_RELOC_MIPS16_GOT16
ENUMX
BFD_RELOC_MIPS16_CALL16
ENUMDOC
Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
16-bit immediate fields
ENUM
BFD_RELOC_MIPS16_HI16
ENUMDOC

View file

@ -1,3 +1,23 @@
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
* config/tc-mips.c (mips16_reloc_p, got16_reloc_p, hi16_reloc_p)
(lo16_reloc_p): New functions.
(reloc_needs_lo_p): Use hi16_reloc_p and got16_reloc_p to
generalize relocation checks.
(matching_lo_reloc): New function.
(fixup_has_matching_lo_p): Use it.
(mips16_mark_labels): Don't clobber a symbol's visibility.
(append_insn): Use hi16_reloc_p and lo16_reloc_p.
(mips16_ip): Handle BFD_RELOC_MIPS16_GOT16 and BFD_RELOC_MIPS16_CALL16.
(md_apply_fix): Likewise.
(mips16_percent_op): Add %got and %call16.
(mips_frob_file): Use got16_reloc_p to generalize relocation checks.
Use matching_lo_reloc.
(mips_force_relocation): Use hi16_reloc_p and lo16_reloc_p to
generalize relocation checks.
(mips_fix_adjustable): Use lo16_reloc_p to generalize relocation
checks.
2008-08-06 DJ Delorie <dj@redhat.com>
* NEWS: Mention these changes.

View file

@ -2129,6 +2129,46 @@ md_assemble (char *str)
}
}
/* Convenience functions for abstracting away the differences between
MIPS16 and non-MIPS16 relocations. */
static inline bfd_boolean
mips16_reloc_p (bfd_reloc_code_real_type reloc)
{
switch (reloc)
{
case BFD_RELOC_MIPS16_JMP:
case BFD_RELOC_MIPS16_GPREL:
case BFD_RELOC_MIPS16_GOT16:
case BFD_RELOC_MIPS16_CALL16:
case BFD_RELOC_MIPS16_HI16_S:
case BFD_RELOC_MIPS16_HI16:
case BFD_RELOC_MIPS16_LO16:
return TRUE;
default:
return FALSE;
}
}
static inline bfd_boolean
got16_reloc_p (bfd_reloc_code_real_type reloc)
{
return reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16;
}
static inline bfd_boolean
hi16_reloc_p (bfd_reloc_code_real_type reloc)
{
return reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S;
}
static inline bfd_boolean
lo16_reloc_p (bfd_reloc_code_real_type reloc)
{
return reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16;
}
/* Return true if the given relocation might need a matching %lo().
This is only "might" because SVR4 R_MIPS_GOT16 relocations only
need a matching %lo() when applied to local symbols. */
@ -2137,11 +2177,19 @@ static inline bfd_boolean
reloc_needs_lo_p (bfd_reloc_code_real_type reloc)
{
return (HAVE_IN_PLACE_ADDENDS
&& (reloc == BFD_RELOC_HI16_S
|| reloc == BFD_RELOC_MIPS16_HI16_S
&& (hi16_reloc_p (reloc)
/* VxWorks R_MIPS_GOT16 relocs never need a matching %lo();
all GOT16 relocations evaluate to "G". */
|| (reloc == BFD_RELOC_MIPS_GOT16 && mips_pic != VXWORKS_PIC)));
|| (got16_reloc_p (reloc) && mips_pic != VXWORKS_PIC)));
}
/* Return the type of %lo() reloc needed by RELOC, given that
reloc_needs_lo_p. */
static inline bfd_reloc_code_real_type
matching_lo_reloc (bfd_reloc_code_real_type reloc)
{
return mips16_reloc_p (reloc) ? BFD_RELOC_MIPS16_LO16 : BFD_RELOC_LO16;
}
/* Return true if the given fixup is followed by a matching R_MIPS_LO16
@ -2151,8 +2199,7 @@ static inline bfd_boolean
fixup_has_matching_lo_p (fixS *fixp)
{
return (fixp->fx_next != NULL
&& (fixp->fx_next->fx_r_type == BFD_RELOC_LO16
|| fixp->fx_next->fx_r_type == BFD_RELOC_MIPS16_LO16)
&& fixp->fx_next->fx_r_type == matching_lo_reloc (fixp->fx_r_type)
&& fixp->fx_addsy == fixp->fx_next->fx_addsy
&& fixp->fx_offset == fixp->fx_next->fx_offset);
}
@ -2934,8 +2981,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
&& (reloc_type[0] == BFD_RELOC_16
|| reloc_type[0] == BFD_RELOC_32
|| reloc_type[0] == BFD_RELOC_MIPS_JMP
|| reloc_type[0] == BFD_RELOC_HI16_S
|| reloc_type[0] == BFD_RELOC_LO16
|| reloc_type[0] == BFD_RELOC_GPREL16
|| reloc_type[0] == BFD_RELOC_MIPS_LITERAL
|| reloc_type[0] == BFD_RELOC_GPREL32
@ -2948,8 +2993,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
|| reloc_type[0] == BFD_RELOC_MIPS_REL16
|| reloc_type[0] == BFD_RELOC_MIPS_RELGOT
|| reloc_type[0] == BFD_RELOC_MIPS16_GPREL
|| reloc_type[0] == BFD_RELOC_MIPS16_HI16_S
|| reloc_type[0] == BFD_RELOC_MIPS16_LO16))
|| hi16_reloc_p (reloc_type[0])
|| lo16_reloc_p (reloc_type[0])))
ip->fixp[0]->fx_no_overflow = 1;
if (mips_relax.sequence)
@ -10092,6 +10137,8 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
/* Stuff the immediate value in now, if we can. */
if (imm_expr.X_op == O_constant
&& *imm_reloc > BFD_RELOC_UNUSED
&& *imm_reloc != BFD_RELOC_MIPS16_GOT16
&& *imm_reloc != BFD_RELOC_MIPS16_CALL16
&& insn->pinfo != INSN_MACRO)
{
valueT tmp;
@ -10861,6 +10908,8 @@ static const struct percent_op_match mips16_percent_op[] =
{
{"%lo", BFD_RELOC_MIPS16_LO16},
{"%gprel", BFD_RELOC_MIPS16_GPREL},
{"%got", BFD_RELOC_MIPS16_GOT16},
{"%call16", BFD_RELOC_MIPS16_CALL16},
{"%hi", BFD_RELOC_MIPS16_HI16_S}
};
@ -11954,7 +12003,7 @@ mips_frob_file (void)
/* If a GOT16 relocation turns out to be against a global symbol,
there isn't supposed to be a matching LO. */
if (l->fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
if (got16_reloc_p (l->fixp->fx_r_type)
&& !pic_need_relax (l->fixp->fx_addsy, l->seg))
continue;
@ -11972,12 +12021,7 @@ mips_frob_file (void)
hi_pos = NULL;
lo_pos = NULL;
matched_lo_p = FALSE;
if (l->fixp->fx_r_type == BFD_RELOC_MIPS16_HI16
|| l->fixp->fx_r_type == BFD_RELOC_MIPS16_HI16_S)
looking_for_rtype = BFD_RELOC_MIPS16_LO16;
else
looking_for_rtype = BFD_RELOC_LO16;
looking_for_rtype = matching_lo_reloc (l->fixp->fx_r_type);
for (pos = &seginfo->fix_root; *pos != NULL; pos = &(*pos)->fx_next)
{
@ -12030,8 +12074,8 @@ mips_force_relocation (fixS *fixp)
if (HAVE_NEWABI
&& S_GET_SEGMENT (fixp->fx_addsy) == bfd_abs_section_ptr
&& (fixp->fx_r_type == BFD_RELOC_MIPS_SUB
|| fixp->fx_r_type == BFD_RELOC_HI16_S
|| fixp->fx_r_type == BFD_RELOC_LO16))
|| hi16_reloc_p (fixp->fx_r_type)
|| lo16_reloc_p (fixp->fx_r_type)))
return 1;
return 0;
@ -12119,6 +12163,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_MIPS_CALL_HI16:
case BFD_RELOC_MIPS_CALL_LO16:
case BFD_RELOC_MIPS16_GPREL:
case BFD_RELOC_MIPS16_GOT16:
case BFD_RELOC_MIPS16_CALL16:
case BFD_RELOC_MIPS16_HI16:
case BFD_RELOC_MIPS16_HI16_S:
case BFD_RELOC_MIPS16_JMP:
@ -13926,8 +13972,7 @@ mips_fix_adjustable (fixS *fixp)
placed anywhere. Rather than break backwards compatibility by changing
this, it seems better not to force the issue, and instead keep the
original symbol. This will work with either linker behavior. */
if ((fixp->fx_r_type == BFD_RELOC_LO16
|| fixp->fx_r_type == BFD_RELOC_MIPS16_LO16
if ((lo16_reloc_p (fixp->fx_r_type)
|| reloc_needs_lo_p (fixp->fx_r_type))
&& HAVE_IN_PLACE_ADDENDS
&& (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)

View file

@ -1,3 +1,10 @@
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
* gas/mips/elf-rel8-mips16.d, gas/mips/elf-rel8-mips16.s,
* gas/mips/elf-rel9-mips16.d, gas/mips/elf-rel9-mips16.s,
* gas/mips/elf-rel13-mips16.d, gas/mips/elf-rel13-mips16.s: New tests.
* gas/mips/mips.exp: Run them.
2008-08-01 Peter Bergner <bergner@vnet.ibm.com>
* gas/ppc/power7.d: New.

View file

@ -0,0 +1,17 @@
#as: -march=mips2 -mabi=32 -KPIC
#readelf: --relocs
#name: MIPS ELF reloc 13 (MIPS16 version)
Relocation section '\.rel\.text' at offset .* contains 9 entries:
*Offset * Info * Type * Sym\.Value * Sym\. Name
0+0002 * 0+..66 * R_MIPS16_GOT16 * 0+0000 * \.data
0+0016 * 0+..69 * R_MIPS16_LO16 * 0+0000 * \.data
0+0012 * 0+..66 * R_MIPS16_GOT16 * 0+0000 * \.data
0+001a * 0+..69 * R_MIPS16_LO16 * 0+0000 * \.data
# The next two lines could be in either order.
0+000e * 0+..66 * R_MIPS16_GOT16 * 0+0000 * \.rodata
0+000a * 0+..66 * R_MIPS16_GOT16 * 0+0000 * \.rodata
0+001e * 0+..69 * R_MIPS16_LO16 * 0+0000 * \.rodata
0+0006 * 0+..66 * R_MIPS16_GOT16 * 0+0000 * \.bss
0+0022 * 0+..69 * R_MIPS16_LO16 * 0+0000 * \.bss
#pass

View file

@ -0,0 +1,24 @@
.set mips16
.ent foo
foo:
move $2,$28
lw $4,%got(l1)($2)
lw $4,%got(l2)($2)
lw $4,%got(l3)($2)
lw $4,%got(l3)($2)
lw $4,%got(l1+0x400)($2)
addiu $4,%lo(l1)
addiu $4,%lo(l1+0x400)
addiu $4,%lo(l3)
addiu $4,%lo(l2)
.align 5
.end foo
.data
l1: .word 1
.lcomm l2, 4
.rdata
.word 1
l3: .word 2

View file

@ -0,0 +1,38 @@
#as: -march=mips2 -mabi=32
#objdump: -M gpr-names=numeric -dr
#name: MIPS ELF reloc 8 (MIPS16 version)
.*: file format .*
Disassembly of section \.text:
0+00 <foo>:
0: 675c move \$2,\$28
2: f000 6c00 li \$4,0
2: R_MIPS16_HI16 gvar
6: f400 3480 sll \$4,16
a: f000 4c00 addiu \$4,0
a: R_MIPS16_LO16 gvar
e: f000 9d80 lw \$4,0\(\$5\)
e: R_MIPS16_LO16 gvar
12: f000 9982 lw \$4,2\(\$17\)
16: f000 9a80 lw \$4,0\(\$2\)
16: R_MIPS16_GOT16 \.data
1a: f000 c4a0 sb \$5,0\(\$4\)
1a: R_MIPS16_LO16 \.data
1e: f000 9a80 lw \$4,0\(\$2\)
1e: R_MIPS16_GOT16 \.data
22: f000 4c00 addiu \$4,0
22: R_MIPS16_LO16 \.data
26: f000 9a60 lw \$3,0\(\$2\)
26: R_MIPS16_CALL16 gfunc
2a: f000 4c00 addiu \$4,0
2a: R_MIPS16_CALL16 gfunc
2e: f000 9a80 lw \$4,0\(\$2\)
2e: R_MIPS16_GPREL gvar
32: f000 da80 sw \$4,0\(\$2\)
32: R_MIPS16_GPREL gvar
36: f000 4c00 addiu \$4,0
36: R_MIPS16_GPREL gvar
3a: 6500 nop
#pass

View file

@ -0,0 +1,39 @@
.equ $fprel, 2
.set mips16
.ent foo
foo:
move $2,$gp
# Test various forms of relocation syntax.
li $4,(%hi gvar)
sll $4,16
addiu $4,(%lo (gvar))
lw $4,%lo gvar($5)
# Check that registers aren't confused with $ identifiers.
lw $4,($fprel)($17)
# Check various forms of paired relocations.
lw $4,%got(lvar)($2)
sb $5,%lo(lvar)($4)
lw $4,%got(lvar)($2)
addiu $4,%lo(lvar)
# Check individual relocations.
lw $3,%call16(gfunc)($2)
addiu $4,%call16(gfunc)
lw $4,%gprel(gvar)($2)
sw $4,%gprel(gvar)($2)
addiu $4,%gprel(gvar)
.align 6
.end foo
.data
lvar: .word 1,2

View file

@ -0,0 +1,70 @@
#as: -march=mips2 -mabi=32
#objdump: -M gpr-names=numeric -dr
#name: MIPS ELF reloc 9 (MIPS16 version)
.*: file format .*
Disassembly of section \.text:
0+00 <foo>:
0: 675c move \$2,\$28
2: f000 9a80 lw \$4,0\(\$2\)
2: R_MIPS16_GOT16 \.data
6: f000 4c10 addiu \$4,16
6: R_MIPS16_LO16 \.data
a: f000 9a80 lw \$4,0\(\$2\)
a: R_MIPS16_GOT16 \.data
e: f020 4c00 addiu \$4,32
e: R_MIPS16_LO16 \.data
12: f000 9a80 lw \$4,0\(\$2\)
12: R_MIPS16_GOT16 \.data
16: f7ef 4c1c addiu \$4,32764
16: R_MIPS16_LO16 \.data
1a: f000 9a81 lw \$4,1\(\$2\)
1a: R_MIPS16_GOT16 \.data
1e: f010 4c00 addiu \$4,-32768
1e: R_MIPS16_LO16 \.data
22: f000 9a81 lw \$4,1\(\$2\)
22: R_MIPS16_GOT16 \.data
26: f7ff 4c1c addiu \$4,-4
26: R_MIPS16_LO16 \.data
2a: f000 9a81 lw \$4,1\(\$2\)
2a: R_MIPS16_GOT16 \.data
2e: f000 4c00 addiu \$4,0
2e: R_MIPS16_LO16 \.data
32: f000 9a82 lw \$4,2\(\$2\)
32: R_MIPS16_GOT16 \.data
36: f010 4c10 addiu \$4,-32752
36: R_MIPS16_LO16 \.data
3a: f000 9a82 lw \$4,2\(\$2\)
3a: R_MIPS16_GOT16 \.data
3e: f01e 4c00 addiu \$4,-4096
3e: R_MIPS16_LO16 \.data
42: f000 9a82 lw \$4,2\(\$2\)
42: R_MIPS16_GOT16 \.data
46: f7ff 4c1f addiu \$4,-1
46: R_MIPS16_LO16 \.data
4a: f000 9a82 lw \$4,2\(\$2\)
4a: R_MIPS16_GOT16 \.data
4e: f000 4c00 addiu \$4,0
4e: R_MIPS16_LO16 \.data
52: f000 9a83 lw \$4,3\(\$2\)
52: R_MIPS16_GOT16 \.data
56: f342 4c05 addiu \$4,4933
56: R_MIPS16_LO16 \.data
5a: f018 9a80 lw \$4,-16384\(\$2\)
5a: R_MIPS16_GPREL \.sdata
5e: f018 9a84 lw \$4,-16380\(\$2\)
5e: R_MIPS16_GPREL \.sdata
62: f018 9a84 lw \$4,-16380\(\$2\)
62: R_MIPS16_GPREL \.sdata
66: f018 9a88 lw \$4,-16376\(\$2\)
66: R_MIPS16_GPREL \.sdata
6a: f018 9a8c lw \$4,-16372\(\$2\)
6a: R_MIPS16_GPREL \.sdata
6e: f018 9a94 lw \$4,-16364\(\$2\)
6e: R_MIPS16_GPREL \.sdata
72: f018 9a98 lw \$4,-16360\(\$2\)
72: R_MIPS16_GPREL \.sdata
76: 6500 nop
#pass

View file

@ -0,0 +1,59 @@
.set mips16
.ent foo
foo:
move $2,$28
lw $4,%got(l1)($2)
addiu $4,%lo(l1)
lw $4,%got(l1 + 16)($2)
addiu $4,%lo(l1 + 16)
lw $4,%got(l1 + 0x7fec)($2)
addiu $4,%lo(l1 + 0x7fec)
lw $4,%got(l1 + 0x7ff0)($2)
addiu $4,%lo(l1 + 0x7ff0)
lw $4,%got(l1 + 0xffec)($2)
addiu $4,%lo(l1 + 0xffec)
lw $4,%got(l1 + 0xfff0)($2)
addiu $4,%lo(l1 + 0xfff0)
lw $4,%got(l1 + 0x18000)($2)
addiu $4,%lo(l1 + 0x18000)
lw $4,%got(l2)($2)
addiu $4,%lo(l2)
lw $4,%got(l2 + 0xfff)($2)
addiu $4,%lo(l2 + 0xfff)
lw $4,%got(l2 + 0x1000)($2)
addiu $4,%lo(l2 + 0x1000)
lw $4,%got(l2 + 0x12345)($2)
addiu $4,%lo(l2 + 0x12345)
lw $4,%gprel(l3)($2)
lw $4,%gprel(l3 + 4)($2)
lw $4,%gprel(l4)($2)
lw $4,%gprel(l4 + 4)($2)
lw $4,%gprel(l5)($2)
lw $4,%gprel(l5 + 8)($2)
lw $4,%gprel(l5 + 12)($2)
.align 6
.end foo
.data
.word 1,2,3,4
l1: .word 4,5
.space 0x1f000 - 24
l2: .word 7,8
.sdata
l3: .word 1
l4: .word 2
.word 3
l5: .word 4

View file

@ -653,13 +653,16 @@ if { [istarget mips*-*-vxworks*] } {
}
run_dump_test "elf-rel7"
run_dump_test "elf-rel8"
run_dump_test "elf-rel8-mips16"
run_dump_test "elf-rel9"
run_dump_test "elf-rel9-mips16"
if $has_newabi {
run_dump_test "elf-rel10"
run_dump_test "elf-rel11"
}
run_dump_test "elf-rel12"
run_dump_test "elf-rel13"
run_dump_test "elf-rel13-mips16"
run_dump_test "elf-rel14"
if $has_newabi {

View file

@ -1,3 +1,25 @@
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
* ld-mips-elf/mips16-local-stubs-1.d: Remove stub_for_h3,
which was only referenced by the .pdr section, and was not
actually needed by code.
* ld-mips-elf/mips16-intermix.d: Remove unused static function stubs.
* ld-mips-elf/mips16-pic-1a.s,
ld-mips-elf/mips16-pic-1b.s,
ld-mips-elf/mips16-pic-1-dummy.s,
ld-mips-elf/mips16-pic-1.dd,
ld-mips-elf/mips16-pic-1.gd,
ld-mips-elf/mips16-pic-1.inc,
ld-mips-elf/mips16-pic-1.ld,
ld-mips-elf/mips16-pic-2a.s,
ld-mips-elf/mips16-pic-2b.s,
ld-mips-elf/mips16-pic-2.ad,
ld-mips-elf/mips16-pic-2.dd,
ld-mips-elf/mips16-pic-2.gd,
ld-mips-elf/mips16-pic-2.nd,
ld-mips-elf/mips16-pic-2.rd: New tests.
* ld-mips-elf/mips-elf.exp: Run them.
2008-08-06 Alan Modra <amodra@bigpond.net.au>
* ld-elf/extract-symbol-1sec.d: Update.

View file

@ -56,6 +56,30 @@ set has_newabi [expr [istarget *-*-irix6*] || [istarget mips64*-*-linux*]]
set linux_gnu [expr [istarget mips*-*-linux*]]
set embedded_elf [expr [istarget mips*-*-elf]]
if { $linux_gnu } {
run_ld_link_tests [list \
[list "Dummy shared library for MIPS16 PIC test 1" \
"-shared -melf32btsmip" \
"-EB -32" { mips16-pic-1-dummy.s } \
{} \
"mips16-pic-1-dummy.so"] \
[list "MIPS16 PIC test 1" \
"-melf32btsmip -T mips16-pic-1.ld tmpdir/mips16-pic-1-dummy.so" \
"-EB -32 -I $srcdir/$subdir" { mips16-pic-1a.s mips16-pic-1b.s } \
{ { objdump { -dr -j.text } mips16-pic-1.dd }
{ readelf -A mips16-pic-1.gd } } \
"mips16-pic-1"] \
[list "MIPS16 PIC test 2" \
"-melf32btsmip -T mips16-pic-1.ld -shared" \
"-EB -32 -I $srcdir/$subdir" { mips16-pic-2a.s mips16-pic-2b.s } \
{ { objdump { -dr -j.text } mips16-pic-2.dd } \
{ readelf -A mips16-pic-2.gd } \
{ readelf --symbols mips16-pic-2.nd } \
{ readelf --relocs mips16-pic-2.rd } \
{ readelf -d mips16-pic-2.ad } } \
"mips16-pic-2"]]
}
if { [istarget mips64*-linux-gnu] } {
set o32_as_flags "-32 -EB"
set o32_ld_flags "-melf32btsmip"

View file

@ -14,7 +14,6 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_d
.* l F .text 0+[0-9a-f]+ m32_static_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static_d
.* l F .text 0+[0-9a-f]+ m32_static1_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static1_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static1_d
@ -23,7 +22,6 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static32_d
.* l F .text 0+[0-9a-f]+ m32_static16_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static16_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static16_d
.* l F .text 0+[0-9a-f]+ m32_static_ld
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_ld
.* l F .text 0+[0-9a-f]+ m32_static1_ld
@ -35,7 +33,6 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_dl
.* l F .text 0+[0-9a-f]+ m32_static_dl
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_dl
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static_dl
.* l F .text 0+[0-9a-f]+ m32_static1_dl
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static1_dl
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static1_dl
@ -44,11 +41,9 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static32_dl
.* l F .text 0+[0-9a-f]+ m32_static16_dl
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static16_dl
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static16_dl
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_dlld
.* l F .text 0+[0-9a-f]+ m32_static_dlld
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_dlld
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static_dlld
.* l F .text 0+[0-9a-f]+ m32_static1_dlld
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static1_dlld
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static1_dlld
@ -57,7 +52,6 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static32_dlld
.* l F .text 0+[0-9a-f]+ m32_static16_dlld
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static16_dlld
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static16_dlld
.* l F .text 0+[0-9a-f]+ m32_static_d_l
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_d_l
.* l F .text 0+[0-9a-f]+ m32_static1_d_l
@ -66,10 +60,11 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static32_d_l
.* l F .text 0+[0-9a-f]+ m32_static16_d_l
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static16_d_l
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_d_d
# ??? We aren't yet able to get rid of the symbol table entry for
# __fn_stub_m16_d_d, or its .pdr entry.
.* l F .text 0+[0-9a-f]+ *
.* l F .text 0+[0-9a-f]+ m32_static_d_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static_d_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static_d_d
.* l F .text 0+[0-9a-f]+ m32_static1_d_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static1_d_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static1_d_d
@ -78,7 +73,6 @@ SYMBOL TABLE:
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static32_d_d
.* l F .text 0+[0-9a-f]+ m32_static16_d_d
.* l F .text 0+[0-9a-f]+ 0xf0 m16_static16_d_d
.* l F .text 0+[0-9a-f]+ __fn_stub_m16_static16_d_d
#...
.* l F .text 0+[0-9a-f]+ __call_stub_m32_static1_d
.* l F .text 0+[0-9a-f]+ __call_stub_m16_static1_d

View file

@ -57,13 +57,13 @@ Disassembly of section \.text:
20000068: 00000000 nop
2000006c <caller2>:
2000006c: 1c00 0030 jalx 200000c0 <stub_for_f1>
2000006c: 1c00 002c jalx 200000b0 <stub_for_f1>
20000070: 6500 nop
20000072: 1c00 0038 jalx 200000e0 <stub_for_f2>
20000072: 1c00 0034 jalx 200000d0 <stub_for_f2>
20000076: 6500 nop
20000078: 1c00 0034 jalx 200000d0 <stub_for_g1>
20000078: 1c00 0030 jalx 200000c0 <stub_for_g1>
2000007c: 6500 nop
2000007e: 1c00 003c jalx 200000f0 <stub_for_g2>
2000007e: 1c00 0038 jalx 200000e0 <stub_for_g2>
20000082: 6500 nop
20000084: 1800 0004 jal 20000010 <h1>
20000088: 6500 nop
@ -82,33 +82,26 @@ Disassembly of section \.text:
200000a8: 00200008 jr at
200000ac: 00000000 nop
# This isn't actually called, but is referenced from the .pdr section.
200000b0 <stub_for_h3>:
200000b0 <stub_for_f1>:
200000b0: 3c012000 lui at,0x2000
200000b4: 24210039 addiu at,at,57
200000b4: 24210000 addiu at,at,0
200000b8: 00200008 jr at
200000bc: 00000000 nop
200000c0 <stub_for_f1>:
200000c0 <stub_for_g1>:
200000c0: 3c012000 lui at,0x2000
200000c4: 24210000 addiu at,at,0
200000c4: 24210008 addiu at,at,8
200000c8: 00200008 jr at
200000cc: 00000000 nop
200000d0 <stub_for_g1>:
200000d0 <stub_for_f2>:
200000d0: 3c012000 lui at,0x2000
200000d4: 24210008 addiu at,at,8
200000d4: 24210014 addiu at,at,20
200000d8: 00200008 jr at
200000dc: 00000000 nop
200000e0 <stub_for_f2>:
200000e0 <stub_for_g2>:
200000e0: 3c012000 lui at,0x2000
200000e4: 24210014 addiu at,at,20
200000e4: 2421001c addiu at,at,28
200000e8: 00200008 jr at
200000ec: 00000000 nop
200000f0 <stub_for_g2>:
200000f0: 3c012000 lui at,0x2000
200000f4: 2421001c addiu at,at,28
200000f8: 00200008 jr at
200000fc: 00000000 nop

View file

@ -0,0 +1,15 @@
.abicalls
nop
.macro dummyfn,name
.global \name
.ent \name
\name:
jr $31
.end \name
.endm
dummyfn extern1
dummyfn extern2
dummyfn extern3
dummyfn extern4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,57 @@
Primary GOT:
Canonical gp value: 00057ff0
Reserved entries:
Address Access Initial Purpose
00050000 -32752\(gp\) 00000000 Lazy resolver
00050004 -32748\(gp\) 80000000 Module pointer \(GNU extension\)
Local entries:
Address Access Initial
# GOT page entry
00050008 -32744\(gp\) 00040000
# a_unused4
0005000c -32740\(gp\) 00040461
# b_unused4
00050010 -32736\(gp\) 00040465
# __fn_a_used6
00050014 -32732\(gp\) 00040c28
# __fn_b_used6
00050018 -32728\(gp\) 00040c3c
# __fn_a_used10
0005001c -32724\(gp\) 00040d08
# __fn_b_used10
00050020 -32720\(gp\) 00040d1c
# __fn_a_used12
00050024 -32716\(gp\) 00040d78
# __fn_b_used12
00050028 -32712\(gp\) 00040d8c
# a_unused6
0005002c -32708\(gp\) 000404b1
# b_unused6
00050030 -32704\(gp\) 000404b5
# __fn_a_used8
00050034 -32700\(gp\) 00040c98
# __fn_b_used8
00050038 -32696\(gp\) 00040cac
0005003c -32692\(gp\) 00000000
00050040 -32688\(gp\) 00000000
00050044 -32684\(gp\) 00000000
00050048 -32680\(gp\) 00000000
Global entries:
Address Access Initial Sym\.Val\. Type Ndx Name
0005004c -32676\(gp\) 00040e90 00040e90 FUNC 7 a_used17
00050050 -32672\(gp\) 00040f14 00040f14 FUNC 7 b_used19
00050054 -32668\(gp\) 00040f38 00040f38 FUNC 7 a_used20
00050058 -32664\(gp\) 00040e20 00040e20 FUNC 7 a_used15
0005005c -32660\(gp\) 00040db0 00040db0 FUNC 7 a_used13
00050060 -32656\(gp\) 00040ea4 00040ea4 FUNC 7 b_used17
00050064 -32652\(gp\) 00040f4c 00040f4c FUNC 7 b_used20
00050068 -32648\(gp\) 00040f70 00040f70 FUNC 7 a_used21
0005006c -32644\(gp\) 00040f00 00040f00 FUNC 7 a_used19
00050070 -32640\(gp\) 00040e34 00040e34 FUNC 7 b_used15
00050074 -32636\(gp\) 00040f84 00040f84 FUNC 7 b_used21
00050078 -32632\(gp\) 00040dc4 00040dc4 FUNC 7 b_used13

View file

@ -0,0 +1,147 @@
# Declare a function called NAME and an __fn_NAME stub for it.
# Make the stub use la_TYPE to load the the target address into $2.
.macro stub,name,type
.set nomips16
.section .mips16.fn.\name, "ax", @progbits
.ent __fn_\name
__fn_\name:
la_\type \name
mfc1 $4,$f12
jr $2
nop
.end __fn_\name
.set mips16
.text
.ent \name
\name:
__fn_local_\name:
jr $31
nop
.end \name
.endm
# Like stub, but ensure NAME is a local symbol.
.macro lstub,name,type
stub \name, \type
.equ local_\name,1
.endm
# Like stub, but ensure NAME is a hidden symbol.
.macro hstub,name,type
.globl \name
.hidden \name
stub \name, \type
.endm
# Like lstub, but make the MIPS16 function global rather than local.
.macro gstub,name,type
.globl \name
stub \name, \type
.endm
# Use an absolute sequence to load NAME into a register.
.macro la_noshared,name
lui $2,%hi(\name)
addiu $2,$2,%lo(\name)
.endm
# Use the normal PIC sequence to load __fn_local_NAME into $2
# and emit a dummy relocation against NAME. This macro is always
# used at the start of a function.
.macro la_shared,name
.reloc 0,R_MIPS_NONE,\name
.cpload $25
la $2,__fn_local_\name
.endm
# Use TYPE (either LSTUB, HSTUB or GSTUB) to define functions
# called a_NAME and b_NAME. The former uses absolute accesses
# and the latter uses PIC accesses.
.macro decl,name,type
\type a_\name, noshared
\type b_\name, shared
.endm
# Emit the MIPS16 PIC sequence for setting $28 from $25.
# Make the value of $25 available in $2 as well.
.macro cpload_mips16
li $2,%hi(_gp_disp)
addiu $3,$pc,%lo(_gp_disp)
sll $2,16
addu $2,$2,$3
move $28,$2
.endm
# Likewise, but for non-MIPS16 code.
.macro cpload_nomips16
.cpload $25
move $2,$28
.endm
# Start a PIC function in ISA mode MODE, which is either "mips16"
# or "nomips16".
.macro pic_prologue,mode
cpload_\mode
addiu $sp,$sp,-32
sw $2,16($sp)
sw $31,20($sp)
.endm
# Use a PIC function to call NAME.
.macro pic_call,name,mode
.ifdef local_\name
.ifc \mode,mips16
lw $2,%got(__fn_local_\name)($2)
addiu $2,%lo(__fn_local_\name)
.else
lw $2,%got(\name)($2)
addiu $2,%lo(\name)
.endif
.else
lw $2,%call16(\name)($2)
.endif
jalr $2
move $25,$2
lw $2,16($sp)
move $28,$2
.endm
# Finish a PIC function started by pic_prologue.
.macro pic_epilogue
lw $2,20($sp)
jr $2
addiu $sp,$sp,32
.endm
# Use PIC %call16 sequences to call a_NAME and b_NAME.
# MODE selects the ISA mode of the code: either "mips16"
# or "nomips16".
.macro callpic,name,mode
.text
.set \mode
.ent callpic_\name\()_\mode
callpic_\name\()_\mode:
pic_prologue \mode
pic_call a_\name,\mode
pic_call b_\name,\mode
pic_epilogue
.end callpic_\name\()_\mode
.endm
# Use absolute jals to call a_NAME and b_NAME. MODE selects the
# ISA mode of the code: either "mips16" or "nomips16".
.macro jals,name,mode
.text
.set \mode
.ent jals_\name\()_\mode
jals_\name\()_\mode:
.option pic0
jal a_\name
nop
jal b_\name
nop
.option pic2
.end jals_\name\()_\mode
.endm

View file

@ -0,0 +1,22 @@
SECTIONS
{
. = 0x40000;
.interp : { *(.interp) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.dynamic : { *(.dynamic) }
.reginfo : { *(.reginfo) }
.hash : { *(.hash) }
. = ALIGN (0x400);
.text : { *(.text) *(.mips16.*) }
.MIPS.stubs : { *(.MIPS.stubs) }
. = ALIGN (0x400);
.rel.plt : { *(.rel.plt) }
.rel.dyn : { *(.rel.dyn) }
. = 0x50000;
_gp = . + 0x7ff0;
.got : { *(.got) }
. = 0x50400;
.data : { *(.data) }
.rld_map : { *(.rld_map) }
}

View file

@ -0,0 +1,144 @@
.abicalls
.set noreorder
.include "mips16-pic-1.inc"
# Test local stubs that are only used by MIPS16 PIC calls in this file.
decl unused1,lstub
callpic unused1,mips16
# Test local stubs that are only used by MIPS16 jals in this file.
decl unused2,lstub
jals unused2,mips16
# Test local stubs that aren't called at all.
decl unused3,lstub
# Test hidden stubs that are called by MIPS16 PIC calls in this file.
decl unused4,hstub
callpic unused4,mips16
# Test hidden stubs that are called by MIPS16 jals in this file.
decl unused5,hstub
jals unused5,mips16
# Test hidden stubs that are called by MIPS16 PIC calls in another file.
decl unused6,hstub
# Test hidden stubs that are called by MIPS16 jals in another file.
decl unused7,hstub
# Test hidden stubs that aren't called at all.
decl unused8,hstub
# Test global stubs that are called by MIPS16 jals in this file.
decl unused9,gstub
jals unused9,mips16
# Test global stubs that are called by MIPS16 jals in another file.
decl unused10,gstub
# Test global stubs that aren't called at all.
decl unused11,gstub
# Test local stubs that are used by non-MIPS16 PIC calls in this file.
decl used1,lstub
callpic used1,nomips16
# Test local stubs that are used by non-MIPS16 jals in this file.
decl used2,lstub
jals used2,nomips16
# Test local stubs that are used by both MIPS16 and non-MIPS16 PIC
# calls in this file.
decl used3,lstub
callpic used3,nomips16
callpic used3,mips16
# Test local stubs that are used by both MIPS16 and non-MIPS16 jals
# in this file.
decl used4,lstub
jals used4,nomips16
jals used4,mips16
# Test local stubs that are used by a combination of MIPS16 PIC calls
# and non-MIPS16 jals in this file.
decl used5,lstub
jals used5,nomips16
callpic used5,mips16
# Test hidden stubs that are used by non-MIPS16 PIC calls in this file.
decl used6,hstub
callpic used6,nomips16
# Test hidden stubs that are used by non-MIPS16 jals in this file.
decl used7,hstub
jals used7,nomips16
# Test hidden stubs that are used by non-MIPS16 PIC calls in another
# file.
decl used8,hstub
# Test hidden stubs that are used by non-MIPS16 jals in another
# file.
decl used9,hstub
# Test hidden stubs that are used by both MIPS16 and non-MIPS16 PIC
# calls in this file.
decl used10,hstub
callpic used10,nomips16
callpic used10,mips16
# Test hidden stubs that are used by both MIPS16 and non-MIPS16 jals
# in this file.
decl used11,hstub
jals used11,nomips16
jals used11,mips16
# Test hidden stubs that are used by a combination of MIPS16 PIC calls
# and non-MIPS16 jals in this file.
decl used12,hstub
jals used12,nomips16
callpic used12,mips16
# Test global stubs that are used by non-MIPS16 PIC calls in this file.
decl used13,gstub
callpic used13,nomips16
# Test global stubs that are used by non-MIPS16 jals in this file.
decl used14,gstub
jals used14,nomips16
# Test global stubs that are used by non-MIPS16 PIC calls in another
# file.
decl used15,gstub
# Test global stubs that are used by non-MIPS16 jals in another file.
decl used16,gstub
# Test global stubs that are used by both MIPS16 and non-MIPS16 PIC
# calls in this file.
decl used17,gstub
callpic used17,nomips16
callpic used17,mips16
# Test global stubs that are used by both MIPS16 and non-MIPS16 jals
# in this file.
decl used18,gstub
jals used18,nomips16
jals used18,mips16
# Test global stubs that are used by a combination of MIPS16 PIC calls
# and non-MIPS16 jals in this file.
decl used19,gstub
jals used19,nomips16
callpic used19,mips16
# Test global stubs that are used by MIPS16 PIC calls in this file.
# We currently force all targets of call16 relocations to be dynamic,
# and the stub must be the definition of the dynamic symbol.
decl used20,gstub
callpic used20,mips16
# Test global stubs that are used by MIPS16 PIC calls in another file.
# Needed for the same reason as used21.
decl used21,gstub

View file

@ -0,0 +1,19 @@
.abicalls
.set noreorder
.include "mips16-pic-1.inc"
callpic unused6,mips16
jals unused7,mips16
jals unused10,mips16
callpic used8,nomips16
jals used9,nomips16
callpic used15,nomips16
jals used16,nomips16
callpic used21,mips16
.globl __start
.ent __start
.set nomips16
__start:
nop
.end __start

View file

@ -0,0 +1,6 @@
# [MIPS_GOTSYM, MIPS_SYMTABNO) covers used4...used7.
#...
.* \(MIPS_SYMTABNO\) * 10
#...
.* \(MIPS_GOTSYM\) * 0x6
#pass

View file

@ -0,0 +1,208 @@
.*
Disassembly of section \.text:
00040400 <unused1>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040404 <unused2>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040408 <unused3>:
.*: [^\t]* jr ra
.*: [^\t]* nop
0004040c <unused4>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040410 <unused5>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040414 <used1>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040418 <used2>:
.*: [^\t]* jr ra
.*: [^\t]* nop
0004041c <used3>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040420 <\.mips16\.used4>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040424 <\.mips16\.used5>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040428 <\.mips16\.used6>:
.*: [^\t]* jr ra
.*: [^\t]* nop
0004042c <\.mips16\.used7>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040430 <\.mips16\.used8>:
.*: [^\t]* jr ra
.*: [^\t]* nop
00040434 <foo>:
.*: [^\t]* li v0,1
.*: [^\t]* la v1,47ff0 <.*>
.*: [^\t]* sll v0,16
.*: [^\t]* addu v0,v1
.*: [^\t]* move gp,v0
.*: [^\t]* addiu sp,-32
.*: [^\t]* sw v0,16\(sp\)
.*: [^\t]* sw ra,20\(sp\)
# 40400: unused1
.*: [^\t]* lw v0,-32744\(v0\)
.*: [^\t]* addiu v0,1025
.*: [^\t]* jalr v0
.*: [^\t]* move t9,v0
.*: [^\t]* lw v0,16\(sp\)
.*: [^\t]* move gp,v0
.*: [^\t]* lw v0,-32740\(v0\)
.*: [^\t]* jalr v0
.*: [^\t]* move t9,v0
.*: [^\t]* lw v0,16\(sp\)
.*: [^\t]* move gp,v0
.*: [^\t]* lw v0,-32708\(v0\)
.*: [^\t]* jalr v0
.*: [^\t]* move t9,v0
.*: [^\t]* lw v0,16\(sp\)
.*: [^\t]* move gp,v0
.*: [^\t]* lw v0,20\(sp\)
.*: [^\t]* jr v0
.*: [^\t]* addiu sp,32
#...
00040480 <bar>:
.*: [^\t]* li v0,1
.*: [^\t]* la v1,47ff0 <.*>
.*: [^\t]* sll v0,16
.*: [^\t]* addu v0,v1
.*: [^\t]* move gp,v0
.*: [^\t]* addiu sp,-32
.*: [^\t]* sw v0,16\(sp\)
.*: [^\t]* sw ra,20\(sp\)
.*: [^\t]* lw v0,-32736\(v0\)
.*: [^\t]* jalr v0
.*: [^\t]* move t9,v0
.*: [^\t]* lw v0,16\(sp\)
.*: [^\t]* move gp,v0
.*: [^\t]* lw v0,-32696\(v0\)
.*: [^\t]* jalr v0
.*: [^\t]* move t9,v0
.*: [^\t]* lw v0,16\(sp\)
.*: [^\t]* move gp,v0
.*: [^\t]* lw v0,20\(sp\)
.*: [^\t]* jr v0
.*: [^\t]* addiu sp,32
#...
000404c0 <__fn_used1>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40414: used1
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1045
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
000404e4 <__fn_used2>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40418: used2
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1049
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
00040508 <__fn_used3>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 4041c: used3
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1053
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
0004052c <used4>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40420: used4
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1057
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
00040550 <used5>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40424: used5
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1061
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
00040574 <used6>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40428: used6
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1065
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
00040598 <used7>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 4042c: used7
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1069
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop
000405bc <used8>:
.*: [^\t]* lui gp,.*
.*: [^\t]* addiu gp,gp,.*
.*: [^\t]* addu gp,gp,t9
# 40430: used8
.*: [^\t]* lw v0,-32744\(gp\)
.*: [^\t]* nop
.*: [^\t]* addiu v0,v0,1073
.*: [^\t]* mfc1 a0,\$f12
.*: [^\t]* jr v0
.*: [^\t]* nop

View file

@ -0,0 +1,28 @@
Primary GOT:
Canonical gp value: 00057ff0
Reserved entries:
Address Access Initial Purpose
00050000 -32752\(gp\) 00000000 Lazy resolver
00050004 -32748\(gp\) 80000000 Module pointer \(GNU extension\)
Local entries:
Address Access Initial
00050008 -32744\(gp\) 00040000
0005000c -32740\(gp\) 00040409
00050010 -32736\(gp\) 0004040d
00050014 -32732\(gp\) 00000000
00050018 -32728\(gp\) 00000000
0005001c -32724\(gp\) 00000000
00050020 -32720\(gp\) 00000000
00050024 -32716\(gp\) 00000000
00050028 -32712\(gp\) 00000000
Global entries:
Address Access Initial Sym\.Val\. Type Ndx Name
0005002c -32708\(gp\) 00040574 00040574 FUNC 6 used6
00050030 -32704\(gp\) 0004052c 0004052c FUNC 6 used4
00050034 -32700\(gp\) 00040550 00040550 FUNC 6 used5
00050038 -32696\(gp\) 00040598 00040598 FUNC 6 used7

View file

@ -0,0 +1,10 @@
# used8 should come before MIPS_GOTSYM.
#...
4: 000405bc 36 FUNC GLOBAL DEFAULT .* used8
5: .* _GLOBAL_OFFSET_TABLE_
6: 00040574 36 FUNC GLOBAL DEFAULT .* used6
7: 0004052c 36 FUNC GLOBAL DEFAULT .* used4
8: 00040550 36 FUNC GLOBAL DEFAULT .* used5
9: 00040598 36 FUNC GLOBAL DEFAULT .* used7
#pass

View file

@ -0,0 +1,9 @@
Relocation section '\.rel\.dyn' .*:
.*
0+00000 * [0-9]+ * R_MIPS_NONE *
0+50400 * [0-9]+ * R_MIPS_REL32 *
0+50404 * [0-9]+ * R_MIPS_REL32 *
0+50410 * [0-9]+ * R_MIPS_REL32 *
0+50408 * [0-9]+ * R_MIPS_REL32 * 0004052c * used4
0+50414 * [0-9]+ * R_MIPS_REL32 * 00040550 * used5

View file

@ -0,0 +1,63 @@
.abicalls
.set noreorder
.include "mips16-pic-1.inc"
# Test local stubs that are only used by MIPS16 PIC calls in this file.
lstub unused1,shared
# Test local stubs that aren't called at all.
lstub unused2,shared
# Test hidden stubs that are called by MIPS16 PIC calls in this file.
hstub unused3,shared
# Test hidden stubs that are called by MIPS16 PIC calls in another file.
hstub unused4,shared
# Test hidden stubs that aren't called at all.
hstub unused5,shared
# Test local stubs that are referenced by absolute relocations
# in this file.
lstub used1,shared
# Test hidden stubs that are referenced by absolute relocations
# in this file.
hstub used2,shared
# Test hidden stubs that are referenced by absolute relocations
# in another file.
hstub used3,shared
# Test global stubs that are referenced by absolute relocations
# in this file.
gstub used4,shared
# Test global stubs that are referenced by absolute relocations
# in another file.
gstub used5,shared
# Test global stubs that are called by MIPS16 PIC calls in this file.
gstub used6,shared
# Test global stubs that are called by MIPS16 PIC calls in another file.
gstub used7,shared
# Test global stubs that aren't referenced at all.
gstub used8,shared
.set mips16
.ent foo
foo:
pic_prologue mips16
pic_call unused1,mips16
pic_call unused3,mips16
pic_call used6,mips16
pic_epilogue
.end foo
.data
.word used1
.word used2
.word used4

View file

@ -0,0 +1,16 @@
.abicalls
.set noreorder
.include "mips16-pic-1.inc"
.set mips16
.ent bar
bar:
pic_prologue mips16
pic_call unused4,mips16
pic_call used7,mips16
pic_epilogue
.end bar
.data
.word used3
.word used5