I ended up figuring this out for myself, and I provide details here in
case they are useful for others :
To get gdbserver working with TLS reg support was just a case of
recompiling gdbserver with a sysroot generated from my own release.
That was fairly simple (after fixing gdb to work with my header files
that seem to be different from standard in some way).
However, while doing this, I also got gdbserver to be able to debug
multiple threads. This required a new function in libthread_db.so.
I dont have time to submit this as a patch to google, so I will include
it here. Feel free to submit it to google as a patch if you have the
time. This is the log from my svn server. The summary is that I added
td_thr_tls_get_addr to libthread_db.so to get the tls area of a
requested thread. I also made libdl build a static version of its
library as well as the dynamic one so that gdbserver can be built
statically against it (this is not required just to get multithreaded
gdbserver working).
Hope this is of help to someone
Bob
Index: bionic/libthread_db/include/thread_db.h
===================================================================
--- bionic/libthread_db/include/thread_db.h (revision 914)
+++ bionic/libthread_db/include/thread_db.h (revision 915)
@@ -136,6 +136,9 @@
extern char const ** td_symbol_list(void);
+extern td_err_e
+td_thr_tls_get_addr(const td_thrhandle_t *th, void *map_address,
+ size_t offset, void **address);
#ifdef __cplusplus
}
#endif
Index: bionic/libthread_db/libthread_db.c
===================================================================
--- bionic/libthread_db/libthread_db.c (revision 914)
+++ bionic/libthread_db/libthread_db.c (revision 915)
@@ -181,3 +181,12 @@
return err;
}
+td_err_e
+td_thr_tls_get_addr(const td_thrhandle_t *th, void *map_address,
+ size_t offset, void **address)
+{
+ pthread_t pth = th->tid;
+ *address = pthread_get_tls(pth);
+ return TD_OK;
+}
+
Index: bionic/libdl/Android.mk
===================================================================
--- bionic/libdl/Android.mk (revision 914)
+++ bionic/libdl/Android.mk (revision 915)
@@ -53,6 +53,55 @@
include $(BUILD_SHARED_LIBRARY)
+include $(CLEAR_VARS)
+
+# NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so
pulls from
+# libgcc.a are made static to libdl.so. This in turn ensures that
libraries that
+# a) pull symbols from libgcc.a and b) depend on libdl.so will not rely
on libdl.so
+# to provide those symbols, but will instead pull them from libgcc.a.
Specifically,
+# we use this property to make sure libc.so has its own copy of the
code from
+# libgcc.a it uses.
+#
+# DO NOT REMOVE --exclude-libs!
+
+LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a
+
+# for x86, exclude libgcc_eh.a for the same reasons as above
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_ARCH),x86)
+LOCAL_LDFLAGS += -Wl,--exclude-libs=libgcc_eh.a
+endif
+endif
+
+LOCAL_SRC_FILES:= libdl.c
+
+LOCAL_MODULE:= libdl
+
+# NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a
needs a
+# few symbols from libc. Using --no-undefined here results in having to
link
+# against libc creating a circular dependency which is removed and we
end up
+# with missing symbols. Since this library is just a bunch of stubs, we set
+# LOCAL_ALLOW_UNDEFINED_SYMBOLS to remove --no-undefined from the
linker flags.
+LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+
+ifeq ($(TARGET_ARCH),sh)
+# for SuperH, additional code is necessary to handle .ctors section.
+GEN_SOBEGIN := $(TARGET_OUT_STATIC_LIBRARIES)/sobegin.o
+$(GEN_SOBEGIN): $(LOCAL_PATH)/arch-sh/sobegin.S
+ @mkdir -p $(dir $@)
+ $(TARGET_CC) -o $@ -c $<
+
+GEN_SOEND := $(TARGET_OUT_STATIC_LIBRARIES)/soend.o
+$(GEN_SOEND): $(LOCAL_PATH)/arch-sh/soend.S
+ @mkdir -p $(dir $@)
+ $(TARGET_CC) -o $@ -c $<
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GEN_SOBEGIN) $(GEN_SOEND)
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
BUILD_DLTEST:=0
ifeq ($(BUILD_DLTEST),1)
Index: bionic/libc/include/pthread.h
===================================================================
--- bionic/libc/include/pthread.h (revision 914)
+++ bionic/libc/include/pthread.h (revision 915)
@@ -107,6 +107,7 @@
extern "C" {
#endif
+void** pthread_get_tls(pthread_t *thread);
int pthread_attr_init(pthread_attr_t * attr);
int pthread_attr_destroy(pthread_attr_t * attr);
Index: bionic/libc/bionic/pthread.c
===================================================================
--- bionic/libc/bionic/pthread.c (revision 914)
+++ bionic/libc/bionic/pthread.c (revision 915)
@@ -1879,3 +1879,10 @@
}
return 0;
}
+
+void** pthread_get_tls(pthread_t *thread)
+{
+ pthread_internal_t * pthi = (pthread_internal_t *)thread;
+ return pthi->tls;
+}
+
On 04/11/10 15:41, Robert Beckett wrote:
Hi,
In porting android to our A8 cortext based board, we have enabled TLS.
This works fine with bionic in general, however, it seems to cause
problems with gdbserver.
Looking at the gdbserver source, it tries to get an address for
td_thr_tls_get_addr, which is not implemented in bionics thread-db
library.
Can anyone tell me if google are planning on adding support for this
to their thread-db library, or give me hints on how to implement this
myself?
When I last looked at this a while ago (cant remember where in the
source I saw it), it looked like bionic (specifically the linker)
assumed a set format and address for the TLS area, which may not be
compatible with glibc (presumably what gdbserver is targetting).
Certainly the function to get the TLS address i seem to remember just
used a macro which gave a known address plus and offset for the TLS
address. Does anyone know if just implementing the function that gdb
expects to just call the tls address macro (cant remember the name off
hand) would work, or would the TLS structure in memory be incompatible
with gdb.
The only other alternative would be for us to disable TLS support,
which other manufacturers seem to do. Can someone comment on why TLS
is not gernerally enabled?
Thanks
Bob
--
unsubscribe: [email protected]
website: http://groups.google.com/group/android-porting