Перейти к содержанию
    

Скрипт линкера для gcc

В процессе изучения документации линкера для 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
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точнее, почему после .text стоит '*'.
Потому что при компиляции с опцией -ffunction-sections каждая функция попадет в отдельный сегмент .text.имя_функции и это позволит линкеру по опции --gc-sections выкинуть секции, на которые нет ссылок. Т.е. выкинуть неиспользуемые функции. А '*' в .text*указывает как раз на все секции, имя которых начинается с .text Аналогично для неиспользуемых переменных - ключ компилятора -fdata-sections

2 Что означает *(vtable)? Я конечно подозреваю, что это как-то связано с таблицей виртуальных функций, но хотелось бы уточнить.
Да, вроде как она. Во всяком случае когда линкер не может ее построить (не все функции определены), он ругается именно на vtable. Хотя(!) использую виртуальные функции, а секции vtable нет ни в моих скриптах, ни в map-файле. Судя по .map таблицы виртуальных функций попадают в секции .rodata*

 

 

P.S. Скрипт не совсем удачный. Работать он будет, но написан не совсем... прямо.

сравните (обратите внимание на 'AT'):

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) }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть запись

.data : /* place init values immediatly after .text section */

{

_data = .;

*(.ramfunc*)

 

*(.data*)

 

_edata = .;

_data_image = LOADADDR(.data);

 

PROVIDE (edata = .);

} > RAM AT > ROM

размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в
_etext = .;
Я правильно понял?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть запись размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в Я правильно понял?
Почти. Только размещается она в RAM (т.е. там резервируется память и туда указывают ссылки), а ее начальные значения помещаются в ROM. Аналогично и с векторами.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...