g ++,静态初始化和-nostdlib

问题描述 投票:12回答:2

即使使用-nostdlib / .init节添加自己的crti.s和crtn.s,[.fini编译/链接似乎也阻止了静态初始化。

是否有解决方法可以使g ++生成插入在.init中或可以手动调用的静态初始化代码?

这是我尝试过的:

g++ -o test.o -c -fno-use-cxa-atexit test.cc  # has _start (entry point) 
                                              #   that calls _init and _main
as -o crti.o crti.s      # has _init in section .init
as -o crtn.o crtn.s
g++ -o test ./crti.o test.o -nodefaultlibs -nostartfiles ./crtn.o

[-nodefaultlibs仅包括静态初始化代码和调用,但强制使用libc-_start / _init。

-nodefaultlibs -nostartfiles允许我使用自己的_start / _init,但不包括代码或对静态初始化的调用。

gcc g++ static-initialization
2个回答
11
投票

来自gcc linker docs

-nostdlib

请勿在以下情况下使用标准的系统启动文件或库链接。 没有启动文件,只有指定的库传递给链接器,以及指定系统链接的选项库,例如-static-libgcc或-shared-libgcc,将被忽略。

因此使用,

-nodefaultlibs

链接时请勿使用标准系统库。 仅将您指定的库传递到链接器,将忽略指定系统库链接的选项,例如-static-libgcc或-shared-libgcc。 除非使用-nostartfiles,否则通常使用标准启动文件。编译器可能会生成对memcmp,memset,memcpy和memmove的调用。这些条目通常由libc中的条目解析。指定此选项后,应通过其他某种机制来提供这些入口点。

也尝试,

g++ -Wl, -static

-Wl      passes the next command on to the linker
-static  On systems that support dynamic linking, this prevents linking with 
         the shared libraries. On other systems, this option has no effect.

0
投票

我也在解决这个问题。

从我的.cc文件生成程序集,找到以下代码。

似乎有两个标签值得关注。第一个是我未编写的函数,它分解为:

“ __ static_initialization_and_destruction_0(int,int)”

似乎有第二个函数调用此函数,其中两个整数似乎是直肠拔出的乘积。这个叫做“ _GLOBAL__sub_I_main”。根据c ++ filt的说法,它没有被打乱,只是看起来像那样。 :)

如果在我的.cc文件中添加_GLOBAL__sub_I_main的声明,并在main中调用它,则我的静态变量将正确初始化。不过,我不确定如何告诉链接器执行其操作。有谣言说-Ur会这样做,但是到目前为止我的结果一直令人困惑。

我以为我可以编写一个程序在目标文件上运行nm,并编写一个全局函数来调用它们,但是我不确定如何调用它们,因为我假定它们将具有每个目标文件中的名称相同。

嗯.....

    movl    $0, %eax    #, _15
    addq    $56, %rsp   #,
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE26:
    .size   main, .-main
    .type   _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB27:
    .cfi_startproc
    subq    $24, %rsp   #,
    .cfi_def_cfa_offset 32
    movl    %edi, 12(%rsp)  # __initialize_p, __initialize_p
    movl    %esi, 8(%rsp)   # __priority, __priority
    cmpl    $1, 12(%rsp)    #, __initialize_p
    jne .L35    #,
    cmpl    $65535, 8(%rsp) #, __priority
    jne .L35    #,
    call    calc    #
    movl    %eax, _ZL8stat_int(%rip)    # _1, stat_int
.L35:
# bin/static.cc:38: };
    nop
    addq    $24, %rsp   #,
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE27:
    .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
    .type   _GLOBAL__sub_I__Z9write_hexm, @function
_GLOBAL__sub_I__Z9write_hexm:
.LFB28:
    .cfi_startproc
    subq    $8, %rsp    #,
    .cfi_def_cfa_offset 16
    movl    $65535, %esi    #,
    movl    $1, %edi    #,
    call    _Z41__static_initialization_and_destruction_0ii #
    addq    $8, %rsp    #,
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE28:
    .size   _GLOBAL__sub_I__Z9write_hexm, .-_GLOBAL__sub_I__Z9write_hexm
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I__Z9write_hexm
    .section    .rodata
    .align 8
    .type   _ZZ4calcE19__PRETTY_FUNCTION__, @object
    .size   _ZZ4calcE19__PRETTY_FUNCTION__, 11
_ZZ4calcE19__PRETTY_FUNCTION__:
    .string "int calc()"
    .align 16
    .type   _ZZ4mainE19__PRETTY_FUNCTION__, @object
    .size   _ZZ4mainE19__PRETTY_FUNCTION__, 22
_ZZ4mainE19__PRETTY_FUNCTION__:
    .string "int main(int, char**)"
    .ident  "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
    .section    .note.GNU-stack,"",@progbits
© www.soinside.com 2019 - 2024. All rights reserved.