[libc] Switch to use a macro which does not insert a section for every libc function.

Summary:
The new macro also inserts the C alias for the C++ implementations
without needing an objcopy based post processing step. The CMake
rules have been updated to reflect this. More CMake cleanup can be
taken up in future rounds and appropriate TODOs have been added for them.

Reviewers: mcgrathr, sivachandra

Subscribers:
GitOrigin-RevId: a0b65a7bcd6065688189b3d678c42ed6af9603db
diff --git a/cmake/modules/LLVMLibCObjectRules.cmake b/cmake/modules/LLVMLibCObjectRules.cmake
index 32900d8..93f772d 100644
--- a/cmake/modules/LLVMLibCObjectRules.cmake
+++ b/cmake/modules/LLVMLibCObjectRules.cmake
@@ -147,10 +147,26 @@
     message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
   endif()
 
-  set(objects_target_name "${fq_target_name}_objects")
+  set(common_compile_options -fpie ${LLVM_CXX_STD_default} -ffreestanding ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS})
+  set(internal_target_name ${fq_target_name}.__internal__)
+  set(include_dirs ${LIBC_BUILD_DIR}/include ${LIBC_SOURCE_DIR} ${LIBC_BUILD_DIR})
+  get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
+  set(full_deps_list ${fq_deps_list} libc.src.__support.common)
 
   add_library(
-    ${objects_target_name}
+    ${internal_target_name}
+    # TODO: We don't need an object library for internal consumption.
+    # A future change should switch this to a normal static library.
+    OBJECT
+    ${ADD_ENTRYPOINT_OBJ_SRCS}
+    ${ADD_ENTRYPOINT_OBJ_HDRS}
+  )
+  target_compile_options(${internal_target_name} BEFORE PRIVATE ${common_compile_options})
+  target_include_directories(${internal_target_name} PRIVATE ${include_dirs})
+  add_dependencies(${internal_target_name} ${full_deps_list})
+
+  add_library(
+    ${fq_target_name}
     # We want an object library as the objects will eventually get packaged into
     # an archive (like libc.a).
     OBJECT
@@ -158,68 +174,20 @@
     ${ADD_ENTRYPOINT_OBJ_HDRS}
   )
   target_compile_options(
-    ${objects_target_name}
-    BEFORE
-    PRIVATE
-      -fpie ${LLVM_CXX_STD_default} -ffreestanding
+      ${fq_target_name} BEFORE PRIVATE ${common_compile_options} -DLLVM_LIBC_PUBLIC_PACKAGING
   )
-  target_include_directories(
-    ${objects_target_name}
-    PRIVATE
-      ${LIBC_BUILD_DIR}/include
-      ${LIBC_SOURCE_DIR}
-      ${LIBC_BUILD_DIR}
-  )
-  get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
-  add_dependencies(
-    ${objects_target_name}
-    libc.src.__support.common
-    ${fq_deps_list}
-  )
+  target_include_directories(${fq_target_name} PRIVATE ${include_dirs})
+  add_dependencies(${fq_target_name} ${full_deps_list})
 
-  if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS)
-    target_compile_options(
-      ${objects_target_name}
-      PRIVATE ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}
-    )
-  endif()
-
-  set(object_file_raw "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_raw.o")
-  set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o")
-
-  set(input_objects $<TARGET_OBJECTS:${objects_target_name}>)
-  add_custom_command(
-    OUTPUT ${object_file_raw}
-    DEPENDS ${input_objects}
-    COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
-  )
-
-  set(alias_attributes "0,function,global")
-  if(ADD_ENTRYPOINT_OBJ_REDIRECTED)
-    set(alias_attributes "${alias_attributes},hidden")
-  endif()
-
-  add_custom_command(
-    OUTPUT ${object_file}
-    # We llvm-objcopy here as GNU-binutils objcopy does not support the 'hidden' flag.
-    DEPENDS ${object_file_raw} ${llvm-objcopy}
-    COMMAND $<TARGET_FILE:llvm-objcopy> --add-symbol
-            "${entrypoint_name}=.llvm.libc.entrypoint.${entrypoint_name}:${alias_attributes}"
-            ${object_file_raw} ${object_file}
-  )
-
-  add_custom_target(
-    ${fq_target_name}
-    ALL
-    DEPENDS ${object_file}
-  )
   set_target_properties(
     ${fq_target_name}
     PROPERTIES
       "ENTRYPOINT_NAME" ${entrypoint_name}
       "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
-      "OBJECT_FILE" "${object_file}"
-      "OBJECT_FILE_RAW" "${object_file_raw}"
+      "OBJECT_FILE" $<TARGET_OBJECTS:${fq_target_name}>
+      # TODO: We don't need to list internal object files if the internal
+      # target is a normal static library.
+      "OBJECT_FILE_RAW" $<TARGET_OBJECTS:${internal_target_name}>
       "DEPS" "${fq_deps_list}"
   )
 
@@ -273,7 +241,7 @@
       # crossplatform touch.
       COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp}
       COMMENT "Linting... ${target_name}"
-      DEPENDS clang-tidy ${objects_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
+      DEPENDS clang-tidy ${internal_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
diff --git a/src/__support/common.h.def b/src/__support/common.h.def
index a1bb78d..48c63de 100644
--- a/src/__support/common.h.def
+++ b/src/__support/common.h.def
@@ -15,8 +15,19 @@
 #define unlikely(x) __builtin_expect (x, 0)
 #define UNUSED __attribute__((unused))
 
-<!> Include the platform specific definitions at build time. For example, that
-<!> of entrypoint macro.
-%%include_file(${platform_defs})
+#ifndef LLVM_LIBC_FUNCTION_ATTR
+  #define LLVM_LIBC_FUNCTION_ATTR
+#endif
+
+#ifdef LLVM_LIBC_PUBLIC_PACKAGING
+#define LLVM_LIBC_FUNCTION(type, name, arglist) \
+  type name arglist; \
+  LLVM_LIBC_FUNCTION_ATTR decltype(__llvm_libc::name) __##name##_impl__ __asm__(#name); \
+  decltype(__llvm_libc::name) name [[gnu::alias(#name)]]; \
+  type __##name##_impl__ arglist                                        
+#else
+#define LLVM_LIBC_FUNCTION(type, name, arglist)\
+  type name arglist
+#endif
 
 #endif // LLVM_LIBC_SUPPORT_COMMON_H
diff --git a/src/assert/__assert_fail.cpp b/src/assert/__assert_fail.cpp
index 114a368..614e130 100644
--- a/src/assert/__assert_fail.cpp
+++ b/src/assert/__assert_fail.cpp
@@ -24,8 +24,9 @@
   __llvm_libc::syscall(SYS_write, 2, s, length);
 }
 
-void LLVM_LIBC_ENTRYPOINT(__assert_fail)(const char *assertion, const char *file,
-                                         unsigned line, const char *function) {
+LLVM_LIBC_FUNCTION(void, __assert_fail,
+                   (const char *assertion, const char *file, unsigned line,
+                    const char *function)) {
   writeToStderr(file);
   writeToStderr(": Assertion failed: '");
   writeToStderr(assertion);
diff --git a/src/ctype/isalnum.cpp b/src/ctype/isalnum.cpp
index 54c4f80..3e8da72 100644
--- a/src/ctype/isalnum.cpp
+++ b/src/ctype/isalnum.cpp
@@ -15,6 +15,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isalnum)(int c) { return internal::isalnum(c); }
+LLVM_LIBC_FUNCTION(int, isalnum, (int c)) { return internal::isalnum(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/isalpha.cpp b/src/ctype/isalpha.cpp
index 4b37254..cecf1b5 100644
--- a/src/ctype/isalpha.cpp
+++ b/src/ctype/isalpha.cpp
@@ -15,6 +15,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isalpha)(int c) { return internal::isalpha(c); }
+LLVM_LIBC_FUNCTION(int, isalpha, (int c)) { return internal::isalpha(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/isblank.cpp b/src/ctype/isblank.cpp
index fa28d84..b29d19a 100644
--- a/src/ctype/isblank.cpp
+++ b/src/ctype/isblank.cpp
@@ -14,7 +14,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isblank)(int c) {
+LLVM_LIBC_FUNCTION(int, isblank, (int c)) {
   const unsigned char ch = c;
   return ch == ' ' || ch == '\t';
 }
diff --git a/src/ctype/iscntrl.cpp b/src/ctype/iscntrl.cpp
index 06ee7cc..8962bca 100644
--- a/src/ctype/iscntrl.cpp
+++ b/src/ctype/iscntrl.cpp
@@ -14,7 +14,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(iscntrl)(int c) {
+LLVM_LIBC_FUNCTION(int, iscntrl, (int c)) {
   const unsigned char ch = c;
   return ch < 0x20 || ch == 0x7f;
 }
diff --git a/src/ctype/isdigit.cpp b/src/ctype/isdigit.cpp
index 94ec42a..8471e4b 100644
--- a/src/ctype/isdigit.cpp
+++ b/src/ctype/isdigit.cpp
@@ -14,6 +14,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isdigit)(int c) { return internal::isdigit(c); }
+LLVM_LIBC_FUNCTION(int, isdigit, (int c)) { return internal::isdigit(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/isgraph.cpp b/src/ctype/isgraph.cpp
index c7a488c..2bb6a57 100644
--- a/src/ctype/isgraph.cpp
+++ b/src/ctype/isgraph.cpp
@@ -15,6 +15,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isgraph)(int c) { return internal::isgraph(c); }
+LLVM_LIBC_FUNCTION(int, isgraph, (int c)) { return internal::isgraph(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/islower.cpp b/src/ctype/islower.cpp
index ae1291b..907a322 100644
--- a/src/ctype/islower.cpp
+++ b/src/ctype/islower.cpp
@@ -15,6 +15,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(islower)(int c) { return internal::islower(c); }
+LLVM_LIBC_FUNCTION(int, islower, (int c)) { return internal::islower(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/isprint.cpp b/src/ctype/isprint.cpp
index 6d0ebbb..a80500b 100644
--- a/src/ctype/isprint.cpp
+++ b/src/ctype/isprint.cpp
@@ -14,7 +14,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isprint)(int c) {
+LLVM_LIBC_FUNCTION(int, isprint, (int c)) {
   const unsigned ch = c;
   return (ch - ' ') < 95;
 }
diff --git a/src/ctype/ispunct.cpp b/src/ctype/ispunct.cpp
index a810c64..064b7b0 100644
--- a/src/ctype/ispunct.cpp
+++ b/src/ctype/ispunct.cpp
@@ -15,7 +15,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(ispunct)(int c) {
+LLVM_LIBC_FUNCTION(int, ispunct, (int c)) {
   return !internal::isalnum(c) && internal::isgraph(c);
 }
 
diff --git a/src/ctype/isspace.cpp b/src/ctype/isspace.cpp
index ed6e161..4a269ef 100644
--- a/src/ctype/isspace.cpp
+++ b/src/ctype/isspace.cpp
@@ -14,7 +14,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isspace)(int c) {
+LLVM_LIBC_FUNCTION(int, isspace, (int c)) {
   const unsigned ch = c;
   return ch == ' ' || (ch - '\t') < 5;
 }
diff --git a/src/ctype/isupper.cpp b/src/ctype/isupper.cpp
index 9b0e523..f1c56fc 100644
--- a/src/ctype/isupper.cpp
+++ b/src/ctype/isupper.cpp
@@ -15,6 +15,6 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isupper)(int c) { return internal::isupper(c); }
+LLVM_LIBC_FUNCTION(int, isupper, (int c)) { return internal::isupper(c); }
 
 } // namespace __llvm_libc
diff --git a/src/ctype/isxdigit.cpp b/src/ctype/isxdigit.cpp
index 497cf46..5ee1b10 100644
--- a/src/ctype/isxdigit.cpp
+++ b/src/ctype/isxdigit.cpp
@@ -15,7 +15,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isxdigit)(int c) {
+LLVM_LIBC_FUNCTION(int, isxdigit, (int c)) {
   const unsigned ch = c;
   return internal::isdigit(ch) || (ch | 32) - 'a' < 6;
 }
diff --git a/src/ctype/tolower.cpp b/src/ctype/tolower.cpp
index 6fd3006..c01f4f0 100644
--- a/src/ctype/tolower.cpp
+++ b/src/ctype/tolower.cpp
@@ -15,7 +15,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(tolower)(int c) {
+LLVM_LIBC_FUNCTION(int, tolower, (int c)) {
   if (internal::isupper(c))
     return c + 'a' - 'A';
   return c;
diff --git a/src/ctype/toupper.cpp b/src/ctype/toupper.cpp
index 8d591c2..254befc 100644
--- a/src/ctype/toupper.cpp
+++ b/src/ctype/toupper.cpp
@@ -15,7 +15,7 @@
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(toupper)(int c) {
+LLVM_LIBC_FUNCTION(int, toupper, (int c)) {
   if (internal::islower(c))
     return c + 'A' - 'a';
   return c;
diff --git a/src/errno/__errno_location.cpp b/src/errno/__errno_location.cpp
index 3e7c769..54c5acb 100644
--- a/src/errno/__errno_location.cpp
+++ b/src/errno/__errno_location.cpp
@@ -17,6 +17,6 @@
 // __errno_location is not really an entry point but we still want it to behave
 // like an entry point because the errno macro resolves to the C symbol
 // "__errno_location".
-int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
+LLVM_LIBC_FUNCTION(int *, __errno_location, ()) { return &__errno; }
 
 } // namespace __llvm_libc
diff --git a/src/fenv/feclearexcept.cpp b/src/fenv/feclearexcept.cpp
index c407ac4..be180f6 100644
--- a/src/fenv/feclearexcept.cpp
+++ b/src/fenv/feclearexcept.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(feclearexcept)(int e) {
+LLVM_LIBC_FUNCTION(int, feclearexcept, (int e)) {
   return fputil::clearExcept(e);
 }
 
diff --git a/src/fenv/fegetround.cpp b/src/fenv/fegetround.cpp
index 0eb9224..669b861 100644
--- a/src/fenv/fegetround.cpp
+++ b/src/fenv/fegetround.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(fegetround)() { return fputil::getRound(); }
+LLVM_LIBC_FUNCTION(int, fegetround, ()) { return fputil::getRound(); }
 
 } // namespace __llvm_libc
diff --git a/src/fenv/feraiseexcept.cpp b/src/fenv/feraiseexcept.cpp
index a9e93e6..cc3f11a 100644
--- a/src/fenv/feraiseexcept.cpp
+++ b/src/fenv/feraiseexcept.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(feraiseexcept)(int e) {
+LLVM_LIBC_FUNCTION(int, feraiseexcept, (int e)) {
   return fputil::raiseExcept(e);
 }
 
diff --git a/src/fenv/fesetround.cpp b/src/fenv/fesetround.cpp
index 3f6077d..50e726f 100644
--- a/src/fenv/fesetround.cpp
+++ b/src/fenv/fesetround.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(fesetround)(int m) { return fputil::setRound(m); }
+LLVM_LIBC_FUNCTION(int, fesetround, (int m)) { return fputil::setRound(m); }
 
 } // namespace __llvm_libc
diff --git a/src/fenv/fetestexcept.cpp b/src/fenv/fetestexcept.cpp
index 38ec17b..d4f5e1e 100644
--- a/src/fenv/fetestexcept.cpp
+++ b/src/fenv/fetestexcept.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(fetestexcept)(int e) { return fputil::testExcept(e); }
+LLVM_LIBC_FUNCTION(int, fetestexcept, (int e)) { return fputil::testExcept(e); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ceil.cpp b/src/math/ceil.cpp
index 06ef903..7d603e7 100644
--- a/src/math/ceil.cpp
+++ b/src/math/ceil.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(ceil)(double x) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return fputil::ceil(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ceilf.cpp b/src/math/ceilf.cpp
index d44e273..361f507 100644
--- a/src/math/ceilf.cpp
+++ b/src/math/ceilf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(ceilf)(float x) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return fputil::ceil(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ceill.cpp b/src/math/ceill.cpp
index 8ac806d..525e40b 100644
--- a/src/math/ceill.cpp
+++ b/src/math/ceill.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(ceill)(long double x) {
+LLVM_LIBC_FUNCTION(long double, ceill, (long double x)) {
   return fputil::ceil(x);
 }
 
diff --git a/src/math/copysign.cpp b/src/math/copysign.cpp
index 5eee71f..5d7af25 100644
--- a/src/math/copysign.cpp
+++ b/src/math/copysign.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(copysign)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, copysign, (double x, double y)) {
   return fputil::copysign(x, y);
 }
 
diff --git a/src/math/copysignf.cpp b/src/math/copysignf.cpp
index c730dd3..beec120 100644
--- a/src/math/copysignf.cpp
+++ b/src/math/copysignf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(copysignf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, copysignf, (float x, float y)) {
   return fputil::copysign(x, y);
 }
 
diff --git a/src/math/copysignl.cpp b/src/math/copysignl.cpp
index b165b8f..c00b7a7 100644
--- a/src/math/copysignl.cpp
+++ b/src/math/copysignl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(copysignl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, copysignl, (long double x, long double y)) {
   return fputil::copysign(x, y);
 }
 
diff --git a/src/math/cosf.cpp b/src/math/cosf.cpp
index 762e931..ad0dfed 100644
--- a/src/math/cosf.cpp
+++ b/src/math/cosf.cpp
@@ -20,7 +20,7 @@
 // error is 0.5303 * 2^-23. A single-step range reduction is used for
 // small values. Large inputs have their range reduced using fast integer
 // arithmetic.
-float LLVM_LIBC_ENTRYPOINT(cosf)(float y) {
+LLVM_LIBC_FUNCTION(float, cosf, (float y)) {
   double x = y;
   double s;
   int n;
diff --git a/src/math/exp2f.cpp b/src/math/exp2f.cpp
index 38db872..012cb82 100644
--- a/src/math/exp2f.cpp
+++ b/src/math/exp2f.cpp
@@ -20,7 +20,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(exp2f)(float x) {
+LLVM_LIBC_FUNCTION(float, exp2f, (float x)) {
   uint32_t abstop;
   uint64_t ki, t;
   // double_t for better performance on targets with FLT_EVAL_METHOD==2.
diff --git a/src/math/expf.cpp b/src/math/expf.cpp
index 61c8613..df10e4e 100644
--- a/src/math/expf.cpp
+++ b/src/math/expf.cpp
@@ -21,7 +21,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(expf)(float x) {
+LLVM_LIBC_FUNCTION(float, expf, (float x)) {
   uint32_t abstop;
   uint64_t ki, t;
   // double_t for better performance on targets with FLT_EVAL_METHOD == 2.
diff --git a/src/math/fabs.cpp b/src/math/fabs.cpp
index ff78f1b..7069e1d 100644
--- a/src/math/fabs.cpp
+++ b/src/math/fabs.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(fabs)(double x) { return fputil::abs(x); }
+LLVM_LIBC_FUNCTION(double, fabs, (double x)) { return fputil::abs(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/fabsf.cpp b/src/math/fabsf.cpp
index 9aa1419..6ed9ef7 100644
--- a/src/math/fabsf.cpp
+++ b/src/math/fabsf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(fabsf)(float x) { return fputil::abs(x); }
+LLVM_LIBC_FUNCTION(float, fabsf, (float x)) { return fputil::abs(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/fabsl.cpp b/src/math/fabsl.cpp
index 6e8f728..3a36459 100644
--- a/src/math/fabsl.cpp
+++ b/src/math/fabsl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(fabsl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, fabsl, (long double x)) {
   return fputil::abs(x);
 }
 
diff --git a/src/math/fdim.cpp b/src/math/fdim.cpp
index 23b475c..ebc998e 100644
--- a/src/math/fdim.cpp
+++ b/src/math/fdim.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(fdim)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fdim, (double x, double y)) {
   return fputil::fdim(x, y);
 }
 
diff --git a/src/math/fdimf.cpp b/src/math/fdimf.cpp
index 84f307b..d922bb9 100644
--- a/src/math/fdimf.cpp
+++ b/src/math/fdimf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(fdimf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fdimf, (float x, float y)) {
   return fputil::fdim(x, y);
 }
 
diff --git a/src/math/fdiml.cpp b/src/math/fdiml.cpp
index 60c0a74..5149484 100644
--- a/src/math/fdiml.cpp
+++ b/src/math/fdiml.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(fdiml)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fdiml, (long double x, long double y)) {
   return fputil::fdim(x, y);
 }
 
diff --git a/src/math/floor.cpp b/src/math/floor.cpp
index cc2fde5..a7a7d78 100644
--- a/src/math/floor.cpp
+++ b/src/math/floor.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(floor)(double x) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(double, floor, (double x)) { return fputil::floor(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/floorf.cpp b/src/math/floorf.cpp
index e220ab4..da464b6 100644
--- a/src/math/floorf.cpp
+++ b/src/math/floorf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(floorf)(float x) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(float, floorf, (float x)) { return fputil::floor(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/floorl.cpp b/src/math/floorl.cpp
index 1e7d7b1..38d30b8 100644
--- a/src/math/floorl.cpp
+++ b/src/math/floorl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(floorl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, floorl, (long double x)) {
   return fputil::floor(x);
 }
 
diff --git a/src/math/fmaf.cpp b/src/math/fmaf.cpp
index 1860d88..6b989c7 100644
--- a/src/math/fmaf.cpp
+++ b/src/math/fmaf.cpp
@@ -13,7 +13,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(fmaf)(float x, float y, float z) {
+LLVM_LIBC_FUNCTION(float, fmaf, (float x, float y, float z)){
   // Product is exact.
   double prod = static_cast<double>(x) * static_cast<double>(y);
   double z_d = static_cast<double>(z);
diff --git a/src/math/fmax.cpp b/src/math/fmax.cpp
index ba5d933..8090126 100644
--- a/src/math/fmax.cpp
+++ b/src/math/fmax.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(fmax)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
   return fputil::fmax(x, y);
 }
 
diff --git a/src/math/fmaxf.cpp b/src/math/fmaxf.cpp
index 5562904..c4932c4 100644
--- a/src/math/fmaxf.cpp
+++ b/src/math/fmaxf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(fmaxf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
   return fputil::fmax(x, y);
 }
 
diff --git a/src/math/fmaxl.cpp b/src/math/fmaxl.cpp
index c944187..acfa9f2 100644
--- a/src/math/fmaxl.cpp
+++ b/src/math/fmaxl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(fmaxl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fmaxl, (long double x, long double y)) {
   return fputil::fmax(x, y);
 }
 
diff --git a/src/math/fmin.cpp b/src/math/fmin.cpp
index ef5efad..f4a0056 100644
--- a/src/math/fmin.cpp
+++ b/src/math/fmin.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(fmin)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
   return fputil::fmin(x, y);
 }
 
diff --git a/src/math/fminf.cpp b/src/math/fminf.cpp
index 97ad399..a5c8579 100644
--- a/src/math/fminf.cpp
+++ b/src/math/fminf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(fminf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
   return fputil::fmin(x, y);
 }
 
diff --git a/src/math/fminl.cpp b/src/math/fminl.cpp
index e66f0d7..9324c14 100644
--- a/src/math/fminl.cpp
+++ b/src/math/fminl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(fminl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fminl, (long double x, long double y)) {
   return fputil::fmin(x, y);
 }
 
diff --git a/src/math/frexp.cpp b/src/math/frexp.cpp
index 8449929..81d5f9e 100644
--- a/src/math/frexp.cpp
+++ b/src/math/frexp.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(frexp)(double x, int *exp) {
+LLVM_LIBC_FUNCTION(double, frexp, (double x, int *exp)) {
   return fputil::frexp(x, *exp);
 }
 
diff --git a/src/math/frexpf.cpp b/src/math/frexpf.cpp
index 94dac9f..5d9a5b5 100644
--- a/src/math/frexpf.cpp
+++ b/src/math/frexpf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(frexpf)(float x, int *exp) {
+LLVM_LIBC_FUNCTION(float, frexpf, (float x, int *exp)) {
   return fputil::frexp(x, *exp);
 }
 
diff --git a/src/math/frexpl.cpp b/src/math/frexpl.cpp
index 939ac71..ccdc184 100644
--- a/src/math/frexpl.cpp
+++ b/src/math/frexpl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(frexpl)(long double x, int *exp) {
+LLVM_LIBC_FUNCTION(long double, frexpl, (long double x, int *exp)) {
   return fputil::frexp(x, *exp);
 }
 
diff --git a/src/math/hypot.cpp b/src/math/hypot.cpp
index 9d59365..77a83d8 100644
--- a/src/math/hypot.cpp
+++ b/src/math/hypot.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(hypot)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, hypot, (double x, double y)) {
   return __llvm_libc::fputil::hypot(x, y);
 }
 
diff --git a/src/math/hypotf.cpp b/src/math/hypotf.cpp
index ebe7e97..eefc47e 100644
--- a/src/math/hypotf.cpp
+++ b/src/math/hypotf.cpp
@@ -10,7 +10,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(hypotf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
   return __llvm_libc::fputil::hypot(x, y);
 }
 
diff --git a/src/math/ilogb.cpp b/src/math/ilogb.cpp
index 001925b..d2d3772 100644
--- a/src/math/ilogb.cpp
+++ b/src/math/ilogb.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(ilogb)(double x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::ilogb(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ilogbf.cpp b/src/math/ilogbf.cpp
index d62b22b..529530d 100644
--- a/src/math/ilogbf.cpp
+++ b/src/math/ilogbf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(ilogbf)(float x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::ilogb(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ilogbl.cpp b/src/math/ilogbl.cpp
index 0ad791f..92d9936 100644
--- a/src/math/ilogbl.cpp
+++ b/src/math/ilogbl.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(ilogbl)(long double x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) { return fputil::ilogb(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/ldexp.cpp b/src/math/ldexp.cpp
index 1eefd10..9d8ffb5 100644
--- a/src/math/ldexp.cpp
+++ b/src/math/ldexp.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(ldexp)(double x, int exp) {
+LLVM_LIBC_FUNCTION(double, ldexp, (double x, int exp)) {
   return fputil::ldexp(x, exp);
 }
 
diff --git a/src/math/ldexpf.cpp b/src/math/ldexpf.cpp
index 5c44254..94030c0 100644
--- a/src/math/ldexpf.cpp
+++ b/src/math/ldexpf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(ldexpf)(float x, int exp) {
+LLVM_LIBC_FUNCTION(float, ldexpf, (float x, int exp)) {
   return fputil::ldexp(x, exp);
 }
 
diff --git a/src/math/ldexpl.cpp b/src/math/ldexpl.cpp
index 10ec660..08aba33 100644
--- a/src/math/ldexpl.cpp
+++ b/src/math/ldexpl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(ldexpl)(long double x, int exp) {
+LLVM_LIBC_FUNCTION(long double, ldexpl, (long double x, int exp)) {
   return fputil::ldexp(x, exp);
 }
 
diff --git a/src/math/llrint.cpp b/src/math/llrint.cpp
index 182eaa5..2f41526 100644
--- a/src/math/llrint.cpp
+++ b/src/math/llrint.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llrint)(double x) {
+LLVM_LIBC_FUNCTION(long long, llrint, (double x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<double,
                                                               long long>(x);
 }
diff --git a/src/math/llrintf.cpp b/src/math/llrintf.cpp
index 33f6cb6..35dca58 100644
--- a/src/math/llrintf.cpp
+++ b/src/math/llrintf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llrintf)(float x) {
+LLVM_LIBC_FUNCTION(long long, llrintf, (float x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<float, long long>(
       x);
 }
diff --git a/src/math/llrintl.cpp b/src/math/llrintl.cpp
index 725b3d5..9628863 100644
--- a/src/math/llrintl.cpp
+++ b/src/math/llrintl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llrintl)(long double x) {
+LLVM_LIBC_FUNCTION(long long, llrintl, (long double x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<long double,
                                                               long long>(x);
 }
diff --git a/src/math/llround.cpp b/src/math/llround.cpp
index 25f7e91..79042cf 100644
--- a/src/math/llround.cpp
+++ b/src/math/llround.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llround)(double x) {
+LLVM_LIBC_FUNCTION(long long, llround, (double x)) {
   return fputil::roundToSignedInteger<double, long long>(x);
 }
 
diff --git a/src/math/llroundf.cpp b/src/math/llroundf.cpp
index e0b3471..5601676 100644
--- a/src/math/llroundf.cpp
+++ b/src/math/llroundf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llroundf)(float x) {
+LLVM_LIBC_FUNCTION(long long, llroundf, (float x)) {
   return fputil::roundToSignedInteger<float, long long>(x);
 }
 
diff --git a/src/math/llroundl.cpp b/src/math/llroundl.cpp
index 4df0b81..88bd699 100644
--- a/src/math/llroundl.cpp
+++ b/src/math/llroundl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llroundl)(long double x) {
+LLVM_LIBC_FUNCTION(long long, llroundl, (long double x)) {
   return fputil::roundToSignedInteger<long double, long long>(x);
 }
 
diff --git a/src/math/logb.cpp b/src/math/logb.cpp
index 7475785..d1f5a5e 100644
--- a/src/math/logb.cpp
+++ b/src/math/logb.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(logb)(double x) { return fputil::logb(x); }
+LLVM_LIBC_FUNCTION(double, logb, (double x)) { return fputil::logb(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/logbf.cpp b/src/math/logbf.cpp
index bfe8e85..03a4c6d 100644
--- a/src/math/logbf.cpp
+++ b/src/math/logbf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(logbf)(float x) { return fputil::logb(x); }
+LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return fputil::logb(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/logbl.cpp b/src/math/logbl.cpp
index 57255e7..386a504 100644
--- a/src/math/logbl.cpp
+++ b/src/math/logbl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(logbl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, logbl, (long double x)) {
   return fputil::logb(x);
 }
 
diff --git a/src/math/lrint.cpp b/src/math/lrint.cpp
index f7ac026..2cfdf34 100644
--- a/src/math/lrint.cpp
+++ b/src/math/lrint.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lrint)(double x) {
+LLVM_LIBC_FUNCTION(long, lrint, (double x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<double, long>(x);
 }
 
diff --git a/src/math/lrintf.cpp b/src/math/lrintf.cpp
index ab59119..a5eb5f0 100644
--- a/src/math/lrintf.cpp
+++ b/src/math/lrintf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lrintf)(float x) {
+LLVM_LIBC_FUNCTION(long, lrintf, (float x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<float, long>(x);
 }
 
diff --git a/src/math/lrintl.cpp b/src/math/lrintl.cpp
index ae0e699..0157ed1 100644
--- a/src/math/lrintl.cpp
+++ b/src/math/lrintl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lrintl)(long double x) {
+LLVM_LIBC_FUNCTION(long, lrintl, (long double x)) {
   return fputil::roundToSignedIntegerUsingCurrentRoundingMode<long double,
                                                               long>(x);
 }
diff --git a/src/math/lround.cpp b/src/math/lround.cpp
index 3fb9028..669b5c4 100644
--- a/src/math/lround.cpp
+++ b/src/math/lround.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lround)(double x) {
+LLVM_LIBC_FUNCTION(long, lround, (double x)) {
   return fputil::roundToSignedInteger<double, long>(x);
 }
 
diff --git a/src/math/lroundf.cpp b/src/math/lroundf.cpp
index 0388bdf..ae69637 100644
--- a/src/math/lroundf.cpp
+++ b/src/math/lroundf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lroundf)(float x) {
+LLVM_LIBC_FUNCTION(long, lroundf, (float x)) {
   return fputil::roundToSignedInteger<float, long>(x);
 }
 
diff --git a/src/math/lroundl.cpp b/src/math/lroundl.cpp
index 27310ae..36ea2ae 100644
--- a/src/math/lroundl.cpp
+++ b/src/math/lroundl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(lroundl)(long double x) {
+LLVM_LIBC_FUNCTION(long, lroundl, (long double x)) {
   return fputil::roundToSignedInteger<long double, long>(x);
 }
 
diff --git a/src/math/modf.cpp b/src/math/modf.cpp
index 5146600..1942f8f 100644
--- a/src/math/modf.cpp
+++ b/src/math/modf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(modf)(double x, double *iptr) {
+LLVM_LIBC_FUNCTION(double, modf, (double x, double *iptr)) {
   return fputil::modf(x, *iptr);
 }
 
diff --git a/src/math/modff.cpp b/src/math/modff.cpp
index 4847fe2..603f2c7 100644
--- a/src/math/modff.cpp
+++ b/src/math/modff.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(modff)(float x, float *iptr) {
+LLVM_LIBC_FUNCTION(float, modff, (float x, float *iptr)) {
   return fputil::modf(x, *iptr);
 }
 
diff --git a/src/math/modfl.cpp b/src/math/modfl.cpp
index 83a0746..8102bc5 100644
--- a/src/math/modfl.cpp
+++ b/src/math/modfl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(modfl)(long double x, long double *iptr) {
+LLVM_LIBC_FUNCTION(long double, modfl, (long double x, long double *iptr)) {
   return fputil::modf(x, *iptr);
 }
 
diff --git a/src/math/nearbyint.cpp b/src/math/nearbyint.cpp
index 0938952..26ff0f4 100644
--- a/src/math/nearbyint.cpp
+++ b/src/math/nearbyint.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(nearbyint)(double x) {
+LLVM_LIBC_FUNCTION(double, nearbyint, (double x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/nearbyintf.cpp b/src/math/nearbyintf.cpp
index cc19da6..d073dc1 100644
--- a/src/math/nearbyintf.cpp
+++ b/src/math/nearbyintf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(nearbyintf)(float x) {
+LLVM_LIBC_FUNCTION(float, nearbyintf, (float x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/nearbyintl.cpp b/src/math/nearbyintl.cpp
index 5618832..d10e1db 100644
--- a/src/math/nearbyintl.cpp
+++ b/src/math/nearbyintl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(nearbyintl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, nearbyintl, (long double x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/nextafter.cpp b/src/math/nextafter.cpp
index 8ba1553..80eabbd 100644
--- a/src/math/nextafter.cpp
+++ b/src/math/nextafter.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(nextafter)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, nextafter, (double x, double y)) {
   return fputil::nextafter(x, y);
 }
 
diff --git a/src/math/nextafterf.cpp b/src/math/nextafterf.cpp
index dab591e..acde903 100644
--- a/src/math/nextafterf.cpp
+++ b/src/math/nextafterf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(nextafterf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, nextafterf, (float x, float y)) {
   return fputil::nextafter(x, y);
 }
 
diff --git a/src/math/nextafterl.cpp b/src/math/nextafterl.cpp
index 4a9b64c..c4eee4c 100644
--- a/src/math/nextafterl.cpp
+++ b/src/math/nextafterl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(nextafterl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, nextafterl, (long double x, long double y)) {
   return fputil::nextafter(x, y);
 }
 
diff --git a/src/math/remainder.cpp b/src/math/remainder.cpp
index 880e6a6..d8e254b 100644
--- a/src/math/remainder.cpp
+++ b/src/math/remainder.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(remainder)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, remainder, (double x, double y)) {
   int quotient;
   return fputil::remquo(x, y, quotient);
 }
diff --git a/src/math/remainderf.cpp b/src/math/remainderf.cpp
index bab3201..3c4e564 100644
--- a/src/math/remainderf.cpp
+++ b/src/math/remainderf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(remainderf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, remainderf, (float x, float y)) {
   int quotient;
   return fputil::remquo(x, y, quotient);
 }
diff --git a/src/math/remainderl.cpp b/src/math/remainderl.cpp
index bd9bc49..842595e 100644
--- a/src/math/remainderl.cpp
+++ b/src/math/remainderl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(remainderl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, remainderl, (long double x, long double y)) {
   int quotient;
   return fputil::remquo(x, y, quotient);
 }
diff --git a/src/math/remquo.cpp b/src/math/remquo.cpp
index b61d7d4..89803ba 100644
--- a/src/math/remquo.cpp
+++ b/src/math/remquo.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(remquo)(double x, double y, int *exp) {
+LLVM_LIBC_FUNCTION(double, remquo, (double x, double y, int *exp)) {
   return fputil::remquo(x, y, *exp);
 }
 
diff --git a/src/math/remquof.cpp b/src/math/remquof.cpp
index 246bee0..0330c43 100644
--- a/src/math/remquof.cpp
+++ b/src/math/remquof.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(remquof)(float x, float y, int *exp) {
+LLVM_LIBC_FUNCTION(float, remquof, (float x, float y, int *exp)) {
   return fputil::remquo(x, y, *exp);
 }
 
diff --git a/src/math/remquol.cpp b/src/math/remquol.cpp
index 8e02876..9a30acd 100644
--- a/src/math/remquol.cpp
+++ b/src/math/remquol.cpp
@@ -11,8 +11,8 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(remquol)(long double x, long double y,
-                                          int *exp) {
+LLVM_LIBC_FUNCTION(long double, remquol,
+                   (long double x, long double y, int *exp)) {
   return fputil::remquo(x, y, *exp);
 }
 
diff --git a/src/math/rint.cpp b/src/math/rint.cpp
index 5081d0a..056d05a 100644
--- a/src/math/rint.cpp
+++ b/src/math/rint.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(rint)(double x) {
+LLVM_LIBC_FUNCTION(double, rint, (double x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/rintf.cpp b/src/math/rintf.cpp
index 7535ee6..77a28c8 100644
--- a/src/math/rintf.cpp
+++ b/src/math/rintf.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(rintf)(float x) {
+LLVM_LIBC_FUNCTION(float, rintf, (float x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/rintl.cpp b/src/math/rintl.cpp
index cc617a2..fb4819a 100644
--- a/src/math/rintl.cpp
+++ b/src/math/rintl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(rintl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, rintl, (long double x)) {
   return fputil::roundUsingCurrentRoundingMode(x);
 }
 
diff --git a/src/math/round.cpp b/src/math/round.cpp
index 44a1119..ed36a12 100644
--- a/src/math/round.cpp
+++ b/src/math/round.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(round)(double x) { return fputil::round(x); }
+LLVM_LIBC_FUNCTION(double, round, (double x)) { return fputil::round(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/roundf.cpp b/src/math/roundf.cpp
index 8cbb315..a2be709 100644
--- a/src/math/roundf.cpp
+++ b/src/math/roundf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(roundf)(float x) { return fputil::round(x); }
+LLVM_LIBC_FUNCTION(float, roundf, (float x)) { return fputil::round(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/roundl.cpp b/src/math/roundl.cpp
index afb1a89..7e3ba5e 100644
--- a/src/math/roundl.cpp
+++ b/src/math/roundl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(roundl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, roundl, (long double x)) {
   return fputil::round(x);
 }
 
diff --git a/src/math/sincosf.cpp b/src/math/sincosf.cpp
index a52af17..4903af3 100644
--- a/src/math/sincosf.cpp
+++ b/src/math/sincosf.cpp
@@ -20,7 +20,7 @@
 // error is 0.5303 * 2^-23. A single-step range reduction is used for
 // small values. Large inputs have their range reduced using fast integer
 // arithmetic.
-void LLVM_LIBC_ENTRYPOINT(sincosf)(float y, float *sinp, float *cosp) {
+LLVM_LIBC_FUNCTION(void, sincosf, (float y, float *sinp, float *cosp)) {
   double x = y;
   double s;
   int n;
diff --git a/src/math/sinf.cpp b/src/math/sinf.cpp
index 49496f3..40bdc44 100644
--- a/src/math/sinf.cpp
+++ b/src/math/sinf.cpp
@@ -20,7 +20,7 @@
 // error is 0.5303 * 2^-23. A single-step range reduction is used for
 // small values. Large inputs have their range reduced using fast integer
 // arithmetic.
-float LLVM_LIBC_ENTRYPOINT(sinf)(float y) {
+LLVM_LIBC_FUNCTION(float, sinf, (float y)) {
   double x = y;
   double s;
   int n;
diff --git a/src/math/sqrt.cpp b/src/math/sqrt.cpp
index 32d38e6..7c6a115 100644
--- a/src/math/sqrt.cpp
+++ b/src/math/sqrt.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(sqrt)(double x) { return fputil::sqrt(x); }
+LLVM_LIBC_FUNCTION(double, sqrt, (double x)) { return fputil::sqrt(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/sqrtf.cpp b/src/math/sqrtf.cpp
index 391fa6a..5383e93 100644
--- a/src/math/sqrtf.cpp
+++ b/src/math/sqrtf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(sqrtf)(float x) { return fputil::sqrt(x); }
+LLVM_LIBC_FUNCTION(float, sqrtf, (float x)) { return fputil::sqrt(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/sqrtl.cpp b/src/math/sqrtl.cpp
index 1645034..a526e5e 100644
--- a/src/math/sqrtl.cpp
+++ b/src/math/sqrtl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(sqrtl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, sqrtl, (long double x)) {
   return fputil::sqrt(x);
 }
 
diff --git a/src/math/trunc.cpp b/src/math/trunc.cpp
index 0749e11..68b5b85 100644
--- a/src/math/trunc.cpp
+++ b/src/math/trunc.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-double LLVM_LIBC_ENTRYPOINT(trunc)(double x) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(double, trunc, (double x)) { return fputil::trunc(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/truncf.cpp b/src/math/truncf.cpp
index 0372571..8b9949f 100644
--- a/src/math/truncf.cpp
+++ b/src/math/truncf.cpp
@@ -11,6 +11,6 @@
 
 namespace __llvm_libc {
 
-float LLVM_LIBC_ENTRYPOINT(truncf)(float x) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(float, truncf, (float x)) { return fputil::trunc(x); }
 
 } // namespace __llvm_libc
diff --git a/src/math/truncl.cpp b/src/math/truncl.cpp
index 0eb557a..f78a193 100644
--- a/src/math/truncl.cpp
+++ b/src/math/truncl.cpp
@@ -11,7 +11,7 @@
 
 namespace __llvm_libc {
 
-long double LLVM_LIBC_ENTRYPOINT(truncl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, truncl, (long double x)) {
   return fputil::trunc(x);
 }
 
diff --git a/src/signal/linux/raise.cpp b/src/signal/linux/raise.cpp
index 15f748c..eccc4f7 100644
--- a/src/signal/linux/raise.cpp
+++ b/src/signal/linux/raise.cpp
@@ -13,7 +13,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(raise)(int sig) {
+LLVM_LIBC_FUNCTION(int, raise, (int sig)) {
   __llvm_libc::Sigset sigset;
   __llvm_libc::block_all_signals(sigset);
   long pid = __llvm_libc::syscall(SYS_getpid);
diff --git a/src/signal/linux/sigaction.cpp b/src/signal/linux/sigaction.cpp
index 47e9072..602fc71 100644
--- a/src/signal/linux/sigaction.cpp
+++ b/src/signal/linux/sigaction.cpp
@@ -28,9 +28,9 @@
   dest.sa_restorer = source.sa_restorer;
 }
 
-int LLVM_LIBC_ENTRYPOINT(sigaction)(
-    int signal, const struct __sigaction *__restrict libc_new,
-    struct __sigaction *__restrict libc_old) {
+LLVM_LIBC_FUNCTION(int, sigaction,
+                   (int signal, const struct __sigaction *__restrict libc_new,
+                    struct __sigaction *__restrict libc_old)) {
   struct sigaction kernel_new;
   if (libc_new) {
     copySigaction(kernel_new, *libc_new);
diff --git a/src/signal/linux/sigaddset.cpp b/src/signal/linux/sigaddset.cpp
index 2afb83c..bc51ef6 100644
--- a/src/signal/linux/sigaddset.cpp
+++ b/src/signal/linux/sigaddset.cpp
@@ -15,7 +15,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(sigaddset)(sigset_t *set, int signum) {
+LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {
   if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
     llvmlibc_errno = EINVAL;
     return -1;
diff --git a/src/signal/linux/sigdelset.cpp b/src/signal/linux/sigdelset.cpp
index 7eb3a60..f870f71 100644
--- a/src/signal/linux/sigdelset.cpp
+++ b/src/signal/linux/sigdelset.cpp
@@ -15,7 +15,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(sigdelset)(sigset_t *set, int signum) {
+LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {
   if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
     llvmlibc_errno = EINVAL;
     return -1;
diff --git a/src/signal/linux/sigemptyset.cpp b/src/signal/linux/sigemptyset.cpp
index d581832..bce5fea 100644
--- a/src/signal/linux/sigemptyset.cpp
+++ b/src/signal/linux/sigemptyset.cpp
@@ -15,7 +15,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(sigemptyset)(sigset_t *set) {
+LLVM_LIBC_FUNCTION(int, sigemptyset, (sigset_t * set)) {
   if (!set) {
     llvmlibc_errno = EINVAL;
     return -1;
diff --git a/src/signal/linux/sigfillset.cpp b/src/signal/linux/sigfillset.cpp
index bb4281a..1b908f1 100644
--- a/src/signal/linux/sigfillset.cpp
+++ b/src/signal/linux/sigfillset.cpp
@@ -15,7 +15,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(sigfillset)(sigset_t *set) {
+LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {
   if (!set) {
     llvmlibc_errno = EINVAL;
     return -1;
diff --git a/src/signal/linux/signal.cpp b/src/signal/linux/signal.cpp
index 5de51ea..fc04877 100644
--- a/src/signal/linux/signal.cpp
+++ b/src/signal/linux/signal.cpp
@@ -14,7 +14,7 @@
 
 namespace __llvm_libc {
 
-sighandler_t LLVM_LIBC_ENTRYPOINT(signal)(int signum, sighandler_t handler) {
+LLVM_LIBC_FUNCTION(sighandler_t, signal, (int signum, sighandler_t handler)) {
   struct __sigaction action, old;
   action.sa_handler = handler;
   action.sa_flags = SA_RESTART;
diff --git a/src/signal/linux/sigprocmask.cpp b/src/signal/linux/sigprocmask.cpp
index e4c7059..e4b101c 100644
--- a/src/signal/linux/sigprocmask.cpp
+++ b/src/signal/linux/sigprocmask.cpp
@@ -14,8 +14,9 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(sigprocmask)(int how, const sigset_t *__restrict set,
-                                      sigset_t *__restrict oldset) {
+LLVM_LIBC_FUNCTION(int, sigprocmask,
+                   (int how, const sigset_t *__restrict set,
+                    sigset_t *__restrict oldset)) {
   int ret = __llvm_libc::syscall(SYS_rt_sigprocmask, how, set, oldset,
                                  sizeof(sigset_t));
   if (!ret)
diff --git a/src/stdlib/abort.cpp b/src/stdlib/abort.cpp
index e21e74f..1da8161 100644
--- a/src/stdlib/abort.cpp
+++ b/src/stdlib/abort.cpp
@@ -14,7 +14,7 @@
 
 namespace __llvm_libc {
 
-void LLVM_LIBC_ENTRYPOINT(abort)() {
+LLVM_LIBC_FUNCTION(void, abort, ()) {
   // TODO: When sigprocmask and sigaction land:
   // Unblock SIGABRT, raise it, if it was ignored or the handler returned,
   // change its action to SIG_DFL, raise it again.
diff --git a/src/stdlib/abs.cpp b/src/stdlib/abs.cpp
index 74c47cd..eba2b7d 100644
--- a/src/stdlib/abs.cpp
+++ b/src/stdlib/abs.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(abs)(int n) {
+LLVM_LIBC_FUNCTION(int, abs, (int n)) {
   // integer_abs from abs_utils.h.
   return integer_abs(n);
 }
diff --git a/src/stdlib/labs.cpp b/src/stdlib/labs.cpp
index 427cb9d..d2aa816 100644
--- a/src/stdlib/labs.cpp
+++ b/src/stdlib/labs.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-long LLVM_LIBC_ENTRYPOINT(labs)(long n) {
+LLVM_LIBC_FUNCTION(long, labs, (long n)) {
   // integer_abs from abs_utils.h.
   return integer_abs(n);
 }
diff --git a/src/stdlib/linux/_Exit.cpp b/src/stdlib/linux/_Exit.cpp
index 1c5f60a..7fdd60f 100644
--- a/src/stdlib/linux/_Exit.cpp
+++ b/src/stdlib/linux/_Exit.cpp
@@ -14,7 +14,7 @@
 
 namespace __llvm_libc {
 
-void LLVM_LIBC_ENTRYPOINT(_Exit)(int status) {
+LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
   for (;;) {
     __llvm_libc::syscall(SYS_exit_group, status);
     __llvm_libc::syscall(SYS_exit, status);
diff --git a/src/stdlib/llabs.cpp b/src/stdlib/llabs.cpp
index 8878ce4..7a83fcb 100644
--- a/src/stdlib/llabs.cpp
+++ b/src/stdlib/llabs.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-long long LLVM_LIBC_ENTRYPOINT(llabs)(long long n) {
+LLVM_LIBC_FUNCTION(long long, llabs, (long long n)) {
   // integer_abs from abs_utils.h.
   return integer_abs(n);
 }
diff --git a/src/string/bzero.cpp b/src/string/bzero.cpp
index 60c059a..3c76ef6 100644
--- a/src/string/bzero.cpp
+++ b/src/string/bzero.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-void LLVM_LIBC_ENTRYPOINT(bzero)(void *ptr, size_t count) {
+LLVM_LIBC_FUNCTION(void, bzero, (void *ptr, size_t count)) {
   GeneralPurposeMemset(reinterpret_cast<char *>(ptr), 0, count);
 }
 
diff --git a/src/string/memchr.cpp b/src/string/memchr.cpp
index c95e272..02b4016 100644
--- a/src/string/memchr.cpp
+++ b/src/string/memchr.cpp
@@ -15,7 +15,7 @@
 namespace __llvm_libc {
 
 // TODO: Look at performance benefits of comparing words.
-void *LLVM_LIBC_ENTRYPOINT(memchr)(const void *src, int c, size_t n) {
+LLVM_LIBC_FUNCTION(void *, memchr, (const void *src, int c, size_t n)) {
   return internal::find_first_character(
       reinterpret_cast<const unsigned char *>(src), c, n);
 }
diff --git a/src/string/memcmp.cpp b/src/string/memcmp.cpp
index 1bd1c60..5569ab2 100644
--- a/src/string/memcmp.cpp
+++ b/src/string/memcmp.cpp
@@ -13,8 +13,8 @@
 namespace __llvm_libc {
 
 // TODO: It is a simple implementation, an optimized version is preparing.
-int LLVM_LIBC_ENTRYPOINT(memcmp)(const void *lhs, const void *rhs,
-                                 size_t count) {
+LLVM_LIBC_FUNCTION(int, memcmp,
+                   (const void *lhs, const void *rhs, size_t count)) {
   const unsigned char *_lhs = reinterpret_cast<const unsigned char *>(lhs);
   const unsigned char *_rhs = reinterpret_cast<const unsigned char *>(rhs);
   for (size_t i = 0; i < count; ++i)
diff --git a/src/string/memcpy.cpp b/src/string/memcpy.cpp
index 00d66ea..a145b90 100644
--- a/src/string/memcpy.cpp
+++ b/src/string/memcpy.cpp
@@ -55,8 +55,9 @@
   return CopyAlignedBlocks<32>(dst, src, count);
 }
 
-void *LLVM_LIBC_ENTRYPOINT(memcpy)(void *__restrict dst,
-                                   const void *__restrict src, size_t size) {
+LLVM_LIBC_FUNCTION(void *, memcpy,
+                   (void *__restrict dst, const void *__restrict src,
+                    size_t size)) {
   memcpy_impl(reinterpret_cast<char *>(dst),
               reinterpret_cast<const char *>(src), size);
   return dst;
diff --git a/src/string/memrchr.cpp b/src/string/memrchr.cpp
index 81b0345..b010b8a 100644
--- a/src/string/memrchr.cpp
+++ b/src/string/memrchr.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-void *LLVM_LIBC_ENTRYPOINT(memrchr)(const void *src, int c, size_t n) {
+LLVM_LIBC_FUNCTION(void *, memrchr, (const void *src, int c, size_t n)) {
   const unsigned char *str = reinterpret_cast<const unsigned char *>(src);
   const unsigned char ch = c;
   for (; n != 0; --n) {
diff --git a/src/string/memset.cpp b/src/string/memset.cpp
index cf1be5e..945aeda 100644
--- a/src/string/memset.cpp
+++ b/src/string/memset.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-void *LLVM_LIBC_ENTRYPOINT(memset)(void *dst, int value, size_t count) {
+LLVM_LIBC_FUNCTION(void *, memset, (void *dst, int value, size_t count)) {
   GeneralPurposeMemset(reinterpret_cast<char *>(dst),
                        static_cast<unsigned char>(value), count);
   return dst;
diff --git a/src/string/strcat.cpp b/src/string/strcat.cpp
index f5e8616..176a42a 100644
--- a/src/string/strcat.cpp
+++ b/src/string/strcat.cpp
@@ -14,8 +14,8 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strcat)(char *__restrict dest,
-                                   const char *__restrict src) {
+LLVM_LIBC_FUNCTION(char *, strcat,
+                   (char *__restrict dest, const char *__restrict src)) {
   __llvm_libc::strcpy(dest + internal::string_length(dest), src);
   return dest;
 }
diff --git a/src/string/strchr.cpp b/src/string/strchr.cpp
index eac0e51..6288b64 100644
--- a/src/string/strchr.cpp
+++ b/src/string/strchr.cpp
@@ -13,7 +13,7 @@
 namespace __llvm_libc {
 
 // TODO: Look at performance benefits of comparing words.
-char *LLVM_LIBC_ENTRYPOINT(strchr)(const char *src, int c) {
+LLVM_LIBC_FUNCTION(char *, strchr, (const char *src, int c)) {
   unsigned char *str =
       const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(src));
   const unsigned char ch = c;
diff --git a/src/string/strcmp.cpp b/src/string/strcmp.cpp
index 4ef7a77..8468b3c 100644
--- a/src/string/strcmp.cpp
+++ b/src/string/strcmp.cpp
@@ -13,7 +13,7 @@
 namespace __llvm_libc {
 
 // TODO: Look at benefits for comparing words at a time.
-int LLVM_LIBC_ENTRYPOINT(strcmp)(const char *left, const char *right) {
+LLVM_LIBC_FUNCTION(int, strcmp, (const char *left, const char *right)) {
   for (; *left && *left == *right; ++left, ++right)
     ;
   return *reinterpret_cast<const unsigned char *>(left) -
diff --git a/src/string/strcpy.cpp b/src/string/strcpy.cpp
index 69a40c9..d081d6c 100644
--- a/src/string/strcpy.cpp
+++ b/src/string/strcpy.cpp
@@ -14,8 +14,8 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *__restrict dest,
-                                   const char *__restrict src) {
+LLVM_LIBC_FUNCTION(char *, strcpy,
+                   (char *__restrict dest, const char *__restrict src)) {
   return reinterpret_cast<char *>(
       __llvm_libc::memcpy(dest, src, internal::string_length(src) + 1));
 }
diff --git a/src/string/strcspn.cpp b/src/string/strcspn.cpp
index a19b3fb..d4929c5 100644
--- a/src/string/strcspn.cpp
+++ b/src/string/strcspn.cpp
@@ -13,7 +13,7 @@
 
 namespace __llvm_libc {
 
-size_t LLVM_LIBC_ENTRYPOINT(strcspn)(const char *src, const char *segment) {
+LLVM_LIBC_FUNCTION(size_t, strcspn, (const char *src, const char *segment)) {
   return internal::complementary_span(src, segment);
 }
 
diff --git a/src/string/strlen.cpp b/src/string/strlen.cpp
index 81e1f17..c7b192b 100644
--- a/src/string/strlen.cpp
+++ b/src/string/strlen.cpp
@@ -15,7 +15,7 @@
 
 // TODO: investigate the performance of this function.
 // There might be potential for compiler optimization.
-size_t LLVM_LIBC_ENTRYPOINT(strlen)(const char *src) {
+LLVM_LIBC_FUNCTION(size_t, strlen, (const char *src)) {
   return internal::string_length(src);
 }
 
diff --git a/src/string/strncpy.cpp b/src/string/strncpy.cpp
index 45255e3..2749502 100644
--- a/src/string/strncpy.cpp
+++ b/src/string/strncpy.cpp
@@ -13,8 +13,9 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strncpy)(char *__restrict dest,
-                                    const char *__restrict src, size_t n) {
+LLVM_LIBC_FUNCTION(char *, strncpy,
+                   (char *__restrict dest, const char *__restrict src,
+                    size_t n)) {
   size_t i = 0;
   // Copy up until \0 is found.
   for (; i < n && src[i] != '\0'; ++i)
diff --git a/src/string/strnlen.cpp b/src/string/strnlen.cpp
index ea8fa9c..dc208b0 100644
--- a/src/string/strnlen.cpp
+++ b/src/string/strnlen.cpp
@@ -14,7 +14,7 @@
 
 namespace __llvm_libc {
 
-size_t LLVM_LIBC_ENTRYPOINT(strnlen)(const char *src, size_t n) {
+LLVM_LIBC_FUNCTION(size_t, strnlen, (const char *src, size_t n)) {
   const void *temp = internal::find_first_character(
       reinterpret_cast<const unsigned char *>(src), '\0', n);
   return temp ? reinterpret_cast<const char *>(temp) - src : n;
diff --git a/src/string/strpbrk.cpp b/src/string/strpbrk.cpp
index bbd2cec..fc2cadc 100644
--- a/src/string/strpbrk.cpp
+++ b/src/string/strpbrk.cpp
@@ -13,7 +13,7 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strpbrk)(const char *src, const char *breakset) {
+LLVM_LIBC_FUNCTION(char *, strpbrk, (const char *src, const char *breakset)) {
   src += internal::complementary_span(src, breakset);
   return *src ? const_cast<char *>(src) : nullptr;
 }
diff --git a/src/string/strrchr.cpp b/src/string/strrchr.cpp
index 374a802..33a638b 100644
--- a/src/string/strrchr.cpp
+++ b/src/string/strrchr.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strrchr)(const char *src, int c) {
+LLVM_LIBC_FUNCTION(char *, strrchr, (const char *src, int c)) {
   const char ch = c;
   char *last_occurrence = nullptr;
   do {
diff --git a/src/string/strspn.cpp b/src/string/strspn.cpp
index c85fc8b..893b2c9 100644
--- a/src/string/strspn.cpp
+++ b/src/string/strspn.cpp
@@ -14,7 +14,7 @@
 
 namespace __llvm_libc {
 
-size_t LLVM_LIBC_ENTRYPOINT(strspn)(const char *src, const char *segment) {
+LLVM_LIBC_FUNCTION(size_t, strspn, (const char *src, const char *segment)) {
   const char *initial = src;
   cpp::Bitset<256> bitset;
 
diff --git a/src/string/strstr.cpp b/src/string/strstr.cpp
index a598f66..3ec32fd 100644
--- a/src/string/strstr.cpp
+++ b/src/string/strstr.cpp
@@ -15,7 +15,7 @@
 
 // TODO: This is a simple brute force implementation. This can be
 // improved upon using well known string matching algorithms.
-char *LLVM_LIBC_ENTRYPOINT(strstr)(const char *haystack, const char *needle) {
+LLVM_LIBC_FUNCTION(char *, strstr, (const char *haystack, const char *needle)) {
   for (size_t i = 0; haystack[i]; ++i) {
     size_t j;
     for (j = 0; haystack[i + j] && haystack[i + j] == needle[j]; ++j)
diff --git a/src/string/strtok.cpp b/src/string/strtok.cpp
index 3a8ab99..281197e 100644
--- a/src/string/strtok.cpp
+++ b/src/string/strtok.cpp
@@ -15,8 +15,9 @@
 
 static char *strtok_str = nullptr;
 
-char *LLVM_LIBC_ENTRYPOINT(strtok)(char *__restrict src,
-                                   const char *__restrict delimiter_string) {
+LLVM_LIBC_FUNCTION(char *, strtok,
+                   (char *__restrict src,
+                    const char *__restrict delimiter_string)) {
   return internal::string_token(src, delimiter_string, &strtok_str);
 }
 
diff --git a/src/string/strtok_r.cpp b/src/string/strtok_r.cpp
index 4f9ab34..d1cc675 100644
--- a/src/string/strtok_r.cpp
+++ b/src/string/strtok_r.cpp
@@ -13,9 +13,10 @@
 
 namespace __llvm_libc {
 
-char *LLVM_LIBC_ENTRYPOINT(strtok_r)(char *__restrict src,
-                                     const char *__restrict delimiter_string,
-                                     char **__restrict saveptr) {
+LLVM_LIBC_FUNCTION(char *, strtok_r,
+                   (char *__restrict src,
+                    const char *__restrict delimiter_string,
+                    char **__restrict saveptr)) {
   return internal::string_token(src, delimiter_string, saveptr);
 }
 
diff --git a/src/string/x86/memcpy.cpp b/src/string/x86/memcpy.cpp
index 2e2148e..7c5740b 100644
--- a/src/string/x86/memcpy.cpp
+++ b/src/string/x86/memcpy.cpp
@@ -80,8 +80,9 @@
   return CopyRepMovsb(dst, src, count);
 }
 
-void *LLVM_LIBC_ENTRYPOINT(memcpy)(void *__restrict dst,
-                                   const void *__restrict src, size_t size) {
+LLVM_LIBC_FUNCTION(void *, memcpy,
+                   (void *__restrict dst, const void *__restrict src,
+                    size_t size)) {
   memcpy_x86(reinterpret_cast<char *>(dst), reinterpret_cast<const char *>(src),
              size);
   return dst;
diff --git a/src/sys/mman/linux/mmap.cpp b/src/sys/mman/linux/mmap.cpp
index 616cd98..31e114a 100644
--- a/src/sys/mman/linux/mmap.cpp
+++ b/src/sys/mman/linux/mmap.cpp
@@ -19,8 +19,9 @@
 
 // This function is currently linux only. It has to be refactored suitably if
 // mmap is to be supported on non-linux operating systems also.
-void *LLVM_LIBC_ENTRYPOINT(mmap)(void *addr, size_t size, int prot, int flags,
-                                 int fd, off_t offset) {
+LLVM_LIBC_FUNCTION(void *, mmap,
+                   (void *addr, size_t size, int prot, int flags, int fd,
+                    off_t offset)) {
   // A lot of POSIX standard prescribed validation of the parameters is not
   // done in this function as modern linux versions do it in the syscall.
   // TODO: Perform argument validation not done by the linux syscall.
diff --git a/src/sys/mman/linux/munmap.cpp b/src/sys/mman/linux/munmap.cpp
index 1f112f8..fd89773 100644
--- a/src/sys/mman/linux/munmap.cpp
+++ b/src/sys/mman/linux/munmap.cpp
@@ -17,7 +17,7 @@
 
 // This function is currently linux only. It has to be refactored suitably if
 // mmap is to be supported on non-linux operating systems also.
-int LLVM_LIBC_ENTRYPOINT(munmap)(void *addr, size_t size) {
+LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
   long ret_val =
       __llvm_libc::syscall(SYS_munmap, reinterpret_cast<long>(addr), size);
 
diff --git a/src/threads/linux/call_once.cpp b/src/threads/linux/call_once.cpp
index 058f370..9e1d935 100644
--- a/src/threads/linux/call_once.cpp
+++ b/src/threads/linux/call_once.cpp
@@ -22,7 +22,8 @@
 static constexpr unsigned WAITING = 0x22;
 static constexpr unsigned FINISH = 0x33;
 
-void LLVM_LIBC_ENTRYPOINT(call_once)(once_flag *flag, __call_once_func_t func) {
+LLVM_LIBC_FUNCTION(void, call_once,
+                   (once_flag * flag, __call_once_func_t func)) {
   FutexData *futex_word = reinterpret_cast<FutexData *>(flag);
   unsigned int not_called = ONCE_FLAG_INIT;
 
diff --git a/src/threads/linux/mtx_init.cpp b/src/threads/linux/mtx_init.cpp
index 329843c..610098a 100644
--- a/src/threads/linux/mtx_init.cpp
+++ b/src/threads/linux/mtx_init.cpp
@@ -12,7 +12,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(mtx_init)(mtx_t *mutex, int type) {
+LLVM_LIBC_FUNCTION(int, mtx_init, (mtx_t * mutex, int type)) {
   *(reinterpret_cast<uint32_t *>(mutex->__internal_data)) = MS_Free;
   mutex->__mtx_type = type;
   return thrd_success;
diff --git a/src/threads/linux/mtx_lock.cpp b/src/threads/linux/mtx_lock.cpp
index 44a82df..923b1b6 100644
--- a/src/threads/linux/mtx_lock.cpp
+++ b/src/threads/linux/mtx_lock.cpp
@@ -18,7 +18,7 @@
 namespace __llvm_libc {
 
 // The implementation currently handles only plain mutexes.
-int LLVM_LIBC_ENTRYPOINT(mtx_lock)(mtx_t *mutex) {
+LLVM_LIBC_FUNCTION(int, mtx_lock, (mtx_t * mutex)) {
   FutexData *futex_data = reinterpret_cast<FutexData *>(mutex->__internal_data);
   while (true) {
     uint32_t mutex_status = MS_Free;
diff --git a/src/threads/linux/mtx_unlock.cpp b/src/threads/linux/mtx_unlock.cpp
index 2517063..370e1b1 100644
--- a/src/threads/linux/mtx_unlock.cpp
+++ b/src/threads/linux/mtx_unlock.cpp
@@ -18,7 +18,7 @@
 namespace __llvm_libc {
 
 // The implementation currently handles only plain mutexes.
-int LLVM_LIBC_ENTRYPOINT(mtx_unlock)(mtx_t *mutex) {
+LLVM_LIBC_FUNCTION(int, mtx_unlock, (mtx_t * mutex)) {
   FutexData *futex_word = reinterpret_cast<FutexData *>(mutex->__internal_data);
   while (true) {
     uint32_t mutex_status = MS_Waiting;
diff --git a/src/threads/linux/thrd_create.cpp b/src/threads/linux/thrd_create.cpp
index 946000e..ff47e53 100644
--- a/src/threads/linux/thrd_create.cpp
+++ b/src/threads/linux/thrd_create.cpp
@@ -35,8 +35,8 @@
                                      start_args->func(start_args->arg));
 }
 
-int LLVM_LIBC_ENTRYPOINT(thrd_create)(thrd_t *thread, thrd_start_t func,
-                                      void *arg) {
+LLVM_LIBC_FUNCTION(int, thrd_create,
+                   (thrd_t * thread, thrd_start_t func, void *arg)) {
   unsigned clone_flags =
       CLONE_VM        // Share the memory space with the parent.
       | CLONE_FS      // Share the file system with the parent.
diff --git a/src/threads/linux/thrd_join.cpp b/src/threads/linux/thrd_join.cpp
index 18e6b6f..c0ad33c 100644
--- a/src/threads/linux/thrd_join.cpp
+++ b/src/threads/linux/thrd_join.cpp
@@ -18,7 +18,7 @@
 
 namespace __llvm_libc {
 
-int LLVM_LIBC_ENTRYPOINT(thrd_join)(thrd_t *thread, int *retval) {
+LLVM_LIBC_FUNCTION(int, thrd_join, (thrd_t * thread, int *retval)) {
   FutexData *clear_tid_address =
       reinterpret_cast<FutexData *>(thread->__clear_tid);
 
diff --git a/src/time/mktime.cpp b/src/time/mktime.cpp
index 4187971..c99cf87 100644
--- a/src/time/mktime.cpp
+++ b/src/time/mktime.cpp
@@ -42,7 +42,7 @@
   return static_cast<time_t>(-1);
 }
 
-time_t LLVM_LIBC_ENTRYPOINT(mktime)(struct tm *t1) {
+LLVM_LIBC_FUNCTION(time_t, mktime, (struct tm * t1)) {
   // Unlike most C Library functions, mktime doesn't just die on bad input.
   // TODO(rtenneti); Handle leap seconds. Handle out of range time and date
   // values that don't overflow or underflow.
diff --git a/src/unistd/linux/write.cpp b/src/unistd/linux/write.cpp
index 2778346..de0efb9 100644
--- a/src/unistd/linux/write.cpp
+++ b/src/unistd/linux/write.cpp
@@ -15,7 +15,7 @@
 
 namespace __llvm_libc {
 
-ssize_t LLVM_LIBC_ENTRYPOINT(write)(int fd, const void *buf, size_t count) {
+LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) {
   long ret = __llvm_libc::syscall(SYS_write, fd, buf, count);
   if (ret < 0) {
     llvmlibc_errno = -ret;