[PATCH,SPU] Generate .fixup section to support PIC
Trevor_Smigiel@playstation.sony.com
Trevor_Smigiel@playstation.sony.com
Wed Aug 5 02:05:00 GMT 2009
Hi,
The SPU ABI requires PIC to support plugins. If DLL's or PIE's were
supported, they would also require PIC.
Currently, the SPU ABI does not generate correct PIC if the code
contains SPU_ADDR32 relocations. SPU_ADDR32 relocations correspond to
things like the addresses stored in global variables. The values
computed for these relocations must be updated at run-time to get the
correct run-time value.
To implement this we add a new section called .fixup. The address
corresponding to the r_offset of each SPU_ADDR32 relocation is encoded
into the .fixup section at link time. The value of the relocation is
stored at that address in the output file. At run time, code will
process the .fixup section, updating the values at the addresses.
A .fixup section consists of N records. Each record is 4 bytes. The
first record is addressed with the symbol __fixup_start. The last
record is a sentinal with the value 0. The other records are formatted
thusly:
most significant 28 bits
- contain the most significant 28 bits of a quadword address. In
other words (record & 0xfffffff0) results in a quadword address.
least significant 4 bits
- a bit mask specifying which words in the quadword should be updated.
This allows some compression for arrays of pointers, like vtables.
The bits match the words as if they were expanded with the 'fsm'
instruction.
The following code can be used at run time to process the .fixup
section:
static void
__init_fixups (unsigned int pic_base)
{
unsigned int * fixup = __fixup_start;
__vector unsigned int *addr;
for ( ; *fixup; fixup++)
{
addr = (__vector unsigned int *)((pic_base + *fixup) & -16);
*addr += (spu_splats (pic_base) & spu_maskw (*fixup));
}
}
The attached patch has been bootstrapped and tested on x86 and SPU with
no new regressions.
Ok to check in?
Trevor
2009-08-04 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
bfd/
* elf32-spu.h (spu_elf_params): Add member emit_fixups.
(spu_elf_size_sections): Declare prototype.
* elf32-spu.c (spu_link_hash_table): Add member sfixup.
(FIXUP_RECORD_SIZE, FIXUP_GET, FIXUP_PUT): New macros.
(spu_elf_emit_fixup): New function.
(spu_elf_relocate_section): Emit fixup for each SPU_ADDR32.
(spu_elf_size_sections): New function.
ld/
* emulparams/elf32_spu.sh (OTHER_READONLY_SECTIONS): Add .fixup
section and __fixup_start symbol.
* emultempl/spuelf.em (params): Initialize emit_fixups member.
(spu_before_allocation): Call spu_elf_size_sections.
(OPTION_SPU_EMIT_FIXUPS): Define.
(PARSE_AND_LIST_LONGOPTS): Add --emit-fixups.
(PARSE_AND_LIST_ARGS_CASES): Handle --emit-fixups.
* ld.texinfo (--emit-fixups): Document.
ld/testsuite/
* ld-spu/fixup.d: New.
* ld-spu/fixup.s: New.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: spu-fixups.patch
Type: text/x-diff
Size: 10486 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20090805/26f0d053/attachment.bin>
More information about the Binutils
mailing list