Re: Question on __retarget_lock function
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
On 07/12/2024 08:58, Kedar Karandikar wrote: > Hi > I am trying to override the __retarget_lock* dummy functions that are > provided by NewLib lock.c in my baremetal environment. > > I was trying not to touch the newlib source code, but rather implement > those functions in my framework. > > However, the functions defined in lock.c do not have a “weak” attribute > next to the functions and this causes linker error when I try to define > them in my framework. > > Any reason why they are not defined as weak? Is the expectation that I > update the functions directly in newlib lock.c and compile the newlib > after that? > > Thanks for the help! > > -Kedar K Karandikar I had the same problem with the version of Newlib provided with the GCC toolchain with STM's STM32CubeIDE. (And the OpenSTM32 Workbench one as well.) The problem is that 'struct _lock' and _LOCK_T (struct _lock *) are supposed to be defined by the target platform implementer. Because of this, the functions cannot be defined as weak so as to be overridable by the end user. Newlib's lock.c is simply an example dummy implementation but STM in their stupidity chose to simply compile in this code which defines struct _lock as being a single byte structure. That makes reimplementing for, say, FreeRTOS tricky. What I did was use GCC's symbol wrapper to reimplement all the __retarget_lock_xxxx() functions and overlay them in the linker. (See the GCC LD --wrap option.) The functions can simply cast the _LOCK_T arguments to pointers to the real mutex objects (e.g. cast to SemaphoreHandle_t which is itself a pointer to an opaque mutex object) and do similar for the _LOCK_T pointer output parameters in the init functions after obtaining a mutex pointer from the threading library. However all the wrapper functions check their _LOCK_T arguments against a static lookup table mapping from pointers to the predefined library lock objects (e.g. &__lock___sinit_recursive_mutex) to actual mutex objects/object pointers values. Before starting the main() and switching into multithreaded mode, I call an internal function that creates/initialized recursive or non-recursive mutexes as appropriate for all the NULL SemaphoreHandle_t values in the lookup table. It's messy but it works. Unfortunately, that's just the start of your problem if your vendor has compiled in the dummy lock.c. If they've compiled GCC single-threaded, the C++ STL, C & C++ atomics either aren't implemented or aren't thread safe either which has knock-on effects for everything else in the C++ libraries when using a pre-emptive threading library A better approach to take if you have the time is to bite the bullet and create your own GCC & newlib toolchain, provide the required stubs for all newlib's locking and for POSIX threads using your threading library and compile GCC as POSIX-thread aware. That way all the C/C++ atomics and Newlib APIs are fully reentrant. But it's a much bigger job of course. -- Sam Edge
OpenPGP_0xE6200DE0C92CEC06_and_old_rev.asc
(application/pgp-keys, 1.1 KB)
-----BEGIN PGP PUBLIC KEY BLOCK----- xjMEZRUsPRYJKwYBBAHaRw8BAQdAJJIM3nIi/0AlR8YNKSbIucsGaX/dfmp7oBLT C6Di1UHNIlNhbSBFZGdlIDxzYW0uZWRnZS5uZXdsaWJAZ214LmNvbT7CjwQTFggA NxYhBNdZ6mE651AobMQsM+YgDeDJLOwGBQJlFSw9BQkSzAMAAhsDBAsJCAcFFQgJ CgsFFgIDAQAACgkQ5iAN4Mks7AY5JAEApAAHuSOu21+x2uLpSmN2mi/yCAS5cGpy OYfUVJ6kTloA+wVEhOFeeRAl8jQCEw0QOki/+7hGW1N9z3qG+ND14vUIzjgEZRUs PRIKKwYBBAGXVQEFAQEHQKiCziMIYxB6C419NstmKUgH6/TQ0DmtAqBhhBjEC9UZ AwEIB8J+BBgWCAAmFiEE11nqYTrnUChsxCwz5iAN4Mks7AYFAmUVLD0FCRLMAwAC GwwACgkQ5iAN4Mks7AbuRgD+IQL27tV1vjSXHL0uKObS+pcZETsH3FA1LwR8cZw3 3x4A/iqA04meXfecoyi3lr5O20NsWSsucpzazIAH8hYzrT0OxjMEZRUsPBYJKwYB BAHaRw8BAQdAfTvjyHM/Oum9+RhQ4sczPMQ3qZ1rvy+R7xOgV5fIpWLCeAQgFggA IBYhBNT+XGXKdDxOakWZc0GqKxqf/+MDBQJlFTKLAh0AAAoJEEGqKxqf/+MDuTEA /0gy4cxdzIE7hL3ehbcjmkpqc0CHnkbYPnUsweMxZAcTAQCKWOy7f66LyqsImOHg EBCQ+ttUK1xX+fl7wtoeeG/RBc44BGUVLDwSCisGAQQBl1UBBQEBB0DNsJdpv0iR 5XIyxFG8OSqDQojGSVmaSCFwiUXjRxwPDAMBCAfCfgQYFggAJhYhBNT+XGXKdDxO akWZc0GqKxqf/+MDBQJlFSw8BQkSzAMAAhsMAAoJEEGqKxqf/+MDY84BALkIC2Ao 5uqJlP2hIfRyAlDO3CiGB+pcoPqfL+yTLFQzAP46VlC/2Ll0LI3tBmYZ0aDLu0N+ bN3b0msL+HioGuigBg== =R8EG -----END PGP PUBLIC KEY BLOCK-----
OpenPGP_signature.asc
(application/pgp-signature, 236 B)
-----BEGIN PGP SIGNATURE----- wnsEABYIACMWIQTXWephOudQKGzELDPmIA3gySzsBgUCZ1QrnAUDAAAAAAAKCRDmIA3gySzsBs+J APwKhDT3c7CJ8bhHwy9YtpAshvdyMbpbNeFLiIx5kNswIwD/YqhLAOtawC5CKuTqdRkfe10nJjCr C7xioXy/HjFMEAg= =Bcms -----END PGP SIGNATURE-----