Skip to content

Conversation

@FuPeiJiang
Copy link

@FuPeiJiang FuPeiJiang commented Nov 1, 2025

meson's cc.has_function(f) only does a link check (faster)
on Android's bionic libc, reallocarray links, but the headers don't define reallocarray

older malloc.h (on termux):

/**
 * [reallocarray(3)](https://man7.org/linux/man-pages/man3/reallocarray.3.html)
 * resizes allocated memory on the heap.
 *
 * Equivalent to `realloc(__ptr, __item_count * __item_size)` but fails if the
 * multiplication overflows.
 *
 * Returns a pointer (which may be different from `__ptr`) to the resized
 * memory on success and returns a null pointer and sets `errno` on failure
 * (but see the notes for malloc()).
 */
#if __ANDROID_API__ >= 29
__nodiscard void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) __INTRODUCED_IN(29);
#elif defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
#include <errno.h>
static __inline __nodiscard void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) {
  size_t __new_size;
  if (__builtin_mul_overflow(__item_count, __item_size, &__new_size)) {
    errno = ENOMEM;
    return NULL;
  }
  return realloc(__ptr, __new_size);
}
#endif

if the header does not define it, (__ANDROID_API__ too low), then use compat.c fallback ?

cc.has_header_symbol(header, f, args: ['-D_GNU_SOURCE'])

symbol check is not a function check, but I don't know how to do a function check
-D_GNU_SOURCE is needed because this is the command used by meson:

... -D_FILE_OFFSET_BITS=64 -O0 -Werror=implicit-function-declaration -std=c11

without -std=c11, it'd work,

#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#include <alloca.h>
...
void *reallocarray (void *, size_t, size_t);
void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);
#endif

somewhere above:

conf.set('_GNU_SOURCE', true)

defines _GNU_SOURCE, but I found no way of passing conf to cc.has_header_symbol to not have to do

args: ['-D_GNU_SOURCE']
extras:

cc.has_function()

#define reallocarray meson_disable_define_of_reallocarray

#include <limits.h>
#undef reallocarray

#ifdef __cplusplus
extern "C"
#endif
char reallocarray (void);

#if defined __stub_reallocarray || defined __stub___reallocarray
fail fail fail this function is not going to work
#endif

int main(void) {
    return reallocarray ();
}

cc.has_header_symbol()

#include <stdlib.h>
int main(void) {
    /* If it's not defined as a macro, try to use as a symbol */
    #ifndef reallocarray
        reallocarray;
    #endif
    return 0;
}

@rom1v
Copy link
Collaborator

rom1v commented Nov 2, 2025

Thank you for the PR.

on Android's bionic libc, reallocarray links, but the headers don't define reallocarray

Just for information, does this fix the issue:

diff --git app/src/compat.h app/src/compat.h
index 296d1a9ff..59a2771a2 100644
--- app/src/compat.h
+++ app/src/compat.h
@@ -103,7 +103,7 @@ long nrand48(unsigned short xsubi[3]);
 long jrand48(unsigned short xsubi[3]);
 #endif
 
-#ifndef HAVE_REALLOCARRAY
+#if !defined(HAVE_REALLOCARRAY) || (defined(__ANDROID_API__) && __ANDROID_API__ < 29)
 void *reallocarray(void *ptr, size_t nmemb, size_t size);
 #endif
 

?

EDIT: fixed the condition

@FuPeiJiang
Copy link
Author

Just for information, does this fix the issue:

diff --git app/src/compat.h app/src/compat.h
index 296d1a9ff..59a2771a2 100644
--- app/src/compat.h
+++ app/src/compat.h
@@ -103,7 +103,7 @@ long nrand48(unsigned short xsubi[3]);
 long jrand48(unsigned short xsubi[3]);
 #endif
 
-#ifndef HAVE_REALLOCARRAY
+#if !defined(HAVE_REALLOCARRAY) || (defined(__ANDROID_API__) && __ANDROID_API__ < 29)
 void *reallocarray(void *ptr, size_t nmemb, size_t size);
 #endif
 

EDIT: fixed the condition ?

This declares reallocarray when __ANDROID_API__ < 29 (and links to /system/lib64/libc.so)
which may not be desired, if truly targetting __ANDROID_API__ < 29 (older /system/lib64/libc.so doesn't contain reallocarray)

if you want to inline the condition, then:
when __ANDROID_API__ < 29: it should use fallback reallocarray defined in compat.c (declare and define instead of just declare)

diff --git a/app/src/compat.c b/app/src/compat.c
index 785f843..289f54f 100644
--- a/app/src/compat.c
+++ b/app/src/compat.c
@@ -3,7 +3,7 @@
 #include "config.h"
 
 #include <assert.h>
-#ifndef HAVE_REALLOCARRAY
+#if !defined(HAVE_REALLOCARRAY) || (defined(__ANDROID_API__) && __ANDROID_API__ < 29)
 # include <errno.h>
 #endif
 #include <stdlib.h>
@@ -98,7 +98,7 @@ long jrand48(unsigned short xsubi[3]) {
 #endif
 #endif
 
-#ifndef HAVE_REALLOCARRAY
+#if !defined(HAVE_REALLOCARRAY) || (defined(__ANDROID_API__) && __ANDROID_API__ < 29)
 void *reallocarray(void *ptr, size_t nmemb, size_t size) {
     size_t bytes;
     if (__builtin_mul_overflow(nmemb, size, &bytes)) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants