Chinaunix首页 | 论坛 | 博客
  • 博客访问: 550562
  • 博文数量: 469
  • 博客积分: 50
  • 博客等级: 民兵
  • 技术积分: 1495
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-15 21:04
文章分类

全部博文(469)

文章存档

2015年(81)

2014年(125)

2013年(261)

2012年(2)

分类: LINUX

2013-12-23 14:56:27

原文地址:ld script初探 作者:moonflow

a、Q&A

Q:为什么编出来的应用肯定是在用户地址空间运行,而内核编出来的代码却一定是运行在内核空间?

A:链接器(Linker):目的是描述输入文件的sections是如何映射到输出文件中,并控制输出文件的内存排列。而且ld就是使用这个缺省的script内置在链接器中。正是这些再起着作用.

b、链接脚本具体实践
链接脚本中无论是输出文件还是输入文件,主要数据是文件中的各种段,把输入文件中的段称为输入段(Input Sections),输出文件中的段称为
输出段(Output Sections)。
一般链接脚本名都以lds作为扩展名,ld script

ld script语法:
1.语句之间使用分号";"作为分隔符,但是对于命令语句来说也可以使用换行来结束该语句。
2.脚本文件中使用到的文件名、格式名或段名等凡包含";"或其他的分隔符的,都要使用双引号将该名字全称引用起来。

实践:hello.c

  1. #include <stdio.h>

  2. int main()
  3. {
  4. printf("Hello World\n");
  5. return 0;
  6. }

预处理:gcc -E hello.c -o hello.i
编译:gcc -S hello.i -o hello.s
汇编:as hello.s -o hello.o
链接:ld -static -verbose /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginT.o -
L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib -L/lib hello.o -start-group -lgcc -lgcc_eh -lc -end-group
/usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/crtn.o > 1.txt

1.txt

  1. GNU ld version 2.17.50.0.6-9.el5 20061020
  2. Supported emulations:
  3. elf_i386
  4. i386linux
  5. using internal linker script:
  6. ==================================================
  7. /* Script for -z combreloc: combine and sort reloc sections */
  8. OUTPUT_FORMAT("elf32-i386", "elf32-i386",
  9. "elf32-i386") ;输出文件使用的BFD格式
  10. OUTPUT_ARCH(i386) ;设置输出文件的machine architecture
  11. ENTRY(_start) ;将符号SYMBOL的值设置成入口地址
  12. SEARCH_DIR("/usr/i386-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); ;
  13. 义搜索路径
  14. SECTIONS
  15. {
  16. /* Read-only sections, merged into text segment: */
  17. PROVIDE (__executable_start = 0x08048000); ;PROVIDE关键字用于定义这类符号:在目标文件内被引用,但没有在任何目标文件内被定义
  18. 的符号
  19. . = 0x08048000 + SIZEOF_HEADERS; ;当前地址为0x08048000 + SIZEOF_HEADERS
  20. .interp : { *(.interp) }
  21. .hash : { *(.hash) }
  22. .gnu.hash : { *(.gnu.hash) }
  23. .dynsym : { *(.dynsym) }
  24. .dynstr : { *(.dynstr) }
  25. .gnu.version : { *(.gnu.version) }
  26. .gnu.version_d : { *(.gnu.version_d) }
  27. .gnu.version_r : { *(.gnu.version_r) } ;包含相关的段
  28. .rel.dyn :
  29. {
  30. *(.rel.init)
  31. *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
  32. *(.rel.fini)
  33. *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
  34. *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
  35. *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
  36. *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
  37. *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
  38. *(.rel.ctors)
  39. *(.rel.dtors)
  40. *(.rel.got)
  41. *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
  42. }
  43. .rela.dyn :
  44. {
  45. *(.rela.init)
  46. *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
  47. *(.rela.fini)
  48. *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
  49. *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
  50. *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
  51. *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
  52. *(.rela.ctors)
  53. *(.rela.dtors)
  54. *(.rela.got)
  55. *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
  56. }
  57. .rel.plt : { *(.rel.plt) }
  58. .rela.plt : { *(.rela.plt) } ;包含相关的段
  59. .init :
  60. {
  61. KEEP (*(.init)) ;KEEP()强制连接器保留一些特定的section
  62. } =0x90909090
  63. .plt : { *(.plt) }
  64. .text :
  65. {
  66. *(.text .stub .text.* .gnu.linkonce.t.*)
  67. KEEP (*(.text.*personality*))
  68. /* .gnu.warning sections are handled specially by elf32.em. */
  69. *(.gnu.warning)
  70. } =0x90909090 ;填充0x9090
  71. .fini :
  72. {
  73. KEEP (*(.fini))
  74. } =0x90909090
  75. PROVIDE (__etext = .); ;PROVIDE关键字用于定义这类符号:在目标文件内被引用,但没有在任何目标文件内被定义的符号
  76. PROVIDE (_etext = .);
  77. PROVIDE (etext = .);
  78. .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  79. .rodata1 : { *(.rodata1) }
  80. .eh_frame_hdr : { *(.eh_frame_hdr) }
  81. .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  82. .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  83. /* Adjust the address for the data segment. We want to adjust up to
  84. the same address within the page on the next page up. */
  85. . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . =
  86. DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  87. /* Exception handling */
  88. .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  89. .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  90. /* Thread Local Storage sections */
  91. .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  92. .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  93. .preinit_array :
  94. {
  95. PROVIDE_HIDDEN (__preinit_array_start = .);
  96. KEEP (*(.preinit_array))
  97. PROVIDE_HIDDEN (__preinit_array_end = .);
  98. }
  99. .init_array :
  100. {
  101. PROVIDE_HIDDEN (__init_array_start = .);
  102. KEEP (*(SORT(.init_array.*)))
  103. KEEP (*(.init_array))
  104. PROVIDE_HIDDEN (__init_array_end = .);
  105. }
  106. .fini_array :
  107. {
  108. PROVIDE_HIDDEN (__fini_array_start = .);
  109. KEEP (*(.fini_array))
  110. KEEP (*(SORT(.fini_array.*)))
  111. PROVIDE_HIDDEN (__fini_array_end = .);
  112. }
  113. .ctors :
  114. {
  115. /* gcc uses crtbegin.o to find the start of
  116. the constructors, so we make sure it is
  117. first. Because this is a wildcard, it
  118. doesn't matter if the user does not
  119. actually link against crtbegin.o; the
  120. linker won't look for a file to match a
  121. wildcard. The wildcard also means that it
  122. doesn't matter which directory crtbegin.o
  123. is in. */
  124. KEEP (*crtbegin.o(.ctors))
  125. KEEP (*crtbegin?.o(.ctors))
  126. /* We don't want to include the .ctor section from
  127. the crtend.o file until after the sorted ctors.
  128. The .ctor section from the crtend file contains the
  129. end of ctors marker and it must be last */
  130. KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
  131. KEEP (*(SORT(.ctors.*)))
  132. KEEP (*(.ctors))
  133. }
  134. .dtors :
  135. {
  136. KEEP (*crtbegin.o(.dtors))
  137. KEEP (*crtbegin?.o(.dtors))
  138. KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
  139. KEEP (*(SORT(.dtors.*)))
  140. KEEP (*(.dtors))
  141. }
  142. .jcr : { KEEP (*(.jcr)) }
  143. .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
  144. .dynamic : { *(.dynamic) }
  145. .got : { *(.got) }
  146. . = DATA_SEGMENT_RELRO_END (12, .);
  147. .got.plt : { *(.got.plt) }
  148. .data :
  149. {
  150. *(.data .data.* .gnu.linkonce.d.*)
  151. KEEP (*(.gnu.linkonce.d.*personality*))
  152. SORT(CONSTRUCTORS)
  153. }
  154. .data1 : { *(.data1) }
  155. _edata = .; PROVIDE (edata = .);
  156. __bss_start = .;
  157. .bss :
  158. {
  159. *(.dynbss)
  160. *(.bss .bss.* .gnu.linkonce.b.*)
  161. *(COMMON)
  162. /* Align here to ensure that the .bss section occupies space up to
  163. _end. Align after .bss to ensure correct alignment even if the
  164. .bss section disappears because there are no input sections.
  165. FIXME: Why do we need it? When there is no .bss section, we don't
  166. pad the .data section. */
  167. . = ALIGN(. != 0 ? 32 / 8 : 1);
  168. }
  169. . = ALIGN(32 / 8);
  170. . = ALIGN(32 / 8);
  171. _end = .; PROVIDE (end = .);
  172. . = DATA_SEGMENT_END (.);
  173. /* Stabs debugging sections. */
  174. .stab 0 : { *(.stab) }
  175. .stabstr 0 : { *(.stabstr) }
  176. .stab.excl 0 : { *(.stab.excl) }
  177. .stab.exclstr 0 : { *(.stab.exclstr) }
  178. .stab.index 0 : { *(.stab.index) }
  179. .stab.indexstr 0 : { *(.stab.indexstr) }
  180. .comment 0 : { *(.comment) }
  181. /* DWARF debug sections.
  182. Symbols in the DWARF debugging sections are relative to the beginning
  183. of the section so we begin them at 0. */
  184. /* DWARF 1 */
  185. .debug 0 : { *(.debug) }
  186. .line 0 : { *(.line) }
  187. /* GNU DWARF 1 extensions */
  188. .debug_srcinfo 0 : { *(.debug_srcinfo) }
  189. .debug_sfnames 0 : { *(.debug_sfnames) }
  190. /* DWARF 1.1 and DWARF 2 */
  191. .debug_aranges 0 : { *(.debug_aranges) }
  192. .debug_pubnames 0 : { *(.debug_pubnames) }
  193. /* DWARF 2 */
  194. .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
  195. .debug_abbrev 0 : { *(.debug_abbrev) }
  196. .debug_line 0 : { *(.debug_line) }
  197. .debug_frame 0 : { *(.debug_frame) }
  198. .debug_str 0 : { *(.debug_str) }
  199. .debug_loc 0 : { *(.debug_loc) }
  200. .debug_macinfo 0 : { *(.debug_macinfo) }
  201. /* SGI/MIPS DWARF 2 extensions */
  202. .debug_weaknames 0 : { *(.debug_weaknames) }
  203. .debug_funcnames 0 : { *(.debug_funcnames) }
  204. .debug_typenames 0 : { *(.debug_typenames) }
  205. .debug_varnames 0 : { *(.debug_varnames) }
  206. /* DWARF 3 */
  207. .debug_pubtypes 0 : { *(.debug_pubtypes) }
  208. .debug_ranges 0 : { *(.debug_ranges) }
  209. /DISCARD/ : { *(.note.GNU-stack) }
  210. }


  211. ==================================================
  212. attempt to open /usr/lib/crt1.o succeeded
  213. /usr/lib/crt1.o
  214. ........
  215. /usr/lib/crtn.o

c、参考链接:
http://blog.chinaunix.net/space.php?uid=20433875&do=blog&id=1680446

http://blog.chinaunix.net/space.php?uid=10678279&do=blog&id=2936584
http://hi.baidu.com/dljaye/blog/item/7b56fb9be84909b9c9eaf486.html



<<程序员自我修养>>:ld链接脚本

阅读(701) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~