llvm.org GIT mirror llvm / f7463aa
[mips][mcjit] Add the majority of N32 support. The missing piece is relocation composition for %hi(%neg(%gp_rel(x))) and similar. Patch by: Daniel Sanders git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284724 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Dardis 3 years ago
4 changed file(s) with 194 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
584584 if (Arch == Triple::UnknownArch ||
585585 !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
586586 IsMipsO32ABI = false;
587 IsMipsN32ABI = false;
587588 IsMipsN64ABI = false;
588589 return;
589590 }
590591 unsigned AbiVariant;
591592 Obj.getPlatformFlags(AbiVariant);
592593 IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
594 IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
593595 IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
594 if (AbiVariant & ELF::EF_MIPS_ABI2)
595 llvm_unreachable("Mips N32 ABI is not supported yet");
596 }
597
598 void RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section,
599 uint64_t Offset, uint64_t Value,
600 uint32_t Type, int64_t Addend,
601 uint64_t SymOffset,
602 SID SectionID) {
596 }
597
598 void RuntimeDyldELF::resolveMIPSN32Relocation(const SectionEntry &Section,
599 uint64_t Offset, uint64_t Value,
600 uint32_t Type, int64_t Addend,
601 uint64_t SymOffset,
602 SID SectionID) {
603 int64_t CalculatedValue = evaluateMIPS64Relocation(
604 Section, Offset, Value, Type, Addend, SymOffset, SectionID);
605 applyMIPS64Relocation(Section.getAddressWithOffset(Offset), CalculatedValue,
606 Type);
607 }
608
609 void RuntimeDyldELF::resolveMIPSN64Relocation(const SectionEntry &Section,
610 uint64_t Offset, uint64_t Value,
611 uint32_t Type, int64_t Addend,
612 uint64_t SymOffset,
613 SID SectionID) {
603614 uint32_t r_type = Type & 0xff;
604615 uint32_t r_type2 = (Type >> 8) & 0xff;
605616 uint32_t r_type3 = (Type >> 16) & 0xff;
668679 case ELF::R_MIPS_GOT_PAGE: {
669680 uint8_t *LocalGOTAddr =
670681 getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset;
671 uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, 8);
682 uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, getGOTEntrySize());
672683
673684 Value += Addend;
674685 if (Type == ELF::R_MIPS_GOT_PAGE)
678689 assert(GOTEntry == Value &&
679690 "GOT entry has two different addresses.");
680691 else
681 writeBytesUnaligned(Value, LocalGOTAddr, 8);
692 writeBytesUnaligned(Value, LocalGOTAddr, getGOTEntrySize());
682693
683694 return (SymOffset - 0x7ff0) & 0xffff;
684695 }
11301141 if (IsMipsO32ABI)
11311142 resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
11321143 Type, (uint32_t)(Addend & 0xffffffffL));
1144 else if (IsMipsN32ABI)
1145 resolveMIPSN32Relocation(Section, Offset, Value, Type, Addend, SymOffset,
1146 SectionID);
11331147 else if (IsMipsN64ABI)
1134 resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
1135 SectionID);
1148 resolveMIPSN64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
1149 SectionID);
11361150 else
11371151 llvm_unreachable("Mips ABI not handled");
11381152 break;
14681482 Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
14691483 processSimpleRelocation(SectionID, Offset, RelType, Value);
14701484 }
1471 } else if (IsMipsN64ABI) {
1485 } else if (IsMipsN32ABI || IsMipsN64ABI) {
14721486 uint32_t r_type = RelType & 0xff;
14731487 RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
14741488 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
18051819 case Triple::mipsel:
18061820 case Triple::mips64:
18071821 case Triple::mips64el:
1808 if (IsMipsO32ABI)
1822 if (IsMipsO32ABI || IsMipsN32ABI)
18091823 Result = sizeof(uint32_t);
18101824 else if (IsMipsN64ABI)
18111825 Result = sizeof(uint64_t);
18701884 // For now, initialize all GOT entries to zero. We'll fill them in as
18711885 // needed when GOT-based relocations are applied.
18721886 memset(Addr, 0, TotalSize);
1873 if (IsMipsN64ABI) {
1887 if (IsMipsN32ABI || IsMipsN64ABI) {
18741888 // To correctly resolve Mips GOT relocations, we need a mapping from
18751889 // object's sections to GOTs.
18761890 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
5454 void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
5555 uint64_t Value, uint32_t Type, int64_t Addend);
5656
57 void resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset,
58 uint64_t Value, uint32_t Type, int64_t Addend,
59 uint64_t SymOffset, SID SectionID);
57 void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset,
58 uint64_t Value, uint32_t Type, int64_t Addend,
59 uint64_t SymOffset, SID SectionID);
60 void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset,
61 uint64_t Value, uint32_t Type, int64_t Addend,
62 uint64_t SymOffset, SID SectionID);
6063
6164 int64_t evaluateMIPS64Relocation(const SectionEntry &Section,
6265 uint64_t Offset, uint64_t Value,
289289 Triple::ArchType Arch;
290290 bool IsTargetLittleEndian;
291291 bool IsMipsO32ABI;
292 bool IsMipsN32ABI;
292293 bool IsMipsN64ABI;
293294
294295 // True if all sections should be passed to the memory manager, false if only
352353
353354 virtual void setMipsABI(const ObjectFile &Obj) {
354355 IsMipsO32ABI = false;
356 IsMipsN32ABI = false;
355357 IsMipsN64ABI = false;
356358 }
357359
0 # RUN: llvm-mc -triple=mips64el-unknown-linux -target-abi n32 -code-model=small -filetype=obj -o %T/test_ELF_N32.o %s
1 # RUN: llc -mtriple=mips64el-unknown-linux -target-abi n32 -filetype=obj -o %T/test_ELF_ExternalFunction_N32.o %S/Inputs/ExternalFunction.ll
2 # RUN: llvm-rtdyld -triple=mips64el-unknown-linux -verify -map-section test_ELF_N32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_N32.o,.text=0x10000 -check=%s %/T/test_ELF_N32.o %T/test_ELF_ExternalFunction_N32.o
3
4 # RUN: llvm-mc -triple=mips64-unknown-linux -target-abi n32 -code-model=small -filetype=obj -o %T/test_ELF_N32.o %s
5 # RUN: llc -mtriple=mips64-unknown-linux -target-abi n32 -filetype=obj -o %T/test_ELF_ExternalFunction_N32.o %S/Inputs/ExternalFunction.ll
6 # RUN: llvm-rtdyld -triple=mips64-unknown-linux -verify -map-section test_ELF_N32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_N32.o,.text=0x10000 -check=%s %/T/test_ELF_N32.o %T/test_ELF_ExternalFunction_N32.o
7
8 .data
9 # Test R_MIPS_PC32 relocation.
10 # rtdyld-check: *{4}(R_MIPS_PC32) = (foo - R_MIPS_PC32)[31:0]
11 R_MIPS_PC32:
12 .word foo-.
13 # rtdyld-check: *{4}(R_MIPS_PC32 + 4) = (foo - tmp1)[31:0]
14 tmp1:
15 .4byte foo-tmp1
16
17 .text
18 .abicalls
19 .section .mdebug.abi64,"",@progbits
20 .nan legacy
21 .file "ELF_N32_PIC_relocations.ll"
22 .text
23 .globl bar
24 .align 3
25 .type bar,@function
26 .set nomicromips
27 .set nomips16
28 .ent bar
29 bar:
30 .frame $fp,40,$ra
31 .mask 0x00000000,0
32 .fmask 0x00000000,0
33 .set noreorder
34 .set nomacro
35 .set noat
36 daddiu $sp, $sp, -40
37 sd $ra, 32($sp)
38 sd $fp, 24($sp)
39 move $fp, $sp
40 sd $4, 16($fp)
41 lb $2, 0($4)
42 sd $4, 8($fp)
43
44 # Test R_MIPS_26 relocation.
45 # rtdyld-check: decode_operand(insn1, 0)[27:0] = foo[27:0]
46 insn1:
47 .option pic0
48 jal foo
49 .option pic2
50 nop
51
52 # Test R_MIPS_PC16 relocation.
53 # rtdyld-check: decode_operand(insn2, 1)[17:0] = (foo - insn2)[17:0]
54 insn2:
55 bal foo
56 nop
57
58 move $sp, $fp
59 ld $ra, 32($sp)
60 ld $fp, 24($sp)
61 daddiu $sp, $sp, 32
62 jr $ra
63 nop
64 .set at
65 .set macro
66 .set reorder
67 .end bar
68 $func_end0:
69 .size bar, ($func_end0)-bar
70
71 .globl main
72 .align 3
73 .type main,@function
74 .set nomicromips
75 .set nomips16
76 .ent main
77 main:
78 .frame $fp,32,$ra
79 .mask 0x00000000,0
80 .fmask 0x00000000,0
81 .set noreorder
82 .set nomacro
83 .set noat
84 daddiu $sp, $sp, -32
85 sd $ra, 24($sp)
86 sd $fp, 16($sp)
87 sd $gp, 8($sp)
88 move $fp, $sp
89
90 # $gp register contains address of the .got section + 0x7FF0. 0x7FF0 is
91 # the offset of $gp from the beginning of the .got section. Check that we are
92 # loading address of the page pointer from correct offset. In this case
93 # the page pointer is the first entry in the .got section, so offset will be
94 # 0 - 0x7FF0.
95 # rtdyld-check: decode_operand(insn5, 2)[15:0] = 0x8010
96 #
97 # Check that the global offset table contains the page pointer.
98 # rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got)) = (_str + 0x8000) & 0xffff0000
99 insn5:
100 ld $25, %got_page(_str)($1)
101
102 # Check the offset of _str from the page pointer.
103 # rtdyld-check: decode_operand(insn6, 2)[15:0] = _str[15:0]
104 insn6:
105 daddiu $25, $25, %got_ofst(_str)
106
107 # Check that we are loading address of var from correct offset. In this case
108 # var is the second entry in the .got section, so offset will be 4 - 0x7FF0.
109 # rtdyld-check: decode_operand(insn7, 2)[15:0] = 0x8014
110 #
111 # Check that the global offset table contains the address of the var.
112 # rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got) + 4) = var
113 insn7:
114 ld $2, %got_disp(var)($1)
115 sd $25, 0($2)
116
117 # Check that we are loading address of bar from correct offset. In this case
118 # bar is the third entry in the .got section, so offset will be 8 - 0x7FF0.
119 # rtdyld-check: decode_operand(insn8, 2)[15:0] = 0x8018
120 #
121 # Check that the global offset table contains the address of the bar.
122 # rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got) + 8) = bar
123 insn8:
124 ld $2, %call16(bar)($1)
125
126 move $4, $25
127 move $gp, $1
128 move $25, $2
129 jalr $25
130 nop
131 move $sp, $fp
132 ld $gp, 8($sp)
133 ld $fp, 16($sp)
134 ld $ra, 24($sp)
135 daddiu $sp, $sp, 32
136 jr $ra
137 nop
138 .set at
139 .set macro
140 .set reorder
141 .end main
142 $func_end1:
143 .size main, ($func_end1)-main
144
145 .type _str,@object
146 .section .rodata.str1.1,"aMS",@progbits,1
147 _str:
148 .asciz "test"
149 .size _str, 5
150
151 .type var,@object
152 .comm var,8,8
153
154 .section ".note.GNU-stack","",@progbits
155 .text