Hello tech@,

The attached diff changes the order in which clang will allocate
registers on X86, specifically so EBX / RBX are selected last. The
reason is because some instructions using RBX as the destination operand
and either RAX or RCX as the source result in machine code that includes
a C3 or CB byte, which is useful as a return in ROP gadgets. By choosing
EBX/RBX last, there are less of these instructions, and therefore less
of these gadgets.


diff --git lib/Target/X86/X86RegisterInfo.td lib/Target/X86/X86RegisterInfo.td
index 3a61a7247c7..f5106c40445 100644
--- lib/Target/X86/X86RegisterInfo.td
+++ lib/Target/X86/X86RegisterInfo.td
@@ -339,8 +339,8 @@ def GR16 : RegisterClass<"X86", [i16], 16,
                               R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W)>;

 def GR32 : RegisterClass<"X86", [i32], 32,
-                         (add EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
-                              R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D)>;
+                         (add EAX, ECX, EDX, ESI, EDI, EBP, ESP,
+                              R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D, 
EBX)>;

 // GR64 - 64-bit GPRs. This oddly includes RIP, which isn't accurate, since
 // RIP isn't really a register and it can't be used anywhere except in an
@@ -349,7 +349,7 @@ def GR32 : RegisterClass<"X86", [i32], 32,
 // tests because of the inclusion of RIP in this register class.
 def GR64 : RegisterClass<"X86", [i64], 64,
                          (add RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
-                              RBX, R14, R15, R12, R13, RBP, RSP, RIP)>;
+                              R14, R15, R12, R13, RBP, RSP, RIP, RBX)>;

 // Segment registers for use by MOV instructions (and others) that have a
 //   segment register as one operand.  Always contain a 16-bit segment

Reply via email to