Hello
I hope someone can educate me on this.
Recently I encountered code where object file had relocation of type R_X86_64_32S, and definition of it was in some python .so file. The object file was build without -fpic. This was with llvm-12:
00000000004006e0 <_ZN22shared_ptr_from_python11convertibleEP7_object>:
4006e0: b9 28 10 60 00 movl $0x601028, %ecx # imm = 0x601028
00000000004006e1: R_X86_64_32 _Py_NoneStruct
4006e5: 31 c0 xorl %eax, %eax
4006e7: 48 81 ff 28 10 60 00 cmpq $0x601028, %rdi # imm = 0x601028
00000000004006ea: R_X86_64_32S _Py_NoneStruct
4006ee: 48 0f 44 c1 cmoveq %rcx, %rax
4006f2: c3 retq
4006f3: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
4006fd: 0f 1f 00 nopl (%rax)
With llvm-15/trunk it is using what I would expect:
0000000000001160 <_ZN22shared_ptr_from_python11convertibleEP7_object>:
1160: 48 8b 0d 71 2e 00 00 movq 0x2e71(%rip), %rcx # 0x3fd8 <main.cpp+0x3fd8>
0000000000001163: R_X86_64_REX_GOTPCRELX _Py_NoneStruct-0x4
1167: 31 c0 xorl %eax, %eax
1169: 48 39 cf cmpq %rcx, %rdi
116c: 48 0f 44 c1 cmoveq %rcx, %rax
1170: c3 retq
1171: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
117b: 0f 1f 44 00 00 nopl (%rax,%rax)
I think I am missing something, but shouldn’t it always go through GOT since it’s not known where dynamic linker will load the dynamic library?
Small(ish) Repro build with -O3
helper.hpp
extern "C" {
typedef struct _object {
int p;
} PyObject;
extern PyObject _Py_NoneStruct;
}
struct shared_ptr_from_python {
void *(*foo)(PyObject *p);
shared_ptr_from_python() {
foo = &convertible;
}
private:
static void* convertible(PyObject *p) {
if (p == (&_Py_NoneStruct))
return p;
return 0;
}
};
main.cpp
#include "helper.hpp"
extern int helper2(shared_ptr_from_python &ptr);
extern PyObject *_Py_NoneStruct2;
int main(){
shared_ptr_from_python ptr;
return helper2(ptr);
}