[PATCH] RuntimeDyldMachO should handle RIP-relative relocations correctly, and the corresponding tests should have coverage for this

Filip Pizlo fpizlo at apple.com
Sun May 12 18:04:18 PDT 2013


The small code model on X86_64 involves using RIP-relative relocations, particularly for the constant pool.

The RuntimeDyldMachO doesn't understand these correctly.  In particular, it doesn't understand what offset immediate will be used in a RIP-relative reference to a local symbol as in:

	.section	__TEXT,__literal8,8byte_literals
	.align	3
LABEL:
     .quad <blah>
	.section	__TEXT,__text,regular,pure_instructions
# …. bunch of things things
addsd LABEL(%rip), %xmm0

In MachO, the "LABEL(%rip)" will be transformed into an offset from the addsd instruction to where the compiler thought the __literal8 section will be placed (plus the offset of the immediate within the __literal8 section, but that offset is zero, in this example).  For example, the compiler may place the __literal8 section right after the __text section, in which case the offset immediate in the addsd instruction will correspond to the size of the __text section, minus the offset of the addsd instruction, and then plus whatever padding/alignment for the __literal8 section.

So, for example, if we then allocated the __literal8 section exactly after the __text section in the MCJIT, then we wouldn't want to change the offset in the addsd instruction.  More broadly, we would want to:

1) subtract out the offset to the __literal8 section according to the MachO file (i.e. the offset from the referencing instruction - the addsd in this example - to the __literal8 section)
2) add in the true offset to the __literal8 section after both __text and __literal8 have addresses in target memory.

Note that after (1) we will have an offset from the start of  __literal8 to the constant that the code is actually referencing.  Then after (2) we have the correct offset that the code should actually be using.

This allows for the __literal8 section to be placed anywhere we want, and also allows the compiler to convey specific offsets inside of constant pools.

This is different from other relocations; for example if we had used the large code model instead, then we would have a load immediate (for example "movabsq $LABEL, %rax"), where the $LABEL that is encoded in the MachO file will be an offset of the __literal8 section relative to the *start* of the module, rather than relative to the instruction that had the reference.

The RuntimeDyldMachO now only gets this part-way right.  It knows how to handle non-PC-relative relocations just fine.  For PC-relative ones, it knows how to do (2) above, but it doesn't understand how to do (1): it assumes that the code has an offset from the start of the module, rather than an offset from the referencing instruction.

The included patch fixes this bug.

I also include a separate patch that does some stuff to the tests, including adding coverage for small code model on x86_64.  It makes sense for a lot of JIT clients to use the small code model, and I believe it's good for LLVM to have test coverage for this.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: fixrip.patch
Type: application/octet-stream
Size: 503 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130512/7f310feb/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fixtests.patch
Type: application/octet-stream
Size: 8393 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130512/7f310feb/attachment-0001.obj>
-------------- next part --------------


-Filip



More information about the llvm-commits mailing list