Index: lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -46,6 +46,7 @@ case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: case X86::reloc_global_offset_table: + case X86::reloc_branch_4byte_pcrel: case FK_SecRel_4: case FK_Data_4: return 2; @@ -86,6 +87,7 @@ {"reloc_signed_4byte_relax", 0, 32, 0}, {"reloc_global_offset_table", 0, 32, 0}, {"reloc_global_offset_table8", 0, 64, 0}, + {"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, }; if (Kind < FirstTargetFixupKind) @@ -93,6 +95,7 @@ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); + assert(Infos[Kind - FirstTargetFixupKind].Name && "Empty fixup name!"); return Infos[Kind - FirstTargetFixupKind]; } Index: lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -75,6 +75,9 @@ case X86::reloc_riprel_4byte_relax_rex: case X86::reloc_riprel_4byte_movq_load: return RT64_32; + case X86::reloc_branch_4byte_pcrel: + Modifier = MCSymbolRefExpr::VK_PLT; + return RT64_32; case FK_PCRel_2: case FK_Data_2: return RT64_16; Index: lib/Target/X86/MCTargetDesc/X86FixupKinds.h =================================================================== --- lib/Target/X86/MCTargetDesc/X86FixupKinds.h +++ lib/Target/X86/MCTargetDesc/X86FixupKinds.h @@ -30,6 +30,7 @@ // of the instruction. Used only // for _GLOBAL_OFFSET_TABLE_. reloc_global_offset_table8, // 64-bit variant. + reloc_branch_4byte_pcrel, // 32-bit PC relative branch. // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind Index: lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -152,6 +152,8 @@ uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, int MemOperand, const MCInstrDesc &Desc) const; + + bool isPCRel32Branch(const MCInst &MI) const; }; } // end anonymous namespace @@ -276,6 +278,23 @@ return false; } +bool X86MCCodeEmitter::isPCRel32Branch(const MCInst &MI) const { + unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4) || + getImmFixupKind(Desc.TSFlags) != FK_PCRel_4) + return false; + + unsigned CurOp = X86II::getOperandBias(Desc); + const MCOperand &Op = MI.getOperand(CurOp); + if (!Op.isExpr() || Op.getExpr()->getKind() != MCExpr::SymbolRef) + return false; + + const MCSymbolRefExpr *Ref = + static_cast(Op.getExpr()); + return Ref->getKind() == MCSymbolRefExpr::VK_None; +} + void X86MCCodeEmitter:: EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, @@ -331,7 +350,8 @@ FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) || - FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex)) + FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) || + FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) ImmOffset -= 4; if (FixupKind == FK_PCRel_2) ImmOffset -= 2; @@ -1287,9 +1307,18 @@ EmitByte(BaseOpcode, CurByte, OS); break; } - case X86II::RawFrm: + case X86II::RawFrm: { EmitByte(BaseOpcode, CurByte, OS); + + if (!is64BitMode(STI) || !isPCRel32Branch(MI)) + break; + + const MCOperand &Op = MI.getOperand(CurOp++); + EmitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags), + MCFixupKind(X86::reloc_branch_4byte_pcrel), CurByte, OS, + Fixups); break; + } case X86II::RawFrmMemOffs: // Emit segment override opcode prefix as needed. EmitSegmentOverridePrefix(CurByte, 1, MI, OS); Index: lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -94,6 +94,7 @@ case X86::reloc_riprel_4byte_movq_load: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: + case X86::reloc_branch_4byte_pcrel: case FK_Data_4: return 2; case FK_Data_8: return 3; } Index: lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp @@ -62,6 +62,7 @@ case X86::reloc_riprel_4byte_movq_load: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_branch_4byte_pcrel: return COFF::IMAGE_REL_AMD64_REL32; case FK_Data_4: case X86::reloc_signed_4byte: Index: test/CodeGen/X86/cmp.ll =================================================================== --- test/CodeGen/X86/cmp.ll +++ test/CodeGen/X86/cmp.ll @@ -240,7 +240,7 @@ ; CHECK-NEXT: pushq %rax # encoding: [0x50] ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq test12b # encoding: [0xe8,A,A,A,A] -; CHECK-NEXT: # fixup A - offset: 1, value: test12b-4, kind: FK_PCRel_4 +; CHECK-NEXT: # fixup A - offset: 1, value: test12b-4, kind: reloc_branch_4byte_pcrel ; CHECK-NEXT: testb %al, %al # encoding: [0x84,0xc0] ; CHECK-NEXT: je .LBB12_2 # encoding: [0x74,A] ; CHECK-NEXT: # fixup A - offset: 1, value: .LBB12_2-1, kind: FK_PCRel_1 Index: test/CodeGen/X86/fma.ll =================================================================== --- test/CodeGen/X86/fma.ll +++ test/CodeGen/X86/fma.ll @@ -137,7 +137,7 @@ ; FMA64-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10] ; FMA64-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24] ; FMA64-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A] -; FMA64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4 +; FMA64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel ; FMA64-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38] ; FMA64-NEXT: retq ## encoding: [0xc3] ; @@ -151,7 +151,7 @@ ; FMACALL64-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10] ; FMACALL64-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24] ; FMACALL64-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A] -; FMACALL64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4 +; FMACALL64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel ; FMACALL64-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38] ; FMACALL64-NEXT: retq ## encoding: [0xc3] ; @@ -165,7 +165,7 @@ ; AVX512-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10] ; AVX512-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24] ; AVX512-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A] -; AVX512-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4 +; AVX512-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel ; AVX512-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38] ; AVX512-NEXT: retq ## encoding: [0xc3] ; @@ -179,7 +179,7 @@ ; AVX512VL-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10] ; AVX512VL-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24] ; AVX512VL-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A] -; AVX512VL-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4 +; AVX512VL-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel ; AVX512VL-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38] ; AVX512VL-NEXT: retq ## encoding: [0xc3] entry: Index: test/CodeGen/X86/x86-interrupt_cc.ll =================================================================== --- test/CodeGen/X86/x86-interrupt_cc.ll +++ test/CodeGen/X86/x86-interrupt_cc.ll @@ -161,7 +161,7 @@ ; CHECK64-KNL-NEXT: .cfi_offset %k7, -82 ; CHECK64-KNL-NEXT: cld ## encoding: [0xfc] ; CHECK64-KNL-NEXT: callq _bar ## encoding: [0xe8,A,A,A,A] -; CHECK64-KNL-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: FK_PCRel_4 +; CHECK64-KNL-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: reloc_branch_4byte_pcrel ; CHECK64-KNL-NEXT: vmovups (%rsp), %zmm0 ## 64-byte Reload ; CHECK64-KNL-NEXT: ## encoding: [0x62,0xf1,0x7c,0x48,0x10,0x04,0x24] ; CHECK64-KNL-NEXT: vmovups {{[0-9]+}}(%rsp), %zmm1 ## 64-byte Reload @@ -410,7 +410,7 @@ ; CHECK64-SKX-NEXT: cld ## encoding: [0xfc] ; CHECK64-SKX-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77] ; CHECK64-SKX-NEXT: callq _bar ## encoding: [0xe8,A,A,A,A] -; CHECK64-SKX-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: FK_PCRel_4 +; CHECK64-SKX-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: reloc_branch_4byte_pcrel ; CHECK64-SKX-NEXT: vmovups (%rsp), %zmm0 ## 64-byte Reload ; CHECK64-SKX-NEXT: ## encoding: [0x62,0xf1,0x7c,0x48,0x10,0x04,0x24] ; CHECK64-SKX-NEXT: vmovups {{[0-9]+}}(%rsp), %zmm1 ## 64-byte Reload Index: test/MC/ELF/basic-elf-64.s =================================================================== --- test/MC/ELF/basic-elf-64.s +++ test/MC/ELF/basic-elf-64.s @@ -13,6 +13,7 @@ callq puts xorl %eax, %eax addq $8, %rsp + call foo@GOTPCREL ret .Ltmp0: .size main, .Ltmp0-main @@ -44,14 +45,15 @@ // CHECK: Name: .rela.text -// CHECK: Relocations [ -// CHECK: Section {{.*}} .rela.text { -// CHECK: 0x5 R_X86_64_32 .rodata.str1.1 0x0 -// CHECK: 0xA R_X86_64_PC32 puts 0xFFFFFFFFFFFFFFFC -// CHECK: 0xF R_X86_64_32 .rodata.str1.1 0x6 -// CHECK: 0x14 R_X86_64_PC32 puts 0xFFFFFFFFFFFFFFFC -// CHECK: } -// CHECK: ] +// CHECK: Relocations [ +// CHECK: Section {{.*}} .rela.text { +// CHECK-NEXT: 0x5 R_X86_64_32 .rodata.str1.1 0x0 +// CHECK-NEXT: 0xA R_X86_64_PLT32 puts 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0xF R_X86_64_32 .rodata.str1.1 0x6 +// CHECK-NEXT: 0x14 R_X86_64_PLT32 puts 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0x1F R_X86_64_GOTPCREL foo 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK: Symbol { // CHECK: Binding: Local Index: test/MC/ELF/ifunc-reloc.s =================================================================== --- test/MC/ELF/ifunc-reloc.s +++ test/MC/ELF/ifunc-reloc.s @@ -11,6 +11,6 @@ // CHECK: Relocations [ // CHECK-NEXT: Section {{.*}} .rela.text { -// CHECK-NEXT: 0x1 R_X86_64_PC32 sym 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0x1 R_X86_64_PLT32 sym 0xFFFFFFFFFFFFFFFC // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/MC/ELF/weak-diff.s =================================================================== --- test/MC/ELF/weak-diff.s +++ test/MC/ELF/weak-diff.s @@ -2,7 +2,7 @@ // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.text { -// CHECK-NEXT: 0x1D R_X86_64_PC32 f2 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0x1D R_X86_64_PLT32 f2 0xFFFFFFFFFFFFFFFC // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/MC/ELF/weak-relocation.s =================================================================== --- test/MC/ELF/weak-relocation.s +++ test/MC/ELF/weak-relocation.s @@ -9,6 +9,6 @@ // CHECK: Relocations [ // CHECK-NEXT: Section ({{[0-9]+}}) .rela.text { -// CHECK-NEXT: 0x1 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0x1 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/MC/ELF/weakref-reloc.s =================================================================== --- test/MC/ELF/weakref-reloc.s +++ test/MC/ELF/weakref-reloc.s @@ -9,6 +9,6 @@ // CHECK: Relocations [ // CHECK-NEXT: Section ({{[0-9]+}}) {{[^ ]+}} { // CHECK-NEXT: 0x1 R_X86_64_PLT32 zed 0xFFFFFFFFFFFFFFFC -// CHECK-NEXT: 0x6 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: 0x6 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC // CHECK-NEXT: } // CHECK-NEXT: ]