In the (inlined) function para_strerror() of error.h we compile in
the call to osl_strerror() if and only if osl.h has been included
(in which case the preprocessor macro _OSL_H is defined). This is
wrong because an osl error code might well be passed to a function
defined in a compilation unit which does not include osl.h. If this
function calls para_strerror(), we will segfault or worse.
We need to check at link time whether osl_strerror is a defined
symbol rather than checking a preprocessor macro at compile time.
Fortunately, a little linker fu helps us out here. This patch
introduces a weak reference to osl_strerror to tell whether
osl_strerror is defined.
/** Set the osl error bit for the given number. */
#define OSL_ERRNO_TO_PARA_ERROR(num) ((num) | (1 << OSL_ERROR_BIT))
+
+static const char *weak_osl_strerror(int) __attribute__ ((weakref("osl_strerror")));
/**
* Paraslash's version of strerror(3).
*
_static_inline_ const char *para_strerror(int num)
{
assert(num > 0);
-#ifdef _OSL_H
- if (IS_OSL_ERROR(num))
- return osl_strerror(num & ~(1U << OSL_ERROR_BIT));
-#endif
+ if (IS_OSL_ERROR(num)) {
+ assert(weak_osl_strerror);
+ return weak_osl_strerror(num & ~(1U << OSL_ERROR_BIT));
+ }
if (IS_SYSTEM_ERROR(num))
return strerror(num & ~(1U << SYSTEM_ERROR_BIT));
return para_errlist[ERRNUM_TO_SS(num)][ERRNUM_TO_INDEX(num)];