RFC:elf32-m68k.c for coldfire v4e

Peter Barada peter@the-baradas.com
Thu Feb 10 21:31:00 GMT 2005


>  I think I have struck in an unusual problem. I have to modify PLT entries
>in elf32-m68k.c file so that they are valid for coldfire v4e. (due to
>constraints in addr mode). I could successfully modify and test the changes.
>
>Though these changes should be valid for m68k as well but the size of PLT is
>increased a bit. What I want to know is will this be acceptable? If not then
>
>How can I decide which PLT is to be used among m68k, cpu32 or cfv4e? I may
>create a new target may be coldfire-linux but there will be a code
>duplication of elf32-m68k.c. I hope I am clear in expressing. I am also
>attaching the patch with this mail ( just for review )

You should look into how the code for the CPU32 does it since the
CPU32 has different sized PLT entries as well:

#define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CPU32)

The EF_CPU32 flag is set in the elf header in gas/config/tc-m68k.c,
m68k_elf_final_processing(), you should do the same for an added 'EF_MCF'
flag, and use that to decide to use the mcf PLT entry.  Here's the
extract where you'd need to modify the code to decide which to use:

in elf_m68k_adjust_dynamic_symbol:

...

      /* If this is the first .plt entry, make room for the special
	 first entry.  */
      if (s->_raw_size == 0)
	{
	  if (CPU32_FLAG (dynobj))
	    s->_raw_size += PLT_CPU32_ENTRY_SIZE;
	  else
	    s->_raw_size += PLT_ENTRY_SIZE;
	}

...

      /* Make room for this entry.  */
      if (CPU32_FLAG (dynobj))
        s->_raw_size += PLT_CPU32_ENTRY_SIZE;
      else
        s->_raw_size += PLT_ENTRY_SIZE;


Another thing I noticed is that you should comment the plt0 for v4e better
so that you don't need a programmers manual to find that 0x203c is
'move.l #,%d0' and 0x4e71 is 'nop'.  Here's the PLT entries that I
came up with for ColdFire:

#define MCF_FLAG(abfd)    (elf_elfheader (abfd)->e_flags & EF_MCF)

#define PLT_MCF_ENTRY_SIZE 24
/* Procedure linkage table entries for ColdFire */
static const bfd_byte elf_mcf_plt0_entry[PLT_MCF_ENTRY_SIZE] =
{
  0x43, 0xf9,              /* lea addr, %a1 */
  0, 0, 0, 0,              /* replaced with offset to .got + 4 */
  0x2f, 0x3b, 0x98, 0xfa,  /* movel %pc@(-6,%a1),-(%sp) */
  0x43, 0xf9,              /* lea addr, %a1 */
  0, 0, 0, 0,              /* replaced with offset to .got + 8 */
  0x22, 0x7b, 0x98, 0xfa,  /* movel %pc@(-6,%a1),%a1 */
  0x4e, 0xd1,              /* jmp %a1@ */
  0x4e, 0x71,              /* nop */
};

static const bfd_byte elf_mcf_plt_entry[PLT_MCF_ENTRY_SIZE] =
{
  0x43, 0xf9,              /* lea addr, %a1 */
  0, 0, 0, 0,              /* replaced with offset to symbol's .got entry.  */
  0x22, 0x7b, 0x98, 0xfa,  /* movel %pc@(-6,%a1),%a1 */
  0x4e, 0x4d1,             /* jmp %a1@ */
  0x2f, 0x3c,              /* move.l #offset,-(%sp) */
  0, 0, 0, 0,              /* replaced with offset into relocation table.  */
  0x60, 0xff,              /* bra.l .plt */
  0, 0, 0, 0,              /* replaced with offset to start of .plt.  */
};


And the code in elf_m68k_adjust_dynamic_symbol:

...

      /* If this is the first .plt entry, make room for the special
	 first entry.  */
      if (s->_raw_size == 0)
	{
	  if (CPU32_FLAG (dynobj))
	    s->_raw_size += PLT_CPU32_ENTRY_SIZE;
	  else if (MCF_FLAG (dynobj))
	    s->_raw_size += PLT_MCF_ENTRY_SIZE;
          else
	    s->_raw_size += PLT_ENTRY_SIZE;
	}

...

      /* Make room for this entry.  */
      if (CPU32_FLAG (dynobj))
        s->_raw_size += PLT_CPU32_ENTRY_SIZE;
      else if (MCF_FLAG (dynobj))
        s->_raw_size += PLT_MCF_ENTRY_SIZE;
      else
        s->_raw_size += PLT_ENTRY_SIZE;


Drop me a line if you have any further questions...

-- 
Peter Barada
peter@the-baradas.com



More information about the Binutils mailing list