bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 6 Aug 2008 19:44:47 +0000 (19:44 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Wed, 6 Aug 2008 19:44:47 +0000 (19:44 +0000)
* 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.

36 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-mips.c
bfd/elf64-mips.c
bfd/elfn32-mips.c
bfd/elfxx-mips.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/elf-rel13-mips16.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel13-mips16.s [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel8-mips16.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel8-mips16.s [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel9-mips16.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel9-mips16.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/mips16-intermix.d
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.d
ld/testsuite/ld-mips-elf/mips16-pic-1-dummy.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1.dd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1.gd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1.inc [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1.ld [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1a.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-1b.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2.ad [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2.dd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2.gd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2.nd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2.rd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2a.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-pic-2b.s [new file with mode: 0644]

index 1bcbc408350696b8a810b6030a3910a6abbc335c..ead15cdd1c9bd04abc0f665bc7129edd77247fc9 100644 (file)
@@ -1,3 +1,60 @@
+2008-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * reloc.c (BFD_RELOC_MIPS16_GOT16, BFD_RELOC_MIPS16_CALL16): Declare.
+       * libbfd.h, bfd-in2.h: Regenerate.
+       * elf32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
+       R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+       (mips16_reloc_map): Add mappings.
+       * elf64-mips.c (mips16_elf64_howto_table_rel): Fill in reserved
+       R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+       (mips16_elf64_howto_table_rela): Likewise.
+       (mips16_reloc_map): Add mappings.
+       * elfn32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
+       R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+       (elf_mips16_howto_table_rela): Likewise.
+       (mips16_reloc_map): Add mappings.
+       * elfxx-mips.c (mips_elf_create_shadow_symbol): New function.
+       (section_allows_mips16_refs_p): Likewise.
+       (mips16_stub_symndx): Likewise.
+       (mips_elf_check_mips16_stubs): Treat the data argument as a
+       bfd_link_info.  Mark every dynamic symbol as needing MIPS16 stubs
+       and create a "shadow" symbol for the original MIPS16 definition.
+       (mips16_reloc_p, got16_reloc_p, call16_reloc_p, hi16_reloc_p)
+       (lo16_reloc_p, mips16_call_reloc_p): New functions.
+       (_bfd_mips16_elf_reloc_unshuffle): Use mips16_reloc_p to generalize
+       relocation checks.
+       (_bfd_mips16_elf_reloc_shuffle): Likewise.
+       (_bfd_mips_elf_lo16_reloc): Handle R_MIPS16_GOT16.
+       (mips_elf_got16_entry): Add comment.
+       (mips_elf_calculate_relocation): Use hi16_reloc_p,
+       lo16_reloc_p, mips16_call_reloc_p, call16_reloc_p and got16_reloc_p
+       to generalize relocation checks.  Use section_allows_mips16_refs_p
+       instead of mips16_stub_section_p.   Handle R_MIPS16_CALL16 and
+       R_MIPS16_GOT16, allowing the former to refer directly to a
+       MIPS16 function if its stub is not needed.
+       (mips16_stub_section_p): Delete.
+       (_bfd_mips_elf_symbol_processing): Convert odd-valued function
+       symbols into even MIPS16 symbols.
+       (mips_elf_add_lo16_rel_addend): Use mips16_reloc_p to generalize
+       a relocation check.
+       (_bfd_mips_elf_check_relocs): Calculate "bed" and "rel_end"
+       earlier in the function.  Use mips16_stub_symndx to identify
+       the target function.  Avoid out-of-bounds accesses when the
+       stub has no relocations; report an error instead.  Use
+       section_allows_mips16_refs_p instead of mips16_stub_section_p.
+       Use mips16_call_reloc_p and got16_reloc_p to generalize relocation
+       checks.  Handle R_MIPS16_CALL16 and R_MIPS16_GOT16.  Don't create
+       dynamic relocations for absolute references to __gnu_local_gp.
+       (_bfd_mips_elf_always_size_sections): Pass a bfd_link_info as
+       the argument to mips_elf_check_mips16_stubs.  Generalize comment.
+       (_bfd_mips_elf_relocate_section): Use hi16_reloc_p and got16_reloc_p
+       to generalize relocation checks.
+       (_bfd_mips_elf_finish_dynamic_symbol): If a dynamic MIPS16 function
+       symbol has a non-MIPS16 stub, redirect the symbol to the stub.
+       Fix an overly long line.  Don't give dynamic symbols type STO_MIPS16.
+       (_bfd_mips_elf_gc_sweep_hook): Handle R_MIPS16_CALL16 and
+       R_MIPS16_GOT16.
+
 2008-08-06  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-ppc.c (ppc_elf_relax_section): Clear R_PPC_PLTREL24 addend.
index f8e34acd9fe2fa230850a654bd1aeffdde866f92..edd0e2a2a19267fd96be14afb356eae9b78e20fa 100644 (file)
@@ -2604,6 +2604,11 @@ to compensate for the borrow when the low bits are added.  */
 /* Low 16 bits of pc-relative value  */
   BFD_RELOC_LO16_PCREL,
 
+/* Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+16-bit immediate fields  */
+  BFD_RELOC_MIPS16_GOT16,
+  BFD_RELOC_MIPS16_CALL16,
+
 /* MIPS16 high 16 bits of 32-bit value.  */
   BFD_RELOC_MIPS16_HI16,
 
index 3d39dc9361217ff98f3c454f7e073559e37d16ac..81699916faf22bfeb7e72b6d10a510a36b46cf93 100644 (file)
@@ -771,11 +771,35 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 reference to global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_GOT16),
+  /* A MIPS16 reference to the global offset table.  */
+  HOWTO (R_MIPS16_GOT16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_got16_reloc, /* special_function */
+        "R_MIPS16_GOT16",      /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 16 bit call through global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_CALL16),
+  /* A MIPS16 call through the global offset table.  */
+  HOWTO (R_MIPS16_CALL16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_generic_reloc, /* special_function */
+        "R_MIPS16_CALL16",     /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
   HOWTO (R_MIPS16_HI16,                /* type */
@@ -1224,6 +1248,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
 {
   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
 };
index e8e00fb9e8c1137e98b627e6d2494153fc947df5..520fafe68c67ce7718602af391e1ea063a04fc6b 100644 (file)
@@ -1503,11 +1503,35 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 reference to global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_GOT16),
+  /* A MIPS16 reference to the global offset table.  */
+  HOWTO (R_MIPS16_GOT16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_got16_reloc, /* special_function */
+        "R_MIPS16_GOT16",      /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 16 bit call through global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_CALL16),
+  /* A MIPS16 call through the global offset table.  */
+  HOWTO (R_MIPS16_CALL16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_generic_reloc, /* special_function */
+        "R_MIPS16_CALL16",     /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
   HOWTO (R_MIPS16_HI16,                /* type */
@@ -1575,11 +1599,35 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 reference to global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_GOT16),
+  /* A MIPS16 reference to the global offset table.  */
+  HOWTO (R_MIPS16_GOT16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_got16_reloc, /* special_function */
+        "R_MIPS16_GOT16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 16 bit call through global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_CALL16),
+  /* A MIPS16 call through the global offset table.  */
+  HOWTO (R_MIPS16_CALL16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_generic_reloc, /* special_function */
+        "R_MIPS16_CALL16",     /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
   HOWTO (R_MIPS16_HI16,                /* type */
@@ -2197,6 +2245,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
 {
   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
 };
index 74133c5a9df3304344eaa42834c1627ae3523f48..2a2d59ed3480e56060e459424510920874a0b884 100644 (file)
@@ -1496,11 +1496,35 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 reference to global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_GOT16),
+  /* A MIPS16 reference to the global offset table.  */
+  HOWTO (R_MIPS16_GOT16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_got16_reloc, /* special_function */
+        "R_MIPS16_GOT16",      /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 16 bit call through global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_CALL16),
+  /* A MIPS16 call through the global offset table.  */
+  HOWTO (R_MIPS16_CALL16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_generic_reloc, /* special_function */
+        "R_MIPS16_CALL16",     /* name */
+        TRUE,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
   HOWTO (R_MIPS16_HI16,                /* type */
@@ -1568,11 +1592,35 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 reference to global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_GOT16),
+  /* A MIPS16 reference to the global offset table.  */
+  HOWTO (R_MIPS16_GOT16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_got16_reloc, /* special_function */
+        "R_MIPS16_GOT16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
-  /* A placeholder for MIPS16 16 bit call through global offset table.  */
-  EMPTY_HOWTO (R_MIPS16_CALL16),
+  /* A MIPS16 call through the global offset table.  */
+  HOWTO (R_MIPS16_CALL16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_generic_reloc, /* special_function */
+        "R_MIPS16_CALL16",     /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
   HOWTO (R_MIPS16_HI16,                /* type */
@@ -2041,6 +2089,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
 {
   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
 };
index 827915caa9e1eca40e8d7be612cff547f5d8fb4f..00f33bd64ec6bce3ba5b464d02adde81184e8ea8 100644 (file)
@@ -525,8 +525,6 @@ static bfd_boolean mips_elf_sort_hash_table_f
   (struct mips_elf_link_hash_entry *, void *);
 static bfd_vma mips_elf_high
   (bfd_vma);
-static bfd_boolean mips16_stub_section_p
-  (bfd *, asection *);
 static bfd_boolean mips_elf_create_dynamic_relocation
   (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
    struct mips_elf_link_hash_entry *, asection *, bfd_vma,
@@ -1148,17 +1146,104 @@ mips_elf_create_procedure_table (void *handle, bfd *abfd,
     free (sv);
   return FALSE;
 }
+\f
+/* 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.  */
+
+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;
+}
 
-   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
+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);
-}
 \f
 /* 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);
+    }
 }
 \f
 /* 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:
index 2c974986792ca32ad4e96d6cda6603a998c0f9f5..640b2840f5391cc9c0e21097b5847b8b0d41c40a 100644 (file)
@@ -964,6 +964,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_HI16_PCREL",
   "BFD_RELOC_HI16_S_PCREL",
   "BFD_RELOC_LO16_PCREL",
+  "BFD_RELOC_MIPS16_GOT16",
+  "BFD_RELOC_MIPS16_CALL16",
   "BFD_RELOC_MIPS16_HI16",
   "BFD_RELOC_MIPS16_HI16_S",
   "BFD_RELOC_MIPS16_LO16",
index 03f0f9f32880bb2bbf8992deec19334d6eb5126d..8881f8f23bfc1684a2244da04963dbea592e01da 100644 (file)
@@ -2153,6 +2153,13 @@ ENUM
 ENUMDOC
   Low 16 bits of pc-relative value
 
+ENUM
+  BFD_RELOC_MIPS16_GOT16
+ENUMX
+  BFD_RELOC_MIPS16_CALL16
+ENUMDOC
+  Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+     16-bit immediate fields
 ENUM
   BFD_RELOC_MIPS16_HI16
 ENUMDOC
index 6f03d9230a18138f815c3e4b2f55c4d31f3492e4..11a0d246821b3aa60e482aba81b289c3133e548a 100644 (file)
@@ -1,3 +1,23 @@
+2008-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/tc-mips.c (mips16_reloc_p, got16_reloc_p, hi16_reloc_p)
+       (lo16_reloc_p): New functions.
+       (reloc_needs_lo_p): Use hi16_reloc_p and got16_reloc_p to
+       generalize relocation checks.
+       (matching_lo_reloc): New function.
+       (fixup_has_matching_lo_p): Use it.
+       (mips16_mark_labels): Don't clobber a symbol's visibility.
+       (append_insn): Use hi16_reloc_p and lo16_reloc_p.
+       (mips16_ip): Handle BFD_RELOC_MIPS16_GOT16 and BFD_RELOC_MIPS16_CALL16.
+       (md_apply_fix): Likewise.
+       (mips16_percent_op): Add %got and %call16.
+       (mips_frob_file): Use got16_reloc_p to generalize relocation checks.
+       Use matching_lo_reloc.
+       (mips_force_relocation): Use hi16_reloc_p and lo16_reloc_p to
+       generalize relocation checks.
+       (mips_fix_adjustable): Use lo16_reloc_p to generalize relocation
+       checks.
+
 2008-08-06  DJ Delorie  <dj@redhat.com>
 
        * NEWS: Mention these changes.
index 1e2adc39ae0bf719d521518fcbb697dd012ff0a9..c03cca2e0465d55087198d71c4a8631be8bf1f16 100644 (file)
@@ -2129,6 +2129,46 @@ md_assemble (char *str)
     }
 }
 
+/* Convenience functions for abstracting away the differences between
+   MIPS16 and non-MIPS16 relocations.  */
+
+static inline bfd_boolean
+mips16_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  switch (reloc)
+    {
+    case BFD_RELOC_MIPS16_JMP:
+    case BFD_RELOC_MIPS16_GPREL:
+    case BFD_RELOC_MIPS16_GOT16:
+    case BFD_RELOC_MIPS16_CALL16:
+    case BFD_RELOC_MIPS16_HI16_S:
+    case BFD_RELOC_MIPS16_HI16:
+    case BFD_RELOC_MIPS16_LO16:
+      return TRUE;
+
+    default:
+      return FALSE;
+    }
+}
+
+static inline bfd_boolean
+got16_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16;
+}
+
+static inline bfd_boolean
+hi16_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S;
+}
+
+static inline bfd_boolean
+lo16_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16;
+}
+
 /* Return true if the given relocation might need a matching %lo().
    This is only "might" because SVR4 R_MIPS_GOT16 relocations only
    need a matching %lo() when applied to local symbols.  */
@@ -2137,11 +2177,19 @@ static inline bfd_boolean
 reloc_needs_lo_p (bfd_reloc_code_real_type reloc)
 {
   return (HAVE_IN_PLACE_ADDENDS
-         && (reloc == BFD_RELOC_HI16_S
-             || reloc == BFD_RELOC_MIPS16_HI16_S
+         && (hi16_reloc_p (reloc)
              /* VxWorks R_MIPS_GOT16 relocs never need a matching %lo();
                 all GOT16 relocations evaluate to "G".  */
-             || (reloc == BFD_RELOC_MIPS_GOT16 && mips_pic != VXWORKS_PIC)));
+             || (got16_reloc_p (reloc) && mips_pic != VXWORKS_PIC)));
+}
+
+/* Return the type of %lo() reloc needed by RELOC, given that
+   reloc_needs_lo_p.  */
+
+static inline bfd_reloc_code_real_type
+matching_lo_reloc (bfd_reloc_code_real_type reloc)
+{
+  return mips16_reloc_p (reloc) ? BFD_RELOC_MIPS16_LO16 : BFD_RELOC_LO16;
 }
 
 /* Return true if the given fixup is followed by a matching R_MIPS_LO16
@@ -2151,8 +2199,7 @@ static inline bfd_boolean
 fixup_has_matching_lo_p (fixS *fixp)
 {
   return (fixp->fx_next != NULL
-         && (fixp->fx_next->fx_r_type == BFD_RELOC_LO16
-            || fixp->fx_next->fx_r_type == BFD_RELOC_MIPS16_LO16)
+         && fixp->fx_next->fx_r_type == matching_lo_reloc (fixp->fx_r_type)
          && fixp->fx_addsy == fixp->fx_next->fx_addsy
          && fixp->fx_offset == fixp->fx_next->fx_offset);
 }
@@ -2934,8 +2981,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              && (reloc_type[0] == BFD_RELOC_16
                  || reloc_type[0] == BFD_RELOC_32
                  || reloc_type[0] == BFD_RELOC_MIPS_JMP
-                 || reloc_type[0] == BFD_RELOC_HI16_S
-                 || reloc_type[0] == BFD_RELOC_LO16
                  || reloc_type[0] == BFD_RELOC_GPREL16
                  || reloc_type[0] == BFD_RELOC_MIPS_LITERAL
                  || reloc_type[0] == BFD_RELOC_GPREL32
@@ -2948,8 +2993,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  || reloc_type[0] == BFD_RELOC_MIPS_REL16
                  || reloc_type[0] == BFD_RELOC_MIPS_RELGOT
                  || reloc_type[0] == BFD_RELOC_MIPS16_GPREL
-                 || reloc_type[0] == BFD_RELOC_MIPS16_HI16_S
-                 || reloc_type[0] == BFD_RELOC_MIPS16_LO16))
+                 || hi16_reloc_p (reloc_type[0])
+                 || lo16_reloc_p (reloc_type[0])))
            ip->fixp[0]->fx_no_overflow = 1;
 
          if (mips_relax.sequence)
@@ -10092,6 +10137,8 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
                  /* Stuff the immediate value in now, if we can.  */
                  if (imm_expr.X_op == O_constant
                      && *imm_reloc > BFD_RELOC_UNUSED
+                     && *imm_reloc != BFD_RELOC_MIPS16_GOT16
+                     && *imm_reloc != BFD_RELOC_MIPS16_CALL16
                      && insn->pinfo != INSN_MACRO)
                    {
                      valueT tmp;
@@ -10861,6 +10908,8 @@ static const struct percent_op_match mips16_percent_op[] =
 {
   {"%lo", BFD_RELOC_MIPS16_LO16},
   {"%gprel", BFD_RELOC_MIPS16_GPREL},
+  {"%got", BFD_RELOC_MIPS16_GOT16},
+  {"%call16", BFD_RELOC_MIPS16_CALL16},
   {"%hi", BFD_RELOC_MIPS16_HI16_S}
 };
 
@@ -11954,7 +12003,7 @@ mips_frob_file (void)
 
       /* If a GOT16 relocation turns out to be against a global symbol,
         there isn't supposed to be a matching LO.  */
-      if (l->fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
+      if (got16_reloc_p (l->fixp->fx_r_type)
          && !pic_need_relax (l->fixp->fx_addsy, l->seg))
        continue;
 
@@ -11972,12 +12021,7 @@ mips_frob_file (void)
       hi_pos = NULL;
       lo_pos = NULL;
       matched_lo_p = FALSE;
-      
-      if (l->fixp->fx_r_type == BFD_RELOC_MIPS16_HI16
-          || l->fixp->fx_r_type == BFD_RELOC_MIPS16_HI16_S)
-        looking_for_rtype = BFD_RELOC_MIPS16_LO16;
-      else
-        looking_for_rtype = BFD_RELOC_LO16;
+      looking_for_rtype = matching_lo_reloc (l->fixp->fx_r_type);
 
       for (pos = &seginfo->fix_root; *pos != NULL; pos = &(*pos)->fx_next)
        {
@@ -12030,8 +12074,8 @@ mips_force_relocation (fixS *fixp)
   if (HAVE_NEWABI
       && S_GET_SEGMENT (fixp->fx_addsy) == bfd_abs_section_ptr
       && (fixp->fx_r_type == BFD_RELOC_MIPS_SUB
-         || fixp->fx_r_type == BFD_RELOC_HI16_S
-         || fixp->fx_r_type == BFD_RELOC_LO16))
+         || hi16_reloc_p (fixp->fx_r_type)
+         || lo16_reloc_p (fixp->fx_r_type)))
     return 1;
 
   return 0;
@@ -12119,6 +12163,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS_CALL_HI16:
     case BFD_RELOC_MIPS_CALL_LO16:
     case BFD_RELOC_MIPS16_GPREL:
+    case BFD_RELOC_MIPS16_GOT16:
+    case BFD_RELOC_MIPS16_CALL16:
     case BFD_RELOC_MIPS16_HI16:
     case BFD_RELOC_MIPS16_HI16_S:
     case BFD_RELOC_MIPS16_JMP:
@@ -13926,8 +13972,7 @@ mips_fix_adjustable (fixS *fixp)
      placed anywhere.  Rather than break backwards compatibility by changing
      this, it seems better not to force the issue, and instead keep the
      original symbol.  This will work with either linker behavior.  */
-  if ((fixp->fx_r_type == BFD_RELOC_LO16
-       || fixp->fx_r_type == BFD_RELOC_MIPS16_LO16
+  if ((lo16_reloc_p (fixp->fx_r_type)
        || reloc_needs_lo_p (fixp->fx_r_type))
       && HAVE_IN_PLACE_ADDENDS
       && (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
index 7516f50c323a5c0c3a773056a549731fe9a69ea4..e75b7cf50a49445fc0204964d57e07a7aa3b4554 100644 (file)
@@ -1,3 +1,10 @@
+2008-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * gas/mips/elf-rel8-mips16.d, gas/mips/elf-rel8-mips16.s,
+       * gas/mips/elf-rel9-mips16.d, gas/mips/elf-rel9-mips16.s,
+       * gas/mips/elf-rel13-mips16.d, gas/mips/elf-rel13-mips16.s: New tests.
+       * gas/mips/mips.exp: Run them.
+
 2008-08-01  Peter Bergner  <bergner@vnet.ibm.com>
 
        * gas/ppc/power7.d: New.
diff --git a/gas/testsuite/gas/mips/elf-rel13-mips16.d b/gas/testsuite/gas/mips/elf-rel13-mips16.d
new file mode 100644 (file)
index 0000000..aa404ab
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/mips/elf-rel13-mips16.s b/gas/testsuite/gas/mips/elf-rel13-mips16.s
new file mode 100644 (file)
index 0000000..2983f0e
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/mips/elf-rel8-mips16.d b/gas/testsuite/gas/mips/elf-rel8-mips16.d
new file mode 100644 (file)
index 0000000..7c834fa
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/mips/elf-rel8-mips16.s b/gas/testsuite/gas/mips/elf-rel8-mips16.s
new file mode 100644 (file)
index 0000000..0c9eefe
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/mips/elf-rel9-mips16.d b/gas/testsuite/gas/mips/elf-rel9-mips16.d
new file mode 100644 (file)
index 0000000..738c6fd
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/mips/elf-rel9-mips16.s b/gas/testsuite/gas/mips/elf-rel9-mips16.s
new file mode 100644 (file)
index 0000000..a4f54ed
--- /dev/null
@@ -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
index 16edfb73a9bab35a91413e3195c35025ce06e9cd..3c4a9192079af95bdcecad256d7bc4bdd8a47f04 100644 (file)
@@ -653,13 +653,16 @@ if { [istarget mips*-*-vxworks*] } {
        }
        run_dump_test "elf-rel7"
        run_dump_test "elf-rel8"
+       run_dump_test "elf-rel8-mips16"
        run_dump_test "elf-rel9"
+       run_dump_test "elf-rel9-mips16"
        if $has_newabi {
            run_dump_test "elf-rel10"
            run_dump_test "elf-rel11"
        }
        run_dump_test "elf-rel12"
        run_dump_test "elf-rel13"
+       run_dump_test "elf-rel13-mips16"
        run_dump_test "elf-rel14"
 
        if $has_newabi {
index 717d3385baf97ad25dcc1251f38fefe10c41bad2..60e3601f0cf69c50f1770b21e8078c16ad6f2139 100644 (file)
@@ -1,3 +1,25 @@
+2008-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * ld-mips-elf/mips16-local-stubs-1.d: Remove stub_for_h3,
+       which was only referenced by the .pdr section, and was not
+       actually needed by code.
+       * ld-mips-elf/mips16-intermix.d: Remove unused static function stubs.
+       * ld-mips-elf/mips16-pic-1a.s,
+       ld-mips-elf/mips16-pic-1b.s,
+       ld-mips-elf/mips16-pic-1-dummy.s,
+       ld-mips-elf/mips16-pic-1.dd,
+       ld-mips-elf/mips16-pic-1.gd,
+       ld-mips-elf/mips16-pic-1.inc,
+       ld-mips-elf/mips16-pic-1.ld,
+       ld-mips-elf/mips16-pic-2a.s,
+       ld-mips-elf/mips16-pic-2b.s,
+       ld-mips-elf/mips16-pic-2.ad,
+       ld-mips-elf/mips16-pic-2.dd,
+       ld-mips-elf/mips16-pic-2.gd,
+       ld-mips-elf/mips16-pic-2.nd,
+       ld-mips-elf/mips16-pic-2.rd: New tests.
+       * ld-mips-elf/mips-elf.exp: Run them.
+
 2008-08-06  Alan Modra  <amodra@bigpond.net.au>
 
        * ld-elf/extract-symbol-1sec.d: Update.
index 80493e980ec1b2ec59cc9e1e79541e4709a038c6..29cd3bb87756d7b3f1f88f0ab27b0ba2e561e718 100644 (file)
@@ -56,6 +56,30 @@ set has_newabi [expr [istarget *-*-irix6*] || [istarget mips64*-*-linux*]]
 set linux_gnu [expr [istarget mips*-*-linux*]]
 set embedded_elf [expr [istarget mips*-*-elf]]
 
+if { $linux_gnu } {
+    run_ld_link_tests [list \
+       [list "Dummy shared library for MIPS16 PIC test 1" \
+             "-shared -melf32btsmip" \
+             "-EB -32" { mips16-pic-1-dummy.s } \
+             {} \
+             "mips16-pic-1-dummy.so"] \
+       [list "MIPS16 PIC test 1" \
+             "-melf32btsmip -T mips16-pic-1.ld tmpdir/mips16-pic-1-dummy.so" \
+             "-EB -32 -I $srcdir/$subdir" { mips16-pic-1a.s mips16-pic-1b.s } \
+             { { objdump { -dr -j.text } mips16-pic-1.dd }
+               { readelf -A mips16-pic-1.gd } } \
+             "mips16-pic-1"] \
+       [list "MIPS16 PIC test 2" \
+             "-melf32btsmip -T mips16-pic-1.ld -shared" \
+             "-EB -32 -I $srcdir/$subdir" { mips16-pic-2a.s mips16-pic-2b.s } \
+             { { objdump { -dr -j.text } mips16-pic-2.dd } \
+               { readelf -A mips16-pic-2.gd } \
+               { readelf --symbols mips16-pic-2.nd } \
+               { readelf --relocs mips16-pic-2.rd } \
+               { readelf -d mips16-pic-2.ad } } \
+            "mips16-pic-2"]]
+}
+
 if { [istarget mips64*-linux-gnu] } {
     set o32_as_flags "-32 -EB"
     set o32_ld_flags "-melf32btsmip"
index 5c6ee689ab872ab315c2c2df0883152232a5eb07..cc8c1fe5b4a10479514d7a964bb9eef8a4d704f4 100644 (file)
@@ -14,7 +14,6 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_d
 .* l     F .text       0+[0-9a-f]+ m32_static_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_d
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static_d
 .* l     F .text       0+[0-9a-f]+ m32_static1_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static1_d
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static1_d
@@ -23,7 +22,6 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static32_d
 .* l     F .text       0+[0-9a-f]+ m32_static16_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static16_d
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static16_d
 .* l     F .text       0+[0-9a-f]+ m32_static_ld
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_ld
 .* l     F .text       0+[0-9a-f]+ m32_static1_ld
@@ -35,7 +33,6 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_dl
 .* l     F .text       0+[0-9a-f]+ m32_static_dl
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_dl
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static_dl
 .* l     F .text       0+[0-9a-f]+ m32_static1_dl
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static1_dl
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static1_dl
@@ -44,11 +41,9 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static32_dl
 .* l     F .text       0+[0-9a-f]+ m32_static16_dl
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static16_dl
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static16_dl
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_dlld
 .* l     F .text       0+[0-9a-f]+ m32_static_dlld
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_dlld
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static_dlld
 .* l     F .text       0+[0-9a-f]+ m32_static1_dlld
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static1_dlld
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static1_dlld
@@ -57,7 +52,6 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static32_dlld
 .* l     F .text       0+[0-9a-f]+ m32_static16_dlld
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static16_dlld
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static16_dlld
 .* l     F .text       0+[0-9a-f]+ m32_static_d_l
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_d_l
 .* l     F .text       0+[0-9a-f]+ m32_static1_d_l
@@ -66,10 +60,11 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static32_d_l
 .* l     F .text       0+[0-9a-f]+ m32_static16_d_l
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static16_d_l
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_d_d
+# ??? We aren't yet able to get rid of the symbol table entry for
+# __fn_stub_m16_d_d, or its .pdr entry.
+.* l     F .text       0+[0-9a-f]+ *
 .* l     F .text       0+[0-9a-f]+ m32_static_d_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static_d_d
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static_d_d
 .* l     F .text       0+[0-9a-f]+ m32_static1_d_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static1_d_d
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static1_d_d
@@ -78,7 +73,6 @@ SYMBOL TABLE:
 .* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static32_d_d
 .* l     F .text       0+[0-9a-f]+ m32_static16_d_d
 .* l     F .text       0+[0-9a-f]+ 0xf0 m16_static16_d_d
-.* l     F .text       0+[0-9a-f]+ __fn_stub_m16_static16_d_d
 #...
 .* l     F .text       0+[0-9a-f]+ __call_stub_m32_static1_d
 .* l     F .text       0+[0-9a-f]+ __call_stub_m16_static1_d
index 9990493c1b9804cbbbb20ebabd1028312f220ce6..1ffa1d124537fec26218e8df0a266406736276cb 100644 (file)
@@ -57,13 +57,13 @@ Disassembly of section \.text:
 20000068:      00000000        nop
 
 2000006c <caller2>:
-2000006c:      1c00 0030       jalx    200000c0 <stub_for_f1>
+2000006c:      1c00 002c       jalx    200000b0 <stub_for_f1>
 20000070:      6500            nop
-20000072:      1c00 0038       jalx    200000e0 <stub_for_f2>
+20000072:      1c00 0034       jalx    200000d0 <stub_for_f2>
 20000076:      6500            nop
-20000078:      1c00 0034       jalx    200000d0 <stub_for_g1>
+20000078:      1c00 0030       jalx    200000c0 <stub_for_g1>
 2000007c:      6500            nop
-2000007e:      1c00 003c       jalx    200000f0 <stub_for_g2>
+2000007e:      1c00 0038       jalx    200000e0 <stub_for_g2>
 20000082:      6500            nop
 20000084:      1800 0004       jal     20000010 <h1>
 20000088:      6500            nop
@@ -82,33 +82,26 @@ Disassembly of section \.text:
 200000a8:      00200008        jr      at
 200000ac:      00000000        nop
 
-# This isn't actually called, but is referenced from the .pdr section.
-200000b0 <stub_for_h3>:
+200000b0 <stub_for_f1>:
 200000b0:      3c012000        lui     at,0x2000
-200000b4:      24210039        addiu   at,at,57
+200000b4:      24210000        addiu   at,at,0
 200000b8:      00200008        jr      at
 200000bc:      00000000        nop
 
-200000c0 <stub_for_f1>:
+200000c0 <stub_for_g1>:
 200000c0:      3c012000        lui     at,0x2000
-200000c4:      24210000        addiu   at,at,0
+200000c4:      24210008        addiu   at,at,8
 200000c8:      00200008        jr      at
 200000cc:      00000000        nop
 
-200000d0 <stub_for_g1>:
+200000d0 <stub_for_f2>:
 200000d0:      3c012000        lui     at,0x2000
-200000d4:      24210008        addiu   at,at,8
+200000d4:      24210014        addiu   at,at,20
 200000d8:      00200008        jr      at
 200000dc:      00000000        nop
 
-200000e0 <stub_for_f2>:
+200000e0 <stub_for_g2>:
 200000e0:      3c012000        lui     at,0x2000
-200000e4:      24210014        addiu   at,at,20
+200000e4:      2421001c        addiu   at,at,28
 200000e8:      00200008        jr      at
 200000ec:      00000000        nop
-
-200000f0 <stub_for_g2>:
-200000f0:      3c012000        lui     at,0x2000
-200000f4:      2421001c        addiu   at,at,28
-200000f8:      00200008        jr      at
-200000fc:      00000000        nop
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1-dummy.s b/ld/testsuite/ld-mips-elf/mips16-pic-1-dummy.s
new file mode 100644 (file)
index 0000000..6ee56e0
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1.dd b/ld/testsuite/ld-mips-elf/mips16-pic-1.dd
new file mode 100644 (file)
index 0000000..c853733
--- /dev/null
@@ -0,0 +1,1227 @@
+
+.*
+
+
+Disassembly of section \.text:
+
+00040400 <a_unused1>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040404 <b_unused1>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040408 <callpic_unused1_mips16>:
+.*:    [^\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\)
+# 0x40400: a_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
+# 0x40404: b_unused2
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,1029
+.*:    [^\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
+
+00040444 <a_unused2>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040448 <b_unused2>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004044c <jals_unused2_mips16>:
+.*:    [^\t]*  jal     .* <a_unused2>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_unused2>
+.*:    [^\t]*  nop
+
+00040458 <a_unused3>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004045c <b_unused3>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040460 <a_unused4>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040464 <b_unused4>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040468 <callpic_unused4_mips16>:
+.*:    [^\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,-32740\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32736\(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
+
+0004049c <a_unused5>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404a0 <b_unused5>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404a4 <jals_unused5_mips16>:
+.*:    [^\t]*  jal     .* <a_unused5>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_unused5>
+.*:    [^\t]*  nop
+
+000404b0 <a_unused6>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404b4 <b_unused6>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404b8 <a_unused7>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404bc <b_unused7>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404c0 <a_unused8>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404c4 <b_unused8>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404c8 <a_unused9>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404cc <b_unused9>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404d0 <jals_unused9_mips16>:
+.*:    [^\t]*  jal     .* <a_unused9>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_unused9>
+.*:    [^\t]*  nop
+
+000404dc <a_unused10>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404e0 <b_unused10>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404e4 <a_unused11>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404e8 <b_unused11>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404ec <a_used1>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404f0 <b_used1>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000404f4 <callpic_used1_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+# 0x40b10: __fn_a_used1
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,v0,2832
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+# 0x40b24: __fn_b_used1
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,v0,2852
+.*:    [^\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,sp,32
+
+0004054c <a_used2>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040550 <b_used2>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040554 <jals_used2_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used2>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used2>
+.*:    [^\t]*  nop
+
+00040564 <a_used3>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040568 <b_used3>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004056c <callpic_used3_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+# 0x40b80: __fn_a_used3
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,v0,2944
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+# 0x40b94: __fn_b_used3
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,v0,2964
+.*:    [^\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,sp,32
+
+000405c4 <callpic_used3_mips16>:
+.*:    [^\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\)
+# 0x40564: a_used3
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,1381
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+# 0x40568: b_used3
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,1385
+.*:    [^\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
+
+00040600 <a_used4>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040604 <b_used4>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040608 <jals_used4_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used4>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used4>
+.*:    [^\t]*  nop
+
+00040618 <jals_used4_mips16>:
+.*:    [^\t]*  jal     .* <a_used4>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_used4>
+.*:    [^\t]*  nop
+
+00040624 <a_used5>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040628 <b_used5>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004062c <jals_used5_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used5>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used5>
+.*:    [^\t]*  nop
+
+0004063c <callpic_used5_mips16>:
+.*:    [^\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\)
+# 0x40624: a_used5
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,1573
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+# 0x40628: b_used5
+.*:    [^\t]*  lw      v0,-32744\(v0\)
+.*:    [^\t]*  addiu   v0,1577
+.*:    [^\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
+
+00040678 <a_used6>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004067c <b_used6>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040680 <callpic_used6_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32732\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32728\(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,sp,32
+
+000406d0 <a_used7>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406d4 <b_used7>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406d8 <jals_used7_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used7>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used7>
+.*:    [^\t]*  nop
+
+000406e8 <a_used8>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406ec <b_used8>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406f0 <a_used9>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406f4 <b_used9>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406f8 <a_used10>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000406fc <b_used10>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040700 <callpic_used10_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32724\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32720\(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,sp,32
+
+00040750 <callpic_used10_mips16>:
+.*:    [^\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,-32724\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32720\(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
+
+00040784 <a_used11>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040788 <b_used11>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004078c <jals_used11_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used11>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used11>
+.*:    [^\t]*  nop
+
+0004079c <jals_used11_mips16>:
+.*:    [^\t]*  jal     .* <a_used11>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_used11>
+.*:    [^\t]*  nop
+
+000407a8 <a_used12>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000407ac <b_used12>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000407b0 <jals_used12_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used12>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used12>
+.*:    [^\t]*  nop
+
+000407c0 <callpic_used12_mips16>:
+.*:    [^\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,-32716\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32712\(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
+
+000407f4 <.mips16.a_used13>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000407f8 <.mips16.b_used13>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000407fc <callpic_used13_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32660\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32632\(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,sp,32
+
+0004084c <a_used14>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040850 <b_used14>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040854 <jals_used14_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used14>
+.*:    [^\t]*  nop
+ .*:   [^\t]*  jal     .* <__fn_b_used14>
+.*:    [^\t]*  nop
+
+00040864 <.mips16.a_used15>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040868 <.mips16.b_used15>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004086c <a_used16>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040870 <b_used16>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040874 <.mips16.a_used17>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040878 <.mips16.b_used17>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004087c <callpic_used17_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32676\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32656\(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,sp,32
+
+000408cc <callpic_used17_mips16>:
+.*:    [^\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,-32676\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32656\(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
+
+00040900 <a_used18>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040904 <b_used18>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040908 <jals_used18_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used18>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used18>
+.*:    [^\t]*  nop
+
+00040918 <jals_used18_mips16>:
+.*:    [^\t]*  jal     .* <a_used18>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_used18>
+.*:    [^\t]*  nop
+
+00040924 <.mips16.a_used19>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040928 <.mips16.b_used19>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+0004092c <jals_used19_nomips16>:
+.*:    [^\t]*  jal     .* <a_used19>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_used19>
+.*:    [^\t]*  nop
+
+0004093c <callpic_used19_mips16>:
+.*:    [^\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,-32644\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32672\(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
+
+00040970 <.mips16.a_used20>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040974 <.mips16.b_used20>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+00040978 <callpic_used20_mips16>:
+.*:    [^\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,-32668\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32652\(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
+
+000409ac <.mips16.a_used21>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+
+000409b0 <.mips16.b_used21>:
+.*:    [^\t]*  jr      ra
+.*:    [^\t]*  nop
+#...
+
+000409c0 <callpic_unused6_mips16>:
+.*:    [^\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,-32708\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32704\(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
+
+000409f4 <jals_unused7_mips16>:
+.*:    [^\t]*  jal     .* <a_unused7>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_unused7>
+.*:    [^\t]*  nop
+
+00040a00 <jals_unused10_mips16>:
+.*:    [^\t]*  jal     .* <a_unused10>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <b_unused10>
+.*:    [^\t]*  nop
+
+00040a0c <callpic_used8_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32700\(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,sp,32
+
+00040a5c <jals_used9_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used9>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used9>
+.*:    [^\t]*  nop
+
+00040a6c <callpic_used15_nomips16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+.*:    [^\t]*  move    v0,gp
+.*:    [^\t]*  addiu   sp,sp,-32
+.*:    [^\t]*  sw      v0,16\(sp\)
+.*:    [^\t]*  sw      ra,20\(sp\)
+.*:    [^\t]*  lw      v0,-32664\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32640\(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,sp,32
+
+00040abc <jals_used16_nomips16>:
+.*:    [^\t]*  jal     .* <__fn_a_used16>
+.*:    [^\t]*  nop
+.*:    [^\t]*  jal     .* <__fn_b_used16>
+.*:    [^\t]*  nop
+
+00040acc <callpic_used21_mips16>:
+.*:    [^\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,-32648\(v0\)
+.*:    [^\t]*  jalr    v0
+.*:    [^\t]*  move    t9,v0
+.*:    [^\t]*  lw      v0,16\(sp\)
+.*:    [^\t]*  move    gp,v0
+.*:    [^\t]*  lw      v0,-32636\(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
+
+00040b00 <__start>:
+       \.\.\.
+
+00040b10 <__fn_a_used1>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040b24 <__fn_b_used1>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x404f0: b_used1
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1265
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040b48 <__fn_a_used2>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040b5c <__fn_b_used2>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40550: b_used2
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1361
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040b80 <__fn_a_used3>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040b94 <__fn_b_used3>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40568: b_used3
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1385
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040bb8 <__fn_a_used4>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040bcc <__fn_b_used4>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40604: b_used4
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1541
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040bf0 <__fn_a_used5>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c04 <__fn_b_used5>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40628: b_used5
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1577
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c28 <__fn_a_used6>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c3c <__fn_b_used6>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x4067c: b_used6
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1661
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c60 <__fn_a_used7>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c74 <__fn_b_used7>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x406d4: b_used7
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1749
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040c98 <__fn_a_used8>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040cac <__fn_b_used8>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x406ec: b_used8
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1773
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040cd0 <__fn_a_used9>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040ce4 <__fn_b_used9>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x406f4: b_used9
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1781
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d08 <__fn_a_used10>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d1c <__fn_b_used10>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x406fc: b_used10
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1789
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d40 <__fn_a_used11>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d54 <__fn_b_used11>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40788: b_used11
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1929
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d78 <__fn_a_used12>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040d8c <__fn_b_used12>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x407ac: b_used12
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,1965
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040db0 <a_used13>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040dc4 <b_used13>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x407f8: .mips16.b_used13
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2041
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040de8 <__fn_a_used14>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040dfc <__fn_b_used14>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40850: b_used14
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2129
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040e20 <a_used15>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040e34 <b_used15>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40628: .mips16.b_used15
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2153
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040e58 <__fn_a_used16>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040e6c <__fn_b_used16>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40870: b_used16
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2161
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040e90 <a_used17>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040ea4 <b_used17>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40878: .mips16.b_used17
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2169
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040ec8 <__fn_a_used18>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040edc <__fn_b_used18>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40904: b_used18
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2309
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f00 <a_used19>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f14 <b_used19>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40928: .mips16.b_used19
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2345
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f38 <a_used20>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f4c <b_used20>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x40974: .mips16.b_used20
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2421
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f70 <a_used21>:
+.*:    [^\t]*  lui     v0,.*
+.*:    [^\t]*  addiu   v0,v0,.*
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
+
+00040f84 <b_used21>:
+.*:    [^\t]*  lui     gp,.*
+.*:    [^\t]*  addiu   gp,gp,.*
+.*:    [^\t]*  addu    gp,gp,t9
+# 0x409b0: .mips16.b_used21
+.*:    [^\t]*  lw      v0,-32744\(gp\)
+.*:    [^\t]*  nop
+.*:    [^\t]*  addiu   v0,v0,2481
+.*:    [^\t]*  mfc1    a0,\$f12
+.*:    [^\t]*  jr      v0
+.*:    [^\t]*  nop
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1.gd b/ld/testsuite/ld-mips-elf/mips16-pic-1.gd
new file mode 100644 (file)
index 0000000..874a319
--- /dev/null
@@ -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
+
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1.inc b/ld/testsuite/ld-mips-elf/mips16-pic-1.inc
new file mode 100644 (file)
index 0000000..9268a07
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1.ld b/ld/testsuite/ld-mips-elf/mips16-pic-1.ld
new file mode 100644 (file)
index 0000000..91f1464
--- /dev/null
@@ -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) }
+}
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1a.s b/ld/testsuite/ld-mips-elf/mips16-pic-1a.s
new file mode 100644 (file)
index 0000000..14ea93c
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-1b.s b/ld/testsuite/ld-mips-elf/mips16-pic-1b.s
new file mode 100644 (file)
index 0000000..9a17072
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2.ad b/ld/testsuite/ld-mips-elf/mips16-pic-2.ad
new file mode 100644 (file)
index 0000000..95c53e5
--- /dev/null
@@ -0,0 +1,6 @@
+# [MIPS_GOTSYM, MIPS_SYMTABNO) covers used4...used7.
+#...
+ .* \(MIPS_SYMTABNO\) * 10
+#...
+ .* \(MIPS_GOTSYM\) * 0x6
+#pass
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2.dd b/ld/testsuite/ld-mips-elf/mips16-pic-2.dd
new file mode 100644 (file)
index 0000000..75ea6dc
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2.gd b/ld/testsuite/ld-mips-elf/mips16-pic-2.gd
new file mode 100644 (file)
index 0000000..ebc341e
--- /dev/null
@@ -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
+
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2.nd b/ld/testsuite/ld-mips-elf/mips16-pic-2.nd
new file mode 100644 (file)
index 0000000..c4ad9fd
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2.rd b/ld/testsuite/ld-mips-elf/mips16-pic-2.rd
new file mode 100644 (file)
index 0000000..8411dbe
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2a.s b/ld/testsuite/ld-mips-elf/mips16-pic-2a.s
new file mode 100644 (file)
index 0000000..08a1269
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-pic-2b.s b/ld/testsuite/ld-mips-elf/mips16-pic-2b.s
new file mode 100644 (file)
index 0000000..2a66b5a
--- /dev/null
@@ -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