aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2006-06-14 08:27:41 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2006-06-14 08:27:41 +0000
commitcc3e26bed74f5e492b5d042afe2c2616975de445 (patch)
tree2489da5f10688b77c52d166aac4a27ba18242287
parent5fa222e4424d1e940baaff61d73b704588ff970e (diff)
downloadfsf-binutils-gdb-cc3e26bed74f5e492b5d042afe2c2616975de445.zip
fsf-binutils-gdb-cc3e26bed74f5e492b5d042afe2c2616975de445.tar.gz
fsf-binutils-gdb-cc3e26bed74f5e492b5d042afe2c2616975de445.tar.bz2
bfd/
* elf32-m68k.c (elf_m68k_plt_info): New structure. (elf_m68k_plt0_entry): Add R_68K_PC32-style in-place addends. (elf_m68k_plt_entry): Likewise. (elf_m68k_plt_info): New table. (CFV4E_PLT_ENTRY_SIZE): Rename to... (ISAB_PLT_ENTRY_SIZE): ...this. (CFV4E_FLAG): Delete. (elf_cfv4e_plt0_entry): Rename to... (elf_isab_plt0_entry): ...this. Adjust comments. Use (-6,%pc,%d0) for the second instruction too. (elf_cfv4e_plt_entry): Rename to... (elf_isab_plt_entry): ...this. Adjust comments and use (-6,%pc,%d0). (elf_isab_plt_info): New table. (CPU32_FLAG): Delete. (PLT_CPU32_ENTRY_SIZE): Rename to... (CPU32_PLT_ENTRY_SIZE): ...this. (elf_cpu32_plt0_entry): Update bounds accordingly. Add R_68K_PC32- style in-place addends. (elf_cpu32_plt_entry): Likewise. (elf_cpu32_plt_info): New table. (elf_m68k_link_hash_table): Add a plt_info field. (elf_m68k_link_hash_table_create): Initialize it. (elf_m68k_get_plt_info): New function. (elf_m68k_always_size_sections): Likewise. (elf_m68k_adjust_dynamic_symbol): Use the plt_info hash table field. (elf_m68k_install_pc32): New function. (elf_m68k_finish_dynamic_symbol): Factor code using plt_info and elf_m68k_install_pc32. (elf_m68k_finish_dynamic_sections): Likewise. (elf_m68k_plt_sym_val): Use elf_m68k_get_plt_info. (elf_backend_always_size_sections): Define. ld/testsuite/ * ld-m68k/plt1.s, ld-m68k/plt1-empty.s, ld-m68k/plt1.ld: New files. * ld-m68k/plt1-68020.d, ld-m68k/plt1-cpu32.d: Likewise. * ld-m68k/plt1-isab.d: Likewise. * ld-m68k/m68k.exp: Run new PLT tests.
-rw-r--r--bfd/ChangeLog34
-rw-r--r--bfd/elf32-m68k.c307
-rw-r--r--ld/testsuite/ChangeLog7
-rw-r--r--ld/testsuite/ld-m68k/m68k.exp9
-rw-r--r--ld/testsuite/ld-m68k/plt1-68020.d35
-rw-r--r--ld/testsuite/ld-m68k/plt1-cpu32.d43
-rw-r--r--ld/testsuite/ld-m68k/plt1-empty.s3
-rw-r--r--ld/testsuite/ld-m68k/plt1-isab.d44
-rw-r--r--ld/testsuite/ld-m68k/plt1.ld23
-rw-r--r--ld/testsuite/ld-m68k/plt1.s3
10 files changed, 366 insertions, 142 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5090a01..aed0518 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,37 @@
+2006-06-14 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-m68k.c (elf_m68k_plt_info): New structure.
+ (elf_m68k_plt0_entry): Add R_68K_PC32-style in-place addends.
+ (elf_m68k_plt_entry): Likewise.
+ (elf_m68k_plt_info): New table.
+ (CFV4E_PLT_ENTRY_SIZE): Rename to...
+ (ISAB_PLT_ENTRY_SIZE): ...this.
+ (CFV4E_FLAG): Delete.
+ (elf_cfv4e_plt0_entry): Rename to...
+ (elf_isab_plt0_entry): ...this. Adjust comments. Use (-6,%pc,%d0)
+ for the second instruction too.
+ (elf_cfv4e_plt_entry): Rename to...
+ (elf_isab_plt_entry): ...this. Adjust comments and use (-6,%pc,%d0).
+ (elf_isab_plt_info): New table.
+ (CPU32_FLAG): Delete.
+ (PLT_CPU32_ENTRY_SIZE): Rename to...
+ (CPU32_PLT_ENTRY_SIZE): ...this.
+ (elf_cpu32_plt0_entry): Update bounds accordingly. Add R_68K_PC32-
+ style in-place addends.
+ (elf_cpu32_plt_entry): Likewise.
+ (elf_cpu32_plt_info): New table.
+ (elf_m68k_link_hash_table): Add a plt_info field.
+ (elf_m68k_link_hash_table_create): Initialize it.
+ (elf_m68k_get_plt_info): New function.
+ (elf_m68k_always_size_sections): Likewise.
+ (elf_m68k_adjust_dynamic_symbol): Use the plt_info hash table field.
+ (elf_m68k_install_pc32): New function.
+ (elf_m68k_finish_dynamic_symbol): Factor code using plt_info and
+ elf_m68k_install_pc32.
+ (elf_m68k_finish_dynamic_sections): Likewise.
+ (elf_m68k_plt_sym_val): Use elf_m68k_get_plt_info.
+ (elf_backend_always_size_sections): Define.
+
2006-06-14 Alan Modra <amodra@bigpond.net.au>
* elflink.c (elf_link_add_object_symbols): Save and restore
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index df988a8..e8bb275 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -190,6 +190,40 @@ reloc_type_lookup (abfd, code)
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+/* Describes one of the various PLT styles. */
+
+struct elf_m68k_plt_info
+{
+ /* The size of each PLT entry. */
+ bfd_vma size;
+
+ /* The template for the first PLT entry. */
+ const bfd_byte *plt0_entry;
+
+ /* Offsets of fields in PLT0_ENTRY that require R_68K_PC32 relocations.
+ The comments by each member indicate the value that the relocation
+ is against. */
+ struct {
+ unsigned int got4; /* .got + 4 */
+ unsigned int got8; /* .got + 8 */
+ } plt0_relocs;
+
+ /* The template for a symbol's PLT entry. */
+ const bfd_byte *symbol_entry;
+
+ /* Offsets of fields in SYMBOL_ENTRY that require R_68K_PC32 relocations.
+ The comments by each member indicate the value that the relocation
+ is against. */
+ struct {
+ unsigned int got; /* the symbol's .got.plt entry */
+ unsigned int plt; /* .plt */
+ } symbol_relocs;
+
+ /* The offset of the resolver stub from the start of SYMBOL_ENTRY.
+ The stub starts with "move.l #relocoffset,%d0". */
+ bfd_vma symbol_resolve_entry;
+};
+
/* The size in bytes of an entry in the procedure linkage table. */
#define PLT_ENTRY_SIZE 20
@@ -200,9 +234,9 @@ reloc_type_lookup (abfd, code)
static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
{
0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
- 0, 0, 0, 0, /* replaced with offset to .got + 4. */
+ 0, 0, 0, 2, /* + (.got + 4) - . */
0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
- 0, 0, 0, 0, /* replaced with offset to .got + 8. */
+ 0, 0, 0, 2, /* + (.got + 8) - . */
0, 0, 0, 0 /* pad out to 20 bytes. */
};
@@ -211,71 +245,84 @@ static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
{
0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
- 0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */
+ 0, 0, 0, 2, /* + (.got.plt entry) - . */
0x2f, 0x3c, /* move.l #offset,-(%sp) */
- 0, 0, 0, 0, /* replaced with offset into relocation table. */
+ 0, 0, 0, 0, /* + reloc index */
0x60, 0xff, /* bra.l .plt */
- 0, 0, 0, 0 /* replaced with offset to start of .plt. */
+ 0, 0, 0, 0 /* + .plt - . */
};
+static const struct elf_m68k_plt_info elf_m68k_plt_info = {
+ PLT_ENTRY_SIZE,
+ elf_m68k_plt0_entry, { 4, 12 },
+ elf_m68k_plt_entry, { 4, 16 }, 8
+};
-#define CFV4E_PLT_ENTRY_SIZE 24
-
-#define CFV4E_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_M68K_CFV4E)
+#define ISAB_PLT_ENTRY_SIZE 24
-static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] =
+static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
{
- 0x20, 0x3c,
- 0, 0, 0, 0, /* Replaced with offset to .got + 4. */
- 0x2f, 0x3b, 0x08, 0xfa, /* move.l (%pc,addr),-(%sp) */
- 0x20, 0x3c,
- 0, 0, 0, 0, /* Replaced with offset to .got + 8. */
- 0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got + 4) - . */
+ 0x2f, 0x3b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),-(%sp) */
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got + 8) - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
0x4e, 0xd0, /* jmp (%a0) */
0x4e, 0x71 /* nop */
};
/* Subsequent entries in a procedure linkage table look like this. */
-static const bfd_byte elf_cfv4e_plt_entry[CFV4E_PLT_ENTRY_SIZE] =
+static const bfd_byte elf_isab_plt_entry[ISAB_PLT_ENTRY_SIZE] =
{
- 0x20, 0x3c,
- 0, 0, 0, 0, /* Replaced with offset to symbol's .got entry. */
- 0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got.plt entry) - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
0x4e, 0xd0, /* jmp (%a0) */
0x2f, 0x3c, /* move.l #offset,-(%sp) */
- 0, 0, 0, 0, /* Replaced with offset into relocation table. */
+ 0, 0, 0, 0, /* + reloc index */
0x60, 0xff, /* bra.l .plt */
- 0, 0, 0, 0 /* Replaced with offset to start of .plt. */
+ 0, 0, 0, 0 /* + .plt - . */
};
-#define CPU32_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_M68K_CPU32)
+static const struct elf_m68k_plt_info elf_isab_plt_info = {
+ ISAB_PLT_ENTRY_SIZE,
+ elf_isab_plt0_entry, { 2, 12 },
+ elf_isab_plt_entry, { 2, 20 }, 12
+};
-#define PLT_CPU32_ENTRY_SIZE 24
+#define CPU32_PLT_ENTRY_SIZE 24
/* Procedure linkage table entries for the cpu32 */
-static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
+static const bfd_byte elf_cpu32_plt0_entry[CPU32_PLT_ENTRY_SIZE] =
{
0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
- 0, 0, 0, 0, /* replaced with offset to .got + 4. */
+ 0, 0, 0, 2, /* + (.got + 4) - . */
0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
- 0, 0, 0, 0, /* replace with offset to .got +8. */
+ 0, 0, 0, 2, /* + (.got + 8) - . */
0x4e, 0xd1, /* jmp %a1@ */
0, 0, 0, 0, /* pad out to 24 bytes. */
0, 0
};
-static const bfd_byte elf_cpu32_plt_entry[PLT_CPU32_ENTRY_SIZE] =
+static const bfd_byte elf_cpu32_plt_entry[CPU32_PLT_ENTRY_SIZE] =
{
0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
- 0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */
+ 0, 0, 0, 2, /* + (.got.plt entry) - . */
0x4e, 0xd1, /* jmp %a1@ */
0x2f, 0x3c, /* move.l #offset,-(%sp) */
- 0, 0, 0, 0, /* replaced with offset into relocation table. */
+ 0, 0, 0, 0, /* + reloc index */
0x60, 0xff, /* bra.l .plt */
- 0, 0, 0, 0, /* replaced with offset to start of .plt. */
+ 0, 0, 0, 0, /* + .plt - . */
0, 0
};
+static const struct elf_m68k_plt_info elf_cpu32_plt_info = {
+ CPU32_PLT_ENTRY_SIZE,
+ elf_cpu32_plt0_entry, { 4, 12 },
+ elf_cpu32_plt_entry, { 4, 18 }, 10
+};
+
/* The m68k linker needs to keep track of the number of relocs that it
decides to copy in check_relocs for each symbol. This is so that it
can discard PC relative relocs if it doesn't need them when linking
@@ -315,6 +362,10 @@ struct elf_m68k_link_hash_table
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
+
+ /* The PLT format used by this link, or NULL if the format has not
+ yet been chosen. */
+ const struct elf_m68k_plt_info *plt_info;
};
/* Get the m68k ELF linker hash table from a link_info structure. */
@@ -370,6 +421,7 @@ elf_m68k_link_hash_table_create (abfd)
}
ret->sym_sec.abfd = NULL;
+ ret->plt_info = NULL;
return &ret->root.root;
}
@@ -1070,6 +1122,32 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
return TRUE;
}
+
+/* Return the type of PLT associated with OUTPUT_BFD. */
+
+static const struct elf_m68k_plt_info *
+elf_m68k_get_plt_info (bfd *output_bfd)
+{
+ unsigned int features;
+
+ features = bfd_m68k_mach_to_features (bfd_get_mach (output_bfd));
+ if (features & cpu32)
+ return &elf_cpu32_plt_info;
+ if (features & mcfisa_b)
+ return &elf_isab_plt_info;
+ return &elf_m68k_plt_info;
+}
+
+/* This function is called after all the input files have been read,
+ and the input sections have been assigned to output sections.
+ It's a convenient place to determine the PLT style. */
+
+static bfd_boolean
+elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ elf_m68k_hash_table (info)->plt_info = elf_m68k_get_plt_info (output_bfd);
+ return TRUE;
+}
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
@@ -1082,10 +1160,12 @@ elf_m68k_adjust_dynamic_symbol (info, h)
struct bfd_link_info *info;
struct elf_link_hash_entry *h;
{
+ struct elf_m68k_link_hash_table *htab;
bfd *dynobj;
asection *s;
unsigned int power_of_two;
+ htab = elf_m68k_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
/* Make sure we know what is going on here. */
@@ -1135,14 +1215,7 @@ elf_m68k_adjust_dynamic_symbol (info, h)
/* If this is the first .plt entry, make room for the special
first entry. */
if (s->size == 0)
- {
- if (CPU32_FLAG (dynobj))
- s->size += PLT_CPU32_ENTRY_SIZE;
- else if (CFV4E_FLAG (dynobj))
- s->size += CFV4E_PLT_ENTRY_SIZE;
- else
- s->size += PLT_ENTRY_SIZE;
- }
+ s->size = htab->plt_info->size;
/* If this symbol is not defined in a regular file, and we are
not generating a shared library, then set the symbol to this
@@ -1159,12 +1232,7 @@ elf_m68k_adjust_dynamic_symbol (info, h)
h->plt.offset = s->size;
/* Make room for this entry. */
- if (CPU32_FLAG (dynobj))
- s->size += PLT_CPU32_ENTRY_SIZE;
- else if (CFV4E_FLAG (dynobj))
- s->size += CFV4E_PLT_ENTRY_SIZE;
- else
- s->size += PLT_ENTRY_SIZE;
+ s->size += htab->plt_info->size;
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
@@ -1909,6 +1977,21 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
return TRUE;
}
+/* Install an M_68K_PC32 relocation against VALUE at offset OFFSET
+ into section SEC. */
+
+static void
+elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value)
+{
+ /* Make VALUE PC-relative. */
+ value -= sec->output_section->vma + offset;
+
+ /* Apply any in-place addend. */
+ value += bfd_get_32 (sec->owner, sec->contents + offset);
+
+ bfd_put_32 (sec->owner, value, sec->contents + offset);
+}
+
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
@@ -1920,12 +2003,12 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
Elf_Internal_Sym *sym;
{
bfd *dynobj;
- int plt_off1, plt_off2, plt_off3;
dynobj = elf_hash_table (info)->dynobj;
if (h->plt.offset != (bfd_vma) -1)
{
+ const struct elf_m68k_plt_info *plt_info;
asection *splt;
asection *sgot;
asection *srela;
@@ -1939,6 +2022,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
BFD_ASSERT (h->dynindx != -1);
+ plt_info = elf_m68k_hash_table (info)->plt_info;
splt = bfd_get_section_by_name (dynobj, ".plt");
sgot = bfd_get_section_by_name (dynobj, ".got.plt");
srela = bfd_get_section_by_name (dynobj, ".rela.plt");
@@ -1948,66 +2032,36 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
corresponds to this symbol. This is the index of this symbol
in all the symbols for which we are making plt entries. The
first entry in the procedure linkage table is reserved. */
- if (CPU32_FLAG (output_bfd))
- plt_index = (h->plt.offset / PLT_CPU32_ENTRY_SIZE) - 1;
- else if (CFV4E_FLAG (output_bfd))
- plt_index = (h->plt.offset / CFV4E_PLT_ENTRY_SIZE) - 1;
- else
- plt_index = (h->plt.offset / PLT_ENTRY_SIZE) - 1;
+ plt_index = (h->plt.offset / plt_info->size) - 1;
/* Get the offset into the .got table of the entry that
corresponds to this function. Each .got entry is 4 bytes.
The first three are reserved. */
got_offset = (plt_index + 3) * 4;
- if (CPU32_FLAG (output_bfd))
- {
- /* Fill in the entry in the procedure linkage table. */
- memcpy (splt->contents + h->plt.offset, elf_cpu32_plt_entry,
- PLT_CPU32_ENTRY_SIZE);
- plt_off1 = 4;
- plt_off2 = 12;
- plt_off3 = 18;
- }
- else if (CFV4E_FLAG (output_bfd))
- {
- memcpy (splt->contents + h->plt.offset, elf_cfv4e_plt_entry,
- CFV4E_PLT_ENTRY_SIZE);
- plt_off1 = 2;
- plt_off2 = 14;
- plt_off3 = 20;
- }
- else
- {
- /* Fill in the entry in the procedure linkage table. */
- memcpy (splt->contents + h->plt.offset, elf_m68k_plt_entry,
- PLT_ENTRY_SIZE);
- plt_off1 = 4;
- plt_off2 = 10;
- plt_off3 = 16;
- }
-
- /* The offset is relative to the first extension word. */
- bfd_put_32 (output_bfd,
- sgot->output_section->vma
- + sgot->output_offset
- + got_offset
- - (splt->output_section->vma
- + h->plt.offset
- + (CFV4E_FLAG (output_bfd) ? 8 : 2)),
- splt->contents + h->plt.offset + plt_off1);
+ memcpy (splt->contents + h->plt.offset,
+ plt_info->symbol_entry,
+ plt_info->size);
+
+ elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.got,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset));
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
- splt->contents + h->plt.offset + plt_off2);
- bfd_put_32 (output_bfd, - (h->plt.offset + plt_off3),
- splt->contents + h->plt.offset + plt_off3);
+ splt->contents
+ + h->plt.offset
+ + plt_info->symbol_resolve_entry + 2);
+
+ elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.plt,
+ splt->output_section->vma);
/* Fill in the entry in the global offset table. */
bfd_put_32 (output_bfd,
(splt->output_section->vma
+ splt->output_offset
+ h->plt.offset
- + (CFV4E_FLAG (output_bfd) ? 12 : 8)),
+ + plt_info->symbol_resolve_entry),
sgot->contents + got_offset);
/* Fill in the entry in the .rela.plt section. */
@@ -2185,54 +2239,23 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
/* Fill in the first entry in the procedure linkage table. */
if (splt->size > 0)
{
- if (CFV4E_FLAG (output_bfd))
- {
- memcpy (splt->contents, elf_cfv4e_plt0_entry, CFV4E_PLT_ENTRY_SIZE);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 4
- - (splt->output_section->vma + 2)),
- splt->contents + 2);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 8
- - (splt->output_section->vma + 10) - 8),
- splt->contents + 12);
- elf_section_data (splt->output_section)->this_hdr.sh_entsize
- = CFV4E_PLT_ENTRY_SIZE;
- }
- else if (CPU32_FLAG (output_bfd))
- {
- memcpy (splt->contents, elf_cpu32_plt0_entry, PLT_CPU32_ENTRY_SIZE);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 4
- - (splt->output_section->vma + 2)),
- splt->contents + 4);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 8
- - (splt->output_section->vma + 10)),
- splt->contents + 12);
- elf_section_data (splt->output_section)->this_hdr.sh_entsize
- = PLT_CPU32_ENTRY_SIZE;
- }
- else
- {
- memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 4
- - (splt->output_section->vma + 2)),
- splt->contents + 4);
- bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 8
- - (splt->output_section->vma + 10)),
- splt->contents + 12);
- elf_section_data (splt->output_section)->this_hdr.sh_entsize
- = PLT_ENTRY_SIZE;
- }
+ const struct elf_m68k_plt_info *plt_info;
+
+ plt_info = elf_m68k_hash_table (info)->plt_info;
+ memcpy (splt->contents, plt_info->plt0_entry, plt_info->size);
+
+ elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got4,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + 4));
+
+ elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got8,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + 8));
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = plt_info->size;
}
}
@@ -2401,9 +2424,7 @@ static bfd_vma
elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
const arelent *rel ATTRIBUTE_UNUSED)
{
- if (CPU32_FLAG (plt->owner))
- return plt->vma + (i + 1) * PLT_CPU32_ENTRY_SIZE;
- return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+ return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size;
}
#define TARGET_BIG_SYM bfd_elf32_m68k_vec
@@ -2417,6 +2438,8 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
#define elf_backend_check_relocs elf_m68k_check_relocs
+#define elf_backend_always_size_sections \
+ elf_m68k_always_size_sections
#define elf_backend_adjust_dynamic_symbol \
elf_m68k_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections \
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 66a5dac..fb9b87d 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-14 Richard Sandiford <richard@codesourcery.com>
+
+ * ld-m68k/plt1.s, ld-m68k/plt1-empty.s, ld-m68k/plt1.ld: New files.
+ * ld-m68k/plt1-68020.d, ld-m68k/plt1-cpu32.d: Likewise.
+ * ld-m68k/plt1-isab.d: Likewise.
+ * ld-m68k/m68k.exp: Run new PLT tests.
+
2006-06-12 Thiemo Seufer <ths@mips.com>
* ld-mips-elf/multi-got-no-shared.d: Adjust for recent change of
diff --git a/ld/testsuite/ld-m68k/m68k.exp b/ld/testsuite/ld-m68k/m68k.exp
index a1096a8..042f1b9 100644
--- a/ld/testsuite/ld-m68k/m68k.exp
+++ b/ld/testsuite/ld-m68k/m68k.exp
@@ -53,3 +53,12 @@ run_dump_test "merge-error-1d"
run_dump_test "merge-error-1e"
run_dump_test "merge-ok-1a"
run_dump_test "merge-ok-1b"
+
+foreach { id sources } { a { plt1.s } b { plt1-empty.s plt1.s } } {
+ foreach arch { 68020 cpu32 isab } {
+ run_ld_link_tests [list \
+ [list "PLT 1$id ($arch)" "-shared -T plt1.ld" "-m$arch" \
+ $sources [list [list objdump -dr plt1-$arch.d]] \
+ plt1-${id}-${arch}.so]]
+ }
+}
diff --git a/ld/testsuite/ld-m68k/plt1-68020.d b/ld/testsuite/ld-m68k/plt1-68020.d
new file mode 100644
index 0000000..964acb6
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1-68020.d
@@ -0,0 +1,35 @@
+
+.*: file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x14>:
+ 20800: 2f3b 0170 0000 movel %pc@\(30404 <_GLOBAL_OFFSET_TABLE_\+0x4>\),%sp@-
+ 20806: fc02
+ 20808: 4efb 0171 0000 jmp %pc@\(30408 <_GLOBAL_OFFSET_TABLE_\+0x8>\)@\(00000000\)
+ 2080e: fbfe
+ 20810: 0000 0000 orib #0,%d0
+
+00020814 <f.@plt>:
+ 20814: 4efb 0171 0000 jmp %pc@\(3040c <_GLOBAL_OFFSET_TABLE_\+0xc>\)@\(00000000\)
+ 2081a: fbf6
+ 2081c: 2f3c 0000 0000 movel #0,%sp@-
+ 20822: 60ff ffff ffdc bral 20800 <f.@plt-0x14>
+
+00020828 <f.@plt>:
+ 20828: 4efb 0171 0000 jmp %pc@\(30410 <_GLOBAL_OFFSET_TABLE_\+0x10>\)@\(00000000\)
+ 2082e: fbe6
+ 20830: 2f3c 0000 000c movel #12,%sp@-
+ 20836: 60ff ffff ffc8 bral 20800 <f.@plt-0x14>
+
+0002083c <f.@plt>:
+ 2083c: 4efb 0171 0000 jmp %pc@\(30414 <_GLOBAL_OFFSET_TABLE_\+0x14>\)@\(00000000\)
+ 20842: fbd6
+ 20844: 2f3c 0000 0018 movel #24,%sp@-
+ 2084a: 60ff ffff ffb4 bral 20800 <f.@plt-0x14>
+Disassembly of section \.text:
+
+00020c00 <.*>:
+ 20c00: 61ff ffff fc.. bsrl 208.. <f1@plt>
+ 20c06: 61ff ffff fc.. bsrl 208.. <f2@plt>
+ 20c0c: 61ff ffff fc.. bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1-cpu32.d b/ld/testsuite/ld-m68k/plt1-cpu32.d
new file mode 100644
index 0000000..a497740
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1-cpu32.d
@@ -0,0 +1,43 @@
+
+.*: file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x18>:
+ 20800: 2f3b 0170 0000 movel %pc@\(30404 <_GLOBAL_OFFSET_TABLE_\+0x4>\),%sp@-
+ 20806: fc02
+ 20808: 227b 0170 0000 moveal %pc@\(30408 <_GLOBAL_OFFSET_TABLE_\+0x8>\),%a1
+ 2080e: fbfe
+ 20810: 4ed1 jmp %a1@
+ 20812: 0000 0000 orib #0,%d0
+ \.\.\.
+
+00020818 <f.@plt>:
+ 20818: 227b 0170 0000 moveal %pc@\(3040c <_GLOBAL_OFFSET_TABLE_\+0xc>\),%a1
+ 2081e: fbf2
+ 20820: 4ed1 jmp %a1@
+ 20822: 2f3c 0000 0000 movel #0,%sp@-
+ 20828: 60ff ffff ffd6 bral 20800 <f.@plt-0x18>
+ \.\.\.
+
+00020830 <f.@plt>:
+ 20830: 227b 0170 0000 moveal %pc@\(30410 <_GLOBAL_OFFSET_TABLE_\+0x10>\),%a1
+ 20836: fbde
+ 20838: 4ed1 jmp %a1@
+ 2083a: 2f3c 0000 000c movel #12,%sp@-
+ 20840: 60ff ffff ffbe bral 20800 <f.@plt-0x18>
+ \.\.\.
+
+00020848 <f.@plt>:
+ 20848: 227b 0170 0000 moveal %pc@\(30414 <_GLOBAL_OFFSET_TABLE_\+0x14>\),%a1
+ 2084e: fbca
+ 20850: 4ed1 jmp %a1@
+ 20852: 2f3c 0000 0018 movel #24,%sp@-
+ 20858: 60ff ffff ffa6 bral 20800 <f.@plt-0x18>
+ \.\.\.
+Disassembly of section \.text:
+
+00020c00 <.*>:
+ 20c00: 61ff ffff fc.. bsrl 208.. <f1@plt>
+ 20c06: 61ff ffff fc.. bsrl 208.. <f2@plt>
+ 20c0c: 61ff ffff fc.. bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1-empty.s b/ld/testsuite/ld-m68k/plt1-empty.s
new file mode 100644
index 0000000..a59477d
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1-empty.s
@@ -0,0 +1,3 @@
+ .text
+ .globl foo
+foo:
diff --git a/ld/testsuite/ld-m68k/plt1-isab.d b/ld/testsuite/ld-m68k/plt1-isab.d
new file mode 100644
index 0000000..a9aeacb
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1-isab.d
@@ -0,0 +1,44 @@
+
+.*: file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x18>:
+# _GLOBAL_OFFSET_TABLE_ + 4 == 0x30404 == 0x20802 + 0xfc02
+ 20800: 203c 0000 fc02 movel #64514,%d0
+ 20806: 2f3b 08fa movel %pc@\(20802 <f.@plt-0x16>,%d0:l\),%sp@-
+# _GLOBAL_OFFSET_TABLE_ + 8 == 0x30408 == 0x2080c + 0xfbfc
+ 2080a: 203c 0000 fbfc movel #64508,%d0
+ 20810: 207b 08fa moveal %pc@\(2080c <f.@plt-0xc>,%d0:l\),%a0
+ 20814: 4ed0 jmp %a0@
+ 20816: 4e71 nop
+
+00020818 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 12 == 0x3040c == 0x2081a + 0xfbf2
+ 20818: 203c 0000 fbf2 movel #64498,%d0
+ 2081e: 207b 08fa moveal %pc@\(2081a <f.@plt\+0x2>,%d0:l\),%a0
+ 20822: 4ed0 jmp %a0@
+ 20824: 2f3c 0000 0000 movel #0,%sp@-
+ 2082a: 60ff ffff ffd4 bral 20800 <f.@plt-0x18>
+
+00020830 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 16 == 0x30410 == 0x20832 + 0xfbde
+ 20830: 203c 0000 fbde movel #64478,%d0
+ 20836: 207b 08fa moveal %pc@\(20832 <f.@plt\+0x2>,%d0:l\),%a0
+ 2083a: 4ed0 jmp %a0@
+ 2083c: 2f3c 0000 000c movel #12,%sp@-
+ 20842: 60ff ffff ffbc bral 20800 <f.@plt-0x18>
+
+00020848 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 20 == 0x30414 == 0x2084a + 0xfbca
+ 20848: 203c 0000 fbca movel #64458,%d0
+ 2084e: 207b 08fa moveal %pc@\(2084a <f.@plt\+0x2>,%d0:l\),%a0
+ 20852: 4ed0 jmp %a0@
+ 20854: 2f3c 0000 0018 movel #24,%sp@-
+ 2085a: 60ff ffff ffa4 bral 20800 <f.@plt-0x18>
+Disassembly of section \.text:
+
+00020c00 <.*>:
+ 20c00: 61ff ffff fc.. bsrl 208.. <f1@plt>
+ 20c06: 61ff ffff fc.. bsrl 208.. <f2@plt>
+ 20c0c: 61ff ffff fc.. bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1.ld b/ld/testsuite/ld-m68k/plt1.ld
new file mode 100644
index 0000000..718e2ad
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1.ld
@@ -0,0 +1,23 @@
+SECTIONS
+{
+ . = 0x20000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+
+ . = ALIGN (0x400);
+ .rela.plt : { *(.rela.plt) }
+
+ . = ALIGN (0x400);
+ .plt : { *(.plt) }
+
+ . = ALIGN (0x400);
+ .text : { *(.text) }
+
+ . = ALIGN (0x10000);
+ .dynamic : { *(.dynamic) }
+
+ . = ALIGN (0x400);
+ .got : { *(.got.plt) *(.got) }
+}
diff --git a/ld/testsuite/ld-m68k/plt1.s b/ld/testsuite/ld-m68k/plt1.s
new file mode 100644
index 0000000..855fb19
--- /dev/null
+++ b/ld/testsuite/ld-m68k/plt1.s
@@ -0,0 +1,3 @@
+ bsr.l f1@PLTPC
+ bsr.l f2@PLTPC
+ bsr.l f3@PLTPC