diff --git a/projects/rocm-core/CHANGELOG.md b/projects/rocm-core/CHANGELOG.md index 7be9b06418..ec10512fc3 100644 --- a/projects/rocm-core/CHANGELOG.md +++ b/projects/rocm-core/CHANGELOG.md @@ -1,7 +1,9 @@ Change Logs for rocm-core - -Unreleased ROCm6.0.0 release +Unreleased ROCm6.1.0 release + - Added new API to get ROCm install Path (getROCmInstallPath()) at runtime + using dlinfo of rocm-core Target Library. +ROCm6.0.0 release - Added script to convert RUNPATH in libraries and binaries to RPATH. - Disabled ROCm file reorg backward compatibility diff --git a/projects/rocm-core/CMakeLists.txt b/projects/rocm-core/CMakeLists.txt index 3400824a47..35ec1229e3 100644 --- a/projects/rocm-core/CMakeLists.txt +++ b/projects/rocm-core/CMakeLists.txt @@ -29,6 +29,9 @@ set( CORE_TARGET "rocm-core" ) project( ${CORE_TARGET} CXX ) +## Define Lib Target Name and Lib Target Install Dir to be available to c++ source +add_definitions( -DTARGET_LIBRARY_NAME=\"${CORE_TARGET}\" -DTARGET_LIBRARY_INSTALL_DIR=\"${CMAKE_INSTALL_LIBDIR}\" ) + ## Verbose output. set( CMAKE_VERBOSE_MAKEFILE on ) @@ -67,7 +70,7 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/rocm-core.prerm ${BUILD_DIR}/prerm @ #Generate BUILD_INFO configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/rocm_version.h.in ${BUILD_DIR}/rocm_version.h @ONLY ) - +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/rocm_getpath.h.in ${BUILD_DIR}/rocm_getpath.h @ONLY ) #File reorg Backward compatibility function if(NOT WIN32) if(FILE_REORG_BACKWARD_COMPATIBILITY) @@ -92,12 +95,13 @@ if(NOT WIN32) endif() #Make the rocmlib -set( SRCS rocm_version.cpp ) +set( SRCS rocm_version.cpp rocm_getpath.cpp) add_library( ${CORE_TARGET} ${SRCS} ) set( CXX_FLAGS ${CXX_FLAGS} -g -fPIC -fvisibility=hidden -W -Wall -Wextra -Wno-unused-parameter -Wformat-security -Wundef -Wshadow -Wpointer-arith -Wcast-qual -Wmissing-declarations -Wredundant-decls -Wunreachable-code -std=c++11 ) set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,nodelete -Wl,-no-undefined" ) target_include_directories( ${CORE_TARGET} PRIVATE ${BUILD_DIR} ) +target_link_libraries( ${CORE_TARGET} PRIVATE dl ) ## Set the VERSION and SOVERSION values set( SO_VERSION_STRING "${SO_MAJOR}.${SO_MINOR}.${ROCM_LIBPATCH_VERSION}" ) @@ -121,7 +125,10 @@ install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION .info COMPONENT install ( TARGETS ${CORE_TARGET} DESTINATION ${CMAKE_INSTALL_LIBDIR} PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT ${COMP_TYPE} ) -install ( FILES ${BUILD_DIR}/rocm_version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocm-core COMPONENT runtime ) +install ( FILES ${BUILD_DIR}/rocm_version.h ${BUILD_DIR}/rocm_getpath.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocm-core + COMPONENT runtime ) + install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/runpath_to_rpath.py DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/rocm-core COMPONENT runtime ) install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/rocmmod DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime ) diff --git a/projects/rocm-core/rocm_getpath.cpp b/projects/rocm-core/rocm_getpath.cpp new file mode 100644 index 0000000000..52f2fdcdee --- /dev/null +++ b/projects/rocm-core/rocm_getpath.cpp @@ -0,0 +1,161 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// MIT License +// +// Copyright (c) 2017 - 2024 Advanced Micro Devices, Inc. All rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include /* PATH_MAX */ +#include +#include +#include +#include "rocm_getpath.h" + +/* Macro for NULL CHECK */ +#define NULL_CHECK(ptr) if(!ptr) return PathIncorrecPararmeters; + + +/* Target Library Install Dir */ +#define TARGET_LIB_INSTALL_DIR TARGET_LIBRARY_INSTALL_DIR + +/* Target Library Name Buf Size */ +#define LIBRARY_FILENAME_BUFSZ (PATH_MAX+1) + +/* Internal Function to get Base Path - Ref from Icarus Logic*/ +static int getROCmBase(char *buf); + +/* Public Function to get the ROCm Install Base Path +// Argument1 (out) : InstallPath (char** pointer which will return InstallPath found) +// Argument2 (out) : InstallPathLen (Pointer to integer (size of InstallPath) returned) +// Usage : +// char *installPath=NULL; +// int installPathLen = 0; +// installStatus = getROCmInstallPath( &installPath, &installPathLen ); +// if(installStatus !=PathSuccess ){ // error occured +// ... +// } +// free(installPath); //caller must free allocated memory after usage. +// ... + +*/ +PathErrors_t getROCmInstallPath( char** InstallPath, unsigned int *InstallPathLen ) { + + NULL_CHECK(InstallPath); + NULL_CHECK(InstallPathLen); + int ret = PathErrorMAX; + char *bufPtr = (char *)NULL; + unsigned int bufSz = 0; + + bufPtr = (char *)malloc( LIBRARY_FILENAME_BUFSZ * sizeof(char) ); + memset( bufPtr, 0, LIBRARY_FILENAME_BUFSZ ); + *InstallPathLen = 0; + *InstallPath = NULL; + + ret = getROCmBase(bufPtr); + if (0 > ret){ + free(bufPtr); + return (PathErrors_t)ret; + } + else if (0 == ret){ + free(bufPtr); + return PathFailedToGetBase; + } + else{ + bufSz = ret;//additional char for null termination + } + + *InstallPath = bufPtr; + *InstallPathLen = bufSz; + return PathSuccess; +} + +/* General purpose function that fills the directory to find rocm related stuff */ +/* returns the offset into the buffer for the terminating NUL or -1 for error */ +/* The buffer should be at least PATH_MAX */ +static int getROCmBase(char *buf) +{ + int len=0; + char *envStr=NULL; + char libFileName[LIBRARY_FILENAME_BUFSZ]; + char *end=NULL; + + if ((envStr = getenv("ROCM_PATH"))) { + /* User space override, essentially just copied through as long as it is not too long */ + len = strlen(envStr); + if (len > 0) { + if (envStr[len] == '/') { + /* Already has at least one terminating */ + len--; + } + if (len > PATH_MAX-1 ) { + return PathValuesTooLong; + } + strncpy(buf, envStr, len); + buf[len]='/'; + buf[len+1]='\0'; + + /* Length of string including trailing '/' */ + return len+1; + } + } + + sprintf(libFileName, "lib%s.so", TARGET_LIBRARY_NAME); + void *handle=dlopen(libFileName,RTLD_NOW); + if (!handle){ + /* We can't find the library */ + return PathLinuxRuntimeErrors; + } + /* Variable to hold the return value from dlinfo */ + struct link_map *map = (struct link_map*)NULL; + /* Query the runtime linker */ + dlinfo(handle,RTLD_DI_LINKMAP,&map); + if (map ->l_name && realpath(map ->l_name,buf)) { + /* Get Library Directory Path */ + char *end = strrchr(buf, '/'); + if (end && end > buf) { + *end = '\0'; + } + } + else{ + /* If l_name is NULL or realpath() failed + * Close handle before return error */ + dlclose(handle); + return PathLinuxRuntimeErrors; + } + + dlclose(handle); + /* find the start of substring TARGET_LIB_INSTALL_DIR + * To strip down Path up to Parent Directory of TARGET_LIB_INSTALL_DIR. */ + end=strstr(buf, TARGET_LIB_INSTALL_DIR); + if( NULL == end ){ + /* We can't find the library install directory*/ + return PathLinuxRuntimeErrors; + } + *end = '\0'; + + /* Length of Path String up to Parent Directoy (ROCm Base Path) + * with trailing '/'.*/ + len = strlen(buf); + return len; +} + diff --git a/projects/rocm-core/rocm_getpath.h.in b/projects/rocm-core/rocm_getpath.h.in new file mode 100644 index 0000000000..b4dab8e1d2 --- /dev/null +++ b/projects/rocm-core/rocm_getpath.h.in @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////// +//// +//// MIT License +//// +//// Copyright (c) 2017 - 2024 Advanced Micro Devices, Inc. All rights Reserved. +//// +//// Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +//// +//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//// +////////////////////////////////////////////////////////////////////////////////// + + +#ifndef _ROCM_GETPATH_H_ +#define _ROCM_GETPATH_H_ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LIB_API_PUBLIC __attribute__ ((visibility ("default"))) + +/* Return Status Flag Definitions*/ +typedef enum { + PathSuccess=0, + PathIncorrecPararmeters = -994, + PathValuesNotDefined = -995, + PathValuesTooLong = -996, + PathFailedToGetBase = -997, + PathLinuxRuntimeErrors = -998, + PathErrorMAX = -999 //This should always be last value in the enumerations +} PathErrors_t; + +// API for getting the ROCmInstallPath +// Return val : PathErrors_t (API execution status) +// Argument1 (out) : InstallPath (char** pointer which will return InstallPath found ) +// Argument2 (out) : InstallPathLen (Pointer to integer (size of InstallPath) returned) +// Usage : +// char *installPath=NULL; +// int installPathLen = 0; +// installStatus = getROCmInstallPath( &installPath, &installPathLen ); +// if(installStatus !=PathSuccess ){ // error occured +// ... +// } +// free(installPath); //caller must free allocated memory after usage. +// ... +// } +LIB_API_PUBLIC PathErrors_t getROCmInstallPath(char **InstallPath, unsigned int *InstallPathLen) __attribute__((nonnull)) ; + +#ifdef __cplusplus +} // end extern "C" block +#endif + +#endif //_ROCM_GETPATH_H_ header guard +