[PATCH] [Mips64] Add support for MCJIT for MIPS64r2 and MIPS64r6

Daniel Sanders daniel.sanders at imgtec.com
Wed May 27 07:50:13 PDT 2015


REPOSITORY
  rL LLVM

================
Comment at: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp:526-529
@@ +525,6 @@
+  // next type of the same relocation entry.
+  useCalculatedValue = !applyRelocation;
+  applyRelocation = r_type2 == ELF::R_MIPS_NONE;
+  resolveMIPS64Relocation(Section, RE.Offset, Value, r_type, RE.Addend,
+                          RE.SectionID, RE.SymOffset);
+
----------------
petarj wrote:
> dsanders wrote:
> > dsanders wrote:
> > > vradosavljevic wrote:
> > > > dsanders wrote:
> > > > > vradosavljevic wrote:
> > > > > > dsanders wrote:
> > > > > > > This particular overload of resolveMIPS64Relocation is only called from this function. So if we rename it to evaluateMIPS64Relocation(), stop it applying the reloc, and have it take/return the current calculated value we can use it as per this pseudo-code:
> > > > > > >   int64_t calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type, RE.Addend, RE.SectionID, RE.SymOffset, calculatedValue);
> > > > > > >   if (r_type2 == ELF::R_MIPS_NONE)
> > > > > > >     applyMIPS64Relocation(Section.Address + RE.Offset, calculatedValue);
> > > > > > > This is neater than passing values in side-channels such as member variables.
> > > > > > My understanding of Mips64 ABI is there can be more relocation entries for the same instruction, so i'm using applyRelocation, useCalculatedValue and calculatedValue as members variables to keep them for the following relocation entry if that's the case.
> > > > > > 
> > > > > > Mips64 ABI allows us e.g.:
> > > > > > 000000000000000c R_MIPS_GPREL16 main
> > > > > > 000000000000000c R_MIPS_SUB *ABS*
> > > > > > 000000000000000c R_MIPS_HI16 *ABS*
> > > > > > 
> > > > > > 000000000000000c R_MIPS_GPREL16 main
> > > > > > 000000000000000c R_MIPS_SUB *ABS*
> > > > > > 000000000000000c R_MIPS_HI16 *ABS*
> > > > > > 
> > > > > > So if this is the case (theoretically), we should use result of r_type3 from the first relocation entry, for r_type in the second relocation entry (in our case we should use calculatedValue).
> > > > > > 
> > > > > > From Mips64 ABI:
> > > > > > 
> > > > > > //Up to three operations may be specified per record, by the fields r_type , r_type2 , and r_type3 . They are applied in that order, and a zero field implies no further operations from this record. (The following record may continue the sequence if it references the same offset.)//
> > > > > > 
> > > > > There are multiple ABI's that can be used on Mips64. When you refer to the 'Mips64 ABI', I believe you are referring to the N64 ABI. Is this correct?  There is also an N32 ABI which behaves differently. For example, the 3-in-1 reloc encoding only applies to the N64 ABI and not the N32 ABI, and pointers/symbols are 4-bytes for N32 and 8-bytes for N64.
> > > > > For the sake of completeness, there is also the O64 ABI and the EABI64 ABI but we haven't implemented those two.
> > > > > 
> > > > > My main issue with this chunk of code was its use of sideband mechanisms to implement argument/return value passing instead of using a normal function call. It passes arguments in by writing to a member, returns them by writing to a member, and reads the result by reading a member. Using function arguments and return values is much clearer and does not increase the size of the object unnecessarily.
> > > > > 
> > > > > Here's the example code with all three relocs accounted for and tidied up:
> > > > >   int64_t calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type, RE.Addend, RE.SectionID, RE.SymOffset, calculatedValue);
> > > > >   if (r_type2 != ELF::R_MIPS_NONE)
> > > > >     calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type2, RE.Addend, RE.SectionID, RE.SymOffset, calculatedValue);
> > > > >   if (r_type3 != ELF::R_MIPS_NONE)
> > > > >     calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type3, RE.Addend, RE.SectionID, RE.SymOffset, calculatedValue);
> > > > >   applyMIPS64Relocation(Section.Address + RE.Offset, calculatedValue);
> > > > > 
> > > > Yes, i'm referring to Mips N64 ABI. This may not be the end of calculating, so we need to check if the next relocation entry is for the same instruction. If it is for the same instruction, we need to send calculatedValue to next relocation entry.
> > > Ah, I see the complicating issue. I'm going to have to look up the details of relocation composition to comment on that. The main thing I'm wondering is why Mips needs to do this and other targets don't. I know that some relocation mechanisms would write the calculated value to the section data after one relocation and read it back for the next relocation.
> > I've now looked it up. The 64-bit ELF Object
> > File Specification (available at https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf), gives the following definition for the 'A' operands:
> >   Represents an addend obtained as the value of the field being relocated
> >   prior to relocation (.rel), from a .rela addend field, or as the preceding
> >   result for a composed relocation (either).
> > 
> > Since N64 uses RELA relocations, I believe my example above should be passing in calculatedValue instead of RE.Addend for all except the first relocation for that address, like so:
> >   int64_t calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type, RE.Addend, RE.SectionID, RE.SymOffset);
> >   if (r_type2 != ELF::R_MIPS_NONE)
> >     calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type2, calculatedValue, RE.SectionID, RE.SymOffset);
> >   if (r_type3 != ELF::R_MIPS_NONE)
> >     calculatedValue = evaluateMIPS64Relocation(Section, RE.Offset, Value, r_type3, calculatedValue, RE.SectionID, RE.SymOffset);
> >   applyMIPS64Relocation(Section.Address + RE.Offset, calculatedValue);
> > 
> > It's possible that the two calculatedValue arguments should be 'calculatedValue + RE.Addend' but the spec was a bit unclear on this so I'm not 100% sure. Your current patch implements the former so I've gone with that.
> > 
> > > Yes, i'm referring to Mips N64 ABI. This may not be the end of calculating, so we need
> > > to check if the next relocation entry is for the same instruction. If it is for the same
> > > instruction, we need to send calculatedValue to next relocation entry.
> > 
> > Why not handle composition of multiple relocs in resolveRelocationList?
> > 
> > > The main thing I'm wondering is why Mips needs to do this and other targets don't. 
> > 
> > To partially answer my own question, relocation composition isn't particularly unique to to Mips but it seems that we may use it more often than other targets.
> What Vladimir is trying to say is that - theoretically speaking - getting calculatedValue for r_type can require calculatedValue that we calculated from r_type3 in the previous RelocationEntry.
Yes, I understood that. What I'm trying to say is that you don't need sideband data to achieve that. resolveRelocationList can iterate over all the composed relocations, evaluating it as it goes, and then it can apply the calculated value.

http://reviews.llvm.org/D9667

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list