[Development] Q_GADGET = relocation on staticMetaObject; Q_OBJECT = no relocation; known?

Thiago Macieira thiago.macieira at intel.com
Tue Oct 1 02:30:33 CEST 2013


On terça-feira, 1 de outubro de 2013 01:09:07, Marc Mutz wrote:
> I 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20130930/8719551a/attachment.sig>


More information about the Development mailing list