应用程序——链接脚本

来源:互联网 发布:macbook rar解压软件 编辑:程序博客网 时间:2024/06/14 03:39

1.序

应用程序也可以像内核一样按照一定规则的组织模块。通过链接脚本就可以做到。

2.查看默认链接脚本

没有链接脚本,程序也是不知道如何在内存当中进行组织的。只不过一般情况下,做应用的程序员不
需要关心而已。

leon@netview:~$ leon@netview:~$ ld --verboseGNU ld (GNU Binutils for Ubuntu) 2.24  Supported emulations:   elf_i386   i386linux   elf32_x86_64   elf_x86_64   elf_l1om   elf_k1om   i386pep   i386peusing internal linker script:==================================================/* Script for -z combreloc: combine and sort reloc sections */OUTPUT_FORMAT("elf32-i386", "elf32-i386",              "elf32-i386")OUTPUT_ARCH(i386)ENTRY(_start)SEARCH_DIR("/usr/i686-linux-gnu/lib32"); SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"); SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib");SECTIONS{  /* Read-only sections, merged into text segment: */  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;  .interp         : { *(.interp) }  .note.gnu.build-id : { *(.note.gnu.build-id) }  .hash           : { *(.hash) }  .gnu.hash       : { *(.gnu.hash) }  .dynsym         : { *(.dynsym) }  .dynstr         : { *(.dynstr) }  .gnu.version    : { *(.gnu.version) }  .gnu.version_d  : { *(.gnu.version_d) }  .gnu.version_r  : { *(.gnu.version_r) }  .rel.dyn        :    {      *(.rel.init)      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)      *(.rel.fini)      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)      *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)      *(.rel.ctors)      *(.rel.dtors)      *(.rel.got)      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)      *(.rel.ifunc)    }  .rel.plt        :    {      *(.rel.plt)      PROVIDE_HIDDEN (__rel_iplt_start = .);      *(.rel.iplt)      PROVIDE_HIDDEN (__rel_iplt_end = .);    }  .init           :  {    KEEP (*(SORT_NONE(.init)))  }  .plt            : { *(.plt) *(.iplt) }  .text           :  {    *(.text.unlikely .text.*_unlikely .text.unlikely.*)    *(.text.exit .text.exit.*)    *(.text.startup .text.startup.*)    *(.text.hot .text.hot.*)    *(.text .stub .text.* .gnu.linkonce.t.*)    /* .gnu.warning sections are handled specially by elf32.em.  */    *(.gnu.warning)  }  .fini           :  {    KEEP (*(SORT_NONE(.fini)))  }  PROVIDE (__etext = .);  PROVIDE (_etext = .);  PROVIDE (etext = .);  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }  .rodata1        : { *(.rodata1) }  .eh_frame_hdr : { *(.eh_frame_hdr) }  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table  .gcc_except_table.*) }  /* These sections are generated by the Sun/Oracle C++ compiler.  */  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges  .exception_ranges*) }  /* Adjust the address for the data segment.  We want to adjust up to     the same address within the page on the next page up.  */  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));  /* Exception handling  */  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }  /* Thread Local Storage sections  */  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }  .preinit_array     :  {    PROVIDE_HIDDEN (__preinit_array_start = .);    KEEP (*(.preinit_array))    PROVIDE_HIDDEN (__preinit_array_end = .);  }  .init_array     :  {    PROVIDE_HIDDEN (__init_array_start = .);    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))    PROVIDE_HIDDEN (__init_array_end = .);  }  .fini_array     :  {    PROVIDE_HIDDEN (__fini_array_start = .);    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))    PROVIDE_HIDDEN (__fini_array_end = .);  }  .ctors          :  {    /* gcc uses crtbegin.o to find the start of       the constructors, so we make sure it is       first.  Because this is a wildcard, it       doesn't matter if the user does not       actually link against crtbegin.o; the       linker won't look for a file to match a       wildcard.  The wildcard also means that it       doesn't matter which directory crtbegin.o       is in.  */    KEEP (*crtbegin.o(.ctors))    KEEP (*crtbegin?.o(.ctors))    /* We don't want to include the .ctor section from       the crtend.o file until after the sorted ctors.       The .ctor section from the crtend file contains the       end of ctors marker and it must be last */    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))    KEEP (*(SORT(.ctors.*)))    KEEP (*(.ctors))  }  .dtors          :  {    KEEP (*crtbegin.o(.dtors))    KEEP (*crtbegin?.o(.dtors))    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))    KEEP (*(SORT(.dtors.*)))    KEEP (*(.dtors))  }  .jcr            : { KEEP (*(.jcr)) }  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }  .dynamic        : { *(.dynamic) }  .got            : { *(.got) *(.igot) }  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 12 ? 12 : 0, .);  .got.plt        : { *(.got.plt)  *(.igot.plt) }  .data           :  {    *(.data .data.* .gnu.linkonce.d.*)    SORT(CONSTRUCTORS)  }  .data1          : { *(.data1) }  _edata = .; PROVIDE (edata = .);  . = .;  __bss_start = .;  .bss            :  {   *(.dynbss)   *(.bss .bss.* .gnu.linkonce.b.*)   *(COMMON)   /* Align here to ensure that the .bss section occupies space up to      _end.  Align after .bss to ensure correct alignment even if the      .bss section disappears because there are no input sections.      FIXME: Why do we need it? When there is no .bss section, we don't      pad the .data section.  */   . = ALIGN(. != 0 ? 32 / 8 : 1);  }  . = ALIGN(32 / 8);  . = SEGMENT_START("ldata-segment", .);  . = ALIGN(32 / 8);  _end = .; PROVIDE (end = .);  . = DATA_SEGMENT_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_line.* .debug_line_end ) }  .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) }  /* DWARF 3 */  .debug_pubtypes 0 : { *(.debug_pubtypes) }  .debug_ranges   0 : { *(.debug_ranges) }  /* DWARF Extension.  */  .debug_macro    0 : { *(.debug_macro) }  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }}==================================================leon@netview:~$ 
leon@netview:~$ leon@netview:~$ arm-linux-ld --verboseGNU ld (Sourcery G++ Lite 2008q3-72) 2.18.50.20080215  Supported emulations:   armelf_linux_eabi   armelfb_linux_eabiusing internal linker script:==================================================/* Script for -z combreloc: combine and sort reloc sections */OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",              "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");SECTIONS{  /* Read-only sections, merged into text segment: */  PROVIDE (__executable_start = 0x00008000); . = 0x00008000 + SIZEOF_HEADERS;  .interp         : { *(.interp) }  .note.gnu.build-id : { *(.note.gnu.build-id) }  .hash           : { *(.hash) }  .gnu.hash       : { *(.gnu.hash) }  .dynsym         : { *(.dynsym) }  .dynstr         : { *(.dynstr) }  .gnu.version    : { *(.gnu.version) }  .gnu.version_d  : { *(.gnu.version_d) }  .gnu.version_r  : { *(.gnu.version_r) }  .rel.dyn        :    {      *(.rel.init)      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)      *(.rel.fini)      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)      *(.rel.ctors)      *(.rel.dtors)      *(.rel.got)      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)    }  .rela.dyn       :    {      *(.rela.init)      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)      *(.rela.fini)      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)      *(.rela.ctors)      *(.rela.dtors)      *(.rela.got)      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)    }  .rel.plt        : { *(.rel.plt) }  .rela.plt       : { *(.rela.plt) }  .init           :  {    KEEP (*(.init))  } =0  .plt            : { *(.plt) }  .text           :  {    *(.text .stub .text.* .gnu.linkonce.t.*)    /* .gnu.warning sections are handled specially by elf32.em.  */    *(.gnu.warning)    *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)  } =0  .fini           :  {    KEEP (*(.fini))  } =0  PROVIDE (__etext = .);  PROVIDE (_etext = .);  PROVIDE (etext = .);  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }  .rodata1        : { *(.rodata1) }  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }   __exidx_start = .;  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }   __exidx_end = .;  .eh_frame_hdr : { *(.eh_frame_hdr) }  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }  /* Adjust the address for the data segment.  We want to adjust up to     the same address within the page on the next page up.  */  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));  /* Exception handling  */  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }  /* Thread Local Storage sections  */  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }  .preinit_array     :  {    PROVIDE_HIDDEN (__preinit_array_start = .);    KEEP (*(.preinit_array))    PROVIDE_HIDDEN (__preinit_array_end = .);  }  .init_array     :  {     PROVIDE_HIDDEN (__init_array_start = .);     KEEP (*(SORT(.init_array.*)))     KEEP (*(.init_array))     PROVIDE_HIDDEN (__init_array_end = .);  }  .fini_array     :  {    PROVIDE_HIDDEN (__fini_array_start = .);    KEEP (*(.fini_array))    KEEP (*(SORT(.fini_array.*)))    PROVIDE_HIDDEN (__fini_array_end = .);  }  .ctors          :  {    /* gcc uses crtbegin.o to find the start of       the constructors, so we make sure it is       first.  Because this is a wildcard, it       doesn't matter if the user does not       actually link against crtbegin.o; the       linker won't look for a file to match a       wildcard.  The wildcard also means that it       doesn't matter which directory crtbegin.o       is in.  */    KEEP (*crtbegin.o(.ctors))    KEEP (*crtbegin?.o(.ctors))    /* We don't want to include the .ctor section from       the crtend.o file until after the sorted ctors.       The .ctor section from the crtend file contains the       end of ctors marker and it must be last */    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))    KEEP (*(SORT(.ctors.*)))    KEEP (*(.ctors))  }  .dtors          :  {    KEEP (*crtbegin.o(.dtors))    KEEP (*crtbegin?.o(.dtors))    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))    KEEP (*(SORT(.dtors.*)))    KEEP (*(.dtors))  }  .jcr            : { KEEP (*(.jcr)) }  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }  .dynamic        : { *(.dynamic) }  . = DATA_SEGMENT_RELRO_END (0, .);  .got            : { *(.got.plt) *(.got) }  .data           :  {    __data_start = . ;    *(.data .data.* .gnu.linkonce.d.*)    SORT(CONSTRUCTORS)  }  .data1          : { *(.data1) }  _edata = .; PROVIDE (edata = .);  __bss_start = .;  __bss_start__ = .;  .bss            :  {   *(.dynbss)   *(.bss .bss.* .gnu.linkonce.b.*)   *(COMMON)   /* Align here to ensure that the .bss section occupies space up to      _end.  Align after .bss to ensure correct alignment even if the      .bss section disappears because there are no input sections.      FIXME: Why do we need it? When there is no .bss section, we don't      pad the .data section.  */   . = ALIGN(. != 0 ? 32 / 8 : 1);  }  _bss_end__ = . ; __bss_end__ = . ;  . = ALIGN(32 / 8);  . = ALIGN(32 / 8);  __end__ = . ;  _end = .; PROVIDE (end = .);  . = DATA_SEGMENT_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) }  /* DWARF 3 */  .debug_pubtypes 0 : { *(.debug_pubtypes) }  .debug_ranges   0 : { *(.debug_ranges) }  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }}==================================================leon@netview:~$ 
leon@netview:~$ arm-hisiv300-linux-ld --verboseGNU ld (Hisilicon_v300) 2.24.0.20131220  Supported emulations:   armelf_linux_eabi   armelfb_linux_eabiusing internal linker script:==================================================/* Script for -z combreloc: combine and sort reloc sections */OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",              "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");SECTIONS{  /* Read-only sections, merged into text segment: */  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x00008000)); . = SEGMENT_START("text-segment", 0x00008000) + SIZEOF_HEADERS;  .interp         : { *(.interp) }  .note.gnu.build-id : { *(.note.gnu.build-id) }  .hash           : { *(.hash) }  .gnu.hash       : { *(.gnu.hash) }  .dynsym         : { *(.dynsym) }  .dynstr         : { *(.dynstr) }  .gnu.version    : { *(.gnu.version) }  .gnu.version_d  : { *(.gnu.version_d) }  .gnu.version_r  : { *(.gnu.version_r) }  .rel.dyn        :    {      *(.rel.init)      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)      *(.rel.fini)      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)      *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)      *(.rel.ctors)      *(.rel.dtors)      *(.rel.got)      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)      PROVIDE_HIDDEN (__rel_iplt_start = .);      *(.rel.iplt)      PROVIDE_HIDDEN (__rel_iplt_end = .);      PROVIDE_HIDDEN (__rela_iplt_start = .);      PROVIDE_HIDDEN (__rela_iplt_end = .);    }  .rela.dyn       :    {      *(.rela.init)      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)      *(.rela.fini)      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)      *(.rela.ctors)      *(.rela.dtors)      *(.rela.got)      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)      PROVIDE_HIDDEN (__rel_iplt_start = .);      PROVIDE_HIDDEN (__rel_iplt_end = .);      PROVIDE_HIDDEN (__rela_iplt_start = .);      *(.rela.iplt)      PROVIDE_HIDDEN (__rela_iplt_end = .);    }  .rel.plt        :    {      *(.rel.plt)    }  .rela.plt       :    {      *(.rela.plt)    }  .init           :  {    KEEP (*(SORT_NONE(.init)))  }  .plt            : { *(.plt) }  .iplt           : { *(.iplt) }  .text           :  {    *(.text.unlikely .text.*_unlikely .text.unlikely.*)    *(.text.exit .text.exit.*)    *(.text.startup .text.startup.*)    *(.text.hot .text.hot.*)    *(.text .stub .text.* .gnu.linkonce.t.*)    /* .gnu.warning sections are handled specially by elf32.em.  */    *(.gnu.warning)    *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)  }  .fini           :  {    KEEP (*(SORT_NONE(.fini)))  }  PROVIDE (__etext = .);  PROVIDE (_etext = .);  PROVIDE (etext = .);  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }  .rodata1        : { *(.rodata1) }  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }   PROVIDE_HIDDEN (__exidx_start = .);  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }   PROVIDE_HIDDEN (__exidx_end = .);  .eh_frame_hdr : { *(.eh_frame_hdr) }  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table  .gcc_except_table.*) }  /* These sections are generated by the Sun/Oracle C++ compiler.  */  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges  .exception_ranges*) }  /* Adjust the address for the data segment.  We want to adjust up to     the same address within the page on the next page up.  */  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));  /* Exception handling  */  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }  /* Thread Local Storage sections  */  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }  .preinit_array     :  {    PROVIDE_HIDDEN (__preinit_array_start = .);    KEEP (*(.preinit_array))    PROVIDE_HIDDEN (__preinit_array_end = .);  }  .init_array     :  {    PROVIDE_HIDDEN (__init_array_start = .);    KEEP (*(SORT(.init_array.*)))    KEEP (*(.init_array ))    PROVIDE_HIDDEN (__init_array_end = .);  }  .fini_array     :  {    PROVIDE_HIDDEN (__fini_array_start = .);    KEEP (*(SORT(.fini_array.*)))    KEEP (*(.fini_array ))    PROVIDE_HIDDEN (__fini_array_end = .);  }  .ctors          :  {    /* gcc uses crtbegin.o to find the start of       the constructors, so we make sure it is       first.  Because this is a wildcard, it       doesn't matter if the user does not       actually link against crtbegin.o; the       linker won't look for a file to match a       wildcard.  The wildcard also means that it       doesn't matter which directory crtbegin.o       is in.  */    KEEP (*crtbegin.o(.ctors))    KEEP (*crtbegin?.o(.ctors))    /* We don't want to include the .ctor section from       the crtend.o file until after the sorted ctors.       The .ctor section from the crtend file contains the       end of ctors marker and it must be last */    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))    KEEP (*(SORT(.ctors.*)))    KEEP (*(.ctors))  }  .dtors          :  {    KEEP (*crtbegin.o(.dtors))    KEEP (*crtbegin?.o(.dtors))    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))    KEEP (*(SORT(.dtors.*)))    KEEP (*(.dtors))  }  .jcr            : { KEEP (*(.jcr)) }  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }  .dynamic        : { *(.dynamic) }  . = DATA_SEGMENT_RELRO_END (0, .);  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }  .data           :  {    PROVIDE (__data_start = .);    *(.data .data.* .gnu.linkonce.d.*)    SORT(CONSTRUCTORS)  }  .data1          : { *(.data1) }  _edata = .; PROVIDE (edata = .);  . = .;  __bss_start = .;  __bss_start__ = .;  .bss            :  {   *(.dynbss)   *(.bss .bss.* .gnu.linkonce.b.*)   *(COMMON)   /* Align here to ensure that the .bss section occupies space up to      _end.  Align after .bss to ensure correct alignment even if the      .bss section disappears because there are no input sections.      FIXME: Why do we need it? When there is no .bss section, we don't      pad the .data section.  */   . = ALIGN(. != 0 ? 32 / 8 : 1);  }  _bss_end__ = . ; __bss_end__ = . ;  . = ALIGN(32 / 8);  . = SEGMENT_START("ldata-segment", .);  . = ALIGN(32 / 8);  __end__ = . ;  _end = .; PROVIDE (end = .);  . = DATA_SEGMENT_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_line.* .debug_line_end ) }  .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) }  /* DWARF 3 */  .debug_pubtypes 0 : { *(.debug_pubtypes) }  .debug_ranges   0 : { *(.debug_ranges) }  /* DWARF Extension.  */  .debug_macro    0 : { *(.debug_macro) }  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }}==================================================leon@netview:~$ 

3.举例

源码

/*************************************************** * Function :  * Author : leon * Creat Date : 2017/09/05  16:2:48 * Description : gcc -Wall -T ./cmd.lds -o cmd cmd.c * In-Parameter :  * Return :  * Modify :  **************************************************/#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/time.h>#include <sys/stat.h>#include <errno.h>#include <unistd.h>struct cmd_tbl_s {    char        *name;      /* Command Name         */    int     maxargs;    /* maximum number of arguments  */    int     repeatable; /* autorepeat allowed?      */                    /* Implementation function  */    int     (*cmd)(struct cmd_tbl_s *, int, int, char *[]);    char        *usage;     /* Usage message    (short) */    char        *help;      /* Help  message    (long)  */};typedef struct cmd_tbl_s    cmd_tbl_t;#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}static int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){    printf("\n\r========= (%s) =========\n\r",__func__);    printf("usage:\n\r%s\n\r",cmdtp->usage);    printf("help:\n\r%s\n\r",cmdtp->help);    printf("\n\r========= (%s) =========\n\r",__func__);    return 0;}U_BOOT_CMD(    bootm,  16, 1,  do_bootm,    "bootm   - boot application image from memory\n",    "[addr [arg ...]]     - boot application image stored in memory\n\r"    "passing arguments 'arg ...'; when booting a Linux kernel,\n\r"    "'arg' can be the address of an initrd image\n\r");static int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){    printf("\n\r========= (%s) =========\n\r",__func__);    printf("usage:\n\r%s\n\r",cmdtp->usage);    printf("help:\n\r%s\n\r",cmdtp->help);    printf("\n\r========= (%s) =========\n\r",__func__);    return 0;}U_BOOT_CMD(    hello,  16, 1,  do_hello,    "hello   - show hello\n",    "show hello help\n");extern cmd_tbl_t  __u_boot_cmd_start;extern cmd_tbl_t  __u_boot_cmd_end;static cmd_tbl_t *find_cmd (const char *cmd){    cmd_tbl_t *cmdtp;    cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;    /*Init value */    const char *p;    int len;    int n_found = 0;    /*     * Some commands allow length modifiers (like "cp.b");     * compare command name only until first dot.     */    len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);    for (cmdtp = &__u_boot_cmd_start;         cmdtp != &__u_boot_cmd_end;         cmdtp++) {        if (strncmp (cmd, cmdtp->name, len) == 0) {            if (len == strlen (cmdtp->name))                return cmdtp;   /* full match */            cmdtp_temp = cmdtp; /* abbreviated command ? */            n_found++;        }    }    if (n_found == 1) {         /* exactly one match */        return cmdtp_temp;    }    return NULL;    /* not found or ambiguous command */}intmain(int argc, char *argv[]){       cmd_tbl_t *cmdtp;    if (argc != 2) {        fprintf(stderr, "Usage: %s <cmd>\n", argv[0]);        exit(EXIT_FAILURE);    }    cmdtp = find_cmd(argv[1]);    if(!cmdtp)    {        fprintf(stderr, "cmd: %s not find.\n", argv[1]);        exit(EXIT_FAILURE);    }    cmdtp->cmd(cmdtp,0,argc,argv);    return 0;}

脚本 (该例子改编自uboot)

/* Script for -z combreloc: combine and sort reloc sections */OUTPUT_FORMAT("elf32-i386", "elf32-i386",              "elf32-i386")OUTPUT_ARCH(i386)ENTRY(_start)SEARCH_DIR("/usr/i686-linux-gnu/lib32"); SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"); SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib");SECTIONS{  /* Read-only sections, merged into text segment: */  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;  .interp         : { *(.interp) }  .note.gnu.build-id : { *(.note.gnu.build-id) }  .hash           : { *(.hash) }  .gnu.hash       : { *(.gnu.hash) }  .dynsym         : { *(.dynsym) }  .dynstr         : { *(.dynstr) }  .gnu.version    : { *(.gnu.version) }  .gnu.version_d  : { *(.gnu.version_d) }  .gnu.version_r  : { *(.gnu.version_r) }  .rel.dyn        :    {      *(.rel.init)      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)      *(.rel.fini)      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)      *(.rel.ctors)      *(.rel.dtors)      *(.rel.got)      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)      *(.rel.ifunc)    }  .rel.plt        :    {      *(.rel.plt)      PROVIDE_HIDDEN (__rel_iplt_start = .);      *(.rel.iplt)      PROVIDE_HIDDEN (__rel_iplt_end = .);    }  .init           :  {    KEEP (*(.init))  } =0x90909090  .plt            : { *(.plt) *(.iplt) }  .text           :  {    *(.text.unlikely .text.*_unlikely)    *(.text.exit .text.exit.*)    *(.text.startup .text.startup.*)    *(.text.hot .text.hot.*)    *(.text .stub .text.* .gnu.linkonce.t.*)    /* .gnu.warning sections are handled specially by elf32.em.  */    *(.gnu.warning)  } =0x90909090  .fini           :  {    KEEP (*(.fini))  } =0x90909090  PROVIDE (__etext = .);  PROVIDE (_etext = .);  PROVIDE (etext = .);  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }  .rodata1        : { *(.rodata1) }  .eh_frame_hdr : { *(.eh_frame_hdr) }  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table  .gcc_except_table.*) }  /* These sections are generated by the Sun/Oracle C++ compiler.  */  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges  .exception_ranges*) }  /* Adjust the address for the data segment.  We want to adjust up to     the same address within the page on the next page up.  */  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));  /* Exception handling  */  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }  /* Thread Local Storage sections  */  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }  .preinit_array     :  {    PROVIDE_HIDDEN (__preinit_array_start = .);    KEEP (*(.preinit_array))    PROVIDE_HIDDEN (__preinit_array_end = .);  }  .init_array     :  {    PROVIDE_HIDDEN (__init_array_start = .);    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))    KEEP (*(.init_array))    KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))    PROVIDE_HIDDEN (__init_array_end = .);  }  .fini_array     :  {    PROVIDE_HIDDEN (__fini_array_start = .);    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))    KEEP (*(.fini_array))    KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))    PROVIDE_HIDDEN (__fini_array_end = .);  }  .ctors          :  {    /* gcc uses crtbegin.o to find the start of       the constructors, so we make sure it is       first.  Because this is a wildcard, it       doesn't matter if the user does not       actually link against crtbegin.o; the       linker won't look for a file to match a       wildcard.  The wildcard also means that it       doesn't matter which directory crtbegin.o       is in.  */    KEEP (*crtbegin.o(.ctors))    KEEP (*crtbegin?.o(.ctors))    /* We don't want to include the .ctor section from       the crtend.o file until after the sorted ctors.       The .ctor section from the crtend file contains the       end of ctors marker and it must be last */    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))    KEEP (*(SORT(.ctors.*)))    KEEP (*(.ctors))  }  .dtors          :  {    KEEP (*crtbegin.o(.dtors))    KEEP (*crtbegin?.o(.dtors))    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))    KEEP (*(SORT(.dtors.*)))    KEEP (*(.dtors))  }  .jcr            : { KEEP (*(.jcr)) }  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }  .dynamic        : { *(.dynamic) }  .got            : { *(.got) *(.igot) }  . = DATA_SEGMENT_RELRO_END (12, .);  .got.plt        : { *(.got.plt)  *(.igot.plt) }  .data           :  {    *(.data .data.* .gnu.linkonce.d.*)    SORT(CONSTRUCTORS)  }  .data1          : { *(.data1) }  _edata = .; PROVIDE (edata = .);  . = .;  __u_boot_cmd_start = .;    .u_boot_cmd : { *(.u_boot_cmd) }    __u_boot_cmd_end = .;  __bss_start = .;  .bss            :  {   *(.dynbss)   *(.bss .bss.* .gnu.linkonce.b.*)   *(COMMON)   /* Align here to ensure that the .bss section occupies space up to      _end.  Align after .bss to ensure correct alignment even if the      .bss section disappears because there are no input sections.      FIXME: Why do we need it? When there is no .bss section, we don't      pad the .data section.  */   . = ALIGN(. != 0 ? 32 / 8 : 1);  }  . = ALIGN(32 / 8);  . = ALIGN(32 / 8);  _end = .; PROVIDE (end = .);  . = DATA_SEGMENT_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) }  /* DWARF 3 */  .debug_pubtypes 0 : { *(.debug_pubtypes) }  .debug_ranges   0 : { *(.debug_ranges) }  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }}

4. linux内核类似实现方法

extern initcall_t __initcall_start[], __initcall_end[];static void __init do_initcalls(void){    initcall_t *call;    int count = preempt_count();    for (call = __initcall_start; call < __initcall_end; call++) {        //省略...        result = (*call)();        //省略...}

linux-2.6.24\include\linux\init.h

#define module_init(x)  __initcall(x);#define __initcall(fn) device_initcall(fn)#define device_initcall(fn)     __define_initcall("6",fn,6)#define __define_initcall(level,fn,id) \    static initcall_t __initcall_##fn##id __attribute_used__ \    __attribute__((__section__(".initcall" level ".init"))) = fn

vmlinux.lds.S 脚本

/* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */#include <asm-generic/vmlinux.lds.h>#include <asm/thread_info.h>#include <asm/memory.h>OUTPUT_ARCH(arm)ENTRY(stext)#ifndef __ARMEB__jiffies = jiffies_64;#elsejiffies = jiffies_64 + 4;#endifSECTIONS{#ifdef CONFIG_XIP_KERNEL    . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);#else    . = PAGE_OFFSET + TEXT_OFFSET;#endif    .text.head : {        _stext = .;        _sinittext = .;        *(.text.head)    }    .init : {           /* Init code and data       */            *(.init.text)        _einittext = .;        __proc_info_begin = .;            *(.proc.info.init)        __proc_info_end = .;        __arch_info_begin = .;            *(.arch.info.init)        __arch_info_end = .;        __tagtable_begin = .;            *(.taglist.init)        __tagtable_end = .;        . = ALIGN(16);        __setup_start = .;            *(.init.setup)        __setup_end = .;        __early_begin = .;            *(.early_param.init)        __early_end = .;        __initcall_start = .;            INITCALLS        __initcall_end = .;        __con_initcall_start = .;            *(.con_initcall.init)        __con_initcall_end = .;        __security_initcall_start = .;            *(.security_initcall.init)        __security_initcall_end = .;#ifdef CONFIG_BLK_DEV_INITRD        . = ALIGN(32);        __initramfs_start = .;            usr/built-in.o(.init.ramfs)        __initramfs_end = .;#endif        . = ALIGN(4096);        __per_cpu_start = .;            *(.data.percpu)            *(.data.percpu.shared_aligned)        __per_cpu_end = .;#ifndef CONFIG_XIP_KERNEL        __init_begin = _stext;        *(.init.data)        . = ALIGN(4096);        __init_end = .;#endif    }    /DISCARD/ : {           /* Exit code and data       */        *(.exit.text)        *(.exit.data)        *(.exitcall.exit)#ifndef CONFIG_MMU        *(.fixup)        *(__ex_table)#endif    }    .text : {           /* Real text segment        */        _text = .;      /* Text and read-only data  */            __exception_text_start = .;            *(.exception.text)            __exception_text_end = .;            TEXT_TEXT            SCHED_TEXT            LOCK_TEXT#ifdef CONFIG_MMU            *(.fixup)#endif            *(.gnu.warning)            *(.rodata)            *(.rodata.*)            *(.glue_7)            *(.glue_7t)        *(.got)         /* Global offset table      */    }    RODATA    _etext = .;         /* End of text and rodata section */#ifdef CONFIG_XIP_KERNEL    __data_loc = ALIGN(4);      /* location in binary */    . = PAGE_OFFSET + TEXT_OFFSET;#else    . = ALIGN(THREAD_SIZE);    __data_loc = .;#endif    .data : AT(__data_loc) {        __data_start = .;   /* address in memory */        /*         * first, the init task union, aligned         * to an 8192 byte boundary.         */        *(.data.init_task)#ifdef CONFIG_XIP_KERNEL        . = ALIGN(4096);        __init_begin = .;        *(.init.data)        . = ALIGN(4096);        __init_end = .;#endif        . = ALIGN(4096);        __nosave_begin = .;        *(.data.nosave)        . = ALIGN(4096);        __nosave_end = .;        /*         * then the cacheline aligned data         */        . = ALIGN(32);        *(.data.cacheline_aligned)        /*         * The exception fixup table (might need resorting at runtime)         */        . = ALIGN(32);        __start___ex_table = .;#ifdef CONFIG_MMU        *(__ex_table)#endif        __stop___ex_table = .;        /*         * and the usual data section         */        DATA_DATA        CONSTRUCTORS        _edata = .;    }    _edata_loc = __data_loc + SIZEOF(.data);    .bss : {        __bss_start = .;    /* BSS              */        *(.bss)        *(COMMON)        _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) }}/* * These must never be empty * If you have to comment these two assert statements out, your * binutils is too old (for other reasons as well) */ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

vmlinux.lds.h 文件

#define INITCALLS                           \    *(.initcall0.init)                      \    *(.initcall0s.init)                     \    *(.initcall1.init)                      \    *(.initcall1s.init)                     \    *(.initcall2.init)                      \    *(.initcall2s.init)                     \    *(.initcall3.init)                      \    *(.initcall3s.init)                     \    *(.initcall4.init)                      \    *(.initcall4s.init)                     \    *(.initcall5.init)                      \    *(.initcall5s.init)                     \    *(.initcallrootfs.init)                     \    *(.initcall6.init)                      \    *(.initcall6s.init)                     \    *(.initcall7.init)                      \    *(.initcall7s.init)

应用

module_init(init_ext2_fs)module_exit(exit_ext2_fs)
module_init(init_jffs2_fs);module_exit(exit_jffs2_fs);
module_init(init_ext4_fs)module_exit(exit_ext4_fs)
原创粉丝点击