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. 下面為一個例子:

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的參數中沒有指定鏈接腳本,則使用默認鏈接腳本)。

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) } } ==================================================
上面的默認鏈接腳本較為復雜,下面是一個簡潔的鏈接腳本:

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

#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

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

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,建議用后者,更清晰。
最簡單的鏈接腳本

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的地址(應該是虛擬地址)方式,會使用默認的鏈接腳本,會引入許多無關符號,不是太好。