[LV] [PATCH] VAX/ELF: Store all call-saved registers upon PLT stub entry
Hello, For the VAX processor the list of registers to be preserved across procedure calls is specified by the 16-bit word at the entry point, called the entry mask. That word is interpreted by the procedure call instruction and the registers requested are stored on the stack together with a copy of the entry mask before control is transferred. Later on, this data is used by the return instruction to restore the registers previously saved. This poses a problem with PLT stubs used for lazy run-time resolving. The stubs are called as if they were actual procedures, so they have to provide information about which registers to store. That information is not available at the static link time as PLT entries are normally only created for global symbol references to shared objects and such symbols, even if available from the same binary, are subject to preemption. Therefore this information has to be orchestrated somehow. I could see two possible solutions: 1. Either to create a fake mask to include the call-saved registers the lazy resolver actually clobbers. This approach has a potential advantage of not requiring unnecessary stack transfers. Unfortunately the advantage is quickly flushed down the drain as the piece of code called by the PLT stub has to recreate the stack frame manually by retrieving the mask from the address to be called once it has been resolved, determining which registers have to be saved, copying part of the stack frame already created down the stack, inserting the extra registers and updating the mask stored on the stack. 2. Always save all the call-saved registers. This has a potential performance disadvantage, but I believe it to be negligible as the area near the stack pointer is typically hot in the cache and the lazy resolver is only called at most once per function per program execution. The advantage is simplicity. All the stores are done by the call instruction, which has been designed (and undoubtedly optimised) for this kind of operation. There is no need to do fragile fiddling with the stack in the lazy resolver and on average the actual performance may not be worse at all. The difference is going to be lost in the lazy resolver's overhead anyway. The current approach in BFD seems to be #1 above and I would like to get it changed to the #2. Given the issues with the VAX/ELF backend I'm not sure if the PLT stubs have already been used in actual software, raising binary compatibility concerns. If so, I would limit this change to Linux (regrettably creating an incompatible ELF flavour), otherwise I suggest it to be applied universally. While the standard VAX ABI only defines <R11:R6> as call-saved, the mask I chose includes <R5:R2> too due to the -fcall-saved-REG GCC option -- the information about which registers are consider call-saved is not carried along binaries. OTOH, <R1:R0> are skipped as they are result registers and must never be saved across calls. bfd/ 2009-06-04 Maciej W. Rozycki <macro@linux-mips.org> * elf32-vax.c (elf_vax_plt_entry): Set the entry mask to include <R11:R2>. Comments? Maciej binutils-2.19.1-vax-plt-mask.patch diff -up --recursive --new-file binutils-2.19.1.macro/bfd/elf32-vax.c binutils-2.19.1/bfd/elf32-vax.c --- binutils-2.19.1.macro/bfd/elf32-vax.c 2008-01-11 09:07:03.000000000 +0000 +++ binutils-2.19.1/bfd/elf32-vax.c 2009-04-20 20:11:20.000000000 +0000 @@ -368,7 +368,7 @@ static const bfd_byte elf_vax_plt0_entry static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] = { - 0x40, 0x00, /* .word ^M<r6> */ + 0xfc, 0x0f, /* .word ^M<r11:r2> */ 0x16, 0xef, /* jsb L^(pc) */ 0, 0, 0, 0, /* replaced with offset to start of .plt */ 0, 0, 0, 0, /* index into .rela.plt */ _______________________________________________ Linux-Vax mailing list Linux-Vax@mail.pergamentum.com http://mail.pergamentum.com/mailman/listinfo/linux-vax
Teilnehmer (3)
-
Jan-Benedict Glaw
-
Maciej W. Rozycki
-
Nick Clifton