[libc] Implement 'getenv' on the GPU target (#102376)

Summary:
This patch implements 'getenv'. I was torn on how to implement this,
since realistically we only have access to this environment pointer in
the "loader" interface. An alternative would be to use an RPC call every
time, but I think that's overkill for what this will be used for. A
better solution is just to emit a common `DataEnvironment` that contains
all of the host visible resources to initialize. Right now this is the
`env_ptr`, `clock_freq`, and `rpc_client`.

I did this by making the `app.h` interface that Linux uses more general,
could possibly move that into a separate patch, but I figured it's
easier to see with the usage.
This commit is contained in:
Joseph Huber
2024-08-08 06:45:42 -05:00
committed by GitHub
parent 8f0c865d10
commit 1a92cc5a0a
22 changed files with 84 additions and 26 deletions

View File

@@ -1,3 +1,7 @@
#TODO: Properly select the correct subdirectory.
add_subdirectory(linux)
add_header_library(
app_h
HDRS
app.h
DEPENDS
libc.src.__support.common
)

20
libc/config/app.h Normal file
View File

@@ -0,0 +1,20 @@
//===-- Classes to capture properites of applications -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_CONFIG_APP_H
#define LLVM_LIBC_CONFIG_APP_H
#include "src/__support/macros/properties/architectures.h"
#if defined(LIBC_TARGET_ARCH_IS_GPU)
#include "gpu/app.h"
#elif defined(__linux__)
#include "linux/app.h"
#endif
#endif // LLVM_LIBC_CONFIG_APP_H

28
libc/config/gpu/app.h Normal file
View File

@@ -0,0 +1,28 @@
//===-- Classes to capture properites of GPU applications -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_CONFIG_GPU_APP_H
#define LLVM_LIBC_CONFIG_GPU_APP_H
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
// TODO: Move other global values here and export them to the host.
struct DataEnvironment {
uintptr_t *env_ptr;
};
extern DataEnvironment app;
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_CONFIG_GPU_APP_H

View File

@@ -167,6 +167,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.strtoull
libc.src.stdlib.at_quick_exit
libc.src.stdlib.quick_exit
libc.src.stdlib.getenv
# TODO: Implement these correctly
libc.src.stdlib.aligned_alloc

View File

@@ -1,7 +0,0 @@
add_header_library(
app_h
HDRS
app.h
DEPENDS
libc.src.__support.common
)

View File

@@ -77,7 +77,7 @@ add_object_library(
thread.cpp
DEPENDS
.futex_utils
libc.config.linux.app_h
libc.config.app_h
libc.include.sys_syscall
libc.include.fcntl
libc.src.errno.errno

View File

@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/threads/thread.h"
#include "config/linux/app.h"
#include "config/app.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/stringstream.h"

View File

@@ -62,7 +62,7 @@ add_entrypoint_object(
HDRS
getenv.h
DEPENDS
libc.config.linux.app_h
libc.config.app_h
)
add_entrypoint_object(

View File

@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/getenv.h"
#include "config/linux/app.h"
#include "config/app.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

View File

@@ -11,7 +11,7 @@ add_entrypoint_object(
libc.src.__support.threads.callonce
libc.src.__support.common
libc.src.errno.errno
libc.config.linux.app_h
libc.config.app_h
libc.src.fcntl.open
libc.src.unistd.read
libc.src.unistd.close

View File

@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/sys/auxv/getauxval.h"
#include "config/linux/app.h"
#include "config/app.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

View File

@@ -34,7 +34,7 @@ function(add_startup_object name)
RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}
RUNTIME_OUTPUT_NAME ${name}.o)
target_link_options(${fq_target_name}.exe PRIVATE
"-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
"-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
endif()
endfunction()

View File

@@ -3,6 +3,7 @@ add_startup_object(
SRC
start.cpp
DEPENDS
libc.config.app_h
libc.src.__support.RPC.rpc_client
libc.src.__support.GPU.utils
libc.src.stdlib.exit

View File

@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "config/gpu/app.h"
#include "src/__support/GPU/utils.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/macros/config.h"
@@ -16,6 +17,8 @@ extern "C" int main(int argc, char **argv, char **envp);
namespace LIBC_NAMESPACE_DECL {
DataEnvironment app;
extern "C" uintptr_t __init_array_start[];
extern "C" uintptr_t __init_array_end[];
extern "C" uintptr_t __fini_array_start[];
@@ -40,6 +43,8 @@ static void call_fini_array_callbacks() {
extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel]] void
_begin(int argc, char **argv, char **env) {
__atomic_store_n(&LIBC_NAMESPACE::app.env_ptr,
reinterpret_cast<uintptr_t *>(env), __ATOMIC_RELAXED);
// We want the fini array callbacks to be run after other atexit
// callbacks are run. So, we register them before running the init
// array callbacks as they can potentially register their own atexit

View File

@@ -3,6 +3,7 @@ add_startup_object(
SRC
start.cpp
DEPENDS
libc.config.app_h
libc.src.__support.RPC.rpc_client
libc.src.__support.GPU.utils
libc.src.stdlib.exit

View File

@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "config/gpu/app.h"
#include "src/__support/GPU/utils.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/macros/config.h"
@@ -16,6 +17,8 @@ extern "C" int main(int argc, char **argv, char **envp);
namespace LIBC_NAMESPACE_DECL {
DataEnvironment app;
extern "C" {
// Nvidia's 'nvlink' linker does not provide these symbols. We instead need
// to manually create them and update the globals in the loader implememtation.
@@ -46,6 +49,9 @@ static void call_fini_array_callbacks() {
extern "C" [[gnu::visibility("protected"), clang::nvptx_kernel]] void
_begin(int argc, char **argv, char **env) {
__atomic_store_n(&LIBC_NAMESPACE::app.env_ptr,
reinterpret_cast<uintptr_t *>(env), __ATOMIC_RELAXED);
// We want the fini array callbacks to be run after other atexit
// callbacks are run. So, we register them before running the init
// array callbacks as they can potentially register their own atexit

View File

@@ -95,7 +95,7 @@ add_object_library(
HDRS
do_start.h
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.include.sys_mman
libc.include.sys_syscall
libc.include.llvm-libc-macros.link_macros

View File

@@ -3,7 +3,7 @@ add_startup_object(
SRC
tls.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.include.sys_mman
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -18,7 +18,7 @@ add_startup_object(
SRC
start.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
COMPILE_OPTIONS
-fno-omit-frame-pointer
-ffreestanding # To avoid compiler warnings about calling the main function.

View File

@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "config/linux/app.h"
#include "config/app.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {

View File

@@ -3,7 +3,7 @@ add_startup_object(
SRC
tls.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.include.sys_mman
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -18,7 +18,7 @@ add_startup_object(
SRC
start.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.src.__support.macros.attributes
COMPILE_OPTIONS
-fno-omit-frame-pointer

View File

@@ -3,7 +3,7 @@ add_startup_object(
SRC
tls.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.include.sys_mman
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -20,7 +20,7 @@ add_startup_object(
SRC
start.cpp
DEPENDS
libc.config.linux.app_h
libc.config.app_h
libc.src.__support.macros.attributes
COMPILE_OPTIONS
-fno-stack-protector

View File

@@ -13,4 +13,3 @@ add_integration_test(
FRANCE=Paris
GERMANY=Berlin
)