[libc-commits] [libc] 4052bc8 - [libc] Make errno an entrypoint.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Thu Mar 2 22:59:29 PST 2023


Author: Siva Chandra Reddy
Date: 2023-03-03T06:59:19Z
New Revision: 4052bc86745ab50965846329fdd3eaa500c31520

URL: https://github.com/llvm/llvm-project/commit/4052bc86745ab50965846329fdd3eaa500c31520
DIFF: https://github.com/llvm/llvm-project/commit/4052bc86745ab50965846329fdd3eaa500c31520.diff

LOG: [libc] Make errno an entrypoint.

The entrypoint has been added to the various entrypoint lists. The libc
code style doc has been updated with information on how errno should be
set from the libc runtime code.

Reviewed By: lntue

Differential Revision: https://reviews.llvm.org/D145179

Added: 
    

Modified: 
    libc/cmake/modules/LLVMLibCLibraryRules.cmake
    libc/config/baremetal/entrypoints.txt
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/arm/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/dev/code_style.rst
    libc/src/errno/CMakeLists.txt
    libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp

Removed: 
    


################################################################################
diff  --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
index 279e15b82fa3f..6d37232c8ae57 100644
--- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake
+++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
@@ -1,4 +1,6 @@
 function(collect_object_file_deps target result)
+  # NOTE: This function does add entrypoint targets to |result|.
+  # It is expected that the caller adds them separately.
   set(all_deps "")
   get_target_property(target_type ${target} "TARGET_TYPE")
   if(NOT target_type)
@@ -28,7 +30,6 @@ function(collect_object_file_deps target result)
       endif()
       set(entrypoint_target ${aliasee})
     endif()
-    list(APPEND all_deps ${entrypoint_target})
     get_target_property(deps ${target} "DEPS")
     foreach(dep IN LISTS deps)
       collect_object_file_deps(${dep} dep_targets)
@@ -80,6 +81,21 @@ function(add_entrypoint_library target_name)
     endif()
     collect_object_file_deps(${dep} recursive_deps)
     list(APPEND all_deps ${recursive_deps})
+    # Add the entrypoint object target explicitly as collect_object_file_deps
+    # only collects object files from non-entrypoint targets.
+    if(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
+      set(entrypoint_target ${dep})
+      get_target_property(is_alias ${entrypoint_target} "IS_ALIAS")
+      if(is_alias)
+        get_target_property(aliasee ${entrypoint_target} "DEPS")
+        if(NOT aliasee)
+          message(FATAL_ERROR
+                  "Entrypoint alias ${entrypoint_target} does not have an aliasee.")
+        endif()
+        set(entrypoint_target ${aliasee})
+      endif()
+    endif()
+    list(APPEND all_deps ${entrypoint_target})
   endforeach(dep)
   list(REMOVE_DUPLICATES all_deps)
   set(objects "")

diff  --git a/libc/config/baremetal/entrypoints.txt b/libc/config/baremetal/entrypoints.txt
index 5dc233ef8dd0b..183cf1b66a88d 100644
--- a/libc/config/baremetal/entrypoints.txt
+++ b/libc/config/baremetal/entrypoints.txt
@@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
 
+    # errno.h entrypoints
+    libc.src.errno.errno
+
     # string.h entrypoints
     libc.src.string.bcmp
     libc.src.string.bcopy

diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 6865133826cb3..7656be999b0a4 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
     
+    # errno.h entrypoints
+    libc.src.errno.errno
+
     # fcntl.h entrypoints
     libc.src.fcntl.creat
     libc.src.fcntl.open

diff  --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 98d00aa5c9c93..a3f6dafd8b52f 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
 
+    # errno.h entrypoints
+    libc.src.errno.errno
+
     # string.h entrypoints
     libc.src.string.bcmp
     libc.src.string.bcopy

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c90ec052b459b..5899c1d00c865 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
 
+    # errno.h entrypoints
+    libc.src.errno.errno
+
     # fcntl.h entrypoints
     libc.src.fcntl.creat
     libc.src.fcntl.open

diff  --git a/libc/docs/dev/code_style.rst b/libc/docs/dev/code_style.rst
index 74fe8de6d026e..48197eee2763e 100644
--- a/libc/docs/dev/code_style.rst
+++ b/libc/docs/dev/code_style.rst
@@ -65,3 +65,40 @@ When defining functions inline in header files, we follow certain rules:
    definitions that are implicitly inline. Examples of such functions are
    class methods (static and non-static) defined inline and ``constexpr``
    functions.
+
+Setting ``errno`` from runtime code
+===================================
+
+Many libc functions set ``errno`` to indicate an error condition. If LLVM's libc
+is being used as the only libc, then the ``errno`` from LLVM's libc is affected.
+If LLVM's libc is being used in the :ref:`overlay_mode`, then the ``errno`` from
+the system libc is affected. When a libc function, which can potentially affect
+the ``errno``, is called from a unit test, we do not want the global ``errno``
+(as in, the ``errno`` of the process thread running the unit test) to be
+affected. If the global ``errno`` is affected, then the operation of the unit
+test infrastructure itself can be affected. To avoid perturbing the unit test
+infrastructure around the setting of ``errno``, the following rules are to be
+followed:
+
+#. A special macro named ``libc_errno`` defined in ``src/errno/libc_errno.h``
+   should be used when setting ``errno`` from libc runtime code. For example,
+   code to set ``errno`` to ``EINVAL`` should be:
+
+   .. code-block:: c++
+
+    libc_errno = EINVAL;
+
+#. ``errno`` should be set just before returning from the implementation of the
+   public function. It should not be set from within helper functions. Helper
+   functions should use idiomatic C++ constructs like
+   `cpp::optional <https://github.com/llvm/llvm-project/blob/main/libc/src/__support/CPP/optional.h>`_
+   and
+   `ErrorOr <https://github.com/llvm/llvm-project/blob/main/libc/src/__support/error_or.h>`_
+   to return error values.
+
+#. The header file ``src/errno/libc_errno.h`` is shipped as part of the target
+   corresponding to the ``errno`` entrypoint ``libc.src.errno.errno``. We do
+   not in general allow dependecies between entrypoints. However, the ``errno``
+   entrypoint is the only exceptional entrypoint on which other entrypoints
+   should explicitly depend on if they set ``errno`` to indicate error
+   conditions.

diff  --git a/libc/src/errno/CMakeLists.txt b/libc/src/errno/CMakeLists.txt
index dd1cdc04cd6b0..61b56047ce0a4 100644
--- a/libc/src/errno/CMakeLists.txt
+++ b/libc/src/errno/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_object_library(
+add_entrypoint_object(
   errno
   SRCS
     libc_errno.cpp

diff  --git a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
index 016826faf77ee..667d4eb1d72ea 100644
--- a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
+++ b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
@@ -26,6 +26,8 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) {
   llvm_libc::APIIndexer G(records);
   std::unordered_set<std::string> headerFileSet;
   for (const auto &entrypoint : EntrypointNamesOption) {
+    if (entrypoint == "errno")
+      continue;
     auto match = G.FunctionToHeaderMap.find(entrypoint);
     if (match == G.FunctionToHeaderMap.end()) {
       auto objectMatch = G.ObjectToHeaderMap.find(entrypoint);
@@ -47,6 +49,8 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) {
 
   OS << "extern \"C\" int main() {\n";
   for (const auto &entrypoint : EntrypointNamesOption) {
+    if (entrypoint == "errno")
+      continue;
     auto match = G.FunctionSpecMap.find(entrypoint);
     if (match == G.FunctionSpecMap.end()) {
       auto objectMatch = G.ObjectSpecMap.find(entrypoint);


        


More information about the libc-commits mailing list