Created
November 18, 2015 11:19
-
-
Save eldesh/aa44c1b7aeed3d11523c to your computer and use it in GitHub Desktop.
実行した環境で、指定された名前で共有ライブラリがリンクされるとどのパスのライブラリがリンクされるかを標準出力に書き出す。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 動的リンクされたライブラリのパスを表示する | |
* | |
* **Linux specific program** | |
* | |
* build: | |
* $ gcc -Wall -pedantic-errors -std=c99 -DNDEBUG -o sopath sopath.c -ldl | |
*/ | |
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <link.h> | |
#include <dlfcn.h> | |
#include <libgen.h> // use POSIX version basename | |
typedef struct dl_phdr_info dl_phdr_info; | |
/** | |
* 渡した文字列を破壊しない basename | |
*/ | |
char * normal_dirname (char const * path) { | |
char * p = strdup(path); | |
char * base = strdup(basename(p)); | |
free(p); | |
return base; | |
} | |
enum { | |
NOTFOUND_LIB = 0, | |
FOUND_LIB | |
}; | |
/** | |
* @param info 共有オブジェクトの情報 | |
* @param size infoのサイズ | |
* @param data dl_iterate_phdr の第2引数に渡された値 | |
* @ret dl_iterate_phdr の返り値. 0 を返す場合は dl_iterate_phdr がその場で終了する. | |
*/ | |
static int | |
find_solib (dl_phdr_info * info, size_t size, void * data) { | |
#if !defined NDEBUG | |
printf("name=%s (%d segments)\n" | |
, info->dlpi_name, info->dlpi_phnum); | |
#endif | |
char const * libname = data; | |
char * base = normal_dirname(info->dlpi_name); | |
if (!strcmp(base, libname)) { // found lib | |
free(base); | |
printf("%s\n", info->dlpi_name); | |
return FOUND_LIB; | |
} | |
free(base); | |
base = NULL; | |
#if !defined NDEBUG | |
for (int i=0; i<info->dlpi_phnum; ++i) { | |
printf("\t\t header %2d: address=%10p\n" | |
, i, (void*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr)); | |
} | |
#endif | |
return NOTFOUND_LIB; | |
} | |
static void | |
usage (char const * prog) { | |
printf("usage: %s library\n", prog); | |
printf("\tlibrary\tthe name of the shared library\n"); | |
} | |
int main (int argc, char * argv[]) { | |
if (argc != 2) { | |
usage(argv[0]); | |
return EXIT_FAILURE; | |
} | |
void * lib = dlopen(argv[1], RTLD_LAZY); | |
if (!lib) { | |
fprintf(stderr, "fail: dlopen %s\n", dlerror()); | |
return EXIT_FAILURE; | |
} | |
if (FOUND_LIB == dl_iterate_phdr(find_solib, argv[1])) { | |
// printf("found %s\n", argv[1]); | |
return EXIT_SUCCESS; | |
} | |
return EXIT_FAILURE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment