-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[X86][LLD] Handle R_X86_64_CODE_6_GOTTPOFF relocation type #117675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
b9cfa55
8d56798
451a507
3f4aeab
6204ae1
23176d9
43d3c1b
78e0327
279cae2
645ecde
7e5beeb
9c9470e
c30d72b
c5f27c3
6e584af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -401,6 +401,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, | |
case R_X86_64_CODE_4_GOTPCRELX: | ||
case R_X86_64_GOTTPOFF: | ||
case R_X86_64_CODE_4_GOTTPOFF: | ||
case R_X86_64_CODE_6_GOTTPOFF: | ||
return R_GOT_PC; | ||
case R_X86_64_GOTOFF64: | ||
return R_GOTPLTREL; | ||
|
@@ -562,8 +563,9 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, | |
} | ||
} | ||
|
||
// In some conditions, R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF relocation can | ||
// be optimized to R_X86_64_TPOFF32 so that it does not use GOT. | ||
// In some conditions, | ||
// R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF/R_X86_64_CODE_6_GOTTPOFF | ||
// relocation can be optimized to R_X86_64_TPOFF32 so that it does not use GOT. | ||
void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, | ||
uint64_t val) const { | ||
uint8_t *inst = loc - 3; | ||
|
@@ -623,6 +625,41 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, | |
<< "R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ " | ||
"instructions only"; | ||
} | ||
} else if (rel.type == R_X86_64_CODE_6_GOTTPOFF) { | ||
if (loc[-6] != 0x62) { | ||
Err(ctx) << getErrorLoc(ctx, loc - 6) | ||
<< "Invalid prefix with R_X86_64_CODE_6_GOTTPOFF!"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new error messages must be tested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
return; | ||
} | ||
// Check bits are satisfied: | ||
// loc[-5]: X==1 (inverted polarity), (loc[-5] & 0x7) == 0x4 | ||
// loc[-4]: W==1, X2==1 (inverted polarity), pp==0b00(NP) | ||
// loc[-3]: NF==1 or ND==1 | ||
// loc[-2]: opcode==0x1 or opcode==0x3 | ||
// loc[-1]: Mod==0b00, RM==0b101 | ||
if (((loc[-5] & 0x47) == 0x44) && ((loc[-4] & 0x87) == 0x84) && | ||
((loc[-3] & 0x14) != 0) && (loc[-2] == 0x1 || loc[-2] == 0x3) && | ||
((loc[-1] & 0xc7) == 0x5)) { | ||
// "addq %reg1, foo@GOTTPOFF(%rip), %reg2" -> "addq $foo, %reg1, %reg2" | ||
// "addq foo@GOTTPOFF(%rip), %reg1, %reg2" -> "addq $foo, %reg1, %reg2" | ||
// "{nf} addq %reg1, foo@GOTTPOFF(%rip), %reg2" | ||
// -> "{nf} addq $foo, %reg1, %reg2" | ||
// "{nf} addq name@GOTTPOFF(%rip), %reg1, %reg2" | ||
// -> "{nf} addq $foo, %reg1, %reg2" | ||
// "{nf} addq name@GOTTPOFF(%rip), %reg" -> "{nf} addq $foo, %reg" | ||
loc[-2] = 0x81; | ||
// Move R bits to B bits in EVEX payloads and ModRM byte. | ||
const uint8_t evexPayload0 = loc[-5]; | ||
if ((evexPayload0 & (1 << 7)) == 0) | ||
loc[-5] = (evexPayload0 | (1 << 7)) & ~(1 << 5); | ||
if ((evexPayload0 & (1 << 4)) == 0) | ||
loc[-5] = evexPayload0 | (1 << 4) | (1 << 3); | ||
*regSlot = 0xc0 | reg; | ||
} else { | ||
Err(ctx) << getErrorLoc(ctx, loc - 6) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new error messages must be tested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
<< "R_X86_64_CODE_6_GOTTPOFF must be used in ADDQ instructions " | ||
"with NDD/NF/NDD+NF only"; | ||
} | ||
} else { | ||
llvm_unreachable("Unsupported relocation type!"); | ||
} | ||
|
@@ -782,6 +819,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { | |
case R_X86_64_PC32: | ||
case R_X86_64_GOTTPOFF: | ||
case R_X86_64_CODE_4_GOTTPOFF: | ||
case R_X86_64_CODE_6_GOTTPOFF: | ||
case R_X86_64_PLT32: | ||
case R_X86_64_TLSGD: | ||
case R_X86_64_TLSLD: | ||
|
@@ -893,6 +931,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { | |
break; | ||
case R_X86_64_GOTTPOFF: | ||
case R_X86_64_CODE_4_GOTTPOFF: | ||
case R_X86_64_CODE_6_GOTTPOFF: | ||
if (rel.expr == R_RELAX_TLS_IE_TO_LE) { | ||
relaxTlsIeToLe(loc, rel, val); | ||
} else { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, there is a problem with the newly added relocation optimization. Unlike the relocation w/ REX prefix, we don't check the bits strictly. For example, we don't check if the W, X, pp and zero bits in EVEX payload2. This brings an potential issue that the linker hides the bug of assembler.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can easily edit the binary in obj file to produce an invalid encoding with R_X86_64_CODE_6_GOTTPOFF relocation, e.g. set the zero bits in payload2 to ones. And then feed the modified the obj to linker, it would error nothing with this implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean it's better to check the bits strictly as for REX2 prefix? Since we may not use EGPR in instructions with NDD/NF, so it's not necessary to check X bits. I've added check for W bits. Seemed it's complicated to check pp bits. I'll take a look and will add later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Please help review. Thanks.