pthread_setspecific returns an errno value, unlike the Sce function it wraps,
and neither POSIX export had a test. Check the FreeBSD 11.4 results of
_pthread_setspecific and _pthread_getspecific (lib/libthr/thread/thr_spec.c
lines 165-194 and 196-222): a key outside the valid range or a deleted key
makes setspecific return EINVAL (22), getspecific returns NULL for such a key
and for a key never set, a stored value is read back, NULL can be stored, a
new key with a reused number starts empty, and another thread has its own
value.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
FreeBSD code reaches its thread pointer through %fs and macOS cannot set
the fs base. The macOS relinker turns each %fs access of a guest image
into a stub that reads the thread pointer from a pthread key and calls
Aps5GuestTlsAllocate on a thread's first access, registers the TLS
descriptor of an image with Aps5GuestTlsRegister, and routes
__tls_get_addr to Aps5GuestTlsGetAddr. No library provided them, so a
relinked executable could not start.
- Aps5GuestTlsRegister validates the descriptor the relinker wrote and
creates the key; its destructor frees the block of a thread.
- Aps5GuestTlsAllocateThreadPointer allocates the block (the TLS template
followed by zeros, then a 0x100-byte thread control block whose first
word points at itself, as on FreeBSD) and stores the thread pointer
under the key.
- Aps5GuestTlsAllocate is the entry the stubs call: rax holds the
descriptor and returns the thread pointer, every other register is
preserved, the upper halves of the ymm registers only where AVX exists.
- Aps5GuestTlsGetAddr returns the block of the thread plus the offset.
Co-authored-by: mugurc <[email protected]>
On Linux the first exception the allocation test throws goes through
libc's unwinder, which caches two frame descriptions with operator new
for the rest of the process. The test counted them as blocks leaked by
i2t_ASN1_OBJECT and failed every fault case. A first failing conversion
now runs before the counted cases, and the blocks it leaves are not
tracked. Against the head before the allocation fix the test still
reports the escaped exceptions.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
i2t_ASN1_OBJECT threw and was declared without parameters. It now
prints an object's long name, or its short name, or its dotted OID, as
OBJ_obj2txt does in LibreSSL 2.5.4, the version string the module
holds: the NID is the object's own or found by the same binary search
over the same order, an unassigned NID reports OBJ_R_UNKNOWN_NID for
each name lookup, a truncated subidentifier returns 0 after the parts
already written, and arcs past 64 bits are printed exactly.
The 956 objects (short and long names, NID, OID) and their search order
are generated from 2.5.4's objects.txt and obj_mac.num with its own
objects.pl and obj_dat.pl, so d2i code can later hand out the same
static objects LibreSSL does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>