gcc의 on-function-section 및 -f 데이터-section 옵션 쿼리
아래는 기능 섹션 및 데이터 섹션 옵션에 대한 GCC 페이지에 나와 있습니다.
-ffunction-sections -fdata-sections
대상이 임의 섹션을 지원하는 경우 각 함수 또는 데이터 항목을 출력 파일의 해당 섹션에 배치합니다.함수의 이름 또는 데이터 항목의 이름에 따라 출력 파일의 섹션 이름이 결정됩니다.링커가 최적화를 수행하여 명령 공간의 참조 위치를 개선할 수 있는 시스템에서 이 옵션을 사용합니다.ELF 개체 형식을 사용하는 대부분의 시스템과 Solaris 2를 실행하는 SPARC 프로세서에는 이러한 최적화 기능이 있는 링커가 있습니다. AIX는 향후 이러한 최적화 기능이 있을 수 있습니다.
이러한 옵션은 이러한 옵션을 사용함으로써 상당한 이점이 있을 때만 사용하십시오.이러한 옵션을 지정하면 어셈블리 및 링커가 더 큰 개체 및 실행 파일을 생성하고 속도가 느려집니다.이 옵션을 지정하면 모든 시스템에서 gprof를 사용할 수 없으며 이 옵션과 -g를 모두 지정하면 디버깅에 문제가 있을 수 있습니다.
이러한 옵션이 실행 파일 크기를 줄이는 데 도움이 될 것이라는 생각이 들었습니다.이 페이지에 더 큰 실행 파일을 만들 것이라고 표시되는 이유는 무엇입니까?내가 뭘 빼놓았나요?
흥롭게도를 사용하는 것은 하기용사입니다.-fdata-sections
사용자의 함수 풀을 문자 그대로 만들 수 있으므로 함수 자체를 더 크게 만들 수 있습니다.저는 특히 ARM에서 이것을 발견했지만, 다른 곳에서는 사실일 가능성이 높습니다.제가 테스트한 바이너리는 0.25% 성장하는데 그쳤지만, 성장했습니다.변경된 기능의 분해를 보면 그 이유를 알 수 있었습니다.
개체 파일의 모든 BSS(또는 DATA) 항목이 단일 섹션에 할당된 경우 컴파일러는 해당 섹션의 주소를 함수 리터럴 풀에 저장하고 함수의 해당 주소에서 알려진 오프셋으로 로드를 생성하여 데이터에 액세스할 수 있습니다. 하만활하면화성지면을 하면.-fdata-sections
각 BSS(또는 DATA) 데이터 조각을 자체 섹션에 배치하고, 이러한 섹션 중 어떤 섹션이 나중에 가비지 수집되는지 또는 링커가 이 모든 섹션을 최종 실행 이미지에 배치할 순서를 모르기 때문에 단일 주소의 오프셋을 사용하여 더 이상 데이터를 로드할 수 없습니다.따라서 사용된 데이터별로 리터럴 풀의 항목을 할당해야 합니다. 링커가 최종 이미지에 무엇이 들어가고 어디로 가는지 파악한 후에는 데이터의 실제 주소로 리터럴 풀 항목을 수정할 수 있습니다.
는▁with▁so,네,지서.-Wl,--gc-sections
실제 함수 텍스트가 더 크기 때문에 결과 이미지가 더 커질 수 있습니다.
아래에 최소한의 예를 추가했습니다.
아래 코드는 제가 말하는 행동을 확인하기에 충분합니다.실제 코드에서 의심스러운 글로벌 변수의 변동성 선언과 사용에 당황하지 마십시오.여기서 -f 데이터 섹션을 사용할 때 두 개의 데이터 섹션을 만들 수 있습니다.
static volatile int head;
static volatile int tail;
int queue_empty(void)
{
return head == tail;
}
이 테스트에 사용되는 GCC 버전은 다음과 같습니다.
gcc version 6.1.1 20160526 (Arch Repository)
첫째, -f 데이터 섹션이 없으면 다음과 같은 정보를 얻을 수 있습니다.
> arm-none-eabi-gcc -march=armv6-m \
-mcpu=cortex-m0 \
-mthumb \
-Os \
-c \
-o test.o \
test.c
> arm-none-eabi-objdump -dr test.o
00000000 <queue_empty>:
0: 4b03 ldr r3, [pc, #12] ; (10 <queue_empty+0x10>)
2: 6818 ldr r0, [r3, #0]
4: 685b ldr r3, [r3, #4]
6: 1ac0 subs r0, r0, r3
8: 4243 negs r3, r0
a: 4158 adcs r0, r3
c: 4770 bx lr
e: 46c0 nop ; (mov r8, r8)
10: 00000000 .word 0x00000000
10: R_ARM_ABS32 .bss
> arm-none-eabi-nm -S test.o
00000000 00000004 b head
00000000 00000014 T queue_empty
00000004 00000004 b tail
arm-none-eabi-nm
이고 queue_empty는 20바이트(1416진수)입니다.arm-none-eabi-objdump
출력은 함수의 끝에 단일 재배치 단어가 있음을 나타냅니다. 이는 BSS 섹션(초기화되지 않은 데이터 섹션)의 주소입니다.함수의 첫 번째 명령은 해당 값(BSS의 주소)을 r3에 로드합니다.다음 두 명령은 r3에 상대적으로 로드되어 각각 0 및 4바이트씩 오프셋됩니다.이 두 하중은 머리와 꼬리 값의 하중입니다.다음 출력의 첫 번째 열에서 오프셋을 확인할 수 있습니다.arm-none-eabi-nm
.nop
기능의 끝에 있는 것은 리터럴 풀의 주소를 워드 정렬하는 것입니다.
다음으로 -fdata-sections가 추가되면 어떻게 되는지 살펴보겠습니다.
arm-none-eabi-gcc -march=armv6-m \
-mcpu=cortex-m0 \
-mthumb \
-Os \
-fdata-sections \
-c \
-o test.o \
test.c
arm-none-eabi-objdump -dr test.o
00000000 <queue_empty>:
0: 4b03 ldr r3, [pc, #12] ; (10 <queue_empty+0x10>)
2: 6818 ldr r0, [r3, #0]
4: 4b03 ldr r3, [pc, #12] ; (14 <queue_empty+0x14>)
6: 681b ldr r3, [r3, #0]
8: 1ac0 subs r0, r0, r3
a: 4243 negs r3, r0
c: 4158 adcs r0, r3
e: 4770 bx lr
...
10: R_ARM_ABS32 .bss.head
14: R_ARM_ABS32 .bss.tail
arm-none-eabi-nm -S test.o
00000000 00000004 b head
00000000 00000018 T queue_empty
00000000 00000004 b tail
즉시 queue_empty의 길이가 4바이트 증가하여 24바이트(1816진수)가 되었으며 queue_empty의 리터럴 풀에서 수행해야 할 두 개의 재배치가 있음을 알 수 있습니다.이러한 재배치는 각 글로벌 변수에 대해 하나씩 생성된 두 BSS 섹션의 주소에 해당합니다.컴파일러는 링커가 두 섹션을 삽입하게 될 상대적 위치를 알 수 없기 때문에 여기에 두 개의 주소가 있어야 합니다.queue_empty의 시작 부분에 있는 명령어를 보면 추가 로드가 있음을 알 수 있습니다. 컴파일러는 섹션의 주소와 해당 섹션의 변수 값을 얻기 위해 별도의 로드 쌍을 생성해야 합니다.이 버전의 queue_empty에서 추가 명령어를 사용하면 함수의 본문이 길어지는 것이 아니라 이전에 사용하지 않았던 자리를 차지할 뿐이지만 일반적으로는 그렇지 않습니다.
이러한 컴파일러 옵션을 사용할 때 링커 옵션을 추가할 수 있습니다.-Wl,--gc-sections
사용되지 않는 모든 코드를 제거합니다.
사용할 수 있습니다.-ffunction-sections
그리고.-fdata-sections
각 함수와 전역 데이터 변수가 별도의 섹션에 배치되므로 정적 라이브러리의 크기가 증가합니다.
그런 다음 사용합니다.-Wl,--gc-sections
이 정적 라이브러리와 연결된 프로그램에서 사용되지 않는 섹션을 제거합니다.
따라서 이러한 플래그가 없는 경우보다 최종 이진수가 더 작아집니다.
하지만 조심하세요, 왜냐하면-Wl,--gc-sections
물건을 부술 수 있습니다.
추가 단계를 추가하고 더 나은 결과를 얻을 수 있습니다..a
보관:
- 는 첫, gcc와 g++와 함께 됩니다.
-ffunction-sections
-fdata-sections
- 그 다음에
.o
는 물이안들니다어에 ..a
으로 합니다.ar rcs file.a *.o
- 마지막으로, 링커는 다음과 같이 호출됩니다.
-Wl,-gc-sections,-u,main
션들 - 모두를 위해, 최적화는 다음과 같이 설정됩니다.
-Os
.
얼마 전에 시도해봤는데 결과를 보니 정렬이 다른 물체의 순서에 따라 크기가 증가한 것 같습니다.일반적으로 링커는 개체를 정렬하여 두 개체 사이의 패딩을 작게 유지하지만 개별 섹션 간이 아니라 섹션 내에서만 작동하는 것처럼 보입니다.따라서 각 함수에 대해 데이터 섹션 사이에 추가 패딩이 발생하여 전체 공간이 증가하는 경우가 많습니다.
-Wl,-gc-sections가 있는 정적 lib의 경우, 사용되지 않는 섹션을 제거하면 작은 증가를 보충할 가능성이 높습니다.
언급URL : https://stackoverflow.com/questions/4274804/query-on-ffunction-section-fdata-sections-options-of-gcc
'programing' 카테고리의 다른 글
백분율 계산 (0) | 2023.06.11 |
---|---|
Visual Studio Code에서 Python용 가상 환경을 설정하려면 어떻게 해야 합니까? (0) | 2023.06.11 |
R마크다운에서 코드를 표시하고 출력을 숨기는 방법은 무엇입니까? (0) | 2023.06.11 |
WooCommerce에서 결제가 없는 경우 X일 후 자동으로 주문 취소 (0) | 2023.06.11 |
Mysql 로드의 임의 피크가 모든 사용자를 느리게 함 (0) | 2023.06.11 |