2011-01-11 23:53:41 +00:00
|
|
|
@ RUN: llvm-mc %s -triple=armv7-linux-gnueabi | FileCheck -check-prefix=ASM %s
|
2011-01-12 00:19:25 +00:00
|
|
|
@ RUN: llvm-mc %s -triple=armv7-linux-gnueabi -filetype=obj -o - | \
|
2013-04-12 04:06:46 +00:00
|
|
|
@ RUN: llvm-readobj -s -sd -sr | FileCheck -check-prefix=OBJ %s
|
2011-01-11 23:53:41 +00:00
|
|
|
.syntax unified
|
|
|
|
.text
|
|
|
|
.globl barf
|
|
|
|
.align 2
|
|
|
|
.type barf,%function
|
|
|
|
barf: @ @barf
|
|
|
|
@ BB#0: @ %entry
|
|
|
|
movw r0, :lower16:GOT-(.LPC0_2+8)
|
This fixes one divergence between LLVM and binutils for ARM in the
text section.
Assume the following bit of annotated assembly:
.section .data.rel.ro,"aw",%progbits
.align 2
.LAlpha:
.long startval(GOTOFF)
.text
.align 2
.type main,%function
.align 4
main: ;;; assume "main" starts at offset 0x20
0x0 push {r11, lr}
0x4 movw r0, :lower16:(.LAlpha-(.LBeta+8))
;;; ==> (.AddrOf(.LAlpha) - ((.AddrOf(.LBeta) - .AddrOf(".")) + 8)
;;; ==> (??? - ((16-4) + 8) = -20
0x8 movt r0, :upper16:(.LAlpha-(.LBeta+8))
;;; ==> (.AddrOf(.LAlpha) - ((.AddrOf(.LBeta) - .AddrOf(".")) + 8)
;;; ==> (??? - ((16-8) + 8) = -16
0xc ... blah
.LBeta:
0x10 add r0, pc, r0
0x14 ... blah
.LGamma:
0x18 add r1, pc, r1
Above snippet results in the following relocs in the .o file for the
first pair of movw/movt instructions
00000024 R_ARM_MOVW_PREL_NC .LAlpha
00000028 R_ARM_MOVT_PREL .LAlpha
And the encoded instructions in the .o file for main: must be
00000020 <main>:
20: e92d4800 push {fp, lr}
24: e30f0fec movw r0, #65516 ; 0xffec i.e. -20
28: e34f0ff0 movt r0, #65520 ; 0xfff0 i.e. -16
However, llc (prior to this commit) generates the following sequence
00000020 <main>:
20: e92d4800 push {fp, lr}
24: e30f0fec movw r0, #65516 ; 0xffec - i.e. -20
28: e34f0fff movt r0, #65535 ; 0xffff - i.e. -1
What has to happen in the ArmAsmBackend is that if the relocation is PC
relative, the 16 bits encoded as part of movw and movt must be both addends,
not addresses. It makes sense to encode addresses by right shifting the value
by 16, but the result is incorrect for PIC.
i.e., the right shift by 16 for movt is ONLY valid for the NON-PCRel case.
This change agrees with what GNU as does, and makes the PIC code run.
MC/ARM/elf-movt.s covers this case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131674 91177308-0d34-0410-b5e6-96231b3b80d8
2011-05-19 20:55:25 +00:00
|
|
|
movt r0, :upper16:GOT-(.LPC0_2+8)
|
2011-01-11 23:53:41 +00:00
|
|
|
.LPC0_2:
|
2011-01-13 07:58:56 +00:00
|
|
|
@ ASM: movw r0, :lower16:(GOT-(.LPC0_2+8))
|
This fixes one divergence between LLVM and binutils for ARM in the
text section.
Assume the following bit of annotated assembly:
.section .data.rel.ro,"aw",%progbits
.align 2
.LAlpha:
.long startval(GOTOFF)
.text
.align 2
.type main,%function
.align 4
main: ;;; assume "main" starts at offset 0x20
0x0 push {r11, lr}
0x4 movw r0, :lower16:(.LAlpha-(.LBeta+8))
;;; ==> (.AddrOf(.LAlpha) - ((.AddrOf(.LBeta) - .AddrOf(".")) + 8)
;;; ==> (??? - ((16-4) + 8) = -20
0x8 movt r0, :upper16:(.LAlpha-(.LBeta+8))
;;; ==> (.AddrOf(.LAlpha) - ((.AddrOf(.LBeta) - .AddrOf(".")) + 8)
;;; ==> (??? - ((16-8) + 8) = -16
0xc ... blah
.LBeta:
0x10 add r0, pc, r0
0x14 ... blah
.LGamma:
0x18 add r1, pc, r1
Above snippet results in the following relocs in the .o file for the
first pair of movw/movt instructions
00000024 R_ARM_MOVW_PREL_NC .LAlpha
00000028 R_ARM_MOVT_PREL .LAlpha
And the encoded instructions in the .o file for main: must be
00000020 <main>:
20: e92d4800 push {fp, lr}
24: e30f0fec movw r0, #65516 ; 0xffec i.e. -20
28: e34f0ff0 movt r0, #65520 ; 0xfff0 i.e. -16
However, llc (prior to this commit) generates the following sequence
00000020 <main>:
20: e92d4800 push {fp, lr}
24: e30f0fec movw r0, #65516 ; 0xffec - i.e. -20
28: e34f0fff movt r0, #65535 ; 0xffff - i.e. -1
What has to happen in the ArmAsmBackend is that if the relocation is PC
relative, the 16 bits encoded as part of movw and movt must be both addends,
not addresses. It makes sense to encode addresses by right shifting the value
by 16, but the result is incorrect for PIC.
i.e., the right shift by 16 for movt is ONLY valid for the NON-PCRel case.
This change agrees with what GNU as does, and makes the PIC code run.
MC/ARM/elf-movt.s covers this case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131674 91177308-0d34-0410-b5e6-96231b3b80d8
2011-05-19 20:55:25 +00:00
|
|
|
@ ASM-NEXT: movt r0, :upper16:(GOT-(.LPC0_2+8))
|
2011-01-11 23:53:41 +00:00
|
|
|
|
2011-01-12 00:19:25 +00:00
|
|
|
@@ make sure that the text section fixups are sane too
|
2013-04-12 04:06:46 +00:00
|
|
|
@ OBJ: Section {
|
|
|
|
@ OBJ: Name: .text
|
|
|
|
@ OBJ-NEXT: Type: SHT_PROGBITS
|
|
|
|
@ OBJ-NEXT: Flags [ (0x6)
|
|
|
|
@ OBJ-NEXT: SHF_ALLOC
|
|
|
|
@ OBJ-NEXT: SHF_EXECINSTR
|
|
|
|
@ OBJ-NEXT: ]
|
|
|
|
@ OBJ-NEXT: Address: 0x0
|
|
|
|
@ OBJ-NEXT: Offset: 0x34
|
|
|
|
@ OBJ-NEXT: Size: 8
|
|
|
|
@ OBJ-NEXT: Link: 0
|
|
|
|
@ OBJ-NEXT: Info: 0
|
|
|
|
@ OBJ-NEXT: AddressAlignment: 4
|
|
|
|
@ OBJ-NEXT: EntrySize: 0
|
|
|
|
@ OBJ-NEXT: Relocations [
|
|
|
|
@ OBJ-NEXT: ]
|
|
|
|
@ OBJ-NEXT: SectionData (
|
|
|
|
@ OBJ-NEXT: 0000: F00F0FE3 F40F4FE3
|
|
|
|
@ OBJ-NEXT: )
|
2013-05-30 03:05:14 +00:00
|
|
|
@ OBJ-NEXT: }
|
|
|
|
@ OBJ-NEXT: Section {
|
|
|
|
@ OBJ-NEXT: Index: 2
|
|
|
|
@ OBJ-NEXT: Name: .rel.text (1)
|
|
|
|
@ OBJ-NEXT: Type: SHT_REL (0x9)
|
|
|
|
@ OBJ-NEXT: Flags [ (0x0)
|
|
|
|
@ OBJ-NEXT: ]
|
|
|
|
@ OBJ-NEXT: Address: 0x0
|
|
|
|
@ OBJ-NEXT: Offset: 0x22C
|
|
|
|
@ OBJ-NEXT: Size: 16
|
|
|
|
@ OBJ-NEXT: Link: 6
|
|
|
|
@ OBJ-NEXT: Info: 1
|
|
|
|
@ OBJ-NEXT: AddressAlignment: 4
|
|
|
|
@ OBJ-NEXT: EntrySize: 8
|
|
|
|
@ OBJ-NEXT: Relocations [
|
|
|
|
@ OBJ-NEXT: 0x0 R_ARM_MOVW_PREL_NC
|
|
|
|
@ OBJ-NEXT: 0x4 R_ARM_MOVT_PREL
|
|
|
|
@ OBJ-NEXT: ]
|
|
|
|
@ OBJ-NEXT: SectionData (
|
|
|
|
@ OBJ-NEXT: 0000: 00000000 2D060000 04000000 2E060000 |....-...........|
|
|
|
|
@ OBJ-NEXT: )
|
|
|
|
@ OBJ-NEXT: }
|