초기 조사 :
A.C
extern void b(void);
void a(void);
int main() {
a();
return 0;
}
void a() {
b();
}
b.S
.extern a
b:
jmp a
b.c
012,366,680,653,233,325,565,
$ gcc -c a.c
$ gcc -c b.c -o b_gcc.o
$ as b.S -o b_as.o
$ gcc a.o b_gcc.o -o test_gcc
$ gcc a.o b_as.o -o test_as
a.o: In function `a':
a.c:(.text+0x15): undefined reference to `b'
collect2: error: ld returned 1 exit status
그래서 무엇을주는 출력? GCC가 아닌 GAS는 왜 괜찮습니까?
$ objdump -t b_gcc.o > syms_gcc
$ objdump -t b_as.o > syms_as
$ diff syms_gcc syms_as
2c2
< b_gcc.o: file format elf64-x86-64
---
> b_as.o: file format elf64-x86-64
5d4
< 0000000000000000 l df *ABS* 0000000000000000 b.c
9,12c8
< 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
< 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
< 0000000000000000 l d .comment 0000000000000000 .comment
< 0000000000000000 g F .text 000000000000000b b
---
> 0000000000000000 l .text 0000000000000000 b
좋아, 그래서 gcc
는 b
전역 심볼 있습니다. b.S
에 .global b
을 시도하자 :
$ as b.S -o b_as2.o
$ gcc a.o b_as2.o
$
성공. 그래서 gcc
/ld
은 정적 라이브러리에없는 것에 대한 다중 패스 심볼 해석을 수행합니다. 그러나 만 글로벌 심볼을 찾습니다. 다음은 최종 b.S
:
.extern a
.global b
b:
jmp a
몇 가지 질문입니다. (a) 그 타겟팅은 무엇입니까? yasm, nasm, 가스 같은 것도 없습니다. (b)'a.c'에서 void a()를 선언해야합니다. 그렇지 않으면 컴파일되지 않습니다. (c)'b()'를 C 함수로 변경하고 링크 명령을 시도하는 것이 좋습니다. 필자가 아는 한, 링크에 대해 말하는 종류의 순서 종속성을 얻는 유일한 시간은 정적 라이브러리 링커의 동작입니다. 문제의 실례를주기 위해 질문을 업데이트 할 수 있습니까? – lockcmpxchg8b
그것은로 gnu입니다. 나는 커지면서 운영 체제를 쓰고 있는데, 나는 이런 식으로 생각했다. –
sry, 내 문제는 가스가 내 초기 조사가 윙에 있었다는 것이 었습니다. 적절한 리눅스로 이동하면 내가 잘 당신의 예제를 조립하자. 아래 해결 방법. TL : DR은 'b'가 전역 적이 지 않다는 것이 문제입니다. – lockcmpxchg8b