2014-04-23 1 views
3

Windows에서 clang과 ld 버전을 사용하여 Linux ELF 파일에 대한 교차 컴파일을 설정하려고합니다. elf64를 지원하도록 컴파일되었습니다. clang 컴파일 부분은 괜찮습니다. 리눅스에서 링크 될 때 작동하는 ELF obj 파일을 출력합니다. 내 테스트 케이스 cpp는 printf 문을 포함하는 메인 코드이다.Windows에서 Linux 용 교차 컴파일 (링커 출력 파일이 Linux에서 실행 파일로 실행되지 않고 기호가 정의되지 않음)

Windows에서 링크를 시도하려면 우분투에서 모든 라이브러리를 복사하고 올바른 순서로 링커 인수로 필요한 라이브러리를 지정하십시오 (g ++에서 수행하는 ld 호출에 표시됨). 문제는 출력 파일이 linux에서 생성 된 파일과 약간 다르며 실행 파일로 실행되지 않는다는 것입니다. 예를 들어 윈도우에 링크 된 버전에는 리눅스 버전 대신 "puts"가되는 것처럼 보이는 정의되지 않은 심볼 "printf"가 있다는 것을 알았습니다.

아무튼 내가 무슨 일이 일어나고 있는지 아는 사람이 있는지 궁금합니다.

내 실제 연결 인수

는 다음과 같습니다

[email protected]:/shared$ nm ./Test 
0000000000601040 B __bss_start 
0000000000601040 b completed.6992 
0000000000601030 D __data_start 
0000000000601030 W data_start 
0000000000400470 t deregister_tm_clones 
00000000004004e0 t __do_global_dtors_aux 
0000000000600e18 t __do_global_dtors_aux_fini_array_entry 
0000000000601038 D __dso_handle 
0000000000600e28 d _DYNAMIC 
0000000000601040 D _edata 
0000000000601048 B _end 
00000000004005e4 T _fini 
0000000000400500 t frame_dummy 
0000000000600e10 t __frame_dummy_init_array_entry 
0000000000400718 r __FRAME_END__ 
0000000000601000 d _GLOBAL_OFFSET_TABLE_ 
       w __gmon_start__ 
00000000004003e0 T _init 
0000000000600e18 t __init_array_end 
0000000000600e10 t __init_array_start 
00000000004005f0 R _IO_stdin_used 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
0000000000600e20 d __JCR_END__ 
0000000000600e20 d __JCR_LIST__ 
       w _Jv_RegisterClasses 
00000000004005e0 T __libc_csu_fini 
0000000000400550 T __libc_csu_init 
       U [email protected]@GLIBC_2.2.5 
000000000040052d T main 
       U [email protected]@GLIBC_2.2.5 
00000000004004a0 t register_tm_clones 
0000000000400440 T _start 
0000000000601040 D __TMC_END__ 

윈도우에 연결 :

================================================== 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\ld-2.17.so succeeded 
I:\Linux\libs\lib\x86_64-linux-gnu\ld-2.17.so 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crt1.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crt1.o 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crti.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crti.o 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtbegin.o succeeded 
I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtbegin.o 
attempt to open Test.o succeeded 
Test.o 
attempt to open I:\Linux\lib\x86_64-linux-gnu\libstdc++.so.6.0.18 succeeded 
I:\Linux\lib\x86_64-linux-gnu\libstdc++.so.6.0.18 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\libm-2.17.so succeeded 
I:\Linux\libs\lib\x86_64-linux-gnu\libm-2.17.so 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\libgcc.a succeeded 
attempt to open I:\Linux\lib\x86_64-linux-gnu\libc.so succeeded 
opened script file I:\Linux\lib\x86_64-linux-gnu\libc.so 
attempt to open /lib/x86_64-linux-gnu/libc.so.6 succeeded 
/lib/x86_64-linux-gnu/libc.so.6 
attempt to open /usr/lib/x86_64-linux-gnu/libc_nonshared.a succeeded 
(I:/Linux/lib/x86_64-linux-gnu/libc_nonshared.a)elf-init.oS 
attempt to open /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 succeeded 
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
attempt to open I:\Linux\lib\x86_64-linux-gnu\libc_nonshared.a succeeded 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtend.o succeeded 
I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtend.o 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crtn.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crtn.o 
ld-linux-x86-64.so.2 needed by I:/Linux/libs/lib/x86_64-linux-gnu/libc-2.17.so 
found ld-2.17.so at I:\Linux\libs\lib\x86_64-linux-gnu\ld-2.17.so 
리눅스에

================================================== 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o succeeded 
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o succeeded 
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o succeeded 
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o 
attempt to open Test.o succeeded 
Test.o 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so succeeded 
-lstdc++ (/usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so) 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libm.so failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libm.a failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.so succeeded 
-lm (/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.so) 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so succeeded 
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so) 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.so failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a succeeded 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libc.so failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libc.a failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libc.so succeeded 
opened script file /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libc.so 
opened script file /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libc.so 
attempt to open /lib/x86_64-linux-gnu/libc.so.6 succeeded 
/lib/x86_64-linux-gnu/libc.so.6 
attempt to open /usr/lib/x86_64-linux-gnu/libc_nonshared.a succeeded 
(/usr/lib/x86_64-linux-gnu/libc_nonshared.a)elf-init.oS 
attempt to open /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 succeeded 
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so succeeded 
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so) 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.so failed 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a succeeded 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o succeeded 
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o 
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o succeeded 
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o 
ld-linux-x86-64.so.2 needed by /lib/x86_64-linux-gnu/libc.so.6 
found ld-linux-x86-64.so.2 at /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 

나노 출력 :

LFLAGS = --build-id --eh-frame-hdr --oformat elf64-x86-64 -m elf_x86_64 --hash-style=gnu --as-needed -z relro --verbose 

LIBDIRS = -LI:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1 -LI:\\Linux\\libs\\lib\\x86_64-linux-gnu -LI:\\Linux\\libs\\lib -LI:\\Linux\\lib\\x86_64-linux-gnu -LI:\\Linux\\lib 

LIBS = I:\Linux\libs\lib\x86_64-linux-gnu\\ld-2.17.so I:\\Linux\\lib\\x86_64-linux-gnu\\crt1.o I:\\Linux\\lib\\x86_64-linux-gnu\\crti.o I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\crtbegin.o Test.o I:\Linux\lib\x86_64-linux-gnu\\libstdc++.so.6.0.18 I:\Linux\libs\lib\x86_64-linux-gnu\\libgcc_s.so.1 I:\Linux\gcc\x86_64-linux-gnu\4.8.1\\libgcc.a I:\Linux\libs\lib\x86_64-linux-gnu\\libc.so.6 I:\Linux\lib\x86_64-linux-gnu\\libc_nonshared.a I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\crtend.o I:\\Linux\\lib\\x86_64-linux-gnu\\crtn.o 

all: $(MAIN) 
    ./ld-new.exe $(LFLAGS) $(LIBDIRS) $(LIBS) -o Test 

$(MAIN): 
    clang $(CFLAGS) $(SYSINCLUDES) -o $(OBJS) -x c++ $(SRCS) 

리눅스에 연결 01 창 23,516,

nm의 출력은 실행 파일

[email protected]:/shared$ nm ./Test 
0000000000601040 B __bss_start 
0000000000601040 b completed.6992 
0000000000601030 D __data_start 
0000000000601030 W data_start 
0000000000400470 t deregister_tm_clones 
00000000004004e0 t __do_global_dtors_aux 
0000000000600e18 t __do_global_dtors_aux_fini_array_entry 
0000000000601038 D __dso_handle 
0000000000600e28 d _DYNAMIC 
0000000000601040 D _edata 
0000000000601048 B _end 
00000000004005f4 T _fini 
0000000000400500 t frame_dummy 
0000000000600e10 t __frame_dummy_init_array_entry 
0000000000400728 r __FRAME_END__ 
0000000000601000 d _GLOBAL_OFFSET_TABLE_ 
       w __gmon_start__ 
00000000004003d8 T _init 
0000000000600e18 t __init_array_end 
0000000000600e10 t __init_array_start 
0000000000400600 R _IO_stdin_used 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
0000000000600e20 d __JCR_END__ 
0000000000600e20 d __JCR_LIST__ 
       w _Jv_RegisterClasses 
00000000004005f0 T __libc_csu_fini 
0000000000400560 T __libc_csu_init 
       U [email protected]@GLIBC_2.2.5 
0000000000400530 T main 
       U [email protected]@GLIBC_2.2.5 
00000000004004a0 t register_tm_clones 
0000000000400440 T _start 
0000000000601040 D __TMC_END__ 
[email protected]:/shared$ ./Test 
bash: ./Test: No such file or directory 

편집 - 자세한 정보를 생성

으로 내가 우분투는 메시지를주는 말은 실행되지 않습니다 : 여기에

bash: ./Test: No such file or directory 

파일의 결과를/ldd

[email protected]:/shared$ file ./Test 
./Test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xee999db5a0e77d05f50d8fd78a27fc3ac52584b1, not stripped 
[email protected]:/shared$ ldd ./Test 
    linux-vdso.so.1 => (0x00007ffff2bfe000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5e2b60c000) 
    /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f5e2b9eb000) 

EDIT 2-

나는 리눅스에서 정확한 링크 과정을 복제하는 데 더 가까워지고있다. 창에

LFLAGS = --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker I:\\Linux\\libs\\lib\\x86_64-linux-gnu\\ld-2.17.so -z relro --verbose 

LIBDIRS = -LI:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1 -LI:\\Linux\\libs\\lib\\x86_64-linux-gnu -LI:\\Linux\\libs\\lib -LI:\\Linux\\lib\\x86_64-linux-gnu -LI:\\Linux\\lib 

LIBS_BEGIN = I:\\Linux\\lib\\x86_64-linux-gnu\\crt1.o I:\\Linux\\lib\\x86_64-linux-gnu\\crti.o I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\crtbegin.o 
LIBS_END = I:\\Linux\\lib\\gcc\\x86_64-linux-gnu\\4.8.1\\libstdc++.so I:\\Linux\\libs\\lib\\x86_64-linux-gnu\\libgcc_s.so.1 I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\libgcc.a I:\\Linux\\lib\\x86_64-linux-gnu\\libc_nonshared.a I:\\Linux\\libs\\lib\\x86_64-linux-gnu\\ld-linux-x86-64.so.2 I:\\Linux\\libs\\lib\\x86_64-linux-gnu\\libc.so.6 I:\\Linux\\libs\\lib\\x86_64-linux-gnu\\libgcc_s.so.1 I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\libgcc.a I:\\Linux\\gcc\\x86_64-linux-gnu\\4.8.1\\crtend.o I:\\Linux\\lib\\x86_64-linux-gnu\\crtn.o 

all: $(MAIN) 
    ./ld-new.exe $(LFLAGS) -o Test $(LIBS_BEGIN) $(LIBDIRS) $(OBJS) $(LIBS_END) 

업데이트 연결 :

================================================== 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crt1.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crt1.o 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crti.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crti.o 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtbegin.o succeeded 
I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtbegin.o 
attempt to open Test.o succeeded 
Test.o 
attempt to open I:\Linux\lib\gcc\x86_64-linux-gnu\4.8.1\libstdc++.so succeeded 
I:\Linux\lib\gcc\x86_64-linux-gnu\4.8.1\libstdc++.so 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\libgcc_s.so.1 succeeded 
I:\Linux\libs\lib\x86_64-linux-gnu\libgcc_s.so.1 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\libgcc.a succeeded 
attempt to open I:\Linux\lib\x86_64-linux-gnu\libc_nonshared.a succeeded 
(I:\Linux\lib\x86_64-linux-gnu\libc_nonshared.a)elf-init.oS 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\ld-linux-x86-64.so.2 succeede 
d 
I:\Linux\libs\lib\x86_64-linux-gnu\ld-linux-x86-64.so.2 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\libc.so.6 succeeded 
I:\Linux\libs\lib\x86_64-linux-gnu\libc.so.6 
attempt to open I:\Linux\libs\lib\x86_64-linux-gnu\libgcc_s.so.1 succeeded 
I:\Linux\libs\lib\x86_64-linux-gnu\libgcc_s.so.1 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\libgcc.a succeeded 
attempt to open I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtend.o succeeded 
I:\Linux\gcc\x86_64-linux-gnu\4.8.1\crtend.o 
attempt to open I:\Linux\lib\x86_64-linux-gnu\crtn.o succeeded 
I:\Linux\lib\x86_64-linux-gnu\crtn.o 
ld-linux-x86-64.so.2 needed by I:\Linux\libs\lib\x86_64-linux-gnu\libc.so.6 
found ld-linux-x86-64.so.2 at I:\Linux\libs\lib\x86_64-linux-gnu\ld-linux-x86-64 
.so.2 
파일에

업데이트 나노 실행 "테스트"파일에 LLVM-readobj의

0000000000601040 B __bss_start 
0000000000601040 b completed.6992 
0000000000601030 D __data_start 
0000000000601030 W data_start 
0000000000400490 t deregister_tm_clones 
0000000000400500 t __do_global_dtors_aux 
0000000000600e18 t __do_global_dtors_aux_fini_array_entry 
0000000000601038 D __dso_handle 
0000000000600e28 d _DYNAMIC 
0000000000601040 D _edata 
0000000000601048 B _end 
0000000000400614 T _fini 
0000000000400520 t frame_dummy 
0000000000600e10 t __frame_dummy_init_array_entry 
0000000000400748 r __FRAME_END__ 
0000000000601000 d _GLOBAL_OFFSET_TABLE_ 
       w __gmon_start__ 
00000000004003f8 T _init 
0000000000600e18 t __init_array_end 
0000000000600e10 t __init_array_start 
0000000000400620 R _IO_stdin_used 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
0000000000600e20 d __JCR_END__ 
0000000000600e20 d __JCR_LIST__ 
       w _Jv_RegisterClasses 
0000000000400610 T __libc_csu_fini 
0000000000400580 T __libc_csu_init 
       U [email protected]@GLIBC_2.2.5 
0000000000400550 T main 
       U [email protected]@GLIBC_2.2.5 
00000000004004c0 t register_tm_clones 
0000000000400460 T _start 
0000000000601040 D __TMC_END__ 

결과 :

I:\LLVM_BUILD\VC12\64\Release\bin>llvm-readobj -file-headers Test 

File: Test 
Format: ELF64-x86-64 
Arch: x86_64 
AddressSize: 64bit 
LoadName: 
ElfHeader { 
    Ident { 
    Magic: (7F 45 4C 46) 
    Class: 64-bit (0x2) 
    DataEncoding: LittleEndian (0x1) 
    FileVersion: 1 
    OS/ABI: SystemV (0x0) 
    ABIVersion: 0 
    Unused: (00 00 00 00 00 00 00) 
    } 
    Type: Executable (0x2) 
    Machine: EM_X86_64 (0x3E) 
    Version: 1 
    Entry: 0x400460 
    ProgramHeaderOffset: 0x40 
    SectionHeaderOffset: 0x11C0 
    Flags [ (0x0) 
    ] 
    HeaderSize: 64 
    ProgramHeaderEntrySize: 56 
    ProgramHeaderCount: 9 
    SectionHeaderEntrySize: 64 
    SectionHeaderCount: 30 
    StringTableSectionIndex: 27 

실제 연결된 육체가있는 실행 파일 파일 자체 :

https://dl.dropboxusercontent.com/u/1735585/Test 
+1

파일에 현재 사용자의 실행 권한이 있습니까? –

+0

예 ls -l : -rwxr-xr-x 1의 결과 kk 8594 Apr 23 11:56 테스트 – user2380227

+0

glibc와 같은 라이브러리의 특정 버전과 연결하려는 경우 해당 헤더와 함께 컴파일하는 것이 좋습니다 동일한 버전의 라이브러리. –

답변

4

"해당 파일 또는 디렉토리 없음"오류는 파일이 존재하고 실행 가능하면 약간 혼란 스러울 수 있습니다. ELF 인터프리터 (공유 라이브러리 링크를 수행하는 프로그램)가없는 경우 파일 실행시에도 오류가 발생합니다.

여기가 발생합니다. readelf -l Test에서 관련 라인 :

INTERP   0x0000000000000238 0x0000000000400238 0x0000000000400238 
       0x000000000000002e 0x000000000000002e R  1 
    [Requesting program interpreter: I:\Linux\libs\lib\x86_64-linux-gnu\ld-2.17.so] 

분명히 인터프리터는 리눅스 시스템에서 찾을 수 없습니다. 어떤 이유로 ldd은 해당 항목에 대한 올바른 인터프리터에 파일 매핑을 보여줍니다.

Windows 빌드 환경에서 문제를 해결하는 방법을 알려줄 수는 없지만 올바른 해석기를 사용하면 ldd은 매핑을 표시하지 않습니다. 예 :

$ ldd /bin/true 
    linux-vdso.so.1 (0x00007fff1bbff000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f94ff99f000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007f94ffd73000) 
+0

['patchelf' tool] (https://nixos.org/patchelf.html)은 저자가 기존 ELF 파일에서 인터프리터를 변경할 수 있도록합니다. 빠른 점검에 사용할 수 있습니다. Andreas, 대답 해줘서 고마워! – osgx

+0

답변을 수락하는 데 지연되어 죄송합니다. 당신은 절대적으로 정확하고 통역사를 패치하면 문제가 해결됩니다. ld를 수정 한 후에는 리눅스와 완벽하게 교차 할 수있게되었습니다. 내 질문에 대답 할 시간을 내 주셔서 고맙습니다. 정말 고마워요! – user2380227