Add __riscv_flush_icache() to <sys/cachectl.h>.

The obsolete mips header rides again!

The most interesting part of this change is that I've removed the hack
that meant that all system call wrappers starting with `__` defaulted to
being hidden symbols. That's no longer useful given our linker scripts,
and it actively got in the way here because the public libc symbol
actually starts with `__` in glibc, and it would be weird and annoying
for developers if we chose a different name.

Test: strace
Change-Id: I230479787895e8e34f566ade36346a8241eea998
diff --git a/docs/status.md b/docs/status.md
index 1838b85..fc68b80 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -62,6 +62,7 @@
     functions for avoiding $TZ if you need to use multiple timezones in
     multi-threaded C).
   * `mbsrtowcs_l` and `wcsrtombs_l` aliases for `mbsrtowcs` and `wcsrtombs`.
+  * New system call wrapper: `__riscv_flush_icache` (`<sys/cachectl.h>`).
 
 New libc functions in U (API level 34):
   * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 08017f1..5f49c8c 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -356,7 +356,7 @@
 int     cacheflush:__ARM_NR_cacheflush(long start, long end, long flags)  arm
 
 # riscv64-specific
-int _flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
+int __riscv_flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
 
 # x86-specific
 int     __set_thread_area:set_thread_area(void*) x86
diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h
index 5ec295d..fd775ee 100644
--- a/libc/include/sys/cachectl.h
+++ b/libc/include/sys/cachectl.h
@@ -28,6 +28,27 @@
 
 #pragma once
 
+/*
+ * @file sys/cachectl.h
+ * @brief Architecture-specific cache control.
+ */
+
 #include <sys/cdefs.h>
 
-/* This header file is obsolete. */
+__BEGIN_DECLS
+
+/**
+ * Flag for __riscv_flush_icache() to indicate that only the current
+ * thread's instruction cache needs to be flushed (rather than the
+ * default of all threads).
+ */
+#define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL
+
+/**
+ * __riscv_flush_icache(2) flushes the instruction cache for the given range of addresses.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
+int __riscv_flush_icache(void* __start, void* __end, unsigned long __flags);
+
+__END_DECLS
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c69e609..41d18a6 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1589,6 +1589,7 @@
     localtime_rz;
     mbsrtowcs_l;
     mktime_z;
+    __riscv_flush_icache; # riscv64
     timespec_getres;
     tzalloc;
     tzfree;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 4f33777..8c457c8 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -227,11 +227,6 @@
     aliases = syscall["aliases"]
     for alias in aliases:
         stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"])
-
-    # Use hidden visibility on LP64 for any functions beginning with underscores.
-    if pointer_length == 64 and syscall["func"].startswith("__"):
-        stub += '.hidden ' + syscall["func"] + '\n'
-
     return stub
 
 
diff --git a/tests/Android.bp b/tests/Android.bp
index 36a3a37..8dc8eaf 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -470,6 +470,7 @@
         "struct_layout_test.cpp",
         "sstream_test.cpp",
         "sys_auxv_test.cpp",
+        "sys_cachectl_test.cpp",
         "sys_epoll_test.cpp",
         "sys_mman_test.cpp",
         "sys_msg_test.cpp",
diff --git a/tests/sys_cachectl_test.cpp b/tests/sys_cachectl_test.cpp
new file mode 100644
index 0000000..d9ece4f
--- /dev/null
+++ b/tests/sys_cachectl_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#if __has_include(<sys/cachectl.h>)
+#include <sys/cachectl.h>
+#endif
+
+TEST(sys_cachectl, __riscv_flush_icache) {
+#if defined(__riscv) && __has_include(<sys/cachectl.h>)
+  // As of Linux 6.4, the address range is ignored (so nullptr is fine),
+  // and the flags you actually want are 0 ("all threads"),
+  // but we test the unusual flag just to make sure it works.
+  ASSERT_EQ(0, __riscv_flush_icache(nullptr, nullptr, SYS_RISCV_FLUSH_ICACHE_LOCAL));
+#else
+  GTEST_SKIP() << "__riscv_flush_icache requires riscv64";
+#endif
+}