[llvm] r284724 - [mips][mcjit] Add the majority of N32 support.

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 20 06:02:23 PDT 2016


Author: sdardis
Date: Thu Oct 20 08:02:23 2016
New Revision: 284724

URL: http://llvm.org/viewvc/llvm-project?rev=284724&view=rev
Log:
[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

Added:
    llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s
Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=284724&r1=284723&r2=284724&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Thu Oct 20 08:02:23 2016
@@ -585,22 +585,33 @@ void RuntimeDyldELF::setMipsABI(const Ob
   if (Arch == Triple::UnknownArch ||
       !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
     IsMipsO32ABI = false;
+    IsMipsN32ABI = false;
     IsMipsN64ABI = false;
     return;
   }
   unsigned AbiVariant;
   Obj.getPlatformFlags(AbiVariant);
   IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
+  IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
   IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
-  if (AbiVariant & ELF::EF_MIPS_ABI2)
-    llvm_unreachable("Mips N32 ABI is not supported yet");
 }
 
-void RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section,
-                                             uint64_t Offset, uint64_t Value,
-                                             uint32_t Type, int64_t Addend,
-                                             uint64_t SymOffset,
-                                             SID SectionID) {
+void RuntimeDyldELF::resolveMIPSN32Relocation(const SectionEntry &Section,
+                                              uint64_t Offset, uint64_t Value,
+                                              uint32_t Type, int64_t Addend,
+                                              uint64_t SymOffset,
+                                              SID SectionID) {
+  int64_t CalculatedValue = evaluateMIPS64Relocation(
+      Section, Offset, Value, Type, Addend, SymOffset, SectionID);
+  applyMIPS64Relocation(Section.getAddressWithOffset(Offset), CalculatedValue,
+                        Type);
+}
+
+void RuntimeDyldELF::resolveMIPSN64Relocation(const SectionEntry &Section,
+                                              uint64_t Offset, uint64_t Value,
+                                              uint32_t Type, int64_t Addend,
+                                              uint64_t SymOffset,
+                                              SID SectionID) {
   uint32_t r_type = Type & 0xff;
   uint32_t r_type2 = (Type >> 8) & 0xff;
   uint32_t r_type3 = (Type >> 16) & 0xff;
@@ -669,7 +680,7 @@ RuntimeDyldELF::evaluateMIPS64Relocation
   case ELF::R_MIPS_GOT_PAGE: {
     uint8_t *LocalGOTAddr =
         getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset;
-    uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, 8);
+    uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, getGOTEntrySize());
 
     Value += Addend;
     if (Type == ELF::R_MIPS_GOT_PAGE)
@@ -679,7 +690,7 @@ RuntimeDyldELF::evaluateMIPS64Relocation
       assert(GOTEntry == Value &&
                    "GOT entry has two different addresses.");
     else
-      writeBytesUnaligned(Value, LocalGOTAddr, 8);
+      writeBytesUnaligned(Value, LocalGOTAddr, getGOTEntrySize());
 
     return (SymOffset - 0x7ff0) & 0xffff;
   }
@@ -1131,9 +1142,12 @@ void RuntimeDyldELF::resolveRelocation(c
     if (IsMipsO32ABI)
       resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
                             Type, (uint32_t)(Addend & 0xffffffffL));
+    else if (IsMipsN32ABI)
+      resolveMIPSN32Relocation(Section, Offset, Value, Type, Addend, SymOffset,
+                               SectionID);
     else if (IsMipsN64ABI)
-      resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
-                              SectionID);
+      resolveMIPSN64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
+                               SectionID);
     else
       llvm_unreachable("Mips ABI not handled");
     break;
@@ -1469,7 +1483,7 @@ RuntimeDyldELF::processRelocationRef(
         Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
       processSimpleRelocation(SectionID, Offset, RelType, Value);
     }
-  } else if (IsMipsN64ABI) {
+  } else if (IsMipsN32ABI || IsMipsN64ABI) {
     uint32_t r_type = RelType & 0xff;
     RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
     if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
@@ -1806,7 +1820,7 @@ size_t RuntimeDyldELF::getGOTEntrySize()
   case Triple::mipsel:
   case Triple::mips64:
   case Triple::mips64el:
-    if (IsMipsO32ABI)
+    if (IsMipsO32ABI || IsMipsN32ABI)
       Result = sizeof(uint32_t);
     else if (IsMipsN64ABI)
       Result = sizeof(uint64_t);
@@ -1871,7 +1885,7 @@ Error RuntimeDyldELF::finalizeLoad(const
     // For now, initialize all GOT entries to zero.  We'll fill them in as
     // needed when GOT-based relocations are applied.
     memset(Addr, 0, TotalSize);
-    if (IsMipsN64ABI) {
+    if (IsMipsN32ABI || IsMipsN64ABI) {
       // To correctly resolve Mips GOT relocations, we need a mapping from
       // object's sections to GOTs.
       for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=284724&r1=284723&r2=284724&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Thu Oct 20 08:02:23 2016
@@ -55,9 +55,12 @@ class RuntimeDyldELF : public RuntimeDyl
   void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
                                 uint64_t Value, uint32_t Type, int64_t Addend);
 
-  void resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset,
-                               uint64_t Value, uint32_t Type, int64_t Addend,
-                               uint64_t SymOffset, SID SectionID);
+  void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset,
+                                uint64_t Value, uint32_t Type, int64_t Addend,
+                                uint64_t SymOffset, SID SectionID);
+  void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset,
+                                uint64_t Value, uint32_t Type, int64_t Addend,
+                                uint64_t SymOffset, SID SectionID);
 
   int64_t evaluateMIPS64Relocation(const SectionEntry &Section,
                                    uint64_t Offset, uint64_t Value,

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=284724&r1=284723&r2=284724&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Thu Oct 20 08:02:23 2016
@@ -290,6 +290,7 @@ protected:
   Triple::ArchType Arch;
   bool IsTargetLittleEndian;
   bool IsMipsO32ABI;
+  bool IsMipsN32ABI;
   bool IsMipsN64ABI;
 
   // True if all sections should be passed to the memory manager, false if only
@@ -353,6 +354,7 @@ protected:
 
   virtual void setMipsABI(const ObjectFile &Obj) {
     IsMipsO32ABI = false;
+    IsMipsN32ABI = false;
     IsMipsN64ABI = false;
   }
 

Added: llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s?rev=284724&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s (added)
+++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s Thu Oct 20 08:02:23 2016
@@ -0,0 +1,156 @@
+# RUN: llvm-mc -triple=mips64el-unknown-linux -target-abi n32 -code-model=small -filetype=obj -o %T/test_ELF_N32.o %s
+# RUN: llc -mtriple=mips64el-unknown-linux -target-abi n32 -filetype=obj -o %T/test_ELF_ExternalFunction_N32.o %S/Inputs/ExternalFunction.ll
+# 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
+
+# RUN: llvm-mc -triple=mips64-unknown-linux -target-abi n32 -code-model=small -filetype=obj -o %T/test_ELF_N32.o %s
+# RUN: llc -mtriple=mips64-unknown-linux -target-abi n32 -filetype=obj -o %T/test_ELF_ExternalFunction_N32.o %S/Inputs/ExternalFunction.ll
+# 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
+
+	.data
+# Test R_MIPS_PC32 relocation.
+# rtdyld-check: *{4}(R_MIPS_PC32) = (foo - R_MIPS_PC32)[31:0]
+R_MIPS_PC32:
+	.word foo-.
+# rtdyld-check: *{4}(R_MIPS_PC32 + 4) = (foo - tmp1)[31:0]
+tmp1:
+	.4byte foo-tmp1
+
+	.text
+	.abicalls
+	.section	.mdebug.abi64,"", at progbits
+	.nan	legacy
+	.file	"ELF_N32_PIC_relocations.ll"
+	.text
+	.globl	bar
+	.align	3
+	.type	bar, at function
+	.set	nomicromips
+	.set	nomips16
+	.ent	bar
+bar:
+	.frame	$fp,40,$ra
+	.mask 	0x00000000,0
+	.fmask	0x00000000,0
+	.set	noreorder
+	.set	nomacro
+	.set	noat
+	daddiu	$sp, $sp, -40
+	sd	$ra, 32($sp)
+	sd	$fp, 24($sp)
+	move	 $fp, $sp
+	sd	$4, 16($fp)
+	lb	$2, 0($4)
+	sd	$4, 8($fp)
+
+# Test R_MIPS_26 relocation.
+# rtdyld-check:  decode_operand(insn1, 0)[27:0] = foo[27:0]
+insn1:
+	.option pic0
+	jal   foo
+	.option pic2
+	nop
+
+# Test R_MIPS_PC16 relocation.
+# rtdyld-check:  decode_operand(insn2, 1)[17:0] = (foo - insn2)[17:0]
+insn2:
+	bal   foo
+	nop
+
+	move	 $sp, $fp
+	ld	$ra, 32($sp)
+	ld	$fp, 24($sp)
+	daddiu	$sp, $sp, 32
+	jr	$ra
+	nop
+	.set	at
+	.set	macro
+	.set	reorder
+	.end	bar
+$func_end0:
+	.size	bar, ($func_end0)-bar
+
+	.globl	main
+	.align	3
+	.type	main, at function
+	.set	nomicromips
+	.set	nomips16
+	.ent	main
+main:
+	.frame	$fp,32,$ra
+	.mask 	0x00000000,0
+	.fmask	0x00000000,0
+	.set	noreorder
+	.set	nomacro
+	.set	noat
+	daddiu	$sp, $sp, -32
+	sd	$ra, 24($sp)
+	sd	$fp, 16($sp)
+	sd	$gp, 8($sp)
+	move	 $fp, $sp
+
+# $gp register contains address of the .got section + 0x7FF0. 0x7FF0 is
+# the offset of $gp from the beginning of the .got section. Check that we are
+# loading address of the page pointer from correct offset. In this case
+# the page pointer is the first entry in the .got section, so offset will be
+# 0 - 0x7FF0.
+# rtdyld-check:  decode_operand(insn5, 2)[15:0] = 0x8010
+#
+# Check that the global offset table contains the page pointer.
+# rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got)) = (_str + 0x8000) & 0xffff0000
+insn5:
+	ld	$25, %got_page(_str)($1)
+
+# Check the offset of _str from the page pointer.
+# rtdyld-check:  decode_operand(insn6, 2)[15:0] = _str[15:0]
+insn6:
+	daddiu	$25, $25, %got_ofst(_str)
+
+# Check that we are loading address of var from correct offset. In this case
+# var is the second entry in the .got section, so offset will be 4 - 0x7FF0.
+# rtdyld-check:  decode_operand(insn7, 2)[15:0] = 0x8014
+#
+# Check that the global offset table contains the address of the var.
+# rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got) + 4) = var
+insn7:
+	ld	$2, %got_disp(var)($1)
+	sd	$25, 0($2)
+
+# Check that we are loading address of bar from correct offset. In this case
+# bar is the third entry in the .got section, so offset will be 8 - 0x7FF0.
+# rtdyld-check:  decode_operand(insn8, 2)[15:0] = 0x8018
+#
+# Check that the global offset table contains the address of the bar.
+# rtdyld-check: *{4}(section_addr(test_ELF_N32.o, .got) + 8) = bar
+insn8:
+	ld	$2, %call16(bar)($1)
+
+	move	 $4, $25
+	move	 $gp, $1
+	move	 $25, $2
+	jalr	$25
+	nop
+	move	 $sp, $fp
+	ld	$gp, 8($sp)
+	ld	$fp, 16($sp)
+	ld	$ra, 24($sp)
+	daddiu	$sp, $sp, 32
+	jr	$ra
+	nop
+	.set	at
+	.set	macro
+	.set	reorder
+	.end	main
+$func_end1:
+	.size	main, ($func_end1)-main
+
+	.type	_str, at object
+	.section	.rodata.str1.1,"aMS", at progbits,1
+_str:
+	.asciz	"test"
+	.size	_str, 5
+
+	.type	var, at object
+	.comm	var,8,8
+
+	.section	".note.GNU-stack","", at progbits
+	.text




More information about the llvm-commits mailing list