Open andykaylor opened 11 years ago
mentioned in issue llvm/llvm-bugzilla-archive#20457
I filed a separate bug as http://llvm.org/bugs/show_bug.cgi?id=21423
I believe you should be able to work around that problem by compiling with large memory model, which prevents generation of the relocation in question.
This doesn't seem to be the case.
$ cat test.s test: .cfi_startproc .cfi_endproc $ as test.s -o test.o; readelf -r test.o R_X86_64_PC32 $ llvm-mc -filetype=obj test.s -o test.o; readelf -r test.o R_X86_64_PC32 $ llvm-mc -filetype=obj -code-model=large test.s -o test.o; readelf -r test.o R_X86_64_PC32
That is, this particular relocation is always R_X86_64_PC32, regardless of code model.
Which large memory model compiling option are you talking about?
Sorry, llvm calls it CodeModel. I believe it is an argument to most of the API functions for creating an instance of MCJIT, but I believe it can also be embedded in a Module. I'm not sure which one is used if they conflict, but probably the one in the Module.
If you use CodeModel::JITDefault that will get translated to CodeModel::Large on 64-bit x86 platforms. By contrast, CodeModel::Default is translated to CodeModel::Small.
You could also try using the PIC relocation model. I know PIC support is at least partially implemented for Intel64 architecture, but I don't know how robust it is.
What is the right solution here?
I believe you should be able to work around that problem by compiling with large memory model, which prevents generation of the relocation in question.
Which large memory model compiling option are you talking about?
What is the right solution here?
I believe you should be able to work around that problem by compiling with large memory model, which prevents generation of the relocation in question.
FTL http://trac.webkit.org/wiki/FTLJIT seems to hit this problem. FTL tells LLVM to use its own memory manager, instead of using the default SectionMemoryManager.
JavaScriptCore's memory manager happens to allocate code sections and data sections far away, not near to each other. There are R_X86_64_PC32 relocations from .eh_frame (a data section) to .text (a code section), which trigger an assertion failure.
What is the right solution here?
Generating a stub for function calls will work for everything except for function pointer comparison. However there's nothing you can do about data references. I think the proper solution would be to use the Small position independent code model (PIC) and use the GOT/PLT for references, as they can be resolved as 64 bit and will give proper function pointers. I don't see a need to generate large or medium model code.
Extended Description
On x86-64 platforms, RuntimeDyldELF cannot be guaranteed to handle 32-bit relative relocations correctly. Although the SectionMemoryManager attempts to allocate all loaded sections in proximity to one another, this cannot be guaranteed. Furthermore, RuntimeDyldELF should not be dependent upon the memory manager's allocation scheme to perform correctly.
The specific relocation in question is R_X86_64_PC32, which is typically used with a call or jump instruction. It may be possible to solve this problem by generating a stub within the source section that can bridge the gap to the target section. However, some investigation is necessary to verify that this approach will work in all cases.
Note that the assertion in the RuntimeDyldELF handler for the R_X86_64_32 and R_X86_64_32S relocation types covers a different situation. If that assertion fires, it is almost certainly because code was generated with the small memory model and is being loaded above the 2GB boundary. When the small memory model is used on x86-64 (not recommended), it is the responsible of the client code to provide a memory manager which guarantees that code will be loaded below the 2GB boundary.