Skip to content

[libc] Fix the api-test integration test #79627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

gchatelet
Copy link
Contributor

@gchatelet gchatelet commented Jan 26, 2024

This patch

  • Revives the api-test that was broken
  • Adapts PrototypeTestGen to take the list of entrypoints via a file instead of arguments. The command line was becoming too long and was rejected by the shell.
  • Makes sure that symbols are present in the final library by taking their address resulting in link error.

@llvmbot llvmbot added the libc label Jan 26, 2024
@gchatelet gchatelet marked this pull request as draft January 26, 2024 18:24
@llvmbot
Copy link
Member

llvmbot commented Jan 26, 2024

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/79627.diff

4 Files Affected:

  • (modified) libc/test/CMakeLists.txt (+4-4)
  • (modified) libc/test/src/CMakeLists.txt (+20-13)
  • (modified) libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt (+14-2)
  • (modified) libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp (+23-6)
diff --git a/libc/test/CMakeLists.txt b/libc/test/CMakeLists.txt
index f22f2b183aca92..0773e9cf15242e 100644
--- a/libc/test/CMakeLists.txt
+++ b/libc/test/CMakeLists.txt
@@ -14,14 +14,14 @@ if(LIBC_TARGET_ARCHITECTURE_IS_GPU AND
   return()
 endif()
 
-add_subdirectory(include)
-add_subdirectory(src)
-add_subdirectory(utils)
-
 if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_BAREMETAL)
   add_subdirectory(IntegrationTest)
 endif()
 
+add_subdirectory(include)
+add_subdirectory(src)
+add_subdirectory(utils) # uses IntegrationTest
+
 if(NOT LLVM_LIBC_FULL_BUILD)
   return()
 endif()
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 6bd8ace9ea71af..6a3cc9d1449880 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -82,8 +82,7 @@ if(LLVM_RUNTIMES_BUILD OR LIBC_HDRGEN_EXE)
   return()
 endif()
 
-set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_api_test.cpp)
-
+# Generate api public entrypoints.
 set(entrypoints_name_list "")
 foreach(entry IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
   get_target_property(entry_name ${entry} "ENTRYPOINT_NAME")
@@ -91,22 +90,30 @@ foreach(entry IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
 endforeach()
 
 # TODO: Remove these when they are added to the TableGen.
-list(REMOVE_ITEM entrypoints_name_list "__assert_fail" "__errno_location")
-list(TRANSFORM entrypoints_name_list PREPEND "-e=")
+list(REMOVE_ITEM entrypoints_name_list "prctl" "getauxval" "__stack_chk_fail")
+string(REPLACE ";" "," entrypoints_name_list "${entrypoints_name_list}")
 
-file(GLOB spec_files ${LIBC_SOURCE_DIR}/spec/*.td)
+set(public_entrypoints ${CMAKE_CURRENT_BINARY_DIR}/public_entrypoints.txt)
+file(WRITE ${public_entrypoints} "${entrypoints_name_list}")
 
 # Generate api test souce code.
+set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_api_test.cpp)
+file(GLOB spec_files ${LIBC_SOURCE_DIR}/spec/*.td)
 add_custom_command(
   OUTPUT ${public_test}
-  COMMAND $<TARGET_FILE:libc-prototype-testgen> -o ${public_test}
-          ${entrypoints_name_list}
-          -I ${LIBC_SOURCE_DIR}
-          ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
-
-  DEPENDS ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td ${spec_files}
-          libc-prototype-testgen ${TARGET_PUBLIC_HEADERS}
-          ${LIBC_TARGET}
+  COMMAND
+    "$<TARGET_FILE:libc-prototype-testgen>"
+      -o ${public_test}
+      --entrypoints_file ${public_entrypoints}
+      -I ${LIBC_SOURCE_DIR}
+      ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
+  DEPENDS
+    ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
+    ${spec_files}
+    ${public_entrypoints}
+    libc-prototype-testgen
+    ${TARGET_PUBLIC_HEADERS}
+    ${LIBC_TARGET}
 )
 
 add_custom_target(libc-api-test)
diff --git a/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt b/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt
index 9e25c21c6b3593..331eb70b7e9891 100644
--- a/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt
+++ b/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt
@@ -1,5 +1,17 @@
+include(TableGen)
+
+set(LLVM_LINK_COMPONENTS Support)
+
 add_tablegen(libc-prototype-testgen LLVM_LIBC
   PrototypeTestGen.cpp
 )
-target_link_libraries(libc-prototype-testgen PRIVATE LibcTableGenUtil)
-target_include_directories(libc-prototype-testgen PRIVATE ${LIBC_SOURCE_DIR})
+target_link_libraries(libc-prototype-testgen
+  PRIVATE
+    LibcTableGenUtil
+)
+target_include_directories(libc-prototype-testgen
+  PRIVATE
+    ${LIBC_SOURCE_DIR}
+    ${LLVM_INCLUDE_DIR}
+    ${LLVM_MAIN_INCLUDE_DIR}
+)
diff --git a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
index 551b97caf81fd6..b1f89fbea0256d 100644
--- a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
+++ b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp
@@ -8,16 +8,19 @@
 
 #include "utils/LibcTableGenUtil/APIIndexer.h"
 
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/TableGen/Main.h"
 #include "llvm/TableGen/Record.h"
 
 namespace {
 
-llvm::cl::list<std::string>
-    EntrypointNamesOption("e", llvm::cl::desc("<list of entrypoints>"),
-                          llvm::cl::OneOrMore);
+llvm::cl::opt<std::string> EntrypointsFilename(
+    "entrypoints_file",
+    llvm::cl::desc("file containing the comma separated list of entrypoints"),
+    llvm::cl::Required);
 
 } // anonymous namespace
 
@@ -25,7 +28,13 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) {
   OS << "#include \"src/__support/CPP/type_traits.h\"\n";
   llvm_libc::APIIndexer G(records);
   std::unordered_set<std::string> headerFileSet;
-  for (const auto &entrypoint : EntrypointNamesOption) {
+
+  auto Entrypoints = llvm::MemoryBuffer::getFile(EntrypointsFilename);
+
+  std::vector<std::string> entrypoints;
+  for (auto entrypoint : llvm::split((*Entrypoints)->getBuffer(), ','))
+    entrypoints.push_back(entrypoint.str());
+  for (auto entrypoint : entrypoints) {
     if (entrypoint == "errno")
       continue;
     auto match = G.FunctionToHeaderMap.find(entrypoint);
@@ -48,7 +57,7 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) {
   OS << '\n';
 
   OS << "extern \"C\" int main() {\n";
-  for (const auto &entrypoint : EntrypointNamesOption) {
+  for (const auto &entrypoint : entrypoints) {
     if (entrypoint == "errno")
       continue;
     auto match = G.FunctionSpecMap.find(entrypoint);
@@ -91,9 +100,17 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) {
        << " prototype in TableGen does not match public header" << '"';
     OS << ");\n";
   }
+  OS << '\n';
+  OS << "  // Check that all entrypoints are present in the binary";
+  OS << "  uintptr_t check = 0;\n";
+  for (const auto &entrypoint : entrypoints) {
+    if (entrypoint == "errno")
+      continue;
+    OS << "  check += reinterpret_cast<uintptr_t>(&" << entrypoint << ");\n";
+  }
 
   OS << '\n';
-  OS << "  return 0;\n";
+  OS << "  return check != 0 ? 0 : 1;\n";
   OS << "}\n\n";
 
   return false;

@gchatelet
Copy link
Contributor Author

This needs #79319 to be in first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants