2017-03-21 5 views
0

-fpie를 사용하여 ARM 용으로 컴파일 된 코드 모듈이 있으며 처음 실행될 때 BSS를 지우고 싶습니다. 그러나 BSS 섹션의 시작과 끝 부분에 대한 링커 스크립트 심볼을 참조하면 로컬 변수에 절대 주소가 포함 된 코드가 생성됩니다.위치 독립적 코드에서 링커 정의 기호 참조

Disassembly of section .text: 

00180000 <code_entry>: 
    180000: e92d0007 push {r0, r1, r2} 
    180004: e3a00000 mov r0, #0 
    180008: e59f1014 ldr r1, [pc, #20] ; 180024 <loop_bss+0x14> 
    18000c: e59f2014 ldr r2, [pc, #20] ; 180028 <loop_bss+0x18> 

00180010 <loop_bss>: 
    180010: e4810004 str r0, [r1], #4 
    180014: e1510002 cmp r1, r2 
    180018: bafffffc blt 180010 <loop_bss> 
    18001c: e8bd0007 pop {r0, r1, r2} 
    180020: ea00189f b 1862a4 <startPICode> 
    180024: 00194360 andseq r4, r9, r0, ror #6 
    180028: 001950e8 andseq r5, r9, r8, ror #1 

Readelf 내 ELF 파일이 더 재배치가 없음을 나타냅니다

.section entry_point 

code_entry: 
    # Save arguments to the stack 
    push {r0-r2} 

    # Loop over the BSS section, set it all to 0 
    mov  r0, #0 
    ldr  r1, =__bss_start 
    ldr  r2, =__bss_end 
loop_bss: 
    str  r0, [r1], #4 
    cmp  r1, r2 
    blt  loop_bss 

    # Pop arguments from the stack 
    pop  {r0-r2} 

    # Branch to C code (which will return to caller on its own) 
    b  startPICode 

출력은 다음과 같다 :

여기 내 조립 진입 점입니다.

링커 심볼이 항상 절대 주소가 될 정수라고 생각하면 맞습니까? 그렇다면로드 또는 실행 시간에 주소를 수정하는 방법이 있습니까? 아니면이 코드에 대해 BSS를 지우는 다른 올바른 방법이 있습니까?

편집 : 일부 readelf -s 출력을 추가합니다. 관련 .S 파일과 BSS와 관련된 모든 내용이 있습니다.

Symbol table '.symtab' contains 812 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 00180000  0 SECTION LOCAL DEFAULT 1 
    2: 0019297c  0 SECTION LOCAL DEFAULT 2 
    3: 00192994  0 SECTION LOCAL DEFAULT 3 
    4: 001929b0  0 SECTION LOCAL DEFAULT 4 
    5: 00193808  0 SECTION LOCAL DEFAULT 5 
    6: 001942dc  0 SECTION LOCAL DEFAULT 6 
    7: 00194350  0 SECTION LOCAL DEFAULT 7 
    8: 00194358  0 SECTION LOCAL DEFAULT 8 
    9: 0019435c  0 SECTION LOCAL DEFAULT 9 
    10: 00194360  0 SECTION LOCAL DEFAULT 10 
    11: 00194360  0 SECTION LOCAL DEFAULT 11 
    12: 001950e8  0 SECTION LOCAL DEFAULT 12 
    13: 001970f0  0 SECTION LOCAL DEFAULT 13 
    14: 00000000  0 SECTION LOCAL DEFAULT 14 
    15: 00000000  0 SECTION LOCAL DEFAULT 15 
    16: 00000000  0 SECTION LOCAL DEFAULT 16 
    17: 00000000  0 SECTION LOCAL DEFAULT 17 
    18: 00000000  0 SECTION LOCAL DEFAULT 18 
    19: 00000000  0 SECTION LOCAL DEFAULT 19 
    20: 00000000  0 SECTION LOCAL DEFAULT 20 
    21: 00000000  0 SECTION LOCAL DEFAULT 21 
    22: 00000000  0 SECTION LOCAL DEFAULT 22 
    23: 00000000  0 SECTION LOCAL DEFAULT 23 
    24: 00000000  0 FILE LOCAL DEFAULT ABS ./src/entry.o 
    25: 00180000  0 NOTYPE LOCAL DEFAULT 1 code_entry 
    26: 00180000  0 NOTYPE LOCAL DEFAULT 1 $a 
    27: 00180010  0 NOTYPE LOCAL DEFAULT 1 loop_bss 
    28: 00180024  0 NOTYPE LOCAL DEFAULT 1 $d 
    29: 00000124  0 NOTYPE LOCAL DEFAULT 17 $d 

    484: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __sbss_start 

    525: 00193804  0 NOTYPE GLOBAL DEFAULT 5 __sbss2_end 

    555: 001950e8  0 NOTYPE GLOBAL DEFAULT 11 __bss_end 

    565: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __tbss_start 

    581: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __sbss_end 

    599: 00193804  0 NOTYPE GLOBAL DEFAULT 5 __sbss2_start 

    667: 00194360  0 NOTYPE GLOBAL DEFAULT 11 __bss_start 

    753: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __tbss_end 
+0

readelf -s 을 게시 할 수 있습니까? 이게 베어 메탈 이니? – InfinitelyManic

+0

예, 이것은 베어 메탈입니다. 나는 완전한 readelf를 게시하고 싶지 않다. 그러나 게시에 도움이되는 특정 기호가 있습니까? –

+0

* bss * – InfinitelyManic

답변

0

귀하가 생산 한 코드는 재배치가 불가능합니다. 재배치가 가능하도록하려면 주소를 명시 적으로 __bss_start__bss_end으로 설정해야합니다. 예를 들어 : R3에

.section entry_point 

bss_start_rel: 
    .word __bss_start__ - bss_start_rel 
bss_end_rel: 
    .word __bss_end__ - bss_start_rel 

.global code_entry 
code_entry: 
    # Save arguments to the stack 
    push {r0-r2} 

    # Loop over the BSS section, set it all to 0 
    mov  r0, #0 
    adr  r3, bss_start_rel 
    ldr  r1, bss_start_rel 
    ldr  r2, bss_end_rel 
    add  r1, r1, r3 
    add  r2, r2, r3 

    ... 

ADR 의사 명령어 결과 bss_start_rel의 주소 PC 상대 산술. (예 sub r3, pc, #24)를 사용하여로드된다. 이는 __bss_start____bss_end__의 위치를 ​​계산하는 기준으로 사용되며 상대 위치는 bss_start_relbss_start_end에 저장됩니다.

+0

정확히 내가 필요로하는 것, 도와 줘서 고마워! –