Sto provando a compilare un sorgente con tcc (ver 0.9.26) contro un file .o generato da gcc, ma ha un comportamento strano. Gcc (ver 5.3.0) è di MinGW 64 bit.comportamento strano quando si tenta di compilare un sorgente con tcc contro gcc generato .o file
In particolare, ho i seguenti due file (te1.c te2.c). Ho i seguenti comandi sulla scatola 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!!!
noti che tagliato 4 byte dalla stringa 1234567in dummy!!!\n
. Mi chiedo se cosa potrebbe essere andato storto.
Grazie Jin
======== file di te1.c ===========
#include <stdio.h>
void dummy() {
printf1("1234567in dummy!!!\n");
}
file di ======== 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;
}
Aggiornamento 1
Saw una differenza di assemb tra te1.o (te1.c compilato da tcc) e te1_gcc.o (te1.c compilato da gcc). Nel tcc compilato, ho visto lea -0x4(%rip),%rcx
, sul gcc compilato, ho visto lea 0x0(%rip),%rcx
. Non so perché.
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
Update2
Utilizzando un editor binario, ho cambiato il codice macchina in te1.o (prodotto da gcc) e cambiato lea 0(%rip),%rcx
-lea -0x4(%rip),%rcx
e utilizzando il TCC di collegarlo, le opere exe portato bene. Più precisamente, ho fatto
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!!!
Update 3
Come richiesto, ecco l'output del 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
È probabile che 'tcc' e' gcc' abbiano convenzioni di chiamata predefinite diverse. Potrebbe volerlo controllare. –
Se 'te1.c' ha' extern void printf1 (char * p); 'o include un'intestazione che dichiara' printf() '? – RastaJedi
Problema collaterale: 'extern void dummy();' dovrebbe essere 'extern void dummy (void);', altrimenti 'main()' potrebbe chiamare 'dummy (1,2,3)' senza avviso/errore. – chux