How to get tls on i386?

36 views
Skip to first unread message

chainhelen

unread,
Feb 1, 2020, 3:31:45 AM2/1/20
to delve-dev
How to get tls on i386? (for parsing G struct)

1. According to sys_linux_386.s#L606
we can konw golang on i386 call `set_thread_area` to set addr about tls.  (Gs about entry_number usually is 0x33 if I understand it rigth?).

2. According to ptrace.2, we can use `PTRACE_GET_THREAD_AREA` to get tls on i386, 
But here ptrace_linux_386.go#L69 ( the code I write ) always get error `invalid argument`.  
line 75 print `!!!!!!  tid := 25589, err := invalid argument, gs := 51`.    

3. In order to resolve this error, I look up for gdb codes and get func `x86_linux_get_thread_area` in `x86-linux-nat.c` , but I don't konw how to call it.



Not sure what's wrong about the way about `sys.PTRACE_GET_THREAD_AREA` ptrace_linux_386.go#L69  in golang ?  
Anyone can help me? Just giving me some ideas to find reason is ok.  
Thx, I will be appreciated.

Alessandro Arzilli

unread,
Feb 3, 2020, 7:06:37 AM2/3/20
to chainhelen, delve-dev
The manpage for ptrace says:

This operation performs a similar task to get_thread_area(2). It reads the TLS entry in the GDT whose index is given in addr, placing a copy of the entry into the struct user_desc pointed to by data. (By contrast with get_thread_area(2), the entry_number of the struct user_desc is ignored.)

And the manpage for get_thread_area says:

EINVAL u_info->entry_number is out of bounds.

Presumably it's returning "invalid argument" because the argument you are passing as addr is wrong.

But judging from the manpages I'd guess that the right way to call that is:

syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GET_THREAD_AREA, uintptr(tid), uintptr(gs), uintptr(unsafe.Pointer(&ud)), 0, 0)

On Sat, Feb 01, 2020 at 12:31:45AM -0800, chainhelen wrote:
> How to get tls on i386? (for parsing G struct)
>
> 1. According to sys_linux_386.s#L606
> <https://github.com/golang/go/blob/dev.boringcrypto.go1.12/src/runtime/sys_linux_386.s#L606>
> ,
> we can konw golang on i386 call `set_thread_area` to set addr about tls.
> (Gs about entry_number usually is 0x33 if I understand it rigth?).
>
> 2. According to ptrace.2
> <http://man7.org/linux/man-pages/man2/ptrace.2.html>, we can use
> `PTRACE_GET_THREAD_AREA` to get tls on i386,
> But here ptrace_linux_386.go#L69
> <https://github.com/chainhelen/delve/blob/i386/pkg/proc/native/ptrace_linux_386.go#L69> (
> the code I write ) always get error `invalid argument`.
> line 75
> <https://github.com/chainhelen/delve/blob/i386/pkg/proc/native/ptrace_linux_386.go#L75>
> print `!!!!!! tid := 25589, err := invalid argument, gs := 51`.
>
> 3. In order to resolve this error, I look up for gdb codes and get func
> `x86_linux_get_thread_area` in `x86-linux-nat.c` , but I don't konw how to
> call it.
>
>
>
> Not sure what's wrong about the way about `sys.PTRACE_GET_THREAD_AREA`
> ptrace_linux_386.go#L69
> <https://github.com/chainhelen/delve/blob/i386/pkg/proc/native/ptrace_linux_386.go#L69>
> in golang ?
> Anyone can help me? Just giving me some ideas to find reason is ok.
> Thx, I will be appreciated.
>
> --
> You received this message because you are subscribed to the Google Groups "delve-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to delve-dev+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/delve-dev/76dc491e-e1b8-4793-a290-9be1bc056cf4%40googlegroups.com.

chainhelen

unread,
Feb 12, 2020, 7:37:31 AM2/12/20
to delve-dev
Oh, thx, I get the right way, the front 3 bit of gs register is entry number. 

syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GET_THREAD_AREA, uintptr(tid), uintptr(gs>>3), uintptr(unsafe.Pointer(&ud)), 0, 0). 

Appreciated.

在 2020年2月3日星期一 UTC+8下午8:06:37,alessandro.arzilli写道:
> To unsubscribe from this group and stop receiving emails from it, send an email to delv...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages