Skip to content

Commit

Permalink
Add weak ceilf symbol and definition (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anilm3 committed Feb 16, 2024
1 parent 961551e commit 2931993
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 16 deletions.
10 changes: 6 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ endif()

include(GNUInstallDirs)

add_library(glibc_compat OBJECT ${libddwaf_SOURCE_DIR}/src/glibc-compat/time64.c)
set_target_properties(glibc_compat PROPERTIES POSITION_INDEPENDENT_CODE 1)
add_library(glibc_compat_time64 OBJECT ${libddwaf_SOURCE_DIR}/src/glibc-compat/time64.c)
set_target_properties(glibc_compat_time64 PROPERTIES POSITION_INDEPENDENT_CODE 1)

add_library(glibc_compat_math OBJECT ${libddwaf_SOURCE_DIR}/src/glibc-compat/math.c)
set_target_properties(glibc_compat_math PROPERTIES POSITION_INDEPENDENT_CODE 1)

try_compile(STDLIB_MAP_RECURSIVE ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/try_rec_map.cpp
Expand All @@ -68,8 +71,7 @@ if(LINUX)
set(LIBDDWAF_INTERFACE_LIBRARIES
$<$<BOOL:${LIBPTHREAD}>:pthread>
$<$<BOOL:${LIBRT}>:rt>
$<$<BOOL:${LIBDL}>:dl>
$<$<BOOL:${LIBM}>:m>)
$<$<BOOL:${LIBDL}>:dl>)
elseif(WIN32)
list(APPEND LIBDDWAF_INTERFACE_LIBRARIES ws2_32)
endif()
Expand Down
4 changes: 2 additions & 2 deletions cmake/shared.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if(LINUX)
-Wl,--build-id=0x${BUILD_ID}
${LIBDDWAF_PRIVATE_LIBRARIES}
-static-libstdc++
glibc_compat)
glibc_compat_time64 glibc_compat_math)

if(NOT (CMAKE_BUILD_TYPE MATCHES Debug))
set(SYMBOL_FILE $<TARGET_FILE:libddwaf_shared>.debug)
Expand Down Expand Up @@ -79,5 +79,5 @@ elseif (MINGW)
-Wl,--build-id=0x${BUILD_ID}
${LIBDDWAF_PRIVATE_LIBRARIES}
-static-libstdc++
glibc_compat)
glibc_compat_time64 glibc_compat_math)
endif()
5 changes: 3 additions & 2 deletions cmake/static.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ install(TARGETS libddwaf_static EXPORT libddwaf-config

# Post-processing on the static library
if(LINUX)
add_dependencies(libddwaf_static glibc_compat)
add_dependencies(libddwaf_static glibc_compat_time64 glibc_compat_math)
add_custom_command(TARGET libddwaf_static POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ar_comb
COMMAND ${CMAKE_COMMAND} -E chdir ar_comb ${CMAKE_AR} -x $<TARGET_FILE:libddwaf_static>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_OBJECTS:glibc_compat> ar_comb
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_OBJECTS:glibc_compat_time64> ar_comb
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_OBJECTS:glibc_compat_math> ar_comb
COMMAND ${CMAKE_AR} -qcs ar_comb/combined${CMAKE_STATIC_LIBRARY_SUFFIX} ar_comb/*.o*

COMMAND ${CMAKE_COMMAND} -E copy ar_comb/combined${CMAKE_STATIC_LIBRARY_SUFFIX} $<TARGET_FILE:libddwaf_static>
Expand Down
2 changes: 2 additions & 0 deletions smoketest/smoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>

static ddwaf_object *prepare_rule() {
ddwaf_object *ret = malloc(sizeof *ret);
Expand Down Expand Up @@ -244,5 +245,6 @@ int main() {
return 1;
}
puts("result is valid");

return 0;
}
90 changes: 90 additions & 0 deletions src/glibc-compat/math.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Unless explicitly stated otherwise all files in this repository are
// dual-licensed under the Apache-2.0 License or BSD-3-Clause License.
//
// This product includes software developed at Datadog
// (https://www.datadoghq.com/). Copyright 2023 Datadog, Inc.

#if defined(__linux__)

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#include <stdint.h>
#include <stdlib.h>

#if defined(__aarch64__)
// Extracted from https://git.musl-libc.org/cgit/musl/tree/src/math/aarch64/ceilf.c
static float ceilf_local(float x)
{
__asm__ ("frintp %s0, %s1" : "=w"(x) : "w"(x));
return x;
}
#else
/* fp_force_eval ensures that the input value is computed when that's
otherwise unused. To prevent the constant folding of the input
expression, an additional fp_barrier may be needed or a compilation
mode that does so (e.g. -frounding-math in gcc). Then it can be
used to evaluate an expression for its fenv side-effects only. */

static inline void fp_force_evalf(float x)
{
volatile float y;
y = x;
(void)y;
}

static float ceilf_local(float x)
{
// Extracted from https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
union {float f; uint32_t i;} u = {x};
int e = (int)(u.i >> 23 & 0xff) - 0x7f;
uint32_t m;

if (e >= 23) {
return x;
}
if (e >= 0) {
m = 0x007fffff >> e;
if ((u.i & m) == 0) {
return x;
}
fp_force_evalf(x + 0x1p120f);
if (u.i >> 31 == 0){
u.i += m;
}
u.i &= ~m;
} else {
fp_force_evalf(x + 0x1p120f);
if (u.i >> 31) {
u.f = -0.0;
} else if (u.i << 1) {
u.f = 1.0;
}
}
return u.f;
}
#endif

#define unlikely(x) __builtin_expect(!!(x), 0)

typedef float (*ceilf_t)(float);

__attribute__((weak))
float ceilf(float x)
{
static ceilf_t ceilf_global_;

// benign race
if (unlikely(ceilf_global_ == NULL)) {
void *ceilf_sym = dlsym(RTLD_DEFAULT, "ceilf");
if (ceilf_sym == NULL || ceilf_sym == &ceilf) {
ceilf_global_ = &ceilf_local;
} else {
ceilf_global_ = (ceilf_t)ceilf_sym;
}
}
return ceilf_global_(x);
}
#endif

16 changes: 8 additions & 8 deletions src/glibc-compat/time64.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
// This product includes software developed at Datadog
// (https://www.datadoghq.com/). Copyright 2023 Datadog, Inc.

#include <stdlib.h>

#if defined(__linux__) && !defined(__GLIBC__) && (defined(__arm__) || defined(__i386__))

#include <stdlib.h>
#include <features.h>

__attribute__((weak))
Expand All @@ -16,6 +15,7 @@ int __nanosleep64(void *req, void *rem) {
(void) rem;
abort();
}

__attribute__((weak))
int __nanosleep_time64(void *req, void *rem) {
return __nanosleep64(req, rem);
Expand All @@ -28,19 +28,19 @@ int __pthread_cond_timedwait64(void *cond, void *mutex, void *abstime) {
(void) abstime;
abort();
}

__attribute__((weak))
int __pthread_cond_timedwait_time64(void *cond, void *mutex, void *abstime) {
return __pthread_cond_timedwait64(cond, mutex, abstime);
}

__attribute__((weak))
void *dlsym(void * handle, const char *name) {
(void) handle;
(void) name;
abort();
}
void *dlsym(void * handle, const char *name);

// use weak attribute so that on static builds there is no indirection
__attribute__((weak))
void *__dlsym_time64(void *handle, const char *name) {
// no problem calling the plain dlsym as we don't use the function for which
// it would make a difference
return dlsym(handle, name);
}

Expand Down

0 comments on commit 2931993

Please sign in to comment.