[lld] r271506 - [ELF] Split too long X86_64TargetInfo::relaxGot method. NFC.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 2 02:22:00 PDT 2016
Author: grimar
Date: Thu Jun 2 04:22:00 2016
New Revision: 271506
URL: http://llvm.org/viewvc/llvm-project?rev=271506&view=rev
Log:
[ELF] Split too long X86_64TargetInfo::relaxGot method. NFC.
Patch adds relaxGotNoPic() method to handle no-PIC path.
Modified:
lld/trunk/ELF/Target.cpp
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=271506&r1=271505&r2=271506&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Jun 2 04:22:00 2016
@@ -120,6 +120,10 @@ public:
void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
+
+private:
+ void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
+ uint8_t ModRm) const;
};
class PPCTargetInfo final : public TargetInfo {
@@ -760,47 +764,13 @@ RelExpr X86_64TargetInfo::adjustRelaxGot
return Config->Pic ? RelExpr : R_RELAX_GOT_PC_NOPIC;
}
-void X86_64TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
- const uint8_t Op = Loc[-2];
- const uint8_t ModRm = Loc[-1];
-
- // Convert mov foo at GOTPCREL(%rip), %reg to lea foo(%rip), %reg.
- if (Op == 0x8b) {
- *(Loc - 2) = 0x8d;
- relocateOne(Loc, R_X86_64_PC32, Val);
- return;
- }
-
- // Convert call/jmp instructions.
- if (Op == 0xff) {
- if (ModRm == 0x15) {
- // ABI says we can convert call *foo at GOTPCREL(%rip) to nop call foo.
- // Instead we convert to addr32 call foo, where addr32 is instruction
- // prefix. That makes result expression to be a single instruction.
- *(Loc - 2) = 0x67; // addr32 prefix
- *(Loc - 1) = 0xe8; // call
- } else {
- assert(ModRm == 0x25);
- // Convert jmp *foo at GOTPCREL(%rip) to jmp foo nop.
- // jmp doesn't return, so it is fine to use nop here, it is just a stub.
- *(Loc - 2) = 0xe9; // jmp
- *(Loc + 3) = 0x90; // nop
- Loc -= 1;
- Val += 1;
- }
- relocateOne(Loc, R_X86_64_PC32, Val);
- return;
- }
-
- assert(!Config->Pic);
- // We are relaxing a rip relative to an absolute, so compensate for the old
- // -4 addend.
- Val += 4;
- // "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
- // (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
- // 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
- // can be used as reference.
-
+// A subset of relaxations can only be applied for no-PIC. This method
+// handles such relaxations. Instructions encoding information was taken from:
+// "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
+// (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
+// 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
+void X86_64TargetInfo::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
+ uint8_t ModRm) const {
const uint8_t Rex = Loc[-3];
// Convert "test %reg, foo at GOTPCREL(%rip)" to "test $foo, %reg".
if (Op == 0x85) {
@@ -862,6 +832,44 @@ void X86_64TargetInfo::relaxGot(uint8_t
relocateOne(Loc, R_X86_64_PC32, Val);
}
+void X86_64TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
+ const uint8_t Op = Loc[-2];
+ const uint8_t ModRm = Loc[-1];
+
+ // Convert mov foo at GOTPCREL(%rip), %reg to lea foo(%rip), %reg.
+ if (Op == 0x8b) {
+ *(Loc - 2) = 0x8d;
+ relocateOne(Loc, R_X86_64_PC32, Val);
+ return;
+ }
+
+ // Convert call/jmp instructions.
+ if (Op == 0xff) {
+ if (ModRm == 0x15) {
+ // ABI says we can convert call *foo at GOTPCREL(%rip) to nop call foo.
+ // Instead we convert to addr32 call foo, where addr32 is instruction
+ // prefix. That makes result expression to be a single instruction.
+ *(Loc - 2) = 0x67; // addr32 prefix
+ *(Loc - 1) = 0xe8; // call
+ } else {
+ assert(ModRm == 0x25);
+ // Convert jmp *foo at GOTPCREL(%rip) to jmp foo nop.
+ // jmp doesn't return, so it is fine to use nop here, it is just a stub.
+ *(Loc - 2) = 0xe9; // jmp
+ *(Loc + 3) = 0x90; // nop
+ Loc -= 1;
+ Val += 1;
+ }
+ relocateOne(Loc, R_X86_64_PC32, Val);
+ return;
+ }
+
+ assert(!Config->Pic);
+ // We are relaxing a rip relative to an absolute, so compensate
+ // for the old -4 addend.
+ relaxGotNoPic(Loc, Val + 4, Op, ModRm);
+}
+
// Relocation masks following the #lo(value), #hi(value), #ha(value),
// #higher(value), #highera(value), #highest(value), and #highesta(value)
// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
More information about the llvm-commits
mailing list