Jump to content

    
Sign in to follow this  
id_soft

undefined reference to `_init'

Recommended Posts

Пытаюсь собрать пустой проект для sam3s. Линковщик ругается на неверную ссылку на функцию _init, которая, в свою очередь, вызывается из __libc_init_array(). cstartup.c взял из softpack от Atmel.

Что это за функция _init()? Кто ее должен реализовывать и для чего она нужна?

Share this post


Link to post
Share on other sites
Пытаюсь собрать пустой проект для sam3s. Линковщик ругается на неверную ссылку на функцию _init, которая, в свою очередь, вызывается из __libc_init_array(). cstartup.c взял из softpack от Atmel.

Что это за функция _init()? Кто ее должен реализовывать и для чего она нужна?

 

это не ошибка. у вас нормальная полная реализация CRT кода по стандарту.

работает это так:

1 в crt имеется конструкция вида

 
....
extern void __libc_init_array(void);
  __libc_init_array();
....

2. в скрипте линкера должны быть определены подсекции

                            _image_start_  = .;
        _vec_start_ = .;
        KEEP(*(.flash_vec_table*))
        _vec_end_ = ALIGN( . , 8);
        
        _text_start_ = _vec_end_;[b]
        /* вызов статических конструкторов */
        __preinit_array_start = .;
        KEEP(*(.preinit_array*))
        __preinit_array_end = .;
        __init_array_start  = .;
        KEEP(*(.init_array*))
        __init_array_end    = .;[/b]
        
        *(.text)
        *(.text*)                        /*

это говорит линкеру куда складывать указатели функции помеченные атрибутами как конструкторы. получается вектор угазателей по адресу __init_array_start

3. при выполнении кода CRT вызывается __libc_init_array(), в newlib она определяется так :

/* These magic symbols are provided by the linker.  */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));

extern void _init (void);
extern void _fini (void);
[b]
/* Iterate over all the init routines.  */
void
__libc_init_array (void)
{
  size_t count;
  size_t i;

  count = __preinit_array_end - __preinit_array_start;
  for (i = 0; i < count; i++)
    __preinit_array_start[i] ();

  _init ();

  count = __init_array_end - __init_array_start;
  for (i = 0; i < count; i++)
    __init_array_start[i] ();
}
[/b]
/* Run all the cleanup routines.  */
void
__libc_fini_array (void)
{
  size_t count;
  size_t i;
  
  count = __fini_array_end - __fini_array_start;
  for (i = count; i > 0; i--)
    __fini_array_start[i-1] ();

  _fini ();
}

 

видно что она идет по алресам и вызывет поочереди все фукции из ветрора "preinit" . далее далее вызывает _init () - эта функция должна быть определена пользователем если нада вмешатся в инииализацию. после нее вызываются конструкторы из вектора "init" - соственно сюда линкер складывает все функции с атрибутом __attribute__((constructor))

 

 

4. обычно в коде libc _init определена как "слабосвязанная" заглушка

void __attribute__ ((weak)) _init(void)  {}

но в newlib почемуто отсутствует. я добавил это в свой crt код.

 

теперь она не будет бкспокоить ликер - тело определено (пустое).

 

5. Самое последнее что обычно влияет на пользователя - Вы определеяет свою версию _init и Ваша реализация подменяется компиллером вместо заглушки. иначе вы ничего не видите и неподозреваете про нее и линкет ставит заглушку.

 

 

ps. если вышеприведенная хренатень не будет работать, то в случае компиляции C++ кода вы сможете обнаружить что не создаются глобальные объекты - как уже наверно понятно, некому будет вызвать их конструкторы.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this