bfd/
* 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:
parent
d57a3c85f6
commit
738e53487d
36 changed files with 2862 additions and 145 deletions
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
348
bfd/elfxx-mips.c
348
bfd/elfxx-mips.c
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
17
gas/testsuite/gas/mips/elf-rel13-mips16.d
Normal file
17
gas/testsuite/gas/mips/elf-rel13-mips16.d
Normal 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
|
24
gas/testsuite/gas/mips/elf-rel13-mips16.s
Normal file
24
gas/testsuite/gas/mips/elf-rel13-mips16.s
Normal 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
|
38
gas/testsuite/gas/mips/elf-rel8-mips16.d
Normal file
38
gas/testsuite/gas/mips/elf-rel8-mips16.d
Normal 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
|
39
gas/testsuite/gas/mips/elf-rel8-mips16.s
Normal file
39
gas/testsuite/gas/mips/elf-rel8-mips16.s
Normal 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
|
70
gas/testsuite/gas/mips/elf-rel9-mips16.d
Normal file
70
gas/testsuite/gas/mips/elf-rel9-mips16.d
Normal 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
|
59
gas/testsuite/gas/mips/elf-rel9-mips16.s
Normal file
59
gas/testsuite/gas/mips/elf-rel9-mips16.s
Normal 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
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
15
ld/testsuite/ld-mips-elf/mips16-pic-1-dummy.s
Normal file
15
ld/testsuite/ld-mips-elf/mips16-pic-1-dummy.s
Normal 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
|
1227
ld/testsuite/ld-mips-elf/mips16-pic-1.dd
Normal file
1227
ld/testsuite/ld-mips-elf/mips16-pic-1.dd
Normal file
File diff suppressed because it is too large
Load diff
57
ld/testsuite/ld-mips-elf/mips16-pic-1.gd
Normal file
57
ld/testsuite/ld-mips-elf/mips16-pic-1.gd
Normal 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
|
||||
|
147
ld/testsuite/ld-mips-elf/mips16-pic-1.inc
Normal file
147
ld/testsuite/ld-mips-elf/mips16-pic-1.inc
Normal 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
|
22
ld/testsuite/ld-mips-elf/mips16-pic-1.ld
Normal file
22
ld/testsuite/ld-mips-elf/mips16-pic-1.ld
Normal 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) }
|
||||
}
|
144
ld/testsuite/ld-mips-elf/mips16-pic-1a.s
Normal file
144
ld/testsuite/ld-mips-elf/mips16-pic-1a.s
Normal 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
|
19
ld/testsuite/ld-mips-elf/mips16-pic-1b.s
Normal file
19
ld/testsuite/ld-mips-elf/mips16-pic-1b.s
Normal 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
|
6
ld/testsuite/ld-mips-elf/mips16-pic-2.ad
Normal file
6
ld/testsuite/ld-mips-elf/mips16-pic-2.ad
Normal file
|
@ -0,0 +1,6 @@
|
|||
# [MIPS_GOTSYM, MIPS_SYMTABNO) covers used4...used7.
|
||||
#...
|
||||
.* \(MIPS_SYMTABNO\) * 10
|
||||
#...
|
||||
.* \(MIPS_GOTSYM\) * 0x6
|
||||
#pass
|
208
ld/testsuite/ld-mips-elf/mips16-pic-2.dd
Normal file
208
ld/testsuite/ld-mips-elf/mips16-pic-2.dd
Normal 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
|
28
ld/testsuite/ld-mips-elf/mips16-pic-2.gd
Normal file
28
ld/testsuite/ld-mips-elf/mips16-pic-2.gd
Normal 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
|
||||
|
10
ld/testsuite/ld-mips-elf/mips16-pic-2.nd
Normal file
10
ld/testsuite/ld-mips-elf/mips16-pic-2.nd
Normal 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
|
9
ld/testsuite/ld-mips-elf/mips16-pic-2.rd
Normal file
9
ld/testsuite/ld-mips-elf/mips16-pic-2.rd
Normal 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
|
63
ld/testsuite/ld-mips-elf/mips16-pic-2a.s
Normal file
63
ld/testsuite/ld-mips-elf/mips16-pic-2a.s
Normal 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
|
16
ld/testsuite/ld-mips-elf/mips16-pic-2b.s
Normal file
16
ld/testsuite/ld-mips-elf/mips16-pic-2b.s
Normal 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
|
Loading…
Reference in a new issue