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

 
 
 
Reply to this topicStart new topic
> Скрипт линкера для gcc, Непонятные моменты
Lyrri
сообщение May 30 2011, 20:32
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 15-01-11
Из: Киев
Пользователь №: 62 244



В процессе изучения документации линкера для CodeSourcery G++ Lite и примеров скриптов возникли следующие вопросы:

1 Что означает запись *(.text*)? Точнее, почему после .text стоит '*'. Вот пример записи входной секции из документации:
Цитата
For example, to include all input ‘.text’ sections, you would write: *(.text) (стр. 50 3.6.4.1 Input Section Basics ).

2 Что означает *(vtable)? Я конечно подозреваю, что это как-то связано с таблицей виртуальных функций, но хотелось бы уточнить.

Скрипт линкера взят из примеров для LM3S6965 Evaluation Board.
Собственно, сам скрипт линкера:
Код
MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        *(.text*)                  /*Почему в конце '*' ?*/
        *(.rodata*)
        _etext = .;
    } > FLASH
    .data : AT(ADDR(.text) + SIZEOF(.text))
    {
        _data = .;
        *(vtable)                 /*Что и зачем это?*/
        *(.data*)
        _edata = .;
    } > SRAM
    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > SRAM
}

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 30 2011, 21:01
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Lyrri @ May 30 2011, 23:32) *
Точнее, почему после .text стоит '*'.
Потому что при компиляции с опцией -ffunction-sections каждая функция попадет в отдельный сегмент .text.имя_функции и это позволит линкеру по опции --gc-sections выкинуть секции, на которые нет ссылок. Т.е. выкинуть неиспользуемые функции. А '*' в .text*указывает как раз на все секции, имя которых начинается с .text Аналогично для неиспользуемых переменных - ключ компилятора -fdata-sections
QUOTE (Lyrri @ May 30 2011, 23:32) *
2 Что означает *(vtable)? Я конечно подозреваю, что это как-то связано с таблицей виртуальных функций, но хотелось бы уточнить.
Да, вроде как она. Во всяком случае когда линкер не может ее построить (не все функции определены), он ругается именно на vtable. Хотя(!) использую виртуальные функции, а секции vtable нет ни в моих скриптах, ни в map-файле. Судя по .map таблицы виртуальных функций попадают в секции .rodata*


P.S. Скрипт не совсем удачный. Работать он будет, но написан не совсем... прямо.
сравните (обратите внимание на 'AT'):
CODE
ENTRY(_start)
IRQ_STACK_SIZE = 0x100;
SYS_STACK_SIZE = 0x200;

/* memory layout */
MEMORY
{
  ROM (rx)      : ORIGIN = 0x00100000, LENGTH = 64K
  RAM (rwx)     : ORIGIN = 0x00200000, LENGTH = 0x00004000
  REMAPPED (rwx): ORIGIN = 0x00000000, LENGTH = LENGTH(RAM)
}

SECTIONS
{
  .vectors :
  {
    KEEP(*(.vectors))
  } > REMAPPED AT > ROM
  
  /* first section is .text which is used for code */
  .text :
  {
    __ctors_start = .;
    KEEP(SORT(*)(.ctors))
    KEEP(SORT(*)(.init_array))
    
     __ctors_end = .;
     __dtors_start = .;
    KEEP(SORT(*)(.dtors))
     __dtors_end = .;

    . = ALIGN(4);

    *(.text*)            /* code */

    *(.rodata)          /* read-only data (constants) */
    *(.rodata*)

    *(.glue_7)
    *(.glue_7t)
  } > ROM

  . = ALIGN(4);
  _etext = .;

  /* .data section which is used for initialized data */
  .data : /* place init values immediatly after .text section */
  {
    _data = .;
    *(.ramfunc*)
    
    *(.data*)

    _edata = .;
    _data_image = LOADADDR(.data);

    PROVIDE (edata = .);
  } > RAM  AT > ROM

  . = ALIGN(4);

  /* .bss section which is used for uninitialized data */
  .bss: (NOLOAD) :
  {
    __bss_start = .;
    __bss_start__ = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } > RAM

  . = ALIGN(4);
  PROVIDE (__bss_end = .);

  .noinit (NOLOAD) :
  {
     PROVIDE (__noinit_start = .);
    *(.noinit*)
     PROVIDE (__noinit_end = .);
     _end = .;
     PROVIDE (__heap_start = .);
  } > RAM

  .stack :
  {
    . = ALIGN(4);
    . += SYS_STACK_SIZE;
    PROVIDE (__stack = .);
    . += IRQ_STACK_SIZE;
    PROVIDE (__stack_irq = .);
    /*  allocate stacks if needed */
    PROVIDE (__stack_fiq = .);
    PROVIDE (__stack_und = .);
    PROVIDE (__stack_abort = .);
    PROVIDE (__stack_svc = .);
    
  } > RAM

  _end = .;
  PROVIDE (end = .);

  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Lyrri
сообщение May 31 2011, 06:11
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 15-01-11
Из: Киев
Пользователь №: 62 244



То есть запись
Цитата
.data : /* place init values immediatly after .text section */
{
_data = .;
*(.ramfunc*)

*(.data*)

_edata = .;
_data_image = LOADADDR(.data);

PROVIDE (edata = .);
} > RAM AT > ROM
размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в
Цитата
_etext = .;
Я правильно понял?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 31 2011, 06:33
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Lyrri @ May 31 2011, 09:11) *
То есть запись размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в Я правильно понял?
Почти. Только размещается она в RAM (т.е. там резервируется память и туда указывают ссылки), а ее начальные значения помещаются в ROM. Аналогично и с векторами.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Lyrri
сообщение May 31 2011, 06:47
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 15-01-11
Из: Киев
Пользователь №: 62 244



Спасибо. Теперь все встало на свои места.
Go to the top of the page
 
+Quote Post

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

 


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


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