Fix an issue in some Thumb fixups, where the effective PC address needs to be 4-byte...
authorOwen Anderson <resistor@mac.com>
Thu, 9 Dec 2010 20:27:52 +0000 (20:27 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 9 Dec 2010 20:27:52 +0000 (20:27 +0000)
the offset.  Add a new fixup flag to represent this, and use it for the one fixups that I have a testcase for needing
this.  It's quite likely that the other Thumb fixups will need this too, and to have their fixup encoding logic
adjusted accordingly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121408 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCCodeEmitter.h
lib/MC/MCAssembler.cpp
lib/Target/ARM/ARMAsmBackend.cpp
lib/Target/ARM/ARMMCCodeEmitter.cpp

index eac06ede2abbbdaa39a4d12e446409d9b41cecb9..2588661b62a802317c251a3dc78569382f7f69b5 100644 (file)
@@ -25,7 +25,10 @@ struct MCFixupKindInfo {
   enum FixupKindFlags {
     /// Is this fixup kind PCrelative? This is used by the assembler backend to
     /// evaluate fixup values in a target independent manner when possible.
-    FKF_IsPCRel = (1 << 0)
+    FKF_IsPCRel = (1 << 0),
+    
+    // Should this fixup kind force a 4-byte aligned effective PC value?
+    FKF_IsAligned = (1 << 1)
   };
 
   /// A target specific name for the fixup kind. The names will be unique for
index 323352ff8b790ed6959b3524f27cff7f524ff819..319f04cfe707981409fb71909271977118dfa561 100644 (file)
@@ -253,8 +253,15 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
   if (IsResolved)
     IsResolved = Writer.IsFixupFullyResolved(*this, Target, IsPCRel, DF);
 
-  if (IsPCRel)
-    Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
+  if (IsPCRel) {
+    bool ShouldAlignPC = Emitter.getFixupKindInfo(
+                        Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsAligned;
+    // PC should be aligned to a 4-byte value.
+    if (ShouldAlignPC)
+      Value -= Layout.getFragmentOffset(DF) + (Fixup.getOffset() & ~0x3);
+    else
+      Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
+  }
 
   return IsResolved;
 }
index 6be9f9288e21b51b2c06cba14d71e5ae5b48e4bf..606437efbb441392c7f56962dfa236d15649d25f 100644 (file)
@@ -100,10 +100,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   }
   case ARM::fixup_arm_ldst_pcrel_12:
     // ARM PC-relative values are offset by 8.
-    Value -= 6;
+    Value -= 4;
   case ARM::fixup_t2_ldst_pcrel_12: {
     // Offset by 4, adjusted by two due to the half-word ordering of thumb.
-    Value -= 2;
+    Value -= 4;
     bool isAdd = true;
     if ((int64_t)Value < 0) {
       Value = -Value;
index c81833b28f8881b550cc2d9232c89730bcfeb359..4d8791c9989d6b09aeec1179984fafff92bb3f16 100644 (file)
@@ -47,7 +47,8 @@ public:
     const static MCFixupKindInfo Infos[] = {
       // name                       off   bits  flags
       { "fixup_arm_ldst_pcrel_12",  1,    24,   MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_t2_ldst_pcrel_12",   0,    32,   MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_t2_ldst_pcrel_12",   0,    32,   MCFixupKindInfo::FKF_IsPCRel |
+                                                MCFixupKindInfo::FKF_IsAligned},
       { "fixup_arm_pcrel_10",       1,    24,   MCFixupKindInfo::FKF_IsPCRel },
       { "fixup_t2_pcrel_10",        0,    32,   MCFixupKindInfo::FKF_IsPCRel },
       { "fixup_arm_adr_pcrel_12",   1,    24,   MCFixupKindInfo::FKF_IsPCRel },