programing

이 GCC 오류 "..."에 맞게 재배치가 잘렸습니다." " " " " ? ?

prostudy 2022. 7. 24. 21:13
반응형

이 GCC 오류 "..."에 맞게 재배치가 잘렸습니다." " " " " ? ?

호스트 액셀러레이터 시스템의 호스트 측을 프로그래밍하고 있습니다.호스트는 Ubuntu Linux의 PC에서 실행되며 USB 연결을 통해 내장 하드웨어와 통신합니다.통신은 임베디드 하드웨어의 메모리 간에 메모리 청크를 복사하여 수행됩니다.

보드의 메모리에는 데이터를 쓰고 읽는 메일박스로 사용하는 메모리 영역이 있습니다.우편함은 구조체로 정의되며 동일한 정의를 사용하여 호스트 공간에 미러 우편함을 할당합니다.

과거에 이 기술을 성공적으로 사용했기 때문에 현재 프로젝트의 워크스페이스에 호스트 Eclipse 프로젝트를 복사하여 적절한 이름을 변경했습니다.이상한 점은 호스트 프로젝트를 빌드할 때 다음과 같은 메시지가 나타난다는 것입니다.

구축 대상: fft2d_host
호출: GCC C 링커
gcc -L/opt/adapteva/esdk/tools/host/x86_64/lib -o "fft2d_host" ./src/fft2d_host.o -le_host -lrt

./src/fft2d_host.o: 함수 'main'에서:

fft2d_host.c:(.text+0x280): 위치에 맞게 잘린 재배치: ./src/fft2d_host.o의 COMMON 섹션에 정의된 기호 '메일함'에 대한 R_X86_64_PC32

이 오류는 무엇을 의미하며 이전 프로젝트에서 문제가 없는데도 현재 프로젝트를 기반으로 구축되지 않는 이유는 무엇입니까?

상대 주소 지정 방식의 대상이 선택한 상대 주소 지정 모드의 32비트 변위에서 지원할 수 있는 것보다 더 멀리 떨어져 있도록 프로젝트를 링크하려고 합니다.이는 현재 프로젝트가 더 크거나 오브젝트 파일을 다른 순서로 링크하거나 불필요하게 확장적인 매핑 스킴이 있기 때문일 수 있습니다.

이 질문은 오류 메시지의 일반적인 부분에 대해 웹 검색을 수행하는 것이 효율적인 이유를 보여주는 완벽한 예입니다. 다음과 같은 내용을 찾을 수 있습니다.

http://www.technovelty.org/code/c/relocation-truncated.html

몇 가지 치료법을 제안해 주죠.

오류를 생성하는 최소 예제

main.S주소 이동처%eax(32비트).

메인

_start:
    mov $_start, %eax

linker.ld

SECTIONS
{
    /* This says where `.text` will go in the executable. */
    . = 0x100000000;
    .text :
    {
        *(*)
    }
}

x86-64로 컴파일:

as -o main.o main.S
ld -o main.out -T linker.ld main.o

결과ld:

(.text+0x1): relocation truncated to fit: R_X86_64_32 against `.text'

다음 사항에 유의하십시오.

  • as모든 것을 걸다.text다른 섹션이 지정되지 않은 경우
  • ld를 사용합니다..text디폴트 엔트리 포인트로서ENTRY.따라서_start의 첫 번째 바이트입니다..text.

수정 방법: 사용 방법linker.ld대신 시작에서 1을 빼십시오.

SECTIONS
{
    . = 0xFFFFFFFF;
    .text :
    {
        *(*)
    }
}

주의:

  • 우리는 만들 수 없다_start를 사용한 이 예에서는 글로벌.global _start그렇지 않으면 실패합니다.글로벌 심볼에 정렬 제약이 있기 때문에 이러한 현상이 발생한다고 생각합니다.0xFFFFFFF0동작합니다).TODO는 ELF 표준에서 어디에 문서화되어 있습니까?

  • .text세그먼트에는 정렬 제약도 있습니다.p_align == 2M단, 링커는 세그먼트를 다음 위치에 배치할 수 있을 정도로 스마트합니다.0xFFE00000, 0 으로 채웁니다.0xFFFFFFFF및 세트e_entry == 0xFFFFFFFF이 방법은 작동하지만 크기가 큰 실행 파일을 생성합니다.

Ubuntu 14.04 AMD64, Binutils 2.24에서 테스트 완료.

설명.

우선 최소한의 예시로 재배치가 무엇인지 이해할 필요가 있습니다.https://stackoverflow.com/a/30507725/895245

다음으로, 다음 항목을 살펴봅니다.objdump -Sr main.o:

0000000000000000 <_start>:
   0:   b8 00 00 00 00          mov    $0x0,%eax
                        1: R_X86_64_32  .text

인텔의 메뉴얼에 기재되어 있는 순서를 보면, 다음과 같습니다.

  • b8이건...mov로.%eax
  • 0즉시 이동할 수 있는 값입니다.%eax. 재배치에 의해, 다음의 주소가 포함되게 됩니다._start.

32비트 레지스터로 이동하는 경우 즉시 32비트여야 합니다.

단, 여기서 재배치는 32비트를 수정하여 주소 저장해야 합니다._start연결되면 그 안에 들어갈 수 있습니다.

0x10000000032비트에 맞지 않지만0xFFFFFFFF그래요. 그래서 오류입니다.

이 에러는, 예를 들면, 잘라내기를 생성하는 재배치에서만 발생합니다.R_X86_64_32(8 ~ 4 바이트), 단, 켜지지 않음R_X86_64_64.

또한 다음과 같이 확장 0 대신 부호 확장이 필요한 재배치 유형이 있습니다.R_X86_64_32S. 도 참조해 주세요.https://stackoverflow.com/a/33289761/895245

R_AARCH64_PREL32

질문: aarch64 베어메탈 프로그램을 만들 때 "main.o:(.eh_frame+0x1c)": "R_AARCH64_PREL32"가 ".text"에 맞도록 잘린 재배치를 방지하는 방법:

Cygwin에 대해서-mcmodel=medium는 이미 기본값이므로 도움이 되지 않습니다.나에게 추가-Wl,--image-base -Wl,0x10000000에러를 수정했습니다.

대부분의 경우 이 오류는 프로그램이 너무 크다는 을 의미하며, 하나 이상의 매우 큰 데이터 개체가 포함되어 있기 때문에 프로그램이 너무 크다는 것을 의미합니다.예를들면,

char large_array[1ul << 31];
int other_global;
int main(void) { return other_global; }

는 x86-64/Linux에서 디폴트모드로 컴파일되어 최적화가 이루어지지 않은 경우 "relocation truncated to fit" 오류가 발생합니다.(최적화를 켜면 적어도 이론적으로는large_array미사용 및/또는other_global는 기입되지 않기 때문에, 문제를 일으키지 않는 코드를 생성합니다.)

디폴트로는 GCC는 이 아키텍처에서 "소형 코드 모델"을 사용합니다.이 아키텍처에서는 프로그램의 코드와 정적으로 할당된 데이터는 모두 주소 공간의 최소 2GB에 맞춰야 합니다.(정확한 상한은 약 2GB~2MB입니다.모든 프로그램의 주소 공간 중 가장 낮은 2MB는 영구적으로 사용할 수 없기 때문입니다.공유 라이브러리 또는 위치에 의존하지 않는 실행 파일을 컴파일 하는 경우, 모든 코드와 데이터는 2기가바이트에 들어갈 필요가 있지만 주소 공간 하단에 고정되지 않습니다.) large_array 다 소비하기 에, consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumes consumesother_global, 「」에 대해 , 「」에 대해서, 「」가 할당되어 있습니다.main도달할 수 없습니다. 오류가 오류는 이 됩니다.large_array는 이 에러를 알입니다.복잡한 경우 컴파일러는 다음 사항을 알 수 없기 때문입니다.other_global손이 닿지 않을 테니까 간단한 사건에는 시도조차 안 해요.

대부분의 경우, 이 에러가 발생했을 때의 올바른 대응은, 거대한 정적 어레이나 기가바이트의 머신 코드를 필요로 하지 않게, 프로그램을 리팩터링 하는 것입니다.단, 어떤 이유로 꼭 필요한 경우에는 "중간" 또는 "대형" 코드 모델을 사용하여 다소 덜 효율적인 코드 생성 가격으로 제한을 해제할 수 있습니다.이러한 코드 모델은 x86-64에 특화되어 있습니다.다른 대부분의 아키텍처에서도 비슷한 것이 존재하지만, 정확한 "모델" 집합과 관련된 제한은 다릅니다.(예를 들어 32비트 아키텍처에서는 코드와 데이터의 총량이 2바이트 정도로24 제한되는 "작은" 모델이 있을 수 있습니다.)

스택스페이스가 2GiB가 넘는 큰 프로그램을 작성하다가 이 문제가 발생하였습니다.해결방법은 GCC와 인텔의 컴파일러가 모두 지원하는 플래그를 추가하는 것이었습니다.

에러 메세지의 순서에 따라 대처해 주세요.내 경우 위의 오류는 "정의되지 않은 참조"였고, 더 흥미로운 "로케이션 잘라내기" 오류로 시각적으로 건너뛰었습니다.사실, 제 문제는 "정의되지 않은 참조" 메시지를 야기하는 오래된 라이브러리였습니다.그것을 고치고 나서, 「재배치 잘림」도 없어졌습니다.

저도 똑같은 문제에 부딪혔어요.후 " " "를 하지 않음-fexceptions 플래그,, " " " "

언급URL : https://stackoverflow.com/questions/10486116/what-does-this-gcc-error-relocation-truncated-to-fit-mean

반응형