флаги доступа - PullRequest
       11

флаги доступа

1 голос
/ 26 марта 2012

Я нахожусь внутри общего объекта (кода), загруженного с помощью dlopen. Я хочу знать флаги, заданные для вызова загрузки. У меня нет доступа к загрузчику (коду) - например, это может быть интерпретатор сценария, но я должен создать последующие вызовы dlopen с теми же флагами

Как я могу это сделать?

Ответы [ 2 ]

3 голосов
/ 07 июня 2014

Вы можете использовать следующую библиотеку вместо отладчика:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

typedef void *(*orig_dlopen_type)(const char *file, int mode);

void *dlopen(const char *file, int mode)
{
    fprintf(stderr, "dlopen called (mode: %d) on %s\n", mode, file);
    orig_dlopen_type orig_dlopen;
    orig_dlopen = (orig_dlopen_type)dlsym(RTLD_NEXT, "dlopen");
    return orig_dlopen(file, mode);
}

Компилировать с gcc -shared -fPIC dlopen_trace.c -o dlopen_trace.so -ldl

Затем выполнить вашу программу как обычно с LD_PRELOAD=dlopen_trace.so.Вы должны печатать строку отладки каждый раз, когда вызывается dlopen.

Если вы хотите, вы также можете изменить флаги на маршруте ...

0 голосов
/ 26 марта 2012

Я думаю, что это невозможно без помощи отладчиков.

Из последнего glibc-кода , вот исходный код dlopen

void *
dlopen (const char *file, int mode)
{
  return __dlopen (file, mode, RETURN_ADDRESS (0));
}

И __dlopen, в свою очередь, определяется как

void *
__dlopen (const char *file, int mode DL_CALLER_DECL)
{
# ifdef SHARED
  if (__builtin_expect (_dlfcn_hook != NULL, 0))
    return _dlfcn_hook->dlopen (file, mode, DL_CALLER);
# endif

  struct dlopen_args args;
  args.file = file;
  args.mode = mode;
  args.caller = DL_CALLER;

# ifdef SHARED
  return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
# else
  if (_dlerror_run (dlopen_doit, &args))
    return NULL;

  __libc_register_dl_open_hook ((struct link_map *) args.new);
  __libc_register_dlfcn_hook ((struct link_map *) args.new);

  return args.new;
# endif
}

Флаги, которые вы ищете, RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL и RTLD_LOCAL имеют ИЛИ и хранятся в переменной mode,Как вы можете видеть, нет никакого пути, по которому он передается обратно или что-то в этом роде.

РЕДАКТИРОВАТЬ : Кажется, что действительно существует способ достичь того, чего вы хотите, как показано другимответ.Если вы не можете принять мой ответ, я могу удалить его, чтобы помочь будущим посетителям

...