On 12 December 2013 21:02, Michael Hudson-Doyle
<michael.hud...@linaro.org> wrote:
> Hi,
>
> Thanks for the respsonse.
>
> Will Newton <will.new...@linaro.org> writes:
>
>> On 12 December 2013 08:00, Michael Hudson-Doyle
>> <michael.hud...@linaro.org> wrote:
>>> Hi all,
>>>
>>> I have a bit of a strange one.  I'm not after a full solution, just any
>>> hints that quickly come to mind :)
>>>
>>> After a few simple patches I have a build of mongodb for aarch64 (built
>>> with gcc-4.8).  However, all of the test binaries that the build spits
>>> out immediately segfault.  gdb-ing shows that they segfault inside this
>>> macro:
>>>
>>> TSP_DECLARE(OwnedOstreamVector, threadOstreamCache);
>>>
>>> This expands to:
>>>
>>> #  define TSP_DECLARE(T,p) \
>>>     extern __thread T* _ ## p; \
>>>     template<> inline T* TSP<T>::get() const { return _ ## p; } \
>>>     extern TSP<T> p;
>>>
>>> And indeed, it's mongo::TSP<mongo::OwnedPointerVector<...> >::get()
>>> const that we're segfaulting in.  This is the disassembly of this
>>> function (at -O0) with the faulting instruction marked:
>>>
>>>    0x00000000004b4b6c <+0>:     stp     x29, x30, [sp,#-32]!
>>>    0x00000000004b4b70 <+4>:     mov     x29, sp
>>>    0x00000000004b4b74 <+8>:     str     x0, [x29,#16]
>>>    0x00000000004b4b78 <+12>:    adrp    x0, 0x64c000
>>>    0x00000000004b4b7c <+16>:    ldr     x0, [x0,#776]
>>>    0x00000000004b4b80 <+20>:    nop
>>>    0x00000000004b4b84 <+24>:    nop
>>>    0x00000000004b4b88 <+28>:    mrs     x1, tpidr_el0
>>>    0x00000000004b4b8c <+32>:    add     x0, x1, x0
>>> => 0x00000000004b4b90 <+36>:    ldr     x0, [x0]
>>>    0x00000000004b4b94 <+40>:    ldp     x29, x30, [sp],#32
>>>    0x00000000004b4b98 <+44>:    ret
>>>
>>> And the registers:
>>>
>>> (gdb) info registers
>>> x0             0x7fb863fd70     548554407280
>>
>> This value looks surprisingly large if it is an offset from TP (x1).
>
> Yeah, it does a bit doesn't it.
>
> (gdb) p/x $x0 - $x1
> $9 = 0x648680
>
> (not really a suspicious number)
>
> I guess I don't understand the adrp code.  My understanding is that:
>
> 0x00000000004b4b78 <+12>:    adrp    x0, 0x64c000
>
> would result in 0x4b4000 + 0x64c000 in x0 and then

The disassembler may have done this for you, would 0x64c000 make more sense?

> 0x00000000004b4b7c <+16>:    ldr     x0, [x0,#776]
>
> reads from 0x4b4000 + 0x64c000 + 776 but
>
> (gdb) x 0x4b4000 + 0x64c000 + 776
> 0xb00308:       Cannot access memory at address 0xb00308
>
> (I'm not sure if the disassembly for adrp has the immediate shifted or
> not, but anyway:
>
> (gdb) x 0x4b4000 + (0x64c000<<12) + 776
> 0x4c4b4308:     Cannot access memory at address 0x4c4b4308)
>
> So I'm clearly missing something here...
>
>>> x1             0x7fb7ff76f0     548547819248
>>
>> Have you tried printing the memory at this address? It looks like it
>> is probably ok...
>
> Yeah, it's fine.

I guess that means that the thread pointer is probably correct.

> (gdb) x/20g $x1
> 0x7fb7ff76f0:   0x0000007fb7ff7e28      0x0000000000000000
> 0x7fb7ff7700:   0x0000000000000000      0x0000000000000000
> 0x7fb7ff7710:   0x0000000000000000      0x0000000000000000
> 0x7fb7ff7720:   0x0000000000000000      0x0000007fb7e5ce50
> 0x7fb7ff7730:   0x0000007fb7e5fff8      0x0000000000000000
> 0x7fb7ff7740:   0x0000007fb7e1bab8      0x0000007fb7e1b4b8
> 0x7fb7ff7750:   0x0000007fb7e1c3b8      0x0000007fb7e5c550
> 0x7fb7ff7760:   0x0000000000000000      0x0000000000000000
> 0x7fb7ff7770:   0x0000000000000000      0x0000000000000000
> 0x7fb7ff7780:   0x0000000000000000      0x0000000000000000
>
> The end of /proc/$pid/maps looks like this:
>
> 7fb7fd3000-7fb7fee000 r-xp 00000000 08:01 4330216                        
> /lib/aarch64-linux-gnu/ld-2.17.so
> 7fb7ff3000-7fb7ffc000 rwxp 00000000 00:00 0
> 7fb7ffc000-7fb7ffe000 r-xp 00000000 00:00 0                              
> [vdso]
> 7fb7ffe000-7fb7fff000 r-xp 0001b000 08:01 4330216                        
> /lib/aarch64-linux-gnu/ld-2.17.so
> 7fb7fff000-7fb8001000 rwxp 0001c000 08:01 4330216                        
> /lib/aarch64-linux-gnu/ld-2.17.so
> 7ffffdf000-8000000000 rwxp 00000000 00:00 0                              
> [stack]
>
> So $x1 is within a random 36k map and $x0 is off in la la land between
> a bit of ld-2.17.so and the stack.
>
>>> x2             0x0      0
>>> x3             0x7fb7fc11b8     548547596728
>>> x4             0x1      1
>>> x5             0x0      0
>>> x6             0x50     80
>>> x7             0x0      0
>>> x8             0x0      0
>>> x9             0x6165727473676f4c       7018141438804717388
>>> x10            0x0      0
>>> x11            0x0      0
>>> x12            0x2      2
>>> x13            0x10     16
>>> x14            0x0      0
>>> x15            0x7fb7e5e590     548546143632
>>> x16            0x64b3d8 6599640
>>> x17            0x7fb7f667d0     548547225552
>>> x18            0x7fffffdab0     549755804336
>>> x19            0x7fffffed50     549755809104
>>> x20            0xb      11
>>> x21            0xb      11
>>> x22            0x6500b0 6619312
>>> x23            0x650070 6619248
>>> x24            0x7fffffff       2147483647
>>> x25            0x64db40 6609728
>>> x26            0x7fffffeda0     549755809184
>>> x27            0x653d00 6634752
>>> x28            0x7fffffe750     549755807568
>>> x29            0x7fffffe4d0     549755806928
>>> x30            0x4b4ed4 4935380
>>> sp             0x7fffffe4d0     0x7fffffe4d0
>>> pc             0x4b4b90 0x4b4b90 
>>> <mongo::TSP<mongo::OwnedPointerVector<std::basic_ostringstream<char, 
>>> std::char_traits<char>, std::allocator<char> > > >::get() const+36>
>>> cpsr           0x20000000       536870912
>>> fpsr           0x0      0
>>> fpcr           0x0      0
>>>
>>> If I recompile this object file without -fPIC, it works.
>>>
>>> I guess I see three things that could be wrong:
>>>
>>>  1) The operand to "adrp    x0, 0x64c000"[1]
>>>  2) The operand to "ldr     x0, [x0,#776]"
>>
>> Is there a dynamic reloc for this GOT slot?
>
> How would I tell? :)

Generally the TLS code will load the TP then load an offset from the
GOT that the dynamic linker has fixed up based on a dynamic relocation
which should reference the correct symbol etc.

I would guess that 0x64c000 is the base of the GOT and 776 is the
offset into it (but I could be wrong). objdump -h will give you the
layout of the sections, objdump -R will dump the relocations.

-- 
Will Newton
Toolchain Working Group, Linaro

_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to