gcc, ld
GCC
gcc除了具备基本的c文件编译功能外,还把其它工具的功能也集成了进来,比如as的汇编功能,ld的链接功能。
因此,gcc也可以通过-Wa, option,将option传给汇编器as;也可以通过-Wl, option,将option传给链接器ld。
-N,gcc手册中没看到该选项,这是属于链接器ld的选项,gcc并没有。该选项用于将text设为writable,见后面ld部分介绍。
-L,gcc手册中只有-Ldir用来设置搜索库文件的目录,单独用-L没看该选项
基本选项
-S,大写
Compile only; do not assemble or link,输出汇编文件.s
-c,小写
Compile and assemble, but do not link.
如果不加-c,那么gcc会直接编译+链接为可执行文件。
-o <file>
Place the output into <file>
-v
Print (on standard error output) the commands executed to run the stages of compilation. Also print the version number of the compiler driver program and of the preprocessor and the compiler proper. 下面为一个例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
sparc-elf-gcc.exe -v -c ../src/main.c -o ../obj/main.o Reading specs from /cygdrive/c/SPE-C2.5/bin/../lib/gcc-lib/sparc-elf/3.2.3/specs Configured with: ../gcc-3.2.3/configure --target=sparc-elf --prefix=/opt/sparc-elf-3.2.3 --with-gnu-as --with-gnu-ld --verbose --enable-languages=c,c++ --disable-shared --disable-nls --with-cpu=leon Thread model: single gcc version 3.2.3 /cygdrive/c/SPE-C2.5/bin/../lib/gcc-lib/sparc-elf/3.2.3/cc1.exe -lang-c -v -iprefix /cygdrive/c/SPE-C2.5/bin/../lib/gcc-lib/sparc-elf/3.2.3/ -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=3 -D__GXX_ABI_VERSION=102 -Dsparc -D__elf__ -D__sparc__ -D__elf__ -D__sparc -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc ../src/main.c -quiet -dumpbase main.c -version -o /cygdrive/c/user/default/AppData/Local/Temp/ccuy9Z2h.s GNU CPP version 3.2.3 (cpplib) (sparc ELF) GNU C version 3.2.3 (sparc-elf) compiled by GNU C version 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125). ignoring nonexistent directory "/cygdrive/c/SPE-C2.5/sparc-elf/sys-include" ignoring nonexistent directory "/opt/sparc-elf-3.2.3/include" ignoring nonexistent directory "/opt/sparc-elf-3.2.3/lib/gcc-lib/sparc-elf/3.2.3/include" ignoring nonexistent directory "/opt/sparc-elf-3.2.3/lib/gcc-lib/sparc-elf/3.2.3/../../../../sparc-elf/sys-include" ignoring nonexistent directory "/opt/sparc-elf-3.2.3/lib/gcc-lib/sparc-elf/3.2.3/../../../../sparc-elf/include" #include "..." search starts here: #include <...> search starts here: /cygdrive/c/SPE-C2.5/lib/gcc-lib/sparc-elf/3.2.3/include /cygdrive/c/SPE-C2.5/sparc-elf/include End of search list. /cygdrive/c/SPE-C2.5/bin/../lib/gcc-lib/sparc-elf/3.2.3/../../../../sparc-elf/bin/as.exe --traditional-format -V -Qy -s -o ../obj/main.o /cygdrive/c/user/default/AppData/Local/Temp/ccuy9Z2h.s GNU assembler version 2.13.2.1 (sparc-elf) using BFD version 2.13.2.1
关于搜索路径的选项
-Idir
Add the directory dir to the head of the list of directories to be searched for header files.
This can be used to override a system header file, substituting your own version, since these
directories are searched before the system header file directories. If you use more than one
`-I' option, the directories are scanned in left-to-right order; the standard system
directories come after.
-Ldir
Add directory dir to the list of directories to be searched for `-l'
-Bprefix
这个和-I,-L有什么关系呢?感觉有点重复。
This option specifies where to find the executables, libraries, include files, and data files of
the compiler itself.
-B <directory>
Add <directory> to the compiler's search paths
This option specifies where to find the executables, libraries, include files, and data files of the compiler itself.
关于语言的选项
-fno-asm
Do not recognize asm
, inline
or typeof
as a keyword, so that code can use these words as identifiers. You can use the keywords __asm__
, __inline__
and __typeof__
instead. `-ansi' implies `-fno-asm'.
不识别asm、inline等关键字。有时候需要在C程序中内嵌汇编语言,这时候就需要用一个关键字告诉编译器这是汇编程序。怎么告诉呢?有两种方法,一种是asm(""),另一种是__asm__(""),两个下划线underscore。对于ansi来说,只能识别__asm__,不识别asm,因此,如果有ansi选项,就暗含有fno-asm。
但有什么时候需要用这个选项呢?这个选项导致只能识别__asm__,不能识别asm,难道不是识别的越多越好吗?难道会主动使用asm作其它用途?或许吧。
那么,是否还应该有-fasm关键字呢,--help中没有,但加上这个选项并不报错;实际即使乱写为-fasmaaaaaa,也不会报错。因此-fasm实际不起作用,但gcc检测到-f后面的不识别,但也不报错。
-fno-builtin
Don't recognize builtin functions that do not begin with `__builtin_' as prefix. Currently, the functions affected include abort, abs, alloca, cos, exit, fabs, ffs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy, and strlen.
GCC normally generates special code to handle certain builtin functions more efficiently; for instance, calls to alloca may become single instructions that adjust the stack directly, and calls to memcpy may become inline copy loops. The resulting code is often both smaller and faster, but since the function calls no longer appear as such, you cannot set a breakpoint on those calls, nor can you change the behavior of the functions by linking with a different library.
The `-ansi' option prevents alloca and ffs from being builtin functions, since these functions do not have an ANSI standard meaning.
预处理选项
-nostdinc,
不要搜索系统标准头文件目录。通过使用`-nostdinc' and `-I-',可以限定只搜索指定目录的头文件。
Do not search the standard system directories for header files. Only the directories you have specified with `-I' options (and the current directory, if appropriate) are searched. See section 2.12 Options for Directory Search, for information on `-I'.
By using both `-nostdinc' and `-I-', you can limit the include-file search path to only those directories you specify explicitly.
警告选项
-Wall,
输出所有警告
All of the above `-W' options combined. This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.
调试选项
-g
-g生成操作系统固有的格式,对于sparc来说,使用-g会生成stab格式。
如果使用-g -gdwarf-2,则会生成dwarf-2格式的调试信息,不再生成stab格式的。这两个选项允许同时存在。
如果使用-gstabs -dwarf-2,则后一个-dwarf-2会并忽略,因为和stabs冲突,即生成stabs格式的调试信息。这两个是同时存在是不允许的。
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
On most systems that use stabs format, `-g' enables use of extra debugging information that only GDB can use; this extra information makes debugging work better in GDB but will probably make other debuggers crash or refuse to read the program. If you want to control for certain whether to generate the extra information, use `-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', `-gdwarf-1+', or `-gdwarf-1' (see below).
处理器相关选项
-mv8
对于sparc处理器,默认生成v7版本代码,如果使用v8,需要显式指定-mv8。
These two options select variations on the SPARC architecture. By default (unless specifically configured for the Fujitsu SPARClite), GCC generates code for the v7 variant of the SPARC architecture. `-mv8' will give you SPARC v8 code. The only difference from v7 code is that the compiler emits the integer multiply and integer divide instructions which exist in SPARC v8 but not in SPARC v7.
链接选项
-nostartfiles
用于设置不使用标准系统启动文件。在win10上,不使用该选项生成的可执行elf文件有66KB,使用该选项生成的可行性elf文件仅2KB。
Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib
or -nodefaultlibs
is used.
-nodefaultlibs
Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker. The standard startup files are used normally, unless -nostartfiles
is used. The compiler may generate calls to memcmp, memset, and memcpy for System V (and ANSI C) environments or to bcopy and bzero for BSD environments. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
-nostdlib
不使用标准的系统启动文件和库。该选项是上面两个选项的并集。
Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be passed to the linker. The compiler may generate calls to memcmp, memset, and memcpy for System V (and ANSI C) environments or to bcopy and bzero for BSD environments. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
One of the standard libraries bypassed by `-nostdlib' and `-nodefaultlibs' is `libgcc.a', a library of internal subroutines that GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See section Interfacing to GCC Output, for more discussion of `libgcc.a'.) In most cases, you need `libgcc.a' even when you want to avoid other standard libraries. In other words, when you specify `-nostdlib' or `-nodefaultlibs' you should usually specify `-lgcc' as well. This ensures that you have no unresolved references to internal GCC library subroutines. (For example, `__main', used to ensure C++ constructors will be called; see section collect2
.)
-static
不要动态链接。
On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect.
LD
--verbose
Display the version number for ld
and list the linker emulations supported. Display which input files can and cannot be opened. Display the linker script if using a default builtin script.
实际输出如下:版本为2.13.2.1,支持模拟处理器为sparcleon(sparc是处理器体系结构,leon是一个具体实现),有默认链接脚本(如果ld的参数中没有指定链接脚本,则使用默认链接脚本)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
sparc-elf-ld.exe --verbose GNU ld version 2.13.2.1 Supported emulations: sparcleon using internal linker script: ================================================== /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-sparc") SEARCH_DIR("/opt/sparc-elf-3.2.3/sparc-elf/lib"); ENTRY(start) /* Base address of the on-CPU peripherals */ LEON_REG = 0x80000000; _LEON_REG = 0x80000000; MEMORY { rom : ORIGIN = 0x00000000, LENGTH = 256M ram : ORIGIN = 0x40000000, LENGTH = 2048M } SECTIONS { .text : { CREATE_OBJECT_SYMBOLS *(.text) etext = .; . = ALIGN (16); *(.eh_frame) . = ALIGN (16); *(.gnu.linkonce.t*) /* C++ constructors */ ___CTOR_LIST__ = .; LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2) *(SORT(.ctors.*)) *(.ctors) LONG(0) ___CTOR_END__ = .; ___DTOR_LIST__ = .; LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2) *(SORT(.dtors.*)) *(.dtors) LONG(0) ___DTOR_END__ = .; _rodata_start = .; *(.rodata*) *(.gnu.linkonce.r*) _erodata = ALIGN( 0x10 ) ; *(.gnu.linkonce*) *(.init) *(.fini) *(.lit) *(.shdata) . = ALIGN (16); etext = .; } > ram .gcc_except_table : { *(.gcc_except_table) } > ram .data : { *(.data .data.* ) edata = .; _edata = .; __edata = .; } > ram .bss : { . = ALIGN(0x8); bss_start = .; _bss_start = .; __bss_start = .; *(.bss .bss.* ) *(COMMON) } > ram . = ALIGN(0x8); end = .; _end = .; __end = .; __heap1 = .; .jcr . (NOLOAD) : { *(.jcr) } .stab 0 (NOLOAD) : { [ .stab ] } .stabstr 0 (NOLOAD) : { [ .stabstr ] } .debug 0 : { *(.debug) } .line 0 : { *(.line) } .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_info 0 : { *(.debug_info) } .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) } .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } ==================================================
上面的默认链接脚本较为复杂,下面是一个简洁的链接脚本:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
MEMORY { rom : ORIGIN = 0x08000000, LENGTH = 512K ram : ORIGIN = 0x70000000, LENGTH = 8M } SECTIONS { .text : { *(.text) }>ram .data : { *(.data) }>ram .bss : { *(.bss) }>ram }
默认链接脚本增加了许多符号,比如各种节的起始和结束的符号,符号还多一个以下划线为起始的,等等。这些符号不知什么地方会用到。另外,还有C++的支持,比如ctor和dtor节。可以以简洁的链接脚本为基础,缺少什么符号,再按需增加,这样链接脚本比较简单。
-x
--discard-all
Delete all local symbols.哪些是local符号?
-X
--discard-locals
哪些是临时的local符号?
Delete all temporary local symbols. For most targets, this is all local symbols whose names begin with `L'.
-n
--nmagic
Set the text segment to be read only, and mark the output as NMAGIC
if possible.
将text设置为writable可写
-N
--omagic
Set the text and data sections to be readable and writable. Also, do not page-align the data segment. If the output format supports Unix style magic numbers, mark the output as OMAGIC
.
把text设置为可写有什么好处呢?
下面是网上的几个提问,
https://stackoverflow.com/questions/48549036/does-gcc-have-an-n-option
https://stackoverflow.com/questions/27581279/make-text-segment-writable-elf
https://stackoverflow.com/questions/48549036/does-gcc-have-an-n-option
其中一个提问提到如下描述:(virus,感觉这些东西是黑客、病毒的基础哈。)
In "Learning Linux Binary Analysis" by Ryan "elfmaster" O'Neill.
Another neat trick that I just recently discovered during the construction of the Skeksi virus for 64-bit Linux is to merge the text and data segment into a single segment, that is, read+write+execute (RWX), by using the
-N
option with gcc.
设置text为可写,
除了用-N外,
还可以通过linker script将text属性设置为writable,是吗?没找到例子?
也可以用objcopy,$(OBJCOPY) --set-section-flags .text=code,data,alloc,contents,load test-tmp.exe test.exe
一个例子,使用-N后,text节的属性变为WAX
Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 70000000 000058 001760 00 WAX 0 0 8 [ 2] .data PROGBITS 70001760 0017b8 000004 00 WA 0 0 4 [ 3] .bss NOBITS 70001764 0017bc 000004 00 WA 0 0 4
-Map mapfile
Print a link map to the file mapfile. See the description of the `-M' option, above.
-M
--print-map
Print a link map to the standard output. A link map provides information about the link, including the following:
- Where object files and symbols are mapped into memory.
- How common symbols are allocated.
- All archive members included in the link, with a mention of the symbol which caused the archive member to be brought in.
一个简单例子:
main.c
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <math.h> int var_data = 1; int var_bss; int main() { double d; d = sin(3.14/2); return 0; }
sparc-elf-ld.exe ../obj/main.o -nostartfiles -script=linkerscript.ld -Map mapfile -L$(GCC_ROOT)\sparc-elf\lib\v8 -lm -o main.elf
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Archive member included because of file (symbol) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) ../obj/main.o (sin) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) (__ieee754_rem_pio2) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_cos.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) (__kernel_cos) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) (__kernel_rem_pio2) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_sin.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) (__kernel_sin) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_fabs.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) (fabs) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_floor.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) (floor) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) (scalbn) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_copysign.o) C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) (copysign) Allocating common symbols Common symbol size file var_bss 0x4 ../obj/main.o Memory Configuration Name Origin Length Attributes rom 0x08000000 0x00080000 ram 0x70000000 0x00800000 *default* 0x00000000 0xffffffff Linker script and memory map LOAD ../obj/add.o LOAD ../obj/main.o .text 0x70000000 0x1760 *(.text) .text 0x70000000 0x34 ../obj/add.o 0x70000000 add .text 0x70000034 0x3c ../obj/main.o 0x70000034 main .text 0x70000070 0xdc C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) 0x70000070 sin .text 0x7000014c 0x3ac C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) 0x7000014c __ieee754_rem_pio2 .text 0x700004f8 0x154 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_cos.o) 0x700004f8 __kernel_cos .text 0x7000064c 0x858 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) 0x7000064c __kernel_rem_pio2 .text 0x70000ea4 0xfc C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_sin.o) 0x70000ea4 __kernel_sin .text 0x70000fa0 0x2c C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_fabs.o) 0x70000fa0 fabs .text 0x70000fcc 0x1c0 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_floor.o) 0x70000fcc floor .text 0x7000118c 0x170 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) 0x7000118c scalbn .text 0x700012fc 0x40 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_copysign.o) 0x700012fc copysign 0x70001340 . = ALIGN (0x10) *fill* 0x7000133c 0x4 00 *(.rodata*) .rodata 0x70001340 0x8 ../obj/main.o .rodata 0x70001348 0x228 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) .rodata 0x70001570 0x80 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_cos.o) .rodata 0x700015f0 0xa8 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) .rodata 0x70001698 0x70 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_sin.o) .rodata 0x70001708 0x18 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_floor.o) .rodata 0x70001720 0x40 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) .data 0x70001760 0x4 *(.data) .data 0x70001760 0x4 ../obj/main.o 0x70001760 var_data .bss 0x70001764 0x4 *(.bss) COMMON 0x70001764 0x4 ../obj/main.o 0x0 (size before relaxing) 0x70001764 var_bss LOAD C:\SPE-C2.5\sparc-elf\lib\v8/libm.a OUTPUT(main.elf elf32-sparc) .comment 0x00000000 0xc6 .comment 0x00000000 0x12 ../obj/add.o .comment 0x00000012 0x12 ../obj/main.o .comment 0x00000024 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) .comment 0x00000036 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) .comment 0x00000048 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_cos.o) .comment 0x0000005a 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) .comment 0x0000006c 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_sin.o) .comment 0x0000007e 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_fabs.o) .comment 0x00000090 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_floor.o) .comment 0x000000a2 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) .comment 0x000000b4 0x12 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_copysign.o) .stab 0x00000000 0x30f0 .stab 0x00000000 0x738 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) .stab 0x00000738 0x930 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) 0xd68 (size before relaxing) .stab 0x00001068 0x480 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_cos.o) 0x8b8 (size before relaxing) .stab 0x000014e8 0x99c C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) 0xdd4 (size before relaxing) .stab 0x00001e84 0x384 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(k_sin.o) 0x7bc (size before relaxing) .stab 0x00002208 0x270 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_fabs.o) 0x6a8 (size before relaxing) .stab 0x00002478 0x48c C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_floor.o) 0x8c4 (size before relaxing) .stab 0x00002904 0x4c8 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_scalbn.o) 0x900 (size before relaxing) .stab 0x00002dcc 0x324 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_copysign.o) 0x75c (size before relaxing) .stabstr 0x00000000 0x2521 .stabstr 0x00000000 0x2521 C:\SPE-C2.5\sparc-elf\lib\v8/libm.a(s_sin.o) 0x0 (size before relaxing)
输出的mapfile如下:
Archive member included because of file (symbol)
由于文件(符号)包含的归档文件成员,比如main.o中的sin引用了libm.a中的s_sin.o文件。
Allocating common symbols
分配的公共符号,即bss变量。
Memory Configuration
内存配置。
Linker script and memory map
这个没有内容?
LOAD ../obj/main.o
列举所有o文件?
.text
列举text段,这里会按照地址顺序,也是按照文件顺序,列举所有文件的text段(因为链接脚本中是将所有输入文件的text段整体放在一起),还可以看到包含了libm.a的text段。
.data
.bss
实际工程
main.c
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int main() { return 0; }
编译:sparc-elf-gcc.exe -c main.c -o main.o
链接:sparc-elf-ld.exe main.o -nostartfiles -o main.elf
链接过程报错cannot find entry symbol start如下:
sparc-elf-ld: warning: cannot find entry symbol start; defaulting to 40000000
是因为默认链接脚本(ld --verbose可以查看)中通过ENTRY(start)指定了入口为start,但是没有找到start符号,所以,将entry默认为ram起始0x4000 0000
如何指定链接脚本,不使用默认链接脚本呢
-Tlinkerscritp.ld或者-script=linkerscript.ld,建议用后者,更清晰。
最简单的链接脚本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
SECTIONS { . = 0x08000000; .text : { *(.text) } . = 0x70000000; .data : { *(.data) } .bss : { *(.bss) } }
关于入口点
入口点可以不指定,可以使用默认。若命令参数中无-e,链接脚本中无ENTRY(symbol),没有定义start,那么就会用text的起始地址。需要保证text的起始地址为入口(入口函数所在o文件在链接时放在所有o文件的第一个)。一般该处为中断向量表,那如何用-e指定?如果text搬移到ram,怎么指定?
默认顺序如下
• the `-e' entry command-line option;
• the ENTRY(symbol) command in a linker script;
• the value of the symbol start , if defined;
• the address of the first byte of the `.text' section, if present;
• The address 0
用-e指定入口点和-Ttext指定text的地址(应该是虚拟地址)方式,会使用默认的链接脚本,会引入许多无关符号,不是太好。