@@ -98,6 +98,7 @@ enum EdgeKind_aarch32 : Edge::Kind {
9898 Thumb_MovtPrel,
9999
100100 LastThumbRelocation = Thumb_MovtPrel,
101+ LastRelocation = LastThumbRelocation,
101102};
102103
103104// / Flags enum for AArch32-specific symbol properties
@@ -163,65 +164,107 @@ struct HalfWords {
163164 const uint16_t Lo; // Second halfword
164165};
165166
166- // / Collection of named constants per fixup kind. It may contain but is not
167- // / limited to the following entries:
167+ // / FixupInfo base class is required for dynamic lookups.
168+ struct FixupInfoBase {
169+ static const FixupInfoBase *getDynFixupInfo (Edge::Kind K);
170+ virtual ~FixupInfoBase () {}
171+ };
172+
173+ // / FixupInfo checks for Arm edge kinds work on 32-bit words
174+ struct FixupInfoArm : public FixupInfoBase {
175+ bool (*checkOpcode)(uint32_t Wd) = nullptr ;
176+ };
177+
178+ // / FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
179+ struct FixupInfoThumb : public FixupInfoBase {
180+ bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr ;
181+ };
182+
183+ // / Collection of named constants per fixup kind
168184// /
185+ // / Mandatory entries:
169186// / Opcode - Values of the op-code bits in the instruction, with
170187// / unaffected bits nulled
171188// / OpcodeMask - Mask with all bits set that encode the op-code
189+ // /
190+ // / Other common entries:
172191// / ImmMask - Mask with all bits set that encode the immediate value
173192// / RegMask - Mask with all bits set that encode the register
174193// /
194+ // / Specializations can add further custom fields without restrictions.
195+ // /
175196template <EdgeKind_aarch32 Kind> struct FixupInfo {};
176197
177- template <> struct FixupInfo <Arm_Jump24> {
198+ namespace {
199+ struct FixupInfoArmBranch : public FixupInfoArm {
178200 static constexpr uint32_t Opcode = 0x0a000000 ;
179- static constexpr uint32_t OpcodeMask = 0x0f000000 ;
180201 static constexpr uint32_t ImmMask = 0x00ffffff ;
181- static constexpr uint32_t Unconditional = 0xe0000000 ;
182- static constexpr uint32_t CondMask = 0xe0000000 ; // excluding BLX bit
202+ };
203+ } // namespace
204+
205+ template <> struct FixupInfo <Arm_Jump24> : public FixupInfoArmBranch {
206+ static constexpr uint32_t OpcodeMask = 0x0f000000 ;
183207};
184208
185- template <> struct FixupInfo <Arm_Call> : public FixupInfo<Arm_Jump24> {
209+ template <> struct FixupInfo <Arm_Call> : public FixupInfoArmBranch {
186210 static constexpr uint32_t OpcodeMask = 0x0e000000 ;
211+ static constexpr uint32_t CondMask = 0xe0000000 ; // excluding BLX bit
212+ static constexpr uint32_t Unconditional = 0xe0000000 ;
187213 static constexpr uint32_t BitH = 0x01000000 ;
188214 static constexpr uint32_t BitBlx = 0x10000000 ;
189215};
190216
191- template <> struct FixupInfo <Arm_MovtAbs> {
192- static constexpr uint32_t Opcode = 0x03400000 ;
217+ namespace {
218+ struct FixupInfoArmMov : public FixupInfoArm {
193219 static constexpr uint32_t OpcodeMask = 0x0ff00000 ;
194220 static constexpr uint32_t ImmMask = 0x000f0fff ;
195221 static constexpr uint32_t RegMask = 0x0000f000 ;
196222};
223+ } // namespace
224+
225+ template <> struct FixupInfo <Arm_MovtAbs> : public FixupInfoArmMov {
226+ static constexpr uint32_t Opcode = 0x03400000 ;
227+ };
197228
198- template <> struct FixupInfo <Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
229+ template <> struct FixupInfo <Arm_MovwAbsNC> : public FixupInfoArmMov {
199230 static constexpr uint32_t Opcode = 0x03000000 ;
200231};
201232
202- template <> struct FixupInfo <Thumb_Jump24> {
233+ template <> struct FixupInfo <Thumb_Jump24> : public FixupInfoThumb {
203234 static constexpr HalfWords Opcode{0xf000 , 0x9000 };
204235 static constexpr HalfWords OpcodeMask{0xf800 , 0x9000 };
205236 static constexpr HalfWords ImmMask{0x07ff , 0x2fff };
206237};
207238
208- template <> struct FixupInfo <Thumb_Call> {
239+ template <> struct FixupInfo <Thumb_Call> : public FixupInfoThumb {
209240 static constexpr HalfWords Opcode{0xf000 , 0xc000 };
210241 static constexpr HalfWords OpcodeMask{0xf800 , 0xc000 };
211242 static constexpr HalfWords ImmMask{0x07ff , 0x2fff };
212243 static constexpr uint16_t LoBitH = 0x0001 ;
213244 static constexpr uint16_t LoBitNoBlx = 0x1000 ;
214245};
215246
216- template <> struct FixupInfo <Thumb_MovtAbs> {
217- static constexpr HalfWords Opcode{ 0xf2c0 , 0x0000 };
247+ namespace {
248+ struct FixupInfoThumbMov : public FixupInfoThumb {
218249 static constexpr HalfWords OpcodeMask{0xfbf0 , 0x8000 };
219250 static constexpr HalfWords ImmMask{0x040f , 0x70ff };
220251 static constexpr HalfWords RegMask{0x0000 , 0x0f00 };
221252};
253+ } // namespace
222254
223- template <>
224- struct FixupInfo <Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
255+ template <> struct FixupInfo <Thumb_MovtAbs> : public FixupInfoThumbMov {
256+ static constexpr HalfWords Opcode{0xf2c0 , 0x0000 };
257+ };
258+
259+ template <> struct FixupInfo <Thumb_MovtPrel> : public FixupInfoThumbMov {
260+ static constexpr HalfWords Opcode{0xf2c0 , 0x0000 };
261+ };
262+
263+ template <> struct FixupInfo <Thumb_MovwAbsNC> : public FixupInfoThumbMov {
264+ static constexpr HalfWords Opcode{0xf240 , 0x0000 };
265+ };
266+
267+ template <> struct FixupInfo <Thumb_MovwPrelNC> : public FixupInfoThumbMov {
225268 static constexpr HalfWords Opcode{0xf240 , 0x0000 };
226269};
227270
0 commit comments