Skip to content

Instantly share code, notes, and snippets.

@eldesh
Created November 18, 2015 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eldesh/aa44c1b7aeed3d11523c to your computer and use it in GitHub Desktop.
Save eldesh/aa44c1b7aeed3d11523c to your computer and use it in GitHub Desktop.
実行した環境で、指定された名前で共有ライブラリがリンクされるとどのパスのライブラリがリンクされるかを標準出力に書き出す。
/**
* 動的リンクされたライブラリのパスを表示する
*
* **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