배포판에 gcc가 --enable-default-pie
으로 구성되어 있으므로 기본적으로 위치 독립적 실행 파일을 만들고 있습니다 (실행 파일과 라이브러리의 ASLR 허용). 해당 재배치는 PIC/PIE에서 허용되지 않습니다.
gcc -fno-pie -no-pie
을 사용하면이 동작을 이전 동작으로 다시 정의 할 수 있습니다.-no-pie
은 링커 옵션 인 -fno-pie
is the code-gen option입니다. -fno-pie
만 있으면 gcc는 여전히 -pie
과 연결되지 않는 mov eax, offset .LC0
과 같은 코드를 만듭니다.
:
(A July 2017 patch는 GCC와의 compat를 들어, -nopie
에 대한 -no-pie
별칭을 만들어 clang -fno-pie -nopie
,하지만 clang4.0.1는 없습니다. 그 소리는 PIE도 기본적으로 활성화 할 수 있습니다.)
-no-pie
만 있으면 (여전히 -fpie
) 컴파일러 생성 코드는보다 느리지 만 ASLR의 혜택을받지 않는 위치 종속적 실행 파일로 연결됩니다. 패널티는 주로 정적 저장소 클래스가있는 파일 범위 변수 static
대신 전역에 액세스 할 때 발생합니다. -fPIE
은 64 비트 코드에서는 -fPIC
보다 훨씬 나쁘지 만 32 비트에서는 여전히 나쁘다는 점에 유의하십시오. some examples on the Godbolt compiler explorer을 참조하십시오. The sorry state of dynamic libraries on Linux을 참조하십시오.
gcc가 이렇게 구성된 경우 gcc -v |& grep -o -e '[^ ]*pie'
은 --enable-default-pie
을 인쇄합니다. 이 구성 옵션에 대한 지원이 early 2015의 gcc에 추가되었습니다. 우분투는 16.10에서, 데비안은 gcc 6.2.0-7
에서 (커널 빌드 오류 : https://lkml.org/lkml/2016/10/21/904) 같은 시간대에 사용 가능하게했습니다. 관련 항목 : Build compressed x86 kernels as PIE.
그 자체는 기본값을 변경하지 않았습니다. 여전히 정상적으로 작동합니다 (최소한 binutils 2.28을 사용하는 아치 리눅스에서). 변경 사항은 이 명시 적으로 -static
또는 -no-pie
을 사용하지 않는 한 기본적으로 -pie
을 링커 옵션으로 전달한다는 것입니다.
NASM 소스 파일에서 절대 주소를 얻으려면 a32 mov eax, [abs buf]
을 사용했습니다. 관련
nasm -felf64 -Worphan-labels -g -Fdwarf testloop.asm &&
ld -o testloop testloop.o # works
gcc -v -nostdlib testloop.o # doesn't work
...
..../collect2 ... -pie ...
/usr/bin/ld: testloop.o: relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
gcc -v -no-pie -nostdlib testloop.o # works
gcc -v -static -nostdlib testloop.o # also works: -static implies -no-pie
(67 a1 40 f1 60 00
인텔의 CPU에 LCP 스톨)했다 It does을 6 바이트 방법 작은 절대 주소 (주소 크기 + MOV의 EAX, moffs를 인코딩하는 경우 I 테스트 하였다..) building static/dynamic executables with/without libc, defining _start
or main
한다.
file
및 readelf
은 파이가 아니라 실행 "객체를 공유"하는 것을 말한다.
$ gcc -fno-pie -no-pie -O3 hello.c
$ file a.out
a.out: ELF 64-bit LSB executable, ...
$ gcc -O3 hello.c
$ file a.out
a.out: ELF 64-bit LSB shared object, ...
세미는 관련 : 또 다른 최근의 GCC 기능은 gcc -fno-plt
입니다. 마지막으로 공유 라이브러리에 대한 호출은 PLT 트램펄린이없는 call [rip + [email protected]]
(AT & T call *[email protected](%rip)
) 일 수 있습니다.
Distros는 쓰기가 가능한 + 실행 메모리 페이지가 필요 없기 때문에 조만간 지원을 시작할 것입니다. 라이브러리 공유 호출을 많이하는 프로그램의 경우 상당히 빠릅니다. x86-64 clang -O2 -g
tramp3d 컴파일은 하드웨어에 관계없이 41.6s에서 36.8s로 변경됩니다. the patch author tested on. (clang은 공유 라이브러리 호출의 최악의 시나리오 일 수 있습니다.)
지연 연결 대신 초기 바인딩이 필요하므로 즉시 종료되는 큰 프로그램의 경우 속도가 느립니다. (예 : clang --version
또는 hello.c
을 컴파일). 이 속도 저하는 사전 링크를 통해 줄일 수 있습니다.
그러나 PIC 코드의 외부 변수에 대한 GOT 오버 헤드는 제거되지 않습니다. (위의 godbolt 링크 참조).
'-m32'의 경우 이것은 PC를 보관할 소중한 레지스터를 낭비하기 때문에 매우 나쁩니다. 내 64 비트 배포판에서도 플래그가 활성화되어 있으므로'-m32 '도이 플래그를 사용합니다. –