OSDN Git Service

2019/01/01(Tue) 12:13
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Tue, 1 Jan 2019 03:11:48 +0000 (12:11 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Tue, 1 Jan 2019 03:11:48 +0000 (12:11 +0900)
 (LibBrownie)
  * SearchLib: support for LD_LIBRARY_PATH environmet-variable & DT_RUNPATH (.dynamic section)

include/libbrownie.h
include/libgoblin.h
libbrownie/Makefile
libbrownie/drd64_libbrownie_searchlib.c
libbrownie/drd64_libbrownie_searchlib.h
libbrownie/test_libbrownie_searchlib.c
libgoblin/test_libgoblin_loadprog.c

index 5427464..942df0f 100644 (file)
@@ -120,7 +120,12 @@ LIBBROWNIE_LDSOHINTS_API
 #endif
 LIBBROWNIE_SEARCHLIB_API
        int LibBrownie_GetLibraryPath(
-                       char *pstr_solibpath, char *pstr_solibname, char *pstr_rpath, char *pstr_ldsohints );
+                       char *pstr_solibpath,
+                       char *pstr_solibname,
+                       char *pstr_dt_rpath,
+                       char *pstr_dt_runpath,
+                       char *pstr_env_ldlibpath,
+                       char *pstr_ldsohints );
 
 
 #endif /* DRD64_HEADER_XXX */
index a84c0bf..1e2ed4c 100644 (file)
@@ -46,6 +46,7 @@ typedef struct        {
        char    str_localpath[DRD64_MAX_PATH];
        char    str_filename[DRD64_MAX_PATH];
        char    str_rpath[DRD64_MAX_PATH];
+       char    str_runpath[DRD64_MAX_PATH];
        int             i_bid;
 } LibGoblin_ObjectFilePath;
 
index 1bb29ec..a986e8f 100644 (file)
@@ -73,10 +73,12 @@ TEST_OBJS = \
                        test_libbrownie_searchlib.o
 TEST_HEADER = test_libbrownie.h
 
+TESTPROG = ../testdata/dwarftest
+
 
 all:   $(LIBBROWNIE_TARGET) test
 build: $(LIBBROWNIE_TARGET)
-test:  $(TEST_TARGET)
+test:  $(TEST_TARGET) $(TESTPROG)
                ./$(TEST_TARGET)
 
 $(LIBBROWNIE_TARGET): $(LIBBROWNIE_OBJS)
@@ -129,6 +131,9 @@ $(TEST_TARGET): $(TEST_OBJS) $(LIBBROWNIE_OBJS) $(LIBBROWNIE_TARGET)
        $(CC) -o $(TEST_TARGET) $(FLAGS_DEBUG) $(LIBBROWNIE_OBJS) $(TEST_OBJS) $(LIBBROWNIE_TARGET) \
                                $(TEST_FLAGS_LINKER) -lcunit
 
+$(TESTPROG):
+       $(MAKE) -C ../testdata all
+
 clean:
        rm -f *.o
        rm -f $(LIBBROWNIE_TARGET)
index 5576d4b..0a3bfa9 100644 (file)
@@ -51,7 +51,7 @@ int LibBrownie_SearchLib_IsExistLibrary(
 )
 ----------------------------------------------------------------------*/
 int
-       LibBrownie_SearchLib_IsExistLibrary(
+       SearchLib_IsExistLibrary(
                        char    *pstr_path,
                        char    *pstr_solibname )
 {
@@ -77,11 +77,62 @@ int
 }
 
 
+/*----------------------------------------------------------------------
+Search & Get Library Exist-Path from colon-separated Path Lists.
+----------------------------------------------------------------------*/
+int
+       SearchLib_SearchLibInPathArrays(
+                       char    *pstr_solibpath,        // out
+                       char    *pstr_pathlist,         // in
+                       char    *pstr_solibname )       // in
+{
+       int             i_flag;
+       int             i_result;
+       int             i_err;
+       size_t  sz_len;
+       char    *pstr_pathtemp;
+       char    *pstr_nowpath;
+       char    *pstr_nowpos;
+       
+       // alloc & copy pstr_pathlist -> pstr_pathtemp ---
+       sz_len  = strlen( pstr_pathlist );
+       pstr_pathtemp   = (char *)alloca( sz_len + 1 );
+       strncpy( pstr_pathtemp, pstr_pathlist, sz_len + 1 );
+
+       i_result                = -0x01;
+       i_flag                  = 0x00;
+       pstr_nowpath    = pstr_pathtemp;
+       pstr_nowpos             = pstr_pathtemp;
+       do{
+               if(( ':' == *pstr_nowpos ) || ( '\0' == *pstr_nowpos))  {
+                       if( '\0' == *pstr_nowpos )      { i_flag        = 0x01; }
+                       else                                            { *pstr_nowpos  = '\0'; }
+
+                       i_err   = SearchLib_IsExistLibrary( pstr_nowpath, pstr_solibname );
+                       if( 0x00 == i_err )     {
+                               i_result        = 0x00;
+                               strncpy( pstr_solibpath, pstr_nowpath, DRD64_MAX_PATH );
+                               goto goto_SearchLib_SearchLibInPathArrays_post;
+                       }       
+                       
+                       if( 0x00 == i_flag )    { *pstr_nowpos  = ':'; }
+                       
+                       pstr_nowpath    = pstr_nowpos + 1;
+               }
+       
+       }while( '\0' != *pstr_nowpos++ );
+
+goto_SearchLib_SearchLibInPathArrays_post:
+       return i_result;
+}
+
+
 /***********************************************************************
 int LibBrownie_GetLibraryPath(
        char    *pstr_solibpath,        [OUT] .so existed Library FullPath 
        char    *pstr_solibname,        [IN] .so Library Filename
-       char    *pstr_rpath,            [IN] rpath string from .dynamic seciton
+       char    *pstr_dt_rpath,         [IN] RPATH string from .dynamic seciton
+       char    *pstr_dt_runpath,       [IN] RUNPATH string from .dynamic seciton
        char    *pstr_ldsohints         [IN] LD_LIBRARYPATH env string.
 )
 
@@ -94,15 +145,13 @@ int
        LibBrownie_GetLibraryPath(
                        char    *pstr_solibpath, 
                        char    *pstr_solibname,
-                       char    *pstr_rpath,
+                       char    *pstr_dt_rpath,
+                       char    *pstr_dt_runpath,
+                       char    *pstr_env_ldlibpath,
                        char    *pstr_ldsohints )
 {
-       int             i_result;
-       int             i_flag;
-       size_t  sz_len;
-       char    *pstr_hintslist;
-       char    *pstr_nowpath;
-       char    *pstr_nowpos;
+       int             i_err;
+       int             i_result        = 0x00;
 
        if( NULL == pstr_solibpath )    {
                return -0x01;
@@ -112,54 +161,63 @@ int
                return -0x02;
        }
 
-       // LocalLibrary ( rpath in .dynamic section)
-       if( NULL != pstr_rpath )        {
-               if( '\0' != *pstr_rpath )       {
-                       i_result        = LibBrownie_SearchLib_IsExistLibrary( pstr_rpath, pstr_solibname );
-                       if( 0x00 == i_result )  {
-                               pstr_nowpath    = pstr_rpath;
-                               goto goto_LibBrownie_GetLibraryPath_setting;
-                       }
+       // <Order Info from man ld.so>------------------------------------------ 
+       //   1. DT_RPATH of the referencing object unless that object also
+       //      contains a DT_RUNPATH tag
+       //   2. DT_RPATH of the program unless the referencing object contains
+       //      a DT_RUNPATH tag
+       if( NULL != pstr_dt_rpath )     {
+               // XXX: pstr_dt_runpath != NULL for WARNING!!
+               i_err   = SearchLib_SearchLibInPathArrays(
+                                                       pstr_solibpath, pstr_dt_rpath, pstr_solibname );
+               if( 0x00 == i_err )     {
+                       i_result        = 0x01;
+                       goto goto_LibBrownie_GetLibraryPath_post;
                }
        }
 
-       // System Library ( in /usr/lib | /usr/local/lib | ... )
-       //   Get from LD_LIBRARYPATH dir.
-       sz_len  = strlen( pstr_ldsohints );
-       pstr_hintslist  = (char *)alloca( sz_len + 1 );
-       if( NULL == pstr_hintslist )    {
-               return -0x03;
+       // <Order Info from man ld.so>------------------------------------------ 
+       // 3.   Path indicated by LD_LIBRARY_PATH environment variable
+       if( NULL != pstr_env_ldlibpath )        {
+               i_err   = SearchLib_SearchLibInPathArrays(
+                                                       pstr_solibpath, pstr_env_ldlibpath, pstr_solibname );
+               if( 0x00 == i_err )     {
+                       i_result        = 0x03;
+                       goto goto_LibBrownie_GetLibraryPath_post;
+               }
+       }
+       
+       // <Order Info from man ld.so>------------------------------------------ 
+       // 4.   DT_RUNPATH of the referencing object
+       if( NULL != pstr_dt_runpath )   {
+               i_err   = SearchLib_SearchLibInPathArrays(
+                                                       pstr_solibpath, pstr_dt_runpath, pstr_solibname );
+               if( 0x00 == i_err )     {
+                       i_result        = 0x04;
+                       goto goto_LibBrownie_GetLibraryPath_post;
+               }
        }
 
-       strncpy( pstr_hintslist, pstr_ldsohints, sz_len + 1 );
+       // <Order Info from man ld.so>------------------------------------------ 
+       // 5.   Hints file produced by the ldconfig(8) utility
+       i_err   = SearchLib_SearchLibInPathArrays(
+                                                       pstr_solibpath, pstr_ldsohints, pstr_solibname );
+       if( 0x00 == i_err )     {
+               i_result        = 0x05;
+               goto goto_LibBrownie_GetLibraryPath_post;
+       }
 
-       i_flag                  = 0x00;
-       pstr_nowpath    = pstr_hintslist;
-       pstr_nowpos             = pstr_hintslist;
-       do{
-               if(( ':' == *pstr_nowpos ) || ( '\0' == *pstr_nowpos))  {
-                       if( '\0' == *pstr_nowpos )      { i_flag        = 0x01; }
-                       else                                            { *pstr_nowpos  = '\0'; }
-                       i_result        = LibBrownie_SearchLib_IsExistLibrary( pstr_nowpath, pstr_solibname );
-                       if( 0x00 == i_result )  {
-                               goto goto_LibBrownie_GetLibraryPath_setting;
-                       }       
-                       
-                       if( 0x00 != i_flag )    {
-                               return -0x04;
-                       }
-                       else
-                               { *pstr_nowpos  = ':'; }
-                       
-                       pstr_nowpath    = pstr_nowpos + 1;
-               }
-       
-       }while( '\0' != *pstr_nowpos++ );
+       // 6.   The /lib and /usr/lib directories, unless the referencing
+       //      object was linked using the "-z nodefaultlib" option
+       i_err   = SearchLib_SearchLibInPathArrays(
+                                                       pstr_solibpath, "/lib:/usr/lib", pstr_solibname );
+       if( 0x00 == i_err )     {
+               i_result        = 0x06;
+       }
 
-goto_LibBrownie_GetLibraryPath_setting:
-       strncpy( pstr_solibpath, pstr_nowpath, DRD64_MAX_PATH );
+goto_LibBrownie_GetLibraryPath_post:
 
-       return 0x00;
+       return i_result;
 }
 
                
index 5cce9ef..06aa2a6 100644 (file)
@@ -43,6 +43,8 @@ Comment:
        #define LIBBROWNIE_SEARCHLIB_EXTERN             extern
 #endif
 
+#define        LIBBROWNIE_SEARCHLIB_ENV_LDLIBPATH      "LD_LIBRARY_PATH"
+
 
 
 #endif /* DRD64_HEADER_XXX */
index 34f1b7a..5c02a72 100644 (file)
@@ -39,39 +39,90 @@ Comment:
 #include"drd64_libbrownie.h"
 
 /*----------------------------------------------------------------------
+1/2.RPATH 
 ----------------------------------------------------------------------*/
-void Test_LibBrownie_SearchLib_test00_001_sub(int i_testid, char *pstr_solibname)
+void Test_LibBrownie_SearchLib_test01_sub(
+               int i_testid, char *pstr_env_ldlibpath, char *pstr_ldhints, char *pstr_solibname)
 {
        int             i_result;
-       char    *pstr_result;
        char    str_resolvpath[DRD64_MAX_PATH];
        
-       pstr_result     = LibBrownie_GetLoadLibraryPath( LIBBROWNIE_LDHINTS_ELF64 );
-       CU_ASSERT( NULL != pstr_result );
 
        i_result        = LibBrownie_GetLibraryPath(
-                                               str_resolvpath, pstr_solibname, NULL, pstr_result );
-       CU_ASSERT( 0x00 == i_result );
-       printf(" SearchLib Test%03d: %s\n", i_testid, str_resolvpath );
+                                               str_resolvpath, pstr_solibname, ".:..:../testdata", NULL,
+                                               pstr_env_ldlibpath, pstr_ldhints );
+       CU_ASSERT( 0x00 < i_result );
+
+       printf(" SearchLib Test1%02d: %s [%d]\n", i_testid, str_resolvpath, i_result );
 
        return;
 }
 
 /*----------------------------------------------------------------------
+4.RUNPATH 
 ----------------------------------------------------------------------*/
-void Test_LibBrownie_SearchLib_test00_001(void)
+void Test_LibBrownie_SearchLib_test04_sub(
+               int i_testid, char *pstr_env_ldlibpath, char *pstr_ldhints, char *pstr_solibname)
 {
        int             i_result;
-       char    *pstr_result;
        char    str_resolvpath[DRD64_MAX_PATH];
        
+
+       i_result        = LibBrownie_GetLibraryPath(
+                                               str_resolvpath, pstr_solibname, NULL, ".:..:../testdata", 
+                                               pstr_env_ldlibpath, pstr_ldhints );
+       CU_ASSERT( 0x00 < i_result );
+
+       printf(" SearchLib Test4%02d: %s [%d]\n", i_testid, str_resolvpath, i_result );
+
+       return;
+}
+
+/*----------------------------------------------------------------------
+LDHINTS files
+----------------------------------------------------------------------*/
+void Test_LibBrownie_SearchLib_test05_sub(
+               int i_testid, char *pstr_env_ldlibpath, char *pstr_ldhints, char *pstr_solibname)
+{
+       int             i_result;
+       char    str_resolvpath[DRD64_MAX_PATH];
+       
+
+       i_result        = LibBrownie_GetLibraryPath(
+                                               str_resolvpath, pstr_solibname, NULL, NULL,
+                                               pstr_env_ldlibpath, pstr_ldhints );
+       CU_ASSERT( 0x00 < i_result );
+
+       printf(" SearchLib Test5%02d: %s [%d]\n", i_testid, str_resolvpath, i_result );
+
+       return;
+}
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+void Test_LibBrownie_SearchLib_test00_001(void)
+{
+       int             i_result;
+       char    *pstr_ldhints;
+       char    *pstr_env_ldlibpath;
+
+       pstr_ldhints    = LibBrownie_GetLoadLibraryPath( LIBBROWNIE_LDHINTS_ELF64 );
+       CU_ASSERT( NULL != pstr_ldhints );
+
+       pstr_env_ldlibpath      = getenv( LIBBROWNIE_SEARCHLIB_ENV_LDLIBPATH );
+       
        i_result        = LibBrownie_Init();
        CU_ASSERT( i_result == 0x00 );
 
-       Test_LibBrownie_SearchLib_test00_001_sub( 1, "libc.so.7" );
-       Test_LibBrownie_SearchLib_test00_001_sub( 2, "libbz2.so.4" );
-       Test_LibBrownie_SearchLib_test00_001_sub( 3, "libX11.so.6" );
-       Test_LibBrownie_SearchLib_test00_001_sub( 4, "libLTO.so" );
+       Test_LibBrownie_SearchLib_test01_sub( 1, pstr_env_ldlibpath, pstr_ldhints, "libsotest.so" );
+
+       Test_LibBrownie_SearchLib_test04_sub( 1, pstr_env_ldlibpath, pstr_ldhints, "libsonodbg.so" );
+
+       Test_LibBrownie_SearchLib_test05_sub( 1, pstr_env_ldlibpath, pstr_ldhints, "libc.so.7" );
+       Test_LibBrownie_SearchLib_test05_sub( 2, pstr_env_ldlibpath, pstr_ldhints, "libbz2.so.4" );
+       Test_LibBrownie_SearchLib_test05_sub( 3, pstr_env_ldlibpath, pstr_ldhints, "libX11.so.6" );
+       Test_LibBrownie_SearchLib_test05_sub( 4, pstr_env_ldlibpath, pstr_ldhints, "libLTO.so" );
+
 
        LibBrownie_FreeLoadLibraryPath( LIBBROWNIE_LDHINTS_ELF64 );
 
index a94d8ca..d81d519 100644 (file)
@@ -66,11 +66,11 @@ void Test_LibGoblin_LoadProg_API_LoadProgram_test00_001( void )
                                                                                        "../testdata/dwarftest" );
        CU_ASSERT( 0x00 == i_result );
 
-
        while( 0x00 < LibGoblin_GetUnresolv_ObjectFilePath( i_pgid, &t_objpath ) )      {
                i_result        = LibBrownie_GetLibraryPath(
                                                        t_objpath.str_localpath,
                                                        t_objpath.str_filename, t_objpath.str_rpath, pstr_ldpath );
+
                CU_ASSERT( 0x00 == i_result );
                if( 0x00 != i_result )
                        { goto  goto_Test_LibGoblin_LoadProg_API_LoadProgram_test00_001_post; }