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的地址(应该是虚拟地址)方式,会使用默认的链接脚本,会引入许多无关符号,不是太好。

 

posted on 2020-02-06 20:31  yanhc  阅读(3370)  评论(0编辑  收藏  举报

导航