* Re: m68k PLT fixes and cleanups
[not found] <87y7wyks8y.fsf@talisman.home>
@ 2006-06-07 14:49 ` Richard Sandiford
2006-06-09 15:03 ` Nick Clifton
0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2006-06-07 14:49 UTC (permalink / raw)
To: binutils
Ping!
Richard Sandiford <richard@codesourcery.com> writes:
> This patch contains some fixes and cleanups related to m68k PLTs.
>
> The most important problem fixed by this patch is that we aren't
> consistent in how we choose between the three available PLT styles
> (68020, cpu32 and isab). Sometimes we key the choice off the output
> bfd and sometimes off the dynobj. Unfortunately, these two tests are
> not guaranteed to give the same results. If a file contains no actual
> code, the assembler will not set the ELF flags to require a particular
> processor (this is a deliberate feature). And if the first object in
> a dynamic link is such an object, we might use it as the dynobj.
> Thus we can have a situation where the dynobj tests think we want
> a 68020 PLT and the output_bfd tests think we want a cpu32 or cfv4e
> PLT. The result is a garbled mess.
>
> I think the best way to fix this is to choose the PLT up-front and
> record it in the hash table. Unlike the output bfd, this hash table
> is always to hand in the places that matter. This is also what
> other targets do.
>
> I found the current code a bit confusing, with the cfv4e code throwing
> in a few different constant here and there. So, rather than use an
> enumeration for the new hash table field, I decided to add a structure
> that describes the information specific to each style of PLT. I hope
> this makes the code clearer.
>
> Another two fixes:
>
> - The cfv4e stubs work for any ISA B processor. I've renamed the
> stub and changed the conditions accordingly.
>
> - The disassembler doesn't know about the size of cfv4e stubs. If you
> try to disassemble a cfv4e object, the magic @plt symbols are placed
> at the wrong offsets, leading to very confusing output.
>
> And another two cleanups:
>
> - Sometimes the cfv4e PLT used "move.l #foo@PCREL,%d0; insn (-6,%pc,%d0)"
> and sometimes it used "move.l #foo-6,PCREL,%d0; insn (0,%pc,%d0)".
> I found this confusing when looking at disassembly, so I thought I'd
> change it to be consistent.
>
> So, which form to pick? I personally find the "(-6,%pc,%d0)" form
> much easier to read, because I'm used to 32-bit pc-relative offsets
> being relative to the current instruction's operands, not some later
> instruction's. So that's what I used.
>
> - I renamed PLT_CPU32_ENTRY_SIZE to CPU32_PLT_ENTRY_SIZE to be
> consistent with the other *_SIZE macros and the names of the
> cpu32 PLT templates.
>
> I've tried to make sure the new linker tests are not sensitive to
> secondary things like the order of the hash table, the size of the
> symbol table, etc.
>
> Tested on m68k-elf. Also tested on binutils-csl-2_17-branch on
> a 5485evb. OK to install?
>
> Richard
>
>
> 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.
>
> Index: bfd/elf32-m68k.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
> retrieving revision 1.89
> diff -u -p -r1.89 elf32-m68k.c
> --- bfd/elf32-m68k.c 25 Mar 2006 10:24:27 -0000 1.89
> +++ bfd/elf32-m68k.c 19 May 2006 13:46:32 -0000
> @@ -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_entr
> 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,
>
> return TRUE;
> }
> +\f
> +/* 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, i
> 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_b
> 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_b
>
> 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_b
> 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
> /* 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 a
> #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 \
> Index: ld/testsuite/ld-m68k/m68k.exp
> ===================================================================
> RCS file: /cvs/src/src/ld/testsuite/ld-m68k/m68k.exp,v
> retrieving revision 1.2
> diff -u -p -r1.2 m68k.exp
> --- ld/testsuite/ld-m68k/m68k.exp 25 Mar 2006 10:24:27 -0000 1.2
> +++ ld/testsuite/ld-m68k/m68k.exp 19 May 2006 13:46:32 -0000
> @@ -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]]
> + }
> +}
> Index: ld/testsuite/ld-m68k/plt1-68020.d
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1-68020.d
> diff -N ld/testsuite/ld-m68k/plt1-68020.d
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1-68020.d 19 May 2006 13:46:32 -0000
> @@ -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>
> Index: ld/testsuite/ld-m68k/plt1-cpu32.d
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1-cpu32.d
> diff -N ld/testsuite/ld-m68k/plt1-cpu32.d
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1-cpu32.d 19 May 2006 13:46:32 -0000
> @@ -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>
> Index: ld/testsuite/ld-m68k/plt1-empty.s
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1-empty.s
> diff -N ld/testsuite/ld-m68k/plt1-empty.s
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1-empty.s 19 May 2006 13:46:32 -0000
> @@ -0,0 +1,3 @@
> + .text
> + .globl foo
> +foo:
> Index: ld/testsuite/ld-m68k/plt1-isab.d
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1-isab.d
> diff -N ld/testsuite/ld-m68k/plt1-isab.d
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1-isab.d 19 May 2006 13:46:32 -0000
> @@ -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>
> Index: ld/testsuite/ld-m68k/plt1.ld
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1.ld
> diff -N ld/testsuite/ld-m68k/plt1.ld
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1.ld 19 May 2006 13:46:32 -0000
> @@ -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) }
> +}
> Index: ld/testsuite/ld-m68k/plt1.s
> ===================================================================
> RCS file: ld/testsuite/ld-m68k/plt1.s
> diff -N ld/testsuite/ld-m68k/plt1.s
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ ld/testsuite/ld-m68k/plt1.s 19 May 2006 13:46:32 -0000
> @@ -0,0 +1,3 @@
> + bsr.l f1@PLTPC
> + bsr.l f2@PLTPC
> + bsr.l f3@PLTPC
^ permalink raw reply [flat|nested] 2+ messages in thread