Как запустить конструктор, даже если определена опция -nostdlib - PullRequest
3 голосов
/ 21 января 2011

У меня есть динамическая библиотека, которая содержит конструктор.

__attribute__ ((constructor))
void construct() {
    // This is initialization code
}

Библиотека скомпилирована с параметром -nostdlib, и я не могу это изменить.В результате в библиотеке нет разделов .ctor и .dtor, а конструктор не загружается при загрузке библиотеки.

Как написано там должны быть специальные меры, позволяющие запускатьконструктор даже в этом случае.Не могли бы вы дать мне совет, что и как это можно сделать?

Ответы [ 3 ]

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

На некоторых платформах создаются секции .init_array/.fini_array для включения всех глобальных конструкторов / деструкторов.Вы можете использовать это.

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

Хм пропустил ту часть, где нет разделов .ctor и .dtor ... забудь об этом.

#include <stdio.h>
#include <stdint.h>

typedef void (*func)(void);

__attribute__((constructor))
void func1(void) {
     printf("func1\n");
}

__attribute__((constructor))
void func2(void) {
     printf("func2\n");
}

extern func* __init_array_start;

int main(int argc, char **argv)
{
     func *funcarr = (func*)&__init_array_start;
     func f;
     int idx;

     printf("start %p\n", *funcarr);

     // iterate over the array
     for (idx = 0; ; ++idx) {
          f = funcarr[idx];

          // skip the end of array marker (0xFFFFFFFF) on 64 bit it's twice as long ;)
          if (f == (void*)~0)
               continue;

          // till f is NULL which indicates the start of the array
          if (f == NULL)
               break;

          printf("constructor %p\n", *f);
          f();
     }

     return 0;
}

Что дает:

Compilation started at Fri Mar  9 09:28:29

make test && ./test
 cc     test.c   -o test
 func2
 func1
 start 0xffffffff
 constructor 0x80483f4
 func1
 constructor 0x8048408
 func2

Возможно, вам нужно поменяться местамипродолжить и прервать, если вы работаете в системе Big Endian, но я не совсем уверен.

Но точно так же, как в случае с R .. использование статических конструкторов в библиотеках не очень приятно для разработчиков, использующих вашу библиотеку:р

0 голосов
/ 21 января 2011

Зачем вам конструкторы? Большинство программистов, с которыми я работаю, включая меня, отказываются использовать библиотеки с глобальными конструкторами, потому что слишком часто они вносят ошибки, путая исходное состояние программы при вводе main. Один конкретный пример, который я могу вспомнить, это OpenAL, который ломал программы, когда он был просто связан, даже если он никогда не вызывался. Я не был тем в проекте, который имел дело с этой ошибкой, но если я не ошибаюсь, это как-то связано со взломом ALSA и прекращением использования ALSA основной программой позже.

Если ваша библиотека имеет нетривиальное глобальное состояние, вместо этого посмотрите, можете ли вы просто использовать глобальные структуры и инициализаторы. Возможно, вам придется добавить флаги с некоторыми указателями, чтобы указать, указывают ли они на выделенную память или статическую память. Другой метод - отложить инициализацию до первого вызова, но это может вызвать проблемы с безопасностью потока, если вы не используете pthread_once или аналогичный.

...