@@ -71,19 +71,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7171 //
7272 // Name Offset (bits) Size (bits) Flags
7373 {" fixup_arm_ldst_pcrel_12" , 0 , 32 , 0 },
74- {" fixup_t2_ldst_pcrel_12" , 0 , 32 ,
75- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
74+ {" fixup_t2_ldst_pcrel_12" , 0 , 32 , 0 },
7675 {" fixup_arm_pcrel_10_unscaled" , 0 , 32 , 0 },
7776 {" fixup_arm_pcrel_10" , 0 , 32 , 0 },
78- {" fixup_t2_pcrel_10" , 0 , 32 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
77+ {" fixup_t2_pcrel_10" , 0 , 32 , 0 },
7978 {" fixup_arm_pcrel_9" , 0 , 32 , 0 },
80- {" fixup_t2_pcrel_9" , 0 , 32 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
79+ {" fixup_t2_pcrel_9" , 0 , 32 , 0 },
8180 {" fixup_arm_ldst_abs_12" , 0 , 32 , 0 },
82- {" fixup_thumb_adr_pcrel_10" , 0 , 8 ,
83- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
81+ {" fixup_thumb_adr_pcrel_10" , 0 , 8 , 0 },
8482 {" fixup_arm_adr_pcrel_12" , 0 , 32 , 0 },
85- {" fixup_t2_adr_pcrel_12" , 0 , 32 ,
86- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
83+ {" fixup_t2_adr_pcrel_12" , 0 , 32 , 0 },
8784 {" fixup_arm_condbranch" , 0 , 24 , 0 },
8885 {" fixup_arm_uncondbranch" , 0 , 24 , 0 },
8986 {" fixup_t2_condbranch" , 0 , 32 , 0 },
@@ -93,10 +90,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
9390 {" fixup_arm_condbl" , 0 , 24 , 0 },
9491 {" fixup_arm_blx" , 0 , 24 , 0 },
9592 {" fixup_arm_thumb_bl" , 0 , 32 , 0 },
96- {" fixup_arm_thumb_blx" , 0 , 32 ,
97- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
93+ {" fixup_arm_thumb_blx" , 0 , 32 , 0 },
9894 {" fixup_arm_thumb_cb" , 0 , 16 , 0 },
99- {" fixup_arm_thumb_cp" , 0 , 8 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
95+ {" fixup_arm_thumb_cp" , 0 , 8 , 0 },
10096 {" fixup_arm_thumb_bcc" , 0 , 8 , 0 },
10197 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
10298 // - 19.
@@ -124,19 +120,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
124120 //
125121 // Name Offset (bits) Size (bits) Flags
126122 {" fixup_arm_ldst_pcrel_12" , 0 , 32 , 0 },
127- {" fixup_t2_ldst_pcrel_12" , 0 , 32 ,
128- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
123+ {" fixup_t2_ldst_pcrel_12" , 0 , 32 , 0 },
129124 {" fixup_arm_pcrel_10_unscaled" , 0 , 32 , 0 },
130125 {" fixup_arm_pcrel_10" , 0 , 32 , 0 },
131- {" fixup_t2_pcrel_10" , 0 , 32 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
126+ {" fixup_t2_pcrel_10" , 0 , 32 , 0 },
132127 {" fixup_arm_pcrel_9" , 0 , 32 , 0 },
133- {" fixup_t2_pcrel_9" , 0 , 32 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
128+ {" fixup_t2_pcrel_9" , 0 , 32 , 0 },
134129 {" fixup_arm_ldst_abs_12" , 0 , 32 , 0 },
135- {" fixup_thumb_adr_pcrel_10" , 8 , 8 ,
136- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
130+ {" fixup_thumb_adr_pcrel_10" , 8 , 8 , 0 },
137131 {" fixup_arm_adr_pcrel_12" , 0 , 32 , 0 },
138- {" fixup_t2_adr_pcrel_12" , 0 , 32 ,
139- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
132+ {" fixup_t2_adr_pcrel_12" , 0 , 32 , 0 },
140133 {" fixup_arm_condbranch" , 8 , 24 , 0 },
141134 {" fixup_arm_uncondbranch" , 8 , 24 , 0 },
142135 {" fixup_t2_condbranch" , 0 , 32 , 0 },
@@ -146,10 +139,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
146139 {" fixup_arm_condbl" , 8 , 24 , 0 },
147140 {" fixup_arm_blx" , 8 , 24 , 0 },
148141 {" fixup_arm_thumb_bl" , 0 , 32 , 0 },
149- {" fixup_arm_thumb_blx" , 0 , 32 ,
150- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
142+ {" fixup_arm_thumb_blx" , 0 , 32 , 0 },
151143 {" fixup_arm_thumb_cb" , 0 , 16 , 0 },
152- {" fixup_arm_thumb_cp" , 8 , 8 , MCFixupKindInfo::FKF_IsAlignedDownTo32Bits },
144+ {" fixup_arm_thumb_cp" , 8 , 8 , 0 },
153145 {" fixup_arm_thumb_bcc" , 8 , 8 , 0 },
154146 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
155147 // - 19.
@@ -1106,6 +1098,25 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
11061098 }
11071099}
11081100
1101+ std::optional<bool > ARMAsmBackend::evaluateFixup (const MCFragment &F,
1102+ MCFixup &Fixup, MCValue &,
1103+ uint64_t &Value) {
1104+ // For a few PC-relative fixups in Thumb mode, offsets need to be aligned
1105+ // down. We compensate here because the default handler's `Value` decrement
1106+ // doesn't account for this alignment.
1107+ switch (Fixup.getTargetKind ()) {
1108+ case ARM::fixup_t2_ldst_pcrel_12:
1109+ case ARM::fixup_t2_pcrel_10:
1110+ case ARM::fixup_t2_pcrel_9:
1111+ case ARM::fixup_thumb_adr_pcrel_10:
1112+ case ARM::fixup_t2_adr_pcrel_12:
1113+ case ARM::fixup_arm_thumb_blx:
1114+ case ARM::fixup_arm_thumb_cp:
1115+ Value = (Asm->getFragmentOffset (F) + Fixup.getOffset ()) % 4 ;
1116+ }
1117+ return {};
1118+ }
1119+
11091120void ARMAsmBackend::applyFixup (const MCFragment &F, const MCFixup &Fixup,
11101121 const MCValue &Target,
11111122 MutableArrayRef<char > Data, uint64_t Value,
0 commit comments