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

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
View Code

 

 關於搜索路徑的選項

-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 asminline 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) }
}


==================================================
View Code

上面的默認鏈接腳本較為復雜,下面是一個簡潔的鏈接腳本:

MEMORY
{
    rom    :    ORIGIN = 0x08000000, LENGTH = 512K
    ram    :    ORIGIN = 0x70000000, LENGTH = 8M
}

SECTIONS
{
    .text : 
    { 
        *(.text) 
    }>ram

    .data : 
    { 
        *(.data) 
    }>ram
    
    .bss : 
    { 
        *(.bss) 
    }>ram
}
View Code

默認鏈接腳本增加了許多符號,比如各種節的起始和結束的符號,符號還多一個以下划線為起始的,等等。這些符號不知什么地方會用到。另外,還有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/38913369/windows-enforces-read-only-text-section-even-thus-disabled-by-the-ld-linker

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;
}
View Code

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)
View Code

輸出的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;
}
View Code

編譯: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) }
}
View Code

關於入口點

入口點可以不指定,可以使用默認。若命令參數中無-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的地址(應該是虛擬地址)方式,會使用默認的鏈接腳本,會引入許多無關符號,不是太好。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM