Page 1 of 1
How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Sun Aug 25, 2024 11:35 am
by stopa
Hi, I'm trying to port a library that uses pthread, and thread local storage. After compiling and linking, I get undefined references to __tls_get_addr, that's why I'm trying to implement it.
After looking up how to implement it, I came across this site:
https://maskray.me/blog/2021-02-14-all- ... al-storage
This site explains that there's one parameter of type size_t* that points to an array of two elements, a module ID, and the offset from the beginning of the local storage respectively, and that it returns a void*. With this information, I tried some variations of this implementation:
void *__tls_get_addr(size_t *v)
{
void* localStorage = getThreadLocalStorage();
const size_t tls_index = v[1];
return localStorage + tls_index;
}
I also tried using getThreadStaticBuffers instead, with no success. (The 3ds crashes only when trying to access these specific tls variables, after returning from the __tls_get_addr function)
If anyone has any idea of how I could achieve a correct implementation I would really appreciate it
.
Re: How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Mon Sep 02, 2024 5:08 pm
by fincs
On the 3DS (and on the Switch) we use the local-exec TLS model. __tls_get_addr is a function used in other (slower) TLS models. Which library are you trying to port exactly? I suspect the library is being built with incorrect compiler flags.
Re: How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Tue Sep 03, 2024 5:46 pm
by stopa
Hi!
I'm trying to port librdkafka.
I managed to get TLS working (apparently) a few days ago using the "-ftls-model=initial-exec" flag to compile the library.
That way it wouldn't have to use the __tls_get_addr function.
Is there a reason we should use local-exec?
Re: How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Tue Sep 03, 2024 5:53 pm
by fincs
Dynamic linking does not exist on 3DS, so there is effectively no difference between initial-exec and local-exec. In any case, using local-exec makes it explicit that we assume all TLS variables to be contained within the same (only) module.
Usually it should not be necessary to explicitly specify the TLS model when building code. Which exact steps did you follow to build librdkafka? To me it sounds like something is being miscompiled as a shared library (which, like I said, does not work on 3DS).
Re: How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Wed Sep 04, 2024 8:44 pm
by stopa
I'm using this command to configure build:
Code: Select all
NM=${DEVKITARM}/bin/arm-none-eabi-nm LD=${DEVKITARM}/bin/arm-none-eabi-ld \
STRIP=${DEVKITARM}/bin/arm-none-eabi-strip \
OBJDUMP=${DEVKITARM}/bin/arm-none-eabi-objdump \
RANLIB=${DEVKITARM}/bin/arm-none-eabi-ranlib \
AR=${DEVKITARM}/bin/arm-none-eabi-ar \
STATIC_LIB_libpthread=${DEVKITARM}/arm-none-eabi/lib/libpthread.a \
STATIC_LIB_libctru=${DEVKITPRO}/libctru/lib/libctru.a
./configure --cc="${DEVKITARM}/bin/arm-none-eabi-gcc" \
--cxx="${DEVKITARM}/bin/arm-none-eabi-g++" \
--enable-static --disable-zstd --disable-ssl --disable-devel --arch=armv6k \
--CXXFLAGS=" -fno-exceptions -fpic -march=armv6k -mtune=mpcore -mtp=soft -mfloat-abi=hard -std=gnu++23 -ftls-model=initial-exec" \
--CFLAGS="-D__3DS__ -std=gnu23 -g -Wall -O2 -mword-relocations -ffunction-sections -fstack-protector-all -march=armv6k -mfloat-abi=hard -mtp=soft -fpic -ftls-model=initial-exec" \
--includedir=${DEVKITPRO}/libctru/include/ \
--libdir=${DEVKITPRO}/libctru/lib/ \
--LDFLAGS="-g -march=armv6k -mtune=mpcore -mtp=soft -fpic -mfloat-abi=hard -ftls-model=initial-exec" \
--target=arm-none-eabi --disable-shared --enable-syslog --enable-devel
After that, make'ing and make install'ing should install the static lib to ${DEVKITPRO}/libctru/ (include and lib folders) which isn't the best, but oh well.
All of the following are the changes necessary to compile the library, not for it to run and work. There are some other changes for it to half-ass run.
I'll be hosting the code in my github page as I think that's easier than making all the changes manually.
https://github.com/Noxor11/librdkafka-3ds
I wanted to include changes here, but this site thinks I'm a spammer just because I use tutanota.
Re: How should I implement __tls_get_addr (if it shouldn't be implemented already)
Posted: Thu Sep 05, 2024 8:16 pm
by WinterMute
You don't need most of what you've added to your configure command.
Code: Select all
source /opt/devkitpro/3dsvars.sh
./configure --host=arm-none-eabi --prefix=/path/to/local/libs \
--enable-static --disable-ssl --disable-devel --arch=armv6k \
--disable-shared --enable-syslog --enable-devel \
--CFLAGS=${CFLAGS} \
--CXXFLAGS=${CXXFLAGS} \
--LDFLAGS=${LDFLAGS}
Should do most of what you need. Ideally PR a package with this when it's usable. https://github.com/confluentinc/librdka ... cket_msg.h is probably something we want to sort out at toolchain level.
You should look perhaps at some way to disable ipv6 support rather than replacing ipv6 structs with ipv4 ones. I appreciate you're still just getting this thing to compile at this stage but worth noting for future endeavours.
Also: please note --prefix=/path/to/local/libs should ideally not be /opt/devkitpro/portlibs/3ds because ultimately that should be where official packages get installed & placing things there manually causes issues.