programing

R_X86_64_32S 및 R_X86_64_64 재배치란 무엇입니까?

coolbiz 2022. 7. 4. 23:02
반응형

R_X86_64_32S 및 R_X86_64_64 재배치란 무엇입니까?

64비트 FreeB에서 C 애플리케이션을 컴파일하려고 했을 때 다음 오류가 발생하였습니다.SD:

공유 개체를 만들 때 재배치 R_X86_64_32S를 사용할 수 없습니다. -fPIC로 다시 컴파일하십시오.

뭐가R_X86_64_32S이전과 같은 것R_X86_64_64?

에러에 대해 구글을 검색했습니다.원인이 있을 수 있습니다.R_X86_64_32S의 진의를 알 수 있으면 좋겠습니다.

이 중 하나를 이해하기 위해서는 먼저 다음을 수행해야 합니다.

  • 재배치의 최소한의 예를 참조해 주세요.https://stackoverflow.com/a/30507725/895245
  • ELF 파일의 기본 구조를 이해합니다.https://stackoverflow.com/a/30648229/895245

표준

R_X86_64_64,R_X86_64_32그리고.R_X86_64_32S는 모두 시스템 V AMD ABI에 의해 정의되며, 여기에는 ELF 파일 형식의 AMD64 사양이 포함되어 있습니다.

이러한 값들은 모두 다음 값에서 사용할 수 있는 값입니다.ELF32_R_TYPE재배치 엔트리의 필드(ELF 형식의 아키텍처 중립 부분을 지정하는 System V ABI 4.1(1997)에 규정되어 있습니다.이 표준은 필드만 지정하고 아치 종속 값은 지정하지 않습니다.

4.4.1 "Relocation Types" 아래에 요약 표가 표시됩니다.

Name          Field   Calculation
------------  ------  -----------
R_X86_64_64   word64  A + S
R_X86_64_32   word32  A + S
R_X86_64_32S  word32  A + S

이 표는 나중에 설명하겠습니다.

그리고 메모:

R_X86_64_32그리고.R_X86_64_32S재배치에서는 계산된 값이 32비트로 잘립니다.링커는 R_X86_64_32(R_X86_64_32S) 재배치용으로 생성된 값이 원래 64비트 값으로 제로 확장(부호 확장)되는지 확인해야 합니다.

R_X86_64_64 및 R_X86_64_32의 예

먼저 알아봅시다R_X86_64_64그리고.R_X86_64_32:

.section .text
    /* Both a and b contain the address of s. */
    a: .long s
    b: .quad s
    s:

그 후, 다음과 같이 입력합니다.

as --64 -o main.o main.S
objdump -dzr main.o

내용:

0000000000000000 <a>:
   0:   00 00                   add    %al,(%rax)
                        0: R_X86_64_32  .text+0xc
   2:   00 00                   add    %al,(%rax)

0000000000000004 <b>:
   4:   00 00                   add    %al,(%rax)
                        4: R_X86_64_64  .text+0xc
   6:   00 00                   add    %al,(%rax)
   8:   00 00                   add    %al,(%rax)
   a:   00 00                   add    %al,(%rax)

Ubuntu 14.04, Binutils 2.24로 테스트 완료.

지금은 디스어셈블리를 무시하고(데이터이므로 의미가 없음) 라벨, 바이트 및 재배치만 확인합니다.

첫 번째 재배치:

0: R_X86_64_32  .text+0xc

즉, 다음과 같습니다.

  • 0: 바이트 0(라벨)에 따라 동작합니다.a)
  • R_X86_64_: AMD64 시스템 V ABI의 모든 재배치 유형에 사용되는 프레픽스
  • 32: 라벨의 64비트주소s32비트 주소로 잘려나간 이유는.long(4바이트)
  • .text: 델은.text부분
  • 0xc: 재배치 엔트리의 필드인 추가입니다.

재배치 주소는 다음과 같이 계산됩니다.

A + S

장소:

  • A: 추가, 여기0xC
  • S: 이전 전 기호 값, 여기00 00 00 00 == 0

따라서 재배치 후 새 주소는 0xC == 12바이트가 됩니다..text부분.

이게 바로 우리가 예상했던 거야s다음에 오다.long(4바이트) 및 a.quad(8 바이트).

R_X86_64_64여기서 주소를 잘라낼 필요가 없기 때문에 유사하지만 단순합니다.s이는 표준에서 ~word64대신word32에서Field기둥.

R_X86_64_32S와 R_X86_64_32의 비교

의 차이점R_X86_64_32SR_X86_64_32링커가 "적합하도록 재배치가 잘려 있다"고 불만을 제기하는 경우:

  • 32: 재배치 후 잘린 값이 이전 값을 확장하지 않는 경우(잘린 바이트가 0이어야 함) 불만을 제기합니다.

    예:FF FF FF FF 80 00 00 00로.80 00 00 00에 의해 불만이 발생합니다.FF FF FF FF0이 아닙니다.

  • 32S: 재배치 후 잘린 값이 이전 값을 확장하지 않으면 불만을 제기합니다.

    예:FF FF FF FF 80 00 00 00로.80 00 00 00괜찮아요, 왜냐하면 마지막 부분인80 00 00 00잘린 비트는 모두 1입니다.

다음 항목도 참조하십시오.이 GCC 오류 "..."에 맞게 재배치가 잘렸습니다." " " " " ? ?

R_X86_64_32S다음 방법으로 생성할 수 있습니다.

.section .text
.global _start
_start:
    mov s, %eax
    s:

그 후, 다음과 같이 입력합니다.

as --64 -o main.o main.S
objdump -dzr main.o

제공 내용:

0000000000000000 <_start>:
   0:   8b 04 25 00 00 00 00    mov    0x0,%eax
                        3: R_X86_64_32S .text+0x7

이제 다음 위치에 맞게 잘린 "재배치"를 관찰할 수 있습니다.32S링커 스크립트 사용:

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

지금:

ld -Tlink.ld a.o

문제 없습니다.0xFFFFFFFF80000000로 잘리다80000000부호 확장자입니다.

단, 링커 스크립트를 다음과 같이 변경했을 경우:

. = 0xFFFF0FFF80000000;

이 시점에서 에러가 발생합니다.왜냐하면0더 이상 신호 연장을 하지 않게 만들었죠

사용 이유32S는, 「」를 참조해 주세요.32즉시용:어셈블러가 R_X86_64_32와 같은 0 확장 대신 R_X86_64_32S와 같은 부호 확장 재배치를 사용하는 것이 좋은 때는 언제입니까?

R_X86_64_32S 및 PIE(위치에 의존하지 않는 실행 파일)

는 위치 파일(예: R_X86_64_32S)에서할 수 gcc -pie그렇지 않으면 다음 링크에서 장애가 발생합니다.

relocation R_X86_64_32S against `.text' can not be used when making a PIE object; recompile with -fPIC

l

gcc 및 ld의 위치 독립 실행 파일에 대한 -fPIE 옵션은 무엇입니까?에서 설명하는 최소한의 예를 제시했습니다.

R_X86_64_32S ★★★★★★★★★★★★★★★★★」R_X86_64_64는 amd64 아키텍처용으로 컴파일된 코드의 재배치 유형 이름입니다.모두 amd64 ABI에서 검색할 수 있습니다.그 말에 따르면R_X86_64_64할 수 있습니다.

  • R_X86_64 - 모든 이름 앞에 이 문자가 붙습니다.
  • 64 - 64비트 직접 재배치

★★★★★★★★★★★★★★★★★」R_X86_64_32S 삭제:

  • R_X86_64 - 프리픽스
  • 32S - 값을 32비트로 잘라내고 부호 확장

이는 기본적으로 두 경우 모두 "이번 이전으로 지적된 심볼의 가치와 추가 사항"을 의미합니다.★★★의 R_X86_64_32S링커는 생성된 값이 원래 64비트 값으로 시그널링되는지 확인합니다.

이제 실행 파일에서 코드 및 데이터 세그먼트에는 지정된 가상 기반 주소가 지정됩니다.실행 가능 코드는 공유되지 않으며 각 실행 가능 파일은 자체 새 주소 공간을 가집니다.즉, 컴파일러는 데이터 섹션의 위치를 정확히 알고 있으며 직접 참조할 수 있습니다.반면 라이브러리는 데이터 섹션이 기본 주소에서 지정된 오프셋에 있는 것만 알 수 있습니다. 기본 주소의 값은 실행 시에만 알 수 있습니다.따라서 모든 라이브러리는 메모리 내 어디에 있든 실행할 수 있는 코드(위치 독립 코드(또는 줄여서 PIC))를 사용하여 생성되어야 합니다.

이제 문제를 해결할 때 오류 메시지가 나타납니다.

, , 는, 는, 는을 사용하지 않고 한 것입니다.-fPIC필요에 따라 플래그를 설정합니다.

 gcc -shared foo.c -o libfoo.so # Wrong

전화하셔야 합니다.

 gcc -shared -fPIC foo.c -o libfoo.so # Right

ELF 플랫폼(Linux)에서 공유 객체는 위치 독립 코드(메모리 내의 어느 위치에서나 실행할 수 있는 코드)로 컴파일됩니다.이 플래그를 지정하지 않으면 생성되는 코드는 위치에 따라 다르므로 이 공유 객체를 사용할 수 없습니다.

위의 답변은 이러한 재배치가 무엇인지 보여줍니다.GCC - mcmodel= large 플래그를 사용하여 x86_64 개체를 구축하면 이 모델에서는 컴파일러가 재배치된 주소에 대해 가정하지 않기 때문에 R_X86_64_32S를 방지할 수 있다는 것을 알게 되었습니다.

다음과 같은 경우:

extern int myarr[];

int test(int i)
{
  return myarr[i];
}

gcc -O2 -fno-pie -c test_array.c할 때는 분해해체해 주세요.objdump -drz test_array.o하가있있 있있있다다

 0: 48 63 ff                movslq %edi,%rdi
 3: 8b 04 bd 00 00 00 00    mov    0x0(,%rdi,4),%eax
        6: R_X86_64_32S myarr
 a: c3                      ret    

-mcmodel=large ,, -),gcc -mcmodel=large -O2 -fno-pie -c test_array.c하가있있 있있있다다

 0: 48 b8 00 00 00 00 00    movabs $0x0,%rax
 7: 00 00 00 
        2: R_X86_64_64  myarr
 a: 48 63 ff                movslq %edi,%rdi
 d: 8b 04 b8                mov    (%rax,%rdi,4),%eax
10: c3                      ret    

나는 이 문제에 부딪혔는데 이 대답이 나에게 도움이 되지 않는다는 것을 알았다.정적 라이브러리를 공유 라이브러리와 연결하려고 했습니다.또, -fPIC 스위치를 커맨드 라인에 배치하는 것에 대해서도 조사했습니다(다른 회답에 기재되어 있습니다).이 문제를 해결한 유일한 방법은 정적 라이브러리를 공유로 변경하는 것이었습니다.fPIC 에 관한 에러 메세지는, 여러가지 원인으로 생각할 수 있습니다만, 기본적으로는 라이브러리가 어떻게 구축되고 있는지, 또 다른 방법으로 구축되고 있는지 의심해 보는 것이 좋습니다.

제 경우 컴파일할 프로그램이 리모트디렉토리에서 공유 라이브러리를 찾을 것으로 예상되어 문제가 발생했는데, 그 이유는 대응하는 정적 라이브러리만 실수로 존재했기 때문입니다.

사실 이 재배치 오류는 위장된 파일을 찾을 수 없는 오류입니다.

이 다른 스레드에는 어떻게 대처했는지 자세히 기재되어 있습니다.https://stackoverflow.com/a/42388145/5459638

언급URL : https://stackoverflow.com/questions/6093547/what-do-r-x86-64-32s-and-r-x86-64-64-relocation-mean

반응형