summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Rules.mak3
-rw-r--r--include/unistd.h9
-rw-r--r--ldso/ldso/dl-elf.c2
-rw-r--r--ldso/ldso/dl-startup.c2
-rw-r--r--libc/sysdeps/linux/common/getentropy.c45
-rw-r--r--libc/sysdeps/linux/common/getrandom.c3
-rw-r--r--libc/sysdeps/linux/common/sys/random.h18
7 files changed, 77 insertions, 5 deletions
diff --git a/Rules.mak b/Rules.mak
index 309ebcbff..1aa1be93a 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -671,6 +671,9 @@ endif
ifeq ($(TARGET_ARCH),bfin)
CFLAGS += -Wno-implicit-function-declaration
endif
+ifeq ($(TARGET_ARCH),frv)
+CFLAGS += -Wno-implicit-function-declaration
+endif
ifneq ($(strip $(UCLIBC_EXTRA_LDFLAGS)),"")
LDFLAGS += $(call qstrip,$(UCLIBC_EXTRA_LDFLAGS))
endif
diff --git a/include/unistd.h b/include/unistd.h
index d50e1e4d3..e45266f14 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -1250,6 +1250,15 @@ extern void swab (const void *__restrict __from, void *__restrict __to,
extern char *ctermid (char *__s) __THROW;
#endif
+/* OpenBSD-compatible access to random bytes.
+ May be a cancellation point here, unlike in glibc/musl. */
+#ifdef _DEFAULT_SOURCE
+# ifndef __getentropy_defined
+extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur;
+# define __getentropy_defined
+# endif
+#endif
+
__END_DECLS
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 4f50d62b7..6656acb0f 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -1028,7 +1028,7 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag)
return goof;
}
-#if !defined(__FDPIC__) && !defined(__DSBT__)
+#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__)
/* Process DT_RELR relative relocations */
DL_RELOCATE_RELR(tpnt);
#endif
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
index e0d8c8fff..ec6b72a39 100644
--- a/ldso/ldso/dl-startup.c
+++ b/ldso/ldso/dl-startup.c
@@ -267,7 +267,7 @@ DL_START(unsigned long args)
that once we are done, we have considerably more flexibility. */
SEND_EARLY_STDERR_DEBUG("About to do library loader relocations\n");
-#if !defined(__FDPIC__) && !defined(__DSBT__)
+#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__)
/* Process DT_RELR relative relocations */
DL_RELOCATE_RELR(tpnt);
#endif
diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c
new file mode 100644
index 000000000..55bd48a12
--- /dev/null
+++ b/libc/sysdeps/linux/common/getentropy.c
@@ -0,0 +1,45 @@
+/*
+ * getentropy() by wrapping getrandom(), for µClibc-ng
+ *
+ * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2
+ *
+ * Note: may be a thread cancellation point, unlike the
+ * implementations in glibc and musl libc. Should this
+ * ever become a concern, it will need patching.
+ */
+
+#define _DEFAULT_SOURCE
+#include <errno.h>
+#include <unistd.h>
+#include <sys/random.h>
+
+#ifdef __NR_getrandom
+int
+getentropy(void *__buf, size_t __len)
+{
+ ssize_t n;
+
+ if (__len > 256U) {
+ errno = EIO;
+ return (-1);
+ }
+
+ again:
+ if ((n = getrandom(__buf, __len, 0)) == -1)
+ switch (errno) {
+ case EAGAIN: /* should not happen but better safe than sorry */
+ case EINTR:
+ goto again;
+ default:
+ errno = EIO;
+ /* FALLTHROUGH */
+ case EFAULT:
+ case ENOSYS:
+ return (-1);
+ }
+ if ((size_t)n != __len)
+ /* also shouldn’t happen (safety net) */
+ goto again;
+ return (0);
+}
+#endif
diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c
index bb9841463..1db1663b9 100644
--- a/libc/sysdeps/linux/common/getrandom.c
+++ b/libc/sysdeps/linux/common/getrandom.c
@@ -8,6 +8,7 @@
#include <sys/syscall.h>
#include <sys/random.h>
+
#ifdef __NR_getrandom
-_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
+_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
#endif
diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h
index 3d24e439b..c3d9cf575 100644
--- a/libc/sysdeps/linux/common/sys/random.h
+++ b/libc/sysdeps/linux/common/sys/random.h
@@ -4,11 +4,19 @@
#ifndef _SYS_RANDOM_H
#define _SYS_RANDOM_H 1
+
#include <features.h>
#include <stddef.h>
__BEGIN_DECLS
+#include <bits/types.h>
+
+#ifndef __ssize_t_defined
+typedef __ssize_t ssize_t;
+# define __ssize_t_defined
+#endif
+
#if defined __UCLIBC_LINUX_SPECIFIC__
# if 0 /*def __ASSUME_GETRANDOM_SYSCALL */
# include <linux/random.h>
@@ -26,9 +34,15 @@ __BEGIN_DECLS
# define GRND_RANDOM 0x0002
# define GRND_INSECURE 0x0004
# endif
-/* FIXME: aren't there a couple of __restrict and const missing ? */
-extern int getrandom(void *__buf, size_t count, unsigned int flags)
+extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags)
__nonnull ((1)) __wur;
+
+/* OpenBSD-compatible access to random bytes.
+ May be a cancellation point here, unlike in glibc/musl. */
+# ifndef __getentropy_defined
+extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur;
+# define __getentropy_defined
+# endif
#endif
__END_DECLS