[PATCH} [Review Request] MCJIT PIC support for x86-64

Kaylor, Andrew andrew.kaylor at intel.com
Tue Aug 13 11:38:05 PDT 2013


Hi all,

The attached patch implements PIC relocation support in MCJIT for small and large memory models on x86-64 architecture targets with ELF (plus a few tests).

It seemed like a good idea to solicit some feedback about the choices I've made in my implementation before I commit it.  I'm directly addressing a few people who I think might know something about this stuff, but opinions are welcome from everyone.

I expect that the tests will fail on several non-x86-64 platforms, but I don't know which ones.  If someone can take the time to try them out (only the test patch need be applied for this purpose) I'll mark them as XFAIL in advance.  Otherwise, I'm going to have to rely on the buildbots to tell me what won't work.

I've tried to make the GOT support platform independent where possible, but it only gets executed for x86-64 targets.

There were just a few minor tweaks necessary to support large code model PIC, notably handling of the R_X86_64_PC64 relocation type and recognition of ST_Data symbols.

For small code model, I had to handle R_X86_64_PLT32 and R_X86_64_GOTPCREL relocations and thus some sort of PLT and GOT support.  This is more interesting so I'll describe what I did in a bit of detail here.  As background, since MC emits a relocatable object to be loaded by MCJIT we need to do both linking and loading.  An important implication of this is that the emitted object does not contain '.plt' or '.got' sections.  It's left to RuntimeDyld to allocate those as needed.

For R_X86_64_PLT32 it seemed that if the symbol associated with the relocation was a function defined in the module being loaded I could just remap this as a R_X86_64_PC32 relocation which would result in a PC-relative call directly to the function.  I could have done this with external symbols as well, but since there is no way to guarantee in that case that the external function will be within 2^32 bytes of the relocation target I decided it was preferable to implement something like normal PLT support for that case.

I say "something like normal PLT support" because rather than actually allocate a true PLT section/segment I reused the existing stub mechanism in the RuntimeDyld, and I did not implement any sort of lazy binding mechanism.  I did associate a GOT entry with each stub and implemented the stub as a jump using a RIP-relative reference to the address provided in GOT entry.  However, I am always mapping the GOT entry directly to the function at load time.  It should be fairly straight-forward to implement lazy binding in the future if it is needed.

For the GOT support, I added a SmallVector to RuntimeDyldELF which gets populated with RelocationValueRef objects as GOT-based relocations are processed.  I also added a 'finalizeLoad' method in the base RuntimeDyldImpl class to give the ELF implementation a handy place to allocate memory for the GOT, which it does using RuntimeDyldMemoryManager::allocateDataSection().  Initially, I'm leaving all of the GOT entries initialized to zero.  When a relocation is resolved that references a GOT entry I am using the information provided by RuntimeDyldELF::resolveRelocation() (which now knows the actual address of the symbol) to populate the GOT entry.  Finally, the resolveRelocation handler calculates the PC-relative offset to the GOT entry and fills it in.

The GOT implementation was a little messy because the existing ELF relocation processing code was combining the symbol offset and the relocation addend.  Rather than revise all of the code that relied on this usually reasonable behavior I just added a new field to keep the symbol offset and used that to calculate the original addend in the one case where I needed it.

Thanks in advance for any feedback.

-Andy

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130813/1ec94a36/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mcjit-pic.patch
Type: application/octet-stream
Size: 18894 bytes
Desc: mcjit-pic.patch
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130813/1ec94a36/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mcjit-pic-tests.patch
Type: application/octet-stream
Size: 9790 bytes
Desc: mcjit-pic-tests.patch
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130813/1ec94a36/attachment-0001.obj>


More information about the llvm-commits mailing list