реклама на сайте
подробности

 
 
> undefined reference to `_init', cortex-m3, GCC, newlib, ошибка линкера
id_soft
сообщение Mar 17 2011, 12:15
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 28-07-05
Пользователь №: 7 168



Пытаюсь собрать пустой проект для sam3s. Линковщик ругается на неверную ссылку на функцию _init, которая, в свою очередь, вызывается из __libc_init_array(). cstartup.c взял из softpack от Atmel.
Что это за функция _init()? Кто ее должен реализовывать и для чего она нужна?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
klen
сообщение Mar 17 2011, 20:34
Сообщение #2


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(id_soft @ Mar 17 2011, 15:15) *
Пытаюсь собрать пустой проект для 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++ кода вы сможете обнаружить что не создаются глобальные объекты - как уже наверно понятно, некому будет вызвать их конструкторы.
Go to the top of the page
 
+Quote Post
id_soft
сообщение Mar 18 2011, 12:14
Сообщение #3





Группа: Новичок
Сообщений: 8
Регистрация: 28-07-05
Пользователь №: 7 168



Спасибо за помощь. Проект собрался без ошибок. Буду пробовать в железе.
Go to the top of the page
 
+Quote Post
Злодей
сообщение Jun 1 2011, 18:48
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Спасибо!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 06:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01389 секунд с 7
ELECTRONIX ©2004-2016