@@ -156,7 +156,10 @@ class AArch64TargetInfo final : public TargetInfo {
156156 int32_t Index, unsigned RelOff) const override ;
157157 bool usesOnlyLowPageBits (uint32_t Type) const override ;
158158 void relocateOne (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
159+ RelExpr adjustRelaxExpr (uint32_t Type, const uint8_t *Data,
160+ RelExpr Expr) const override ;
159161 void relaxTlsGdToLe (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
162+ void relaxTlsGdToIe (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
160163 void relaxTlsIeToLe (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
161164};
162165
@@ -1141,6 +1144,16 @@ RelExpr AArch64TargetInfo::getRelExpr(uint32_t Type,
11411144 }
11421145}
11431146
1147+ RelExpr AArch64TargetInfo::adjustRelaxExpr (uint32_t Type, const uint8_t *Data,
1148+ RelExpr Expr) const {
1149+ if (Expr == R_RELAX_TLS_GD_TO_IE) {
1150+ if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
1151+ return R_RELAX_TLS_GD_TO_IE_PAGE_PC;
1152+ return R_RELAX_TLS_GD_TO_IE_ABS;
1153+ }
1154+ return Expr;
1155+ }
1156+
11441157bool AArch64TargetInfo::usesOnlyLowPageBits (uint32_t Type) const {
11451158 switch (Type) {
11461159 default :
@@ -1320,6 +1333,7 @@ void AArch64TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
13201333 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12_NC]
13211334 // add x0, x0, :tlsdesc_los:v [_AARCH64_TLSDESC_ADD_LO12_NC]
13221335 // .tlsdesccall [R_AARCH64_TLSDESC_CALL]
1336+ // blr x1
13231337 // And it can optimized to:
13241338 // movz x0, #0x0, lsl #16
13251339 // movk x0, #0x10
@@ -1348,6 +1362,38 @@ void AArch64TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
13481362 write32le (Loc, NewInst);
13491363}
13501364
1365+ void AArch64TargetInfo::relaxTlsGdToIe (uint8_t *Loc, uint32_t Type,
1366+ uint64_t Val) const {
1367+ // TLSDESC Global-Dynamic relocation are in the form:
1368+ // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
1369+ // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12_NC]
1370+ // add x0, x0, :tlsdesc_los:v [_AARCH64_TLSDESC_ADD_LO12_NC]
1371+ // .tlsdesccall [R_AARCH64_TLSDESC_CALL]
1372+ // blr x1
1373+ // And it can optimized to:
1374+ // adrp x0, :gottprel:v
1375+ // ldr x0, [x0, :gottprel_lo12:v]
1376+ // nop
1377+ // nop
1378+
1379+ switch (Type) {
1380+ case R_AARCH64_TLSDESC_ADD_LO12_NC:
1381+ case R_AARCH64_TLSDESC_CALL:
1382+ write32le (Loc, 0xd503201f ); // nop
1383+ break ;
1384+ case R_AARCH64_TLSDESC_ADR_PAGE21:
1385+ write32le (Loc, 0x90000000 ); // adrp
1386+ relocateOne (Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
1387+ break ;
1388+ case R_AARCH64_TLSDESC_LD64_LO12_NC:
1389+ write32le (Loc, 0xf9400000 ); // ldr
1390+ relocateOne (Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
1391+ break ;
1392+ default :
1393+ llvm_unreachable (" unsupported Relocation for TLS GD to LE relax" );
1394+ }
1395+ }
1396+
13511397void AArch64TargetInfo::relaxTlsIeToLe (uint8_t *Loc, uint32_t Type,
13521398 uint64_t Val) const {
13531399 checkUInt<32 >(Val, Type);
0 commit comments