【问题标题】:how to access linker symbol in c code with MinGW?如何使用 MinGW 访问 c 代码中的链接器符号?
【发布时间】:2020-01-23 19:54:59
【问题描述】:

我正在使用 Mingw gcc 和 ld 为 Windows 生成可执行文件。 我想在c代码中访问一段的起始地址,但是我尝试了很多方法,没有一个有效。

我的链接器脚本文件有这个:

  .data BLOCK(__section_alignment__) :
  {
    __data_start__ = . ;
    *(.data)
    *(.data2)
    *(SORT(.data$*))
    KEEP(*(.jcr))
    __data_end__ = . ;
    *(.data_cygwin_nocopy)
  }

在 C 代码中我这样做:

extern char  __data_start__;
uint32_t  test = &__data_start__;

并得到这个错误: 未定义对__data_start__的引用

谁能帮我解决这个问题? 谢谢

【问题讨论】:

  • 一些 ABI 要求符号前导 _(下划线),例如int foo() 将给出符号 _foo;因此,对于 mingw32,定义 ___data_start(3 个前导 _'s)可能会奏效。
  • 感谢您的建议,但不幸的是这也不起作用。
  • 当您与-Wl,-Map,x.map 链接时,您会在地图文件中看到这些符号,即在x.map 中?
  • 是的,我可以看到地图文件中的符号。
  • 奇怪,那么链接器应该能够解决它们。您还可以将 -save-temps 添加到 gcc 选项并检查它定义了相应符号的程序集文件 (*.s)。这些符号也在目标文件 (*.o) 中,并由 nm 显示。在某些全局优化的情况下,gcc 将 module.c 中的符号设为本地。在这种情况下,您可以使用__attribute__((__externally_visible__)) 声明它。

标签: gcc linker mingw


【解决方案1】:

mingw32 使用前导下划线,即编译器将为每个符号添加一个_(下划线)。您显示的链接器描述文件的一部分是默认链接器脚本的一部分(至少在我的安装中),对于您的代码,我收到了提到的错误

int main()
{
    extern char __data_start__;
    return (int) &__data_start__;
}

-save-temps,汇编代码有

    movl    $___data_start__, %eax

其中有 3 领先 _ 而不仅仅是 2。

因此,有两种解决方案:您可以建议编译器发出__data_start__ 作为程序集名称,即GCC extension

int main()
{
    extern char some_identifier __asm("__data_start__");
    return (int) &some_identifier;
}

或者你可以使用_data_start:

int main()
{
    extern char _data_start__;
    return (int) &_data_start__;
}

在程序集/目标文件中都使用__data_start__

    movl    $__data_start__, %eax

i686-w64-mingw32-nm module.o

         U __data_start__

【讨论】:

  • 感谢您的帮助。我使用了第二个选项,它解决了我的错误。
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
相关资源
最近更新 更多