链接描述文件定义的变量

linker script defined variables

我开发一个程序已经有一段时间了,但最近我买了一台新笔记本电脑,在设置我的开发环境并下载我的存储库的一个新副本后,我收到了以下两个错误。

ingw32/bin/ld.exe: target pei-x86-64 not found
collect2.exe: error: ld returned 1 exit status
mingw32-make: *** [makefile:43: Debug] Error 1

我认为这是一个简单的更正错误,我生成了一个新的链接描述文件并将输出格式从 OUTPUT_FORMAT(pei-x86-64) 更改为 OUTPUT_FORMAT(pei-i386)。我编译它期待一个干净的构建,但是我收到以下错误

./bin/Debug/cryptor.o:main.c:(.cryptor+0x41): undefined reference to `START_OF_PAYLOAD'
./bin/Debug/cryptor.o:main.c:(.cryptor+0x4d): undefined reference to `END_OF_PAYLOAD'

这不是我在我以前的开发框或我一直在调整我的项目的 linux 框中遇到的错误

我一直在使用 mingw32-make.exe 4.2.1 x86_w64-mingw32 在我的新系统上使用 mingw32-make.exe 4.2.1 i686-w64-mingw32

两个系统的代码路径相同。这是 git 克隆

的构建

main.c

__attribute__((constructor(101), section(".cryptor"))) int construct()
{
        extern UINT64 START_OF_PAYLOAD;
        extern UINT64 END_OF_PAYLOAD;

.
.
.
}

win32linker.ld

 .cryptor BLOCK(__section_alignment__) :{
        *(.cryptor)
  }
  .payload BLOCK(__section_alignment__) : {
    START_OF_PAYLOAD = . ;
    *(.payload)


    . = ALIGN(0x200); /*minimum size of a section*/
    END_OF_PAYLOAD = . ;
  }

这两个部分是在 .text 部分之后立即定义的。如果能帮助诊断此问题的根本原因,我将不胜感激。文档也将不胜感激。

提前致谢

编辑

这是我正在使用的 GCC 标志

调试

gcc -c  $(SrcPath)/main.c  -o $(Dpath)/cryptor.o
gcc -c  ./payload/$(Payload)/client/*.c  -o $(Dpath)/payload.o $(INC)
gcc -g -T $(SrcPath)/win32Linker.ld  $(Dpath)/cryptor.o $(Dpath)/payload.o -o $(Dpath)/cryptor.exe

发布

gcc -c  $(SrcPath)/main.c  -o $(Dpath)/cryptor.o
gcc -c  ./payload/$(Payload)/client/*.c  -o $(Dpath)/payload.o $(INC)
gcc -s -static -mwindows -fvisibility=hidden -T $(SrcPath)/win32Linker.ld  $(Rpath)/cryptor.o $(Rpath)/payload.o -o $(Rpath)/cryptor.exe -lCrypt32 -lWs2_32 -lBCrypt

我在 ld --verbose 输出中找到了关于修复此问题的简介。显然,问题的根源归结为名称修改

解决方案很简单,因为我只需要在链接描述文件中解决两种可能的名称修改方案。

  .cryptor BLOCK(__section_alignment__) :{
        *(.cryptor)
  }

  .payload BLOCK(__section_alignment__) : {
        START_OF_PAYLOAD = . ;
        *(.payload)
        . = ALIGN(0x200); /*minimum size of a section*/
    END_OF_PAYLOAD = . ;
  }
  /*
   * took forever to figure this out. apparently, this is the correct way to make
   * sure the variables can be exported
   */
  _START_OF_PAYLOAD = START_OF_PAYLOAD;
  __START_OF_PAYLOAD = START_OF_PAYLOAD;
  _END_OF_PAYLOAD = END_OF_PAYLOAD;
  __END_OF_PAYLOAD = END_OF_PAYLOAD;

现在我导入的符号可以从外部变量中正确读取。接下来就是强制兼容在32bit和64bit架构上都正确,应该是交叉编译兼容的状态。


这最终成为部分解决方案

此外,我必须对头文件做一些工作并添加 search_dir 和 output_format 说明符以使一切以合理的方式工作。这花了一些时间,但这个项目是复杂的,并且是针对多个平台而设计的。但由于这是(由于项目的性质)特定于我的项目的机制,我省略了这些细节,但希望这个答案能解决其他人的问题!