author | Alberto Bertogli
<albertito@blitiri.com.ar> 2024-06-09 08:37:06 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2024-06-09 16:05:55 UTC |
parent | 1f659e4165072905776c1005238428a975cbffcd |
.gitignore | +1 | -0 |
preload/posix/Makefile | +10 | -2 |
preload/posix/build-check-redefine-64.c | +30 | -0 |
preload/posix/build-env.h.in | +3 | -0 |
preload/posix/codegen.h | +1 | -0 |
preload/posix/generate | +9 | -1 |
preload/posix/modules/posix.custom.c | +3 | -1 |
diff --git a/.gitignore b/.gitignore index b80b6b7..9e445d9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ preload/posix/*.so preload/posix/build-flags preload/posix/build-libcsoname preload/posix/build-needlibdl +preload/posix/build-check-redefine-64 preload/posix/build-env.h preload/posix/function_list preload/posix/modules/*.o diff --git a/preload/posix/Makefile b/preload/posix/Makefile index 5c6162c..ecc5c55 100644 --- a/preload/posix/Makefile +++ b/preload/posix/Makefile @@ -92,12 +92,19 @@ build-libcsoname: @test "`cat $@`" != "" || \ (echo "Error finding soname, please report"; rm $@; exit 1) -build-env.h: build-env.h.in build-libcsoname +# Some platforms alias 64-bit functions at the asm level, in which case we +# need to skip generating the 64-bit variants. +# This helper detects that situation. +build-check-redefine-64: + @$(CC) -c build-check-redefine-64.c -o /dev/null 2>/dev/null \ + && echo 1 > $@ || echo 0 > $@ + +build-env.h: build-env.h.in build-libcsoname build-check-redefine-64 @echo " GEN $@" $(Q) sed "s+@@LIBC_SONAME@@+`cat build-libcsoname`+g" build-env.h.in \ + | sed "s+@@CAN_DEFINE_64BIT_FUNCTIONS@@+`cat build-check-redefine-64`+g" \ > build-env.h - fiu_posix_preload.so: build-flags build-env.h build-needlibdl \ $(OBJS) ../../libfiu/hash.c $(NICE_CC) $(ALL_CFLAGS) -shared -fPIC $(OBJS) ../../libfiu/hash.c \ @@ -124,6 +131,7 @@ uninstall: clean: rm -f $(OBJS) $(GEN_OBJS:.o=.c) $(GEN_FL) rm -f build-flags build-env.h build-libcsoname build-needlibdl + rm -f build-check-redefine-64 rm -f function_list fiu_posix_preload.so rm -f *.bb *.bbg *.da *.gcov *.gcda *.gcno gmon.out rm -f modules/*.bb modules/*.bbg modules/*.da diff --git a/preload/posix/build-check-redefine-64.c b/preload/posix/build-check-redefine-64.c new file mode 100644 index 0000000..b5b0e4f --- /dev/null +++ b/preload/posix/build-check-redefine-64.c @@ -0,0 +1,30 @@ +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/select.h> +#include <poll.h> +#include <fcntl.h> +#include <errno.h> + +// Some platforms the functions that have 64-bit (e.g. pread64, pwrite64) have +// an assembler alias declared for the base variant in the header; while other +// platforms don't do that and have the two functions declared separately. +// +// On the platforms that use assembler aliases, we can't redefine the 64-bit +// variants. +// +// See https://bugs.debian.org/1066938 for more details. +// +// To detect this, we define both functions here. If there is an assembler +// alias declared in the header, then compiling this will result in an error +// like "Error: symbol `pread64' is already defined". + +ssize_t pread(int fd, void *buf, size_t count, off_t offset) { + return 0; +} + +ssize_t pread64(int fd, void *buf, size_t count, off_t offset) { + return 0; +} diff --git a/preload/posix/build-env.h.in b/preload/posix/build-env.h.in index 63c06f6..8e6f5cf 100644 --- a/preload/posix/build-env.h.in +++ b/preload/posix/build-env.h.in @@ -9,4 +9,7 @@ /* libc's soname, used for dlopen()ing the C library */ #define LIBC_SONAME "@@LIBC_SONAME@@" +/* Whether 64-bit functions can be defined alongside the base ones */ +#define LIBFIU_CAN_DEFINE_64BIT_FUNCTIONS @@CAN_DEFINE_64BIT_FUNCTIONS@@ + #endif diff --git a/preload/posix/codegen.h b/preload/posix/codegen.h index 5ca27a8..2272f47 100644 --- a/preload/posix/codegen.h +++ b/preload/posix/codegen.h @@ -2,6 +2,7 @@ #ifndef _FIU_CODEGEN #define _FIU_CODEGEN +#include "build-env.h" #include <fiu.h> /* fiu_* */ #include <stdlib.h> /* NULL, random() */ diff --git a/preload/posix/generate b/preload/posix/generate index 5e1999a..c13dbe6 100755 --- a/preload/posix/generate +++ b/preload/posix/generate @@ -185,7 +185,15 @@ class Function: f.ret_type = f.ret_type.replace("off_t", "off64_t") # This is glibc-specific, so surround it with #ifdefs. - return [Verbatim("#ifdef __GLIBC__"), f, Verbatim("#endif")] + # Also only apply it if we can define the 64-bit functions on the same + # file (detected at build-time). + return [ + Verbatim("#ifdef __GLIBC__"), + Verbatim("#if LIBFIU_CAN_DEFINE_64BIT_FUNCTIONS"), + f, + Verbatim("#endif // LIBFIU_CAN_DEFINE_64BIT_FUNCTIONS"), + Verbatim("#endif // __GLIBC__"), + ] def get_all_variants(self): """Returns all variants of the given function provided via diff --git a/preload/posix/modules/posix.custom.c b/preload/posix/modules/posix.custom.c index 4f8b5fc..ceb99a5 100644 --- a/preload/posix/modules/posix.custom.c +++ b/preload/posix/modules/posix.custom.c @@ -103,6 +103,7 @@ mkwrap_bottom(open, (pathname, flags, mode)) /* The 64-bit variant for glibc. * The code is identical to open(), just using open64() where appropriate. */ #ifdef __GLIBC__ +#if LIBFIU_CAN_DEFINE_64BIT_FUNCTIONS mkwrap_init(int, open64, (const char *pathname, int flags, ...), (const char *, int, ...)) @@ -183,7 +184,8 @@ mkwrap_body_called(open, (pathname, flags, mode), -1) mkwrap_body_errno("posix/io/oc/open", -1) mkwrap_bottom(open64, (pathname, flags, mode)) -#endif +#endif // LIBFIU_CAN_DEFINE_64BIT_FUNCTIONS +#endif // __GLIBC__ /* * To simulate ferror() properly, we need to keep track of which FILE * have