This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFA: m68k ELF backend PLT for CPU32 support


Hi there,

There is one thing in bfd/elf32-m68k.c that has been bugging me for a while and
looks like a bug to me. The m68k ELF ABI spec (thanks Nick!) defines the
instruction sequences for the procedure linkage table (PLT). These standard
sequences assume a 68020 or higher CPU. A 68000 or even a CPU32 doesn't cut it.
While I thought about creating a 68000-compatible PLT and decided that it isn't
possible / isn't worth it, CPU32 is a different story and someone has already
implemented CPU32 PLT support in bfd/elf32-m68k.c. However, the PLT entry 0 it
defines looks completely bogus to me. Just look at it (best done with a copy of
the ABI spec in hand, figure 5-5 on page 5-8) and convince yourself of this.
The code at the start of PLT is supposed to push the longword in GOT entry 1 on
the stack and jump to the address in GOT entry 2. The instruction sequence that
bfd/elf32-m68k.c uses for 68020 and higher does exactly this, and it is in fact
the exact instruction sequence given in the ABI spec. However, the current
CPU32 instruction sequence does something else: it jumps to the address in GOT
entry 1 and doesn't use the contents of GOT entry 2 at all.

So here is my question to whoever has added the CPU32 support: is this really
intentional? Do you have a different ABI for CPU32 where the dynamic linker
fills in GOT entries 1 and 2 differently and expects a different stack layout
on entry? I just have a hard time believing this, it would seem much more
logical to me that the ABI should be the same, as aside from the actual
instruction sequences used in the PLT, absolutely nothing in the SVR4 ABI spec
or in the way m68k ELF dynamic linkers work is specific to the 68020 or
incompatible with the CPU32, and this seems much more like a plain bug. But
then this code has never worked at all. How has it made its way into CVS then?

If I am correct in assuming that this is a bug, that the dynamic linker ABI is
processor-independent, and that CPU32 should still use the same SVR4 ABI, the
patch below fixes it. It uses a new instruction sequence that does the same
thing as the one in the spec, but in CPU32 instructions. Note that CPU32 PLT
instruction sequences clobber A1 on entry to the called function. This has
already been the case before this patch, and is due to CPU32 limitations. But
the SVR4 ABI has no problem with A1 being clobbered on entry to functions,
which is yet another argument in its favor!

--
Michael Sokolov		Harhan Engineering Laboratory
Public Service Agent	International Free Computing Task Force
			International Engineering and Science Task Force
			615 N GOOD LATIMER EXPY STE #4
			DALLAS TX 75204-5852 USA

Phone: +1-214-824-7693 (Harhan Eng Lab office)
E-mail: msokolov@ivan.Harhan.ORG (ARPA TCP/SMTP) (UUCP coming soon)

2000-09-15  Michael Sokolov  <msokolov@ivan.Harhan.ORG>

	* elf32-m68k.c (elf_cpu32_plt0_entry): Change the PLT entry 0
	instruction sequence to actually work.
	(elf_m68k_finish_dynamic_sections): Change the patch-in offset
	accordingly.

Index: elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.17
diff -c -r1.17 elf32-m68k.c
*** elf32-m68k.c	2000/09/15 18:52:12	1.17
--- elf32-m68k.c	2000/09/15 23:23:04
***************
*** 224,234 ****
  /* Procedure linkage table entries for the cpu32 */
  static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
  {
!   0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
    0, 0, 0, 0,             /* replaced with offset to .got + 4.  */
!   0x4e, 0xd1,             /* jmp %a1@ */
    0, 0, 0, 0,             /* replace with offset to .got +8. */
!   0, 0, 0, 0,             /* pad out to 24 bytes.  */
    0, 0, 0, 0,             /* pad out to 24 bytes.  */
    0, 0
  };
--- 224,234 ----
  /* Procedure linkage table entries for the cpu32 */
  static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
  {
!   0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
    0, 0, 0, 0,             /* replaced with offset to .got + 4.  */
!   0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
    0, 0, 0, 0,             /* replace with offset to .got +8. */
!   0x4e, 0xd1,             /* jmp %a1@ */
    0, 0, 0, 0,             /* pad out to 24 bytes.  */
    0, 0
  };
***************
*** 2154,2160 ****
  		          (sgot->output_section->vma
  		           + sgot->output_offset + 8
  		           - (splt->output_section->vma + 10)),
! 		          splt->contents + 10);
                elf_section_data (splt->output_section)->this_hdr.sh_entsize 
                 = PLT_CPU32_ENTRY_SIZE;
              }
--- 2154,2160 ----
  		          (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;
              }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]