C++ 在64位机器上使用静态链接库编译位置无关的可执行文件

C++ 在64位机器上使用静态链接库编译位置无关的可执行文件,c++,compilation,openssl,static-libraries,32bit-64bit,C++,Compilation,Openssl,Static Libraries,32bit 64bit,当我尝试使用以下命令行编译时: g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable 我收到以下错误消息: /usr/bin/ld: /tmp/ccNHn5FA.o: Die Umlagerung von /tmp/ccNH

当我尝试使用以下命令行编译时:

g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
我收到以下错误消息:

/usr/bin/ld: /tmp/ccNHn5FA.o: Die Umlagerung von 
/tmp/ccNHn5FA.o: error adding symbols: Ungültiger Wert
collect2: error: ld returned 1 exit status
我想知道为什么这不起作用,因为在我的32位机器上,完全相同的命令行可以正常工作。我做错了什么

当我尝试使用以下命令行编译时:

g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
我收到以下错误消息

编辑:我刚刚注意到
-Fpie
。我不相信那是一面真正的旗帜
-fPIC
-fPIE
是编译器标志
-pie
是程序的链接器标志,
-shared
是共享对象的等效链接器标志

/usr/lib/x86_64-linux-gnu/libcrypto.a
中的目标文件需要使用
-fPIC
-fPIE
进行编译

归档只是对象文件的集合。我相信
readelf-rR
会告诉你其中是否有搬迁信息:

$mkdir对象
$cd对象/
$cp/usr/lib/x86_64-linux-gnu/libcrypto.a。
$ar x libcrypto.a
$ls
a_bitstr.o cryptlib.o gost_asn1.o rsa_lib.o
...
$readelf--relocs cryptlib.o
偏移量0x2700处的重定位节“.rela.text”包含133个条目:
偏移信息类型Sym。值符号。名称+加数
000000000008 000400000002 R_X86_64_PC32 0000000000000000.bss+9b
0000000000 10 001f00000004 R_X86_64_PLT32 0000000000000000 BUF_标准-4
...
偏移量0x3378处的“重新定位节”.rela.data.rel.ro.local'包含41个条目:
偏移信息类型Sym。值符号。名称+加数
000000000000000500000001 R_X86_64_64 0000000000000000.rodata.str1.1+3e
000000000008 000500000001 R_X86_64_64 0000000000000000.rodata.str1.1+48
...
偏移量0x3750处的重定位部分“.rela.eh_frame”包含36个条目:
偏移信息类型Sym。值符号。名称+加数
0000000000 20 00020000002 R_X86_64_PC32 0000000000000000.text+0
0000000000 58 00020000002 R_X86_64_PC32 0000000000000000.text+b0
...
对于openssl,最简单的方法可能是下载最新版本,然后配置
shared
以获得
-fPIC
。另请参见OpenSSL wiki上的

相关,请参见。它是在Android环境下提出的,但在这里也适用。它解释了
-fPIC
-fPIE
工作的原因



(评论)为什么这在我的32位机器上工作?当我只使用-fPIC或-fPIE编译时,为什么强化检查(如果是饼图或不是饼图,则检查)的结果是负数

32位和64位有不同的要求,所以我相信在32位i386机器上“一切正常”。但64位x86_64计算机需要
-fPIE
-fPIC
。因为我不知道,其他人会告诉你细节。这里有一个问题/答案可以解释它:

您的强化检查可能失败,因为您使用重新定位信息(
-fPIC
-fPIE
)编译,但您没有链接重新定位信息(
-pie
用于程序或
-shared
用于共享对象)。因此链接器没有将相关部分添加到Elf二进制文件中


与此相关,Tobias Klein有一个整洁的工具,用于审核Elf二进制文件。它与微软的类似


我一直使用它来验收测试二进制文件。(我从事软件安全工作,这是我的诀窍之一,可以确保使用最佳实践按照规范构建程序)。

为什么在我的32位机器上可以这样做?当我只使用-fPIC或-fPIE编译时,为什么强化检查(如果是饼图或不是饼图,则检查)的结果是负数?