summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libc-stdio.h72
-rw-r--r--src/libc-verbose.h20
-rw-r--r--src/libc.c13
3 files changed, 79 insertions, 26 deletions
diff --git a/src/libc-stdio.h b/src/libc-stdio.h
new file mode 100644
index 0000000..7f09c74
--- /dev/null
+++ b/src/libc-stdio.h
@@ -0,0 +1,72 @@
+#pragma once
+
+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)
+{
+ // Can't compare just memory addresses because GNU libstdc++ copies the FILE struct...
+ // Maybe there could be a cleaner solution, this may in practice break if standard streams
+ // are opened with different flags in C++.
+ if (memcmp(f, "stdin", sizeof("stdin")))
+ return stdin;
+ else if (memcmp(f, "stdout", sizeof("stdout")))
+ return stdout;
+ else if (memcmp(f, "stderr", sizeof("stderr")))
+ 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));
+}
+
+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-verbose.h b/src/libc-verbose.h
index 190f0b1..2d46f17 100644
--- a/src/libc-verbose.h
+++ b/src/libc-verbose.h
@@ -144,26 +144,6 @@ bionic_unlink(const char *path)
return unlink(path);
}
-size_t
-bionic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- char buf[256], fname[256] = {0};
- 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};
- 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);
-}
-
char*
bionic_getenv(const char *name)
{
diff --git a/src/libc.c b/src/libc.c
index 66b0d8d..447220e 100644
--- a/src/libc.c
+++ b/src/libc.c
@@ -14,10 +14,6 @@
#include <netdb.h> // h_errno
#include "wrapper/verbose.h"
-#ifdef VERBOSE_FUNCTIONS
-# include "libc-verbose.h"
-#endif
-
struct bionic_dirent {
uint64_t d_ino;
int64_t d_off;
@@ -74,9 +70,10 @@ 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"
+
const char *bionic__ctype_, *bionic__tolower_tab_, *bionic__toupper_tab_;
-char bionic___sF[0x54] = {0};
-unsigned int bionic___page_size = PAGE_SIZE;
+const unsigned int bionic___page_size = PAGE_SIZE;
__attribute_const__
int*
@@ -378,3 +375,7 @@ bionic___futex_wake(volatile void* ftx, int count)
return syscall(SYS_futex, ftx, FUTEX_WAKE, count, NULL, 0);
}
#endif
+
+#ifdef VERBOSE_FUNCTIONS
+# include "libc-verbose.h"
+#endif