@@ -401,6 +401,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
401
401
case R_X86_64_CODE_4_GOTPCRELX:
402
402
case R_X86_64_GOTTPOFF:
403
403
case R_X86_64_CODE_4_GOTTPOFF:
404
+ case R_X86_64_CODE_6_GOTTPOFF:
404
405
return R_GOT_PC;
405
406
case R_X86_64_GOTOFF64:
406
407
return R_GOTPLTREL;
@@ -562,8 +563,9 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
562
563
}
563
564
}
564
565
565
- // In some conditions, R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF relocation can
566
- // be optimized to R_X86_64_TPOFF32 so that it does not use GOT.
566
+ // In some conditions,
567
+ // R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF/R_X86_64_CODE_6_GOTTPOFF
568
+ // relocation can be optimized to R_X86_64_TPOFF32 so that it does not use GOT.
567
569
void X86_64::relaxTlsIeToLe (uint8_t *loc, const Relocation &rel,
568
570
uint64_t val) const {
569
571
uint8_t *inst = loc - 3 ;
@@ -623,6 +625,26 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
623
625
<< " R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ "
624
626
" instructions only" ;
625
627
}
628
+ } else if (rel.type == R_X86_64_CODE_6_GOTTPOFF) {
629
+ if (loc[-6 ] != 0x62 ) {
630
+ Err (ctx) << getErrorLoc (ctx, loc - 6 )
631
+ << " Invalid prefix with R_X86_64_CODE_6_GOTTPOFF!" ;
632
+ return ;
633
+ }
634
+ if (loc[-2 ] == 0x3 || loc[-2 ] == 0x1 ) {
635
+ // "addq foo@gottpoff(%rip), %reg1, %reg2" -> "addq $foo, %reg1, %reg2"
636
+ loc[-2 ] = 0x81 ;
637
+ // Move R bits to B bits in EVEX payloads and ModRM byte.
638
+ if ((loc[-5 ] & (1 << 7 )) == 0 )
639
+ loc[-5 ] = (loc[-5 ] | (1 << 7 )) & ~(1 << 5 );
640
+ if ((loc[-5 ] & (1 << 4 )) == 0 )
641
+ loc[-5 ] = loc[-5 ] | (1 << 4 ) | (1 << 3 );
642
+ *regSlot = 0xc0 | reg;
643
+ } else {
644
+ Err (ctx)
645
+ << getErrorLoc (ctx, loc - 6 )
646
+ << " R_X86_64_CODE_6_GOTTPOFF must be used in ADDQ instructions only" ;
647
+ }
626
648
} else {
627
649
llvm_unreachable (" Unsupported relocation type!" );
628
650
}
@@ -782,6 +804,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const {
782
804
case R_X86_64_PC32:
783
805
case R_X86_64_GOTTPOFF:
784
806
case R_X86_64_CODE_4_GOTTPOFF:
807
+ case R_X86_64_CODE_6_GOTTPOFF:
785
808
case R_X86_64_PLT32:
786
809
case R_X86_64_TLSGD:
787
810
case R_X86_64_TLSLD:
@@ -893,6 +916,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
893
916
break ;
894
917
case R_X86_64_GOTTPOFF:
895
918
case R_X86_64_CODE_4_GOTTPOFF:
919
+ case R_X86_64_CODE_6_GOTTPOFF:
896
920
if (rel.expr == R_RELAX_TLS_IE_TO_LE) {
897
921
relaxTlsIeToLe (loc, rel, val);
898
922
} else {
0 commit comments