Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Скрипт линкера для gcc
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Lyrri
В процессе изучения документации линкера для 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
}

Сергей Борщ
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) }
}
Lyrri
То есть запись
Цитата
.data : /* place init values immediatly after .text section */
{
_data = .;
*(.ramfunc*)

*(.data*)

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

PROVIDE (edata = .);
} > RAM AT > ROM
размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в
Цитата
_etext = .;
Я правильно понял?
Сергей Борщ
QUOTE (Lyrri @ May 31 2011, 09:11) *
То есть запись размещает секцию .data в ROM (для хранения) исходя из значения счетчика позиций. А счетчик позиций перед размещением (в данном примере) содержит значение, которое также хранится в Я правильно понял?
Почти. Только размещается она в RAM (т.е. там резервируется память и туда указывают ссылки), а ее начальные значения помещаются в ROM. Аналогично и с векторами.
Lyrri
Спасибо. Теперь все встало на свои места.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.