基本的命令 通过预处理、汇编、编译和链接,将源文件编译成可执行文件。 -E: 只预处理目标文件,生成源代码。 例如:">
锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

gcc 编译参数 so查找路径

时间:2023-05-30 04:37:00 wl系列传感器wlcal5

基本的命令">基本的命令

通过预处理、汇编、编译和链接,将源文件编译成可执行文件。

-E: 只预处理目标文件,生成源代码。

例如:g -Etest.cpp -o test.i

-S: 预处理和编译目标文件,生成汇编代码。

例如:g -S test.cpp -o test.s

-o: 预处理、编译和汇编目标文件,生效obj文件。

例如:g -c test.cpp -o test.o

-fsyntax-only : 只检查代码,不做任何其他动作。

常用的安全编译选项

ALSR 随机处理地址

系统级配置不属于gcc编译器的类别。

栈保护

栈保护在编译阶段进行,因此以下参数传输给编译器。

直接上英文, 更容易理解。

  • -fstack-protector:

    Emit extra code to check for buffer overflows, such as stack smashing attacks.
    This is done by adding a guard variable to functions with vulnerable objects.
    This includes functions that call alloca, and functions with buffers larger than
    or equal to 8 bytes. The guards are initialized when a function is entered and
    then checked when the function exits. If a guard check fails, an error message
    is printed and the program exits. Only variables that are actually allocated
    on the stack are considered, optimized away variables or variables allocated in
    registers don’t count.

  • -fstack-protector-all:

    Like ‘-fstack-protector’ except that all functions are protected.

  • -fstack-protector-strong:

    Like ‘-fstack-protector’ but includes additional functions to be protected —
    those that have local array definitions, or have references to local frame addresses. Only variables that are actually allocated on the stack are considered,
    optimized away variables or variables allocated in registers don’t count.

  • -fstack-protector-explicit:

    Like ‘-fstack-protector’ but only protects those functions which have the
    stack_protect attribute.

说明:

  1. 原理是在缓冲区和函数返回控制信息之间插入哨兵变量, 当缓冲区溢出时, 哨兵变量值将首先被覆盖, 这样就可以判断溢出攻击的发生。
  2. 在保护字符数组溢出的同时,使用堆栈保护选项还打算将局部变量中的数组放置在函数堆栈的高地址中,并将其他变量放置在低地址中。
  3. 性能损失:fstack-protector-all > fstack-protector-strong > fstack-protector.

堆栈不能保护

该保护作用于链接阶段,因此需要将参数传递给链接器。 使用-Wl,格式传输到链接器。

使用格式如下:-Wl, -z noexecstack选项。可用于动态库,ELF可执行文件的格式。

作用原理:首先,缓冲区溢出成功后实施shellcode实现攻击目的, 而shellcode只要操作系统限制在缓冲区,只要操作系统限制了堆栈内存区域的不可执行状态,一旦受到攻击,就会报告错误并返回。

GOT表的保护

该保护作用于链接阶段, 也将参数传递给链接器。

使用格式:

  • -Wl, -z relro: Create RELRO program header, RELRO表示 relocation read only, 只读重定位段。 GOT表用于重定位。
  • -Wl, -z now: Mark object non-lazy runtime binding

作用原理:动态链的ELF使用二进制程序称为全局偏移表(GOT)查找表动态分析位于共享库的函数。攻击者通过缓冲区溢出进行修改GOT通过增加表项的函数地址来实现攻击目的。RELRO可以预防选项GOT表被恶意重写。 另外,GOT表的保护会影响程序的加载速度。

代码与地址无关 -fPIC

作用阶段为编译器,参数格式为:-fPIC或者-fpic.

  • -fpic: Generate position-independent code (PIC) suitable for use in a shared library,
    if supported for the target machine. Such code accesses all constant addresses
    through a global offset table (GOT). The dynamic loader resolves the GOT
    entries when the program starts (the dynamic loader is not part of GCC; it
    is part of the operating system). If the GOT size for the linked executable
    exceeds a machine-specific maximum size, you get an error message from the
    linker indicating that ‘-fpic’ does not work; in that case, recompile with ‘-fPIC’
    instead. (These maximums are 8k on the SPARC, 28k on AArch64 and 32k on
    the m68k and RS/6000. The x86 has no such limit.)
    Position-independent code requires special support, and therefore works only on
    certain machines. For the x86, GCC supports PIC for System V but not for the
    Sun 386i. Code generated for the IBM RS/6000 is always position-independent.
    When this flag is set, the macrospicandPICare defined to 1.

  • -fPIC: If supported for the target machine, emit position-independent code, suitable
    for dynamic linking and avoiding any limit on the size of the global offset table.
    This option makes a difference on AArch64, m68k, PowerPC and SPARC.
    Position-independent code requires special support, and therefore works only
    on certain machines

地址与可执行无关 -fPIE

作用于编译器, 参数格式如下:-fPIE或者-fPIC/code>, 与fPIC非常类似。

These options are similar to ‘-fpic’ and ‘-fPIC’, but the generated positionindependent code can be
only linked into executables. Usually these options are used to compile code that will be linked using
the ‘-pie’ GCC option.

说明: PIE是GCC与操作系统的产物,提供了地址无关的功能。 ASLR是基础,只有操作系统开启了ASLR功能时,-fpie选项添加的随机化特征才会在程序加载和运行时展现。

栈检查 -fstack-check

stack-check选项作用于编译器。它会在每个栈空间最低层部分设置一个安全缓冲区,如果函数中申请的栈空间进入了该区域,就会触发异常。对应的英文资料如下:

Generate code to verify that you do not go beyond the boundary of the stack. You should specify this flag if you are running in an environment with multiple threads, but you only rarely need to specify it in a single-threaded environment since stack overflow is automatically detected on nearly all systems if there is only one stack.
Note that this switch does not actually cause checking to be done; the operating system or the language runtime must do that. The switch causes generation of code to ensure that they see the stack being extended.

整数溢出检查 -ftrapv

编译选项,使用了它之后,在执行有符号整数间的加减乘运算时,不是通过CPU的指令,而是用包含了GCC附属库的libgcc.c里面的函数来实现。对性能影响比较大。

忽略栈指针-fomit-frame-pointer和-fno-omit-frame-pointer

如果在编译时指定了-fno-omit-frame-pointer,那么就没有帧指针了,所以也就无法进行栈回溯了,默认有帧指针。backtrace

常用告警选项

-w 选项:

禁止了所有的告警(完全不推荐使用)

-Werror选项:

把所有的警告标识为错误。

-Werror= ** 选项:

把指定的警告标识为错误。

- Wno-error= **选项:

取消指定的警告为错误。

- Wchar-subscripts 选项:

对数组下标为char类型给出警告。这是一个常见的错误。因为大多数char类型为有符号数。

- Wfatal-errors 选项:

编译器遇到第一个错误时,就停止下来,不继续检查更多错误。
我不建议使用, 每次编译就出一个错误,多浪费时间。

-Wreturn-type 选项:

Warn whenever a function is defined with a return type that defaults to int.
当函数定义了非void类型的返回值类型但是没有return时,给出警告。
当函数定义中,没有控制所有的返回值路径时,也会给出警告。

-Wunused选项:

定义了变量不使用,一个函数声明为静态但不定义,函数有返回值,调用了函数不使用(想要避免,加void强转一下), 等等等等, 都会给警告。具体包含了以下这些:

-Wunused-but-set-parameter
-Wunused-but-set-variable
-Wunused-const-variable
-Wunused-const-variable=
-Wunused-dummy-argument
-Wunused-function
-Wunused-label
-Wunused-local-typedefs
-Wunused-macros
-Wunused-parameter
-Wunused-result
-Wunused-value
-Wunused-variable

-Wuninitialized 选项:

变量不初始化就使用, 给警告。
c++类的能成员变量为非静态的引用或者const变量, 如果不使用构造函数进行初始化, 给警告。

Warn if an automatic variable is used without first being initialized. In C++,
warn if a non-static reference or non-static const member appears in a class
without constructors.

Wsign-compare 选项:

对有符号数与无符号数的比较,给出警告。

-Wall 选项:

它打开了一大堆常用的编译告警选项,能覆盖大部分的需求了。

-Waddress
-Warray-bounds=1 (only with ‘-O2’)
-Wbool-compare
-Wbool-operation
-Wc++11-compat -Wc++14-compat
-Wcatch-value (C++ and Objective-C++ only)
-Wchar-subscripts
-Wcomment
-Wduplicate-decl-specifier (C and Objective-C only)
-Wenum-compare (in C/ObjC; this is on by default in C++)
-Wenum-conversion in C/ObjC;
-Wformat
-Wformat-overflow
-Wformat-truncation
-Wint-in-bool-context
-Wimplicit (C and Objective-C only)
-Wimplicit-int (C and Objective-C only)
-Wimplicit-function-declaration (C and Objective-C only)
-Winit-self (only for C++)
-Wlogical-not-parentheses
-Wmain (only for C/ObjC and unless ‘-ffreestanding’)
-Wmaybe-uninitialized
-Wmemset-elt-size
-Wmemset-transposed-args
-Wmisleading-indentation (only for C/C++)
-Wmissing-attributes
-Wmissing-braces (only for C/ObjC)
-Wmultistatement-macros
-Wnarrowing (only for C++)
-Wnonnull
-Wnonnull-compare
-Wopenmp-simd
-Wparentheses
-Wpessimizing-move (only for C++)
-Wpointer-sign
-Wreorder
-Wrestrict
-Wreturn-type
-Wsequence-point
-Wsign-compare (only in C++)
-Wsizeof-pointer-div
-Wsizeof-pointer-memaccess
-Wstrict-aliasing
-Wstrict-overflow=1
-Wswitch
-Wtautological-compare
-Wtrigraphs
-Wuninitialized
-Wunknown-pragmas
-Wunused-function
-Wunused-label
-Wunused-value
-Wunused-variable
-Wvolatile-register-var
-Wzero-length-bounds

-Wextra选项(原为-W, 已经弃用了):

它会打开-Wall选项没有打开的一些编译警告,包括:

-Wclobbered
-Wcast-function-type
-Wdeprecated-copy (C++ only)
-Wempty-body
-Wignored-qualifiers
-Wimplicit-fallthrough=3
-Wmissing-field-initializers
-Wmissing-parameter-type (C only)
-Wold-style-declaration (C only)
-Woverride-init
-Wsign-compare (C only)
-Wstring-compare
-Wredundant-move (only for C++)
-Wtype-limits
-Wuninitialized
-Wshift-negative-value (in C++03 and in C99 and newer)
-Wunused-parameter (only with ‘-Wunused’ or ‘-Wall’)
-Wunused-but-set-parameter (only with ‘-Wunused’ or ‘-Wall’)

 -Wl

表示编译器将后面的参数传递给链接器ld。

-Wl,-rpath-link=./lib

-Wl,-rapth='${ORIGIN}'/lib//ORIGIN elf文件位置,so就是so的位置所在目录

 --enable-new-dtags //-rpath 产生DL_RUNPATH 建议用这个,可以被LD_LIBRARY_PATH覆盖
 --disable-new-dtags
 //-rpath 产生DL_RPATH
 

编译时链接库需要分为两类: 直接引用 间接引用

  • 直接引用 被源码中直接调用的库
  • 间接引用 被调用库的依赖库
  • -lxxx 指定具体的库名称,编译时需要显式指定直接引用的库名称
  • -L 指定链接库的位置,编译时需要显式指定直接引用的库位置
  • -Wl,-rpath-link ,用于编译时指定间接引用的库位置
    如果知道所有间接引用的库文件名称,并且不嫌麻烦,也可以用-lxxx显式指定每一个库(不推荐-lxxx)
  • -Wl,-rpath ,有两个作用:
    1. 用于编译时指定间接引用的库位置,作用同-Wl,-rpath-link
    2. 用于运行时指定所有引用库的位置,作用同修改环境变量(LD_LIBRARY_PATH),并且库路径引用优先级高于LD_LIBRARY_PATH
  • 使用建议
    1. 编译命令中使用-Wl,-rpath-link 指定间接引用库位置(编译时),使用-Wl,-rpath 指定引用库位置(运行时)
    2. -Wl,-rpath-link 在 -Wl,-rpath 前

指定搜索路径的其他方法:

1 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:my_lib_dir


/etc下三个ld.so的条目

$ls /etc/ | grep ld.so
ld.so.cache
ld.so.conf
ld.so.conf.d

ld.so.conf.d是在ld.so.conf中include的

$cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

/usr/local/lib

2 /etc/ld.so.cache中缓存了动态库路径,可以通过修改配置文件/etc/ld.so.conf中指定的动态库搜索路径,然后执行ldconfig命令来改变。

3 放到系统默认搜索路径下,找到缺少的动态库,将其加到/lib,/usr/lib中的一个文件夹下, 系统默认的搜索路径。将库文件放置在其中,运行时就可以搜索到了。

顺序
Unless loading object has RUNPATH:
    RPATH of the loading object,
        then the RPATH of its loader (unless it has a RUNPATH), ...,
        until the end of the chain, which is either the executable
        or an object loaded by dlopen
    Unless executable has RUNPATH:
        RPATH of the executable
LD_LIBRARY_PATH
RUNPATH of the loading object
ld.so.cache
default dirs
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章