@@ -69,6 +69,11 @@ class AArch64Thunk : public Thunk {
6969private:
7070 bool mayUseShortThunk = true ;
7171 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 () {}
7277};
7378
7479// AArch64 long range Thunks.
@@ -82,6 +87,8 @@ class AArch64ABSLongThunk final : public AArch64Thunk {
8287
8388private:
8489 void writeLong (uint8_t *buf) override ;
90+ void addLongMapSyms () override ;
91+ ThunkSection *tsec = nullptr ;
8592};
8693
8794class AArch64ADRPThunk final : public AArch64Thunk {
@@ -148,6 +155,8 @@ class ARMThunk : public Thunk {
148155 // can create layout oscillations in certain corner cases which would prevent
149156 // the layout from converging.
150157 bool mayUseShortThunk = true ;
158+ // See comment in AArch64Thunk.
159+ virtual void addLongMapSyms () {}
151160};
152161
153162// Base class for Thumb-2 thunks.
@@ -176,6 +185,8 @@ class ThumbThunk : public Thunk {
176185private:
177186 // See comment in ARMThunk above.
178187 bool mayUseShortThunk = true ;
188+ // See comment in AArch64Thunk.
189+ virtual void addLongMapSyms () {}
179190};
180191
181192// Specific ARM Thunk implementations. The naming convention is:
@@ -229,6 +240,10 @@ class ThumbV6MABSLongThunk final : public ThumbThunk {
229240 uint32_t sizeLong () override { return 12 ; }
230241 void writeLong (uint8_t *buf) override ;
231242 void addSymbols (ThunkSection &isec) override ;
243+
244+ private:
245+ void addLongMapSyms () override ;
246+ ThunkSection *tsec = nullptr ;
232247};
233248
234249class ThumbV6MABSXOLongThunk final : public ThumbThunk {
@@ -249,6 +264,10 @@ class ThumbV6MPILongThunk final : public ThumbThunk {
249264 uint32_t sizeLong () override { return 16 ; }
250265 void writeLong (uint8_t *buf) override ;
251266 void addSymbols (ThunkSection &isec) override ;
267+
268+ private:
269+ void addLongMapSyms () override ;
270+ ThunkSection *tsec = nullptr ;
252271};
253272
254273// Architectures v4, v5 and v6 do not support the movt/movw instructions. v5 and
@@ -267,6 +286,10 @@ class ARMV5LongLdrPcThunk final : public ARMThunk {
267286 uint32_t sizeLong () override { return 8 ; }
268287 void writeLong (uint8_t *buf) override ;
269288 void addSymbols (ThunkSection &isec) override ;
289+
290+ private:
291+ void addLongMapSyms () override ;
292+ ThunkSection *tsec = nullptr ;
270293};
271294
272295// Implementations of Thunks for v4. BLX is not supported, and loads
@@ -279,6 +302,10 @@ class ARMV4PILongBXThunk final : public ARMThunk {
279302 uint32_t sizeLong () override { return 16 ; }
280303 void writeLong (uint8_t *buf) override ;
281304 void addSymbols (ThunkSection &isec) override ;
305+
306+ private:
307+ void addLongMapSyms () override ;
308+ ThunkSection *tsec = nullptr ;
282309};
283310
284311class ARMV4PILongThunk final : public ARMThunk {
@@ -289,6 +316,10 @@ class ARMV4PILongThunk final : public ARMThunk {
289316 uint32_t sizeLong () override { return 12 ; }
290317 void writeLong (uint8_t *buf) override ;
291318 void addSymbols (ThunkSection &isec) override ;
319+
320+ private:
321+ void addLongMapSyms () override ;
322+ ThunkSection *tsec = nullptr ;
292323};
293324
294325class ThumbV4PILongBXThunk final : public ThumbThunk {
@@ -299,6 +330,10 @@ class ThumbV4PILongBXThunk final : public ThumbThunk {
299330 uint32_t sizeLong () override { return 16 ; }
300331 void writeLong (uint8_t *buf) override ;
301332 void addSymbols (ThunkSection &isec) override ;
333+
334+ private:
335+ void addLongMapSyms () override ;
336+ ThunkSection *tsec = nullptr ;
302337};
303338
304339class ThumbV4PILongThunk final : public ThumbThunk {
@@ -309,6 +344,10 @@ class ThumbV4PILongThunk final : public ThumbThunk {
309344 uint32_t sizeLong () override { return 20 ; }
310345 void writeLong (uint8_t *buf) override ;
311346 void addSymbols (ThunkSection &isec) override ;
347+
348+ private:
349+ void addLongMapSyms () override ;
350+ ThunkSection *tsec = nullptr ;
312351};
313352
314353class ARMV4ABSLongBXThunk final : public ARMThunk {
@@ -319,6 +358,10 @@ class ARMV4ABSLongBXThunk final : public ARMThunk {
319358 uint32_t sizeLong () override { return 12 ; }
320359 void writeLong (uint8_t *buf) override ;
321360 void addSymbols (ThunkSection &isec) override ;
361+
362+ private:
363+ void addLongMapSyms () override ;
364+ ThunkSection *tsec = nullptr ;
322365};
323366
324367class ThumbV4ABSLongBXThunk final : public ThumbThunk {
@@ -329,6 +372,10 @@ class ThumbV4ABSLongBXThunk final : public ThumbThunk {
329372 uint32_t sizeLong () override { return 12 ; }
330373 void writeLong (uint8_t *buf) override ;
331374 void addSymbols (ThunkSection &isec) override ;
375+
376+ private:
377+ void addLongMapSyms () override ;
378+ ThunkSection *tsec = nullptr ;
332379};
333380
334381class ThumbV4ABSLongThunk final : public ThumbThunk {
@@ -339,6 +386,10 @@ class ThumbV4ABSLongThunk final : public ThumbThunk {
339386 uint32_t sizeLong () override { return 16 ; }
340387 void writeLong (uint8_t *buf) override ;
341388 void addSymbols (ThunkSection &isec) override ;
389+
390+ private:
391+ void addLongMapSyms () override ;
392+ ThunkSection *tsec = nullptr ;
342393};
343394
344395// The AVR devices need thunks for R_AVR_LO8_LDI_GS/R_AVR_HI8_LDI_GS
@@ -560,6 +611,8 @@ bool AArch64Thunk::getMayUseShortThunk() {
560611 uint64_t s = getAArch64ThunkDestVA (ctx, destination, addend);
561612 uint64_t p = getThunkTargetSym ()->getVA (ctx);
562613 mayUseShortThunk = llvm::isInt<28 >(s - p);
614+ if (!mayUseShortThunk)
615+ addLongMapSyms ();
563616 return mayUseShortThunk;
564617}
565618
@@ -602,8 +655,12 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
602655 addSymbol (ctx.saver .save (" __AArch64AbsLongThunk_" + destination.getName ()),
603656 STT_FUNC, 0 , isec);
604657 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);
607664}
608665
609666// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
@@ -691,11 +748,14 @@ bool ARMThunk::getMayUseShortThunk() {
691748 uint64_t s = getARMThunkDestVA (ctx, destination);
692749 if (s & 1 ) {
693750 mayUseShortThunk = false ;
751+ addLongMapSyms ();
694752 return false ;
695753 }
696754 uint64_t p = getThunkTargetSym ()->getVA (ctx);
697755 int64_t offset = s - p - 8 ;
698756 mayUseShortThunk = llvm::isInt<26 >(offset);
757+ if (!mayUseShortThunk)
758+ addLongMapSyms ();
699759 return mayUseShortThunk;
700760}
701761
@@ -729,16 +789,19 @@ bool ARMThunk::isCompatibleWith(const InputSection &isec,
729789// (see comment for mayUseShortThunk)
730790// && the arch supports Thumb branch range extension.
731791bool ThumbThunk::getMayUseShortThunk () {
732- if (!mayUseShortThunk || !ctx. arg . armJ1J2BranchEncoding )
792+ if (!mayUseShortThunk)
733793 return false ;
734794 uint64_t s = getARMThunkDestVA (ctx, destination);
735- if ((s & 1 ) == 0 ) {
795+ if ((s & 1 ) == 0 || !ctx. arg . armJ1J2BranchEncoding ) {
736796 mayUseShortThunk = false ;
797+ addLongMapSyms ();
737798 return false ;
738799 }
739800 uint64_t p = getThunkTargetSym ()->getVA (ctx) & ~1 ;
740801 int64_t offset = s - p - 4 ;
741802 mayUseShortThunk = llvm::isInt<25 >(offset);
803+ if (!mayUseShortThunk)
804+ addLongMapSyms ();
742805 return mayUseShortThunk;
743806}
744807
@@ -856,8 +919,12 @@ void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
856919 addSymbol (ctx.saver .save (" __Thumbv6MABSLongThunk_" + destination.getName ()),
857920 STT_FUNC, 1 , isec);
858921 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);
861928}
862929
863930void ThumbV6MABSXOLongThunk::writeLong (uint8_t *buf) {
@@ -912,8 +979,12 @@ void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
912979 addSymbol (ctx.saver .save (" __Thumbv6MPILongThunk_" + destination.getName ()),
913980 STT_FUNC, 1 , isec);
914981 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);
917988}
918989
919990void ARMV5LongLdrPcThunk::writeLong (uint8_t *buf) {
@@ -927,8 +998,12 @@ void ARMV5LongLdrPcThunk::addSymbols(ThunkSection &isec) {
927998 addSymbol (ctx.saver .save (" __ARMv5LongLdrPcThunk_" + destination.getName ()),
928999 STT_FUNC, 0 , isec);
9291000 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);
9321007}
9331008
9341009void ARMV4ABSLongBXThunk::writeLong (uint8_t *buf) {
@@ -943,8 +1018,12 @@ void ARMV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
9431018 addSymbol (ctx.saver .save (" __ARMv4ABSLongBXThunk_" + destination.getName ()),
9441019 STT_FUNC, 0 , isec);
9451020 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);
9481027}
9491028
9501029void ThumbV4ABSLongBXThunk::writeLong (uint8_t *buf) {
@@ -961,9 +1040,13 @@ void ThumbV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
9611040 addSymbol (ctx.saver .save (" __Thumbv4ABSLongBXThunk_" + destination.getName ()),
9621041 STT_FUNC, 1 , isec);
9631042 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);
9671050}
9681051
9691052void ThumbV4ABSLongThunk::writeLong (uint8_t *buf) {
@@ -981,9 +1064,13 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
9811064 addSymbol (ctx.saver .save (" __Thumbv4ABSLongThunk_" + destination.getName ()),
9821065 STT_FUNC, 1 , isec);
9831066 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);
9871074}
9881075
9891076void ARMV4PILongBXThunk::writeLong (uint8_t *buf) {
@@ -1000,8 +1087,12 @@ void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
10001087 addSymbol (ctx.saver .save (" __ARMv4PILongBXThunk_" + destination.getName ()),
10011088 STT_FUNC, 0 , isec);
10021089 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);
10051096}
10061097
10071098void ARMV4PILongThunk::writeLong (uint8_t *buf) {
@@ -1017,8 +1108,12 @@ void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
10171108 addSymbol (ctx.saver .save (" __ARMv4PILongThunk_" + destination.getName ()),
10181109 STT_FUNC, 0 , isec);
10191110 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);
10221117}
10231118
10241119void ThumbV4PILongBXThunk::writeLong (uint8_t *buf) {
@@ -1037,9 +1132,13 @@ void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
10371132 addSymbol (ctx.saver .save (" __Thumbv4PILongBXThunk_" + destination.getName ()),
10381133 STT_FUNC, 1 , isec);
10391134 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);
10431142}
10441143
10451144void ThumbV4PILongThunk::writeLong (uint8_t *buf) {
@@ -1059,9 +1158,13 @@ void ThumbV4PILongThunk::addSymbols(ThunkSection &isec) {
10591158 addSymbol (ctx.saver .save (" __Thumbv4PILongThunk_" + destination.getName ()),
10601159 STT_FUNC, 1 , isec);
10611160 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);
10651168}
10661169
10671170// Use the long jump which covers a range up to 8MiB.
0 commit comments