gpt4 book ai didi

c++ - 尝试使用 tcc 针对 gcc 生成的 .o 文件编译源代码时出现奇怪的行为

转载 作者:可可西里 更新时间:2023-11-01 15:56:26 25 4
gpt4 key购买 nike

我正在尝试使用 tcc(版本 0.9.26)针对 gcc 生成的 .o 文件编译源代码,但它有奇怪的行为。 gcc (ver 5.3.0) 来自 MinGW 64 位。

更具体地说,我有以下两个文件 (te1.c te2.c)。我在 windows7 框上执行了以下命令

c:\tcc> gcc -c te1.c
c:\tcc> objcopy -O elf64-x86-64 te1.o #this is needed because te1.o from previous step is in COFF format, tcc only understand ELF format
c:\tcc> tcc te2.c te1.o
c:\tcc> te2.exe
567in dummy!!!

请注意,它从字符串 1234567in dummy!!!\n 中截断了 4 个字节。想知道是不是出了什么问题。

谢谢进

========文件te1.c===========

#include <stdio.h>

void dummy () {
printf1("1234567in dummy!!!\n");
}

========文件te2.c===========

#include <stdio.h>

void printf1(char *p) {
printf("%s\n",p);
}
extern void dummy();
int main(int argc, char *argv[]) {
dummy();
return 0;
}

更新 1

看到 te1.o(由 tcc 编译的 te1.c)和 te1_gcc.o(由 gcc 编译的 te1.c)之间的汇编差异。在编译的tcc中,我看到了lea -0x4(%rip),%rcx,在编译的gcc中,我看到了lea 0x0(%rip),%rcx。不知道为什么。

C:\temp>objdump -d te1.o

te1.o: file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <dummy>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 81 ec 20 00 00 00 sub $0x20,%rsp
b: 48 8d 0d fc ff ff ff lea -0x4(%rip),%rcx # e <dummy+0xe>
12: e8 fc ff ff ff callq 13 <dummy+0x13>
17: c9 leaveq
18: c3 retq
19: 00 00 add %al,(%rax)
1b: 00 01 add %al,(%rcx)
1d: 04 02 add $0x2,%al
1f: 05 04 03 01 50 add $0x50010304,%eax

C:\temp>objdump -d te1_gcc.o

te1_gcc.o: file format pe-x86-64


Disassembly of section .text:

0000000000000000 <dummy>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 20 sub $0x20,%rsp
8: 48 8d 0d 00 00 00 00 lea 0x0(%rip),%rcx # f <dummy+0xf>
f: e8 00 00 00 00 callq 14 <dummy+0x14>
14: 90 nop
15: 48 83 c4 20 add $0x20,%rsp
19: 5d pop %rbp
1a: c3 retq
1b: 90 nop
1c: 90 nop
1d: 90 nop
1e: 90 nop
1f: 90 nop

更新2

使用二进制编辑器,我更改了 te1.o 中的机器码(由 gcc 生成)并将 lea 0(%rip),%rcx 更改为 lea -0x4(%rip ),%rcx 并使用 tcc 链接它,生成的 exe 工作正常。更准确地说,我做到了

c:\tcc> gcc -c te1.c
c:\tcc> objcopy -O elf64-x86-64 te1.o
c:\tcc> use a binary editor to the change the bytes from (48 8d 0d 00 00 00 00) to (48 8d 0d fc ff ff ff)
c:\tcc> tcc te2.c te1.o
c:\tcc> te2
1234567in dummy!!!

更新 3

根据要求,这是 objdump -r te1.o

的输出
C:\temp>gcc -c te1.c

C:\temp>objdump -r te1.o

te1.o: file format pe-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
000000000000000b R_X86_64_PC32 .rdata
0000000000000010 R_X86_64_PC32 printf1


RELOCATION RECORDS FOR [.pdata]:
OFFSET TYPE VALUE
0000000000000000 rva32 .text
0000000000000004 rva32 .text
0000000000000008 rva32 .xdata



C:\temp>objdump -d te1.o

te1.o: file format pe-x86-64


Disassembly of section .text:

0000000000000000 <dummy>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 20 sub $0x20,%rsp
8: 48 8d 0d 00 00 00 00 lea 0x0(%rip),%rcx # f <dummy+0xf>
f: e8 00 00 00 00 callq 14 <dummy+0x14>
14: 90 nop
15: 48 83 c4 20 add $0x20,%rsp
19: 5d pop %rbp
1a: c3 retq
1b: 90 nop
1c: 90 nop
1d: 90 nop
1e: 90 nop
1f: 90 nop

最佳答案

tcc 或调用约定无关。它与 elf64-x86-64 和 pe-x86-64 格式的不同链接器约定有关。

使用 PE,链接器将隐式减去 4 来计算最终偏移量。

对于 ELF,它不会这样做。因此,0 是 PE 的正确初始值,-4 是 ELF 的正确初始值。

不幸的是,objcopy 不会转换此 -> objcopy 中的错误。

关于c++ - 尝试使用 tcc 针对 gcc 生成的 .o 文件编译源代码时出现奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38337121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com