m68k PLT fixes and cleanups

Richard Sandiford richard@codesourcery.com
Wed Jun 7 14:49:00 GMT 2006


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;
>  }
> +
> +/* 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



More information about the Binutils mailing list