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./bin/../lib/gcc-lib/sparc-elf/3.2./specs
Configured with: ../gcc-3.2./configure --target=sparc-elf --prefix=/opt/sparc-elf-3.2. --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.
/cygdrive/c/SPE-C2./bin/../lib/gcc-lib/sparc-elf/3.2./cc1.exe -lang-c -v -iprefix /cygdrive/c/SPE-C2./bin/../lib/gcc-lib/sparc-elf/3.2./ -D__GNUC__= -D__GNUC_MINOR__= -D__GNUC_PATCHLEVEL__= -D__GXX_ABI_VERSION= -Dsparc -D__elf__ -D__sparc__ -D__elf__ -D__sparc -D__NO_INLINE__ -D__STDC_HOSTED__= -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. (cpplib) (sparc ELF)
GNU C version 3.2. (sparc-elf)
compiled by GNU C version 3.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./lib/gcc-lib/sparc-elf/3.2./include
/cygdrive/c/SPE-C2./sparc-elf/include
End of search list.
/cygdrive/c/SPE-C2./bin/../lib/gcc-lib/sparc-elf/3.2./../../../../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 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 ();
*(.eh_frame)
. = ALIGN ();
*(.gnu.linkonce.t*)
/* C++ constructors */
___CTOR_LIST__ = .;
LONG((___CTOR_END__ - ___CTOR_LIST__) / - )
*(SORT(.ctors.*))
*(.ctors)
LONG()
___CTOR_END__ = .;
___DTOR_LIST__ = .;
LONG((___DTOR_END__ - ___DTOR_LIST__) / - )
*(SORT(.dtors.*))
*(.dtors)
LONG()
___DTOR_END__ = .;
_rodata_start = .;
*(.rodata*)
*(.gnu.linkonce.r*)
_erodata = ALIGN( 0x10 ) ;
*(.gnu.linkonce*)
*(.init)
*(.fini)
*(.lit)
*(.shdata)
. = ALIGN ();
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 (NOLOAD) :
{
[ .stab ]
}
.stabstr (NOLOAD) :
{
[ .stabstr ]
}
.debug : { *(.debug) }
.line : { *(.line) }
.debug_srcinfo : { *(.debug_srcinfo) }
.debug_sfnames : { *(.debug_sfnames) }
.debug_aranges : { *(.debug_aranges) }
.debug_pubnames : { *(.debug_pubnames) }
.debug_info : { *(.debug_info) }
.debug_abbrev : { *(.debug_abbrev) }
.debug_line : { *(.debug_line) }
.debug_frame : { *(.debug_frame) }
.debug_str : { *(.debug_str) }
.debug_loc : { *(.debug_loc) }
.debug_macinfo : { *(.debug_macinfo) }
.debug_weaknames : { *(.debug_weaknames) }
.debug_funcnames : { *(.debug_funcnames) }
.debug_typenames : { *(.debug_typenames) }
.debug_varnames : { *(.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/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
[ ] NULL
[ ] .text PROGBITS WAX
[ ] .data PROGBITS 0017b8 WA
[ ] .bss NOBITS 0017bc WA

-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 = ;
int var_bss; int main()
{
double d; d = sin(3.14/); return ;
}

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.\sparc-elf\lib\v8/libm.a(s_sin.o)
../obj/main.o (sin)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_sin.o) (__ieee754_rem_pio2)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_cos.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_sin.o) (__kernel_cos)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) (__kernel_rem_pio2)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_sin.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_sin.o) (__kernel_sin)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_fabs.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o) (fabs)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_floor.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) (floor)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_scalbn.o)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o) (scalbn)
C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_copysign.o)
C:\SPE-C2.\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.\sparc-elf\lib\v8/libm.a(s_sin.o)
0x70000070 sin
.text 0x7000014c 0x3ac C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o)
0x7000014c __ieee754_rem_pio2
.text 0x700004f8 0x154 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_cos.o)
0x700004f8 __kernel_cos
.text 0x7000064c 0x858 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o)
0x7000064c __kernel_rem_pio2
.text 0x70000ea4 0xfc C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_sin.o)
0x70000ea4 __kernel_sin
.text 0x70000fa0 0x2c C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_fabs.o)
0x70000fa0 fabs
.text 0x70000fcc 0x1c0 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_floor.o)
0x70000fcc floor
.text 0x7000118c 0x170 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_scalbn.o)
0x7000118c scalbn
.text 0x700012fc 0x40 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_copysign.o)
0x700012fc copysign
0x70001340 . = ALIGN (0x10)
*fill* 0x7000133c 0x4
*(.rodata*)
.rodata 0x70001340 0x8 ../obj/main.o
.rodata 0x70001348 0x228 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o)
.rodata 0x70001570 0x80 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_cos.o)
.rodata 0x700015f0 0xa8 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o)
.rodata 0x70001698 0x70 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_sin.o)
.rodata 0x70001708 0x18 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_floor.o)
.rodata 0x70001720 0x40 C:\SPE-C2.\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.\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.\sparc-elf\lib\v8/libm.a(s_sin.o)
.comment 0x00000036 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o)
.comment 0x00000048 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_cos.o)
.comment 0x0000005a 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o)
.comment 0x0000006c 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_sin.o)
.comment 0x0000007e 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_fabs.o)
.comment 0x00000090 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_floor.o)
.comment 0x000000a2 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_scalbn.o)
.comment 0x000000b4 0x12 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_copysign.o) .stab 0x00000000 0x30f0
.stab 0x00000000 0x738 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_sin.o)
.stab 0x00000738 0x930 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(e_rem_pio2.o)
0xd68 (size before relaxing)
.stab 0x00001068 0x480 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_cos.o)
0x8b8 (size before relaxing)
.stab 0x000014e8 0x99c C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_rem_pio2.o)
0xdd4 (size before relaxing)
.stab 0x00001e84 0x384 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(k_sin.o)
0x7bc (size before relaxing)
.stab 0x00002208 0x270 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_fabs.o)
0x6a8 (size before relaxing)
.stab 0x00002478 0x48c C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_floor.o)
0x8c4 (size before relaxing)
.stab 0x00002904 0x4c8 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_scalbn.o)
0x900 (size before relaxing)
.stab 0x00002dcc 0x324 C:\SPE-C2.\sparc-elf\lib\v8/libm.a(s_copysign.o)
0x75c (size before relaxing) .stabstr 0x00000000 0x2521
.stabstr 0x00000000 0x2521 C:\SPE-C2.\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 ;
}

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

gcc, ld的更多相关文章

  1. gcc ld 链接器相关知识,调试指令(程序员的自我修养----链接、装载与库)

    最近解决一个动态链接上的问题,因为以前从来没有接触过这方面的知识,所以恶补了一下,首先要了解gcc编译指令(makefile),ld链接器的选项(还有连接脚本section指定内存位置),熟悉查看连接 ...

  2. Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别

    昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [root@typecodes tcpmsg]# g ...

  3. (转)完全用GNU/Linux工作 by 王珢

    完全用GNU/Linux工作 王珢      (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...

  4. ffmpeg编译参数详解

    Usage: configure [options]用 法:configure [选项]Options: [defaults in brackets after descriptions]选   项: ...

  5. s3c2440 上txt 小说阅读器

    文件结构 Makefile: CROSSCOMPILE := arm-linux- CFLAGS := -Wall -O2 -c LDFLAGS := -lm -lfreetype CC := $(C ...

  6. liunx中字符驱动编写的简单模板

    下面是关于字符驱动两个程序,主要是说明驱动编写的思想,理解驱动是怎么一步一步被实现的. 驱动的第一个实现程序,是相对于裸机编程的,主要是体会一下驱动编程思想: cdev.h: 所包含的头文件 #ifn ...

  7. 转发一篇C++编译器环境搭建的文章

    一.环境配置 1.  下载安装MinGW      地址  http://sourceforge.net/projects/mingw/ 2.  设置环境变量            在path变量中, ...

  8. vbox 虚拟机共享文件夹 debian

    主机64位windows7 虚拟机Debian 8 64位 注意:在网络更新时,可能需要修改 etc/apt/sources.list 文件,把前几条从CD更新删除掉,这样就会从网络更新 1.vbox ...

  9. FFMPEG ./configure 参数及意义

    FFMPEG版本:2.6.2,编译环境:ubuntu 14.4. 不同版本的FFMPEG参数可能不同,可在FFMPEG目录下使用以下命令查看 ./configure --help --help pri ...

随机推荐

  1. Spring Boot2 系列教程 (十七) | 整合 WebSocket 实现聊天室

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 昨天那篇介绍了 WebSocket 实现广播,也即服务器端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器.但 ...

  2. 单词匹配 - hash

    哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. 给你一部魔咒词 ...

  3. CF - 高精度 + 贪心

    Last year Bob earned by selling memory sticks. During each of n days of his work one of the two foll ...

  4. Java动态编译技术原理

    这里介绍Java动态编译技术原理! 编译,一般来说就是将源代码转换成机器码的过程,比如在C语言中中,将C语言源代码编译成a.out,,但是在Java中的理解可能有点不同,编译指的是将java 源代码转 ...

  5. ORM _meta

    import os if __name__ == '__main__': os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'XadminDemon.se ...

  6. 使用整体模型模板辅助器 Using Whole-Model Templated Helpers 模板辅助器方法 精通ASP.NET MVC 5

    怎么会

  7. 从O365中获取users到D365中

    用D365 online可能会遇到这样的问题.  顾客需要获取O365 user的email address 发email使用. 但是又不想给这部分的users licenses. 那我们就可以通过g ...

  8. Python3基础之数据类型(字典)

    Python3数据类型之 字典 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({} ...

  9. Python zmq的三种简单模式

    ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层,像框架一样的一个 socket library,他使得 Socket 编程更加简单.简洁和性能更高. 是一个消息处理队列库,可在多个 ...

  10. GC原理---垃圾收集器

    垃圾收集器 如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现 Serial收集器 串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收.新生代.老 ...