diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index ce7949db638..2e75ea154be 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -232,10 +232,35 @@ enum { R_386_GOTOFF = 9, R_386_GOTPC = 10, R_386_32PLT = 11, + R_386_TLS_TPOFF = 14, + R_386_TLS_IE = 15, + R_386_TLS_GOTIE = 16, + R_386_TLS_LE = 17, + R_386_TLS_GD = 18, + R_386_TLS_LDM = 19, R_386_16 = 20, R_386_PC16 = 21, R_386_8 = 22, - R_386_PC8 = 23 + R_386_PC8 = 23, + R_386_TLS_GD_32 = 24, + R_386_TLS_GD_PUSH = 25, + R_386_TLS_GD_CALL = 26, + R_386_TLS_GD_POP = 27, + R_386_TLS_LDM_32 = 28, + R_386_TLS_LDM_PUSH = 29, + R_386_TLS_LDM_CALL = 30, + R_386_TLS_LDM_POP = 31, + R_386_TLS_LDO_32 = 32, + R_386_TLS_IE_32 = 33, + R_386_TLS_LE_32 = 34, + R_386_TLS_DTPMOD32 = 35, + R_386_TLS_DTPOFF32 = 36, + R_386_TLS_TPOFF32 = 37, + R_386_TLS_GOTDESC = 39, + R_386_TLS_DESC_CALL = 40, + R_386_TLS_DESC = 41, + R_386_IRELATIVE = 42, + R_386_NUM = 43 }; // Section header. diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 90473dbac9c..1e4484d91b8 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -79,6 +79,7 @@ static bool isFixupKindX86PCRel(unsigned Kind) { } static bool RelocNeedsGOT(unsigned Type) { + // FIXME: Can we use the VariantKind? switch (Type) { default: return false; @@ -88,6 +89,10 @@ static bool RelocNeedsGOT(unsigned Type) { case ELF::R_X86_64_TPOFF32: case ELF::R_X86_64_TLSGD: case ELF::R_X86_64_GOTTPOFF: + case ELF::R_386_TLS_GD: + case ELF::R_386_TLS_LE_32: + case ELF::R_386_TLS_IE: + case ELF::R_386_TLS_LE: return true; } } @@ -766,6 +771,18 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, case MCSymbolRefExpr::VK_GOTOFF: Type = ELF::R_386_GOTOFF; break; + case MCSymbolRefExpr::VK_TLSGD: + Type = ELF::R_386_TLS_GD; + break; + case MCSymbolRefExpr::VK_TPOFF: + Type = ELF::R_386_TLS_LE_32; + break; + case MCSymbolRefExpr::VK_INDNTPOFF: + Type = ELF::R_386_TLS_IE; + break; + case MCSymbolRefExpr::VK_NTPOFF: + Type = ELF::R_386_TLS_LE; + break; } break; case FK_Data_2: Type = ELF::R_386_16; break; diff --git a/test/MC/ELF/relocation-386.s b/test/MC/ELF/relocation-386.s index 06885fdf309..a3e07f57cd3 100644 --- a/test/MC/ELF/relocation-386.s +++ b/test/MC/ELF/relocation-386.s @@ -50,6 +50,33 @@ // CHECK-NEXT: ('r_type', 0x00000003 // CHECK-NEXT: ), +// Relocation 5 (foo@TLSGD) is of type R_386_TLS_GD +// CHECK-NEXT: # Relocation 0x00000005 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x0000000b) +// CHECK-NEXT: ('r_type', 0x00000012) +// CHECK-NEXT: ), + +// Relocation 6 ($foo@TPOFF) is of type R_386_TLS_LE_32 +// CHECK-NEXT: # Relocation 0x00000006 +// CHECK-NEXT: (('r_offset', 0x00000025) +// CHECK-NEXT: ('r_sym', 0x0000000b) +// CHECK-NEXT: ('r_type', 0x00000022) +// CHECK-NEXT: ), + +// Relocation 7 (foo@INDNTPOFF) is of type R_386_TLS_IE +// CHECK-NEXT: # Relocation 0x00000007 +// CHECK-NEXT: (('r_offset', 0x0000002b) +// CHECK-NEXT: ('r_sym', 0x0000000b) +// CHECK-NEXT: ('r_type', 0x0000000f) +// CHECK-NEXT: ), + +// Relocation 8 (foo@NTPOFF) is of type R_386_TLS_LE +// CHECK-NEXT: # Relocation 0x00000008 +// CHECK-NEXT: (('r_offset', 0x00000031) +// CHECK-NEXT: ('r_sym', 0x0000000b) +// CHECK-NEXT: ('r_type', 0x00000011) + .text bar: leal .Lfoo@GOTOFF(%ebx), %eax @@ -66,6 +93,11 @@ bar2: movl bar2j@GOT(%eax), %eax + leal foo@TLSGD(, %ebx,1), %eax + movl $foo@TPOFF, %edx + movl foo@INDNTPOFF, %ecx + addl foo@NTPOFF(%eax), %eax + .section .rodata.str1.16,"aMS",@progbits,1 .Lfoo: .asciz "bool llvm::llvm_start_multithreaded()"