summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-06-02 22:00:18 +0300
committerJari Vetoniemi <mailroxas@gmail.com>2018-06-02 22:03:58 +0300
commit9edd4a9979f520abc6a3f5c0029966b5cc0f280e (patch)
treec94fe900e1e7b3987fe4794163e62a06a18b5af4
parent6e5e3de6214bb792b126d481598e3e9313ea3bbb (diff)
libc: Wrap low level glibc io calls for stdio
This is much less work and actually works better.
-rw-r--r--Makefile3
-rw-r--r--src/libc-stdio.c42
-rw-r--r--src/libc-stdio.h102
-rw-r--r--src/libc.c9
4 files changed, 52 insertions, 104 deletions
diff --git a/Makefile b/Makefile
index d5dc142..c7d0515 100644
--- a/Makefile
+++ b/Makefile
@@ -34,9 +34,10 @@ runtime/libdl.so: private override CPPFLAGS += -D_GNU_SOURCE -DLINKER_DEBUG=1
runtime/libdl.so: private override CFLAGS += -Wno-pedantic -Wno-variadic-macros -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
runtime/libdl.so: wrapper.a src/linker/dlfcn.c src/linker/linker.c src/linker/linker_environ.c src/linker/rt.c src/linker/strlcpy.c
runtime/libc.so: private override CPPFLAGS += -D_GNU_SOURCE
+runtime/libc.so: private override LDFLAGS += -Wl,-wrap,_IO_file_xsputn
runtime/libc.so: private override CFLAGS += -Wno-deprecated-declarations
runtime/libc.so: private override LDLIBS += `pkg-config --libs libbsd libunwind`
-runtime/libc.so: verbose src/libc.c
+runtime/libc.so: verbose src/libc.c src/libc-stdio.c
runtime/libpthread.so: private override CPPFLAGS += -D_GNU_SOURCE
runtime/libpthread.so: private override LDLIBS += -lpthread
runtime/libpthread.so: src/libpthread.c
diff --git a/src/libc-stdio.c b/src/libc-stdio.c
new file mode 100644
index 0000000..713497b
--- /dev/null
+++ b/src/libc-stdio.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+struct bionic___sFILE {
+#if defined(__LP64__)
+ char __private[152];
+#else
+ char __private[84];
+#endif
+} __attribute__((aligned(sizeof(void*))));
+
+// Bionic standard stream support pre-M Android
+// Post-M it's saner and they point to stdin/stdout/stderr symbols instead
+const struct bionic___sFILE bionic___sF[3] = {
+ {{ 's', 't', 'd', 'i', 'n' }},
+ {{ 's', 't', 'd', 'o', 'u', 't' }},
+ {{ 's', 't', 'd', 'e', 'r', 'r' }}
+};
+
+static inline FILE*
+bionic_file_to_glibc_file(FILE *f)
+{
+ if (f == (void*)&bionic___sF[0])
+ return stdin;
+ else if (f == (void*)&bionic___sF[1])
+ return stdout;
+ else if (f == (void*)&bionic___sF[2])
+ return stderr;
+ return f;
+}
+
+// Wrapping internal glibc VTABLE functions to handle bionic's pre-M crap
+// We define __real_IO_file_xsputn in libc.c so linker will link our library,
+// it's not used however for anything.
+
+extern size_t
+__real_IO_file_xsputn(FILE *f, const void *buf, size_t n);
+
+size_t
+__wrap_IO_file_xsputn(FILE *f, const void *buf, size_t n)
+{
+ return __real_IO_file_xsputn(bionic_file_to_glibc_file(f), buf, n);
+}
diff --git a/src/libc-stdio.h b/src/libc-stdio.h
deleted file mode 100644
index 9dacd21..0000000
--- a/src/libc-stdio.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#pragma once
-
-#include <wchar.h>
-
-struct bionic___sFILE {
-#if defined(__LP64__)
- char __private[152];
-#else
- char __private[84];
-#endif
-} __attribute__((aligned(sizeof(void*))));
-
-// Bionic standard stream support pre-M Android
-// Post-M it's saner and they point to stdin/stdout/stderr symbols instead
-const struct bionic___sFILE bionic___sF[3] = {
- {{ 's', 't', 'd', 'i', 'n' }},
- {{ 's', 't', 'd', 'o', 'u', 't' }},
- {{ 's', 't', 'd', 'e', 'r', 'r' }}
-};
-
-static inline FILE*
-bionic_file_to_glibc_file(FILE *f)
-{
- if (f == (void*)&bionic___sF[0])
- return stdin;
- else if (f == (void*)&bionic___sF[1])
- return stdout;
- else if (f == (void*)&bionic___sF[2])
- return stderr;
- return f;
-}
-
-FILE*
-bionic_freopen(const char *filename, const char *modes, FILE *stream)
-{
- return freopen(filename, modes, bionic_file_to_glibc_file(stream));
-}
-
-int
-bionic_fclose(FILE *stream)
-{
- return fclose(bionic_file_to_glibc_file(stream));
-}
-
-int
-bionic_fputc(int c, FILE *stream)
-{
- return fputc(c, bionic_file_to_glibc_file(stream));
-}
-
-int
-bionic_putc(int c, FILE *stream)
-{
- return putc(c, bionic_file_to_glibc_file(stream));
-}
-
-
-int
-bionic_fputs(const char *c, FILE *stream)
-{
- return fputs(c, bionic_file_to_glibc_file(stream));
-}
-
-wint_t
-bionic_fputwc(wchar_t wc, FILE *stream)
-{
- return fputwc(wc, bionic_file_to_glibc_file(stream));
-}
-
-wint_t
-bionic_putwc(wchar_t wc, FILE *stream)
-{
- return putwc(wc, bionic_file_to_glibc_file(stream));
-}
-
-size_t
-bionic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- char buf[256], fname[256] = {0};
- stream = bionic_file_to_glibc_file(stream);
- snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream));
- readlink(buf, fname, sizeof(fname));
- verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream);
- return fread(ptr, size, nmemb, stream);
-}
-
-size_t
-bionic_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- char buf[256], fname[256] = {0};
- stream = bionic_file_to_glibc_file(stream);
- snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream));
- readlink(buf, fname, sizeof(fname));
- verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream);
- return fwrite(ptr, size, nmemb, stream);
-}
-
-int
-bionic_fflush(FILE *stream)
-{
- return fflush(bionic_file_to_glibc_file(stream));
-}
diff --git a/src/libc.c b/src/libc.c
index a61acd0..7d24275 100644
--- a/src/libc.c
+++ b/src/libc.c
@@ -72,7 +72,14 @@ tkill(int tid, int sig)
// Stuff needed for runtime compatibility, but not neccessary for linking
// Also stuff that exists in glibc, but needs to be wrapped for runtime compatibility
-#include "libc-stdio.h"
+// Some defines from app-stdio.c as per GNU linker's manual for --wrap:
+// You may wish to provide a __real_malloc function as well, so that links without the
+// --wrap option will succeed. If you do this, you should not put the definition of
+// __real_malloc in the same file as __wrap_malloc; if you do, the assembler may resolve
+// the call before the linker has a chance to wrap it to malloc.
+
+size_t __real_IO_file_xsputn(FILE *f, const void *buf, size_t n) {}
+
#include "libc-ctype.h"
const unsigned int bionic___page_size = PAGE_SIZE;