@@ -69,6 +69,11 @@ class AArch64Thunk : public Thunk {
69
69
private:
70
70
bool mayUseShortThunk = true ;
71
71
virtual void writeLong (uint8_t *buf) = 0;
72
+ // A thunk may be written out as a short or long, and we may not know which
73
+ // type at thunk creation time. In some thunk implementations the long thunk
74
+ // has additional mapping symbols. Thus function can be overridden to add
75
+ // these additional mapping symbols.
76
+ virtual void addLongMapSyms () {}
72
77
};
73
78
74
79
// AArch64 long range Thunks.
@@ -82,6 +87,8 @@ class AArch64ABSLongThunk final : public AArch64Thunk {
82
87
83
88
private:
84
89
void writeLong (uint8_t *buf) override ;
90
+ void addLongMapSyms () override ;
91
+ ThunkSection *tsec = nullptr ;
85
92
};
86
93
87
94
class AArch64ADRPThunk final : public AArch64Thunk {
@@ -148,6 +155,8 @@ class ARMThunk : public Thunk {
148
155
// can create layout oscillations in certain corner cases which would prevent
149
156
// the layout from converging.
150
157
bool mayUseShortThunk = true ;
158
+ // See comment in AArch64Thunk.
159
+ virtual void addLongMapSyms () {}
151
160
};
152
161
153
162
// Base class for Thumb-2 thunks.
@@ -176,6 +185,8 @@ class ThumbThunk : public Thunk {
176
185
private:
177
186
// See comment in ARMThunk above.
178
187
bool mayUseShortThunk = true ;
188
+ // See comment in AArch64Thunk.
189
+ virtual void addLongMapSyms () {}
179
190
};
180
191
181
192
// Specific ARM Thunk implementations. The naming convention is:
@@ -229,6 +240,10 @@ class ThumbV6MABSLongThunk final : public ThumbThunk {
229
240
uint32_t sizeLong () override { return 12 ; }
230
241
void writeLong (uint8_t *buf) override ;
231
242
void addSymbols (ThunkSection &isec) override ;
243
+
244
+ private:
245
+ void addLongMapSyms () override ;
246
+ ThunkSection *tsec = nullptr ;
232
247
};
233
248
234
249
class ThumbV6MABSXOLongThunk final : public ThumbThunk {
@@ -249,6 +264,10 @@ class ThumbV6MPILongThunk final : public ThumbThunk {
249
264
uint32_t sizeLong () override { return 16 ; }
250
265
void writeLong (uint8_t *buf) override ;
251
266
void addSymbols (ThunkSection &isec) override ;
267
+
268
+ private:
269
+ void addLongMapSyms () override ;
270
+ ThunkSection *tsec = nullptr ;
252
271
};
253
272
254
273
// Architectures v4, v5 and v6 do not support the movt/movw instructions. v5 and
@@ -267,6 +286,10 @@ class ARMV5LongLdrPcThunk final : public ARMThunk {
267
286
uint32_t sizeLong () override { return 8 ; }
268
287
void writeLong (uint8_t *buf) override ;
269
288
void addSymbols (ThunkSection &isec) override ;
289
+
290
+ private:
291
+ void addLongMapSyms () override ;
292
+ ThunkSection *tsec = nullptr ;
270
293
};
271
294
272
295
// Implementations of Thunks for v4. BLX is not supported, and loads
@@ -279,6 +302,10 @@ class ARMV4PILongBXThunk final : public ARMThunk {
279
302
uint32_t sizeLong () override { return 16 ; }
280
303
void writeLong (uint8_t *buf) override ;
281
304
void addSymbols (ThunkSection &isec) override ;
305
+
306
+ private:
307
+ void addLongMapSyms () override ;
308
+ ThunkSection *tsec = nullptr ;
282
309
};
283
310
284
311
class ARMV4PILongThunk final : public ARMThunk {
@@ -289,6 +316,10 @@ class ARMV4PILongThunk final : public ARMThunk {
289
316
uint32_t sizeLong () override { return 12 ; }
290
317
void writeLong (uint8_t *buf) override ;
291
318
void addSymbols (ThunkSection &isec) override ;
319
+
320
+ private:
321
+ void addLongMapSyms () override ;
322
+ ThunkSection *tsec = nullptr ;
292
323
};
293
324
294
325
class ThumbV4PILongBXThunk final : public ThumbThunk {
@@ -299,6 +330,10 @@ class ThumbV4PILongBXThunk final : public ThumbThunk {
299
330
uint32_t sizeLong () override { return 16 ; }
300
331
void writeLong (uint8_t *buf) override ;
301
332
void addSymbols (ThunkSection &isec) override ;
333
+
334
+ private:
335
+ void addLongMapSyms () override ;
336
+ ThunkSection *tsec = nullptr ;
302
337
};
303
338
304
339
class ThumbV4PILongThunk final : public ThumbThunk {
@@ -309,6 +344,10 @@ class ThumbV4PILongThunk final : public ThumbThunk {
309
344
uint32_t sizeLong () override { return 20 ; }
310
345
void writeLong (uint8_t *buf) override ;
311
346
void addSymbols (ThunkSection &isec) override ;
347
+
348
+ private:
349
+ void addLongMapSyms () override ;
350
+ ThunkSection *tsec = nullptr ;
312
351
};
313
352
314
353
class ARMV4ABSLongBXThunk final : public ARMThunk {
@@ -319,6 +358,10 @@ class ARMV4ABSLongBXThunk final : public ARMThunk {
319
358
uint32_t sizeLong () override { return 12 ; }
320
359
void writeLong (uint8_t *buf) override ;
321
360
void addSymbols (ThunkSection &isec) override ;
361
+
362
+ private:
363
+ void addLongMapSyms () override ;
364
+ ThunkSection *tsec = nullptr ;
322
365
};
323
366
324
367
class ThumbV4ABSLongBXThunk final : public ThumbThunk {
@@ -329,6 +372,10 @@ class ThumbV4ABSLongBXThunk final : public ThumbThunk {
329
372
uint32_t sizeLong () override { return 12 ; }
330
373
void writeLong (uint8_t *buf) override ;
331
374
void addSymbols (ThunkSection &isec) override ;
375
+
376
+ private:
377
+ void addLongMapSyms () override ;
378
+ ThunkSection *tsec = nullptr ;
332
379
};
333
380
334
381
class ThumbV4ABSLongThunk final : public ThumbThunk {
@@ -339,6 +386,10 @@ class ThumbV4ABSLongThunk final : public ThumbThunk {
339
386
uint32_t sizeLong () override { return 16 ; }
340
387
void writeLong (uint8_t *buf) override ;
341
388
void addSymbols (ThunkSection &isec) override ;
389
+
390
+ private:
391
+ void addLongMapSyms () override ;
392
+ ThunkSection *tsec = nullptr ;
342
393
};
343
394
344
395
// The AVR devices need thunks for R_AVR_LO8_LDI_GS/R_AVR_HI8_LDI_GS
@@ -560,6 +611,8 @@ bool AArch64Thunk::getMayUseShortThunk() {
560
611
uint64_t s = getAArch64ThunkDestVA (ctx, destination, addend);
561
612
uint64_t p = getThunkTargetSym ()->getVA (ctx);
562
613
mayUseShortThunk = llvm::isInt<28 >(s - p);
614
+ if (!mayUseShortThunk)
615
+ addLongMapSyms ();
563
616
return mayUseShortThunk;
564
617
}
565
618
@@ -602,8 +655,12 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
602
655
addSymbol (ctx.saver .save (" __AArch64AbsLongThunk_" + destination.getName ()),
603
656
STT_FUNC, 0 , isec);
604
657
addSymbol (" $x" , STT_NOTYPE, 0 , isec);
605
- if (!getMayUseShortThunk ())
606
- addSymbol (" $d" , STT_NOTYPE, 8 , isec);
658
+ tsec = &isec;
659
+ (void )getMayUseShortThunk ();
660
+ }
661
+
662
+ void AArch64ABSLongThunk::addLongMapSyms () {
663
+ addSymbol (" $d" , STT_NOTYPE, 8 , *tsec);
607
664
}
608
665
609
666
// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
@@ -691,11 +748,14 @@ bool ARMThunk::getMayUseShortThunk() {
691
748
uint64_t s = getARMThunkDestVA (ctx, destination);
692
749
if (s & 1 ) {
693
750
mayUseShortThunk = false ;
751
+ addLongMapSyms ();
694
752
return false ;
695
753
}
696
754
uint64_t p = getThunkTargetSym ()->getVA (ctx);
697
755
int64_t offset = s - p - 8 ;
698
756
mayUseShortThunk = llvm::isInt<26 >(offset);
757
+ if (!mayUseShortThunk)
758
+ addLongMapSyms ();
699
759
return mayUseShortThunk;
700
760
}
701
761
@@ -729,16 +789,19 @@ bool ARMThunk::isCompatibleWith(const InputSection &isec,
729
789
// (see comment for mayUseShortThunk)
730
790
// && the arch supports Thumb branch range extension.
731
791
bool ThumbThunk::getMayUseShortThunk () {
732
- if (!mayUseShortThunk || !ctx. arg . armJ1J2BranchEncoding )
792
+ if (!mayUseShortThunk)
733
793
return false ;
734
794
uint64_t s = getARMThunkDestVA (ctx, destination);
735
- if ((s & 1 ) == 0 ) {
795
+ if ((s & 1 ) == 0 || !ctx. arg . armJ1J2BranchEncoding ) {
736
796
mayUseShortThunk = false ;
797
+ addLongMapSyms ();
737
798
return false ;
738
799
}
739
800
uint64_t p = getThunkTargetSym ()->getVA (ctx) & ~1 ;
740
801
int64_t offset = s - p - 4 ;
741
802
mayUseShortThunk = llvm::isInt<25 >(offset);
803
+ if (!mayUseShortThunk)
804
+ addLongMapSyms ();
742
805
return mayUseShortThunk;
743
806
}
744
807
@@ -856,8 +919,12 @@ void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
856
919
addSymbol (ctx.saver .save (" __Thumbv6MABSLongThunk_" + destination.getName ()),
857
920
STT_FUNC, 1 , isec);
858
921
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
859
- if (!getMayUseShortThunk ())
860
- addSymbol (" $d" , STT_NOTYPE, 8 , isec);
922
+ tsec = &isec;
923
+ (void )getMayUseShortThunk ();
924
+ }
925
+
926
+ void ThumbV6MABSLongThunk::addLongMapSyms () {
927
+ addSymbol (" $d" , STT_NOTYPE, 8 , *tsec);
861
928
}
862
929
863
930
void ThumbV6MABSXOLongThunk::writeLong (uint8_t *buf) {
@@ -912,8 +979,12 @@ void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
912
979
addSymbol (ctx.saver .save (" __Thumbv6MPILongThunk_" + destination.getName ()),
913
980
STT_FUNC, 1 , isec);
914
981
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
915
- if (!getMayUseShortThunk ())
916
- addSymbol (" $d" , STT_NOTYPE, 12 , isec);
982
+ tsec = &isec;
983
+ (void )getMayUseShortThunk ();
984
+ }
985
+
986
+ void ThumbV6MPILongThunk::addLongMapSyms () {
987
+ addSymbol (" $d" , STT_NOTYPE, 12 , *tsec);
917
988
}
918
989
919
990
void ARMV5LongLdrPcThunk::writeLong (uint8_t *buf) {
@@ -927,8 +998,12 @@ void ARMV5LongLdrPcThunk::addSymbols(ThunkSection &isec) {
927
998
addSymbol (ctx.saver .save (" __ARMv5LongLdrPcThunk_" + destination.getName ()),
928
999
STT_FUNC, 0 , isec);
929
1000
addSymbol (" $a" , STT_NOTYPE, 0 , isec);
930
- if (!getMayUseShortThunk ())
931
- addSymbol (" $d" , STT_NOTYPE, 4 , isec);
1001
+ tsec = &isec;
1002
+ (void )getMayUseShortThunk ();
1003
+ }
1004
+
1005
+ void ARMV5LongLdrPcThunk::addLongMapSyms () {
1006
+ addSymbol (" $d" , STT_NOTYPE, 4 , *tsec);
932
1007
}
933
1008
934
1009
void ARMV4ABSLongBXThunk::writeLong (uint8_t *buf) {
@@ -943,8 +1018,12 @@ void ARMV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
943
1018
addSymbol (ctx.saver .save (" __ARMv4ABSLongBXThunk_" + destination.getName ()),
944
1019
STT_FUNC, 0 , isec);
945
1020
addSymbol (" $a" , STT_NOTYPE, 0 , isec);
946
- if (!getMayUseShortThunk ())
947
- addSymbol (" $d" , STT_NOTYPE, 8 , isec);
1021
+ tsec = &isec;
1022
+ (void )getMayUseShortThunk ();
1023
+ }
1024
+
1025
+ void ARMV4ABSLongBXThunk::addLongMapSyms () {
1026
+ addSymbol (" $d" , STT_NOTYPE, 8 , *tsec);
948
1027
}
949
1028
950
1029
void ThumbV4ABSLongBXThunk::writeLong (uint8_t *buf) {
@@ -961,9 +1040,13 @@ void ThumbV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
961
1040
addSymbol (ctx.saver .save (" __Thumbv4ABSLongBXThunk_" + destination.getName ()),
962
1041
STT_FUNC, 1 , isec);
963
1042
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
964
- addSymbol (" $a" , STT_NOTYPE, 4 , isec);
965
- if (!getMayUseShortThunk ())
966
- addSymbol (" $d" , STT_NOTYPE, 8 , isec);
1043
+ tsec = &isec;
1044
+ (void )getMayUseShortThunk ();
1045
+ }
1046
+
1047
+ void ThumbV4ABSLongBXThunk::addLongMapSyms () {
1048
+ addSymbol (" $a" , STT_NOTYPE, 4 , *tsec);
1049
+ addSymbol (" $d" , STT_NOTYPE, 8 , *tsec);
967
1050
}
968
1051
969
1052
void ThumbV4ABSLongThunk::writeLong (uint8_t *buf) {
@@ -981,9 +1064,13 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
981
1064
addSymbol (ctx.saver .save (" __Thumbv4ABSLongThunk_" + destination.getName ()),
982
1065
STT_FUNC, 1 , isec);
983
1066
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
984
- addSymbol (" $a" , STT_NOTYPE, 4 , isec);
985
- if (!getMayUseShortThunk ())
986
- addSymbol (" $d" , STT_NOTYPE, 12 , isec);
1067
+ tsec = &isec;
1068
+ (void )getMayUseShortThunk ();
1069
+ }
1070
+
1071
+ void ThumbV4ABSLongThunk::addLongMapSyms () {
1072
+ addSymbol (" $a" , STT_NOTYPE, 4 , *tsec);
1073
+ addSymbol (" $d" , STT_NOTYPE, 12 , *tsec);
987
1074
}
988
1075
989
1076
void ARMV4PILongBXThunk::writeLong (uint8_t *buf) {
@@ -1000,8 +1087,12 @@ void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
1000
1087
addSymbol (ctx.saver .save (" __ARMv4PILongBXThunk_" + destination.getName ()),
1001
1088
STT_FUNC, 0 , isec);
1002
1089
addSymbol (" $a" , STT_NOTYPE, 0 , isec);
1003
- if (!getMayUseShortThunk ())
1004
- addSymbol (" $d" , STT_NOTYPE, 12 , isec);
1090
+ tsec = &isec;
1091
+ (void )getMayUseShortThunk ();
1092
+ }
1093
+
1094
+ void ARMV4PILongBXThunk::addLongMapSyms () {
1095
+ addSymbol (" $d" , STT_NOTYPE, 12 , *tsec);
1005
1096
}
1006
1097
1007
1098
void ARMV4PILongThunk::writeLong (uint8_t *buf) {
@@ -1017,8 +1108,12 @@ void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
1017
1108
addSymbol (ctx.saver .save (" __ARMv4PILongThunk_" + destination.getName ()),
1018
1109
STT_FUNC, 0 , isec);
1019
1110
addSymbol (" $a" , STT_NOTYPE, 0 , isec);
1020
- if (!getMayUseShortThunk ())
1021
- addSymbol (" $d" , STT_NOTYPE, 8 , isec);
1111
+ tsec = &isec;
1112
+ (void )getMayUseShortThunk ();
1113
+ }
1114
+
1115
+ void ARMV4PILongThunk::addLongMapSyms () {
1116
+ addSymbol (" $d" , STT_NOTYPE, 8 , *tsec);
1022
1117
}
1023
1118
1024
1119
void ThumbV4PILongBXThunk::writeLong (uint8_t *buf) {
@@ -1037,9 +1132,13 @@ void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
1037
1132
addSymbol (ctx.saver .save (" __Thumbv4PILongBXThunk_" + destination.getName ()),
1038
1133
STT_FUNC, 1 , isec);
1039
1134
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
1040
- addSymbol (" $a" , STT_NOTYPE, 4 , isec);
1041
- if (!getMayUseShortThunk ())
1042
- addSymbol (" $d" , STT_NOTYPE, 12 , isec);
1135
+ tsec = &isec;
1136
+ (void )getMayUseShortThunk ();
1137
+ }
1138
+
1139
+ void ThumbV4PILongBXThunk::addLongMapSyms () {
1140
+ addSymbol (" $a" , STT_NOTYPE, 4 , *tsec);
1141
+ addSymbol (" $d" , STT_NOTYPE, 12 , *tsec);
1043
1142
}
1044
1143
1045
1144
void ThumbV4PILongThunk::writeLong (uint8_t *buf) {
@@ -1059,9 +1158,13 @@ void ThumbV4PILongThunk::addSymbols(ThunkSection &isec) {
1059
1158
addSymbol (ctx.saver .save (" __Thumbv4PILongThunk_" + destination.getName ()),
1060
1159
STT_FUNC, 1 , isec);
1061
1160
addSymbol (" $t" , STT_NOTYPE, 0 , isec);
1062
- addSymbol (" $a" , STT_NOTYPE, 4 , isec);
1063
- if (!getMayUseShortThunk ())
1064
- addSymbol (" $d" , STT_NOTYPE, 16 , isec);
1161
+ tsec = &isec;
1162
+ (void )getMayUseShortThunk ();
1163
+ }
1164
+
1165
+ void ThumbV4PILongThunk::addLongMapSyms () {
1166
+ addSymbol (" $a" , STT_NOTYPE, 4 , *tsec);
1167
+ addSymbol (" $d" , STT_NOTYPE, 16 , *tsec);
1065
1168
}
1066
1169
1067
1170
// Use the long jump which covers a range up to 8MiB.
0 commit comments