Post by Marc MutzI don't see any difference between the staticMetaObject's declared in
and generated from Q_GADGET as opposed to ones in/from Q_OBJECT with the
notable exception of a non-nullptr parent metaobject pointer. I don't
see, though, how a nullptr could cause a relocation whereas a
non-nullptr removes it.
Is that a known issue? Does someone have an explanation?
Let's look at the .so:
# Getting the size of QMetaObject
$ gcc -fPIE -xc++ -S -o - -I$QTOBJDIR/include -include QtCore/qobject.h -
<<<'int x = sizeof(QMetaObject);' | grep -A1 x:
x:
.long 48
# Getting the addresses of two meta objects
$ nm -DC libQt5Core.so | egrep '(QEvent|QCoreApplication)::staticMetaObject'
00000000006703a0 D QCoreApplication::staticMetaObject
00000000006690e0 D QEvent::staticMetaObject
# Get the section addresses (eu-readelf prints in one line)
$ eu-readelf -S libQt5Core.so | \
awk ' /00000000006[67]/ { printf "%-20s %16s %08s %s\n", $2, $4, $6, $8 }'
.tbss 00000000006683e0 00000008 WAT
.data.rel.ro.local 00000000006683e0 00000d30 WA
.jcr 0000000000669110 00000008 WA
.data.rel.ro 0000000000669120 00008178 WA
.dynamic 0000000000671298 000002b0 WA
.got 0000000000671560 00000a88 WA
.got.plt 0000000000671fe8 000075d8 WA
.data 00000000006795c0 00000c70 WA
.tm_clone_table 000000000067a230 00000000 WA
.fini_array 000000000067a230 00000010 WA
.init_array 000000000067a240 00000060 WA
.bss 000000000067a2a0 00001c50 WA
So we conclude that QEvent::staticMetaObject is in .data.rel.ro.local but
QCoreApplication::staticMetaObject is in .data.rel.ro.
So both objects are in "read only data that can't be in .rodata because it has
relocations" sections. The difference is the .local part. Otherwise, both
sections are identical: same permissions and both get listed in the same ELF
segments (check with eu-readelf -l or readelf -l).
Let's look at the relocations for those symbols:
# Here's where the size of the object is useful
$ objdump -R libQt5Core.so.5 | egrep '^0000000000669(0e|0f|10).' | sort
00000000006690e8 R_X86_64_RELATIVE *ABS*+0x0000000000565800
00000000006690f0 R_X86_64_RELATIVE *ABS*+0x0000000000564d20
$ objdump -R libQt5Core.so.5 | grep '^00000000006703[abc].' | sort
00000000006703a0 R_X86_64_64 _ZN7QObject16staticMetaObjectE
00000000006703a8 R_X86_64_RELATIVE *ABS*+0x0000000000564c00
00000000006703b0 R_X86_64_RELATIVE *ABS*+0x0000000000564a60
00000000006703b8 R_X86_64_RELATIVE *ABS*+0x0000000000432560
So here is seemingly the cause: a relocation by name, as opposed to a relative
relocation.
So it's not that nullptr causes a relocation. It *removes* a relocation.
That's the difference.
You may be asking what the difference is. Well, I guess the difference wouldn't
show up on a library. It would only show up on an executable, where the
relocations to the base address would be resolved by the static linker.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center