summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2019-07-10 05:00:37 +0000
committerRui Ueyama <ruiu@google.com>2019-07-10 05:00:37 +0000
commit3837f4273fcc40cc519035479aefe78e5cbd3055 (patch)
tree38a9202cec6963abe68d7c2ef6648e4cd2d48578 /lld
parent21b28fb8c5fe32e38dcb2768aa8820fa7a51c522 (diff)
downloadbcm5719-llvm-3837f4273fcc40cc519035479aefe78e5cbd3055.tar.gz
bcm5719-llvm-3837f4273fcc40cc519035479aefe78e5cbd3055.zip
[Coding style change] Rename variables so that they start with a lowercase letter
This patch is mechanically generated by clang-llvm-rename tool that I wrote using Clang Refactoring Engine just for creating this patch. You can see the source code of the tool at https://reviews.llvm.org/D64123. There's no manual post-processing; you can generate the same patch by re-running the tool against lld's code base. Here is the main discussion thread to change the LLVM coding style: https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html In the discussion thread, I proposed we use lld as a testbed for variable naming scheme change, and this patch does that. I chose to rename variables so that they are in camelCase, just because that is a minimal change to make variables to start with a lowercase letter. Note to downstream patch maintainers: if you are maintaining a downstream lld repo, just rebasing ahead of this commit would cause massive merge conflicts because this patch essentially changes every line in the lld subdirectory. But there's a remedy. clang-llvm-rename tool is a batch tool, so you can rename variables in your downstream repo with the tool. Given that, here is how to rebase your repo to a commit after the mass renaming: 1. rebase to the commit just before the mass variable renaming, 2. apply the tool to your downstream repo to mass-rename variables locally, and 3. rebase again to the head. Most changes made by the tool should be identical for a downstream repo and for the head, so at the step 3, almost all changes should be merged and disappear. I'd expect that there would be some lines that you need to merge by hand, but that shouldn't be too many. Differential Revision: https://reviews.llvm.org/D64121 llvm-svn: 365595
Diffstat (limited to 'lld')
-rw-r--r--lld/ELF/AArch64ErrataFix.cpp460
-rw-r--r--lld/ELF/AArch64ErrataFix.h10
-rw-r--r--lld/ELF/Arch/AArch64.cpp408
-rw-r--r--lld/ELF/Arch/AMDGPU.cpp62
-rw-r--r--lld/ELF/Arch/ARM.cpp438
-rw-r--r--lld/ELF/Arch/AVR.cpp30
-rw-r--r--lld/ELF/Arch/Hexagon.cpp186
-rw-r--r--lld/ELF/Arch/MSP430.cpp42
-rw-r--r--lld/ELF/Arch/Mips.cpp594
-rw-r--r--lld/ELF/Arch/MipsArchTree.cpp232
-rw-r--r--lld/ELF/Arch/PPC.cpp342
-rw-r--r--lld/ELF/Arch/PPC64.cpp644
-rw-r--r--lld/ELF/Arch/RISCV.cpp356
-rw-r--r--lld/ELF/Arch/SPARCV9.cpp92
-rw-r--r--lld/ELF/Arch/X86.cpp366
-rw-r--r--lld/ELF/Arch/X86_64.cpp476
-rw-r--r--lld/ELF/CallGraphSort.cpp178
-rw-r--r--lld/ELF/Config.h348
-rw-r--r--lld/ELF/DWARF.cpp102
-rw-r--r--lld/ELF/DWARF.h58
-rw-r--r--lld/ELF/Driver.cpp1788
-rw-r--r--lld/ELF/Driver.h32
-rw-r--r--lld/ELF/DriverUtils.cpp180
-rw-r--r--lld/ELF/EhFrame.cpp130
-rw-r--r--lld/ELF/EhFrame.h4
-rw-r--r--lld/ELF/ICF.cpp324
-rw-r--r--lld/ELF/InputFiles.cpp1358
-rw-r--r--lld/ELF/InputFiles.h232
-rw-r--r--lld/ELF/InputSection.cpp1044
-rw-r--r--lld/ELF/InputSection.h226
-rw-r--r--lld/ELF/LTO.cpp290
-rw-r--r--lld/ELF/LTO.h14
-rw-r--r--lld/ELF/LinkerScript.cpp978
-rw-r--r--lld/ELF/LinkerScript.h212
-rw-r--r--lld/ELF/MapFile.cpp224
-rw-r--r--lld/ELF/MarkLive.cpp242
-rw-r--r--lld/ELF/OutputSections.cpp410
-rw-r--r--lld/ELF/OutputSections.h98
-rw-r--r--lld/ELF/Relocations.cpp1300
-rw-r--r--lld/ELF/Relocations.h50
-rw-r--r--lld/ELF/ScriptLexer.cpp214
-rw-r--r--lld/ELF/ScriptLexer.h22
-rw-r--r--lld/ELF/ScriptParser.cpp1218
-rw-r--r--lld/ELF/ScriptParser.h8
-rw-r--r--lld/ELF/SymbolTable.cpp230
-rw-r--r--lld/ELF/SymbolTable.h36
-rw-r--r--lld/ELF/Symbols.cpp506
-rw-r--r--lld/ELF/Symbols.h326
-rw-r--r--lld/ELF/SyntheticSections.cpp3346
-rw-r--r--lld/ELF/SyntheticSections.h692
-rw-r--r--lld/ELF/Target.cpp90
-rw-r--r--lld/ELF/Target.h210
-rw-r--r--lld/ELF/Thunks.cpp808
-rw-r--r--lld/ELF/Thunks.h24
-rw-r--r--lld/ELF/Writer.cpp2274
-rw-r--r--lld/ELF/Writer.h20
56 files changed, 12292 insertions, 12292 deletions
diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp
index ebf43ea5095..e72e25cb43f 100644
--- a/lld/ELF/AArch64ErrataFix.cpp
+++ b/lld/ELF/AArch64ErrataFix.cpp
@@ -56,8 +56,8 @@ using namespace lld::elf;
// ADRP
// | 1 | immlo (2) | 1 | 0 0 0 0 | immhi (19) | Rd (5) |
-static bool isADRP(uint32_t Instr) {
- return (Instr & 0x9f000000) == 0x90000000;
+static bool isADRP(uint32_t instr) {
+ return (instr & 0x9f000000) == 0x90000000;
}
// Load and store bit patterns from ARMv8-A ARM ARM.
@@ -66,8 +66,8 @@ static bool isADRP(uint32_t Instr) {
// All loads and stores have 1 (at bit postion 27), (0 at bit position 25).
// | op0 x op1 (2) | 1 op2 0 op3 (2) | x | op4 (5) | xxxx | op5 (2) | x (10) |
-static bool isLoadStoreClass(uint32_t Instr) {
- return (Instr & 0x0a000000) == 0x08000000;
+static bool isLoadStoreClass(uint32_t instr) {
+ return (instr & 0x0a000000) == 0x08000000;
}
// LDN/STN multiple no offset
@@ -82,20 +82,20 @@ static bool isLoadStoreClass(uint32_t Instr) {
// opcode == 0110 ST1 3 registers.
// opcode == 0111 ST1 1 register.
// opcode == 1010 ST1 2 registers.
-static bool isST1MultipleOpcode(uint32_t Instr) {
- return (Instr & 0x0000f000) == 0x00002000 ||
- (Instr & 0x0000f000) == 0x00006000 ||
- (Instr & 0x0000f000) == 0x00007000 ||
- (Instr & 0x0000f000) == 0x0000a000;
+static bool isST1MultipleOpcode(uint32_t instr) {
+ return (instr & 0x0000f000) == 0x00002000 ||
+ (instr & 0x0000f000) == 0x00006000 ||
+ (instr & 0x0000f000) == 0x00007000 ||
+ (instr & 0x0000f000) == 0x0000a000;
}
-static bool isST1Multiple(uint32_t Instr) {
- return (Instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(Instr);
+static bool isST1Multiple(uint32_t instr) {
+ return (instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(instr);
}
// Writes to Rn (writeback).
-static bool isST1MultiplePost(uint32_t Instr) {
- return (Instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(Instr);
+static bool isST1MultiplePost(uint32_t instr) {
+ return (instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(instr);
}
// LDN/STN single no offset
@@ -110,41 +110,41 @@ static bool isST1MultiplePost(uint32_t Instr) {
// opcode == 000 ST1 8-bit.
// opcode == 010 ST1 16-bit.
// opcode == 100 ST1 32 or 64-bit (Size determines which).
-static bool isST1SingleOpcode(uint32_t Instr) {
- return (Instr & 0x0040e000) == 0x00000000 ||
- (Instr & 0x0040e000) == 0x00004000 ||
- (Instr & 0x0040e000) == 0x00008000;
+static bool isST1SingleOpcode(uint32_t instr) {
+ return (instr & 0x0040e000) == 0x00000000 ||
+ (instr & 0x0040e000) == 0x00004000 ||
+ (instr & 0x0040e000) == 0x00008000;
}
-static bool isST1Single(uint32_t Instr) {
- return (Instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(Instr);
+static bool isST1Single(uint32_t instr) {
+ return (instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(instr);
}
// Writes to Rn (writeback).
-static bool isST1SinglePost(uint32_t Instr) {
- return (Instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(Instr);
+static bool isST1SinglePost(uint32_t instr) {
+ return (instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(instr);
}
-static bool isST1(uint32_t Instr) {
- return isST1Multiple(Instr) || isST1MultiplePost(Instr) ||
- isST1Single(Instr) || isST1SinglePost(Instr);
+static bool isST1(uint32_t instr) {
+ return isST1Multiple(instr) || isST1MultiplePost(instr) ||
+ isST1Single(instr) || isST1SinglePost(instr);
}
// Load/store exclusive
// | size (2) 00 | 1000 | o2 L o1 | Rs (5) | o0 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for Stores.
-static bool isLoadStoreExclusive(uint32_t Instr) {
- return (Instr & 0x3f000000) == 0x08000000;
+static bool isLoadStoreExclusive(uint32_t instr) {
+ return (instr & 0x3f000000) == 0x08000000;
}
-static bool isLoadExclusive(uint32_t Instr) {
- return (Instr & 0x3f400000) == 0x08400000;
+static bool isLoadExclusive(uint32_t instr) {
+ return (instr & 0x3f400000) == 0x08400000;
}
// Load register literal
// | opc (2) 01 | 1 V 00 | imm19 | Rt (5) |
-static bool isLoadLiteral(uint32_t Instr) {
- return (Instr & 0x3b000000) == 0x18000000;
+static bool isLoadLiteral(uint32_t instr) {
+ return (instr & 0x3b000000) == 0x18000000;
}
// Load/store no-allocate pair
@@ -152,8 +152,8 @@ static bool isLoadLiteral(uint32_t Instr) {
// | opc (2) 10 | 1 V 00 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for stores.
// Never writes to register
-static bool isSTNP(uint32_t Instr) {
- return (Instr & 0x3bc00000) == 0x28000000;
+static bool isSTNP(uint32_t instr) {
+ return (instr & 0x3bc00000) == 0x28000000;
}
// Load/store register pair
@@ -161,69 +161,69 @@ static bool isSTNP(uint32_t Instr) {
// | opc (2) 10 | 1 V 00 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for stores, V == 0 for Scalar, V == 1 for Simd/FP
// Writes to Rn.
-static bool isSTPPost(uint32_t Instr) {
- return (Instr & 0x3bc00000) == 0x28800000;
+static bool isSTPPost(uint32_t instr) {
+ return (instr & 0x3bc00000) == 0x28800000;
}
// (offset)
// | opc (2) 10 | 1 V 01 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
-static bool isSTPOffset(uint32_t Instr) {
- return (Instr & 0x3bc00000) == 0x29000000;
+static bool isSTPOffset(uint32_t instr) {
+ return (instr & 0x3bc00000) == 0x29000000;
}
// (pre-index)
// | opc (2) 10 | 1 V 01 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// Writes to Rn.
-static bool isSTPPre(uint32_t Instr) {
- return (Instr & 0x3bc00000) == 0x29800000;
+static bool isSTPPre(uint32_t instr) {
+ return (instr & 0x3bc00000) == 0x29800000;
}
-static bool isSTP(uint32_t Instr) {
- return isSTPPost(Instr) || isSTPOffset(Instr) || isSTPPre(Instr);
+static bool isSTP(uint32_t instr) {
+ return isSTPPost(instr) || isSTPOffset(instr) || isSTPPre(instr);
}
// Load/store register (unscaled immediate)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 00 | Rn (5) | Rt (5) |
// V == 0 for Scalar, V == 1 for Simd/FP.
-static bool isLoadStoreUnscaled(uint32_t Instr) {
- return (Instr & 0x3b000c00) == 0x38000000;
+static bool isLoadStoreUnscaled(uint32_t instr) {
+ return (instr & 0x3b000c00) == 0x38000000;
}
// Load/store register (immediate post-indexed)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 01 | Rn (5) | Rt (5) |
-static bool isLoadStoreImmediatePost(uint32_t Instr) {
- return (Instr & 0x3b200c00) == 0x38000400;
+static bool isLoadStoreImmediatePost(uint32_t instr) {
+ return (instr & 0x3b200c00) == 0x38000400;
}
// Load/store register (unprivileged)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 10 | Rn (5) | Rt (5) |
-static bool isLoadStoreUnpriv(uint32_t Instr) {
- return (Instr & 0x3b200c00) == 0x38000800;
+static bool isLoadStoreUnpriv(uint32_t instr) {
+ return (instr & 0x3b200c00) == 0x38000800;
}
// Load/store register (immediate pre-indexed)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 11 | Rn (5) | Rt (5) |
-static bool isLoadStoreImmediatePre(uint32_t Instr) {
- return (Instr & 0x3b200c00) == 0x38000c00;
+static bool isLoadStoreImmediatePre(uint32_t instr) {
+ return (instr & 0x3b200c00) == 0x38000c00;
}
// Load/store register (register offset)
// | size (2) 11 | 1 V 00 | opc (2) 1 | Rm (5) | option (3) S | 10 | Rn | Rt |
-static bool isLoadStoreRegisterOff(uint32_t Instr) {
- return (Instr & 0x3b200c00) == 0x38200800;
+static bool isLoadStoreRegisterOff(uint32_t instr) {
+ return (instr & 0x3b200c00) == 0x38200800;
}
// Load/store register (unsigned immediate)
// | size (2) 11 | 1 V 01 | opc (2) | imm12 | Rn (5) | Rt (5) |
-static bool isLoadStoreRegisterUnsigned(uint32_t Instr) {
- return (Instr & 0x3b000000) == 0x39000000;
+static bool isLoadStoreRegisterUnsigned(uint32_t instr) {
+ return (instr & 0x3b000000) == 0x39000000;
}
// Rt is always in bit position 0 - 4.
-static uint32_t getRt(uint32_t Instr) { return (Instr & 0x1f); }
+static uint32_t getRt(uint32_t instr) { return (instr & 0x1f); }
// Rn is always in bit position 5 - 9.
-static uint32_t getRn(uint32_t Instr) { return (Instr >> 5) & 0x1f; }
+static uint32_t getRn(uint32_t instr) { return (instr >> 5) & 0x1f; }
// C4.1.2 Branches, Exception Generating and System instructions
// | op0 (3) 1 | 01 op1 (4) | x (22) |
@@ -232,41 +232,41 @@ static uint32_t getRn(uint32_t Instr) { return (Instr >> 5) & 0x1f; }
// op0 == x00 101 op1 == xxxx Unconditional Branch immediate.
// op0 == x01 101 op1 == 0xxx Compare and branch immediate.
// op0 == x01 101 op1 == 1xxx Test and branch immediate.
-static bool isBranch(uint32_t Instr) {
- return ((Instr & 0xfe000000) == 0xd6000000) || // Cond branch.
- ((Instr & 0xfe000000) == 0x54000000) || // Uncond branch reg.
- ((Instr & 0x7c000000) == 0x14000000) || // Uncond branch imm.
- ((Instr & 0x7c000000) == 0x34000000); // Compare and test branch.
+static bool isBranch(uint32_t instr) {
+ return ((instr & 0xfe000000) == 0xd6000000) || // Cond branch.
+ ((instr & 0xfe000000) == 0x54000000) || // Uncond branch reg.
+ ((instr & 0x7c000000) == 0x14000000) || // Uncond branch imm.
+ ((instr & 0x7c000000) == 0x34000000); // Compare and test branch.
}
-static bool isV8SingleRegisterNonStructureLoadStore(uint32_t Instr) {
- return isLoadStoreUnscaled(Instr) || isLoadStoreImmediatePost(Instr) ||
- isLoadStoreUnpriv(Instr) || isLoadStoreImmediatePre(Instr) ||
- isLoadStoreRegisterOff(Instr) || isLoadStoreRegisterUnsigned(Instr);
+static bool isV8SingleRegisterNonStructureLoadStore(uint32_t instr) {
+ return isLoadStoreUnscaled(instr) || isLoadStoreImmediatePost(instr) ||
+ isLoadStoreUnpriv(instr) || isLoadStoreImmediatePre(instr) ||
+ isLoadStoreRegisterOff(instr) || isLoadStoreRegisterUnsigned(instr);
}
// Note that this function refers to v8.0 only and does not include the
// additional load and store instructions added for in later revisions of
// the architecture such as the Atomic memory operations introduced
// in v8.1.
-static bool isV8NonStructureLoad(uint32_t Instr) {
- if (isLoadExclusive(Instr))
+static bool isV8NonStructureLoad(uint32_t instr) {
+ if (isLoadExclusive(instr))
return true;
- if (isLoadLiteral(Instr))
+ if (isLoadLiteral(instr))
return true;
- else if (isV8SingleRegisterNonStructureLoadStore(Instr)) {
+ else if (isV8SingleRegisterNonStructureLoadStore(instr)) {
// For Load and Store single register, Loads are derived from a
// combination of the Size, V and Opc fields.
- uint32_t Size = (Instr >> 30) & 0xff;
- uint32_t V = (Instr >> 26) & 0x1;
- uint32_t Opc = (Instr >> 22) & 0x3;
+ uint32_t size = (instr >> 30) & 0xff;
+ uint32_t v = (instr >> 26) & 0x1;
+ uint32_t opc = (instr >> 22) & 0x3;
// For the load and store instructions that we are decoding.
// Opc == 0 are all stores.
// Opc == 1 with a couple of exceptions are loads. The exceptions are:
// Size == 00 (0), V == 1, Opc == 10 (2) which is a store and
// Size == 11 (3), V == 0, Opc == 10 (2) which is a prefetch.
- return Opc != 0 && !(Size == 0 && V == 1 && Opc == 2) &&
- !(Size == 3 && V == 0 && Opc == 2);
+ return opc != 0 && !(size == 0 && v == 1 && opc == 2) &&
+ !(size == 3 && v == 0 && opc == 2);
}
return false;
}
@@ -275,18 +275,18 @@ static bool isV8NonStructureLoad(uint32_t Instr) {
// needed for errata 843419.
// Instruction with writeback updates the index register after the load/store.
-static bool hasWriteback(uint32_t Instr) {
- return isLoadStoreImmediatePre(Instr) || isLoadStoreImmediatePost(Instr) ||
- isSTPPre(Instr) || isSTPPost(Instr) || isST1SinglePost(Instr) ||
- isST1MultiplePost(Instr);
+static bool hasWriteback(uint32_t instr) {
+ return isLoadStoreImmediatePre(instr) || isLoadStoreImmediatePost(instr) ||
+ isSTPPre(instr) || isSTPPost(instr) || isST1SinglePost(instr) ||
+ isST1MultiplePost(instr);
}
// For the load and store class of instructions, a load can write to the
// destination register, a load and a store can write to the base register when
// the instruction has writeback.
-static bool doesLoadStoreWriteToReg(uint32_t Instr, uint32_t Reg) {
- return (isV8NonStructureLoad(Instr) && getRt(Instr) == Reg) ||
- (hasWriteback(Instr) && getRn(Instr) == Reg);
+static bool doesLoadStoreWriteToReg(uint32_t instr, uint32_t reg) {
+ return (isV8NonStructureLoad(instr) && getRt(instr) == reg) ||
+ (hasWriteback(instr) && getRn(instr) == reg);
}
// Scanner for Cortex-A53 errata 843419
@@ -318,18 +318,18 @@ static bool doesLoadStoreWriteToReg(uint32_t Instr, uint32_t Reg) {
// Return true if the Instruction sequence Adrp, Instr2, and Instr4 match
// the erratum sequence. The Adrp, Instr2 and Instr4 correspond to 1.), 2.),
// and 4.) in the Scanner for Cortex-A53 errata comment above.
-static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2,
- uint32_t Instr4) {
- if (!isADRP(Instr1))
+static bool is843419ErratumSequence(uint32_t instr1, uint32_t instr2,
+ uint32_t instr4) {
+ if (!isADRP(instr1))
return false;
- uint32_t Rn = getRt(Instr1);
- return isLoadStoreClass(Instr2) &&
- (isLoadStoreExclusive(Instr2) || isLoadLiteral(Instr2) ||
- isV8SingleRegisterNonStructureLoadStore(Instr2) || isSTP(Instr2) ||
- isSTNP(Instr2) || isST1(Instr2)) &&
- !doesLoadStoreWriteToReg(Instr2, Rn) &&
- isLoadStoreRegisterUnsigned(Instr4) && getRn(Instr4) == Rn;
+ uint32_t rn = getRt(instr1);
+ return isLoadStoreClass(instr2) &&
+ (isLoadStoreExclusive(instr2) || isLoadLiteral(instr2) ||
+ isV8SingleRegisterNonStructureLoadStore(instr2) || isSTP(instr2) ||
+ isSTNP(instr2) || isST1(instr2)) &&
+ !doesLoadStoreWriteToReg(instr2, rn) &&
+ isLoadStoreRegisterUnsigned(instr4) && getRn(instr4) == rn;
}
// Scan the instruction sequence starting at Offset Off from the base of
@@ -338,89 +338,89 @@ static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2,
// instructions we've scanned.
// Return the offset of the load or store instruction in IS that we want to
// patch or 0 if no patch required.
-static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,
- uint64_t Limit) {
- uint64_t ISAddr = IS->getVA(0);
+static uint64_t scanCortexA53Errata843419(InputSection *isec, uint64_t &off,
+ uint64_t limit) {
+ uint64_t isecAddr = isec->getVA(0);
// Advance Off so that (ISAddr + Off) modulo 0x1000 is at least 0xff8.
- uint64_t InitialPageOff = (ISAddr + Off) & 0xfff;
- if (InitialPageOff < 0xff8)
- Off += 0xff8 - InitialPageOff;
+ uint64_t initialPageOff = (isecAddr + off) & 0xfff;
+ if (initialPageOff < 0xff8)
+ off += 0xff8 - initialPageOff;
- bool OptionalAllowed = Limit - Off > 12;
- if (Off >= Limit || Limit - Off < 12) {
+ bool optionalAllowed = limit - off > 12;
+ if (off >= limit || limit - off < 12) {
// Need at least 3 4-byte sized instructions to trigger erratum.
- Off = Limit;
+ off = limit;
return 0;
}
- uint64_t PatchOff = 0;
- const uint8_t *Buf = IS->data().begin();
- const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
- uint32_t Instr1 = *InstBuf++;
- uint32_t Instr2 = *InstBuf++;
- uint32_t Instr3 = *InstBuf++;
- if (is843419ErratumSequence(Instr1, Instr2, Instr3)) {
- PatchOff = Off + 8;
- } else if (OptionalAllowed && !isBranch(Instr3)) {
- uint32_t Instr4 = *InstBuf++;
- if (is843419ErratumSequence(Instr1, Instr2, Instr4))
- PatchOff = Off + 12;
+ uint64_t patchOff = 0;
+ const uint8_t *buf = isec->data().begin();
+ const ulittle32_t *instBuf = reinterpret_cast<const ulittle32_t *>(buf + off);
+ uint32_t instr1 = *instBuf++;
+ uint32_t instr2 = *instBuf++;
+ uint32_t instr3 = *instBuf++;
+ if (is843419ErratumSequence(instr1, instr2, instr3)) {
+ patchOff = off + 8;
+ } else if (optionalAllowed && !isBranch(instr3)) {
+ uint32_t instr4 = *instBuf++;
+ if (is843419ErratumSequence(instr1, instr2, instr4))
+ patchOff = off + 12;
}
- if (((ISAddr + Off) & 0xfff) == 0xff8)
- Off += 4;
+ if (((isecAddr + off) & 0xfff) == 0xff8)
+ off += 4;
else
- Off += 0xffc;
- return PatchOff;
+ off += 0xffc;
+ return patchOff;
}
class lld::elf::Patch843419Section : public SyntheticSection {
public:
- Patch843419Section(InputSection *P, uint64_t Off);
+ Patch843419Section(InputSection *p, uint64_t off);
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override { return 8; }
uint64_t getLDSTAddr() const;
// The Section we are patching.
- const InputSection *Patchee;
+ const InputSection *patchee;
// The offset of the instruction in the Patchee section we are patching.
- uint64_t PatcheeOffset;
+ uint64_t patcheeOffset;
// A label for the start of the Patch that we can use as a relocation target.
- Symbol *PatchSym;
+ Symbol *patchSym;
};
-lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off)
+lld::elf::Patch843419Section::Patch843419Section(InputSection *p, uint64_t off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 4,
".text.patch"),
- Patchee(P), PatcheeOffset(Off) {
- this->Parent = P->getParent();
- PatchSym = addSyntheticLocal(
+ patchee(p), patcheeOffset(off) {
+ this->parent = p->getParent();
+ patchSym = addSyntheticLocal(
Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
getSize(), *this);
addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this);
}
uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {
- return Patchee->getVA(PatcheeOffset);
+ return patchee->getVA(patcheeOffset);
}
-void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {
+void lld::elf::Patch843419Section::writeTo(uint8_t *buf) {
// Copy the instruction that we will be replacing with a branch in the
// Patchee Section.
- write32le(Buf, read32le(Patchee->data().begin() + PatcheeOffset));
+ write32le(buf, read32le(patchee->data().begin() + patcheeOffset));
// Apply any relocation transferred from the original PatcheeSection.
// For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc
// also adds OutSecOff so we need to subtract to avoid double counting.
- this->relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + getSize());
+ this->relocateAlloc(buf - outSecOff, buf - outSecOff + getSize());
// Return address is the next instruction after the one we have just copied.
- uint64_t S = getLDSTAddr() + 4;
- uint64_t P = PatchSym->getVA() + 4;
- Target->relocateOne(Buf + 4, R_AARCH64_JUMP26, S - P);
+ uint64_t s = getLDSTAddr() + 4;
+ uint64_t p = patchSym->getVA() + 4;
+ target->relocateOne(buf + 4, R_AARCH64_JUMP26, s - p);
}
void AArch64Err843419Patcher::init() {
@@ -434,47 +434,47 @@ void AArch64Err843419Patcher::init() {
// within sections. If there is no next symbol then the half open interval is
// [Symbol Value, End of section). The type, code or data, is determined by
// the mapping symbol name, $x for code, $d for data.
- auto IsCodeMapSymbol = [](const Symbol *B) {
- return B->getName() == "$x" || B->getName().startswith("$x.");
+ auto isCodeMapSymbol = [](const Symbol *b) {
+ return b->getName() == "$x" || b->getName().startswith("$x.");
};
- auto IsDataMapSymbol = [](const Symbol *B) {
- return B->getName() == "$d" || B->getName().startswith("$d.");
+ auto isDataMapSymbol = [](const Symbol *b) {
+ return b->getName() == "$d" || b->getName().startswith("$d.");
};
// Collect mapping symbols for every executable InputSection.
- for (InputFile *File : ObjectFiles) {
- auto *F = cast<ObjFile<ELF64LE>>(File);
- for (Symbol *B : F->getLocalSymbols()) {
- auto *Def = dyn_cast<Defined>(B);
- if (!Def)
+ for (InputFile *file : objectFiles) {
+ auto *f = cast<ObjFile<ELF64LE>>(file);
+ for (Symbol *b : f->getLocalSymbols()) {
+ auto *def = dyn_cast<Defined>(b);
+ if (!def)
continue;
- if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))
+ if (!isCodeMapSymbol(def) && !isDataMapSymbol(def))
continue;
- if (auto *Sec = dyn_cast_or_null<InputSection>(Def->Section))
- if (Sec->Flags & SHF_EXECINSTR)
- SectionMap[Sec].push_back(Def);
+ if (auto *sec = dyn_cast_or_null<InputSection>(def->section))
+ if (sec->flags & SHF_EXECINSTR)
+ sectionMap[sec].push_back(def);
}
}
// For each InputSection make sure the mapping symbols are in sorted in
// ascending order and free from consecutive runs of mapping symbols with
// the same type. For example we must remove the redundant $d.1 from $x.0
// $d.0 $d.1 $x.1.
- for (auto &KV : SectionMap) {
- std::vector<const Defined *> &MapSyms = KV.second;
- if (MapSyms.size() <= 1)
+ for (auto &kv : sectionMap) {
+ std::vector<const Defined *> &mapSyms = kv.second;
+ if (mapSyms.size() <= 1)
continue;
- llvm::stable_sort(MapSyms, [](const Defined *A, const Defined *B) {
- return A->Value < B->Value;
+ llvm::stable_sort(mapSyms, [](const Defined *a, const Defined *b) {
+ return a->value < b->value;
});
- MapSyms.erase(
- std::unique(MapSyms.begin(), MapSyms.end(),
- [=](const Defined *A, const Defined *B) {
- return (IsCodeMapSymbol(A) && IsCodeMapSymbol(B)) ||
- (IsDataMapSymbol(A) && IsDataMapSymbol(B));
+ mapSyms.erase(
+ std::unique(mapSyms.begin(), mapSyms.end(),
+ [=](const Defined *a, const Defined *b) {
+ return (isCodeMapSymbol(a) && isCodeMapSymbol(b)) ||
+ (isDataMapSymbol(a) && isDataMapSymbol(b));
}),
- MapSyms.end());
+ mapSyms.end());
}
- Initialized = true;
+ initialized = true;
}
// Insert the PatchSections we have created back into the
@@ -483,60 +483,60 @@ void AArch64Err843419Patcher::init() {
// executable sections, although we may need to insert them earlier if the
// InputSectionDescription is larger than the maximum branch range.
void AArch64Err843419Patcher::insertPatches(
- InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
- uint64_t ISLimit;
- uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;
- uint64_t PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
- uint64_t OutSecAddr = ISD.Sections.front()->getParent()->Addr;
+ InputSectionDescription &isd, std::vector<Patch843419Section *> &patches) {
+ uint64_t isecLimit;
+ uint64_t prevISLimit = isd.sections.front()->outSecOff;
+ uint64_t patchUpperBound = prevISLimit + target->getThunkSectionSpacing();
+ uint64_t outSecAddr = isd.sections.front()->getParent()->addr;
// Set the OutSecOff of patches to the place where we want to insert them.
// We use a similar strategy to Thunk placement. Place patches roughly
// every multiple of maximum branch range.
- auto PatchIt = Patches.begin();
- auto PatchEnd = Patches.end();
- for (const InputSection *IS : ISD.Sections) {
- ISLimit = IS->OutSecOff + IS->getSize();
- if (ISLimit > PatchUpperBound) {
- while (PatchIt != PatchEnd) {
- if ((*PatchIt)->getLDSTAddr() - OutSecAddr >= PrevISLimit)
+ auto patchIt = patches.begin();
+ auto patchEnd = patches.end();
+ for (const InputSection *isec : isd.sections) {
+ isecLimit = isec->outSecOff + isec->getSize();
+ if (isecLimit > patchUpperBound) {
+ while (patchIt != patchEnd) {
+ if ((*patchIt)->getLDSTAddr() - outSecAddr >= prevISLimit)
break;
- (*PatchIt)->OutSecOff = PrevISLimit;
- ++PatchIt;
+ (*patchIt)->outSecOff = prevISLimit;
+ ++patchIt;
}
- PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
+ patchUpperBound = prevISLimit + target->getThunkSectionSpacing();
}
- PrevISLimit = ISLimit;
+ prevISLimit = isecLimit;
}
- for (; PatchIt != PatchEnd; ++PatchIt) {
- (*PatchIt)->OutSecOff = ISLimit;
+ for (; patchIt != patchEnd; ++patchIt) {
+ (*patchIt)->outSecOff = isecLimit;
}
// merge all patch sections. We use the OutSecOff assigned above to
// determine the insertion point. This is ok as we only merge into an
// InputSectionDescription once per pass, and at the end of the pass
// assignAddresses() will recalculate all the OutSecOff values.
- std::vector<InputSection *> Tmp;
- Tmp.reserve(ISD.Sections.size() + Patches.size());
- auto MergeCmp = [](const InputSection *A, const InputSection *B) {
- if (A->OutSecOff < B->OutSecOff)
+ std::vector<InputSection *> tmp;
+ tmp.reserve(isd.sections.size() + patches.size());
+ auto mergeCmp = [](const InputSection *a, const InputSection *b) {
+ if (a->outSecOff < b->outSecOff)
return true;
- if (A->OutSecOff == B->OutSecOff && isa<Patch843419Section>(A) &&
- !isa<Patch843419Section>(B))
+ if (a->outSecOff == b->outSecOff && isa<Patch843419Section>(a) &&
+ !isa<Patch843419Section>(b))
return true;
return false;
};
- std::merge(ISD.Sections.begin(), ISD.Sections.end(), Patches.begin(),
- Patches.end(), std::back_inserter(Tmp), MergeCmp);
- ISD.Sections = std::move(Tmp);
+ std::merge(isd.sections.begin(), isd.sections.end(), patches.begin(),
+ patches.end(), std::back_inserter(tmp), mergeCmp);
+ isd.sections = std::move(tmp);
}
// Given an erratum sequence that starts at address AdrpAddr, with an
// instruction that we need to patch at PatcheeOffset from the start of
// InputSection IS, create a Patch843419 Section and add it to the
// Patches that we need to insert.
-static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
- InputSection *IS,
- std::vector<Patch843419Section *> &Patches) {
+static void implementPatch(uint64_t adrpAddr, uint64_t patcheeOffset,
+ InputSection *isec,
+ std::vector<Patch843419Section *> &patches) {
// There may be a relocation at the same offset that we are patching. There
// are four cases that we need to consider.
// Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this
@@ -551,29 +551,29 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
// and replace the relocation with a R_AARCH_JUMP26 branch relocation.
// Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
// relocation at the offset.
- auto RelIt = llvm::find_if(IS->Relocations, [=](const Relocation &R) {
- return R.Offset == PatcheeOffset;
+ auto relIt = llvm::find_if(isec->relocations, [=](const Relocation &r) {
+ return r.offset == patcheeOffset;
});
- if (RelIt != IS->Relocations.end() &&
- (RelIt->Type == R_AARCH64_JUMP26 || RelIt->Expr == R_RELAX_TLS_IE_TO_LE))
+ if (relIt != isec->relocations.end() &&
+ (relIt->type == R_AARCH64_JUMP26 || relIt->expr == R_RELAX_TLS_IE_TO_LE))
return;
log("detected cortex-a53-843419 erratum sequence starting at " +
- utohexstr(AdrpAddr) + " in unpatched output.");
+ utohexstr(adrpAddr) + " in unpatched output.");
- auto *PS = make<Patch843419Section>(IS, PatcheeOffset);
- Patches.push_back(PS);
+ auto *ps = make<Patch843419Section>(isec, patcheeOffset);
+ patches.push_back(ps);
- auto MakeRelToPatch = [](uint64_t Offset, Symbol *PatchSym) {
- return Relocation{R_PC, R_AARCH64_JUMP26, Offset, 0, PatchSym};
+ auto makeRelToPatch = [](uint64_t offset, Symbol *patchSym) {
+ return Relocation{R_PC, R_AARCH64_JUMP26, offset, 0, patchSym};
};
- if (RelIt != IS->Relocations.end()) {
- PS->Relocations.push_back(
- {RelIt->Expr, RelIt->Type, 0, RelIt->Addend, RelIt->Sym});
- *RelIt = MakeRelToPatch(PatcheeOffset, PS->PatchSym);
+ if (relIt != isec->relocations.end()) {
+ ps->relocations.push_back(
+ {relIt->expr, relIt->type, 0, relIt->addend, relIt->sym});
+ *relIt = makeRelToPatch(patcheeOffset, ps->patchSym);
} else
- IS->Relocations.push_back(MakeRelToPatch(PatcheeOffset, PS->PatchSym));
+ isec->relocations.push_back(makeRelToPatch(patcheeOffset, ps->patchSym));
}
// Scan all the instructions in InputSectionDescription, for each instance of
@@ -581,40 +581,40 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
// Patch843419Sections that need to be applied to ISD.
std::vector<Patch843419Section *>
AArch64Err843419Patcher::patchInputSectionDescription(
- InputSectionDescription &ISD) {
- std::vector<Patch843419Section *> Patches;
- for (InputSection *IS : ISD.Sections) {
+ InputSectionDescription &isd) {
+ std::vector<Patch843419Section *> patches;
+ for (InputSection *isec : isd.sections) {
// LLD doesn't use the erratum sequence in SyntheticSections.
- if (isa<SyntheticSection>(IS))
+ if (isa<SyntheticSection>(isec))
continue;
// Use SectionMap to make sure we only scan code and not inline data.
// We have already sorted MapSyms in ascending order and removed consecutive
// mapping symbols of the same type. Our range of executable instructions to
// scan is therefore [CodeSym->Value, DataSym->Value) or [CodeSym->Value,
// section size).
- std::vector<const Defined *> &MapSyms = SectionMap[IS];
+ std::vector<const Defined *> &mapSyms = sectionMap[isec];
- auto CodeSym = llvm::find_if(MapSyms, [&](const Defined *MS) {
- return MS->getName().startswith("$x");
+ auto codeSym = llvm::find_if(mapSyms, [&](const Defined *ms) {
+ return ms->getName().startswith("$x");
});
- while (CodeSym != MapSyms.end()) {
- auto DataSym = std::next(CodeSym);
- uint64_t Off = (*CodeSym)->Value;
- uint64_t Limit =
- (DataSym == MapSyms.end()) ? IS->data().size() : (*DataSym)->Value;
+ while (codeSym != mapSyms.end()) {
+ auto dataSym = std::next(codeSym);
+ uint64_t off = (*codeSym)->value;
+ uint64_t limit =
+ (dataSym == mapSyms.end()) ? isec->data().size() : (*dataSym)->value;
- while (Off < Limit) {
- uint64_t StartAddr = IS->getVA(Off);
- if (uint64_t PatcheeOffset = scanCortexA53Errata843419(IS, Off, Limit))
- implementPatch(StartAddr, PatcheeOffset, IS, Patches);
+ while (off < limit) {
+ uint64_t startAddr = isec->getVA(off);
+ if (uint64_t patcheeOffset = scanCortexA53Errata843419(isec, off, limit))
+ implementPatch(startAddr, patcheeOffset, isec, patches);
}
- if (DataSym == MapSyms.end())
+ if (dataSym == mapSyms.end())
break;
- CodeSym = std::next(DataSym);
+ codeSym = std::next(dataSym);
}
}
- return Patches;
+ return patches;
}
// For each InputSectionDescription make one pass over the executable sections
@@ -630,22 +630,22 @@ AArch64Err843419Patcher::patchInputSectionDescription(
// Ouptut and Input Sections may have been changed.
// Returns false if no patches were required and no changes were made.
bool AArch64Err843419Patcher::createFixes() {
- if (Initialized == false)
+ if (initialized == false)
init();
- bool AddressesChanged = false;
- for (OutputSection *OS : OutputSections) {
- if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
+ bool addressesChanged = false;
+ for (OutputSection *os : outputSections) {
+ if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))
continue;
- for (BaseCommand *BC : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
- std::vector<Patch843419Section *> Patches =
- patchInputSectionDescription(*ISD);
- if (!Patches.empty()) {
- insertPatches(*ISD, Patches);
- AddressesChanged = true;
+ for (BaseCommand *bc : os->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(bc)) {
+ std::vector<Patch843419Section *> patches =
+ patchInputSectionDescription(*isd);
+ if (!patches.empty()) {
+ insertPatches(*isd, patches);
+ addressesChanged = true;
}
}
}
- return AddressesChanged;
+ return addressesChanged;
}
diff --git a/lld/ELF/AArch64ErrataFix.h b/lld/ELF/AArch64ErrataFix.h
index 48ddb7c8337..e4752e7bb8a 100644
--- a/lld/ELF/AArch64ErrataFix.h
+++ b/lld/ELF/AArch64ErrataFix.h
@@ -29,19 +29,19 @@ public:
private:
std::vector<Patch843419Section *>
- patchInputSectionDescription(InputSectionDescription &ISD);
+ patchInputSectionDescription(InputSectionDescription &isd);
- void insertPatches(InputSectionDescription &ISD,
- std::vector<Patch843419Section *> &Patches);
+ void insertPatches(InputSectionDescription &isd,
+ std::vector<Patch843419Section *> &patches);
void init();
// A cache of the mapping symbols defined by the InputSecion sorted in order
// of ascending value with redundant symbols removed. These describe
// the ranges of code and data in an executable InputSection.
- std::map<InputSection *, std::vector<const Defined *>> SectionMap;
+ std::map<InputSection *, std::vector<const Defined *>> sectionMap;
- bool Initialized = false;
+ bool initialized = false;
};
} // namespace elf
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 0695ffa9db3..47371c2ee1a 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -23,59 +23,59 @@ using namespace lld::elf;
// Page(Expr) is the page address of the expression Expr, defined
// as (Expr & ~0xFFF). (This applies even if the machine page size
// supported by the platform has a different value.)
-uint64_t elf::getAArch64Page(uint64_t Expr) {
- return Expr & ~static_cast<uint64_t>(0xFFF);
+uint64_t elf::getAArch64Page(uint64_t expr) {
+ return expr & ~static_cast<uint64_t>(0xFFF);
}
namespace {
class AArch64 : public TargetInfo {
public:
AArch64();
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const override;
uint32_t getThunkSectionSpacing() const override;
- bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
- bool usesOnlyLowPageBits(RelType Type) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const override;
- void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
+ bool usesOnlyLowPageBits(RelType type) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const override;
+ void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
AArch64::AArch64() {
- CopyRel = R_AARCH64_COPY;
- RelativeRel = R_AARCH64_RELATIVE;
- IRelativeRel = R_AARCH64_IRELATIVE;
- GotRel = R_AARCH64_GLOB_DAT;
- NoneRel = R_AARCH64_NONE;
- PltRel = R_AARCH64_JUMP_SLOT;
- SymbolicRel = R_AARCH64_ABS64;
- TlsDescRel = R_AARCH64_TLSDESC;
- TlsGotRel = R_AARCH64_TLS_TPREL64;
- PltEntrySize = 16;
- PltHeaderSize = 32;
- DefaultMaxPageSize = 65536;
+ copyRel = R_AARCH64_COPY;
+ relativeRel = R_AARCH64_RELATIVE;
+ iRelativeRel = R_AARCH64_IRELATIVE;
+ gotRel = R_AARCH64_GLOB_DAT;
+ noneRel = R_AARCH64_NONE;
+ pltRel = R_AARCH64_JUMP_SLOT;
+ symbolicRel = R_AARCH64_ABS64;
+ tlsDescRel = R_AARCH64_TLSDESC;
+ tlsGotRel = R_AARCH64_TLS_TPREL64;
+ pltEntrySize = 16;
+ pltHeaderSize = 32;
+ defaultMaxPageSize = 65536;
// Align to the 2 MiB page size (known as a superpage or huge page).
// FreeBSD automatically promotes 2 MiB-aligned allocations.
- DefaultImageBase = 0x200000;
+ defaultImageBase = 0x200000;
- NeedsThunks = true;
+ needsThunks = true;
}
-RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_AARCH64_TLSDESC_ADR_PAGE21:
return R_AARCH64_TLSDESC_PAGE;
case R_AARCH64_TLSDESC_LD64_LO12:
@@ -117,18 +117,18 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
}
}
-RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- if (Expr == R_RELAX_TLS_GD_TO_IE) {
- if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
+RelExpr AArch64::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ if (expr == R_RELAX_TLS_GD_TO_IE) {
+ if (type == R_AARCH64_TLSDESC_ADR_PAGE21)
return R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC;
return R_RELAX_TLS_GD_TO_IE_ABS;
}
- return Expr;
+ return expr;
}
-bool AArch64::usesOnlyLowPageBits(RelType Type) const {
- switch (Type) {
+bool AArch64::usesOnlyLowPageBits(RelType type) const {
+ switch (type) {
default:
return false;
case R_AARCH64_ADD_ABS_LO12_NC:
@@ -145,18 +145,18 @@ bool AArch64::usesOnlyLowPageBits(RelType Type) const {
}
}
-RelType AArch64::getDynRel(RelType Type) const {
- if (Type == R_AARCH64_ABS64)
- return Type;
+RelType AArch64::getDynRel(RelType type) const {
+ if (type == R_AARCH64_ABS64)
+ return type;
return R_AARCH64_NONE;
}
-void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
- write64le(Buf, In.Plt->getVA());
+void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const {
+ write64le(buf, in.plt->getVA());
}
-void AArch64::writePltHeader(uint8_t *Buf) const {
- const uint8_t PltData[] = {
+void AArch64::writePltHeader(uint8_t *buf) const {
+ const uint8_t pltData[] = {
0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2]))
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))]
@@ -166,42 +166,42 @@ void AArch64::writePltHeader(uint8_t *Buf) const {
0x1f, 0x20, 0x03, 0xd5, // nop
0x1f, 0x20, 0x03, 0xd5 // nop
};
- memcpy(Buf, PltData, sizeof(PltData));
-
- uint64_t Got = In.GotPlt->getVA();
- uint64_t Plt = In.Plt->getVA();
- relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
- relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
- relocateOne(Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, Got + 16);
+ memcpy(buf, pltData, sizeof(pltData));
+
+ uint64_t got = in.gotPlt->getVA();
+ uint64_t plt = in.plt->getVA();
+ relocateOne(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(got + 16) - getAArch64Page(plt + 4));
+ relocateOne(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
+ relocateOne(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
}
-void AArch64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Inst[] = {
+void AArch64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t inst[] = {
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))]
0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[n]))
0x20, 0x02, 0x1f, 0xd6 // br x17
};
- memcpy(Buf, Inst, sizeof(Inst));
+ memcpy(buf, inst, sizeof(inst));
- relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(GotPltEntryAddr) - getAArch64Page(PltEntryAddr));
- relocateOne(Buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, GotPltEntryAddr);
- relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr);
+ relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(gotPltEntryAddr) - getAArch64Page(pltEntryAddr));
+ relocateOne(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
+ relocateOne(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
}
-bool AArch64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
+bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
// ELF for the ARM 64-bit architecture, section Call and Jump relocations
// only permits range extension thunks for R_AARCH64_CALL26 and
// R_AARCH64_JUMP26 relocation types.
- if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
+ if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
return false;
- uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
- return !inBranchRange(Type, BranchAddr, Dst);
+ uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
+ return !inBranchRange(type, branchAddr, dst);
}
uint32_t AArch64::getThunkSectionSpacing() const {
@@ -211,70 +211,70 @@ uint32_t AArch64::getThunkSectionSpacing() const {
return (128 * 1024 * 1024) - 0x30000;
}
-bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
- if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
+bool AArch64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
+ if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
return true;
// The AArch64 call and unconditional branch instructions have a range of
// +/- 128 MiB.
- uint64_t Range = 128 * 1024 * 1024;
- if (Dst > Src) {
+ uint64_t range = 128 * 1024 * 1024;
+ if (dst > src) {
// Immediate of branch is signed.
- Range -= 4;
- return Dst - Src <= Range;
+ range -= 4;
+ return dst - src <= range;
}
- return Src - Dst <= Range;
+ return src - dst <= range;
}
-static void write32AArch64Addr(uint8_t *L, uint64_t Imm) {
- uint32_t ImmLo = (Imm & 0x3) << 29;
- uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
- uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
- write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
+static void write32AArch64Addr(uint8_t *l, uint64_t imm) {
+ uint32_t immLo = (imm & 0x3) << 29;
+ uint32_t immHi = (imm & 0x1FFFFC) << 3;
+ uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3);
+ write32le(l, (read32le(l) & ~mask) | immLo | immHi);
}
// Return the bits [Start, End] from Val shifted Start bits.
// For instance, getBits(0xF0, 4, 8) returns 0xF.
-static uint64_t getBits(uint64_t Val, int Start, int End) {
- uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
- return (Val >> Start) & Mask;
+static uint64_t getBits(uint64_t val, int start, int end) {
+ uint64_t mask = ((uint64_t)1 << (end + 1 - start)) - 1;
+ return (val >> start) & mask;
}
-static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
+static void or32le(uint8_t *p, int32_t v) { write32le(p, read32le(p) | v); }
// Update the immediate field in a AARCH64 ldr, str, and add instruction.
-static void or32AArch64Imm(uint8_t *L, uint64_t Imm) {
- or32le(L, (Imm & 0xFFF) << 10);
+static void or32AArch64Imm(uint8_t *l, uint64_t imm) {
+ or32le(l, (imm & 0xFFF) << 10);
}
-void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void AArch64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_AARCH64_ABS16:
case R_AARCH64_PREL16:
- checkIntUInt(Loc, Val, 16, Type);
- write16le(Loc, Val);
+ checkIntUInt(loc, val, 16, type);
+ write16le(loc, val);
break;
case R_AARCH64_ABS32:
case R_AARCH64_PREL32:
- checkIntUInt(Loc, Val, 32, Type);
- write32le(Loc, Val);
+ checkIntUInt(loc, val, 32, type);
+ write32le(loc, val);
break;
case R_AARCH64_ABS64:
case R_AARCH64_PREL64:
- write64le(Loc, Val);
+ write64le(loc, val);
break;
case R_AARCH64_ADD_ABS_LO12_NC:
- or32AArch64Imm(Loc, Val);
+ or32AArch64Imm(loc, val);
break;
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_ADR_PREL_PG_HI21:
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
case R_AARCH64_TLSDESC_ADR_PAGE21:
- checkInt(Loc, Val, 33, Type);
- write32AArch64Addr(Loc, Val >> 12);
+ checkInt(loc, val, 33, type);
+ write32AArch64Addr(loc, val >> 12);
break;
case R_AARCH64_ADR_PREL_LO21:
- checkInt(Loc, Val, 21, Type);
- write32AArch64Addr(Loc, Val);
+ checkInt(loc, val, 21, type);
+ write32AArch64Addr(loc, val);
break;
case R_AARCH64_JUMP26:
// Normally we would just write the bits of the immediate field, however
@@ -284,75 +284,75 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// opcode and the immediate (0 001 | 01 imm26) we can do this
// transformation by placing a R_AARCH64_JUMP26 relocation at the offset of
// the instruction we want to patch.
- write32le(Loc, 0x14000000);
+ write32le(loc, 0x14000000);
LLVM_FALLTHROUGH;
case R_AARCH64_CALL26:
- checkInt(Loc, Val, 28, Type);
- or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
+ checkInt(loc, val, 28, type);
+ or32le(loc, (val & 0x0FFFFFFC) >> 2);
break;
case R_AARCH64_CONDBR19:
case R_AARCH64_LD_PREL_LO19:
- checkAlignment(Loc, Val, 4, Type);
- checkInt(Loc, Val, 21, Type);
- or32le(Loc, (Val & 0x1FFFFC) << 3);
+ checkAlignment(loc, val, 4, type);
+ checkInt(loc, val, 21, type);
+ or32le(loc, (val & 0x1FFFFC) << 3);
break;
case R_AARCH64_LDST8_ABS_LO12_NC:
case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
- or32AArch64Imm(Loc, getBits(Val, 0, 11));
+ or32AArch64Imm(loc, getBits(val, 0, 11));
break;
case R_AARCH64_LDST16_ABS_LO12_NC:
case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
- checkAlignment(Loc, Val, 2, Type);
- or32AArch64Imm(Loc, getBits(Val, 1, 11));
+ checkAlignment(loc, val, 2, type);
+ or32AArch64Imm(loc, getBits(val, 1, 11));
break;
case R_AARCH64_LDST32_ABS_LO12_NC:
case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
- checkAlignment(Loc, Val, 4, Type);
- or32AArch64Imm(Loc, getBits(Val, 2, 11));
+ checkAlignment(loc, val, 4, type);
+ or32AArch64Imm(loc, getBits(val, 2, 11));
break;
case R_AARCH64_LDST64_ABS_LO12_NC:
case R_AARCH64_LD64_GOT_LO12_NC:
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
case R_AARCH64_TLSDESC_LD64_LO12:
- checkAlignment(Loc, Val, 8, Type);
- or32AArch64Imm(Loc, getBits(Val, 3, 11));
+ checkAlignment(loc, val, 8, type);
+ or32AArch64Imm(loc, getBits(val, 3, 11));
break;
case R_AARCH64_LDST128_ABS_LO12_NC:
case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC:
- checkAlignment(Loc, Val, 16, Type);
- or32AArch64Imm(Loc, getBits(Val, 4, 11));
+ checkAlignment(loc, val, 16, type);
+ or32AArch64Imm(loc, getBits(val, 4, 11));
break;
case R_AARCH64_MOVW_UABS_G0_NC:
- or32le(Loc, (Val & 0xFFFF) << 5);
+ or32le(loc, (val & 0xFFFF) << 5);
break;
case R_AARCH64_MOVW_UABS_G1_NC:
- or32le(Loc, (Val & 0xFFFF0000) >> 11);
+ or32le(loc, (val & 0xFFFF0000) >> 11);
break;
case R_AARCH64_MOVW_UABS_G2_NC:
- or32le(Loc, (Val & 0xFFFF00000000) >> 27);
+ or32le(loc, (val & 0xFFFF00000000) >> 27);
break;
case R_AARCH64_MOVW_UABS_G3:
- or32le(Loc, (Val & 0xFFFF000000000000) >> 43);
+ or32le(loc, (val & 0xFFFF000000000000) >> 43);
break;
case R_AARCH64_TSTBR14:
- checkInt(Loc, Val, 16, Type);
- or32le(Loc, (Val & 0xFFFC) << 3);
+ checkInt(loc, val, 16, type);
+ or32le(loc, (val & 0xFFFC) << 3);
break;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
- checkUInt(Loc, Val, 24, Type);
- or32AArch64Imm(Loc, Val >> 12);
+ checkUInt(loc, val, 24, type);
+ or32AArch64Imm(loc, val >> 12);
break;
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
case R_AARCH64_TLSDESC_ADD_LO12:
- or32AArch64Imm(Loc, Val);
+ or32AArch64Imm(loc, val);
break;
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
-void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void AArch64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
// TLSDESC Global-Dynamic relocation are in the form:
// adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
// ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
@@ -364,25 +364,25 @@ void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// movk x0, #0x10
// nop
// nop
- checkUInt(Loc, Val, 32, Type);
+ checkUInt(loc, val, 32, type);
- switch (Type) {
+ switch (type) {
case R_AARCH64_TLSDESC_ADD_LO12:
case R_AARCH64_TLSDESC_CALL:
- write32le(Loc, 0xd503201f); // nop
+ write32le(loc, 0xd503201f); // nop
return;
case R_AARCH64_TLSDESC_ADR_PAGE21:
- write32le(Loc, 0xd2a00000 | (((Val >> 16) & 0xffff) << 5)); // movz
+ write32le(loc, 0xd2a00000 | (((val >> 16) & 0xffff) << 5)); // movz
return;
case R_AARCH64_TLSDESC_LD64_LO12:
- write32le(Loc, 0xf2800000 | ((Val & 0xffff) << 5)); // movk
+ write32le(loc, 0xf2800000 | ((val & 0xffff) << 5)); // movk
return;
default:
llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
}
}
-void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void AArch64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
// TLSDESC Global-Dynamic relocation are in the form:
// adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
// ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
@@ -395,37 +395,37 @@ void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// nop
// nop
- switch (Type) {
+ switch (type) {
case R_AARCH64_TLSDESC_ADD_LO12:
case R_AARCH64_TLSDESC_CALL:
- write32le(Loc, 0xd503201f); // nop
+ write32le(loc, 0xd503201f); // nop
break;
case R_AARCH64_TLSDESC_ADR_PAGE21:
- write32le(Loc, 0x90000000); // adrp
- relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
+ write32le(loc, 0x90000000); // adrp
+ relocateOne(loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, val);
break;
case R_AARCH64_TLSDESC_LD64_LO12:
- write32le(Loc, 0xf9400000); // ldr
- relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
+ write32le(loc, 0xf9400000); // ldr
+ relocateOne(loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, val);
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
}
}
-void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- checkUInt(Loc, Val, 32, Type);
+void AArch64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ checkUInt(loc, val, 32, type);
- if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
+ if (type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
// Generate MOVZ.
- uint32_t RegNo = read32le(Loc) & 0x1f;
- write32le(Loc, (0xd2a00000 | RegNo) | (((Val >> 16) & 0xffff) << 5));
+ uint32_t regNo = read32le(loc) & 0x1f;
+ write32le(loc, (0xd2a00000 | regNo) | (((val >> 16) & 0xffff) << 5));
return;
}
- if (Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
+ if (type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
// Generate MOVK.
- uint32_t RegNo = read32le(Loc) & 0x1f;
- write32le(Loc, (0xf2800000 | RegNo) | ((Val & 0xffff) << 5));
+ uint32_t regNo = read32le(loc) & 0x1f;
+ write32le(loc, (0xf2800000 | regNo) | ((val & 0xffff) << 5));
return;
}
llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
@@ -470,19 +470,19 @@ namespace {
class AArch64BtiPac final : public AArch64 {
public:
AArch64BtiPac();
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
private:
- bool BtiHeader; // bti instruction needed in PLT Header
- bool BtiEntry; // bti instruction needed in PLT Entry
- bool PacEntry; // autia1716 instruction needed in PLT Entry
+ bool btiHeader; // bti instruction needed in PLT Header
+ bool btiEntry; // bti instruction needed in PLT Entry
+ bool pacEntry; // autia1716 instruction needed in PLT Entry
};
} // namespace
AArch64BtiPac::AArch64BtiPac() {
- BtiHeader = (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
+ btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
// A BTI (Branch Target Indicator) Plt Entry is only required if the
// address of the PLT entry can be taken by the program, which permits an
// indirect jump to the PLT entry. This can happen when the address
@@ -490,16 +490,16 @@ AArch64BtiPac::AArch64BtiPac() {
// the function in an executable being taken by a shared library.
// FIXME: There is a potential optimization to omit the BTI if we detect
// that the address of the PLT entry isn't taken.
- BtiEntry = BtiHeader && !Config->Shared;
- PacEntry = (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC);
+ btiEntry = btiHeader && !config->shared;
+ pacEntry = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC);
- if (BtiEntry || PacEntry)
- PltEntrySize = 24;
+ if (btiEntry || pacEntry)
+ pltEntrySize = 24;
}
-void AArch64BtiPac::writePltHeader(uint8_t *Buf) const {
- const uint8_t BtiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
- const uint8_t PltData[] = {
+void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
+ const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
+ const uint8_t pltData[] = {
0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2]))
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))]
@@ -508,80 +508,80 @@ void AArch64BtiPac::writePltHeader(uint8_t *Buf) const {
0x1f, 0x20, 0x03, 0xd5, // nop
0x1f, 0x20, 0x03, 0xd5 // nop
};
- const uint8_t NopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
+ const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
- uint64_t Got = In.GotPlt->getVA();
- uint64_t Plt = In.Plt->getVA();
+ uint64_t got = in.gotPlt->getVA();
+ uint64_t plt = in.plt->getVA();
- if (BtiHeader) {
+ if (btiHeader) {
// PltHeader is called indirectly by Plt[N]. Prefix PltData with a BTI C
// instruction.
- memcpy(Buf, BtiData, sizeof(BtiData));
- Buf += sizeof(BtiData);
- Plt += sizeof(BtiData);
+ memcpy(buf, btiData, sizeof(btiData));
+ buf += sizeof(btiData);
+ plt += sizeof(btiData);
}
- memcpy(Buf, PltData, sizeof(PltData));
+ memcpy(buf, pltData, sizeof(pltData));
- relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(Got + 16) - getAArch64Page(Plt + 8));
- relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
- relocateOne(Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, Got + 16);
- if (!BtiHeader)
+ relocateOne(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(got + 16) - getAArch64Page(plt + 8));
+ relocateOne(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
+ relocateOne(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
+ if (!btiHeader)
// We didn't add the BTI c instruction so round out size with NOP.
- memcpy(Buf + sizeof(PltData), NopData, sizeof(NopData));
+ memcpy(buf + sizeof(pltData), nopData, sizeof(nopData));
}
-void AArch64BtiPac::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
+void AArch64BtiPac::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
// The PLT entry is of the form:
// [BtiData] AddrInst (PacBr | StdBr) [NopData]
- const uint8_t BtiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
- const uint8_t AddrInst[] = {
+ const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
+ const uint8_t addrInst[] = {
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))]
0x10, 0x02, 0x00, 0x91 // add x16, x16, Offset(&(.plt.got[n]))
};
- const uint8_t PacBr[] = {
+ const uint8_t pacBr[] = {
0x9f, 0x21, 0x03, 0xd5, // autia1716
0x20, 0x02, 0x1f, 0xd6 // br x17
};
- const uint8_t StdBr[] = {
+ const uint8_t stdBr[] = {
0x20, 0x02, 0x1f, 0xd6, // br x17
0x1f, 0x20, 0x03, 0xd5 // nop
};
- const uint8_t NopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
+ const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
- if (BtiEntry) {
- memcpy(Buf, BtiData, sizeof(BtiData));
- Buf += sizeof(BtiData);
- PltEntryAddr += sizeof(BtiData);
+ if (btiEntry) {
+ memcpy(buf, btiData, sizeof(btiData));
+ buf += sizeof(btiData);
+ pltEntryAddr += sizeof(btiData);
}
- memcpy(Buf, AddrInst, sizeof(AddrInst));
- relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(GotPltEntryAddr) -
- getAArch64Page(PltEntryAddr));
- relocateOne(Buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, GotPltEntryAddr);
- relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr);
+ memcpy(buf, addrInst, sizeof(addrInst));
+ relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(gotPltEntryAddr) -
+ getAArch64Page(pltEntryAddr));
+ relocateOne(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
+ relocateOne(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
- if (PacEntry)
- memcpy(Buf + sizeof(AddrInst), PacBr, sizeof(PacBr));
+ if (pacEntry)
+ memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
else
- memcpy(Buf + sizeof(AddrInst), StdBr, sizeof(StdBr));
- if (!BtiEntry)
+ memcpy(buf + sizeof(addrInst), stdBr, sizeof(stdBr));
+ if (!btiEntry)
// We didn't add the BTI c instruction so round out size with NOP.
- memcpy(Buf + sizeof(AddrInst) + sizeof(StdBr), NopData, sizeof(NopData));
+ memcpy(buf + sizeof(addrInst) + sizeof(stdBr), nopData, sizeof(nopData));
}
static TargetInfo *getTargetInfo() {
- if (Config->AndFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
+ if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
- static AArch64BtiPac T;
- return &T;
+ static AArch64BtiPac t;
+ return &t;
}
- static AArch64 T;
- return &T;
+ static AArch64 t;
+ return &t;
}
TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); }
diff --git a/lld/ELF/Arch/AMDGPU.cpp b/lld/ELF/Arch/AMDGPU.cpp
index 4a9c9ab6c88..f2e32ca0996 100644
--- a/lld/ELF/Arch/AMDGPU.cpp
+++ b/lld/ELF/Arch/AMDGPU.cpp
@@ -25,63 +25,63 @@ class AMDGPU final : public TargetInfo {
public:
AMDGPU();
uint32_t calcEFlags() const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
};
} // namespace
AMDGPU::AMDGPU() {
- RelativeRel = R_AMDGPU_RELATIVE64;
- GotRel = R_AMDGPU_ABS64;
- NoneRel = R_AMDGPU_NONE;
- SymbolicRel = R_AMDGPU_ABS64;
+ relativeRel = R_AMDGPU_RELATIVE64;
+ gotRel = R_AMDGPU_ABS64;
+ noneRel = R_AMDGPU_NONE;
+ symbolicRel = R_AMDGPU_ABS64;
}
-static uint32_t getEFlags(InputFile *File) {
- return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags;
+static uint32_t getEFlags(InputFile *file) {
+ return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader()->e_flags;
}
uint32_t AMDGPU::calcEFlags() const {
- assert(!ObjectFiles.empty());
- uint32_t Ret = getEFlags(ObjectFiles[0]);
+ assert(!objectFiles.empty());
+ uint32_t ret = getEFlags(objectFiles[0]);
// Verify that all input files have the same e_flags.
- for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) {
- if (Ret == getEFlags(F))
+ for (InputFile *f : makeArrayRef(objectFiles).slice(1)) {
+ if (ret == getEFlags(f))
continue;
- error("incompatible e_flags: " + toString(F));
+ error("incompatible e_flags: " + toString(f));
return 0;
}
- return Ret;
+ return ret;
}
-void AMDGPU::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void AMDGPU::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_AMDGPU_ABS32:
case R_AMDGPU_GOTPCREL:
case R_AMDGPU_GOTPCREL32_LO:
case R_AMDGPU_REL32:
case R_AMDGPU_REL32_LO:
- write32le(Loc, Val);
+ write32le(loc, val);
break;
case R_AMDGPU_ABS64:
case R_AMDGPU_REL64:
- write64le(Loc, Val);
+ write64le(loc, val);
break;
case R_AMDGPU_GOTPCREL32_HI:
case R_AMDGPU_REL32_HI:
- write32le(Loc, Val >> 32);
+ write32le(loc, val >> 32);
break;
default:
llvm_unreachable("unknown relocation");
}
}
-RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr AMDGPU::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_AMDGPU_ABS32:
case R_AMDGPU_ABS64:
return R_ABS;
@@ -95,19 +95,19 @@ RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S,
case R_AMDGPU_GOTPCREL32_HI:
return R_GOT_PC;
default:
- error(getErrorLocation(Loc) + "unknown relocation (" + Twine(Type) +
- ") against symbol " + toString(S));
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
return R_NONE;
}
}
-RelType AMDGPU::getDynRel(RelType Type) const {
- if (Type == R_AMDGPU_ABS64)
- return Type;
+RelType AMDGPU::getDynRel(RelType type) const {
+ if (type == R_AMDGPU_ABS64)
+ return type;
return R_AMDGPU_NONE;
}
TargetInfo *elf::getAMDGPUTargetInfo() {
- static AMDGPU Target;
- return &Target;
+ static AMDGPU target;
+ return &target;
}
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 61a22ae8d6b..b69974fc72c 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -26,62 +26,62 @@ class ARM final : public TargetInfo {
public:
ARM();
uint32_t calcEFlags() const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
- int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- void addPltSymbols(InputSection &IS, uint64_t Off) const override;
- void addPltHeaderSymbols(InputSection &ISD) const override;
- bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
+ int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ void addPltSymbols(InputSection &isec, uint64_t off) const override;
+ void addPltHeaderSymbols(InputSection &isd) const override;
+ bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const override;
uint32_t getThunkSectionSpacing() const override;
- bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
ARM::ARM() {
- CopyRel = R_ARM_COPY;
- RelativeRel = R_ARM_RELATIVE;
- IRelativeRel = R_ARM_IRELATIVE;
- GotRel = R_ARM_GLOB_DAT;
- NoneRel = R_ARM_NONE;
- PltRel = R_ARM_JUMP_SLOT;
- SymbolicRel = R_ARM_ABS32;
- TlsGotRel = R_ARM_TLS_TPOFF32;
- TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
- TlsOffsetRel = R_ARM_TLS_DTPOFF32;
- GotBaseSymInGotPlt = false;
- PltEntrySize = 16;
- PltHeaderSize = 32;
- TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
- NeedsThunks = true;
+ copyRel = R_ARM_COPY;
+ relativeRel = R_ARM_RELATIVE;
+ iRelativeRel = R_ARM_IRELATIVE;
+ gotRel = R_ARM_GLOB_DAT;
+ noneRel = R_ARM_NONE;
+ pltRel = R_ARM_JUMP_SLOT;
+ symbolicRel = R_ARM_ABS32;
+ tlsGotRel = R_ARM_TLS_TPOFF32;
+ tlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
+ tlsOffsetRel = R_ARM_TLS_DTPOFF32;
+ gotBaseSymInGotPlt = false;
+ pltEntrySize = 16;
+ pltHeaderSize = 32;
+ trapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
+ needsThunks = true;
}
uint32_t ARM::calcEFlags() const {
// The ABIFloatType is used by loaders to detect the floating point calling
// convention.
- uint32_t ABIFloatType = 0;
- if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
- Config->ARMVFPArgs == ARMVFPArgKind::Default)
- ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
- else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
- ABIFloatType = EF_ARM_ABI_FLOAT_HARD;
+ uint32_t abiFloatType = 0;
+ if (config->armVFPArgs == ARMVFPArgKind::Base ||
+ config->armVFPArgs == ARMVFPArgKind::Default)
+ abiFloatType = EF_ARM_ABI_FLOAT_SOFT;
+ else if (config->armVFPArgs == ARMVFPArgKind::VFP)
+ abiFloatType = EF_ARM_ABI_FLOAT_HARD;
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
// but we don't have any firm guarantees of conformance. Linux AArch64
// kernels (as of 2016) require an EABI version to be set.
- return EF_ARM_EABI_VER5 | ABIFloatType;
+ return EF_ARM_EABI_VER5 | abiFloatType;
}
-RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_ARM_THM_JUMP11:
return R_PC;
case R_ARM_CALL:
@@ -106,11 +106,11 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
case R_ARM_SBREL32:
return R_ARM_SBREL;
case R_ARM_TARGET1:
- return Config->Target1Rel ? R_PC : R_ABS;
+ return config->target1Rel ? R_PC : R_ABS;
case R_ARM_TARGET2:
- if (Config->Target2 == Target2Policy::Rel)
+ if (config->target2 == Target2Policy::Rel)
return R_PC;
- if (Config->Target2 == Target2Policy::Abs)
+ if (config->target2 == Target2Policy::Abs)
return R_ABS;
return R_GOT_PC;
case R_ARM_TLS_GD32:
@@ -143,25 +143,25 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
}
}
-RelType ARM::getDynRel(RelType Type) const {
- if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel))
+RelType ARM::getDynRel(RelType type) const {
+ if ((type == R_ARM_ABS32) || (type == R_ARM_TARGET1 && !config->target1Rel))
return R_ARM_ABS32;
return R_ARM_NONE;
}
-void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
- write32le(Buf, In.Plt->getVA());
+void ARM::writeGotPlt(uint8_t *buf, const Symbol &) const {
+ write32le(buf, in.plt->getVA());
}
-void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
+void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
// An ARM entry is the address of the ifunc resolver function.
- write32le(Buf, S.getVA());
+ write32le(buf, s.getVA());
}
// Long form PLT Header that does not have any restrictions on the displacement
// of the .plt from the .plt.got.
-static void writePltHeaderLong(uint8_t *Buf) {
- const uint8_t PltData[] = {
+static void writePltHeaderLong(uint8_t *buf) {
+ const uint8_t pltData[] = {
0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]!
0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2
0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
@@ -170,128 +170,128 @@ static void writePltHeaderLong(uint8_t *Buf) {
0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
0xd4, 0xd4, 0xd4, 0xd4};
- memcpy(Buf, PltData, sizeof(PltData));
- uint64_t GotPlt = In.GotPlt->getVA();
- uint64_t L1 = In.Plt->getVA() + 8;
- write32le(Buf + 16, GotPlt - L1 - 8);
+ memcpy(buf, pltData, sizeof(pltData));
+ uint64_t gotPlt = in.gotPlt->getVA();
+ uint64_t l1 = in.plt->getVA() + 8;
+ write32le(buf + 16, gotPlt - l1 - 8);
}
// The default PLT header requires the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
-void ARM::writePltHeader(uint8_t *Buf) const {
+void ARM::writePltHeader(uint8_t *buf) const {
// Use a similar sequence to that in writePlt(), the difference is the calling
// conventions mean we use lr instead of ip. The PLT entry is responsible for
// saving lr on the stack, the dynamic loader is responsible for reloading
// it.
- const uint32_t PltData[] = {
+ const uint32_t pltData[] = {
0xe52de004, // L1: str lr, [sp,#-4]!
0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4)
0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4)
0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
};
- uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
- if (!llvm::isUInt<27>(Offset)) {
+ uint64_t offset = in.gotPlt->getVA() - in.plt->getVA() - 4;
+ if (!llvm::isUInt<27>(offset)) {
// We cannot encode the Offset, use the long form.
- writePltHeaderLong(Buf);
+ writePltHeaderLong(buf);
return;
}
- write32le(Buf + 0, PltData[0]);
- write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
- write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
- write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
- memcpy(Buf + 16, TrapInstr.data(), 4); // Pad to 32-byte boundary
- memcpy(Buf + 20, TrapInstr.data(), 4);
- memcpy(Buf + 24, TrapInstr.data(), 4);
- memcpy(Buf + 28, TrapInstr.data(), 4);
+ write32le(buf + 0, pltData[0]);
+ write32le(buf + 4, pltData[1] | ((offset >> 20) & 0xff));
+ write32le(buf + 8, pltData[2] | ((offset >> 12) & 0xff));
+ write32le(buf + 12, pltData[3] | (offset & 0xfff));
+ memcpy(buf + 16, trapInstr.data(), 4); // Pad to 32-byte boundary
+ memcpy(buf + 20, trapInstr.data(), 4);
+ memcpy(buf + 24, trapInstr.data(), 4);
+ memcpy(buf + 28, trapInstr.data(), 4);
}
-void ARM::addPltHeaderSymbols(InputSection &IS) const {
- addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
- addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
+void ARM::addPltHeaderSymbols(InputSection &isec) const {
+ addSyntheticLocal("$a", STT_NOTYPE, 0, 0, isec);
+ addSyntheticLocal("$d", STT_NOTYPE, 16, 0, isec);
}
// Long form PLT entries that do not have any restrictions on the displacement
// of the .plt from the .plt.got.
-static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) {
- const uint8_t PltData[] = {
+static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) {
+ const uint8_t pltData[] = {
0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2
0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip]
0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8
};
- memcpy(Buf, PltData, sizeof(PltData));
- uint64_t L1 = PltEntryAddr + 4;
- write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
+ memcpy(buf, pltData, sizeof(pltData));
+ uint64_t l1 = pltEntryAddr + 4;
+ write32le(buf + 12, gotPltEntryAddr - l1 - 8);
}
// The default PLT entries require the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
-void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
+void ARM::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
// The PLT entry is similar to the example given in Appendix A of ELF for
// the Arm Architecture. Instead of using the Group Relocations to find the
// optimal rotation for the 8-bit immediate used in the add instructions we
// hard code the most compact rotations for simplicity. This saves a load
// instruction over the long plt sequences.
- const uint32_t PltData[] = {
+ const uint32_t pltData[] = {
0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.plt.got) - L1 - 8
0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.plt.got) - L1 - 8
0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8
};
- uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8;
- if (!llvm::isUInt<27>(Offset)) {
+ uint64_t offset = gotPltEntryAddr - pltEntryAddr - 8;
+ if (!llvm::isUInt<27>(offset)) {
// We cannot encode the Offset, use the long form.
- writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff);
+ writePltLong(buf, gotPltEntryAddr, pltEntryAddr, index, relOff);
return;
}
- write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
- write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
- write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
- memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary
+ write32le(buf + 0, pltData[0] | ((offset >> 20) & 0xff));
+ write32le(buf + 4, pltData[1] | ((offset >> 12) & 0xff));
+ write32le(buf + 8, pltData[2] | (offset & 0xfff));
+ memcpy(buf + 12, trapInstr.data(), 4); // Pad to 16-byte boundary
}
-void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
- addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
- addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
+void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {
+ addSyntheticLocal("$a", STT_NOTYPE, off, 0, isec);
+ addSyntheticLocal("$d", STT_NOTYPE, off + 12, 0, isec);
}
-bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
+bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
// If S is an undefined weak symbol and does not have a PLT entry then it
// will be resolved as a branch to the next instruction.
- if (S.isUndefWeak() && !S.isInPlt())
+ if (s.isUndefWeak() && !s.isInPlt())
return false;
// A state change from ARM to Thumb and vice versa must go through an
// interworking thunk if the relocation type is not R_ARM_CALL or
// R_ARM_THM_CALL.
- switch (Type) {
+ switch (type) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
// Source is ARM, all PLT entries are ARM so no interworking required.
// Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
- if (Expr == R_PC && ((S.getVA() & 1) == 1))
+ if (expr == R_PC && ((s.getVA() & 1) == 1))
return true;
LLVM_FALLTHROUGH;
case R_ARM_CALL: {
- uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
- return !inBranchRange(Type, BranchAddr, Dst);
+ uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
+ return !inBranchRange(type, branchAddr, dst);
}
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
// Source is Thumb, all PLT entries are ARM so interworking is required.
// Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
- if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
+ if (expr == R_PLT_PC || ((s.getVA() & 1) == 0))
return true;
LLVM_FALLTHROUGH;
case R_ARM_THM_CALL: {
- uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
- return !inBranchRange(Type, BranchAddr, Dst);
+ uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
+ return !inBranchRange(type, branchAddr, dst);
}
}
return false;
@@ -327,55 +327,55 @@ uint32_t ARM::getThunkSectionSpacing() const {
// range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
// ARMv6T2) the range is +/- 4MiB.
- return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
+ return (config->armJ1J2BranchEncoding) ? 0x1000000 - 0x30000
: 0x400000 - 0x7500;
}
-bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
- uint64_t Range;
- uint64_t InstrSize;
+bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
+ uint64_t range;
+ uint64_t instrSize;
- switch (Type) {
+ switch (type) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- Range = 0x2000000;
- InstrSize = 4;
+ range = 0x2000000;
+ instrSize = 4;
break;
case R_ARM_THM_JUMP19:
- Range = 0x100000;
- InstrSize = 2;
+ range = 0x100000;
+ instrSize = 2;
break;
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
- InstrSize = 2;
+ range = config->armJ1J2BranchEncoding ? 0x1000000 : 0x400000;
+ instrSize = 2;
break;
default:
return true;
}
// PC at Src is 2 instructions ahead, immediate of branch is signed
- if (Src > Dst)
- Range -= 2 * InstrSize;
+ if (src > dst)
+ range -= 2 * instrSize;
else
- Range += InstrSize;
+ range += instrSize;
- if ((Dst & 0x1) == 0)
+ if ((dst & 0x1) == 0)
// Destination is ARM, if ARM caller then Src is already 4-byte aligned.
// If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
// destination will be 4 byte aligned.
- Src &= ~0x3;
+ src &= ~0x3;
else
// Bit 0 == 1 denotes Thumb state, it is not part of the range
- Dst &= ~0x1;
+ dst &= ~0x1;
- uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
- return Distance <= Range;
+ uint64_t distance = (src > dst) ? src - dst : dst - src;
+ return distance <= range;
}
-void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void ARM::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_ARM_ABS32:
case R_ARM_BASE_PREL:
case R_ARM_GOTOFF32:
@@ -393,132 +393,132 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_ARM_TLS_LE32:
case R_ARM_TLS_TPOFF32:
case R_ARM_TLS_DTPOFF32:
- write32le(Loc, Val);
+ write32le(loc, val);
break;
case R_ARM_PREL31:
- checkInt(Loc, Val, 31, Type);
- write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
+ checkInt(loc, val, 31, type);
+ write32le(loc, (read32le(loc) & 0x80000000) | (val & ~0x80000000));
break;
case R_ARM_CALL:
// R_ARM_CALL is used for BL and BLX instructions, depending on the
// value of bit 0 of Val, we must select a BL or BLX instruction
- if (Val & 1) {
+ if (val & 1) {
// If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
// The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
- checkInt(Loc, Val, 26, Type);
- write32le(Loc, 0xfa000000 | // opcode
- ((Val & 2) << 23) | // H
- ((Val >> 2) & 0x00ffffff)); // imm24
+ checkInt(loc, val, 26, type);
+ write32le(loc, 0xfa000000 | // opcode
+ ((val & 2) << 23) | // H
+ ((val >> 2) & 0x00ffffff)); // imm24
break;
}
- if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
+ if ((read32le(loc) & 0xfe000000) == 0xfa000000)
// BLX (always unconditional) instruction to an ARM Target, select an
// unconditional BL.
- write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
+ write32le(loc, 0xeb000000 | (read32le(loc) & 0x00ffffff));
// fall through as BL encoding is shared with B
LLVM_FALLTHROUGH;
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
- checkInt(Loc, Val, 26, Type);
- write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
+ checkInt(loc, val, 26, type);
+ write32le(loc, (read32le(loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
break;
case R_ARM_THM_JUMP11:
- checkInt(Loc, Val, 12, Type);
- write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
+ checkInt(loc, val, 12, type);
+ write16le(loc, (read32le(loc) & 0xf800) | ((val >> 1) & 0x07ff));
break;
case R_ARM_THM_JUMP19:
// Encoding T3: Val = S:J2:J1:imm6:imm11:0
- checkInt(Loc, Val, 21, Type);
- write16le(Loc,
- (read16le(Loc) & 0xfbc0) | // opcode cond
- ((Val >> 10) & 0x0400) | // S
- ((Val >> 12) & 0x003f)); // imm6
- write16le(Loc + 2,
+ checkInt(loc, val, 21, type);
+ write16le(loc,
+ (read16le(loc) & 0xfbc0) | // opcode cond
+ ((val >> 10) & 0x0400) | // S
+ ((val >> 12) & 0x003f)); // imm6
+ write16le(loc + 2,
0x8000 | // opcode
- ((Val >> 8) & 0x0800) | // J2
- ((Val >> 5) & 0x2000) | // J1
- ((Val >> 1) & 0x07ff)); // imm11
+ ((val >> 8) & 0x0800) | // J2
+ ((val >> 5) & 0x2000) | // J1
+ ((val >> 1) & 0x07ff)); // imm11
break;
case R_ARM_THM_CALL:
// R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
// value of bit 0 of Val, we must select a BL or BLX instruction
- if ((Val & 1) == 0) {
+ if ((val & 1) == 0) {
// Ensure BLX destination is 4-byte aligned. As BLX instruction may
// only be two byte aligned. This must be done before overflow check
- Val = alignTo(Val, 4);
+ val = alignTo(val, 4);
}
// Bit 12 is 0 for BLX, 1 for BL
- write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
- if (!Config->ARMJ1J2BranchEncoding) {
+ write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | (val & 1) << 12);
+ if (!config->armJ1J2BranchEncoding) {
// Older Arm architectures do not support R_ARM_THM_JUMP24 and have
// different encoding rules and range due to J1 and J2 always being 1.
- checkInt(Loc, Val, 23, Type);
- write16le(Loc,
+ checkInt(loc, val, 23, type);
+ write16le(loc,
0xf000 | // opcode
- ((Val >> 12) & 0x07ff)); // imm11
- write16le(Loc + 2,
- (read16le(Loc + 2) & 0xd000) | // opcode
+ ((val >> 12) & 0x07ff)); // imm11
+ write16le(loc + 2,
+ (read16le(loc + 2) & 0xd000) | // opcode
0x2800 | // J1 == J2 == 1
- ((Val >> 1) & 0x07ff)); // imm11
+ ((val >> 1) & 0x07ff)); // imm11
break;
}
// Fall through as rest of encoding is the same as B.W
LLVM_FALLTHROUGH;
case R_ARM_THM_JUMP24:
// Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
- checkInt(Loc, Val, 25, Type);
- write16le(Loc,
+ checkInt(loc, val, 25, type);
+ write16le(loc,
0xf000 | // opcode
- ((Val >> 14) & 0x0400) | // S
- ((Val >> 12) & 0x03ff)); // imm10
- write16le(Loc + 2,
- (read16le(Loc + 2) & 0xd000) | // opcode
- (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
- (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
- ((Val >> 1) & 0x07ff)); // imm11
+ ((val >> 14) & 0x0400) | // S
+ ((val >> 12) & 0x03ff)); // imm10
+ write16le(loc + 2,
+ (read16le(loc + 2) & 0xd000) | // opcode
+ (((~(val >> 10)) ^ (val >> 11)) & 0x2000) | // J1
+ (((~(val >> 11)) ^ (val >> 13)) & 0x0800) | // J2
+ ((val >> 1) & 0x07ff)); // imm11
break;
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVW_PREL_NC:
- write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
- (Val & 0x0fff));
+ write32le(loc, (read32le(loc) & ~0x000f0fff) | ((val & 0xf000) << 4) |
+ (val & 0x0fff));
break;
case R_ARM_MOVT_ABS:
case R_ARM_MOVT_PREL:
- write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
- (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
+ write32le(loc, (read32le(loc) & ~0x000f0fff) |
+ (((val >> 16) & 0xf000) << 4) | ((val >> 16) & 0xfff));
break;
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVT_PREL:
// Encoding T1: A = imm4:i:imm3:imm8
- write16le(Loc,
+ write16le(loc,
0xf2c0 | // opcode
- ((Val >> 17) & 0x0400) | // i
- ((Val >> 28) & 0x000f)); // imm4
- write16le(Loc + 2,
- (read16le(Loc + 2) & 0x8f00) | // opcode
- ((Val >> 12) & 0x7000) | // imm3
- ((Val >> 16) & 0x00ff)); // imm8
+ ((val >> 17) & 0x0400) | // i
+ ((val >> 28) & 0x000f)); // imm4
+ write16le(loc + 2,
+ (read16le(loc + 2) & 0x8f00) | // opcode
+ ((val >> 12) & 0x7000) | // imm3
+ ((val >> 16) & 0x00ff)); // imm8
break;
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVW_PREL_NC:
// Encoding T3: A = imm4:i:imm3:imm8
- write16le(Loc,
+ write16le(loc,
0xf240 | // opcode
- ((Val >> 1) & 0x0400) | // i
- ((Val >> 12) & 0x000f)); // imm4
- write16le(Loc + 2,
- (read16le(Loc + 2) & 0x8f00) | // opcode
- ((Val << 4) & 0x7000) | // imm3
- (Val & 0x00ff)); // imm8
+ ((val >> 1) & 0x0400) | // i
+ ((val >> 12) & 0x000f)); // imm4
+ write16le(loc + 2,
+ (read16le(loc + 2) & 0x8f00) | // opcode
+ ((val << 4) & 0x7000) | // imm3
+ (val & 0x00ff)); // imm8
break;
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
-int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
- switch (Type) {
+int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
+ switch (type) {
default:
return 0;
case R_ARM_ABS32:
@@ -534,47 +534,47 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
case R_ARM_TLS_LDO32:
case R_ARM_TLS_IE32:
case R_ARM_TLS_LE32:
- return SignExtend64<32>(read32le(Buf));
+ return SignExtend64<32>(read32le(buf));
case R_ARM_PREL31:
- return SignExtend64<31>(read32le(Buf));
+ return SignExtend64<31>(read32le(buf));
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
- return SignExtend64<26>(read32le(Buf) << 2);
+ return SignExtend64<26>(read32le(buf) << 2);
case R_ARM_THM_JUMP11:
- return SignExtend64<12>(read16le(Buf) << 1);
+ return SignExtend64<12>(read16le(buf) << 1);
case R_ARM_THM_JUMP19: {
// Encoding T3: A = S:J2:J1:imm10:imm6:0
- uint16_t Hi = read16le(Buf);
- uint16_t Lo = read16le(Buf + 2);
- return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
- ((Lo & 0x0800) << 8) | // J2
- ((Lo & 0x2000) << 5) | // J1
- ((Hi & 0x003f) << 12) | // imm6
- ((Lo & 0x07ff) << 1)); // imm11:0
+ uint16_t hi = read16le(buf);
+ uint16_t lo = read16le(buf + 2);
+ return SignExtend64<20>(((hi & 0x0400) << 10) | // S
+ ((lo & 0x0800) << 8) | // J2
+ ((lo & 0x2000) << 5) | // J1
+ ((hi & 0x003f) << 12) | // imm6
+ ((lo & 0x07ff) << 1)); // imm11:0
}
case R_ARM_THM_CALL:
- if (!Config->ARMJ1J2BranchEncoding) {
+ if (!config->armJ1J2BranchEncoding) {
// Older Arm architectures do not support R_ARM_THM_JUMP24 and have
// different encoding rules and range due to J1 and J2 always being 1.
- uint16_t Hi = read16le(Buf);
- uint16_t Lo = read16le(Buf + 2);
- return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11
- ((Lo & 0x7ff) << 1)); // imm11:0
+ uint16_t hi = read16le(buf);
+ uint16_t lo = read16le(buf + 2);
+ return SignExtend64<22>(((hi & 0x7ff) << 12) | // imm11
+ ((lo & 0x7ff) << 1)); // imm11:0
break;
}
LLVM_FALLTHROUGH;
case R_ARM_THM_JUMP24: {
// Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
// I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
- uint16_t Hi = read16le(Buf);
- uint16_t Lo = read16le(Buf + 2);
- return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
- (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
- (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
- ((Hi & 0x003ff) << 12) | // imm0
- ((Lo & 0x007ff) << 1)); // imm11:0
+ uint16_t hi = read16le(buf);
+ uint16_t lo = read16le(buf + 2);
+ return SignExtend64<24>(((hi & 0x0400) << 14) | // S
+ (~((lo ^ (hi << 3)) << 10) & 0x00800000) | // I1
+ (~((lo ^ (hi << 1)) << 11) & 0x00400000) | // I2
+ ((hi & 0x003ff) << 12) | // imm0
+ ((lo & 0x007ff) << 1)); // imm11:0
}
// ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
// MOVT is in the range -32768 <= A < 32768
@@ -582,25 +582,25 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL: {
- uint64_t Val = read32le(Buf) & 0x000f0fff;
- return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
+ uint64_t val = read32le(buf) & 0x000f0fff;
+ return SignExtend64<16>(((val & 0x000f0000) >> 4) | (val & 0x00fff));
}
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL: {
// Encoding T3: A = imm4:i:imm3:imm8
- uint16_t Hi = read16le(Buf);
- uint16_t Lo = read16le(Buf + 2);
- return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
- ((Hi & 0x0400) << 1) | // i
- ((Lo & 0x7000) >> 4) | // imm3
- (Lo & 0x00ff)); // imm8
+ uint16_t hi = read16le(buf);
+ uint16_t lo = read16le(buf + 2);
+ return SignExtend64<16>(((hi & 0x000f) << 12) | // imm4
+ ((hi & 0x0400) << 1) | // i
+ ((lo & 0x7000) >> 4) | // imm3
+ (lo & 0x00ff)); // imm8
}
}
}
TargetInfo *elf::getARMTargetInfo() {
- static ARM Target;
- return &Target;
+ static ARM target;
+ return &target;
}
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 5a573238d6d..869f0fe0c52 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -43,34 +43,34 @@ namespace {
class AVR final : public TargetInfo {
public:
AVR();
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
-AVR::AVR() { NoneRel = R_AVR_NONE; }
+AVR::AVR() { noneRel = R_AVR_NONE; }
-RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
+RelExpr AVR::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
return R_ABS;
}
-void AVR::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void AVR::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_AVR_CALL: {
- uint16_t Hi = Val >> 17;
- uint16_t Lo = Val >> 1;
- write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1));
- write16le(Loc + 2, Lo);
+ uint16_t hi = val >> 17;
+ uint16_t lo = val >> 1;
+ write16le(loc, read16le(loc) | ((hi >> 1) << 4) | (hi & 1));
+ write16le(loc + 2, lo);
break;
}
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
TargetInfo *elf::getAVRTargetInfo() {
- static AVR Target;
- return &Target;
+ static AVR target;
+ return &target;
}
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 1ebadc9a422..c497a6df798 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -27,65 +27,65 @@ class Hexagon final : public TargetInfo {
public:
Hexagon();
uint32_t calcEFlags() const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
};
} // namespace
Hexagon::Hexagon() {
- PltRel = R_HEX_JMP_SLOT;
- RelativeRel = R_HEX_RELATIVE;
- GotRel = R_HEX_GLOB_DAT;
- SymbolicRel = R_HEX_32;
+ pltRel = R_HEX_JMP_SLOT;
+ relativeRel = R_HEX_RELATIVE;
+ gotRel = R_HEX_GLOB_DAT;
+ symbolicRel = R_HEX_32;
// The zero'th GOT entry is reserved for the address of _DYNAMIC. The
// next 3 are reserved for the dynamic loader.
- GotPltHeaderEntriesNum = 4;
+ gotPltHeaderEntriesNum = 4;
- PltEntrySize = 16;
- PltHeaderSize = 32;
+ pltEntrySize = 16;
+ pltHeaderSize = 32;
// Hexagon Linux uses 64K pages by default.
- DefaultMaxPageSize = 0x10000;
- NoneRel = R_HEX_NONE;
+ defaultMaxPageSize = 0x10000;
+ noneRel = R_HEX_NONE;
}
uint32_t Hexagon::calcEFlags() const {
- assert(!ObjectFiles.empty());
+ assert(!objectFiles.empty());
// The architecture revision must always be equal to or greater than
// greatest revision in the list of inputs.
- uint32_t Ret = 0;
- for (InputFile *F : ObjectFiles) {
- uint32_t EFlags = cast<ObjFile<ELF32LE>>(F)->getObj().getHeader()->e_flags;
- if (EFlags > Ret)
- Ret = EFlags;
+ uint32_t ret = 0;
+ for (InputFile *f : objectFiles) {
+ uint32_t eflags = cast<ObjFile<ELF32LE>>(f)->getObj().getHeader()->e_flags;
+ if (eflags > ret)
+ ret = eflags;
}
- return Ret;
+ return ret;
}
-static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
- uint32_t Result = 0;
- size_t Off = 0;
+static uint32_t applyMask(uint32_t mask, uint32_t data) {
+ uint32_t result = 0;
+ size_t off = 0;
- for (size_t Bit = 0; Bit != 32; ++Bit) {
- uint32_t ValBit = (Data >> Off) & 1;
- uint32_t MaskBit = (Mask >> Bit) & 1;
- if (MaskBit) {
- Result |= (ValBit << Bit);
- ++Off;
+ for (size_t bit = 0; bit != 32; ++bit) {
+ uint32_t valBit = (data >> off) & 1;
+ uint32_t maskBit = (mask >> bit) & 1;
+ if (maskBit) {
+ result |= (valBit << bit);
+ ++off;
}
}
- return Result;
+ return result;
}
-RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_HEX_B9_PCREL:
case R_HEX_B9_PCREL_X:
case R_HEX_B13_PCREL:
@@ -108,16 +108,16 @@ RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
}
}
-static uint32_t findMaskR6(uint32_t Insn) {
+static uint32_t findMaskR6(uint32_t insn) {
// There are (arguably too) many relocation masks for the DSP's
// R_HEX_6_X type. The table below is used to select the correct mask
// for the given instruction.
struct InstructionMask {
- uint32_t CmpMask;
- uint32_t RelocMask;
+ uint32_t cmpMask;
+ uint32_t relocMask;
};
- static const InstructionMask R6[] = {
+ static const InstructionMask r6[] = {
{0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
{0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
{0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
@@ -135,124 +135,124 @@ static uint32_t findMaskR6(uint32_t Insn) {
// Duplex forms have a fixed mask and parse bits 15:14 are always
// zero. Non-duplex insns will always have at least one bit set in the
// parse field.
- if ((0xC000 & Insn) == 0x0)
+ if ((0xC000 & insn) == 0x0)
return 0x03f00000;
- for (InstructionMask I : R6)
- if ((0xff000000 & Insn) == I.CmpMask)
- return I.RelocMask;
+ for (InstructionMask i : r6)
+ if ((0xff000000 & insn) == i.cmpMask)
+ return i.relocMask;
error("unrecognized instruction for R_HEX_6 relocation: 0x" +
- utohexstr(Insn));
+ utohexstr(insn));
return 0;
}
-static uint32_t findMaskR8(uint32_t Insn) {
- if ((0xff000000 & Insn) == 0xde000000)
+static uint32_t findMaskR8(uint32_t insn) {
+ if ((0xff000000 & insn) == 0xde000000)
return 0x00e020e8;
- if ((0xff000000 & Insn) == 0x3c000000)
+ if ((0xff000000 & insn) == 0x3c000000)
return 0x0000207f;
return 0x00001fe0;
}
-static uint32_t findMaskR11(uint32_t Insn) {
- if ((0xff000000 & Insn) == 0xa1000000)
+static uint32_t findMaskR11(uint32_t insn) {
+ if ((0xff000000 & insn) == 0xa1000000)
return 0x060020ff;
return 0x06003fe0;
}
-static uint32_t findMaskR16(uint32_t Insn) {
- if ((0xff000000 & Insn) == 0x48000000)
+static uint32_t findMaskR16(uint32_t insn) {
+ if ((0xff000000 & insn) == 0x48000000)
return 0x061f20ff;
- if ((0xff000000 & Insn) == 0x49000000)
+ if ((0xff000000 & insn) == 0x49000000)
return 0x061f3fe0;
- if ((0xff000000 & Insn) == 0x78000000)
+ if ((0xff000000 & insn) == 0x78000000)
return 0x00df3fe0;
- if ((0xff000000 & Insn) == 0xb0000000)
+ if ((0xff000000 & insn) == 0xb0000000)
return 0x0fe03fe0;
error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
- utohexstr(Insn));
+ utohexstr(insn));
return 0;
}
-static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
+static void or32le(uint8_t *p, int32_t v) { write32le(p, read32le(p) | v); }
-void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void Hexagon::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_HEX_NONE:
break;
case R_HEX_6_PCREL_X:
case R_HEX_6_X:
- or32le(Loc, applyMask(findMaskR6(read32le(Loc)), Val));
+ or32le(loc, applyMask(findMaskR6(read32le(loc)), val));
break;
case R_HEX_8_X:
- or32le(Loc, applyMask(findMaskR8(read32le(Loc)), Val));
+ or32le(loc, applyMask(findMaskR8(read32le(loc)), val));
break;
case R_HEX_9_X:
- or32le(Loc, applyMask(0x00003fe0, Val & 0x3f));
+ or32le(loc, applyMask(0x00003fe0, val & 0x3f));
break;
case R_HEX_10_X:
- or32le(Loc, applyMask(0x00203fe0, Val & 0x3f));
+ or32le(loc, applyMask(0x00203fe0, val & 0x3f));
break;
case R_HEX_11_X:
case R_HEX_GOT_11_X:
- or32le(Loc, applyMask(findMaskR11(read32le(Loc)), Val & 0x3f));
+ or32le(loc, applyMask(findMaskR11(read32le(loc)), val & 0x3f));
break;
case R_HEX_12_X:
- or32le(Loc, applyMask(0x000007e0, Val));
+ or32le(loc, applyMask(0x000007e0, val));
break;
case R_HEX_16_X: // These relocs only have 6 effective bits.
case R_HEX_GOT_16_X:
- or32le(Loc, applyMask(findMaskR16(read32le(Loc)), Val & 0x3f));
+ or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0x3f));
break;
case R_HEX_32:
case R_HEX_32_PCREL:
- or32le(Loc, Val);
+ or32le(loc, val);
break;
case R_HEX_32_6_X:
case R_HEX_GOT_32_6_X:
- or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
+ or32le(loc, applyMask(0x0fff3fff, val >> 6));
break;
case R_HEX_B9_PCREL:
- or32le(Loc, applyMask(0x003000fe, Val >> 2));
+ or32le(loc, applyMask(0x003000fe, val >> 2));
break;
case R_HEX_B9_PCREL_X:
- or32le(Loc, applyMask(0x003000fe, Val & 0x3f));
+ or32le(loc, applyMask(0x003000fe, val & 0x3f));
break;
case R_HEX_B13_PCREL:
- or32le(Loc, applyMask(0x00202ffe, Val >> 2));
+ or32le(loc, applyMask(0x00202ffe, val >> 2));
break;
case R_HEX_B15_PCREL:
- or32le(Loc, applyMask(0x00df20fe, Val >> 2));
+ or32le(loc, applyMask(0x00df20fe, val >> 2));
break;
case R_HEX_B15_PCREL_X:
- or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));
+ or32le(loc, applyMask(0x00df20fe, val & 0x3f));
break;
case R_HEX_B22_PCREL:
case R_HEX_PLT_B22_PCREL:
- or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
+ or32le(loc, applyMask(0x1ff3ffe, val >> 2));
break;
case R_HEX_B22_PCREL_X:
- or32le(Loc, applyMask(0x1ff3ffe, Val & 0x3f));
+ or32le(loc, applyMask(0x1ff3ffe, val & 0x3f));
break;
case R_HEX_B32_PCREL_X:
- or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
+ or32le(loc, applyMask(0x0fff3fff, val >> 6));
break;
case R_HEX_HI16:
- or32le(Loc, applyMask(0x00c03fff, Val >> 16));
+ or32le(loc, applyMask(0x00c03fff, val >> 16));
break;
case R_HEX_LO16:
- or32le(Loc, applyMask(0x00c03fff, Val));
+ or32le(loc, applyMask(0x00c03fff, val));
break;
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
break;
}
}
-void Hexagon::writePltHeader(uint8_t *Buf) const {
- const uint8_t PltData[] = {
+void Hexagon::writePltHeader(uint8_t *buf) const {
+ const uint8_t pltData[] = {
0x00, 0x40, 0x00, 0x00, // { immext (#0)
0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0@PCREL) } # @GOT0
0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn
@@ -262,30 +262,30 @@ void Hexagon::writePltHeader(uint8_t *Buf) const {
0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
0x0c, 0xdb, 0x00, 0x54, // trap0(#0xdb) # bring plt0 into 16byte alignment
};
- memcpy(Buf, PltData, sizeof(PltData));
+ memcpy(buf, pltData, sizeof(pltData));
// Offset from PLT0 to the GOT.
- uint64_t Off = In.GotPlt->getVA() - In.Plt->getVA();
- relocateOne(Buf, R_HEX_B32_PCREL_X, Off);
- relocateOne(Buf + 4, R_HEX_6_PCREL_X, Off);
+ uint64_t off = in.gotPlt->getVA() - in.plt->getVA();
+ relocateOne(buf, R_HEX_B32_PCREL_X, off);
+ relocateOne(buf + 4, R_HEX_6_PCREL_X, off);
}
-void Hexagon::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Inst[] = {
+void Hexagon::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t inst[] = {
0x00, 0x40, 0x00, 0x00, // { immext (#0)
0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) }
0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)
0x00, 0xc0, 0x9c, 0x52, // jumpr r28
};
- memcpy(Buf, Inst, sizeof(Inst));
+ memcpy(buf, inst, sizeof(inst));
- relocateOne(Buf, R_HEX_B32_PCREL_X, GotPltEntryAddr - PltEntryAddr);
- relocateOne(Buf + 4, R_HEX_6_PCREL_X, GotPltEntryAddr - PltEntryAddr);
+ relocateOne(buf, R_HEX_B32_PCREL_X, gotPltEntryAddr - pltEntryAddr);
+ relocateOne(buf + 4, R_HEX_6_PCREL_X, gotPltEntryAddr - pltEntryAddr);
}
TargetInfo *elf::getHexagonTargetInfo() {
- static Hexagon Target;
- return &Target;
+ static Hexagon target;
+ return &target;
}
diff --git a/lld/ELF/Arch/MSP430.cpp b/lld/ELF/Arch/MSP430.cpp
index 0f0b5662ec8..90664396c85 100644
--- a/lld/ELF/Arch/MSP430.cpp
+++ b/lld/ELF/Arch/MSP430.cpp
@@ -33,20 +33,20 @@ namespace {
class MSP430 final : public TargetInfo {
public:
MSP430();
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
MSP430::MSP430() {
// mov.b #0, r3
- TrapInstr = {0x43, 0x43, 0x43, 0x43};
+ trapInstr = {0x43, 0x43, 0x43, 0x43};
}
-RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr MSP430::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_MSP430_10_PCREL:
case R_MSP430_16_PCREL:
case R_MSP430_16_PCREL_BYTE:
@@ -59,35 +59,35 @@ RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
}
}
-void MSP430::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void MSP430::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_MSP430_8:
- checkIntUInt(Loc, Val, 8, Type);
- *Loc = Val;
+ checkIntUInt(loc, val, 8, type);
+ *loc = val;
break;
case R_MSP430_16:
case R_MSP430_16_PCREL:
case R_MSP430_16_BYTE:
case R_MSP430_16_PCREL_BYTE:
- checkIntUInt(Loc, Val, 16, Type);
- write16le(Loc, Val);
+ checkIntUInt(loc, val, 16, type);
+ write16le(loc, val);
break;
case R_MSP430_32:
- checkIntUInt(Loc, Val, 32, Type);
- write32le(Loc, Val);
+ checkIntUInt(loc, val, 32, type);
+ write32le(loc, val);
break;
case R_MSP430_10_PCREL: {
- int16_t Offset = ((int16_t)Val >> 1) - 1;
- checkInt(Loc, Offset, 10, Type);
- write16le(Loc, (read16le(Loc) & 0xFC00) | (Offset & 0x3FF));
+ int16_t offset = ((int16_t)val >> 1) - 1;
+ checkInt(loc, offset, 10, type);
+ write16le(loc, (read16le(loc) & 0xFC00) | (offset & 0x3FF));
break;
}
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
TargetInfo *elf::getMSP430TargetInfo() {
- static MSP430 Target;
- return &Target;
+ static MSP430 target;
+ return &target;
}
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 18fc6968f5d..24b3957acd9 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -28,47 +28,47 @@ template <class ELFT> class MIPS final : public TargetInfo {
public:
MIPS();
uint32_t calcEFlags() const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
- RelType getDynRel(RelType Type) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- bool usesOnlyLowPageBits(RelType Type) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
+ RelType getDynRel(RelType type) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ bool usesOnlyLowPageBits(RelType type) const override;
};
} // namespace
template <class ELFT> MIPS<ELFT>::MIPS() {
- GotPltHeaderEntriesNum = 2;
- DefaultMaxPageSize = 65536;
- GotBaseSymInGotPlt = false;
- PltEntrySize = 16;
- PltHeaderSize = 32;
- CopyRel = R_MIPS_COPY;
- NoneRel = R_MIPS_NONE;
- PltRel = R_MIPS_JUMP_SLOT;
- NeedsThunks = true;
+ gotPltHeaderEntriesNum = 2;
+ defaultMaxPageSize = 65536;
+ gotBaseSymInGotPlt = false;
+ pltEntrySize = 16;
+ pltHeaderSize = 32;
+ copyRel = R_MIPS_COPY;
+ noneRel = R_MIPS_NONE;
+ pltRel = R_MIPS_JUMP_SLOT;
+ needsThunks = true;
// Set `sigrie 1` as a trap instruction.
- write32(TrapInstr.data(), 0x04170001);
+ write32(trapInstr.data(), 0x04170001);
if (ELFT::Is64Bits) {
- RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
- SymbolicRel = R_MIPS_64;
- TlsGotRel = R_MIPS_TLS_TPREL64;
- TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
- TlsOffsetRel = R_MIPS_TLS_DTPREL64;
+ relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
+ symbolicRel = R_MIPS_64;
+ tlsGotRel = R_MIPS_TLS_TPREL64;
+ tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
+ tlsOffsetRel = R_MIPS_TLS_DTPREL64;
} else {
- RelativeRel = R_MIPS_REL32;
- SymbolicRel = R_MIPS_32;
- TlsGotRel = R_MIPS_TLS_TPREL32;
- TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
- TlsOffsetRel = R_MIPS_TLS_DTPREL32;
+ relativeRel = R_MIPS_REL32;
+ symbolicRel = R_MIPS_32;
+ tlsGotRel = R_MIPS_TLS_TPREL32;
+ tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
+ tlsOffsetRel = R_MIPS_TLS_DTPREL32;
}
}
@@ -77,13 +77,13 @@ template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
}
template <class ELFT>
-RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
+RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
// See comment in the calculateMipsRelChain.
- if (ELFT::Is64Bits || Config->MipsN32Abi)
- Type &= 0xff;
+ if (ELFT::Is64Bits || config->mipsN32Abi)
+ type &= 0xff;
- switch (Type) {
+ switch (type) {
case R_MIPS_JALR:
case R_MICROMIPS_JALR:
return R_HINT;
@@ -107,9 +107,9 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
// offset between start of function and 'gp' value which by default
// equal to the start of .got section. In that case we consider these
// relocations as relative.
- if (&S == ElfSym::MipsGpDisp)
+ if (&s == ElfSym::mipsGpDisp)
return R_MIPS_GOT_GP_PC;
- if (&S == ElfSym::MipsLocalGp)
+ if (&s == ElfSym::mipsLocalGp)
return R_MIPS_GOT_GP;
LLVM_FALLTHROUGH;
case R_MIPS_32:
@@ -146,7 +146,7 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
return R_PC;
case R_MIPS_GOT16:
case R_MICROMIPS_GOT16:
- if (S.isLocal())
+ if (s.isLocal())
return R_MIPS_GOT_LOCAL_PAGE;
LLVM_FALLTHROUGH;
case R_MIPS_CALL16:
@@ -175,213 +175,213 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
case R_MIPS_NONE:
return R_NONE;
default:
- error(getErrorLocation(Loc) + "unknown relocation (" + Twine(Type) +
- ") against symbol " + toString(S));
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
return R_NONE;
}
}
-template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
- if (Type == SymbolicRel)
- return Type;
+template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
+ if (type == symbolicRel)
+ return type;
return R_MIPS_NONE;
}
template <class ELFT>
-void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
- uint64_t VA = In.Plt->getVA();
+void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
+ uint64_t va = in.plt->getVA();
if (isMicroMips())
- VA |= 1;
- write32<ELFT::TargetEndianness>(Buf, VA);
+ va |= 1;
+ write32<ELFT::TargetEndianness>(buf, va);
}
-template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) {
+template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
// The major opcode of a microMIPS instruction needs to appear
// in the first 16-bit word (lowest address) for efficient hardware
// decode so that it knows if the instruction is 16-bit or 32-bit
// as early as possible. To do so, little-endian binaries keep 16-bit
// words in a big-endian order. That is why we have to swap these
// words to get a correct value.
- uint32_t V = read32<E>(Loc);
+ uint32_t v = read32<E>(loc);
if (E == support::little)
- return (V << 16) | (V >> 16);
- return V;
+ return (v << 16) | (v >> 16);
+ return v;
}
template <endianness E>
-static void writeValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
- uint8_t Shift) {
- uint32_t Instr = read32<E>(Loc);
- uint32_t Mask = 0xffffffff >> (32 - BitsSize);
- uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
- write32<E>(Loc, Data);
+static void writeValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
+ uint8_t shift) {
+ uint32_t instr = read32<E>(loc);
+ uint32_t mask = 0xffffffff >> (32 - bitsSize);
+ uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
+ write32<E>(loc, data);
}
template <endianness E>
-static void writeShuffleValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
- uint8_t Shift) {
+static void writeShuffleValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
+ uint8_t shift) {
// See comments in readShuffle for purpose of this code.
- uint16_t *Words = (uint16_t *)Loc;
+ uint16_t *words = (uint16_t *)loc;
if (E == support::little)
- std::swap(Words[0], Words[1]);
+ std::swap(words[0], words[1]);
- writeValue<E>(Loc, V, BitsSize, Shift);
+ writeValue<E>(loc, v, bitsSize, shift);
if (E == support::little)
- std::swap(Words[0], Words[1]);
+ std::swap(words[0], words[1]);
}
template <endianness E>
-static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
- uint8_t Shift) {
- uint16_t Instr = read16<E>(Loc);
- uint16_t Mask = 0xffff >> (16 - BitsSize);
- uint16_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
- write16<E>(Loc, Data);
+static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
+ uint8_t shift) {
+ uint16_t instr = read16<E>(loc);
+ uint16_t mask = 0xffff >> (16 - bitsSize);
+ uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
+ write16<E>(loc, data);
}
-template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
- const endianness E = ELFT::TargetEndianness;
+template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
+ const endianness e = ELFT::TargetEndianness;
if (isMicroMips()) {
- uint64_t GotPlt = In.GotPlt->getVA();
- uint64_t Plt = In.Plt->getVA();
+ uint64_t gotPlt = in.gotPlt->getVA();
+ uint64_t plt = in.plt->getVA();
// Overwrite trap instructions written by Writer::writeTrapInstr.
- memset(Buf, 0, PltHeaderSize);
-
- write16<E>(Buf, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
- write16<E>(Buf + 4, 0xff23); // lw $25, 0($3)
- write16<E>(Buf + 8, 0x0535); // subu16 $2, $2, $3
- write16<E>(Buf + 10, 0x2525); // srl16 $2, $2, 2
- write16<E>(Buf + 12, 0x3302); // addiu $24, $2, -2
- write16<E>(Buf + 14, 0xfffe);
- write16<E>(Buf + 16, 0x0dff); // move $15, $31
+ memset(buf, 0, pltHeaderSize);
+
+ write16<e>(buf, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
+ write16<e>(buf + 4, 0xff23); // lw $25, 0($3)
+ write16<e>(buf + 8, 0x0535); // subu16 $2, $2, $3
+ write16<e>(buf + 10, 0x2525); // srl16 $2, $2, 2
+ write16<e>(buf + 12, 0x3302); // addiu $24, $2, -2
+ write16<e>(buf + 14, 0xfffe);
+ write16<e>(buf + 16, 0x0dff); // move $15, $31
if (isMipsR6()) {
- write16<E>(Buf + 18, 0x0f83); // move $28, $3
- write16<E>(Buf + 20, 0x472b); // jalrc $25
- write16<E>(Buf + 22, 0x0c00); // nop
- relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
+ write16<e>(buf + 18, 0x0f83); // move $28, $3
+ write16<e>(buf + 20, 0x472b); // jalrc $25
+ write16<e>(buf + 22, 0x0c00); // nop
+ relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
} else {
- write16<E>(Buf + 18, 0x45f9); // jalrc $25
- write16<E>(Buf + 20, 0x0f83); // move $28, $3
- write16<E>(Buf + 22, 0x0c00); // nop
- relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
+ write16<e>(buf + 18, 0x45f9); // jalrc $25
+ write16<e>(buf + 20, 0x0f83); // move $28, $3
+ write16<e>(buf + 22, 0x0c00); // nop
+ relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
}
return;
}
- if (Config->MipsN32Abi) {
- write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
- write32<E>(Buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
- write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
- write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14
- write32<E>(Buf + 16, 0x03e07825); // move $15, $31
- write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
+ if (config->mipsN32Abi) {
+ write32<e>(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
+ write32<e>(buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
+ write32<e>(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
+ write32<e>(buf + 12, 0x030ec023); // subu $24, $24, $14
+ write32<e>(buf + 16, 0x03e07825); // move $15, $31
+ write32<e>(buf + 20, 0x0018c082); // srl $24, $24, 2
} else if (ELFT::Is64Bits) {
- write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
- write32<E>(Buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
- write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
- write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14
- write32<E>(Buf + 16, 0x03e07825); // move $15, $31
- write32<E>(Buf + 20, 0x0018c0c2); // srl $24, $24, 3
+ write32<e>(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
+ write32<e>(buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
+ write32<e>(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
+ write32<e>(buf + 12, 0x030ec023); // subu $24, $24, $14
+ write32<e>(buf + 16, 0x03e07825); // move $15, $31
+ write32<e>(buf + 20, 0x0018c0c2); // srl $24, $24, 3
} else {
- write32<E>(Buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
- write32<E>(Buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
- write32<E>(Buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
- write32<E>(Buf + 12, 0x031cc023); // subu $24, $24, $28
- write32<E>(Buf + 16, 0x03e07825); // move $15, $31
- write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
+ write32<e>(buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
+ write32<e>(buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
+ write32<e>(buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
+ write32<e>(buf + 12, 0x031cc023); // subu $24, $24, $28
+ write32<e>(buf + 16, 0x03e07825); // move $15, $31
+ write32<e>(buf + 20, 0x0018c082); // srl $24, $24, 2
}
- uint32_t JalrInst = Config->ZHazardplt ? 0x0320fc09 : 0x0320f809;
- write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
- write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
+ uint32_t jalrInst = config->zHazardplt ? 0x0320fc09 : 0x0320f809;
+ write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
+ write32<e>(buf + 28, 0x2718fffe); // subu $24, $24, 2
- uint64_t GotPlt = In.GotPlt->getVA();
- writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
- writeValue<E>(Buf + 4, GotPlt, 16, 0);
- writeValue<E>(Buf + 8, GotPlt, 16, 0);
+ uint64_t gotPlt = in.gotPlt->getVA();
+ writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
+ writeValue<e>(buf + 4, gotPlt, 16, 0);
+ writeValue<e>(buf + 8, gotPlt, 16, 0);
}
template <class ELFT>
-void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const endianness E = ELFT::TargetEndianness;
+void MIPS<ELFT>::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const endianness e = ELFT::TargetEndianness;
if (isMicroMips()) {
// Overwrite trap instructions written by Writer::writeTrapInstr.
- memset(Buf, 0, PltEntrySize);
+ memset(buf, 0, pltEntrySize);
if (isMipsR6()) {
- write16<E>(Buf, 0x7840); // addiupc $2, (GOTPLT) - .
- write16<E>(Buf + 4, 0xff22); // lw $25, 0($2)
- write16<E>(Buf + 8, 0x0f02); // move $24, $2
- write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
- relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
+ write16<e>(buf, 0x7840); // addiupc $2, (GOTPLT) - .
+ write16<e>(buf + 4, 0xff22); // lw $25, 0($2)
+ write16<e>(buf + 8, 0x0f02); // move $24, $2
+ write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
+ relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
} else {
- write16<E>(Buf, 0x7900); // addiupc $2, (GOTPLT) - .
- write16<E>(Buf + 4, 0xff22); // lw $25, 0($2)
- write16<E>(Buf + 8, 0x4599); // jrc $25 / jr16 $25
- write16<E>(Buf + 10, 0x0f02); // move $24, $2
- relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
+ write16<e>(buf, 0x7900); // addiupc $2, (GOTPLT) - .
+ write16<e>(buf + 4, 0xff22); // lw $25, 0($2)
+ write16<e>(buf + 8, 0x4599); // jrc $25 / jr16 $25
+ write16<e>(buf + 10, 0x0f02); // move $24, $2
+ relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
}
return;
}
- uint32_t LoadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
- uint32_t JrInst = isMipsR6() ? (Config->ZHazardplt ? 0x03200409 : 0x03200009)
- : (Config->ZHazardplt ? 0x03200408 : 0x03200008);
- uint32_t AddInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
-
- write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
- write32<E>(Buf + 4, LoadInst); // l[wd] $25, %lo(.got.plt entry)($15)
- write32<E>(Buf + 8, JrInst); // jr $25 / jr.hb $25
- write32<E>(Buf + 12, AddInst); // [d]addiu $24, $15, %lo(.got.plt entry)
- writeValue<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
- writeValue<E>(Buf + 4, GotPltEntryAddr, 16, 0);
- writeValue<E>(Buf + 12, GotPltEntryAddr, 16, 0);
+ uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
+ uint32_t jrInst = isMipsR6() ? (config->zHazardplt ? 0x03200409 : 0x03200009)
+ : (config->zHazardplt ? 0x03200408 : 0x03200008);
+ uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
+
+ write32<e>(buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
+ write32<e>(buf + 4, loadInst); // l[wd] $25, %lo(.got.plt entry)($15)
+ write32<e>(buf + 8, jrInst); // jr $25 / jr.hb $25
+ write32<e>(buf + 12, addInst); // [d]addiu $24, $15, %lo(.got.plt entry)
+ writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
+ writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
+ writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
}
template <class ELFT>
-bool MIPS<ELFT>::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
+bool MIPS<ELFT>::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
// Any MIPS PIC code function is invoked with its address in register $t9.
// So if we have a branch instruction from non-PIC code to the PIC one
// we cannot make the jump directly and need to create a small stubs
// to save the target function address.
// See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (Type != R_MIPS_26 && Type != R_MIPS_PC26_S2 &&
- Type != R_MICROMIPS_26_S1 && Type != R_MICROMIPS_PC26_S1)
+ if (type != R_MIPS_26 && type != R_MIPS_PC26_S2 &&
+ type != R_MICROMIPS_26_S1 && type != R_MICROMIPS_PC26_S1)
return false;
- auto *F = dyn_cast_or_null<ObjFile<ELFT>>(File);
- if (!F)
+ auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
+ if (!f)
return false;
// If current file has PIC code, LA25 stub is not required.
- if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
+ if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
return false;
- auto *D = dyn_cast<Defined>(&S);
+ auto *d = dyn_cast<Defined>(&s);
// LA25 is required if target file has PIC code
// or target symbol is a PIC symbol.
- return D && isMipsPIC<ELFT>(D);
+ return d && isMipsPIC<ELFT>(d);
}
template <class ELFT>
-int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
- const endianness E = ELFT::TargetEndianness;
- switch (Type) {
+int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
+ const endianness e = ELFT::TargetEndianness;
+ switch (type) {
case R_MIPS_32:
case R_MIPS_GPREL32:
case R_MIPS_TLS_DTPREL32:
case R_MIPS_TLS_TPREL32:
- return SignExtend64<32>(read32<E>(Buf));
+ return SignExtend64<32>(read32<e>(buf));
case R_MIPS_26:
// FIXME (simon): If the relocation target symbol is not a PLT entry
// we should use another expression for calculation:
// ((A << 2) | (P & 0xf0000000)) >> 2
- return SignExtend64<28>(read32<E>(Buf) << 2);
+ return SignExtend64<28>(read32<e>(buf) << 2);
case R_MIPS_GOT16:
case R_MIPS_HI16:
case R_MIPS_PCHI16:
- return SignExtend64<16>(read32<E>(Buf)) << 16;
+ return SignExtend64<16>(read32<e>(buf)) << 16;
case R_MIPS_GPREL16:
case R_MIPS_LO16:
case R_MIPS_PCLO16:
@@ -389,54 +389,54 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
case R_MIPS_TLS_DTPREL_LO16:
case R_MIPS_TLS_TPREL_HI16:
case R_MIPS_TLS_TPREL_LO16:
- return SignExtend64<16>(read32<E>(Buf));
+ return SignExtend64<16>(read32<e>(buf));
case R_MICROMIPS_GOT16:
case R_MICROMIPS_HI16:
- return SignExtend64<16>(readShuffle<E>(Buf)) << 16;
+ return SignExtend64<16>(readShuffle<e>(buf)) << 16;
case R_MICROMIPS_GPREL16:
case R_MICROMIPS_LO16:
case R_MICROMIPS_TLS_DTPREL_HI16:
case R_MICROMIPS_TLS_DTPREL_LO16:
case R_MICROMIPS_TLS_TPREL_HI16:
case R_MICROMIPS_TLS_TPREL_LO16:
- return SignExtend64<16>(readShuffle<E>(Buf));
+ return SignExtend64<16>(readShuffle<e>(buf));
case R_MICROMIPS_GPREL7_S2:
- return SignExtend64<9>(readShuffle<E>(Buf) << 2);
+ return SignExtend64<9>(readShuffle<e>(buf) << 2);
case R_MIPS_PC16:
- return SignExtend64<18>(read32<E>(Buf) << 2);
+ return SignExtend64<18>(read32<e>(buf) << 2);
case R_MIPS_PC19_S2:
- return SignExtend64<21>(read32<E>(Buf) << 2);
+ return SignExtend64<21>(read32<e>(buf) << 2);
case R_MIPS_PC21_S2:
- return SignExtend64<23>(read32<E>(Buf) << 2);
+ return SignExtend64<23>(read32<e>(buf) << 2);
case R_MIPS_PC26_S2:
- return SignExtend64<28>(read32<E>(Buf) << 2);
+ return SignExtend64<28>(read32<e>(buf) << 2);
case R_MIPS_PC32:
- return SignExtend64<32>(read32<E>(Buf));
+ return SignExtend64<32>(read32<e>(buf));
case R_MICROMIPS_26_S1:
- return SignExtend64<27>(readShuffle<E>(Buf) << 1);
+ return SignExtend64<27>(readShuffle<e>(buf) << 1);
case R_MICROMIPS_PC7_S1:
- return SignExtend64<8>(read16<E>(Buf) << 1);
+ return SignExtend64<8>(read16<e>(buf) << 1);
case R_MICROMIPS_PC10_S1:
- return SignExtend64<11>(read16<E>(Buf) << 1);
+ return SignExtend64<11>(read16<e>(buf) << 1);
case R_MICROMIPS_PC16_S1:
- return SignExtend64<17>(readShuffle<E>(Buf) << 1);
+ return SignExtend64<17>(readShuffle<e>(buf) << 1);
case R_MICROMIPS_PC18_S3:
- return SignExtend64<21>(readShuffle<E>(Buf) << 3);
+ return SignExtend64<21>(readShuffle<e>(buf) << 3);
case R_MICROMIPS_PC19_S2:
- return SignExtend64<21>(readShuffle<E>(Buf) << 2);
+ return SignExtend64<21>(readShuffle<e>(buf) << 2);
case R_MICROMIPS_PC21_S1:
- return SignExtend64<22>(readShuffle<E>(Buf) << 1);
+ return SignExtend64<22>(readShuffle<e>(buf) << 1);
case R_MICROMIPS_PC23_S2:
- return SignExtend64<25>(readShuffle<E>(Buf) << 2);
+ return SignExtend64<25>(readShuffle<e>(buf) << 2);
case R_MICROMIPS_PC26_S1:
- return SignExtend64<27>(readShuffle<E>(Buf) << 1);
+ return SignExtend64<27>(readShuffle<e>(buf) << 1);
default:
return 0;
}
}
static std::pair<uint32_t, uint64_t>
-calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) {
+calculateMipsRelChain(uint8_t *loc, RelType type, uint64_t val) {
// MIPS N64 ABI packs multiple relocations into the single relocation
// record. In general, all up to three relocations can have arbitrary
// types. In fact, Clang and GCC uses only a few combinations. For now,
@@ -449,57 +449,57 @@ calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) {
// relocations used to modify result of the first one: extend it to
// 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
// at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
- RelType Type2 = (Type >> 8) & 0xff;
- RelType Type3 = (Type >> 16) & 0xff;
- if (Type2 == R_MIPS_NONE && Type3 == R_MIPS_NONE)
- return std::make_pair(Type, Val);
- if (Type2 == R_MIPS_64 && Type3 == R_MIPS_NONE)
- return std::make_pair(Type2, Val);
- if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16))
- return std::make_pair(Type3, -Val);
- error(getErrorLocation(Loc) + "unsupported relocations combination " +
- Twine(Type));
- return std::make_pair(Type & 0xff, Val);
+ RelType type2 = (type >> 8) & 0xff;
+ RelType type3 = (type >> 16) & 0xff;
+ if (type2 == R_MIPS_NONE && type3 == R_MIPS_NONE)
+ return std::make_pair(type, val);
+ if (type2 == R_MIPS_64 && type3 == R_MIPS_NONE)
+ return std::make_pair(type2, val);
+ if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || type3 == R_MIPS_LO16))
+ return std::make_pair(type3, -val);
+ error(getErrorLocation(loc) + "unsupported relocations combination " +
+ Twine(type));
+ return std::make_pair(type & 0xff, val);
}
-static bool isBranchReloc(RelType Type) {
- return Type == R_MIPS_26 || Type == R_MIPS_PC26_S2 ||
- Type == R_MIPS_PC21_S2 || Type == R_MIPS_PC16;
+static bool isBranchReloc(RelType type) {
+ return type == R_MIPS_26 || type == R_MIPS_PC26_S2 ||
+ type == R_MIPS_PC21_S2 || type == R_MIPS_PC16;
}
-static bool isMicroBranchReloc(RelType Type) {
- return Type == R_MICROMIPS_26_S1 || Type == R_MICROMIPS_PC16_S1 ||
- Type == R_MICROMIPS_PC10_S1 || Type == R_MICROMIPS_PC7_S1;
+static bool isMicroBranchReloc(RelType type) {
+ return type == R_MICROMIPS_26_S1 || type == R_MICROMIPS_PC16_S1 ||
+ type == R_MICROMIPS_PC10_S1 || type == R_MICROMIPS_PC7_S1;
}
template <class ELFT>
-static uint64_t fixupCrossModeJump(uint8_t *Loc, RelType Type, uint64_t Val) {
+static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
// Here we need to detect jump/branch from regular MIPS code
// to a microMIPS target and vice versa. In that cases jump
// instructions need to be replaced by their "cross-mode"
// equivalents.
- const endianness E = ELFT::TargetEndianness;
- bool IsMicroTgt = Val & 0x1;
- bool IsCrossJump = (IsMicroTgt && isBranchReloc(Type)) ||
- (!IsMicroTgt && isMicroBranchReloc(Type));
- if (!IsCrossJump)
- return Val;
-
- switch (Type) {
+ const endianness e = ELFT::TargetEndianness;
+ bool isMicroTgt = val & 0x1;
+ bool isCrossJump = (isMicroTgt && isBranchReloc(type)) ||
+ (!isMicroTgt && isMicroBranchReloc(type));
+ if (!isCrossJump)
+ return val;
+
+ switch (type) {
case R_MIPS_26: {
- uint32_t Inst = read32<E>(Loc) >> 26;
- if (Inst == 0x3 || Inst == 0x1d) { // JAL or JALX
- writeValue<E>(Loc, 0x1d << 26, 32, 0);
- return Val;
+ uint32_t inst = read32<e>(loc) >> 26;
+ if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
+ writeValue<e>(loc, 0x1d << 26, 32, 0);
+ return val;
}
break;
}
case R_MICROMIPS_26_S1: {
- uint32_t Inst = readShuffle<E>(Loc) >> 26;
- if (Inst == 0x3d || Inst == 0x3c) { // JAL32 or JALX32
- Val >>= 1;
- writeShuffleValue<E>(Loc, 0x3c << 26, 32, 0);
- return Val;
+ uint32_t inst = readShuffle<e>(loc) >> 26;
+ if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
+ val >>= 1;
+ writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
+ return val;
}
break;
}
@@ -515,68 +515,68 @@ static uint64_t fixupCrossModeJump(uint8_t *Loc, RelType Type, uint64_t Val) {
llvm_unreachable("unexpected jump/branch relocation");
}
- error(getErrorLocation(Loc) +
+ error(getErrorLocation(loc) +
"unsupported jump/branch instruction between ISA modes referenced by " +
- toString(Type) + " relocation");
- return Val;
+ toString(type) + " relocation");
+ return val;
}
template <class ELFT>
-void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- const endianness E = ELFT::TargetEndianness;
+void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ const endianness e = ELFT::TargetEndianness;
- if (ELFT::Is64Bits || Config->MipsN32Abi)
- std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
+ if (ELFT::Is64Bits || config->mipsN32Abi)
+ std::tie(type, val) = calculateMipsRelChain(loc, type, val);
// Detect cross-mode jump/branch and fix instruction.
- Val = fixupCrossModeJump<ELFT>(Loc, Type, Val);
+ val = fixupCrossModeJump<ELFT>(loc, type, val);
// Thread pointer and DRP offsets from the start of TLS data area.
// https://www.linux-mips.org/wiki/NPTL
- if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 ||
- Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64 ||
- Type == R_MICROMIPS_TLS_DTPREL_HI16 ||
- Type == R_MICROMIPS_TLS_DTPREL_LO16) {
- Val -= 0x8000;
- } else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 ||
- Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64 ||
- Type == R_MICROMIPS_TLS_TPREL_HI16 ||
- Type == R_MICROMIPS_TLS_TPREL_LO16) {
- Val -= 0x7000;
+ if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
+ type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
+ type == R_MICROMIPS_TLS_DTPREL_HI16 ||
+ type == R_MICROMIPS_TLS_DTPREL_LO16) {
+ val -= 0x8000;
+ } else if (type == R_MIPS_TLS_TPREL_HI16 || type == R_MIPS_TLS_TPREL_LO16 ||
+ type == R_MIPS_TLS_TPREL32 || type == R_MIPS_TLS_TPREL64 ||
+ type == R_MICROMIPS_TLS_TPREL_HI16 ||
+ type == R_MICROMIPS_TLS_TPREL_LO16) {
+ val -= 0x7000;
}
- switch (Type) {
+ switch (type) {
case R_MIPS_32:
case R_MIPS_GPREL32:
case R_MIPS_TLS_DTPREL32:
case R_MIPS_TLS_TPREL32:
- write32<E>(Loc, Val);
+ write32<e>(loc, val);
break;
case R_MIPS_64:
case R_MIPS_TLS_DTPREL64:
case R_MIPS_TLS_TPREL64:
- write64<E>(Loc, Val);
+ write64<e>(loc, val);
break;
case R_MIPS_26:
- writeValue<E>(Loc, Val, 26, 2);
+ writeValue<e>(loc, val, 26, 2);
break;
case R_MIPS_GOT16:
// The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
// is updated addend (not a GOT index). In that case write high 16 bits
// to store a correct addend value.
- if (Config->Relocatable) {
- writeValue<E>(Loc, Val + 0x8000, 16, 16);
+ if (config->relocatable) {
+ writeValue<e>(loc, val + 0x8000, 16, 16);
} else {
- checkInt(Loc, Val, 16, Type);
- writeValue<E>(Loc, Val, 16, 0);
+ checkInt(loc, val, 16, type);
+ writeValue<e>(loc, val, 16, 0);
}
break;
case R_MICROMIPS_GOT16:
- if (Config->Relocatable) {
- writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16);
+ if (config->relocatable) {
+ writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
} else {
- checkInt(Loc, Val, 16, Type);
- writeShuffleValue<E>(Loc, Val, 16, 0);
+ checkInt(loc, val, 16, type);
+ writeShuffleValue<e>(loc, val, 16, 0);
}
break;
case R_MIPS_CALL16:
@@ -586,7 +586,7 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_MIPS_TLS_GD:
case R_MIPS_TLS_GOTTPREL:
case R_MIPS_TLS_LDM:
- checkInt(Loc, Val, 16, Type);
+ checkInt(loc, val, 16, type);
LLVM_FALLTHROUGH;
case R_MIPS_CALL_LO16:
case R_MIPS_GOT_LO16:
@@ -595,13 +595,13 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_MIPS_PCLO16:
case R_MIPS_TLS_DTPREL_LO16:
case R_MIPS_TLS_TPREL_LO16:
- writeValue<E>(Loc, Val, 16, 0);
+ writeValue<e>(loc, val, 16, 0);
break;
case R_MICROMIPS_GPREL16:
case R_MICROMIPS_TLS_GD:
case R_MICROMIPS_TLS_LDM:
- checkInt(Loc, Val, 16, Type);
- writeShuffleValue<E>(Loc, Val, 16, 0);
+ checkInt(loc, val, 16, type);
+ writeShuffleValue<e>(loc, val, 16, 0);
break;
case R_MICROMIPS_CALL16:
case R_MICROMIPS_CALL_LO16:
@@ -609,11 +609,11 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_MICROMIPS_TLS_DTPREL_LO16:
case R_MICROMIPS_TLS_GOTTPREL:
case R_MICROMIPS_TLS_TPREL_LO16:
- writeShuffleValue<E>(Loc, Val, 16, 0);
+ writeShuffleValue<e>(loc, val, 16, 0);
break;
case R_MICROMIPS_GPREL7_S2:
- checkInt(Loc, Val, 7, Type);
- writeShuffleValue<E>(Loc, Val, 7, 2);
+ checkInt(loc, val, 7, type);
+ writeShuffleValue<e>(loc, val, 7, 2);
break;
case R_MIPS_CALL_HI16:
case R_MIPS_GOT_HI16:
@@ -621,113 +621,113 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_MIPS_PCHI16:
case R_MIPS_TLS_DTPREL_HI16:
case R_MIPS_TLS_TPREL_HI16:
- writeValue<E>(Loc, Val + 0x8000, 16, 16);
+ writeValue<e>(loc, val + 0x8000, 16, 16);
break;
case R_MICROMIPS_CALL_HI16:
case R_MICROMIPS_GOT_HI16:
case R_MICROMIPS_HI16:
case R_MICROMIPS_TLS_DTPREL_HI16:
case R_MICROMIPS_TLS_TPREL_HI16:
- writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16);
+ writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
break;
case R_MIPS_HIGHER:
- writeValue<E>(Loc, Val + 0x80008000, 16, 32);
+ writeValue<e>(loc, val + 0x80008000, 16, 32);
break;
case R_MIPS_HIGHEST:
- writeValue<E>(Loc, Val + 0x800080008000, 16, 48);
+ writeValue<e>(loc, val + 0x800080008000, 16, 48);
break;
case R_MIPS_JALR:
case R_MICROMIPS_JALR:
// Ignore this optimization relocation for now
break;
case R_MIPS_PC16:
- checkAlignment(Loc, Val, 4, Type);
- checkInt(Loc, Val, 18, Type);
- writeValue<E>(Loc, Val, 16, 2);
+ checkAlignment(loc, val, 4, type);
+ checkInt(loc, val, 18, type);
+ writeValue<e>(loc, val, 16, 2);
break;
case R_MIPS_PC19_S2:
- checkAlignment(Loc, Val, 4, Type);
- checkInt(Loc, Val, 21, Type);
- writeValue<E>(Loc, Val, 19, 2);
+ checkAlignment(loc, val, 4, type);
+ checkInt(loc, val, 21, type);
+ writeValue<e>(loc, val, 19, 2);
break;
case R_MIPS_PC21_S2:
- checkAlignment(Loc, Val, 4, Type);
- checkInt(Loc, Val, 23, Type);
- writeValue<E>(Loc, Val, 21, 2);
+ checkAlignment(loc, val, 4, type);
+ checkInt(loc, val, 23, type);
+ writeValue<e>(loc, val, 21, 2);
break;
case R_MIPS_PC26_S2:
- checkAlignment(Loc, Val, 4, Type);
- checkInt(Loc, Val, 28, Type);
- writeValue<E>(Loc, Val, 26, 2);
+ checkAlignment(loc, val, 4, type);
+ checkInt(loc, val, 28, type);
+ writeValue<e>(loc, val, 26, 2);
break;
case R_MIPS_PC32:
- writeValue<E>(Loc, Val, 32, 0);
+ writeValue<e>(loc, val, 32, 0);
break;
case R_MICROMIPS_26_S1:
case R_MICROMIPS_PC26_S1:
- checkInt(Loc, Val, 27, Type);
- writeShuffleValue<E>(Loc, Val, 26, 1);
+ checkInt(loc, val, 27, type);
+ writeShuffleValue<e>(loc, val, 26, 1);
break;
case R_MICROMIPS_PC7_S1:
- checkInt(Loc, Val, 8, Type);
- writeMicroRelocation16<E>(Loc, Val, 7, 1);
+ checkInt(loc, val, 8, type);
+ writeMicroRelocation16<e>(loc, val, 7, 1);
break;
case R_MICROMIPS_PC10_S1:
- checkInt(Loc, Val, 11, Type);
- writeMicroRelocation16<E>(Loc, Val, 10, 1);
+ checkInt(loc, val, 11, type);
+ writeMicroRelocation16<e>(loc, val, 10, 1);
break;
case R_MICROMIPS_PC16_S1:
- checkInt(Loc, Val, 17, Type);
- writeShuffleValue<E>(Loc, Val, 16, 1);
+ checkInt(loc, val, 17, type);
+ writeShuffleValue<e>(loc, val, 16, 1);
break;
case R_MICROMIPS_PC18_S3:
- checkInt(Loc, Val, 21, Type);
- writeShuffleValue<E>(Loc, Val, 18, 3);
+ checkInt(loc, val, 21, type);
+ writeShuffleValue<e>(loc, val, 18, 3);
break;
case R_MICROMIPS_PC19_S2:
- checkInt(Loc, Val, 21, Type);
- writeShuffleValue<E>(Loc, Val, 19, 2);
+ checkInt(loc, val, 21, type);
+ writeShuffleValue<e>(loc, val, 19, 2);
break;
case R_MICROMIPS_PC21_S1:
- checkInt(Loc, Val, 22, Type);
- writeShuffleValue<E>(Loc, Val, 21, 1);
+ checkInt(loc, val, 22, type);
+ writeShuffleValue<e>(loc, val, 21, 1);
break;
case R_MICROMIPS_PC23_S2:
- checkInt(Loc, Val, 25, Type);
- writeShuffleValue<E>(Loc, Val, 23, 2);
+ checkInt(loc, val, 25, type);
+ writeShuffleValue<e>(loc, val, 23, 2);
break;
default:
llvm_unreachable("unknown relocation");
}
}
-template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
- return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST ||
- Type == R_MICROMIPS_LO16;
+template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
+ return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
+ type == R_MICROMIPS_LO16;
}
// Return true if the symbol is a PIC function.
-template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
- if (!Sym->isFunc())
+template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
+ if (!sym->isFunc())
return false;
- if (Sym->StOther & STO_MIPS_PIC)
+ if (sym->stOther & STO_MIPS_PIC)
return true;
- if (!Sym->Section)
+ if (!sym->section)
return false;
- ObjFile<ELFT> *File =
- cast<InputSectionBase>(Sym->Section)->template getFile<ELFT>();
- if (!File)
+ ObjFile<ELFT> *file =
+ cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
+ if (!file)
return false;
- return File->getObj().getHeader()->e_flags & EF_MIPS_PIC;
+ return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
}
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
- static MIPS<ELFT> Target;
- return &Target;
+ static MIPS<ELFT> target;
+ return &target;
}
template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp
index 0d3ed41c8e1..f64d0375645 100644
--- a/lld/ELF/Arch/MipsArchTree.cpp
+++ b/lld/ELF/Arch/MipsArchTree.cpp
@@ -28,18 +28,18 @@ using namespace lld::elf;
namespace {
struct ArchTreeEdge {
- uint32_t Child;
- uint32_t Parent;
+ uint32_t child;
+ uint32_t parent;
};
struct FileFlags {
- InputFile *File;
- uint32_t Flags;
+ InputFile *file;
+ uint32_t flags;
};
} // namespace
-static StringRef getAbiName(uint32_t Flags) {
- switch (Flags) {
+static StringRef getAbiName(uint32_t flags) {
+ switch (flags) {
case 0:
return "n64";
case EF_MIPS_ABI2:
@@ -57,76 +57,76 @@ static StringRef getAbiName(uint32_t Flags) {
}
}
-static StringRef getNanName(bool IsNan2008) {
- return IsNan2008 ? "2008" : "legacy";
+static StringRef getNanName(bool isNan2008) {
+ return isNan2008 ? "2008" : "legacy";
}
-static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
+static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; }
-static void checkFlags(ArrayRef<FileFlags> Files) {
- assert(!Files.empty() && "expected non-empty file list");
+static void checkFlags(ArrayRef<FileFlags> files) {
+ assert(!files.empty() && "expected non-empty file list");
- uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
- bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
- bool Fp = Files[0].Flags & EF_MIPS_FP64;
+ uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
+ bool nan = files[0].flags & EF_MIPS_NAN2008;
+ bool fp = files[0].flags & EF_MIPS_FP64;
- for (const FileFlags &F : Files) {
- if (Config->Is64 && F.Flags & EF_MIPS_MICROMIPS)
- error(toString(F.File) + ": microMIPS 64-bit is not supported");
+ for (const FileFlags &f : files) {
+ if (config->is64 && f.flags & EF_MIPS_MICROMIPS)
+ error(toString(f.file) + ": microMIPS 64-bit is not supported");
- uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
- if (ABI != ABI2)
- error(toString(F.File) + ": ABI '" + getAbiName(ABI2) +
- "' is incompatible with target ABI '" + getAbiName(ABI) + "'");
+ uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
+ if (abi != abi2)
+ error(toString(f.file) + ": ABI '" + getAbiName(abi2) +
+ "' is incompatible with target ABI '" + getAbiName(abi) + "'");
- bool Nan2 = F.Flags & EF_MIPS_NAN2008;
- if (Nan != Nan2)
- error(toString(F.File) + ": -mnan=" + getNanName(Nan2) +
- " is incompatible with target -mnan=" + getNanName(Nan));
+ bool nan2 = f.flags & EF_MIPS_NAN2008;
+ if (nan != nan2)
+ error(toString(f.file) + ": -mnan=" + getNanName(nan2) +
+ " is incompatible with target -mnan=" + getNanName(nan));
- bool Fp2 = F.Flags & EF_MIPS_FP64;
- if (Fp != Fp2)
- error(toString(F.File) + ": -mfp" + getFpName(Fp2) +
- " is incompatible with target -mfp" + getFpName(Fp));
+ bool fp2 = f.flags & EF_MIPS_FP64;
+ if (fp != fp2)
+ error(toString(f.file) + ": -mfp" + getFpName(fp2) +
+ " is incompatible with target -mfp" + getFpName(fp));
}
}
-static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
- uint32_t Ret = 0;
- for (const FileFlags &F : Files)
- Ret |= F.Flags &
+static uint32_t getMiscFlags(ArrayRef<FileFlags> files) {
+ uint32_t ret = 0;
+ for (const FileFlags &f : files)
+ ret |= f.flags &
(EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
- return Ret;
+ return ret;
}
-static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
+static uint32_t getPicFlags(ArrayRef<FileFlags> files) {
// Check PIC/non-PIC compatibility.
- bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
- for (const FileFlags &F : Files.slice(1)) {
- bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
- if (IsPic && !IsPic2)
- warn(toString(F.File) +
+ bool isPic = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
+ for (const FileFlags &f : files.slice(1)) {
+ bool isPic2 = f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
+ if (isPic && !isPic2)
+ warn(toString(f.file) +
": linking non-abicalls code with abicalls code " +
- toString(Files[0].File));
- if (!IsPic && IsPic2)
- warn(toString(F.File) +
+ toString(files[0].file));
+ if (!isPic && isPic2)
+ warn(toString(f.file) +
": linking abicalls code with non-abicalls code " +
- toString(Files[0].File));
+ toString(files[0].file));
}
// Compute the result PIC/non-PIC flag.
- uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
- for (const FileFlags &F : Files.slice(1))
- Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
+ uint32_t ret = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
+ for (const FileFlags &f : files.slice(1))
+ ret &= f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
// PIC code is inherently CPIC and may not set CPIC flag explicitly.
- if (Ret & EF_MIPS_PIC)
- Ret |= EF_MIPS_CPIC;
- return Ret;
+ if (ret & EF_MIPS_PIC)
+ ret |= EF_MIPS_CPIC;
+ return ret;
}
-static ArchTreeEdge ArchTree[] = {
+static ArchTreeEdge archTree[] = {
// MIPS32R6 and MIPS64R6 are not compatible with other extensions
// MIPS64R2 extensions.
{EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
@@ -166,25 +166,25 @@ static ArchTreeEdge ArchTree[] = {
{EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
};
-static bool isArchMatched(uint32_t New, uint32_t Res) {
- if (New == Res)
+static bool isArchMatched(uint32_t New, uint32_t res) {
+ if (New == res)
return true;
- if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
+ if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, res))
return true;
- if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
+ if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, res))
return true;
- for (const auto &Edge : ArchTree) {
- if (Res == Edge.Child) {
- Res = Edge.Parent;
- if (Res == New)
+ for (const auto &edge : archTree) {
+ if (res == edge.child) {
+ res = edge.parent;
+ if (res == New)
return true;
}
}
return false;
}
-static StringRef getMachName(uint32_t Flags) {
- switch (Flags & EF_MIPS_MACH) {
+static StringRef getMachName(uint32_t flags) {
+ switch (flags & EF_MIPS_MACH) {
case EF_MIPS_MACH_NONE:
return "";
case EF_MIPS_MACH_3900:
@@ -228,8 +228,8 @@ static StringRef getMachName(uint32_t Flags) {
}
}
-static StringRef getArchName(uint32_t Flags) {
- switch (Flags & EF_MIPS_ARCH) {
+static StringRef getArchName(uint32_t flags) {
+ switch (flags & EF_MIPS_ARCH) {
case EF_MIPS_ARCH_1:
return "mips1";
case EF_MIPS_ARCH_2:
@@ -257,12 +257,12 @@ static StringRef getArchName(uint32_t Flags) {
}
}
-static std::string getFullArchName(uint32_t Flags) {
- StringRef Arch = getArchName(Flags);
- StringRef Mach = getMachName(Flags);
- if (Mach.empty())
- return Arch.str();
- return (Arch + " (" + Mach + ")").str();
+static std::string getFullArchName(uint32_t flags) {
+ StringRef arch = getArchName(flags);
+ StringRef mach = getMachName(flags);
+ if (mach.empty())
+ return arch.str();
+ return (arch + " (" + mach + ")").str();
}
// There are (arguably too) many MIPS ISAs out there. Their relationships
@@ -274,55 +274,55 @@ static std::string getFullArchName(uint32_t Flags) {
// Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
// are incompatible because nor mips3 is a parent for misp32, nor mips32
// is a parent for mips3.
-static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
- uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
+static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
+ uint32_t ret = files[0].flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
- for (const FileFlags &F : Files.slice(1)) {
- uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
+ for (const FileFlags &f : files.slice(1)) {
+ uint32_t New = f.flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
// Check ISA compatibility.
- if (isArchMatched(New, Ret))
+ if (isArchMatched(New, ret))
continue;
- if (!isArchMatched(Ret, New)) {
- error("incompatible target ISA:\n>>> " + toString(Files[0].File) + ": " +
- getFullArchName(Ret) + "\n>>> " + toString(F.File) + ": " +
+ if (!isArchMatched(ret, New)) {
+ error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " +
+ getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " +
getFullArchName(New));
return 0;
}
- Ret = New;
+ ret = New;
}
- return Ret;
+ return ret;
}
template <class ELFT> uint32_t elf::calcMipsEFlags() {
- std::vector<FileFlags> V;
- for (InputFile *F : ObjectFiles)
- V.push_back({F, cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
- if (V.empty())
+ std::vector<FileFlags> v;
+ for (InputFile *f : objectFiles)
+ v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
+ if (v.empty())
return 0;
- checkFlags(V);
- return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
+ checkFlags(v);
+ return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v);
}
-static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
- if (FpA == FpB)
+static int compareMipsFpAbi(uint8_t fpA, uint8_t fpB) {
+ if (fpA == fpB)
return 0;
- if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
+ if (fpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
return 1;
- if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
- FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
+ if (fpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
+ fpA == Mips::Val_GNU_MIPS_ABI_FP_64)
return 1;
- if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
+ if (fpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
return -1;
- if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
- FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
- FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
+ if (fpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
+ fpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
+ fpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
return 1;
return -1;
}
-static StringRef getMipsFpAbiName(uint8_t FpAbi) {
- switch (FpAbi) {
+static StringRef getMipsFpAbiName(uint8_t fpAbi) {
+ switch (fpAbi) {
case Mips::Val_GNU_MIPS_ABI_FP_ANY:
return "any";
case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
@@ -344,43 +344,43 @@ static StringRef getMipsFpAbiName(uint8_t FpAbi) {
}
}
-uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
- StringRef FileName) {
- if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
- return NewFlag;
- if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
- error(FileName + ": floating point ABI '" + getMipsFpAbiName(NewFlag) +
+uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
+ StringRef fileName) {
+ if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
+ return newFlag;
+ if (compareMipsFpAbi(oldFlag, newFlag) < 0)
+ error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) +
"' is incompatible with target floating point ABI '" +
- getMipsFpAbiName(OldFlag) + "'");
- return OldFlag;
+ getMipsFpAbiName(oldFlag) + "'");
+ return oldFlag;
}
-template <class ELFT> static bool isN32Abi(const InputFile *F) {
- if (auto *EF = dyn_cast<ELFFileBase>(F))
- return EF->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
+template <class ELFT> static bool isN32Abi(const InputFile *f) {
+ if (auto *ef = dyn_cast<ELFFileBase>(f))
+ return ef->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
return false;
}
-bool elf::isMipsN32Abi(const InputFile *F) {
- switch (Config->EKind) {
+bool elf::isMipsN32Abi(const InputFile *f) {
+ switch (config->ekind) {
case ELF32LEKind:
- return isN32Abi<ELF32LE>(F);
+ return isN32Abi<ELF32LE>(f);
case ELF32BEKind:
- return isN32Abi<ELF32BE>(F);
+ return isN32Abi<ELF32BE>(f);
case ELF64LEKind:
- return isN32Abi<ELF64LE>(F);
+ return isN32Abi<ELF64LE>(f);
case ELF64BEKind:
- return isN32Abi<ELF64BE>(F);
+ return isN32Abi<ELF64BE>(f);
default:
llvm_unreachable("unknown Config->EKind");
}
}
-bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; }
+bool elf::isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; }
bool elf::isMipsR6() {
- uint32_t Arch = Config->EFlags & EF_MIPS_ARCH;
- return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6;
+ uint32_t arch = config->eflags & EF_MIPS_ARCH;
+ return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
}
template uint32_t elf::calcMipsEFlags<ELF32LE>();
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index de2c1ee7f9e..46c5891e4f8 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -23,45 +23,45 @@ namespace {
class PPC final : public TargetInfo {
public:
PPC();
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
- void writeGotHeader(uint8_t *Buf) const override;
- void writePltHeader(uint8_t *Buf) const override {
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
+ void writeGotHeader(uint8_t *buf) const override;
+ void writePltHeader(uint8_t *buf) const override {
llvm_unreachable("should call writePPC32GlinkSection() instead");
}
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override {
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override {
llvm_unreachable("should call writePPC32GlinkSection() instead");
}
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- bool needsThunk(RelExpr Expr, RelType RelocType, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ bool needsThunk(RelExpr expr, RelType relocType, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const override;
uint32_t getThunkSectionSpacing() const override;
- bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const override;
- int getTlsGdRelaxSkip(RelType Type) const override;
- void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const override;
+ int getTlsGdRelaxSkip(RelType type) const override;
+ void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
-static uint16_t lo(uint32_t V) { return V; }
-static uint16_t ha(uint32_t V) { return (V + 0x8000) >> 16; }
+static uint16_t lo(uint32_t v) { return v; }
+static uint16_t ha(uint32_t v) { return (v + 0x8000) >> 16; }
-static uint32_t readFromHalf16(const uint8_t *Loc) {
- return read32(Config->IsLE ? Loc : Loc - 2);
+static uint32_t readFromHalf16(const uint8_t *loc) {
+ return read32(config->isLE ? loc : loc - 2);
}
-static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) {
- write32(Config->IsLE ? Loc : Loc - 2, Insn);
+static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
+ write32(config->isLE ? loc : loc - 2, insn);
}
-void elf::writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries) {
+void elf::writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
// On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an
// absolute address from a specific .plt slot (usually called .got.plt on
// other targets) and jumps there.
@@ -72,124 +72,124 @@ void elf::writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries) {
// instruction in .glink, filled in by PPC::writeGotPlt().
// Write N `b PLTresolve` first.
- for (size_t I = 0; I != NumEntries; ++I)
- write32(Buf + 4 * I, 0x48000000 | 4 * (NumEntries - I));
- Buf += 4 * NumEntries;
+ for (size_t i = 0; i != numEntries; ++i)
+ write32(buf + 4 * i, 0x48000000 | 4 * (numEntries - i));
+ buf += 4 * numEntries;
// Then write PLTresolve(), which has two forms: PIC and non-PIC. PLTresolve()
// computes the PLT index (by computing the distance from the landing b to
// itself) and calls _dl_runtime_resolve() (in glibc).
- uint32_t GOT = In.Got->getVA();
- uint32_t Glink = In.Plt->getVA(); // VA of .glink
- const uint8_t *End = Buf + 64;
- if (Config->Pic) {
- uint32_t AfterBcl = In.Plt->getSize() - Target->PltHeaderSize + 12;
- uint32_t GotBcl = GOT + 4 - (Glink + AfterBcl);
- write32(Buf + 0, 0x3d6b0000 | ha(AfterBcl)); // addis r11,r11,1f-glink@ha
- write32(Buf + 4, 0x7c0802a6); // mflr r0
- write32(Buf + 8, 0x429f0005); // bcl 20,30,.+4
- write32(Buf + 12, 0x396b0000 | lo(AfterBcl)); // 1: addi r11,r11,1b-.glink@l
- write32(Buf + 16, 0x7d8802a6); // mflr r12
- write32(Buf + 20, 0x7c0803a6); // mtlr r0
- write32(Buf + 24, 0x7d6c5850); // sub r11,r11,r12
- write32(Buf + 28, 0x3d8c0000 | ha(GotBcl)); // addis 12,12,GOT+4-1b@ha
- if (ha(GotBcl) == ha(GotBcl + 4)) {
- write32(Buf + 32, 0x800c0000 | lo(GotBcl)); // lwz r0,r12,GOT+4-1b@l(r12)
- write32(Buf + 36,
- 0x818c0000 | lo(GotBcl + 4)); // lwz r12,r12,GOT+8-1b@l(r12)
+ uint32_t got = in.got->getVA();
+ uint32_t glink = in.plt->getVA(); // VA of .glink
+ const uint8_t *end = buf + 64;
+ if (config->isPic) {
+ uint32_t afterBcl = in.plt->getSize() - target->pltHeaderSize + 12;
+ uint32_t gotBcl = got + 4 - (glink + afterBcl);
+ write32(buf + 0, 0x3d6b0000 | ha(afterBcl)); // addis r11,r11,1f-glink@ha
+ write32(buf + 4, 0x7c0802a6); // mflr r0
+ write32(buf + 8, 0x429f0005); // bcl 20,30,.+4
+ write32(buf + 12, 0x396b0000 | lo(afterBcl)); // 1: addi r11,r11,1b-.glink@l
+ write32(buf + 16, 0x7d8802a6); // mflr r12
+ write32(buf + 20, 0x7c0803a6); // mtlr r0
+ write32(buf + 24, 0x7d6c5850); // sub r11,r11,r12
+ write32(buf + 28, 0x3d8c0000 | ha(gotBcl)); // addis 12,12,GOT+4-1b@ha
+ if (ha(gotBcl) == ha(gotBcl + 4)) {
+ write32(buf + 32, 0x800c0000 | lo(gotBcl)); // lwz r0,r12,GOT+4-1b@l(r12)
+ write32(buf + 36,
+ 0x818c0000 | lo(gotBcl + 4)); // lwz r12,r12,GOT+8-1b@l(r12)
} else {
- write32(Buf + 32, 0x840c0000 | lo(GotBcl)); // lwzu r0,r12,GOT+4-1b@l(r12)
- write32(Buf + 36, 0x818c0000 | 4); // lwz r12,r12,4(r12)
+ write32(buf + 32, 0x840c0000 | lo(gotBcl)); // lwzu r0,r12,GOT+4-1b@l(r12)
+ write32(buf + 36, 0x818c0000 | 4); // lwz r12,r12,4(r12)
}
- write32(Buf + 40, 0x7c0903a6); // mtctr 0
- write32(Buf + 44, 0x7c0b5a14); // add r0,11,11
- write32(Buf + 48, 0x7d605a14); // add r11,0,11
- write32(Buf + 52, 0x4e800420); // bctr
- Buf += 56;
+ write32(buf + 40, 0x7c0903a6); // mtctr 0
+ write32(buf + 44, 0x7c0b5a14); // add r0,11,11
+ write32(buf + 48, 0x7d605a14); // add r11,0,11
+ write32(buf + 52, 0x4e800420); // bctr
+ buf += 56;
} else {
- write32(Buf + 0, 0x3d800000 | ha(GOT + 4)); // lis r12,GOT+4@ha
- write32(Buf + 4, 0x3d6b0000 | ha(-Glink)); // addis r11,r11,-Glink@ha
- if (ha(GOT + 4) == ha(GOT + 8))
- write32(Buf + 8, 0x800c0000 | lo(GOT + 4)); // lwz r0,GOT+4@l(r12)
+ write32(buf + 0, 0x3d800000 | ha(got + 4)); // lis r12,GOT+4@ha
+ write32(buf + 4, 0x3d6b0000 | ha(-glink)); // addis r11,r11,-Glink@ha
+ if (ha(got + 4) == ha(got + 8))
+ write32(buf + 8, 0x800c0000 | lo(got + 4)); // lwz r0,GOT+4@l(r12)
else
- write32(Buf + 8, 0x840c0000 | lo(GOT + 4)); // lwzu r0,GOT+4@l(r12)
- write32(Buf + 12, 0x396b0000 | lo(-Glink)); // addi r11,r11,-Glink@l
- write32(Buf + 16, 0x7c0903a6); // mtctr r0
- write32(Buf + 20, 0x7c0b5a14); // add r0,r11,r11
- if (ha(GOT + 4) == ha(GOT + 8))
- write32(Buf + 24, 0x818c0000 | lo(GOT + 8)); // lwz r12,GOT+8@ha(r12)
+ write32(buf + 8, 0x840c0000 | lo(got + 4)); // lwzu r0,GOT+4@l(r12)
+ write32(buf + 12, 0x396b0000 | lo(-glink)); // addi r11,r11,-Glink@l
+ write32(buf + 16, 0x7c0903a6); // mtctr r0
+ write32(buf + 20, 0x7c0b5a14); // add r0,r11,r11
+ if (ha(got + 4) == ha(got + 8))
+ write32(buf + 24, 0x818c0000 | lo(got + 8)); // lwz r12,GOT+8@ha(r12)
else
- write32(Buf + 24, 0x818c0000 | 4); // lwz r12,4(r12)
- write32(Buf + 28, 0x7d605a14); // add r11,r0,r11
- write32(Buf + 32, 0x4e800420); // bctr
- Buf += 36;
+ write32(buf + 24, 0x818c0000 | 4); // lwz r12,4(r12)
+ write32(buf + 28, 0x7d605a14); // add r11,r0,r11
+ write32(buf + 32, 0x4e800420); // bctr
+ buf += 36;
}
// Pad with nop. They should not be executed.
- for (; Buf < End; Buf += 4)
- write32(Buf, 0x60000000);
+ for (; buf < end; buf += 4)
+ write32(buf, 0x60000000);
}
PPC::PPC() {
- GotRel = R_PPC_GLOB_DAT;
- NoneRel = R_PPC_NONE;
- PltRel = R_PPC_JMP_SLOT;
- RelativeRel = R_PPC_RELATIVE;
- IRelativeRel = R_PPC_IRELATIVE;
- SymbolicRel = R_PPC_ADDR32;
- GotBaseSymInGotPlt = false;
- GotHeaderEntriesNum = 3;
- GotPltHeaderEntriesNum = 0;
- PltHeaderSize = 64; // size of PLTresolve in .glink
- PltEntrySize = 4;
+ gotRel = R_PPC_GLOB_DAT;
+ noneRel = R_PPC_NONE;
+ pltRel = R_PPC_JMP_SLOT;
+ relativeRel = R_PPC_RELATIVE;
+ iRelativeRel = R_PPC_IRELATIVE;
+ symbolicRel = R_PPC_ADDR32;
+ gotBaseSymInGotPlt = false;
+ gotHeaderEntriesNum = 3;
+ gotPltHeaderEntriesNum = 0;
+ pltHeaderSize = 64; // size of PLTresolve in .glink
+ pltEntrySize = 4;
- NeedsThunks = true;
+ needsThunks = true;
- TlsModuleIndexRel = R_PPC_DTPMOD32;
- TlsOffsetRel = R_PPC_DTPREL32;
- TlsGotRel = R_PPC_TPREL32;
+ tlsModuleIndexRel = R_PPC_DTPMOD32;
+ tlsOffsetRel = R_PPC_DTPREL32;
+ tlsGotRel = R_PPC_TPREL32;
- DefaultMaxPageSize = 65536;
- DefaultImageBase = 0x10000000;
+ defaultMaxPageSize = 65536;
+ defaultImageBase = 0x10000000;
- write32(TrapInstr.data(), 0x7fe00008);
+ write32(trapInstr.data(), 0x7fe00008);
}
-void PPC::writeGotHeader(uint8_t *Buf) const {
+void PPC::writeGotHeader(uint8_t *buf) const {
// _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC
// glibc stores _dl_runtime_resolve in _GLOBAL_OFFSET_TABLE_[1],
// link_map in _GLOBAL_OFFSET_TABLE_[2].
- write32(Buf, Main->Dynamic->getVA());
+ write32(buf, mainPart->dynamic->getVA());
}
-void PPC::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+void PPC::writeGotPlt(uint8_t *buf, const Symbol &s) const {
// Address of the symbol resolver stub in .glink .
- write32(Buf, In.Plt->getVA() + 4 * S.PltIndex);
+ write32(buf, in.plt->getVA() + 4 * s.pltIndex);
}
-bool PPC::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
- if (Type != R_PPC_REL24 && Type != R_PPC_PLTREL24)
+bool PPC::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
+ if (type != R_PPC_REL24 && type != R_PPC_PLTREL24)
return false;
- if (S.isInPlt())
+ if (s.isInPlt())
return true;
- if (S.isUndefWeak())
+ if (s.isUndefWeak())
return false;
- return !(Expr == R_PC && PPC::inBranchRange(Type, BranchAddr, S.getVA()));
+ return !(expr == R_PC && PPC::inBranchRange(type, branchAddr, s.getVA()));
}
uint32_t PPC::getThunkSectionSpacing() const { return 0x2000000; }
-bool PPC::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
- uint64_t Offset = Dst - Src;
- if (Type == R_PPC_REL24 || Type == R_PPC_PLTREL24)
- return isInt<26>(Offset);
+bool PPC::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
+ uint64_t offset = dst - src;
+ if (type == R_PPC_REL24 || type == R_PPC_PLTREL24)
+ return isInt<26>(offset);
llvm_unreachable("unsupported relocation type used in branch");
}
-RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr PPC::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_PPC_DTPREL16:
case R_PPC_DTPREL16_HA:
case R_PPC_DTPREL16_HI:
@@ -231,45 +231,45 @@ RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
}
}
-RelType PPC::getDynRel(RelType Type) const {
- if (Type == R_PPC_ADDR32)
- return Type;
+RelType PPC::getDynRel(RelType type) const {
+ if (type == R_PPC_ADDR32)
+ return type;
return R_PPC_NONE;
}
-static std::pair<RelType, uint64_t> fromDTPREL(RelType Type, uint64_t Val) {
- uint64_t DTPBiasedVal = Val - 0x8000;
- switch (Type) {
+static std::pair<RelType, uint64_t> fromDTPREL(RelType type, uint64_t val) {
+ uint64_t dtpBiasedVal = val - 0x8000;
+ switch (type) {
case R_PPC_DTPREL16:
- return {R_PPC64_ADDR16, DTPBiasedVal};
+ return {R_PPC64_ADDR16, dtpBiasedVal};
case R_PPC_DTPREL16_HA:
- return {R_PPC_ADDR16_HA, DTPBiasedVal};
+ return {R_PPC_ADDR16_HA, dtpBiasedVal};
case R_PPC_DTPREL16_HI:
- return {R_PPC_ADDR16_HI, DTPBiasedVal};
+ return {R_PPC_ADDR16_HI, dtpBiasedVal};
case R_PPC_DTPREL16_LO:
- return {R_PPC_ADDR16_LO, DTPBiasedVal};
+ return {R_PPC_ADDR16_LO, dtpBiasedVal};
case R_PPC_DTPREL32:
- return {R_PPC_ADDR32, DTPBiasedVal};
+ return {R_PPC_ADDR32, dtpBiasedVal};
default:
- return {Type, Val};
+ return {type, val};
}
}
-void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- RelType NewType;
- std::tie(NewType, Val) = fromDTPREL(Type, Val);
- switch (NewType) {
+void PPC::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ RelType newType;
+ std::tie(newType, val) = fromDTPREL(type, val);
+ switch (newType) {
case R_PPC_ADDR16:
- checkIntUInt(Loc, Val, 16, Type);
- write16(Loc, Val);
+ checkIntUInt(loc, val, 16, type);
+ write16(loc, val);
break;
case R_PPC_GOT16:
case R_PPC_GOT_TLSGD16:
case R_PPC_GOT_TLSLD16:
case R_PPC_GOT_TPREL16:
case R_PPC_TPREL16:
- checkInt(Loc, Val, 16, Type);
- write16(Loc, Val);
+ checkInt(loc, val, 16, type);
+ write16(loc, val);
break;
case R_PPC_ADDR16_HA:
case R_PPC_DTPREL16_HA:
@@ -278,7 +278,7 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_PPC_GOT_TPREL16_HA:
case R_PPC_REL16_HA:
case R_PPC_TPREL16_HA:
- write16(Loc, ha(Val));
+ write16(loc, ha(val));
break;
case R_PPC_ADDR16_HI:
case R_PPC_DTPREL16_HI:
@@ -287,7 +287,7 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_PPC_GOT_TPREL16_HI:
case R_PPC_REL16_HI:
case R_PPC_TPREL16_HI:
- write16(Loc, Val >> 16);
+ write16(loc, val >> 16);
break;
case R_PPC_ADDR16_LO:
case R_PPC_DTPREL16_LO:
@@ -296,43 +296,43 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_PPC_GOT_TPREL16_LO:
case R_PPC_REL16_LO:
case R_PPC_TPREL16_LO:
- write16(Loc, Val);
+ write16(loc, val);
break;
case R_PPC_ADDR32:
case R_PPC_REL32:
- write32(Loc, Val);
+ write32(loc, val);
break;
case R_PPC_REL14: {
- uint32_t Mask = 0x0000FFFC;
- checkInt(Loc, Val, 16, Type);
- checkAlignment(Loc, Val, 4, Type);
- write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
+ uint32_t mask = 0x0000FFFC;
+ checkInt(loc, val, 16, type);
+ checkAlignment(loc, val, 4, type);
+ write32(loc, (read32(loc) & ~mask) | (val & mask));
break;
}
case R_PPC_REL24:
case R_PPC_LOCAL24PC:
case R_PPC_PLTREL24: {
- uint32_t Mask = 0x03FFFFFC;
- checkInt(Loc, Val, 26, Type);
- checkAlignment(Loc, Val, 4, Type);
- write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
+ uint32_t mask = 0x03FFFFFC;
+ checkInt(loc, val, 26, type);
+ checkAlignment(loc, val, 4, type);
+ write32(loc, (read32(loc) & ~mask) | (val & mask));
break;
}
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
-RelExpr PPC::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- if (Expr == R_RELAX_TLS_GD_TO_IE)
+RelExpr PPC::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ if (expr == R_RELAX_TLS_GD_TO_IE)
return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
- if (Expr == R_RELAX_TLS_LD_TO_LE)
+ if (expr == R_RELAX_TLS_LD_TO_LE)
return R_RELAX_TLS_LD_TO_LE_ABS;
- return Expr;
+ return expr;
}
-int PPC::getTlsGdRelaxSkip(RelType Type) const {
+int PPC::getTlsGdRelaxSkip(RelType type) const {
// A __tls_get_addr call instruction is marked with 2 relocations:
//
// R_PPC_TLSGD / R_PPC_TLSLD: marker relocation
@@ -341,84 +341,84 @@ int PPC::getTlsGdRelaxSkip(RelType Type) const {
// After the relaxation we no longer call __tls_get_addr and should skip both
// relocations to not create a false dependence on __tls_get_addr being
// defined.
- if (Type == R_PPC_TLSGD || Type == R_PPC_TLSLD)
+ if (type == R_PPC_TLSGD || type == R_PPC_TLSLD)
return 2;
return 1;
}
-void PPC::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC_GOT_TLSGD16: {
// addi rT, rA, x@got@tlsgd --> lwz rT, x@got@tprel(rA)
- uint32_t Insn = readFromHalf16(Loc);
- writeFromHalf16(Loc, 0x80000000 | (Insn & 0x03ff0000));
- relocateOne(Loc, R_PPC_GOT_TPREL16, Val);
+ uint32_t insn = readFromHalf16(loc);
+ writeFromHalf16(loc, 0x80000000 | (insn & 0x03ff0000));
+ relocateOne(loc, R_PPC_GOT_TPREL16, val);
break;
}
case R_PPC_TLSGD:
// bl __tls_get_addr(x@tldgd) --> add r3, r3, r2
- write32(Loc, 0x7c631214);
+ write32(loc, 0x7c631214);
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
}
}
-void PPC::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC_GOT_TLSGD16:
// addi r3, r31, x@got@tlsgd --> addis r3, r2, x@tprel@ha
- writeFromHalf16(Loc, 0x3c620000 | ha(Val));
+ writeFromHalf16(loc, 0x3c620000 | ha(val));
break;
case R_PPC_TLSGD:
// bl __tls_get_addr(x@tldgd) --> add r3, r3, x@tprel@l
- write32(Loc, 0x38630000 | lo(Val));
+ write32(loc, 0x38630000 | lo(val));
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
}
}
-void PPC::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC_GOT_TLSLD16:
// addi r3, rA, x@got@tlsgd --> addis r3, r2, 0
- writeFromHalf16(Loc, 0x3c620000);
+ writeFromHalf16(loc, 0x3c620000);
break;
case R_PPC_TLSLD:
// r3+x@dtprel computes r3+x-0x8000, while we want it to compute r3+x@tprel
// = r3+x-0x7000, so add 4096 to r3.
// bl __tls_get_addr(x@tlsld) --> addi r3, r3, 4096
- write32(Loc, 0x38631000);
+ write32(loc, 0x38631000);
break;
case R_PPC_DTPREL16:
case R_PPC_DTPREL16_HA:
case R_PPC_DTPREL16_HI:
case R_PPC_DTPREL16_LO:
- relocateOne(Loc, Type, Val);
+ relocateOne(loc, type, val);
break;
default:
llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
}
}
-void PPC::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC_GOT_TPREL16: {
// lwz rT, x@got@tprel(rA) --> addis rT, r2, x@tprel@ha
- uint32_t RT = readFromHalf16(Loc) & 0x03e00000;
- writeFromHalf16(Loc, 0x3c020000 | RT | ha(Val));
+ uint32_t rt = readFromHalf16(loc) & 0x03e00000;
+ writeFromHalf16(loc, 0x3c020000 | rt | ha(val));
break;
}
case R_PPC_TLS: {
- uint32_t Insn = read32(Loc);
- if (Insn >> 26 != 31)
+ uint32_t insn = read32(loc);
+ if (insn >> 26 != 31)
error("unrecognized instruction for IE to LE R_PPC_TLS");
// addi rT, rT, x@tls --> addi rT, rT, x@tprel@l
- uint32_t DFormOp = getPPCDFormOp((read32(Loc) & 0x000007fe) >> 1);
- if (DFormOp == 0)
+ uint32_t dFormOp = getPPCDFormOp((read32(loc) & 0x000007fe) >> 1);
+ if (dFormOp == 0)
error("unrecognized instruction for IE to LE R_PPC_TLS");
- write32(Loc, (DFormOp << 26) | (Insn & 0x03ff0000) | lo(Val));
+ write32(loc, (dFormOp << 26) | (insn & 0x03ff0000) | lo(val));
break;
}
default:
@@ -427,6 +427,6 @@ void PPC::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
}
TargetInfo *elf::getPPCTargetInfo() {
- static PPC Target;
- return &Target;
+ static PPC target;
+ return &target;
}
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 4af935e8a80..96b829101f8 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -19,8 +19,8 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-static uint64_t PPC64TocOffset = 0x8000;
-static uint64_t DynamicThreadPointerOffset = 0x8000;
+static uint64_t ppc64TocOffset = 0x8000;
+static uint64_t dynamicThreadPointerOffset = 0x8000;
// The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
// instructions that can be used as part of the initial exec TLS sequence.
@@ -64,16 +64,16 @@ uint64_t elf::getPPC64TocBase() {
// TOC starts where the first of these sections starts. We always create a
// .got when we see a relocation that uses it, so for us the start is always
// the .got.
- uint64_t TocVA = In.Got->getVA();
+ uint64_t tocVA = in.got->getVA();
// Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
// thus permitting a full 64 Kbytes segment. Note that the glibc startup
// code (crt1.o) assumes that you can get from the TOC base to the
// start of the .toc section with only a single (signed) 16-bit relocation.
- return TocVA + PPC64TocOffset;
+ return tocVA + ppc64TocOffset;
}
-unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
+unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
// The offset is encoded into the 3 most significant bits of the st_other
// field, with some special values described in section 3.4.1 of the ABI:
// 0 --> Zero offset between the GEP and LEP, and the function does NOT use
@@ -85,29 +85,29 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
// 2 --> 2^2 = 4 bytes --> 1 instruction.
// 6 --> 2^6 = 64 bytes --> 16 instructions.
// 7 --> Reserved.
- uint8_t GepToLep = (StOther >> 5) & 7;
- if (GepToLep < 2)
+ uint8_t gepToLep = (stOther >> 5) & 7;
+ if (gepToLep < 2)
return 0;
// The value encoded in the st_other bits is the
// log-base-2(offset).
- if (GepToLep < 7)
- return 1 << GepToLep;
+ if (gepToLep < 7)
+ return 1 << gepToLep;
error("reserved value of 7 in the 3 most-significant-bits of st_other");
return 0;
}
-bool elf::isPPC64SmallCodeModelTocReloc(RelType Type) {
+bool elf::isPPC64SmallCodeModelTocReloc(RelType type) {
// The only small code model relocations that access the .toc section.
- return Type == R_PPC64_TOC16 || Type == R_PPC64_TOC16_DS;
+ return type == R_PPC64_TOC16 || type == R_PPC64_TOC16_DS;
}
// Find the R_PPC64_ADDR64 in .rela.toc with matching offset.
template <typename ELFT>
static std::pair<Defined *, int64_t>
-getRelaTocSymAndAddend(InputSectionBase *TocSec, uint64_t Offset) {
- if (TocSec->NumRelocations == 0)
+getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
+ if (tocSec->numRelocations == 0)
return {};
// .rela.toc contains exclusively R_PPC64_ADDR64 relocations sorted by
@@ -119,16 +119,16 @@ getRelaTocSymAndAddend(InputSectionBase *TocSec, uint64_t Offset) {
// points to a relocation with larger r_offset. Do a linear probe then.
// Constants are extremely uncommon in .toc and the extra number of array
// accesses can be seen as a small constant.
- ArrayRef<typename ELFT::Rela> Relas = TocSec->template relas<ELFT>();
- uint64_t Index = std::min<uint64_t>(Offset / 8, Relas.size() - 1);
+ ArrayRef<typename ELFT::Rela> relas = tocSec->template relas<ELFT>();
+ uint64_t index = std::min<uint64_t>(offset / 8, relas.size() - 1);
for (;;) {
- if (Relas[Index].r_offset == Offset) {
- Symbol &Sym = TocSec->getFile<ELFT>()->getRelocTargetSym(Relas[Index]);
- return {dyn_cast<Defined>(&Sym), getAddend<ELFT>(Relas[Index])};
+ if (relas[index].r_offset == offset) {
+ Symbol &sym = tocSec->getFile<ELFT>()->getRelocTargetSym(relas[index]);
+ return {dyn_cast<Defined>(&sym), getAddend<ELFT>(relas[index])};
}
- if (Relas[Index].r_offset < Offset || Index == 0)
+ if (relas[index].r_offset < offset || index == 0)
break;
- --Index;
+ --index;
}
return {};
}
@@ -153,35 +153,35 @@ getRelaTocSymAndAddend(InputSectionBase *TocSec, uint64_t Offset) {
// ld/lwa 3, 0(3) # load the value from the address
//
// Returns true if the relaxation is performed.
-bool elf::tryRelaxPPC64TocIndirection(RelType Type, const Relocation &Rel,
- uint8_t *BufLoc) {
- assert(Config->TocOptimize);
- if (Rel.Addend < 0)
+bool elf::tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
+ uint8_t *bufLoc) {
+ assert(config->tocOptimize);
+ if (rel.addend < 0)
return false;
// If the symbol is not the .toc section, this isn't a toc-indirection.
- Defined *DefSym = dyn_cast<Defined>(Rel.Sym);
- if (!DefSym || !DefSym->isSection() || DefSym->Section->Name != ".toc")
+ Defined *defSym = dyn_cast<Defined>(rel.sym);
+ if (!defSym || !defSym->isSection() || defSym->section->name != ".toc")
return false;
- Defined *D;
- int64_t Addend;
- auto *TocISB = cast<InputSectionBase>(DefSym->Section);
- std::tie(D, Addend) =
- Config->IsLE ? getRelaTocSymAndAddend<ELF64LE>(TocISB, Rel.Addend)
- : getRelaTocSymAndAddend<ELF64BE>(TocISB, Rel.Addend);
+ Defined *d;
+ int64_t addend;
+ auto *tocISB = cast<InputSectionBase>(defSym->section);
+ std::tie(d, addend) =
+ config->isLE ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend)
+ : getRelaTocSymAndAddend<ELF64BE>(tocISB, rel.addend);
// Only non-preemptable defined symbols can be relaxed.
- if (!D || D->IsPreemptible)
+ if (!d || d->isPreemptible)
return false;
// Two instructions can materialize a 32-bit signed offset from the toc base.
- uint64_t TocRelative = D->getVA(Addend) - getPPC64TocBase();
- if (!isInt<32>(TocRelative))
+ uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase();
+ if (!isInt<32>(tocRelative))
return false;
// Add PPC64TocOffset that will be subtracted by relocateOne().
- Target->relaxGot(BufLoc, Type, TocRelative + PPC64TocOffset);
+ target->relaxGot(bufLoc, type, tocRelative + ppc64TocOffset);
return true;
}
@@ -189,30 +189,30 @@ namespace {
class PPC64 final : public TargetInfo {
public:
PPC64();
- int getTlsGdRelaxSkip(RelType Type) const override;
+ int getTlsGdRelaxSkip(RelType type) const override;
uint32_t calcEFlags() const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void writeGotHeader(uint8_t *Buf) const override;
- bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ void writeGotHeader(uint8_t *buf) const override;
+ bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const override;
uint32_t getThunkSectionSpacing() const override;
- bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
- RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const override;
- void relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
-
- bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const override;
+ bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
+ RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const override;
+ void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+
+ bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const override;
};
} // namespace
@@ -220,19 +220,19 @@ public:
// #higher(value), #highera(value), #highest(value), and #highesta(value)
// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
// document.
-static uint16_t lo(uint64_t V) { return V; }
-static uint16_t hi(uint64_t V) { return V >> 16; }
-static uint16_t ha(uint64_t V) { return (V + 0x8000) >> 16; }
-static uint16_t higher(uint64_t V) { return V >> 32; }
-static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; }
-static uint16_t highest(uint64_t V) { return V >> 48; }
-static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; }
+static uint16_t lo(uint64_t v) { return v; }
+static uint16_t hi(uint64_t v) { return v >> 16; }
+static uint16_t ha(uint64_t v) { return (v + 0x8000) >> 16; }
+static uint16_t higher(uint64_t v) { return v >> 32; }
+static uint16_t highera(uint64_t v) { return (v + 0x8000) >> 32; }
+static uint16_t highest(uint64_t v) { return v >> 48; }
+static uint16_t highesta(uint64_t v) { return (v + 0x8000) >> 48; }
// Extracts the 'PO' field of an instruction encoding.
-static uint8_t getPrimaryOpCode(uint32_t Encoding) { return (Encoding >> 26); }
+static uint8_t getPrimaryOpCode(uint32_t encoding) { return (encoding >> 26); }
-static bool isDQFormInstruction(uint32_t Encoding) {
- switch (getPrimaryOpCode(Encoding)) {
+static bool isDQFormInstruction(uint32_t encoding) {
+ switch (getPrimaryOpCode(encoding)) {
default:
return false;
case 56:
@@ -242,12 +242,12 @@ static bool isDQFormInstruction(uint32_t Encoding) {
// There are both DS and DQ instruction forms with this primary opcode.
// Namely `lxv` and `stxv` are the DQ-forms that use it.
// The DS 'XO' bits being set to 01 is restricted to DQ form.
- return (Encoding & 3) == 0x1;
+ return (encoding & 3) == 0x1;
}
}
-static bool isInstructionUpdateForm(uint32_t Encoding) {
- switch (getPrimaryOpCode(Encoding)) {
+static bool isInstructionUpdateForm(uint32_t encoding) {
+ switch (getPrimaryOpCode(encoding)) {
default:
return false;
case LBZU:
@@ -266,7 +266,7 @@ static bool isInstructionUpdateForm(uint32_t Encoding) {
// between LD/LDU/LWA
case LD:
case STD:
- return (Encoding & 3) == 1;
+ return (encoding & 3) == 1;
}
}
@@ -275,38 +275,38 @@ static bool isInstructionUpdateForm(uint32_t Encoding) {
// pointer is pointing into the middle of the word we want to extract, and on
// little-endian it is pointing to the start of the word. These 2 helpers are to
// simplify reading and writing in that context.
-static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) {
- write32(Config->IsLE ? Loc : Loc - 2, Insn);
+static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
+ write32(config->isLE ? loc : loc - 2, insn);
}
-static uint32_t readFromHalf16(const uint8_t *Loc) {
- return read32(Config->IsLE ? Loc : Loc - 2);
+static uint32_t readFromHalf16(const uint8_t *loc) {
+ return read32(config->isLE ? loc : loc - 2);
}
PPC64::PPC64() {
- GotRel = R_PPC64_GLOB_DAT;
- NoneRel = R_PPC64_NONE;
- PltRel = R_PPC64_JMP_SLOT;
- RelativeRel = R_PPC64_RELATIVE;
- IRelativeRel = R_PPC64_IRELATIVE;
- SymbolicRel = R_PPC64_ADDR64;
- PltEntrySize = 4;
- GotBaseSymInGotPlt = false;
- GotHeaderEntriesNum = 1;
- GotPltHeaderEntriesNum = 2;
- PltHeaderSize = 60;
- NeedsThunks = true;
-
- TlsModuleIndexRel = R_PPC64_DTPMOD64;
- TlsOffsetRel = R_PPC64_DTPREL64;
-
- TlsGotRel = R_PPC64_TPREL64;
-
- NeedsMoreStackNonSplit = false;
+ gotRel = R_PPC64_GLOB_DAT;
+ noneRel = R_PPC64_NONE;
+ pltRel = R_PPC64_JMP_SLOT;
+ relativeRel = R_PPC64_RELATIVE;
+ iRelativeRel = R_PPC64_IRELATIVE;
+ symbolicRel = R_PPC64_ADDR64;
+ pltEntrySize = 4;
+ gotBaseSymInGotPlt = false;
+ gotHeaderEntriesNum = 1;
+ gotPltHeaderEntriesNum = 2;
+ pltHeaderSize = 60;
+ needsThunks = true;
+
+ tlsModuleIndexRel = R_PPC64_DTPMOD64;
+ tlsOffsetRel = R_PPC64_DTPREL64;
+
+ tlsGotRel = R_PPC64_TPREL64;
+
+ needsMoreStackNonSplit = false;
// We need 64K pages (at least under glibc/Linux, the loader won't
// set different permissions on a finer granularity than that).
- DefaultMaxPageSize = 65536;
+ defaultMaxPageSize = 65536;
// The PPC64 ELF ABI v1 spec, says:
//
@@ -316,12 +316,12 @@ PPC64::PPC64() {
//
// And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
// use 0x10000000 as the starting address.
- DefaultImageBase = 0x10000000;
+ defaultImageBase = 0x10000000;
- write32(TrapInstr.data(), 0x7fe00008);
+ write32(trapInstr.data(), 0x7fe00008);
}
-int PPC64::getTlsGdRelaxSkip(RelType Type) const {
+int PPC64::getTlsGdRelaxSkip(RelType type) const {
// A __tls_get_addr call instruction is marked with 2 relocations:
//
// R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
@@ -330,44 +330,44 @@ int PPC64::getTlsGdRelaxSkip(RelType Type) const {
// After the relaxation we no longer call __tls_get_addr and should skip both
// relocations to not create a false dependence on __tls_get_addr being
// defined.
- if (Type == R_PPC64_TLSGD || Type == R_PPC64_TLSLD)
+ if (type == R_PPC64_TLSGD || type == R_PPC64_TLSLD)
return 2;
return 1;
}
-static uint32_t getEFlags(InputFile *File) {
- if (Config->EKind == ELF64BEKind)
- return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
- return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags;
+static uint32_t getEFlags(InputFile *file) {
+ if (config->ekind == ELF64BEKind)
+ return cast<ObjFile<ELF64BE>>(file)->getObj().getHeader()->e_flags;
+ return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader()->e_flags;
}
// This file implements v2 ABI. This function makes sure that all
// object files have v2 or an unspecified version as an ABI version.
uint32_t PPC64::calcEFlags() const {
- for (InputFile *F : ObjectFiles) {
- uint32_t Flag = getEFlags(F);
- if (Flag == 1)
- error(toString(F) + ": ABI version 1 is not supported");
- else if (Flag > 2)
- error(toString(F) + ": unrecognized e_flags: " + Twine(Flag));
+ for (InputFile *f : objectFiles) {
+ uint32_t flag = getEFlags(f);
+ if (flag == 1)
+ error(toString(f) + ": ABI version 1 is not supported");
+ else if (flag > 2)
+ error(toString(f) + ": unrecognized e_flags: " + Twine(flag));
}
return 2;
}
-void PPC64::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC64_TOC16_HA:
// Convert "addis reg, 2, .LC0@toc@h" to "addis reg, 2, var@toc@h" or "nop".
- relocateOne(Loc, Type, Val);
+ relocateOne(loc, type, val);
break;
case R_PPC64_TOC16_LO_DS: {
// Convert "ld reg, .LC0@toc@l(reg)" to "addi reg, reg, var@toc@l" or
// "addi reg, 2, var@toc".
- uint32_t Insn = readFromHalf16(Loc);
- if (getPrimaryOpCode(Insn) != LD)
+ uint32_t insn = readFromHalf16(loc);
+ if (getPrimaryOpCode(insn) != LD)
error("expected a 'ld' for got-indirect to toc-relative relaxing");
- writeFromHalf16(Loc, (Insn & 0x03ffffff) | 0x38000000);
- relocateOne(Loc, R_PPC64_TOC16_LO, Val);
+ writeFromHalf16(loc, (insn & 0x03ffffff) | 0x38000000);
+ relocateOne(loc, R_PPC64_TOC16_LO, val);
break;
}
default:
@@ -375,7 +375,7 @@ void PPC64::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
}
}
-void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void PPC64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
// Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement.
// The general dynamic code sequence for a global `x` will look like:
// Instruction Relocation Symbol
@@ -391,30 +391,30 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// bl __tls_get_addr(x@tlsgd) into nop
// nop into addi r3, r3, x@tprel@l
- switch (Type) {
+ switch (type) {
case R_PPC64_GOT_TLSGD16_HA:
- writeFromHalf16(Loc, 0x60000000); // nop
+ writeFromHalf16(loc, 0x60000000); // nop
break;
case R_PPC64_GOT_TLSGD16:
case R_PPC64_GOT_TLSGD16_LO:
- writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
- relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
+ writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13
+ relocateOne(loc, R_PPC64_TPREL16_HA, val);
break;
case R_PPC64_TLSGD:
- write32(Loc, 0x60000000); // nop
- write32(Loc + 4, 0x38630000); // addi r3, r3
+ write32(loc, 0x60000000); // nop
+ write32(loc + 4, 0x38630000); // addi r3, r3
// Since we are relocating a half16 type relocation and Loc + 4 points to
// the start of an instruction we need to advance the buffer by an extra
// 2 bytes on BE.
- relocateOne(Loc + 4 + (Config->EKind == ELF64BEKind ? 2 : 0),
- R_PPC64_TPREL16_LO, Val);
+ relocateOne(loc + 4 + (config->ekind == ELF64BEKind ? 2 : 0),
+ R_PPC64_TPREL16_LO, val);
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
}
}
-void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
// Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
// The local dynamic code sequence for a global `x` will look like:
// Instruction Relocation Symbol
@@ -430,16 +430,16 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// bl __tls_get_addr(x@tlsgd) into nop
// nop into addi r3, r3, 4096
- switch (Type) {
+ switch (type) {
case R_PPC64_GOT_TLSLD16_HA:
- writeFromHalf16(Loc, 0x60000000); // nop
+ writeFromHalf16(loc, 0x60000000); // nop
break;
case R_PPC64_GOT_TLSLD16_LO:
- writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
+ writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13, 0
break;
case R_PPC64_TLSLD:
- write32(Loc, 0x60000000); // nop
- write32(Loc + 4, 0x38631000); // addi r3, r3, 4096
+ write32(loc, 0x60000000); // nop
+ write32(loc + 4, 0x38631000); // addi r3, r3, 4096
break;
case R_PPC64_DTPREL16:
case R_PPC64_DTPREL16_HA:
@@ -447,15 +447,15 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_PPC64_DTPREL16_DS:
case R_PPC64_DTPREL16_LO:
case R_PPC64_DTPREL16_LO_DS:
- relocateOne(Loc, Type, Val);
+ relocateOne(loc, type, val);
break;
default:
llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
}
}
-unsigned elf::getPPCDFormOp(unsigned SecondaryOp) {
- switch (SecondaryOp) {
+unsigned elf::getPPCDFormOp(unsigned secondaryOp) {
+ switch (secondaryOp) {
case LBZX:
return LBZ;
case LHZX:
@@ -479,7 +479,7 @@ unsigned elf::getPPCDFormOp(unsigned SecondaryOp) {
}
}
-void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
// The initial exec code sequence for a global `x` will look like:
// Instruction Relocation Symbol
// addis r9, r2, x@got@tprel@ha R_PPC64_GOT_TPREL16_HA x
@@ -499,28 +499,28 @@ void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// instruction, if we are accessing memory it will use any of the X-form
// indexed load or store instructions.
- unsigned Offset = (Config->EKind == ELF64BEKind) ? 2 : 0;
- switch (Type) {
+ unsigned offset = (config->ekind == ELF64BEKind) ? 2 : 0;
+ switch (type) {
case R_PPC64_GOT_TPREL16_HA:
- write32(Loc - Offset, 0x60000000); // nop
+ write32(loc - offset, 0x60000000); // nop
break;
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_DS: {
- uint32_t RegNo = read32(Loc - Offset) & 0x03E00000; // bits 6-10
- write32(Loc - Offset, 0x3C0D0000 | RegNo); // addis RegNo, r13
- relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
+ uint32_t regNo = read32(loc - offset) & 0x03E00000; // bits 6-10
+ write32(loc - offset, 0x3C0D0000 | regNo); // addis RegNo, r13
+ relocateOne(loc, R_PPC64_TPREL16_HA, val);
break;
}
case R_PPC64_TLS: {
- uint32_t PrimaryOp = getPrimaryOpCode(read32(Loc));
- if (PrimaryOp != 31)
+ uint32_t primaryOp = getPrimaryOpCode(read32(loc));
+ if (primaryOp != 31)
error("unrecognized instruction for IE to LE R_PPC64_TLS");
- uint32_t SecondaryOp = (read32(Loc) & 0x000007FE) >> 1; // bits 21-30
- uint32_t DFormOp = getPPCDFormOp(SecondaryOp);
- if (DFormOp == 0)
+ uint32_t secondaryOp = (read32(loc) & 0x000007FE) >> 1; // bits 21-30
+ uint32_t dFormOp = getPPCDFormOp(secondaryOp);
+ if (dFormOp == 0)
error("unrecognized instruction for IE to LE R_PPC64_TLS");
- write32(Loc, ((DFormOp << 26) | (read32(Loc) & 0x03FFFFFF)));
- relocateOne(Loc + Offset, R_PPC64_TPREL16_LO, Val);
+ write32(loc, ((dFormOp << 26) | (read32(loc) & 0x03FFFFFF)));
+ relocateOne(loc + offset, R_PPC64_TPREL16_LO, val);
break;
}
default:
@@ -529,9 +529,9 @@ void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
}
}
-RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_PPC64_GOT16:
case R_PPC64_GOT16_DS:
case R_PPC64_GOT16_HA:
@@ -546,7 +546,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
return R_GOTREL;
case R_PPC64_TOC16_HA:
case R_PPC64_TOC16_LO_DS:
- return Config->TocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL;
+ return config->tocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL;
case R_PPC64_TOC:
return R_PPC64_TOCBASE;
case R_PPC64_REL14:
@@ -611,121 +611,121 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
}
}
-RelType PPC64::getDynRel(RelType Type) const {
- if (Type == R_PPC64_ADDR64 || Type == R_PPC64_TOC)
+RelType PPC64::getDynRel(RelType type) const {
+ if (type == R_PPC64_ADDR64 || type == R_PPC64_TOC)
return R_PPC64_ADDR64;
return R_PPC64_NONE;
}
-void PPC64::writeGotHeader(uint8_t *Buf) const {
- write64(Buf, getPPC64TocBase());
+void PPC64::writeGotHeader(uint8_t *buf) const {
+ write64(buf, getPPC64TocBase());
}
-void PPC64::writePltHeader(uint8_t *Buf) const {
+void PPC64::writePltHeader(uint8_t *buf) const {
// The generic resolver stub goes first.
- write32(Buf + 0, 0x7c0802a6); // mflr r0
- write32(Buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
- write32(Buf + 8, 0x7d6802a6); // mflr r11
- write32(Buf + 12, 0x7c0803a6); // mtlr r0
- write32(Buf + 16, 0x7d8b6050); // subf r12, r11, r12
- write32(Buf + 20, 0x380cffcc); // subi r0,r12,52
- write32(Buf + 24, 0x7800f082); // srdi r0,r0,62,2
- write32(Buf + 28, 0xe98b002c); // ld r12,44(r11)
- write32(Buf + 32, 0x7d6c5a14); // add r11,r12,r11
- write32(Buf + 36, 0xe98b0000); // ld r12,0(r11)
- write32(Buf + 40, 0xe96b0008); // ld r11,8(r11)
- write32(Buf + 44, 0x7d8903a6); // mtctr r12
- write32(Buf + 48, 0x4e800420); // bctr
+ write32(buf + 0, 0x7c0802a6); // mflr r0
+ write32(buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
+ write32(buf + 8, 0x7d6802a6); // mflr r11
+ write32(buf + 12, 0x7c0803a6); // mtlr r0
+ write32(buf + 16, 0x7d8b6050); // subf r12, r11, r12
+ write32(buf + 20, 0x380cffcc); // subi r0,r12,52
+ write32(buf + 24, 0x7800f082); // srdi r0,r0,62,2
+ write32(buf + 28, 0xe98b002c); // ld r12,44(r11)
+ write32(buf + 32, 0x7d6c5a14); // add r11,r12,r11
+ write32(buf + 36, 0xe98b0000); // ld r12,0(r11)
+ write32(buf + 40, 0xe96b0008); // ld r11,8(r11)
+ write32(buf + 44, 0x7d8903a6); // mtctr r12
+ write32(buf + 48, 0x4e800420); // bctr
// The 'bcl' instruction will set the link register to the address of the
// following instruction ('mflr r11'). Here we store the offset from that
// instruction to the first entry in the GotPlt section.
- int64_t GotPltOffset = In.GotPlt->getVA() - (In.Plt->getVA() + 8);
- write64(Buf + 52, GotPltOffset);
+ int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8);
+ write64(buf + 52, gotPltOffset);
}
-void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- int32_t Offset = PltHeaderSize + Index * PltEntrySize;
+void PPC64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ int32_t offset = pltHeaderSize + index * pltEntrySize;
// bl __glink_PLTresolve
- write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
+ write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc));
}
-static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
+static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {
// Relocations relative to the toc-base need to be adjusted by the Toc offset.
- uint64_t TocBiasedVal = Val - PPC64TocOffset;
+ uint64_t tocBiasedVal = val - ppc64TocOffset;
// Relocations relative to dtv[dtpmod] need to be adjusted by the DTP offset.
- uint64_t DTPBiasedVal = Val - DynamicThreadPointerOffset;
+ uint64_t dtpBiasedVal = val - dynamicThreadPointerOffset;
- switch (Type) {
+ switch (type) {
// TOC biased relocation.
case R_PPC64_GOT16:
case R_PPC64_GOT_TLSGD16:
case R_PPC64_GOT_TLSLD16:
case R_PPC64_TOC16:
- return {R_PPC64_ADDR16, TocBiasedVal};
+ return {R_PPC64_ADDR16, tocBiasedVal};
case R_PPC64_GOT16_DS:
case R_PPC64_TOC16_DS:
case R_PPC64_GOT_TPREL16_DS:
case R_PPC64_GOT_DTPREL16_DS:
- return {R_PPC64_ADDR16_DS, TocBiasedVal};
+ return {R_PPC64_ADDR16_DS, tocBiasedVal};
case R_PPC64_GOT16_HA:
case R_PPC64_GOT_TLSGD16_HA:
case R_PPC64_GOT_TLSLD16_HA:
case R_PPC64_GOT_TPREL16_HA:
case R_PPC64_GOT_DTPREL16_HA:
case R_PPC64_TOC16_HA:
- return {R_PPC64_ADDR16_HA, TocBiasedVal};
+ return {R_PPC64_ADDR16_HA, tocBiasedVal};
case R_PPC64_GOT16_HI:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSLD16_HI:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_TOC16_HI:
- return {R_PPC64_ADDR16_HI, TocBiasedVal};
+ return {R_PPC64_ADDR16_HI, tocBiasedVal};
case R_PPC64_GOT16_LO:
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_TOC16_LO:
- return {R_PPC64_ADDR16_LO, TocBiasedVal};
+ return {R_PPC64_ADDR16_LO, tocBiasedVal};
case R_PPC64_GOT16_LO_DS:
case R_PPC64_TOC16_LO_DS:
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_DTPREL16_LO_DS:
- return {R_PPC64_ADDR16_LO_DS, TocBiasedVal};
+ return {R_PPC64_ADDR16_LO_DS, tocBiasedVal};
// Dynamic Thread pointer biased relocation types.
case R_PPC64_DTPREL16:
- return {R_PPC64_ADDR16, DTPBiasedVal};
+ return {R_PPC64_ADDR16, dtpBiasedVal};
case R_PPC64_DTPREL16_DS:
- return {R_PPC64_ADDR16_DS, DTPBiasedVal};
+ return {R_PPC64_ADDR16_DS, dtpBiasedVal};
case R_PPC64_DTPREL16_HA:
- return {R_PPC64_ADDR16_HA, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HA, dtpBiasedVal};
case R_PPC64_DTPREL16_HI:
- return {R_PPC64_ADDR16_HI, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HI, dtpBiasedVal};
case R_PPC64_DTPREL16_HIGHER:
- return {R_PPC64_ADDR16_HIGHER, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HIGHER, dtpBiasedVal};
case R_PPC64_DTPREL16_HIGHERA:
- return {R_PPC64_ADDR16_HIGHERA, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HIGHERA, dtpBiasedVal};
case R_PPC64_DTPREL16_HIGHEST:
- return {R_PPC64_ADDR16_HIGHEST, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HIGHEST, dtpBiasedVal};
case R_PPC64_DTPREL16_HIGHESTA:
- return {R_PPC64_ADDR16_HIGHESTA, DTPBiasedVal};
+ return {R_PPC64_ADDR16_HIGHESTA, dtpBiasedVal};
case R_PPC64_DTPREL16_LO:
- return {R_PPC64_ADDR16_LO, DTPBiasedVal};
+ return {R_PPC64_ADDR16_LO, dtpBiasedVal};
case R_PPC64_DTPREL16_LO_DS:
- return {R_PPC64_ADDR16_LO_DS, DTPBiasedVal};
+ return {R_PPC64_ADDR16_LO_DS, dtpBiasedVal};
case R_PPC64_DTPREL64:
- return {R_PPC64_ADDR64, DTPBiasedVal};
+ return {R_PPC64_ADDR64, dtpBiasedVal};
default:
- return {Type, Val};
+ return {type, val};
}
}
-static bool isTocOptType(RelType Type) {
- switch (Type) {
+static bool isTocOptType(RelType type) {
+ switch (type) {
case R_PPC64_GOT16_HA:
case R_PPC64_GOT16_LO_DS:
case R_PPC64_TOC16_HA:
@@ -737,69 +737,69 @@ static bool isTocOptType(RelType Type) {
}
}
-void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void PPC64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
// We need to save the original relocation type to use in diagnostics, and
// use the original type to determine if we should toc-optimize the
// instructions being relocated.
- RelType OriginalType = Type;
- bool ShouldTocOptimize = isTocOptType(Type);
+ RelType originalType = type;
+ bool shouldTocOptimize = isTocOptType(type);
// For dynamic thread pointer relative, toc-relative, and got-indirect
// relocations, proceed in terms of the corresponding ADDR16 relocation type.
- std::tie(Type, Val) = toAddr16Rel(Type, Val);
+ std::tie(type, val) = toAddr16Rel(type, val);
- switch (Type) {
+ switch (type) {
case R_PPC64_ADDR14: {
- checkAlignment(Loc, Val, 4, Type);
+ checkAlignment(loc, val, 4, type);
// Preserve the AA/LK bits in the branch instruction
- uint8_t AALK = Loc[3];
- write16(Loc + 2, (AALK & 3) | (Val & 0xfffc));
+ uint8_t aalk = loc[3];
+ write16(loc + 2, (aalk & 3) | (val & 0xfffc));
break;
}
case R_PPC64_ADDR16:
- checkIntUInt(Loc, Val, 16, OriginalType);
- write16(Loc, Val);
+ checkIntUInt(loc, val, 16, originalType);
+ write16(loc, val);
break;
case R_PPC64_ADDR32:
- checkIntUInt(Loc, Val, 32, OriginalType);
- write32(Loc, Val);
+ checkIntUInt(loc, val, 32, originalType);
+ write32(loc, val);
break;
case R_PPC64_ADDR16_DS:
case R_PPC64_TPREL16_DS: {
- checkInt(Loc, Val, 16, OriginalType);
+ checkInt(loc, val, 16, originalType);
// DQ-form instructions use bits 28-31 as part of the instruction encoding
// DS-form instructions only use bits 30-31.
- uint16_t Mask = isDQFormInstruction(readFromHalf16(Loc)) ? 0xf : 0x3;
- checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
- write16(Loc, (read16(Loc) & Mask) | lo(Val));
+ uint16_t mask = isDQFormInstruction(readFromHalf16(loc)) ? 0xf : 0x3;
+ checkAlignment(loc, lo(val), mask + 1, originalType);
+ write16(loc, (read16(loc) & mask) | lo(val));
} break;
case R_PPC64_ADDR16_HA:
case R_PPC64_REL16_HA:
case R_PPC64_TPREL16_HA:
- if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
- writeFromHalf16(Loc, 0x60000000);
+ if (config->tocOptimize && shouldTocOptimize && ha(val) == 0)
+ writeFromHalf16(loc, 0x60000000);
else
- write16(Loc, ha(Val));
+ write16(loc, ha(val));
break;
case R_PPC64_ADDR16_HI:
case R_PPC64_REL16_HI:
case R_PPC64_TPREL16_HI:
- write16(Loc, hi(Val));
+ write16(loc, hi(val));
break;
case R_PPC64_ADDR16_HIGHER:
case R_PPC64_TPREL16_HIGHER:
- write16(Loc, higher(Val));
+ write16(loc, higher(val));
break;
case R_PPC64_ADDR16_HIGHERA:
case R_PPC64_TPREL16_HIGHERA:
- write16(Loc, highera(Val));
+ write16(loc, highera(val));
break;
case R_PPC64_ADDR16_HIGHEST:
case R_PPC64_TPREL16_HIGHEST:
- write16(Loc, highest(Val));
+ write16(loc, highest(val));
break;
case R_PPC64_ADDR16_HIGHESTA:
case R_PPC64_TPREL16_HIGHESTA:
- write16(Loc, highesta(Val));
+ write16(loc, highesta(val));
break;
case R_PPC64_ADDR16_LO:
case R_PPC64_REL16_LO:
@@ -807,93 +807,93 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the
// toc-pointer register r2, as the base register.
- if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
- uint32_t Insn = readFromHalf16(Loc);
- if (isInstructionUpdateForm(Insn))
- error(getErrorLocation(Loc) +
+ if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
+ uint32_t insn = readFromHalf16(loc);
+ if (isInstructionUpdateForm(insn))
+ error(getErrorLocation(loc) +
"can't toc-optimize an update instruction: 0x" +
- utohexstr(Insn));
- writeFromHalf16(Loc, (Insn & 0xffe00000) | 0x00020000 | lo(Val));
+ utohexstr(insn));
+ writeFromHalf16(loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
} else {
- write16(Loc, lo(Val));
+ write16(loc, lo(val));
}
break;
case R_PPC64_ADDR16_LO_DS:
case R_PPC64_TPREL16_LO_DS: {
// DQ-form instructions use bits 28-31 as part of the instruction encoding
// DS-form instructions only use bits 30-31.
- uint32_t Insn = readFromHalf16(Loc);
- uint16_t Mask = isDQFormInstruction(Insn) ? 0xf : 0x3;
- checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
- if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
+ uint32_t insn = readFromHalf16(loc);
+ uint16_t mask = isDQFormInstruction(insn) ? 0xf : 0x3;
+ checkAlignment(loc, lo(val), mask + 1, originalType);
+ if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the toc
// pointer register r2, as the base register.
- if (isInstructionUpdateForm(Insn))
- error(getErrorLocation(Loc) +
+ if (isInstructionUpdateForm(insn))
+ error(getErrorLocation(loc) +
"Can't toc-optimize an update instruction: 0x" +
- Twine::utohexstr(Insn));
- Insn &= 0xffe00000 | Mask;
- writeFromHalf16(Loc, Insn | 0x00020000 | lo(Val));
+ Twine::utohexstr(insn));
+ insn &= 0xffe00000 | mask;
+ writeFromHalf16(loc, insn | 0x00020000 | lo(val));
} else {
- write16(Loc, (read16(Loc) & Mask) | lo(Val));
+ write16(loc, (read16(loc) & mask) | lo(val));
}
} break;
case R_PPC64_TPREL16:
- checkInt(Loc, Val, 16, OriginalType);
- write16(Loc, Val);
+ checkInt(loc, val, 16, originalType);
+ write16(loc, val);
break;
case R_PPC64_REL32:
- checkInt(Loc, Val, 32, Type);
- write32(Loc, Val);
+ checkInt(loc, val, 32, type);
+ write32(loc, val);
break;
case R_PPC64_ADDR64:
case R_PPC64_REL64:
case R_PPC64_TOC:
- write64(Loc, Val);
+ write64(loc, val);
break;
case R_PPC64_REL14: {
- uint32_t Mask = 0x0000FFFC;
- checkInt(Loc, Val, 16, Type);
- checkAlignment(Loc, Val, 4, Type);
- write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
+ uint32_t mask = 0x0000FFFC;
+ checkInt(loc, val, 16, type);
+ checkAlignment(loc, val, 4, type);
+ write32(loc, (read32(loc) & ~mask) | (val & mask));
break;
}
case R_PPC64_REL24: {
- uint32_t Mask = 0x03FFFFFC;
- checkInt(Loc, Val, 26, Type);
- checkAlignment(Loc, Val, 4, Type);
- write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
+ uint32_t mask = 0x03FFFFFC;
+ checkInt(loc, val, 26, type);
+ checkAlignment(loc, val, 4, type);
+ write32(loc, (read32(loc) & ~mask) | (val & mask));
break;
}
case R_PPC64_DTPREL64:
- write64(Loc, Val - DynamicThreadPointerOffset);
+ write64(loc, val - dynamicThreadPointerOffset);
break;
default:
- error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type));
+ error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
}
}
-bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
- if (Type != R_PPC64_REL14 && Type != R_PPC64_REL24)
+bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
+ if (type != R_PPC64_REL14 && type != R_PPC64_REL24)
return false;
// If a function is in the Plt it needs to be called with a call-stub.
- if (S.isInPlt())
+ if (s.isInPlt())
return true;
// If a symbol is a weak undefined and we are compiling an executable
// it doesn't need a range-extending thunk since it can't be called.
- if (S.isUndefWeak() && !Config->Shared)
+ if (s.isUndefWeak() && !config->shared)
return false;
// If the offset exceeds the range of the branch type then it will need
// a range-extending thunk.
// See the comment in getRelocTargetVA() about R_PPC64_CALL.
- return !inBranchRange(Type, BranchAddr,
- S.getVA() +
- getPPC64GlobalEntryToLocalEntryOffset(S.StOther));
+ return !inBranchRange(type, branchAddr,
+ s.getVA() +
+ getPPC64GlobalEntryToLocalEntryOffset(s.stOther));
}
uint32_t PPC64::getThunkSectionSpacing() const {
@@ -904,22 +904,22 @@ uint32_t PPC64::getThunkSectionSpacing() const {
return 0x2000000;
}
-bool PPC64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
- int64_t Offset = Dst - Src;
- if (Type == R_PPC64_REL14)
- return isInt<16>(Offset);
- if (Type == R_PPC64_REL24)
- return isInt<26>(Offset);
+bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
+ int64_t offset = dst - src;
+ if (type == R_PPC64_REL14)
+ return isInt<16>(offset);
+ if (type == R_PPC64_REL24)
+ return isInt<26>(offset);
llvm_unreachable("unsupported relocation type used in branch");
}
-RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- if (Expr == R_RELAX_TLS_GD_TO_IE)
+RelExpr PPC64::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ if (expr == R_RELAX_TLS_GD_TO_IE)
return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
- if (Expr == R_RELAX_TLS_LD_TO_LE)
+ if (expr == R_RELAX_TLS_LD_TO_LE)
return R_RELAX_TLS_LD_TO_LE_ABS;
- return Expr;
+ return expr;
}
// Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement.
@@ -939,24 +939,24 @@ RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
// thread pointer.
// Since the nop must directly follow the call, the R_PPC64_TLSGD relocation is
// used as the relaxation hint for both steps 2 and 3.
-void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void PPC64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_PPC64_GOT_TLSGD16_HA:
// This is relaxed from addis rT, r2, sym@got@tlsgd@ha to
// addis rT, r2, sym@got@tprel@ha.
- relocateOne(Loc, R_PPC64_GOT_TPREL16_HA, Val);
+ relocateOne(loc, R_PPC64_GOT_TPREL16_HA, val);
return;
case R_PPC64_GOT_TLSGD16_LO: {
// Relax from addi r3, rA, sym@got@tlsgd@l to
// ld r3, sym@got@tprel@l(rA)
- uint32_t RA = (readFromHalf16(Loc) & (0x1f << 16));
- writeFromHalf16(Loc, 0xe8600000 | RA);
- relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
+ uint32_t ra = (readFromHalf16(loc) & (0x1f << 16));
+ writeFromHalf16(loc, 0xe8600000 | ra);
+ relocateOne(loc, R_PPC64_GOT_TPREL16_LO_DS, val);
return;
}
case R_PPC64_TLSGD:
- write32(Loc, 0x60000000); // bl __tls_get_addr(sym@tlsgd) --> nop
- write32(Loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
+ write32(loc, 0x60000000); // bl __tls_get_addr(sym@tlsgd) --> nop
+ write32(loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
return;
default:
llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
@@ -991,86 +991,86 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// pair by split-stack-size-adjust.
// addis r12, r1, ha(-stack-frame size - split-stack-adjust-size)
// addi r12, r12, l(-stack-frame size - split-stack-adjust-size)
-bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const {
+bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const {
// If the caller has a global entry point adjust the buffer past it. The start
// of the split-stack prologue will be at the local entry point.
- Loc += getPPC64GlobalEntryToLocalEntryOffset(StOther);
+ loc += getPPC64GlobalEntryToLocalEntryOffset(stOther);
// At the very least we expect to see a load of some split-stack data from the
// tcb, and 2 instructions that calculate the ending stack address this
// function will require. If there is not enough room for at least 3
// instructions it can't be a split-stack prologue.
- if (Loc + 12 >= End)
+ if (loc + 12 >= end)
return false;
// First instruction must be `ld r0, -0x7000-64(r13)`
- if (read32(Loc) != 0xe80d8fc0)
+ if (read32(loc) != 0xe80d8fc0)
return false;
- int16_t HiImm = 0;
- int16_t LoImm = 0;
+ int16_t hiImm = 0;
+ int16_t loImm = 0;
// First instruction can be either an addis if the frame size is larger then
// 32K, or an addi if the size is less then 32K.
- int32_t FirstInstr = read32(Loc + 4);
- if (getPrimaryOpCode(FirstInstr) == 15) {
- HiImm = FirstInstr & 0xFFFF;
- } else if (getPrimaryOpCode(FirstInstr) == 14) {
- LoImm = FirstInstr & 0xFFFF;
+ int32_t firstInstr = read32(loc + 4);
+ if (getPrimaryOpCode(firstInstr) == 15) {
+ hiImm = firstInstr & 0xFFFF;
+ } else if (getPrimaryOpCode(firstInstr) == 14) {
+ loImm = firstInstr & 0xFFFF;
} else {
return false;
}
// Second instruction is either an addi or a nop. If the first instruction was
// an addi then LoImm is set and the second instruction must be a nop.
- uint32_t SecondInstr = read32(Loc + 8);
- if (!LoImm && getPrimaryOpCode(SecondInstr) == 14) {
- LoImm = SecondInstr & 0xFFFF;
- } else if (SecondInstr != 0x60000000) {
+ uint32_t secondInstr = read32(loc + 8);
+ if (!loImm && getPrimaryOpCode(secondInstr) == 14) {
+ loImm = secondInstr & 0xFFFF;
+ } else if (secondInstr != 0x60000000) {
return false;
}
// The register operands of the first instruction should be the stack-pointer
// (r1) as the input (RA) and r12 as the output (RT). If the second
// instruction is not a nop, then it should use r12 as both input and output.
- auto CheckRegOperands = [](uint32_t Instr, uint8_t ExpectedRT,
- uint8_t ExpectedRA) {
- return ((Instr & 0x3E00000) >> 21 == ExpectedRT) &&
- ((Instr & 0x1F0000) >> 16 == ExpectedRA);
+ auto checkRegOperands = [](uint32_t instr, uint8_t expectedRT,
+ uint8_t expectedRA) {
+ return ((instr & 0x3E00000) >> 21 == expectedRT) &&
+ ((instr & 0x1F0000) >> 16 == expectedRA);
};
- if (!CheckRegOperands(FirstInstr, 12, 1))
+ if (!checkRegOperands(firstInstr, 12, 1))
return false;
- if (SecondInstr != 0x60000000 && !CheckRegOperands(SecondInstr, 12, 12))
+ if (secondInstr != 0x60000000 && !checkRegOperands(secondInstr, 12, 12))
return false;
- int32_t StackFrameSize = (HiImm * 65536) + LoImm;
+ int32_t stackFrameSize = (hiImm * 65536) + loImm;
// Check that the adjusted size doesn't overflow what we can represent with 2
// instructions.
- if (StackFrameSize < Config->SplitStackAdjustSize + INT32_MIN) {
- error(getErrorLocation(Loc) + "split-stack prologue adjustment overflows");
+ if (stackFrameSize < config->splitStackAdjustSize + INT32_MIN) {
+ error(getErrorLocation(loc) + "split-stack prologue adjustment overflows");
return false;
}
- int32_t AdjustedStackFrameSize =
- StackFrameSize - Config->SplitStackAdjustSize;
+ int32_t adjustedStackFrameSize =
+ stackFrameSize - config->splitStackAdjustSize;
- LoImm = AdjustedStackFrameSize & 0xFFFF;
- HiImm = (AdjustedStackFrameSize + 0x8000) >> 16;
- if (HiImm) {
- write32(Loc + 4, 0x3D810000 | (uint16_t)HiImm);
+ loImm = adjustedStackFrameSize & 0xFFFF;
+ hiImm = (adjustedStackFrameSize + 0x8000) >> 16;
+ if (hiImm) {
+ write32(loc + 4, 0x3D810000 | (uint16_t)hiImm);
// If the low immediate is zero the second instruction will be a nop.
- SecondInstr = LoImm ? 0x398C0000 | (uint16_t)LoImm : 0x60000000;
- write32(Loc + 8, SecondInstr);
+ secondInstr = loImm ? 0x398C0000 | (uint16_t)loImm : 0x60000000;
+ write32(loc + 8, secondInstr);
} else {
// addi r12, r1, imm
- write32(Loc + 4, (0x39810000) | (uint16_t)LoImm);
- write32(Loc + 8, 0x60000000);
+ write32(loc + 4, (0x39810000) | (uint16_t)loImm);
+ write32(loc + 8, 0x60000000);
}
return true;
}
TargetInfo *elf::getPPC64TargetInfo() {
- static PPC64 Target;
- return &Target;
+ static PPC64 target;
+ return &target;
}
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 5f7043bc471..ddd9b9f7e5c 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -23,20 +23,20 @@ class RISCV final : public TargetInfo {
public:
RISCV();
uint32_t calcEFlags() const override;
- void writeGotHeader(uint8_t *Buf) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- RelType getDynRel(RelType Type) const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ void writeGotHeader(uint8_t *buf) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ RelType getDynRel(RelType type) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // end anonymous namespace
-const uint64_t DTPOffset = 0x800;
+const uint64_t dtpOffset = 0x800;
enum Op {
ADDI = 0x13,
@@ -56,91 +56,91 @@ enum Reg {
X_T3 = 28,
};
-static uint32_t hi20(uint32_t Val) { return (Val + 0x800) >> 12; }
-static uint32_t lo12(uint32_t Val) { return Val & 4095; }
+static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; }
+static uint32_t lo12(uint32_t val) { return val & 4095; }
-static uint32_t itype(uint32_t Op, uint32_t Rd, uint32_t Rs1, uint32_t Imm) {
- return Op | (Rd << 7) | (Rs1 << 15) | (Imm << 20);
+static uint32_t itype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t imm) {
+ return op | (rd << 7) | (rs1 << 15) | (imm << 20);
}
-static uint32_t rtype(uint32_t Op, uint32_t Rd, uint32_t Rs1, uint32_t Rs2) {
- return Op | (Rd << 7) | (Rs1 << 15) | (Rs2 << 20);
+static uint32_t rtype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t rs2) {
+ return op | (rd << 7) | (rs1 << 15) | (rs2 << 20);
}
-static uint32_t utype(uint32_t Op, uint32_t Rd, uint32_t Imm) {
- return Op | (Rd << 7) | (Imm << 12);
+static uint32_t utype(uint32_t op, uint32_t rd, uint32_t imm) {
+ return op | (rd << 7) | (imm << 12);
}
RISCV::RISCV() {
- CopyRel = R_RISCV_COPY;
- NoneRel = R_RISCV_NONE;
- PltRel = R_RISCV_JUMP_SLOT;
- RelativeRel = R_RISCV_RELATIVE;
- if (Config->Is64) {
- SymbolicRel = R_RISCV_64;
- TlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
- TlsOffsetRel = R_RISCV_TLS_DTPREL64;
- TlsGotRel = R_RISCV_TLS_TPREL64;
+ copyRel = R_RISCV_COPY;
+ noneRel = R_RISCV_NONE;
+ pltRel = R_RISCV_JUMP_SLOT;
+ relativeRel = R_RISCV_RELATIVE;
+ if (config->is64) {
+ symbolicRel = R_RISCV_64;
+ tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
+ tlsOffsetRel = R_RISCV_TLS_DTPREL64;
+ tlsGotRel = R_RISCV_TLS_TPREL64;
} else {
- SymbolicRel = R_RISCV_32;
- TlsModuleIndexRel = R_RISCV_TLS_DTPMOD32;
- TlsOffsetRel = R_RISCV_TLS_DTPREL32;
- TlsGotRel = R_RISCV_TLS_TPREL32;
+ symbolicRel = R_RISCV_32;
+ tlsModuleIndexRel = R_RISCV_TLS_DTPMOD32;
+ tlsOffsetRel = R_RISCV_TLS_DTPREL32;
+ tlsGotRel = R_RISCV_TLS_TPREL32;
}
- GotRel = SymbolicRel;
+ gotRel = symbolicRel;
// .got[0] = _DYNAMIC
- GotBaseSymInGotPlt = false;
- GotHeaderEntriesNum = 1;
+ gotBaseSymInGotPlt = false;
+ gotHeaderEntriesNum = 1;
// .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map
- GotPltHeaderEntriesNum = 2;
+ gotPltHeaderEntriesNum = 2;
- PltEntrySize = 16;
- PltHeaderSize = 32;
+ pltEntrySize = 16;
+ pltHeaderSize = 32;
}
-static uint32_t getEFlags(InputFile *F) {
- if (Config->Is64)
- return cast<ObjFile<ELF64LE>>(F)->getObj().getHeader()->e_flags;
- return cast<ObjFile<ELF32LE>>(F)->getObj().getHeader()->e_flags;
+static uint32_t getEFlags(InputFile *f) {
+ if (config->is64)
+ return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader()->e_flags;
+ return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader()->e_flags;
}
uint32_t RISCV::calcEFlags() const {
- assert(!ObjectFiles.empty());
+ assert(!objectFiles.empty());
- uint32_t Target = getEFlags(ObjectFiles.front());
+ uint32_t target = getEFlags(objectFiles.front());
- for (InputFile *F : ObjectFiles) {
- uint32_t EFlags = getEFlags(F);
- if (EFlags & EF_RISCV_RVC)
- Target |= EF_RISCV_RVC;
+ for (InputFile *f : objectFiles) {
+ uint32_t eflags = getEFlags(f);
+ if (eflags & EF_RISCV_RVC)
+ target |= EF_RISCV_RVC;
- if ((EFlags & EF_RISCV_FLOAT_ABI) != (Target & EF_RISCV_FLOAT_ABI))
- error(toString(F) +
+ if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
+ error(toString(f) +
": cannot link object files with different floating-point ABI");
- if ((EFlags & EF_RISCV_RVE) != (Target & EF_RISCV_RVE))
- error(toString(F) +
+ if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
+ error(toString(f) +
": cannot link object files with different EF_RISCV_RVE");
}
- return Target;
+ return target;
}
-void RISCV::writeGotHeader(uint8_t *Buf) const {
- if (Config->Is64)
- write64le(Buf, Main->Dynamic->getVA());
+void RISCV::writeGotHeader(uint8_t *buf) const {
+ if (config->is64)
+ write64le(buf, mainPart->dynamic->getVA());
else
- write32le(Buf, Main->Dynamic->getVA());
+ write32le(buf, mainPart->dynamic->getVA());
}
-void RISCV::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
- if (Config->Is64)
- write64le(Buf, In.Plt->getVA());
+void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const {
+ if (config->is64)
+ write64le(buf, in.plt->getVA());
else
- write32le(Buf, In.Plt->getVA());
+ write32le(buf, in.plt->getVA());
}
-void RISCV::writePltHeader(uint8_t *Buf) const {
+void RISCV::writePltHeader(uint8_t *buf) const {
// 1: auipc t2, %pcrel_hi(.got.plt)
// sub t1, t1, t3
// l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve
@@ -149,40 +149,40 @@ void RISCV::writePltHeader(uint8_t *Buf) const {
// srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0]
// l[wd] t0, Wordsize(t0); t0 = link_map
// jr t3
- uint32_t Offset = In.GotPlt->getVA() - In.Plt->getVA();
- uint32_t Load = Config->Is64 ? LD : LW;
- write32le(Buf + 0, utype(AUIPC, X_T2, hi20(Offset)));
- write32le(Buf + 4, rtype(SUB, X_T1, X_T1, X_T3));
- write32le(Buf + 8, itype(Load, X_T3, X_T2, lo12(Offset)));
- write32le(Buf + 12, itype(ADDI, X_T1, X_T1, -Target->PltHeaderSize - 12));
- write32le(Buf + 16, itype(ADDI, X_T0, X_T2, lo12(Offset)));
- write32le(Buf + 20, itype(SRLI, X_T1, X_T1, Config->Is64 ? 1 : 2));
- write32le(Buf + 24, itype(Load, X_T0, X_T0, Config->Wordsize));
- write32le(Buf + 28, itype(JALR, 0, X_T3, 0));
+ uint32_t offset = in.gotPlt->getVA() - in.plt->getVA();
+ uint32_t load = config->is64 ? LD : LW;
+ write32le(buf + 0, utype(AUIPC, X_T2, hi20(offset)));
+ write32le(buf + 4, rtype(SUB, X_T1, X_T1, X_T3));
+ write32le(buf + 8, itype(load, X_T3, X_T2, lo12(offset)));
+ write32le(buf + 12, itype(ADDI, X_T1, X_T1, -target->pltHeaderSize - 12));
+ write32le(buf + 16, itype(ADDI, X_T0, X_T2, lo12(offset)));
+ write32le(buf + 20, itype(SRLI, X_T1, X_T1, config->is64 ? 1 : 2));
+ write32le(buf + 24, itype(load, X_T0, X_T0, config->wordsize));
+ write32le(buf + 28, itype(JALR, 0, X_T3, 0));
}
-void RISCV::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
+void RISCV::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
// 1: auipc t3, %pcrel_hi(f@.got.plt)
// l[wd] t3, %pcrel_lo(1b)(t3)
// jalr t1, t3
// nop
- uint32_t Offset = GotPltEntryAddr - PltEntryAddr;
- write32le(Buf + 0, utype(AUIPC, X_T3, hi20(Offset)));
- write32le(Buf + 4, itype(Config->Is64 ? LD : LW, X_T3, X_T3, lo12(Offset)));
- write32le(Buf + 8, itype(JALR, X_T1, X_T3, 0));
- write32le(Buf + 12, itype(ADDI, 0, 0, 0));
+ uint32_t offset = gotPltEntryAddr - pltEntryAddr;
+ write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset)));
+ write32le(buf + 4, itype(config->is64 ? LD : LW, X_T3, X_T3, lo12(offset)));
+ write32le(buf + 8, itype(JALR, X_T1, X_T3, 0));
+ write32le(buf + 12, itype(ADDI, 0, 0, 0));
}
-RelType RISCV::getDynRel(RelType Type) const {
- return Type == Target->SymbolicRel ? Type
+RelType RISCV::getDynRel(RelType type) const {
+ return type == target->symbolicRel ? type
: static_cast<RelType>(R_RISCV_NONE);
}
-RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_RISCV_ADD8:
case R_RISCV_ADD16:
case R_RISCV_ADD32:
@@ -215,7 +215,7 @@ RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
case R_RISCV_TLS_GD_HI20:
return R_TLSGD_PC;
case R_RISCV_TLS_GOT_HI20:
- Config->HasStaticTlsModel = true;
+ config->hasStaticTlsModel = true;
return R_GOT_PC;
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_LO12_I:
@@ -231,106 +231,106 @@ RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
}
// Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63.
-static uint32_t extractBits(uint64_t V, uint32_t Begin, uint32_t End) {
- return (V & ((1ULL << (Begin + 1)) - 1)) >> End;
+static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
+ return (v & ((1ULL << (begin + 1)) - 1)) >> end;
}
-void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
- const uint64_t Val) const {
- const unsigned Bits = Config->Wordsize * 8;
+void RISCV::relocateOne(uint8_t *loc, const RelType type,
+ const uint64_t val) const {
+ const unsigned bits = config->wordsize * 8;
- switch (Type) {
+ switch (type) {
case R_RISCV_32:
- write32le(Loc, Val);
+ write32le(loc, val);
return;
case R_RISCV_64:
- write64le(Loc, Val);
+ write64le(loc, val);
return;
case R_RISCV_RVC_BRANCH: {
- checkInt(Loc, static_cast<int64_t>(Val) >> 1, 8, Type);
- checkAlignment(Loc, Val, 2, Type);
- uint16_t Insn = read16le(Loc) & 0xE383;
- uint16_t Imm8 = extractBits(Val, 8, 8) << 12;
- uint16_t Imm4_3 = extractBits(Val, 4, 3) << 10;
- uint16_t Imm7_6 = extractBits(Val, 7, 6) << 5;
- uint16_t Imm2_1 = extractBits(Val, 2, 1) << 3;
- uint16_t Imm5 = extractBits(Val, 5, 5) << 2;
- Insn |= Imm8 | Imm4_3 | Imm7_6 | Imm2_1 | Imm5;
-
- write16le(Loc, Insn);
+ checkInt(loc, static_cast<int64_t>(val) >> 1, 8, type);
+ checkAlignment(loc, val, 2, type);
+ uint16_t insn = read16le(loc) & 0xE383;
+ uint16_t imm8 = extractBits(val, 8, 8) << 12;
+ uint16_t imm4_3 = extractBits(val, 4, 3) << 10;
+ uint16_t imm7_6 = extractBits(val, 7, 6) << 5;
+ uint16_t imm2_1 = extractBits(val, 2, 1) << 3;
+ uint16_t imm5 = extractBits(val, 5, 5) << 2;
+ insn |= imm8 | imm4_3 | imm7_6 | imm2_1 | imm5;
+
+ write16le(loc, insn);
return;
}
case R_RISCV_RVC_JUMP: {
- checkInt(Loc, static_cast<int64_t>(Val) >> 1, 11, Type);
- checkAlignment(Loc, Val, 2, Type);
- uint16_t Insn = read16le(Loc) & 0xE003;
- uint16_t Imm11 = extractBits(Val, 11, 11) << 12;
- uint16_t Imm4 = extractBits(Val, 4, 4) << 11;
- uint16_t Imm9_8 = extractBits(Val, 9, 8) << 9;
- uint16_t Imm10 = extractBits(Val, 10, 10) << 8;
- uint16_t Imm6 = extractBits(Val, 6, 6) << 7;
- uint16_t Imm7 = extractBits(Val, 7, 7) << 6;
- uint16_t Imm3_1 = extractBits(Val, 3, 1) << 3;
- uint16_t Imm5 = extractBits(Val, 5, 5) << 2;
- Insn |= Imm11 | Imm4 | Imm9_8 | Imm10 | Imm6 | Imm7 | Imm3_1 | Imm5;
-
- write16le(Loc, Insn);
+ checkInt(loc, static_cast<int64_t>(val) >> 1, 11, type);
+ checkAlignment(loc, val, 2, type);
+ uint16_t insn = read16le(loc) & 0xE003;
+ uint16_t imm11 = extractBits(val, 11, 11) << 12;
+ uint16_t imm4 = extractBits(val, 4, 4) << 11;
+ uint16_t imm9_8 = extractBits(val, 9, 8) << 9;
+ uint16_t imm10 = extractBits(val, 10, 10) << 8;
+ uint16_t imm6 = extractBits(val, 6, 6) << 7;
+ uint16_t imm7 = extractBits(val, 7, 7) << 6;
+ uint16_t imm3_1 = extractBits(val, 3, 1) << 3;
+ uint16_t imm5 = extractBits(val, 5, 5) << 2;
+ insn |= imm11 | imm4 | imm9_8 | imm10 | imm6 | imm7 | imm3_1 | imm5;
+
+ write16le(loc, insn);
return;
}
case R_RISCV_RVC_LUI: {
- int64_t Imm = SignExtend64(Val + 0x800, Bits) >> 12;
- checkInt(Loc, Imm, 6, Type);
- if (Imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0`
- write16le(Loc, (read16le(Loc) & 0x0F83) | 0x4000);
+ int64_t imm = SignExtend64(val + 0x800, bits) >> 12;
+ checkInt(loc, imm, 6, type);
+ if (imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0`
+ write16le(loc, (read16le(loc) & 0x0F83) | 0x4000);
} else {
- uint16_t Imm17 = extractBits(Val + 0x800, 17, 17) << 12;
- uint16_t Imm16_12 = extractBits(Val + 0x800, 16, 12) << 2;
- write16le(Loc, (read16le(Loc) & 0xEF83) | Imm17 | Imm16_12);
+ uint16_t imm17 = extractBits(val + 0x800, 17, 17) << 12;
+ uint16_t imm16_12 = extractBits(val + 0x800, 16, 12) << 2;
+ write16le(loc, (read16le(loc) & 0xEF83) | imm17 | imm16_12);
}
return;
}
case R_RISCV_JAL: {
- checkInt(Loc, static_cast<int64_t>(Val) >> 1, 20, Type);
- checkAlignment(Loc, Val, 2, Type);
+ checkInt(loc, static_cast<int64_t>(val) >> 1, 20, type);
+ checkAlignment(loc, val, 2, type);
- uint32_t Insn = read32le(Loc) & 0xFFF;
- uint32_t Imm20 = extractBits(Val, 20, 20) << 31;
- uint32_t Imm10_1 = extractBits(Val, 10, 1) << 21;
- uint32_t Imm11 = extractBits(Val, 11, 11) << 20;
- uint32_t Imm19_12 = extractBits(Val, 19, 12) << 12;
- Insn |= Imm20 | Imm10_1 | Imm11 | Imm19_12;
+ uint32_t insn = read32le(loc) & 0xFFF;
+ uint32_t imm20 = extractBits(val, 20, 20) << 31;
+ uint32_t imm10_1 = extractBits(val, 10, 1) << 21;
+ uint32_t imm11 = extractBits(val, 11, 11) << 20;
+ uint32_t imm19_12 = extractBits(val, 19, 12) << 12;
+ insn |= imm20 | imm10_1 | imm11 | imm19_12;
- write32le(Loc, Insn);
+ write32le(loc, insn);
return;
}
case R_RISCV_BRANCH: {
- checkInt(Loc, static_cast<int64_t>(Val) >> 1, 12, Type);
- checkAlignment(Loc, Val, 2, Type);
+ checkInt(loc, static_cast<int64_t>(val) >> 1, 12, type);
+ checkAlignment(loc, val, 2, type);
- uint32_t Insn = read32le(Loc) & 0x1FFF07F;
- uint32_t Imm12 = extractBits(Val, 12, 12) << 31;
- uint32_t Imm10_5 = extractBits(Val, 10, 5) << 25;
- uint32_t Imm4_1 = extractBits(Val, 4, 1) << 8;
- uint32_t Imm11 = extractBits(Val, 11, 11) << 7;
- Insn |= Imm12 | Imm10_5 | Imm4_1 | Imm11;
+ uint32_t insn = read32le(loc) & 0x1FFF07F;
+ uint32_t imm12 = extractBits(val, 12, 12) << 31;
+ uint32_t imm10_5 = extractBits(val, 10, 5) << 25;
+ uint32_t imm4_1 = extractBits(val, 4, 1) << 8;
+ uint32_t imm11 = extractBits(val, 11, 11) << 7;
+ insn |= imm12 | imm10_5 | imm4_1 | imm11;
- write32le(Loc, Insn);
+ write32le(loc, insn);
return;
}
// auipc + jalr pair
case R_RISCV_CALL:
case R_RISCV_CALL_PLT: {
- int64_t Hi = SignExtend64(Val + 0x800, Bits) >> 12;
- checkInt(Loc, Hi, 20, Type);
- if (isInt<20>(Hi)) {
- relocateOne(Loc, R_RISCV_PCREL_HI20, Val);
- relocateOne(Loc + 4, R_RISCV_PCREL_LO12_I, Val);
+ int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
+ checkInt(loc, hi, 20, type);
+ if (isInt<20>(hi)) {
+ relocateOne(loc, R_RISCV_PCREL_HI20, val);
+ relocateOne(loc + 4, R_RISCV_PCREL_LO12_I, val);
}
return;
}
@@ -341,78 +341,78 @@ void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
case R_RISCV_TLS_GOT_HI20:
case R_RISCV_TPREL_HI20:
case R_RISCV_HI20: {
- uint64_t Hi = Val + 0x800;
- checkInt(Loc, SignExtend64(Hi, Bits) >> 12, 20, Type);
- write32le(Loc, (read32le(Loc) & 0xFFF) | (Hi & 0xFFFFF000));
+ uint64_t hi = val + 0x800;
+ checkInt(loc, SignExtend64(hi, bits) >> 12, 20, type);
+ write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000));
return;
}
case R_RISCV_PCREL_LO12_I:
case R_RISCV_TPREL_LO12_I:
case R_RISCV_LO12_I: {
- uint64_t Hi = (Val + 0x800) >> 12;
- uint64_t Lo = Val - (Hi << 12);
- write32le(Loc, (read32le(Loc) & 0xFFFFF) | ((Lo & 0xFFF) << 20));
+ uint64_t hi = (val + 0x800) >> 12;
+ uint64_t lo = val - (hi << 12);
+ write32le(loc, (read32le(loc) & 0xFFFFF) | ((lo & 0xFFF) << 20));
return;
}
case R_RISCV_PCREL_LO12_S:
case R_RISCV_TPREL_LO12_S:
case R_RISCV_LO12_S: {
- uint64_t Hi = (Val + 0x800) >> 12;
- uint64_t Lo = Val - (Hi << 12);
- uint32_t Imm11_5 = extractBits(Lo, 11, 5) << 25;
- uint32_t Imm4_0 = extractBits(Lo, 4, 0) << 7;
- write32le(Loc, (read32le(Loc) & 0x1FFF07F) | Imm11_5 | Imm4_0);
+ uint64_t hi = (val + 0x800) >> 12;
+ uint64_t lo = val - (hi << 12);
+ uint32_t imm11_5 = extractBits(lo, 11, 5) << 25;
+ uint32_t imm4_0 = extractBits(lo, 4, 0) << 7;
+ write32le(loc, (read32le(loc) & 0x1FFF07F) | imm11_5 | imm4_0);
return;
}
case R_RISCV_ADD8:
- *Loc += Val;
+ *loc += val;
return;
case R_RISCV_ADD16:
- write16le(Loc, read16le(Loc) + Val);
+ write16le(loc, read16le(loc) + val);
return;
case R_RISCV_ADD32:
- write32le(Loc, read32le(Loc) + Val);
+ write32le(loc, read32le(loc) + val);
return;
case R_RISCV_ADD64:
- write64le(Loc, read64le(Loc) + Val);
+ write64le(loc, read64le(loc) + val);
return;
case R_RISCV_SUB6:
- *Loc = (*Loc & 0xc0) | (((*Loc & 0x3f) - Val) & 0x3f);
+ *loc = (*loc & 0xc0) | (((*loc & 0x3f) - val) & 0x3f);
return;
case R_RISCV_SUB8:
- *Loc -= Val;
+ *loc -= val;
return;
case R_RISCV_SUB16:
- write16le(Loc, read16le(Loc) - Val);
+ write16le(loc, read16le(loc) - val);
return;
case R_RISCV_SUB32:
- write32le(Loc, read32le(Loc) - Val);
+ write32le(loc, read32le(loc) - val);
return;
case R_RISCV_SUB64:
- write64le(Loc, read64le(Loc) - Val);
+ write64le(loc, read64le(loc) - val);
return;
case R_RISCV_SET6:
- *Loc = (*Loc & 0xc0) | (Val & 0x3f);
+ *loc = (*loc & 0xc0) | (val & 0x3f);
return;
case R_RISCV_SET8:
- *Loc = Val;
+ *loc = val;
return;
case R_RISCV_SET16:
- write16le(Loc, Val);
+ write16le(loc, val);
return;
case R_RISCV_SET32:
case R_RISCV_32_PCREL:
- write32le(Loc, Val);
+ write32le(loc, val);
return;
case R_RISCV_TLS_DTPREL32:
- write32le(Loc, Val - DTPOffset);
+ write32le(loc, val - dtpOffset);
break;
case R_RISCV_TLS_DTPREL64:
- write64le(Loc, Val - DTPOffset);
+ write64le(loc, val - dtpOffset);
break;
case R_RISCV_ALIGN:
@@ -430,13 +430,13 @@ void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
case R_RISCV_GPREL_I:
case R_RISCV_GPREL_S:
default:
- error(getErrorLocation(Loc) +
- "unimplemented relocation: " + toString(Type));
+ error(getErrorLocation(loc) +
+ "unimplemented relocation: " + toString(type));
return;
}
}
TargetInfo *elf::getRISCVTargetInfo() {
- static RISCV Target;
- return &Target;
+ static RISCV target;
+ return &target;
}
diff --git a/lld/ELF/Arch/SPARCV9.cpp b/lld/ELF/Arch/SPARCV9.cpp
index 7d85f8697ec..5299206dd91 100644
--- a/lld/ELF/Arch/SPARCV9.cpp
+++ b/lld/ELF/Arch/SPARCV9.cpp
@@ -23,32 +23,32 @@ namespace {
class SPARCV9 final : public TargetInfo {
public:
SPARCV9();
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ void writePlt(uint8_t *buf, uint64_t gotEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
SPARCV9::SPARCV9() {
- CopyRel = R_SPARC_COPY;
- GotRel = R_SPARC_GLOB_DAT;
- NoneRel = R_SPARC_NONE;
- PltRel = R_SPARC_JMP_SLOT;
- RelativeRel = R_SPARC_RELATIVE;
- SymbolicRel = R_SPARC_64;
- PltEntrySize = 32;
- PltHeaderSize = 4 * PltEntrySize;
+ copyRel = R_SPARC_COPY;
+ gotRel = R_SPARC_GLOB_DAT;
+ noneRel = R_SPARC_NONE;
+ pltRel = R_SPARC_JMP_SLOT;
+ relativeRel = R_SPARC_RELATIVE;
+ symbolicRel = R_SPARC_64;
+ pltEntrySize = 32;
+ pltHeaderSize = 4 * pltEntrySize;
- DefaultCommonPageSize = 8192;
- DefaultMaxPageSize = 0x100000;
- DefaultImageBase = 0x100000;
+ defaultCommonPageSize = 8192;
+ defaultMaxPageSize = 0x100000;
+ defaultImageBase = 0x100000;
}
-RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- switch (Type) {
+RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ switch (type) {
case R_SPARC_32:
case R_SPARC_UA32:
case R_SPARC_64:
@@ -68,65 +68,65 @@ RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S,
case R_SPARC_NONE:
return R_NONE;
default:
- error(getErrorLocation(Loc) + "unknown relocation (" + Twine(Type) +
- ") against symbol " + toString(S));
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
return R_NONE;
}
}
-void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void SPARCV9::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_SPARC_32:
case R_SPARC_UA32:
// V-word32
- checkUInt(Loc, Val, 32, Type);
- write32be(Loc, Val);
+ checkUInt(loc, val, 32, type);
+ write32be(loc, val);
break;
case R_SPARC_DISP32:
// V-disp32
- checkInt(Loc, Val, 32, Type);
- write32be(Loc, Val);
+ checkInt(loc, val, 32, type);
+ write32be(loc, val);
break;
case R_SPARC_WDISP30:
case R_SPARC_WPLT30:
// V-disp30
- checkInt(Loc, Val, 32, Type);
- write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff));
+ checkInt(loc, val, 32, type);
+ write32be(loc, (read32be(loc) & ~0x3fffffff) | ((val >> 2) & 0x3fffffff));
break;
case R_SPARC_22:
// V-imm22
- checkUInt(Loc, Val, 22, Type);
- write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff));
+ checkUInt(loc, val, 22, type);
+ write32be(loc, (read32be(loc) & ~0x003fffff) | (val & 0x003fffff));
break;
case R_SPARC_GOT22:
case R_SPARC_PC22:
// T-imm22
- write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff));
+ write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 10) & 0x003fffff));
break;
case R_SPARC_WDISP19:
// V-disp19
- checkInt(Loc, Val, 21, Type);
- write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff));
+ checkInt(loc, val, 21, type);
+ write32be(loc, (read32be(loc) & ~0x0007ffff) | ((val >> 2) & 0x0007ffff));
break;
case R_SPARC_GOT10:
case R_SPARC_PC10:
// T-simm10
- write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff));
+ write32be(loc, (read32be(loc) & ~0x000003ff) | (val & 0x000003ff));
break;
case R_SPARC_64:
case R_SPARC_UA64:
// V-xword64
- write64be(Loc, Val);
+ write64be(loc, val);
break;
default:
llvm_unreachable("unknown relocation");
}
}
-void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t PltData[] = {
+void SPARCV9::writePlt(uint8_t *buf, uint64_t gotEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t pltData[] = {
0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1
0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1
0x01, 0x00, 0x00, 0x00, // nop
@@ -136,14 +136,14 @@ void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
0x01, 0x00, 0x00, 0x00, // nop
0x01, 0x00, 0x00, 0x00 // nop
};
- memcpy(Buf, PltData, sizeof(PltData));
+ memcpy(buf, pltData, sizeof(pltData));
- uint64_t Off = PltHeaderSize + PltEntrySize * Index;
- relocateOne(Buf, R_SPARC_22, Off);
- relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize));
+ uint64_t off = pltHeaderSize + pltEntrySize * index;
+ relocateOne(buf, R_SPARC_22, off);
+ relocateOne(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));
}
TargetInfo *elf::getSPARCV9TargetInfo() {
- static SPARCV9 Target;
- return &Target;
+ static SPARCV9 target;
+ return &target;
}
diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index ebc59ab2895..e1dd231e8e8 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -23,63 +23,63 @@ namespace {
class X86 : public TargetInfo {
public:
X86();
- int getTlsGdRelaxSkip(RelType Type) const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
- void writeGotPltHeader(uint8_t *Buf) const override;
- RelType getDynRel(RelType Type) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
-
- RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const override;
- void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ int getTlsGdRelaxSkip(RelType type) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
+ void writeGotPltHeader(uint8_t *buf) const override;
+ RelType getDynRel(RelType type) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+
+ RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const override;
+ void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
};
} // namespace
X86::X86() {
- CopyRel = R_386_COPY;
- GotRel = R_386_GLOB_DAT;
- NoneRel = R_386_NONE;
- PltRel = R_386_JUMP_SLOT;
- IRelativeRel = R_386_IRELATIVE;
- RelativeRel = R_386_RELATIVE;
- SymbolicRel = R_386_32;
- TlsGotRel = R_386_TLS_TPOFF;
- TlsModuleIndexRel = R_386_TLS_DTPMOD32;
- TlsOffsetRel = R_386_TLS_DTPOFF32;
- PltEntrySize = 16;
- PltHeaderSize = 16;
- TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
+ copyRel = R_386_COPY;
+ gotRel = R_386_GLOB_DAT;
+ noneRel = R_386_NONE;
+ pltRel = R_386_JUMP_SLOT;
+ iRelativeRel = R_386_IRELATIVE;
+ relativeRel = R_386_RELATIVE;
+ symbolicRel = R_386_32;
+ tlsGotRel = R_386_TLS_TPOFF;
+ tlsModuleIndexRel = R_386_TLS_DTPMOD32;
+ tlsOffsetRel = R_386_TLS_DTPOFF32;
+ pltEntrySize = 16;
+ pltHeaderSize = 16;
+ trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the non-PAE large page size (known as a superpage or huge page).
// FreeBSD automatically promotes large, superpage-aligned allocations.
- DefaultImageBase = 0x400000;
+ defaultImageBase = 0x400000;
}
-int X86::getTlsGdRelaxSkip(RelType Type) const {
+int X86::getTlsGdRelaxSkip(RelType type) const {
return 2;
}
-RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
+RelExpr X86::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
// There are 4 different TLS variable models with varying degrees of
// flexibility and performance. LocalExec and InitialExec models are fast but
// less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
// dynamic section to let runtime know about that.
- if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
- Type == R_386_TLS_GOTIE)
- Config->HasStaticTlsModel = true;
+ if (type == R_386_TLS_LE || type == R_386_TLS_LE_32 || type == R_386_TLS_IE ||
+ type == R_386_TLS_GOTIE)
+ config->hasStaticTlsModel = true;
- switch (Type) {
+ switch (type) {
case R_386_8:
case R_386_16:
case R_386_32:
@@ -137,7 +137,7 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
// instruction. That means a ModRM byte is at Loc[-1]. By taking a look at
// the byte, we can determine whether the instruction uses the operand as an
// absolute address (R_GOT) or a register-relative address (R_GOTPLT).
- return (Loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOTPLT;
+ return (loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOTPLT;
case R_386_TLS_GOTIE:
return R_GOTPLT;
case R_386_GOTOFF:
@@ -149,17 +149,17 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
case R_386_NONE:
return R_NONE;
default:
- error(getErrorLocation(Loc) + "unknown relocation (" + Twine(Type) +
- ") against symbol " + toString(S));
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
return R_NONE;
}
}
-RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- switch (Expr) {
+RelExpr X86::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ switch (expr) {
default:
- return Expr;
+ return expr;
case R_RELAX_TLS_GD_TO_IE:
return R_RELAX_TLS_GD_TO_IE_GOTPLT;
case R_RELAX_TLS_GD_TO_LE:
@@ -167,84 +167,84 @@ RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,
}
}
-void X86::writeGotPltHeader(uint8_t *Buf) const {
- write32le(Buf, Main->Dynamic->getVA());
+void X86::writeGotPltHeader(uint8_t *buf) const {
+ write32le(buf, mainPart->dynamic->getVA());
}
-void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+void X86::writeGotPlt(uint8_t *buf, const Symbol &s) const {
// Entries in .got.plt initially points back to the corresponding
// PLT entries with a fixed offset to skip the first instruction.
- write32le(Buf, S.getPltVA() + 6);
+ write32le(buf, s.getPltVA() + 6);
}
-void X86::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
+void X86::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
// An x86 entry is the address of the ifunc resolver function.
- write32le(Buf, S.getVA());
+ write32le(buf, s.getVA());
}
-RelType X86::getDynRel(RelType Type) const {
- if (Type == R_386_TLS_LE)
+RelType X86::getDynRel(RelType type) const {
+ if (type == R_386_TLS_LE)
return R_386_TLS_TPOFF;
- if (Type == R_386_TLS_LE_32)
+ if (type == R_386_TLS_LE_32)
return R_386_TLS_TPOFF32;
- return Type;
+ return type;
}
-void X86::writePltHeader(uint8_t *Buf) const {
- if (Config->Pic) {
- const uint8_t V[] = {
+void X86::writePltHeader(uint8_t *buf) const {
+ if (config->isPic) {
+ const uint8_t v[] = {
0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx)
0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
0x90, 0x90, 0x90, 0x90 // nop
};
- memcpy(Buf, V, sizeof(V));
+ memcpy(buf, v, sizeof(v));
return;
}
- const uint8_t PltData[] = {
+ const uint8_t pltData[] = {
0xff, 0x35, 0, 0, 0, 0, // pushl (GOTPLT+4)
0xff, 0x25, 0, 0, 0, 0, // jmp *(GOTPLT+8)
0x90, 0x90, 0x90, 0x90, // nop
};
- memcpy(Buf, PltData, sizeof(PltData));
- uint32_t GotPlt = In.GotPlt->getVA();
- write32le(Buf + 2, GotPlt + 4);
- write32le(Buf + 8, GotPlt + 8);
+ memcpy(buf, pltData, sizeof(pltData));
+ uint32_t gotPlt = in.gotPlt->getVA();
+ write32le(buf + 2, gotPlt + 4);
+ write32le(buf + 8, gotPlt + 8);
}
-void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- if (Config->Pic) {
- const uint8_t Inst[] = {
+void X86::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ if (config->isPic) {
+ const uint8_t inst[] = {
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
0x68, 0, 0, 0, 0, // pushl $reloc_offset
0xe9, 0, 0, 0, 0, // jmp .PLT0@PC
};
- memcpy(Buf, Inst, sizeof(Inst));
- write32le(Buf + 2, GotPltEntryAddr - In.GotPlt->getVA());
+ memcpy(buf, inst, sizeof(inst));
+ write32le(buf + 2, gotPltEntryAddr - in.gotPlt->getVA());
} else {
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
0x68, 0, 0, 0, 0, // pushl $reloc_offset
0xe9, 0, 0, 0, 0, // jmp .PLT0@PC
};
- memcpy(Buf, Inst, sizeof(Inst));
- write32le(Buf + 2, GotPltEntryAddr);
+ memcpy(buf, inst, sizeof(inst));
+ write32le(buf + 2, gotPltEntryAddr);
}
- write32le(Buf + 7, RelOff);
- write32le(Buf + 12, -PltHeaderSize - PltEntrySize * Index - 16);
+ write32le(buf + 7, relOff);
+ write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
}
-int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
- switch (Type) {
+int64_t X86::getImplicitAddend(const uint8_t *buf, RelType type) const {
+ switch (type) {
case R_386_8:
case R_386_PC8:
- return SignExtend64<8>(*Buf);
+ return SignExtend64<8>(*buf);
case R_386_16:
case R_386_PC16:
- return SignExtend64<16>(read16le(Buf));
+ return SignExtend64<16>(read16le(buf));
case R_386_32:
case R_386_GOT32:
case R_386_GOT32X:
@@ -254,28 +254,28 @@ int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
case R_386_PLT32:
case R_386_TLS_LDO_32:
case R_386_TLS_LE:
- return SignExtend64<32>(read32le(Buf));
+ return SignExtend64<32>(read32le(buf));
default:
return 0;
}
}
-void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_386_8:
// R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
// being used for some 16-bit programs such as boot loaders, so
// we want to support them.
- checkIntUInt(Loc, Val, 8, Type);
- *Loc = Val;
+ checkIntUInt(loc, val, 8, type);
+ *loc = val;
break;
case R_386_PC8:
- checkInt(Loc, Val, 8, Type);
- *Loc = Val;
+ checkInt(loc, val, 8, type);
+ *loc = val;
break;
case R_386_16:
- checkIntUInt(Loc, Val, 16, Type);
- write16le(Loc, Val);
+ checkIntUInt(loc, val, 16, type);
+ write16le(loc, val);
break;
case R_386_PC16:
// R_386_PC16 is normally used with 16 bit code. In that situation
@@ -288,8 +288,8 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// current location subtracted from it.
// We just check that Val fits in 17 bits. This misses some cases, but
// should have no false positives.
- checkInt(Loc, Val, 17, Type);
- write16le(Loc, Val);
+ checkInt(loc, val, 17, type);
+ write16le(loc, val);
break;
case R_386_32:
case R_386_GOT32:
@@ -310,86 +310,86 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_386_TLS_LE_32:
case R_386_TLS_TPOFF:
case R_386_TLS_TPOFF32:
- checkInt(Loc, Val, 32, Type);
- write32le(Loc, Val);
+ checkInt(loc, val, 32, type);
+ write32le(loc, val);
break;
default:
llvm_unreachable("unknown relocation");
}
}
-void X86::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
// Convert
// leal x@tlsgd(, %ebx, 1),
// call __tls_get_addr@plt
// to
// movl %gs:0,%eax
// subl $x@ntpoff,%eax
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
0x81, 0xe8, 0, 0, 0, 0, // subl Val(%ebx), %eax
};
- memcpy(Loc - 3, Inst, sizeof(Inst));
- write32le(Loc + 5, Val);
+ memcpy(loc - 3, inst, sizeof(inst));
+ write32le(loc + 5, val);
}
-void X86::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
// Convert
// leal x@tlsgd(, %ebx, 1),
// call __tls_get_addr@plt
// to
// movl %gs:0, %eax
// addl x@gotntpoff(%ebx), %eax
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
0x03, 0x83, 0, 0, 0, 0, // addl Val(%ebx), %eax
};
- memcpy(Loc - 3, Inst, sizeof(Inst));
- write32le(Loc + 5, Val);
+ memcpy(loc - 3, inst, sizeof(inst));
+ write32le(loc + 5, val);
}
// In some conditions, relocations can be optimized to avoid using GOT.
// This function does that for Initial Exec to Local Exec case.
-void X86::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
// Ulrich's document section 6.2 says that @gotntpoff can
// be used with MOVL or ADDL instructions.
// @indntpoff is similar to @gotntpoff, but for use in
// position dependent code.
- uint8_t Reg = (Loc[-1] >> 3) & 7;
+ uint8_t reg = (loc[-1] >> 3) & 7;
- if (Type == R_386_TLS_IE) {
- if (Loc[-1] == 0xa1) {
+ if (type == R_386_TLS_IE) {
+ if (loc[-1] == 0xa1) {
// "movl foo@indntpoff,%eax" -> "movl $foo,%eax"
// This case is different from the generic case below because
// this is a 5 byte instruction while below is 6 bytes.
- Loc[-1] = 0xb8;
- } else if (Loc[-2] == 0x8b) {
+ loc[-1] = 0xb8;
+ } else if (loc[-2] == 0x8b) {
// "movl foo@indntpoff,%reg" -> "movl $foo,%reg"
- Loc[-2] = 0xc7;
- Loc[-1] = 0xc0 | Reg;
+ loc[-2] = 0xc7;
+ loc[-1] = 0xc0 | reg;
} else {
// "addl foo@indntpoff,%reg" -> "addl $foo,%reg"
- Loc[-2] = 0x81;
- Loc[-1] = 0xc0 | Reg;
+ loc[-2] = 0x81;
+ loc[-1] = 0xc0 | reg;
}
} else {
- assert(Type == R_386_TLS_GOTIE);
- if (Loc[-2] == 0x8b) {
+ assert(type == R_386_TLS_GOTIE);
+ if (loc[-2] == 0x8b) {
// "movl foo@gottpoff(%rip),%reg" -> "movl $foo,%reg"
- Loc[-2] = 0xc7;
- Loc[-1] = 0xc0 | Reg;
+ loc[-2] = 0xc7;
+ loc[-1] = 0xc0 | reg;
} else {
// "addl foo@gotntpoff(%rip),%reg" -> "leal foo(%reg),%reg"
- Loc[-2] = 0x8d;
- Loc[-1] = 0x80 | (Reg << 3) | Reg;
+ loc[-2] = 0x8d;
+ loc[-1] = 0x80 | (reg << 3) | reg;
}
}
- write32le(Loc, Val);
+ write32le(loc, val);
}
-void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- if (Type == R_386_TLS_LDO_32) {
- write32le(Loc, Val);
+void X86::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ if (type == R_386_TLS_LDO_32) {
+ write32le(loc, val);
return;
}
@@ -400,45 +400,45 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// movl %gs:0,%eax
// nop
// leal 0(%esi,1),%esi
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0,%eax
0x90, // nop
0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi
};
- memcpy(Loc - 2, Inst, sizeof(Inst));
+ memcpy(loc - 2, inst, sizeof(inst));
}
namespace {
class RetpolinePic : public X86 {
public:
RetpolinePic();
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
};
class RetpolineNoPic : public X86 {
public:
RetpolineNoPic();
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
};
} // namespace
RetpolinePic::RetpolinePic() {
- PltHeaderSize = 48;
- PltEntrySize = 32;
+ pltHeaderSize = 48;
+ pltEntrySize = 32;
}
-void RetpolinePic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
- write32le(Buf, S.getPltVA() + 17);
+void RetpolinePic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
+ write32le(buf, s.getPltVA() + 17);
}
-void RetpolinePic::writePltHeader(uint8_t *Buf) const {
- const uint8_t Insn[] = {
+void RetpolinePic::writePltHeader(uint8_t *buf) const {
+ const uint8_t insn[] = {
0xff, 0xb3, 4, 0, 0, 0, // 0: pushl 4(%ebx)
0x50, // 6: pushl %eax
0x8b, 0x83, 8, 0, 0, 0, // 7: mov 8(%ebx), %eax
@@ -455,13 +455,13 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const {
0xc3, // 2e: ret
0xcc, // 2f: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
}
-void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Insn[] = {
+void RetpolinePic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t insn[] = {
0x50, // pushl %eax
0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax
0xe8, 0, 0, 0, 0, // call plt+0x20
@@ -470,28 +470,28 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
0xe9, 0, 0, 0, 0, // jmp plt+0
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
-
- uint32_t Ebx = In.GotPlt->getVA();
- unsigned Off = PltHeaderSize + PltEntrySize * Index;
- write32le(Buf + 3, GotPltEntryAddr - Ebx);
- write32le(Buf + 8, -Off - 12 + 32);
- write32le(Buf + 13, -Off - 17 + 18);
- write32le(Buf + 18, RelOff);
- write32le(Buf + 23, -Off - 27);
+ memcpy(buf, insn, sizeof(insn));
+
+ uint32_t ebx = in.gotPlt->getVA();
+ unsigned off = pltHeaderSize + pltEntrySize * index;
+ write32le(buf + 3, gotPltEntryAddr - ebx);
+ write32le(buf + 8, -off - 12 + 32);
+ write32le(buf + 13, -off - 17 + 18);
+ write32le(buf + 18, relOff);
+ write32le(buf + 23, -off - 27);
}
RetpolineNoPic::RetpolineNoPic() {
- PltHeaderSize = 48;
- PltEntrySize = 32;
+ pltHeaderSize = 48;
+ pltEntrySize = 32;
}
-void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
- write32le(Buf, S.getPltVA() + 16);
+void RetpolineNoPic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
+ write32le(buf, s.getPltVA() + 16);
}
-void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
- const uint8_t Insn[] = {
+void RetpolineNoPic::writePltHeader(uint8_t *buf) const {
+ const uint8_t insn[] = {
0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4
0x50, // 6: pushl %eax
0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax
@@ -509,17 +509,17 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
0xc3, // 2e: ret
0xcc, // 2f: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
- uint32_t GotPlt = In.GotPlt->getVA();
- write32le(Buf + 2, GotPlt + 4);
- write32le(Buf + 8, GotPlt + 8);
+ uint32_t gotPlt = in.gotPlt->getVA();
+ write32le(buf + 2, gotPlt + 4);
+ write32le(buf + 8, gotPlt + 8);
}
-void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Insn[] = {
+void RetpolineNoPic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t insn[] = {
0x50, // 0: pushl %eax
0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax
0xe8, 0, 0, 0, 0, // 6: call plt+0x20
@@ -529,26 +529,26 @@ void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding
0xcc, // 1f: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
-
- unsigned Off = PltHeaderSize + PltEntrySize * Index;
- write32le(Buf + 2, GotPltEntryAddr);
- write32le(Buf + 7, -Off - 11 + 32);
- write32le(Buf + 12, -Off - 16 + 17);
- write32le(Buf + 17, RelOff);
- write32le(Buf + 22, -Off - 26);
+ memcpy(buf, insn, sizeof(insn));
+
+ unsigned off = pltHeaderSize + pltEntrySize * index;
+ write32le(buf + 2, gotPltEntryAddr);
+ write32le(buf + 7, -off - 11 + 32);
+ write32le(buf + 12, -off - 16 + 17);
+ write32le(buf + 17, relOff);
+ write32le(buf + 22, -off - 26);
}
TargetInfo *elf::getX86TargetInfo() {
- if (Config->ZRetpolineplt) {
- if (Config->Pic) {
- static RetpolinePic T;
- return &T;
+ if (config->zRetpolineplt) {
+ if (config->isPic) {
+ static RetpolinePic t;
+ return &t;
}
- static RetpolineNoPic T;
- return &T;
+ static RetpolineNoPic t;
+ return &t;
}
- static X86 T;
- return &T;
+ static X86 t;
+ return &t;
}
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 33c031c440a..de67aa5c33d 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -25,58 +25,58 @@ namespace {
class X86_64 : public TargetInfo {
public:
X86_64();
- int getTlsGdRelaxSkip(RelType Type) const override;
- RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const override;
- RelType getDynRel(RelType Type) const override;
- void writeGotPltHeader(uint8_t *Buf) const override;
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
- void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
-
- RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const override;
- void relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
- bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const override;
+ int getTlsGdRelaxSkip(RelType type) const override;
+ RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const override;
+ RelType getDynRel(RelType type) const override;
+ void writeGotPltHeader(uint8_t *buf) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
+ void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+
+ RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const override;
+ void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const override;
};
} // namespace
X86_64::X86_64() {
- CopyRel = R_X86_64_COPY;
- GotRel = R_X86_64_GLOB_DAT;
- NoneRel = R_X86_64_NONE;
- PltRel = R_X86_64_JUMP_SLOT;
- RelativeRel = R_X86_64_RELATIVE;
- IRelativeRel = R_X86_64_IRELATIVE;
- SymbolicRel = R_X86_64_64;
- TlsDescRel = R_X86_64_TLSDESC;
- TlsGotRel = R_X86_64_TPOFF64;
- TlsModuleIndexRel = R_X86_64_DTPMOD64;
- TlsOffsetRel = R_X86_64_DTPOFF64;
- PltEntrySize = 16;
- PltHeaderSize = 16;
- TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
+ copyRel = R_X86_64_COPY;
+ gotRel = R_X86_64_GLOB_DAT;
+ noneRel = R_X86_64_NONE;
+ pltRel = R_X86_64_JUMP_SLOT;
+ relativeRel = R_X86_64_RELATIVE;
+ iRelativeRel = R_X86_64_IRELATIVE;
+ symbolicRel = R_X86_64_64;
+ tlsDescRel = R_X86_64_TLSDESC;
+ tlsGotRel = R_X86_64_TPOFF64;
+ tlsModuleIndexRel = R_X86_64_DTPMOD64;
+ tlsOffsetRel = R_X86_64_DTPOFF64;
+ pltEntrySize = 16;
+ pltHeaderSize = 16;
+ trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the large page size (known as a superpage or huge page).
// FreeBSD automatically promotes large, superpage-aligned allocations.
- DefaultImageBase = 0x200000;
+ defaultImageBase = 0x200000;
}
-int X86_64::getTlsGdRelaxSkip(RelType Type) const { return 2; }
+int X86_64::getTlsGdRelaxSkip(RelType type) const { return 2; }
-RelExpr X86_64::getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const {
- if (Type == R_X86_64_GOTTPOFF)
- Config->HasStaticTlsModel = true;
+RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const {
+ if (type == R_X86_64_GOTTPOFF)
+ config->hasStaticTlsModel = true;
- switch (Type) {
+ switch (type) {
case R_X86_64_8:
case R_X86_64_16:
case R_X86_64_32:
@@ -122,62 +122,62 @@ RelExpr X86_64::getRelExpr(RelType Type, const Symbol &S,
case R_X86_64_NONE:
return R_NONE;
default:
- error(getErrorLocation(Loc) + "unknown relocation (" + Twine(Type) +
- ") against symbol " + toString(S));
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
return R_NONE;
}
}
-void X86_64::writeGotPltHeader(uint8_t *Buf) const {
+void X86_64::writeGotPltHeader(uint8_t *buf) const {
// The first entry holds the value of _DYNAMIC. It is not clear why that is
// required, but it is documented in the psabi and the glibc dynamic linker
// seems to use it (note that this is relevant for linking ld.so, not any
// other program).
- write64le(Buf, Main->Dynamic->getVA());
+ write64le(buf, mainPart->dynamic->getVA());
}
-void X86_64::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+void X86_64::writeGotPlt(uint8_t *buf, const Symbol &s) const {
// See comments in X86::writeGotPlt.
- write64le(Buf, S.getPltVA() + 6);
+ write64le(buf, s.getPltVA() + 6);
}
-void X86_64::writePltHeader(uint8_t *Buf) const {
- const uint8_t PltData[] = {
+void X86_64::writePltHeader(uint8_t *buf) const {
+ const uint8_t pltData[] = {
0xff, 0x35, 0, 0, 0, 0, // pushq GOTPLT+8(%rip)
0xff, 0x25, 0, 0, 0, 0, // jmp *GOTPLT+16(%rip)
0x0f, 0x1f, 0x40, 0x00, // nop
};
- memcpy(Buf, PltData, sizeof(PltData));
- uint64_t GotPlt = In.GotPlt->getVA();
- uint64_t Plt = In.Plt->getVA();
- write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
- write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
+ memcpy(buf, pltData, sizeof(pltData));
+ uint64_t gotPlt = in.gotPlt->getVA();
+ uint64_t plt = in.plt->getVA();
+ write32le(buf + 2, gotPlt - plt + 2); // GOTPLT+8
+ write32le(buf + 8, gotPlt - plt + 4); // GOTPLT+16
}
-void X86_64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Inst[] = {
+void X86_64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t inst[] = {
0xff, 0x25, 0, 0, 0, 0, // jmpq *got(%rip)
0x68, 0, 0, 0, 0, // pushq <relocation index>
0xe9, 0, 0, 0, 0, // jmpq plt[0]
};
- memcpy(Buf, Inst, sizeof(Inst));
+ memcpy(buf, inst, sizeof(inst));
- write32le(Buf + 2, GotPltEntryAddr - PltEntryAddr - 6);
- write32le(Buf + 7, Index);
- write32le(Buf + 12, -PltHeaderSize - PltEntrySize * Index - 16);
+ write32le(buf + 2, gotPltEntryAddr - pltEntryAddr - 6);
+ write32le(buf + 7, index);
+ write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
}
-RelType X86_64::getDynRel(RelType Type) const {
- if (Type == R_X86_64_64 || Type == R_X86_64_PC64 || Type == R_X86_64_SIZE32 ||
- Type == R_X86_64_SIZE64)
- return Type;
+RelType X86_64::getDynRel(RelType type) const {
+ if (type == R_X86_64_64 || type == R_X86_64_PC64 || type == R_X86_64_SIZE32 ||
+ type == R_X86_64_SIZE64)
+ return type;
return R_X86_64_NONE;
}
-void X86_64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- if (Type == R_X86_64_TLSGD) {
+void X86_64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ if (type == R_X86_64_TLSGD) {
// Convert
// .byte 0x66
// leaq x@tlsgd(%rip), %rdi
@@ -185,39 +185,39 @@ void X86_64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// rex64
// call __tls_get_addr@plt
// to the following two instructions.
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00,
0x00, 0x00, // mov %fs:0x0,%rax
0x48, 0x8d, 0x80, 0, 0, 0, 0, // lea x@tpoff,%rax
};
- memcpy(Loc - 4, Inst, sizeof(Inst));
+ memcpy(loc - 4, inst, sizeof(inst));
// The original code used a pc relative relocation and so we have to
// compensate for the -4 in had in the addend.
- write32le(Loc + 8, Val + 4);
+ write32le(loc + 8, val + 4);
} else {
// Convert
// lea x@tlsgd(%rip), %rax
// call *(%rax)
// to the following two instructions.
- assert(Type == R_X86_64_GOTPC32_TLSDESC);
- if (memcmp(Loc - 3, "\x48\x8d\x05", 3)) {
- error(getErrorLocation(Loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
+ assert(type == R_X86_64_GOTPC32_TLSDESC);
+ if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
+ error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
"in callq *x@tlsdesc(%rip), %rax");
return;
}
// movq $x@tpoff(%rip),%rax
- Loc[-2] = 0xc7;
- Loc[-1] = 0xc0;
- write32le(Loc, Val + 4);
+ loc[-2] = 0xc7;
+ loc[-1] = 0xc0;
+ write32le(loc, val + 4);
// xchg ax,ax
- Loc[4] = 0x66;
- Loc[5] = 0x90;
+ loc[4] = 0x66;
+ loc[5] = 0x90;
}
}
-void X86_64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- if (Type == R_X86_64_TLSGD) {
+void X86_64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+ if (type == R_X86_64_TLSGD) {
// Convert
// .byte 0x66
// leaq x@tlsgd(%rip), %rdi
@@ -225,96 +225,96 @@ void X86_64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// rex64
// call __tls_get_addr@plt
// to the following two instructions.
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00,
0x00, 0x00, // mov %fs:0x0,%rax
0x48, 0x03, 0x05, 0, 0, 0, 0, // addq x@gottpoff(%rip),%rax
};
- memcpy(Loc - 4, Inst, sizeof(Inst));
+ memcpy(loc - 4, inst, sizeof(inst));
// Both code sequences are PC relatives, but since we are moving the
// constant forward by 8 bytes we have to subtract the value by 8.
- write32le(Loc + 8, Val - 8);
+ write32le(loc + 8, val - 8);
} else {
// Convert
// lea x@tlsgd(%rip), %rax
// call *(%rax)
// to the following two instructions.
- assert(Type == R_X86_64_GOTPC32_TLSDESC);
- if (memcmp(Loc - 3, "\x48\x8d\x05", 3)) {
- error(getErrorLocation(Loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
+ assert(type == R_X86_64_GOTPC32_TLSDESC);
+ if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
+ error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
"in callq *x@tlsdesc(%rip), %rax");
return;
}
// movq x@gottpoff(%rip),%rax
- Loc[-2] = 0x8b;
- write32le(Loc, Val);
+ loc[-2] = 0x8b;
+ write32le(loc, val);
// xchg ax,ax
- Loc[4] = 0x66;
- Loc[5] = 0x90;
+ loc[4] = 0x66;
+ loc[5] = 0x90;
}
}
// In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
// R_X86_64_TPOFF32 so that it does not use GOT.
-void X86_64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- uint8_t *Inst = Loc - 3;
- uint8_t Reg = Loc[-1] >> 3;
- uint8_t *RegSlot = Loc - 1;
+void X86_64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ uint8_t *inst = loc - 3;
+ uint8_t reg = loc[-1] >> 3;
+ uint8_t *regSlot = loc - 1;
// Note that ADD with RSP or R12 is converted to ADD instead of LEA
// because LEA with these registers needs 4 bytes to encode and thus
// wouldn't fit the space.
- if (memcmp(Inst, "\x48\x03\x25", 3) == 0) {
+ if (memcmp(inst, "\x48\x03\x25", 3) == 0) {
// "addq foo@gottpoff(%rip),%rsp" -> "addq $foo,%rsp"
- memcpy(Inst, "\x48\x81\xc4", 3);
- } else if (memcmp(Inst, "\x4c\x03\x25", 3) == 0) {
+ memcpy(inst, "\x48\x81\xc4", 3);
+ } else if (memcmp(inst, "\x4c\x03\x25", 3) == 0) {
// "addq foo@gottpoff(%rip),%r12" -> "addq $foo,%r12"
- memcpy(Inst, "\x49\x81\xc4", 3);
- } else if (memcmp(Inst, "\x4c\x03", 2) == 0) {
+ memcpy(inst, "\x49\x81\xc4", 3);
+ } else if (memcmp(inst, "\x4c\x03", 2) == 0) {
// "addq foo@gottpoff(%rip),%r[8-15]" -> "leaq foo(%r[8-15]),%r[8-15]"
- memcpy(Inst, "\x4d\x8d", 2);
- *RegSlot = 0x80 | (Reg << 3) | Reg;
- } else if (memcmp(Inst, "\x48\x03", 2) == 0) {
+ memcpy(inst, "\x4d\x8d", 2);
+ *regSlot = 0x80 | (reg << 3) | reg;
+ } else if (memcmp(inst, "\x48\x03", 2) == 0) {
// "addq foo@gottpoff(%rip),%reg -> "leaq foo(%reg),%reg"
- memcpy(Inst, "\x48\x8d", 2);
- *RegSlot = 0x80 | (Reg << 3) | Reg;
- } else if (memcmp(Inst, "\x4c\x8b", 2) == 0) {
+ memcpy(inst, "\x48\x8d", 2);
+ *regSlot = 0x80 | (reg << 3) | reg;
+ } else if (memcmp(inst, "\x4c\x8b", 2) == 0) {
// "movq foo@gottpoff(%rip),%r[8-15]" -> "movq $foo,%r[8-15]"
- memcpy(Inst, "\x49\xc7", 2);
- *RegSlot = 0xc0 | Reg;
- } else if (memcmp(Inst, "\x48\x8b", 2) == 0) {
+ memcpy(inst, "\x49\xc7", 2);
+ *regSlot = 0xc0 | reg;
+ } else if (memcmp(inst, "\x48\x8b", 2) == 0) {
// "movq foo@gottpoff(%rip),%reg" -> "movq $foo,%reg"
- memcpy(Inst, "\x48\xc7", 2);
- *RegSlot = 0xc0 | Reg;
+ memcpy(inst, "\x48\xc7", 2);
+ *regSlot = 0xc0 | reg;
} else {
- error(getErrorLocation(Loc - 3) +
+ error(getErrorLocation(loc - 3) +
"R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only");
}
// The original code used a PC relative relocation.
// Need to compensate for the -4 it had in the addend.
- write32le(Loc, Val + 4);
+ write32le(loc, val + 4);
}
-void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
- if (Type == R_X86_64_DTPOFF64) {
- write64le(Loc, Val);
+void X86_64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+ if (type == R_X86_64_DTPOFF64) {
+ write64le(loc, val);
return;
}
- if (Type == R_X86_64_DTPOFF32) {
- write32le(Loc, Val);
+ if (type == R_X86_64_DTPOFF32) {
+ write32le(loc, val);
return;
}
- const uint8_t Inst[] = {
+ const uint8_t inst[] = {
0x66, 0x66, // .word 0x6666
0x66, // .byte 0x66
0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
};
- if (Loc[4] == 0xe8) {
+ if (loc[4] == 0xe8) {
// Convert
// leaq bar@tlsld(%rip), %rdi # 48 8d 3d <Loc>
// callq __tls_get_addr@PLT # e8 <disp32>
@@ -324,11 +324,11 @@ void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// .byte 0x66
// mov %fs:0,%rax
// leaq bar@tpoff(%rax), %rcx
- memcpy(Loc - 3, Inst, sizeof(Inst));
+ memcpy(loc - 3, inst, sizeof(inst));
return;
}
- if (Loc[4] == 0xff && Loc[5] == 0x15) {
+ if (loc[4] == 0xff && loc[5] == 0x15) {
// Convert
// leaq x@tlsld(%rip),%rdi # 48 8d 3d <Loc>
// call *__tls_get_addr@GOTPCREL(%rip) # ff 15 <disp32>
@@ -337,36 +337,36 @@ void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
// movq %fs:0,%rax
// See "Table 11.9: LD -> LE Code Transition (LP64)" in
// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
- Loc[-3] = 0x66;
- memcpy(Loc - 2, Inst, sizeof(Inst));
+ loc[-3] = 0x66;
+ memcpy(loc - 2, inst, sizeof(inst));
return;
}
- error(getErrorLocation(Loc - 3) +
+ error(getErrorLocation(loc - 3) +
"expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
}
-void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- switch (Type) {
+void X86_64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
+ switch (type) {
case R_X86_64_8:
- checkIntUInt(Loc, Val, 8, Type);
- *Loc = Val;
+ checkIntUInt(loc, val, 8, type);
+ *loc = val;
break;
case R_X86_64_PC8:
- checkInt(Loc, Val, 8, Type);
- *Loc = Val;
+ checkInt(loc, val, 8, type);
+ *loc = val;
break;
case R_X86_64_16:
- checkIntUInt(Loc, Val, 16, Type);
- write16le(Loc, Val);
+ checkIntUInt(loc, val, 16, type);
+ write16le(loc, val);
break;
case R_X86_64_PC16:
- checkInt(Loc, Val, 16, Type);
- write16le(Loc, Val);
+ checkInt(loc, val, 16, type);
+ write16le(loc, val);
break;
case R_X86_64_32:
- checkUInt(Loc, Val, 32, Type);
- write32le(Loc, Val);
+ checkUInt(loc, val, 32, type);
+ write32le(loc, val);
break;
case R_X86_64_32S:
case R_X86_64_TPOFF32:
@@ -383,8 +383,8 @@ void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_X86_64_TLSLD:
case R_X86_64_DTPOFF32:
case R_X86_64_SIZE32:
- checkInt(Loc, Val, 32, Type);
- write32le(Loc, Val);
+ checkInt(loc, val, 32, type);
+ write32le(loc, val);
break;
case R_X86_64_64:
case R_X86_64_DTPOFF64:
@@ -393,37 +393,37 @@ void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_X86_64_GOT64:
case R_X86_64_GOTOFF64:
case R_X86_64_GOTPC64:
- write64le(Loc, Val);
+ write64le(loc, val);
break;
default:
llvm_unreachable("unknown relocation");
}
}
-RelExpr X86_64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr RelExpr) const {
- if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX)
- return RelExpr;
- const uint8_t Op = Data[-2];
- const uint8_t ModRm = Data[-1];
+RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr relExpr) const {
+ if (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)
+ return relExpr;
+ const uint8_t op = data[-2];
+ const uint8_t modRm = data[-1];
// FIXME: When PIC is disabled and foo is defined locally in the
// lower 32 bit address space, memory operand in mov can be converted into
// immediate operand. Otherwise, mov must be changed to lea. We support only
// latter relaxation at this moment.
- if (Op == 0x8b)
+ if (op == 0x8b)
return R_RELAX_GOT_PC;
// Relax call and jmp.
- if (Op == 0xff && (ModRm == 0x15 || ModRm == 0x25))
+ if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
return R_RELAX_GOT_PC;
// Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
// If PIC then no relaxation is available.
// We also don't relax test/binop instructions without REX byte,
// they are 32bit operations and not common to have.
- assert(Type == R_X86_64_REX_GOTPCRELX);
- return Config->Pic ? RelExpr : R_RELAX_GOT_PC_NOPIC;
+ assert(type == R_X86_64_REX_GOTPCRELX);
+ return config->isPic ? relExpr : R_RELAX_GOT_PC_NOPIC;
}
// A subset of relaxations can only be applied for no-PIC. This method
@@ -431,11 +431,11 @@ RelExpr X86_64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
// "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)
-static void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
- uint8_t ModRm) {
- const uint8_t Rex = Loc[-3];
+static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
+ uint8_t modRm) {
+ const uint8_t rex = loc[-3];
// Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
- if (Op == 0x85) {
+ if (op == 0x85) {
// See "TEST-Logical Compare" (4-428 Vol. 2B),
// TEST r/m64, r64 uses "full" ModR / M byte (no opcode extension).
@@ -452,11 +452,11 @@ static void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
// 0x38 == 00 111 000 binary.
// We transfer reg2 to reg1 here as operand.
// See "2.1.3 ModR/M and SIB Bytes" (Vol. 2A 2-3).
- Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3; // ModR/M byte.
+ loc[-1] = 0xc0 | (modRm & 0x38) >> 3; // ModR/M byte.
// Change opcode from TEST r/m64, r64 to TEST r/m64, imm32
// See "TEST-Logical Compare" (4-428 Vol. 2B).
- Loc[-2] = 0xf7;
+ loc[-2] = 0xf7;
// Move R bit to the B bit in REX byte.
// REX byte is encoded as 0100WRXB, where
@@ -469,8 +469,8 @@ static void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
// REX.B This 1-bit value is an extension to the MODRM.rm field or the
// SIB.base field.
// See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
- Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
- write32le(Loc, Val);
+ loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+ write32le(loc, val);
return;
}
@@ -480,7 +480,7 @@ static void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
// Convert "binop foo@GOTPCREL(%rip), %reg" to "binop $foo, %reg".
// Logic is close to one for test instruction above, but we also
// write opcode extension here, see below for details.
- Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3 | (Op & 0x3c); // ModR/M byte.
+ loc[-1] = 0xc0 | (modRm & 0x38) >> 3 | (op & 0x3c); // ModR/M byte.
// Primary opcode is 0x81, opcode extension is one of:
// 000b = ADD, 001b is OR, 010b is ADC, 011b is SBB,
@@ -489,67 +489,67 @@ static void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
// See "3.2 INSTRUCTIONS (A-M)" (Vol. 2A 3-15),
// "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
// descriptions about each operation.
- Loc[-2] = 0x81;
- Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
- write32le(Loc, Val);
+ loc[-2] = 0x81;
+ loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+ write32le(loc, val);
}
-void X86_64::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
- const uint8_t Op = Loc[-2];
- const uint8_t ModRm = Loc[-1];
+void X86_64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
+ const uint8_t op = loc[-2];
+ const uint8_t modRm = loc[-1];
// Convert "mov foo@GOTPCREL(%rip),%reg" to "lea foo(%rip),%reg".
- if (Op == 0x8b) {
- Loc[-2] = 0x8d;
- write32le(Loc, Val);
+ if (op == 0x8b) {
+ loc[-2] = 0x8d;
+ write32le(loc, val);
return;
}
- if (Op != 0xff) {
+ if (op != 0xff) {
// We are relaxing a rip relative to an absolute, so compensate
// for the old -4 addend.
- assert(!Config->Pic);
- relaxGotNoPic(Loc, Val + 4, Op, ModRm);
+ assert(!config->isPic);
+ relaxGotNoPic(loc, val + 4, op, modRm);
return;
}
// Convert call/jmp instructions.
- if (ModRm == 0x15) {
+ if (modRm == 0x15) {
// ABI says we can convert "call *foo@GOTPCREL(%rip)" to "nop; call foo".
// Instead we convert to "addr32 call foo" where addr32 is an instruction
// prefix. That makes result expression to be a single instruction.
- Loc[-2] = 0x67; // addr32 prefix
- Loc[-1] = 0xe8; // call
- write32le(Loc, Val);
+ loc[-2] = 0x67; // addr32 prefix
+ loc[-1] = 0xe8; // call
+ write32le(loc, val);
return;
}
// Convert "jmp *foo@GOTPCREL(%rip)" to "jmp foo; nop".
// jmp doesn't return, so it is fine to use nop here, it is just a stub.
- assert(ModRm == 0x25);
- Loc[-2] = 0xe9; // jmp
- Loc[3] = 0x90; // nop
- write32le(Loc - 1, Val + 1);
+ assert(modRm == 0x25);
+ loc[-2] = 0xe9; // jmp
+ loc[3] = 0x90; // nop
+ write32le(loc - 1, val + 1);
}
// A split-stack prologue starts by checking the amount of stack remaining
// in one of two ways:
// A) Comparing of the stack pointer to a field in the tcb.
// B) Or a load of a stack pointer offset with an lea to r10 or r11.
-bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const {
- if (!Config->Is64) {
+bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const {
+ if (!config->is64) {
error("Target doesn't support split stacks.");
return false;
}
- if (Loc + 8 >= End)
+ if (loc + 8 >= end)
return false;
// Replace "cmp %fs:0x70,%rsp" and subsequent branch
// with "stc, nopl 0x0(%rax,%rax,1)"
- if (memcmp(Loc, "\x64\x48\x3b\x24\x25", 5) == 0) {
- memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
+ if (memcmp(loc, "\x64\x48\x3b\x24\x25", 5) == 0) {
+ memcpy(loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
return true;
}
@@ -557,11 +557,11 @@ bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
// be r10 or r11. The lea instruction feeds a subsequent compare which checks
// if there is X available stack space. Making X larger effectively reserves
// that much additional space. The stack grows downward so subtract the value.
- if (memcmp(Loc, "\x4c\x8d\x94\x24", 4) == 0 ||
- memcmp(Loc, "\x4c\x8d\x9c\x24", 4) == 0) {
+ if (memcmp(loc, "\x4c\x8d\x94\x24", 4) == 0 ||
+ memcmp(loc, "\x4c\x8d\x9c\x24", 4) == 0) {
// The offset bytes are encoded four bytes after the start of the
// instruction.
- write32le(Loc + 4, read32le(Loc + 4) - 0x4000);
+ write32le(loc + 4, read32le(loc + 4) - 0x4000);
return true;
}
return false;
@@ -580,33 +580,33 @@ namespace {
class Retpoline : public X86_64 {
public:
Retpoline();
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
};
class RetpolineZNow : public X86_64 {
public:
RetpolineZNow();
- void writeGotPlt(uint8_t *Buf, const Symbol &S) const override {}
- void writePltHeader(uint8_t *Buf) const override;
- void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
- int32_t Index, unsigned RelOff) const override;
+ void writeGotPlt(uint8_t *buf, const Symbol &s) const override {}
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
+ int32_t index, unsigned relOff) const override;
};
} // namespace
Retpoline::Retpoline() {
- PltHeaderSize = 48;
- PltEntrySize = 32;
+ pltHeaderSize = 48;
+ pltEntrySize = 32;
}
-void Retpoline::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
- write64le(Buf, S.getPltVA() + 17);
+void Retpoline::writeGotPlt(uint8_t *buf, const Symbol &s) const {
+ write64le(buf, s.getPltVA() + 17);
}
-void Retpoline::writePltHeader(uint8_t *Buf) const {
- const uint8_t Insn[] = {
+void Retpoline::writePltHeader(uint8_t *buf) const {
+ const uint8_t insn[] = {
0xff, 0x35, 0, 0, 0, 0, // 0: pushq GOTPLT+8(%rip)
0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 6: mov GOTPLT+16(%rip), %r11
0xe8, 0x0e, 0x00, 0x00, 0x00, // d: callq next
@@ -619,18 +619,18 @@ void Retpoline::writePltHeader(uint8_t *Buf) const {
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 25: int3; padding
0xcc, 0xcc, 0xcc, 0xcc, // 2c: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
- uint64_t GotPlt = In.GotPlt->getVA();
- uint64_t Plt = In.Plt->getVA();
- write32le(Buf + 2, GotPlt - Plt - 6 + 8);
- write32le(Buf + 9, GotPlt - Plt - 13 + 16);
+ uint64_t gotPlt = in.gotPlt->getVA();
+ uint64_t plt = in.plt->getVA();
+ write32le(buf + 2, gotPlt - plt - 6 + 8);
+ write32le(buf + 9, gotPlt - plt - 13 + 16);
}
-void Retpoline::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Insn[] = {
+void Retpoline::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t insn[] = {
0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11
0xe8, 0, 0, 0, 0, // 7: callq plt+0x20
0xe9, 0, 0, 0, 0, // c: jmp plt+0x12
@@ -638,24 +638,24 @@ void Retpoline::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
0xe9, 0, 0, 0, 0, // 16: jmp plt+0
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1b: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
- uint64_t Off = PltHeaderSize + PltEntrySize * Index;
+ uint64_t off = pltHeaderSize + pltEntrySize * index;
- write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
- write32le(Buf + 8, -Off - 12 + 32);
- write32le(Buf + 13, -Off - 17 + 18);
- write32le(Buf + 18, Index);
- write32le(Buf + 23, -Off - 27);
+ write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
+ write32le(buf + 8, -off - 12 + 32);
+ write32le(buf + 13, -off - 17 + 18);
+ write32le(buf + 18, index);
+ write32le(buf + 23, -off - 27);
}
RetpolineZNow::RetpolineZNow() {
- PltHeaderSize = 32;
- PltEntrySize = 16;
+ pltHeaderSize = 32;
+ pltEntrySize = 16;
}
-void RetpolineZNow::writePltHeader(uint8_t *Buf) const {
- const uint8_t Insn[] = {
+void RetpolineZNow::writePltHeader(uint8_t *buf) const {
+ const uint8_t insn[] = {
0xe8, 0x0b, 0x00, 0x00, 0x00, // 0: call next
0xf3, 0x90, // 5: loop: pause
0x0f, 0xae, 0xe8, // 7: lfence
@@ -667,35 +667,35 @@ void RetpolineZNow::writePltHeader(uint8_t *Buf) const {
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding
0xcc, // 1f: int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
}
-void RetpolineZNow::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {
- const uint8_t Insn[] = {
+void RetpolineZNow::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {
+ const uint8_t insn[] = {
0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11
0xe9, 0, 0, 0, 0, // jmp plt+0
0xcc, 0xcc, 0xcc, 0xcc, // int3; padding
};
- memcpy(Buf, Insn, sizeof(Insn));
+ memcpy(buf, insn, sizeof(insn));
- write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
- write32le(Buf + 8, -PltHeaderSize - PltEntrySize * Index - 12);
+ write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
+ write32le(buf + 8, -pltHeaderSize - pltEntrySize * index - 12);
}
static TargetInfo *getTargetInfo() {
- if (Config->ZRetpolineplt) {
- if (Config->ZNow) {
- static RetpolineZNow T;
- return &T;
+ if (config->zRetpolineplt) {
+ if (config->zNow) {
+ static RetpolineZNow t;
+ return &t;
}
- static Retpoline T;
- return &T;
+ static Retpoline t;
+ return &t;
}
- static X86_64 T;
- return &T;
+ static X86_64 t;
+ return &t;
}
TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo(); }
diff --git a/lld/ELF/CallGraphSort.cpp b/lld/ELF/CallGraphSort.cpp
index eacaca72d8d..c9a62f69acc 100644
--- a/lld/ELF/CallGraphSort.cpp
+++ b/lld/ELF/CallGraphSort.cpp
@@ -51,24 +51,24 @@ using namespace lld::elf;
namespace {
struct Edge {
- int From;
- uint64_t Weight;
+ int from;
+ uint64_t weight;
};
struct Cluster {
- Cluster(int Sec, size_t S) : Sections{Sec}, Size(S) {}
+ Cluster(int sec, size_t s) : sections{sec}, size(s) {}
double getDensity() const {
- if (Size == 0)
+ if (size == 0)
return 0;
- return double(Weight) / double(Size);
+ return double(weight) / double(size);
}
- std::vector<int> Sections;
- size_t Size = 0;
- uint64_t Weight = 0;
- uint64_t InitialWeight = 0;
- Edge BestPred = {-1, 0};
+ std::vector<int> sections;
+ size_t size = 0;
+ uint64_t weight = 0;
+ uint64_t initialWeight = 0;
+ Edge bestPred = {-1, 0};
};
class CallGraphSort {
@@ -78,8 +78,8 @@ public:
DenseMap<const InputSectionBase *, int> run();
private:
- std::vector<Cluster> Clusters;
- std::vector<const InputSectionBase *> Sections;
+ std::vector<Cluster> clusters;
+ std::vector<const InputSectionBase *> sections;
void groupClusters();
};
@@ -99,23 +99,23 @@ using SectionPair =
// Symbols, and generate a graph between InputSections with the provided
// weights.
CallGraphSort::CallGraphSort() {
- MapVector<SectionPair, uint64_t> &Profile = Config->CallGraphProfile;
- DenseMap<const InputSectionBase *, int> SecToCluster;
-
- auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {
- auto Res = SecToCluster.insert(std::make_pair(IS, Clusters.size()));
- if (Res.second) {
- Sections.push_back(IS);
- Clusters.emplace_back(Clusters.size(), IS->getSize());
+ MapVector<SectionPair, uint64_t> &profile = config->callGraphProfile;
+ DenseMap<const InputSectionBase *, int> secToCluster;
+
+ auto getOrCreateNode = [&](const InputSectionBase *isec) -> int {
+ auto res = secToCluster.insert(std::make_pair(isec, clusters.size()));
+ if (res.second) {
+ sections.push_back(isec);
+ clusters.emplace_back(clusters.size(), isec->getSize());
}
- return Res.first->second;
+ return res.first->second;
};
// Create the graph.
- for (std::pair<SectionPair, uint64_t> &C : Profile) {
- const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);
- const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);
- uint64_t Weight = C.second;
+ for (std::pair<SectionPair, uint64_t> &c : profile) {
+ const auto *fromSB = cast<InputSectionBase>(c.first.first->repl);
+ const auto *toSB = cast<InputSectionBase>(c.first.second->repl);
+ uint64_t weight = c.second;
// Ignore edges between input sections belonging to different output
// sections. This is done because otherwise we would end up with clusters
@@ -123,94 +123,94 @@ CallGraphSort::CallGraphSort() {
// output. This messes with the cluster size and density calculations. We
// would also end up moving input sections in other output sections without
// moving them closer to what calls them.
- if (FromSB->getOutputSection() != ToSB->getOutputSection())
+ if (fromSB->getOutputSection() != toSB->getOutputSection())
continue;
- int From = GetOrCreateNode(FromSB);
- int To = GetOrCreateNode(ToSB);
+ int from = getOrCreateNode(fromSB);
+ int to = getOrCreateNode(toSB);
- Clusters[To].Weight += Weight;
+ clusters[to].weight += weight;
- if (From == To)
+ if (from == to)
continue;
// Remember the best edge.
- Cluster &ToC = Clusters[To];
- if (ToC.BestPred.From == -1 || ToC.BestPred.Weight < Weight) {
- ToC.BestPred.From = From;
- ToC.BestPred.Weight = Weight;
+ Cluster &toC = clusters[to];
+ if (toC.bestPred.from == -1 || toC.bestPred.weight < weight) {
+ toC.bestPred.from = from;
+ toC.bestPred.weight = weight;
}
}
- for (Cluster &C : Clusters)
- C.InitialWeight = C.Weight;
+ for (Cluster &c : clusters)
+ c.initialWeight = c.weight;
}
// It's bad to merge clusters which would degrade the density too much.
-static bool isNewDensityBad(Cluster &A, Cluster &B) {
- double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);
- return NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION;
+static bool isNewDensityBad(Cluster &a, Cluster &b) {
+ double newDensity = double(a.weight + b.weight) / double(a.size + b.size);
+ return newDensity < a.getDensity() / MAX_DENSITY_DEGRADATION;
}
-static void mergeClusters(Cluster &Into, Cluster &From) {
- Into.Sections.insert(Into.Sections.end(), From.Sections.begin(),
- From.Sections.end());
- Into.Size += From.Size;
- Into.Weight += From.Weight;
- From.Sections.clear();
- From.Size = 0;
- From.Weight = 0;
+static void mergeClusters(Cluster &into, Cluster &from) {
+ into.sections.insert(into.sections.end(), from.sections.begin(),
+ from.sections.end());
+ into.size += from.size;
+ into.weight += from.weight;
+ from.sections.clear();
+ from.size = 0;
+ from.weight = 0;
}
// Group InputSections into clusters using the Call-Chain Clustering heuristic
// then sort the clusters by density.
void CallGraphSort::groupClusters() {
- std::vector<int> SortedSecs(Clusters.size());
- std::vector<Cluster *> SecToCluster(Clusters.size());
+ std::vector<int> sortedSecs(clusters.size());
+ std::vector<Cluster *> secToCluster(clusters.size());
- for (size_t I = 0; I < Clusters.size(); ++I) {
- SortedSecs[I] = I;
- SecToCluster[I] = &Clusters[I];
+ for (size_t i = 0; i < clusters.size(); ++i) {
+ sortedSecs[i] = i;
+ secToCluster[i] = &clusters[i];
}
- llvm::stable_sort(SortedSecs, [&](int A, int B) {
- return Clusters[A].getDensity() > Clusters[B].getDensity();
+ llvm::stable_sort(sortedSecs, [&](int a, int b) {
+ return clusters[a].getDensity() > clusters[b].getDensity();
});
- for (int SI : SortedSecs) {
+ for (int si : sortedSecs) {
// Clusters[SI] is the same as SecToClusters[SI] here because it has not
// been merged into another cluster yet.
- Cluster &C = Clusters[SI];
+ Cluster &c = clusters[si];
// Don't consider merging if the edge is unlikely.
- if (C.BestPred.From == -1 || C.BestPred.Weight * 10 <= C.InitialWeight)
+ if (c.bestPred.from == -1 || c.bestPred.weight * 10 <= c.initialWeight)
continue;
- Cluster *PredC = SecToCluster[C.BestPred.From];
- if (PredC == &C)
+ Cluster *predC = secToCluster[c.bestPred.from];
+ if (predC == &c)
continue;
- if (C.Size + PredC->Size > MAX_CLUSTER_SIZE)
+ if (c.size + predC->size > MAX_CLUSTER_SIZE)
continue;
- if (isNewDensityBad(*PredC, C))
+ if (isNewDensityBad(*predC, c))
continue;
// NOTE: Consider using a disjoint-set to track section -> cluster mapping
// if this is ever slow.
- for (int SI : C.Sections)
- SecToCluster[SI] = PredC;
+ for (int si : c.sections)
+ secToCluster[si] = predC;
- mergeClusters(*PredC, C);
+ mergeClusters(*predC, c);
}
// Remove empty or dead nodes. Invalidates all cluster indices.
- llvm::erase_if(Clusters, [](const Cluster &C) {
- return C.Size == 0 || C.Sections.empty();
+ llvm::erase_if(clusters, [](const Cluster &c) {
+ return c.size == 0 || c.sections.empty();
});
// Sort by density.
- llvm::stable_sort(Clusters, [](const Cluster &A, const Cluster &B) {
- return A.getDensity() > B.getDensity();
+ llvm::stable_sort(clusters, [](const Cluster &a, const Cluster &b) {
+ return a.getDensity() > b.getDensity();
});
}
@@ -218,35 +218,35 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
groupClusters();
// Generate order.
- DenseMap<const InputSectionBase *, int> OrderMap;
- ssize_t CurOrder = 1;
-
- for (const Cluster &C : Clusters)
- for (int SecIndex : C.Sections)
- OrderMap[Sections[SecIndex]] = CurOrder++;
-
- if (!Config->PrintSymbolOrder.empty()) {
- std::error_code EC;
- raw_fd_ostream OS(Config->PrintSymbolOrder, EC, sys::fs::F_None);
- if (EC) {
- error("cannot open " + Config->PrintSymbolOrder + ": " + EC.message());
- return OrderMap;
+ DenseMap<const InputSectionBase *, int> orderMap;
+ ssize_t curOrder = 1;
+
+ for (const Cluster &c : clusters)
+ for (int secIndex : c.sections)
+ orderMap[sections[secIndex]] = curOrder++;
+
+ if (!config->printSymbolOrder.empty()) {
+ std::error_code ec;
+ raw_fd_ostream os(config->printSymbolOrder, ec, sys::fs::F_None);
+ if (ec) {
+ error("cannot open " + config->printSymbolOrder + ": " + ec.message());
+ return orderMap;
}
// Print the symbols ordered by C3, in the order of increasing CurOrder
// Instead of sorting all the OrderMap, just repeat the loops above.
- for (const Cluster &C : Clusters)
- for (int SecIndex : C.Sections)
+ for (const Cluster &c : clusters)
+ for (int secIndex : c.sections)
// Search all the symbols in the file of the section
// and find out a Defined symbol with name that is within the section.
- for (Symbol *Sym: Sections[SecIndex]->File->getSymbols())
- if (!Sym->isSection()) // Filter out section-type symbols here.
- if (auto *D = dyn_cast<Defined>(Sym))
- if (Sections[SecIndex] == D->Section)
- OS << Sym->getName() << "\n";
+ for (Symbol *sym: sections[secIndex]->file->getSymbols())
+ if (!sym->isSection()) // Filter out section-type symbols here.
+ if (auto *d = dyn_cast<Defined>(sym))
+ if (sections[secIndex] == d->section)
+ os << sym->getName() << "\n";
}
- return OrderMap;
+ return orderMap;
}
// Sort sections by the profile data provided by -callgraph-profile-file
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 3b3087987e6..54991c72778 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -62,17 +62,17 @@ enum class Target2Policy { Abs, Rel, GotRel };
enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
struct SymbolVersion {
- llvm::StringRef Name;
- bool IsExternCpp;
- bool HasWildcard;
+ llvm::StringRef name;
+ bool isExternCpp;
+ bool hasWildcard;
};
// This struct contains symbols version definition that
// can be found in version script if it is used for link.
struct VersionDefinition {
- llvm::StringRef Name;
- uint16_t Id = 0;
- std::vector<SymbolVersion> Globals;
+ llvm::StringRef name;
+ uint16_t id = 0;
+ std::vector<SymbolVersion> globals;
};
// This struct contains the global configuration for the linker.
@@ -80,177 +80,177 @@ struct VersionDefinition {
// and such fields have the same name as the corresponding options.
// Most fields are initialized by the driver.
struct Configuration {
- uint8_t OSABI = 0;
- uint32_t AndFeatures = 0;
- llvm::CachePruningPolicy ThinLTOCachePolicy;
- llvm::StringMap<uint64_t> SectionStartMap;
- llvm::StringRef Chroot;
- llvm::StringRef DynamicLinker;
- llvm::StringRef DwoDir;
- llvm::StringRef Entry;
- llvm::StringRef Emulation;
- llvm::StringRef Fini;
- llvm::StringRef Init;
- llvm::StringRef LTOAAPipeline;
- llvm::StringRef LTOCSProfileFile;
- llvm::StringRef LTONewPmPasses;
- llvm::StringRef LTOObjPath;
- llvm::StringRef LTOSampleProfile;
- llvm::StringRef MapFile;
- llvm::StringRef OutputFile;
- llvm::StringRef OptRemarksFilename;
- llvm::StringRef OptRemarksPasses;
- llvm::StringRef OptRemarksFormat;
- llvm::StringRef ProgName;
- llvm::StringRef PrintSymbolOrder;
- llvm::StringRef SoName;
- llvm::StringRef Sysroot;
- llvm::StringRef ThinLTOCacheDir;
- llvm::StringRef ThinLTOIndexOnlyArg;
- std::pair<llvm::StringRef, llvm::StringRef> ThinLTOObjectSuffixReplace;
- std::pair<llvm::StringRef, llvm::StringRef> ThinLTOPrefixReplace;
- std::string Rpath;
- std::vector<VersionDefinition> VersionDefinitions;
- std::vector<llvm::StringRef> AuxiliaryList;
- std::vector<llvm::StringRef> FilterList;
- std::vector<llvm::StringRef> SearchPaths;
- std::vector<llvm::StringRef> SymbolOrderingFile;
- std::vector<llvm::StringRef> Undefined;
- std::vector<SymbolVersion> DynamicList;
- std::vector<SymbolVersion> VersionScriptGlobals;
- std::vector<SymbolVersion> VersionScriptLocals;
- std::vector<uint8_t> BuildIdVector;
+ uint8_t osabi = 0;
+ uint32_t andFeatures = 0;
+ llvm::CachePruningPolicy thinLTOCachePolicy;
+ llvm::StringMap<uint64_t> sectionStartMap;
+ llvm::StringRef chroot;
+ llvm::StringRef dynamicLinker;
+ llvm::StringRef dwoDir;
+ llvm::StringRef entry;
+ llvm::StringRef emulation;
+ llvm::StringRef fini;
+ llvm::StringRef init;
+ llvm::StringRef ltoAAPipeline;
+ llvm::StringRef ltoCSProfileFile;
+ llvm::StringRef ltoNewPmPasses;
+ llvm::StringRef ltoObjPath;
+ llvm::StringRef ltoSampleProfile;
+ llvm::StringRef mapFile;
+ llvm::StringRef outputFile;
+ llvm::StringRef optRemarksFilename;
+ llvm::StringRef optRemarksPasses;
+ llvm::StringRef optRemarksFormat;
+ llvm::StringRef progName;
+ llvm::StringRef printSymbolOrder;
+ llvm::StringRef soName;
+ llvm::StringRef sysroot;
+ llvm::StringRef thinLTOCacheDir;
+ llvm::StringRef thinLTOIndexOnlyArg;
+ std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
+ std::pair<llvm::StringRef, llvm::StringRef> thinLTOPrefixReplace;
+ std::string rpath;
+ std::vector<VersionDefinition> versionDefinitions;
+ std::vector<llvm::StringRef> auxiliaryList;
+ std::vector<llvm::StringRef> filterList;
+ std::vector<llvm::StringRef> searchPaths;
+ std::vector<llvm::StringRef> symbolOrderingFile;
+ std::vector<llvm::StringRef> undefined;
+ std::vector<SymbolVersion> dynamicList;
+ std::vector<SymbolVersion> versionScriptGlobals;
+ std::vector<SymbolVersion> versionScriptLocals;
+ std::vector<uint8_t> buildIdVector;
llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
uint64_t>
- CallGraphProfile;
- bool AllowMultipleDefinition;
- bool AllowShlibUndefined;
- bool AndroidPackDynRelocs;
- bool ARMHasBlx = false;
- bool ARMHasMovtMovw = false;
- bool ARMJ1J2BranchEncoding = false;
- bool AsNeeded = false;
- bool Bsymbolic;
- bool BsymbolicFunctions;
- bool CallGraphProfileSort;
- bool CheckSections;
- bool CompressDebugSections;
- bool Cref;
- bool DefineCommon;
- bool Demangle = true;
- bool DependentLibraries;
- bool DisableVerify;
- bool EhFrameHdr;
- bool EmitLLVM;
- bool EmitRelocs;
- bool EnableNewDtags;
- bool ExecuteOnly;
- bool ExportDynamic;
- bool FixCortexA53Errata843419;
- bool ForceBTI;
- bool FormatBinary = false;
- bool RequireCET;
- bool GcSections;
- bool GdbIndex;
- bool GnuHash = false;
- bool GnuUnique;
- bool HasDynamicList = false;
- bool HasDynSymTab;
- bool IgnoreDataAddressEquality;
- bool IgnoreFunctionAddressEquality;
- bool LTOCSProfileGenerate;
- bool LTODebugPassManager;
- bool LTONewPassManager;
- bool MergeArmExidx;
- bool MipsN32Abi = false;
- bool Nmagic;
- bool NoinhibitExec;
- bool Nostdlib;
- bool OFormatBinary;
- bool Omagic;
- bool OptRemarksWithHotness;
- bool PacPlt;
- bool PicThunk;
- bool Pie;
- bool PrintGcSections;
- bool PrintIcfSections;
- bool Relocatable;
- bool RelrPackDynRelocs;
- bool SaveTemps;
- bool SingleRoRx;
- bool Shared;
- bool Static = false;
- bool SysvHash = false;
- bool Target1Rel;
- bool Trace;
- bool ThinLTOEmitImportsFiles;
- bool ThinLTOIndexOnly;
- bool TocOptimize;
- bool UndefinedVersion;
- bool UseAndroidRelrTags = false;
- bool WarnBackrefs;
- bool WarnCommon;
- bool WarnIfuncTextrel;
- bool WarnMissingEntry;
- bool WarnSymbolOrdering;
- bool WriteAddends;
- bool ZCombreloc;
- bool ZCopyreloc;
- bool ZExecstack;
- bool ZGlobal;
- bool ZHazardplt;
- bool ZIfuncNoplt;
- bool ZInitfirst;
- bool ZInterpose;
- bool ZKeepTextSectionPrefix;
- bool ZNodefaultlib;
- bool ZNodelete;
- bool ZNodlopen;
- bool ZNow;
- bool ZOrigin;
- bool ZRelro;
- bool ZRodynamic;
- bool ZText;
- bool ZRetpolineplt;
- bool ZWxneeded;
- DiscardPolicy Discard;
- ICFLevel ICF;
- OrphanHandlingPolicy OrphanHandling;
- SortSectionPolicy SortSection;
- StripPolicy Strip;
- UnresolvedPolicy UnresolvedSymbols;
- Target2Policy Target2;
- ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
- BuildIdKind BuildId = BuildIdKind::None;
- ELFKind EKind = ELFNoneKind;
- uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
- uint16_t EMachine = llvm::ELF::EM_NONE;
- llvm::Optional<uint64_t> ImageBase;
- uint64_t CommonPageSize;
- uint64_t MaxPageSize;
- uint64_t MipsGotSize;
- uint64_t ZStackSize;
- unsigned LTOPartitions;
- unsigned LTOO;
- unsigned Optimize;
- unsigned ThinLTOJobs;
- int32_t SplitStackAdjustSize;
+ callGraphProfile;
+ bool allowMultipleDefinition;
+ bool allowShlibUndefined;
+ bool androidPackDynRelocs;
+ bool armHasBlx = false;
+ bool armHasMovtMovw = false;
+ bool armJ1J2BranchEncoding = false;
+ bool asNeeded = false;
+ bool bsymbolic;
+ bool bsymbolicFunctions;
+ bool callGraphProfileSort;
+ bool checkSections;
+ bool compressDebugSections;
+ bool cref;
+ bool defineCommon;
+ bool demangle = true;
+ bool dependentLibraries;
+ bool disableVerify;
+ bool ehFrameHdr;
+ bool emitLLVM;
+ bool emitRelocs;
+ bool enableNewDtags;
+ bool executeOnly;
+ bool exportDynamic;
+ bool fixCortexA53Errata843419;
+ bool forceBTI;
+ bool formatBinary = false;
+ bool requireCET;
+ bool gcSections;
+ bool gdbIndex;
+ bool gnuHash = false;
+ bool gnuUnique;
+ bool hasDynamicList = false;
+ bool hasDynSymTab;
+ bool ignoreDataAddressEquality;
+ bool ignoreFunctionAddressEquality;
+ bool ltoCSProfileGenerate;
+ bool ltoDebugPassManager;
+ bool ltoNewPassManager;
+ bool mergeArmExidx;
+ bool mipsN32Abi = false;
+ bool nmagic;
+ bool noinhibitExec;
+ bool nostdlib;
+ bool oFormatBinary;
+ bool omagic;
+ bool optRemarksWithHotness;
+ bool pacPlt;
+ bool picThunk;
+ bool pie;
+ bool printGcSections;
+ bool printIcfSections;
+ bool relocatable;
+ bool relrPackDynRelocs;
+ bool saveTemps;
+ bool singleRoRx;
+ bool shared;
+ bool isStatic = false;
+ bool sysvHash = false;
+ bool target1Rel;
+ bool trace;
+ bool thinLTOEmitImportsFiles;
+ bool thinLTOIndexOnly;
+ bool tocOptimize;
+ bool undefinedVersion;
+ bool useAndroidRelrTags = false;
+ bool warnBackrefs;
+ bool warnCommon;
+ bool warnIfuncTextrel;
+ bool warnMissingEntry;
+ bool warnSymbolOrdering;
+ bool writeAddends;
+ bool zCombreloc;
+ bool zCopyreloc;
+ bool zExecstack;
+ bool zGlobal;
+ bool zHazardplt;
+ bool zIfuncNoplt;
+ bool zInitfirst;
+ bool zInterpose;
+ bool zKeepTextSectionPrefix;
+ bool zNodefaultlib;
+ bool zNodelete;
+ bool zNodlopen;
+ bool zNow;
+ bool zOrigin;
+ bool zRelro;
+ bool zRodynamic;
+ bool zText;
+ bool zRetpolineplt;
+ bool zWxneeded;
+ DiscardPolicy discard;
+ ICFLevel icf;
+ OrphanHandlingPolicy orphanHandling;
+ SortSectionPolicy sortSection;
+ StripPolicy strip;
+ UnresolvedPolicy unresolvedSymbols;
+ Target2Policy target2;
+ ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default;
+ BuildIdKind buildId = BuildIdKind::None;
+ ELFKind ekind = ELFNoneKind;
+ uint16_t defaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
+ uint16_t emachine = llvm::ELF::EM_NONE;
+ llvm::Optional<uint64_t> imageBase;
+ uint64_t commonPageSize;
+ uint64_t maxPageSize;
+ uint64_t mipsGotSize;
+ uint64_t zStackSize;
+ unsigned ltoPartitions;
+ unsigned ltoo;
+ unsigned optimize;
+ unsigned thinLTOJobs;
+ int32_t splitStackAdjustSize;
// The following config options do not directly correspond to any
// particualr command line options.
// True if we need to pass through relocations in input files to the
// output file. Usually false because we consume relocations.
- bool CopyRelocs;
+ bool copyRelocs;
// True if the target is ELF64. False if ELF32.
- bool Is64;
+ bool is64;
// True if the target is little-endian. False if big-endian.
- bool IsLE;
+ bool isLE;
// endianness::little if IsLE is true. endianness::big otherwise.
- llvm::support::endianness Endianness;
+ llvm::support::endianness endianness;
// True if the target is the little-endian MIPS64.
//
@@ -264,7 +264,7 @@ struct Configuration {
// name whatever that means. A fun hypothesis is that "EL" is short for
// little-endian written in the little-endian order, but I don't know
// if that's true.)
- bool IsMips64EL;
+ bool isMips64EL;
// True if we need to set the DF_STATIC_TLS flag to an output file,
// which works as a hint to the dynamic loader that the file contains
@@ -278,10 +278,10 @@ struct Configuration {
// Since the flag is updated by multi-threaded code, we use std::atomic.
// (Writing to a variable is not considered thread-safe even if the
// variable is boolean and we always set the same value from all threads.)
- std::atomic<bool> HasStaticTlsModel{false};
+ std::atomic<bool> hasStaticTlsModel{false};
// Holds set of ELF header flags for the target.
- uint32_t EFlags = 0;
+ uint32_t eflags = 0;
// The ELF spec defines two types of relocation table entries, RELA and
// REL. RELA is a triplet of (offset, info, addend) while REL is a
@@ -297,23 +297,23 @@ struct Configuration {
// Each ABI defines its relocation type. IsRela is true if target
// uses RELA. As far as we know, all 64-bit ABIs are using RELA. A
// few 32-bit ABIs are using RELA too.
- bool IsRela;
+ bool isRela;
// True if we are creating position-independent code.
- bool Pic;
+ bool isPic;
// 4 for ELF32, 8 for ELF64.
- int Wordsize;
+ int wordsize;
};
// The only instance of Configuration struct.
-extern Configuration *Config;
+extern Configuration *config;
-static inline void errorOrWarn(const Twine &Msg) {
- if (!Config->NoinhibitExec)
- error(Msg);
+static inline void errorOrWarn(const Twine &msg) {
+ if (!config->noinhibitExec)
+ error(msg);
else
- warn(Msg);
+ warn(msg);
}
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index 58ac056b7e2..ab06d066b07 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -25,32 +25,32 @@ using namespace llvm::object;
using namespace lld;
using namespace lld::elf;
-template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) {
- for (InputSectionBase *Sec : Obj->getSections()) {
- if (!Sec)
+template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
+ for (InputSectionBase *sec : obj->getSections()) {
+ if (!sec)
continue;
- if (LLDDWARFSection *M =
- StringSwitch<LLDDWARFSection *>(Sec->Name)
- .Case(".debug_addr", &AddrSection)
- .Case(".debug_gnu_pubnames", &GnuPubNamesSection)
- .Case(".debug_gnu_pubtypes", &GnuPubTypesSection)
- .Case(".debug_info", &InfoSection)
- .Case(".debug_ranges", &RangeSection)
- .Case(".debug_rnglists", &RngListsSection)
- .Case(".debug_line", &LineSection)
+ if (LLDDWARFSection *m =
+ StringSwitch<LLDDWARFSection *>(sec->name)
+ .Case(".debug_addr", &addrSection)
+ .Case(".debug_gnu_pubnames", &gnuPubNamesSection)
+ .Case(".debug_gnu_pubtypes", &gnuPubTypesSection)
+ .Case(".debug_info", &infoSection)
+ .Case(".debug_ranges", &rangeSection)
+ .Case(".debug_rnglists", &rngListsSection)
+ .Case(".debug_line", &lineSection)
.Default(nullptr)) {
- M->Data = toStringRef(Sec->data());
- M->Sec = Sec;
+ m->Data = toStringRef(sec->data());
+ m->sec = sec;
continue;
}
- if (Sec->Name == ".debug_abbrev")
- AbbrevSection = toStringRef(Sec->data());
- else if (Sec->Name == ".debug_str")
- StrSection = toStringRef(Sec->data());
- else if (Sec->Name == ".debug_line_str")
- LineStringSection = toStringRef(Sec->data());
+ if (sec->name == ".debug_abbrev")
+ abbrevSection = toStringRef(sec->data());
+ else if (sec->name == ".debug_str")
+ strSection = toStringRef(sec->data());
+ else if (sec->name == ".debug_line_str")
+ lineStringSection = toStringRef(sec->data());
}
}
@@ -58,17 +58,17 @@ namespace {
template <class RelTy> struct LLDRelocationResolver {
// In the ELF ABIs, S sepresents the value of the symbol in the relocation
// entry. For Rela, the addend is stored as part of the relocation entry.
- static uint64_t resolve(object::RelocationRef Ref, uint64_t S,
+ static uint64_t resolve(object::RelocationRef ref, uint64_t s,
uint64_t /* A */) {
- return S + Ref.getRawDataRefImpl().p;
+ return s + ref.getRawDataRefImpl().p;
}
};
template <class ELFT> struct LLDRelocationResolver<Elf_Rel_Impl<ELFT, false>> {
// For Rel, the addend A is supplied by the caller.
- static uint64_t resolve(object::RelocationRef /*Ref*/, uint64_t S,
- uint64_t A) {
- return S + A;
+ static uint64_t resolve(object::RelocationRef /*Ref*/, uint64_t s,
+ uint64_t a) {
+ return s + a;
}
};
} // namespace
@@ -79,47 +79,47 @@ template <class ELFT> struct LLDRelocationResolver<Elf_Rel_Impl<ELFT, false>> {
template <class ELFT>
template <class RelTy>
Optional<RelocAddrEntry>
-LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos,
- ArrayRef<RelTy> Rels) const {
- auto It =
- partition_point(Rels, [=](const RelTy &A) { return A.r_offset < Pos; });
- if (It == Rels.end() || It->r_offset != Pos)
+LLDDwarfObj<ELFT>::findAux(const InputSectionBase &sec, uint64_t pos,
+ ArrayRef<RelTy> rels) const {
+ auto it =
+ partition_point(rels, [=](const RelTy &a) { return a.r_offset < pos; });
+ if (it == rels.end() || it->r_offset != pos)
return None;
- const RelTy &Rel = *It;
+ const RelTy &rel = *it;
- const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
- uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
- const typename ELFT::Sym &Sym = File->template getELFSyms<ELFT>()[SymIndex];
- uint32_t SecIndex = File->getSectionIndex(Sym);
+ const ObjFile<ELFT> *file = sec.getFile<ELFT>();
+ uint32_t symIndex = rel.getSymbol(config->isMips64EL);
+ const typename ELFT::Sym &sym = file->template getELFSyms<ELFT>()[symIndex];
+ uint32_t secIndex = file->getSectionIndex(sym);
// An undefined symbol may be a symbol defined in a discarded section. We
// shall still resolve it. This is important for --gdb-index: the end address
// offset of an entry in .debug_ranges is relocated. If it is not resolved,
// its zero value will terminate the decoding of .debug_ranges prematurely.
- Symbol &S = File->getRelocTargetSym(Rel);
- uint64_t Val = 0;
- if (auto *DR = dyn_cast<Defined>(&S)) {
- Val = DR->Value;
+ Symbol &s = file->getRelocTargetSym(rel);
+ uint64_t val = 0;
+ if (auto *dr = dyn_cast<Defined>(&s)) {
+ val = dr->value;
// FIXME: We should be consistent about always adding the file
// offset or not.
- if (DR->Section->Flags & ELF::SHF_ALLOC)
- Val += cast<InputSection>(DR->Section)->getOffsetInFile();
+ if (dr->section->flags & ELF::SHF_ALLOC)
+ val += cast<InputSection>(dr->section)->getOffsetInFile();
}
- DataRefImpl D;
- D.p = getAddend<ELFT>(Rel);
- return RelocAddrEntry{SecIndex, RelocationRef(D, nullptr),
- LLDRelocationResolver<RelTy>::resolve, Val};
+ DataRefImpl d;
+ d.p = getAddend<ELFT>(rel);
+ return RelocAddrEntry{secIndex, RelocationRef(d, nullptr),
+ LLDRelocationResolver<RelTy>::resolve, val};
}
template <class ELFT>
-Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &S,
- uint64_t Pos) const {
- auto &Sec = static_cast<const LLDDWARFSection &>(S);
- if (Sec.Sec->AreRelocsRela)
- return findAux(*Sec.Sec, Pos, Sec.Sec->template relas<ELFT>());
- return findAux(*Sec.Sec, Pos, Sec.Sec->template rels<ELFT>());
+Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &s,
+ uint64_t pos) const {
+ auto &sec = static_cast<const LLDDWARFSection &>(s);
+ if (sec.sec->areRelocsRela)
+ return findAux(*sec.sec, pos, sec.sec->template relas<ELFT>());
+ return findAux(*sec.sec, pos, sec.sec->template rels<ELFT>());
}
template class elf::LLDDwarfObj<ELF32LE>;
diff --git a/lld/ELF/DWARF.h b/lld/ELF/DWARF.h
index 09796158e32..42602294500 100644
--- a/lld/ELF/DWARF.h
+++ b/lld/ELF/DWARF.h
@@ -20,70 +20,70 @@ namespace elf {
class InputSection;
struct LLDDWARFSection final : public llvm::DWARFSection {
- InputSectionBase *Sec = nullptr;
+ InputSectionBase *sec = nullptr;
};
template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject {
public:
- explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
+ explicit LLDDwarfObj(ObjFile<ELFT> *obj);
void forEachInfoSections(
- llvm::function_ref<void(const llvm::DWARFSection &)> F) const override {
- F(InfoSection);
+ llvm::function_ref<void(const llvm::DWARFSection &)> f) const override {
+ f(infoSection);
}
const llvm::DWARFSection &getRangeSection() const override {
- return RangeSection;
+ return rangeSection;
}
const llvm::DWARFSection &getRnglistsSection() const override {
- return RngListsSection;
+ return rngListsSection;
}
const llvm::DWARFSection &getLineSection() const override {
- return LineSection;
+ return lineSection;
}
const llvm::DWARFSection &getAddrSection() const override {
- return AddrSection;
+ return addrSection;
}
const llvm::DWARFSection &getGnuPubNamesSection() const override {
- return GnuPubNamesSection;
+ return gnuPubNamesSection;
}
const llvm::DWARFSection &getGnuPubTypesSection() const override {
- return GnuPubTypesSection;
+ return gnuPubTypesSection;
}
StringRef getFileName() const override { return ""; }
- StringRef getAbbrevSection() const override { return AbbrevSection; }
- StringRef getStringSection() const override { return StrSection; }
- StringRef getLineStringSection() const override { return LineStringSection; }
+ StringRef getAbbrevSection() const override { return abbrevSection; }
+ StringRef getStringSection() const override { return strSection; }
+ StringRef getLineStringSection() const override { return lineStringSection; }
bool isLittleEndian() const override {
return ELFT::TargetEndianness == llvm::support::little;
}
- llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
- uint64_t Pos) const override;
+ llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &sec,
+ uint64_t pos) const override;
private:
template <class RelTy>
- llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &Sec,
- uint64_t Pos,
- ArrayRef<RelTy> Rels) const;
-
- LLDDWARFSection GnuPubNamesSection;
- LLDDWARFSection GnuPubTypesSection;
- LLDDWARFSection InfoSection;
- LLDDWARFSection RangeSection;
- LLDDWARFSection RngListsSection;
- LLDDWARFSection LineSection;
- LLDDWARFSection AddrSection;
- StringRef AbbrevSection;
- StringRef StrSection;
- StringRef LineStringSection;
+ llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &sec,
+ uint64_t pos,
+ ArrayRef<RelTy> rels) const;
+
+ LLDDWARFSection gnuPubNamesSection;
+ LLDDWARFSection gnuPubTypesSection;
+ LLDDWARFSection infoSection;
+ LLDDWARFSection rangeSection;
+ LLDDWARFSection rngListsSection;
+ LLDDWARFSection lineSection;
+ LLDDWARFSection addrSection;
+ StringRef abbrevSection;
+ StringRef strSection;
+ StringRef lineStringSection;
};
} // namespace elf
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 85cfdca2dc2..77ef2ba5f12 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -68,49 +68,49 @@ using namespace llvm::support;
using namespace lld;
using namespace lld::elf;
-Configuration *elf::Config;
-LinkerDriver *elf::Driver;
+Configuration *elf::config;
+LinkerDriver *elf::driver;
-static void setConfigs(opt::InputArgList &Args);
-static void readConfigs(opt::InputArgList &Args);
+static void setConfigs(opt::InputArgList &args);
+static void readConfigs(opt::InputArgList &args);
-bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
- raw_ostream &Error) {
- errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
+bool elf::link(ArrayRef<const char *> args, bool canExitEarly,
+ raw_ostream &error) {
+ errorHandler().LogName = args::getFilenameWithoutExe(args[0]);
errorHandler().ErrorLimitExceededMsg =
"too many errors emitted, stopping now (use "
"-error-limit=0 to see all errors)";
- errorHandler().ErrorOS = &Error;
- errorHandler().ExitEarly = CanExitEarly;
- errorHandler().ColorDiagnostics = Error.has_colors();
+ errorHandler().ErrorOS = &error;
+ errorHandler().ExitEarly = canExitEarly;
+ errorHandler().ColorDiagnostics = error.has_colors();
- InputSections.clear();
- OutputSections.clear();
- BinaryFiles.clear();
- BitcodeFiles.clear();
- ObjectFiles.clear();
- SharedFiles.clear();
+ inputSections.clear();
+ outputSections.clear();
+ binaryFiles.clear();
+ bitcodeFiles.clear();
+ objectFiles.clear();
+ sharedFiles.clear();
- Config = make<Configuration>();
- Driver = make<LinkerDriver>();
- Script = make<LinkerScript>();
- Symtab = make<SymbolTable>();
+ config = make<Configuration>();
+ driver = make<LinkerDriver>();
+ script = make<LinkerScript>();
+ symtab = make<SymbolTable>();
- Tar = nullptr;
- memset(&In, 0, sizeof(In));
+ tar = nullptr;
+ memset(&in, 0, sizeof(in));
- Partitions = {Partition()};
+ partitions = {Partition()};
- SharedFile::VernauxNum = 0;
+ SharedFile::vernauxNum = 0;
- Config->ProgName = Args[0];
+ config->progName = args[0];
- Driver->main(Args);
+ driver->main(args);
// Exit immediately if we don't need to return to the caller.
// This saves time because the overhead of calling destructors
// for all globally-allocated objects is not negligible.
- if (CanExitEarly)
+ if (canExitEarly)
exitLld(errorCount() ? 1 : 0);
freeArena();
@@ -118,16 +118,16 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
}
// Parses a linker -m option.
-static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
- uint8_t OSABI = 0;
- StringRef S = Emul;
- if (S.endswith("_fbsd")) {
- S = S.drop_back(5);
- OSABI = ELFOSABI_FREEBSD;
+static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
+ uint8_t osabi = 0;
+ StringRef s = emul;
+ if (s.endswith("_fbsd")) {
+ s = s.drop_back(5);
+ osabi = ELFOSABI_FREEBSD;
}
- std::pair<ELFKind, uint16_t> Ret =
- StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+ std::pair<ELFKind, uint16_t> ret =
+ StringSwitch<std::pair<ELFKind, uint16_t>>(s)
.Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec",
{ELF64LEKind, EM_AARCH64})
.Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
@@ -146,101 +146,101 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
.Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
.Default({ELFNoneKind, EM_NONE});
- if (Ret.first == ELFNoneKind)
- error("unknown emulation: " + Emul);
- return std::make_tuple(Ret.first, Ret.second, OSABI);
+ if (ret.first == ELFNoneKind)
+ error("unknown emulation: " + emul);
+ return std::make_tuple(ret.first, ret.second, osabi);
}
// Returns slices of MB by parsing MB as an archive file.
// Each slice consists of a member file in the archive.
std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
- MemoryBufferRef MB) {
- std::unique_ptr<Archive> File =
- CHECK(Archive::create(MB),
- MB.getBufferIdentifier() + ": failed to parse archive");
-
- std::vector<std::pair<MemoryBufferRef, uint64_t>> V;
- Error Err = Error::success();
- bool AddToTar = File->isThin() && Tar;
- for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
- Archive::Child C =
- CHECK(COrErr, MB.getBufferIdentifier() +
+ MemoryBufferRef mb) {
+ std::unique_ptr<Archive> file =
+ CHECK(Archive::create(mb),
+ mb.getBufferIdentifier() + ": failed to parse archive");
+
+ std::vector<std::pair<MemoryBufferRef, uint64_t>> v;
+ Error err = Error::success();
+ bool addToTar = file->isThin() && tar;
+ for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) {
+ Archive::Child c =
+ CHECK(cOrErr, mb.getBufferIdentifier() +
": could not get the child of the archive");
- MemoryBufferRef MBRef =
- CHECK(C.getMemoryBufferRef(),
- MB.getBufferIdentifier() +
+ MemoryBufferRef mbref =
+ CHECK(c.getMemoryBufferRef(),
+ mb.getBufferIdentifier() +
": could not get the buffer for a child of the archive");
- if (AddToTar)
- Tar->append(relativeToRoot(check(C.getFullName())), MBRef.getBuffer());
- V.push_back(std::make_pair(MBRef, C.getChildOffset()));
+ if (addToTar)
+ tar->append(relativeToRoot(check(c.getFullName())), mbref.getBuffer());
+ v.push_back(std::make_pair(mbref, c.getChildOffset()));
}
- if (Err)
- fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
- toString(std::move(Err)));
+ if (err)
+ fatal(mb.getBufferIdentifier() + ": Archive::children failed: " +
+ toString(std::move(err)));
// Take ownership of memory buffers created for members of thin archives.
- for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
- make<std::unique_ptr<MemoryBuffer>>(std::move(MB));
+ for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
+ make<std::unique_ptr<MemoryBuffer>>(std::move(mb));
- return V;
+ return v;
}
// Opens a file and create a file object. Path has to be resolved already.
-void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
+void LinkerDriver::addFile(StringRef path, bool withLOption) {
using namespace sys::fs;
- Optional<MemoryBufferRef> Buffer = readFile(Path);
- if (!Buffer.hasValue())
+ Optional<MemoryBufferRef> buffer = readFile(path);
+ if (!buffer.hasValue())
return;
- MemoryBufferRef MBRef = *Buffer;
+ MemoryBufferRef mbref = *buffer;
- if (Config->FormatBinary) {
- Files.push_back(make<BinaryFile>(MBRef));
+ if (config->formatBinary) {
+ files.push_back(make<BinaryFile>(mbref));
return;
}
- switch (identify_magic(MBRef.getBuffer())) {
+ switch (identify_magic(mbref.getBuffer())) {
case file_magic::unknown:
- readLinkerScript(MBRef);
+ readLinkerScript(mbref);
return;
case file_magic::archive: {
// Handle -whole-archive.
- if (InWholeArchive) {
- for (const auto &P : getArchiveMembers(MBRef))
- Files.push_back(createObjectFile(P.first, Path, P.second));
+ if (inWholeArchive) {
+ for (const auto &p : getArchiveMembers(mbref))
+ files.push_back(createObjectFile(p.first, path, p.second));
return;
}
- std::unique_ptr<Archive> File =
- CHECK(Archive::create(MBRef), Path + ": failed to parse archive");
+ std::unique_ptr<Archive> file =
+ CHECK(Archive::create(mbref), path + ": failed to parse archive");
// If an archive file has no symbol table, it is likely that a user
// is attempting LTO and using a default ar command that doesn't
// understand the LLVM bitcode file. It is a pretty common error, so
// we'll handle it as if it had a symbol table.
- if (!File->isEmpty() && !File->hasSymbolTable()) {
+ if (!file->isEmpty() && !file->hasSymbolTable()) {
// Check if all members are bitcode files. If not, ignore, which is the
// default action without the LTO hack described above.
- for (const std::pair<MemoryBufferRef, uint64_t> &P :
- getArchiveMembers(MBRef))
- if (identify_magic(P.first.getBuffer()) != file_magic::bitcode) {
- error(Path + ": archive has no index; run ranlib to add one");
+ for (const std::pair<MemoryBufferRef, uint64_t> &p :
+ getArchiveMembers(mbref))
+ if (identify_magic(p.first.getBuffer()) != file_magic::bitcode) {
+ error(path + ": archive has no index; run ranlib to add one");
return;
}
- for (const std::pair<MemoryBufferRef, uint64_t> &P :
- getArchiveMembers(MBRef))
- Files.push_back(make<LazyObjFile>(P.first, Path, P.second));
+ for (const std::pair<MemoryBufferRef, uint64_t> &p :
+ getArchiveMembers(mbref))
+ files.push_back(make<LazyObjFile>(p.first, path, p.second));
return;
}
// Handle the regular case.
- Files.push_back(make<ArchiveFile>(std::move(File)));
+ files.push_back(make<ArchiveFile>(std::move(file)));
return;
}
case file_magic::elf_shared_object:
- if (Config->Static || Config->Relocatable) {
- error("attempted static link of dynamic object " + Path);
+ if (config->isStatic || config->relocatable) {
+ error("attempted static link of dynamic object " + path);
return;
}
@@ -254,27 +254,27 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
// If a file was specified by -lfoo, the directory part is not
// significant, as a user did not specify it. This behavior is
// compatible with GNU.
- Files.push_back(
- make<SharedFile>(MBRef, WithLOption ? path::filename(Path) : Path));
+ files.push_back(
+ make<SharedFile>(mbref, withLOption ? path::filename(path) : path));
return;
case file_magic::bitcode:
case file_magic::elf_relocatable:
- if (InLib)
- Files.push_back(make<LazyObjFile>(MBRef, "", 0));
+ if (inLib)
+ files.push_back(make<LazyObjFile>(mbref, "", 0));
else
- Files.push_back(createObjectFile(MBRef));
+ files.push_back(createObjectFile(mbref));
break;
default:
- error(Path + ": unknown file type");
+ error(path + ": unknown file type");
}
}
// Add a given library by searching it from input search paths.
-void LinkerDriver::addLibrary(StringRef Name) {
- if (Optional<std::string> Path = searchLibrary(Name))
- addFile(*Path, /*WithLOption=*/true);
+void LinkerDriver::addLibrary(StringRef name) {
+ if (Optional<std::string> path = searchLibrary(name))
+ addFile(*path, /*WithLOption=*/true);
else
- error("unable to find library -l" + Name);
+ error("unable to find library -l" + name);
}
// This function is called on startup. We need this for LTO since
@@ -293,117 +293,117 @@ static void initLLVM() {
static void checkOptions() {
// The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
// table which is a relatively new feature.
- if (Config->EMachine == EM_MIPS && Config->GnuHash)
+ if (config->emachine == EM_MIPS && config->gnuHash)
error("the .gnu.hash section is not compatible with the MIPS target");
- if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)
+ if (config->fixCortexA53Errata843419 && config->emachine != EM_AARCH64)
error("--fix-cortex-a53-843419 is only supported on AArch64 targets");
- if (Config->TocOptimize && Config->EMachine != EM_PPC64)
+ if (config->tocOptimize && config->emachine != EM_PPC64)
error("--toc-optimize is only supported on the PowerPC64 target");
- if (Config->Pie && Config->Shared)
+ if (config->pie && config->shared)
error("-shared and -pie may not be used together");
- if (!Config->Shared && !Config->FilterList.empty())
+ if (!config->shared && !config->filterList.empty())
error("-F may not be used without -shared");
- if (!Config->Shared && !Config->AuxiliaryList.empty())
+ if (!config->shared && !config->auxiliaryList.empty())
error("-f may not be used without -shared");
- if (!Config->Relocatable && !Config->DefineCommon)
+ if (!config->relocatable && !config->defineCommon)
error("-no-define-common not supported in non relocatable output");
- if (Config->ZText && Config->ZIfuncNoplt)
+ if (config->zText && config->zIfuncNoplt)
error("-z text and -z ifunc-noplt may not be used together");
- if (Config->Relocatable) {
- if (Config->Shared)
+ if (config->relocatable) {
+ if (config->shared)
error("-r and -shared may not be used together");
- if (Config->GcSections)
+ if (config->gcSections)
error("-r and --gc-sections may not be used together");
- if (Config->GdbIndex)
+ if (config->gdbIndex)
error("-r and --gdb-index may not be used together");
- if (Config->ICF != ICFLevel::None)
+ if (config->icf != ICFLevel::None)
error("-r and --icf may not be used together");
- if (Config->Pie)
+ if (config->pie)
error("-r and -pie may not be used together");
}
- if (Config->ExecuteOnly) {
- if (Config->EMachine != EM_AARCH64)
+ if (config->executeOnly) {
+ if (config->emachine != EM_AARCH64)
error("-execute-only is only supported on AArch64 targets");
- if (Config->SingleRoRx && !Script->HasSectionsCommand)
+ if (config->singleRoRx && !script->hasSectionsCommand)
error("-execute-only and -no-rosegment cannot be used together");
}
- if (Config->ZRetpolineplt && Config->RequireCET)
+ if (config->zRetpolineplt && config->requireCET)
error("--require-cet may not be used with -z retpolineplt");
- if (Config->EMachine != EM_AARCH64) {
- if (Config->PacPlt)
+ if (config->emachine != EM_AARCH64) {
+ if (config->pacPlt)
error("--pac-plt only supported on AArch64");
- if (Config->ForceBTI)
+ if (config->forceBTI)
error("--force-bti only supported on AArch64");
}
}
-static const char *getReproduceOption(opt::InputArgList &Args) {
- if (auto *Arg = Args.getLastArg(OPT_reproduce))
- return Arg->getValue();
+static const char *getReproduceOption(opt::InputArgList &args) {
+ if (auto *arg = args.getLastArg(OPT_reproduce))
+ return arg->getValue();
return getenv("LLD_REPRODUCE");
}
-static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
- for (auto *Arg : Args.filtered(OPT_z))
- if (Key == Arg->getValue())
+static bool hasZOption(opt::InputArgList &args, StringRef key) {
+ for (auto *arg : args.filtered(OPT_z))
+ if (key == arg->getValue())
return true;
return false;
}
-static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
+static bool getZFlag(opt::InputArgList &args, StringRef k1, StringRef k2,
bool Default) {
- for (auto *Arg : Args.filtered_reverse(OPT_z)) {
- if (K1 == Arg->getValue())
+ for (auto *arg : args.filtered_reverse(OPT_z)) {
+ if (k1 == arg->getValue())
return true;
- if (K2 == Arg->getValue())
+ if (k2 == arg->getValue())
return false;
}
return Default;
}
-static bool isKnownZFlag(StringRef S) {
- return S == "combreloc" || S == "copyreloc" || S == "defs" ||
- S == "execstack" || S == "global" || S == "hazardplt" ||
- S == "ifunc-noplt" || S == "initfirst" || S == "interpose" ||
- S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
- S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
- S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
- S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
- S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
- S == "rodynamic" || S == "text" || S == "wxneeded" ||
- S.startswith("common-page-size") || S.startswith("max-page-size=") ||
- S.startswith("stack-size=");
+static bool isKnownZFlag(StringRef s) {
+ return s == "combreloc" || s == "copyreloc" || s == "defs" ||
+ s == "execstack" || s == "global" || s == "hazardplt" ||
+ s == "ifunc-noplt" || s == "initfirst" || s == "interpose" ||
+ s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" ||
+ s == "nocombreloc" || s == "nocopyreloc" || s == "nodefaultlib" ||
+ s == "nodelete" || s == "nodlopen" || s == "noexecstack" ||
+ s == "nokeep-text-section-prefix" || s == "norelro" || s == "notext" ||
+ s == "now" || s == "origin" || s == "relro" || s == "retpolineplt" ||
+ s == "rodynamic" || s == "text" || s == "wxneeded" ||
+ s.startswith("common-page-size") || s.startswith("max-page-size=") ||
+ s.startswith("stack-size=");
}
// Report an error for an unknown -z option.
-static void checkZOptions(opt::InputArgList &Args) {
- for (auto *Arg : Args.filtered(OPT_z))
- if (!isKnownZFlag(Arg->getValue()))
- error("unknown -z value: " + StringRef(Arg->getValue()));
+static void checkZOptions(opt::InputArgList &args) {
+ for (auto *arg : args.filtered(OPT_z))
+ if (!isKnownZFlag(arg->getValue()))
+ error("unknown -z value: " + StringRef(arg->getValue()));
}
-void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
- ELFOptTable Parser;
- opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
+void LinkerDriver::main(ArrayRef<const char *> argsArr) {
+ ELFOptTable parser;
+ opt::InputArgList args = parser.parse(argsArr.slice(1));
// Interpret this flag early because error() depends on them.
- errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
- checkZOptions(Args);
+ errorHandler().ErrorLimit = args::getInteger(args, OPT_error_limit, 20);
+ checkZOptions(args);
// Handle -help
- if (Args.hasArg(OPT_help)) {
+ if (args.hasArg(OPT_help)) {
printHelp();
return;
}
@@ -423,39 +423,39 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
// lot of "configure" scripts out there that are generated by old version
// of Libtool. We cannot convince every software developer to migrate to
// the latest version and re-generate scripts. So we have this hack.
- if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
+ if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
message(getLLDVersion() + " (compatible with GNU linkers)");
- if (const char *Path = getReproduceOption(Args)) {
+ if (const char *path = getReproduceOption(args)) {
// Note that --reproduce is a debug option so you can ignore it
// if you are trying to understand the whole picture of the code.
- Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
- TarWriter::create(Path, path::stem(Path));
- if (ErrOrWriter) {
- Tar = std::move(*ErrOrWriter);
- Tar->append("response.txt", createResponseFile(Args));
- Tar->append("version.txt", getLLDVersion() + "\n");
+ Expected<std::unique_ptr<TarWriter>> errOrWriter =
+ TarWriter::create(path, path::stem(path));
+ if (errOrWriter) {
+ tar = std::move(*errOrWriter);
+ tar->append("response.txt", createResponseFile(args));
+ tar->append("version.txt", getLLDVersion() + "\n");
} else {
- error("--reproduce: " + toString(ErrOrWriter.takeError()));
+ error("--reproduce: " + toString(errOrWriter.takeError()));
}
}
- readConfigs(Args);
+ readConfigs(args);
// The behavior of -v or --version is a bit strange, but this is
// needed for compatibility with GNU linkers.
- if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT))
+ if (args.hasArg(OPT_v) && !args.hasArg(OPT_INPUT))
return;
- if (Args.hasArg(OPT_version))
+ if (args.hasArg(OPT_version))
return;
initLLVM();
- createFiles(Args);
+ createFiles(args);
if (errorCount())
return;
inferMachineType();
- setConfigs(Args);
+ setConfigs(args);
checkOptions();
if (errorCount())
return;
@@ -463,178 +463,178 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
// The Target instance handles target-specific stuff, such as applying
// relocations or writing a PLT section. It also contains target-dependent
// values such as a default image base address.
- Target = getTarget();
+ target = getTarget();
- switch (Config->EKind) {
+ switch (config->ekind) {
case ELF32LEKind:
- link<ELF32LE>(Args);
+ link<ELF32LE>(args);
return;
case ELF32BEKind:
- link<ELF32BE>(Args);
+ link<ELF32BE>(args);
return;
case ELF64LEKind:
- link<ELF64LE>(Args);
+ link<ELF64LE>(args);
return;
case ELF64BEKind:
- link<ELF64BE>(Args);
+ link<ELF64BE>(args);
return;
default:
llvm_unreachable("unknown Config->EKind");
}
}
-static std::string getRpath(opt::InputArgList &Args) {
- std::vector<StringRef> V = args::getStrings(Args, OPT_rpath);
- return llvm::join(V.begin(), V.end(), ":");
+static std::string getRpath(opt::InputArgList &args) {
+ std::vector<StringRef> v = args::getStrings(args, OPT_rpath);
+ return llvm::join(v.begin(), v.end(), ":");
}
// Determines what we should do if there are remaining unresolved
// symbols after the name resolution.
-static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
- UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
+static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &args) {
+ UnresolvedPolicy errorOrWarn = args.hasFlag(OPT_error_unresolved_symbols,
OPT_warn_unresolved_symbols, true)
? UnresolvedPolicy::ReportError
: UnresolvedPolicy::Warn;
// Process the last of -unresolved-symbols, -no-undefined or -z defs.
- for (auto *Arg : llvm::reverse(Args)) {
- switch (Arg->getOption().getID()) {
+ for (auto *arg : llvm::reverse(args)) {
+ switch (arg->getOption().getID()) {
case OPT_unresolved_symbols: {
- StringRef S = Arg->getValue();
- if (S == "ignore-all" || S == "ignore-in-object-files")
+ StringRef s = arg->getValue();
+ if (s == "ignore-all" || s == "ignore-in-object-files")
return UnresolvedPolicy::Ignore;
- if (S == "ignore-in-shared-libs" || S == "report-all")
- return ErrorOrWarn;
- error("unknown --unresolved-symbols value: " + S);
+ if (s == "ignore-in-shared-libs" || s == "report-all")
+ return errorOrWarn;
+ error("unknown --unresolved-symbols value: " + s);
continue;
}
case OPT_no_undefined:
- return ErrorOrWarn;
+ return errorOrWarn;
case OPT_z:
- if (StringRef(Arg->getValue()) == "defs")
- return ErrorOrWarn;
+ if (StringRef(arg->getValue()) == "defs")
+ return errorOrWarn;
continue;
}
}
// -shared implies -unresolved-symbols=ignore-all because missing
// symbols are likely to be resolved at runtime using other DSOs.
- if (Config->Shared)
+ if (config->shared)
return UnresolvedPolicy::Ignore;
- return ErrorOrWarn;
+ return errorOrWarn;
}
-static Target2Policy getTarget2(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_target2, "got-rel");
- if (S == "rel")
+static Target2Policy getTarget2(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_target2, "got-rel");
+ if (s == "rel")
return Target2Policy::Rel;
- if (S == "abs")
+ if (s == "abs")
return Target2Policy::Abs;
- if (S == "got-rel")
+ if (s == "got-rel")
return Target2Policy::GotRel;
- error("unknown --target2 option: " + S);
+ error("unknown --target2 option: " + s);
return Target2Policy::GotRel;
}
-static bool isOutputFormatBinary(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_oformat, "elf");
- if (S == "binary")
+static bool isOutputFormatBinary(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_oformat, "elf");
+ if (s == "binary")
return true;
- if (!S.startswith("elf"))
- error("unknown --oformat value: " + S);
+ if (!s.startswith("elf"))
+ error("unknown --oformat value: " + s);
return false;
}
-static DiscardPolicy getDiscard(opt::InputArgList &Args) {
- if (Args.hasArg(OPT_relocatable))
+static DiscardPolicy getDiscard(opt::InputArgList &args) {
+ if (args.hasArg(OPT_relocatable))
return DiscardPolicy::None;
- auto *Arg =
- Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
- if (!Arg)
+ auto *arg =
+ args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
+ if (!arg)
return DiscardPolicy::Default;
- if (Arg->getOption().getID() == OPT_discard_all)
+ if (arg->getOption().getID() == OPT_discard_all)
return DiscardPolicy::All;
- if (Arg->getOption().getID() == OPT_discard_locals)
+ if (arg->getOption().getID() == OPT_discard_locals)
return DiscardPolicy::Locals;
return DiscardPolicy::None;
}
-static StringRef getDynamicLinker(opt::InputArgList &Args) {
- auto *Arg = Args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
- if (!Arg || Arg->getOption().getID() == OPT_no_dynamic_linker)
+static StringRef getDynamicLinker(opt::InputArgList &args) {
+ auto *arg = args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
+ if (!arg || arg->getOption().getID() == OPT_no_dynamic_linker)
return "";
- return Arg->getValue();
+ return arg->getValue();
}
-static ICFLevel getICF(opt::InputArgList &Args) {
- auto *Arg = Args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
- if (!Arg || Arg->getOption().getID() == OPT_icf_none)
+static ICFLevel getICF(opt::InputArgList &args) {
+ auto *arg = args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
+ if (!arg || arg->getOption().getID() == OPT_icf_none)
return ICFLevel::None;
- if (Arg->getOption().getID() == OPT_icf_safe)
+ if (arg->getOption().getID() == OPT_icf_safe)
return ICFLevel::Safe;
return ICFLevel::All;
}
-static StripPolicy getStrip(opt::InputArgList &Args) {
- if (Args.hasArg(OPT_relocatable))
+static StripPolicy getStrip(opt::InputArgList &args) {
+ if (args.hasArg(OPT_relocatable))
return StripPolicy::None;
- auto *Arg = Args.getLastArg(OPT_strip_all, OPT_strip_debug);
- if (!Arg)
+ auto *arg = args.getLastArg(OPT_strip_all, OPT_strip_debug);
+ if (!arg)
return StripPolicy::None;
- if (Arg->getOption().getID() == OPT_strip_all)
+ if (arg->getOption().getID() == OPT_strip_all)
return StripPolicy::All;
return StripPolicy::Debug;
}
-static uint64_t parseSectionAddress(StringRef S, opt::InputArgList &Args,
- const opt::Arg &Arg) {
- uint64_t VA = 0;
- if (S.startswith("0x"))
- S = S.drop_front(2);
- if (!to_integer(S, VA, 16))
- error("invalid argument: " + Arg.getAsString(Args));
- return VA;
+static uint64_t parseSectionAddress(StringRef s, opt::InputArgList &args,
+ const opt::Arg &arg) {
+ uint64_t va = 0;
+ if (s.startswith("0x"))
+ s = s.drop_front(2);
+ if (!to_integer(s, va, 16))
+ error("invalid argument: " + arg.getAsString(args));
+ return va;
}
-static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
- StringMap<uint64_t> Ret;
- for (auto *Arg : Args.filtered(OPT_section_start)) {
- StringRef Name;
- StringRef Addr;
- std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
- Ret[Name] = parseSectionAddress(Addr, Args, *Arg);
+static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &args) {
+ StringMap<uint64_t> ret;
+ for (auto *arg : args.filtered(OPT_section_start)) {
+ StringRef name;
+ StringRef addr;
+ std::tie(name, addr) = StringRef(arg->getValue()).split('=');
+ ret[name] = parseSectionAddress(addr, args, *arg);
}
- if (auto *Arg = Args.getLastArg(OPT_Ttext))
- Ret[".text"] = parseSectionAddress(Arg->getValue(), Args, *Arg);
- if (auto *Arg = Args.getLastArg(OPT_Tdata))
- Ret[".data"] = parseSectionAddress(Arg->getValue(), Args, *Arg);
- if (auto *Arg = Args.getLastArg(OPT_Tbss))
- Ret[".bss"] = parseSectionAddress(Arg->getValue(), Args, *Arg);
- return Ret;
+ if (auto *arg = args.getLastArg(OPT_Ttext))
+ ret[".text"] = parseSectionAddress(arg->getValue(), args, *arg);
+ if (auto *arg = args.getLastArg(OPT_Tdata))
+ ret[".data"] = parseSectionAddress(arg->getValue(), args, *arg);
+ if (auto *arg = args.getLastArg(OPT_Tbss))
+ ret[".bss"] = parseSectionAddress(arg->getValue(), args, *arg);
+ return ret;
}
-static SortSectionPolicy getSortSection(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_sort_section);
- if (S == "alignment")
+static SortSectionPolicy getSortSection(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_sort_section);
+ if (s == "alignment")
return SortSectionPolicy::Alignment;
- if (S == "name")
+ if (s == "name")
return SortSectionPolicy::Name;
- if (!S.empty())
- error("unknown --sort-section rule: " + S);
+ if (!s.empty())
+ error("unknown --sort-section rule: " + s);
return SortSectionPolicy::Default;
}
-static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_orphan_handling, "place");
- if (S == "warn")
+static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_orphan_handling, "place");
+ if (s == "warn")
return OrphanHandlingPolicy::Warn;
- if (S == "error")
+ if (s == "error")
return OrphanHandlingPolicy::Error;
- if (S != "place")
- error("unknown --orphan-handling mode: " + S);
+ if (s != "place")
+ error("unknown --orphan-handling mode: " + s);
return OrphanHandlingPolicy::Place;
}
@@ -642,410 +642,410 @@ static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
// synonym for "sha1" because all our hash functions including
// -build-id=sha1 are actually tree hashes for performance reasons.
static std::pair<BuildIdKind, std::vector<uint8_t>>
-getBuildId(opt::InputArgList &Args) {
- auto *Arg = Args.getLastArg(OPT_build_id, OPT_build_id_eq);
- if (!Arg)
+getBuildId(opt::InputArgList &args) {
+ auto *arg = args.getLastArg(OPT_build_id, OPT_build_id_eq);
+ if (!arg)
return {BuildIdKind::None, {}};
- if (Arg->getOption().getID() == OPT_build_id)
+ if (arg->getOption().getID() == OPT_build_id)
return {BuildIdKind::Fast, {}};
- StringRef S = Arg->getValue();
- if (S == "fast")
+ StringRef s = arg->getValue();
+ if (s == "fast")
return {BuildIdKind::Fast, {}};
- if (S == "md5")
+ if (s == "md5")
return {BuildIdKind::Md5, {}};
- if (S == "sha1" || S == "tree")
+ if (s == "sha1" || s == "tree")
return {BuildIdKind::Sha1, {}};
- if (S == "uuid")
+ if (s == "uuid")
return {BuildIdKind::Uuid, {}};
- if (S.startswith("0x"))
- return {BuildIdKind::Hexstring, parseHex(S.substr(2))};
+ if (s.startswith("0x"))
+ return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
- if (S != "none")
- error("unknown --build-id style: " + S);
+ if (s != "none")
+ error("unknown --build-id style: " + s);
return {BuildIdKind::None, {}};
}
-static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_pack_dyn_relocs, "none");
- if (S == "android")
+static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_pack_dyn_relocs, "none");
+ if (s == "android")
return {true, false};
- if (S == "relr")
+ if (s == "relr")
return {false, true};
- if (S == "android+relr")
+ if (s == "android+relr")
return {true, true};
- if (S != "none")
- error("unknown -pack-dyn-relocs format: " + S);
+ if (s != "none")
+ error("unknown -pack-dyn-relocs format: " + s);
return {false, false};
}
-static void readCallGraph(MemoryBufferRef MB) {
+static void readCallGraph(MemoryBufferRef mb) {
// Build a map from symbol name to section
- DenseMap<StringRef, Symbol *> Map;
- for (InputFile *File : ObjectFiles)
- for (Symbol *Sym : File->getSymbols())
- Map[Sym->getName()] = Sym;
-
- auto FindSection = [&](StringRef Name) -> InputSectionBase * {
- Symbol *Sym = Map.lookup(Name);
- if (!Sym) {
- if (Config->WarnSymbolOrdering)
- warn(MB.getBufferIdentifier() + ": no such symbol: " + Name);
+ DenseMap<StringRef, Symbol *> map;
+ for (InputFile *file : objectFiles)
+ for (Symbol *sym : file->getSymbols())
+ map[sym->getName()] = sym;
+
+ auto findSection = [&](StringRef name) -> InputSectionBase * {
+ Symbol *sym = map.lookup(name);
+ if (!sym) {
+ if (config->warnSymbolOrdering)
+ warn(mb.getBufferIdentifier() + ": no such symbol: " + name);
return nullptr;
}
- maybeWarnUnorderableSymbol(Sym);
+ maybeWarnUnorderableSymbol(sym);
- if (Defined *DR = dyn_cast_or_null<Defined>(Sym))
- return dyn_cast_or_null<InputSectionBase>(DR->Section);
+ if (Defined *dr = dyn_cast_or_null<Defined>(sym))
+ return dyn_cast_or_null<InputSectionBase>(dr->section);
return nullptr;
};
- for (StringRef Line : args::getLines(MB)) {
- SmallVector<StringRef, 3> Fields;
- Line.split(Fields, ' ');
- uint64_t Count;
+ for (StringRef line : args::getLines(mb)) {
+ SmallVector<StringRef, 3> fields;
+ line.split(fields, ' ');
+ uint64_t count;
- if (Fields.size() != 3 || !to_integer(Fields[2], Count)) {
- error(MB.getBufferIdentifier() + ": parse error");
+ if (fields.size() != 3 || !to_integer(fields[2], count)) {
+ error(mb.getBufferIdentifier() + ": parse error");
return;
}
- if (InputSectionBase *From = FindSection(Fields[0]))
- if (InputSectionBase *To = FindSection(Fields[1]))
- Config->CallGraphProfile[std::make_pair(From, To)] += Count;
+ if (InputSectionBase *from = findSection(fields[0]))
+ if (InputSectionBase *to = findSection(fields[1]))
+ config->callGraphProfile[std::make_pair(from, to)] += count;
}
}
template <class ELFT> static void readCallGraphsFromObjectFiles() {
- for (auto File : ObjectFiles) {
- auto *Obj = cast<ObjFile<ELFT>>(File);
+ for (auto file : objectFiles) {
+ auto *obj = cast<ObjFile<ELFT>>(file);
- for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) {
- auto *FromSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_from));
- auto *ToSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_to));
- if (!FromSym || !ToSym)
+ for (const Elf_CGProfile_Impl<ELFT> &cgpe : obj->cgProfile) {
+ auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_from));
+ auto *toSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_to));
+ if (!fromSym || !toSym)
continue;
- auto *From = dyn_cast_or_null<InputSectionBase>(FromSym->Section);
- auto *To = dyn_cast_or_null<InputSectionBase>(ToSym->Section);
- if (From && To)
- Config->CallGraphProfile[{From, To}] += CGPE.cgp_weight;
+ auto *from = dyn_cast_or_null<InputSectionBase>(fromSym->section);
+ auto *to = dyn_cast_or_null<InputSectionBase>(toSym->section);
+ if (from && to)
+ config->callGraphProfile[{from, to}] += cgpe.cgp_weight;
}
}
}
-static bool getCompressDebugSections(opt::InputArgList &Args) {
- StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
- if (S == "none")
+static bool getCompressDebugSections(opt::InputArgList &args) {
+ StringRef s = args.getLastArgValue(OPT_compress_debug_sections, "none");
+ if (s == "none")
return false;
- if (S != "zlib")
- error("unknown --compress-debug-sections value: " + S);
+ if (s != "zlib")
+ error("unknown --compress-debug-sections value: " + s);
if (!zlib::isAvailable())
error("--compress-debug-sections: zlib is not available");
return true;
}
-static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &Args,
- unsigned Id) {
- auto *Arg = Args.getLastArg(Id);
- if (!Arg)
+static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
+ unsigned id) {
+ auto *arg = args.getLastArg(id);
+ if (!arg)
return {"", ""};
- StringRef S = Arg->getValue();
- std::pair<StringRef, StringRef> Ret = S.split(';');
- if (Ret.second.empty())
- error(Arg->getSpelling() + " expects 'old;new' format, but got " + S);
- return Ret;
+ StringRef s = arg->getValue();
+ std::pair<StringRef, StringRef> ret = s.split(';');
+ if (ret.second.empty())
+ error(arg->getSpelling() + " expects 'old;new' format, but got " + s);
+ return ret;
}
// Parse the symbol ordering file and warn for any duplicate entries.
-static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef MB) {
- SetVector<StringRef> Names;
- for (StringRef S : args::getLines(MB))
- if (!Names.insert(S) && Config->WarnSymbolOrdering)
- warn(MB.getBufferIdentifier() + ": duplicate ordered symbol: " + S);
+static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef mb) {
+ SetVector<StringRef> names;
+ for (StringRef s : args::getLines(mb))
+ if (!names.insert(s) && config->warnSymbolOrdering)
+ warn(mb.getBufferIdentifier() + ": duplicate ordered symbol: " + s);
- return Names.takeVector();
+ return names.takeVector();
}
-static void parseClangOption(StringRef Opt, const Twine &Msg) {
- std::string Err;
- raw_string_ostream OS(Err);
+static void parseClangOption(StringRef opt, const Twine &msg) {
+ std::string err;
+ raw_string_ostream os(err);
- const char *Argv[] = {Config->ProgName.data(), Opt.data()};
- if (cl::ParseCommandLineOptions(2, Argv, "", &OS))
+ const char *argv[] = {config->progName.data(), opt.data()};
+ if (cl::ParseCommandLineOptions(2, argv, "", &os))
return;
- OS.flush();
- error(Msg + ": " + StringRef(Err).trim());
+ os.flush();
+ error(msg + ": " + StringRef(err).trim());
}
// Initializes Config members by the command line options.
-static void readConfigs(opt::InputArgList &Args) {
- errorHandler().Verbose = Args.hasArg(OPT_verbose);
+static void readConfigs(opt::InputArgList &args) {
+ errorHandler().Verbose = args.hasArg(OPT_verbose);
errorHandler().FatalWarnings =
- Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
- ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
+ args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
+ ThreadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
- Config->AllowMultipleDefinition =
- Args.hasFlag(OPT_allow_multiple_definition,
+ config->allowMultipleDefinition =
+ args.hasFlag(OPT_allow_multiple_definition,
OPT_no_allow_multiple_definition, false) ||
- hasZOption(Args, "muldefs");
- Config->AllowShlibUndefined =
- Args.hasFlag(OPT_allow_shlib_undefined, OPT_no_allow_shlib_undefined,
- Args.hasArg(OPT_shared));
- Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
- Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
- Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
- Config->CheckSections =
- Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
- Config->Chroot = Args.getLastArgValue(OPT_chroot);
- Config->CompressDebugSections = getCompressDebugSections(Args);
- Config->Cref = Args.hasFlag(OPT_cref, OPT_no_cref, false);
- Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common,
- !Args.hasArg(OPT_relocatable));
- Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
- Config->DependentLibraries = Args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
- Config->DisableVerify = Args.hasArg(OPT_disable_verify);
- Config->Discard = getDiscard(Args);
- Config->DwoDir = Args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
- Config->DynamicLinker = getDynamicLinker(Args);
- Config->EhFrameHdr =
- Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
- Config->EmitLLVM = Args.hasArg(OPT_plugin_opt_emit_llvm, false);
- Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
- Config->CallGraphProfileSort = Args.hasFlag(
+ hasZOption(args, "muldefs");
+ config->allowShlibUndefined =
+ args.hasFlag(OPT_allow_shlib_undefined, OPT_no_allow_shlib_undefined,
+ args.hasArg(OPT_shared));
+ config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
+ config->bsymbolic = args.hasArg(OPT_Bsymbolic);
+ config->bsymbolicFunctions = args.hasArg(OPT_Bsymbolic_functions);
+ config->checkSections =
+ args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
+ config->chroot = args.getLastArgValue(OPT_chroot);
+ config->compressDebugSections = getCompressDebugSections(args);
+ config->cref = args.hasFlag(OPT_cref, OPT_no_cref, false);
+ config->defineCommon = args.hasFlag(OPT_define_common, OPT_no_define_common,
+ !args.hasArg(OPT_relocatable));
+ config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
+ config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
+ config->disableVerify = args.hasArg(OPT_disable_verify);
+ config->discard = getDiscard(args);
+ config->dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
+ config->dynamicLinker = getDynamicLinker(args);
+ config->ehFrameHdr =
+ args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
+ config->emitLLVM = args.hasArg(OPT_plugin_opt_emit_llvm, false);
+ config->emitRelocs = args.hasArg(OPT_emit_relocs);
+ config->callGraphProfileSort = args.hasFlag(
OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
- Config->EnableNewDtags =
- Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
- Config->Entry = Args.getLastArgValue(OPT_entry);
- Config->ExecuteOnly =
- Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
- Config->ExportDynamic =
- Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
- Config->FilterList = args::getStrings(Args, OPT_filter);
- Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
- Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419);
- Config->ForceBTI = Args.hasArg(OPT_force_bti);
- Config->RequireCET = Args.hasArg(OPT_require_cet);
- Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
- Config->GnuUnique = Args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
- Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
- Config->ICF = getICF(Args);
- Config->IgnoreDataAddressEquality =
- Args.hasArg(OPT_ignore_data_address_equality);
- Config->IgnoreFunctionAddressEquality =
- Args.hasArg(OPT_ignore_function_address_equality);
- Config->Init = Args.getLastArgValue(OPT_init, "_init");
- Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
- Config->LTOCSProfileGenerate = Args.hasArg(OPT_lto_cs_profile_generate);
- Config->LTOCSProfileFile = Args.getLastArgValue(OPT_lto_cs_profile_file);
- Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
- Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager);
- Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
- Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
- Config->LTOObjPath = Args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
- Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
- Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile);
- Config->MapFile = Args.getLastArgValue(OPT_Map);
- Config->MipsGotSize = args::getInteger(Args, OPT_mips_got_size, 0xfff0);
- Config->MergeArmExidx =
- Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
- Config->Nmagic = Args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
- Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
- Config->Nostdlib = Args.hasArg(OPT_nostdlib);
- Config->OFormatBinary = isOutputFormatBinary(Args);
- Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false);
- Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
- Config->OptRemarksPasses = Args.getLastArgValue(OPT_opt_remarks_passes);
- Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
- Config->OptRemarksFormat = Args.getLastArgValue(OPT_opt_remarks_format);
- Config->Optimize = args::getInteger(Args, OPT_O, 1);
- Config->OrphanHandling = getOrphanHandling(Args);
- Config->OutputFile = Args.getLastArgValue(OPT_o);
- Config->PacPlt = Args.hasArg(OPT_pac_plt);
- Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
- Config->PrintIcfSections =
- Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
- Config->PrintGcSections =
- Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
- Config->PrintSymbolOrder =
- Args.getLastArgValue(OPT_print_symbol_order);
- Config->Rpath = getRpath(Args);
- Config->Relocatable = Args.hasArg(OPT_relocatable);
- Config->SaveTemps = Args.hasArg(OPT_save_temps);
- Config->SearchPaths = args::getStrings(Args, OPT_library_path);
- Config->SectionStartMap = getSectionStartMap(Args);
- Config->Shared = Args.hasArg(OPT_shared);
- Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
- Config->SoName = Args.getLastArgValue(OPT_soname);
- Config->SortSection = getSortSection(Args);
- Config->SplitStackAdjustSize = args::getInteger(Args, OPT_split_stack_adjust_size, 16384);
- Config->Strip = getStrip(Args);
- Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
- Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
- Config->Target2 = getTarget2(Args);
- Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
- Config->ThinLTOCachePolicy = CHECK(
- parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
+ config->enableNewDtags =
+ args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
+ config->entry = args.getLastArgValue(OPT_entry);
+ config->executeOnly =
+ args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
+ config->exportDynamic =
+ args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
+ config->filterList = args::getStrings(args, OPT_filter);
+ config->fini = args.getLastArgValue(OPT_fini, "_fini");
+ config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419);
+ config->forceBTI = args.hasArg(OPT_force_bti);
+ config->requireCET = args.hasArg(OPT_require_cet);
+ config->gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
+ config->gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
+ config->gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
+ config->icf = getICF(args);
+ config->ignoreDataAddressEquality =
+ args.hasArg(OPT_ignore_data_address_equality);
+ config->ignoreFunctionAddressEquality =
+ args.hasArg(OPT_ignore_function_address_equality);
+ config->init = args.getLastArgValue(OPT_init, "_init");
+ config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
+ config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
+ config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
+ config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
+ config->ltoNewPassManager = args.hasArg(OPT_lto_new_pass_manager);
+ config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes);
+ config->ltoo = args::getInteger(args, OPT_lto_O, 2);
+ config->ltoObjPath = args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
+ config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
+ config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
+ config->mapFile = args.getLastArgValue(OPT_Map);
+ config->mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0);
+ config->mergeArmExidx =
+ args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
+ config->nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
+ config->noinhibitExec = args.hasArg(OPT_noinhibit_exec);
+ config->nostdlib = args.hasArg(OPT_nostdlib);
+ config->oFormatBinary = isOutputFormatBinary(args);
+ config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
+ config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
+ config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
+ config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
+ config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
+ config->optimize = args::getInteger(args, OPT_O, 1);
+ config->orphanHandling = getOrphanHandling(args);
+ config->outputFile = args.getLastArgValue(OPT_o);
+ config->pacPlt = args.hasArg(OPT_pac_plt);
+ config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
+ config->printIcfSections =
+ args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
+ config->printGcSections =
+ args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
+ config->printSymbolOrder =
+ args.getLastArgValue(OPT_print_symbol_order);
+ config->rpath = getRpath(args);
+ config->relocatable = args.hasArg(OPT_relocatable);
+ config->saveTemps = args.hasArg(OPT_save_temps);
+ config->searchPaths = args::getStrings(args, OPT_library_path);
+ config->sectionStartMap = getSectionStartMap(args);
+ config->shared = args.hasArg(OPT_shared);
+ config->singleRoRx = args.hasArg(OPT_no_rosegment);
+ config->soName = args.getLastArgValue(OPT_soname);
+ config->sortSection = getSortSection(args);
+ config->splitStackAdjustSize = args::getInteger(args, OPT_split_stack_adjust_size, 16384);
+ config->strip = getStrip(args);
+ config->sysroot = args.getLastArgValue(OPT_sysroot);
+ config->target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
+ config->target2 = getTarget2(args);
+ config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
+ config->thinLTOCachePolicy = CHECK(
+ parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
"--thinlto-cache-policy: invalid cache policy");
- Config->ThinLTOEmitImportsFiles =
- Args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
- Config->ThinLTOIndexOnly = Args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
- Args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
- Config->ThinLTOIndexOnlyArg =
- Args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
- Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
- Config->ThinLTOObjectSuffixReplace =
- getOldNewOptions(Args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
- Config->ThinLTOPrefixReplace =
- getOldNewOptions(Args, OPT_plugin_opt_thinlto_prefix_replace_eq);
- Config->Trace = Args.hasArg(OPT_trace);
- Config->Undefined = args::getStrings(Args, OPT_undefined);
- Config->UndefinedVersion =
- Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
- Config->UseAndroidRelrTags = Args.hasFlag(
+ config->thinLTOEmitImportsFiles =
+ args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
+ config->thinLTOIndexOnly = args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
+ args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
+ config->thinLTOIndexOnlyArg =
+ args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
+ config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u);
+ config->thinLTOObjectSuffixReplace =
+ getOldNewOptions(args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
+ config->thinLTOPrefixReplace =
+ getOldNewOptions(args, OPT_plugin_opt_thinlto_prefix_replace_eq);
+ config->trace = args.hasArg(OPT_trace);
+ config->undefined = args::getStrings(args, OPT_undefined);
+ config->undefinedVersion =
+ args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
+ config->useAndroidRelrTags = args.hasFlag(
OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
- Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
- Config->WarnBackrefs =
- Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
- Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
- Config->WarnIfuncTextrel =
- Args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
- Config->WarnSymbolOrdering =
- Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
- Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
- Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
- Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
- Config->ZGlobal = hasZOption(Args, "global");
- Config->ZHazardplt = hasZOption(Args, "hazardplt");
- Config->ZIfuncNoplt = hasZOption(Args, "ifunc-noplt");
- Config->ZInitfirst = hasZOption(Args, "initfirst");
- Config->ZInterpose = hasZOption(Args, "interpose");
- Config->ZKeepTextSectionPrefix = getZFlag(
- Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
- Config->ZNodefaultlib = hasZOption(Args, "nodefaultlib");
- Config->ZNodelete = hasZOption(Args, "nodelete");
- Config->ZNodlopen = hasZOption(Args, "nodlopen");
- Config->ZNow = getZFlag(Args, "now", "lazy", false);
- Config->ZOrigin = hasZOption(Args, "origin");
- Config->ZRelro = getZFlag(Args, "relro", "norelro", true);
- Config->ZRetpolineplt = hasZOption(Args, "retpolineplt");
- Config->ZRodynamic = hasZOption(Args, "rodynamic");
- Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
- Config->ZText = getZFlag(Args, "text", "notext", true);
- Config->ZWxneeded = hasZOption(Args, "wxneeded");
+ config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);
+ config->warnBackrefs =
+ args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
+ config->warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
+ config->warnIfuncTextrel =
+ args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
+ config->warnSymbolOrdering =
+ args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
+ config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
+ config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
+ config->zExecstack = getZFlag(args, "execstack", "noexecstack", false);
+ config->zGlobal = hasZOption(args, "global");
+ config->zHazardplt = hasZOption(args, "hazardplt");
+ config->zIfuncNoplt = hasZOption(args, "ifunc-noplt");
+ config->zInitfirst = hasZOption(args, "initfirst");
+ config->zInterpose = hasZOption(args, "interpose");
+ config->zKeepTextSectionPrefix = getZFlag(
+ args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
+ config->zNodefaultlib = hasZOption(args, "nodefaultlib");
+ config->zNodelete = hasZOption(args, "nodelete");
+ config->zNodlopen = hasZOption(args, "nodlopen");
+ config->zNow = getZFlag(args, "now", "lazy", false);
+ config->zOrigin = hasZOption(args, "origin");
+ config->zRelro = getZFlag(args, "relro", "norelro", true);
+ config->zRetpolineplt = hasZOption(args, "retpolineplt");
+ config->zRodynamic = hasZOption(args, "rodynamic");
+ config->zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
+ config->zText = getZFlag(args, "text", "notext", true);
+ config->zWxneeded = hasZOption(args, "wxneeded");
// Parse LTO options.
- if (auto *Arg = Args.getLastArg(OPT_plugin_opt_mcpu_eq))
- parseClangOption(Saver.save("-mcpu=" + StringRef(Arg->getValue())),
- Arg->getSpelling());
+ if (auto *arg = args.getLastArg(OPT_plugin_opt_mcpu_eq))
+ parseClangOption(Saver.save("-mcpu=" + StringRef(arg->getValue())),
+ arg->getSpelling());
- for (auto *Arg : Args.filtered(OPT_plugin_opt))
- parseClangOption(Arg->getValue(), Arg->getSpelling());
+ for (auto *arg : args.filtered(OPT_plugin_opt))
+ parseClangOption(arg->getValue(), arg->getSpelling());
// Parse -mllvm options.
- for (auto *Arg : Args.filtered(OPT_mllvm))
- parseClangOption(Arg->getValue(), Arg->getSpelling());
+ for (auto *arg : args.filtered(OPT_mllvm))
+ parseClangOption(arg->getValue(), arg->getSpelling());
- if (Config->LTOO > 3)
- error("invalid optimization level for LTO: " + Twine(Config->LTOO));
- if (Config->LTOPartitions == 0)
+ if (config->ltoo > 3)
+ error("invalid optimization level for LTO: " + Twine(config->ltoo));
+ if (config->ltoPartitions == 0)
error("--lto-partitions: number of threads must be > 0");
- if (Config->ThinLTOJobs == 0)
+ if (config->thinLTOJobs == 0)
error("--thinlto-jobs: number of threads must be > 0");
- if (Config->SplitStackAdjustSize < 0)
+ if (config->splitStackAdjustSize < 0)
error("--split-stack-adjust-size: size must be >= 0");
// Parse ELF{32,64}{LE,BE} and CPU type.
- if (auto *Arg = Args.getLastArg(OPT_m)) {
- StringRef S = Arg->getValue();
- std::tie(Config->EKind, Config->EMachine, Config->OSABI) =
- parseEmulation(S);
- Config->MipsN32Abi = (S == "elf32btsmipn32" || S == "elf32ltsmipn32");
- Config->Emulation = S;
+ if (auto *arg = args.getLastArg(OPT_m)) {
+ StringRef s = arg->getValue();
+ std::tie(config->ekind, config->emachine, config->osabi) =
+ parseEmulation(s);
+ config->mipsN32Abi = (s == "elf32btsmipn32" || s == "elf32ltsmipn32");
+ config->emulation = s;
}
// Parse -hash-style={sysv,gnu,both}.
- if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
- StringRef S = Arg->getValue();
- if (S == "sysv")
- Config->SysvHash = true;
- else if (S == "gnu")
- Config->GnuHash = true;
- else if (S == "both")
- Config->SysvHash = Config->GnuHash = true;
+ if (auto *arg = args.getLastArg(OPT_hash_style)) {
+ StringRef s = arg->getValue();
+ if (s == "sysv")
+ config->sysvHash = true;
+ else if (s == "gnu")
+ config->gnuHash = true;
+ else if (s == "both")
+ config->sysvHash = config->gnuHash = true;
else
- error("unknown -hash-style: " + S);
+ error("unknown -hash-style: " + s);
}
- if (Args.hasArg(OPT_print_map))
- Config->MapFile = "-";
+ if (args.hasArg(OPT_print_map))
+ config->mapFile = "-";
// Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
// As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
// it.
- if (Config->Nmagic || Config->Omagic)
- Config->ZRelro = false;
+ if (config->nmagic || config->omagic)
+ config->zRelro = false;
- std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args);
+ std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
- std::tie(Config->AndroidPackDynRelocs, Config->RelrPackDynRelocs) =
- getPackDynRelocs(Args);
+ std::tie(config->androidPackDynRelocs, config->relrPackDynRelocs) =
+ getPackDynRelocs(args);
- if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)){
- if (Args.hasArg(OPT_call_graph_ordering_file))
+ if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
+ if (args.hasArg(OPT_call_graph_ordering_file))
error("--symbol-ordering-file and --call-graph-order-file "
"may not be used together");
- if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())){
- Config->SymbolOrderingFile = getSymbolOrderingFile(*Buffer);
+ if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue())){
+ config->symbolOrderingFile = getSymbolOrderingFile(*buffer);
// Also need to disable CallGraphProfileSort to prevent
// LLD order symbols with CGProfile
- Config->CallGraphProfileSort = false;
+ config->callGraphProfileSort = false;
}
}
// If --retain-symbol-file is used, we'll keep only the symbols listed in
// the file and discard all others.
- if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
- Config->DefaultSymbolVersion = VER_NDX_LOCAL;
- if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
- for (StringRef S : args::getLines(*Buffer))
- Config->VersionScriptGlobals.push_back(
- {S, /*IsExternCpp*/ false, /*HasWildcard*/ false});
+ if (auto *arg = args.getLastArg(OPT_retain_symbols_file)) {
+ config->defaultSymbolVersion = VER_NDX_LOCAL;
+ if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
+ for (StringRef s : args::getLines(*buffer))
+ config->versionScriptGlobals.push_back(
+ {s, /*IsExternCpp*/ false, /*HasWildcard*/ false});
}
- bool HasExportDynamic =
- Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
+ bool hasExportDynamic =
+ args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
// Parses -dynamic-list and -export-dynamic-symbol. They make some
// symbols private. Note that -export-dynamic takes precedence over them
// as it says all symbols should be exported.
- if (!HasExportDynamic) {
- for (auto *Arg : Args.filtered(OPT_dynamic_list))
- if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
- readDynamicList(*Buffer);
-
- for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
- Config->DynamicList.push_back(
- {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
+ if (!hasExportDynamic) {
+ for (auto *arg : args.filtered(OPT_dynamic_list))
+ if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
+ readDynamicList(*buffer);
+
+ for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
+ config->dynamicList.push_back(
+ {arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
}
// If --export-dynamic-symbol=foo is given and symbol foo is defined in
// an object file in an archive file, that object file should be pulled
// out and linked. (It doesn't have to behave like that from technical
// point of view, but this is needed for compatibility with GNU.)
- for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
- Config->Undefined.push_back(Arg->getValue());
+ for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
+ config->undefined.push_back(arg->getValue());
- for (auto *Arg : Args.filtered(OPT_version_script))
- if (Optional<std::string> Path = searchScript(Arg->getValue())) {
- if (Optional<MemoryBufferRef> Buffer = readFile(*Path))
- readVersionScript(*Buffer);
+ for (auto *arg : args.filtered(OPT_version_script))
+ if (Optional<std::string> path = searchScript(arg->getValue())) {
+ if (Optional<MemoryBufferRef> buffer = readFile(*path))
+ readVersionScript(*buffer);
} else {
- error(Twine("cannot find version script ") + Arg->getValue());
+ error(Twine("cannot find version script ") + arg->getValue());
}
}
@@ -1053,18 +1053,18 @@ static void readConfigs(opt::InputArgList &Args) {
// command line options, but computed based on other Config values.
// This function initialize such members. See Config.h for the details
// of these values.
-static void setConfigs(opt::InputArgList &Args) {
- ELFKind K = Config->EKind;
- uint16_t M = Config->EMachine;
-
- Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
- Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind);
- Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind);
- Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
- Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
- Config->Pic = Config->Pie || Config->Shared;
- Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
- Config->Wordsize = Config->Is64 ? 8 : 4;
+static void setConfigs(opt::InputArgList &args) {
+ ELFKind k = config->ekind;
+ uint16_t m = config->emachine;
+
+ config->copyRelocs = (config->relocatable || config->emitRelocs);
+ config->is64 = (k == ELF64LEKind || k == ELF64BEKind);
+ config->isLE = (k == ELF32LEKind || k == ELF64LEKind);
+ config->endianness = config->isLE ? endianness::little : endianness::big;
+ config->isMips64EL = (k == ELF64LEKind && m == EM_MIPS);
+ config->isPic = config->pie || config->shared;
+ config->picThunk = args.hasArg(OPT_pic_veneer, config->isPic);
+ config->wordsize = config->is64 ? 8 : 4;
// ELF defines two different ways to store relocation addends as shown below:
//
@@ -1079,150 +1079,150 @@ static void setConfigs(opt::InputArgList &Args) {
// You cannot choose which one, Rel or Rela, you want to use. Instead each
// ABI defines which one you need to use. The following expression expresses
// that.
- Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
- M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
- M == EM_X86_64;
+ config->isRela = m == EM_AARCH64 || m == EM_AMDGPU || m == EM_HEXAGON ||
+ m == EM_PPC || m == EM_PPC64 || m == EM_RISCV ||
+ m == EM_X86_64;
// If the output uses REL relocations we must store the dynamic relocation
// addends to the output sections. We also store addends for RELA relocations
// if --apply-dynamic-relocs is used.
// We default to not writing the addends when using RELA relocations since
// any standard conforming tool can find it in r_addend.
- Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
+ config->writeAddends = args.hasFlag(OPT_apply_dynamic_relocs,
OPT_no_apply_dynamic_relocs, false) ||
- !Config->IsRela;
+ !config->isRela;
- Config->TocOptimize =
- Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
+ config->tocOptimize =
+ args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64);
}
// Returns a value of "-format" option.
-static bool isFormatBinary(StringRef S) {
- if (S == "binary")
+static bool isFormatBinary(StringRef s) {
+ if (s == "binary")
return true;
- if (S == "elf" || S == "default")
+ if (s == "elf" || s == "default")
return false;
- error("unknown -format value: " + S +
+ error("unknown -format value: " + s +
" (supported formats: elf, default, binary)");
return false;
}
-void LinkerDriver::createFiles(opt::InputArgList &Args) {
+void LinkerDriver::createFiles(opt::InputArgList &args) {
// For --{push,pop}-state.
- std::vector<std::tuple<bool, bool, bool>> Stack;
+ std::vector<std::tuple<bool, bool, bool>> stack;
// Iterate over argv to process input files and positional arguments.
- for (auto *Arg : Args) {
- switch (Arg->getOption().getID()) {
+ for (auto *arg : args) {
+ switch (arg->getOption().getID()) {
case OPT_library:
- addLibrary(Arg->getValue());
+ addLibrary(arg->getValue());
break;
case OPT_INPUT:
- addFile(Arg->getValue(), /*WithLOption=*/false);
+ addFile(arg->getValue(), /*WithLOption=*/false);
break;
case OPT_defsym: {
- StringRef From;
- StringRef To;
- std::tie(From, To) = StringRef(Arg->getValue()).split('=');
- if (From.empty() || To.empty())
- error("-defsym: syntax error: " + StringRef(Arg->getValue()));
+ StringRef from;
+ StringRef to;
+ std::tie(from, to) = StringRef(arg->getValue()).split('=');
+ if (from.empty() || to.empty())
+ error("-defsym: syntax error: " + StringRef(arg->getValue()));
else
- readDefsym(From, MemoryBufferRef(To, "-defsym"));
+ readDefsym(from, MemoryBufferRef(to, "-defsym"));
break;
}
case OPT_script:
- if (Optional<std::string> Path = searchScript(Arg->getValue())) {
- if (Optional<MemoryBufferRef> MB = readFile(*Path))
- readLinkerScript(*MB);
+ if (Optional<std::string> path = searchScript(arg->getValue())) {
+ if (Optional<MemoryBufferRef> mb = readFile(*path))
+ readLinkerScript(*mb);
break;
}
- error(Twine("cannot find linker script ") + Arg->getValue());
+ error(Twine("cannot find linker script ") + arg->getValue());
break;
case OPT_as_needed:
- Config->AsNeeded = true;
+ config->asNeeded = true;
break;
case OPT_format:
- Config->FormatBinary = isFormatBinary(Arg->getValue());
+ config->formatBinary = isFormatBinary(arg->getValue());
break;
case OPT_no_as_needed:
- Config->AsNeeded = false;
+ config->asNeeded = false;
break;
case OPT_Bstatic:
case OPT_omagic:
case OPT_nmagic:
- Config->Static = true;
+ config->isStatic = true;
break;
case OPT_Bdynamic:
- Config->Static = false;
+ config->isStatic = false;
break;
case OPT_whole_archive:
- InWholeArchive = true;
+ inWholeArchive = true;
break;
case OPT_no_whole_archive:
- InWholeArchive = false;
+ inWholeArchive = false;
break;
case OPT_just_symbols:
- if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue())) {
- Files.push_back(createObjectFile(*MB));
- Files.back()->JustSymbols = true;
+ if (Optional<MemoryBufferRef> mb = readFile(arg->getValue())) {
+ files.push_back(createObjectFile(*mb));
+ files.back()->justSymbols = true;
}
break;
case OPT_start_group:
- if (InputFile::IsInGroup)
+ if (InputFile::isInGroup)
error("nested --start-group");
- InputFile::IsInGroup = true;
+ InputFile::isInGroup = true;
break;
case OPT_end_group:
- if (!InputFile::IsInGroup)
+ if (!InputFile::isInGroup)
error("stray --end-group");
- InputFile::IsInGroup = false;
- ++InputFile::NextGroupId;
+ InputFile::isInGroup = false;
+ ++InputFile::nextGroupId;
break;
case OPT_start_lib:
- if (InLib)
+ if (inLib)
error("nested --start-lib");
- if (InputFile::IsInGroup)
+ if (InputFile::isInGroup)
error("may not nest --start-lib in --start-group");
- InLib = true;
- InputFile::IsInGroup = true;
+ inLib = true;
+ InputFile::isInGroup = true;
break;
case OPT_end_lib:
- if (!InLib)
+ if (!inLib)
error("stray --end-lib");
- InLib = false;
- InputFile::IsInGroup = false;
- ++InputFile::NextGroupId;
+ inLib = false;
+ InputFile::isInGroup = false;
+ ++InputFile::nextGroupId;
break;
case OPT_push_state:
- Stack.emplace_back(Config->AsNeeded, Config->Static, InWholeArchive);
+ stack.emplace_back(config->asNeeded, config->isStatic, inWholeArchive);
break;
case OPT_pop_state:
- if (Stack.empty()) {
+ if (stack.empty()) {
error("unbalanced --push-state/--pop-state");
break;
}
- std::tie(Config->AsNeeded, Config->Static, InWholeArchive) = Stack.back();
- Stack.pop_back();
+ std::tie(config->asNeeded, config->isStatic, inWholeArchive) = stack.back();
+ stack.pop_back();
break;
}
}
- if (Files.empty() && errorCount() == 0)
+ if (files.empty() && errorCount() == 0)
error("no input files");
}
// If -m <machine_type> was not given, infer it from object files.
void LinkerDriver::inferMachineType() {
- if (Config->EKind != ELFNoneKind)
+ if (config->ekind != ELFNoneKind)
return;
- for (InputFile *F : Files) {
- if (F->EKind == ELFNoneKind)
+ for (InputFile *f : files) {
+ if (f->ekind == ELFNoneKind)
continue;
- Config->EKind = F->EKind;
- Config->EMachine = F->EMachine;
- Config->OSABI = F->OSABI;
- Config->MipsN32Abi = Config->EMachine == EM_MIPS && isMipsN32Abi(F);
+ config->ekind = f->ekind;
+ config->emachine = f->emachine;
+ config->osabi = f->osabi;
+ config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f);
return;
}
error("target emulation unknown: -m or at least one .o file required");
@@ -1230,72 +1230,72 @@ void LinkerDriver::inferMachineType() {
// Parse -z max-page-size=<value>. The default value is defined by
// each target.
-static uint64_t getMaxPageSize(opt::InputArgList &Args) {
- uint64_t Val = args::getZOptionValue(Args, OPT_z, "max-page-size",
- Target->DefaultMaxPageSize);
- if (!isPowerOf2_64(Val))
+static uint64_t getMaxPageSize(opt::InputArgList &args) {
+ uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
+ target->defaultMaxPageSize);
+ if (!isPowerOf2_64(val))
error("max-page-size: value isn't a power of 2");
- if (Config->Nmagic || Config->Omagic) {
- if (Val != Target->DefaultMaxPageSize)
+ if (config->nmagic || config->omagic) {
+ if (val != target->defaultMaxPageSize)
warn("-z max-page-size set, but paging disabled by omagic or nmagic");
return 1;
}
- return Val;
+ return val;
}
// Parse -z common-page-size=<value>. The default value is defined by
// each target.
-static uint64_t getCommonPageSize(opt::InputArgList &Args) {
- uint64_t Val = args::getZOptionValue(Args, OPT_z, "common-page-size",
- Target->DefaultCommonPageSize);
- if (!isPowerOf2_64(Val))
+static uint64_t getCommonPageSize(opt::InputArgList &args) {
+ uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
+ target->defaultCommonPageSize);
+ if (!isPowerOf2_64(val))
error("common-page-size: value isn't a power of 2");
- if (Config->Nmagic || Config->Omagic) {
- if (Val != Target->DefaultCommonPageSize)
+ if (config->nmagic || config->omagic) {
+ if (val != target->defaultCommonPageSize)
warn("-z common-page-size set, but paging disabled by omagic or nmagic");
return 1;
}
// CommonPageSize can't be larger than MaxPageSize.
- if (Val > Config->MaxPageSize)
- Val = Config->MaxPageSize;
- return Val;
+ if (val > config->maxPageSize)
+ val = config->maxPageSize;
+ return val;
}
// Parses -image-base option.
-static Optional<uint64_t> getImageBase(opt::InputArgList &Args) {
+static Optional<uint64_t> getImageBase(opt::InputArgList &args) {
// Because we are using "Config->MaxPageSize" here, this function has to be
// called after the variable is initialized.
- auto *Arg = Args.getLastArg(OPT_image_base);
- if (!Arg)
+ auto *arg = args.getLastArg(OPT_image_base);
+ if (!arg)
return None;
- StringRef S = Arg->getValue();
- uint64_t V;
- if (!to_integer(S, V)) {
- error("-image-base: number expected, but got " + S);
+ StringRef s = arg->getValue();
+ uint64_t v;
+ if (!to_integer(s, v)) {
+ error("-image-base: number expected, but got " + s);
return 0;
}
- if ((V % Config->MaxPageSize) != 0)
- warn("-image-base: address isn't multiple of page size: " + S);
- return V;
+ if ((v % config->maxPageSize) != 0)
+ warn("-image-base: address isn't multiple of page size: " + s);
+ return v;
}
// Parses `--exclude-libs=lib,lib,...`.
// The library names may be delimited by commas or colons.
-static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
- DenseSet<StringRef> Ret;
- for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
- StringRef S = Arg->getValue();
+static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &args) {
+ DenseSet<StringRef> ret;
+ for (auto *arg : args.filtered(OPT_exclude_libs)) {
+ StringRef s = arg->getValue();
for (;;) {
- size_t Pos = S.find_first_of(",:");
- if (Pos == StringRef::npos)
+ size_t pos = s.find_first_of(",:");
+ if (pos == StringRef::npos)
break;
- Ret.insert(S.substr(0, Pos));
- S = S.substr(Pos + 1);
+ ret.insert(s.substr(0, pos));
+ s = s.substr(pos + 1);
}
- Ret.insert(S);
+ ret.insert(s);
}
- return Ret;
+ return ret;
}
// Handles the -exclude-libs option. If a static library file is specified
@@ -1304,71 +1304,71 @@ static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
// A special library name "ALL" means all archive files.
//
// This is not a popular option, but some programs such as bionic libc use it.
-static void excludeLibs(opt::InputArgList &Args) {
- DenseSet<StringRef> Libs = getExcludeLibs(Args);
- bool All = Libs.count("ALL");
-
- auto Visit = [&](InputFile *File) {
- if (!File->ArchiveName.empty())
- if (All || Libs.count(path::filename(File->ArchiveName)))
- for (Symbol *Sym : File->getSymbols())
- if (!Sym->isLocal() && Sym->File == File)
- Sym->VersionId = VER_NDX_LOCAL;
+static void excludeLibs(opt::InputArgList &args) {
+ DenseSet<StringRef> libs = getExcludeLibs(args);
+ bool all = libs.count("ALL");
+
+ auto visit = [&](InputFile *file) {
+ if (!file->archiveName.empty())
+ if (all || libs.count(path::filename(file->archiveName)))
+ for (Symbol *sym : file->getSymbols())
+ if (!sym->isLocal() && sym->file == file)
+ sym->versionId = VER_NDX_LOCAL;
};
- for (InputFile *File : ObjectFiles)
- Visit(File);
+ for (InputFile *file : objectFiles)
+ visit(file);
- for (BitcodeFile *File : BitcodeFiles)
- Visit(File);
+ for (BitcodeFile *file : bitcodeFiles)
+ visit(file);
}
// Force Sym to be entered in the output. Used for -u or equivalent.
-static void handleUndefined(Symbol *Sym) {
+static void handleUndefined(Symbol *sym) {
// Since a symbol may not be used inside the program, LTO may
// eliminate it. Mark the symbol as "used" to prevent it.
- Sym->IsUsedInRegularObj = true;
+ sym->isUsedInRegularObj = true;
- if (Sym->isLazy())
- Sym->fetch();
+ if (sym->isLazy())
+ sym->fetch();
}
// As an extention to GNU linkers, lld supports a variant of `-u`
// which accepts wildcard patterns. All symbols that match a given
// pattern are handled as if they were given by `-u`.
-static void handleUndefinedGlob(StringRef Arg) {
- Expected<GlobPattern> Pat = GlobPattern::create(Arg);
- if (!Pat) {
- error("--undefined-glob: " + toString(Pat.takeError()));
+static void handleUndefinedGlob(StringRef arg) {
+ Expected<GlobPattern> pat = GlobPattern::create(arg);
+ if (!pat) {
+ error("--undefined-glob: " + toString(pat.takeError()));
return;
}
- std::vector<Symbol *> Syms;
- Symtab->forEachSymbol([&](Symbol *Sym) {
+ std::vector<Symbol *> syms;
+ symtab->forEachSymbol([&](Symbol *sym) {
// Calling Sym->fetch() from here is not safe because it may
// add new symbols to the symbol table, invalidating the
// current iterator. So we just keep a note.
- if (Pat->match(Sym->getName()))
- Syms.push_back(Sym);
+ if (pat->match(sym->getName()))
+ syms.push_back(sym);
});
- for (Symbol *Sym : Syms)
- handleUndefined(Sym);
+ for (Symbol *sym : syms)
+ handleUndefined(sym);
}
-static void handleLibcall(StringRef Name) {
- Symbol *Sym = Symtab->find(Name);
- if (!Sym || !Sym->isLazy())
+static void handleLibcall(StringRef name) {
+ Symbol *sym = symtab->find(name);
+ if (!sym || !sym->isLazy())
return;
- MemoryBufferRef MB;
- if (auto *LO = dyn_cast<LazyObject>(Sym))
- MB = LO->File->MB;
+ MemoryBufferRef mb;
+ if (auto *lo = dyn_cast<LazyObject>(sym))
+ mb = lo->file->mb;
else
- MB = cast<LazyArchive>(Sym)->getMemberBuffer();
+ mb = cast<LazyArchive>(sym)->getMemberBuffer();
- if (isBitcode(MB))
- Sym->fetch();
+ if (isBitcode(mb))
+ sym->fetch();
}
// Replaces common symbols with defined symbols reside in .bss sections.
@@ -1376,17 +1376,17 @@ static void handleLibcall(StringRef Name) {
// result, the passes after the symbol resolution won't see any
// symbols of type CommonSymbol.
static void replaceCommonSymbols() {
- Symtab->forEachSymbol([](Symbol *Sym) {
- auto *S = dyn_cast<CommonSymbol>(Sym);
- if (!S)
+ symtab->forEachSymbol([](Symbol *sym) {
+ auto *s = dyn_cast<CommonSymbol>(sym);
+ if (!s)
return;
- auto *Bss = make<BssSection>("COMMON", S->Size, S->Alignment);
- Bss->File = S->File;
- Bss->markDead();
- InputSections.push_back(Bss);
- S->replace(Defined{S->File, S->getName(), S->Binding, S->StOther, S->Type,
- /*Value=*/0, S->Size, Bss});
+ auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
+ bss->file = s->file;
+ bss->markDead();
+ inputSections.push_back(bss);
+ s->replace(Defined{s->file, s->getName(), s->binding, s->stOther, s->type,
+ /*Value=*/0, s->size, bss});
});
}
@@ -1395,78 +1395,78 @@ static void replaceCommonSymbols() {
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
static void demoteSharedSymbols() {
- Symtab->forEachSymbol([](Symbol *Sym) {
- auto *S = dyn_cast<SharedSymbol>(Sym);
- if (!S || S->getFile().IsNeeded)
+ symtab->forEachSymbol([](Symbol *sym) {
+ auto *s = dyn_cast<SharedSymbol>(sym);
+ if (!s || s->getFile().isNeeded)
return;
- bool Used = S->Used;
- S->replace(Undefined{nullptr, S->getName(), STB_WEAK, S->StOther, S->Type});
- S->Used = Used;
+ bool used = s->used;
+ s->replace(Undefined{nullptr, s->getName(), STB_WEAK, s->stOther, s->type});
+ s->used = used;
});
}
// The section referred to by S is considered address-significant. Set the
// KeepUnique flag on the section if appropriate.
-static void markAddrsig(Symbol *S) {
- if (auto *D = dyn_cast_or_null<Defined>(S))
- if (D->Section)
+static void markAddrsig(Symbol *s) {
+ if (auto *d = dyn_cast_or_null<Defined>(s))
+ if (d->section)
// We don't need to keep text sections unique under --icf=all even if they
// are address-significant.
- if (Config->ICF == ICFLevel::Safe || !(D->Section->Flags & SHF_EXECINSTR))
- D->Section->KeepUnique = true;
+ if (config->icf == ICFLevel::Safe || !(d->section->flags & SHF_EXECINSTR))
+ d->section->keepUnique = true;
}
// Record sections that define symbols mentioned in --keep-unique <symbol>
// and symbols referred to by address-significance tables. These sections are
// ineligible for ICF.
template <class ELFT>
-static void findKeepUniqueSections(opt::InputArgList &Args) {
- for (auto *Arg : Args.filtered(OPT_keep_unique)) {
- StringRef Name = Arg->getValue();
- auto *D = dyn_cast_or_null<Defined>(Symtab->find(Name));
- if (!D || !D->Section) {
- warn("could not find symbol " + Name + " to keep unique");
+static void findKeepUniqueSections(opt::InputArgList &args) {
+ for (auto *arg : args.filtered(OPT_keep_unique)) {
+ StringRef name = arg->getValue();
+ auto *d = dyn_cast_or_null<Defined>(symtab->find(name));
+ if (!d || !d->section) {
+ warn("could not find symbol " + name + " to keep unique");
continue;
}
- D->Section->KeepUnique = true;
+ d->section->keepUnique = true;
}
// --icf=all --ignore-data-address-equality means that we can ignore
// the dynsym and address-significance tables entirely.
- if (Config->ICF == ICFLevel::All && Config->IgnoreDataAddressEquality)
+ if (config->icf == ICFLevel::All && config->ignoreDataAddressEquality)
return;
// Symbols in the dynsym could be address-significant in other executables
// or DSOs, so we conservatively mark them as address-significant.
- Symtab->forEachSymbol([&](Symbol *Sym) {
- if (Sym->includeInDynsym())
- markAddrsig(Sym);
+ symtab->forEachSymbol([&](Symbol *sym) {
+ if (sym->includeInDynsym())
+ markAddrsig(sym);
});
// Visit the address-significance table in each object file and mark each
// referenced symbol as address-significant.
- for (InputFile *F : ObjectFiles) {
- auto *Obj = cast<ObjFile<ELFT>>(F);
- ArrayRef<Symbol *> Syms = Obj->getSymbols();
- if (Obj->AddrsigSec) {
- ArrayRef<uint8_t> Contents =
- check(Obj->getObj().getSectionContents(Obj->AddrsigSec));
- const uint8_t *Cur = Contents.begin();
- while (Cur != Contents.end()) {
- unsigned Size;
- const char *Err;
- uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
- if (Err)
- fatal(toString(F) + ": could not decode addrsig section: " + Err);
- markAddrsig(Syms[SymIndex]);
- Cur += Size;
+ for (InputFile *f : objectFiles) {
+ auto *obj = cast<ObjFile<ELFT>>(f);
+ ArrayRef<Symbol *> syms = obj->getSymbols();
+ if (obj->addrsigSec) {
+ ArrayRef<uint8_t> contents =
+ check(obj->getObj().getSectionContents(obj->addrsigSec));
+ const uint8_t *cur = contents.begin();
+ while (cur != contents.end()) {
+ unsigned size;
+ const char *err;
+ uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err);
+ if (err)
+ fatal(toString(f) + ": could not decode addrsig section: " + err);
+ markAddrsig(syms[symIndex]);
+ cur += size;
}
} else {
// If an object file does not have an address-significance table,
// conservatively mark all of its symbols as address-significant.
- for (Symbol *S : Syms)
- markAddrsig(S);
+ for (Symbol *s : syms)
+ markAddrsig(s);
}
}
}
@@ -1475,20 +1475,20 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
// are used to control which partition a symbol is allocated to. See
// https://lld.llvm.org/Partitions.html for more details on partitions.
template <typename ELFT>
-static void readSymbolPartitionSection(InputSectionBase *S) {
+static void readSymbolPartitionSection(InputSectionBase *s) {
// Read the relocation that refers to the partition's entry point symbol.
- Symbol *Sym;
- if (S->AreRelocsRela)
- Sym = &S->getFile<ELFT>()->getRelocTargetSym(S->template relas<ELFT>()[0]);
+ Symbol *sym;
+ if (s->areRelocsRela)
+ sym = &s->getFile<ELFT>()->getRelocTargetSym(s->template relas<ELFT>()[0]);
else
- Sym = &S->getFile<ELFT>()->getRelocTargetSym(S->template rels<ELFT>()[0]);
- if (!isa<Defined>(Sym) || !Sym->includeInDynsym())
+ sym = &s->getFile<ELFT>()->getRelocTargetSym(s->template rels<ELFT>()[0]);
+ if (!isa<Defined>(sym) || !sym->includeInDynsym())
return;
- StringRef PartName = reinterpret_cast<const char *>(S->data().data());
- for (Partition &Part : Partitions) {
- if (Part.Name == PartName) {
- Sym->Partition = Part.getNumber();
+ StringRef partName = reinterpret_cast<const char *>(s->data().data());
+ for (Partition &part : partitions) {
+ if (part.name == partName) {
+ sym->partition = part.getNumber();
return;
}
}
@@ -1496,33 +1496,33 @@ static void readSymbolPartitionSection(InputSectionBase *S) {
// Forbid partitions from being used on incompatible targets, and forbid them
// from being used together with various linker features that assume a single
// set of output sections.
- if (Script->HasSectionsCommand)
- error(toString(S->File) +
+ if (script->hasSectionsCommand)
+ error(toString(s->file) +
": partitions cannot be used with the SECTIONS command");
- if (Script->hasPhdrsCommands())
- error(toString(S->File) +
+ if (script->hasPhdrsCommands())
+ error(toString(s->file) +
": partitions cannot be used with the PHDRS command");
- if (!Config->SectionStartMap.empty())
- error(toString(S->File) + ": partitions cannot be used with "
+ if (!config->sectionStartMap.empty())
+ error(toString(s->file) + ": partitions cannot be used with "
"--section-start, -Ttext, -Tdata or -Tbss");
- if (Config->EMachine == EM_MIPS)
- error(toString(S->File) + ": partitions cannot be used on this target");
+ if (config->emachine == EM_MIPS)
+ error(toString(s->file) + ": partitions cannot be used on this target");
// Impose a limit of no more than 254 partitions. This limit comes from the
// sizes of the Partition fields in InputSectionBase and Symbol, as well as
// the amount of space devoted to the partition number in RankFlags.
- if (Partitions.size() == 254)
+ if (partitions.size() == 254)
fatal("may not have more than 254 partitions");
- Partitions.emplace_back();
- Partition &NewPart = Partitions.back();
- NewPart.Name = PartName;
- Sym->Partition = NewPart.getNumber();
+ partitions.emplace_back();
+ Partition &newPart = partitions.back();
+ newPart.name = partName;
+ sym->partition = newPart.getNumber();
}
-static Symbol *addUndefined(StringRef Name) {
- return Symtab->addSymbol(
- Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
+static Symbol *addUndefined(StringRef name) {
+ return symtab->addSymbol(
+ Undefined{nullptr, name, STB_GLOBAL, STV_DEFAULT, 0});
}
// This function is where all the optimizations of link-time
@@ -1534,16 +1534,16 @@ static Symbol *addUndefined(StringRef Name) {
// the compiler at once, it can do a whole-program optimization.
template <class ELFT> void LinkerDriver::compileBitcodeFiles() {
// Compile bitcode files and replace bitcode symbols.
- LTO.reset(new BitcodeCompiler);
- for (BitcodeFile *File : BitcodeFiles)
- LTO->add(*File);
-
- for (InputFile *File : LTO->compile()) {
- auto *Obj = cast<ObjFile<ELFT>>(File);
- Obj->parse(/*IgnoreComdats=*/true);
- for (Symbol *Sym : Obj->getGlobalSymbols())
- Sym->parseSymbolVersion();
- ObjectFiles.push_back(File);
+ lto.reset(new BitcodeCompiler);
+ for (BitcodeFile *file : bitcodeFiles)
+ lto->add(*file);
+
+ for (InputFile *file : lto->compile()) {
+ auto *obj = cast<ObjFile<ELFT>>(file);
+ obj->parse(/*IgnoreComdats=*/true);
+ for (Symbol *sym : obj->getGlobalSymbols())
+ sym->parseSymbolVersion();
+ objectFiles.push_back(file);
}
}
@@ -1556,9 +1556,9 @@ template <class ELFT> void LinkerDriver::compileBitcodeFiles() {
//
// This data structure is instantiated for each -wrap option.
struct WrappedSymbol {
- Symbol *Sym;
- Symbol *Real;
- Symbol *Wrap;
+ Symbol *sym;
+ Symbol *real;
+ Symbol *wrap;
};
// Handles -wrap option.
@@ -1566,33 +1566,33 @@ struct WrappedSymbol {
// This function instantiates wrapper symbols. At this point, they seem
// like they are not being used at all, so we explicitly set some flags so
// that LTO won't eliminate them.
-static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
- std::vector<WrappedSymbol> V;
- DenseSet<StringRef> Seen;
+static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
+ std::vector<WrappedSymbol> v;
+ DenseSet<StringRef> seen;
- for (auto *Arg : Args.filtered(OPT_wrap)) {
- StringRef Name = Arg->getValue();
- if (!Seen.insert(Name).second)
+ for (auto *arg : args.filtered(OPT_wrap)) {
+ StringRef name = arg->getValue();
+ if (!seen.insert(name).second)
continue;
- Symbol *Sym = Symtab->find(Name);
- if (!Sym)
+ Symbol *sym = symtab->find(name);
+ if (!sym)
continue;
- Symbol *Real = addUndefined(Saver.save("__real_" + Name));
- Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name));
- V.push_back({Sym, Real, Wrap});
+ Symbol *real = addUndefined(Saver.save("__real_" + name));
+ Symbol *wrap = addUndefined(Saver.save("__wrap_" + name));
+ v.push_back({sym, real, wrap});
// We want to tell LTO not to inline symbols to be overwritten
// because LTO doesn't know the final symbol contents after renaming.
- Real->CanInline = false;
- Sym->CanInline = false;
+ real->canInline = false;
+ sym->canInline = false;
// Tell LTO not to eliminate these symbols.
- Sym->IsUsedInRegularObj = true;
- Wrap->IsUsedInRegularObj = true;
+ sym->isUsedInRegularObj = true;
+ wrap->isUsedInRegularObj = true;
}
- return V;
+ return v;
}
// Do renaming for -wrap by updating pointers to symbols.
@@ -1600,24 +1600,24 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
// When this function is executed, only InputFiles and symbol table
// contain pointers to symbol objects. We visit them to replace pointers,
// so that wrapped symbols are swapped as instructed by the command line.
-static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) {
- DenseMap<Symbol *, Symbol *> Map;
- for (const WrappedSymbol &W : Wrapped) {
- Map[W.Sym] = W.Wrap;
- Map[W.Real] = W.Sym;
+static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
+ DenseMap<Symbol *, Symbol *> map;
+ for (const WrappedSymbol &w : wrapped) {
+ map[w.sym] = w.wrap;
+ map[w.real] = w.sym;
}
// Update pointers in input files.
- parallelForEach(ObjectFiles, [&](InputFile *File) {
- MutableArrayRef<Symbol *> Syms = File->getMutableSymbols();
- for (size_t I = 0, E = Syms.size(); I != E; ++I)
- if (Symbol *S = Map.lookup(Syms[I]))
- Syms[I] = S;
+ parallelForEach(objectFiles, [&](InputFile *file) {
+ MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
+ for (size_t i = 0, e = syms.size(); i != e; ++i)
+ if (Symbol *s = map.lookup(syms[i]))
+ syms[i] = s;
});
// Update pointers in the symbol table.
- for (const WrappedSymbol &W : Wrapped)
- Symtab->wrap(W.Sym, W.Real, W.Wrap);
+ for (const WrappedSymbol &w : wrapped)
+ symtab->wrap(w.sym, w.real, w.wrap);
}
// To enable CET (x86's hardware-assited control flow enforcement), each
@@ -1633,30 +1633,30 @@ static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) {
// Note that the CET-aware PLT is not implemented yet. We do error
// check only.
template <class ELFT> static uint32_t getAndFeatures() {
- if (Config->EMachine != EM_386 && Config->EMachine != EM_X86_64 &&
- Config->EMachine != EM_AARCH64)
+ if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
+ config->emachine != EM_AARCH64)
return 0;
- uint32_t Ret = -1;
- for (InputFile *F : ObjectFiles) {
- uint32_t Features = cast<ObjFile<ELFT>>(F)->AndFeatures;
- if (Config->ForceBTI && !(Features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
- warn(toString(F) + ": --force-bti: file does not have BTI property");
- Features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
- } else if (!Features && Config->RequireCET)
- error(toString(F) + ": --require-cet: file is not compatible with CET");
- Ret &= Features;
+ uint32_t ret = -1;
+ for (InputFile *f : objectFiles) {
+ uint32_t features = cast<ObjFile<ELFT>>(f)->andFeatures;
+ if (config->forceBTI && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
+ warn(toString(f) + ": --force-bti: file does not have BTI property");
+ features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+ } else if (!features && config->requireCET)
+ error(toString(f) + ": --require-cet: file is not compatible with CET");
+ ret &= features;
}
// Force enable pointer authentication Plt, we don't warn in this case as
// this does not require support in the object for correctness.
- if (Config->PacPlt)
- Ret |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
+ if (config->pacPlt)
+ ret |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
- return Ret;
+ return ret;
}
-static const char *LibcallRoutineNames[] = {
+static const char *libcallRoutineNames[] = {
#define HANDLE_LIBCALL(code, name) name,
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
@@ -1664,48 +1664,48 @@ static const char *LibcallRoutineNames[] = {
// Do actual linking. Note that when this function is called,
// all linker scripts have already been parsed.
-template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
+template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// If a -hash-style option was not given, set to a default value,
// which varies depending on the target.
- if (!Args.hasArg(OPT_hash_style)) {
- if (Config->EMachine == EM_MIPS)
- Config->SysvHash = true;
+ if (!args.hasArg(OPT_hash_style)) {
+ if (config->emachine == EM_MIPS)
+ config->sysvHash = true;
else
- Config->SysvHash = Config->GnuHash = true;
+ config->sysvHash = config->gnuHash = true;
}
// Default output filename is "a.out" by the Unix tradition.
- if (Config->OutputFile.empty())
- Config->OutputFile = "a.out";
+ if (config->outputFile.empty())
+ config->outputFile = "a.out";
// Fail early if the output file or map file is not writable. If a user has a
// long link, e.g. due to a large LTO link, they do not wish to run it and
// find that it failed because there was a mistake in their command-line.
- if (auto E = tryCreateFile(Config->OutputFile))
- error("cannot open output file " + Config->OutputFile + ": " + E.message());
- if (auto E = tryCreateFile(Config->MapFile))
- error("cannot open map file " + Config->MapFile + ": " + E.message());
+ if (auto e = tryCreateFile(config->outputFile))
+ error("cannot open output file " + config->outputFile + ": " + e.message());
+ if (auto e = tryCreateFile(config->mapFile))
+ error("cannot open map file " + config->mapFile + ": " + e.message());
if (errorCount())
return;
// Use default entry point name if no name was given via the command
// line nor linker scripts. For some reason, MIPS entry point name is
// different from others.
- Config->WarnMissingEntry =
- (!Config->Entry.empty() || (!Config->Shared && !Config->Relocatable));
- if (Config->Entry.empty() && !Config->Relocatable)
- Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
+ config->warnMissingEntry =
+ (!config->entry.empty() || (!config->shared && !config->relocatable));
+ if (config->entry.empty() && !config->relocatable)
+ config->entry = (config->emachine == EM_MIPS) ? "__start" : "_start";
// Handle --trace-symbol.
- for (auto *Arg : Args.filtered(OPT_trace_symbol))
- Symtab->insert(Arg->getValue())->Traced = true;
+ for (auto *arg : args.filtered(OPT_trace_symbol))
+ symtab->insert(arg->getValue())->traced = true;
// Add all files to the symbol table. This will add almost all
// symbols that we need to the symbol table. This process might
// add files to the link, via autolinking, these files are always
// appended to the Files vector.
- for (size_t I = 0; I < Files.size(); ++I)
- parseFile(Files[I]);
+ for (size_t i = 0; i < files.size(); ++i)
+ parseFile(files[i]);
// Now that we have every file, we can decide if we will need a
// dynamic symbol table.
@@ -1713,26 +1713,26 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// producing a shared library.
// We also need one if any shared libraries are used and for pie executables
// (probably because the dynamic linker needs it).
- Config->HasDynSymTab =
- !SharedFiles.empty() || Config->Pic || Config->ExportDynamic;
+ config->hasDynSymTab =
+ !sharedFiles.empty() || config->isPic || config->exportDynamic;
// Some symbols (such as __ehdr_start) are defined lazily only when there
// are undefined symbols for them, so we add these to trigger that logic.
- for (StringRef Name : Script->ReferencedSymbols)
- addUndefined(Name);
+ for (StringRef name : script->referencedSymbols)
+ addUndefined(name);
// Handle the `--undefined <sym>` options.
- for (StringRef Arg : Config->Undefined)
- if (Symbol *Sym = Symtab->find(Arg))
- handleUndefined(Sym);
+ for (StringRef arg : config->undefined)
+ if (Symbol *sym = symtab->find(arg))
+ handleUndefined(sym);
// If an entry symbol is in a static archive, pull out that file now.
- if (Symbol *Sym = Symtab->find(Config->Entry))
- handleUndefined(Sym);
+ if (Symbol *sym = symtab->find(config->entry))
+ handleUndefined(sym);
// Handle the `--undefined-glob <pattern>` options.
- for (StringRef Pat : args::getStrings(Args, OPT_undefined_glob))
- handleUndefinedGlob(Pat);
+ for (StringRef pat : args::getStrings(args, OPT_undefined_glob))
+ handleUndefinedGlob(pat);
// If any of our inputs are bitcode files, the LTO code generator may create
// references to certain library functions that might not be explicit in the
@@ -1751,9 +1751,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// to, i.e. if the symbol's definition is in bitcode. Any other required
// libcall symbols will be added to the link after LTO when we add the LTO
// object file to the link.
- if (!BitcodeFiles.empty())
- for (const char *S : LibcallRoutineNames)
- handleLibcall(S);
+ if (!bitcodeFiles.empty())
+ for (const char *s : libcallRoutineNames)
+ handleLibcall(s);
// Return if there were name resolution errors.
if (errorCount())
@@ -1761,27 +1761,27 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// Now when we read all script files, we want to finalize order of linker
// script commands, which can be not yet final because of INSERT commands.
- Script->processInsertCommands();
+ script->processInsertCommands();
// We want to declare linker script's symbols early,
// so that we can version them.
// They also might be exported if referenced by DSOs.
- Script->declareSymbols();
+ script->declareSymbols();
// Handle the -exclude-libs option.
- if (Args.hasArg(OPT_exclude_libs))
- excludeLibs(Args);
+ if (args.hasArg(OPT_exclude_libs))
+ excludeLibs(args);
// Create ElfHeader early. We need a dummy section in
// addReservedSymbols to mark the created symbols as not absolute.
- Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
- Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
+ Out::elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
+ Out::elfHeader->size = sizeof(typename ELFT::Ehdr);
// Create wrapped symbols for -wrap option.
- std::vector<WrappedSymbol> Wrapped = addWrappedSymbols(Args);
+ std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
// We need to create some reserved symbols such as _end. Create them.
- if (!Config->Relocatable)
+ if (!config->relocatable)
addReservedSymbols();
// Apply version scripts.
@@ -1789,8 +1789,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// For a relocatable output, version scripts don't make sense, and
// parsing a symbol version string (e.g. dropping "@ver1" from a symbol
// name "foo@ver1") rather do harm, so we don't call this if -r is given.
- if (!Config->Relocatable)
- Symtab->scanVersionScript();
+ if (!config->relocatable)
+ symtab->scanVersionScript();
// Do link-time optimization if given files are LLVM bitcode files.
// This compiles bitcode files into real object files.
@@ -1804,83 +1804,83 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// If -thinlto-index-only is given, we should create only "index
// files" and not object files. Index file creation is already done
// in addCombinedLTOObject, so we are done if that's the case.
- if (Config->ThinLTOIndexOnly)
+ if (config->thinLTOIndexOnly)
return;
// Likewise, --plugin-opt=emit-llvm is an option to make LTO create
// an output file in bitcode and exit, so that you can just get a
// combined bitcode file.
- if (Config->EmitLLVM)
+ if (config->emitLLVM)
return;
// Apply symbol renames for -wrap.
- if (!Wrapped.empty())
- wrapSymbols(Wrapped);
+ if (!wrapped.empty())
+ wrapSymbols(wrapped);
// Now that we have a complete list of input files.
// Beyond this point, no new files are added.
// Aggregate all input sections into one place.
- for (InputFile *F : ObjectFiles)
- for (InputSectionBase *S : F->getSections())
- if (S && S != &InputSection::Discarded)
- InputSections.push_back(S);
- for (BinaryFile *F : BinaryFiles)
- for (InputSectionBase *S : F->getSections())
- InputSections.push_back(cast<InputSection>(S));
-
- llvm::erase_if(InputSections, [](InputSectionBase *S) {
- if (S->Type == SHT_LLVM_SYMPART) {
- readSymbolPartitionSection<ELFT>(S);
+ for (InputFile *f : objectFiles)
+ for (InputSectionBase *s : f->getSections())
+ if (s && s != &InputSection::discarded)
+ inputSections.push_back(s);
+ for (BinaryFile *f : binaryFiles)
+ for (InputSectionBase *s : f->getSections())
+ inputSections.push_back(cast<InputSection>(s));
+
+ llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ if (s->type == SHT_LLVM_SYMPART) {
+ readSymbolPartitionSection<ELFT>(s);
return true;
}
// We do not want to emit debug sections if --strip-all
// or -strip-debug are given.
- return Config->Strip != StripPolicy::None &&
- (S->Name.startswith(".debug") || S->Name.startswith(".zdebug"));
+ return config->strip != StripPolicy::None &&
+ (s->name.startswith(".debug") || s->name.startswith(".zdebug"));
});
// Now that the number of partitions is fixed, save a pointer to the main
// partition.
- Main = &Partitions[0];
+ mainPart = &partitions[0];
// Read .note.gnu.property sections from input object files which
// contain a hint to tweak linker's and loader's behaviors.
- Config->AndFeatures = getAndFeatures<ELFT>();
+ config->andFeatures = getAndFeatures<ELFT>();
// The Target instance handles target-specific stuff, such as applying
// relocations or writing a PLT section. It also contains target-dependent
// values such as a default image base address.
- Target = getTarget();
+ target = getTarget();
- Config->EFlags = Target->calcEFlags();
+ config->eflags = target->calcEFlags();
// MaxPageSize (sometimes called abi page size) is the maximum page size that
// the output can be run on. For example if the OS can use 4k or 64k page
// sizes then MaxPageSize must be 64 for the output to be useable on both.
// All important alignment decisions must use this value.
- Config->MaxPageSize = getMaxPageSize(Args);
+ config->maxPageSize = getMaxPageSize(args);
// CommonPageSize is the most common page size that the output will be run on.
// For example if an OS can use 4k or 64k page sizes and 4k is more common
// than 64k then CommonPageSize is set to 4k. CommonPageSize can be used for
// optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
// is limited to writing trap instructions on the last executable segment.
- Config->CommonPageSize = getCommonPageSize(Args);
+ config->commonPageSize = getCommonPageSize(args);
- Config->ImageBase = getImageBase(Args);
+ config->imageBase = getImageBase(args);
- if (Config->EMachine == EM_ARM) {
+ if (config->emachine == EM_ARM) {
// FIXME: These warnings can be removed when lld only uses these features
// when the input objects have been compiled with an architecture that
// supports them.
- if (Config->ARMHasBlx == false)
+ if (config->armHasBlx == false)
warn("lld uses blx instruction, no object with architecture supporting "
"feature detected");
}
// This adds a .comment section containing a version string. We have to add it
// before mergeSections because the .comment section is a mergeable section.
- if (!Config->Relocatable)
- InputSections.push_back(createCommentSection());
+ if (!config->relocatable)
+ inputSections.push_back(createCommentSection());
// Replace common symbols with regular symbols.
replaceCommonSymbols();
@@ -1891,16 +1891,16 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
markLive<ELFT>();
demoteSharedSymbols();
mergeSections();
- if (Config->ICF != ICFLevel::None) {
- findKeepUniqueSections<ELFT>(Args);
+ if (config->icf != ICFLevel::None) {
+ findKeepUniqueSections<ELFT>(args);
doIcf<ELFT>();
}
// Read the callgraph now that we know what was gced or icfed
- if (Config->CallGraphProfileSort) {
- if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
- if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
- readCallGraph(*Buffer);
+ if (config->callGraphProfileSort) {
+ if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
+ if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
+ readCallGraph(*buffer);
readCallGraphsFromObjectFiles<ELFT>();
}
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 76b91be2119..3115e28d166 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -22,37 +22,37 @@
namespace lld {
namespace elf {
-extern class LinkerDriver *Driver;
+extern class LinkerDriver *driver;
class LinkerDriver {
public:
- void main(ArrayRef<const char *> Args);
- void addFile(StringRef Path, bool WithLOption);
- void addLibrary(StringRef Name);
+ void main(ArrayRef<const char *> args);
+ void addFile(StringRef path, bool withLOption);
+ void addLibrary(StringRef name);
private:
- void createFiles(llvm::opt::InputArgList &Args);
+ void createFiles(llvm::opt::InputArgList &args);
void inferMachineType();
- template <class ELFT> void link(llvm::opt::InputArgList &Args);
+ template <class ELFT> void link(llvm::opt::InputArgList &args);
template <class ELFT> void compileBitcodeFiles();
// True if we are in --whole-archive and --no-whole-archive.
- bool InWholeArchive = false;
+ bool inWholeArchive = false;
// True if we are in --start-lib and --end-lib.
- bool InLib = false;
+ bool inLib = false;
// For LTO.
- std::unique_ptr<BitcodeCompiler> LTO;
+ std::unique_ptr<BitcodeCompiler> lto;
- std::vector<InputFile *> Files;
+ std::vector<InputFile *> files;
};
// Parses command line options.
class ELFOptTable : public llvm::opt::OptTable {
public:
ELFOptTable();
- llvm::opt::InputArgList parse(ArrayRef<const char *> Argv);
+ llvm::opt::InputArgList parse(ArrayRef<const char *> argv);
};
// Create enum with OPT_xxx values for each option in Options.td
@@ -64,12 +64,12 @@ enum {
};
void printHelp();
-std::string createResponseFile(const llvm::opt::InputArgList &Args);
+std::string createResponseFile(const llvm::opt::InputArgList &args);
-llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
-llvm::Optional<std::string> searchScript(StringRef Path);
-llvm::Optional<std::string> searchLibraryBaseName(StringRef Path);
-llvm::Optional<std::string> searchLibrary(StringRef Path);
+llvm::Optional<std::string> findFromSearchPaths(StringRef path);
+llvm::Optional<std::string> searchScript(StringRef path);
+llvm::Optional<std::string> searchLibraryBaseName(StringRef path);
+llvm::Optional<std::string> searchLibrary(StringRef path);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 32f364ec6ef..4abccc135a9 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -41,7 +41,7 @@ using namespace lld::elf;
#undef PREFIX
// Create table mapping all options defined in Options.td
-static const opt::OptTable::Info OptInfo[] = {
+static const opt::OptTable::Info optInfo[] = {
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
{X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
@@ -49,36 +49,36 @@ static const opt::OptTable::Info OptInfo[] = {
#undef OPTION
};
-ELFOptTable::ELFOptTable() : OptTable(OptInfo) {}
+ELFOptTable::ELFOptTable() : OptTable(optInfo) {}
// Set color diagnostics according to -color-diagnostics={auto,always,never}
// or -no-color-diagnostics flags.
-static void handleColorDiagnostics(opt::InputArgList &Args) {
- auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
+static void handleColorDiagnostics(opt::InputArgList &args) {
+ auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
OPT_no_color_diagnostics);
- if (!Arg)
+ if (!arg)
return;
- if (Arg->getOption().getID() == OPT_color_diagnostics) {
+ if (arg->getOption().getID() == OPT_color_diagnostics) {
errorHandler().ColorDiagnostics = true;
- } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
+ } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
errorHandler().ColorDiagnostics = false;
} else {
- StringRef S = Arg->getValue();
- if (S == "always")
+ StringRef s = arg->getValue();
+ if (s == "always")
errorHandler().ColorDiagnostics = true;
- else if (S == "never")
+ else if (s == "never")
errorHandler().ColorDiagnostics = false;
- else if (S != "auto")
- error("unknown option: --color-diagnostics=" + S);
+ else if (s != "auto")
+ error("unknown option: --color-diagnostics=" + s);
}
}
-static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
- if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) {
- StringRef S = Arg->getValue();
- if (S != "windows" && S != "posix")
- error("invalid response file quoting: " + S);
- if (S == "windows")
+static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
+ if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
+ StringRef s = arg->getValue();
+ if (s != "windows" && s != "posix")
+ error("invalid response file quoting: " + s);
+ if (s == "windows")
return cl::TokenizeWindowsCommandLine;
return cl::TokenizeGNUCommandLine;
}
@@ -96,56 +96,56 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
// `--plugin-opt <foo>` is converted to `--plugin-opt=<foo>`. This is a
// bit hacky, but looks like it is still better than handling --plugin-opt
// options by hand.
-static void concatLTOPluginOptions(SmallVectorImpl<const char *> &Args) {
- SmallVector<const char *, 256> V;
- for (size_t I = 0, E = Args.size(); I != E; ++I) {
- StringRef S = Args[I];
- if ((S == "-plugin-opt" || S == "--plugin-opt") && I + 1 != E) {
- V.push_back(Saver.save(S + "=" + Args[I + 1]).data());
- ++I;
+static void concatLTOPluginOptions(SmallVectorImpl<const char *> &args) {
+ SmallVector<const char *, 256> v;
+ for (size_t i = 0, e = args.size(); i != e; ++i) {
+ StringRef s = args[i];
+ if ((s == "-plugin-opt" || s == "--plugin-opt") && i + 1 != e) {
+ v.push_back(Saver.save(s + "=" + args[i + 1]).data());
+ ++i;
} else {
- V.push_back(Args[I]);
+ v.push_back(args[i]);
}
}
- Args = std::move(V);
+ args = std::move(v);
}
// Parses a given list of options.
-opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
+opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> argv) {
// Make InputArgList from string vectors.
- unsigned MissingIndex;
- unsigned MissingCount;
- SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
+ unsigned missingIndex;
+ unsigned missingCount;
+ SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
// We need to get the quoting style for response files before parsing all
// options so we parse here before and ignore all the options but
// --rsp-quoting.
- opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
+ opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
// Expand response files (arguments in the form of @<filename>)
// and then parse the argument again.
- cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec);
- concatLTOPluginOptions(Vec);
- Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
-
- handleColorDiagnostics(Args);
- if (MissingCount)
- error(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
-
- for (auto *Arg : Args.filtered(OPT_UNKNOWN)) {
- std::string Nearest;
- if (findNearest(Arg->getAsString(Args), Nearest) > 1)
- error("unknown argument '" + Arg->getAsString(Args) + "'");
+ cl::ExpandResponseFiles(Saver, getQuotingStyle(args), vec);
+ concatLTOPluginOptions(vec);
+ args = this->ParseArgs(vec, missingIndex, missingCount);
+
+ handleColorDiagnostics(args);
+ if (missingCount)
+ error(Twine(args.getArgString(missingIndex)) + ": missing argument");
+
+ for (auto *arg : args.filtered(OPT_UNKNOWN)) {
+ std::string nearest;
+ if (findNearest(arg->getAsString(args), nearest) > 1)
+ error("unknown argument '" + arg->getAsString(args) + "'");
else
- error("unknown argument '" + Arg->getAsString(Args) +
- "', did you mean '" + Nearest + "'");
+ error("unknown argument '" + arg->getAsString(args) +
+ "', did you mean '" + nearest + "'");
}
- return Args;
+ return args;
}
void elf::printHelp() {
ELFOptTable().PrintHelp(
- outs(), (Config->ProgName + " [options] file...").str().c_str(), "lld",
+ outs(), (config->progName + " [options] file...").str().c_str(), "lld",
false /*ShowHidden*/, true /*ShowAllAliases*/);
outs() << "\n";
@@ -154,36 +154,36 @@ void elf::printHelp() {
// in a message for the -help option. If it doesn't match, the scripts
// assume that the linker doesn't support very basic features such as
// shared libraries. Therefore, we need to print out at least "elf".
- outs() << Config->ProgName << ": supported targets: elf\n";
+ outs() << config->progName << ": supported targets: elf\n";
}
-static std::string rewritePath(StringRef S) {
- if (fs::exists(S))
- return relativeToRoot(S);
- return S;
+static std::string rewritePath(StringRef s) {
+ if (fs::exists(s))
+ return relativeToRoot(s);
+ return s;
}
// Reconstructs command line arguments so that so that you can re-run
// the same command with the same inputs. This is for --reproduce.
-std::string elf::createResponseFile(const opt::InputArgList &Args) {
- SmallString<0> Data;
- raw_svector_ostream OS(Data);
- OS << "--chroot .\n";
+std::string elf::createResponseFile(const opt::InputArgList &args) {
+ SmallString<0> data;
+ raw_svector_ostream os(data);
+ os << "--chroot .\n";
// Copy the command line to the output while rewriting paths.
- for (auto *Arg : Args) {
- switch (Arg->getOption().getID()) {
+ for (auto *arg : args) {
+ switch (arg->getOption().getID()) {
case OPT_reproduce:
break;
case OPT_INPUT:
- OS << quote(rewritePath(Arg->getValue())) << "\n";
+ os << quote(rewritePath(arg->getValue())) << "\n";
break;
case OPT_o:
// If -o path contains directories, "lld @response.txt" will likely
// fail because the archive we are creating doesn't contain empty
// directories for the output path (-o doesn't create directories).
// Strip directories to prevent the issue.
- OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n";
+ os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n";
break;
case OPT_dynamic_list:
case OPT_library_path:
@@ -192,62 +192,62 @@ std::string elf::createResponseFile(const opt::InputArgList &Args) {
case OPT_symbol_ordering_file:
case OPT_sysroot:
case OPT_version_script:
- OS << Arg->getSpelling() << " " << quote(rewritePath(Arg->getValue()))
+ os << arg->getSpelling() << " " << quote(rewritePath(arg->getValue()))
<< "\n";
break;
default:
- OS << toString(*Arg) << "\n";
+ os << toString(*arg) << "\n";
}
}
- return Data.str();
+ return data.str();
}
// Find a file by concatenating given paths. If a resulting path
// starts with "=", the character is replaced with a --sysroot value.
-static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
- SmallString<128> S;
- if (Path1.startswith("="))
- path::append(S, Config->Sysroot, Path1.substr(1), Path2);
+static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
+ SmallString<128> s;
+ if (path1.startswith("="))
+ path::append(s, config->sysroot, path1.substr(1), path2);
else
- path::append(S, Path1, Path2);
+ path::append(s, path1, path2);
- if (fs::exists(S))
- return S.str().str();
+ if (fs::exists(s))
+ return s.str().str();
return None;
}
-Optional<std::string> elf::findFromSearchPaths(StringRef Path) {
- for (StringRef Dir : Config->SearchPaths)
- if (Optional<std::string> S = findFile(Dir, Path))
- return S;
+Optional<std::string> elf::findFromSearchPaths(StringRef path) {
+ for (StringRef dir : config->searchPaths)
+ if (Optional<std::string> s = findFile(dir, path))
+ return s;
return None;
}
// This is for -l<basename>. We'll look for lib<basename>.so or lib<basename>.a from
// search paths.
-Optional<std::string> elf::searchLibraryBaseName(StringRef Name) {
- for (StringRef Dir : Config->SearchPaths) {
- if (!Config->Static)
- if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".so"))
- return S;
- if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a"))
- return S;
+Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
+ for (StringRef dir : config->searchPaths) {
+ if (!config->isStatic)
+ if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
+ return s;
+ if (Optional<std::string> s = findFile(dir, "lib" + name + ".a"))
+ return s;
}
return None;
}
// This is for -l<namespec>.
-Optional<std::string> elf::searchLibrary(StringRef Name) {
- if (Name.startswith(":"))
- return findFromSearchPaths(Name.substr(1));
- return searchLibraryBaseName (Name);
+Optional<std::string> elf::searchLibrary(StringRef name) {
+ if (name.startswith(":"))
+ return findFromSearchPaths(name.substr(1));
+ return searchLibraryBaseName (name);
}
// If a linker/version script doesn't exist in the current directory, we also
// look for the script in the '-L' search paths. This matches the behaviour of
// '-T', --version-script=, and linker script INPUT() command in ld.bfd.
-Optional<std::string> elf::searchScript(StringRef Name) {
- if (fs::exists(Name))
- return Name.str();
- return findFromSearchPaths(Name);
+Optional<std::string> elf::searchScript(StringRef name) {
+ if (fs::exists(name))
+ return name.str();
+ return findFromSearchPaths(name);
}
diff --git a/lld/ELF/EhFrame.cpp b/lld/ELF/EhFrame.cpp
index 236b895f61c..b3245dd0166 100644
--- a/lld/ELF/EhFrame.cpp
+++ b/lld/ELF/EhFrame.cpp
@@ -36,72 +36,72 @@ using namespace lld::elf;
namespace {
class EhReader {
public:
- EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
+ EhReader(InputSectionBase *s, ArrayRef<uint8_t> d) : isec(s), d(d) {}
size_t readEhRecordSize();
uint8_t getFdeEncoding();
private:
- template <class P> void failOn(const P *Loc, const Twine &Msg) {
- fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
- IS->getObjMsg((const uint8_t *)Loc - IS->data().data()));
+ template <class P> void failOn(const P *loc, const Twine &msg) {
+ fatal("corrupted .eh_frame: " + msg + "\n>>> defined in " +
+ isec->getObjMsg((const uint8_t *)loc - isec->data().data()));
}
uint8_t readByte();
- void skipBytes(size_t Count);
+ void skipBytes(size_t count);
StringRef readString();
void skipLeb128();
void skipAugP();
- InputSectionBase *IS;
- ArrayRef<uint8_t> D;
+ InputSectionBase *isec;
+ ArrayRef<uint8_t> d;
};
}
-size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
- return EhReader(S, S->data().slice(Off)).readEhRecordSize();
+size_t elf::readEhRecordSize(InputSectionBase *s, size_t off) {
+ return EhReader(s, s->data().slice(off)).readEhRecordSize();
}
// .eh_frame section is a sequence of records. Each record starts with
// a 4 byte length field. This function reads the length.
size_t EhReader::readEhRecordSize() {
- if (D.size() < 4)
- failOn(D.data(), "CIE/FDE too small");
+ if (d.size() < 4)
+ failOn(d.data(), "CIE/FDE too small");
// First 4 bytes of CIE/FDE is the size of the record.
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
// but we do not support that format yet.
- uint64_t V = read32(D.data());
- if (V == UINT32_MAX)
- failOn(D.data(), "CIE/FDE too large");
- uint64_t Size = V + 4;
- if (Size > D.size())
- failOn(D.data(), "CIE/FDE ends past the end of the section");
- return Size;
+ uint64_t v = read32(d.data());
+ if (v == UINT32_MAX)
+ failOn(d.data(), "CIE/FDE too large");
+ uint64_t size = v + 4;
+ if (size > d.size())
+ failOn(d.data(), "CIE/FDE ends past the end of the section");
+ return size;
}
// Read a byte and advance D by one byte.
uint8_t EhReader::readByte() {
- if (D.empty())
- failOn(D.data(), "unexpected end of CIE");
- uint8_t B = D.front();
- D = D.slice(1);
- return B;
+ if (d.empty())
+ failOn(d.data(), "unexpected end of CIE");
+ uint8_t b = d.front();
+ d = d.slice(1);
+ return b;
}
-void EhReader::skipBytes(size_t Count) {
- if (D.size() < Count)
- failOn(D.data(), "CIE is too small");
- D = D.slice(Count);
+void EhReader::skipBytes(size_t count) {
+ if (d.size() < count)
+ failOn(d.data(), "CIE is too small");
+ d = d.slice(count);
}
// Read a null-terminated string.
StringRef EhReader::readString() {
- const uint8_t *End = llvm::find(D, '\0');
- if (End == D.end())
- failOn(D.data(), "corrupted CIE (failed to read string)");
- StringRef S = toStringRef(D.slice(0, End - D.begin()));
- D = D.slice(S.size() + 1);
- return S;
+ const uint8_t *end = llvm::find(d, '\0');
+ if (end == d.end())
+ failOn(d.data(), "corrupted CIE (failed to read string)");
+ StringRef s = toStringRef(d.slice(0, end - d.begin()));
+ d = d.slice(s.size() + 1);
+ return s;
}
// Skip an integer encoded in the LEB128 format.
@@ -109,21 +109,21 @@ StringRef EhReader::readString() {
// But we need to be at least able to skip it so that we can read
// the field that follows a LEB128 number.
void EhReader::skipLeb128() {
- const uint8_t *ErrPos = D.data();
- while (!D.empty()) {
- uint8_t Val = D.front();
- D = D.slice(1);
- if ((Val & 0x80) == 0)
+ const uint8_t *errPos = d.data();
+ while (!d.empty()) {
+ uint8_t val = d.front();
+ d = d.slice(1);
+ if ((val & 0x80) == 0)
return;
}
- failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
+ failOn(errPos, "corrupted CIE (failed to read LEB128)");
}
-static size_t getAugPSize(unsigned Enc) {
- switch (Enc & 0x0f) {
+static size_t getAugPSize(unsigned enc) {
+ switch (enc & 0x0f) {
case DW_EH_PE_absptr:
case DW_EH_PE_signed:
- return Config->Wordsize;
+ return config->wordsize;
case DW_EH_PE_udata2:
case DW_EH_PE_sdata2:
return 2;
@@ -138,29 +138,29 @@ static size_t getAugPSize(unsigned Enc) {
}
void EhReader::skipAugP() {
- uint8_t Enc = readByte();
- if ((Enc & 0xf0) == DW_EH_PE_aligned)
- failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported");
- size_t Size = getAugPSize(Enc);
- if (Size == 0)
- failOn(D.data() - 1, "unknown FDE encoding");
- if (Size >= D.size())
- failOn(D.data() - 1, "corrupted CIE");
- D = D.slice(Size);
+ uint8_t enc = readByte();
+ if ((enc & 0xf0) == DW_EH_PE_aligned)
+ failOn(d.data() - 1, "DW_EH_PE_aligned encoding is not supported");
+ size_t size = getAugPSize(enc);
+ if (size == 0)
+ failOn(d.data() - 1, "unknown FDE encoding");
+ if (size >= d.size())
+ failOn(d.data() - 1, "corrupted CIE");
+ d = d.slice(size);
}
-uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
- return EhReader(P->Sec, P->data()).getFdeEncoding();
+uint8_t elf::getFdeEncoding(EhSectionPiece *p) {
+ return EhReader(p->sec, p->data()).getFdeEncoding();
}
uint8_t EhReader::getFdeEncoding() {
skipBytes(8);
- int Version = readByte();
- if (Version != 1 && Version != 3)
- failOn(D.data() - 1,
- "FDE version 1 or 3 expected, but got " + Twine(Version));
+ int version = readByte();
+ if (version != 1 && version != 3)
+ failOn(d.data() - 1,
+ "FDE version 1 or 3 expected, but got " + Twine(version));
- StringRef Aug = readString();
+ StringRef aug = readString();
// Skip code and data alignment factors.
skipLeb128();
@@ -168,7 +168,7 @@ uint8_t EhReader::getFdeEncoding() {
// Skip the return address register. In CIE version 1 this is a single
// byte. In CIE version 3 this is an unsigned LEB128.
- if (Version == 1)
+ if (version == 1)
readByte();
else
skipLeb128();
@@ -176,22 +176,22 @@ uint8_t EhReader::getFdeEncoding() {
// We only care about an 'R' value, but other records may precede an 'R'
// record. Unfortunately records are not in TLV (type-length-value) format,
// so we need to teach the linker how to skip records for each type.
- for (char C : Aug) {
- if (C == 'R')
+ for (char c : aug) {
+ if (c == 'R')
return readByte();
- if (C == 'z') {
+ if (c == 'z') {
skipLeb128();
continue;
}
- if (C == 'P') {
+ if (c == 'P') {
skipAugP();
continue;
}
- if (C == 'L') {
+ if (c == 'L') {
readByte();
continue;
}
- failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
+ failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug);
}
return DW_EH_PE_absptr;
}
diff --git a/lld/ELF/EhFrame.h b/lld/ELF/EhFrame.h
index 165d72b79ce..20dd6126ec8 100644
--- a/lld/ELF/EhFrame.h
+++ b/lld/ELF/EhFrame.h
@@ -16,8 +16,8 @@ namespace elf {
class InputSectionBase;
struct EhSectionPiece;
-size_t readEhRecordSize(InputSectionBase *S, size_t Off);
-uint8_t getFdeEncoding(EhSectionPiece *P);
+size_t readEhRecordSize(InputSectionBase *s, size_t off);
+uint8_t getFdeEncoding(EhSectionPiece *p);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 08f7ad3cda4..fa64b9e6347 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -98,33 +98,33 @@ public:
void run();
private:
- void segregate(size_t Begin, size_t End, bool Constant);
+ void segregate(size_t begin, size_t end, bool constant);
template <class RelTy>
- bool constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
- const InputSection *B, ArrayRef<RelTy> RelsB);
+ bool constantEq(const InputSection *a, ArrayRef<RelTy> relsA,
+ const InputSection *b, ArrayRef<RelTy> relsB);
template <class RelTy>
- bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
- const InputSection *B, ArrayRef<RelTy> RelsB);
+ bool variableEq(const InputSection *a, ArrayRef<RelTy> relsA,
+ const InputSection *b, ArrayRef<RelTy> relsB);
- bool equalsConstant(const InputSection *A, const InputSection *B);
- bool equalsVariable(const InputSection *A, const InputSection *B);
+ bool equalsConstant(const InputSection *a, const InputSection *b);
+ bool equalsVariable(const InputSection *a, const InputSection *b);
- size_t findBoundary(size_t Begin, size_t End);
+ size_t findBoundary(size_t begin, size_t end);
- void forEachClassRange(size_t Begin, size_t End,
- llvm::function_ref<void(size_t, size_t)> Fn);
+ void forEachClassRange(size_t begin, size_t end,
+ llvm::function_ref<void(size_t, size_t)> fn);
- void forEachClass(llvm::function_ref<void(size_t, size_t)> Fn);
+ void forEachClass(llvm::function_ref<void(size_t, size_t)> fn);
- std::vector<InputSection *> Sections;
+ std::vector<InputSection *> sections;
// We repeat the main loop while `Repeat` is true.
- std::atomic<bool> Repeat;
+ std::atomic<bool> repeat;
// The main loop counter.
- int Cnt = 0;
+ int cnt = 0;
// We have two locations for equivalence classes. On the first iteration
// of the main loop, Class[0] has a valid value, and Class[1] contains
@@ -150,42 +150,42 @@ private:
// because we can safely read the next class without worrying about race
// conditions. Using the same location makes this algorithm converge
// faster because it uses results of the same iteration earlier.
- int Current = 0;
- int Next = 0;
+ int current = 0;
+ int next = 0;
};
}
// Returns true if section S is subject of ICF.
-static bool isEligible(InputSection *S) {
- if (!S->isLive() || S->KeepUnique || !(S->Flags & SHF_ALLOC))
+static bool isEligible(InputSection *s) {
+ if (!s->isLive() || s->keepUnique || !(s->flags & SHF_ALLOC))
return false;
// Don't merge writable sections. .data.rel.ro sections are marked as writable
// but are semantically read-only.
- if ((S->Flags & SHF_WRITE) && S->Name != ".data.rel.ro" &&
- !S->Name.startswith(".data.rel.ro."))
+ if ((s->flags & SHF_WRITE) && s->name != ".data.rel.ro" &&
+ !s->name.startswith(".data.rel.ro."))
return false;
// SHF_LINK_ORDER sections are ICF'd as a unit with their dependent sections,
// so we don't consider them for ICF individually.
- if (S->Flags & SHF_LINK_ORDER)
+ if (s->flags & SHF_LINK_ORDER)
return false;
// Don't merge synthetic sections as their Data member is not valid and empty.
// The Data member needs to be valid for ICF as it is used by ICF to determine
// the equality of section contents.
- if (isa<SyntheticSection>(S))
+ if (isa<SyntheticSection>(s))
return false;
// .init and .fini contains instructions that must be executed to initialize
// and finalize the process. They cannot and should not be merged.
- if (S->Name == ".init" || S->Name == ".fini")
+ if (s->name == ".init" || s->name == ".fini")
return false;
// A user program may enumerate sections named with a C identifier using
// __start_* and __stop_* symbols. We cannot ICF any such sections because
// that could change program semantics.
- if (isValidCIdentifier(S->Name))
+ if (isValidCIdentifier(s->name))
return false;
return true;
@@ -193,7 +193,7 @@ static bool isEligible(InputSection *S) {
// Split an equivalence class into smaller classes.
template <class ELFT>
-void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
+void ICF<ELFT>::segregate(size_t begin, size_t end, bool constant) {
// This loop rearranges sections in [Begin, End) so that all sections
// that are equal in terms of equals{Constant,Variable} are contiguous
// in [Begin, End).
@@ -202,93 +202,93 @@ void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
// issue in practice because the number of the distinct sections in
// each range is usually very small.
- while (Begin < End) {
+ while (begin < end) {
// Divide [Begin, End) into two. Let Mid be the start index of the
// second group.
- auto Bound =
- std::stable_partition(Sections.begin() + Begin + 1,
- Sections.begin() + End, [&](InputSection *S) {
- if (Constant)
- return equalsConstant(Sections[Begin], S);
- return equalsVariable(Sections[Begin], S);
+ auto bound =
+ std::stable_partition(sections.begin() + begin + 1,
+ sections.begin() + end, [&](InputSection *s) {
+ if (constant)
+ return equalsConstant(sections[begin], s);
+ return equalsVariable(sections[begin], s);
});
- size_t Mid = Bound - Sections.begin();
+ size_t mid = bound - sections.begin();
// Now we split [Begin, End) into [Begin, Mid) and [Mid, End) by
// updating the sections in [Begin, Mid). We use Mid as an equivalence
// class ID because every group ends with a unique index.
- for (size_t I = Begin; I < Mid; ++I)
- Sections[I]->Class[Next] = Mid;
+ for (size_t i = begin; i < mid; ++i)
+ sections[i]->eqClass[next] = mid;
// If we created a group, we need to iterate the main loop again.
- if (Mid != End)
- Repeat = true;
+ if (mid != end)
+ repeat = true;
- Begin = Mid;
+ begin = mid;
}
}
// Compare two lists of relocations.
template <class ELFT>
template <class RelTy>
-bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
- const InputSection *SecB, ArrayRef<RelTy> RB) {
- for (size_t I = 0; I < RA.size(); ++I) {
- if (RA[I].r_offset != RB[I].r_offset ||
- RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL))
+bool ICF<ELFT>::constantEq(const InputSection *secA, ArrayRef<RelTy> ra,
+ const InputSection *secB, ArrayRef<RelTy> rb) {
+ for (size_t i = 0; i < ra.size(); ++i) {
+ if (ra[i].r_offset != rb[i].r_offset ||
+ ra[i].getType(config->isMips64EL) != rb[i].getType(config->isMips64EL))
return false;
- uint64_t AddA = getAddend<ELFT>(RA[I]);
- uint64_t AddB = getAddend<ELFT>(RB[I]);
+ uint64_t addA = getAddend<ELFT>(ra[i]);
+ uint64_t addB = getAddend<ELFT>(rb[i]);
- Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
- Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
- if (&SA == &SB) {
- if (AddA == AddB)
+ Symbol &sa = secA->template getFile<ELFT>()->getRelocTargetSym(ra[i]);
+ Symbol &sb = secB->template getFile<ELFT>()->getRelocTargetSym(rb[i]);
+ if (&sa == &sb) {
+ if (addA == addB)
continue;
return false;
}
- auto *DA = dyn_cast<Defined>(&SA);
- auto *DB = dyn_cast<Defined>(&SB);
+ auto *da = dyn_cast<Defined>(&sa);
+ auto *db = dyn_cast<Defined>(&sb);
// Placeholder symbols generated by linker scripts look the same now but
// may have different values later.
- if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
+ if (!da || !db || da->scriptDefined || db->scriptDefined)
return false;
// Relocations referring to absolute symbols are constant-equal if their
// values are equal.
- if (!DA->Section && !DB->Section && DA->Value + AddA == DB->Value + AddB)
+ if (!da->section && !db->section && da->value + addA == db->value + addB)
continue;
- if (!DA->Section || !DB->Section)
+ if (!da->section || !db->section)
return false;
- if (DA->Section->kind() != DB->Section->kind())
+ if (da->section->kind() != db->section->kind())
return false;
// Relocations referring to InputSections are constant-equal if their
// section offsets are equal.
- if (isa<InputSection>(DA->Section)) {
- if (DA->Value + AddA == DB->Value + AddB)
+ if (isa<InputSection>(da->section)) {
+ if (da->value + addA == db->value + addB)
continue;
return false;
}
// Relocations referring to MergeInputSections are constant-equal if their
// offsets in the output section are equal.
- auto *X = dyn_cast<MergeInputSection>(DA->Section);
- if (!X)
+ auto *x = dyn_cast<MergeInputSection>(da->section);
+ if (!x)
return false;
- auto *Y = cast<MergeInputSection>(DB->Section);
- if (X->getParent() != Y->getParent())
+ auto *y = cast<MergeInputSection>(db->section);
+ if (x->getParent() != y->getParent())
return false;
- uint64_t OffsetA =
- SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA;
- uint64_t OffsetB =
- SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB;
- if (OffsetA != OffsetB)
+ uint64_t offsetA =
+ sa.isSection() ? x->getOffset(addA) : x->getOffset(da->value) + addA;
+ uint64_t offsetB =
+ sb.isSection() ? y->getOffset(addB) : y->getOffset(db->value) + addB;
+ if (offsetA != offsetB)
return false;
}
@@ -298,57 +298,57 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
// Compare "non-moving" part of two InputSections, namely everything
// except relocation targets.
template <class ELFT>
-bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
- if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
- A->getSize() != B->getSize() || A->data() != B->data())
+bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
+ if (a->numRelocations != b->numRelocations || a->flags != b->flags ||
+ a->getSize() != b->getSize() || a->data() != b->data())
return false;
// If two sections have different output sections, we cannot merge them.
// FIXME: This doesn't do the right thing in the case where there is a linker
// script. We probably need to move output section assignment before ICF to
// get the correct behaviour here.
- if (getOutputSectionName(A) != getOutputSectionName(B))
+ if (getOutputSectionName(a) != getOutputSectionName(b))
return false;
- if (A->AreRelocsRela)
- return constantEq(A, A->template relas<ELFT>(), B,
- B->template relas<ELFT>());
- return constantEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
+ if (a->areRelocsRela)
+ return constantEq(a, a->template relas<ELFT>(), b,
+ b->template relas<ELFT>());
+ return constantEq(a, a->template rels<ELFT>(), b, b->template rels<ELFT>());
}
// Compare two lists of relocations. Returns true if all pairs of
// relocations point to the same section in terms of ICF.
template <class ELFT>
template <class RelTy>
-bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA,
- const InputSection *SecB, ArrayRef<RelTy> RB) {
- assert(RA.size() == RB.size());
+bool ICF<ELFT>::variableEq(const InputSection *secA, ArrayRef<RelTy> ra,
+ const InputSection *secB, ArrayRef<RelTy> rb) {
+ assert(ra.size() == rb.size());
- for (size_t I = 0; I < RA.size(); ++I) {
+ for (size_t i = 0; i < ra.size(); ++i) {
// The two sections must be identical.
- Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
- Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
- if (&SA == &SB)
+ Symbol &sa = secA->template getFile<ELFT>()->getRelocTargetSym(ra[i]);
+ Symbol &sb = secB->template getFile<ELFT>()->getRelocTargetSym(rb[i]);
+ if (&sa == &sb)
continue;
- auto *DA = cast<Defined>(&SA);
- auto *DB = cast<Defined>(&SB);
+ auto *da = cast<Defined>(&sa);
+ auto *db = cast<Defined>(&sb);
// We already dealt with absolute and non-InputSection symbols in
// constantEq, and for InputSections we have already checked everything
// except the equivalence class.
- if (!DA->Section)
+ if (!da->section)
continue;
- auto *X = dyn_cast<InputSection>(DA->Section);
- if (!X)
+ auto *x = dyn_cast<InputSection>(da->section);
+ if (!x)
continue;
- auto *Y = cast<InputSection>(DB->Section);
+ auto *y = cast<InputSection>(db->section);
// Ineligible sections are in the special equivalence class 0.
// They can never be the same in terms of the equivalence class.
- if (X->Class[Current] == 0)
+ if (x->eqClass[current] == 0)
return false;
- if (X->Class[Current] != Y->Class[Current])
+ if (x->eqClass[current] != y->eqClass[current])
return false;
};
@@ -357,19 +357,19 @@ bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA,
// Compare "moving" part of two InputSections, namely relocation targets.
template <class ELFT>
-bool ICF<ELFT>::equalsVariable(const InputSection *A, const InputSection *B) {
- if (A->AreRelocsRela)
- return variableEq(A, A->template relas<ELFT>(), B,
- B->template relas<ELFT>());
- return variableEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
+bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
+ if (a->areRelocsRela)
+ return variableEq(a, a->template relas<ELFT>(), b,
+ b->template relas<ELFT>());
+ return variableEq(a, a->template rels<ELFT>(), b, b->template rels<ELFT>());
}
-template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
- uint32_t Class = Sections[Begin]->Class[Current];
- for (size_t I = Begin + 1; I < End; ++I)
- if (Class != Sections[I]->Class[Current])
- return I;
- return End;
+template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t begin, size_t end) {
+ uint32_t eqClass = sections[begin]->eqClass[current];
+ for (size_t i = begin + 1; i < end; ++i)
+ if (eqClass != sections[i]->eqClass[current])
+ return i;
+ return end;
}
// Sections in the same equivalence class are contiguous in Sections
@@ -378,125 +378,125 @@ template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
//
// This function calls Fn on every group within [Begin, End).
template <class ELFT>
-void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
- llvm::function_ref<void(size_t, size_t)> Fn) {
- while (Begin < End) {
- size_t Mid = findBoundary(Begin, End);
- Fn(Begin, Mid);
- Begin = Mid;
+void ICF<ELFT>::forEachClassRange(size_t begin, size_t end,
+ llvm::function_ref<void(size_t, size_t)> fn) {
+ while (begin < end) {
+ size_t mid = findBoundary(begin, end);
+ fn(begin, mid);
+ begin = mid;
}
}
// Call Fn on each equivalence class.
template <class ELFT>
-void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {
+void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> fn) {
// If threading is disabled or the number of sections are
// too small to use threading, call Fn sequentially.
- if (!ThreadsEnabled || Sections.size() < 1024) {
- forEachClassRange(0, Sections.size(), Fn);
- ++Cnt;
+ if (!ThreadsEnabled || sections.size() < 1024) {
+ forEachClassRange(0, sections.size(), fn);
+ ++cnt;
return;
}
- Current = Cnt % 2;
- Next = (Cnt + 1) % 2;
+ current = cnt % 2;
+ next = (cnt + 1) % 2;
// Shard into non-overlapping intervals, and call Fn in parallel.
// The sharding must be completed before any calls to Fn are made
// so that Fn can modify the Chunks in its shard without causing data
// races.
- const size_t NumShards = 256;
- size_t Step = Sections.size() / NumShards;
- size_t Boundaries[NumShards + 1];
- Boundaries[0] = 0;
- Boundaries[NumShards] = Sections.size();
-
- parallelForEachN(1, NumShards, [&](size_t I) {
- Boundaries[I] = findBoundary((I - 1) * Step, Sections.size());
+ const size_t numShards = 256;
+ size_t step = sections.size() / numShards;
+ size_t boundaries[numShards + 1];
+ boundaries[0] = 0;
+ boundaries[numShards] = sections.size();
+
+ parallelForEachN(1, numShards, [&](size_t i) {
+ boundaries[i] = findBoundary((i - 1) * step, sections.size());
});
- parallelForEachN(1, NumShards + 1, [&](size_t I) {
- if (Boundaries[I - 1] < Boundaries[I])
- forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
+ parallelForEachN(1, numShards + 1, [&](size_t i) {
+ if (boundaries[i - 1] < boundaries[i])
+ forEachClassRange(boundaries[i - 1], boundaries[i], fn);
});
- ++Cnt;
+ ++cnt;
}
// Combine the hashes of the sections referenced by the given section into its
// hash.
template <class ELFT, class RelTy>
-static void combineRelocHashes(unsigned Cnt, InputSection *IS,
- ArrayRef<RelTy> Rels) {
- uint32_t Hash = IS->Class[Cnt % 2];
- for (RelTy Rel : Rels) {
- Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
- if (auto *D = dyn_cast<Defined>(&S))
- if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
- Hash += RelSec->Class[Cnt % 2];
+static void combineRelocHashes(unsigned cnt, InputSection *isec,
+ ArrayRef<RelTy> rels) {
+ uint32_t hash = isec->eqClass[cnt % 2];
+ for (RelTy rel : rels) {
+ Symbol &s = isec->template getFile<ELFT>()->getRelocTargetSym(rel);
+ if (auto *d = dyn_cast<Defined>(&s))
+ if (auto *relSec = dyn_cast_or_null<InputSection>(d->section))
+ hash += relSec->eqClass[cnt % 2];
}
// Set MSB to 1 to avoid collisions with non-hash IDs.
- IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
+ isec->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
}
-static void print(const Twine &S) {
- if (Config->PrintIcfSections)
- message(S);
+static void print(const Twine &s) {
+ if (config->printIcfSections)
+ message(s);
}
// The main function of ICF.
template <class ELFT> void ICF<ELFT>::run() {
// Collect sections to merge.
- for (InputSectionBase *Sec : InputSections)
- if (auto *S = dyn_cast<InputSection>(Sec))
- if (isEligible(S))
- Sections.push_back(S);
+ for (InputSectionBase *sec : inputSections)
+ if (auto *s = dyn_cast<InputSection>(sec))
+ if (isEligible(s))
+ sections.push_back(s);
// Initially, we use hash values to partition sections.
- parallelForEach(Sections, [&](InputSection *S) {
- S->Class[0] = xxHash64(S->data());
+ parallelForEach(sections, [&](InputSection *s) {
+ s->eqClass[0] = xxHash64(s->data());
});
- for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
- parallelForEach(Sections, [&](InputSection *S) {
- if (S->AreRelocsRela)
- combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
+ for (unsigned cnt = 0; cnt != 2; ++cnt) {
+ parallelForEach(sections, [&](InputSection *s) {
+ if (s->areRelocsRela)
+ combineRelocHashes<ELFT>(cnt, s, s->template relas<ELFT>());
else
- combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
+ combineRelocHashes<ELFT>(cnt, s, s->template rels<ELFT>());
});
}
// From now on, sections in Sections vector are ordered so that sections
// in the same equivalence class are consecutive in the vector.
- llvm::stable_sort(Sections, [](const InputSection *A, const InputSection *B) {
- return A->Class[0] < B->Class[0];
+ llvm::stable_sort(sections, [](const InputSection *a, const InputSection *b) {
+ return a->eqClass[0] < b->eqClass[0];
});
// Compare static contents and assign unique IDs for each static content.
- forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
+ forEachClass([&](size_t begin, size_t end) { segregate(begin, end, true); });
// Split groups by comparing relocations until convergence is obtained.
do {
- Repeat = false;
+ repeat = false;
forEachClass(
- [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
- } while (Repeat);
+ [&](size_t begin, size_t end) { segregate(begin, end, false); });
+ } while (repeat);
- log("ICF needed " + Twine(Cnt) + " iterations");
+ log("ICF needed " + Twine(cnt) + " iterations");
// Merge sections by the equivalence class.
- forEachClassRange(0, Sections.size(), [&](size_t Begin, size_t End) {
- if (End - Begin == 1)
+ forEachClassRange(0, sections.size(), [&](size_t begin, size_t end) {
+ if (end - begin == 1)
return;
- print("selected section " + toString(Sections[Begin]));
- for (size_t I = Begin + 1; I < End; ++I) {
- print(" removing identical section " + toString(Sections[I]));
- Sections[Begin]->replace(Sections[I]);
+ print("selected section " + toString(sections[begin]));
+ for (size_t i = begin + 1; i < end; ++i) {
+ print(" removing identical section " + toString(sections[i]));
+ sections[begin]->replace(sections[i]);
// At this point we know sections merged are fully identical and hence
// we want to remove duplicate implicit dependencies such as link order
// and relocation sections.
- for (InputSection *IS : Sections[I]->DependentSections)
- IS->markDead();
+ for (InputSection *isec : sections[i]->dependentSections)
+ isec->markDead();
}
});
}
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 4d65ef37214..7f0ec2c7d4e 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -40,167 +40,167 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
-bool InputFile::IsInGroup;
-uint32_t InputFile::NextGroupId;
-std::vector<BinaryFile *> elf::BinaryFiles;
-std::vector<BitcodeFile *> elf::BitcodeFiles;
-std::vector<LazyObjFile *> elf::LazyObjFiles;
-std::vector<InputFile *> elf::ObjectFiles;
-std::vector<SharedFile *> elf::SharedFiles;
-
-std::unique_ptr<TarWriter> elf::Tar;
-
-static ELFKind getELFKind(MemoryBufferRef MB, StringRef ArchiveName) {
- unsigned char Size;
- unsigned char Endian;
- std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
-
- auto Report = [&](StringRef Msg) {
- StringRef Filename = MB.getBufferIdentifier();
- if (ArchiveName.empty())
- fatal(Filename + ": " + Msg);
+bool InputFile::isInGroup;
+uint32_t InputFile::nextGroupId;
+std::vector<BinaryFile *> elf::binaryFiles;
+std::vector<BitcodeFile *> elf::bitcodeFiles;
+std::vector<LazyObjFile *> elf::lazyObjFiles;
+std::vector<InputFile *> elf::objectFiles;
+std::vector<SharedFile *> elf::sharedFiles;
+
+std::unique_ptr<TarWriter> elf::tar;
+
+static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
+ unsigned char size;
+ unsigned char endian;
+ std::tie(size, endian) = getElfArchType(mb.getBuffer());
+
+ auto report = [&](StringRef msg) {
+ StringRef filename = mb.getBufferIdentifier();
+ if (archiveName.empty())
+ fatal(filename + ": " + msg);
else
- fatal(ArchiveName + "(" + Filename + "): " + Msg);
+ fatal(archiveName + "(" + filename + "): " + msg);
};
- if (!MB.getBuffer().startswith(ElfMagic))
- Report("not an ELF file");
- if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
- Report("corrupted ELF file: invalid data encoding");
- if (Size != ELFCLASS32 && Size != ELFCLASS64)
- Report("corrupted ELF file: invalid file class");
-
- size_t BufSize = MB.getBuffer().size();
- if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
- (Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
- Report("corrupted ELF file: file is too short");
-
- if (Size == ELFCLASS32)
- return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
- return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
+ if (!mb.getBuffer().startswith(ElfMagic))
+ report("not an ELF file");
+ if (endian != ELFDATA2LSB && endian != ELFDATA2MSB)
+ report("corrupted ELF file: invalid data encoding");
+ if (size != ELFCLASS32 && size != ELFCLASS64)
+ report("corrupted ELF file: invalid file class");
+
+ size_t bufSize = mb.getBuffer().size();
+ if ((size == ELFCLASS32 && bufSize < sizeof(Elf32_Ehdr)) ||
+ (size == ELFCLASS64 && bufSize < sizeof(Elf64_Ehdr)))
+ report("corrupted ELF file: file is too short");
+
+ if (size == ELFCLASS32)
+ return (endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
+ return (endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
}
-InputFile::InputFile(Kind K, MemoryBufferRef M)
- : MB(M), GroupId(NextGroupId), FileKind(K) {
+InputFile::InputFile(Kind k, MemoryBufferRef m)
+ : mb(m), groupId(nextGroupId), fileKind(k) {
// All files within the same --{start,end}-group get the same group ID.
// Otherwise, a new file will get a new group ID.
- if (!IsInGroup)
- ++NextGroupId;
+ if (!isInGroup)
+ ++nextGroupId;
}
-Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
+Optional<MemoryBufferRef> elf::readFile(StringRef path) {
// The --chroot option changes our virtual root directory.
// This is useful when you are dealing with files created by --reproduce.
- if (!Config->Chroot.empty() && Path.startswith("/"))
- Path = Saver.save(Config->Chroot + Path);
+ if (!config->chroot.empty() && path.startswith("/"))
+ path = Saver.save(config->chroot + path);
- log(Path);
+ log(path);
- auto MBOrErr = MemoryBuffer::getFile(Path, -1, false);
- if (auto EC = MBOrErr.getError()) {
- error("cannot open " + Path + ": " + EC.message());
+ auto mbOrErr = MemoryBuffer::getFile(path, -1, false);
+ if (auto ec = mbOrErr.getError()) {
+ error("cannot open " + path + ": " + ec.message());
return None;
}
- std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
- MemoryBufferRef MBRef = MB->getMemBufferRef();
- make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
+ std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
+ MemoryBufferRef mbref = mb->getMemBufferRef();
+ make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take MB ownership
- if (Tar)
- Tar->append(relativeToRoot(Path), MBRef.getBuffer());
- return MBRef;
+ if (tar)
+ tar->append(relativeToRoot(path), mbref.getBuffer());
+ return mbref;
}
// All input object files must be for the same architecture
// (e.g. it does not make sense to link x86 object files with
// MIPS object files.) This function checks for that error.
-static bool isCompatible(InputFile *File) {
- if (!File->isElf() && !isa<BitcodeFile>(File))
+static bool isCompatible(InputFile *file) {
+ if (!file->isElf() && !isa<BitcodeFile>(file))
return true;
- if (File->EKind == Config->EKind && File->EMachine == Config->EMachine) {
- if (Config->EMachine != EM_MIPS)
+ if (file->ekind == config->ekind && file->emachine == config->emachine) {
+ if (config->emachine != EM_MIPS)
return true;
- if (isMipsN32Abi(File) == Config->MipsN32Abi)
+ if (isMipsN32Abi(file) == config->mipsN32Abi)
return true;
}
- if (!Config->Emulation.empty()) {
- error(toString(File) + " is incompatible with " + Config->Emulation);
+ if (!config->emulation.empty()) {
+ error(toString(file) + " is incompatible with " + config->emulation);
} else {
- InputFile *Existing;
- if (!ObjectFiles.empty())
- Existing = ObjectFiles[0];
- else if (!SharedFiles.empty())
- Existing = SharedFiles[0];
+ InputFile *existing;
+ if (!objectFiles.empty())
+ existing = objectFiles[0];
+ else if (!sharedFiles.empty())
+ existing = sharedFiles[0];
else
- Existing = BitcodeFiles[0];
+ existing = bitcodeFiles[0];
- error(toString(File) + " is incompatible with " + toString(Existing));
+ error(toString(file) + " is incompatible with " + toString(existing));
}
return false;
}
-template <class ELFT> static void doParseFile(InputFile *File) {
- if (!isCompatible(File))
+template <class ELFT> static void doParseFile(InputFile *file) {
+ if (!isCompatible(file))
return;
// Binary file
- if (auto *F = dyn_cast<BinaryFile>(File)) {
- BinaryFiles.push_back(F);
- F->parse();
+ if (auto *f = dyn_cast<BinaryFile>(file)) {
+ binaryFiles.push_back(f);
+ f->parse();
return;
}
// .a file
- if (auto *F = dyn_cast<ArchiveFile>(File)) {
- F->parse();
+ if (auto *f = dyn_cast<ArchiveFile>(file)) {
+ f->parse();
return;
}
// Lazy object file
- if (auto *F = dyn_cast<LazyObjFile>(File)) {
- LazyObjFiles.push_back(F);
- F->parse<ELFT>();
+ if (auto *f = dyn_cast<LazyObjFile>(file)) {
+ lazyObjFiles.push_back(f);
+ f->parse<ELFT>();
return;
}
- if (Config->Trace)
- message(toString(File));
+ if (config->trace)
+ message(toString(file));
// .so file
- if (auto *F = dyn_cast<SharedFile>(File)) {
- F->parse<ELFT>();
+ if (auto *f = dyn_cast<SharedFile>(file)) {
+ f->parse<ELFT>();
return;
}
// LLVM bitcode file
- if (auto *F = dyn_cast<BitcodeFile>(File)) {
- BitcodeFiles.push_back(F);
- F->parse<ELFT>();
+ if (auto *f = dyn_cast<BitcodeFile>(file)) {
+ bitcodeFiles.push_back(f);
+ f->parse<ELFT>();
return;
}
// Regular object file
- ObjectFiles.push_back(File);
- cast<ObjFile<ELFT>>(File)->parse();
+ objectFiles.push_back(file);
+ cast<ObjFile<ELFT>>(file)->parse();
}
// Add symbols in File to the symbol table.
-void elf::parseFile(InputFile *File) {
- switch (Config->EKind) {
+void elf::parseFile(InputFile *file) {
+ switch (config->ekind) {
case ELF32LEKind:
- doParseFile<ELF32LE>(File);
+ doParseFile<ELF32LE>(file);
return;
case ELF32BEKind:
- doParseFile<ELF32BE>(File);
+ doParseFile<ELF32BE>(file);
return;
case ELF64LEKind:
- doParseFile<ELF64LE>(File);
+ doParseFile<ELF64LE>(file);
return;
case ELF64BEKind:
- doParseFile<ELF64BE>(File);
+ doParseFile<ELF64BE>(file);
return;
default:
llvm_unreachable("unknown ELFT");
@@ -208,87 +208,87 @@ void elf::parseFile(InputFile *File) {
}
// Concatenates arguments to construct a string representing an error location.
-static std::string createFileLineMsg(StringRef Path, unsigned Line) {
- std::string Filename = path::filename(Path);
- std::string Lineno = ":" + std::to_string(Line);
- if (Filename == Path)
- return Filename + Lineno;
- return Filename + Lineno + " (" + Path.str() + Lineno + ")";
+static std::string createFileLineMsg(StringRef path, unsigned line) {
+ std::string filename = path::filename(path);
+ std::string lineno = ":" + std::to_string(line);
+ if (filename == path)
+ return filename + lineno;
+ return filename + lineno + " (" + path.str() + lineno + ")";
}
template <class ELFT>
-static std::string getSrcMsgAux(ObjFile<ELFT> &File, const Symbol &Sym,
- InputSectionBase &Sec, uint64_t Offset) {
+static std::string getSrcMsgAux(ObjFile<ELFT> &file, const Symbol &sym,
+ InputSectionBase &sec, uint64_t offset) {
// In DWARF, functions and variables are stored to different places.
// First, lookup a function for a given offset.
- if (Optional<DILineInfo> Info = File.getDILineInfo(&Sec, Offset))
- return createFileLineMsg(Info->FileName, Info->Line);
+ if (Optional<DILineInfo> info = file.getDILineInfo(&sec, offset))
+ return createFileLineMsg(info->FileName, info->Line);
// If it failed, lookup again as a variable.
- if (Optional<std::pair<std::string, unsigned>> FileLine =
- File.getVariableLoc(Sym.getName()))
- return createFileLineMsg(FileLine->first, FileLine->second);
+ if (Optional<std::pair<std::string, unsigned>> fileLine =
+ file.getVariableLoc(sym.getName()))
+ return createFileLineMsg(fileLine->first, fileLine->second);
// File.SourceFile contains STT_FILE symbol, and that is a last resort.
- return File.SourceFile;
+ return file.sourceFile;
}
-std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
- uint64_t Offset) {
+std::string InputFile::getSrcMsg(const Symbol &sym, InputSectionBase &sec,
+ uint64_t offset) {
if (kind() != ObjKind)
return "";
- switch (Config->EKind) {
+ switch (config->ekind) {
default:
llvm_unreachable("Invalid kind");
case ELF32LEKind:
- return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), Sym, Sec, Offset);
+ return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), sym, sec, offset);
case ELF32BEKind:
- return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), Sym, Sec, Offset);
+ return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), sym, sec, offset);
case ELF64LEKind:
- return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), Sym, Sec, Offset);
+ return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), sym, sec, offset);
case ELF64BEKind:
- return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), Sym, Sec, Offset);
+ return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset);
}
}
template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
- Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
- for (std::unique_ptr<DWARFUnit> &CU : Dwarf->compile_units()) {
- auto Report = [](Error Err) {
- handleAllErrors(std::move(Err),
- [](ErrorInfoBase &Info) { warn(Info.message()); });
+ dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf->compile_units()) {
+ auto report = [](Error err) {
+ handleAllErrors(std::move(err),
+ [](ErrorInfoBase &info) { warn(info.message()); });
};
- Expected<const DWARFDebugLine::LineTable *> ExpectedLT =
- Dwarf->getLineTableForUnit(CU.get(), Report);
- const DWARFDebugLine::LineTable *LT = nullptr;
- if (ExpectedLT)
- LT = *ExpectedLT;
+ Expected<const DWARFDebugLine::LineTable *> expectedLT =
+ dwarf->getLineTableForUnit(cu.get(), report);
+ const DWARFDebugLine::LineTable *lt = nullptr;
+ if (expectedLT)
+ lt = *expectedLT;
else
- Report(ExpectedLT.takeError());
- if (!LT)
+ report(expectedLT.takeError());
+ if (!lt)
continue;
- LineTables.push_back(LT);
+ lineTables.push_back(lt);
// Loop over variable records and insert them to VariableLoc.
- for (const auto &Entry : CU->dies()) {
- DWARFDie Die(CU.get(), &Entry);
+ for (const auto &entry : cu->dies()) {
+ DWARFDie die(cu.get(), &entry);
// Skip all tags that are not variables.
- if (Die.getTag() != dwarf::DW_TAG_variable)
+ if (die.getTag() != dwarf::DW_TAG_variable)
continue;
// Skip if a local variable because we don't need them for generating
// error messages. In general, only non-local symbols can fail to be
// linked.
- if (!dwarf::toUnsigned(Die.find(dwarf::DW_AT_external), 0))
+ if (!dwarf::toUnsigned(die.find(dwarf::DW_AT_external), 0))
continue;
// Get the source filename index for the variable.
- unsigned File = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_file), 0);
- if (!LT->hasFileAtIndex(File))
+ unsigned file = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_file), 0);
+ if (!lt->hasFileAtIndex(file))
continue;
// Get the line number on which the variable is declared.
- unsigned Line = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_line), 0);
+ unsigned line = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_line), 0);
// Here we want to take the variable name to add it into VariableLoc.
// Variable can have regular and linkage name associated. At first, we try
@@ -296,11 +296,11 @@ template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
// two variables in different namespaces of the same object. Use common
// name otherwise, but handle the case when it also absent in case if the
// input object file lacks some debug info.
- StringRef Name =
- dwarf::toString(Die.find(dwarf::DW_AT_linkage_name),
- dwarf::toString(Die.find(dwarf::DW_AT_name), ""));
- if (!Name.empty())
- VariableLoc.insert({Name, {LT, File, Line}});
+ StringRef name =
+ dwarf::toString(die.find(dwarf::DW_AT_linkage_name),
+ dwarf::toString(die.find(dwarf::DW_AT_name), ""));
+ if (!name.empty())
+ variableLoc.insert({name, {lt, file, line}});
}
}
}
@@ -309,71 +309,71 @@ template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
// object (variable, array, etc) definition.
template <class ELFT>
Optional<std::pair<std::string, unsigned>>
-ObjFile<ELFT>::getVariableLoc(StringRef Name) {
- llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); });
+ObjFile<ELFT>::getVariableLoc(StringRef name) {
+ llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
// Return if we have no debug information about data object.
- auto It = VariableLoc.find(Name);
- if (It == VariableLoc.end())
+ auto it = variableLoc.find(name);
+ if (it == variableLoc.end())
return None;
// Take file name string from line table.
- std::string FileName;
- if (!It->second.LT->getFileNameByIndex(
- It->second.File, nullptr,
- DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FileName))
+ std::string fileName;
+ if (!it->second.lt->getFileNameByIndex(
+ it->second.file, nullptr,
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, fileName))
return None;
- return std::make_pair(FileName, It->second.Line);
+ return std::make_pair(fileName, it->second.line);
}
// Returns source line information for a given offset
// using DWARF debug info.
template <class ELFT>
-Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S,
- uint64_t Offset) {
- llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); });
+Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
+ uint64_t offset) {
+ llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
// Detect SectionIndex for specified section.
- uint64_t SectionIndex = object::SectionedAddress::UndefSection;
- ArrayRef<InputSectionBase *> Sections = S->File->getSections();
- for (uint64_t CurIndex = 0; CurIndex < Sections.size(); ++CurIndex) {
- if (S == Sections[CurIndex]) {
- SectionIndex = CurIndex;
+ uint64_t sectionIndex = object::SectionedAddress::UndefSection;
+ ArrayRef<InputSectionBase *> sections = s->file->getSections();
+ for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) {
+ if (s == sections[curIndex]) {
+ sectionIndex = curIndex;
break;
}
}
// Use fake address calcuated by adding section file offset and offset in
// section. See comments for ObjectInfo class.
- DILineInfo Info;
- for (const llvm::DWARFDebugLine::LineTable *LT : LineTables) {
- if (LT->getFileLineInfoForAddress(
- {S->getOffsetInFile() + Offset, SectionIndex}, nullptr,
- DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info))
- return Info;
+ DILineInfo info;
+ for (const llvm::DWARFDebugLine::LineTable *lt : lineTables) {
+ if (lt->getFileLineInfoForAddress(
+ {s->getOffsetInFile() + offset, sectionIndex}, nullptr,
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, info))
+ return info;
}
return None;
}
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
-std::string lld::toString(const InputFile *F) {
- if (!F)
+std::string lld::toString(const InputFile *f) {
+ if (!f)
return "<internal>";
- if (F->ToStringCache.empty()) {
- if (F->ArchiveName.empty())
- F->ToStringCache = F->getName();
+ if (f->toStringCache.empty()) {
+ if (f->archiveName.empty())
+ f->toStringCache = f->getName();
else
- F->ToStringCache = (F->ArchiveName + "(" + F->getName() + ")").str();
+ f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str();
}
- return F->ToStringCache;
+ return f->toStringCache;
}
-ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
- EKind = getELFKind(MB, "");
+ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {
+ ekind = getELFKind(mb, "");
- switch (EKind) {
+ switch (ekind) {
case ELF32LEKind:
init<ELF32LE>();
break;
@@ -392,10 +392,10 @@ ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
}
template <typename Elf_Shdr>
-static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> Sections, uint32_t Type) {
- for (const Elf_Shdr &Sec : Sections)
- if (Sec.sh_type == Type)
- return &Sec;
+static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> sections, uint32_t type) {
+ for (const Elf_Shdr &sec : sections)
+ if (sec.sh_type == type)
+ return &sec;
return nullptr;
}
@@ -404,57 +404,57 @@ template <class ELFT> void ELFFileBase::init() {
using Elf_Sym = typename ELFT::Sym;
// Initialize trivial attributes.
- const ELFFile<ELFT> &Obj = getObj<ELFT>();
- EMachine = Obj.getHeader()->e_machine;
- OSABI = Obj.getHeader()->e_ident[llvm::ELF::EI_OSABI];
- ABIVersion = Obj.getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
+ const ELFFile<ELFT> &obj = getObj<ELFT>();
+ emachine = obj.getHeader()->e_machine;
+ osabi = obj.getHeader()->e_ident[llvm::ELF::EI_OSABI];
+ abiVersion = obj.getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
- ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
+ ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
// Find a symbol table.
- bool IsDSO =
- (identify_magic(MB.getBuffer()) == file_magic::elf_shared_object);
- const Elf_Shdr *SymtabSec =
- findSection(Sections, IsDSO ? SHT_DYNSYM : SHT_SYMTAB);
+ bool isDSO =
+ (identify_magic(mb.getBuffer()) == file_magic::elf_shared_object);
+ const Elf_Shdr *symtabSec =
+ findSection(sections, isDSO ? SHT_DYNSYM : SHT_SYMTAB);
- if (!SymtabSec)
+ if (!symtabSec)
return;
// Initialize members corresponding to a symbol table.
- FirstGlobal = SymtabSec->sh_info;
+ firstGlobal = symtabSec->sh_info;
- ArrayRef<Elf_Sym> ESyms = CHECK(Obj.symbols(SymtabSec), this);
- if (FirstGlobal == 0 || FirstGlobal > ESyms.size())
+ ArrayRef<Elf_Sym> eSyms = CHECK(obj.symbols(symtabSec), this);
+ if (firstGlobal == 0 || firstGlobal > eSyms.size())
fatal(toString(this) + ": invalid sh_info in symbol table");
- ELFSyms = reinterpret_cast<const void *>(ESyms.data());
- NumELFSyms = ESyms.size();
- StringTable = CHECK(Obj.getStringTableForSymtab(*SymtabSec, Sections), this);
+ elfSyms = reinterpret_cast<const void *>(eSyms.data());
+ numELFSyms = eSyms.size();
+ stringTable = CHECK(obj.getStringTableForSymtab(*symtabSec, sections), this);
}
template <class ELFT>
-uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
+uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {
return CHECK(
- this->getObj().getSectionIndex(&Sym, getELFSyms<ELFT>(), ShndxTable),
+ this->getObj().getSectionIndex(&sym, getELFSyms<ELFT>(), shndxTable),
this);
}
template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() {
- if (this->Symbols.empty())
+ if (this->symbols.empty())
return {};
- return makeArrayRef(this->Symbols).slice(1, this->FirstGlobal - 1);
+ return makeArrayRef(this->symbols).slice(1, this->firstGlobal - 1);
}
template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
- return makeArrayRef(this->Symbols).slice(this->FirstGlobal);
+ return makeArrayRef(this->symbols).slice(this->firstGlobal);
}
-template <class ELFT> void ObjFile<ELFT>::parse(bool IgnoreComdats) {
+template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
// Read a section table. JustSymbols is usually false.
- if (this->JustSymbols)
+ if (this->justSymbols)
initializeJustSymbols();
else
- initializeSections(IgnoreComdats);
+ initializeSections(ignoreComdats);
// Read a symbol table.
initializeSymbols();
@@ -464,11 +464,11 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool IgnoreComdats) {
// They are identified and deduplicated by group name. This function
// returns a group name.
template <class ELFT>
-StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
- const Elf_Shdr &Sec) {
- const Elf_Sym *Sym =
- CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), Sec.sh_info), this);
- StringRef Signature = CHECK(Sym->getName(this->StringTable), this);
+StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
+ const Elf_Shdr &sec) {
+ const Elf_Sym *sym =
+ CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), sec.sh_info), this);
+ StringRef signature = CHECK(sym->getName(this->stringTable), this);
// As a special case, if a symbol is a section symbol and has no name,
// we use a section name as a signature.
@@ -477,12 +477,12 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
// standard, but GNU gold 1.14 (the newest version as of July 2017) or
// older produce such sections as outputs for the -r option, so we need
// a bug-compatibility.
- if (Signature.empty() && Sym->getType() == STT_SECTION)
- return getSectionName(Sec);
- return Signature;
+ if (signature.empty() && sym->getType() == STT_SECTION)
+ return getSectionName(sec);
+ return signature;
}
-template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
+template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec) {
// On a regular link we don't merge sections if -O0 (default is -O1). This
// sometimes makes the linker significantly faster, although the output will
// be bigger.
@@ -495,14 +495,14 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
// SHF_MERGE sections based both on their name and sh_entsize, but that seems
// to be more trouble than it is worth. Instead, we just use the regular (-O1)
// logic for -r.
- if (Config->Optimize == 0 && !Config->Relocatable)
+ if (config->optimize == 0 && !config->relocatable)
return false;
// A mergeable section with size 0 is useless because they don't have
// any data to merge. A mergeable string section with size 0 can be
// argued as invalid because it doesn't end with a null character.
// We'll avoid a mess by handling them as if they were non-mergeable.
- if (Sec.sh_size == 0)
+ if (sec.sh_size == 0)
return false;
// Check for sh_entsize. The ELF spec is not clear about the zero
@@ -510,17 +510,17 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
// the section does not hold a table of fixed-size entries". We know
// that Rust 1.13 produces a string mergeable section with a zero
// sh_entsize. Here we just accept it rather than being picky about it.
- uint64_t EntSize = Sec.sh_entsize;
- if (EntSize == 0)
+ uint64_t entSize = sec.sh_entsize;
+ if (entSize == 0)
return false;
- if (Sec.sh_size % EntSize)
+ if (sec.sh_size % entSize)
fatal(toString(this) +
": SHF_MERGE section size must be a multiple of sh_entsize");
- uint64_t Flags = Sec.sh_flags;
- if (!(Flags & SHF_MERGE))
+ uint64_t flags = sec.sh_flags;
+ if (!(flags & SHF_MERGE))
return false;
- if (Flags & SHF_WRITE)
+ if (flags & SHF_WRITE)
fatal(toString(this) + ": writable SHF_MERGE section is not supported");
return true;
@@ -536,8 +536,8 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
// When the option is given, we link "just symbols". The section table is
// initialized with null pointers.
template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
- ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
- this->Sections.resize(Sections.size());
+ ArrayRef<Elf_Shdr> sections = CHECK(this->getObj().sections(), this);
+ this->sections.resize(sections.size());
}
// An ELF object file may contain a `.deplibs` section. If it exists, the
@@ -546,128 +546,128 @@ template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
// the various ways that a library can be specified to LLD. This ELF extension
// is a form of autolinking and is called `dependent libraries`. It is currently
// unique to LLVM and lld.
-static void addDependentLibrary(StringRef Specifier, const InputFile *F) {
- if (!Config->DependentLibraries)
+static void addDependentLibrary(StringRef specifier, const InputFile *f) {
+ if (!config->dependentLibraries)
return;
- if (fs::exists(Specifier))
- Driver->addFile(Specifier, /*WithLOption=*/false);
- else if (Optional<std::string> S = findFromSearchPaths(Specifier))
- Driver->addFile(*S, /*WithLOption=*/true);
- else if (Optional<std::string> S = searchLibraryBaseName(Specifier))
- Driver->addFile(*S, /*WithLOption=*/true);
+ if (fs::exists(specifier))
+ driver->addFile(specifier, /*WithLOption=*/false);
+ else if (Optional<std::string> s = findFromSearchPaths(specifier))
+ driver->addFile(*s, /*WithLOption=*/true);
+ else if (Optional<std::string> s = searchLibraryBaseName(specifier))
+ driver->addFile(*s, /*WithLOption=*/true);
else
- error(toString(F) +
+ error(toString(f) +
": unable to find library from dependent library specifier: " +
- Specifier);
+ specifier);
}
template <class ELFT>
-void ObjFile<ELFT>::initializeSections(bool IgnoreComdats) {
- const ELFFile<ELFT> &Obj = this->getObj();
+void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
+ const ELFFile<ELFT> &obj = this->getObj();
- ArrayRef<Elf_Shdr> ObjSections = CHECK(Obj.sections(), this);
- uint64_t Size = ObjSections.size();
- this->Sections.resize(Size);
- this->SectionStringTable =
- CHECK(Obj.getSectionStringTable(ObjSections), this);
+ ArrayRef<Elf_Shdr> objSections = CHECK(obj.sections(), this);
+ uint64_t size = objSections.size();
+ this->sections.resize(size);
+ this->sectionStringTable =
+ CHECK(obj.getSectionStringTable(objSections), this);
- for (size_t I = 0, E = ObjSections.size(); I < E; I++) {
- if (this->Sections[I] == &InputSection::Discarded)
+ for (size_t i = 0, e = objSections.size(); i < e; i++) {
+ if (this->sections[i] == &InputSection::discarded)
continue;
- const Elf_Shdr &Sec = ObjSections[I];
+ const Elf_Shdr &sec = objSections[i];
- if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
- CGProfile =
- check(Obj.template getSectionContentsAsArray<Elf_CGProfile>(&Sec));
+ if (sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
+ cgProfile =
+ check(obj.template getSectionContentsAsArray<Elf_CGProfile>(&sec));
// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
// This is compatible with GNU.
- if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) {
- if (Sec.sh_type == SHT_LLVM_ADDRSIG) {
+ if ((sec.sh_flags & SHF_EXCLUDE) && !config->relocatable) {
+ if (sec.sh_type == SHT_LLVM_ADDRSIG) {
// We ignore the address-significance table if we know that the object
// file was created by objcopy or ld -r. This is because these tools
// will reorder the symbols in the symbol table, invalidating the data
// in the address-significance table, which refers to symbols by index.
- if (Sec.sh_link != 0)
- this->AddrsigSec = &Sec;
- else if (Config->ICF == ICFLevel::Safe)
+ if (sec.sh_link != 0)
+ this->addrsigSec = &sec;
+ else if (config->icf == ICFLevel::Safe)
warn(toString(this) + ": --icf=safe is incompatible with object "
"files created using objcopy or ld -r");
}
- this->Sections[I] = &InputSection::Discarded;
+ this->sections[i] = &InputSection::discarded;
continue;
}
- switch (Sec.sh_type) {
+ switch (sec.sh_type) {
case SHT_GROUP: {
// De-duplicate section groups by their signatures.
- StringRef Signature = getShtGroupSignature(ObjSections, Sec);
- this->Sections[I] = &InputSection::Discarded;
+ StringRef signature = getShtGroupSignature(objSections, sec);
+ this->sections[i] = &InputSection::discarded;
- ArrayRef<Elf_Word> Entries =
- CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
- if (Entries.empty())
+ ArrayRef<Elf_Word> entries =
+ CHECK(obj.template getSectionContentsAsArray<Elf_Word>(&sec), this);
+ if (entries.empty())
fatal(toString(this) + ": empty SHT_GROUP");
// The first word of a SHT_GROUP section contains flags. Currently,
// the standard defines only "GRP_COMDAT" flag for the COMDAT group.
// An group with the empty flag doesn't define anything; such sections
// are just skipped.
- if (Entries[0] == 0)
+ if (entries[0] == 0)
continue;
- if (Entries[0] != GRP_COMDAT)
+ if (entries[0] != GRP_COMDAT)
fatal(toString(this) + ": unsupported SHT_GROUP format");
- bool IsNew =
- IgnoreComdats ||
- Symtab->ComdatGroups.try_emplace(CachedHashStringRef(Signature), this)
+ bool isNew =
+ ignoreComdats ||
+ symtab->comdatGroups.try_emplace(CachedHashStringRef(signature), this)
.second;
- if (IsNew) {
- if (Config->Relocatable)
- this->Sections[I] = createInputSection(Sec);
+ if (isNew) {
+ if (config->relocatable)
+ this->sections[i] = createInputSection(sec);
continue;
}
// Otherwise, discard group members.
- for (uint32_t SecIndex : Entries.slice(1)) {
- if (SecIndex >= Size)
+ for (uint32_t secIndex : entries.slice(1)) {
+ if (secIndex >= size)
fatal(toString(this) +
- ": invalid section index in group: " + Twine(SecIndex));
- this->Sections[SecIndex] = &InputSection::Discarded;
+ ": invalid section index in group: " + Twine(secIndex));
+ this->sections[secIndex] = &InputSection::discarded;
}
break;
}
case SHT_SYMTAB_SHNDX:
- ShndxTable = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
+ shndxTable = CHECK(obj.getSHNDXTable(sec, objSections), this);
break;
case SHT_SYMTAB:
case SHT_STRTAB:
case SHT_NULL:
break;
default:
- this->Sections[I] = createInputSection(Sec);
+ this->sections[i] = createInputSection(sec);
}
// .ARM.exidx sections have a reverse dependency on the InputSection they
// have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
- if (Sec.sh_flags & SHF_LINK_ORDER) {
- InputSectionBase *LinkSec = nullptr;
- if (Sec.sh_link < this->Sections.size())
- LinkSec = this->Sections[Sec.sh_link];
- if (!LinkSec)
+ if (sec.sh_flags & SHF_LINK_ORDER) {
+ InputSectionBase *linkSec = nullptr;
+ if (sec.sh_link < this->sections.size())
+ linkSec = this->sections[sec.sh_link];
+ if (!linkSec)
fatal(toString(this) +
- ": invalid sh_link index: " + Twine(Sec.sh_link));
+ ": invalid sh_link index: " + Twine(sec.sh_link));
- InputSection *IS = cast<InputSection>(this->Sections[I]);
- LinkSec->DependentSections.push_back(IS);
- if (!isa<InputSection>(LinkSec))
- error("a section " + IS->Name +
+ InputSection *isec = cast<InputSection>(this->sections[i]);
+ linkSec->dependentSections.push_back(isec);
+ if (!isa<InputSection>(linkSec))
+ error("a section " + isec->name +
" with SHF_LINK_ORDER should not refer a non-regular "
"section: " +
- toString(LinkSec));
+ toString(linkSec));
}
}
}
@@ -675,9 +675,9 @@ void ObjFile<ELFT>::initializeSections(bool IgnoreComdats) {
// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
// the input objects have been compiled.
-static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
- const InputFile *F) {
- if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
+static void updateARMVFPArgs(const ARMAttributeParser &attributes,
+ const InputFile *f) {
+ if (!attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
// If an ABI tag isn't present then it is implicitly given the value of 0
// which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
// including some in glibc that don't use FP args (and should have value 3)
@@ -685,31 +685,31 @@ static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
// as a clash.
return;
- unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
- ARMVFPArgKind Arg;
- switch (VFPArgs) {
+ unsigned vfpArgs = attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
+ ARMVFPArgKind arg;
+ switch (vfpArgs) {
case ARMBuildAttrs::BaseAAPCS:
- Arg = ARMVFPArgKind::Base;
+ arg = ARMVFPArgKind::Base;
break;
case ARMBuildAttrs::HardFPAAPCS:
- Arg = ARMVFPArgKind::VFP;
+ arg = ARMVFPArgKind::VFP;
break;
case ARMBuildAttrs::ToolChainFPPCS:
// Tool chain specific convention that conforms to neither AAPCS variant.
- Arg = ARMVFPArgKind::ToolChain;
+ arg = ARMVFPArgKind::ToolChain;
break;
case ARMBuildAttrs::CompatibleFPAAPCS:
// Object compatible with all conventions.
return;
default:
- error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
+ error(toString(f) + ": unknown Tag_ABI_VFP_args value: " + Twine(vfpArgs));
return;
}
// Follow ld.bfd and error if there is a mix of calling conventions.
- if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
- error(toString(F) + ": incompatible Tag_ABI_VFP_args");
+ if (config->armVFPArgs != arg && config->armVFPArgs != ARMVFPArgKind::Default)
+ error(toString(f) + ": incompatible Tag_ABI_VFP_args");
else
- Config->ARMVFPArgs = Arg;
+ config->armVFPArgs = arg;
}
// The ARM support in lld makes some use of instructions that are not available
@@ -721,11 +721,11 @@ static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
// at compile time. We follow the convention that if at least one input object
// is compiled with an architecture that supports these features then lld is
// permitted to use them.
-static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
- if (!Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
+static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {
+ if (!attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
return;
- auto Arch = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
- switch (Arch) {
+ auto arch = attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ switch (arch) {
case ARMBuildAttrs::Pre_v4:
case ARMBuildAttrs::v4:
case ARMBuildAttrs::v4T:
@@ -737,19 +737,19 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
case ARMBuildAttrs::v6:
case ARMBuildAttrs::v6KZ:
case ARMBuildAttrs::v6K:
- Config->ARMHasBlx = true;
+ config->armHasBlx = true;
// Architectures used in pre-Cortex processors do not support
// The J1 = 1 J2 = 1 Thumb branch range extension, with the exception
// of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do.
break;
default:
// All other Architectures have BLX and extended branch encoding
- Config->ARMHasBlx = true;
- Config->ARMJ1J2BranchEncoding = true;
- if (Arch != ARMBuildAttrs::v6_M && Arch != ARMBuildAttrs::v6S_M)
+ config->armHasBlx = true;
+ config->armJ1J2BranchEncoding = true;
+ if (arch != ARMBuildAttrs::v6_M && arch != ARMBuildAttrs::v6S_M)
// All Architectures used in Cortex processors with the exception
// of v6-M and v6S-M have the MOVT and MOVW instructions.
- Config->ARMHasMovtMovw = true;
+ config->armHasMovtMovw = true;
break;
}
}
@@ -767,126 +767,126 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
// certain type. It seems a bit too much to just store a 32-bit value, perhaps
// the ABI is unnecessarily complicated.
template <class ELFT>
-static uint32_t readAndFeatures(ObjFile<ELFT> *Obj, ArrayRef<uint8_t> Data) {
+static uint32_t readAndFeatures(ObjFile<ELFT> *obj, ArrayRef<uint8_t> data) {
using Elf_Nhdr = typename ELFT::Nhdr;
using Elf_Note = typename ELFT::Note;
- uint32_t FeaturesSet = 0;
- while (!Data.empty()) {
+ uint32_t featuresSet = 0;
+ while (!data.empty()) {
// Read one NOTE record.
- if (Data.size() < sizeof(Elf_Nhdr))
- fatal(toString(Obj) + ": .note.gnu.property: section too short");
+ if (data.size() < sizeof(Elf_Nhdr))
+ fatal(toString(obj) + ": .note.gnu.property: section too short");
- auto *Nhdr = reinterpret_cast<const Elf_Nhdr *>(Data.data());
- if (Data.size() < Nhdr->getSize())
- fatal(toString(Obj) + ": .note.gnu.property: section too short");
+ auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
+ if (data.size() < nhdr->getSize())
+ fatal(toString(obj) + ": .note.gnu.property: section too short");
- Elf_Note Note(*Nhdr);
- if (Nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || Note.getName() != "GNU") {
- Data = Data.slice(Nhdr->getSize());
+ Elf_Note note(*nhdr);
+ if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
+ data = data.slice(nhdr->getSize());
continue;
}
- uint32_t FeatureAndType = Config->EMachine == EM_AARCH64
+ uint32_t featureAndType = config->emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;
// Read a body of a NOTE record, which consists of type-length-value fields.
- ArrayRef<uint8_t> Desc = Note.getDesc();
- while (!Desc.empty()) {
- if (Desc.size() < 8)
- fatal(toString(Obj) + ": .note.gnu.property: section too short");
+ ArrayRef<uint8_t> desc = note.getDesc();
+ while (!desc.empty()) {
+ if (desc.size() < 8)
+ fatal(toString(obj) + ": .note.gnu.property: section too short");
- uint32_t Type = read32le(Desc.data());
- uint32_t Size = read32le(Desc.data() + 4);
+ uint32_t type = read32le(desc.data());
+ uint32_t size = read32le(desc.data() + 4);
- if (Type == FeatureAndType) {
+ if (type == featureAndType) {
// We found a FEATURE_1_AND field. There may be more than one of these
// in a .note.gnu.propery section, for a relocatable object we
// accumulate the bits set.
- FeaturesSet |= read32le(Desc.data() + 8);
+ featuresSet |= read32le(desc.data() + 8);
}
// On 64-bit, a payload may be followed by a 4-byte padding to make its
// size a multiple of 8.
if (ELFT::Is64Bits)
- Size = alignTo(Size, 8);
+ size = alignTo(size, 8);
- Desc = Desc.slice(Size + 8); // +8 for Type and Size
+ desc = desc.slice(size + 8); // +8 for Type and Size
}
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
- Data = Data.slice(Nhdr->getSize());
+ data = data.slice(nhdr->getSize());
}
- return FeaturesSet;
+ return featuresSet;
}
template <class ELFT>
-InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
- uint32_t Idx = Sec.sh_info;
- if (Idx >= this->Sections.size())
- fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx));
- InputSectionBase *Target = this->Sections[Idx];
+InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &sec) {
+ uint32_t idx = sec.sh_info;
+ if (idx >= this->sections.size())
+ fatal(toString(this) + ": invalid relocated section index: " + Twine(idx));
+ InputSectionBase *target = this->sections[idx];
// Strictly speaking, a relocation section must be included in the
// group of the section it relocates. However, LLVM 3.3 and earlier
// would fail to do so, so we gracefully handle that case.
- if (Target == &InputSection::Discarded)
+ if (target == &InputSection::discarded)
return nullptr;
- if (!Target)
+ if (!target)
fatal(toString(this) + ": unsupported relocation reference");
- return Target;
+ return target;
}
// Create a regular InputSection class that has the same contents
// as a given section.
-static InputSection *toRegularSection(MergeInputSection *Sec) {
- return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
- Sec->data(), Sec->Name);
+static InputSection *toRegularSection(MergeInputSection *sec) {
+ return make<InputSection>(sec->file, sec->flags, sec->type, sec->alignment,
+ sec->data(), sec->name);
}
template <class ELFT>
-InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
- StringRef Name = getSectionName(Sec);
+InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &sec) {
+ StringRef name = getSectionName(sec);
- switch (Sec.sh_type) {
+ switch (sec.sh_type) {
case SHT_ARM_ATTRIBUTES: {
- if (Config->EMachine != EM_ARM)
+ if (config->emachine != EM_ARM)
break;
- ARMAttributeParser Attributes;
- ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
- Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
- updateSupportedARMFeatures(Attributes);
- updateARMVFPArgs(Attributes, this);
+ ARMAttributeParser attributes;
+ ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
+ attributes.Parse(contents, /*isLittle*/ config->ekind == ELF32LEKind);
+ updateSupportedARMFeatures(attributes);
+ updateARMVFPArgs(attributes, this);
// FIXME: Retain the first attribute section we see. The eglibc ARM
// dynamic loaders require the presence of an attribute section for dlopen
// to work. In a full implementation we would merge all attribute sections.
- if (In.ARMAttributes == nullptr) {
- In.ARMAttributes = make<InputSection>(*this, Sec, Name);
- return In.ARMAttributes;
+ if (in.armAttributes == nullptr) {
+ in.armAttributes = make<InputSection>(*this, sec, name);
+ return in.armAttributes;
}
- return &InputSection::Discarded;
+ return &InputSection::discarded;
}
case SHT_LLVM_DEPENDENT_LIBRARIES: {
- if (Config->Relocatable)
+ if (config->relocatable)
break;
- ArrayRef<char> Data =
- CHECK(this->getObj().template getSectionContentsAsArray<char>(&Sec), this);
- if (!Data.empty() && Data.back() != '\0') {
+ ArrayRef<char> data =
+ CHECK(this->getObj().template getSectionContentsAsArray<char>(&sec), this);
+ if (!data.empty() && data.back() != '\0') {
error(toString(this) +
": corrupted dependent libraries section (unterminated string): " +
- Name);
- return &InputSection::Discarded;
+ name);
+ return &InputSection::discarded;
}
- for (const char *D = Data.begin(), *E = Data.end(); D < E;) {
- StringRef S(D);
- addDependentLibrary(S, this);
- D += S.size() + 1;
+ for (const char *d = data.begin(), *e = data.end(); d < e;) {
+ StringRef s(d);
+ addDependentLibrary(s, this);
+ d += s.size() + 1;
}
- return &InputSection::Discarded;
+ return &InputSection::discarded;
}
case SHT_RELA:
case SHT_REL: {
@@ -895,25 +895,25 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// and the group is discarded, even though it's a violation of the
// spec. We handle that situation gracefully by discarding dangling
// relocation sections.
- InputSectionBase *Target = getRelocTarget(Sec);
- if (!Target)
+ InputSectionBase *target = getRelocTarget(sec);
+ if (!target)
return nullptr;
// This section contains relocation information.
// If -r is given, we do not interpret or apply relocation
// but just copy relocation sections to output.
- if (Config->Relocatable) {
- InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
+ if (config->relocatable) {
+ InputSection *relocSec = make<InputSection>(*this, sec, name);
// We want to add a dependency to target, similar like we do for
// -emit-relocs below. This is useful for the case when linker script
// contains the "/DISCARD/". It is perhaps uncommon to use a script with
// -r, but we faced it in the Linux kernel and have to handle such case
// and not to crash.
- Target->DependentSections.push_back(RelocSec);
- return RelocSec;
+ target->dependentSections.push_back(relocSec);
+ return relocSec;
}
- if (Target->FirstRelocation)
+ if (target->firstRelocation)
fatal(toString(this) +
": multiple relocation sections to one section are not supported");
@@ -922,33 +922,33 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// because applying relocations at end of linking changes section
// contents. So, we simply handle such sections as non-mergeable ones.
// Degrading like this is acceptable because section merging is optional.
- if (auto *MS = dyn_cast<MergeInputSection>(Target)) {
- Target = toRegularSection(MS);
- this->Sections[Sec.sh_info] = Target;
+ if (auto *ms = dyn_cast<MergeInputSection>(target)) {
+ target = toRegularSection(ms);
+ this->sections[sec.sh_info] = target;
}
- if (Sec.sh_type == SHT_RELA) {
- ArrayRef<Elf_Rela> Rels = CHECK(getObj().relas(&Sec), this);
- Target->FirstRelocation = Rels.begin();
- Target->NumRelocations = Rels.size();
- Target->AreRelocsRela = true;
+ if (sec.sh_type == SHT_RELA) {
+ ArrayRef<Elf_Rela> rels = CHECK(getObj().relas(&sec), this);
+ target->firstRelocation = rels.begin();
+ target->numRelocations = rels.size();
+ target->areRelocsRela = true;
} else {
- ArrayRef<Elf_Rel> Rels = CHECK(getObj().rels(&Sec), this);
- Target->FirstRelocation = Rels.begin();
- Target->NumRelocations = Rels.size();
- Target->AreRelocsRela = false;
+ ArrayRef<Elf_Rel> rels = CHECK(getObj().rels(&sec), this);
+ target->firstRelocation = rels.begin();
+ target->numRelocations = rels.size();
+ target->areRelocsRela = false;
}
- assert(isUInt<31>(Target->NumRelocations));
+ assert(isUInt<31>(target->numRelocations));
// Relocation sections processed by the linker are usually removed
// from the output, so returning `nullptr` for the normal case.
// However, if -emit-relocs is given, we need to leave them in the output.
// (Some post link analysis tools need this information.)
- if (Config->EmitRelocs) {
- InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
+ if (config->emitRelocs) {
+ InputSection *relocSec = make<InputSection>(*this, sec, name);
// We will not emit relocation section if target was discarded.
- Target->DependentSections.push_back(RelocSec);
- return RelocSec;
+ target->dependentSections.push_back(relocSec);
+ return relocSec;
}
return nullptr;
}
@@ -967,8 +967,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// explicitly told to do otherwise (by -z execstack). Because the stack
// executable-ness is controlled solely by command line options,
// .note.GNU-stack sections are simply ignored.
- if (Name == ".note.GNU-stack")
- return &InputSection::Discarded;
+ if (name == ".note.GNU-stack")
+ return &InputSection::discarded;
// Object files that use processor features such as Intel Control-Flow
// Enforcement (CET) or AArch64 Branch Target Identification BTI, use a
@@ -978,31 +978,31 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// Since we merge bitmaps from multiple object files to create a new
// .note.gnu.property containing a single AND'ed bitmap, we discard an input
// file's .note.gnu.property section.
- if (Name == ".note.gnu.property") {
- ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
- this->AndFeatures = readAndFeatures(this, Contents);
- return &InputSection::Discarded;
+ if (name == ".note.gnu.property") {
+ ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
+ this->andFeatures = readAndFeatures(this, contents);
+ return &InputSection::discarded;
}
// Split stacks is a feature to support a discontiguous stack,
// commonly used in the programming language Go. For the details,
// see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled
// for split stack will include a .note.GNU-split-stack section.
- if (Name == ".note.GNU-split-stack") {
- if (Config->Relocatable) {
+ if (name == ".note.GNU-split-stack") {
+ if (config->relocatable) {
error("cannot mix split-stack and non-split-stack in a relocatable link");
- return &InputSection::Discarded;
+ return &InputSection::discarded;
}
- this->SplitStack = true;
- return &InputSection::Discarded;
+ this->splitStack = true;
+ return &InputSection::discarded;
}
// An object file cmpiled for split stack, but where some of the
// functions were compiled with the no_split_stack_attribute will
// include a .note.GNU-no-split-stack section.
- if (Name == ".note.GNU-no-split-stack") {
- this->SomeNoSplitStack = true;
- return &InputSection::Discarded;
+ if (name == ".note.GNU-no-split-stack") {
+ this->someNoSplitStack = true;
+ return &InputSection::discarded;
}
// The linkonce feature is a sort of proto-comdat. Some glibc i386 object
@@ -1010,98 +1010,98 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// sections. Drop those sections to avoid duplicate symbol errors.
// FIXME: This is glibc PR20543, we should remove this hack once that has been
// fixed for a while.
- if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
- Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
- return &InputSection::Discarded;
+ if (name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
+ name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
+ return &InputSection::discarded;
// If we are creating a new .build-id section, strip existing .build-id
// sections so that the output won't have more than one .build-id.
// This is not usually a problem because input object files normally don't
// have .build-id sections, but you can create such files by
// "ld.{bfd,gold,lld} -r --build-id", and we want to guard against it.
- if (Name == ".note.gnu.build-id" && Config->BuildId != BuildIdKind::None)
- return &InputSection::Discarded;
+ if (name == ".note.gnu.build-id" && config->buildId != BuildIdKind::None)
+ return &InputSection::discarded;
// The linker merges EH (exception handling) frames and creates a
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
- if (Name == ".eh_frame" && !Config->Relocatable)
- return make<EhInputSection>(*this, Sec, Name);
+ if (name == ".eh_frame" && !config->relocatable)
+ return make<EhInputSection>(*this, sec, name);
- if (shouldMerge(Sec))
- return make<MergeInputSection>(*this, Sec, Name);
- return make<InputSection>(*this, Sec, Name);
+ if (shouldMerge(sec))
+ return make<MergeInputSection>(*this, sec, name);
+ return make<InputSection>(*this, sec, name);
}
template <class ELFT>
-StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
- return CHECK(getObj().getSectionName(&Sec, SectionStringTable), this);
+StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &sec) {
+ return CHECK(getObj().getSectionName(&sec, sectionStringTable), this);
}
// Initialize this->Symbols. this->Symbols is a parallel array as
// its corresponding ELF symbol table.
template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
- ArrayRef<Elf_Sym> ESyms = this->getELFSyms<ELFT>();
- this->Symbols.resize(ESyms.size());
+ ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
+ this->symbols.resize(eSyms.size());
// Our symbol table may have already been partially initialized
// because of LazyObjFile.
- for (size_t I = 0, End = ESyms.size(); I != End; ++I)
- if (!this->Symbols[I] && ESyms[I].getBinding() != STB_LOCAL)
- this->Symbols[I] =
- Symtab->insert(CHECK(ESyms[I].getName(this->StringTable), this));
+ for (size_t i = 0, end = eSyms.size(); i != end; ++i)
+ if (!this->symbols[i] && eSyms[i].getBinding() != STB_LOCAL)
+ this->symbols[i] =
+ symtab->insert(CHECK(eSyms[i].getName(this->stringTable), this));
// Fill this->Symbols. A symbol is either local or global.
- for (size_t I = 0, End = ESyms.size(); I != End; ++I) {
- const Elf_Sym &ESym = ESyms[I];
+ for (size_t i = 0, end = eSyms.size(); i != end; ++i) {
+ const Elf_Sym &eSym = eSyms[i];
// Read symbol attributes.
- uint32_t SecIdx = getSectionIndex(ESym);
- if (SecIdx >= this->Sections.size())
- fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));
-
- InputSectionBase *Sec = this->Sections[SecIdx];
- uint8_t Binding = ESym.getBinding();
- uint8_t StOther = ESym.st_other;
- uint8_t Type = ESym.getType();
- uint64_t Value = ESym.st_value;
- uint64_t Size = ESym.st_size;
- StringRefZ Name = this->StringTable.data() + ESym.st_name;
+ uint32_t secIdx = getSectionIndex(eSym);
+ if (secIdx >= this->sections.size())
+ fatal(toString(this) + ": invalid section index: " + Twine(secIdx));
+
+ InputSectionBase *sec = this->sections[secIdx];
+ uint8_t binding = eSym.getBinding();
+ uint8_t stOther = eSym.st_other;
+ uint8_t type = eSym.getType();
+ uint64_t value = eSym.st_value;
+ uint64_t size = eSym.st_size;
+ StringRefZ name = this->stringTable.data() + eSym.st_name;
// Handle local symbols. Local symbols are not added to the symbol
// table because they are not visible from other object files. We
// allocate symbol instances and add their pointers to Symbols.
- if (Binding == STB_LOCAL) {
- if (ESym.getType() == STT_FILE)
- SourceFile = CHECK(ESym.getName(this->StringTable), this);
+ if (binding == STB_LOCAL) {
+ if (eSym.getType() == STT_FILE)
+ sourceFile = CHECK(eSym.getName(this->stringTable), this);
- if (this->StringTable.size() <= ESym.st_name)
+ if (this->stringTable.size() <= eSym.st_name)
fatal(toString(this) + ": invalid symbol name offset");
- if (ESym.st_shndx == SHN_UNDEF)
- this->Symbols[I] = make<Undefined>(this, Name, Binding, StOther, Type);
- else if (Sec == &InputSection::Discarded)
- this->Symbols[I] = make<Undefined>(this, Name, Binding, StOther, Type,
- /*DiscardedSecIdx=*/SecIdx);
+ if (eSym.st_shndx == SHN_UNDEF)
+ this->symbols[i] = make<Undefined>(this, name, binding, stOther, type);
+ else if (sec == &InputSection::discarded)
+ this->symbols[i] = make<Undefined>(this, name, binding, stOther, type,
+ /*DiscardedSecIdx=*/secIdx);
else
- this->Symbols[I] =
- make<Defined>(this, Name, Binding, StOther, Type, Value, Size, Sec);
+ this->symbols[i] =
+ make<Defined>(this, name, binding, stOther, type, value, size, sec);
continue;
}
// Handle global undefined symbols.
- if (ESym.st_shndx == SHN_UNDEF) {
- this->Symbols[I]->resolve(Undefined{this, Name, Binding, StOther, Type});
+ if (eSym.st_shndx == SHN_UNDEF) {
+ this->symbols[i]->resolve(Undefined{this, name, binding, stOther, type});
continue;
}
// Handle global common symbols.
- if (ESym.st_shndx == SHN_COMMON) {
- if (Value == 0 || Value >= UINT32_MAX)
- fatal(toString(this) + ": common symbol '" + StringRef(Name.Data) +
- "' has invalid alignment: " + Twine(Value));
- this->Symbols[I]->resolve(
- CommonSymbol{this, Name, Binding, StOther, Type, Value, Size});
+ if (eSym.st_shndx == SHN_COMMON) {
+ if (value == 0 || value >= UINT32_MAX)
+ fatal(toString(this) + ": common symbol '" + StringRef(name.data) +
+ "' has invalid alignment: " + Twine(value));
+ this->symbols[i]->resolve(
+ CommonSymbol{this, name, binding, stOther, type, value, size});
continue;
}
@@ -1110,87 +1110,87 @@ template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
// standard, but in practice, a .eh_frame often directly refer
// COMDAT member sections, and if a comdat group is discarded, some
// defined symbol in a .eh_frame becomes dangling symbols.
- if (Sec == &InputSection::Discarded) {
- this->Symbols[I]->resolve(
- Undefined{this, Name, Binding, StOther, Type, SecIdx});
+ if (sec == &InputSection::discarded) {
+ this->symbols[i]->resolve(
+ Undefined{this, name, binding, stOther, type, secIdx});
continue;
}
// Handle global defined symbols.
- if (Binding == STB_GLOBAL || Binding == STB_WEAK ||
- Binding == STB_GNU_UNIQUE) {
- this->Symbols[I]->resolve(
- Defined{this, Name, Binding, StOther, Type, Value, Size, Sec});
+ if (binding == STB_GLOBAL || binding == STB_WEAK ||
+ binding == STB_GNU_UNIQUE) {
+ this->symbols[i]->resolve(
+ Defined{this, name, binding, stOther, type, value, size, sec});
continue;
}
- fatal(toString(this) + ": unexpected binding: " + Twine((int)Binding));
+ fatal(toString(this) + ": unexpected binding: " + Twine((int)binding));
}
}
-ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
- : InputFile(ArchiveKind, File->getMemoryBufferRef()),
- File(std::move(File)) {}
+ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&file)
+ : InputFile(ArchiveKind, file->getMemoryBufferRef()),
+ file(std::move(file)) {}
void ArchiveFile::parse() {
- for (const Archive::Symbol &Sym : File->symbols())
- Symtab->addSymbol(LazyArchive{*this, Sym});
+ for (const Archive::Symbol &sym : file->symbols())
+ symtab->addSymbol(LazyArchive{*this, sym});
}
// Returns a buffer pointing to a member file containing a given symbol.
-void ArchiveFile::fetch(const Archive::Symbol &Sym) {
- Archive::Child C =
- CHECK(Sym.getMember(), toString(this) +
+void ArchiveFile::fetch(const Archive::Symbol &sym) {
+ Archive::Child c =
+ CHECK(sym.getMember(), toString(this) +
": could not get the member for symbol " +
- Sym.getName());
+ sym.getName());
- if (!Seen.insert(C.getChildOffset()).second)
+ if (!seen.insert(c.getChildOffset()).second)
return;
- MemoryBufferRef MB =
- CHECK(C.getMemoryBufferRef(),
+ MemoryBufferRef mb =
+ CHECK(c.getMemoryBufferRef(),
toString(this) +
": could not get the buffer for the member defining symbol " +
- Sym.getName());
+ sym.getName());
- if (Tar && C.getParent()->isThin())
- Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), MB.getBuffer());
+ if (tar && c.getParent()->isThin())
+ tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());
- InputFile *File = createObjectFile(
- MB, getName(), C.getParent()->isThin() ? 0 : C.getChildOffset());
- File->GroupId = GroupId;
- parseFile(File);
+ InputFile *file = createObjectFile(
+ mb, getName(), c.getParent()->isThin() ? 0 : c.getChildOffset());
+ file->groupId = groupId;
+ parseFile(file);
}
-unsigned SharedFile::VernauxNum;
+unsigned SharedFile::vernauxNum;
// Parse the version definitions in the object file if present, and return a
// vector whose nth element contains a pointer to the Elf_Verdef for version
// identifier n. Version identifiers that are not definitions map to nullptr.
template <typename ELFT>
-static std::vector<const void *> parseVerdefs(const uint8_t *Base,
- const typename ELFT::Shdr *Sec) {
- if (!Sec)
+static std::vector<const void *> parseVerdefs(const uint8_t *base,
+ const typename ELFT::Shdr *sec) {
+ if (!sec)
return {};
// We cannot determine the largest verdef identifier without inspecting
// every Elf_Verdef, but both bfd and gold assign verdef identifiers
// sequentially starting from 1, so we predict that the largest identifier
// will be VerdefCount.
- unsigned VerdefCount = Sec->sh_info;
- std::vector<const void *> Verdefs(VerdefCount + 1);
+ unsigned verdefCount = sec->sh_info;
+ std::vector<const void *> verdefs(verdefCount + 1);
// Build the Verdefs array by following the chain of Elf_Verdef objects
// from the start of the .gnu.version_d section.
- const uint8_t *Verdef = Base + Sec->sh_offset;
- for (unsigned I = 0; I != VerdefCount; ++I) {
- auto *CurVerdef = reinterpret_cast<const typename ELFT::Verdef *>(Verdef);
- Verdef += CurVerdef->vd_next;
- unsigned VerdefIndex = CurVerdef->vd_ndx;
- Verdefs.resize(VerdefIndex + 1);
- Verdefs[VerdefIndex] = CurVerdef;
+ const uint8_t *verdef = base + sec->sh_offset;
+ for (unsigned i = 0; i != verdefCount; ++i) {
+ auto *curVerdef = reinterpret_cast<const typename ELFT::Verdef *>(verdef);
+ verdef += curVerdef->vd_next;
+ unsigned verdefIndex = curVerdef->vd_ndx;
+ verdefs.resize(verdefIndex + 1);
+ verdefs[verdefIndex] = curVerdef;
}
- return Verdefs;
+ return verdefs;
}
// We do not usually care about alignments of data in shared object
@@ -1198,14 +1198,14 @@ static std::vector<const void *> parseVerdefs(const uint8_t *Base,
// DSO symbol to point to .bss due to copy relocation, we need to keep
// the original alignment requirements. We infer it in this function.
template <typename ELFT>
-static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> Sections,
- const typename ELFT::Sym &Sym) {
- uint64_t Ret = UINT64_MAX;
- if (Sym.st_value)
- Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
- if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
- Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
- return (Ret > UINT32_MAX) ? 0 : Ret;
+static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> sections,
+ const typename ELFT::Sym &sym) {
+ uint64_t ret = UINT64_MAX;
+ if (sym.st_value)
+ ret = 1ULL << countTrailingZeros((uint64_t)sym.st_value);
+ if (0 < sym.st_shndx && sym.st_shndx < sections.size())
+ ret = std::min<uint64_t>(ret, sections[sym.st_shndx].sh_addralign);
+ return (ret > UINT32_MAX) ? 0 : ret;
}
// Fully parse the shared object file.
@@ -1230,156 +1230,156 @@ template <class ELFT> void SharedFile::parse() {
using Elf_Verdef = typename ELFT::Verdef;
using Elf_Versym = typename ELFT::Versym;
- ArrayRef<Elf_Dyn> DynamicTags;
- const ELFFile<ELFT> Obj = this->getObj<ELFT>();
- ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
+ ArrayRef<Elf_Dyn> dynamicTags;
+ const ELFFile<ELFT> obj = this->getObj<ELFT>();
+ ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
- const Elf_Shdr *VersymSec = nullptr;
- const Elf_Shdr *VerdefSec = nullptr;
+ const Elf_Shdr *versymSec = nullptr;
+ const Elf_Shdr *verdefSec = nullptr;
// Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
- for (const Elf_Shdr &Sec : Sections) {
- switch (Sec.sh_type) {
+ for (const Elf_Shdr &sec : sections) {
+ switch (sec.sh_type) {
default:
continue;
case SHT_DYNAMIC:
- DynamicTags =
- CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(&Sec), this);
+ dynamicTags =
+ CHECK(obj.template getSectionContentsAsArray<Elf_Dyn>(&sec), this);
break;
case SHT_GNU_versym:
- VersymSec = &Sec;
+ versymSec = &sec;
break;
case SHT_GNU_verdef:
- VerdefSec = &Sec;
+ verdefSec = &sec;
break;
}
}
- if (VersymSec && NumELFSyms == 0) {
+ if (versymSec && numELFSyms == 0) {
error("SHT_GNU_versym should be associated with symbol table");
return;
}
// Search for a DT_SONAME tag to initialize this->SoName.
- for (const Elf_Dyn &Dyn : DynamicTags) {
- if (Dyn.d_tag == DT_NEEDED) {
- uint64_t Val = Dyn.getVal();
- if (Val >= this->StringTable.size())
+ for (const Elf_Dyn &dyn : dynamicTags) {
+ if (dyn.d_tag == DT_NEEDED) {
+ uint64_t val = dyn.getVal();
+ if (val >= this->stringTable.size())
fatal(toString(this) + ": invalid DT_NEEDED entry");
- DtNeeded.push_back(this->StringTable.data() + Val);
- } else if (Dyn.d_tag == DT_SONAME) {
- uint64_t Val = Dyn.getVal();
- if (Val >= this->StringTable.size())
+ dtNeeded.push_back(this->stringTable.data() + val);
+ } else if (dyn.d_tag == DT_SONAME) {
+ uint64_t val = dyn.getVal();
+ if (val >= this->stringTable.size())
fatal(toString(this) + ": invalid DT_SONAME entry");
- SoName = this->StringTable.data() + Val;
+ soName = this->stringTable.data() + val;
}
}
// DSOs are uniquified not by filename but by soname.
- DenseMap<StringRef, SharedFile *>::iterator It;
- bool WasInserted;
- std::tie(It, WasInserted) = Symtab->SoNames.try_emplace(SoName, this);
+ DenseMap<StringRef, SharedFile *>::iterator it;
+ bool wasInserted;
+ std::tie(it, wasInserted) = symtab->soNames.try_emplace(soName, this);
// If a DSO appears more than once on the command line with and without
// --as-needed, --no-as-needed takes precedence over --as-needed because a
// user can add an extra DSO with --no-as-needed to force it to be added to
// the dependency list.
- It->second->IsNeeded |= IsNeeded;
- if (!WasInserted)
+ it->second->isNeeded |= isNeeded;
+ if (!wasInserted)
return;
- SharedFiles.push_back(this);
+ sharedFiles.push_back(this);
- Verdefs = parseVerdefs<ELFT>(Obj.base(), VerdefSec);
+ verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec);
// Parse ".gnu.version" section which is a parallel array for the symbol
// table. If a given file doesn't have a ".gnu.version" section, we use
// VER_NDX_GLOBAL.
- size_t Size = NumELFSyms - FirstGlobal;
- std::vector<uint32_t> Versyms(Size, VER_NDX_GLOBAL);
- if (VersymSec) {
- ArrayRef<Elf_Versym> Versym =
- CHECK(Obj.template getSectionContentsAsArray<Elf_Versym>(VersymSec),
+ size_t size = numELFSyms - firstGlobal;
+ std::vector<uint32_t> versyms(size, VER_NDX_GLOBAL);
+ if (versymSec) {
+ ArrayRef<Elf_Versym> versym =
+ CHECK(obj.template getSectionContentsAsArray<Elf_Versym>(versymSec),
this)
- .slice(FirstGlobal);
- for (size_t I = 0; I < Size; ++I)
- Versyms[I] = Versym[I].vs_index;
+ .slice(firstGlobal);
+ for (size_t i = 0; i < size; ++i)
+ versyms[i] = versym[i].vs_index;
}
// System libraries can have a lot of symbols with versions. Using a
// fixed buffer for computing the versions name (foo@ver) can save a
// lot of allocations.
- SmallString<0> VersionedNameBuffer;
+ SmallString<0> versionedNameBuffer;
// Add symbols to the symbol table.
- ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms<ELFT>();
- for (size_t I = 0; I < Syms.size(); ++I) {
- const Elf_Sym &Sym = Syms[I];
+ ArrayRef<Elf_Sym> syms = this->getGlobalELFSyms<ELFT>();
+ for (size_t i = 0; i < syms.size(); ++i) {
+ const Elf_Sym &sym = syms[i];
// ELF spec requires that all local symbols precede weak or global
// symbols in each symbol table, and the index of first non-local symbol
// is stored to sh_info. If a local symbol appears after some non-local
// symbol, that's a violation of the spec.
- StringRef Name = CHECK(Sym.getName(this->StringTable), this);
- if (Sym.getBinding() == STB_LOCAL) {
- warn("found local symbol '" + Name +
+ StringRef name = CHECK(sym.getName(this->stringTable), this);
+ if (sym.getBinding() == STB_LOCAL) {
+ warn("found local symbol '" + name +
"' in global part of symbol table in file " + toString(this));
continue;
}
- if (Sym.isUndefined()) {
- Symbol *S = Symtab->addSymbol(
- Undefined{this, Name, Sym.getBinding(), Sym.st_other, Sym.getType()});
- S->ExportDynamic = true;
+ if (sym.isUndefined()) {
+ Symbol *s = symtab->addSymbol(
+ Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});
+ s->exportDynamic = true;
continue;
}
// MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly
// assigns VER_NDX_LOCAL to this section global symbol. Here is a
// workaround for this bug.
- uint32_t Idx = Versyms[I] & ~VERSYM_HIDDEN;
- if (Config->EMachine == EM_MIPS && Idx == VER_NDX_LOCAL &&
- Name == "_gp_disp")
+ uint32_t idx = versyms[i] & ~VERSYM_HIDDEN;
+ if (config->emachine == EM_MIPS && idx == VER_NDX_LOCAL &&
+ name == "_gp_disp")
continue;
- uint32_t Alignment = getAlignment<ELFT>(Sections, Sym);
- if (!(Versyms[I] & VERSYM_HIDDEN)) {
- Symtab->addSymbol(SharedSymbol{*this, Name, Sym.getBinding(),
- Sym.st_other, Sym.getType(), Sym.st_value,
- Sym.st_size, Alignment, Idx});
+ uint32_t alignment = getAlignment<ELFT>(sections, sym);
+ if (!(versyms[i] & VERSYM_HIDDEN)) {
+ symtab->addSymbol(SharedSymbol{*this, name, sym.getBinding(),
+ sym.st_other, sym.getType(), sym.st_value,
+ sym.st_size, alignment, idx});
}
// Also add the symbol with the versioned name to handle undefined symbols
// with explicit versions.
- if (Idx == VER_NDX_GLOBAL)
+ if (idx == VER_NDX_GLOBAL)
continue;
- if (Idx >= Verdefs.size() || Idx == VER_NDX_LOCAL) {
- error("corrupt input file: version definition index " + Twine(Idx) +
- " for symbol " + Name + " is out of bounds\n>>> defined in " +
+ if (idx >= verdefs.size() || idx == VER_NDX_LOCAL) {
+ error("corrupt input file: version definition index " + Twine(idx) +
+ " for symbol " + name + " is out of bounds\n>>> defined in " +
toString(this));
continue;
}
- StringRef VerName =
- this->StringTable.data() +
- reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
- VersionedNameBuffer.clear();
- Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
- Symtab->addSymbol(SharedSymbol{*this, Saver.save(Name), Sym.getBinding(),
- Sym.st_other, Sym.getType(), Sym.st_value,
- Sym.st_size, Alignment, Idx});
+ StringRef verName =
+ this->stringTable.data() +
+ reinterpret_cast<const Elf_Verdef *>(verdefs[idx])->getAux()->vda_name;
+ versionedNameBuffer.clear();
+ name = (name + "@" + verName).toStringRef(versionedNameBuffer);
+ symtab->addSymbol(SharedSymbol{*this, Saver.save(name), sym.getBinding(),
+ sym.st_other, sym.getType(), sym.st_value,
+ sym.st_size, alignment, idx});
}
}
-static ELFKind getBitcodeELFKind(const Triple &T) {
- if (T.isLittleEndian())
- return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
- return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
+static ELFKind getBitcodeELFKind(const Triple &t) {
+ if (t.isLittleEndian())
+ return t.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
+ return t.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
}
-static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
- switch (T.getArch()) {
+static uint8_t getBitcodeMachineKind(StringRef path, const Triple &t) {
+ switch (t.getArch()) {
case Triple::aarch64:
return EM_AARCH64;
case Triple::amdgcn:
@@ -1406,24 +1406,24 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
case Triple::riscv64:
return EM_RISCV;
case Triple::x86:
- return T.isOSIAMCU() ? EM_IAMCU : EM_386;
+ return t.isOSIAMCU() ? EM_IAMCU : EM_386;
case Triple::x86_64:
return EM_X86_64;
default:
- error(Path + ": could not infer e_machine from bitcode target triple " +
- T.str());
+ error(path + ": could not infer e_machine from bitcode target triple " +
+ t.str());
return EM_NONE;
}
}
-BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
- uint64_t OffsetInArchive)
- : InputFile(BitcodeKind, MB) {
- this->ArchiveName = ArchiveName;
+BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
+ uint64_t offsetInArchive)
+ : InputFile(BitcodeKind, mb) {
+ this->archiveName = archiveName;
- std::string Path = MB.getBufferIdentifier().str();
- if (Config->ThinLTOIndexOnly)
- Path = replaceThinLTOSuffix(MB.getBufferIdentifier());
+ std::string path = mb.getBufferIdentifier().str();
+ if (config->thinLTOIndexOnly)
+ path = replaceThinLTOSuffix(mb.getBufferIdentifier());
// ThinLTO assumes that all MemoryBufferRefs given to it have a unique
// name. If two archives define two members with the same name, this
@@ -1431,21 +1431,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
// into consideration at LTO time (which very likely causes undefined
// symbols later in the link stage). So we append file offset to make
// filename unique.
- StringRef Name = ArchiveName.empty()
- ? Saver.save(Path)
- : Saver.save(ArchiveName + "(" + Path + " at " +
- utostr(OffsetInArchive) + ")");
- MemoryBufferRef MBRef(MB.getBuffer(), Name);
+ StringRef name = archiveName.empty()
+ ? Saver.save(path)
+ : Saver.save(archiveName + "(" + path + " at " +
+ utostr(offsetInArchive) + ")");
+ MemoryBufferRef mbref(mb.getBuffer(), name);
- Obj = CHECK(lto::InputFile::create(MBRef), this);
+ obj = CHECK(lto::InputFile::create(mbref), this);
- Triple T(Obj->getTargetTriple());
- EKind = getBitcodeELFKind(T);
- EMachine = getBitcodeMachineKind(MB.getBufferIdentifier(), T);
+ Triple t(obj->getTargetTriple());
+ ekind = getBitcodeELFKind(t);
+ emachine = getBitcodeMachineKind(mb.getBufferIdentifier(), t);
}
-static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
- switch (GvVisibility) {
+static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
+ switch (gvVisibility) {
case GlobalValue::DefaultVisibility:
return STV_DEFAULT;
case GlobalValue::HiddenVisibility:
@@ -1457,169 +1457,169 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
}
template <class ELFT>
-static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
- const lto::InputFile::Symbol &ObjSym,
- BitcodeFile &F) {
- StringRef Name = Saver.save(ObjSym.getName());
- uint8_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
- uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
- uint8_t Visibility = mapVisibility(ObjSym.getVisibility());
- bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable();
-
- int C = ObjSym.getComdatIndex();
- if (ObjSym.isUndefined() || (C != -1 && !KeptComdats[C])) {
- Undefined New(&F, Name, Binding, Visibility, Type);
- if (CanOmitFromDynSym)
- New.ExportDynamic = false;
- return Symtab->addSymbol(New);
+static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
+ const lto::InputFile::Symbol &objSym,
+ BitcodeFile &f) {
+ StringRef name = Saver.save(objSym.getName());
+ uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
+ uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;
+ uint8_t visibility = mapVisibility(objSym.getVisibility());
+ bool canOmitFromDynSym = objSym.canBeOmittedFromSymbolTable();
+
+ int c = objSym.getComdatIndex();
+ if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
+ Undefined New(&f, name, binding, visibility, type);
+ if (canOmitFromDynSym)
+ New.exportDynamic = false;
+ return symtab->addSymbol(New);
}
- if (ObjSym.isCommon())
- return Symtab->addSymbol(
- CommonSymbol{&F, Name, Binding, Visibility, STT_OBJECT,
- ObjSym.getCommonAlignment(), ObjSym.getCommonSize()});
+ if (objSym.isCommon())
+ return symtab->addSymbol(
+ CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
+ objSym.getCommonAlignment(), objSym.getCommonSize()});
- Defined New(&F, Name, Binding, Visibility, Type, 0, 0, nullptr);
- if (CanOmitFromDynSym)
- New.ExportDynamic = false;
- return Symtab->addSymbol(New);
+ Defined New(&f, name, binding, visibility, type, 0, 0, nullptr);
+ if (canOmitFromDynSym)
+ New.exportDynamic = false;
+ return symtab->addSymbol(New);
}
template <class ELFT> void BitcodeFile::parse() {
- std::vector<bool> KeptComdats;
- for (StringRef S : Obj->getComdatTable())
- KeptComdats.push_back(
- Symtab->ComdatGroups.try_emplace(CachedHashStringRef(S), this).second);
+ std::vector<bool> keptComdats;
+ for (StringRef s : obj->getComdatTable())
+ keptComdats.push_back(
+ symtab->comdatGroups.try_emplace(CachedHashStringRef(s), this).second);
- for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
- Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
+ for (const lto::InputFile::Symbol &objSym : obj->symbols())
+ symbols.push_back(createBitcodeSymbol<ELFT>(keptComdats, objSym, *this));
- for (auto L : Obj->getDependentLibraries())
- addDependentLibrary(L, this);
+ for (auto l : obj->getDependentLibraries())
+ addDependentLibrary(l, this);
}
void BinaryFile::parse() {
- ArrayRef<uint8_t> Data = arrayRefFromStringRef(MB.getBuffer());
- auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
- 8, Data, ".data");
- Sections.push_back(Section);
+ ArrayRef<uint8_t> data = arrayRefFromStringRef(mb.getBuffer());
+ auto *section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
+ 8, data, ".data");
+ sections.push_back(section);
// For each input file foo that is embedded to a result as a binary
// blob, we define _binary_foo_{start,end,size} symbols, so that
// user programs can access blobs by name. Non-alphanumeric
// characters in a filename are replaced with underscore.
- std::string S = "_binary_" + MB.getBufferIdentifier().str();
- for (size_t I = 0; I < S.size(); ++I)
- if (!isAlnum(S[I]))
- S[I] = '_';
-
- Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_start"), STB_GLOBAL,
- STV_DEFAULT, STT_OBJECT, 0, 0, Section});
- Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_end"), STB_GLOBAL,
- STV_DEFAULT, STT_OBJECT, Data.size(), 0, Section});
- Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_size"), STB_GLOBAL,
- STV_DEFAULT, STT_OBJECT, Data.size(), 0, nullptr});
+ std::string s = "_binary_" + mb.getBufferIdentifier().str();
+ for (size_t i = 0; i < s.size(); ++i)
+ if (!isAlnum(s[i]))
+ s[i] = '_';
+
+ symtab->addSymbol(Defined{nullptr, Saver.save(s + "_start"), STB_GLOBAL,
+ STV_DEFAULT, STT_OBJECT, 0, 0, section});
+ symtab->addSymbol(Defined{nullptr, Saver.save(s + "_end"), STB_GLOBAL,
+ STV_DEFAULT, STT_OBJECT, data.size(), 0, section});
+ symtab->addSymbol(Defined{nullptr, Saver.save(s + "_size"), STB_GLOBAL,
+ STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr});
}
-InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
- uint64_t OffsetInArchive) {
- if (isBitcode(MB))
- return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
+InputFile *elf::createObjectFile(MemoryBufferRef mb, StringRef archiveName,
+ uint64_t offsetInArchive) {
+ if (isBitcode(mb))
+ return make<BitcodeFile>(mb, archiveName, offsetInArchive);
- switch (getELFKind(MB, ArchiveName)) {
+ switch (getELFKind(mb, archiveName)) {
case ELF32LEKind:
- return make<ObjFile<ELF32LE>>(MB, ArchiveName);
+ return make<ObjFile<ELF32LE>>(mb, archiveName);
case ELF32BEKind:
- return make<ObjFile<ELF32BE>>(MB, ArchiveName);
+ return make<ObjFile<ELF32BE>>(mb, archiveName);
case ELF64LEKind:
- return make<ObjFile<ELF64LE>>(MB, ArchiveName);
+ return make<ObjFile<ELF64LE>>(mb, archiveName);
case ELF64BEKind:
- return make<ObjFile<ELF64BE>>(MB, ArchiveName);
+ return make<ObjFile<ELF64BE>>(mb, archiveName);
default:
llvm_unreachable("getELFKind");
}
}
void LazyObjFile::fetch() {
- if (MB.getBuffer().empty())
+ if (mb.getBuffer().empty())
return;
- InputFile *File = createObjectFile(MB, ArchiveName, OffsetInArchive);
- File->GroupId = GroupId;
+ InputFile *file = createObjectFile(mb, archiveName, offsetInArchive);
+ file->groupId = groupId;
- MB = {};
+ mb = {};
// Copy symbol vector so that the new InputFile doesn't have to
// insert the same defined symbols to the symbol table again.
- File->Symbols = std::move(Symbols);
+ file->symbols = std::move(symbols);
- parseFile(File);
+ parseFile(file);
}
template <class ELFT> void LazyObjFile::parse() {
using Elf_Sym = typename ELFT::Sym;
// A lazy object file wraps either a bitcode file or an ELF file.
- if (isBitcode(this->MB)) {
- std::unique_ptr<lto::InputFile> Obj =
- CHECK(lto::InputFile::create(this->MB), this);
- for (const lto::InputFile::Symbol &Sym : Obj->symbols()) {
- if (Sym.isUndefined())
+ if (isBitcode(this->mb)) {
+ std::unique_ptr<lto::InputFile> obj =
+ CHECK(lto::InputFile::create(this->mb), this);
+ for (const lto::InputFile::Symbol &sym : obj->symbols()) {
+ if (sym.isUndefined())
continue;
- Symtab->addSymbol(LazyObject{*this, Saver.save(Sym.getName())});
+ symtab->addSymbol(LazyObject{*this, Saver.save(sym.getName())});
}
return;
}
- if (getELFKind(this->MB, ArchiveName) != Config->EKind) {
- error("incompatible file: " + this->MB.getBufferIdentifier());
+ if (getELFKind(this->mb, archiveName) != config->ekind) {
+ error("incompatible file: " + this->mb.getBufferIdentifier());
return;
}
// Find a symbol table.
- ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
- ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);
+ ELFFile<ELFT> obj = check(ELFFile<ELFT>::create(mb.getBuffer()));
+ ArrayRef<typename ELFT::Shdr> sections = CHECK(obj.sections(), this);
- for (const typename ELFT::Shdr &Sec : Sections) {
- if (Sec.sh_type != SHT_SYMTAB)
+ for (const typename ELFT::Shdr &sec : sections) {
+ if (sec.sh_type != SHT_SYMTAB)
continue;
// A symbol table is found.
- ArrayRef<Elf_Sym> ESyms = CHECK(Obj.symbols(&Sec), this);
- uint32_t FirstGlobal = Sec.sh_info;
- StringRef Strtab = CHECK(Obj.getStringTableForSymtab(Sec, Sections), this);
- this->Symbols.resize(ESyms.size());
+ ArrayRef<Elf_Sym> eSyms = CHECK(obj.symbols(&sec), this);
+ uint32_t firstGlobal = sec.sh_info;
+ StringRef strtab = CHECK(obj.getStringTableForSymtab(sec, sections), this);
+ this->symbols.resize(eSyms.size());
// Get existing symbols or insert placeholder symbols.
- for (size_t I = FirstGlobal, End = ESyms.size(); I != End; ++I)
- if (ESyms[I].st_shndx != SHN_UNDEF)
- this->Symbols[I] = Symtab->insert(CHECK(ESyms[I].getName(Strtab), this));
+ for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
+ if (eSyms[i].st_shndx != SHN_UNDEF)
+ this->symbols[i] = symtab->insert(CHECK(eSyms[i].getName(strtab), this));
// Replace existing symbols with LazyObject symbols.
//
// resolve() may trigger this->fetch() if an existing symbol is an
// undefined symbol. If that happens, this LazyObjFile has served
// its purpose, and we can exit from the loop early.
- for (Symbol *Sym : this->Symbols) {
- if (!Sym)
+ for (Symbol *sym : this->symbols) {
+ if (!sym)
continue;
- Sym->resolve(LazyObject{*this, Sym->getName()});
+ sym->resolve(LazyObject{*this, sym->getName()});
// MemoryBuffer is emptied if this file is instantiated as ObjFile.
- if (MB.getBuffer().empty())
+ if (mb.getBuffer().empty())
return;
}
return;
}
}
-std::string elf::replaceThinLTOSuffix(StringRef Path) {
- StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
- StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
+std::string elf::replaceThinLTOSuffix(StringRef path) {
+ StringRef suffix = config->thinLTOObjectSuffixReplace.first;
+ StringRef repl = config->thinLTOObjectSuffixReplace.second;
- if (Path.consume_back(Suffix))
- return (Path + Repl).str();
- return Path;
+ if (path.consume_back(suffix))
+ return (path + repl).str();
+ return path;
}
template void BitcodeFile::parse<ELF32LE>();
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 588d59ab235..760f72fd198 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -39,7 +39,7 @@ class InputSectionBase;
}
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
-std::string toString(const elf::InputFile *F);
+std::string toString(const elf::InputFile *f);
namespace elf {
@@ -49,13 +49,13 @@ class Symbol;
// If -reproduce option is given, all input files are written
// to this tar archive.
-extern std::unique_ptr<llvm::TarWriter> Tar;
+extern std::unique_ptr<llvm::TarWriter> tar;
// Opens a given file.
-llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
+llvm::Optional<MemoryBufferRef> readFile(StringRef path);
// Add symbols in File to the symbol table.
-void parseFile(InputFile *File);
+void parseFile(InputFile *file);
// The root class of input files.
class InputFile {
@@ -69,21 +69,21 @@ public:
BinaryKind,
};
- Kind kind() const { return FileKind; }
+ Kind kind() const { return fileKind; }
bool isElf() const {
- Kind K = kind();
- return K == ObjKind || K == SharedKind;
+ Kind k = kind();
+ return k == ObjKind || k == SharedKind;
}
- StringRef getName() const { return MB.getBufferIdentifier(); }
- MemoryBufferRef MB;
+ StringRef getName() const { return mb.getBufferIdentifier(); }
+ MemoryBufferRef mb;
// Returns sections. It is a runtime error to call this function
// on files that don't have the notion of sections.
ArrayRef<InputSectionBase *> getSections() const {
- assert(FileKind == ObjKind || FileKind == BinaryKind);
- return Sections;
+ assert(fileKind == ObjKind || fileKind == BinaryKind);
+ return sections;
}
// Returns object file symbols. It is a runtime error to call this
@@ -91,35 +91,35 @@ public:
ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
MutableArrayRef<Symbol *> getMutableSymbols() {
- assert(FileKind == BinaryKind || FileKind == ObjKind ||
- FileKind == BitcodeKind);
- return Symbols;
+ assert(fileKind == BinaryKind || fileKind == ObjKind ||
+ fileKind == BitcodeKind);
+ return symbols;
}
// Filename of .a which contained this file. If this file was
// not in an archive file, it is the empty string. We use this
// string for creating error messages.
- std::string ArchiveName;
+ std::string archiveName;
// If this is an architecture-specific file, the following members
// have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
- ELFKind EKind = ELFNoneKind;
- uint16_t EMachine = llvm::ELF::EM_NONE;
- uint8_t OSABI = 0;
- uint8_t ABIVersion = 0;
+ ELFKind ekind = ELFNoneKind;
+ uint16_t emachine = llvm::ELF::EM_NONE;
+ uint8_t osabi = 0;
+ uint8_t abiVersion = 0;
// Cache for toString(). Only toString() should use this member.
- mutable std::string ToStringCache;
+ mutable std::string toStringCache;
- std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
- uint64_t Offset);
+ std::string getSrcMsg(const Symbol &sym, InputSectionBase &sec,
+ uint64_t offset);
// True if this is an argument for --just-symbols. Usually false.
- bool JustSymbols = false;
+ bool justSymbols = false;
// OutSecOff of .got2 in the current file. This is used by PPC32 -fPIC/-fPIE
// to compute offsets in PLT call stubs.
- uint32_t PPC32Got2OutSecOff = 0;
+ uint32_t ppc32Got2OutSecOff = 0;
// On PPC64 we need to keep track of which files contain small code model
// relocations that access the .toc section. To minimize the chance of a
@@ -130,56 +130,56 @@ public:
// code model relocations support immediates in the range [-0x8000, 0x7FFC],
// making the addressable range relative to the toc pointer
// [.got, .got + 0xFFFC].
- bool PPC64SmallCodeModelTocRelocs = false;
+ bool ppc64SmallCodeModelTocRelocs = false;
// GroupId is used for --warn-backrefs which is an optional error
// checking feature. All files within the same --{start,end}-group or
// --{start,end}-lib get the same group ID. Otherwise, each file gets a new
// group ID. For more info, see checkDependency() in SymbolTable.cpp.
- uint32_t GroupId;
- static bool IsInGroup;
- static uint32_t NextGroupId;
+ uint32_t groupId;
+ static bool isInGroup;
+ static uint32_t nextGroupId;
// Index of MIPS GOT built for this file.
- llvm::Optional<size_t> MipsGotIndex;
+ llvm::Optional<size_t> mipsGotIndex;
- std::vector<Symbol *> Symbols;
+ std::vector<Symbol *> symbols;
protected:
- InputFile(Kind K, MemoryBufferRef M);
- std::vector<InputSectionBase *> Sections;
+ InputFile(Kind k, MemoryBufferRef m);
+ std::vector<InputSectionBase *> sections;
private:
- const Kind FileKind;
+ const Kind fileKind;
};
class ELFFileBase : public InputFile {
public:
- ELFFileBase(Kind K, MemoryBufferRef M);
- static bool classof(const InputFile *F) { return F->isElf(); }
+ ELFFileBase(Kind k, MemoryBufferRef m);
+ static bool classof(const InputFile *f) { return f->isElf(); }
template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
- return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
+ return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer()));
}
- StringRef getStringTable() const { return StringTable; }
+ StringRef getStringTable() const { return stringTable; }
template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
return typename ELFT::SymRange(
- reinterpret_cast<const typename ELFT::Sym *>(ELFSyms), NumELFSyms);
+ reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
}
template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
- return getELFSyms<ELFT>().slice(FirstGlobal);
+ return getELFSyms<ELFT>().slice(firstGlobal);
}
protected:
// Initializes this class's member variables.
template <typename ELFT> void init();
- const void *ELFSyms = nullptr;
- size_t NumELFSyms = 0;
- uint32_t FirstGlobal = 0;
- StringRef StringTable;
+ const void *elfSyms = nullptr;
+ size_t numELFSyms = 0;
+ uint32_t firstGlobal = 0;
+ StringRef stringTable;
};
// .o file.
@@ -192,7 +192,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
using Elf_CGProfile = typename ELFT::CGProfile;
public:
- static bool classof(const InputFile *F) { return F->kind() == ObjKind; }
+ static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
llvm::object::ELFFile<ELFT> getObj() const {
return this->ELFFileBase::getObj<ELFT>();
@@ -201,67 +201,67 @@ public:
ArrayRef<Symbol *> getLocalSymbols();
ArrayRef<Symbol *> getGlobalSymbols();
- ObjFile(MemoryBufferRef M, StringRef ArchiveName) : ELFFileBase(ObjKind, M) {
- this->ArchiveName = ArchiveName;
+ ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) {
+ this->archiveName = archiveName;
}
- void parse(bool IgnoreComdats = false);
+ void parse(bool ignoreComdats = false);
- StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
- const Elf_Shdr &Sec);
+ StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
+ const Elf_Shdr &sec);
- Symbol &getSymbol(uint32_t SymbolIndex) const {
- if (SymbolIndex >= this->Symbols.size())
+ Symbol &getSymbol(uint32_t symbolIndex) const {
+ if (symbolIndex >= this->symbols.size())
fatal(toString(this) + ": invalid symbol index");
- return *this->Symbols[SymbolIndex];
+ return *this->symbols[symbolIndex];
}
- uint32_t getSectionIndex(const Elf_Sym &Sym) const;
+ uint32_t getSectionIndex(const Elf_Sym &sym) const;
- template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
- uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
- return getSymbol(SymIndex);
+ template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
+ uint32_t symIndex = rel.getSymbol(config->isMips64EL);
+ return getSymbol(symIndex);
}
llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
- llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name);
+ llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef name);
// MIPS GP0 value defined by this file. This value represents the gp value
// used to create the relocatable object and required to support
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
- uint32_t MipsGp0 = 0;
+ uint32_t mipsGp0 = 0;
- uint32_t AndFeatures = 0;
+ uint32_t andFeatures = 0;
// Name of source file obtained from STT_FILE symbol value,
// or empty string if there is no such symbol in object file
// symbol table.
- StringRef SourceFile;
+ StringRef sourceFile;
// True if the file defines functions compiled with
// -fsplit-stack. Usually false.
- bool SplitStack = false;
+ bool splitStack = false;
// True if the file defines functions compiled with -fsplit-stack,
// but had one or more functions with the no_split_stack attribute.
- bool SomeNoSplitStack = false;
+ bool someNoSplitStack = false;
// Pointer to this input file's .llvm_addrsig section, if it has one.
- const Elf_Shdr *AddrsigSec = nullptr;
+ const Elf_Shdr *addrsigSec = nullptr;
// SHT_LLVM_CALL_GRAPH_PROFILE table
- ArrayRef<Elf_CGProfile> CGProfile;
+ ArrayRef<Elf_CGProfile> cgProfile;
private:
- void initializeSections(bool IgnoreComdats);
+ void initializeSections(bool ignoreComdats);
void initializeSymbols();
void initializeJustSymbols();
void initializeDwarf();
- InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
- InputSectionBase *createInputSection(const Elf_Shdr &Sec);
- StringRef getSectionName(const Elf_Shdr &Sec);
+ InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
+ InputSectionBase *createInputSection(const Elf_Shdr &sec);
+ StringRef getSectionName(const Elf_Shdr &sec);
- bool shouldMerge(const Elf_Shdr &Sec);
+ bool shouldMerge(const Elf_Shdr &sec);
// Each ELF symbol contains a section index which the symbol belongs to.
// However, because the number of bits dedicated for that is limited, a
@@ -275,24 +275,24 @@ private:
//
// The following variable contains the contents of .symtab_shndx.
// If the section does not exist (which is common), the array is empty.
- ArrayRef<Elf_Word> ShndxTable;
+ ArrayRef<Elf_Word> shndxTable;
// .shstrtab contents.
- StringRef SectionStringTable;
+ StringRef sectionStringTable;
// Debugging information to retrieve source file and line for error
// reporting. Linker may find reasonable number of errors in a
// single object file, so we cache debugging information in order to
// parse it only once for each object file we link.
- std::unique_ptr<llvm::DWARFContext> Dwarf;
- std::vector<const llvm::DWARFDebugLine::LineTable *> LineTables;
+ std::unique_ptr<llvm::DWARFContext> dwarf;
+ std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;
struct VarLoc {
- const llvm::DWARFDebugLine::LineTable *LT;
- unsigned File;
- unsigned Line;
+ const llvm::DWARFDebugLine::LineTable *lt;
+ unsigned file;
+ unsigned line;
};
- llvm::DenseMap<StringRef, VarLoc> VariableLoc;
- llvm::once_flag InitDwarfLine;
+ llvm::DenseMap<StringRef, VarLoc> variableLoc;
+ llvm::once_flag initDwarfLine;
};
// LazyObjFile is analogous to ArchiveFile in the sense that
@@ -304,100 +304,100 @@ private:
// archive file semantics.
class LazyObjFile : public InputFile {
public:
- LazyObjFile(MemoryBufferRef M, StringRef ArchiveName,
- uint64_t OffsetInArchive)
- : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) {
- this->ArchiveName = ArchiveName;
+ LazyObjFile(MemoryBufferRef m, StringRef archiveName,
+ uint64_t offsetInArchive)
+ : InputFile(LazyObjKind, m), offsetInArchive(offsetInArchive) {
+ this->archiveName = archiveName;
}
- static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; }
+ static bool classof(const InputFile *f) { return f->kind() == LazyObjKind; }
template <class ELFT> void parse();
void fetch();
private:
- uint64_t OffsetInArchive;
+ uint64_t offsetInArchive;
};
// An ArchiveFile object represents a .a file.
class ArchiveFile : public InputFile {
public:
- explicit ArchiveFile(std::unique_ptr<Archive> &&File);
- static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
+ explicit ArchiveFile(std::unique_ptr<Archive> &&file);
+ static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
void parse();
// Pulls out an object file that contains a definition for Sym and
// returns it. If the same file was instantiated before, this
// function does nothing (so we don't instantiate the same file
// more than once.)
- void fetch(const Archive::Symbol &Sym);
+ void fetch(const Archive::Symbol &sym);
private:
- std::unique_ptr<Archive> File;
- llvm::DenseSet<uint64_t> Seen;
+ std::unique_ptr<Archive> file;
+ llvm::DenseSet<uint64_t> seen;
};
class BitcodeFile : public InputFile {
public:
- BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
- uint64_t OffsetInArchive);
- static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
+ BitcodeFile(MemoryBufferRef m, StringRef archiveName,
+ uint64_t offsetInArchive);
+ static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
template <class ELFT> void parse();
- std::unique_ptr<llvm::lto::InputFile> Obj;
+ std::unique_ptr<llvm::lto::InputFile> obj;
};
// .so file.
class SharedFile : public ELFFileBase {
public:
- SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
- : ELFFileBase(SharedKind, M), SoName(DefaultSoName),
- IsNeeded(!Config->AsNeeded) {}
+ SharedFile(MemoryBufferRef m, StringRef defaultSoName)
+ : ELFFileBase(SharedKind, m), soName(defaultSoName),
+ isNeeded(!config->asNeeded) {}
// This is actually a vector of Elf_Verdef pointers.
- std::vector<const void *> Verdefs;
+ std::vector<const void *> verdefs;
// If the output file needs Elf_Verneed data structures for this file, this is
// a vector of Elf_Vernaux version identifiers that map onto the entries in
// Verdefs, otherwise it is empty.
- std::vector<unsigned> Vernauxs;
+ std::vector<unsigned> vernauxs;
- static unsigned VernauxNum;
+ static unsigned vernauxNum;
- std::vector<StringRef> DtNeeded;
- std::string SoName;
+ std::vector<StringRef> dtNeeded;
+ std::string soName;
- static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
+ static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
template <typename ELFT> void parse();
// Used for --no-allow-shlib-undefined.
- bool AllNeededIsKnown;
+ bool allNeededIsKnown;
// Used for --as-needed
- bool IsNeeded;
+ bool isNeeded;
};
class BinaryFile : public InputFile {
public:
- explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
- static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
+ explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {}
+ static bool classof(const InputFile *f) { return f->kind() == BinaryKind; }
void parse();
};
-InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
- uint64_t OffsetInArchive = 0);
+InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "",
+ uint64_t offsetInArchive = 0);
-inline bool isBitcode(MemoryBufferRef MB) {
- return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
+inline bool isBitcode(MemoryBufferRef mb) {
+ return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
}
-std::string replaceThinLTOSuffix(StringRef Path);
+std::string replaceThinLTOSuffix(StringRef path);
-extern std::vector<BinaryFile *> BinaryFiles;
-extern std::vector<BitcodeFile *> BitcodeFiles;
-extern std::vector<LazyObjFile *> LazyObjFiles;
-extern std::vector<InputFile *> ObjectFiles;
-extern std::vector<SharedFile *> SharedFiles;
+extern std::vector<BinaryFile *> binaryFiles;
+extern std::vector<BitcodeFile *> bitcodeFiles;
+extern std::vector<LazyObjFile *> lazyObjFiles;
+extern std::vector<InputFile *> objectFiles;
+extern std::vector<SharedFile *> sharedFiles;
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index e11cbbb9a22..a2cbefb6df1 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -40,52 +40,52 @@ using namespace llvm::sys;
using namespace lld;
using namespace lld::elf;
-std::vector<InputSectionBase *> elf::InputSections;
+std::vector<InputSectionBase *> elf::inputSections;
// Returns a string to construct an error message.
-std::string lld::toString(const InputSectionBase *Sec) {
- return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
+std::string lld::toString(const InputSectionBase *sec) {
+ return (toString(sec->file) + ":(" + sec->name + ")").str();
}
template <class ELFT>
-static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File,
- const typename ELFT::Shdr &Hdr) {
- if (Hdr.sh_type == SHT_NOBITS)
- return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size);
- return check(File.getObj().getSectionContents(&Hdr));
+static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &file,
+ const typename ELFT::Shdr &hdr) {
+ if (hdr.sh_type == SHT_NOBITS)
+ return makeArrayRef<uint8_t>(nullptr, hdr.sh_size);
+ return check(file.getObj().getSectionContents(&hdr));
}
-InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
- uint32_t Type, uint64_t Entsize,
- uint32_t Link, uint32_t Info,
- uint32_t Alignment, ArrayRef<uint8_t> Data,
- StringRef Name, Kind SectionKind)
- : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
- Link),
- File(File), RawData(Data) {
+InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
+ uint32_t type, uint64_t entsize,
+ uint32_t link, uint32_t info,
+ uint32_t alignment, ArrayRef<uint8_t> data,
+ StringRef name, Kind sectionKind)
+ : SectionBase(sectionKind, name, flags, entsize, alignment, type, info,
+ link),
+ file(file), rawData(data) {
// In order to reduce memory allocation, we assume that mergeable
// sections are smaller than 4 GiB, which is not an unreasonable
// assumption as of 2017.
- if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
+ if (sectionKind == SectionBase::Merge && rawData.size() > UINT32_MAX)
error(toString(this) + ": section too large");
- NumRelocations = 0;
- AreRelocsRela = false;
+ numRelocations = 0;
+ areRelocsRela = false;
// The ELF spec states that a value of 0 means the section has
// no alignment constraits.
- uint32_t V = std::max<uint32_t>(Alignment, 1);
- if (!isPowerOf2_64(V))
+ uint32_t v = std::max<uint32_t>(alignment, 1);
+ if (!isPowerOf2_64(v))
fatal(toString(this) + ": sh_addralign is not a power of 2");
- this->Alignment = V;
+ this->alignment = v;
// In ELF, each section can be compressed by zlib, and if compressed,
// section name may be mangled by appending "z" (e.g. ".zdebug_info").
// If that's the case, demangle section name so that we can handle a
// section as if it weren't compressed.
- if ((Flags & SHF_COMPRESSED) || Name.startswith(".zdebug")) {
+ if ((flags & SHF_COMPRESSED) || name.startswith(".zdebug")) {
if (!zlib::isAvailable())
- error(toString(File) + ": contains a compressed section, " +
+ error(toString(file) + ": contains a compressed section, " +
"but zlib is not available");
parseCompressedHeader();
}
@@ -94,11 +94,11 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
// SHF_GROUP is a marker that a section belongs to some comdat group.
// That flag doesn't make sense in an executable.
-static uint64_t getFlags(uint64_t Flags) {
- Flags &= ~(uint64_t)SHF_INFO_LINK;
- if (!Config->Relocatable)
- Flags &= ~(uint64_t)SHF_GROUP;
- return Flags;
+static uint64_t getFlags(uint64_t flags) {
+ flags &= ~(uint64_t)SHF_INFO_LINK;
+ if (!config->relocatable)
+ flags &= ~(uint64_t)SHF_GROUP;
+ return flags;
}
// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
@@ -111,99 +111,99 @@ static uint64_t getFlags(uint64_t Flags) {
//
// This function forces SHT_{INIT,FINI}_ARRAY so that we can handle
// incorrect inputs as if they were correct from the beginning.
-static uint64_t getType(uint64_t Type, StringRef Name) {
- if (Type == SHT_PROGBITS && Name.startswith(".init_array."))
+static uint64_t getType(uint64_t type, StringRef name) {
+ if (type == SHT_PROGBITS && name.startswith(".init_array."))
return SHT_INIT_ARRAY;
- if (Type == SHT_PROGBITS && Name.startswith(".fini_array."))
+ if (type == SHT_PROGBITS && name.startswith(".fini_array."))
return SHT_FINI_ARRAY;
- return Type;
+ return type;
}
template <class ELFT>
-InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
- const typename ELFT::Shdr &Hdr,
- StringRef Name, Kind SectionKind)
- : InputSectionBase(&File, getFlags(Hdr.sh_flags),
- getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link,
- Hdr.sh_info, Hdr.sh_addralign,
- getSectionContents(File, Hdr), Name, SectionKind) {
+InputSectionBase::InputSectionBase(ObjFile<ELFT> &file,
+ const typename ELFT::Shdr &hdr,
+ StringRef name, Kind sectionKind)
+ : InputSectionBase(&file, getFlags(hdr.sh_flags),
+ getType(hdr.sh_type, name), hdr.sh_entsize, hdr.sh_link,
+ hdr.sh_info, hdr.sh_addralign,
+ getSectionContents(file, hdr), name, sectionKind) {
// We reject object files having insanely large alignments even though
// they are allowed by the spec. I think 4GB is a reasonable limitation.
// We might want to relax this in the future.
- if (Hdr.sh_addralign > UINT32_MAX)
- fatal(toString(&File) + ": section sh_addralign is too large");
+ if (hdr.sh_addralign > UINT32_MAX)
+ fatal(toString(&file) + ": section sh_addralign is too large");
}
size_t InputSectionBase::getSize() const {
- if (auto *S = dyn_cast<SyntheticSection>(this))
- return S->getSize();
- if (UncompressedSize >= 0)
- return UncompressedSize;
- return RawData.size();
+ if (auto *s = dyn_cast<SyntheticSection>(this))
+ return s->getSize();
+ if (uncompressedSize >= 0)
+ return uncompressedSize;
+ return rawData.size();
}
void InputSectionBase::uncompress() const {
- size_t Size = UncompressedSize;
- char *UncompressedBuf;
+ size_t size = uncompressedSize;
+ char *uncompressedBuf;
{
- static std::mutex Mu;
- std::lock_guard<std::mutex> Lock(Mu);
- UncompressedBuf = BAlloc.Allocate<char>(Size);
+ static std::mutex mu;
+ std::lock_guard<std::mutex> lock(mu);
+ uncompressedBuf = BAlloc.Allocate<char>(size);
}
- if (Error E = zlib::uncompress(toStringRef(RawData), UncompressedBuf, Size))
+ if (Error e = zlib::uncompress(toStringRef(rawData), uncompressedBuf, size))
fatal(toString(this) +
- ": uncompress failed: " + llvm::toString(std::move(E)));
- RawData = makeArrayRef((uint8_t *)UncompressedBuf, Size);
- UncompressedSize = -1;
+ ": uncompress failed: " + llvm::toString(std::move(e)));
+ rawData = makeArrayRef((uint8_t *)uncompressedBuf, size);
+ uncompressedSize = -1;
}
uint64_t InputSectionBase::getOffsetInFile() const {
- const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
- const uint8_t *SecStart = data().begin();
- return SecStart - FileStart;
+ const uint8_t *fileStart = (const uint8_t *)file->mb.getBufferStart();
+ const uint8_t *secStart = data().begin();
+ return secStart - fileStart;
}
-uint64_t SectionBase::getOffset(uint64_t Offset) const {
+uint64_t SectionBase::getOffset(uint64_t offset) const {
switch (kind()) {
case Output: {
- auto *OS = cast<OutputSection>(this);
+ auto *os = cast<OutputSection>(this);
// For output sections we treat offset -1 as the end of the section.
- return Offset == uint64_t(-1) ? OS->Size : Offset;
+ return offset == uint64_t(-1) ? os->size : offset;
}
case Regular:
case Synthetic:
- return cast<InputSection>(this)->getOffset(Offset);
+ return cast<InputSection>(this)->getOffset(offset);
case EHFrame:
// The file crtbeginT.o has relocations pointing to the start of an empty
// .eh_frame that is known to be the first in the link. It does that to
// identify the start of the output .eh_frame.
- return Offset;
+ return offset;
case Merge:
- const MergeInputSection *MS = cast<MergeInputSection>(this);
- if (InputSection *IS = MS->getParent())
- return IS->getOffset(MS->getParentOffset(Offset));
- return MS->getParentOffset(Offset);
+ const MergeInputSection *ms = cast<MergeInputSection>(this);
+ if (InputSection *isec = ms->getParent())
+ return isec->getOffset(ms->getParentOffset(offset));
+ return ms->getParentOffset(offset);
}
llvm_unreachable("invalid section kind");
}
-uint64_t SectionBase::getVA(uint64_t Offset) const {
- const OutputSection *Out = getOutputSection();
- return (Out ? Out->Addr : 0) + getOffset(Offset);
+uint64_t SectionBase::getVA(uint64_t offset) const {
+ const OutputSection *out = getOutputSection();
+ return (out ? out->addr : 0) + getOffset(offset);
}
OutputSection *SectionBase::getOutputSection() {
- InputSection *Sec;
- if (auto *IS = dyn_cast<InputSection>(this))
- Sec = IS;
- else if (auto *MS = dyn_cast<MergeInputSection>(this))
- Sec = MS->getParent();
- else if (auto *EH = dyn_cast<EhInputSection>(this))
- Sec = EH->getParent();
+ InputSection *sec;
+ if (auto *isec = dyn_cast<InputSection>(this))
+ sec = isec;
+ else if (auto *ms = dyn_cast<MergeInputSection>(this))
+ sec = ms->getParent();
+ else if (auto *eh = dyn_cast<EhInputSection>(this))
+ sec = eh->getParent();
else
return cast<OutputSection>(this);
- return Sec ? Sec->getParent() : nullptr;
+ return sec ? sec->getParent() : nullptr;
}
// When a section is compressed, `RawData` consists with a header followed
@@ -214,109 +214,109 @@ void InputSectionBase::parseCompressedHeader() {
using Chdr32 = typename ELF32LE::Chdr;
// Old-style header
- if (Name.startswith(".zdebug")) {
- if (!toStringRef(RawData).startswith("ZLIB")) {
+ if (name.startswith(".zdebug")) {
+ if (!toStringRef(rawData).startswith("ZLIB")) {
error(toString(this) + ": corrupted compressed section header");
return;
}
- RawData = RawData.slice(4);
+ rawData = rawData.slice(4);
- if (RawData.size() < 8) {
+ if (rawData.size() < 8) {
error(toString(this) + ": corrupted compressed section header");
return;
}
- UncompressedSize = read64be(RawData.data());
- RawData = RawData.slice(8);
+ uncompressedSize = read64be(rawData.data());
+ rawData = rawData.slice(8);
// Restore the original section name.
// (e.g. ".zdebug_info" -> ".debug_info")
- Name = Saver.save("." + Name.substr(2));
+ name = Saver.save("." + name.substr(2));
return;
}
- assert(Flags & SHF_COMPRESSED);
- Flags &= ~(uint64_t)SHF_COMPRESSED;
+ assert(flags & SHF_COMPRESSED);
+ flags &= ~(uint64_t)SHF_COMPRESSED;
// New-style 64-bit header
- if (Config->Is64) {
- if (RawData.size() < sizeof(Chdr64)) {
+ if (config->is64) {
+ if (rawData.size() < sizeof(Chdr64)) {
error(toString(this) + ": corrupted compressed section");
return;
}
- auto *Hdr = reinterpret_cast<const Chdr64 *>(RawData.data());
- if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
+ auto *hdr = reinterpret_cast<const Chdr64 *>(rawData.data());
+ if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
error(toString(this) + ": unsupported compression type");
return;
}
- UncompressedSize = Hdr->ch_size;
- Alignment = std::max<uint32_t>(Hdr->ch_addralign, 1);
- RawData = RawData.slice(sizeof(*Hdr));
+ uncompressedSize = hdr->ch_size;
+ alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
+ rawData = rawData.slice(sizeof(*hdr));
return;
}
// New-style 32-bit header
- if (RawData.size() < sizeof(Chdr32)) {
+ if (rawData.size() < sizeof(Chdr32)) {
error(toString(this) + ": corrupted compressed section");
return;
}
- auto *Hdr = reinterpret_cast<const Chdr32 *>(RawData.data());
- if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
+ auto *hdr = reinterpret_cast<const Chdr32 *>(rawData.data());
+ if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
error(toString(this) + ": unsupported compression type");
return;
}
- UncompressedSize = Hdr->ch_size;
- Alignment = std::max<uint32_t>(Hdr->ch_addralign, 1);
- RawData = RawData.slice(sizeof(*Hdr));
+ uncompressedSize = hdr->ch_size;
+ alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
+ rawData = rawData.slice(sizeof(*hdr));
}
InputSection *InputSectionBase::getLinkOrderDep() const {
- assert(Link);
- assert(Flags & SHF_LINK_ORDER);
- return cast<InputSection>(File->getSections()[Link]);
+ assert(link);
+ assert(flags & SHF_LINK_ORDER);
+ return cast<InputSection>(file->getSections()[link]);
}
// Find a function symbol that encloses a given location.
template <class ELFT>
-Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
- for (Symbol *B : File->getSymbols())
- if (Defined *D = dyn_cast<Defined>(B))
- if (D->Section == this && D->Type == STT_FUNC && D->Value <= Offset &&
- Offset < D->Value + D->Size)
- return D;
+Defined *InputSectionBase::getEnclosingFunction(uint64_t offset) {
+ for (Symbol *b : file->getSymbols())
+ if (Defined *d = dyn_cast<Defined>(b))
+ if (d->section == this && d->type == STT_FUNC && d->value <= offset &&
+ offset < d->value + d->size)
+ return d;
return nullptr;
}
// Returns a source location string. Used to construct an error message.
template <class ELFT>
-std::string InputSectionBase::getLocation(uint64_t Offset) {
- std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
+std::string InputSectionBase::getLocation(uint64_t offset) {
+ std::string secAndOffset = (name + "+0x" + utohexstr(offset)).str();
// We don't have file for synthetic sections.
if (getFile<ELFT>() == nullptr)
- return (Config->OutputFile + ":(" + SecAndOffset + ")")
+ return (config->outputFile + ":(" + secAndOffset + ")")
.str();
// First check if we can get desired values from debugging information.
- if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
- return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
- SecAndOffset + ")";
+ if (Optional<DILineInfo> info = getFile<ELFT>()->getDILineInfo(this, offset))
+ return info->FileName + ":" + std::to_string(info->Line) + ":(" +
+ secAndOffset + ")";
// File->SourceFile contains STT_FILE symbol that contains a
// source file name. If it's missing, we use an object file name.
- std::string SrcFile = getFile<ELFT>()->SourceFile;
- if (SrcFile.empty())
- SrcFile = toString(File);
+ std::string srcFile = getFile<ELFT>()->sourceFile;
+ if (srcFile.empty())
+ srcFile = toString(file);
- if (Defined *D = getEnclosingFunction<ELFT>(Offset))
- return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
+ if (Defined *d = getEnclosingFunction<ELFT>(offset))
+ return srcFile + ":(function " + toString(*d) + ": " + secAndOffset + ")";
// If there's no symbol, print out the offset in the section.
- return (SrcFile + ":(" + SecAndOffset + ")");
+ return (srcFile + ":(" + secAndOffset + ")");
}
// This function is intended to be used for constructing an error message.
@@ -325,8 +325,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
//
// Returns an empty string if there's no way to get line info.
-std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
- return File->getSrcMsg(Sym, *this, Offset);
+std::string InputSectionBase::getSrcMsg(const Symbol &sym, uint64_t offset) {
+ return file->getSrcMsg(sym, *this, offset);
}
// Returns a filename string along with an optional section name. This
@@ -338,96 +338,96 @@ std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
// or
//
// path/to/foo.o:(function bar) in archive path/to/bar.a
-std::string InputSectionBase::getObjMsg(uint64_t Off) {
- std::string Filename = File->getName();
+std::string InputSectionBase::getObjMsg(uint64_t off) {
+ std::string filename = file->getName();
- std::string Archive;
- if (!File->ArchiveName.empty())
- Archive = " in archive " + File->ArchiveName;
+ std::string archive;
+ if (!file->archiveName.empty())
+ archive = " in archive " + file->archiveName;
// Find a symbol that encloses a given location.
- for (Symbol *B : File->getSymbols())
- if (auto *D = dyn_cast<Defined>(B))
- if (D->Section == this && D->Value <= Off && Off < D->Value + D->Size)
- return Filename + ":(" + toString(*D) + ")" + Archive;
+ for (Symbol *b : file->getSymbols())
+ if (auto *d = dyn_cast<Defined>(b))
+ if (d->section == this && d->value <= off && off < d->value + d->size)
+ return filename + ":(" + toString(*d) + ")" + archive;
// If there's no symbol, print out the offset in the section.
- return (Filename + ":(" + Name + "+0x" + utohexstr(Off) + ")" + Archive)
+ return (filename + ":(" + name + "+0x" + utohexstr(off) + ")" + archive)
.str();
}
-InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
+InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
-InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type,
- uint32_t Alignment, ArrayRef<uint8_t> Data,
- StringRef Name, Kind K)
- : InputSectionBase(F, Flags, Type,
- /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
- Name, K) {}
+InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
+ uint32_t alignment, ArrayRef<uint8_t> data,
+ StringRef name, Kind k)
+ : InputSectionBase(f, flags, type,
+ /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, alignment, data,
+ name, k) {}
template <class ELFT>
-InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
- StringRef Name)
- : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
+InputSection::InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
+ StringRef name)
+ : InputSectionBase(f, header, name, InputSectionBase::Regular) {}
-bool InputSection::classof(const SectionBase *S) {
- return S->kind() == SectionBase::Regular ||
- S->kind() == SectionBase::Synthetic;
+bool InputSection::classof(const SectionBase *s) {
+ return s->kind() == SectionBase::Regular ||
+ s->kind() == SectionBase::Synthetic;
}
OutputSection *InputSection::getParent() const {
- return cast_or_null<OutputSection>(Parent);
+ return cast_or_null<OutputSection>(parent);
}
// Copy SHT_GROUP section contents. Used only for the -r option.
-template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
+template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) {
// ELFT::Word is the 32-bit integral type in the target endianness.
using u32 = typename ELFT::Word;
- ArrayRef<u32> From = getDataAs<u32>();
- auto *To = reinterpret_cast<u32 *>(Buf);
+ ArrayRef<u32> from = getDataAs<u32>();
+ auto *to = reinterpret_cast<u32 *>(buf);
// The first entry is not a section number but a flag.
- *To++ = From[0];
+ *to++ = from[0];
// Adjust section numbers because section numbers in an input object
// files are different in the output.
- ArrayRef<InputSectionBase *> Sections = File->getSections();
- for (uint32_t Idx : From.slice(1))
- *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
+ ArrayRef<InputSectionBase *> sections = file->getSections();
+ for (uint32_t idx : from.slice(1))
+ *to++ = sections[idx]->getOutputSection()->sectionIndex;
}
InputSectionBase *InputSection::getRelocatedSection() const {
- if (!File || (Type != SHT_RELA && Type != SHT_REL))
+ if (!file || (type != SHT_RELA && type != SHT_REL))
return nullptr;
- ArrayRef<InputSectionBase *> Sections = File->getSections();
- return Sections[Info];
+ ArrayRef<InputSectionBase *> sections = file->getSections();
+ return sections[info];
}
// This is used for -r and --emit-relocs. We can't use memcpy to copy
// relocations because we need to update symbol table offset and section index
// for each relocation. So we copy relocations one by one.
template <class ELFT, class RelTy>
-void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
- InputSectionBase *Sec = getRelocatedSection();
+void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
+ InputSectionBase *sec = getRelocatedSection();
- for (const RelTy &Rel : Rels) {
- RelType Type = Rel.getType(Config->IsMips64EL);
- const ObjFile<ELFT> *File = getFile<ELFT>();
- Symbol &Sym = File->getRelocTargetSym(Rel);
+ for (const RelTy &rel : rels) {
+ RelType type = rel.getType(config->isMips64EL);
+ const ObjFile<ELFT> *file = getFile<ELFT>();
+ Symbol &sym = file->getRelocTargetSym(rel);
- auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
- Buf += sizeof(RelTy);
+ auto *p = reinterpret_cast<typename ELFT::Rela *>(buf);
+ buf += sizeof(RelTy);
if (RelTy::IsRela)
- P->r_addend = getAddend<ELFT>(Rel);
+ p->r_addend = getAddend<ELFT>(rel);
// Output section VA is zero for -r, so r_offset is an offset within the
// section, but for --emit-relocs it is an virtual address.
- P->r_offset = Sec->getVA(Rel.r_offset);
- P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
- Config->IsMips64EL);
+ p->r_offset = sec->getVA(rel.r_offset);
+ p->setSymbolAndType(in.symTab->getSymbolIndex(&sym), type,
+ config->isMips64EL);
- if (Sym.Type == STT_SECTION) {
+ if (sym.type == STT_SECTION) {
// We combine multiple section symbols into only one per
// section. This means we have to update the addend. That is
// trivial for Elf_Rela, but for Elf_Rel we have to write to the
@@ -440,34 +440,34 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// on .gcc_except_table and debug sections.
//
// See the comment in maybeReportUndefined for PPC64 .toc .
- auto *D = dyn_cast<Defined>(&Sym);
- if (!D) {
- if (!Sec->Name.startswith(".debug") &&
- !Sec->Name.startswith(".zdebug") && Sec->Name != ".eh_frame" &&
- Sec->Name != ".gcc_except_table" && Sec->Name != ".toc") {
- uint32_t SecIdx = cast<Undefined>(Sym).DiscardedSecIdx;
- Elf_Shdr_Impl<ELFT> Sec =
- CHECK(File->getObj().sections(), File)[SecIdx];
+ auto *d = dyn_cast<Defined>(&sym);
+ if (!d) {
+ if (!sec->name.startswith(".debug") &&
+ !sec->name.startswith(".zdebug") && sec->name != ".eh_frame" &&
+ sec->name != ".gcc_except_table" && sec->name != ".toc") {
+ uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
+ Elf_Shdr_Impl<ELFT> sec =
+ CHECK(file->getObj().sections(), file)[secIdx];
warn("relocation refers to a discarded section: " +
- CHECK(File->getObj().getSectionName(&Sec), File) +
- "\n>>> referenced by " + getObjMsg(P->r_offset));
+ CHECK(file->getObj().getSectionName(&sec), file) +
+ "\n>>> referenced by " + getObjMsg(p->r_offset));
}
- P->setSymbolAndType(0, 0, false);
+ p->setSymbolAndType(0, 0, false);
continue;
}
- SectionBase *Section = D->Section->Repl;
- if (!Section->isLive()) {
- P->setSymbolAndType(0, 0, false);
+ SectionBase *section = d->section->repl;
+ if (!section->isLive()) {
+ p->setSymbolAndType(0, 0, false);
continue;
}
- int64_t Addend = getAddend<ELFT>(Rel);
- const uint8_t *BufLoc = Sec->data().begin() + Rel.r_offset;
+ int64_t addend = getAddend<ELFT>(rel);
+ const uint8_t *bufLoc = sec->data().begin() + rel.r_offset;
if (!RelTy::IsRela)
- Addend = Target->getImplicitAddend(BufLoc, Type);
+ addend = target->getImplicitAddend(bufLoc, type);
- if (Config->EMachine == EM_MIPS && Config->Relocatable &&
- Target->getRelExpr(Type, Sym, BufLoc) == R_MIPS_GOTREL) {
+ if (config->emachine == EM_MIPS && config->relocatable &&
+ target->getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
// Some MIPS relocations depend on "gp" value. By default,
// this value has 0x7ff0 offset from a .got section. But
// relocatable files produced by a complier or a linker
@@ -479,13 +479,13 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// individual "gp" values used by each input object file.
// As a workaround we add the "gp" value to the relocation
// addend and save it back to the file.
- Addend += Sec->getFile<ELFT>()->MipsGp0;
+ addend += sec->getFile<ELFT>()->mipsGp0;
}
if (RelTy::IsRela)
- P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
- else if (Config->Relocatable && Type != Target->NoneRel)
- Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
+ p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
+ else if (config->relocatable && type != target->noneRel)
+ sec->relocations.push_back({R_ABS, type, rel.r_offset, addend, &sym});
}
}
}
@@ -495,13 +495,13 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// this context is the address of the place P. A further special case is that
// branch relocations to an undefined weak reference resolve to the next
// instruction.
-static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
- uint32_t P) {
- switch (Type) {
+static uint32_t getARMUndefinedRelativeWeakVA(RelType type, uint32_t a,
+ uint32_t p) {
+ switch (type) {
// Unresolved branch relocations to weak references resolve to next
// instruction, this will be either 2 or 4 bytes on from P.
case R_ARM_THM_JUMP11:
- return P + 2 + A;
+ return p + 2 + a;
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24:
@@ -509,10 +509,10 @@ static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
case R_ARM_PREL31:
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
- return P + 4 + A;
+ return p + 4 + a;
case R_ARM_THM_CALL:
// We don't want an interworking BLX to ARM
- return P + 5 + A;
+ return p + 5 + a;
// Unresolved non branch pc-relative relocations
// R_ARM_TARGET2 which can be resolved relatively is not present as it never
// targets a weak-reference.
@@ -521,29 +521,29 @@ static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
case R_ARM_REL32:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
- return P + A;
+ return p + a;
}
llvm_unreachable("ARM pc-relative relocation expected\n");
}
// The comment above getARMUndefinedRelativeWeakVA applies to this function.
-static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
- uint64_t P) {
- switch (Type) {
+static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t type, uint64_t a,
+ uint64_t p) {
+ switch (type) {
// Unresolved branch relocations to weak references resolve to next
// instruction, this is 4 bytes on from P.
case R_AARCH64_CALL26:
case R_AARCH64_CONDBR19:
case R_AARCH64_JUMP26:
case R_AARCH64_TSTBR14:
- return P + 4 + A;
+ return p + 4 + a;
// Unresolved non branch pc-relative relocations
case R_AARCH64_PREL16:
case R_AARCH64_PREL32:
case R_AARCH64_PREL64:
case R_AARCH64_ADR_PREL_LO21:
case R_AARCH64_LD_PREL_LO19:
- return P + A;
+ return p + a;
}
llvm_unreachable("AArch64 pc-relative relocation expected\n");
}
@@ -555,11 +555,11 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
// The procedure call standard only defines a Read Write Position Independent
// RWPI variant so in practice we should expect the static base to be the base
// of the RW segment.
-static uint64_t getARMStaticBase(const Symbol &Sym) {
- OutputSection *OS = Sym.getOutputSection();
- if (!OS || !OS->PtLoad || !OS->PtLoad->FirstSec)
- fatal("SBREL relocation to " + Sym.getName() + " without static base");
- return OS->PtLoad->FirstSec->Addr;
+static uint64_t getARMStaticBase(const Symbol &sym) {
+ OutputSection *os = sym.getOutputSection();
+ if (!os || !os->ptLoad || !os->ptLoad->firstSec)
+ fatal("SBREL relocation to " + sym.getName() + " without static base");
+ return os->ptLoad->firstSec->addr;
}
// For R_RISCV_PC_INDIRECT (R_RISCV_PCREL_LO12_{I,S}), the symbol actually
@@ -568,115 +568,115 @@ static uint64_t getARMStaticBase(const Symbol &Sym) {
//
// This function returns the R_RISCV_PCREL_HI20 relocation from
// R_RISCV_PCREL_LO12's symbol and addend.
-static Relocation *getRISCVPCRelHi20(const Symbol *Sym, uint64_t Addend) {
- const Defined *D = cast<Defined>(Sym);
- if (!D->Section) {
+static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
+ const Defined *d = cast<Defined>(sym);
+ if (!d->section) {
error("R_RISCV_PCREL_LO12 relocation points to an absolute symbol: " +
- Sym->getName());
+ sym->getName());
return nullptr;
}
- InputSection *IS = cast<InputSection>(D->Section);
+ InputSection *isec = cast<InputSection>(d->section);
- if (Addend != 0)
+ if (addend != 0)
warn("Non-zero addend in R_RISCV_PCREL_LO12 relocation to " +
- IS->getObjMsg(D->Value) + " is ignored");
+ isec->getObjMsg(d->value) + " is ignored");
// Relocations are sorted by offset, so we can use std::equal_range to do
// binary search.
- Relocation R;
- R.Offset = D->Value;
- auto Range =
- std::equal_range(IS->Relocations.begin(), IS->Relocations.end(), R,
- [](const Relocation &LHS, const Relocation &RHS) {
- return LHS.Offset < RHS.Offset;
+ Relocation r;
+ r.offset = d->value;
+ auto range =
+ std::equal_range(isec->relocations.begin(), isec->relocations.end(), r,
+ [](const Relocation &lhs, const Relocation &rhs) {
+ return lhs.offset < rhs.offset;
});
- for (auto It = Range.first; It != Range.second; ++It)
- if (It->Type == R_RISCV_PCREL_HI20 || It->Type == R_RISCV_GOT_HI20 ||
- It->Type == R_RISCV_TLS_GD_HI20 || It->Type == R_RISCV_TLS_GOT_HI20)
- return &*It;
+ for (auto it = range.first; it != range.second; ++it)
+ if (it->type == R_RISCV_PCREL_HI20 || it->type == R_RISCV_GOT_HI20 ||
+ it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20)
+ return &*it;
- error("R_RISCV_PCREL_LO12 relocation points to " + IS->getObjMsg(D->Value) +
+ error("R_RISCV_PCREL_LO12 relocation points to " + isec->getObjMsg(d->value) +
" without an associated R_RISCV_PCREL_HI20 relocation");
return nullptr;
}
// A TLS symbol's virtual address is relative to the TLS segment. Add a
// target-specific adjustment to produce a thread-pointer-relative offset.
-static int64_t getTlsTpOffset(const Symbol &S) {
+static int64_t getTlsTpOffset(const Symbol &s) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_@tpoff = 0.
- if (&S == ElfSym::TlsModuleBase)
+ if (&s == ElfSym::tlsModuleBase)
return 0;
- switch (Config->EMachine) {
+ switch (config->emachine) {
case EM_ARM:
case EM_AARCH64:
// Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
// followed by a variable amount of alignment padding, followed by the TLS
// segment.
- return S.getVA(0) + alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
+ return s.getVA(0) + alignTo(config->wordsize * 2, Out::tlsPhdr->p_align);
case EM_386:
case EM_X86_64:
// Variant 2. The TLS segment is located just before the thread pointer.
- return S.getVA(0) - alignTo(Out::TlsPhdr->p_memsz, Out::TlsPhdr->p_align);
+ return s.getVA(0) - alignTo(Out::tlsPhdr->p_memsz, Out::tlsPhdr->p_align);
case EM_PPC:
case EM_PPC64:
// The thread pointer points to a fixed offset from the start of the
// executable's TLS segment. An offset of 0x7000 allows a signed 16-bit
// offset to reach 0x1000 of TCB/thread-library data and 0xf000 of the
// program's TLS segment.
- return S.getVA(0) - 0x7000;
+ return s.getVA(0) - 0x7000;
case EM_RISCV:
- return S.getVA(0);
+ return s.getVA(0);
default:
llvm_unreachable("unhandled Config->EMachine");
}
}
-static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
- uint64_t P, const Symbol &Sym, RelExpr Expr) {
- switch (Expr) {
+static uint64_t getRelocTargetVA(const InputFile *file, RelType type, int64_t a,
+ uint64_t p, const Symbol &sym, RelExpr expr) {
+ switch (expr) {
case R_ABS:
case R_DTPREL:
case R_RELAX_TLS_LD_TO_LE_ABS:
case R_RELAX_GOT_PC_NOPIC:
case R_RISCV_ADD:
- return Sym.getVA(A);
+ return sym.getVA(a);
case R_ADDEND:
- return A;
+ return a;
case R_ARM_SBREL:
- return Sym.getVA(A) - getARMStaticBase(Sym);
+ return sym.getVA(a) - getARMStaticBase(sym);
case R_GOT:
case R_RELAX_TLS_GD_TO_IE_ABS:
- return Sym.getGotVA() + A;
+ return sym.getGotVA() + a;
case R_GOTONLY_PC:
- return In.Got->getVA() + A - P;
+ return in.got->getVA() + a - p;
case R_GOTPLTONLY_PC:
- return In.GotPlt->getVA() + A - P;
+ return in.gotPlt->getVA() + a - p;
case R_GOTREL:
case R_PPC64_RELAX_TOC:
- return Sym.getVA(A) - In.Got->getVA();
+ return sym.getVA(a) - in.got->getVA();
case R_GOTPLTREL:
- return Sym.getVA(A) - In.GotPlt->getVA();
+ return sym.getVA(a) - in.gotPlt->getVA();
case R_GOTPLT:
case R_RELAX_TLS_GD_TO_IE_GOTPLT:
- return Sym.getGotVA() + A - In.GotPlt->getVA();
+ return sym.getGotVA() + a - in.gotPlt->getVA();
case R_TLSLD_GOT_OFF:
case R_GOT_OFF:
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
- return Sym.getGotOffset() + A;
+ return sym.getGotOffset() + a;
case R_AARCH64_GOT_PAGE_PC:
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
- return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
+ return getAArch64Page(sym.getGotVA() + a) - getAArch64Page(p);
case R_GOT_PC:
case R_RELAX_TLS_GD_TO_IE:
- return Sym.getGotVA() + A - P;
+ return sym.getGotVA() + a - p;
case R_HEXAGON_GOT:
- return Sym.getGotVA() - In.GotPlt->getVA();
+ return sym.getGotVA() - in.gotPlt->getVA();
case R_MIPS_GOTREL:
- return Sym.getVA(A) - In.MipsGot->getGp(File);
+ return sym.getVA(a) - in.mipsGot->getGp(file);
case R_MIPS_GOT_GP:
- return In.MipsGot->getGp(File) + A;
+ return in.mipsGot->getGp(file) + a;
case R_MIPS_GOT_GP_PC: {
// R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
// is _gp_disp symbol. In that case we should use the following
@@ -685,76 +685,76 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
// microMIPS variants of these relocations use slightly different
// expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
// to correctly handle less-sugnificant bit of the microMIPS symbol.
- uint64_t V = In.MipsGot->getGp(File) + A - P;
- if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
- V += 4;
- if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)
- V -= 1;
- return V;
+ uint64_t v = in.mipsGot->getGp(file) + a - p;
+ if (type == R_MIPS_LO16 || type == R_MICROMIPS_LO16)
+ v += 4;
+ if (type == R_MICROMIPS_LO16 || type == R_MICROMIPS_HI16)
+ v -= 1;
+ return v;
}
case R_MIPS_GOT_LOCAL_PAGE:
// If relocation against MIPS local symbol requires GOT entry, this entry
// should be initialized by 'page address'. This address is high 16-bits
// of sum the symbol's value and the addend.
- return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
- In.MipsGot->getGp(File);
+ return in.mipsGot->getVA() + in.mipsGot->getPageEntryOffset(file, sym, a) -
+ in.mipsGot->getGp(file);
case R_MIPS_GOT_OFF:
case R_MIPS_GOT_OFF32:
// In case of MIPS if a GOT relocation has non-zero addend this addend
// should be applied to the GOT entry content not to the GOT entry offset.
// That is why we use separate expression type.
- return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
- In.MipsGot->getGp(File);
+ return in.mipsGot->getVA() + in.mipsGot->getSymEntryOffset(file, sym, a) -
+ in.mipsGot->getGp(file);
case R_MIPS_TLSGD:
- return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
- In.MipsGot->getGp(File);
+ return in.mipsGot->getVA() + in.mipsGot->getGlobalDynOffset(file, sym) -
+ in.mipsGot->getGp(file);
case R_MIPS_TLSLD:
- return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
- In.MipsGot->getGp(File);
+ return in.mipsGot->getVA() + in.mipsGot->getTlsIndexOffset(file) -
+ in.mipsGot->getGp(file);
case R_AARCH64_PAGE_PC: {
- uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
- return getAArch64Page(Val) - getAArch64Page(P);
+ uint64_t val = sym.isUndefWeak() ? p + a : sym.getVA(a);
+ return getAArch64Page(val) - getAArch64Page(p);
}
case R_RISCV_PC_INDIRECT: {
- if (const Relocation *HiRel = getRISCVPCRelHi20(&Sym, A))
- return getRelocTargetVA(File, HiRel->Type, HiRel->Addend, Sym.getVA(),
- *HiRel->Sym, HiRel->Expr);
+ if (const Relocation *hiRel = getRISCVPCRelHi20(&sym, a))
+ return getRelocTargetVA(file, hiRel->type, hiRel->addend, sym.getVA(),
+ *hiRel->sym, hiRel->expr);
return 0;
}
case R_PC: {
- uint64_t Dest;
- if (Sym.isUndefWeak()) {
+ uint64_t dest;
+ if (sym.isUndefWeak()) {
// On ARM and AArch64 a branch to an undefined weak resolves to the
// next instruction, otherwise the place.
- if (Config->EMachine == EM_ARM)
- Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
- else if (Config->EMachine == EM_AARCH64)
- Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
- else if (Config->EMachine == EM_PPC)
- Dest = P;
+ if (config->emachine == EM_ARM)
+ dest = getARMUndefinedRelativeWeakVA(type, a, p);
+ else if (config->emachine == EM_AARCH64)
+ dest = getAArch64UndefinedRelativeWeakVA(type, a, p);
+ else if (config->emachine == EM_PPC)
+ dest = p;
else
- Dest = Sym.getVA(A);
+ dest = sym.getVA(a);
} else {
- Dest = Sym.getVA(A);
+ dest = sym.getVA(a);
}
- return Dest - P;
+ return dest - p;
}
case R_PLT:
- return Sym.getPltVA() + A;
+ return sym.getPltVA() + a;
case R_PLT_PC:
case R_PPC64_CALL_PLT:
- return Sym.getPltVA() + A - P;
+ return sym.getPltVA() + a - p;
case R_PPC32_PLTREL:
// R_PPC_PLTREL24 uses the addend (usually 0 or 0x8000) to indicate r30
// stores _GLOBAL_OFFSET_TABLE_ or .got2+0x8000. The addend is ignored for
// target VA compuation.
- return Sym.getPltVA() - P;
+ return sym.getPltVA() - p;
case R_PPC64_CALL: {
- uint64_t SymVA = Sym.getVA(A);
+ uint64_t symVA = sym.getVA(a);
// If we have an undefined weak symbol, we might get here with a symbol
// address of zero. That could overflow, but the code must be unreachable,
// so don't bother doing anything at all.
- if (!SymVA)
+ if (!symVA)
return 0;
// PPC64 V2 ABI describes two entry points to a function. The global entry
@@ -763,12 +763,12 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
// the callee. For local calls the caller and callee share the same
// TOC base and so the TOC pointer initialization code should be skipped by
// branching to the local entry point.
- return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
+ return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(sym.stOther);
}
case R_PPC64_TOCBASE:
- return getPPC64TocBase() + A;
+ return getPPC64TocBase() + a;
case R_RELAX_GOT_PC:
- return Sym.getVA(A) - P;
+ return sym.getVA(a) - p;
case R_RELAX_TLS_GD_TO_LE:
case R_RELAX_TLS_IE_TO_LE:
case R_RELAX_TLS_LD_TO_LE:
@@ -777,35 +777,35 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
// --noinhibit-exec, even a non-weak undefined reference may reach here.
// Just return A, which matches R_ABS, and the behavior of some dynamic
// loaders.
- if (Sym.isUndefined())
- return A;
- return getTlsTpOffset(Sym) + A;
+ if (sym.isUndefined())
+ return a;
+ return getTlsTpOffset(sym) + a;
case R_RELAX_TLS_GD_TO_LE_NEG:
case R_NEG_TLS:
- if (Sym.isUndefined())
- return A;
- return -getTlsTpOffset(Sym) + A;
+ if (sym.isUndefined())
+ return a;
+ return -getTlsTpOffset(sym) + a;
case R_SIZE:
- return Sym.getSize() + A;
+ return sym.getSize() + a;
case R_TLSDESC:
- return In.Got->getGlobalDynAddr(Sym) + A;
+ return in.got->getGlobalDynAddr(sym) + a;
case R_TLSDESC_PC:
- return In.Got->getGlobalDynAddr(Sym) + A - P;
+ return in.got->getGlobalDynAddr(sym) + a - p;
case R_AARCH64_TLSDESC_PAGE:
- return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
- getAArch64Page(P);
+ return getAArch64Page(in.got->getGlobalDynAddr(sym) + a) -
+ getAArch64Page(p);
case R_TLSGD_GOT:
- return In.Got->getGlobalDynOffset(Sym) + A;
+ return in.got->getGlobalDynOffset(sym) + a;
case R_TLSGD_GOTPLT:
- return In.Got->getVA() + In.Got->getGlobalDynOffset(Sym) + A - In.GotPlt->getVA();
+ return in.got->getVA() + in.got->getGlobalDynOffset(sym) + a - in.gotPlt->getVA();
case R_TLSGD_PC:
- return In.Got->getGlobalDynAddr(Sym) + A - P;
+ return in.got->getGlobalDynAddr(sym) + a - p;
case R_TLSLD_GOTPLT:
- return In.Got->getVA() + In.Got->getTlsIndexOff() + A - In.GotPlt->getVA();
+ return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA();
case R_TLSLD_GOT:
- return In.Got->getTlsIndexOff() + A;
+ return in.got->getTlsIndexOff() + a;
case R_TLSLD_PC:
- return In.Got->getTlsIndexVA() + A - P;
+ return in.got->getTlsIndexVA() + a - p;
default:
llvm_unreachable("invalid expression");
}
@@ -819,36 +819,36 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
// So, we handle relocations for non-alloc sections directly in this
// function as a performance optimization.
template <class ELFT, class RelTy>
-void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
- const unsigned Bits = sizeof(typename ELFT::uint) * 8;
+void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
+ const unsigned bits = sizeof(typename ELFT::uint) * 8;
- for (const RelTy &Rel : Rels) {
- RelType Type = Rel.getType(Config->IsMips64EL);
+ for (const RelTy &rel : rels) {
+ RelType type = rel.getType(config->isMips64EL);
// GCC 8.0 or earlier have a bug that they emit R_386_GOTPC relocations
// against _GLOBAL_OFFSET_TABLE_ for .debug_info. The bug has been fixed
// in 2017 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630), but we
// need to keep this bug-compatible code for a while.
- if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
+ if (config->emachine == EM_386 && type == R_386_GOTPC)
continue;
- uint64_t Offset = getOffset(Rel.r_offset);
- uint8_t *BufLoc = Buf + Offset;
- int64_t Addend = getAddend<ELFT>(Rel);
+ uint64_t offset = getOffset(rel.r_offset);
+ uint8_t *bufLoc = buf + offset;
+ int64_t addend = getAddend<ELFT>(rel);
if (!RelTy::IsRela)
- Addend += Target->getImplicitAddend(BufLoc, Type);
+ addend += target->getImplicitAddend(bufLoc, type);
- Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
- RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
- if (Expr == R_NONE)
+ Symbol &sym = getFile<ELFT>()->getRelocTargetSym(rel);
+ RelExpr expr = target->getRelExpr(type, sym, bufLoc);
+ if (expr == R_NONE)
continue;
- if (Expr != R_ABS && Expr != R_DTPREL && Expr != R_RISCV_ADD) {
- std::string Msg = getLocation<ELFT>(Offset) +
- ": has non-ABS relocation " + toString(Type) +
- " against symbol '" + toString(Sym) + "'";
- if (Expr != R_PC) {
- error(Msg);
+ if (expr != R_ABS && expr != R_DTPREL && expr != R_RISCV_ADD) {
+ std::string msg = getLocation<ELFT>(offset) +
+ ": has non-ABS relocation " + toString(type) +
+ " against symbol '" + toString(sym) + "'";
+ if (expr != R_PC) {
+ error(msg);
return;
}
@@ -859,16 +859,16 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// relocations without any errors and relocate them as if they were at
// address 0. For bug-compatibilty, we accept them with warnings. We
// know Steel Bank Common Lisp as of 2018 have this bug.
- warn(Msg);
- Target->relocateOne(BufLoc, Type,
- SignExtend64<Bits>(Sym.getVA(Addend - Offset)));
+ warn(msg);
+ target->relocateOne(bufLoc, type,
+ SignExtend64<bits>(sym.getVA(addend - offset)));
continue;
}
- if (Sym.isTls() && !Out::TlsPhdr)
- Target->relocateOne(BufLoc, Type, 0);
+ if (sym.isTls() && !Out::tlsPhdr)
+ target->relocateOne(bufLoc, type, 0);
else
- Target->relocateOne(BufLoc, Type, SignExtend64<Bits>(Sym.getVA(Addend)));
+ target->relocateOne(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
}
}
@@ -877,100 +877,100 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// relocations aimed to update addends. They are handled in relocateAlloc()
// for allocatable sections, and this function does the same for
// non-allocatable sections, such as sections with debug information.
-static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
- const unsigned Bits = Config->Is64 ? 64 : 32;
+static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
+ const unsigned bits = config->is64 ? 64 : 32;
- for (const Relocation &Rel : Sec->Relocations) {
+ for (const Relocation &rel : sec->relocations) {
// InputSection::copyRelocations() adds only R_ABS relocations.
- assert(Rel.Expr == R_ABS);
- uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
- uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
- Target->relocateOne(BufLoc, Rel.Type, TargetVA);
+ assert(rel.expr == R_ABS);
+ uint8_t *bufLoc = buf + rel.offset + sec->outSecOff;
+ uint64_t targetVA = SignExtend64(rel.sym->getVA(rel.addend), bits);
+ target->relocateOne(bufLoc, rel.type, targetVA);
}
}
template <class ELFT>
-void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
- if (Flags & SHF_EXECINSTR)
- adjustSplitStackFunctionPrologues<ELFT>(Buf, BufEnd);
+void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
+ if (flags & SHF_EXECINSTR)
+ adjustSplitStackFunctionPrologues<ELFT>(buf, bufEnd);
- if (Flags & SHF_ALLOC) {
- relocateAlloc(Buf, BufEnd);
+ if (flags & SHF_ALLOC) {
+ relocateAlloc(buf, bufEnd);
return;
}
- auto *Sec = cast<InputSection>(this);
- if (Config->Relocatable)
- relocateNonAllocForRelocatable(Sec, Buf);
- else if (Sec->AreRelocsRela)
- Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
+ auto *sec = cast<InputSection>(this);
+ if (config->relocatable)
+ relocateNonAllocForRelocatable(sec, buf);
+ else if (sec->areRelocsRela)
+ sec->relocateNonAlloc<ELFT>(buf, sec->template relas<ELFT>());
else
- Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());
+ sec->relocateNonAlloc<ELFT>(buf, sec->template rels<ELFT>());
}
-void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
- assert(Flags & SHF_ALLOC);
- const unsigned Bits = Config->Wordsize * 8;
+void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
+ assert(flags & SHF_ALLOC);
+ const unsigned bits = config->wordsize * 8;
- for (const Relocation &Rel : Relocations) {
- uint64_t Offset = Rel.Offset;
- if (auto *Sec = dyn_cast<InputSection>(this))
- Offset += Sec->OutSecOff;
- uint8_t *BufLoc = Buf + Offset;
- RelType Type = Rel.Type;
+ for (const Relocation &rel : relocations) {
+ uint64_t offset = rel.offset;
+ if (auto *sec = dyn_cast<InputSection>(this))
+ offset += sec->outSecOff;
+ uint8_t *bufLoc = buf + offset;
+ RelType type = rel.type;
- uint64_t AddrLoc = getOutputSection()->Addr + Offset;
- RelExpr Expr = Rel.Expr;
- uint64_t TargetVA = SignExtend64(
- getRelocTargetVA(File, Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr),
- Bits);
+ uint64_t addrLoc = getOutputSection()->addr + offset;
+ RelExpr expr = rel.expr;
+ uint64_t targetVA = SignExtend64(
+ getRelocTargetVA(file, type, rel.addend, addrLoc, *rel.sym, expr),
+ bits);
- switch (Expr) {
+ switch (expr) {
case R_RELAX_GOT_PC:
case R_RELAX_GOT_PC_NOPIC:
- Target->relaxGot(BufLoc, Type, TargetVA);
+ target->relaxGot(bufLoc, type, targetVA);
break;
case R_PPC64_RELAX_TOC:
- if (!tryRelaxPPC64TocIndirection(Type, Rel, BufLoc))
- Target->relocateOne(BufLoc, Type, TargetVA);
+ if (!tryRelaxPPC64TocIndirection(type, rel, bufLoc))
+ target->relocateOne(bufLoc, type, targetVA);
break;
case R_RELAX_TLS_IE_TO_LE:
- Target->relaxTlsIeToLe(BufLoc, Type, TargetVA);
+ target->relaxTlsIeToLe(bufLoc, type, targetVA);
break;
case R_RELAX_TLS_LD_TO_LE:
case R_RELAX_TLS_LD_TO_LE_ABS:
- Target->relaxTlsLdToLe(BufLoc, Type, TargetVA);
+ target->relaxTlsLdToLe(bufLoc, type, targetVA);
break;
case R_RELAX_TLS_GD_TO_LE:
case R_RELAX_TLS_GD_TO_LE_NEG:
- Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
+ target->relaxTlsGdToLe(bufLoc, type, targetVA);
break;
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
case R_RELAX_TLS_GD_TO_IE:
case R_RELAX_TLS_GD_TO_IE_ABS:
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
case R_RELAX_TLS_GD_TO_IE_GOTPLT:
- Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
+ target->relaxTlsGdToIe(bufLoc, type, targetVA);
break;
case R_PPC64_CALL:
// If this is a call to __tls_get_addr, it may be part of a TLS
// sequence that has been relaxed and turned into a nop. In this
// case, we don't want to handle it as a call.
- if (read32(BufLoc) == 0x60000000) // nop
+ if (read32(bufLoc) == 0x60000000) // nop
break;
// Patch a nop (0x60000000) to a ld.
- if (Rel.Sym->NeedsTocRestore) {
- if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) {
- error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc");
+ if (rel.sym->needsTocRestore) {
+ if (bufLoc + 8 > bufEnd || read32(bufLoc + 4) != 0x60000000) {
+ error(getErrorLocation(bufLoc) + "call lacks nop, can't restore toc");
break;
}
- write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
+ write32(bufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
}
- Target->relocateOne(BufLoc, Type, TargetVA);
+ target->relocateOne(bufLoc, type, targetVA);
break;
default:
- Target->relocateOne(BufLoc, Type, TargetVA);
+ target->relocateOne(bufLoc, type, targetVA);
break;
}
}
@@ -979,44 +979,44 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
// For each function-defining prologue, find any calls to __morestack,
// and replace them with calls to __morestack_non_split.
static void switchMorestackCallsToMorestackNonSplit(
- DenseSet<Defined *> &Prologues, std::vector<Relocation *> &MorestackCalls) {
+ DenseSet<Defined *> &prologues, std::vector<Relocation *> &morestackCalls) {
// If the target adjusted a function's prologue, all calls to
// __morestack inside that function should be switched to
// __morestack_non_split.
- Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split");
- if (!MoreStackNonSplit) {
+ Symbol *moreStackNonSplit = symtab->find("__morestack_non_split");
+ if (!moreStackNonSplit) {
error("Mixing split-stack objects requires a definition of "
"__morestack_non_split");
return;
}
// Sort both collections to compare addresses efficiently.
- llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
- return L->Offset < R->Offset;
+ llvm::sort(morestackCalls, [](const Relocation *l, const Relocation *r) {
+ return l->offset < r->offset;
});
- std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
- llvm::sort(Functions, [](const Defined *L, const Defined *R) {
- return L->Value < R->Value;
+ std::vector<Defined *> functions(prologues.begin(), prologues.end());
+ llvm::sort(functions, [](const Defined *l, const Defined *r) {
+ return l->value < r->value;
});
- auto It = MorestackCalls.begin();
- for (Defined *F : Functions) {
+ auto it = morestackCalls.begin();
+ for (Defined *f : functions) {
// Find the first call to __morestack within the function.
- while (It != MorestackCalls.end() && (*It)->Offset < F->Value)
- ++It;
+ while (it != morestackCalls.end() && (*it)->offset < f->value)
+ ++it;
// Adjust all calls inside the function.
- while (It != MorestackCalls.end() && (*It)->Offset < F->Value + F->Size) {
- (*It)->Sym = MoreStackNonSplit;
- ++It;
+ while (it != morestackCalls.end() && (*it)->offset < f->value + f->size) {
+ (*it)->sym = moreStackNonSplit;
+ ++it;
}
}
}
-static bool enclosingPrologueAttempted(uint64_t Offset,
- const DenseSet<Defined *> &Prologues) {
- for (Defined *F : Prologues)
- if (F->Value <= Offset && Offset < F->Value + F->Size)
+static bool enclosingPrologueAttempted(uint64_t offset,
+ const DenseSet<Defined *> &prologues) {
+ for (Defined *f : prologues)
+ if (f->value <= offset && offset < f->value + f->size)
return true;
return false;
}
@@ -1026,30 +1026,30 @@ static bool enclosingPrologueAttempted(uint64_t Offset,
// adjusted to ensure that the called function will have enough stack
// available. Find those functions, and adjust their prologues.
template <class ELFT>
-void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
- uint8_t *End) {
- if (!getFile<ELFT>()->SplitStack)
+void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
+ uint8_t *end) {
+ if (!getFile<ELFT>()->splitStack)
return;
- DenseSet<Defined *> Prologues;
- std::vector<Relocation *> MorestackCalls;
+ DenseSet<Defined *> prologues;
+ std::vector<Relocation *> morestackCalls;
- for (Relocation &Rel : Relocations) {
+ for (Relocation &rel : relocations) {
// Local symbols can't possibly be cross-calls, and should have been
// resolved long before this line.
- if (Rel.Sym->isLocal())
+ if (rel.sym->isLocal())
continue;
// Ignore calls into the split-stack api.
- if (Rel.Sym->getName().startswith("__morestack")) {
- if (Rel.Sym->getName().equals("__morestack"))
- MorestackCalls.push_back(&Rel);
+ if (rel.sym->getName().startswith("__morestack")) {
+ if (rel.sym->getName().equals("__morestack"))
+ morestackCalls.push_back(&rel);
continue;
}
// A relocation to non-function isn't relevant. Sometimes
// __morestack is not marked as a function, so this check comes
// after the name check.
- if (Rel.Sym->Type != STT_FUNC)
+ if (rel.sym->type != STT_FUNC)
continue;
// If the callee's-file was compiled with split stack, nothing to do. In
@@ -1057,117 +1057,117 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
// being produced". So an "undefined" symbol might be provided by a shared
// library. It is not possible to tell how such symbols were compiled, so be
// conservative.
- if (Defined *D = dyn_cast<Defined>(Rel.Sym))
- if (InputSection *IS = cast_or_null<InputSection>(D->Section))
- if (!IS || !IS->getFile<ELFT>() || IS->getFile<ELFT>()->SplitStack)
+ if (Defined *d = dyn_cast<Defined>(rel.sym))
+ if (InputSection *isec = cast_or_null<InputSection>(d->section))
+ if (!isec || !isec->getFile<ELFT>() || isec->getFile<ELFT>()->splitStack)
continue;
- if (enclosingPrologueAttempted(Rel.Offset, Prologues))
+ if (enclosingPrologueAttempted(rel.offset, prologues))
continue;
- if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {
- Prologues.insert(F);
- if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value),
- End, F->StOther))
+ if (Defined *f = getEnclosingFunction<ELFT>(rel.offset)) {
+ prologues.insert(f);
+ if (target->adjustPrologueForCrossSplitStack(buf + getOffset(f->value),
+ end, f->stOther))
continue;
- if (!getFile<ELFT>()->SomeNoSplitStack)
- error(lld::toString(this) + ": " + F->getName() +
- " (with -fsplit-stack) calls " + Rel.Sym->getName() +
+ if (!getFile<ELFT>()->someNoSplitStack)
+ error(lld::toString(this) + ": " + f->getName() +
+ " (with -fsplit-stack) calls " + rel.sym->getName() +
" (without -fsplit-stack), but couldn't adjust its prologue");
}
}
- if (Target->NeedsMoreStackNonSplit)
- switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls);
+ if (target->needsMoreStackNonSplit)
+ switchMorestackCallsToMorestackNonSplit(prologues, morestackCalls);
}
-template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
- if (Type == SHT_NOBITS)
+template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
+ if (type == SHT_NOBITS)
return;
- if (auto *S = dyn_cast<SyntheticSection>(this)) {
- S->writeTo(Buf + OutSecOff);
+ if (auto *s = dyn_cast<SyntheticSection>(this)) {
+ s->writeTo(buf + outSecOff);
return;
}
// If -r or --emit-relocs is given, then an InputSection
// may be a relocation section.
- if (Type == SHT_RELA) {
- copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>());
+ if (type == SHT_RELA) {
+ copyRelocations<ELFT>(buf + outSecOff, getDataAs<typename ELFT::Rela>());
return;
}
- if (Type == SHT_REL) {
- copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>());
+ if (type == SHT_REL) {
+ copyRelocations<ELFT>(buf + outSecOff, getDataAs<typename ELFT::Rel>());
return;
}
// If -r is given, we may have a SHT_GROUP section.
- if (Type == SHT_GROUP) {
- copyShtGroup<ELFT>(Buf + OutSecOff);
+ if (type == SHT_GROUP) {
+ copyShtGroup<ELFT>(buf + outSecOff);
return;
}
// If this is a compressed section, uncompress section contents directly
// to the buffer.
- if (UncompressedSize >= 0) {
- size_t Size = UncompressedSize;
- if (Error E = zlib::uncompress(toStringRef(RawData),
- (char *)(Buf + OutSecOff), Size))
+ if (uncompressedSize >= 0) {
+ size_t size = uncompressedSize;
+ if (Error e = zlib::uncompress(toStringRef(rawData),
+ (char *)(buf + outSecOff), size))
fatal(toString(this) +
- ": uncompress failed: " + llvm::toString(std::move(E)));
- uint8_t *BufEnd = Buf + OutSecOff + Size;
- relocate<ELFT>(Buf, BufEnd);
+ ": uncompress failed: " + llvm::toString(std::move(e)));
+ uint8_t *bufEnd = buf + outSecOff + size;
+ relocate<ELFT>(buf, bufEnd);
return;
}
// Copy section contents from source object file to output file
// and then apply relocations.
- memcpy(Buf + OutSecOff, data().data(), data().size());
- uint8_t *BufEnd = Buf + OutSecOff + data().size();
- relocate<ELFT>(Buf, BufEnd);
+ memcpy(buf + outSecOff, data().data(), data().size());
+ uint8_t *bufEnd = buf + outSecOff + data().size();
+ relocate<ELFT>(buf, bufEnd);
}
-void InputSection::replace(InputSection *Other) {
- Alignment = std::max(Alignment, Other->Alignment);
+void InputSection::replace(InputSection *other) {
+ alignment = std::max(alignment, other->alignment);
// When a section is replaced with another section that was allocated to
// another partition, the replacement section (and its associated sections)
// need to be placed in the main partition so that both partitions will be
// able to access it.
- if (Partition != Other->Partition) {
- Partition = 1;
- for (InputSection *IS : DependentSections)
- IS->Partition = 1;
+ if (partition != other->partition) {
+ partition = 1;
+ for (InputSection *isec : dependentSections)
+ isec->partition = 1;
}
- Other->Repl = Repl;
- Other->markDead();
+ other->repl = repl;
+ other->markDead();
}
template <class ELFT>
-EhInputSection::EhInputSection(ObjFile<ELFT> &F,
- const typename ELFT::Shdr &Header,
- StringRef Name)
- : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {}
+EhInputSection::EhInputSection(ObjFile<ELFT> &f,
+ const typename ELFT::Shdr &header,
+ StringRef name)
+ : InputSectionBase(f, header, name, InputSectionBase::EHFrame) {}
SyntheticSection *EhInputSection::getParent() const {
- return cast_or_null<SyntheticSection>(Parent);
+ return cast_or_null<SyntheticSection>(parent);
}
// Returns the index of the first relocation that points to a region between
// Begin and Begin+Size.
template <class IntTy, class RelTy>
-static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
- unsigned &RelocI) {
+static unsigned getReloc(IntTy begin, IntTy size, const ArrayRef<RelTy> &rels,
+ unsigned &relocI) {
// Start search from RelocI for fast access. That works because the
// relocations are sorted in .eh_frame.
- for (unsigned N = Rels.size(); RelocI < N; ++RelocI) {
- const RelTy &Rel = Rels[RelocI];
- if (Rel.r_offset < Begin)
+ for (unsigned n = rels.size(); relocI < n; ++relocI) {
+ const RelTy &rel = rels[relocI];
+ if (rel.r_offset < begin)
continue;
- if (Rel.r_offset < Begin + Size)
- return RelocI;
+ if (rel.r_offset < begin + size)
+ return relocI;
return -1;
}
return -1;
@@ -1176,84 +1176,84 @@ static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
// .eh_frame is a sequence of CIE or FDE records.
// This function splits an input section into records and returns them.
template <class ELFT> void EhInputSection::split() {
- if (AreRelocsRela)
+ if (areRelocsRela)
split<ELFT>(relas<ELFT>());
else
split<ELFT>(rels<ELFT>());
}
template <class ELFT, class RelTy>
-void EhInputSection::split(ArrayRef<RelTy> Rels) {
- unsigned RelI = 0;
- for (size_t Off = 0, End = data().size(); Off != End;) {
- size_t Size = readEhRecordSize(this, Off);
- Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
+void EhInputSection::split(ArrayRef<RelTy> rels) {
+ unsigned relI = 0;
+ for (size_t off = 0, end = data().size(); off != end;) {
+ size_t size = readEhRecordSize(this, off);
+ pieces.emplace_back(off, this, size, getReloc(off, size, rels, relI));
// The empty record is the end marker.
- if (Size == 4)
+ if (size == 4)
break;
- Off += Size;
+ off += size;
}
}
-static size_t findNull(StringRef S, size_t EntSize) {
+static size_t findNull(StringRef s, size_t entSize) {
// Optimize the common case.
- if (EntSize == 1)
- return S.find(0);
+ if (entSize == 1)
+ return s.find(0);
- for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
- const char *B = S.begin() + I;
- if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
- return I;
+ for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
+ const char *b = s.begin() + i;
+ if (std::all_of(b, b + entSize, [](char c) { return c == 0; }))
+ return i;
}
return StringRef::npos;
}
SyntheticSection *MergeInputSection::getParent() const {
- return cast_or_null<SyntheticSection>(Parent);
+ return cast_or_null<SyntheticSection>(parent);
}
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
-void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
- size_t Off = 0;
- bool IsAlloc = Flags & SHF_ALLOC;
- StringRef S = toStringRef(Data);
-
- while (!S.empty()) {
- size_t End = findNull(S, EntSize);
- if (End == StringRef::npos)
+void MergeInputSection::splitStrings(ArrayRef<uint8_t> data, size_t entSize) {
+ size_t off = 0;
+ bool isAlloc = flags & SHF_ALLOC;
+ StringRef s = toStringRef(data);
+
+ while (!s.empty()) {
+ size_t end = findNull(s, entSize);
+ if (end == StringRef::npos)
fatal(toString(this) + ": string is not null terminated");
- size_t Size = End + EntSize;
+ size_t size = end + entSize;
- Pieces.emplace_back(Off, xxHash64(S.substr(0, Size)), !IsAlloc);
- S = S.substr(Size);
- Off += Size;
+ pieces.emplace_back(off, xxHash64(s.substr(0, size)), !isAlloc);
+ s = s.substr(size);
+ off += size;
}
}
// Split non-SHF_STRINGS section. Such section is a sequence of
// fixed size records.
-void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
- size_t EntSize) {
- size_t Size = Data.size();
- assert((Size % EntSize) == 0);
- bool IsAlloc = Flags & SHF_ALLOC;
-
- for (size_t I = 0; I != Size; I += EntSize)
- Pieces.emplace_back(I, xxHash64(Data.slice(I, EntSize)), !IsAlloc);
+void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
+ size_t entSize) {
+ size_t size = data.size();
+ assert((size % entSize) == 0);
+ bool isAlloc = flags & SHF_ALLOC;
+
+ for (size_t i = 0; i != size; i += entSize)
+ pieces.emplace_back(i, xxHash64(data.slice(i, entSize)), !isAlloc);
}
template <class ELFT>
-MergeInputSection::MergeInputSection(ObjFile<ELFT> &F,
- const typename ELFT::Shdr &Header,
- StringRef Name)
- : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {}
+MergeInputSection::MergeInputSection(ObjFile<ELFT> &f,
+ const typename ELFT::Shdr &header,
+ StringRef name)
+ : InputSectionBase(f, header, name, InputSectionBase::Merge) {}
-MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
- uint64_t Entsize, ArrayRef<uint8_t> Data,
- StringRef Name)
- : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0,
- /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {}
+MergeInputSection::MergeInputSection(uint64_t flags, uint32_t type,
+ uint64_t entsize, ArrayRef<uint8_t> data,
+ StringRef name)
+ : InputSectionBase(nullptr, flags, type, entsize, /*Link*/ 0, /*Info*/ 0,
+ /*Alignment*/ entsize, data, name, SectionBase::Merge) {}
// This function is called after we obtain a complete list of input sections
// that need to be linked. This is responsible to split section contents
@@ -1262,35 +1262,35 @@ MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
// Note that this function is called from parallelForEach. This must be
// thread-safe (i.e. no memory allocation from the pools).
void MergeInputSection::splitIntoPieces() {
- assert(Pieces.empty());
+ assert(pieces.empty());
- if (Flags & SHF_STRINGS)
- splitStrings(data(), Entsize);
+ if (flags & SHF_STRINGS)
+ splitStrings(data(), entsize);
else
- splitNonStrings(data(), Entsize);
+ splitNonStrings(data(), entsize);
}
-SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
- if (this->data().size() <= Offset)
+SectionPiece *MergeInputSection::getSectionPiece(uint64_t offset) {
+ if (this->data().size() <= offset)
fatal(toString(this) + ": offset is outside the section");
// If Offset is not at beginning of a section piece, it is not in the map.
// In that case we need to do a binary search of the original section piece vector.
- auto It = partition_point(
- Pieces, [=](SectionPiece P) { return P.InputOff <= Offset; });
- return &It[-1];
+ auto it = partition_point(
+ pieces, [=](SectionPiece p) { return p.inputOff <= offset; });
+ return &it[-1];
}
// Returns the offset in an output section for a given input offset.
// Because contents of a mergeable section is not contiguous in output,
// it is not just an addition to a base output offset.
-uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {
+uint64_t MergeInputSection::getParentOffset(uint64_t offset) const {
// If Offset is not at beginning of a section piece, it is not in the map.
// In that case we need to search from the original section piece vector.
- const SectionPiece &Piece =
- *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
- uint64_t Addend = Offset - Piece.InputOff;
- return Piece.OutputOff + Addend;
+ const SectionPiece &piece =
+ *(const_cast<MergeInputSection *>(this)->getSectionPiece (offset));
+ uint64_t addend = offset - piece.inputOff;
+ return piece.outputOff + addend;
}
template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index bf678ce030b..dcd4848a0ab 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -31,7 +31,7 @@ class MergeSyntheticSection;
template <class ELFT> class ObjFile;
class OutputSection;
-extern std::vector<Partition> Partitions;
+extern std::vector<Partition> partitions;
// This is the base class of all sections that lld handles. Some are sections in
// input files, some are sections in the produced output file and some exist
@@ -41,18 +41,18 @@ class SectionBase {
public:
enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
- Kind kind() const { return (Kind)SectionKind; }
+ Kind kind() const { return (Kind)sectionKind; }
- StringRef Name;
+ StringRef name;
// This pointer points to the "real" instance of this instance.
// Usually Repl == this. However, if ICF merges two sections,
// Repl pointer of one section points to another section. So,
// if you need to get a pointer to this instance, do not use
// this but instead this->Repl.
- SectionBase *Repl;
+ SectionBase *repl;
- unsigned SectionKind : 3;
+ unsigned sectionKind : 3;
// The next three bit fields are only used by InputSectionBase, but we
// put them here so the struct packs better.
@@ -68,26 +68,26 @@ public:
// .foo takes all .text sections, and .bar becomes empty. To achieve
// this, we need to memorize whether a section has been placed or
// not for each input section.
- unsigned Assigned : 1;
+ unsigned assigned : 1;
- unsigned Bss : 1;
+ unsigned bss : 1;
// Set for sections that should not be folded by ICF.
- unsigned KeepUnique : 1;
+ unsigned keepUnique : 1;
// The 1-indexed partition that this section is assigned to by the garbage
// collector, or 0 if this section is dead. Normally there is only one
// partition, so this will either be 0 or 1.
- uint8_t Partition;
+ uint8_t partition;
elf::Partition &getPartition() const;
// These corresponds to the fields in Elf_Shdr.
- uint32_t Alignment;
- uint64_t Flags;
- uint64_t Entsize;
- uint32_t Type;
- uint32_t Link;
- uint32_t Info;
+ uint32_t alignment;
+ uint64_t flags;
+ uint64_t entsize;
+ uint32_t type;
+ uint32_t link;
+ uint32_t info;
OutputSection *getOutputSection();
const OutputSection *getOutputSection() const {
@@ -96,55 +96,55 @@ public:
// Translate an offset in the input section to an offset in the output
// section.
- uint64_t getOffset(uint64_t Offset) const;
+ uint64_t getOffset(uint64_t offset) const;
- uint64_t getVA(uint64_t Offset = 0) const;
+ uint64_t getVA(uint64_t offset = 0) const;
- bool isLive() const { return Partition != 0; }
- void markLive() { Partition = 1; }
- void markDead() { Partition = 0; }
+ bool isLive() const { return partition != 0; }
+ void markLive() { partition = 1; }
+ void markDead() { partition = 0; }
protected:
- SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
- uint64_t Entsize, uint64_t Alignment, uint32_t Type,
- uint32_t Info, uint32_t Link)
- : Name(Name), Repl(this), SectionKind(SectionKind), Assigned(false),
- Bss(false), KeepUnique(false), Partition(0), Alignment(Alignment),
- Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
+ SectionBase(Kind sectionKind, StringRef name, uint64_t flags,
+ uint64_t entsize, uint64_t alignment, uint32_t type,
+ uint32_t info, uint32_t link)
+ : name(name), repl(this), sectionKind(sectionKind), assigned(false),
+ bss(false), keepUnique(false), partition(0), alignment(alignment),
+ flags(flags), entsize(entsize), type(type), link(link), info(info) {}
};
// This corresponds to a section of an input file.
class InputSectionBase : public SectionBase {
public:
template <class ELFT>
- InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
- StringRef Name, Kind SectionKind);
+ InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
+ StringRef name, Kind sectionKind);
- InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
- uint64_t Entsize, uint32_t Link, uint32_t Info,
- uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
- Kind SectionKind);
+ InputSectionBase(InputFile *file, uint64_t flags, uint32_t type,
+ uint64_t entsize, uint32_t link, uint32_t info,
+ uint32_t alignment, ArrayRef<uint8_t> data, StringRef name,
+ Kind sectionKind);
- static bool classof(const SectionBase *S) { return S->kind() != Output; }
+ static bool classof(const SectionBase *s) { return s->kind() != Output; }
// Relocations that refer to this section.
- unsigned NumRelocations : 31;
- unsigned AreRelocsRela : 1;
- const void *FirstRelocation = nullptr;
+ unsigned numRelocations : 31;
+ unsigned areRelocsRela : 1;
+ const void *firstRelocation = nullptr;
// The file which contains this section. Its dynamic type is always
// ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
// its static type.
- InputFile *File;
+ InputFile *file;
template <class ELFT> ObjFile<ELFT> *getFile() const {
- return cast_or_null<ObjFile<ELFT>>(File);
+ return cast_or_null<ObjFile<ELFT>>(file);
}
ArrayRef<uint8_t> data() const {
- if (UncompressedSize >= 0)
+ if (uncompressedSize >= 0)
uncompress();
- return RawData;
+ return rawData;
}
uint64_t getOffsetInFile() const;
@@ -153,24 +153,24 @@ public:
// like .eh_frame and merge sections are first combined into a
// synthetic section that is then added to an output section. In all
// cases this points one level up.
- SectionBase *Parent = nullptr;
+ SectionBase *parent = nullptr;
template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
- assert(!AreRelocsRela);
+ assert(!areRelocsRela);
return llvm::makeArrayRef(
- static_cast<const typename ELFT::Rel *>(FirstRelocation),
- NumRelocations);
+ static_cast<const typename ELFT::Rel *>(firstRelocation),
+ numRelocations);
}
template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
- assert(AreRelocsRela);
+ assert(areRelocsRela);
return llvm::makeArrayRef(
- static_cast<const typename ELFT::Rela *>(FirstRelocation),
- NumRelocations);
+ static_cast<const typename ELFT::Rela *>(firstRelocation),
+ numRelocations);
}
// InputSections that are dependent on us (reverse dependency for GC)
- llvm::TinyPtrVector<InputSection *> DependentSections;
+ llvm::TinyPtrVector<InputSection *> dependentSections;
// Returns the size of this section (even if this is a common or BSS.)
size_t getSize() const;
@@ -180,23 +180,23 @@ public:
// Get the function symbol that encloses this offset from within the
// section.
template <class ELFT>
- Defined *getEnclosingFunction(uint64_t Offset);
+ Defined *getEnclosingFunction(uint64_t offset);
// Returns a source location string. Used to construct an error message.
- template <class ELFT> std::string getLocation(uint64_t Offset);
- std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
- std::string getObjMsg(uint64_t Offset);
+ template <class ELFT> std::string getLocation(uint64_t offset);
+ std::string getSrcMsg(const Symbol &sym, uint64_t offset);
+ std::string getObjMsg(uint64_t offset);
// Each section knows how to relocate itself. These functions apply
// relocations, assuming that Buf points to this section's copy in
// the mmap'ed output buffer.
- template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
- void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
+ template <class ELFT> void relocate(uint8_t *buf, uint8_t *bufEnd);
+ void relocateAlloc(uint8_t *buf, uint8_t *bufEnd);
// The native ELF reloc data type is not very convenient to handle.
// So we convert ELF reloc records to our own records in Relocations.cpp.
// This vector contains such "cooked" relocations.
- std::vector<Relocation> Relocations;
+ std::vector<Relocation> relocations;
// A function compiled with -fsplit-stack calling a function
// compiled without -fsplit-stack needs its prologue adjusted. Find
@@ -204,26 +204,26 @@ public:
// to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
// information.
template <typename ELFT>
- void adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End);
+ void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end);
template <typename T> llvm::ArrayRef<T> getDataAs() const {
- size_t S = data().size();
- assert(S % sizeof(T) == 0);
- return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
+ size_t s = data().size();
+ assert(s % sizeof(T) == 0);
+ return llvm::makeArrayRef<T>((const T *)data().data(), s / sizeof(T));
}
protected:
void parseCompressedHeader();
void uncompress() const;
- mutable ArrayRef<uint8_t> RawData;
+ mutable ArrayRef<uint8_t> rawData;
// This field stores the uncompressed size of the compressed data in RawData,
// or -1 if RawData is not compressed (either because the section wasn't
// compressed in the first place, or because we ended up uncompressing it).
// Since the feature is not used often, this is usually -1.
- mutable int64_t UncompressedSize = -1;
+ mutable int64_t uncompressedSize = -1;
};
// SectionPiece represents a piece of splittable section contents.
@@ -231,13 +231,13 @@ protected:
// have to be as compact as possible, which is why we don't store the size (can
// be found by looking at the next one).
struct SectionPiece {
- SectionPiece(size_t Off, uint32_t Hash, bool Live)
- : InputOff(Off), Live(Live || !Config->GcSections), Hash(Hash >> 1) {}
+ SectionPiece(size_t off, uint32_t hash, bool live)
+ : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {}
- uint32_t InputOff;
- uint32_t Live : 1;
- uint32_t Hash : 31;
- uint64_t OutputOff = 0;
+ uint32_t inputOff;
+ uint32_t live : 1;
+ uint32_t hash : 31;
+ uint64_t outputOff = 0;
};
static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
@@ -246,74 +246,74 @@ static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
class MergeInputSection : public InputSectionBase {
public:
template <class ELFT>
- MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
- StringRef Name);
- MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
- ArrayRef<uint8_t> Data, StringRef Name);
+ MergeInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
+ StringRef name);
+ MergeInputSection(uint64_t flags, uint32_t type, uint64_t entsize,
+ ArrayRef<uint8_t> data, StringRef name);
- static bool classof(const SectionBase *S) { return S->kind() == Merge; }
+ static bool classof(const SectionBase *s) { return s->kind() == Merge; }
void splitIntoPieces();
// Translate an offset in the input section to an offset in the parent
// MergeSyntheticSection.
- uint64_t getParentOffset(uint64_t Offset) const;
+ uint64_t getParentOffset(uint64_t offset) const;
// Splittable sections are handled as a sequence of data
// rather than a single large blob of data.
- std::vector<SectionPiece> Pieces;
+ std::vector<SectionPiece> pieces;
// Returns I'th piece's data. This function is very hot when
// string merging is enabled, so we want to inline.
LLVM_ATTRIBUTE_ALWAYS_INLINE
- llvm::CachedHashStringRef getData(size_t I) const {
- size_t Begin = Pieces[I].InputOff;
- size_t End =
- (Pieces.size() - 1 == I) ? data().size() : Pieces[I + 1].InputOff;
- return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
+ llvm::CachedHashStringRef getData(size_t i) const {
+ size_t begin = pieces[i].inputOff;
+ size_t end =
+ (pieces.size() - 1 == i) ? data().size() : pieces[i + 1].inputOff;
+ return {toStringRef(data().slice(begin, end - begin)), pieces[i].hash};
}
// Returns the SectionPiece at a given input section offset.
- SectionPiece *getSectionPiece(uint64_t Offset);
- const SectionPiece *getSectionPiece(uint64_t Offset) const {
- return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
+ SectionPiece *getSectionPiece(uint64_t offset);
+ const SectionPiece *getSectionPiece(uint64_t offset) const {
+ return const_cast<MergeInputSection *>(this)->getSectionPiece(offset);
}
SyntheticSection *getParent() const;
private:
- void splitStrings(ArrayRef<uint8_t> A, size_t Size);
- void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
+ void splitStrings(ArrayRef<uint8_t> a, size_t size);
+ void splitNonStrings(ArrayRef<uint8_t> a, size_t size);
};
struct EhSectionPiece {
- EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
- unsigned FirstRelocation)
- : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
+ EhSectionPiece(size_t off, InputSectionBase *sec, uint32_t size,
+ unsigned firstRelocation)
+ : inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {}
ArrayRef<uint8_t> data() {
- return {Sec->data().data() + this->InputOff, Size};
+ return {sec->data().data() + this->inputOff, size};
}
- size_t InputOff;
- ssize_t OutputOff = -1;
- InputSectionBase *Sec;
- uint32_t Size;
- unsigned FirstRelocation;
+ size_t inputOff;
+ ssize_t outputOff = -1;
+ InputSectionBase *sec;
+ uint32_t size;
+ unsigned firstRelocation;
};
// This corresponds to a .eh_frame section of an input file.
class EhInputSection : public InputSectionBase {
public:
template <class ELFT>
- EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
- StringRef Name);
- static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
+ EhInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
+ StringRef name);
+ static bool classof(const SectionBase *s) { return s->kind() == EHFrame; }
template <class ELFT> void split();
- template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
+ template <class ELFT, class RelTy> void split(ArrayRef<RelTy> rels);
// Splittable sections are handled as a sequence of data
// rather than a single large blob of data.
- std::vector<EhSectionPiece> Pieces;
+ std::vector<EhSectionPiece> pieces;
SyntheticSection *getParent() const;
};
@@ -324,17 +324,17 @@ public:
// .eh_frame. It also includes the synthetic sections themselves.
class InputSection : public InputSectionBase {
public:
- InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
- ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
+ InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t alignment,
+ ArrayRef<uint8_t> data, StringRef name, Kind k = Regular);
template <class ELFT>
- InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
- StringRef Name);
+ InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
+ StringRef name);
// Write this section to a mmap'ed file, assuming Buf is pointing to
// beginning of the output section.
- template <class ELFT> void writeTo(uint8_t *Buf);
+ template <class ELFT> void writeTo(uint8_t *buf);
- uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
+ uint64_t getOffset(uint64_t offset) const { return outSecOff + offset; }
OutputSection *getParent() const;
@@ -342,32 +342,32 @@ public:
// OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
// sections. After assignAddresses is called, it represents the offset from
// the beginning of the output section this section was assigned to.
- uint64_t OutSecOff = 0;
+ uint64_t outSecOff = 0;
- static bool classof(const SectionBase *S);
+ static bool classof(const SectionBase *s);
InputSectionBase *getRelocatedSection() const;
template <class ELFT, class RelTy>
- void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
+ void relocateNonAlloc(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
// Used by ICF.
- uint32_t Class[2] = {0, 0};
+ uint32_t eqClass[2] = {0, 0};
// Called by ICF to merge two input sections.
- void replace(InputSection *Other);
+ void replace(InputSection *other);
- static InputSection Discarded;
+ static InputSection discarded;
private:
template <class ELFT, class RelTy>
- void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
+ void copyRelocations(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
- template <class ELFT> void copyShtGroup(uint8_t *Buf);
+ template <class ELFT> void copyShtGroup(uint8_t *buf);
};
// The list of all input sections.
-extern std::vector<InputSectionBase *> InputSections;
+extern std::vector<InputSectionBase *> inputSections;
} // namespace elf
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 361205973c0..7230cc51044 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -47,135 +47,135 @@ using namespace lld::elf;
// Creates an empty file to store a list of object files for final
// linking of distributed ThinLTO.
-static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) {
- std::error_code EC;
- auto Ret =
- llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None);
- if (EC) {
- error("cannot open " + File + ": " + EC.message());
+static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) {
+ std::error_code ec;
+ auto ret =
+ llvm::make_unique<raw_fd_ostream>(file, ec, sys::fs::OpenFlags::F_None);
+ if (ec) {
+ error("cannot open " + file + ": " + ec.message());
return nullptr;
}
- return Ret;
+ return ret;
}
-static std::string getThinLTOOutputFile(StringRef ModulePath) {
- return lto::getThinLTOOutputFile(ModulePath,
- Config->ThinLTOPrefixReplace.first,
- Config->ThinLTOPrefixReplace.second);
+static std::string getThinLTOOutputFile(StringRef modulePath) {
+ return lto::getThinLTOOutputFile(modulePath,
+ config->thinLTOPrefixReplace.first,
+ config->thinLTOPrefixReplace.second);
}
static lto::Config createConfig() {
- lto::Config C;
+ lto::Config c;
// LLD supports the new relocations and address-significance tables.
- C.Options = initTargetOptionsFromCodeGenFlags();
- C.Options.RelaxELFRelocations = true;
- C.Options.EmitAddrsig = true;
+ c.Options = initTargetOptionsFromCodeGenFlags();
+ c.Options.RelaxELFRelocations = true;
+ c.Options.EmitAddrsig = true;
// Always emit a section per function/datum with LTO.
- C.Options.FunctionSections = true;
- C.Options.DataSections = true;
+ c.Options.FunctionSections = true;
+ c.Options.DataSections = true;
- if (Config->Relocatable)
- C.RelocModel = None;
- else if (Config->Pic)
- C.RelocModel = Reloc::PIC_;
+ if (config->relocatable)
+ c.RelocModel = None;
+ else if (config->isPic)
+ c.RelocModel = Reloc::PIC_;
else
- C.RelocModel = Reloc::Static;
+ c.RelocModel = Reloc::Static;
- C.CodeModel = getCodeModelFromCMModel();
- C.DisableVerify = Config->DisableVerify;
- C.DiagHandler = diagnosticHandler;
- C.OptLevel = Config->LTOO;
- C.CPU = getCPUStr();
- C.MAttrs = getMAttrs();
- C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
+ c.CodeModel = getCodeModelFromCMModel();
+ c.DisableVerify = config->disableVerify;
+ c.DiagHandler = diagnosticHandler;
+ c.OptLevel = config->ltoo;
+ c.CPU = getCPUStr();
+ c.MAttrs = getMAttrs();
+ c.CGOptLevel = args::getCGOptLevel(config->ltoo);
// Set up a custom pipeline if we've been asked to.
- C.OptPipeline = Config->LTONewPmPasses;
- C.AAPipeline = Config->LTOAAPipeline;
+ c.OptPipeline = config->ltoNewPmPasses;
+ c.AAPipeline = config->ltoAAPipeline;
// Set up optimization remarks if we've been asked to.
- C.RemarksFilename = Config->OptRemarksFilename;
- C.RemarksPasses = Config->OptRemarksPasses;
- C.RemarksWithHotness = Config->OptRemarksWithHotness;
- C.RemarksFormat = Config->OptRemarksFormat;
-
- C.SampleProfile = Config->LTOSampleProfile;
- C.UseNewPM = Config->LTONewPassManager;
- C.DebugPassManager = Config->LTODebugPassManager;
- C.DwoDir = Config->DwoDir;
-
- C.CSIRProfile = Config->LTOCSProfileFile;
- C.RunCSIRInstr = Config->LTOCSProfileGenerate;
-
- if (Config->EmitLLVM) {
- C.PostInternalizeModuleHook = [](size_t Task, const Module &M) {
- if (std::unique_ptr<raw_fd_ostream> OS = openFile(Config->OutputFile))
- WriteBitcodeToFile(M, *OS, false);
+ c.RemarksFilename = config->optRemarksFilename;
+ c.RemarksPasses = config->optRemarksPasses;
+ c.RemarksWithHotness = config->optRemarksWithHotness;
+ c.RemarksFormat = config->optRemarksFormat;
+
+ c.SampleProfile = config->ltoSampleProfile;
+ c.UseNewPM = config->ltoNewPassManager;
+ c.DebugPassManager = config->ltoDebugPassManager;
+ c.DwoDir = config->dwoDir;
+
+ c.CSIRProfile = config->ltoCSProfileFile;
+ c.RunCSIRInstr = config->ltoCSProfileGenerate;
+
+ if (config->emitLLVM) {
+ c.PostInternalizeModuleHook = [](size_t task, const Module &m) {
+ if (std::unique_ptr<raw_fd_ostream> os = openFile(config->outputFile))
+ WriteBitcodeToFile(m, *os, false);
return false;
};
}
- if (Config->SaveTemps)
- checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
+ if (config->saveTemps)
+ checkError(c.addSaveTemps(config->outputFile.str() + ".",
/*UseInputModulePath*/ true));
- return C;
+ return c;
}
BitcodeCompiler::BitcodeCompiler() {
// Initialize IndexFile.
- if (!Config->ThinLTOIndexOnlyArg.empty())
- IndexFile = openFile(Config->ThinLTOIndexOnlyArg);
+ if (!config->thinLTOIndexOnlyArg.empty())
+ indexFile = openFile(config->thinLTOIndexOnlyArg);
// Initialize LTOObj.
- lto::ThinBackend Backend;
- if (Config->ThinLTOIndexOnly) {
- auto OnIndexWrite = [&](StringRef S) { ThinIndices.erase(S); };
- Backend = lto::createWriteIndexesThinBackend(
- Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
- Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
- } else if (Config->ThinLTOJobs != -1U) {
- Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
+ lto::ThinBackend backend;
+ if (config->thinLTOIndexOnly) {
+ auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
+ backend = lto::createWriteIndexesThinBackend(
+ config->thinLTOPrefixReplace.first, config->thinLTOPrefixReplace.second,
+ config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
+ } else if (config->thinLTOJobs != -1U) {
+ backend = lto::createInProcessThinBackend(config->thinLTOJobs);
}
- LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend,
- Config->LTOPartitions);
+ ltoObj = llvm::make_unique<lto::LTO>(createConfig(), backend,
+ config->ltoPartitions);
// Initialize UsedStartStop.
- Symtab->forEachSymbol([&](Symbol *Sym) {
- StringRef S = Sym->getName();
- for (StringRef Prefix : {"__start_", "__stop_"})
- if (S.startswith(Prefix))
- UsedStartStop.insert(S.substr(Prefix.size()));
+ symtab->forEachSymbol([&](Symbol *sym) {
+ StringRef s = sym->getName();
+ for (StringRef prefix : {"__start_", "__stop_"})
+ if (s.startswith(prefix))
+ usedStartStop.insert(s.substr(prefix.size()));
});
}
BitcodeCompiler::~BitcodeCompiler() = default;
-void BitcodeCompiler::add(BitcodeFile &F) {
- lto::InputFile &Obj = *F.Obj;
- bool IsExec = !Config->Shared && !Config->Relocatable;
+void BitcodeCompiler::add(BitcodeFile &f) {
+ lto::InputFile &obj = *f.obj;
+ bool isExec = !config->shared && !config->relocatable;
- if (Config->ThinLTOIndexOnly)
- ThinIndices.insert(Obj.getName());
+ if (config->thinLTOIndexOnly)
+ thinIndices.insert(obj.getName());
- ArrayRef<Symbol *> Syms = F.getSymbols();
- ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
- std::vector<lto::SymbolResolution> Resols(Syms.size());
+ ArrayRef<Symbol *> syms = f.getSymbols();
+ ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
+ std::vector<lto::SymbolResolution> resols(syms.size());
// Provide a resolution to the LTO API for each symbol.
- for (size_t I = 0, E = Syms.size(); I != E; ++I) {
- Symbol *Sym = Syms[I];
- const lto::InputFile::Symbol &ObjSym = ObjSyms[I];
- lto::SymbolResolution &R = Resols[I];
+ for (size_t i = 0, e = syms.size(); i != e; ++i) {
+ Symbol *sym = syms[i];
+ const lto::InputFile::Symbol &objSym = objSyms[i];
+ lto::SymbolResolution &r = resols[i];
// Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
// reports two symbols for module ASM defined. Without this check, lld
// flags an undefined in IR with a definition in ASM as prevailing.
// Once IRObjectFile is fixed to report only one symbol this hack can
// be removed.
- R.Prevailing = !ObjSym.isUndefined() && Sym->File == &F;
+ r.Prevailing = !objSym.isUndefined() && sym->file == &f;
// We ask LTO to preserve following global symbols:
// 1) All symbols when doing relocatable link, so that them can be used
@@ -183,121 +183,121 @@ void BitcodeCompiler::add(BitcodeFile &F) {
// 2) Symbols that are used in regular objects.
// 3) C named sections if we have corresponding __start_/__stop_ symbol.
// 4) Symbols that are defined in bitcode files and used for dynamic linking.
- R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
- (R.Prevailing && Sym->includeInDynsym()) ||
- UsedStartStop.count(ObjSym.getSectionName());
- const auto *DR = dyn_cast<Defined>(Sym);
- R.FinalDefinitionInLinkageUnit =
- (IsExec || Sym->Visibility != STV_DEFAULT) && DR &&
+ r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
+ (r.Prevailing && sym->includeInDynsym()) ||
+ usedStartStop.count(objSym.getSectionName());
+ const auto *dr = dyn_cast<Defined>(sym);
+ r.FinalDefinitionInLinkageUnit =
+ (isExec || sym->visibility != STV_DEFAULT) && dr &&
// Skip absolute symbols from ELF objects, otherwise PC-rel relocations
// will be generated by for them, triggering linker errors.
// Symbol section is always null for bitcode symbols, hence the check
// for isElf(). Skip linker script defined symbols as well: they have
// no File defined.
- !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf()));
+ !(dr->section == nullptr && (!sym->file || sym->file->isElf()));
- if (R.Prevailing)
- Sym->replace(Undefined{nullptr, Sym->getName(), STB_GLOBAL, STV_DEFAULT,
- Sym->Type});
+ if (r.Prevailing)
+ sym->replace(Undefined{nullptr, sym->getName(), STB_GLOBAL, STV_DEFAULT,
+ sym->type});
// We tell LTO to not apply interprocedural optimization for wrapped
// (with --wrap) symbols because otherwise LTO would inline them while
// their values are still not final.
- R.LinkerRedefined = !Sym->CanInline;
+ r.LinkerRedefined = !sym->canInline;
}
- checkError(LTOObj->add(std::move(F.Obj), Resols));
+ checkError(ltoObj->add(std::move(f.obj), resols));
}
// If LazyObjFile has not been added to link, emit empty index files.
// This is needed because this is what GNU gold plugin does and we have a
// distributed build system that depends on that behavior.
static void thinLTOCreateEmptyIndexFiles() {
- for (LazyObjFile *F : LazyObjFiles) {
- if (!isBitcode(F->MB))
+ for (LazyObjFile *f : lazyObjFiles) {
+ if (!isBitcode(f->mb))
continue;
- std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(F->getName()));
- std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
- if (!OS)
+ std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName()));
+ std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");
+ if (!os)
continue;
- ModuleSummaryIndex M(/*HaveGVs*/ false);
- M.setSkipModuleByDistributedBackend();
- WriteIndexToFile(M, *OS);
- if (Config->ThinLTOEmitImportsFiles)
- openFile(Path + ".imports");
+ ModuleSummaryIndex m(/*HaveGVs*/ false);
+ m.setSkipModuleByDistributedBackend();
+ WriteIndexToFile(m, *os);
+ if (config->thinLTOEmitImportsFiles)
+ openFile(path + ".imports");
}
}
// Merge all the bitcode files we have seen, codegen the result
// and return the resulting ObjectFile(s).
std::vector<InputFile *> BitcodeCompiler::compile() {
- unsigned MaxTasks = LTOObj->getMaxTasks();
- Buf.resize(MaxTasks);
- Files.resize(MaxTasks);
+ unsigned maxTasks = ltoObj->getMaxTasks();
+ buf.resize(maxTasks);
+ files.resize(maxTasks);
// The --thinlto-cache-dir option specifies the path to a directory in which
// to cache native object files for ThinLTO incremental builds. If a path was
// specified, configure LTO to use it as the cache directory.
- lto::NativeObjectCache Cache;
- if (!Config->ThinLTOCacheDir.empty())
- Cache = check(
- lto::localCache(Config->ThinLTOCacheDir,
- [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
- Files[Task] = std::move(MB);
+ lto::NativeObjectCache cache;
+ if (!config->thinLTOCacheDir.empty())
+ cache = check(
+ lto::localCache(config->thinLTOCacheDir,
+ [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
+ files[task] = std::move(mb);
}));
- if (!BitcodeFiles.empty())
- checkError(LTOObj->run(
- [&](size_t Task) {
+ if (!bitcodeFiles.empty())
+ checkError(ltoObj->run(
+ [&](size_t task) {
return llvm::make_unique<lto::NativeObjectStream>(
- llvm::make_unique<raw_svector_ostream>(Buf[Task]));
+ llvm::make_unique<raw_svector_ostream>(buf[task]));
},
- Cache));
+ cache));
// Emit empty index files for non-indexed files
- for (StringRef S : ThinIndices) {
- std::string Path = getThinLTOOutputFile(S);
- openFile(Path + ".thinlto.bc");
- if (Config->ThinLTOEmitImportsFiles)
- openFile(Path + ".imports");
+ for (StringRef s : thinIndices) {
+ std::string path = getThinLTOOutputFile(s);
+ openFile(path + ".thinlto.bc");
+ if (config->thinLTOEmitImportsFiles)
+ openFile(path + ".imports");
}
- if (Config->ThinLTOIndexOnly) {
+ if (config->thinLTOIndexOnly) {
thinLTOCreateEmptyIndexFiles();
- if (!Config->LTOObjPath.empty())
- saveBuffer(Buf[0], Config->LTOObjPath);
+ if (!config->ltoObjPath.empty())
+ saveBuffer(buf[0], config->ltoObjPath);
// ThinLTO with index only option is required to generate only the index
// files. After that, we exit from linker and ThinLTO backend runs in a
// distributed environment.
- if (IndexFile)
- IndexFile->close();
+ if (indexFile)
+ indexFile->close();
return {};
}
- if (!Config->ThinLTOCacheDir.empty())
- pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
+ if (!config->thinLTOCacheDir.empty())
+ pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy);
- if (!Config->LTOObjPath.empty()) {
- saveBuffer(Buf[0], Config->LTOObjPath);
- for (unsigned I = 1; I != MaxTasks; ++I)
- saveBuffer(Buf[I], Config->LTOObjPath + Twine(I));
+ if (!config->ltoObjPath.empty()) {
+ saveBuffer(buf[0], config->ltoObjPath);
+ for (unsigned i = 1; i != maxTasks; ++i)
+ saveBuffer(buf[i], config->ltoObjPath + Twine(i));
}
- if (Config->SaveTemps) {
- saveBuffer(Buf[0], Config->OutputFile + ".lto.o");
- for (unsigned I = 1; I != MaxTasks; ++I)
- saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
+ if (config->saveTemps) {
+ saveBuffer(buf[0], config->outputFile + ".lto.o");
+ for (unsigned i = 1; i != maxTasks; ++i)
+ saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
}
- std::vector<InputFile *> Ret;
- for (unsigned I = 0; I != MaxTasks; ++I)
- if (!Buf[I].empty())
- Ret.push_back(createObjectFile(MemoryBufferRef(Buf[I], "lto.tmp")));
+ std::vector<InputFile *> ret;
+ for (unsigned i = 0; i != maxTasks; ++i)
+ if (!buf[i].empty())
+ ret.push_back(createObjectFile(MemoryBufferRef(buf[i], "lto.tmp")));
- for (std::unique_ptr<MemoryBuffer> &File : Files)
- if (File)
- Ret.push_back(createObjectFile(*File));
- return Ret;
+ for (std::unique_ptr<MemoryBuffer> &file : files)
+ if (file)
+ ret.push_back(createObjectFile(*file));
+ return ret;
}
diff --git a/lld/ELF/LTO.h b/lld/ELF/LTO.h
index 0f0b5bce718..4cb42d84d91 100644
--- a/lld/ELF/LTO.h
+++ b/lld/ELF/LTO.h
@@ -45,16 +45,16 @@ public:
BitcodeCompiler();
~BitcodeCompiler();
- void add(BitcodeFile &F);
+ void add(BitcodeFile &f);
std::vector<InputFile *> compile();
private:
- std::unique_ptr<llvm::lto::LTO> LTOObj;
- std::vector<SmallString<0>> Buf;
- std::vector<std::unique_ptr<MemoryBuffer>> Files;
- llvm::DenseSet<StringRef> UsedStartStop;
- std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
- llvm::DenseSet<StringRef> ThinIndices;
+ std::unique_ptr<llvm::lto::LTO> ltoObj;
+ std::vector<SmallString<0>> buf;
+ std::vector<std::unique_ptr<MemoryBuffer>> files;
+ llvm::DenseSet<StringRef> usedStartStop;
+ std::unique_ptr<llvm::raw_fd_ostream> indexFile;
+ llvm::DenseSet<StringRef> thinIndices;
};
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index b964a542015..ce009149710 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -46,26 +46,26 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
-LinkerScript *elf::Script;
+LinkerScript *elf::script;
-static uint64_t getOutputSectionVA(SectionBase *InputSec, StringRef Loc) {
- if (OutputSection *OS = InputSec->getOutputSection())
- return OS->Addr;
- error(Loc + ": unable to evaluate expression: input section " +
- InputSec->Name + " has no output section assigned");
+static uint64_t getOutputSectionVA(SectionBase *inputSec, StringRef loc) {
+ if (OutputSection *os = inputSec->getOutputSection())
+ return os->addr;
+ error(loc + ": unable to evaluate expression: input section " +
+ inputSec->name + " has no output section assigned");
return 0;
}
uint64_t ExprValue::getValue() const {
- if (Sec)
- return alignTo(Sec->getOffset(Val) + getOutputSectionVA(Sec, Loc),
- Alignment);
- return alignTo(Val, Alignment);
+ if (sec)
+ return alignTo(sec->getOffset(val) + getOutputSectionVA(sec, loc),
+ alignment);
+ return alignTo(val, alignment);
}
uint64_t ExprValue::getSecAddr() const {
- if (Sec)
- return Sec->getOffset(0) + getOutputSectionVA(Sec, Loc);
+ if (sec)
+ return sec->getOffset(0) + getOutputSectionVA(sec, loc);
return 0;
}
@@ -73,100 +73,100 @@ uint64_t ExprValue::getSectionOffset() const {
// If the alignment is trivial, we don't have to compute the full
// value to know the offset. This allows this function to succeed in
// cases where the output section is not yet known.
- if (Alignment == 1 && (!Sec || !Sec->getOutputSection()))
- return Val;
+ if (alignment == 1 && (!sec || !sec->getOutputSection()))
+ return val;
return getValue() - getSecAddr();
}
-OutputSection *LinkerScript::createOutputSection(StringRef Name,
- StringRef Location) {
- OutputSection *&SecRef = NameToOutputSection[Name];
- OutputSection *Sec;
- if (SecRef && SecRef->Location.empty()) {
+OutputSection *LinkerScript::createOutputSection(StringRef name,
+ StringRef location) {
+ OutputSection *&secRef = nameToOutputSection[name];
+ OutputSection *sec;
+ if (secRef && secRef->location.empty()) {
// There was a forward reference.
- Sec = SecRef;
+ sec = secRef;
} else {
- Sec = make<OutputSection>(Name, SHT_PROGBITS, 0);
- if (!SecRef)
- SecRef = Sec;
+ sec = make<OutputSection>(name, SHT_PROGBITS, 0);
+ if (!secRef)
+ secRef = sec;
}
- Sec->Location = Location;
- return Sec;
+ sec->location = location;
+ return sec;
}
-OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) {
- OutputSection *&CmdRef = NameToOutputSection[Name];
- if (!CmdRef)
- CmdRef = make<OutputSection>(Name, SHT_PROGBITS, 0);
- return CmdRef;
+OutputSection *LinkerScript::getOrCreateOutputSection(StringRef name) {
+ OutputSection *&cmdRef = nameToOutputSection[name];
+ if (!cmdRef)
+ cmdRef = make<OutputSection>(name, SHT_PROGBITS, 0);
+ return cmdRef;
}
// Expands the memory region by the specified size.
-static void expandMemoryRegion(MemoryRegion *MemRegion, uint64_t Size,
- StringRef RegionName, StringRef SecName) {
- MemRegion->CurPos += Size;
- uint64_t NewSize = MemRegion->CurPos - MemRegion->Origin;
- if (NewSize > MemRegion->Length)
- error("section '" + SecName + "' will not fit in region '" + RegionName +
- "': overflowed by " + Twine(NewSize - MemRegion->Length) + " bytes");
+static void expandMemoryRegion(MemoryRegion *memRegion, uint64_t size,
+ StringRef regionName, StringRef secName) {
+ memRegion->curPos += size;
+ uint64_t newSize = memRegion->curPos - memRegion->origin;
+ if (newSize > memRegion->length)
+ error("section '" + secName + "' will not fit in region '" + regionName +
+ "': overflowed by " + Twine(newSize - memRegion->length) + " bytes");
}
-void LinkerScript::expandMemoryRegions(uint64_t Size) {
- if (Ctx->MemRegion)
- expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name,
- Ctx->OutSec->Name);
+void LinkerScript::expandMemoryRegions(uint64_t size) {
+ if (ctx->memRegion)
+ expandMemoryRegion(ctx->memRegion, size, ctx->memRegion->name,
+ ctx->outSec->name);
// Only expand the LMARegion if it is different from MemRegion.
- if (Ctx->LMARegion && Ctx->MemRegion != Ctx->LMARegion)
- expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name,
- Ctx->OutSec->Name);
+ if (ctx->lmaRegion && ctx->memRegion != ctx->lmaRegion)
+ expandMemoryRegion(ctx->lmaRegion, size, ctx->lmaRegion->name,
+ ctx->outSec->name);
}
-void LinkerScript::expandOutputSection(uint64_t Size) {
- Ctx->OutSec->Size += Size;
- expandMemoryRegions(Size);
+void LinkerScript::expandOutputSection(uint64_t size) {
+ ctx->outSec->size += size;
+ expandMemoryRegions(size);
}
-void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
- uint64_t Val = E().getValue();
- if (Val < Dot && InSec)
- error(Loc + ": unable to move location counter backward for: " +
- Ctx->OutSec->Name);
+void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
+ uint64_t val = e().getValue();
+ if (val < dot && inSec)
+ error(loc + ": unable to move location counter backward for: " +
+ ctx->outSec->name);
// Update to location counter means update to section size.
- if (InSec)
- expandOutputSection(Val - Dot);
+ if (inSec)
+ expandOutputSection(val - dot);
- Dot = Val;
+ dot = val;
}
// Used for handling linker symbol assignments, for both finalizing
// their values and doing early declarations. Returns true if symbol
// should be defined from linker script.
-static bool shouldDefineSym(SymbolAssignment *Cmd) {
- if (Cmd->Name == ".")
+static bool shouldDefineSym(SymbolAssignment *cmd) {
+ if (cmd->name == ".")
return false;
- if (!Cmd->Provide)
+ if (!cmd->provide)
return true;
// If a symbol was in PROVIDE(), we need to define it only
// when it is a referenced undefined symbol.
- Symbol *B = Symtab->find(Cmd->Name);
- if (B && !B->isDefined())
+ Symbol *b = symtab->find(cmd->name);
+ if (b && !b->isDefined())
return true;
return false;
}
// This function is called from processSectionCommands,
// while we are fixing the output section layout.
-void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
- if (!shouldDefineSym(Cmd))
+void LinkerScript::addSymbol(SymbolAssignment *cmd) {
+ if (!shouldDefineSym(cmd))
return;
// Define a symbol.
- ExprValue Value = Cmd->Expression();
- SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
- uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+ ExprValue value = cmd->expression();
+ SectionBase *sec = value.isAbsolute() ? nullptr : value.sec;
+ uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
// When this function is called, section addresses have not been
// fixed yet. So, we may or may not know the value of the RHS
@@ -179,73 +179,73 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
// We want to set symbol values early if we can. This allows us to
// use symbols as variables in linker scripts. Doing so allows us to
// write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
- uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
+ uint64_t symValue = value.sec ? 0 : value.getValue();
- Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue,
- 0, Sec);
+ Defined New(nullptr, cmd->name, STB_GLOBAL, visibility, STT_NOTYPE, symValue,
+ 0, sec);
- Symbol *Sym = Symtab->insert(Cmd->Name);
- Sym->mergeProperties(New);
- Sym->replace(New);
- Cmd->Sym = cast<Defined>(Sym);
+ Symbol *sym = symtab->insert(cmd->name);
+ sym->mergeProperties(New);
+ sym->replace(New);
+ cmd->sym = cast<Defined>(sym);
}
// This function is called from LinkerScript::declareSymbols.
// It creates a placeholder symbol if needed.
-static void declareSymbol(SymbolAssignment *Cmd) {
- if (!shouldDefineSym(Cmd))
+static void declareSymbol(SymbolAssignment *cmd) {
+ if (!shouldDefineSym(cmd))
return;
- uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, 0, 0,
+ uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
+ Defined New(nullptr, cmd->name, STB_GLOBAL, visibility, STT_NOTYPE, 0, 0,
nullptr);
// We can't calculate final value right now.
- Symbol *Sym = Symtab->insert(Cmd->Name);
- Sym->mergeProperties(New);
- Sym->replace(New);
+ Symbol *sym = symtab->insert(cmd->name);
+ sym->mergeProperties(New);
+ sym->replace(New);
- Cmd->Sym = cast<Defined>(Sym);
- Cmd->Provide = false;
- Sym->ScriptDefined = true;
+ cmd->sym = cast<Defined>(sym);
+ cmd->provide = false;
+ sym->scriptDefined = true;
}
// This method is used to handle INSERT AFTER statement. Here we rebuild
// the list of script commands to mix sections inserted into.
void LinkerScript::processInsertCommands() {
- std::vector<BaseCommand *> V;
- auto Insert = [&](std::vector<BaseCommand *> &From) {
- V.insert(V.end(), From.begin(), From.end());
- From.clear();
+ std::vector<BaseCommand *> v;
+ auto insert = [&](std::vector<BaseCommand *> &from) {
+ v.insert(v.end(), from.begin(), from.end());
+ from.clear();
};
- for (BaseCommand *Base : SectionCommands) {
- if (auto *OS = dyn_cast<OutputSection>(Base)) {
- Insert(InsertBeforeCommands[OS->Name]);
- V.push_back(Base);
- Insert(InsertAfterCommands[OS->Name]);
+ for (BaseCommand *base : sectionCommands) {
+ if (auto *os = dyn_cast<OutputSection>(base)) {
+ insert(insertBeforeCommands[os->name]);
+ v.push_back(base);
+ insert(insertAfterCommands[os->name]);
continue;
}
- V.push_back(Base);
+ v.push_back(base);
}
- for (auto &Cmds : {InsertBeforeCommands, InsertAfterCommands})
- for (const std::pair<StringRef, std::vector<BaseCommand *>> &P : Cmds)
- if (!P.second.empty())
- error("unable to INSERT AFTER/BEFORE " + P.first +
+ for (auto &cmds : {insertBeforeCommands, insertAfterCommands})
+ for (const std::pair<StringRef, std::vector<BaseCommand *>> &p : cmds)
+ if (!p.second.empty())
+ error("unable to INSERT AFTER/BEFORE " + p.first +
": section not defined");
- SectionCommands = std::move(V);
+ sectionCommands = std::move(v);
}
// Symbols defined in script should not be inlined by LTO. At the same time
// we don't know their final values until late stages of link. Here we scan
// over symbol assignment commands and create placeholder symbols if needed.
void LinkerScript::declareSymbols() {
- assert(!Ctx);
- for (BaseCommand *Base : SectionCommands) {
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- declareSymbol(Cmd);
+ assert(!ctx);
+ for (BaseCommand *base : sectionCommands) {
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ declareSymbol(cmd);
continue;
}
@@ -253,75 +253,75 @@ void LinkerScript::declareSymbols() {
// we can't say for sure if it is going to be included or not.
// Skip such sections for now. Improve the checks if we ever
// need symbols from that sections to be declared early.
- auto *Sec = cast<OutputSection>(Base);
- if (Sec->Constraint != ConstraintKind::NoConstraint)
+ auto *sec = cast<OutputSection>(base);
+ if (sec->constraint != ConstraintKind::NoConstraint)
continue;
- for (BaseCommand *Base2 : Sec->SectionCommands)
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base2))
- declareSymbol(Cmd);
+ for (BaseCommand *base2 : sec->sectionCommands)
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base2))
+ declareSymbol(cmd);
}
}
// This function is called from assignAddresses, while we are
// fixing the output section addresses. This function is supposed
// to set the final value for a given symbol assignment.
-void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
- if (Cmd->Name == ".") {
- setDot(Cmd->Expression, Cmd->Location, InSec);
+void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
+ if (cmd->name == ".") {
+ setDot(cmd->expression, cmd->location, inSec);
return;
}
- if (!Cmd->Sym)
+ if (!cmd->sym)
return;
- ExprValue V = Cmd->Expression();
- if (V.isAbsolute()) {
- Cmd->Sym->Section = nullptr;
- Cmd->Sym->Value = V.getValue();
+ ExprValue v = cmd->expression();
+ if (v.isAbsolute()) {
+ cmd->sym->section = nullptr;
+ cmd->sym->value = v.getValue();
} else {
- Cmd->Sym->Section = V.Sec;
- Cmd->Sym->Value = V.getSectionOffset();
+ cmd->sym->section = v.sec;
+ cmd->sym->value = v.getSectionOffset();
}
}
-static std::string getFilename(InputFile *File) {
- if (!File)
+static std::string getFilename(InputFile *file) {
+ if (!file)
return "";
- if (File->ArchiveName.empty())
- return File->getName();
- return (File->ArchiveName + "(" + File->getName() + ")").str();
+ if (file->archiveName.empty())
+ return file->getName();
+ return (file->archiveName + "(" + file->getName() + ")").str();
}
-bool LinkerScript::shouldKeep(InputSectionBase *S) {
- if (KeptSections.empty())
+bool LinkerScript::shouldKeep(InputSectionBase *s) {
+ if (keptSections.empty())
return false;
- std::string Filename = getFilename(S->File);
- for (InputSectionDescription *ID : KeptSections)
- if (ID->FilePat.match(Filename))
- for (SectionPattern &P : ID->SectionPatterns)
- if (P.SectionPat.match(S->Name))
+ std::string filename = getFilename(s->file);
+ for (InputSectionDescription *id : keptSections)
+ if (id->filePat.match(filename))
+ for (SectionPattern &p : id->sectionPatterns)
+ if (p.sectionPat.match(s->name))
return true;
return false;
}
// A helper function for the SORT() command.
static std::function<bool(InputSectionBase *, InputSectionBase *)>
-getComparator(SortSectionPolicy K) {
- switch (K) {
+getComparator(SortSectionPolicy k) {
+ switch (k) {
case SortSectionPolicy::Alignment:
- return [](InputSectionBase *A, InputSectionBase *B) {
+ return [](InputSectionBase *a, InputSectionBase *b) {
// ">" is not a mistake. Sections with larger alignments are placed
// before sections with smaller alignments in order to reduce the
// amount of padding necessary. This is compatible with GNU.
- return A->Alignment > B->Alignment;
+ return a->alignment > b->alignment;
};
case SortSectionPolicy::Name:
- return [](InputSectionBase *A, InputSectionBase *B) {
- return A->Name < B->Name;
+ return [](InputSectionBase *a, InputSectionBase *b) {
+ return a->name < b->name;
};
case SortSectionPolicy::Priority:
- return [](InputSectionBase *A, InputSectionBase *B) {
- return getPriority(A->Name) < getPriority(B->Name);
+ return [](InputSectionBase *a, InputSectionBase *b) {
+ return getPriority(a->name) < getPriority(b->name);
};
default:
llvm_unreachable("unknown sort policy");
@@ -329,22 +329,22 @@ getComparator(SortSectionPolicy K) {
}
// A helper function for the SORT() command.
-static bool matchConstraints(ArrayRef<InputSection *> Sections,
- ConstraintKind Kind) {
- if (Kind == ConstraintKind::NoConstraint)
+static bool matchConstraints(ArrayRef<InputSection *> sections,
+ ConstraintKind kind) {
+ if (kind == ConstraintKind::NoConstraint)
return true;
- bool IsRW = llvm::any_of(
- Sections, [](InputSection *Sec) { return Sec->Flags & SHF_WRITE; });
+ bool isRW = llvm::any_of(
+ sections, [](InputSection *sec) { return sec->flags & SHF_WRITE; });
- return (IsRW && Kind == ConstraintKind::ReadWrite) ||
- (!IsRW && Kind == ConstraintKind::ReadOnly);
+ return (isRW && kind == ConstraintKind::ReadWrite) ||
+ (!isRW && kind == ConstraintKind::ReadOnly);
}
-static void sortSections(MutableArrayRef<InputSection *> Vec,
- SortSectionPolicy K) {
- if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
- llvm::stable_sort(Vec, getComparator(K));
+static void sortSections(MutableArrayRef<InputSection *> vec,
+ SortSectionPolicy k) {
+ if (k != SortSectionPolicy::Default && k != SortSectionPolicy::None)
+ llvm::stable_sort(vec, getComparator(k));
}
// Sort sections as instructed by SORT-family commands and --sort-section
@@ -358,29 +358,29 @@ static void sortSections(MutableArrayRef<InputSection *> Vec,
// --sort-section is handled as an inner SORT command.
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
// 4. If no SORT command is given, sort according to --sort-section.
-static void sortInputSections(MutableArrayRef<InputSection *> Vec,
- const SectionPattern &Pat) {
- if (Pat.SortOuter == SortSectionPolicy::None)
+static void sortInputSections(MutableArrayRef<InputSection *> vec,
+ const SectionPattern &pat) {
+ if (pat.sortOuter == SortSectionPolicy::None)
return;
- if (Pat.SortInner == SortSectionPolicy::Default)
- sortSections(Vec, Config->SortSection);
+ if (pat.sortInner == SortSectionPolicy::Default)
+ sortSections(vec, config->sortSection);
else
- sortSections(Vec, Pat.SortInner);
- sortSections(Vec, Pat.SortOuter);
+ sortSections(vec, pat.sortInner);
+ sortSections(vec, pat.sortOuter);
}
// Compute and remember which sections the InputSectionDescription matches.
std::vector<InputSection *>
-LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
- std::vector<InputSection *> Ret;
+LinkerScript::computeInputSections(const InputSectionDescription *cmd) {
+ std::vector<InputSection *> ret;
// Collects all sections that satisfy constraints of Cmd.
- for (const SectionPattern &Pat : Cmd->SectionPatterns) {
- size_t SizeBefore = Ret.size();
+ for (const SectionPattern &pat : cmd->sectionPatterns) {
+ size_t sizeBefore = ret.size();
- for (InputSectionBase *Sec : InputSections) {
- if (!Sec->isLive() || Sec->Assigned)
+ for (InputSectionBase *sec : inputSections) {
+ if (!sec->isLive() || sec->assigned)
continue;
// For -emit-relocs we have to ignore entries like
@@ -388,59 +388,59 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
// which are common because they are in the default bfd script.
// We do not ignore SHT_REL[A] linker-synthesized sections here because
// want to support scripts that do custom layout for them.
- if (auto *IS = dyn_cast<InputSection>(Sec))
- if (IS->getRelocatedSection())
+ if (auto *isec = dyn_cast<InputSection>(sec))
+ if (isec->getRelocatedSection())
continue;
- std::string Filename = getFilename(Sec->File);
- if (!Cmd->FilePat.match(Filename) ||
- Pat.ExcludedFilePat.match(Filename) ||
- !Pat.SectionPat.match(Sec->Name))
+ std::string filename = getFilename(sec->file);
+ if (!cmd->filePat.match(filename) ||
+ pat.excludedFilePat.match(filename) ||
+ !pat.sectionPat.match(sec->name))
continue;
// It is safe to assume that Sec is an InputSection
// because mergeable or EH input sections have already been
// handled and eliminated.
- Ret.push_back(cast<InputSection>(Sec));
- Sec->Assigned = true;
+ ret.push_back(cast<InputSection>(sec));
+ sec->assigned = true;
}
- sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore),
- Pat);
+ sortInputSections(MutableArrayRef<InputSection *>(ret).slice(sizeBefore),
+ pat);
}
- return Ret;
+ return ret;
}
-void LinkerScript::discard(ArrayRef<InputSection *> V) {
- for (InputSection *S : V) {
- if (S == In.ShStrTab || S == Main->RelaDyn || S == Main->RelrDyn)
- error("discarding " + S->Name + " section is not allowed");
+void LinkerScript::discard(ArrayRef<InputSection *> v) {
+ for (InputSection *s : v) {
+ if (s == in.shStrTab || s == mainPart->relaDyn || s == mainPart->relrDyn)
+ error("discarding " + s->name + " section is not allowed");
// You can discard .hash and .gnu.hash sections by linker scripts. Since
// they are synthesized sections, we need to handle them differently than
// other regular sections.
- if (S == Main->GnuHashTab)
- Main->GnuHashTab = nullptr;
- if (S == Main->HashTab)
- Main->HashTab = nullptr;
-
- S->Assigned = false;
- S->markDead();
- discard(S->DependentSections);
+ if (s == mainPart->gnuHashTab)
+ mainPart->gnuHashTab = nullptr;
+ if (s == mainPart->hashTab)
+ mainPart->hashTab = nullptr;
+
+ s->assigned = false;
+ s->markDead();
+ discard(s->dependentSections);
}
}
std::vector<InputSection *>
-LinkerScript::createInputSectionList(OutputSection &OutCmd) {
- std::vector<InputSection *> Ret;
+LinkerScript::createInputSectionList(OutputSection &outCmd) {
+ std::vector<InputSection *> ret;
- for (BaseCommand *Base : OutCmd.SectionCommands) {
- if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) {
- Cmd->Sections = computeInputSections(Cmd);
- Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
+ for (BaseCommand *base : outCmd.sectionCommands) {
+ if (auto *cmd = dyn_cast<InputSectionDescription>(base)) {
+ cmd->sections = computeInputSections(cmd);
+ ret.insert(ret.end(), cmd->sections.begin(), cmd->sections.end());
}
}
- return Ret;
+ return ret;
}
void LinkerScript::processSectionCommands() {
@@ -453,34 +453,34 @@ void LinkerScript::processSectionCommands() {
// To handle that, create a dummy aether section that fills the void before
// the linker scripts switches to another section. It has an index of one
// which will map to whatever the first actual section is.
- Aether = make<OutputSection>("", 0, SHF_ALLOC);
- Aether->SectionIndex = 1;
+ aether = make<OutputSection>("", 0, SHF_ALLOC);
+ aether->sectionIndex = 1;
// Ctx captures the local AddressState and makes it accessible deliberately.
// This is needed as there are some cases where we cannot just
// thread the current state through to a lambda function created by the
// script parser.
- auto Deleter = make_unique<AddressState>();
- Ctx = Deleter.get();
- Ctx->OutSec = Aether;
+ auto deleter = make_unique<AddressState>();
+ ctx = deleter.get();
+ ctx->outSec = aether;
- size_t I = 0;
+ size_t i = 0;
// Add input sections to output sections.
- for (BaseCommand *Base : SectionCommands) {
+ for (BaseCommand *base : sectionCommands) {
// Handle symbol assignments outside of any output section.
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- addSymbol(Cmd);
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ addSymbol(cmd);
continue;
}
- if (auto *Sec = dyn_cast<OutputSection>(Base)) {
- std::vector<InputSection *> V = createInputSectionList(*Sec);
+ if (auto *sec = dyn_cast<OutputSection>(base)) {
+ std::vector<InputSection *> v = createInputSectionList(*sec);
// The output section name `/DISCARD/' is special.
// Any input section assigned to it is discarded.
- if (Sec->Name == "/DISCARD/") {
- discard(V);
- Sec->SectionCommands.clear();
+ if (sec->name == "/DISCARD/") {
+ discard(v);
+ sec->sectionCommands.clear();
continue;
}
@@ -491,61 +491,61 @@ void LinkerScript::processSectionCommands() {
//
// Because we'll iterate over SectionCommands many more times, the easy
// way to "make it as if it wasn't present" is to make it empty.
- if (!matchConstraints(V, Sec->Constraint)) {
- for (InputSectionBase *S : V)
- S->Assigned = false;
- Sec->SectionCommands.clear();
+ if (!matchConstraints(v, sec->constraint)) {
+ for (InputSectionBase *s : v)
+ s->assigned = false;
+ sec->sectionCommands.clear();
continue;
}
// A directive may contain symbol definitions like this:
// ".foo : { ...; bar = .; }". Handle them.
- for (BaseCommand *Base : Sec->SectionCommands)
- if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
- addSymbol(OutCmd);
+ for (BaseCommand *base : sec->sectionCommands)
+ if (auto *outCmd = dyn_cast<SymbolAssignment>(base))
+ addSymbol(outCmd);
// Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
// is given, input sections are aligned to that value, whether the
// given value is larger or smaller than the original section alignment.
- if (Sec->SubalignExpr) {
- uint32_t Subalign = Sec->SubalignExpr().getValue();
- for (InputSectionBase *S : V)
- S->Alignment = Subalign;
+ if (sec->subalignExpr) {
+ uint32_t subalign = sec->subalignExpr().getValue();
+ for (InputSectionBase *s : v)
+ s->alignment = subalign;
}
// Add input sections to an output section.
- for (InputSection *S : V)
- Sec->addSection(S);
-
- Sec->SectionIndex = I++;
- if (Sec->Noload)
- Sec->Type = SHT_NOBITS;
- if (Sec->NonAlloc)
- Sec->Flags &= ~(uint64_t)SHF_ALLOC;
+ for (InputSection *s : v)
+ sec->addSection(s);
+
+ sec->sectionIndex = i++;
+ if (sec->noload)
+ sec->type = SHT_NOBITS;
+ if (sec->nonAlloc)
+ sec->flags &= ~(uint64_t)SHF_ALLOC;
}
}
- Ctx = nullptr;
+ ctx = nullptr;
}
-static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
- StringRef Name) {
- for (BaseCommand *Base : Vec)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- if (Sec->Name == Name)
- return Sec;
+static OutputSection *findByName(ArrayRef<BaseCommand *> vec,
+ StringRef name) {
+ for (BaseCommand *base : vec)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ if (sec->name == name)
+ return sec;
return nullptr;
}
-static OutputSection *createSection(InputSectionBase *IS,
- StringRef OutsecName) {
- OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>");
- Sec->addSection(cast<InputSection>(IS));
- return Sec;
+static OutputSection *createSection(InputSectionBase *isec,
+ StringRef outsecName) {
+ OutputSection *sec = script->createOutputSection(outsecName, "<internal>");
+ sec->addSection(cast<InputSection>(isec));
+ return sec;
}
static OutputSection *
-addInputSec(StringMap<TinyPtrVector<OutputSection *>> &Map,
- InputSectionBase *IS, StringRef OutsecName) {
+addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
+ InputSectionBase *isec, StringRef outsecName) {
// Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
// option is given. A section with SHT_GROUP defines a "section group", and
// its members have SHF_GROUP attribute. Usually these flags have already been
@@ -553,8 +553,8 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &Map,
// However, for the -r option, we want to pass through all section groups
// as-is because adding/removing members or merging them with other groups
// change their semantics.
- if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP))
- return createSection(IS, OutsecName);
+ if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP))
+ return createSection(isec, outsecName);
// Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
// relocation sections .rela.foo and .rela.bar for example. Most tools do
@@ -562,25 +562,25 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &Map,
// should combine these relocation sections into single output.
// We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
// other REL[A] sections created by linker itself.
- if (!isa<SyntheticSection>(IS) &&
- (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
- auto *Sec = cast<InputSection>(IS);
- OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+ if (!isa<SyntheticSection>(isec) &&
+ (isec->type == SHT_REL || isec->type == SHT_RELA)) {
+ auto *sec = cast<InputSection>(isec);
+ OutputSection *out = sec->getRelocatedSection()->getOutputSection();
- if (Out->RelocationSection) {
- Out->RelocationSection->addSection(Sec);
+ if (out->relocationSection) {
+ out->relocationSection->addSection(sec);
return nullptr;
}
- Out->RelocationSection = createSection(IS, OutsecName);
- return Out->RelocationSection;
+ out->relocationSection = createSection(isec, outsecName);
+ return out->relocationSection;
}
// When control reaches here, mergeable sections have already been merged into
// synthetic sections. For relocatable case we want to create one output
// section per syntetic section so that they have a valid sh_entsize.
- if (Config->Relocatable && (IS->Flags & SHF_MERGE))
- return createSection(IS, OutsecName);
+ if (config->relocatable && (isec->flags & SHF_MERGE))
+ return createSection(isec, outsecName);
// The ELF spec just says
// ----------------------------------------------------------------
@@ -624,161 +624,161 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &Map,
//
// Given the above issues, we instead merge sections by name and error on
// incompatible types and flags.
- TinyPtrVector<OutputSection *> &V = Map[OutsecName];
- for (OutputSection *Sec : V) {
- if (Sec->Partition != IS->Partition)
+ TinyPtrVector<OutputSection *> &v = map[outsecName];
+ for (OutputSection *sec : v) {
+ if (sec->partition != isec->partition)
continue;
- Sec->addSection(cast<InputSection>(IS));
+ sec->addSection(cast<InputSection>(isec));
return nullptr;
}
- OutputSection *Sec = createSection(IS, OutsecName);
- V.push_back(Sec);
- return Sec;
+ OutputSection *sec = createSection(isec, outsecName);
+ v.push_back(sec);
+ return sec;
}
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections() {
- StringMap<TinyPtrVector<OutputSection *>> Map;
- std::vector<OutputSection *> V;
+ StringMap<TinyPtrVector<OutputSection *>> map;
+ std::vector<OutputSection *> v;
- auto Add = [&](InputSectionBase *S) {
- if (!S->isLive() || S->Parent)
+ auto add = [&](InputSectionBase *s) {
+ if (!s->isLive() || s->parent)
return;
- StringRef Name = getOutputSectionName(S);
+ StringRef name = getOutputSectionName(s);
- if (Config->OrphanHandling == OrphanHandlingPolicy::Error)
- error(toString(S) + " is being placed in '" + Name + "'");
- else if (Config->OrphanHandling == OrphanHandlingPolicy::Warn)
- warn(toString(S) + " is being placed in '" + Name + "'");
+ if (config->orphanHandling == OrphanHandlingPolicy::Error)
+ error(toString(s) + " is being placed in '" + name + "'");
+ else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
+ warn(toString(s) + " is being placed in '" + name + "'");
- if (OutputSection *Sec = findByName(SectionCommands, Name)) {
- Sec->addSection(cast<InputSection>(S));
+ if (OutputSection *sec = findByName(sectionCommands, name)) {
+ sec->addSection(cast<InputSection>(s));
return;
}
- if (OutputSection *OS = addInputSec(Map, S, Name))
- V.push_back(OS);
- assert(S->getOutputSection()->SectionIndex == UINT32_MAX);
+ if (OutputSection *os = addInputSec(map, s, name))
+ v.push_back(os);
+ assert(s->getOutputSection()->sectionIndex == UINT32_MAX);
};
// For futher --emit-reloc handling code we need target output section
// to be created before we create relocation output section, so we want
// to create target sections first. We do not want priority handling
// for synthetic sections because them are special.
- for (InputSectionBase *IS : InputSections) {
- if (auto *Sec = dyn_cast<InputSection>(IS))
- if (InputSectionBase *Rel = Sec->getRelocatedSection())
- if (auto *RelIS = dyn_cast_or_null<InputSectionBase>(Rel->Parent))
- Add(RelIS);
- Add(IS);
+ for (InputSectionBase *isec : inputSections) {
+ if (auto *sec = dyn_cast<InputSection>(isec))
+ if (InputSectionBase *rel = sec->getRelocatedSection())
+ if (auto *relIS = dyn_cast_or_null<InputSectionBase>(rel->parent))
+ add(relIS);
+ add(isec);
}
// If no SECTIONS command was given, we should insert sections commands
// before others, so that we can handle scripts which refers them,
// for example: "foo = ABSOLUTE(ADDR(.text)));".
// When SECTIONS command is present we just add all orphans to the end.
- if (HasSectionsCommand)
- SectionCommands.insert(SectionCommands.end(), V.begin(), V.end());
+ if (hasSectionsCommand)
+ sectionCommands.insert(sectionCommands.end(), v.begin(), v.end());
else
- SectionCommands.insert(SectionCommands.begin(), V.begin(), V.end());
+ sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
}
-uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {
- bool IsTbss =
- (Ctx->OutSec->Flags & SHF_TLS) && Ctx->OutSec->Type == SHT_NOBITS;
- uint64_t Start = IsTbss ? Dot + Ctx->ThreadBssOffset : Dot;
- Start = alignTo(Start, Alignment);
- uint64_t End = Start + Size;
+uint64_t LinkerScript::advance(uint64_t size, unsigned alignment) {
+ bool isTbss =
+ (ctx->outSec->flags & SHF_TLS) && ctx->outSec->type == SHT_NOBITS;
+ uint64_t start = isTbss ? dot + ctx->threadBssOffset : dot;
+ start = alignTo(start, alignment);
+ uint64_t end = start + size;
- if (IsTbss)
- Ctx->ThreadBssOffset = End - Dot;
+ if (isTbss)
+ ctx->threadBssOffset = end - dot;
else
- Dot = End;
- return End;
+ dot = end;
+ return end;
}
-void LinkerScript::output(InputSection *S) {
- assert(Ctx->OutSec == S->getParent());
- uint64_t Before = advance(0, 1);
- uint64_t Pos = advance(S->getSize(), S->Alignment);
- S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
+void LinkerScript::output(InputSection *s) {
+ assert(ctx->outSec == s->getParent());
+ uint64_t before = advance(0, 1);
+ uint64_t pos = advance(s->getSize(), s->alignment);
+ s->outSecOff = pos - s->getSize() - ctx->outSec->addr;
// Update output section size after adding each section. This is so that
// SIZEOF works correctly in the case below:
// .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
- expandOutputSection(Pos - Before);
+ expandOutputSection(pos - before);
}
-void LinkerScript::switchTo(OutputSection *Sec) {
- Ctx->OutSec = Sec;
+void LinkerScript::switchTo(OutputSection *sec) {
+ ctx->outSec = sec;
- uint64_t Before = advance(0, 1);
- Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
- expandMemoryRegions(Ctx->OutSec->Addr - Before);
+ uint64_t before = advance(0, 1);
+ ctx->outSec->addr = advance(0, ctx->outSec->alignment);
+ expandMemoryRegions(ctx->outSec->addr - before);
}
// This function searches for a memory region to place the given output
// section in. If found, a pointer to the appropriate memory region is
// returned. Otherwise, a nullptr is returned.
-MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) {
+MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *sec) {
// If a memory region name was specified in the output section command,
// then try to find that region first.
- if (!Sec->MemoryRegionName.empty()) {
- if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName))
- return M;
- error("memory region '" + Sec->MemoryRegionName + "' not declared");
+ if (!sec->memoryRegionName.empty()) {
+ if (MemoryRegion *m = memoryRegions.lookup(sec->memoryRegionName))
+ return m;
+ error("memory region '" + sec->memoryRegionName + "' not declared");
return nullptr;
}
// If at least one memory region is defined, all sections must
// belong to some memory region. Otherwise, we don't need to do
// anything for memory regions.
- if (MemoryRegions.empty())
+ if (memoryRegions.empty())
return nullptr;
// See if a region can be found by matching section flags.
- for (auto &Pair : MemoryRegions) {
- MemoryRegion *M = Pair.second;
- if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0)
- return M;
+ for (auto &pair : memoryRegions) {
+ MemoryRegion *m = pair.second;
+ if ((m->flags & sec->flags) && (m->negFlags & sec->flags) == 0)
+ return m;
}
// Otherwise, no suitable region was found.
- if (Sec->Flags & SHF_ALLOC)
- error("no memory region specified for section '" + Sec->Name + "'");
+ if (sec->flags & SHF_ALLOC)
+ error("no memory region specified for section '" + sec->name + "'");
return nullptr;
}
-static OutputSection *findFirstSection(PhdrEntry *Load) {
- for (OutputSection *Sec : OutputSections)
- if (Sec->PtLoad == Load)
- return Sec;
+static OutputSection *findFirstSection(PhdrEntry *load) {
+ for (OutputSection *sec : outputSections)
+ if (sec->ptLoad == load)
+ return sec;
return nullptr;
}
// This function assigns offsets to input sections and an output section
// for a single sections command (e.g. ".text { *(.text); }").
-void LinkerScript::assignOffsets(OutputSection *Sec) {
- if (!(Sec->Flags & SHF_ALLOC))
- Dot = 0;
+void LinkerScript::assignOffsets(OutputSection *sec) {
+ if (!(sec->flags & SHF_ALLOC))
+ dot = 0;
- Ctx->MemRegion = Sec->MemRegion;
- Ctx->LMARegion = Sec->LMARegion;
- if (Ctx->MemRegion)
- Dot = Ctx->MemRegion->CurPos;
+ ctx->memRegion = sec->memRegion;
+ ctx->lmaRegion = sec->lmaRegion;
+ if (ctx->memRegion)
+ dot = ctx->memRegion->curPos;
- if ((Sec->Flags & SHF_ALLOC) && Sec->AddrExpr)
- setDot(Sec->AddrExpr, Sec->Location, false);
+ if ((sec->flags & SHF_ALLOC) && sec->addrExpr)
+ setDot(sec->addrExpr, sec->location, false);
- switchTo(Sec);
+ switchTo(sec);
- if (Sec->LMAExpr)
- Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot;
+ if (sec->lmaExpr)
+ ctx->lmaOffset = sec->lmaExpr().getValue() - dot;
- if (MemoryRegion *MR = Sec->LMARegion)
- Ctx->LMAOffset = MR->CurPos - Dot;
+ if (MemoryRegion *mr = sec->lmaRegion)
+ ctx->lmaOffset = mr->curPos - dot;
// If neither AT nor AT> is specified for an allocatable section, the linker
// will set the LMA such that the difference between VMA and LMA for the
@@ -786,71 +786,71 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
// https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
// This, however, should only be done by the first "non-header" section
// in the segment.
- if (PhdrEntry *L = Ctx->OutSec->PtLoad)
- if (Sec == findFirstSection(L))
- L->LMAOffset = Ctx->LMAOffset;
+ if (PhdrEntry *l = ctx->outSec->ptLoad)
+ if (sec == findFirstSection(l))
+ l->lmaOffset = ctx->lmaOffset;
// We can call this method multiple times during the creation of
// thunks and want to start over calculation each time.
- Sec->Size = 0;
+ sec->size = 0;
// We visited SectionsCommands from processSectionCommands to
// layout sections. Now, we visit SectionsCommands again to fix
// section offsets.
- for (BaseCommand *Base : Sec->SectionCommands) {
+ for (BaseCommand *base : sec->sectionCommands) {
// This handles the assignments to symbol or to the dot.
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- Cmd->Addr = Dot;
- assignSymbol(Cmd, true);
- Cmd->Size = Dot - Cmd->Addr;
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ cmd->addr = dot;
+ assignSymbol(cmd, true);
+ cmd->size = dot - cmd->addr;
continue;
}
// Handle BYTE(), SHORT(), LONG(), or QUAD().
- if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
- Cmd->Offset = Dot - Ctx->OutSec->Addr;
- Dot += Cmd->Size;
- expandOutputSection(Cmd->Size);
+ if (auto *cmd = dyn_cast<ByteCommand>(base)) {
+ cmd->offset = dot - ctx->outSec->addr;
+ dot += cmd->size;
+ expandOutputSection(cmd->size);
continue;
}
// Handle a single input section description command.
// It calculates and assigns the offsets for each section and also
// updates the output section size.
- for (InputSection *Sec : cast<InputSectionDescription>(Base)->Sections)
- output(Sec);
+ for (InputSection *sec : cast<InputSectionDescription>(base)->sections)
+ output(sec);
}
}
-static bool isDiscardable(OutputSection &Sec) {
- if (Sec.Name == "/DISCARD/")
+static bool isDiscardable(OutputSection &sec) {
+ if (sec.name == "/DISCARD/")
return true;
// We do not remove empty sections that are explicitly
// assigned to any segment.
- if (!Sec.Phdrs.empty())
+ if (!sec.phdrs.empty())
return false;
// We do not want to remove OutputSections with expressions that reference
// symbols even if the OutputSection is empty. We want to ensure that the
// expressions can be evaluated and report an error if they cannot.
- if (Sec.ExpressionsUseSymbols)
+ if (sec.expressionsUseSymbols)
return false;
// OutputSections may be referenced by name in ADDR and LOADADDR expressions,
// as an empty Section can has a valid VMA and LMA we keep the OutputSection
// to maintain the integrity of the other Expression.
- if (Sec.UsedInExpression)
+ if (sec.usedInExpression)
return false;
- for (BaseCommand *Base : Sec.SectionCommands) {
- if (auto Cmd = dyn_cast<SymbolAssignment>(Base))
+ for (BaseCommand *base : sec.sectionCommands) {
+ if (auto cmd = dyn_cast<SymbolAssignment>(base))
// Don't create empty output sections just for unreferenced PROVIDE
// symbols.
- if (Cmd->Name != "." && !Cmd->Sym)
+ if (cmd->name != "." && !cmd->sym)
continue;
- if (!isa<InputSectionDescription>(*Base))
+ if (!isa<InputSectionDescription>(*base))
return false;
}
return true;
@@ -877,35 +877,35 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// The other option is to pick flags that minimize the impact the section
// will have on the rest of the linker. That is why we copy the flags from
// the previous sections. Only a few flags are needed to keep the impact low.
- uint64_t Flags = SHF_ALLOC;
+ uint64_t flags = SHF_ALLOC;
- for (BaseCommand *&Cmd : SectionCommands) {
- auto *Sec = dyn_cast<OutputSection>(Cmd);
- if (!Sec)
+ for (BaseCommand *&cmd : sectionCommands) {
+ auto *sec = dyn_cast<OutputSection>(cmd);
+ if (!sec)
continue;
// Handle align (e.g. ".foo : ALIGN(16) { ... }").
- if (Sec->AlignExpr)
- Sec->Alignment =
- std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue());
+ if (sec->alignExpr)
+ sec->alignment =
+ std::max<uint32_t>(sec->alignment, sec->alignExpr().getValue());
// The input section might have been removed (if it was an empty synthetic
// section), but we at least know the flags.
- if (Sec->HasInputSections)
- Flags = Sec->Flags;
+ if (sec->hasInputSections)
+ flags = sec->flags;
// We do not want to keep any special flags for output section
// in case it is empty.
- bool IsEmpty = getInputSections(Sec).empty();
- if (IsEmpty)
- Sec->Flags = Flags & ((Sec->NonAlloc ? 0 : (uint64_t)SHF_ALLOC) |
+ bool isEmpty = getInputSections(sec).empty();
+ if (isEmpty)
+ sec->flags = flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) |
SHF_WRITE | SHF_EXECINSTR);
- if (IsEmpty && isDiscardable(*Sec)) {
- Sec->markDead();
- Cmd = nullptr;
- } else if (!Sec->isLive()) {
- Sec->markLive();
+ if (isEmpty && isDiscardable(*sec)) {
+ sec->markDead();
+ cmd = nullptr;
+ } else if (!sec->isLive()) {
+ sec->markLive();
}
}
@@ -915,20 +915,20 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// clutter the output.
// We instead remove trivially empty sections. The bfd linker seems even
// more aggressive at removing them.
- llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
+ llvm::erase_if(sectionCommands, [&](BaseCommand *base) { return !base; });
}
void LinkerScript::adjustSectionsAfterSorting() {
// Try and find an appropriate memory region to assign offsets in.
- for (BaseCommand *Base : SectionCommands) {
- if (auto *Sec = dyn_cast<OutputSection>(Base)) {
- if (!Sec->LMARegionName.empty()) {
- if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
- Sec->LMARegion = M;
+ for (BaseCommand *base : sectionCommands) {
+ if (auto *sec = dyn_cast<OutputSection>(base)) {
+ if (!sec->lmaRegionName.empty()) {
+ if (MemoryRegion *m = memoryRegions.lookup(sec->lmaRegionName))
+ sec->lmaRegion = m;
else
- error("memory region '" + Sec->LMARegionName + "' not declared");
+ error("memory region '" + sec->lmaRegionName + "' not declared");
}
- Sec->MemRegion = findMemoryRegion(Sec);
+ sec->memRegion = findMemoryRegion(sec);
}
}
@@ -938,38 +938,38 @@ void LinkerScript::adjustSectionsAfterSorting() {
// Below is an example of such linker script:
// PHDRS { seg PT_LOAD; }
// SECTIONS { .aaa : { *(.aaa) } }
- std::vector<StringRef> DefPhdrs;
- auto FirstPtLoad = llvm::find_if(PhdrsCommands, [](const PhdrsCommand &Cmd) {
- return Cmd.Type == PT_LOAD;
+ std::vector<StringRef> defPhdrs;
+ auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
+ return cmd.type == PT_LOAD;
});
- if (FirstPtLoad != PhdrsCommands.end())
- DefPhdrs.push_back(FirstPtLoad->Name);
+ if (firstPtLoad != phdrsCommands.end())
+ defPhdrs.push_back(firstPtLoad->name);
// Walk the commands and propagate the program headers to commands that don't
// explicitly specify them.
- for (BaseCommand *Base : SectionCommands) {
- auto *Sec = dyn_cast<OutputSection>(Base);
- if (!Sec)
+ for (BaseCommand *base : sectionCommands) {
+ auto *sec = dyn_cast<OutputSection>(base);
+ if (!sec)
continue;
- if (Sec->Phdrs.empty()) {
+ if (sec->phdrs.empty()) {
// To match the bfd linker script behaviour, only propagate program
// headers to sections that are allocated.
- if (Sec->Flags & SHF_ALLOC)
- Sec->Phdrs = DefPhdrs;
+ if (sec->flags & SHF_ALLOC)
+ sec->phdrs = defPhdrs;
} else {
- DefPhdrs = Sec->Phdrs;
+ defPhdrs = sec->phdrs;
}
}
}
-static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
+static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
// If there is no SECTIONS or if the linkerscript is explicit about program
// headers, do our best to allocate them.
- if (!Script->HasSectionsCommand || AllocateHeaders)
+ if (!script->hasSectionsCommand || allocateHeaders)
return 0;
// Otherwise only allocate program headers if that would not add a page.
- return alignDown(Min, Config->MaxPageSize);
+ return alignDown(min, config->maxPageSize);
}
// Try to find an address for the file and program headers output sections,
@@ -983,120 +983,120 @@ static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
//
// If there isn't enough space for these sections, we'll remove them from the
// PT_LOAD segment, and we'll also remove the PT_PHDR segment.
-void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
- uint64_t Min = std::numeric_limits<uint64_t>::max();
- for (OutputSection *Sec : OutputSections)
- if (Sec->Flags & SHF_ALLOC)
- Min = std::min<uint64_t>(Min, Sec->Addr);
-
- auto It = llvm::find_if(
- Phdrs, [](const PhdrEntry *E) { return E->p_type == PT_LOAD; });
- if (It == Phdrs.end())
+void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &phdrs) {
+ uint64_t min = std::numeric_limits<uint64_t>::max();
+ for (OutputSection *sec : outputSections)
+ if (sec->flags & SHF_ALLOC)
+ min = std::min<uint64_t>(min, sec->addr);
+
+ auto it = llvm::find_if(
+ phdrs, [](const PhdrEntry *e) { return e->p_type == PT_LOAD; });
+ if (it == phdrs.end())
return;
- PhdrEntry *FirstPTLoad = *It;
+ PhdrEntry *firstPTLoad = *it;
- bool HasExplicitHeaders =
- llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) {
- return Cmd.HasPhdrs || Cmd.HasFilehdr;
+ bool hasExplicitHeaders =
+ llvm::any_of(phdrsCommands, [](const PhdrsCommand &cmd) {
+ return cmd.hasPhdrs || cmd.hasFilehdr;
});
- bool Paged = !Config->Omagic && !Config->Nmagic;
- uint64_t HeaderSize = getHeaderSize();
- if ((Paged || HasExplicitHeaders) &&
- HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
- Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
- Out::ElfHeader->Addr = Min;
- Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
+ bool paged = !config->omagic && !config->nmagic;
+ uint64_t headerSize = getHeaderSize();
+ if ((paged || hasExplicitHeaders) &&
+ headerSize <= min - computeBase(min, hasExplicitHeaders)) {
+ min = alignDown(min - headerSize, config->maxPageSize);
+ Out::elfHeader->addr = min;
+ Out::programHeaders->addr = min + Out::elfHeader->size;
return;
}
// Error if we were explicitly asked to allocate headers.
- if (HasExplicitHeaders)
+ if (hasExplicitHeaders)
error("could not allocate headers");
- Out::ElfHeader->PtLoad = nullptr;
- Out::ProgramHeaders->PtLoad = nullptr;
- FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad);
+ Out::elfHeader->ptLoad = nullptr;
+ Out::programHeaders->ptLoad = nullptr;
+ firstPTLoad->firstSec = findFirstSection(firstPTLoad);
- llvm::erase_if(Phdrs,
- [](const PhdrEntry *E) { return E->p_type == PT_PHDR; });
+ llvm::erase_if(phdrs,
+ [](const PhdrEntry *e) { return e->p_type == PT_PHDR; });
}
LinkerScript::AddressState::AddressState() {
- for (auto &MRI : Script->MemoryRegions) {
- MemoryRegion *MR = MRI.second;
- MR->CurPos = MR->Origin;
+ for (auto &mri : script->memoryRegions) {
+ MemoryRegion *mr = mri.second;
+ mr->curPos = mr->origin;
}
}
static uint64_t getInitialDot() {
// By default linker scripts use an initial value of 0 for '.',
// but prefer -image-base if set.
- if (Script->HasSectionsCommand)
- return Config->ImageBase ? *Config->ImageBase : 0;
+ if (script->hasSectionsCommand)
+ return config->imageBase ? *config->imageBase : 0;
- uint64_t StartAddr = UINT64_MAX;
+ uint64_t startAddr = UINT64_MAX;
// The Sections with -T<section> have been sorted in order of ascending
// address. We must lower StartAddr if the lowest -T<section address> as
// calls to setDot() must be monotonically increasing.
- for (auto &KV : Config->SectionStartMap)
- StartAddr = std::min(StartAddr, KV.second);
- return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
+ for (auto &kv : config->sectionStartMap)
+ startAddr = std::min(startAddr, kv.second);
+ return std::min(startAddr, target->getImageBase() + elf::getHeaderSize());
}
// Here we assign addresses as instructed by linker script SECTIONS
// sub-commands. Doing that allows us to use final VA values, so here
// we also handle rest commands like symbol assignments and ASSERTs.
void LinkerScript::assignAddresses() {
- Dot = getInitialDot();
-
- auto Deleter = make_unique<AddressState>();
- Ctx = Deleter.get();
- ErrorOnMissingSection = true;
- switchTo(Aether);
-
- for (BaseCommand *Base : SectionCommands) {
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- Cmd->Addr = Dot;
- assignSymbol(Cmd, false);
- Cmd->Size = Dot - Cmd->Addr;
+ dot = getInitialDot();
+
+ auto deleter = make_unique<AddressState>();
+ ctx = deleter.get();
+ errorOnMissingSection = true;
+ switchTo(aether);
+
+ for (BaseCommand *base : sectionCommands) {
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ cmd->addr = dot;
+ assignSymbol(cmd, false);
+ cmd->size = dot - cmd->addr;
continue;
}
- assignOffsets(cast<OutputSection>(Base));
+ assignOffsets(cast<OutputSection>(base));
}
- Ctx = nullptr;
+ ctx = nullptr;
}
// Creates program headers as instructed by PHDRS linker script command.
std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
- std::vector<PhdrEntry *> Ret;
+ std::vector<PhdrEntry *> ret;
// Process PHDRS and FILEHDR keywords because they are not
// real output sections and cannot be added in the following loop.
- for (const PhdrsCommand &Cmd : PhdrsCommands) {
- PhdrEntry *Phdr = make<PhdrEntry>(Cmd.Type, Cmd.Flags ? *Cmd.Flags : PF_R);
+ for (const PhdrsCommand &cmd : phdrsCommands) {
+ PhdrEntry *phdr = make<PhdrEntry>(cmd.type, cmd.flags ? *cmd.flags : PF_R);
- if (Cmd.HasFilehdr)
- Phdr->add(Out::ElfHeader);
- if (Cmd.HasPhdrs)
- Phdr->add(Out::ProgramHeaders);
+ if (cmd.hasFilehdr)
+ phdr->add(Out::elfHeader);
+ if (cmd.hasPhdrs)
+ phdr->add(Out::programHeaders);
- if (Cmd.LMAExpr) {
- Phdr->p_paddr = Cmd.LMAExpr().getValue();
- Phdr->HasLMA = true;
+ if (cmd.lmaExpr) {
+ phdr->p_paddr = cmd.lmaExpr().getValue();
+ phdr->hasLMA = true;
}
- Ret.push_back(Phdr);
+ ret.push_back(phdr);
}
// Add output sections to program headers.
- for (OutputSection *Sec : OutputSections) {
+ for (OutputSection *sec : outputSections) {
// Assign headers specified by linker script
- for (size_t Id : getPhdrIndices(Sec)) {
- Ret[Id]->add(Sec);
- if (!PhdrsCommands[Id].Flags.hasValue())
- Ret[Id]->p_flags |= Sec->getPhdrFlags();
+ for (size_t id : getPhdrIndices(sec)) {
+ ret[id]->add(sec);
+ if (!phdrsCommands[id].flags.hasValue())
+ ret[id]->p_flags |= sec->getPhdrFlags();
}
}
- return Ret;
+ return ret;
}
// Returns true if we should emit an .interp section.
@@ -1105,54 +1105,54 @@ std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
// no PT_INTERP is there, there's no place to emit an
// .interp, so we don't do that in that case.
bool LinkerScript::needsInterpSection() {
- if (PhdrsCommands.empty())
+ if (phdrsCommands.empty())
return true;
- for (PhdrsCommand &Cmd : PhdrsCommands)
- if (Cmd.Type == PT_INTERP)
+ for (PhdrsCommand &cmd : phdrsCommands)
+ if (cmd.type == PT_INTERP)
return true;
return false;
}
-ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) {
- if (Name == ".") {
- if (Ctx)
- return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc};
- error(Loc + ": unable to get location counter value");
+ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
+ if (name == ".") {
+ if (ctx)
+ return {ctx->outSec, false, dot - ctx->outSec->addr, loc};
+ error(loc + ": unable to get location counter value");
return 0;
}
- if (Symbol *Sym = Symtab->find(Name)) {
- if (auto *DS = dyn_cast<Defined>(Sym))
- return {DS->Section, false, DS->Value, Loc};
- if (isa<SharedSymbol>(Sym))
- if (!ErrorOnMissingSection)
- return {nullptr, false, 0, Loc};
+ if (Symbol *sym = symtab->find(name)) {
+ if (auto *ds = dyn_cast<Defined>(sym))
+ return {ds->section, false, ds->value, loc};
+ if (isa<SharedSymbol>(sym))
+ if (!errorOnMissingSection)
+ return {nullptr, false, 0, loc};
}
- error(Loc + ": symbol not found: " + Name);
+ error(loc + ": symbol not found: " + name);
return 0;
}
// Returns the index of the segment named Name.
-static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> Vec,
- StringRef Name) {
- for (size_t I = 0; I < Vec.size(); ++I)
- if (Vec[I].Name == Name)
- return I;
+static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
+ StringRef name) {
+ for (size_t i = 0; i < vec.size(); ++i)
+ if (vec[i].name == name)
+ return i;
return None;
}
// Returns indices of ELF headers containing specific section. Each index is a
// zero based number of ELF header listed within PHDRS {} script block.
-std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Cmd) {
- std::vector<size_t> Ret;
-
- for (StringRef S : Cmd->Phdrs) {
- if (Optional<size_t> Idx = getPhdrIndex(PhdrsCommands, S))
- Ret.push_back(*Idx);
- else if (S != "NONE")
- error(Cmd->Location + ": section header '" + S +
+std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
+ std::vector<size_t> ret;
+
+ for (StringRef s : cmd->phdrs) {
+ if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
+ ret.push_back(*idx);
+ else if (s != "NONE")
+ error(cmd->location + ": section header '" + s +
"' is not listed in PHDRS");
}
- return Ret;
+ return ret;
}
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index fe092b27d6f..9e9c08ef10b 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -38,29 +38,29 @@ class ThunkSection;
// This represents an r-value in the linker script.
struct ExprValue {
- ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
- const Twine &Loc)
- : Sec(Sec), ForceAbsolute(ForceAbsolute), Val(Val), Loc(Loc.str()) {}
+ ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
+ const Twine &loc)
+ : sec(sec), forceAbsolute(forceAbsolute), val(val), loc(loc.str()) {}
- ExprValue(uint64_t Val) : ExprValue(nullptr, false, Val, "") {}
+ ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
- bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
+ bool isAbsolute() const { return forceAbsolute || sec == nullptr; }
uint64_t getValue() const;
uint64_t getSecAddr() const;
uint64_t getSectionOffset() const;
// If a value is relative to a section, it has a non-null Sec.
- SectionBase *Sec;
+ SectionBase *sec;
// True if this expression is enclosed in ABSOLUTE().
// This flag affects the return value of getValue().
- bool ForceAbsolute;
+ bool forceAbsolute;
- uint64_t Val;
- uint64_t Alignment = 1;
+ uint64_t val;
+ uint64_t alignment = 1;
// Original source location. Used for error messages.
- std::string Loc;
+ std::string loc;
};
// This represents an expression in the linker script.
@@ -78,42 +78,42 @@ enum SectionsCommandKind {
};
struct BaseCommand {
- BaseCommand(int K) : Kind(K) {}
- int Kind;
+ BaseCommand(int k) : kind(k) {}
+ int kind;
};
// This represents ". = <expr>" or "<symbol> = <expr>".
struct SymbolAssignment : BaseCommand {
- SymbolAssignment(StringRef Name, Expr E, std::string Loc)
- : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
+ SymbolAssignment(StringRef name, Expr e, std::string loc)
+ : BaseCommand(AssignmentKind), name(name), expression(e), location(loc) {}
- static bool classof(const BaseCommand *C) {
- return C->Kind == AssignmentKind;
+ static bool classof(const BaseCommand *c) {
+ return c->kind == AssignmentKind;
}
// The LHS of an expression. Name is either a symbol name or ".".
- StringRef Name;
- Defined *Sym = nullptr;
+ StringRef name;
+ Defined *sym = nullptr;
// The RHS of an expression.
- Expr Expression;
+ Expr expression;
// Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
- bool Provide = false;
- bool Hidden = false;
+ bool provide = false;
+ bool hidden = false;
// Holds file name and line number for error reporting.
- std::string Location;
+ std::string location;
// A string representation of this command. We use this for -Map.
- std::string CommandString;
+ std::string commandString;
// Address of this assignment command.
- unsigned Addr;
+ unsigned addr;
// Size of this assignment command. This is usually 0, but if
// you move '.' this may be greater than 0.
- unsigned Size;
+ unsigned size;
};
// Linker scripts allow additional constraints to be put on ouput sections.
@@ -126,83 +126,83 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
// target memory. Instances of the struct are created by parsing the
// MEMORY command.
struct MemoryRegion {
- MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags,
- uint32_t NegFlags)
- : Name(Name), Origin(Origin), Length(Length), Flags(Flags),
- NegFlags(NegFlags) {}
-
- std::string Name;
- uint64_t Origin;
- uint64_t Length;
- uint32_t Flags;
- uint32_t NegFlags;
- uint64_t CurPos = 0;
+ MemoryRegion(StringRef name, uint64_t origin, uint64_t length, uint32_t flags,
+ uint32_t negFlags)
+ : name(name), origin(origin), length(length), flags(flags),
+ negFlags(negFlags) {}
+
+ std::string name;
+ uint64_t origin;
+ uint64_t length;
+ uint32_t flags;
+ uint32_t negFlags;
+ uint64_t curPos = 0;
};
// This struct represents one section match pattern in SECTIONS() command.
// It can optionally have negative match pattern for EXCLUDED_FILE command.
// Also it may be surrounded with SORT() command, so contains sorting rules.
struct SectionPattern {
- SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
- : ExcludedFilePat(Pat1), SectionPat(Pat2),
- SortOuter(SortSectionPolicy::Default),
- SortInner(SortSectionPolicy::Default) {}
-
- StringMatcher ExcludedFilePat;
- StringMatcher SectionPat;
- SortSectionPolicy SortOuter;
- SortSectionPolicy SortInner;
+ SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
+ : excludedFilePat(pat1), sectionPat(pat2),
+ sortOuter(SortSectionPolicy::Default),
+ sortInner(SortSectionPolicy::Default) {}
+
+ StringMatcher excludedFilePat;
+ StringMatcher sectionPat;
+ SortSectionPolicy sortOuter;
+ SortSectionPolicy sortInner;
};
struct InputSectionDescription : BaseCommand {
- InputSectionDescription(StringRef FilePattern)
- : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
+ InputSectionDescription(StringRef filePattern)
+ : BaseCommand(InputSectionKind), filePat(filePattern) {}
- static bool classof(const BaseCommand *C) {
- return C->Kind == InputSectionKind;
+ static bool classof(const BaseCommand *c) {
+ return c->kind == InputSectionKind;
}
- StringMatcher FilePat;
+ StringMatcher filePat;
// Input sections that matches at least one of SectionPatterns
// will be associated with this InputSectionDescription.
- std::vector<SectionPattern> SectionPatterns;
+ std::vector<SectionPattern> sectionPatterns;
- std::vector<InputSection *> Sections;
+ std::vector<InputSection *> sections;
// Temporary record of synthetic ThunkSection instances and the pass that
// they were created in. This is used to insert newly created ThunkSections
// into Sections at the end of a createThunks() pass.
- std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections;
+ std::vector<std::pair<ThunkSection *, uint32_t>> thunkSections;
};
// Represents BYTE(), SHORT(), LONG(), or QUAD().
struct ByteCommand : BaseCommand {
- ByteCommand(Expr E, unsigned Size, std::string CommandString)
- : BaseCommand(ByteKind), CommandString(CommandString), Expression(E),
- Size(Size) {}
+ ByteCommand(Expr e, unsigned size, std::string commandString)
+ : BaseCommand(ByteKind), commandString(commandString), expression(e),
+ size(size) {}
- static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; }
+ static bool classof(const BaseCommand *c) { return c->kind == ByteKind; }
// Keeps string representing the command. Used for -Map" is perhaps better.
- std::string CommandString;
+ std::string commandString;
- Expr Expression;
+ Expr expression;
// This is just an offset of this assignment command in the output section.
- unsigned Offset;
+ unsigned offset;
// Size of this data command.
- unsigned Size;
+ unsigned size;
};
struct PhdrsCommand {
- StringRef Name;
- unsigned Type = llvm::ELF::PT_NULL;
- bool HasFilehdr = false;
- bool HasPhdrs = false;
- llvm::Optional<unsigned> Flags;
- Expr LMAExpr = nullptr;
+ StringRef name;
+ unsigned type = llvm::ELF::PT_NULL;
+ bool hasFilehdr = false;
+ bool hasPhdrs = false;
+ llvm::Optional<unsigned> flags;
+ Expr lmaExpr = nullptr;
};
class LinkerScript final {
@@ -211,35 +211,35 @@ class LinkerScript final {
// not be used outside of the scope of a call to the above functions.
struct AddressState {
AddressState();
- uint64_t ThreadBssOffset = 0;
- OutputSection *OutSec = nullptr;
- MemoryRegion *MemRegion = nullptr;
- MemoryRegion *LMARegion = nullptr;
- uint64_t LMAOffset = 0;
+ uint64_t threadBssOffset = 0;
+ OutputSection *outSec = nullptr;
+ MemoryRegion *memRegion = nullptr;
+ MemoryRegion *lmaRegion = nullptr;
+ uint64_t lmaOffset = 0;
};
- llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection;
+ llvm::DenseMap<StringRef, OutputSection *> nameToOutputSection;
- void addSymbol(SymbolAssignment *Cmd);
- void assignSymbol(SymbolAssignment *Cmd, bool InSec);
- void setDot(Expr E, const Twine &Loc, bool InSec);
- void expandOutputSection(uint64_t Size);
- void expandMemoryRegions(uint64_t Size);
+ void addSymbol(SymbolAssignment *cmd);
+ void assignSymbol(SymbolAssignment *cmd, bool inSec);
+ void setDot(Expr e, const Twine &loc, bool inSec);
+ void expandOutputSection(uint64_t size);
+ void expandMemoryRegions(uint64_t size);
std::vector<InputSection *>
computeInputSections(const InputSectionDescription *);
- std::vector<InputSection *> createInputSectionList(OutputSection &Cmd);
+ std::vector<InputSection *> createInputSectionList(OutputSection &cmd);
- std::vector<size_t> getPhdrIndices(OutputSection *Sec);
+ std::vector<size_t> getPhdrIndices(OutputSection *sec);
- MemoryRegion *findMemoryRegion(OutputSection *Sec);
+ MemoryRegion *findMemoryRegion(OutputSection *sec);
- void switchTo(OutputSection *Sec);
- uint64_t advance(uint64_t Size, unsigned Align);
- void output(InputSection *Sec);
+ void switchTo(OutputSection *sec);
+ uint64_t advance(uint64_t size, unsigned align);
+ void output(InputSection *sec);
- void assignOffsets(OutputSection *Sec);
+ void assignOffsets(OutputSection *sec);
// Ctx captures the local AddressState and makes it accessible
// deliberately. This is needed as there are some cases where we cannot just
@@ -247,21 +247,21 @@ class LinkerScript final {
// script parser.
// This should remain a plain pointer as its lifetime is smaller than
// LinkerScript.
- AddressState *Ctx = nullptr;
+ AddressState *ctx = nullptr;
- OutputSection *Aether;
+ OutputSection *aether;
- uint64_t Dot;
+ uint64_t dot;
public:
- OutputSection *createOutputSection(StringRef Name, StringRef Location);
- OutputSection *getOrCreateOutputSection(StringRef Name);
+ OutputSection *createOutputSection(StringRef name, StringRef location);
+ OutputSection *getOrCreateOutputSection(StringRef name);
- bool hasPhdrsCommands() { return !PhdrsCommands.empty(); }
- uint64_t getDot() { return Dot; }
- void discard(ArrayRef<InputSection *> V);
+ bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
+ uint64_t getDot() { return dot; }
+ void discard(ArrayRef<InputSection *> v);
- ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
+ ExprValue getSymbolValue(StringRef name, const Twine &loc);
void addOrphanSections();
void adjustSectionsBeforeSorting();
@@ -270,9 +270,9 @@ public:
std::vector<PhdrEntry *> createPhdrs();
bool needsInterpSection();
- bool shouldKeep(InputSectionBase *S);
+ bool shouldKeep(InputSectionBase *s);
void assignAddresses();
- void allocateHeaders(std::vector<PhdrEntry *> &Phdrs);
+ void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
void processSectionCommands();
void declareSymbols();
@@ -280,31 +280,31 @@ public:
void processInsertCommands();
// SECTIONS command list.
- std::vector<BaseCommand *> SectionCommands;
+ std::vector<BaseCommand *> sectionCommands;
// PHDRS command list.
- std::vector<PhdrsCommand> PhdrsCommands;
+ std::vector<PhdrsCommand> phdrsCommands;
- bool HasSectionsCommand = false;
- bool ErrorOnMissingSection = false;
+ bool hasSectionsCommand = false;
+ bool errorOnMissingSection = false;
// List of section patterns specified with KEEP commands. They will
// be kept even if they are unused and --gc-sections is specified.
- std::vector<InputSectionDescription *> KeptSections;
+ std::vector<InputSectionDescription *> keptSections;
// A map from memory region name to a memory region descriptor.
- llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions;
+ llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
// A list of symbols referenced by the script.
- std::vector<llvm::StringRef> ReferencedSymbols;
+ std::vector<llvm::StringRef> referencedSymbols;
// Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
// to be inserted into SECTIONS commands list.
- llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
- llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands;
+ llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertAfterCommands;
+ llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertBeforeCommands;
};
-extern LinkerScript *Script;
+extern LinkerScript *script;
} // end namespace elf
} // end namespace lld
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index f5d5d5a834e..a4a6238fc65 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -39,65 +39,65 @@ using namespace lld::elf;
using SymbolMapTy = DenseMap<const SectionBase *, SmallVector<Defined *, 4>>;
-static const std::string Indent8 = " "; // 8 spaces
-static const std::string Indent16 = " "; // 16 spaces
+static const std::string indent8 = " "; // 8 spaces
+static const std::string indent16 = " "; // 16 spaces
// Print out the first three columns of a line.
-static void writeHeader(raw_ostream &OS, uint64_t VMA, uint64_t LMA,
- uint64_t Size, uint64_t Align) {
- if (Config->Is64)
- OS << format("%16llx %16llx %8llx %5lld ", VMA, LMA, Size, Align);
+static void writeHeader(raw_ostream &os, uint64_t vma, uint64_t lma,
+ uint64_t size, uint64_t align) {
+ if (config->is64)
+ os << format("%16llx %16llx %8llx %5lld ", vma, lma, size, align);
else
- OS << format("%8llx %8llx %8llx %5lld ", VMA, LMA, Size, Align);
+ os << format("%8llx %8llx %8llx %5lld ", vma, lma, size, align);
}
// Returns a list of all symbols that we want to print out.
static std::vector<Defined *> getSymbols() {
- std::vector<Defined *> V;
- for (InputFile *File : ObjectFiles)
- for (Symbol *B : File->getSymbols())
- if (auto *DR = dyn_cast<Defined>(B))
- if (!DR->isSection() && DR->Section && DR->Section->isLive() &&
- (DR->File == File || DR->NeedsPltAddr || DR->Section->Bss))
- V.push_back(DR);
- return V;
+ std::vector<Defined *> v;
+ for (InputFile *file : objectFiles)
+ for (Symbol *b : file->getSymbols())
+ if (auto *dr = dyn_cast<Defined>(b))
+ if (!dr->isSection() && dr->section && dr->section->isLive() &&
+ (dr->file == file || dr->needsPltAddr || dr->section->bss))
+ v.push_back(dr);
+ return v;
}
// Returns a map from sections to their symbols.
-static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
- SymbolMapTy Ret;
- for (Defined *DR : Syms)
- Ret[DR->Section].push_back(DR);
+static SymbolMapTy getSectionSyms(ArrayRef<Defined *> syms) {
+ SymbolMapTy ret;
+ for (Defined *dr : syms)
+ ret[dr->section].push_back(dr);
// Sort symbols by address. We want to print out symbols in the
// order in the output file rather than the order they appeared
// in the input files.
- for (auto &It : Ret)
- llvm::stable_sort(It.second, [](Defined *A, Defined *B) {
- return A->getVA() < B->getVA();
+ for (auto &it : ret)
+ llvm::stable_sort(it.second, [](Defined *a, Defined *b) {
+ return a->getVA() < b->getVA();
});
- return Ret;
+ return ret;
}
// Construct a map from symbols to their stringified representations.
// Demangling symbols (which is what toString() does) is slow, so
// we do that in batch using parallel-for.
static DenseMap<Symbol *, std::string>
-getSymbolStrings(ArrayRef<Defined *> Syms) {
- std::vector<std::string> Str(Syms.size());
- parallelForEachN(0, Syms.size(), [&](size_t I) {
- raw_string_ostream OS(Str[I]);
- OutputSection *OSec = Syms[I]->getOutputSection();
- uint64_t VMA = Syms[I]->getVA();
- uint64_t LMA = OSec ? OSec->getLMA() + VMA - OSec->getVA(0) : 0;
- writeHeader(OS, VMA, LMA, Syms[I]->getSize(), 1);
- OS << Indent16 << toString(*Syms[I]);
+getSymbolStrings(ArrayRef<Defined *> syms) {
+ std::vector<std::string> str(syms.size());
+ parallelForEachN(0, syms.size(), [&](size_t i) {
+ raw_string_ostream os(str[i]);
+ OutputSection *osec = syms[i]->getOutputSection();
+ uint64_t vma = syms[i]->getVA();
+ uint64_t lma = osec ? osec->getLMA() + vma - osec->getVA(0) : 0;
+ writeHeader(os, vma, lma, syms[i]->getSize(), 1);
+ os << indent16 << toString(*syms[i]);
});
- DenseMap<Symbol *, std::string> Ret;
- for (size_t I = 0, E = Syms.size(); I < E; ++I)
- Ret[Syms[I]] = std::move(Str[I]);
- return Ret;
+ DenseMap<Symbol *, std::string> ret;
+ for (size_t i = 0, e = syms.size(); i < e; ++i)
+ ret[syms[i]] = std::move(str[i]);
+ return ret;
}
// Print .eh_frame contents. Since the section consists of EhSectionPieces,
@@ -106,115 +106,115 @@ getSymbolStrings(ArrayRef<Defined *> Syms) {
// .eh_frame tend to contain a lot of section pieces that are contiguous
// both in input file and output file. Such pieces are squashed before
// being displayed to make output compact.
-static void printEhFrame(raw_ostream &OS, const EhFrameSection *Sec) {
- std::vector<EhSectionPiece> Pieces;
+static void printEhFrame(raw_ostream &os, const EhFrameSection *sec) {
+ std::vector<EhSectionPiece> pieces;
- auto Add = [&](const EhSectionPiece &P) {
+ auto add = [&](const EhSectionPiece &p) {
// If P is adjacent to Last, squash the two.
- if (!Pieces.empty()) {
- EhSectionPiece &Last = Pieces.back();
- if (Last.Sec == P.Sec && Last.InputOff + Last.Size == P.InputOff &&
- Last.OutputOff + Last.Size == P.OutputOff) {
- Last.Size += P.Size;
+ if (!pieces.empty()) {
+ EhSectionPiece &last = pieces.back();
+ if (last.sec == p.sec && last.inputOff + last.size == p.inputOff &&
+ last.outputOff + last.size == p.outputOff) {
+ last.size += p.size;
return;
}
}
- Pieces.push_back(P);
+ pieces.push_back(p);
};
// Gather section pieces.
- for (const CieRecord *Rec : Sec->getCieRecords()) {
- Add(*Rec->Cie);
- for (const EhSectionPiece *Fde : Rec->Fdes)
- Add(*Fde);
+ for (const CieRecord *rec : sec->getCieRecords()) {
+ add(*rec->cie);
+ for (const EhSectionPiece *fde : rec->fdes)
+ add(*fde);
}
// Print out section pieces.
- const OutputSection *OSec = Sec->getOutputSection();
- for (EhSectionPiece &P : Pieces) {
- writeHeader(OS, OSec->Addr + P.OutputOff, OSec->getLMA() + P.OutputOff,
- P.Size, 1);
- OS << Indent8 << toString(P.Sec->File) << ":(" << P.Sec->Name << "+0x"
- << Twine::utohexstr(P.InputOff) + ")\n";
+ const OutputSection *osec = sec->getOutputSection();
+ for (EhSectionPiece &p : pieces) {
+ writeHeader(os, osec->addr + p.outputOff, osec->getLMA() + p.outputOff,
+ p.size, 1);
+ os << indent8 << toString(p.sec->file) << ":(" << p.sec->name << "+0x"
+ << Twine::utohexstr(p.inputOff) + ")\n";
}
}
void elf::writeMapFile() {
- if (Config->MapFile.empty())
+ if (config->mapFile.empty())
return;
// Open a map file for writing.
- std::error_code EC;
- raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
- if (EC) {
- error("cannot open " + Config->MapFile + ": " + EC.message());
+ std::error_code ec;
+ raw_fd_ostream os(config->mapFile, ec, sys::fs::F_None);
+ if (ec) {
+ error("cannot open " + config->mapFile + ": " + ec.message());
return;
}
// Collect symbol info that we want to print out.
- std::vector<Defined *> Syms = getSymbols();
- SymbolMapTy SectionSyms = getSectionSyms(Syms);
- DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms);
+ std::vector<Defined *> syms = getSymbols();
+ SymbolMapTy sectionSyms = getSectionSyms(syms);
+ DenseMap<Symbol *, std::string> symStr = getSymbolStrings(syms);
// Print out the header line.
- int W = Config->Is64 ? 16 : 8;
- OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)
+ int w = config->is64 ? 16 : 8;
+ os << right_justify("VMA", w) << ' ' << right_justify("LMA", w)
<< " Size Align Out In Symbol\n";
- OutputSection* OSec = nullptr;
- for (BaseCommand *Base : Script->SectionCommands) {
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- if (Cmd->Provide && !Cmd->Sym)
+ OutputSection* osec = nullptr;
+ for (BaseCommand *base : script->sectionCommands) {
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ if (cmd->provide && !cmd->sym)
continue;
- uint64_t LMA = OSec ? OSec->getLMA() + Cmd->Addr - OSec->getVA(0) : 0;
- writeHeader(OS, Cmd->Addr, LMA, Cmd->Size, 1);
- OS << Cmd->CommandString << '\n';
+ uint64_t lma = osec ? osec->getLMA() + cmd->addr - osec->getVA(0) : 0;
+ writeHeader(os, cmd->addr, lma, cmd->size, 1);
+ os << cmd->commandString << '\n';
continue;
}
- OSec = cast<OutputSection>(Base);
- writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
- OS << OSec->Name << '\n';
+ osec = cast<OutputSection>(base);
+ writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->alignment);
+ os << osec->name << '\n';
// Dump symbols for each input section.
- for (BaseCommand *Base : OSec->SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- for (InputSection *IS : ISD->Sections) {
- if (auto *EhSec = dyn_cast<EhFrameSection>(IS)) {
- printEhFrame(OS, EhSec);
+ for (BaseCommand *base : osec->sectionCommands) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
+ for (InputSection *isec : isd->sections) {
+ if (auto *ehSec = dyn_cast<EhFrameSection>(isec)) {
+ printEhFrame(os, ehSec);
continue;
}
- writeHeader(OS, IS->getVA(0), OSec->getLMA() + IS->getOffset(0),
- IS->getSize(), IS->Alignment);
- OS << Indent8 << toString(IS) << '\n';
- for (Symbol *Sym : SectionSyms[IS])
- OS << SymStr[Sym] << '\n';
+ writeHeader(os, isec->getVA(0), osec->getLMA() + isec->getOffset(0),
+ isec->getSize(), isec->alignment);
+ os << indent8 << toString(isec) << '\n';
+ for (Symbol *sym : sectionSyms[isec])
+ os << symStr[sym] << '\n';
}
continue;
}
- if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
- writeHeader(OS, OSec->Addr + Cmd->Offset, OSec->getLMA() + Cmd->Offset,
- Cmd->Size, 1);
- OS << Indent8 << Cmd->CommandString << '\n';
+ if (auto *cmd = dyn_cast<ByteCommand>(base)) {
+ writeHeader(os, osec->addr + cmd->offset, osec->getLMA() + cmd->offset,
+ cmd->size, 1);
+ os << indent8 << cmd->commandString << '\n';
continue;
}
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
- if (Cmd->Provide && !Cmd->Sym)
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
+ if (cmd->provide && !cmd->sym)
continue;
- writeHeader(OS, Cmd->Addr, OSec->getLMA() + Cmd->Addr - OSec->getVA(0),
- Cmd->Size, 1);
- OS << Indent8 << Cmd->CommandString << '\n';
+ writeHeader(os, cmd->addr, osec->getLMA() + cmd->addr - osec->getVA(0),
+ cmd->size, 1);
+ os << indent8 << cmd->commandString << '\n';
continue;
}
}
}
}
-static void print(StringRef A, StringRef B) {
- outs() << left_justify(A, 49) << " " << B << "\n";
+static void print(StringRef a, StringRef b) {
+ outs() << left_justify(a, 49) << " " << b << "\n";
}
// Output a cross reference table to stdout. This is for --cref.
@@ -229,18 +229,18 @@ static void print(StringRef A, StringRef B) {
// In this case, strlen is defined by libc.so.6 and used by other two
// files.
void elf::writeCrossReferenceTable() {
- if (!Config->Cref)
+ if (!config->cref)
return;
// Collect symbols and files.
- MapVector<Symbol *, SetVector<InputFile *>> Map;
- for (InputFile *File : ObjectFiles) {
- for (Symbol *Sym : File->getSymbols()) {
- if (isa<SharedSymbol>(Sym))
- Map[Sym].insert(File);
- if (auto *D = dyn_cast<Defined>(Sym))
- if (!D->isLocal() && (!D->Section || D->Section->isLive()))
- Map[D].insert(File);
+ MapVector<Symbol *, SetVector<InputFile *>> map;
+ for (InputFile *file : objectFiles) {
+ for (Symbol *sym : file->getSymbols()) {
+ if (isa<SharedSymbol>(sym))
+ map[sym].insert(file);
+ if (auto *d = dyn_cast<Defined>(sym))
+ if (!d->isLocal() && (!d->section || d->section->isLive()))
+ map[d].insert(file);
}
}
@@ -249,13 +249,13 @@ void elf::writeCrossReferenceTable() {
print("Symbol", "File");
// Print out a table.
- for (auto KV : Map) {
- Symbol *Sym = KV.first;
- SetVector<InputFile *> &Files = KV.second;
+ for (auto kv : map) {
+ Symbol *sym = kv.first;
+ SetVector<InputFile *> &files = kv.second;
- print(toString(*Sym), toString(Sym->File));
- for (InputFile *File : Files)
- if (File != Sym->File)
- print("", toString(File));
+ print(toString(*sym), toString(sym->file));
+ for (InputFile *file : files)
+ if (file != sym->file)
+ print("", toString(file));
}
}
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index ef85075e4a3..1058c97cecc 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -45,76 +45,76 @@ using namespace lld::elf;
namespace {
template <class ELFT> class MarkLive {
public:
- MarkLive(unsigned Partition) : Partition(Partition) {}
+ MarkLive(unsigned partition) : partition(partition) {}
void run();
void moveToMain();
private:
- void enqueue(InputSectionBase *Sec, uint64_t Offset);
- void markSymbol(Symbol *Sym);
+ void enqueue(InputSectionBase *sec, uint64_t offset);
+ void markSymbol(Symbol *sym);
void mark();
template <class RelTy>
- void resolveReloc(InputSectionBase &Sec, RelTy &Rel, bool IsLSDA);
+ void resolveReloc(InputSectionBase &sec, RelTy &rel, bool isLSDA);
template <class RelTy>
- void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels);
+ void scanEhFrameSection(EhInputSection &eh, ArrayRef<RelTy> rels);
// The index of the partition that we are currently processing.
- unsigned Partition;
+ unsigned partition;
// A list of sections to visit.
- SmallVector<InputSection *, 256> Queue;
+ SmallVector<InputSection *, 256> queue;
// There are normally few input sections whose names are valid C
// identifiers, so we just store a std::vector instead of a multimap.
- DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
+ DenseMap<StringRef, std::vector<InputSectionBase *>> cNamedSections;
};
} // namespace
template <class ELFT>
-static uint64_t getAddend(InputSectionBase &Sec,
- const typename ELFT::Rel &Rel) {
- return Target->getImplicitAddend(Sec.data().begin() + Rel.r_offset,
- Rel.getType(Config->IsMips64EL));
+static uint64_t getAddend(InputSectionBase &sec,
+ const typename ELFT::Rel &rel) {
+ return target->getImplicitAddend(sec.data().begin() + rel.r_offset,
+ rel.getType(config->isMips64EL));
}
template <class ELFT>
-static uint64_t getAddend(InputSectionBase &Sec,
- const typename ELFT::Rela &Rel) {
- return Rel.r_addend;
+static uint64_t getAddend(InputSectionBase &sec,
+ const typename ELFT::Rela &rel) {
+ return rel.r_addend;
}
template <class ELFT>
template <class RelTy>
-void MarkLive<ELFT>::resolveReloc(InputSectionBase &Sec, RelTy &Rel,
- bool IsLSDA) {
- Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
+void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
+ bool isLSDA) {
+ Symbol &sym = sec.getFile<ELFT>()->getRelocTargetSym(rel);
// If a symbol is referenced in a live section, it is used.
- Sym.Used = true;
+ sym.used = true;
- if (auto *D = dyn_cast<Defined>(&Sym)) {
- auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section);
- if (!RelSec)
+ if (auto *d = dyn_cast<Defined>(&sym)) {
+ auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section);
+ if (!relSec)
return;
- uint64_t Offset = D->Value;
- if (D->isSection())
- Offset += getAddend<ELFT>(Sec, Rel);
+ uint64_t offset = d->value;
+ if (d->isSection())
+ offset += getAddend<ELFT>(sec, rel);
- if (!IsLSDA || !(RelSec->Flags & SHF_EXECINSTR))
- enqueue(RelSec, Offset);
+ if (!isLSDA || !(relSec->flags & SHF_EXECINSTR))
+ enqueue(relSec, offset);
return;
}
- if (auto *SS = dyn_cast<SharedSymbol>(&Sym))
- if (!SS->isWeak())
- SS->getFile().IsNeeded = true;
+ if (auto *ss = dyn_cast<SharedSymbol>(&sym))
+ if (!ss->isWeak())
+ ss->getFile().isNeeded = true;
- for (InputSectionBase *Sec : CNamedSections.lookup(Sym.getName()))
- enqueue(Sec, 0);
+ for (InputSectionBase *sec : cNamedSections.lookup(sym.getName()))
+ enqueue(sec, 0);
}
// The .eh_frame section is an unfortunate special case.
@@ -133,80 +133,80 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &Sec, RelTy &Rel,
// LSDAs and personality functions if we found that they were unused.
template <class ELFT>
template <class RelTy>
-void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &EH,
- ArrayRef<RelTy> Rels) {
- for (size_t I = 0, End = EH.Pieces.size(); I < End; ++I) {
- EhSectionPiece &Piece = EH.Pieces[I];
- size_t FirstRelI = Piece.FirstRelocation;
- if (FirstRelI == (unsigned)-1)
+void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &eh,
+ ArrayRef<RelTy> rels) {
+ for (size_t i = 0, end = eh.pieces.size(); i < end; ++i) {
+ EhSectionPiece &piece = eh.pieces[i];
+ size_t firstRelI = piece.firstRelocation;
+ if (firstRelI == (unsigned)-1)
continue;
- if (read32<ELFT::TargetEndianness>(Piece.data().data() + 4) == 0) {
+ if (read32<ELFT::TargetEndianness>(piece.data().data() + 4) == 0) {
// This is a CIE, we only need to worry about the first relocation. It is
// known to point to the personality function.
- resolveReloc(EH, Rels[FirstRelI], false);
+ resolveReloc(eh, rels[firstRelI], false);
continue;
}
// This is a FDE. The relocations point to the described function or to
// a LSDA. We only need to keep the LSDA alive, so ignore anything that
// points to executable sections.
- uint64_t PieceEnd = Piece.InputOff + Piece.Size;
- for (size_t J = FirstRelI, End2 = Rels.size(); J < End2; ++J)
- if (Rels[J].r_offset < PieceEnd)
- resolveReloc(EH, Rels[J], true);
+ uint64_t pieceEnd = piece.inputOff + piece.size;
+ for (size_t j = firstRelI, end2 = rels.size(); j < end2; ++j)
+ if (rels[j].r_offset < pieceEnd)
+ resolveReloc(eh, rels[j], true);
}
}
// Some sections are used directly by the loader, so they should never be
// garbage-collected. This function returns true if a given section is such
// section.
-static bool isReserved(InputSectionBase *Sec) {
- switch (Sec->Type) {
+static bool isReserved(InputSectionBase *sec) {
+ switch (sec->type) {
case SHT_FINI_ARRAY:
case SHT_INIT_ARRAY:
case SHT_NOTE:
case SHT_PREINIT_ARRAY:
return true;
default:
- StringRef S = Sec->Name;
- return S.startswith(".ctors") || S.startswith(".dtors") ||
- S.startswith(".init") || S.startswith(".fini") ||
- S.startswith(".jcr");
+ StringRef s = sec->name;
+ return s.startswith(".ctors") || s.startswith(".dtors") ||
+ s.startswith(".init") || s.startswith(".fini") ||
+ s.startswith(".jcr");
}
}
template <class ELFT>
-void MarkLive<ELFT>::enqueue(InputSectionBase *Sec, uint64_t Offset) {
+void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
// Skip over discarded sections. This in theory shouldn't happen, because
// the ELF spec doesn't allow a relocation to point to a deduplicated
// COMDAT section directly. Unfortunately this happens in practice (e.g.
// .eh_frame) so we need to add a check.
- if (Sec == &InputSection::Discarded)
+ if (sec == &InputSection::discarded)
return;
// Usually, a whole section is marked as live or dead, but in mergeable
// (splittable) sections, each piece of data has independent liveness bit.
// So we explicitly tell it which offset is in use.
- if (auto *MS = dyn_cast<MergeInputSection>(Sec))
- MS->getSectionPiece(Offset)->Live = true;
+ if (auto *ms = dyn_cast<MergeInputSection>(sec))
+ ms->getSectionPiece(offset)->live = true;
// Set Sec->Partition to the meet (i.e. the "minimum") of Partition and
// Sec->Partition in the following lattice: 1 < other < 0. If Sec->Partition
// doesn't change, we don't need to do anything.
- if (Sec->Partition == 1 || Sec->Partition == Partition)
+ if (sec->partition == 1 || sec->partition == partition)
return;
- Sec->Partition = Sec->Partition ? 1 : Partition;
+ sec->partition = sec->partition ? 1 : partition;
// Add input section to the queue.
- if (InputSection *S = dyn_cast<InputSection>(Sec))
- Queue.push_back(S);
+ if (InputSection *s = dyn_cast<InputSection>(sec))
+ queue.push_back(s);
}
-template <class ELFT> void MarkLive<ELFT>::markSymbol(Symbol *Sym) {
- if (auto *D = dyn_cast_or_null<Defined>(Sym))
- if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section))
- enqueue(IS, D->Value);
+template <class ELFT> void MarkLive<ELFT>::markSymbol(Symbol *sym) {
+ if (auto *d = dyn_cast_or_null<Defined>(sym))
+ if (auto *isec = dyn_cast_or_null<InputSectionBase>(d->section))
+ enqueue(isec, d->value);
}
// This is the main function of the garbage collector.
@@ -217,51 +217,51 @@ template <class ELFT> void MarkLive<ELFT>::run() {
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
- Symtab->forEachSymbol([&](Symbol *Sym) {
- if (Sym->includeInDynsym() && Sym->Partition == Partition)
- markSymbol(Sym);
+ symtab->forEachSymbol([&](Symbol *sym) {
+ if (sym->includeInDynsym() && sym->partition == partition)
+ markSymbol(sym);
});
// If this isn't the main partition, that's all that we need to preserve.
- if (Partition != 1) {
+ if (partition != 1) {
mark();
return;
}
- markSymbol(Symtab->find(Config->Entry));
- markSymbol(Symtab->find(Config->Init));
- markSymbol(Symtab->find(Config->Fini));
- for (StringRef S : Config->Undefined)
- markSymbol(Symtab->find(S));
- for (StringRef S : Script->ReferencedSymbols)
- markSymbol(Symtab->find(S));
+ markSymbol(symtab->find(config->entry));
+ markSymbol(symtab->find(config->init));
+ markSymbol(symtab->find(config->fini));
+ for (StringRef s : config->undefined)
+ markSymbol(symtab->find(s));
+ for (StringRef s : script->referencedSymbols)
+ markSymbol(symtab->find(s));
// Preserve special sections and those which are specified in linker
// script KEEP command.
- for (InputSectionBase *Sec : InputSections) {
+ for (InputSectionBase *sec : inputSections) {
// Mark .eh_frame sections as live because there are usually no relocations
// that point to .eh_frames. Otherwise, the garbage collector would drop
// all of them. We also want to preserve personality routines and LSDA
// referenced by .eh_frame sections, so we scan them for that here.
- if (auto *EH = dyn_cast<EhInputSection>(Sec)) {
- EH->markLive();
- if (!EH->NumRelocations)
+ if (auto *eh = dyn_cast<EhInputSection>(sec)) {
+ eh->markLive();
+ if (!eh->numRelocations)
continue;
- if (EH->AreRelocsRela)
- scanEhFrameSection(*EH, EH->template relas<ELFT>());
+ if (eh->areRelocsRela)
+ scanEhFrameSection(*eh, eh->template relas<ELFT>());
else
- scanEhFrameSection(*EH, EH->template rels<ELFT>());
+ scanEhFrameSection(*eh, eh->template rels<ELFT>());
}
- if (Sec->Flags & SHF_LINK_ORDER)
+ if (sec->flags & SHF_LINK_ORDER)
continue;
- if (isReserved(Sec) || Script->shouldKeep(Sec)) {
- enqueue(Sec, 0);
- } else if (isValidCIdentifier(Sec->Name)) {
- CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
- CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
+ if (isReserved(sec) || script->shouldKeep(sec)) {
+ enqueue(sec, 0);
+ } else if (isValidCIdentifier(sec->name)) {
+ cNamedSections[Saver.save("__start_" + sec->name)].push_back(sec);
+ cNamedSections[Saver.save("__stop_" + sec->name)].push_back(sec);
}
}
@@ -270,19 +270,19 @@ template <class ELFT> void MarkLive<ELFT>::run() {
template <class ELFT> void MarkLive<ELFT>::mark() {
// Mark all reachable sections.
- while (!Queue.empty()) {
- InputSectionBase &Sec = *Queue.pop_back_val();
+ while (!queue.empty()) {
+ InputSectionBase &sec = *queue.pop_back_val();
- if (Sec.AreRelocsRela) {
- for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>())
- resolveReloc(Sec, Rel, false);
+ if (sec.areRelocsRela) {
+ for (const typename ELFT::Rela &rel : sec.template relas<ELFT>())
+ resolveReloc(sec, rel, false);
} else {
- for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>())
- resolveReloc(Sec, Rel, false);
+ for (const typename ELFT::Rel &rel : sec.template rels<ELFT>())
+ resolveReloc(sec, rel, false);
}
- for (InputSectionBase *IS : Sec.DependentSections)
- enqueue(IS, 0);
+ for (InputSectionBase *isec : sec.dependentSections)
+ enqueue(isec, 0);
}
}
@@ -292,12 +292,12 @@ template <class ELFT> void MarkLive<ELFT>::mark() {
// loaded) and TLS symbols (because we only know how to correctly process TLS
// relocations for the main partition).
template <class ELFT> void MarkLive<ELFT>::moveToMain() {
- for (InputFile *File : ObjectFiles)
- for (Symbol *S : File->getSymbols())
- if (auto *D = dyn_cast<Defined>(S))
- if ((D->Type == STT_GNU_IFUNC || D->Type == STT_TLS) && D->Section &&
- D->Section->isLive())
- markSymbol(S);
+ for (InputFile *file : objectFiles)
+ for (Symbol *s : file->getSymbols())
+ if (auto *d = dyn_cast<Defined>(s))
+ if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section &&
+ d->section->isLive())
+ markSymbol(s);
mark();
}
@@ -307,15 +307,15 @@ template <class ELFT> void MarkLive<ELFT>::moveToMain() {
// so that they are emitted to the output file.
template <class ELFT> void elf::markLive() {
// If -gc-sections is not given, no sections are removed.
- if (!Config->GcSections) {
- for (InputSectionBase *Sec : InputSections)
- Sec->markLive();
+ if (!config->gcSections) {
+ for (InputSectionBase *sec : inputSections)
+ sec->markLive();
// If a DSO defines a symbol referenced in a regular object, it is needed.
- Symtab->forEachSymbol([](Symbol *Sym) {
- if (auto *S = dyn_cast<SharedSymbol>(Sym))
- if (S->IsUsedInRegularObj && !S->isWeak())
- S->getFile().IsNeeded = true;
+ symtab->forEachSymbol([](Symbol *sym) {
+ if (auto *s = dyn_cast<SharedSymbol>(sym))
+ if (s->isUsedInRegularObj && !s->isWeak())
+ s->getFile().isNeeded = true;
});
return;
}
@@ -341,30 +341,30 @@ template <class ELFT> void elf::markLive() {
// or -emit-reloc were given. And they are subject of garbage
// collection because, if we remove a text section, we also
// remove its relocation section.
- for (InputSectionBase *Sec : InputSections) {
- bool IsAlloc = (Sec->Flags & SHF_ALLOC);
- bool IsLinkOrder = (Sec->Flags & SHF_LINK_ORDER);
- bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
+ for (InputSectionBase *sec : inputSections) {
+ bool isAlloc = (sec->flags & SHF_ALLOC);
+ bool isLinkOrder = (sec->flags & SHF_LINK_ORDER);
+ bool isRel = (sec->type == SHT_REL || sec->type == SHT_RELA);
- if (!IsAlloc && !IsLinkOrder && !IsRel)
- Sec->markLive();
+ if (!isAlloc && !isLinkOrder && !isRel)
+ sec->markLive();
}
// Follow the graph to mark all live sections.
- for (unsigned CurPart = 1; CurPart <= Partitions.size(); ++CurPart)
- MarkLive<ELFT>(CurPart).run();
+ for (unsigned curPart = 1; curPart <= partitions.size(); ++curPart)
+ MarkLive<ELFT>(curPart).run();
// If we have multiple partitions, some sections need to live in the main
// partition even if they were allocated to a loadable partition. Move them
// there now.
- if (Partitions.size() != 1)
+ if (partitions.size() != 1)
MarkLive<ELFT>(1).moveToMain();
// Report garbage-collected sections.
- if (Config->PrintGcSections)
- for (InputSectionBase *Sec : InputSections)
- if (!Sec->isLive())
- message("removing unused section " + toString(Sec));
+ if (config->printGcSections)
+ for (InputSectionBase *sec : inputSections)
+ if (!sec->isLive())
+ message("removing unused section " + toString(sec));
}
template void elf::markLive<ELF32LE>();
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 8048609565e..a89bd509bc9 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -30,45 +30,45 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-uint8_t *Out::BufferStart;
-uint8_t Out::First;
-PhdrEntry *Out::TlsPhdr;
-OutputSection *Out::ElfHeader;
-OutputSection *Out::ProgramHeaders;
-OutputSection *Out::PreinitArray;
-OutputSection *Out::InitArray;
-OutputSection *Out::FiniArray;
+uint8_t *Out::bufferStart;
+uint8_t Out::first;
+PhdrEntry *Out::tlsPhdr;
+OutputSection *Out::elfHeader;
+OutputSection *Out::programHeaders;
+OutputSection *Out::preinitArray;
+OutputSection *Out::initArray;
+OutputSection *Out::finiArray;
-std::vector<OutputSection *> elf::OutputSections;
+std::vector<OutputSection *> elf::outputSections;
uint32_t OutputSection::getPhdrFlags() const {
- uint32_t Ret = 0;
- if (Config->EMachine != EM_ARM || !(Flags & SHF_ARM_PURECODE))
- Ret |= PF_R;
- if (Flags & SHF_WRITE)
- Ret |= PF_W;
- if (Flags & SHF_EXECINSTR)
- Ret |= PF_X;
- return Ret;
+ uint32_t ret = 0;
+ if (config->emachine != EM_ARM || !(flags & SHF_ARM_PURECODE))
+ ret |= PF_R;
+ if (flags & SHF_WRITE)
+ ret |= PF_W;
+ if (flags & SHF_EXECINSTR)
+ ret |= PF_X;
+ return ret;
}
template <class ELFT>
-void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
- Shdr->sh_entsize = Entsize;
- Shdr->sh_addralign = Alignment;
- Shdr->sh_type = Type;
- Shdr->sh_offset = Offset;
- Shdr->sh_flags = Flags;
- Shdr->sh_info = Info;
- Shdr->sh_link = Link;
- Shdr->sh_addr = Addr;
- Shdr->sh_size = Size;
- Shdr->sh_name = ShName;
+void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) {
+ shdr->sh_entsize = entsize;
+ shdr->sh_addralign = alignment;
+ shdr->sh_type = type;
+ shdr->sh_offset = offset;
+ shdr->sh_flags = flags;
+ shdr->sh_info = info;
+ shdr->sh_link = link;
+ shdr->sh_addr = addr;
+ shdr->sh_size = size;
+ shdr->sh_name = shName;
}
-OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
+OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags)
: BaseCommand(OutputSectionKind),
- SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
+ SectionBase(Output, name, flags, /*Entsize*/ 0, /*Alignment*/ 1, type,
/*Info*/ 0, /*Link*/ 0) {}
// We allow sections of types listed below to merged into a
@@ -77,102 +77,102 @@ OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
// to be allocated for nobits sections. Other ones don't require
// any special treatment on top of progbits, so there doesn't
// seem to be a harm in merging them.
-static bool canMergeToProgbits(unsigned Type) {
- return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY ||
- Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY ||
- Type == SHT_NOTE;
+static bool canMergeToProgbits(unsigned type) {
+ return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY ||
+ type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY ||
+ type == SHT_NOTE;
}
-void OutputSection::addSection(InputSection *IS) {
- if (!HasInputSections) {
+void OutputSection::addSection(InputSection *isec) {
+ if (!hasInputSections) {
// If IS is the first section to be added to this section,
// initialize Partition, Type, Entsize and flags from IS.
- HasInputSections = true;
- Partition = IS->Partition;
- Type = IS->Type;
- Entsize = IS->Entsize;
- Flags = IS->Flags;
+ hasInputSections = true;
+ partition = isec->partition;
+ type = isec->type;
+ entsize = isec->entsize;
+ flags = isec->flags;
} else {
// Otherwise, check if new type or flags are compatible with existing ones.
- unsigned Mask = SHF_TLS | SHF_LINK_ORDER;
- if ((Flags & Mask) != (IS->Flags & Mask))
- error("incompatible section flags for " + Name + "\n>>> " + toString(IS) +
- ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name +
- ": 0x" + utohexstr(Flags));
-
- if (Type != IS->Type) {
- if (!canMergeToProgbits(Type) || !canMergeToProgbits(IS->Type))
- error("section type mismatch for " + IS->Name + "\n>>> " +
- toString(IS) + ": " +
- getELFSectionTypeName(Config->EMachine, IS->Type) +
- "\n>>> output section " + Name + ": " +
- getELFSectionTypeName(Config->EMachine, Type));
- Type = SHT_PROGBITS;
+ unsigned mask = SHF_TLS | SHF_LINK_ORDER;
+ if ((flags & mask) != (isec->flags & mask))
+ error("incompatible section flags for " + name + "\n>>> " + toString(isec) +
+ ": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name +
+ ": 0x" + utohexstr(flags));
+
+ if (type != isec->type) {
+ if (!canMergeToProgbits(type) || !canMergeToProgbits(isec->type))
+ error("section type mismatch for " + isec->name + "\n>>> " +
+ toString(isec) + ": " +
+ getELFSectionTypeName(config->emachine, isec->type) +
+ "\n>>> output section " + name + ": " +
+ getELFSectionTypeName(config->emachine, type));
+ type = SHT_PROGBITS;
}
}
- IS->Parent = this;
- uint64_t AndMask =
- Config->EMachine == EM_ARM ? (uint64_t)SHF_ARM_PURECODE : 0;
- uint64_t OrMask = ~AndMask;
- uint64_t AndFlags = (Flags & IS->Flags) & AndMask;
- uint64_t OrFlags = (Flags | IS->Flags) & OrMask;
- Flags = AndFlags | OrFlags;
+ isec->parent = this;
+ uint64_t andMask =
+ config->emachine == EM_ARM ? (uint64_t)SHF_ARM_PURECODE : 0;
+ uint64_t orMask = ~andMask;
+ uint64_t andFlags = (flags & isec->flags) & andMask;
+ uint64_t orFlags = (flags | isec->flags) & orMask;
+ flags = andFlags | orFlags;
- Alignment = std::max(Alignment, IS->Alignment);
+ alignment = std::max(alignment, isec->alignment);
// If this section contains a table of fixed-size entries, sh_entsize
// holds the element size. If it contains elements of different size we
// set sh_entsize to 0.
- if (Entsize != IS->Entsize)
- Entsize = 0;
-
- if (!IS->Assigned) {
- IS->Assigned = true;
- if (SectionCommands.empty() ||
- !isa<InputSectionDescription>(SectionCommands.back()))
- SectionCommands.push_back(make<InputSectionDescription>(""));
- auto *ISD = cast<InputSectionDescription>(SectionCommands.back());
- ISD->Sections.push_back(IS);
+ if (entsize != isec->entsize)
+ entsize = 0;
+
+ if (!isec->assigned) {
+ isec->assigned = true;
+ if (sectionCommands.empty() ||
+ !isa<InputSectionDescription>(sectionCommands.back()))
+ sectionCommands.push_back(make<InputSectionDescription>(""));
+ auto *isd = cast<InputSectionDescription>(sectionCommands.back());
+ isd->sections.push_back(isec);
}
}
-static void sortByOrder(MutableArrayRef<InputSection *> In,
- llvm::function_ref<int(InputSectionBase *S)> Order) {
- std::vector<std::pair<int, InputSection *>> V;
- for (InputSection *S : In)
- V.push_back({Order(S), S});
- llvm::stable_sort(V, less_first());
+static void sortByOrder(MutableArrayRef<InputSection *> in,
+ llvm::function_ref<int(InputSectionBase *s)> order) {
+ std::vector<std::pair<int, InputSection *>> v;
+ for (InputSection *s : in)
+ v.push_back({order(s), s});
+ llvm::stable_sort(v, less_first());
- for (size_t I = 0; I < V.size(); ++I)
- In[I] = V[I].second;
+ for (size_t i = 0; i < v.size(); ++i)
+ in[i] = v[i].second;
}
uint64_t elf::getHeaderSize() {
- if (Config->OFormatBinary)
+ if (config->oFormatBinary)
return 0;
- return Out::ElfHeader->Size + Out::ProgramHeaders->Size;
+ return Out::elfHeader->size + Out::programHeaders->size;
}
-bool OutputSection::classof(const BaseCommand *C) {
- return C->Kind == OutputSectionKind;
+bool OutputSection::classof(const BaseCommand *c) {
+ return c->kind == OutputSectionKind;
}
-void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) {
+void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) {
assert(isLive());
- for (BaseCommand *B : SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- sortByOrder(ISD->Sections, Order);
+ for (BaseCommand *b : sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(b))
+ sortByOrder(isd->sections, order);
}
// Fill [Buf, Buf + Size) with Filler.
// This is used for linker script "=fillexp" command.
-static void fill(uint8_t *Buf, size_t Size,
- const std::array<uint8_t, 4> &Filler) {
- size_t I = 0;
- for (; I + 4 < Size; I += 4)
- memcpy(Buf + I, Filler.data(), 4);
- memcpy(Buf + I, Filler.data(), Size - I);
+static void fill(uint8_t *buf, size_t size,
+ const std::array<uint8_t, 4> &filler) {
+ size_t i = 0;
+ for (; i + 4 < size; i += 4)
+ memcpy(buf + i, filler.data(), 4);
+ memcpy(buf + i, filler.data(), size - i);
}
// Compress section contents if this section contains debug info.
@@ -180,145 +180,145 @@ template <class ELFT> void OutputSection::maybeCompress() {
using Elf_Chdr = typename ELFT::Chdr;
// Compress only DWARF debug sections.
- if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) ||
- !Name.startswith(".debug_"))
+ if (!config->compressDebugSections || (flags & SHF_ALLOC) ||
+ !name.startswith(".debug_"))
return;
// Create a section header.
- ZDebugHeader.resize(sizeof(Elf_Chdr));
- auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data());
- Hdr->ch_type = ELFCOMPRESS_ZLIB;
- Hdr->ch_size = Size;
- Hdr->ch_addralign = Alignment;
+ zDebugHeader.resize(sizeof(Elf_Chdr));
+ auto *hdr = reinterpret_cast<Elf_Chdr *>(zDebugHeader.data());
+ hdr->ch_type = ELFCOMPRESS_ZLIB;
+ hdr->ch_size = size;
+ hdr->ch_addralign = alignment;
// Write section contents to a temporary buffer and compress it.
- std::vector<uint8_t> Buf(Size);
- writeTo<ELFT>(Buf.data());
- if (Error E = zlib::compress(toStringRef(Buf), CompressedData))
- fatal("compress failed: " + llvm::toString(std::move(E)));
+ std::vector<uint8_t> buf(size);
+ writeTo<ELFT>(buf.data());
+ if (Error e = zlib::compress(toStringRef(buf), compressedData))
+ fatal("compress failed: " + llvm::toString(std::move(e)));
// Update section headers.
- Size = sizeof(Elf_Chdr) + CompressedData.size();
- Flags |= SHF_COMPRESSED;
+ size = sizeof(Elf_Chdr) + compressedData.size();
+ flags |= SHF_COMPRESSED;
}
-static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
- if (Size == 1)
- *Buf = Data;
- else if (Size == 2)
- write16(Buf, Data);
- else if (Size == 4)
- write32(Buf, Data);
- else if (Size == 8)
- write64(Buf, Data);
+static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
+ if (size == 1)
+ *buf = data;
+ else if (size == 2)
+ write16(buf, data);
+ else if (size == 4)
+ write32(buf, data);
+ else if (size == 8)
+ write64(buf, data);
else
llvm_unreachable("unsupported Size argument");
}
-template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
- if (Type == SHT_NOBITS)
+template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
+ if (type == SHT_NOBITS)
return;
// If -compress-debug-section is specified and if this is a debug seciton,
// we've already compressed section contents. If that's the case,
// just write it down.
- if (!CompressedData.empty()) {
- memcpy(Buf, ZDebugHeader.data(), ZDebugHeader.size());
- memcpy(Buf + ZDebugHeader.size(), CompressedData.data(),
- CompressedData.size());
+ if (!compressedData.empty()) {
+ memcpy(buf, zDebugHeader.data(), zDebugHeader.size());
+ memcpy(buf + zDebugHeader.size(), compressedData.data(),
+ compressedData.size());
return;
}
// Write leading padding.
- std::vector<InputSection *> Sections = getInputSections(this);
- std::array<uint8_t, 4> Filler = getFiller();
- bool NonZeroFiller = read32(Filler.data()) != 0;
- if (NonZeroFiller)
- fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
+ std::vector<InputSection *> sections = getInputSections(this);
+ std::array<uint8_t, 4> filler = getFiller();
+ bool nonZeroFiller = read32(filler.data()) != 0;
+ if (nonZeroFiller)
+ fill(buf, sections.empty() ? size : sections[0]->outSecOff, filler);
- parallelForEachN(0, Sections.size(), [&](size_t I) {
- InputSection *IS = Sections[I];
- IS->writeTo<ELFT>(Buf);
+ parallelForEachN(0, sections.size(), [&](size_t i) {
+ InputSection *isec = sections[i];
+ isec->writeTo<ELFT>(buf);
// Fill gaps between sections.
- if (NonZeroFiller) {
- uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
- uint8_t *End;
- if (I + 1 == Sections.size())
- End = Buf + Size;
+ if (nonZeroFiller) {
+ uint8_t *start = buf + isec->outSecOff + isec->getSize();
+ uint8_t *end;
+ if (i + 1 == sections.size())
+ end = buf + size;
else
- End = Buf + Sections[I + 1]->OutSecOff;
- fill(Start, End - Start, Filler);
+ end = buf + sections[i + 1]->outSecOff;
+ fill(start, end - start, filler);
}
});
// Linker scripts may have BYTE()-family commands with which you
// can write arbitrary bytes to the output. Process them if any.
- for (BaseCommand *Base : SectionCommands)
- if (auto *Data = dyn_cast<ByteCommand>(Base))
- writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
+ for (BaseCommand *base : sectionCommands)
+ if (auto *data = dyn_cast<ByteCommand>(base))
+ writeInt(buf + data->offset, data->expression().getValue(), data->size);
}
-static void finalizeShtGroup(OutputSection *OS,
- InputSection *Section) {
- assert(Config->Relocatable);
+static void finalizeShtGroup(OutputSection *os,
+ InputSection *section) {
+ assert(config->relocatable);
// sh_link field for SHT_GROUP sections should contain the section index of
// the symbol table.
- OS->Link = In.SymTab->getParent()->SectionIndex;
+ os->link = in.symTab->getParent()->sectionIndex;
// sh_info then contain index of an entry in symbol table section which
// provides signature of the section group.
- ArrayRef<Symbol *> Symbols = Section->File->getSymbols();
- OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
+ ArrayRef<Symbol *> symbols = section->file->getSymbols();
+ os->info = in.symTab->getSymbolIndex(symbols[section->info]);
}
void OutputSection::finalize() {
- std::vector<InputSection *> V = getInputSections(this);
- InputSection *First = V.empty() ? nullptr : V[0];
+ std::vector<InputSection *> v = getInputSections(this);
+ InputSection *first = v.empty() ? nullptr : v[0];
- if (Flags & SHF_LINK_ORDER) {
+ if (flags & SHF_LINK_ORDER) {
// We must preserve the link order dependency of sections with the
// SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
// need to translate the InputSection sh_link to the OutputSection sh_link,
// all InputSections in the OutputSection have the same dependency.
- if (auto *EX = dyn_cast<ARMExidxSyntheticSection>(First))
- Link = EX->getLinkOrderDep()->getParent()->SectionIndex;
- else if (auto *D = First->getLinkOrderDep())
- Link = D->getParent()->SectionIndex;
+ if (auto *ex = dyn_cast<ARMExidxSyntheticSection>(first))
+ link = ex->getLinkOrderDep()->getParent()->sectionIndex;
+ else if (auto *d = first->getLinkOrderDep())
+ link = d->getParent()->sectionIndex;
}
- if (Type == SHT_GROUP) {
- finalizeShtGroup(this, First);
+ if (type == SHT_GROUP) {
+ finalizeShtGroup(this, first);
return;
}
- if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
+ if (!config->copyRelocs || (type != SHT_RELA && type != SHT_REL))
return;
- if (isa<SyntheticSection>(First))
+ if (isa<SyntheticSection>(first))
return;
- Link = In.SymTab->getParent()->SectionIndex;
+ link = in.symTab->getParent()->sectionIndex;
// sh_info for SHT_REL[A] sections should contain the section header index of
// the section to which the relocation applies.
- InputSectionBase *S = First->getRelocatedSection();
- Info = S->getOutputSection()->SectionIndex;
- Flags |= SHF_INFO_LINK;
+ InputSectionBase *s = first->getRelocatedSection();
+ info = s->getOutputSection()->sectionIndex;
+ flags |= SHF_INFO_LINK;
}
// Returns true if S matches /Filename.?\.o$/.
-static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
- if (!S.endswith(".o"))
+static bool isCrtBeginEnd(StringRef s, StringRef filename) {
+ if (!s.endswith(".o"))
return false;
- S = S.drop_back(2);
- if (S.endswith(Filename))
+ s = s.drop_back(2);
+ if (s.endswith(filename))
return true;
- return !S.empty() && S.drop_back().endswith(Filename);
+ return !s.empty() && s.drop_back().endswith(filename);
}
-static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
-static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
+static bool isCrtbegin(StringRef s) { return isCrtBeginEnd(s, "crtbegin"); }
+static bool isCrtend(StringRef s) { return isCrtBeginEnd(s, "crtend"); }
// .ctors and .dtors are sorted by this priority from highest to lowest.
//
@@ -338,52 +338,52 @@ static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
// .ctors are duplicate features (and .init_array is newer.) However, there
// are too many real-world use cases of .ctors, so we had no choice to
// support that with this rather ad-hoc semantics.
-static bool compCtors(const InputSection *A, const InputSection *B) {
- bool BeginA = isCrtbegin(A->File->getName());
- bool BeginB = isCrtbegin(B->File->getName());
- if (BeginA != BeginB)
- return BeginA;
- bool EndA = isCrtend(A->File->getName());
- bool EndB = isCrtend(B->File->getName());
- if (EndA != EndB)
- return EndB;
- StringRef X = A->Name;
- StringRef Y = B->Name;
- assert(X.startswith(".ctors") || X.startswith(".dtors"));
- assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
- X = X.substr(6);
- Y = Y.substr(6);
- return X < Y;
+static bool compCtors(const InputSection *a, const InputSection *b) {
+ bool beginA = isCrtbegin(a->file->getName());
+ bool beginB = isCrtbegin(b->file->getName());
+ if (beginA != beginB)
+ return beginA;
+ bool endA = isCrtend(a->file->getName());
+ bool endB = isCrtend(b->file->getName());
+ if (endA != endB)
+ return endB;
+ StringRef x = a->name;
+ StringRef y = b->name;
+ assert(x.startswith(".ctors") || x.startswith(".dtors"));
+ assert(y.startswith(".ctors") || y.startswith(".dtors"));
+ x = x.substr(6);
+ y = y.substr(6);
+ return x < y;
}
// Sorts input sections by the special rules for .ctors and .dtors.
// Unfortunately, the rules are different from the one for .{init,fini}_array.
// Read the comment above.
void OutputSection::sortCtorsDtors() {
- assert(SectionCommands.size() == 1);
- auto *ISD = cast<InputSectionDescription>(SectionCommands[0]);
- llvm::stable_sort(ISD->Sections, compCtors);
+ assert(sectionCommands.size() == 1);
+ auto *isd = cast<InputSectionDescription>(sectionCommands[0]);
+ llvm::stable_sort(isd->sections, compCtors);
}
// If an input string is in the form of "foo.N" where N is a number,
// return N. Otherwise, returns 65536, which is one greater than the
// lowest priority.
-int elf::getPriority(StringRef S) {
- size_t Pos = S.rfind('.');
- if (Pos == StringRef::npos)
+int elf::getPriority(StringRef s) {
+ size_t pos = s.rfind('.');
+ if (pos == StringRef::npos)
return 65536;
- int V;
- if (!to_integer(S.substr(Pos + 1), V, 10))
+ int v;
+ if (!to_integer(s.substr(pos + 1), v, 10))
return 65536;
- return V;
+ return v;
}
-std::vector<InputSection *> elf::getInputSections(OutputSection *OS) {
- std::vector<InputSection *> Ret;
- for (BaseCommand *Base : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- Ret.insert(Ret.end(), ISD->Sections.begin(), ISD->Sections.end());
- return Ret;
+std::vector<InputSection *> elf::getInputSections(OutputSection *os) {
+ std::vector<InputSection *> ret;
+ for (BaseCommand *base : os->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ ret.insert(ret.end(), isd->sections.begin(), isd->sections.end());
+ return ret;
}
// Sorts input sections by section name suffixes, so that .foo.N comes
@@ -394,14 +394,14 @@ std::vector<InputSection *> elf::getInputSections(OutputSection *OS) {
// For more detail, read the section of the GCC's manual about init_priority.
void OutputSection::sortInitFini() {
// Sort sections by priority.
- sort([](InputSectionBase *S) { return getPriority(S->Name); });
+ sort([](InputSectionBase *s) { return getPriority(s->name); });
}
std::array<uint8_t, 4> OutputSection::getFiller() {
- if (Filler)
- return *Filler;
- if (Flags & SHF_EXECINSTR)
- return Target->TrapInstr;
+ if (filler)
+ return *filler;
+ if (flags & SHF_EXECINSTR)
+ return target->trapInstr;
return {0, 0, 0, 0};
}
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index dded729271a..fff8327ea37 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -31,19 +31,19 @@ class InputSectionBase;
// non-overlapping file offsets and VAs.
class OutputSection final : public BaseCommand, public SectionBase {
public:
- OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
+ OutputSection(StringRef name, uint32_t type, uint64_t flags);
- static bool classof(const SectionBase *S) {
- return S->kind() == SectionBase::Output;
+ static bool classof(const SectionBase *s) {
+ return s->kind() == SectionBase::Output;
}
- static bool classof(const BaseCommand *C);
+ static bool classof(const BaseCommand *c);
- uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; }
- template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
+ uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; }
+ template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);
- uint32_t SectionIndex = UINT32_MAX;
- unsigned SortRank;
+ uint32_t sectionIndex = UINT32_MAX;
+ unsigned sortRank;
uint32_t getPhdrFlags() const;
@@ -54,82 +54,82 @@ public:
// section offset we use the following formula: Off = Off_first + VA -
// VA_first, where Off_first and VA_first is file offset and VA of first
// section in PT_LOAD.
- PhdrEntry *PtLoad = nullptr;
+ PhdrEntry *ptLoad = nullptr;
// Pointer to a relocation section for this section. Usually nullptr because
// we consume relocations, but if --emit-relocs is specified (which is rare),
// it may have a non-null value.
- OutputSection *RelocationSection = nullptr;
+ OutputSection *relocationSection = nullptr;
// Initially this field is the number of InputSections that have been added to
// the OutputSection so far. Later on, after a call to assignAddresses, it
// corresponds to the Elf_Shdr member.
- uint64_t Size = 0;
+ uint64_t size = 0;
// The following fields correspond to Elf_Shdr members.
- uint64_t Offset = 0;
- uint64_t Addr = 0;
- uint32_t ShName = 0;
+ uint64_t offset = 0;
+ uint64_t addr = 0;
+ uint32_t shName = 0;
- void addSection(InputSection *IS);
+ void addSection(InputSection *isec);
// The following members are normally only used in linker scripts.
- MemoryRegion *MemRegion = nullptr;
- MemoryRegion *LMARegion = nullptr;
- Expr AddrExpr;
- Expr AlignExpr;
- Expr LMAExpr;
- Expr SubalignExpr;
- std::vector<BaseCommand *> SectionCommands;
- std::vector<StringRef> Phdrs;
- llvm::Optional<std::array<uint8_t, 4>> Filler;
- ConstraintKind Constraint = ConstraintKind::NoConstraint;
- std::string Location;
- std::string MemoryRegionName;
- std::string LMARegionName;
- bool NonAlloc = false;
- bool Noload = false;
- bool ExpressionsUseSymbols = false;
- bool UsedInExpression = false;
- bool InOverlay = false;
+ MemoryRegion *memRegion = nullptr;
+ MemoryRegion *lmaRegion = nullptr;
+ Expr addrExpr;
+ Expr alignExpr;
+ Expr lmaExpr;
+ Expr subalignExpr;
+ std::vector<BaseCommand *> sectionCommands;
+ std::vector<StringRef> phdrs;
+ llvm::Optional<std::array<uint8_t, 4>> filler;
+ ConstraintKind constraint = ConstraintKind::NoConstraint;
+ std::string location;
+ std::string memoryRegionName;
+ std::string lmaRegionName;
+ bool nonAlloc = false;
+ bool noload = false;
+ bool expressionsUseSymbols = false;
+ bool usedInExpression = false;
+ bool inOverlay = false;
// Tracks whether the section has ever had an input section added to it, even
// if the section was later removed (e.g. because it is a synthetic section
// that wasn't needed). This is needed for orphan placement.
- bool HasInputSections = false;
+ bool hasInputSections = false;
void finalize();
- template <class ELFT> void writeTo(uint8_t *Buf);
+ template <class ELFT> void writeTo(uint8_t *buf);
template <class ELFT> void maybeCompress();
- void sort(llvm::function_ref<int(InputSectionBase *S)> Order);
+ void sort(llvm::function_ref<int(InputSectionBase *s)> order);
void sortInitFini();
void sortCtorsDtors();
private:
// Used for implementation of --compress-debug-sections option.
- std::vector<uint8_t> ZDebugHeader;
- llvm::SmallVector<char, 1> CompressedData;
+ std::vector<uint8_t> zDebugHeader;
+ llvm::SmallVector<char, 1> compressedData;
std::array<uint8_t, 4> getFiller();
};
-int getPriority(StringRef S);
+int getPriority(StringRef s);
-std::vector<InputSection *> getInputSections(OutputSection* OS);
+std::vector<InputSection *> getInputSections(OutputSection* os);
// All output sections that are handled by the linker specially are
// globally accessible. Writer initializes them, so don't use them
// until Writer is initialized.
struct Out {
- static uint8_t *BufferStart;
- static uint8_t First;
- static PhdrEntry *TlsPhdr;
- static OutputSection *ElfHeader;
- static OutputSection *ProgramHeaders;
- static OutputSection *PreinitArray;
- static OutputSection *InitArray;
- static OutputSection *FiniArray;
+ static uint8_t *bufferStart;
+ static uint8_t first;
+ static PhdrEntry *tlsPhdr;
+ static OutputSection *elfHeader;
+ static OutputSection *programHeaders;
+ static OutputSection *preinitArray;
+ static OutputSection *initArray;
+ static OutputSection *finiArray;
};
} // namespace elf
@@ -140,7 +140,7 @@ namespace elf {
uint64_t getHeaderSize();
-extern std::vector<OutputSection *> OutputSections;
+extern std::vector<OutputSection *> outputSections;
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index bdd4d7cdc23..654ed2f1fcf 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -65,11 +65,11 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
-static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
- if (Cmd->Sym == &Sym)
- return Cmd->Location;
+static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *cmd = dyn_cast<SymbolAssignment>(base))
+ if (cmd->sym == &sym)
+ return cmd->location;
return None;
}
@@ -78,19 +78,19 @@ static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
// >>> defined in /home/alice/src/foo.o
// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
// >>> /home/alice/src/bar.o:(.text+0x1)
-static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
- uint64_t Off) {
- std::string Msg = "\n>>> defined in ";
- if (Sym.File)
- Msg += toString(Sym.File);
- else if (Optional<std::string> Loc = getLinkerScriptLocation(Sym))
- Msg += *Loc;
-
- Msg += "\n>>> referenced by ";
- std::string Src = S.getSrcMsg(Sym, Off);
- if (!Src.empty())
- Msg += Src + "\n>>> ";
- return Msg + S.getObjMsg(Off);
+static std::string getLocation(InputSectionBase &s, const Symbol &sym,
+ uint64_t off) {
+ std::string msg = "\n>>> defined in ";
+ if (sym.file)
+ msg += toString(sym.file);
+ else if (Optional<std::string> loc = getLinkerScriptLocation(sym))
+ msg += *loc;
+
+ msg += "\n>>> referenced by ";
+ std::string src = s.getSrcMsg(sym, off);
+ if (!src.empty())
+ msg += src + "\n>>> ";
+ return msg + s.getObjMsg(off);
}
namespace {
@@ -119,10 +119,10 @@ struct RelExprMaskBuilder<Head, Tail...> {
// There are fewer than 64 RelExpr's, so we can represent any set of
// RelExpr's as a constant bit mask and test for membership with a
// couple cheap bitwise operations.
-template <RelExpr... Exprs> bool oneof(RelExpr Expr) {
- assert(0 <= Expr && (int)Expr < 64 &&
+template <RelExpr... Exprs> bool oneof(RelExpr expr) {
+ assert(0 <= expr && (int)expr < 64 &&
"RelExpr is too large for 64-bit mask!");
- return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build();
+ return (uint64_t(1) << expr) & RelExprMaskBuilder<Exprs...>::build();
}
// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -131,17 +131,17 @@ template <RelExpr... Exprs> bool oneof(RelExpr Expr) {
// pollute other `handleTlsRelocation` by MIPS `ifs` statements.
// Mips has a custom MipsGotSection that handles the writing of GOT entries
// without dynamic relocations.
-static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,
- InputSectionBase &C, uint64_t Offset,
- int64_t Addend, RelExpr Expr) {
- if (Expr == R_MIPS_TLSLD) {
- In.MipsGot->addTlsIndex(*C.File);
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+static unsigned handleMipsTlsRelocation(RelType type, Symbol &sym,
+ InputSectionBase &c, uint64_t offset,
+ int64_t addend, RelExpr expr) {
+ if (expr == R_MIPS_TLSLD) {
+ in.mipsGot->addTlsIndex(*c.file);
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
- if (Expr == R_MIPS_TLSGD) {
- In.MipsGot->addDynTlsEntry(*C.File, Sym);
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ if (expr == R_MIPS_TLSGD) {
+ in.mipsGot->addDynTlsEntry(*c.file, sym);
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
return 0;
@@ -156,28 +156,28 @@ static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,
// Returns the number of relocations processed.
template <class ELFT>
static unsigned
-handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
- typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
- if (!Sym.isTls())
+handleTlsRelocation(RelType type, Symbol &sym, InputSectionBase &c,
+ typename ELFT::uint offset, int64_t addend, RelExpr expr) {
+ if (!sym.isTls())
return 0;
- if (Config->EMachine == EM_MIPS)
- return handleMipsTlsRelocation(Type, Sym, C, Offset, Addend, Expr);
+ if (config->emachine == EM_MIPS)
+ return handleMipsTlsRelocation(type, sym, c, offset, addend, expr);
if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC>(
- Expr) &&
- Config->Shared) {
- if (In.Got->addDynTlsEntry(Sym)) {
- uint64_t Off = In.Got->getGlobalDynOffset(Sym);
- Main->RelaDyn->addReloc(
- {Target->TlsDescRel, In.Got, Off, !Sym.IsPreemptible, &Sym, 0});
+ expr) &&
+ config->shared) {
+ if (in.got->addDynTlsEntry(sym)) {
+ uint64_t off = in.got->getGlobalDynOffset(sym);
+ mainPart->relaDyn->addReloc(
+ {target->tlsDescRel, in.got, off, !sym.isPreemptible, &sym, 0});
}
- if (Expr != R_TLSDESC_CALL)
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ if (expr != R_TLSDESC_CALL)
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
- bool CanRelax = Config->EMachine != EM_ARM && Config->EMachine != EM_RISCV;
+ bool canRelax = config->emachine != EM_ARM && config->emachine != EM_RISCV;
// If we are producing an executable and the symbol is non-preemptable, it
// must be defined and the code sequence can be relaxed to use Local-Exec.
@@ -186,118 +186,118 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
// we can omit the DTPMOD dynamic relocations and resolve them at link time
// because them are always 1. This may be necessary for static linking as
// DTPMOD may not be expected at load time.
- bool IsLocalInExecutable = !Sym.IsPreemptible && !Config->Shared;
+ bool isLocalInExecutable = !sym.isPreemptible && !config->shared;
// Local Dynamic is for access to module local TLS variables, while still
// being suitable for being dynamically loaded via dlopen. GOT[e0] is the
// module index, with a special value of 0 for the current module. GOT[e1] is
// unused. There only needs to be one module index entry.
if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(
- Expr)) {
+ expr)) {
// Local-Dynamic relocs can be relaxed to Local-Exec.
- if (CanRelax && !Config->Shared) {
- C.Relocations.push_back(
- {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
- Offset, Addend, &Sym});
- return Target->getTlsGdRelaxSkip(Type);
+ if (canRelax && !config->shared) {
+ c.relocations.push_back(
+ {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_LD_TO_LE), type,
+ offset, addend, &sym});
+ return target->getTlsGdRelaxSkip(type);
}
- if (Expr == R_TLSLD_HINT)
+ if (expr == R_TLSLD_HINT)
return 1;
- if (In.Got->addTlsIndex()) {
- if (IsLocalInExecutable)
- In.Got->Relocations.push_back(
- {R_ADDEND, Target->SymbolicRel, In.Got->getTlsIndexOff(), 1, &Sym});
+ if (in.got->addTlsIndex()) {
+ if (isLocalInExecutable)
+ in.got->relocations.push_back(
+ {R_ADDEND, target->symbolicRel, in.got->getTlsIndexOff(), 1, &sym});
else
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got,
- In.Got->getTlsIndexOff(), nullptr);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, in.got,
+ in.got->getTlsIndexOff(), nullptr);
}
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
// Local-Dynamic relocs can be relaxed to Local-Exec.
- if (Expr == R_DTPREL && !Config->Shared) {
- C.Relocations.push_back(
- {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
- Offset, Addend, &Sym});
+ if (expr == R_DTPREL && !config->shared) {
+ c.relocations.push_back(
+ {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_LD_TO_LE), type,
+ offset, addend, &sym});
return 1;
}
// Local-Dynamic sequence where offset of tls variable relative to dynamic
// thread pointer is stored in the got. This cannot be relaxed to Local-Exec.
- if (Expr == R_TLSLD_GOT_OFF) {
- if (!Sym.isInGot()) {
- In.Got->addEntry(Sym);
- uint64_t Off = Sym.getGotOffset();
- In.Got->Relocations.push_back(
- {R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});
+ if (expr == R_TLSLD_GOT_OFF) {
+ if (!sym.isInGot()) {
+ in.got->addEntry(sym);
+ uint64_t off = sym.getGotOffset();
+ in.got->relocations.push_back(
+ {R_ABS, target->tlsOffsetRel, off, 0, &sym});
}
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
- R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(Expr)) {
- if (!CanRelax || Config->Shared) {
- if (In.Got->addDynTlsEntry(Sym)) {
- uint64_t Off = In.Got->getGlobalDynOffset(Sym);
+ R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
+ if (!canRelax || config->shared) {
+ if (in.got->addDynTlsEntry(sym)) {
+ uint64_t off = in.got->getGlobalDynOffset(sym);
- if (IsLocalInExecutable)
+ if (isLocalInExecutable)
// Write one to the GOT slot.
- In.Got->Relocations.push_back(
- {R_ADDEND, Target->SymbolicRel, Off, 1, &Sym});
+ in.got->relocations.push_back(
+ {R_ADDEND, target->symbolicRel, off, 1, &sym});
else
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, in.got, off, &sym);
// If the symbol is preemptible we need the dynamic linker to write
// the offset too.
- uint64_t OffsetOff = Off + Config->Wordsize;
- if (Sym.IsPreemptible)
- Main->RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff,
- &Sym);
+ uint64_t offsetOff = off + config->wordsize;
+ if (sym.isPreemptible)
+ mainPart->relaDyn->addReloc(target->tlsOffsetRel, in.got, offsetOff,
+ &sym);
else
- In.Got->Relocations.push_back(
- {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});
+ in.got->relocations.push_back(
+ {R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
}
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ c.relocations.push_back({expr, type, offset, addend, &sym});
return 1;
}
// Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
// depending on the symbol being locally defined or not.
- if (Sym.IsPreemptible) {
- C.Relocations.push_back(
- {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
- Offset, Addend, &Sym});
- if (!Sym.isInGot()) {
- In.Got->addEntry(Sym);
- Main->RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(),
- &Sym);
+ if (sym.isPreemptible) {
+ c.relocations.push_back(
+ {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_GD_TO_IE), type,
+ offset, addend, &sym});
+ if (!sym.isInGot()) {
+ in.got->addEntry(sym);
+ mainPart->relaDyn->addReloc(target->tlsGotRel, in.got, sym.getGotOffset(),
+ &sym);
}
} else {
- C.Relocations.push_back(
- {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
- Offset, Addend, &Sym});
+ c.relocations.push_back(
+ {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_GD_TO_LE), type,
+ offset, addend, &sym});
}
- return Target->getTlsGdRelaxSkip(Type);
+ return target->getTlsGdRelaxSkip(type);
}
// Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
// defined.
if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC, R_GOT_OFF,
- R_TLSIE_HINT>(Expr) &&
- CanRelax && IsLocalInExecutable) {
- C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});
+ R_TLSIE_HINT>(expr) &&
+ canRelax && isLocalInExecutable) {
+ c.relocations.push_back({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
return 1;
}
- if (Expr == R_TLSIE_HINT)
+ if (expr == R_TLSIE_HINT)
return 1;
return 0;
}
-static RelType getMipsPairType(RelType Type, bool IsLocal) {
- switch (Type) {
+static RelType getMipsPairType(RelType type, bool isLocal) {
+ switch (type) {
case R_MIPS_HI16:
return R_MIPS_LO16;
case R_MIPS_GOT16:
@@ -309,9 +309,9 @@ static RelType getMipsPairType(RelType Type, bool IsLocal) {
// the high 16 bits of the symbol's value. A paired R_MIPS_LO16
// relocations handle low 16 bits of the address. That allows
// to allocate only one GOT entry for every 64 KBytes of local data.
- return IsLocal ? R_MIPS_LO16 : R_MIPS_NONE;
+ return isLocal ? R_MIPS_LO16 : R_MIPS_NONE;
case R_MICROMIPS_GOT16:
- return IsLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
+ return isLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
case R_MIPS_PCHI16:
return R_MIPS_PCLO16;
case R_MICROMIPS_HI16:
@@ -323,38 +323,38 @@ static RelType getMipsPairType(RelType Type, bool IsLocal) {
// True if non-preemptable symbol always has the same value regardless of where
// the DSO is loaded.
-static bool isAbsolute(const Symbol &Sym) {
- if (Sym.isUndefWeak())
+static bool isAbsolute(const Symbol &sym) {
+ if (sym.isUndefWeak())
return true;
- if (const auto *DR = dyn_cast<Defined>(&Sym))
- return DR->Section == nullptr; // Absolute symbol.
+ if (const auto *dr = dyn_cast<Defined>(&sym))
+ return dr->section == nullptr; // Absolute symbol.
return false;
}
-static bool isAbsoluteValue(const Symbol &Sym) {
- return isAbsolute(Sym) || Sym.isTls();
+static bool isAbsoluteValue(const Symbol &sym) {
+ return isAbsolute(sym) || sym.isTls();
}
// Returns true if Expr refers a PLT entry.
-static bool needsPlt(RelExpr Expr) {
- return oneof<R_PLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PLT>(Expr);
+static bool needsPlt(RelExpr expr) {
+ return oneof<R_PLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PLT>(expr);
}
// Returns true if Expr refers a GOT entry. Note that this function
// returns false for TLS variables even though they need GOT, because
// TLS variables uses GOT differently than the regular variables.
-static bool needsGot(RelExpr Expr) {
+static bool needsGot(RelExpr expr) {
return oneof<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
- R_GOT_PC, R_GOTPLT>(Expr);
+ R_GOT_PC, R_GOTPLT>(expr);
}
// True if this expression is of the form Sym - X, where X is a position in the
// file (PC, or GOT for example).
-static bool isRelExpr(RelExpr Expr) {
+static bool isRelExpr(RelExpr expr) {
return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_MIPS_GOTREL, R_PPC64_CALL,
R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC, R_RELAX_GOT_PC,
- R_RISCV_PC_INDIRECT>(Expr);
+ R_RISCV_PC_INDIRECT>(expr);
}
// Returns true if a given relocation can be computed at link-time.
@@ -366,8 +366,8 @@ static bool isRelExpr(RelExpr Expr) {
//
// If this function returns false, that means we need to emit a
// dynamic relocation so that the relocation will be fixed at load-time.
-static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
- InputSectionBase &S, uint64_t RelOff) {
+static bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym,
+ InputSectionBase &s, uint64_t relOff) {
// These expressions always compute a constant
if (oneof<R_DTPREL, R_GOTPLT, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF,
R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
@@ -376,33 +376,33 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC32_PLTREL,
R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_TLSDESC_CALL,
R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT,
- R_TLSIE_HINT>(E))
+ R_TLSIE_HINT>(e))
return true;
// These never do, except if the entire file is position dependent or if
// only the low bits are used.
- if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
- return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
+ if (e == R_GOT || e == R_PLT || e == R_TLSDESC)
+ return target->usesOnlyLowPageBits(type) || !config->isPic;
- if (Sym.IsPreemptible)
+ if (sym.isPreemptible)
return false;
- if (!Config->Pic)
+ if (!config->isPic)
return true;
// The size of a non preemptible symbol is a constant.
- if (E == R_SIZE)
+ if (e == R_SIZE)
return true;
// For the target and the relocation, we want to know if they are
// absolute or relative.
- bool AbsVal = isAbsoluteValue(Sym);
- bool RelE = isRelExpr(E);
- if (AbsVal && !RelE)
+ bool absVal = isAbsoluteValue(sym);
+ bool relE = isRelExpr(e);
+ if (absVal && !relE)
return true;
- if (!AbsVal && RelE)
+ if (!absVal && relE)
return true;
- if (!AbsVal && !RelE)
- return Target->usesOnlyLowPageBits(Type);
+ if (!absVal && !relE)
+ return target->usesOnlyLowPageBits(type);
// Relative relocation to an absolute value. This is normally unrepresentable,
// but if the relocation refers to a weak undefined symbol, we allow it to
@@ -412,22 +412,22 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
// Another special case is MIPS _gp_disp symbol which represents offset
// between start of a function and '_gp' value and defined as absolute just
// to simplify the code.
- assert(AbsVal && RelE);
- if (Sym.isUndefWeak())
+ assert(absVal && relE);
+ if (sym.isUndefWeak())
return true;
// We set the final symbols values for linker script defined symbols later.
// They always can be computed as a link time constant.
- if (Sym.ScriptDefined)
+ if (sym.scriptDefined)
return true;
- error("relocation " + toString(Type) + " cannot refer to absolute symbol: " +
- toString(Sym) + getLocation(S, Sym, RelOff));
+ error("relocation " + toString(type) + " cannot refer to absolute symbol: " +
+ toString(sym) + getLocation(s, sym, relOff));
return true;
}
-static RelExpr toPlt(RelExpr Expr) {
- switch (Expr) {
+static RelExpr toPlt(RelExpr expr) {
+ switch (expr) {
case R_PPC64_CALL:
return R_PPC64_CALL_PLT;
case R_PC:
@@ -435,14 +435,14 @@ static RelExpr toPlt(RelExpr Expr) {
case R_ABS:
return R_PLT;
default:
- return Expr;
+ return expr;
}
}
-static RelExpr fromPlt(RelExpr Expr) {
+static RelExpr fromPlt(RelExpr expr) {
// We decided not to use a plt. Optimize a reference to the plt to a
// reference to the symbol itself.
- switch (Expr) {
+ switch (expr) {
case R_PLT_PC:
case R_PPC32_PLTREL:
return R_PC;
@@ -451,21 +451,21 @@ static RelExpr fromPlt(RelExpr Expr) {
case R_PLT:
return R_ABS;
default:
- return Expr;
+ return expr;
}
}
// Returns true if a given shared symbol is in a read-only segment in a DSO.
-template <class ELFT> static bool isReadOnly(SharedSymbol &SS) {
+template <class ELFT> static bool isReadOnly(SharedSymbol &ss) {
using Elf_Phdr = typename ELFT::Phdr;
// Determine if the symbol is read-only by scanning the DSO's program headers.
- const SharedFile &File = SS.getFile();
- for (const Elf_Phdr &Phdr :
- check(File.template getObj<ELFT>().program_headers()))
- if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
- !(Phdr.p_flags & ELF::PF_W) && SS.Value >= Phdr.p_vaddr &&
- SS.Value < Phdr.p_vaddr + Phdr.p_memsz)
+ const SharedFile &file = ss.getFile();
+ for (const Elf_Phdr &phdr :
+ check(file.template getObj<ELFT>().program_headers()))
+ if ((phdr.p_type == ELF::PT_LOAD || phdr.p_type == ELF::PT_GNU_RELRO) &&
+ !(phdr.p_flags & ELF::PF_W) && ss.value >= phdr.p_vaddr &&
+ ss.value < phdr.p_vaddr + phdr.p_memsz)
return true;
return false;
}
@@ -476,22 +476,22 @@ template <class ELFT> static bool isReadOnly(SharedSymbol &SS) {
// them are copied by a copy relocation, all of them need to be copied.
// Otherwise, they would refer to different places at runtime.
template <class ELFT>
-static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
+static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &ss) {
using Elf_Sym = typename ELFT::Sym;
- SharedFile &File = SS.getFile();
+ SharedFile &file = ss.getFile();
- SmallSet<SharedSymbol *, 4> Ret;
- for (const Elf_Sym &S : File.template getGlobalELFSyms<ELFT>()) {
- if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
- S.getType() == STT_TLS || S.st_value != SS.Value)
+ SmallSet<SharedSymbol *, 4> ret;
+ for (const Elf_Sym &s : file.template getGlobalELFSyms<ELFT>()) {
+ if (s.st_shndx == SHN_UNDEF || s.st_shndx == SHN_ABS ||
+ s.getType() == STT_TLS || s.st_value != ss.value)
continue;
- StringRef Name = check(S.getName(File.getStringTable()));
- Symbol *Sym = Symtab->find(Name);
- if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
- Ret.insert(Alias);
+ StringRef name = check(s.getName(file.getStringTable()));
+ Symbol *sym = symtab->find(name);
+ if (auto *alias = dyn_cast_or_null<SharedSymbol>(sym))
+ ret.insert(alias);
}
- return Ret;
+ return ret;
}
// When a symbol is copy relocated or we create a canonical plt entry, it is
@@ -499,21 +499,21 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
// in .bss and in the case of a canonical plt entry it is in .plt. This function
// replaces the existing symbol with a Defined pointing to the appropriate
// location.
-static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
- uint64_t Size) {
- Symbol Old = Sym;
-
- Sym.replace(Defined{Sym.File, Sym.getName(), Sym.Binding, Sym.StOther,
- Sym.Type, Value, Size, Sec});
-
- Sym.PltIndex = Old.PltIndex;
- Sym.GotIndex = Old.GotIndex;
- Sym.VerdefIndex = Old.VerdefIndex;
- Sym.PPC64BranchltIndex = Old.PPC64BranchltIndex;
- Sym.IsPreemptible = true;
- Sym.ExportDynamic = true;
- Sym.IsUsedInRegularObj = true;
- Sym.Used = true;
+static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
+ uint64_t size) {
+ Symbol old = sym;
+
+ sym.replace(Defined{sym.file, sym.getName(), sym.binding, sym.stOther,
+ sym.type, value, size, sec});
+
+ sym.pltIndex = old.pltIndex;
+ sym.gotIndex = old.gotIndex;
+ sym.verdefIndex = old.verdefIndex;
+ sym.ppc64BranchltIndex = old.ppc64BranchltIndex;
+ sym.isPreemptible = true;
+ sym.exportDynamic = true;
+ sym.isUsedInRegularObj = true;
+ sym.used = true;
}
// Reserve space in .bss or .bss.rel.ro for copy relocation.
@@ -558,29 +558,29 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
// to the variable in .bss. This kind of issue is sometimes very hard to
// debug. What's a solution? Instead of exporting a varaible V from a DSO,
// define an accessor getV().
-template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
+template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
// Copy relocation against zero-sized symbol doesn't make sense.
- uint64_t SymSize = SS.getSize();
- if (SymSize == 0 || SS.Alignment == 0)
- fatal("cannot create a copy relocation for symbol " + toString(SS));
+ uint64_t symSize = ss.getSize();
+ if (symSize == 0 || ss.alignment == 0)
+ fatal("cannot create a copy relocation for symbol " + toString(ss));
// See if this symbol is in a read-only segment. If so, preserve the symbol's
// memory protection by reserving space in the .bss.rel.ro section.
- bool IsRO = isReadOnly<ELFT>(SS);
- BssSection *Sec =
- make<BssSection>(IsRO ? ".bss.rel.ro" : ".bss", SymSize, SS.Alignment);
- if (IsRO)
- In.BssRelRo->getParent()->addSection(Sec);
+ bool isRO = isReadOnly<ELFT>(ss);
+ BssSection *sec =
+ make<BssSection>(isRO ? ".bss.rel.ro" : ".bss", symSize, ss.alignment);
+ if (isRO)
+ in.bssRelRo->getParent()->addSection(sec);
else
- In.Bss->getParent()->addSection(Sec);
+ in.bss->getParent()->addSection(sec);
// Look through the DSO's dynamic symbol table for aliases and create a
// dynamic symbol for each one. This causes the copy relocation to correctly
// interpose any aliases.
- for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
- replaceWithDefined(*Sym, Sec, 0, Sym->Size);
+ for (SharedSymbol *sym : getSymbolsAt<ELFT>(ss))
+ replaceWithDefined(*sym, sec, 0, sym->size);
- Main->RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
+ mainPart->relaDyn->addReloc(target->copyRel, sec, 0, &ss);
}
// MIPS has an odd notion of "paired" relocations to calculate addends.
@@ -588,34 +588,34 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
// R_MIPS_LO16 relocation after that, and an addend is calculated using
// the two relocations.
template <class ELFT, class RelTy>
-static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
- InputSectionBase &Sec, RelExpr Expr,
- bool IsLocal) {
- if (Expr == R_MIPS_GOTREL && IsLocal)
- return Sec.getFile<ELFT>()->MipsGp0;
+static int64_t computeMipsAddend(const RelTy &rel, const RelTy *end,
+ InputSectionBase &sec, RelExpr expr,
+ bool isLocal) {
+ if (expr == R_MIPS_GOTREL && isLocal)
+ return sec.getFile<ELFT>()->mipsGp0;
// The ABI says that the paired relocation is used only for REL.
// See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
if (RelTy::IsRela)
return 0;
- RelType Type = Rel.getType(Config->IsMips64EL);
- uint32_t PairTy = getMipsPairType(Type, IsLocal);
- if (PairTy == R_MIPS_NONE)
+ RelType type = rel.getType(config->isMips64EL);
+ uint32_t pairTy = getMipsPairType(type, isLocal);
+ if (pairTy == R_MIPS_NONE)
return 0;
- const uint8_t *Buf = Sec.data().data();
- uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
+ const uint8_t *buf = sec.data().data();
+ uint32_t symIndex = rel.getSymbol(config->isMips64EL);
// To make things worse, paired relocations might not be contiguous in
// the relocation table, so we need to do linear search. *sigh*
- for (const RelTy *RI = &Rel; RI != End; ++RI)
- if (RI->getType(Config->IsMips64EL) == PairTy &&
- RI->getSymbol(Config->IsMips64EL) == SymIndex)
- return Target->getImplicitAddend(Buf + RI->r_offset, PairTy);
+ for (const RelTy *ri = &rel; ri != end; ++ri)
+ if (ri->getType(config->isMips64EL) == pairTy &&
+ ri->getSymbol(config->isMips64EL) == symIndex)
+ return target->getImplicitAddend(buf + ri->r_offset, pairTy);
- warn("can't find matching " + toString(PairTy) + " relocation for " +
- toString(Type));
+ warn("can't find matching " + toString(pairTy) + " relocation for " +
+ toString(type));
return 0;
}
@@ -623,82 +623,82 @@ static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
// is in a relocation itself. If it is REL, we need to read it from an
// input section.
template <class ELFT, class RelTy>
-static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
- InputSectionBase &Sec, RelExpr Expr,
- bool IsLocal) {
- int64_t Addend;
- RelType Type = Rel.getType(Config->IsMips64EL);
+static int64_t computeAddend(const RelTy &rel, const RelTy *end,
+ InputSectionBase &sec, RelExpr expr,
+ bool isLocal) {
+ int64_t addend;
+ RelType type = rel.getType(config->isMips64EL);
if (RelTy::IsRela) {
- Addend = getAddend<ELFT>(Rel);
+ addend = getAddend<ELFT>(rel);
} else {
- const uint8_t *Buf = Sec.data().data();
- Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
+ const uint8_t *buf = sec.data().data();
+ addend = target->getImplicitAddend(buf + rel.r_offset, type);
}
- if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
- Addend += getPPC64TocBase();
- if (Config->EMachine == EM_MIPS)
- Addend += computeMipsAddend<ELFT>(Rel, End, Sec, Expr, IsLocal);
+ if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC)
+ addend += getPPC64TocBase();
+ if (config->emachine == EM_MIPS)
+ addend += computeMipsAddend<ELFT>(rel, end, sec, expr, isLocal);
- return Addend;
+ return addend;
}
// Custom error message if Sym is defined in a discarded section.
template <class ELFT>
-static std::string maybeReportDiscarded(Undefined &Sym) {
- auto *File = dyn_cast_or_null<ObjFile<ELFT>>(Sym.File);
- if (!File || !Sym.DiscardedSecIdx ||
- File->getSections()[Sym.DiscardedSecIdx] != &InputSection::Discarded)
+static std::string maybeReportDiscarded(Undefined &sym) {
+ auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file);
+ if (!file || !sym.discardedSecIdx ||
+ file->getSections()[sym.discardedSecIdx] != &InputSection::discarded)
return "";
- ArrayRef<Elf_Shdr_Impl<ELFT>> ObjSections =
- CHECK(File->getObj().sections(), File);
-
- std::string Msg;
- if (Sym.Type == ELF::STT_SECTION) {
- Msg = "relocation refers to a discarded section: ";
- Msg += CHECK(
- File->getObj().getSectionName(&ObjSections[Sym.DiscardedSecIdx]), File);
+ ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
+ CHECK(file->getObj().sections(), file);
+
+ std::string msg;
+ if (sym.type == ELF::STT_SECTION) {
+ msg = "relocation refers to a discarded section: ";
+ msg += CHECK(
+ file->getObj().getSectionName(&objSections[sym.discardedSecIdx]), file);
} else {
- Msg = "relocation refers to a symbol in a discarded section: " +
- toString(Sym);
+ msg = "relocation refers to a symbol in a discarded section: " +
+ toString(sym);
}
- Msg += "\n>>> defined in " + toString(File);
+ msg += "\n>>> defined in " + toString(file);
- Elf_Shdr_Impl<ELFT> ELFSec = ObjSections[Sym.DiscardedSecIdx - 1];
- if (ELFSec.sh_type != SHT_GROUP)
- return Msg;
+ Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1];
+ if (elfSec.sh_type != SHT_GROUP)
+ return msg;
// If the discarded section is a COMDAT.
- StringRef Signature = File->getShtGroupSignature(ObjSections, ELFSec);
- if (const InputFile *Prevailing =
- Symtab->ComdatGroups.lookup(CachedHashStringRef(Signature)))
- Msg += "\n>>> section group signature: " + Signature.str() +
- "\n>>> prevailing definition is in " + toString(Prevailing);
- return Msg;
+ StringRef signature = file->getShtGroupSignature(objSections, elfSec);
+ if (const InputFile *prevailing =
+ symtab->comdatGroups.lookup(CachedHashStringRef(signature)))
+ msg += "\n>>> section group signature: " + signature.str() +
+ "\n>>> prevailing definition is in " + toString(prevailing);
+ return msg;
}
// Undefined diagnostics are collected in a vector and emitted once all of
// them are known, so that some postprocessing on the list of undefined symbols
// can happen before lld emits diagnostics.
struct UndefinedDiag {
- Symbol *Sym;
+ Symbol *sym;
struct Loc {
- InputSectionBase *Sec;
- uint64_t Offset;
+ InputSectionBase *sec;
+ uint64_t offset;
};
- std::vector<Loc> Locs;
- bool IsWarning;
+ std::vector<Loc> locs;
+ bool isWarning;
};
-static std::vector<UndefinedDiag> Undefs;
+static std::vector<UndefinedDiag> undefs;
template <class ELFT>
-static void reportUndefinedSymbol(const UndefinedDiag &Undef) {
- Symbol &Sym = *Undef.Sym;
+static void reportUndefinedSymbol(const UndefinedDiag &undef) {
+ Symbol &sym = *undef.sym;
- auto Visibility = [&]() -> std::string {
- switch (Sym.Visibility) {
+ auto visibility = [&]() -> std::string {
+ switch (sym.visibility) {
case STV_INTERNAL:
return "internal ";
case STV_HIDDEN:
@@ -710,71 +710,71 @@ static void reportUndefinedSymbol(const UndefinedDiag &Undef) {
}
};
- std::string Msg = maybeReportDiscarded<ELFT>(cast<Undefined>(Sym));
- if (Msg.empty())
- Msg = "undefined " + Visibility() + "symbol: " + toString(Sym);
+ std::string msg = maybeReportDiscarded<ELFT>(cast<Undefined>(sym));
+ if (msg.empty())
+ msg = "undefined " + visibility() + "symbol: " + toString(sym);
- const size_t MaxUndefReferences = 10;
- size_t I = 0;
- for (UndefinedDiag::Loc L : Undef.Locs) {
- if (I >= MaxUndefReferences)
+ const size_t maxUndefReferences = 10;
+ size_t i = 0;
+ for (UndefinedDiag::Loc l : undef.locs) {
+ if (i >= maxUndefReferences)
break;
- InputSectionBase &Sec = *L.Sec;
- uint64_t Offset = L.Offset;
-
- Msg += "\n>>> referenced by ";
- std::string Src = Sec.getSrcMsg(Sym, Offset);
- if (!Src.empty())
- Msg += Src + "\n>>> ";
- Msg += Sec.getObjMsg(Offset);
- I++;
+ InputSectionBase &sec = *l.sec;
+ uint64_t offset = l.offset;
+
+ msg += "\n>>> referenced by ";
+ std::string src = sec.getSrcMsg(sym, offset);
+ if (!src.empty())
+ msg += src + "\n>>> ";
+ msg += sec.getObjMsg(offset);
+ i++;
}
- if (I < Undef.Locs.size())
- Msg += ("\n>>> referenced " + Twine(Undef.Locs.size() - I) + " more times")
+ if (i < undef.locs.size())
+ msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")
.str();
- if (Sym.getName().startswith("_ZTV"))
- Msg += "\nthe vtable symbol may be undefined because the class is missing "
+ if (sym.getName().startswith("_ZTV"))
+ msg += "\nthe vtable symbol may be undefined because the class is missing "
"its key function (see https://lld.llvm.org/missingkeyfunction)";
- if (Undef.IsWarning)
- warn(Msg);
+ if (undef.isWarning)
+ warn(msg);
else
- error(Msg);
+ error(msg);
}
template <class ELFT> void elf::reportUndefinedSymbols() {
// Find the first "undefined symbol" diagnostic for each diagnostic, and
// collect all "referenced from" lines at the first diagnostic.
- DenseMap<Symbol *, UndefinedDiag *> FirstRef;
- for (UndefinedDiag &Undef : Undefs) {
- assert(Undef.Locs.size() == 1);
- if (UndefinedDiag *Canon = FirstRef.lookup(Undef.Sym)) {
- Canon->Locs.push_back(Undef.Locs[0]);
- Undef.Locs.clear();
+ DenseMap<Symbol *, UndefinedDiag *> firstRef;
+ for (UndefinedDiag &undef : undefs) {
+ assert(undef.locs.size() == 1);
+ if (UndefinedDiag *canon = firstRef.lookup(undef.sym)) {
+ canon->locs.push_back(undef.locs[0]);
+ undef.locs.clear();
} else
- FirstRef[Undef.Sym] = &Undef;
+ firstRef[undef.sym] = &undef;
}
- for (const UndefinedDiag &Undef : Undefs) {
- if (!Undef.Locs.empty())
- reportUndefinedSymbol<ELFT>(Undef);
+ for (const UndefinedDiag &undef : undefs) {
+ if (!undef.locs.empty())
+ reportUndefinedSymbol<ELFT>(undef);
}
- Undefs.clear();
+ undefs.clear();
}
// Report an undefined symbol if necessary.
// Returns true if the undefined symbol will produce an error message.
template <class ELFT>
-static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
- uint64_t Offset) {
- if (!Sym.isUndefined() || Sym.isWeak())
+static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
+ uint64_t offset) {
+ if (!sym.isUndefined() || sym.isWeak())
return false;
- bool CanBeExternal = !Sym.isLocal() && Sym.computeBinding() != STB_LOCAL &&
- Sym.Visibility == STV_DEFAULT;
- if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)
+ bool canBeExternal = !sym.isLocal() && sym.computeBinding() != STB_LOCAL &&
+ sym.visibility == STV_DEFAULT;
+ if (config->unresolvedSymbols == UnresolvedPolicy::Ignore && canBeExternal)
return false;
// clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc
@@ -782,15 +782,15 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
// .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF
// spec says references from outside the group to a STB_LOCAL symbol are not
// allowed. Work around the bug.
- if (Config->EMachine == EM_PPC64 &&
- cast<Undefined>(Sym).DiscardedSecIdx != 0 && Sec.Name == ".toc")
+ if (config->emachine == EM_PPC64 &&
+ cast<Undefined>(sym).discardedSecIdx != 0 && sec.name == ".toc")
return false;
- bool IsWarning =
- (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
- Config->NoinhibitExec;
- Undefs.push_back({&Sym, {{&Sec, Offset}}, IsWarning});
- return !IsWarning;
+ bool isWarning =
+ (config->unresolvedSymbols == UnresolvedPolicy::Warn && canBeExternal) ||
+ config->noinhibitExec;
+ undefs.push_back({&sym, {{&sec, offset}}, isWarning});
+ return !isWarning;
}
// MIPS N32 ABI treats series of successive relocations with the same offset
@@ -798,14 +798,14 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
// packs all relocations into the single relocation record. Here we emulate
// this for the N32 ABI. Iterate over relocation with the same offset and put
// theirs types into the single bit-set.
-template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) {
- RelType Type = 0;
- uint64_t Offset = Rel->r_offset;
-
- int N = 0;
- while (Rel != End && Rel->r_offset == Offset)
- Type |= (Rel++)->getType(Config->IsMips64EL) << (8 * N++);
- return Type;
+template <class RelTy> static RelType getMipsN32RelType(RelTy *&rel, RelTy *end) {
+ RelType type = 0;
+ uint64_t offset = rel->r_offset;
+
+ int n = 0;
+ while (rel != end && rel->r_offset == offset)
+ type |= (rel++)->getType(config->isMips64EL) << (8 * n++);
+ return type;
}
// .eh_frame sections are mergeable input sections, so their input
@@ -822,42 +822,42 @@ template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End)
namespace {
class OffsetGetter {
public:
- explicit OffsetGetter(InputSectionBase &Sec) {
- if (auto *Eh = dyn_cast<EhInputSection>(&Sec))
- Pieces = Eh->Pieces;
+ explicit OffsetGetter(InputSectionBase &sec) {
+ if (auto *eh = dyn_cast<EhInputSection>(&sec))
+ pieces = eh->pieces;
}
// Translates offsets in input sections to offsets in output sections.
// Given offset must increase monotonically. We assume that Piece is
// sorted by InputOff.
- uint64_t get(uint64_t Off) {
- if (Pieces.empty())
- return Off;
+ uint64_t get(uint64_t off) {
+ if (pieces.empty())
+ return off;
- while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)
- ++I;
- if (I == Pieces.size())
+ while (i != pieces.size() && pieces[i].inputOff + pieces[i].size <= off)
+ ++i;
+ if (i == pieces.size())
fatal(".eh_frame: relocation is not in any piece");
// Pieces must be contiguous, so there must be no holes in between.
- assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");
+ assert(pieces[i].inputOff <= off && "Relocation not in any piece");
// Offset -1 means that the piece is dead (i.e. garbage collected).
- if (Pieces[I].OutputOff == -1)
+ if (pieces[i].outputOff == -1)
return -1;
- return Pieces[I].OutputOff + Off - Pieces[I].InputOff;
+ return pieces[i].outputOff + off - pieces[i].inputOff;
}
private:
- ArrayRef<EhSectionPiece> Pieces;
- size_t I = 0;
+ ArrayRef<EhSectionPiece> pieces;
+ size_t i = 0;
};
} // namespace
-static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,
- Symbol *Sym, int64_t Addend, RelExpr Expr,
- RelType Type) {
- Partition &Part = IS->getPartition();
+static void addRelativeReloc(InputSectionBase *isec, uint64_t offsetInSec,
+ Symbol *sym, int64_t addend, RelExpr expr,
+ RelType type) {
+ Partition &part = isec->getPartition();
// Add a relative relocation. If RelrDyn section is enabled, and the
// relocation offset is guaranteed to be even, add the relocation to
@@ -865,29 +865,29 @@ static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,
// RelrDyn sections don't support odd offsets. Also, RelrDyn sections
// don't store the addend values, so we must write it to the relocated
// address.
- if (Part.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
- IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
- Part.RelrDyn->Relocs.push_back({IS, OffsetInSec});
+ if (part.relrDyn && isec->alignment >= 2 && offsetInSec % 2 == 0) {
+ isec->relocations.push_back({expr, type, offsetInSec, addend, sym});
+ part.relrDyn->relocs.push_back({isec, offsetInSec});
return;
}
- Part.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend,
- Expr, Type);
+ part.relaDyn->addReloc(target->relativeRel, isec, offsetInSec, sym, addend,
+ expr, type);
}
template <class ELFT, class GotPltSection>
-static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
- RelocationBaseSection *Rel, RelType Type, Symbol &Sym) {
- Plt->addEntry<ELFT>(Sym);
- GotPlt->addEntry(Sym);
- Rel->addReloc(
- {Type, GotPlt, Sym.getGotPltOffset(), !Sym.IsPreemptible, &Sym, 0});
+static void addPltEntry(PltSection *plt, GotPltSection *gotPlt,
+ RelocationBaseSection *rel, RelType type, Symbol &sym) {
+ plt->addEntry<ELFT>(sym);
+ gotPlt->addEntry(sym);
+ rel->addReloc(
+ {type, gotPlt, sym.getGotPltOffset(), !sym.isPreemptible, &sym, 0});
}
-static void addGotEntry(Symbol &Sym) {
- In.Got->addEntry(Sym);
+static void addGotEntry(Symbol &sym) {
+ in.got->addEntry(sym);
- RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
- uint64_t Off = Sym.getGotOffset();
+ RelExpr expr = sym.isTls() ? R_TLS : R_ABS;
+ uint64_t off = sym.getGotOffset();
// If a GOT slot value can be calculated at link-time, which is now,
// we can just fill that out.
@@ -896,42 +896,42 @@ static void addGotEntry(Symbol &Sym) {
// add a static relocation to a Relocations vector so that
// InputSection::relocate will do the work for us. We may be able
// to just write a value now, but it is a TODO.)
- bool IsLinkTimeConstant =
- !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
- if (IsLinkTimeConstant) {
- In.Got->Relocations.push_back({Expr, Target->SymbolicRel, Off, 0, &Sym});
+ bool isLinkTimeConstant =
+ !sym.isPreemptible && (!config->isPic || isAbsolute(sym));
+ if (isLinkTimeConstant) {
+ in.got->relocations.push_back({expr, target->symbolicRel, off, 0, &sym});
return;
}
// Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
// the GOT slot will be fixed at load-time.
- if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {
- addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->SymbolicRel);
+ if (!sym.isTls() && !sym.isPreemptible && config->isPic && !isAbsolute(sym)) {
+ addRelativeReloc(in.got, off, &sym, 0, R_ABS, target->symbolicRel);
return;
}
- Main->RelaDyn->addReloc(
- Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got, Off, &Sym, 0,
- Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->SymbolicRel);
+ mainPart->relaDyn->addReloc(
+ sym.isTls() ? target->tlsGotRel : target->gotRel, in.got, off, &sym, 0,
+ sym.isPreemptible ? R_ADDEND : R_ABS, target->symbolicRel);
}
// Return true if we can define a symbol in the executable that
// contains the value/function of a symbol defined in a shared
// library.
-static bool canDefineSymbolInExecutable(Symbol &Sym) {
+static bool canDefineSymbolInExecutable(Symbol &sym) {
// If the symbol has default visibility the symbol defined in the
// executable will preempt it.
// Note that we want the visibility of the shared symbol itself, not
// the visibility of the symbol in the output file we are producing. That is
// why we use Sym.StOther.
- if ((Sym.StOther & 0x3) == STV_DEFAULT)
+ if ((sym.stOther & 0x3) == STV_DEFAULT)
return true;
// If we are allowed to break address equality of functions, defining
// a plt entry will allow the program to call the function in the
// .so, but the .so and the executable will no agree on the address
// of the function. Similar logic for objects.
- return ((Sym.isFunc() && Config->IgnoreFunctionAddressEquality) ||
- (Sym.isObject() && Config->IgnoreDataAddressEquality));
+ return ((sym.isFunc() && config->ignoreFunctionAddressEquality) ||
+ (sym.isObject() && config->ignoreDataAddressEquality));
}
// The reason we have to do this early scan is as follows
@@ -948,9 +948,9 @@ static bool canDefineSymbolInExecutable(Symbol &Sym) {
// complicates things for the dynamic linker and means we would have to reserve
// space for the extra PT_LOAD even if we end up not using it.
template <class ELFT, class RelTy>
-static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
- uint64_t Offset, Symbol &Sym, const RelTy &Rel,
- int64_t Addend) {
+static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
+ uint64_t offset, Symbol &sym, const RelTy &rel,
+ int64_t addend) {
// If the relocation is known to be a link-time constant, we know no dynamic
// relocation will be created, pass the control to relocateAlloc() or
// relocateNonAlloc() to resolve it.
@@ -958,23 +958,23 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
// The behavior of an undefined weak reference is implementation defined. If
// the relocation is to a weak undef, and we are producing an executable, let
// relocate{,Non}Alloc() resolve it.
- if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset) ||
- (!Config->Shared && Sym.isUndefWeak())) {
- Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ if (isStaticLinkTimeConstant(expr, type, sym, sec, offset) ||
+ (!config->shared && sym.isUndefWeak())) {
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
return;
}
- bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
- if (CanWrite) {
- RelType Rel = Target->getDynRel(Type);
- if (Expr == R_GOT || (Rel == Target->SymbolicRel && !Sym.IsPreemptible)) {
- addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
+ bool canWrite = (sec.flags & SHF_WRITE) || !config->zText;
+ if (canWrite) {
+ RelType rel = target->getDynRel(type);
+ if (expr == R_GOT || (rel == target->symbolicRel && !sym.isPreemptible)) {
+ addRelativeReloc(&sec, offset, &sym, addend, expr, type);
return;
- } else if (Rel != 0) {
- if (Config->EMachine == EM_MIPS && Rel == Target->SymbolicRel)
- Rel = Target->RelativeRel;
- Sec.getPartition().RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend,
- R_ADDEND, Type);
+ } else if (rel != 0) {
+ if (config->emachine == EM_MIPS && rel == target->symbolicRel)
+ rel = target->relativeRel;
+ sec.getPartition().relaDyn->addReloc(rel, &sec, offset, &sym, addend,
+ R_ADDEND, type);
// MIPS ABI turns using of GOT and dynamic relocations inside out.
// While regular ABI uses dynamic relocations to fill up GOT entries
@@ -991,19 +991,19 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
// to the GOT entry and reads the GOT entry when it needs to perform
// a dynamic relocation.
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
- if (Config->EMachine == EM_MIPS)
- In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
+ if (config->emachine == EM_MIPS)
+ in.mipsGot->addEntry(*sec.file, sym, addend, expr);
return;
}
}
- if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) {
+ if (!canWrite && (config->isPic && !isRelExpr(expr))) {
error(
- "can't create dynamic relocation " + toString(Type) + " against " +
- (Sym.getName().empty() ? "local symbol" : "symbol: " + toString(Sym)) +
+ "can't create dynamic relocation " + toString(type) + " against " +
+ (sym.getName().empty() ? "local symbol" : "symbol: " + toString(sym)) +
" in readonly segment; recompile object files with -fPIC "
"or pass '-Wl,-z,notext' to allow text relocations in the output" +
- getLocation(Sec, Sym, Offset));
+ getLocation(sec, sym, offset));
return;
}
@@ -1013,40 +1013,40 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
// Among R_ABS relocatoin types, SymbolicRel has the same size as the word
// size. Others have fewer bits and may cause runtime overflow in -pie/-shared
// mode. Disallow them.
- if (Config->Shared ||
- (Config->Pie && Expr == R_ABS && Type != Target->SymbolicRel)) {
+ if (config->shared ||
+ (config->pie && expr == R_ABS && type != target->symbolicRel)) {
errorOrWarn(
- "relocation " + toString(Type) + " cannot be used against " +
- (Sym.getName().empty() ? "local symbol" : "symbol " + toString(Sym)) +
- "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
+ "relocation " + toString(type) + " cannot be used against " +
+ (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
+ "; recompile with -fPIC" + getLocation(sec, sym, offset));
return;
}
// If the symbol is undefined we already reported any relevant errors.
- if (Sym.isUndefined())
+ if (sym.isUndefined())
return;
- if (!canDefineSymbolInExecutable(Sym)) {
- error("cannot preempt symbol: " + toString(Sym) +
- getLocation(Sec, Sym, Offset));
+ if (!canDefineSymbolInExecutable(sym)) {
+ error("cannot preempt symbol: " + toString(sym) +
+ getLocation(sec, sym, offset));
return;
}
- if (Sym.isObject()) {
+ if (sym.isObject()) {
// Produce a copy relocation.
- if (auto *SS = dyn_cast<SharedSymbol>(&Sym)) {
- if (!Config->ZCopyreloc)
- error("unresolvable relocation " + toString(Type) +
- " against symbol '" + toString(*SS) +
+ if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
+ if (!config->zCopyreloc)
+ error("unresolvable relocation " + toString(type) +
+ " against symbol '" + toString(*ss) +
"'; recompile with -fPIC or remove '-z nocopyreloc'" +
- getLocation(Sec, Sym, Offset));
- addCopyRelSymbol<ELFT>(*SS);
+ getLocation(sec, sym, offset));
+ addCopyRelSymbol<ELFT>(*ss);
}
- Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
return;
}
- if (Sym.isFunc()) {
+ if (sym.isFunc()) {
// This handles a non PIC program call to function in a shared library. In
// an ideal world, we could just report an error saying the relocation can
// overflow at runtime. In the real world with glibc, crt1.o has a
@@ -1074,65 +1074,65 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
// compiled without -fPIE/-fPIC and doesn't maintain ebx.
// * If a library definition gets preempted to the executable, it will have
// the wrong ebx value.
- if (Config->Pie && Config->EMachine == EM_386)
- errorOrWarn("symbol '" + toString(Sym) +
+ if (config->pie && config->emachine == EM_386)
+ errorOrWarn("symbol '" + toString(sym) +
"' cannot be preempted; recompile with -fPIE" +
- getLocation(Sec, Sym, Offset));
- if (!Sym.isInPlt())
- addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
- if (!Sym.isDefined())
+ getLocation(sec, sym, offset));
+ if (!sym.isInPlt())
+ addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
+ if (!sym.isDefined())
replaceWithDefined(
- Sym, In.Plt,
- Target->PltHeaderSize + Target->PltEntrySize * Sym.PltIndex, 0);
- Sym.NeedsPltAddr = true;
- Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+ sym, in.plt,
+ target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
+ sym.needsPltAddr = true;
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
return;
}
- errorOrWarn("symbol '" + toString(Sym) + "' has no type" +
- getLocation(Sec, Sym, Offset));
+ errorOrWarn("symbol '" + toString(sym) + "' has no type" +
+ getLocation(sec, sym, offset));
}
struct IRelativeReloc {
- RelType Type;
- InputSectionBase *Sec;
- uint64_t Offset;
- Symbol *Sym;
+ RelType type;
+ InputSectionBase *sec;
+ uint64_t offset;
+ Symbol *sym;
};
-static std::vector<IRelativeReloc> IRelativeRelocs;
+static std::vector<IRelativeReloc> iRelativeRelocs;
template <class ELFT, class RelTy>
-static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
- RelTy *End) {
- const RelTy &Rel = *I;
- uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
- Symbol &Sym = Sec.getFile<ELFT>()->getSymbol(SymIndex);
- RelType Type;
+static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
+ RelTy *end) {
+ const RelTy &rel = *i;
+ uint32_t symIndex = rel.getSymbol(config->isMips64EL);
+ Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIndex);
+ RelType type;
// Deal with MIPS oddity.
- if (Config->MipsN32Abi) {
- Type = getMipsN32RelType(I, End);
+ if (config->mipsN32Abi) {
+ type = getMipsN32RelType(i, end);
} else {
- Type = Rel.getType(Config->IsMips64EL);
- ++I;
+ type = rel.getType(config->isMips64EL);
+ ++i;
}
// Get an offset in an output section this relocation is applied to.
- uint64_t Offset = GetOffset.get(Rel.r_offset);
- if (Offset == uint64_t(-1))
+ uint64_t offset = getOffset.get(rel.r_offset);
+ if (offset == uint64_t(-1))
return;
// Error if the target symbol is undefined. Symbol index 0 may be used by
// marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them.
- if (SymIndex != 0 && maybeReportUndefined<ELFT>(Sym, Sec, Rel.r_offset))
+ if (symIndex != 0 && maybeReportUndefined<ELFT>(sym, sec, rel.r_offset))
return;
- const uint8_t *RelocatedAddr = Sec.data().begin() + Rel.r_offset;
- RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
+ const uint8_t *relocatedAddr = sec.data().begin() + rel.r_offset;
+ RelExpr expr = target->getRelExpr(type, sym, relocatedAddr);
// Ignore "hint" relocations because they are only markers for relaxation.
- if (oneof<R_HINT, R_NONE>(Expr))
+ if (oneof<R_HINT, R_NONE>(expr))
return;
// We can separate the small code model relocations into 2 categories:
@@ -1143,21 +1143,21 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// got-based small code model relocs. The .toc sections get placed after the
// end of the linker allocated .got section and we do sort those so sections
// addressed with small code model relocations come first.
- if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(Type))
- Sec.File->PPC64SmallCodeModelTocRelocs = true;
+ if (config->emachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(type))
+ sec.file->ppc64SmallCodeModelTocRelocs = true;
- if (Sym.isGnuIFunc() && !Config->ZText && Config->WarnIfuncTextrel) {
+ if (sym.isGnuIFunc() && !config->zText && config->warnIfuncTextrel) {
warn("using ifunc symbols when text relocations are allowed may produce "
"a binary that will segfault, if the object file is linked with "
"old version of glibc (glibc 2.28 and earlier). If this applies to "
"you, consider recompiling the object files without -fPIC and "
"without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
"turn off this warning." +
- getLocation(Sec, Sym, Offset));
+ getLocation(sec, sym, offset));
}
// Read an addend.
- int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
+ int64_t addend = computeAddend<ELFT>(rel, end, sec, expr, sym.isLocal());
// Relax relocations.
//
@@ -1167,15 +1167,15 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// be resolved within the executable will actually be resolved that way at
// runtime, because the main exectuable is always at the beginning of a search
// list. We can leverage that fact.
- if (!Sym.IsPreemptible && (!Sym.isGnuIFunc() || Config->ZIfuncNoplt)) {
- if (Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
- Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
+ if (!sym.isPreemptible && (!sym.isGnuIFunc() || config->zIfuncNoplt)) {
+ if (expr == R_GOT_PC && !isAbsoluteValue(sym)) {
+ expr = target->adjustRelaxExpr(type, relocatedAddr, expr);
} else {
// Addend of R_PPC_PLTREL24 is used to choose call stub type. It should be
// ignored if optimized to R_PC.
- if (Config->EMachine == EM_PPC && Expr == R_PPC32_PLTREL)
- Addend = 0;
- Expr = fromPlt(Expr);
+ if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)
+ addend = 0;
+ expr = fromPlt(expr);
}
}
@@ -1183,39 +1183,39 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// uses their addresses, we need GOT or GOTPLT to be created.
//
// The 4 types that relative GOTPLT are all x86 and x86-64 specific.
- if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(Expr)) {
- In.GotPlt->HasGotPltOffRel = true;
+ if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(expr)) {
+ in.gotPlt->hasGotPltOffRel = true;
} else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC64_TOCBASE, R_PPC64_RELAX_TOC>(
- Expr)) {
- In.Got->HasGotOffRel = true;
+ expr)) {
+ in.got->hasGotOffRel = true;
}
// Process some TLS relocations, including relaxing TLS relocations.
// Note that this function does not handle all TLS relocations.
- if (unsigned Processed =
- handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) {
- I += (Processed - 1);
+ if (unsigned processed =
+ handleTlsRelocation<ELFT>(type, sym, sec, offset, addend, expr)) {
+ i += (processed - 1);
return;
}
// We were asked not to generate PLT entries for ifuncs. Instead, pass the
// direct relocation on through.
- if (Sym.isGnuIFunc() && Config->ZIfuncNoplt) {
- Sym.ExportDynamic = true;
- Main->RelaDyn->addReloc(Type, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);
+ if (sym.isGnuIFunc() && config->zIfuncNoplt) {
+ sym.exportDynamic = true;
+ mainPart->relaDyn->addReloc(type, &sec, offset, &sym, addend, R_ADDEND, type);
return;
}
// Non-preemptible ifuncs require special handling. First, handle the usual
// case where the symbol isn't one of these.
- if (!Sym.isGnuIFunc() || Sym.IsPreemptible) {
+ if (!sym.isGnuIFunc() || sym.isPreemptible) {
// If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
- if (needsPlt(Expr) && !Sym.isInPlt())
- addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
+ if (needsPlt(expr) && !sym.isInPlt())
+ addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
// Create a GOT slot if a relocation needs GOT.
- if (needsGot(Expr)) {
- if (Config->EMachine == EM_MIPS) {
+ if (needsGot(expr)) {
+ if (config->emachine == EM_MIPS) {
// MIPS ABI has special rules to process GOT entries and doesn't
// require relocation entries for them. A special case is TLS
// relocations. In that case dynamic loader applies dynamic
@@ -1223,9 +1223,9 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
- } else if (!Sym.isInGot()) {
- addGotEntry(Sym);
+ in.mipsGot->addEntry(*sec.file, sym, addend, expr);
+ } else if (!sym.isInGot()) {
+ addGotEntry(sym);
}
}
} else {
@@ -1275,9 +1275,9 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// the exact same way as a GOT entry, so we can avoid needing to make the
// PLT entry canonical by translating such relocations into IRELATIVE
// relocations in the RelaIplt.
- if (!Sym.isInPlt()) {
+ if (!sym.isInPlt()) {
// Create PLT and GOTPLT slots for the symbol.
- Sym.IsInIplt = true;
+ sym.isInIplt = true;
// Create a copy of the symbol to use as the target of the IRELATIVE
// relocation in the IgotPlt. This is in case we make the PLT canonical
@@ -1286,12 +1286,12 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// FIXME: Creating a copy of the symbol here is a bit of a hack. All
// that's really needed to create the IRELATIVE is the section and value,
// so ideally we should just need to copy those.
- auto *DirectSym = make<Defined>(cast<Defined>(Sym));
- addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
- *DirectSym);
- Sym.PltIndex = DirectSym->PltIndex;
+ auto *directSym = make<Defined>(cast<Defined>(sym));
+ addPltEntry<ELFT>(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
+ *directSym);
+ sym.pltIndex = directSym->pltIndex;
}
- if (Expr == R_ABS && Addend == 0 && (Sec.Flags & SHF_WRITE)) {
+ if (expr == R_ABS && addend == 0 && (sec.flags & SHF_WRITE)) {
// We might be able to represent this as an IRELATIVE. But we don't know
// yet whether some later relocation will make the symbol point to a
// canonical PLT, which would make this either a dynamic RELATIVE (PIC) or
@@ -1299,32 +1299,32 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
// required to process the relocation, and after scanRelocs() has been
// called on all relocations, the relocation is resolved by
// addIRelativeRelocs().
- IRelativeRelocs.push_back({Type, &Sec, Offset, &Sym});
+ iRelativeRelocs.push_back({type, &sec, offset, &sym});
return;
}
- if (needsGot(Expr)) {
+ if (needsGot(expr)) {
// Redirect GOT accesses to point to the Igot.
//
// This field is also used to keep track of whether we ever needed a GOT
// entry. If we did and we make the PLT canonical later, we'll need to
// create a GOT entry pointing to the PLT entry for Sym.
- Sym.GotInIgot = true;
- } else if (!needsPlt(Expr)) {
+ sym.gotInIgot = true;
+ } else if (!needsPlt(expr)) {
// Make the ifunc's PLT entry canonical by changing the value of its
// symbol to redirect all references to point to it.
- unsigned EntryOffset = Sym.PltIndex * Target->PltEntrySize;
- if (Config->ZRetpolineplt)
- EntryOffset += Target->PltHeaderSize;
-
- auto &D = cast<Defined>(Sym);
- D.Section = In.Iplt;
- D.Value = EntryOffset;
- D.Size = 0;
+ unsigned entryOffset = sym.pltIndex * target->pltEntrySize;
+ if (config->zRetpolineplt)
+ entryOffset += target->pltHeaderSize;
+
+ auto &d = cast<Defined>(sym);
+ d.section = in.iplt;
+ d.value = entryOffset;
+ d.size = 0;
// It's important to set the symbol type here so that dynamic loaders
// don't try to call the PLT as if it were an ifunc resolver.
- D.Type = STT_FUNC;
+ d.type = STT_FUNC;
- if (Sym.GotInIgot) {
+ if (sym.gotInIgot) {
// We previously encountered a GOT generating reference that we
// redirected to the Igot. Now that the PLT entry is canonical we must
// clear the redirection to the Igot and add a GOT entry. As we've
@@ -1333,74 +1333,74 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
//
// We don't need to worry about creating a MIPS GOT here because ifuncs
// aren't a thing on MIPS.
- Sym.GotInIgot = false;
- addGotEntry(Sym);
+ sym.gotInIgot = false;
+ addGotEntry(sym);
}
}
}
- processRelocAux<ELFT>(Sec, Expr, Type, Offset, Sym, Rel, Addend);
+ processRelocAux<ELFT>(sec, expr, type, offset, sym, rel, addend);
}
template <class ELFT, class RelTy>
-static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
- OffsetGetter GetOffset(Sec);
+static void scanRelocs(InputSectionBase &sec, ArrayRef<RelTy> rels) {
+ OffsetGetter getOffset(sec);
// Not all relocations end up in Sec.Relocations, but a lot do.
- Sec.Relocations.reserve(Rels.size());
+ sec.relocations.reserve(rels.size());
- for (auto I = Rels.begin(), End = Rels.end(); I != End;)
- scanReloc<ELFT>(Sec, GetOffset, I, End);
+ for (auto i = rels.begin(), end = rels.end(); i != end;)
+ scanReloc<ELFT>(sec, getOffset, i, end);
// Sort relocations by offset for more efficient searching for
// R_RISCV_PCREL_HI20 and R_PPC64_ADDR64.
- if (Config->EMachine == EM_RISCV ||
- (Config->EMachine == EM_PPC64 && Sec.Name == ".toc"))
- llvm::stable_sort(Sec.Relocations,
- [](const Relocation &LHS, const Relocation &RHS) {
- return LHS.Offset < RHS.Offset;
+ if (config->emachine == EM_RISCV ||
+ (config->emachine == EM_PPC64 && sec.name == ".toc"))
+ llvm::stable_sort(sec.relocations,
+ [](const Relocation &lhs, const Relocation &rhs) {
+ return lhs.offset < rhs.offset;
});
}
-template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
- if (S.AreRelocsRela)
- scanRelocs<ELFT>(S, S.relas<ELFT>());
+template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
+ if (s.areRelocsRela)
+ scanRelocs<ELFT>(s, s.relas<ELFT>());
else
- scanRelocs<ELFT>(S, S.rels<ELFT>());
+ scanRelocs<ELFT>(s, s.rels<ELFT>());
}
// Figure out which representation to use for any absolute relocs to
// non-preemptible ifuncs that we visited during scanRelocs().
void elf::addIRelativeRelocs() {
- for (IRelativeReloc &R : IRelativeRelocs) {
- if (R.Sym->Type == STT_GNU_IFUNC)
- In.RelaIplt->addReloc(
- {Target->IRelativeRel, R.Sec, R.Offset, true, R.Sym, 0});
- else if (Config->Pic)
- addRelativeReloc(R.Sec, R.Offset, R.Sym, 0, R_ABS, R.Type);
+ for (IRelativeReloc &r : iRelativeRelocs) {
+ if (r.sym->type == STT_GNU_IFUNC)
+ in.relaIplt->addReloc(
+ {target->iRelativeRel, r.sec, r.offset, true, r.sym, 0});
+ else if (config->isPic)
+ addRelativeReloc(r.sec, r.offset, r.sym, 0, R_ABS, r.type);
else
- R.Sec->Relocations.push_back({R_ABS, R.Type, R.Offset, 0, R.Sym});
+ r.sec->relocations.push_back({R_ABS, r.type, r.offset, 0, r.sym});
}
- IRelativeRelocs.clear();
+ iRelativeRelocs.clear();
}
-static bool mergeCmp(const InputSection *A, const InputSection *B) {
+static bool mergeCmp(const InputSection *a, const InputSection *b) {
// std::merge requires a strict weak ordering.
- if (A->OutSecOff < B->OutSecOff)
+ if (a->outSecOff < b->outSecOff)
return true;
- if (A->OutSecOff == B->OutSecOff) {
- auto *TA = dyn_cast<ThunkSection>(A);
- auto *TB = dyn_cast<ThunkSection>(B);
+ if (a->outSecOff == b->outSecOff) {
+ auto *ta = dyn_cast<ThunkSection>(a);
+ auto *tb = dyn_cast<ThunkSection>(b);
// Check if Thunk is immediately before any specific Target
// InputSection for example Mips LA25 Thunks.
- if (TA && TA->getTargetInputSection() == B)
+ if (ta && ta->getTargetInputSection() == b)
return true;
// Place Thunk Sections without specific targets before
// non-Thunk Sections.
- if (TA && !TB && !TA->getTargetInputSection())
+ if (ta && !tb && !ta->getTargetInputSection())
return true;
}
@@ -1410,14 +1410,14 @@ static bool mergeCmp(const InputSection *A, const InputSection *B) {
// Call Fn on every executable InputSection accessed via the linker script
// InputSectionDescription::Sections.
static void forEachInputSectionDescription(
- ArrayRef<OutputSection *> OutputSections,
- llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn) {
- for (OutputSection *OS : OutputSections) {
- if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
+ ArrayRef<OutputSection *> outputSections,
+ llvm::function_ref<void(OutputSection *, InputSectionDescription *)> fn) {
+ for (OutputSection *os : outputSections) {
+ if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))
continue;
- for (BaseCommand *BC : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(BC))
- Fn(OS, ISD);
+ for (BaseCommand *bc : os->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(bc))
+ fn(os, isd);
}
}
@@ -1512,54 +1512,54 @@ static void forEachInputSectionDescription(
// in the Sections vector, and recalculate the InputSection output section
// offsets.
// This may invalidate any output section offsets stored outside of InputSection
-void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
+void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {
forEachInputSectionDescription(
- OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
- if (ISD->ThunkSections.empty())
+ outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
+ if (isd->thunkSections.empty())
return;
// Remove any zero sized precreated Thunks.
- llvm::erase_if(ISD->ThunkSections,
- [](const std::pair<ThunkSection *, uint32_t> &TS) {
- return TS.first->getSize() == 0;
+ llvm::erase_if(isd->thunkSections,
+ [](const std::pair<ThunkSection *, uint32_t> &ts) {
+ return ts.first->getSize() == 0;
});
// ISD->ThunkSections contains all created ThunkSections, including
// those inserted in previous passes. Extract the Thunks created this
// pass and order them in ascending OutSecOff.
- std::vector<ThunkSection *> NewThunks;
- for (const std::pair<ThunkSection *, uint32_t> TS : ISD->ThunkSections)
- if (TS.second == Pass)
- NewThunks.push_back(TS.first);
- llvm::stable_sort(NewThunks,
- [](const ThunkSection *A, const ThunkSection *B) {
- return A->OutSecOff < B->OutSecOff;
+ std::vector<ThunkSection *> newThunks;
+ for (const std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections)
+ if (ts.second == pass)
+ newThunks.push_back(ts.first);
+ llvm::stable_sort(newThunks,
+ [](const ThunkSection *a, const ThunkSection *b) {
+ return a->outSecOff < b->outSecOff;
});
// Merge sorted vectors of Thunks and InputSections by OutSecOff
- std::vector<InputSection *> Tmp;
- Tmp.reserve(ISD->Sections.size() + NewThunks.size());
+ std::vector<InputSection *> tmp;
+ tmp.reserve(isd->sections.size() + newThunks.size());
- std::merge(ISD->Sections.begin(), ISD->Sections.end(),
- NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),
+ std::merge(isd->sections.begin(), isd->sections.end(),
+ newThunks.begin(), newThunks.end(), std::back_inserter(tmp),
mergeCmp);
- ISD->Sections = std::move(Tmp);
+ isd->sections = std::move(tmp);
});
}
// Find or create a ThunkSection within the InputSectionDescription (ISD) that
// is in range of Src. An ISD maps to a range of InputSections described by a
// linker script section pattern such as { .text .text.* }.
-ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS,
- InputSectionDescription *ISD,
- uint32_t Type, uint64_t Src) {
- for (std::pair<ThunkSection *, uint32_t> TP : ISD->ThunkSections) {
- ThunkSection *TS = TP.first;
- uint64_t TSBase = OS->Addr + TS->OutSecOff;
- uint64_t TSLimit = TSBase + TS->getSize();
- if (Target->inBranchRange(Type, Src, (Src > TSLimit) ? TSBase : TSLimit))
- return TS;
+ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os, InputSection *isec,
+ InputSectionDescription *isd,
+ uint32_t type, uint64_t src) {
+ for (std::pair<ThunkSection *, uint32_t> tp : isd->thunkSections) {
+ ThunkSection *ts = tp.first;
+ uint64_t tsBase = os->addr + ts->outSecOff;
+ uint64_t tsLimit = tsBase + ts->getSize();
+ if (target->inBranchRange(type, src, (src > tsLimit) ? tsBase : tsLimit))
+ return ts;
}
// No suitable ThunkSection exists. This can happen when there is a branch
@@ -1567,40 +1567,40 @@ ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS,
// many Thunks. Create a new ThunkSection as close to the InputSection as
// possible. Error if InputSection is so large we cannot place ThunkSection
// anywhere in Range.
- uint64_t ThunkSecOff = IS->OutSecOff;
- if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff)) {
- ThunkSecOff = IS->OutSecOff + IS->getSize();
- if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff))
+ uint64_t thunkSecOff = isec->outSecOff;
+ if (!target->inBranchRange(type, src, os->addr + thunkSecOff)) {
+ thunkSecOff = isec->outSecOff + isec->getSize();
+ if (!target->inBranchRange(type, src, os->addr + thunkSecOff))
fatal("InputSection too large for range extension thunk " +
- IS->getObjMsg(Src - (OS->Addr + IS->OutSecOff)));
+ isec->getObjMsg(src - (os->addr + isec->outSecOff)));
}
- return addThunkSection(OS, ISD, ThunkSecOff);
+ return addThunkSection(os, isd, thunkSecOff);
}
// Add a Thunk that needs to be placed in a ThunkSection that immediately
// precedes its Target.
-ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
- ThunkSection *TS = ThunkedSections.lookup(IS);
- if (TS)
- return TS;
+ThunkSection *ThunkCreator::getISThunkSec(InputSection *isec) {
+ ThunkSection *ts = thunkedSections.lookup(isec);
+ if (ts)
+ return ts;
// Find InputSectionRange within Target Output Section (TOS) that the
// InputSection (IS) that we need to precede is in.
- OutputSection *TOS = IS->getParent();
- for (BaseCommand *BC : TOS->SectionCommands) {
- auto *ISD = dyn_cast<InputSectionDescription>(BC);
- if (!ISD || ISD->Sections.empty())
+ OutputSection *tos = isec->getParent();
+ for (BaseCommand *bc : tos->sectionCommands) {
+ auto *isd = dyn_cast<InputSectionDescription>(bc);
+ if (!isd || isd->sections.empty())
continue;
- InputSection *First = ISD->Sections.front();
- InputSection *Last = ISD->Sections.back();
+ InputSection *first = isd->sections.front();
+ InputSection *last = isd->sections.back();
- if (IS->OutSecOff < First->OutSecOff || Last->OutSecOff < IS->OutSecOff)
+ if (isec->outSecOff < first->outSecOff || last->outSecOff < isec->outSecOff)
continue;
- TS = addThunkSection(TOS, ISD, IS->OutSecOff);
- ThunkedSections[IS] = TS;
- return TS;
+ ts = addThunkSection(tos, isd, isec->outSecOff);
+ thunkedSections[isec] = ts;
+ return ts;
}
return nullptr;
@@ -1623,93 +1623,93 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
// distance from a thunk to its target will be sufficiently small to
// allow for the creation of a short thunk.
void ThunkCreator::createInitialThunkSections(
- ArrayRef<OutputSection *> OutputSections) {
- uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
+ ArrayRef<OutputSection *> outputSections) {
+ uint32_t thunkSectionSpacing = target->getThunkSectionSpacing();
forEachInputSectionDescription(
- OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
- if (ISD->Sections.empty())
+ outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
+ if (isd->sections.empty())
return;
- uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
- uint32_t ISDEnd =
- ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
- uint32_t LastThunkLowerBound = -1;
- if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
- LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
-
- uint32_t ISLimit;
- uint32_t PrevISLimit = ISDBegin;
- uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
-
- for (const InputSection *IS : ISD->Sections) {
- ISLimit = IS->OutSecOff + IS->getSize();
- if (ISLimit > ThunkUpperBound) {
- addThunkSection(OS, ISD, PrevISLimit);
- ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
+ uint32_t isdBegin = isd->sections.front()->outSecOff;
+ uint32_t isdEnd =
+ isd->sections.back()->outSecOff + isd->sections.back()->getSize();
+ uint32_t lastThunkLowerBound = -1;
+ if (isdEnd - isdBegin > thunkSectionSpacing * 2)
+ lastThunkLowerBound = isdEnd - thunkSectionSpacing;
+
+ uint32_t isecLimit;
+ uint32_t prevISLimit = isdBegin;
+ uint32_t thunkUpperBound = isdBegin + thunkSectionSpacing;
+
+ for (const InputSection *isec : isd->sections) {
+ isecLimit = isec->outSecOff + isec->getSize();
+ if (isecLimit > thunkUpperBound) {
+ addThunkSection(os, isd, prevISLimit);
+ thunkUpperBound = prevISLimit + thunkSectionSpacing;
}
- if (ISLimit > LastThunkLowerBound)
+ if (isecLimit > lastThunkLowerBound)
break;
- PrevISLimit = ISLimit;
+ prevISLimit = isecLimit;
}
- addThunkSection(OS, ISD, ISLimit);
+ addThunkSection(os, isd, isecLimit);
});
}
-ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
- InputSectionDescription *ISD,
- uint64_t Off) {
- auto *TS = make<ThunkSection>(OS, Off);
- TS->Partition = OS->Partition;
- ISD->ThunkSections.push_back({TS, Pass});
- return TS;
+ThunkSection *ThunkCreator::addThunkSection(OutputSection *os,
+ InputSectionDescription *isd,
+ uint64_t off) {
+ auto *ts = make<ThunkSection>(os, off);
+ ts->partition = os->partition;
+ isd->thunkSections.push_back({ts, pass});
+ return ts;
}
-static bool isThunkSectionCompatible(InputSection *Source,
- SectionBase *Target) {
+static bool isThunkSectionCompatible(InputSection *source,
+ SectionBase *target) {
// We can't reuse thunks in different loadable partitions because they might
// not be loaded. But partition 1 (the main partition) will always be loaded.
- if (Source->Partition != Target->Partition)
- return Target->Partition == 1;
+ if (source->partition != target->partition)
+ return target->partition == 1;
return true;
}
-std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *IS,
- Relocation &Rel, uint64_t Src) {
- std::vector<Thunk *> *ThunkVec = nullptr;
+std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
+ Relocation &rel, uint64_t src) {
+ std::vector<Thunk *> *thunkVec = nullptr;
// We use (section, offset) pair to find the thunk position if possible so
// that we create only one thunk for aliased symbols or ICFed sections.
- if (auto *D = dyn_cast<Defined>(Rel.Sym))
- if (!D->isInPlt() && D->Section)
- ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];
- if (!ThunkVec)
- ThunkVec = &ThunkedSymbols[Rel.Sym];
+ if (auto *d = dyn_cast<Defined>(rel.sym))
+ if (!d->isInPlt() && d->section)
+ thunkVec = &thunkedSymbolsBySection[{d->section->repl, d->value}];
+ if (!thunkVec)
+ thunkVec = &thunkedSymbols[rel.sym];
// Check existing Thunks for Sym to see if they can be reused
- for (Thunk *T : *ThunkVec)
- if (isThunkSectionCompatible(IS, T->getThunkTargetSym()->Section) &&
- T->isCompatibleWith(*IS, Rel) &&
- Target->inBranchRange(Rel.Type, Src, T->getThunkTargetSym()->getVA()))
- return std::make_pair(T, false);
+ for (Thunk *t : *thunkVec)
+ if (isThunkSectionCompatible(isec, t->getThunkTargetSym()->section) &&
+ t->isCompatibleWith(*isec, rel) &&
+ target->inBranchRange(rel.type, src, t->getThunkTargetSym()->getVA()))
+ return std::make_pair(t, false);
// No existing compatible Thunk in range, create a new one
- Thunk *T = addThunk(*IS, Rel);
- ThunkVec->push_back(T);
- return std::make_pair(T, true);
+ Thunk *t = addThunk(*isec, rel);
+ thunkVec->push_back(t);
+ return std::make_pair(t, true);
}
// Return true if the relocation target is an in range Thunk.
// Return false if the relocation is not to a Thunk. If the relocation target
// was originally to a Thunk, but is no longer in range we revert the
// relocation back to its original non-Thunk target.
-bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
- if (Thunk *T = Thunks.lookup(Rel.Sym)) {
- if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))
+bool ThunkCreator::normalizeExistingThunk(Relocation &rel, uint64_t src) {
+ if (Thunk *t = thunks.lookup(rel.sym)) {
+ if (target->inBranchRange(rel.type, src, rel.sym->getVA()))
return true;
- Rel.Sym = &T->Destination;
- if (Rel.Sym->isInPlt())
- Rel.Expr = toPlt(Rel.Expr);
+ rel.sym = &t->destination;
+ if (rel.sym->isInPlt())
+ rel.expr = toPlt(rel.expr);
}
return false;
}
@@ -1739,15 +1739,15 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
// made no changes. If the target requires range extension thunks, currently
// ARM, then any future change in offset between caller and callee risks a
// relocation out of range error.
-bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
- bool AddressesChanged = false;
+bool ThunkCreator::createThunks(ArrayRef<OutputSection *> outputSections) {
+ bool addressesChanged = false;
- if (Pass == 0 && Target->getThunkSectionSpacing())
- createInitialThunkSections(OutputSections);
+ if (pass == 0 && target->getThunkSectionSpacing())
+ createInitialThunkSections(outputSections);
// With Thunk Size much smaller than branch range we expect to
// converge quickly; if we get to 10 something has gone wrong.
- if (Pass == 10)
+ if (pass == 10)
fatal("thunk creation not converged");
// Create all the Thunks and insert them into synthetic ThunkSections. The
@@ -1756,57 +1756,57 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
// ThunkSections as ThunkSections are not always inserted into the same
// InputSectionDescription as the caller.
forEachInputSectionDescription(
- OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
- for (InputSection *IS : ISD->Sections)
- for (Relocation &Rel : IS->Relocations) {
- uint64_t Src = IS->getVA(Rel.Offset);
+ outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
+ for (InputSection *isec : isd->sections)
+ for (Relocation &rel : isec->relocations) {
+ uint64_t src = isec->getVA(rel.offset);
// If we are a relocation to an existing Thunk, check if it is
// still in range. If not then Rel will be altered to point to its
// original target so another Thunk can be generated.
- if (Pass > 0 && normalizeExistingThunk(Rel, Src))
+ if (pass > 0 && normalizeExistingThunk(rel, src))
continue;
- if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,
- *Rel.Sym))
+ if (!target->needsThunk(rel.expr, rel.type, isec->file, src,
+ *rel.sym))
continue;
- Thunk *T;
- bool IsNew;
- std::tie(T, IsNew) = getThunk(IS, Rel, Src);
+ Thunk *t;
+ bool isNew;
+ std::tie(t, isNew) = getThunk(isec, rel, src);
- if (IsNew) {
+ if (isNew) {
// Find or create a ThunkSection for the new Thunk
- ThunkSection *TS;
- if (auto *TIS = T->getTargetInputSection())
- TS = getISThunkSec(TIS);
+ ThunkSection *ts;
+ if (auto *tis = t->getTargetInputSection())
+ ts = getISThunkSec(tis);
else
- TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src);
- TS->addThunk(T);
- Thunks[T->getThunkTargetSym()] = T;
+ ts = getISDThunkSec(os, isec, isd, rel.type, src);
+ ts->addThunk(t);
+ thunks[t->getThunkTargetSym()] = t;
}
// Redirect relocation to Thunk, we never go via the PLT to a Thunk
- Rel.Sym = T->getThunkTargetSym();
- Rel.Expr = fromPlt(Rel.Expr);
+ rel.sym = t->getThunkTargetSym();
+ rel.expr = fromPlt(rel.expr);
// The addend of R_PPC_PLTREL24 should be ignored after changing to
// R_PC.
- if (Config->EMachine == EM_PPC && Rel.Type == R_PPC_PLTREL24)
- Rel.Addend = 0;
+ if (config->emachine == EM_PPC && rel.type == R_PPC_PLTREL24)
+ rel.addend = 0;
}
- for (auto &P : ISD->ThunkSections)
- AddressesChanged |= P.first->assignOffsets();
+ for (auto &p : isd->thunkSections)
+ addressesChanged |= p.first->assignOffsets();
});
- for (auto &P : ThunkedSections)
- AddressesChanged |= P.second->assignOffsets();
+ for (auto &p : thunkedSections)
+ addressesChanged |= p.second->assignOffsets();
// Merge all created synthetic ThunkSections back into OutputSection
- mergeThunks(OutputSections);
- ++Pass;
- return AddressesChanged;
+ mergeThunks(outputSections);
+ ++pass;
+ return addressesChanged;
}
template void elf::scanRelocations<ELF32LE>(InputSectionBase &);
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index a008a6f1b18..d74d7b9b458 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -102,11 +102,11 @@ enum RelExpr {
// Architecture-neutral representation of relocation.
struct Relocation {
- RelExpr Expr;
- RelType Type;
- uint64_t Offset;
- int64_t Addend;
- Symbol *Sym;
+ RelExpr expr;
+ RelType type;
+ uint64_t offset;
+ int64_t addend;
+ Symbol *sym;
};
// This function writes undefined symbol diagnostics to an internal buffer.
@@ -125,57 +125,57 @@ struct InputSectionDescription;
class ThunkCreator {
public:
// Return true if Thunks have been added to OutputSections
- bool createThunks(ArrayRef<OutputSection *> OutputSections);
+ bool createThunks(ArrayRef<OutputSection *> outputSections);
// The number of completed passes of createThunks this permits us
// to do one time initialization on Pass 0 and put a limit on the
// number of times it can be called to prevent infinite loops.
- uint32_t Pass = 0;
+ uint32_t pass = 0;
private:
- void mergeThunks(ArrayRef<OutputSection *> OutputSections);
+ void mergeThunks(ArrayRef<OutputSection *> outputSections);
- ThunkSection *getISDThunkSec(OutputSection *OS, InputSection *IS,
- InputSectionDescription *ISD, uint32_t Type,
- uint64_t Src);
+ ThunkSection *getISDThunkSec(OutputSection *os, InputSection *isec,
+ InputSectionDescription *isd, uint32_t type,
+ uint64_t src);
- ThunkSection *getISThunkSec(InputSection *IS);
+ ThunkSection *getISThunkSec(InputSection *isec);
- void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
+ void createInitialThunkSections(ArrayRef<OutputSection *> outputSections);
- std::pair<Thunk *, bool> getThunk(InputSection *IS, Relocation &Rel,
- uint64_t Src);
+ std::pair<Thunk *, bool> getThunk(InputSection *isec, Relocation &rel,
+ uint64_t src);
- ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
- uint64_t Off);
+ ThunkSection *addThunkSection(OutputSection *os, InputSectionDescription *,
+ uint64_t off);
- bool normalizeExistingThunk(Relocation &Rel, uint64_t Src);
+ bool normalizeExistingThunk(Relocation &rel, uint64_t src);
// Record all the available Thunks for a Symbol
llvm::DenseMap<std::pair<SectionBase *, uint64_t>, std::vector<Thunk *>>
- ThunkedSymbolsBySection;
- llvm::DenseMap<Symbol *, std::vector<Thunk *>> ThunkedSymbols;
+ thunkedSymbolsBySection;
+ llvm::DenseMap<Symbol *, std::vector<Thunk *>> thunkedSymbols;
// Find a Thunk from the Thunks symbol definition, we can use this to find
// the Thunk from a relocation to the Thunks symbol definition.
- llvm::DenseMap<Symbol *, Thunk *> Thunks;
+ llvm::DenseMap<Symbol *, Thunk *> thunks;
// Track InputSections that have an inline ThunkSection placed in front
// an inline ThunkSection may have control fall through to the section below
// so we need to make sure that there is only one of them.
// The Mips LA25 Thunk is an example of an inline ThunkSection.
- llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
+ llvm::DenseMap<InputSection *, ThunkSection *> thunkedSections;
};
// Return a int64_t to make sure we get the sign extension out of the way as
// early as possible.
template <class ELFT>
-static inline int64_t getAddend(const typename ELFT::Rel &Rel) {
+static inline int64_t getAddend(const typename ELFT::Rel &rel) {
return 0;
}
template <class ELFT>
-static inline int64_t getAddend(const typename ELFT::Rela &Rel) {
- return Rel.r_addend;
+static inline int64_t getAddend(const typename ELFT::Rela &rel) {
+ return rel.r_addend;
}
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp
index bb530d2f52b..953a3df8a31 100644
--- a/lld/ELF/ScriptLexer.cpp
+++ b/lld/ELF/ScriptLexer.cpp
@@ -41,169 +41,169 @@ using namespace lld::elf;
// Returns a whole line containing the current token.
StringRef ScriptLexer::getLine() {
- StringRef S = getCurrentMB().getBuffer();
- StringRef Tok = Tokens[Pos - 1];
+ StringRef s = getCurrentMB().getBuffer();
+ StringRef tok = tokens[pos - 1];
- size_t Pos = S.rfind('\n', Tok.data() - S.data());
- if (Pos != StringRef::npos)
- S = S.substr(Pos + 1);
- return S.substr(0, S.find_first_of("\r\n"));
+ size_t pos = s.rfind('\n', tok.data() - s.data());
+ if (pos != StringRef::npos)
+ s = s.substr(pos + 1);
+ return s.substr(0, s.find_first_of("\r\n"));
}
// Returns 1-based line number of the current token.
size_t ScriptLexer::getLineNumber() {
- StringRef S = getCurrentMB().getBuffer();
- StringRef Tok = Tokens[Pos - 1];
- return S.substr(0, Tok.data() - S.data()).count('\n') + 1;
+ StringRef s = getCurrentMB().getBuffer();
+ StringRef tok = tokens[pos - 1];
+ return s.substr(0, tok.data() - s.data()).count('\n') + 1;
}
// Returns 0-based column number of the current token.
size_t ScriptLexer::getColumnNumber() {
- StringRef Tok = Tokens[Pos - 1];
- return Tok.data() - getLine().data();
+ StringRef tok = tokens[pos - 1];
+ return tok.data() - getLine().data();
}
std::string ScriptLexer::getCurrentLocation() {
- std::string Filename = getCurrentMB().getBufferIdentifier();
- return (Filename + ":" + Twine(getLineNumber())).str();
+ std::string filename = getCurrentMB().getBufferIdentifier();
+ return (filename + ":" + Twine(getLineNumber())).str();
}
-ScriptLexer::ScriptLexer(MemoryBufferRef MB) { tokenize(MB); }
+ScriptLexer::ScriptLexer(MemoryBufferRef mb) { tokenize(mb); }
// We don't want to record cascading errors. Keep only the first one.
-void ScriptLexer::setError(const Twine &Msg) {
+void ScriptLexer::setError(const Twine &msg) {
if (errorCount())
return;
- std::string S = (getCurrentLocation() + ": " + Msg).str();
- if (Pos)
- S += "\n>>> " + getLine().str() + "\n>>> " +
+ std::string s = (getCurrentLocation() + ": " + msg).str();
+ if (pos)
+ s += "\n>>> " + getLine().str() + "\n>>> " +
std::string(getColumnNumber(), ' ') + "^";
- error(S);
+ error(s);
}
// Split S into linker script tokens.
-void ScriptLexer::tokenize(MemoryBufferRef MB) {
- std::vector<StringRef> Vec;
- MBs.push_back(MB);
- StringRef S = MB.getBuffer();
- StringRef Begin = S;
+void ScriptLexer::tokenize(MemoryBufferRef mb) {
+ std::vector<StringRef> vec;
+ mbs.push_back(mb);
+ StringRef s = mb.getBuffer();
+ StringRef begin = s;
for (;;) {
- S = skipSpace(S);
- if (S.empty())
+ s = skipSpace(s);
+ if (s.empty())
break;
// Quoted token. Note that double-quote characters are parts of a token
// because, in a glob match context, only unquoted tokens are interpreted
// as glob patterns. Double-quoted tokens are literal patterns in that
// context.
- if (S.startswith("\"")) {
- size_t E = S.find("\"", 1);
- if (E == StringRef::npos) {
- StringRef Filename = MB.getBufferIdentifier();
- size_t Lineno = Begin.substr(0, S.data() - Begin.data()).count('\n');
- error(Filename + ":" + Twine(Lineno + 1) + ": unclosed quote");
+ if (s.startswith("\"")) {
+ size_t e = s.find("\"", 1);
+ if (e == StringRef::npos) {
+ StringRef filename = mb.getBufferIdentifier();
+ size_t lineno = begin.substr(0, s.data() - begin.data()).count('\n');
+ error(filename + ":" + Twine(lineno + 1) + ": unclosed quote");
return;
}
- Vec.push_back(S.take_front(E + 1));
- S = S.substr(E + 1);
+ vec.push_back(s.take_front(e + 1));
+ s = s.substr(e + 1);
continue;
}
// ">foo" is parsed to ">" and "foo", but ">>" is parsed to ">>".
// "|", "||", "&" and "&&" are different operators.
- if (S.startswith("<<") || S.startswith("<=") || S.startswith(">>") ||
- S.startswith(">=") || S.startswith("||") || S.startswith("&&")) {
- Vec.push_back(S.substr(0, 2));
- S = S.substr(2);
+ if (s.startswith("<<") || s.startswith("<=") || s.startswith(">>") ||
+ s.startswith(">=") || s.startswith("||") || s.startswith("&&")) {
+ vec.push_back(s.substr(0, 2));
+ s = s.substr(2);
continue;
}
// Unquoted token. This is more relaxed than tokens in C-like language,
// so that you can write "file-name.cpp" as one bare token, for example.
- size_t Pos = S.find_first_not_of(
+ size_t pos = s.find_first_not_of(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789_.$/\\~=+[]*?-!^:");
// A character that cannot start a word (which is usually a
// punctuation) forms a single character token.
- if (Pos == 0)
- Pos = 1;
- Vec.push_back(S.substr(0, Pos));
- S = S.substr(Pos);
+ if (pos == 0)
+ pos = 1;
+ vec.push_back(s.substr(0, pos));
+ s = s.substr(pos);
}
- Tokens.insert(Tokens.begin() + Pos, Vec.begin(), Vec.end());
+ tokens.insert(tokens.begin() + pos, vec.begin(), vec.end());
}
// Skip leading whitespace characters or comments.
-StringRef ScriptLexer::skipSpace(StringRef S) {
+StringRef ScriptLexer::skipSpace(StringRef s) {
for (;;) {
- if (S.startswith("/*")) {
- size_t E = S.find("*/", 2);
- if (E == StringRef::npos) {
+ if (s.startswith("/*")) {
+ size_t e = s.find("*/", 2);
+ if (e == StringRef::npos) {
error("unclosed comment in a linker script");
return "";
}
- S = S.substr(E + 2);
+ s = s.substr(e + 2);
continue;
}
- if (S.startswith("#")) {
- size_t E = S.find('\n', 1);
- if (E == StringRef::npos)
- E = S.size() - 1;
- S = S.substr(E + 1);
+ if (s.startswith("#")) {
+ size_t e = s.find('\n', 1);
+ if (e == StringRef::npos)
+ e = s.size() - 1;
+ s = s.substr(e + 1);
continue;
}
- size_t Size = S.size();
- S = S.ltrim();
- if (S.size() == Size)
- return S;
+ size_t size = s.size();
+ s = s.ltrim();
+ if (s.size() == size)
+ return s;
}
}
// An erroneous token is handled as if it were the last token before EOF.
-bool ScriptLexer::atEOF() { return errorCount() || Tokens.size() == Pos; }
+bool ScriptLexer::atEOF() { return errorCount() || tokens.size() == pos; }
// Split a given string as an expression.
// This function returns "3", "*" and "5" for "3*5" for example.
-static std::vector<StringRef> tokenizeExpr(StringRef S) {
- StringRef Ops = "+-*/:!~=<>"; // List of operators
+static std::vector<StringRef> tokenizeExpr(StringRef s) {
+ StringRef ops = "+-*/:!~=<>"; // List of operators
// Quoted strings are literal strings, so we don't want to split it.
- if (S.startswith("\""))
- return {S};
+ if (s.startswith("\""))
+ return {s};
// Split S with operators as separators.
- std::vector<StringRef> Ret;
- while (!S.empty()) {
- size_t E = S.find_first_of(Ops);
+ std::vector<StringRef> ret;
+ while (!s.empty()) {
+ size_t e = s.find_first_of(ops);
// No need to split if there is no operator.
- if (E == StringRef::npos) {
- Ret.push_back(S);
+ if (e == StringRef::npos) {
+ ret.push_back(s);
break;
}
// Get a token before the opreator.
- if (E != 0)
- Ret.push_back(S.substr(0, E));
+ if (e != 0)
+ ret.push_back(s.substr(0, e));
// Get the operator as a token.
// Keep !=, ==, >=, <=, << and >> operators as a single tokens.
- if (S.substr(E).startswith("!=") || S.substr(E).startswith("==") ||
- S.substr(E).startswith(">=") || S.substr(E).startswith("<=") ||
- S.substr(E).startswith("<<") || S.substr(E).startswith(">>")) {
- Ret.push_back(S.substr(E, 2));
- S = S.substr(E + 2);
+ if (s.substr(e).startswith("!=") || s.substr(e).startswith("==") ||
+ s.substr(e).startswith(">=") || s.substr(e).startswith("<=") ||
+ s.substr(e).startswith("<<") || s.substr(e).startswith(">>")) {
+ ret.push_back(s.substr(e, 2));
+ s = s.substr(e + 2);
} else {
- Ret.push_back(S.substr(E, 1));
- S = S.substr(E + 1);
+ ret.push_back(s.substr(e, 1));
+ s = s.substr(e + 1);
}
}
- return Ret;
+ return ret;
}
// In contexts where expressions are expected, the lexer should apply
@@ -216,14 +216,14 @@ static std::vector<StringRef> tokenizeExpr(StringRef S) {
//
// This function may split the current token into multiple tokens.
void ScriptLexer::maybeSplitExpr() {
- if (!InExpr || errorCount() || atEOF())
+ if (!inExpr || errorCount() || atEOF())
return;
- std::vector<StringRef> V = tokenizeExpr(Tokens[Pos]);
- if (V.size() == 1)
+ std::vector<StringRef> v = tokenizeExpr(tokens[pos]);
+ if (v.size() == 1)
return;
- Tokens.erase(Tokens.begin() + Pos);
- Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
+ tokens.erase(tokens.begin() + pos);
+ tokens.insert(tokens.begin() + pos, v.begin(), v.end());
}
StringRef ScriptLexer::next() {
@@ -235,28 +235,28 @@ StringRef ScriptLexer::next() {
setError("unexpected EOF");
return "";
}
- return Tokens[Pos++];
+ return tokens[pos++];
}
StringRef ScriptLexer::peek() {
- StringRef Tok = next();
+ StringRef tok = next();
if (errorCount())
return "";
- Pos = Pos - 1;
- return Tok;
+ pos = pos - 1;
+ return tok;
}
StringRef ScriptLexer::peek2() {
skip();
- StringRef Tok = next();
+ StringRef tok = next();
if (errorCount())
return "";
- Pos = Pos - 2;
- return Tok;
+ pos = pos - 2;
+ return tok;
}
-bool ScriptLexer::consume(StringRef Tok) {
- if (peek() == Tok) {
+bool ScriptLexer::consume(StringRef tok) {
+ if (peek() == tok) {
skip();
return true;
}
@@ -264,12 +264,12 @@ bool ScriptLexer::consume(StringRef Tok) {
}
// Consumes Tok followed by ":". Space is allowed between Tok and ":".
-bool ScriptLexer::consumeLabel(StringRef Tok) {
- if (consume((Tok + ":").str()))
+bool ScriptLexer::consumeLabel(StringRef tok) {
+ if (consume((tok + ":").str()))
return true;
- if (Tokens.size() >= Pos + 2 && Tokens[Pos] == Tok &&
- Tokens[Pos + 1] == ":") {
- Pos += 2;
+ if (tokens.size() >= pos + 2 && tokens[pos] == tok &&
+ tokens[pos + 1] == ":") {
+ pos += 2;
return true;
}
return false;
@@ -277,24 +277,24 @@ bool ScriptLexer::consumeLabel(StringRef Tok) {
void ScriptLexer::skip() { (void)next(); }
-void ScriptLexer::expect(StringRef Expect) {
+void ScriptLexer::expect(StringRef expect) {
if (errorCount())
return;
- StringRef Tok = next();
- if (Tok != Expect)
- setError(Expect + " expected, but got " + Tok);
+ StringRef tok = next();
+ if (tok != expect)
+ setError(expect + " expected, but got " + tok);
}
// Returns true if S encloses T.
-static bool encloses(StringRef S, StringRef T) {
- return S.bytes_begin() <= T.bytes_begin() && T.bytes_end() <= S.bytes_end();
+static bool encloses(StringRef s, StringRef t) {
+ return s.bytes_begin() <= t.bytes_begin() && t.bytes_end() <= s.bytes_end();
}
MemoryBufferRef ScriptLexer::getCurrentMB() {
// Find input buffer containing the current token.
- assert(!MBs.empty() && Pos > 0);
- for (MemoryBufferRef MB : MBs)
- if (encloses(MB.getBuffer(), Tokens[Pos - 1]))
- return MB;
+ assert(!mbs.empty() && pos > 0);
+ for (MemoryBufferRef mb : mbs)
+ if (encloses(mb.getBuffer(), tokens[pos - 1]))
+ return mb;
llvm_unreachable("getCurrentMB: failed to find a token");
}
diff --git a/lld/ELF/ScriptLexer.h b/lld/ELF/ScriptLexer.h
index 19ec3a8234c..98e4cac95a7 100644
--- a/lld/ELF/ScriptLexer.h
+++ b/lld/ELF/ScriptLexer.h
@@ -20,25 +20,25 @@ namespace elf {
class ScriptLexer {
public:
- explicit ScriptLexer(MemoryBufferRef MB);
+ explicit ScriptLexer(MemoryBufferRef mb);
- void setError(const Twine &Msg);
- void tokenize(MemoryBufferRef MB);
- static StringRef skipSpace(StringRef S);
+ void setError(const Twine &msg);
+ void tokenize(MemoryBufferRef mb);
+ static StringRef skipSpace(StringRef s);
bool atEOF();
StringRef next();
StringRef peek();
StringRef peek2();
void skip();
- bool consume(StringRef Tok);
- void expect(StringRef Expect);
- bool consumeLabel(StringRef Tok);
+ bool consume(StringRef tok);
+ void expect(StringRef expect);
+ bool consumeLabel(StringRef tok);
std::string getCurrentLocation();
- std::vector<MemoryBufferRef> MBs;
- std::vector<StringRef> Tokens;
- bool InExpr = false;
- size_t Pos = 0;
+ std::vector<MemoryBufferRef> mbs;
+ std::vector<StringRef> tokens;
+ bool inExpr = false;
+ size_t pos = 0;
private:
void maybeSplitExpr();
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index eb896c6b725..b0f710b78e1 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -43,15 +43,15 @@ using namespace lld::elf;
namespace {
class ScriptParser final : ScriptLexer {
public:
- ScriptParser(MemoryBufferRef MB) : ScriptLexer(MB) {
+ ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
// Initialize IsUnderSysroot
- if (Config->Sysroot == "")
+ if (config->sysroot == "")
return;
- StringRef Path = MB.getBufferIdentifier();
- for (; !Path.empty(); Path = sys::path::parent_path(Path)) {
- if (!sys::fs::equivalent(Config->Sysroot, Path))
+ StringRef path = mb.getBufferIdentifier();
+ for (; !path.empty(); path = sys::path::parent_path(path)) {
+ if (!sys::fs::equivalent(config->sysroot, path))
continue;
- IsUnderSysroot = true;
+ isUnderSysroot = true;
return;
}
}
@@ -59,10 +59,10 @@ public:
void readLinkerScript();
void readVersionScript();
void readDynamicList();
- void readDefsym(StringRef Name);
+ void readDefsym(StringRef name);
private:
- void addFile(StringRef Path);
+ void addFile(StringRef path);
void readAsNeeded();
void readEntry();
@@ -82,23 +82,23 @@ private:
void readVersion();
void readVersionScriptCommand();
- SymbolAssignment *readSymbolAssignment(StringRef Name);
- ByteCommand *readByteCommand(StringRef Tok);
+ SymbolAssignment *readSymbolAssignment(StringRef name);
+ ByteCommand *readByteCommand(StringRef tok);
std::array<uint8_t, 4> readFill();
- bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
- void readSectionAddressType(OutputSection *Cmd);
+ bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
+ void readSectionAddressType(OutputSection *cmd);
OutputSection *readOverlaySectionDescription();
- OutputSection *readOutputSectionDescription(StringRef OutSec);
+ OutputSection *readOutputSectionDescription(StringRef outSec);
std::vector<BaseCommand *> readOverlay();
std::vector<StringRef> readOutputSectionPhdrs();
- InputSectionDescription *readInputSectionDescription(StringRef Tok);
+ InputSectionDescription *readInputSectionDescription(StringRef tok);
StringMatcher readFilePatterns();
std::vector<SectionPattern> readInputSectionsList();
- InputSectionDescription *readInputSectionRules(StringRef FilePattern);
+ InputSectionDescription *readInputSectionRules(StringRef filePattern);
unsigned readPhdrType();
SortSectionPolicy readSortKind();
- SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
- SymbolAssignment *readAssignment(StringRef Tok);
+ SymbolAssignment *readProvideHidden(bool provide, bool hidden);
+ SymbolAssignment *readAssignment(StringRef tok);
void readSort();
Expr readAssert();
Expr readConstant();
@@ -107,88 +107,88 @@ private:
uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
std::pair<uint32_t, uint32_t> readMemoryAttributes();
- Expr combine(StringRef Op, Expr L, Expr R);
+ Expr combine(StringRef op, Expr l, Expr r);
Expr readExpr();
- Expr readExpr1(Expr Lhs, int MinPrec);
+ Expr readExpr1(Expr lhs, int minPrec);
StringRef readParenLiteral();
Expr readPrimary();
- Expr readTernary(Expr Cond);
+ Expr readTernary(Expr cond);
Expr readParenExpr();
// For parsing version script.
std::vector<SymbolVersion> readVersionExtern();
void readAnonymousDeclaration();
- void readVersionDeclaration(StringRef VerStr);
+ void readVersionDeclaration(StringRef verStr);
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
readSymbols();
// True if a script being read is in a subdirectory specified by -sysroot.
- bool IsUnderSysroot = false;
+ bool isUnderSysroot = false;
// A set to detect an INCLUDE() cycle.
- StringSet<> Seen;
+ StringSet<> seen;
};
} // namespace
-static StringRef unquote(StringRef S) {
- if (S.startswith("\""))
- return S.substr(1, S.size() - 2);
- return S;
+static StringRef unquote(StringRef s) {
+ if (s.startswith("\""))
+ return s.substr(1, s.size() - 2);
+ return s;
}
// Some operations only support one non absolute value. Move the
// absolute one to the right hand side for convenience.
-static void moveAbsRight(ExprValue &A, ExprValue &B) {
- if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute()))
- std::swap(A, B);
- if (!B.isAbsolute())
- error(A.Loc + ": at least one side of the expression must be absolute");
+static void moveAbsRight(ExprValue &a, ExprValue &b) {
+ if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
+ std::swap(a, b);
+ if (!b.isAbsolute())
+ error(a.loc + ": at least one side of the expression must be absolute");
}
-static ExprValue add(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
+static ExprValue add(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
}
-static ExprValue sub(ExprValue A, ExprValue B) {
+static ExprValue sub(ExprValue a, ExprValue b) {
// The distance between two symbols in sections is absolute.
- if (!A.isAbsolute() && !B.isAbsolute())
- return A.getValue() - B.getValue();
- return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
+ if (!a.isAbsolute() && !b.isAbsolute())
+ return a.getValue() - b.getValue();
+ return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
}
-static ExprValue bitAnd(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute,
- (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
+static ExprValue bitAnd(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute,
+ (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
}
-static ExprValue bitOr(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute,
- (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
+static ExprValue bitOr(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute,
+ (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
}
void ScriptParser::readDynamicList() {
- Config->HasDynamicList = true;
+ config->hasDynamicList = true;
expect("{");
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
expect(";");
if (!atEOF()) {
setError("EOF expected, but got " + next());
return;
}
- if (!Locals.empty()) {
+ if (!locals.empty()) {
setError("\"local:\" scope not supported in --dynamic-list");
return;
}
- for (SymbolVersion V : Globals)
- Config->DynamicList.push_back(V);
+ for (SymbolVersion v : globals)
+ config->dynamicList.push_back(v);
}
void ScriptParser::readVersionScript() {
@@ -204,14 +204,14 @@ void ScriptParser::readVersionScriptCommand() {
}
while (!atEOF() && !errorCount() && peek() != "}") {
- StringRef VerStr = next();
- if (VerStr == "{") {
+ StringRef verStr = next();
+ if (verStr == "{") {
setError("anonymous version definition is used in "
"combination with other version definitions");
return;
}
expect("{");
- readVersionDeclaration(VerStr);
+ readVersionDeclaration(verStr);
}
}
@@ -223,135 +223,135 @@ void ScriptParser::readVersion() {
void ScriptParser::readLinkerScript() {
while (!atEOF()) {
- StringRef Tok = next();
- if (Tok == ";")
+ StringRef tok = next();
+ if (tok == ";")
continue;
- if (Tok == "ENTRY") {
+ if (tok == "ENTRY") {
readEntry();
- } else if (Tok == "EXTERN") {
+ } else if (tok == "EXTERN") {
readExtern();
- } else if (Tok == "GROUP") {
+ } else if (tok == "GROUP") {
readGroup();
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
- } else if (Tok == "INPUT") {
+ } else if (tok == "INPUT") {
readInput();
- } else if (Tok == "MEMORY") {
+ } else if (tok == "MEMORY") {
readMemory();
- } else if (Tok == "OUTPUT") {
+ } else if (tok == "OUTPUT") {
readOutput();
- } else if (Tok == "OUTPUT_ARCH") {
+ } else if (tok == "OUTPUT_ARCH") {
readOutputArch();
- } else if (Tok == "OUTPUT_FORMAT") {
+ } else if (tok == "OUTPUT_FORMAT") {
readOutputFormat();
- } else if (Tok == "PHDRS") {
+ } else if (tok == "PHDRS") {
readPhdrs();
- } else if (Tok == "REGION_ALIAS") {
+ } else if (tok == "REGION_ALIAS") {
readRegionAlias();
- } else if (Tok == "SEARCH_DIR") {
+ } else if (tok == "SEARCH_DIR") {
readSearchDir();
- } else if (Tok == "SECTIONS") {
+ } else if (tok == "SECTIONS") {
readSections();
- } else if (Tok == "TARGET") {
+ } else if (tok == "TARGET") {
readTarget();
- } else if (Tok == "VERSION") {
+ } else if (tok == "VERSION") {
readVersion();
- } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
- Script->SectionCommands.push_back(Cmd);
+ } else if (SymbolAssignment *cmd = readAssignment(tok)) {
+ script->sectionCommands.push_back(cmd);
} else {
- setError("unknown directive: " + Tok);
+ setError("unknown directive: " + tok);
}
}
}
-void ScriptParser::readDefsym(StringRef Name) {
+void ScriptParser::readDefsym(StringRef name) {
if (errorCount())
return;
- Expr E = readExpr();
+ Expr e = readExpr();
if (!atEOF())
setError("EOF expected, but got " + next());
- SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
- Script->SectionCommands.push_back(Cmd);
+ SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
+ script->sectionCommands.push_back(cmd);
}
-void ScriptParser::addFile(StringRef S) {
- if (IsUnderSysroot && S.startswith("/")) {
- SmallString<128> PathData;
- StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
- if (sys::fs::exists(Path)) {
- Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
+void ScriptParser::addFile(StringRef s) {
+ if (isUnderSysroot && s.startswith("/")) {
+ SmallString<128> pathData;
+ StringRef path = (config->sysroot + s).toStringRef(pathData);
+ if (sys::fs::exists(path)) {
+ driver->addFile(Saver.save(path), /*WithLOption=*/false);
return;
}
}
- if (S.startswith("/")) {
- Driver->addFile(S, /*WithLOption=*/false);
- } else if (S.startswith("=")) {
- if (Config->Sysroot.empty())
- Driver->addFile(S.substr(1), /*WithLOption=*/false);
+ if (s.startswith("/")) {
+ driver->addFile(s, /*WithLOption=*/false);
+ } else if (s.startswith("=")) {
+ if (config->sysroot.empty())
+ driver->addFile(s.substr(1), /*WithLOption=*/false);
else
- Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
+ driver->addFile(Saver.save(config->sysroot + "/" + s.substr(1)),
/*WithLOption=*/false);
- } else if (S.startswith("-l")) {
- Driver->addLibrary(S.substr(2));
- } else if (sys::fs::exists(S)) {
- Driver->addFile(S, /*WithLOption=*/false);
+ } else if (s.startswith("-l")) {
+ driver->addLibrary(s.substr(2));
+ } else if (sys::fs::exists(s)) {
+ driver->addFile(s, /*WithLOption=*/false);
} else {
- if (Optional<std::string> Path = findFromSearchPaths(S))
- Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
+ if (Optional<std::string> path = findFromSearchPaths(s))
+ driver->addFile(Saver.save(*path), /*WithLOption=*/true);
else
- setError("unable to find " + S);
+ setError("unable to find " + s);
}
}
void ScriptParser::readAsNeeded() {
expect("(");
- bool Orig = Config->AsNeeded;
- Config->AsNeeded = true;
+ bool orig = config->asNeeded;
+ config->asNeeded = true;
while (!errorCount() && !consume(")"))
addFile(unquote(next()));
- Config->AsNeeded = Orig;
+ config->asNeeded = orig;
}
void ScriptParser::readEntry() {
// -e <symbol> takes predecence over ENTRY(<symbol>).
expect("(");
- StringRef Tok = next();
- if (Config->Entry.empty())
- Config->Entry = Tok;
+ StringRef tok = next();
+ if (config->entry.empty())
+ config->entry = tok;
expect(")");
}
void ScriptParser::readExtern() {
expect("(");
while (!errorCount() && !consume(")"))
- Config->Undefined.push_back(unquote(next()));
+ config->undefined.push_back(unquote(next()));
}
void ScriptParser::readGroup() {
- bool Orig = InputFile::IsInGroup;
- InputFile::IsInGroup = true;
+ bool orig = InputFile::isInGroup;
+ InputFile::isInGroup = true;
readInput();
- InputFile::IsInGroup = Orig;
- if (!Orig)
- ++InputFile::NextGroupId;
+ InputFile::isInGroup = orig;
+ if (!orig)
+ ++InputFile::nextGroupId;
}
void ScriptParser::readInclude() {
- StringRef Tok = unquote(next());
+ StringRef tok = unquote(next());
- if (!Seen.insert(Tok).second) {
+ if (!seen.insert(tok).second) {
setError("there is a cycle in linker script INCLUDEs");
return;
}
- if (Optional<std::string> Path = searchScript(Tok)) {
- if (Optional<MemoryBufferRef> MB = readFile(*Path))
- tokenize(*MB);
+ if (Optional<std::string> path = searchScript(tok)) {
+ if (Optional<MemoryBufferRef> mb = readFile(*path))
+ tokenize(*mb);
return;
}
- setError("cannot find linker script " + Tok);
+ setError("cannot find linker script " + tok);
}
void ScriptParser::readInput() {
@@ -367,9 +367,9 @@ void ScriptParser::readInput() {
void ScriptParser::readOutput() {
// -o <file> takes predecence over OUTPUT(<file>).
expect("(");
- StringRef Tok = next();
- if (Config->OutputFile.empty())
- Config->OutputFile = unquote(Tok);
+ StringRef tok = next();
+ if (config->outputFile.empty())
+ config->outputFile = unquote(tok);
expect(")");
}
@@ -380,8 +380,8 @@ void ScriptParser::readOutputArch() {
skip();
}
-static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
- return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
+ return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
.Case("elf32-i386", {ELF32LEKind, EM_386})
.Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
.Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
@@ -408,16 +408,16 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
void ScriptParser::readOutputFormat() {
expect("(");
- StringRef Name = unquote(next());
- StringRef S = Name;
- if (S.consume_back("-freebsd"))
- Config->OSABI = ELFOSABI_FREEBSD;
+ StringRef name = unquote(next());
+ StringRef s = name;
+ if (s.consume_back("-freebsd"))
+ config->osabi = ELFOSABI_FREEBSD;
- std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
- if (Config->EMachine == EM_NONE)
- setError("unknown output format name: " + Name);
- if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
- Config->MipsN32Abi = true;
+ std::tie(config->ekind, config->emachine) = parseBfdName(s);
+ if (config->emachine == EM_NONE)
+ setError("unknown output format name: " + name);
+ if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
+ config->mipsN32Abi = true;
if (consume(")"))
return;
@@ -432,46 +432,46 @@ void ScriptParser::readPhdrs() {
expect("{");
while (!errorCount() && !consume("}")) {
- PhdrsCommand Cmd;
- Cmd.Name = next();
- Cmd.Type = readPhdrType();
+ PhdrsCommand cmd;
+ cmd.name = next();
+ cmd.type = readPhdrType();
while (!errorCount() && !consume(";")) {
if (consume("FILEHDR"))
- Cmd.HasFilehdr = true;
+ cmd.hasFilehdr = true;
else if (consume("PHDRS"))
- Cmd.HasPhdrs = true;
+ cmd.hasPhdrs = true;
else if (consume("AT"))
- Cmd.LMAExpr = readParenExpr();
+ cmd.lmaExpr = readParenExpr();
else if (consume("FLAGS"))
- Cmd.Flags = readParenExpr()().getValue();
+ cmd.flags = readParenExpr()().getValue();
else
setError("unexpected header attribute: " + next());
}
- Script->PhdrsCommands.push_back(Cmd);
+ script->phdrsCommands.push_back(cmd);
}
}
void ScriptParser::readRegionAlias() {
expect("(");
- StringRef Alias = unquote(next());
+ StringRef alias = unquote(next());
expect(",");
- StringRef Name = next();
+ StringRef name = next();
expect(")");
- if (Script->MemoryRegions.count(Alias))
- setError("redefinition of memory region '" + Alias + "'");
- if (!Script->MemoryRegions.count(Name))
- setError("memory region '" + Name + "' is not defined");
- Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
+ if (script->memoryRegions.count(alias))
+ setError("redefinition of memory region '" + alias + "'");
+ if (!script->memoryRegions.count(name))
+ setError("memory region '" + name + "' is not defined");
+ script->memoryRegions.insert({alias, script->memoryRegions[name]});
}
void ScriptParser::readSearchDir() {
expect("(");
- StringRef Tok = next();
- if (!Config->Nostdlib)
- Config->SearchPaths.push_back(unquote(Tok));
+ StringRef tok = next();
+ if (!config->nostdlib)
+ config->searchPaths.push_back(unquote(tok));
expect(")");
}
@@ -483,83 +483,83 @@ std::vector<BaseCommand *> ScriptParser::readOverlay() {
// VA and LMA expressions are optional, though for simplicity of
// implementation we assume they are not. That is what OVERLAY was designed
// for first of all: to allow sections with overlapping VAs at different LMAs.
- Expr AddrExpr = readExpr();
+ Expr addrExpr = readExpr();
expect(":");
expect("AT");
- Expr LMAExpr = readParenExpr();
+ Expr lmaExpr = readParenExpr();
expect("{");
- std::vector<BaseCommand *> V;
- OutputSection *Prev = nullptr;
+ std::vector<BaseCommand *> v;
+ OutputSection *prev = nullptr;
while (!errorCount() && !consume("}")) {
// VA is the same for all sections. The LMAs are consecutive in memory
// starting from the base load address specified.
- OutputSection *OS = readOverlaySectionDescription();
- OS->AddrExpr = AddrExpr;
- if (Prev)
- OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; };
+ OutputSection *os = readOverlaySectionDescription();
+ os->addrExpr = addrExpr;
+ if (prev)
+ os->lmaExpr = [=] { return prev->getLMA() + prev->size; };
else
- OS->LMAExpr = LMAExpr;
- V.push_back(OS);
- Prev = OS;
+ os->lmaExpr = lmaExpr;
+ v.push_back(os);
+ prev = os;
}
// According to the specification, at the end of the overlay, the location
// counter should be equal to the overlay base address plus size of the
// largest section seen in the overlay.
// Here we want to create the Dot assignment command to achieve that.
- Expr MoveDot = [=] {
- uint64_t Max = 0;
- for (BaseCommand *Cmd : V)
- Max = std::max(Max, cast<OutputSection>(Cmd)->Size);
- return AddrExpr().getValue() + Max;
+ Expr moveDot = [=] {
+ uint64_t max = 0;
+ for (BaseCommand *cmd : v)
+ max = std::max(max, cast<OutputSection>(cmd)->size);
+ return addrExpr().getValue() + max;
};
- V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation()));
- return V;
+ v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
+ return v;
}
void ScriptParser::readSections() {
- Script->HasSectionsCommand = true;
+ script->hasSectionsCommand = true;
// -no-rosegment is used to avoid placing read only non-executable sections in
// their own segment. We do the same if SECTIONS command is present in linker
// script. See comment for computeFlags().
- Config->SingleRoRx = true;
+ config->singleRoRx = true;
expect("{");
- std::vector<BaseCommand *> V;
+ std::vector<BaseCommand *> v;
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == "OVERLAY") {
- for (BaseCommand *Cmd : readOverlay())
- V.push_back(Cmd);
+ StringRef tok = next();
+ if (tok == "OVERLAY") {
+ for (BaseCommand *cmd : readOverlay())
+ v.push_back(cmd);
continue;
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
continue;
}
- if (BaseCommand *Cmd = readAssignment(Tok))
- V.push_back(Cmd);
+ if (BaseCommand *cmd = readAssignment(tok))
+ v.push_back(cmd);
else
- V.push_back(readOutputSectionDescription(Tok));
+ v.push_back(readOutputSectionDescription(tok));
}
if (!atEOF() && consume("INSERT")) {
- std::vector<BaseCommand *> *Dest = nullptr;
+ std::vector<BaseCommand *> *dest = nullptr;
if (consume("AFTER"))
- Dest = &Script->InsertAfterCommands[next()];
+ dest = &script->insertAfterCommands[next()];
else if (consume("BEFORE"))
- Dest = &Script->InsertBeforeCommands[next()];
+ dest = &script->insertBeforeCommands[next()];
else
setError("expected AFTER/BEFORE, but got '" + next() + "'");
- if (Dest)
- Dest->insert(Dest->end(), V.begin(), V.end());
+ if (dest)
+ dest->insert(dest->end(), v.begin(), v.end());
return;
}
- Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(),
- V.end());
+ script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
+ v.end());
}
void ScriptParser::readTarget() {
@@ -568,19 +568,19 @@ void ScriptParser::readTarget() {
// for --format. We recognize only /^elf/ and "binary" in the linker
// script as well.
expect("(");
- StringRef Tok = next();
+ StringRef tok = next();
expect(")");
- if (Tok.startswith("elf"))
- Config->FormatBinary = false;
- else if (Tok == "binary")
- Config->FormatBinary = true;
+ if (tok.startswith("elf"))
+ config->formatBinary = false;
+ else if (tok == "binary")
+ config->formatBinary = true;
else
- setError("unknown target: " + Tok);
+ setError("unknown target: " + tok);
}
-static int precedence(StringRef Op) {
- return StringSwitch<int>(Op)
+static int precedence(StringRef op) {
+ return StringSwitch<int>(op)
.Cases("*", "/", "%", 8)
.Cases("+", "-", 7)
.Cases("<<", ">>", 6)
@@ -593,10 +593,10 @@ static int precedence(StringRef Op) {
}
StringMatcher ScriptParser::readFilePatterns() {
- std::vector<StringRef> V;
+ std::vector<StringRef> v;
while (!errorCount() && !consume(")"))
- V.push_back(next());
- return StringMatcher(V);
+ v.push_back(next());
+ return StringMatcher(v);
}
SortSectionPolicy ScriptParser::readSortKind() {
@@ -625,24 +625,24 @@ SortSectionPolicy ScriptParser::readSortKind() {
// The semantics of that is section .foo in any file, section .bar in
// any file but a.o, and section .baz in any file but b.o.
std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
- std::vector<SectionPattern> Ret;
+ std::vector<SectionPattern> ret;
while (!errorCount() && peek() != ")") {
- StringMatcher ExcludeFilePat;
+ StringMatcher excludeFilePat;
if (consume("EXCLUDE_FILE")) {
expect("(");
- ExcludeFilePat = readFilePatterns();
+ excludeFilePat = readFilePatterns();
}
- std::vector<StringRef> V;
+ std::vector<StringRef> v;
while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
- V.push_back(unquote(next()));
+ v.push_back(unquote(next()));
- if (!V.empty())
- Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
+ if (!v.empty())
+ ret.push_back({std::move(excludeFilePat), StringMatcher(v)});
else
setError("section pattern is expected");
}
- return Ret;
+ return ret;
}
// Reads contents of "SECTIONS" directive. That directive contains a
@@ -657,52 +657,52 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
//
// <section-list> is parsed by readInputSectionsList().
InputSectionDescription *
-ScriptParser::readInputSectionRules(StringRef FilePattern) {
- auto *Cmd = make<InputSectionDescription>(FilePattern);
+ScriptParser::readInputSectionRules(StringRef filePattern) {
+ auto *cmd = make<InputSectionDescription>(filePattern);
expect("(");
while (!errorCount() && !consume(")")) {
- SortSectionPolicy Outer = readSortKind();
- SortSectionPolicy Inner = SortSectionPolicy::Default;
- std::vector<SectionPattern> V;
- if (Outer != SortSectionPolicy::Default) {
+ SortSectionPolicy outer = readSortKind();
+ SortSectionPolicy inner = SortSectionPolicy::Default;
+ std::vector<SectionPattern> v;
+ if (outer != SortSectionPolicy::Default) {
expect("(");
- Inner = readSortKind();
- if (Inner != SortSectionPolicy::Default) {
+ inner = readSortKind();
+ if (inner != SortSectionPolicy::Default) {
expect("(");
- V = readInputSectionsList();
+ v = readInputSectionsList();
expect(")");
} else {
- V = readInputSectionsList();
+ v = readInputSectionsList();
}
expect(")");
} else {
- V = readInputSectionsList();
+ v = readInputSectionsList();
}
- for (SectionPattern &Pat : V) {
- Pat.SortInner = Inner;
- Pat.SortOuter = Outer;
+ for (SectionPattern &pat : v) {
+ pat.sortInner = inner;
+ pat.sortOuter = outer;
}
- std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
+ std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
}
- return Cmd;
+ return cmd;
}
InputSectionDescription *
-ScriptParser::readInputSectionDescription(StringRef Tok) {
+ScriptParser::readInputSectionDescription(StringRef tok) {
// Input section wildcard can be surrounded by KEEP.
// https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
- if (Tok == "KEEP") {
+ if (tok == "KEEP") {
expect("(");
- StringRef FilePattern = next();
- InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
+ StringRef filePattern = next();
+ InputSectionDescription *cmd = readInputSectionRules(filePattern);
expect(")");
- Script->KeptSections.push_back(Cmd);
- return Cmd;
+ script->keptSections.push_back(cmd);
+ return cmd;
}
- return readInputSectionRules(Tok);
+ return readInputSectionRules(tok);
}
void ScriptParser::readSort() {
@@ -713,33 +713,33 @@ void ScriptParser::readSort() {
Expr ScriptParser::readAssert() {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(",");
- StringRef Msg = unquote(next());
+ StringRef msg = unquote(next());
expect(")");
return [=] {
- if (!E().getValue())
- error(Msg);
- return Script->getDot();
+ if (!e().getValue())
+ error(msg);
+ return script->getDot();
};
}
// Tries to read the special directive for an output section definition which
// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
-bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
- if (Tok1 != "(")
+bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
+ if (tok1 != "(")
return false;
- if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
+ if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY")
return false;
expect("(");
if (consume("NOLOAD")) {
- Cmd->Noload = true;
+ cmd->noload = true;
} else {
skip(); // This is "COPY", "INFO" or "OVERLAY".
- Cmd->NonAlloc = true;
+ cmd->nonAlloc = true;
}
expect(")");
return true;
@@ -756,121 +756,121 @@ bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, Stri
//
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
-void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
- if (readSectionDirective(Cmd, peek(), peek2()))
+void ScriptParser::readSectionAddressType(OutputSection *cmd) {
+ if (readSectionDirective(cmd, peek(), peek2()))
return;
- Cmd->AddrExpr = readExpr();
- if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
+ cmd->addrExpr = readExpr();
+ if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
setError("unknown section directive: " + peek2());
}
-static Expr checkAlignment(Expr E, std::string &Loc) {
+static Expr checkAlignment(Expr e, std::string &loc) {
return [=] {
- uint64_t Alignment = std::max((uint64_t)1, E().getValue());
- if (!isPowerOf2_64(Alignment)) {
- error(Loc + ": alignment must be power of 2");
+ uint64_t alignment = std::max((uint64_t)1, e().getValue());
+ if (!isPowerOf2_64(alignment)) {
+ error(loc + ": alignment must be power of 2");
return (uint64_t)1; // Return a dummy value.
}
- return Alignment;
+ return alignment;
};
}
OutputSection *ScriptParser::readOverlaySectionDescription() {
- OutputSection *Cmd =
- Script->createOutputSection(next(), getCurrentLocation());
- Cmd->InOverlay = true;
+ OutputSection *cmd =
+ script->createOutputSection(next(), getCurrentLocation());
+ cmd->inOverlay = true;
expect("{");
while (!errorCount() && !consume("}"))
- Cmd->SectionCommands.push_back(readInputSectionRules(next()));
- Cmd->Phdrs = readOutputSectionPhdrs();
- return Cmd;
+ cmd->sectionCommands.push_back(readInputSectionRules(next()));
+ cmd->phdrs = readOutputSectionPhdrs();
+ return cmd;
}
-OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
- OutputSection *Cmd =
- Script->createOutputSection(OutSec, getCurrentLocation());
+OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
+ OutputSection *cmd =
+ script->createOutputSection(outSec, getCurrentLocation());
- size_t SymbolsReferenced = Script->ReferencedSymbols.size();
+ size_t symbolsReferenced = script->referencedSymbols.size();
if (peek() != ":")
- readSectionAddressType(Cmd);
+ readSectionAddressType(cmd);
expect(":");
- std::string Location = getCurrentLocation();
+ std::string location = getCurrentLocation();
if (consume("AT"))
- Cmd->LMAExpr = readParenExpr();
+ cmd->lmaExpr = readParenExpr();
if (consume("ALIGN"))
- Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
+ cmd->alignExpr = checkAlignment(readParenExpr(), location);
if (consume("SUBALIGN"))
- Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
+ cmd->subalignExpr = checkAlignment(readParenExpr(), location);
// Parse constraints.
if (consume("ONLY_IF_RO"))
- Cmd->Constraint = ConstraintKind::ReadOnly;
+ cmd->constraint = ConstraintKind::ReadOnly;
if (consume("ONLY_IF_RW"))
- Cmd->Constraint = ConstraintKind::ReadWrite;
+ cmd->constraint = ConstraintKind::ReadWrite;
expect("{");
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == ";") {
+ StringRef tok = next();
+ if (tok == ";") {
// Empty commands are allowed. Do nothing here.
- } else if (SymbolAssignment *Assign = readAssignment(Tok)) {
- Cmd->SectionCommands.push_back(Assign);
- } else if (ByteCommand *Data = readByteCommand(Tok)) {
- Cmd->SectionCommands.push_back(Data);
- } else if (Tok == "CONSTRUCTORS") {
+ } else if (SymbolAssignment *assign = readAssignment(tok)) {
+ cmd->sectionCommands.push_back(assign);
+ } else if (ByteCommand *data = readByteCommand(tok)) {
+ cmd->sectionCommands.push_back(data);
+ } else if (tok == "CONSTRUCTORS") {
// CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
// by name. This is for very old file formats such as ECOFF/XCOFF.
// For ELF, we should ignore.
- } else if (Tok == "FILL") {
+ } else if (tok == "FILL") {
// We handle the FILL command as an alias for =fillexp section attribute,
// which is different from what GNU linkers do.
// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
- Cmd->Filler = readFill();
- } else if (Tok == "SORT") {
+ cmd->filler = readFill();
+ } else if (tok == "SORT") {
readSort();
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
} else if (peek() == "(") {
- Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
+ cmd->sectionCommands.push_back(readInputSectionDescription(tok));
} else {
// We have a file name and no input sections description. It is not a
// commonly used syntax, but still acceptable. In that case, all sections
// from the file will be included.
- auto *ISD = make<InputSectionDescription>(Tok);
- ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})});
- Cmd->SectionCommands.push_back(ISD);
+ auto *isd = make<InputSectionDescription>(tok);
+ isd->sectionPatterns.push_back({{}, StringMatcher({"*"})});
+ cmd->sectionCommands.push_back(isd);
}
}
if (consume(">"))
- Cmd->MemoryRegionName = next();
+ cmd->memoryRegionName = next();
if (consume("AT")) {
expect(">");
- Cmd->LMARegionName = next();
+ cmd->lmaRegionName = next();
}
- if (Cmd->LMAExpr && !Cmd->LMARegionName.empty())
+ if (cmd->lmaExpr && !cmd->lmaRegionName.empty())
error("section can't have both LMA and a load region");
- Cmd->Phdrs = readOutputSectionPhdrs();
+ cmd->phdrs = readOutputSectionPhdrs();
if (peek() == "=" || peek().startswith("=")) {
- InExpr = true;
+ inExpr = true;
consume("=");
- Cmd->Filler = readFill();
- InExpr = false;
+ cmd->filler = readFill();
+ inExpr = false;
}
// Consume optional comma following output section command.
consume(",");
- if (Script->ReferencedSymbols.size() > SymbolsReferenced)
- Cmd->ExpressionsUseSymbols = true;
- return Cmd;
+ if (script->referencedSymbols.size() > symbolsReferenced)
+ cmd->expressionsUseSymbols = true;
+ return cmd;
}
// Reads a `=<fillexp>` expression and returns its value as a big-endian number.
@@ -881,59 +881,59 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
// size, while ld.gold always handles it as a 32-bit big-endian number.
// We are compatible with ld.gold because it's easier to implement.
std::array<uint8_t, 4> ScriptParser::readFill() {
- uint64_t Value = readExpr()().Val;
- if (Value > UINT32_MAX)
+ uint64_t value = readExpr()().val;
+ if (value > UINT32_MAX)
setError("filler expression result does not fit 32-bit: 0x" +
- Twine::utohexstr(Value));
+ Twine::utohexstr(value));
- std::array<uint8_t, 4> Buf;
- write32be(Buf.data(), (uint32_t)Value);
- return Buf;
+ std::array<uint8_t, 4> buf;
+ write32be(buf.data(), (uint32_t)value);
+ return buf;
}
-SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
+SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
expect("(");
- SymbolAssignment *Cmd = readSymbolAssignment(next());
- Cmd->Provide = Provide;
- Cmd->Hidden = Hidden;
+ SymbolAssignment *cmd = readSymbolAssignment(next());
+ cmd->provide = provide;
+ cmd->hidden = hidden;
expect(")");
- return Cmd;
+ return cmd;
}
-SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) {
+SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
// Assert expression returns Dot, so this is equal to ".=."
- if (Tok == "ASSERT")
+ if (tok == "ASSERT")
return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
- size_t OldPos = Pos;
- SymbolAssignment *Cmd = nullptr;
+ size_t oldPos = pos;
+ SymbolAssignment *cmd = nullptr;
if (peek() == "=" || peek() == "+=")
- Cmd = readSymbolAssignment(Tok);
- else if (Tok == "PROVIDE")
- Cmd = readProvideHidden(true, false);
- else if (Tok == "HIDDEN")
- Cmd = readProvideHidden(false, true);
- else if (Tok == "PROVIDE_HIDDEN")
- Cmd = readProvideHidden(true, true);
-
- if (Cmd) {
- Cmd->CommandString =
- Tok.str() + " " +
- llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
+ cmd = readSymbolAssignment(tok);
+ else if (tok == "PROVIDE")
+ cmd = readProvideHidden(true, false);
+ else if (tok == "HIDDEN")
+ cmd = readProvideHidden(false, true);
+ else if (tok == "PROVIDE_HIDDEN")
+ cmd = readProvideHidden(true, true);
+
+ if (cmd) {
+ cmd->commandString =
+ tok.str() + " " +
+ llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
expect(";");
}
- return Cmd;
+ return cmd;
}
-SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
- StringRef Op = next();
- assert(Op == "=" || Op == "+=");
- Expr E = readExpr();
- if (Op == "+=") {
- std::string Loc = getCurrentLocation();
- E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
+SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
+ StringRef op = next();
+ assert(op == "=" || op == "+=");
+ Expr e = readExpr();
+ if (op == "+=") {
+ std::string loc = getCurrentLocation();
+ e = [=] { return add(script->getSymbolValue(name, loc), e()); };
}
- return make<SymbolAssignment>(Name, E, getCurrentLocation());
+ return make<SymbolAssignment>(name, e, getCurrentLocation());
}
// This is an operator-precedence parser to parse a linker
@@ -941,178 +941,178 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
Expr ScriptParser::readExpr() {
// Our lexer is context-aware. Set the in-expression bit so that
// they apply different tokenization rules.
- bool Orig = InExpr;
- InExpr = true;
- Expr E = readExpr1(readPrimary(), 0);
- InExpr = Orig;
- return E;
-}
-
-Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
- if (Op == "+")
- return [=] { return add(L(), R()); };
- if (Op == "-")
- return [=] { return sub(L(), R()); };
- if (Op == "*")
- return [=] { return L().getValue() * R().getValue(); };
- if (Op == "/") {
- std::string Loc = getCurrentLocation();
+ bool orig = inExpr;
+ inExpr = true;
+ Expr e = readExpr1(readPrimary(), 0);
+ inExpr = orig;
+ return e;
+}
+
+Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
+ if (op == "+")
+ return [=] { return add(l(), r()); };
+ if (op == "-")
+ return [=] { return sub(l(), r()); };
+ if (op == "*")
+ return [=] { return l().getValue() * r().getValue(); };
+ if (op == "/") {
+ std::string loc = getCurrentLocation();
return [=]() -> uint64_t {
- if (uint64_t RV = R().getValue())
- return L().getValue() / RV;
- error(Loc + ": division by zero");
+ if (uint64_t rv = r().getValue())
+ return l().getValue() / rv;
+ error(loc + ": division by zero");
return 0;
};
}
- if (Op == "%") {
- std::string Loc = getCurrentLocation();
+ if (op == "%") {
+ std::string loc = getCurrentLocation();
return [=]() -> uint64_t {
- if (uint64_t RV = R().getValue())
- return L().getValue() % RV;
- error(Loc + ": modulo by zero");
+ if (uint64_t rv = r().getValue())
+ return l().getValue() % rv;
+ error(loc + ": modulo by zero");
return 0;
};
}
- if (Op == "<<")
- return [=] { return L().getValue() << R().getValue(); };
- if (Op == ">>")
- return [=] { return L().getValue() >> R().getValue(); };
- if (Op == "<")
- return [=] { return L().getValue() < R().getValue(); };
- if (Op == ">")
- return [=] { return L().getValue() > R().getValue(); };
- if (Op == ">=")
- return [=] { return L().getValue() >= R().getValue(); };
- if (Op == "<=")
- return [=] { return L().getValue() <= R().getValue(); };
- if (Op == "==")
- return [=] { return L().getValue() == R().getValue(); };
- if (Op == "!=")
- return [=] { return L().getValue() != R().getValue(); };
- if (Op == "||")
- return [=] { return L().getValue() || R().getValue(); };
- if (Op == "&&")
- return [=] { return L().getValue() && R().getValue(); };
- if (Op == "&")
- return [=] { return bitAnd(L(), R()); };
- if (Op == "|")
- return [=] { return bitOr(L(), R()); };
+ if (op == "<<")
+ return [=] { return l().getValue() << r().getValue(); };
+ if (op == ">>")
+ return [=] { return l().getValue() >> r().getValue(); };
+ if (op == "<")
+ return [=] { return l().getValue() < r().getValue(); };
+ if (op == ">")
+ return [=] { return l().getValue() > r().getValue(); };
+ if (op == ">=")
+ return [=] { return l().getValue() >= r().getValue(); };
+ if (op == "<=")
+ return [=] { return l().getValue() <= r().getValue(); };
+ if (op == "==")
+ return [=] { return l().getValue() == r().getValue(); };
+ if (op == "!=")
+ return [=] { return l().getValue() != r().getValue(); };
+ if (op == "||")
+ return [=] { return l().getValue() || r().getValue(); };
+ if (op == "&&")
+ return [=] { return l().getValue() && r().getValue(); };
+ if (op == "&")
+ return [=] { return bitAnd(l(), r()); };
+ if (op == "|")
+ return [=] { return bitOr(l(), r()); };
llvm_unreachable("invalid operator");
}
// This is a part of the operator-precedence parser. This function
// assumes that the remaining token stream starts with an operator.
-Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
+Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
while (!atEOF() && !errorCount()) {
// Read an operator and an expression.
if (consume("?"))
- return readTernary(Lhs);
- StringRef Op1 = peek();
- if (precedence(Op1) < MinPrec)
+ return readTernary(lhs);
+ StringRef op1 = peek();
+ if (precedence(op1) < minPrec)
break;
skip();
- Expr Rhs = readPrimary();
+ Expr rhs = readPrimary();
// Evaluate the remaining part of the expression first if the
// next operator has greater precedence than the previous one.
// For example, if we have read "+" and "3", and if the next
// operator is "*", then we'll evaluate 3 * ... part first.
while (!atEOF()) {
- StringRef Op2 = peek();
- if (precedence(Op2) <= precedence(Op1))
+ StringRef op2 = peek();
+ if (precedence(op2) <= precedence(op1))
break;
- Rhs = readExpr1(Rhs, precedence(Op2));
+ rhs = readExpr1(rhs, precedence(op2));
}
- Lhs = combine(Op1, Lhs, Rhs);
+ lhs = combine(op1, lhs, rhs);
}
- return Lhs;
+ return lhs;
}
Expr ScriptParser::getPageSize() {
- std::string Location = getCurrentLocation();
+ std::string location = getCurrentLocation();
return [=]() -> uint64_t {
- if (Target)
- return Config->CommonPageSize;
- error(Location + ": unable to calculate page size");
+ if (target)
+ return config->commonPageSize;
+ error(location + ": unable to calculate page size");
return 4096; // Return a dummy value.
};
}
Expr ScriptParser::readConstant() {
- StringRef S = readParenLiteral();
- if (S == "COMMONPAGESIZE")
+ StringRef s = readParenLiteral();
+ if (s == "COMMONPAGESIZE")
return getPageSize();
- if (S == "MAXPAGESIZE")
- return [] { return Config->MaxPageSize; };
- setError("unknown constant: " + S);
+ if (s == "MAXPAGESIZE")
+ return [] { return config->maxPageSize; };
+ setError("unknown constant: " + s);
return [] { return 0; };
}
// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
// have "K" (Ki) or "M" (Mi) suffixes.
-static Optional<uint64_t> parseInt(StringRef Tok) {
+static Optional<uint64_t> parseInt(StringRef tok) {
// Hexadecimal
- uint64_t Val;
- if (Tok.startswith_lower("0x")) {
- if (!to_integer(Tok.substr(2), Val, 16))
+ uint64_t val;
+ if (tok.startswith_lower("0x")) {
+ if (!to_integer(tok.substr(2), val, 16))
return None;
- return Val;
+ return val;
}
- if (Tok.endswith_lower("H")) {
- if (!to_integer(Tok.drop_back(), Val, 16))
+ if (tok.endswith_lower("H")) {
+ if (!to_integer(tok.drop_back(), val, 16))
return None;
- return Val;
+ return val;
}
// Decimal
- if (Tok.endswith_lower("K")) {
- if (!to_integer(Tok.drop_back(), Val, 10))
+ if (tok.endswith_lower("K")) {
+ if (!to_integer(tok.drop_back(), val, 10))
return None;
- return Val * 1024;
+ return val * 1024;
}
- if (Tok.endswith_lower("M")) {
- if (!to_integer(Tok.drop_back(), Val, 10))
+ if (tok.endswith_lower("M")) {
+ if (!to_integer(tok.drop_back(), val, 10))
return None;
- return Val * 1024 * 1024;
+ return val * 1024 * 1024;
}
- if (!to_integer(Tok, Val, 10))
+ if (!to_integer(tok, val, 10))
return None;
- return Val;
+ return val;
}
-ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
- int Size = StringSwitch<int>(Tok)
+ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
+ int size = StringSwitch<int>(tok)
.Case("BYTE", 1)
.Case("SHORT", 2)
.Case("LONG", 4)
.Case("QUAD", 8)
.Default(-1);
- if (Size == -1)
+ if (size == -1)
return nullptr;
- size_t OldPos = Pos;
- Expr E = readParenExpr();
- std::string CommandString =
- Tok.str() + " " +
- llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
- return make<ByteCommand>(E, Size, CommandString);
+ size_t oldPos = pos;
+ Expr e = readParenExpr();
+ std::string commandString =
+ tok.str() + " " +
+ llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
+ return make<ByteCommand>(e, size, commandString);
}
StringRef ScriptParser::readParenLiteral() {
expect("(");
- bool Orig = InExpr;
- InExpr = false;
- StringRef Tok = next();
- InExpr = Orig;
+ bool orig = inExpr;
+ inExpr = false;
+ StringRef tok = next();
+ inExpr = orig;
expect(")");
- return Tok;
+ return tok;
}
-static void checkIfExists(OutputSection *Cmd, StringRef Location) {
- if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
- error(Location + ": undefined section " + Cmd->Name);
+static void checkIfExists(OutputSection *cmd, StringRef location) {
+ if (cmd->location.empty() && script->errorOnMissingSection)
+ error(location + ": undefined section " + cmd->name);
}
Expr ScriptParser::readPrimary() {
@@ -1120,85 +1120,85 @@ Expr ScriptParser::readPrimary() {
return readParenExpr();
if (consume("~")) {
- Expr E = readPrimary();
- return [=] { return ~E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return ~e().getValue(); };
}
if (consume("!")) {
- Expr E = readPrimary();
- return [=] { return !E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return !e().getValue(); };
}
if (consume("-")) {
- Expr E = readPrimary();
- return [=] { return -E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return -e().getValue(); };
}
- StringRef Tok = next();
- std::string Location = getCurrentLocation();
+ StringRef tok = next();
+ std::string location = getCurrentLocation();
// Built-in functions are parsed here.
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
- if (Tok == "ABSOLUTE") {
- Expr Inner = readParenExpr();
+ if (tok == "ABSOLUTE") {
+ Expr inner = readParenExpr();
return [=] {
- ExprValue I = Inner();
- I.ForceAbsolute = true;
- return I;
+ ExprValue i = inner();
+ i.forceAbsolute = true;
+ return i;
};
}
- if (Tok == "ADDR") {
- StringRef Name = readParenLiteral();
- OutputSection *Sec = Script->getOrCreateOutputSection(Name);
- Sec->UsedInExpression = true;
+ if (tok == "ADDR") {
+ StringRef name = readParenLiteral();
+ OutputSection *sec = script->getOrCreateOutputSection(name);
+ sec->usedInExpression = true;
return [=]() -> ExprValue {
- checkIfExists(Sec, Location);
- return {Sec, false, 0, Location};
+ checkIfExists(sec, location);
+ return {sec, false, 0, location};
};
}
- if (Tok == "ALIGN") {
+ if (tok == "ALIGN") {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
if (consume(")")) {
- E = checkAlignment(E, Location);
- return [=] { return alignTo(Script->getDot(), E().getValue()); };
+ e = checkAlignment(e, location);
+ return [=] { return alignTo(script->getDot(), e().getValue()); };
}
expect(",");
- Expr E2 = checkAlignment(readExpr(), Location);
+ Expr e2 = checkAlignment(readExpr(), location);
expect(")");
return [=] {
- ExprValue V = E();
- V.Alignment = E2().getValue();
- return V;
+ ExprValue v = e();
+ v.alignment = e2().getValue();
+ return v;
};
}
- if (Tok == "ALIGNOF") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
+ if (tok == "ALIGNOF") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
return [=] {
- checkIfExists(Cmd, Location);
- return Cmd->Alignment;
+ checkIfExists(cmd, location);
+ return cmd->alignment;
};
}
- if (Tok == "ASSERT")
+ if (tok == "ASSERT")
return readAssert();
- if (Tok == "CONSTANT")
+ if (tok == "CONSTANT")
return readConstant();
- if (Tok == "DATA_SEGMENT_ALIGN") {
+ if (tok == "DATA_SEGMENT_ALIGN") {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(",");
readExpr();
expect(")");
return [=] {
- return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
+ return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue()));
};
}
- if (Tok == "DATA_SEGMENT_END") {
+ if (tok == "DATA_SEGMENT_END") {
expect("(");
expect(".");
expect(")");
- return [] { return Script->getDot(); };
+ return [] { return script->getDot(); };
}
- if (Tok == "DATA_SEGMENT_RELRO_END") {
+ if (tok == "DATA_SEGMENT_RELRO_END") {
// GNU linkers implements more complicated logic to handle
// DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
// just align to the next page boundary for simplicity.
@@ -1207,113 +1207,113 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- Expr E = getPageSize();
- return [=] { return alignTo(Script->getDot(), E().getValue()); };
+ Expr e = getPageSize();
+ return [=] { return alignTo(script->getDot(), e().getValue()); };
}
- if (Tok == "DEFINED") {
- StringRef Name = readParenLiteral();
- return [=] { return Symtab->find(Name) ? 1 : 0; };
+ if (tok == "DEFINED") {
+ StringRef name = readParenLiteral();
+ return [=] { return symtab->find(name) ? 1 : 0; };
}
- if (Tok == "LENGTH") {
- StringRef Name = readParenLiteral();
- if (Script->MemoryRegions.count(Name) == 0) {
- setError("memory region not defined: " + Name);
+ if (tok == "LENGTH") {
+ StringRef name = readParenLiteral();
+ if (script->memoryRegions.count(name) == 0) {
+ setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return Script->MemoryRegions[Name]->Length; };
+ return [=] { return script->memoryRegions[name]->length; };
}
- if (Tok == "LOADADDR") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
- Cmd->UsedInExpression = true;
+ if (tok == "LOADADDR") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
+ cmd->usedInExpression = true;
return [=] {
- checkIfExists(Cmd, Location);
- return Cmd->getLMA();
+ checkIfExists(cmd, location);
+ return cmd->getLMA();
};
}
- if (Tok == "MAX" || Tok == "MIN") {
+ if (tok == "MAX" || tok == "MIN") {
expect("(");
- Expr A = readExpr();
+ Expr a = readExpr();
expect(",");
- Expr B = readExpr();
+ Expr b = readExpr();
expect(")");
- if (Tok == "MIN")
- return [=] { return std::min(A().getValue(), B().getValue()); };
- return [=] { return std::max(A().getValue(), B().getValue()); };
+ if (tok == "MIN")
+ return [=] { return std::min(a().getValue(), b().getValue()); };
+ return [=] { return std::max(a().getValue(), b().getValue()); };
}
- if (Tok == "ORIGIN") {
- StringRef Name = readParenLiteral();
- if (Script->MemoryRegions.count(Name) == 0) {
- setError("memory region not defined: " + Name);
+ if (tok == "ORIGIN") {
+ StringRef name = readParenLiteral();
+ if (script->memoryRegions.count(name) == 0) {
+ setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return Script->MemoryRegions[Name]->Origin; };
+ return [=] { return script->memoryRegions[name]->origin; };
}
- if (Tok == "SEGMENT_START") {
+ if (tok == "SEGMENT_START") {
expect("(");
skip();
expect(",");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(")");
- return [=] { return E(); };
+ return [=] { return e(); };
}
- if (Tok == "SIZEOF") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
+ if (tok == "SIZEOF") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
// Linker script does not create an output section if its content is empty.
// We want to allow SIZEOF(.foo) where .foo is a section which happened to
// be empty.
- return [=] { return Cmd->Size; };
+ return [=] { return cmd->size; };
}
- if (Tok == "SIZEOF_HEADERS")
+ if (tok == "SIZEOF_HEADERS")
return [=] { return elf::getHeaderSize(); };
// Tok is the dot.
- if (Tok == ".")
- return [=] { return Script->getSymbolValue(Tok, Location); };
+ if (tok == ".")
+ return [=] { return script->getSymbolValue(tok, location); };
// Tok is a literal number.
- if (Optional<uint64_t> Val = parseInt(Tok))
- return [=] { return *Val; };
+ if (Optional<uint64_t> val = parseInt(tok))
+ return [=] { return *val; };
// Tok is a symbol name.
- if (!isValidCIdentifier(Tok))
- setError("malformed number: " + Tok);
- Script->ReferencedSymbols.push_back(Tok);
- return [=] { return Script->getSymbolValue(Tok, Location); };
+ if (!isValidCIdentifier(tok))
+ setError("malformed number: " + tok);
+ script->referencedSymbols.push_back(tok);
+ return [=] { return script->getSymbolValue(tok, location); };
}
-Expr ScriptParser::readTernary(Expr Cond) {
- Expr L = readExpr();
+Expr ScriptParser::readTernary(Expr cond) {
+ Expr l = readExpr();
expect(":");
- Expr R = readExpr();
- return [=] { return Cond().getValue() ? L() : R(); };
+ Expr r = readExpr();
+ return [=] { return cond().getValue() ? l() : r(); };
}
Expr ScriptParser::readParenExpr() {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(")");
- return E;
+ return e;
}
std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
- std::vector<StringRef> Phdrs;
+ std::vector<StringRef> phdrs;
while (!errorCount() && peek().startswith(":")) {
- StringRef Tok = next();
- Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
+ StringRef tok = next();
+ phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
}
- return Phdrs;
+ return phdrs;
}
// Read a program header type name. The next token must be a
// name of a program header type or a constant (e.g. "0x3").
unsigned ScriptParser::readPhdrType() {
- StringRef Tok = next();
- if (Optional<uint64_t> Val = parseInt(Tok))
- return *Val;
+ StringRef tok = next();
+ if (Optional<uint64_t> val = parseInt(tok))
+ return *val;
- unsigned Ret = StringSwitch<unsigned>(Tok)
+ unsigned ret = StringSwitch<unsigned>(tok)
.Case("PT_NULL", PT_NULL)
.Case("PT_LOAD", PT_LOAD)
.Case("PT_DYNAMIC", PT_DYNAMIC)
@@ -1330,56 +1330,56 @@ unsigned ScriptParser::readPhdrType() {
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
.Default(-1);
- if (Ret == (unsigned)-1) {
- setError("invalid program header type: " + Tok);
+ if (ret == (unsigned)-1) {
+ setError("invalid program header type: " + tok);
return PT_NULL;
}
- return Ret;
+ return ret;
}
// Reads an anonymous version declaration.
void ScriptParser::readAnonymousDeclaration() {
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
- for (SymbolVersion V : Locals) {
- if (V.Name == "*")
- Config->DefaultSymbolVersion = VER_NDX_LOCAL;
+ for (SymbolVersion v : locals) {
+ if (v.name == "*")
+ config->defaultSymbolVersion = VER_NDX_LOCAL;
else
- Config->VersionScriptLocals.push_back(V);
+ config->versionScriptLocals.push_back(v);
}
- for (SymbolVersion V : Globals)
- Config->VersionScriptGlobals.push_back(V);
+ for (SymbolVersion v : globals)
+ config->versionScriptGlobals.push_back(v);
expect(";");
}
// Reads a non-anonymous version definition,
// e.g. "VerStr { global: foo; bar; local: *; };".
-void ScriptParser::readVersionDeclaration(StringRef VerStr) {
+void ScriptParser::readVersionDeclaration(StringRef verStr) {
// Read a symbol list.
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
- for (SymbolVersion V : Locals) {
- if (V.Name == "*")
- Config->DefaultSymbolVersion = VER_NDX_LOCAL;
+ for (SymbolVersion v : locals) {
+ if (v.name == "*")
+ config->defaultSymbolVersion = VER_NDX_LOCAL;
else
- Config->VersionScriptLocals.push_back(V);
+ config->versionScriptLocals.push_back(v);
}
// Create a new version definition and add that to the global symbols.
- VersionDefinition Ver;
- Ver.Name = VerStr;
- Ver.Globals = Globals;
+ VersionDefinition ver;
+ ver.name = verStr;
+ ver.globals = globals;
// User-defined version number starts from 2 because 0 and 1 are
// reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
- Ver.Id = Config->VersionDefinitions.size() + 2;
- Config->VersionDefinitions.push_back(Ver);
+ ver.id = config->versionDefinitions.size() + 2;
+ config->versionDefinitions.push_back(ver);
// Each version may have a parent version. For example, "Ver2"
// defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
@@ -1391,39 +1391,39 @@ void ScriptParser::readVersionDeclaration(StringRef VerStr) {
expect(";");
}
-static bool hasWildcard(StringRef S) {
- return S.find_first_of("?*[") != StringRef::npos;
+static bool hasWildcard(StringRef s) {
+ return s.find_first_of("?*[") != StringRef::npos;
}
// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
ScriptParser::readSymbols() {
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::vector<SymbolVersion> *V = &Globals;
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::vector<SymbolVersion> *v = &globals;
while (!errorCount()) {
if (consume("}"))
break;
if (consumeLabel("local")) {
- V = &Locals;
+ v = &locals;
continue;
}
if (consumeLabel("global")) {
- V = &Globals;
+ v = &globals;
continue;
}
if (consume("extern")) {
- std::vector<SymbolVersion> Ext = readVersionExtern();
- V->insert(V->end(), Ext.begin(), Ext.end());
+ std::vector<SymbolVersion> ext = readVersionExtern();
+ v->insert(v->end(), ext.begin(), ext.end());
} else {
- StringRef Tok = next();
- V->push_back({unquote(Tok), false, hasWildcard(Tok)});
+ StringRef tok = next();
+ v->push_back({unquote(tok), false, hasWildcard(tok)});
}
expect(";");
}
- return {Locals, Globals};
+ return {locals, globals};
}
// Reads an "extern C++" directive, e.g.,
@@ -1432,30 +1432,30 @@ ScriptParser::readSymbols() {
// The last semicolon is optional. E.g. this is OK:
// "extern "C++" { ns::*; "f(int, double)" };"
std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
- StringRef Tok = next();
- bool IsCXX = Tok == "\"C++\"";
- if (!IsCXX && Tok != "\"C\"")
+ StringRef tok = next();
+ bool isCXX = tok == "\"C++\"";
+ if (!isCXX && tok != "\"C\"")
setError("Unknown language");
expect("{");
- std::vector<SymbolVersion> Ret;
+ std::vector<SymbolVersion> ret;
while (!errorCount() && peek() != "}") {
- StringRef Tok = next();
- Ret.push_back(
- {unquote(Tok), IsCXX, !Tok.startswith("\"") && hasWildcard(Tok)});
+ StringRef tok = next();
+ ret.push_back(
+ {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
if (consume("}"))
- return Ret;
+ return ret;
expect(";");
}
expect("}");
- return Ret;
+ return ret;
}
-uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
- StringRef S3) {
- if (!consume(S1) && !consume(S2) && !consume(S3)) {
- setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
+uint64_t ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
+ StringRef s3) {
+ if (!consume(s1) && !consume(s2) && !consume(s3)) {
+ setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
return 0;
}
expect("=");
@@ -1469,28 +1469,28 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
void ScriptParser::readMemory() {
expect("{");
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == "INCLUDE") {
+ StringRef tok = next();
+ if (tok == "INCLUDE") {
readInclude();
continue;
}
- uint32_t Flags = 0;
- uint32_t NegFlags = 0;
+ uint32_t flags = 0;
+ uint32_t negFlags = 0;
if (consume("(")) {
- std::tie(Flags, NegFlags) = readMemoryAttributes();
+ std::tie(flags, negFlags) = readMemoryAttributes();
expect(")");
}
expect(":");
- uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
+ uint64_t origin = readMemoryAssignment("ORIGIN", "org", "o");
expect(",");
- uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
+ uint64_t length = readMemoryAssignment("LENGTH", "len", "l");
// Add the memory region to the region map.
- MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
- if (!Script->MemoryRegions.insert({Tok, MR}).second)
- setError("region '" + Tok + "' already defined");
+ MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags);
+ if (!script->memoryRegions.insert({tok, mr}).second)
+ setError("region '" + tok + "' already defined");
}
}
@@ -1498,43 +1498,43 @@ void ScriptParser::readMemory() {
// flags when placing output sections in a memory region. These flags
// are only used when an explicit memory region name is not used.
std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
- uint32_t Flags = 0;
- uint32_t NegFlags = 0;
- bool Invert = false;
-
- for (char C : next().lower()) {
- uint32_t Flag = 0;
- if (C == '!')
- Invert = !Invert;
- else if (C == 'w')
- Flag = SHF_WRITE;
- else if (C == 'x')
- Flag = SHF_EXECINSTR;
- else if (C == 'a')
- Flag = SHF_ALLOC;
- else if (C != 'r')
+ uint32_t flags = 0;
+ uint32_t negFlags = 0;
+ bool invert = false;
+
+ for (char c : next().lower()) {
+ uint32_t flag = 0;
+ if (c == '!')
+ invert = !invert;
+ else if (c == 'w')
+ flag = SHF_WRITE;
+ else if (c == 'x')
+ flag = SHF_EXECINSTR;
+ else if (c == 'a')
+ flag = SHF_ALLOC;
+ else if (c != 'r')
setError("invalid memory region attribute");
- if (Invert)
- NegFlags |= Flag;
+ if (invert)
+ negFlags |= flag;
else
- Flags |= Flag;
+ flags |= flag;
}
- return {Flags, NegFlags};
+ return {flags, negFlags};
}
-void elf::readLinkerScript(MemoryBufferRef MB) {
- ScriptParser(MB).readLinkerScript();
+void elf::readLinkerScript(MemoryBufferRef mb) {
+ ScriptParser(mb).readLinkerScript();
}
-void elf::readVersionScript(MemoryBufferRef MB) {
- ScriptParser(MB).readVersionScript();
+void elf::readVersionScript(MemoryBufferRef mb) {
+ ScriptParser(mb).readVersionScript();
}
-void elf::readDynamicList(MemoryBufferRef MB) {
- ScriptParser(MB).readDynamicList();
+void elf::readDynamicList(MemoryBufferRef mb) {
+ ScriptParser(mb).readDynamicList();
}
-void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
- ScriptParser(MB).readDefsym(Name);
+void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
+ ScriptParser(mb).readDefsym(name);
}
diff --git a/lld/ELF/ScriptParser.h b/lld/ELF/ScriptParser.h
index bc578ac7028..110684761c7 100644
--- a/lld/ELF/ScriptParser.h
+++ b/lld/ELF/ScriptParser.h
@@ -17,15 +17,15 @@ namespace elf {
// Parses a linker script. Calling this function updates
// Config and ScriptConfig.
-void readLinkerScript(MemoryBufferRef MB);
+void readLinkerScript(MemoryBufferRef mb);
// Parses a version script.
-void readVersionScript(MemoryBufferRef MB);
+void readVersionScript(MemoryBufferRef mb);
-void readDynamicList(MemoryBufferRef MB);
+void readDynamicList(MemoryBufferRef mb);
// Parses the defsym expression.
-void readDefsym(StringRef Name, MemoryBufferRef MB);
+void readDefsym(StringRef name, MemoryBufferRef mb);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index cf83e907a73..0fd0eab9bda 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -30,73 +30,73 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-SymbolTable *elf::Symtab;
+SymbolTable *elf::symtab;
-void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
+void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Swap symbols as instructed by -wrap.
- int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
- int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
- int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
+ int &idx1 = symMap[CachedHashStringRef(sym->getName())];
+ int &idx2 = symMap[CachedHashStringRef(real->getName())];
+ int &idx3 = symMap[CachedHashStringRef(wrap->getName())];
- Idx2 = Idx1;
- Idx1 = Idx3;
+ idx2 = idx1;
+ idx1 = idx3;
// Now renaming is complete. No one refers Real symbol. We could leave
// Real as-is, but if Real is written to the symbol table, that may
// contain irrelevant values. So, we copy all values from Sym to Real.
- StringRef S = Real->getName();
- memcpy(Real, Sym, sizeof(SymbolUnion));
- Real->setName(S);
+ StringRef s = real->getName();
+ memcpy(real, sym, sizeof(SymbolUnion));
+ real->setName(s);
}
// Find an existing symbol or create a new one.
-Symbol *SymbolTable::insert(StringRef Name) {
+Symbol *SymbolTable::insert(StringRef name) {
// <name>@@<version> means the symbol is the default version. In that
// case <name>@@<version> will be used to resolve references to <name>.
//
// Since this is a hot path, the following string search code is
// optimized for speed. StringRef::find(char) is much faster than
// StringRef::find(StringRef).
- size_t Pos = Name.find('@');
- if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
- Name = Name.take_front(Pos);
-
- auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
- int &SymIndex = P.first->second;
- bool IsNew = P.second;
-
- if (!IsNew)
- return SymVector[SymIndex];
-
- Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- SymVector.push_back(Sym);
-
- Sym->setName(Name);
- Sym->SymbolKind = Symbol::PlaceholderKind;
- Sym->VersionId = Config->DefaultSymbolVersion;
- Sym->Visibility = STV_DEFAULT;
- Sym->IsUsedInRegularObj = false;
- Sym->ExportDynamic = false;
- Sym->CanInline = true;
- Sym->ScriptDefined = false;
- Sym->Partition = 1;
- return Sym;
+ size_t pos = name.find('@');
+ if (pos != StringRef::npos && pos + 1 < name.size() && name[pos + 1] == '@')
+ name = name.take_front(pos);
+
+ auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
+ int &symIndex = p.first->second;
+ bool isNew = p.second;
+
+ if (!isNew)
+ return symVector[symIndex];
+
+ Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ symVector.push_back(sym);
+
+ sym->setName(name);
+ sym->symbolKind = Symbol::PlaceholderKind;
+ sym->versionId = config->defaultSymbolVersion;
+ sym->visibility = STV_DEFAULT;
+ sym->isUsedInRegularObj = false;
+ sym->exportDynamic = false;
+ sym->canInline = true;
+ sym->scriptDefined = false;
+ sym->partition = 1;
+ return sym;
}
Symbol *SymbolTable::addSymbol(const Symbol &New) {
- Symbol *Sym = Symtab->insert(New.getName());
- Sym->resolve(New);
- return Sym;
+ Symbol *sym = symtab->insert(New.getName());
+ sym->resolve(New);
+ return sym;
}
-Symbol *SymbolTable::find(StringRef Name) {
- auto It = SymMap.find(CachedHashStringRef(Name));
- if (It == SymMap.end())
+Symbol *SymbolTable::find(StringRef name) {
+ auto it = symMap.find(CachedHashStringRef(name));
+ if (it == symMap.end())
return nullptr;
- Symbol *Sym = SymVector[It->second];
- if (Sym->isPlaceholder())
+ Symbol *sym = symVector[it->second];
+ if (sym->isPlaceholder())
return nullptr;
- return Sym;
+ return sym;
}
// Initialize DemangledSyms with a map from demangled symbols to symbol
@@ -113,119 +113,119 @@ Symbol *SymbolTable::find(StringRef Name) {
// So, if "extern C++" feature is used, we need to demangle all known
// symbols.
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
- if (!DemangledSyms) {
- DemangledSyms.emplace();
- for (Symbol *Sym : SymVector) {
- if (!Sym->isDefined() && !Sym->isCommon())
+ if (!demangledSyms) {
+ demangledSyms.emplace();
+ for (Symbol *sym : symVector) {
+ if (!sym->isDefined() && !sym->isCommon())
continue;
- if (Optional<std::string> S = demangleItanium(Sym->getName()))
- (*DemangledSyms)[*S].push_back(Sym);
+ if (Optional<std::string> s = demangleItanium(sym->getName()))
+ (*demangledSyms)[*s].push_back(sym);
else
- (*DemangledSyms)[Sym->getName()].push_back(Sym);
+ (*demangledSyms)[sym->getName()].push_back(sym);
}
}
- return *DemangledSyms;
+ return *demangledSyms;
}
-std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
- if (Ver.IsExternCpp)
- return getDemangledSyms().lookup(Ver.Name);
- if (Symbol *B = find(Ver.Name))
- if (B->isDefined() || B->isCommon())
- return {B};
+std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
+ if (ver.isExternCpp)
+ return getDemangledSyms().lookup(ver.name);
+ if (Symbol *b = find(ver.name))
+ if (b->isDefined() || b->isCommon())
+ return {b};
return {};
}
-std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
- std::vector<Symbol *> Res;
- StringMatcher M(Ver.Name);
+std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver) {
+ std::vector<Symbol *> res;
+ StringMatcher m(ver.name);
- if (Ver.IsExternCpp) {
- for (auto &P : getDemangledSyms())
- if (M.match(P.first()))
- Res.insert(Res.end(), P.second.begin(), P.second.end());
- return Res;
+ if (ver.isExternCpp) {
+ for (auto &p : getDemangledSyms())
+ if (m.match(p.first()))
+ res.insert(res.end(), p.second.begin(), p.second.end());
+ return res;
}
- for (Symbol *Sym : SymVector)
- if ((Sym->isDefined() || Sym->isCommon()) && M.match(Sym->getName()))
- Res.push_back(Sym);
- return Res;
+ for (Symbol *sym : symVector)
+ if ((sym->isDefined() || sym->isCommon()) && m.match(sym->getName()))
+ res.push_back(sym);
+ return res;
}
// If there's only one anonymous version definition in a version
// script file, the script does not actually define any symbol version,
// but just specifies symbols visibilities.
void SymbolTable::handleAnonymousVersion() {
- for (SymbolVersion &Ver : Config->VersionScriptGlobals)
- assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
- for (SymbolVersion &Ver : Config->VersionScriptGlobals)
- assignWildcardVersion(Ver, VER_NDX_GLOBAL);
- for (SymbolVersion &Ver : Config->VersionScriptLocals)
- assignExactVersion(Ver, VER_NDX_LOCAL, "local");
- for (SymbolVersion &Ver : Config->VersionScriptLocals)
- assignWildcardVersion(Ver, VER_NDX_LOCAL);
+ for (SymbolVersion &ver : config->versionScriptGlobals)
+ assignExactVersion(ver, VER_NDX_GLOBAL, "global");
+ for (SymbolVersion &ver : config->versionScriptGlobals)
+ assignWildcardVersion(ver, VER_NDX_GLOBAL);
+ for (SymbolVersion &ver : config->versionScriptLocals)
+ assignExactVersion(ver, VER_NDX_LOCAL, "local");
+ for (SymbolVersion &ver : config->versionScriptLocals)
+ assignWildcardVersion(ver, VER_NDX_LOCAL);
}
// Handles -dynamic-list.
void SymbolTable::handleDynamicList() {
- for (SymbolVersion &Ver : Config->DynamicList) {
- std::vector<Symbol *> Syms;
- if (Ver.HasWildcard)
- Syms = findAllByVersion(Ver);
+ for (SymbolVersion &ver : config->dynamicList) {
+ std::vector<Symbol *> syms;
+ if (ver.hasWildcard)
+ syms = findAllByVersion(ver);
else
- Syms = findByVersion(Ver);
+ syms = findByVersion(ver);
- for (Symbol *B : Syms) {
- if (!Config->Shared)
- B->ExportDynamic = true;
- else if (B->includeInDynsym())
- B->IsPreemptible = true;
+ for (Symbol *b : syms) {
+ if (!config->shared)
+ b->exportDynamic = true;
+ else if (b->includeInDynsym())
+ b->isPreemptible = true;
}
}
}
// Set symbol versions to symbols. This function handles patterns
// containing no wildcard characters.
-void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
- StringRef VersionName) {
- if (Ver.HasWildcard)
+void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
+ StringRef versionName) {
+ if (ver.hasWildcard)
return;
// Get a list of symbols which we need to assign the version to.
- std::vector<Symbol *> Syms = findByVersion(Ver);
- if (Syms.empty()) {
- if (!Config->UndefinedVersion)
- error("version script assignment of '" + VersionName + "' to symbol '" +
- Ver.Name + "' failed: symbol not defined");
+ std::vector<Symbol *> syms = findByVersion(ver);
+ if (syms.empty()) {
+ if (!config->undefinedVersion)
+ error("version script assignment of '" + versionName + "' to symbol '" +
+ ver.name + "' failed: symbol not defined");
return;
}
// Assign the version.
- for (Symbol *Sym : Syms) {
+ for (Symbol *sym : syms) {
// Skip symbols containing version info because symbol versions
// specified by symbol names take precedence over version scripts.
// See parseSymbolVersion().
- if (Sym->getName().contains('@'))
+ if (sym->getName().contains('@'))
continue;
- if (Sym->VersionId != Config->DefaultSymbolVersion &&
- Sym->VersionId != VersionId)
- error("duplicate symbol '" + Ver.Name + "' in version script");
- Sym->VersionId = VersionId;
+ if (sym->versionId != config->defaultSymbolVersion &&
+ sym->versionId != versionId)
+ error("duplicate symbol '" + ver.name + "' in version script");
+ sym->versionId = versionId;
}
}
-void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
- if (!Ver.HasWildcard)
+void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
+ if (!ver.hasWildcard)
return;
// Exact matching takes precendence over fuzzy matching,
// so we set a version to a symbol only if no version has been assigned
// to the symbol. This behavior is compatible with GNU.
- for (Symbol *B : findAllByVersion(Ver))
- if (B->VersionId == Config->DefaultSymbolVersion)
- B->VersionId = VersionId;
+ for (Symbol *b : findAllByVersion(ver))
+ if (b->versionId == config->defaultSymbolVersion)
+ b->versionId = versionId;
}
// This function processes version scripts by updating VersionId
@@ -241,21 +241,21 @@ void SymbolTable::scanVersionScript() {
// First, we assign versions to exact matching symbols,
// i.e. version definitions not containing any glob meta-characters.
- for (VersionDefinition &V : Config->VersionDefinitions)
- for (SymbolVersion &Ver : V.Globals)
- assignExactVersion(Ver, V.Id, V.Name);
+ for (VersionDefinition &v : config->versionDefinitions)
+ for (SymbolVersion &ver : v.globals)
+ assignExactVersion(ver, v.id, v.name);
// Next, we assign versions to fuzzy matching symbols,
// i.e. version definitions containing glob meta-characters.
// Note that because the last match takes precedence over previous matches,
// we iterate over the definitions in the reverse order.
- for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
- for (SymbolVersion &Ver : V.Globals)
- assignWildcardVersion(Ver, V.Id);
+ for (VersionDefinition &v : llvm::reverse(config->versionDefinitions))
+ for (SymbolVersion &ver : v.globals)
+ assignWildcardVersion(ver, v.id);
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
- for (Symbol *Sym : SymVector)
- Sym->parseSymbolVersion();
+ for (Symbol *sym : symVector)
+ sym->parseSymbolVersion();
}
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 68568d25b73..26a5adac6e7 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -33,41 +33,41 @@ namespace elf {
// is one add* function per symbol type.
class SymbolTable {
public:
- void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
+ void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
- void forEachSymbol(llvm::function_ref<void(Symbol *)> Fn) {
- for (Symbol *Sym : SymVector)
- if (!Sym->isPlaceholder())
- Fn(Sym);
+ void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
+ for (Symbol *sym : symVector)
+ if (!sym->isPlaceholder())
+ fn(sym);
}
- Symbol *insert(StringRef Name);
+ Symbol *insert(StringRef name);
Symbol *addSymbol(const Symbol &New);
void scanVersionScript();
- Symbol *find(StringRef Name);
+ Symbol *find(StringRef name);
void handleDynamicList();
// Set of .so files to not link the same shared object file more than once.
- llvm::DenseMap<StringRef, SharedFile *> SoNames;
+ llvm::DenseMap<StringRef, SharedFile *> soNames;
// Comdat groups define "link once" sections. If two comdat groups have the
// same name, only one of them is linked, and the other is ignored. This map
// is used to uniquify them.
- llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> ComdatGroups;
+ llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
private:
- std::vector<Symbol *> findByVersion(SymbolVersion Ver);
- std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
+ std::vector<Symbol *> findByVersion(SymbolVersion ver);
+ std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
void handleAnonymousVersion();
- void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
- StringRef VersionName);
- void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
+ void assignExactVersion(SymbolVersion ver, uint16_t versionId,
+ StringRef versionName);
+ void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
// The order the global symbols are in is not defined. We can use an arbitrary
// order, but it has to be reproducible. That is true even when cross linking.
@@ -76,17 +76,17 @@ private:
// but a bit inefficient.
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
// once symbol resolution is finished.
- llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
- std::vector<Symbol *> SymVector;
+ llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
+ std::vector<Symbol *> symVector;
// A map from demangled symbol names to their symbol objects.
// This mapping is 1:N because two symbols with different versions
// can have the same name. We use this map to handle "extern C++ {}"
// directive in version scripts.
- llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
+ llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> demangledSyms;
};
-extern SymbolTable *Symtab;
+extern SymbolTable *symtab;
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 6a0f9ef39ed..62c552e0482 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -26,36 +26,36 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-Defined *ElfSym::Bss;
-Defined *ElfSym::Etext1;
-Defined *ElfSym::Etext2;
-Defined *ElfSym::Edata1;
-Defined *ElfSym::Edata2;
-Defined *ElfSym::End1;
-Defined *ElfSym::End2;
-Defined *ElfSym::GlobalOffsetTable;
-Defined *ElfSym::MipsGp;
-Defined *ElfSym::MipsGpDisp;
-Defined *ElfSym::MipsLocalGp;
-Defined *ElfSym::RelaIpltStart;
-Defined *ElfSym::RelaIpltEnd;
-Defined *ElfSym::RISCVGlobalPointer;
-Defined *ElfSym::TlsModuleBase;
-
-static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
- switch (Sym.kind()) {
+Defined *ElfSym::bss;
+Defined *ElfSym::etext1;
+Defined *ElfSym::etext2;
+Defined *ElfSym::edata1;
+Defined *ElfSym::edata2;
+Defined *ElfSym::end1;
+Defined *ElfSym::end2;
+Defined *ElfSym::globalOffsetTable;
+Defined *ElfSym::mipsGp;
+Defined *ElfSym::mipsGpDisp;
+Defined *ElfSym::mipsLocalGp;
+Defined *ElfSym::relaIpltStart;
+Defined *ElfSym::relaIpltEnd;
+Defined *ElfSym::riscvGlobalPointer;
+Defined *ElfSym::tlsModuleBase;
+
+static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
+ switch (sym.kind()) {
case Symbol::DefinedKind: {
- auto &D = cast<Defined>(Sym);
- SectionBase *IS = D.Section;
+ auto &d = cast<Defined>(sym);
+ SectionBase *isec = d.section;
// This is an absolute symbol.
- if (!IS)
- return D.Value;
+ if (!isec)
+ return d.value;
- assert(IS != &InputSection::Discarded);
- IS = IS->Repl;
+ assert(isec != &InputSection::discarded);
+ isec = isec->repl;
- uint64_t Offset = D.Value;
+ uint64_t offset = d.value;
// An object in an SHF_MERGE section might be referenced via a
// section symbol (as a hack for reducing the number of local
@@ -68,9 +68,9 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
// To make this work, we incorporate the addend into the section
// offset (and zero out the addend for later processing) so that
// we find the right object in the section.
- if (D.isSection()) {
- Offset += Addend;
- Addend = 0;
+ if (d.isSection()) {
+ offset += addend;
+ addend = 0;
}
// In the typical case, this is actually very simple and boils
@@ -83,7 +83,7 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
// If you understand the data structures involved with this next
// line (and how they get built), then you have a pretty good
// understanding of the linker.
- uint64_t VA = IS->getVA(Offset);
+ uint64_t va = isec->getVA(offset);
// MIPS relocatable files can mix regular and microMIPS code.
// Linker needs to distinguish such code. To do so microMIPS
@@ -94,29 +94,29 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
// a symbol value as-is (.dynamic section, `Elf_Ehdr::e_entry`
// field etc) do the same trick as compiler uses to mark microMIPS
// for CPU - set the less-significant bit.
- if (Config->EMachine == EM_MIPS && isMicroMips() &&
- ((Sym.StOther & STO_MIPS_MICROMIPS) || Sym.NeedsPltAddr))
- VA |= 1;
+ if (config->emachine == EM_MIPS && isMicroMips() &&
+ ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr))
+ va |= 1;
- if (D.isTls() && !Config->Relocatable) {
+ if (d.isTls() && !config->relocatable) {
// Use the address of the TLS segment's first section rather than the
// segment's address, because segment addresses aren't initialized until
// after sections are finalized. (e.g. Measuring the size of .rela.dyn
// for Android relocation packing requires knowing TLS symbol addresses
// during section finalization.)
- if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec)
- fatal(toString(D.File) +
+ if (!Out::tlsPhdr || !Out::tlsPhdr->firstSec)
+ fatal(toString(d.file) +
" has an STT_TLS symbol but doesn't have an SHF_TLS section");
- return VA - Out::TlsPhdr->FirstSec->Addr;
+ return va - Out::tlsPhdr->firstSec->addr;
}
- return VA;
+ return va;
}
case Symbol::SharedKind:
case Symbol::UndefinedKind:
return 0;
case Symbol::LazyArchiveKind:
case Symbol::LazyObjectKind:
- assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
+ assert(sym.isUsedInRegularObj && "lazy symbol reached writer");
return 0;
case Symbol::CommonKind:
llvm_unreachable("common symbol reached writer");
@@ -126,64 +126,64 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
llvm_unreachable("invalid symbol kind");
}
-uint64_t Symbol::getVA(int64_t Addend) const {
- uint64_t OutVA = getSymVA(*this, Addend);
- return OutVA + Addend;
+uint64_t Symbol::getVA(int64_t addend) const {
+ uint64_t outVA = getSymVA(*this, addend);
+ return outVA + addend;
}
uint64_t Symbol::getGotVA() const {
- if (GotInIgot)
- return In.IgotPlt->getVA() + getGotPltOffset();
- return In.Got->getVA() + getGotOffset();
+ if (gotInIgot)
+ return in.igotPlt->getVA() + getGotPltOffset();
+ return in.got->getVA() + getGotOffset();
}
-uint64_t Symbol::getGotOffset() const { return GotIndex * Config->Wordsize; }
+uint64_t Symbol::getGotOffset() const { return gotIndex * config->wordsize; }
uint64_t Symbol::getGotPltVA() const {
- if (IsInIplt)
- return In.IgotPlt->getVA() + getGotPltOffset();
- return In.GotPlt->getVA() + getGotPltOffset();
+ if (isInIplt)
+ return in.igotPlt->getVA() + getGotPltOffset();
+ return in.gotPlt->getVA() + getGotPltOffset();
}
uint64_t Symbol::getGotPltOffset() const {
- if (IsInIplt)
- return PltIndex * Config->Wordsize;
- return (PltIndex + Target->GotPltHeaderEntriesNum) * Config->Wordsize;
+ if (isInIplt)
+ return pltIndex * config->wordsize;
+ return (pltIndex + target->gotPltHeaderEntriesNum) * config->wordsize;
}
uint64_t Symbol::getPPC64LongBranchOffset() const {
- assert(PPC64BranchltIndex != 0xffff);
- return PPC64BranchltIndex * Config->Wordsize;
+ assert(ppc64BranchltIndex != 0xffff);
+ return ppc64BranchltIndex * config->wordsize;
}
uint64_t Symbol::getPltVA() const {
- PltSection *Plt = IsInIplt ? In.Iplt : In.Plt;
- uint64_t OutVA =
- Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;
+ PltSection *plt = isInIplt ? in.iplt : in.plt;
+ uint64_t outVA =
+ plt->getVA() + plt->headerSize + pltIndex * target->pltEntrySize;
// While linking microMIPS code PLT code are always microMIPS
// code. Set the less-significant bit to track that fact.
// See detailed comment in the `getSymVA` function.
- if (Config->EMachine == EM_MIPS && isMicroMips())
- OutVA |= 1;
- return OutVA;
+ if (config->emachine == EM_MIPS && isMicroMips())
+ outVA |= 1;
+ return outVA;
}
uint64_t Symbol::getPPC64LongBranchTableVA() const {
- assert(PPC64BranchltIndex != 0xffff);
- return In.PPC64LongBranchTarget->getVA() +
- PPC64BranchltIndex * Config->Wordsize;
+ assert(ppc64BranchltIndex != 0xffff);
+ return in.ppc64LongBranchTarget->getVA() +
+ ppc64BranchltIndex * config->wordsize;
}
uint64_t Symbol::getSize() const {
- if (const auto *DR = dyn_cast<Defined>(this))
- return DR->Size;
- return cast<SharedSymbol>(this)->Size;
+ if (const auto *dr = dyn_cast<Defined>(this))
+ return dr->size;
+ return cast<SharedSymbol>(this)->size;
}
OutputSection *Symbol::getOutputSection() const {
- if (auto *S = dyn_cast<Defined>(this)) {
- if (auto *Sec = S->Section)
- return Sec->Repl->getOutputSection();
+ if (auto *s = dyn_cast<Defined>(this)) {
+ if (auto *sec = s->section)
+ return sec->repl->getOutputSection();
return nullptr;
}
return nullptr;
@@ -192,16 +192,16 @@ OutputSection *Symbol::getOutputSection() const {
// If a symbol name contains '@', the characters after that is
// a symbol version name. This function parses that.
void Symbol::parseSymbolVersion() {
- StringRef S = getName();
- size_t Pos = S.find('@');
- if (Pos == 0 || Pos == StringRef::npos)
+ StringRef s = getName();
+ size_t pos = s.find('@');
+ if (pos == 0 || pos == StringRef::npos)
return;
- StringRef Verstr = S.substr(Pos + 1);
- if (Verstr.empty())
+ StringRef verstr = s.substr(pos + 1);
+ if (verstr.empty())
return;
// Truncate the symbol name so that it doesn't include the version string.
- NameSize = Pos;
+ nameSize = pos;
// If this is not in this DSO, it is not a definition.
if (!isDefined())
@@ -209,18 +209,18 @@ void Symbol::parseSymbolVersion() {
// '@@' in a symbol name means the default version.
// It is usually the most recent one.
- bool IsDefault = (Verstr[0] == '@');
- if (IsDefault)
- Verstr = Verstr.substr(1);
+ bool isDefault = (verstr[0] == '@');
+ if (isDefault)
+ verstr = verstr.substr(1);
- for (VersionDefinition &Ver : Config->VersionDefinitions) {
- if (Ver.Name != Verstr)
+ for (VersionDefinition &ver : config->versionDefinitions) {
+ if (ver.name != verstr)
continue;
- if (IsDefault)
- VersionId = Ver.Id;
+ if (isDefault)
+ versionId = ver.id;
else
- VersionId = Ver.Id | VERSYM_HIDDEN;
+ versionId = ver.id | VERSYM_HIDDEN;
return;
}
@@ -230,19 +230,19 @@ void Symbol::parseSymbolVersion() {
// so we do not report error in this case. We also do not error
// if the symbol has a local version as it won't be in the dynamic
// symbol table.
- if (Config->Shared && VersionId != VER_NDX_LOCAL)
- error(toString(File) + ": symbol " + S + " has undefined version " +
- Verstr);
+ if (config->shared && versionId != VER_NDX_LOCAL)
+ error(toString(file) + ": symbol " + s + " has undefined version " +
+ verstr);
}
void Symbol::fetch() const {
- if (auto *Sym = dyn_cast<LazyArchive>(this)) {
- cast<ArchiveFile>(Sym->File)->fetch(Sym->Sym);
+ if (auto *sym = dyn_cast<LazyArchive>(this)) {
+ cast<ArchiveFile>(sym->file)->fetch(sym->sym);
return;
}
- if (auto *Sym = dyn_cast<LazyObject>(this)) {
- dyn_cast<LazyObjFile>(Sym->File)->fetch();
+ if (auto *sym = dyn_cast<LazyObject>(this)) {
+ dyn_cast<LazyObjFile>(sym->file)->fetch();
return;
}
@@ -250,59 +250,59 @@ void Symbol::fetch() const {
}
MemoryBufferRef LazyArchive::getMemberBuffer() {
- Archive::Child C = CHECK(
- Sym.getMember(), "could not get the member for symbol " + Sym.getName());
+ Archive::Child c = CHECK(
+ sym.getMember(), "could not get the member for symbol " + sym.getName());
- return CHECK(C.getMemoryBufferRef(),
+ return CHECK(c.getMemoryBufferRef(),
"could not get the buffer for the member defining symbol " +
- Sym.getName());
+ sym.getName());
}
uint8_t Symbol::computeBinding() const {
- if (Config->Relocatable)
- return Binding;
- if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
+ if (config->relocatable)
+ return binding;
+ if (visibility != STV_DEFAULT && visibility != STV_PROTECTED)
return STB_LOCAL;
- if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
+ if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible)
return STB_LOCAL;
- if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
+ if (!config->gnuUnique && binding == STB_GNU_UNIQUE)
return STB_GLOBAL;
- return Binding;
+ return binding;
}
bool Symbol::includeInDynsym() const {
- if (!Config->HasDynSymTab)
+ if (!config->hasDynSymTab)
return false;
if (computeBinding() == STB_LOCAL)
return false;
// If a PIE binary was not linked against any shared libraries, then we can
// safely drop weak undef symbols from .dynsym.
- if (isUndefWeak() && Config->Pie && SharedFiles.empty())
+ if (isUndefWeak() && config->pie && sharedFiles.empty())
return false;
- return isUndefined() || isShared() || ExportDynamic;
+ return isUndefined() || isShared() || exportDynamic;
}
// Print out a log message for --trace-symbol.
-void elf::printTraceSymbol(const Symbol *Sym) {
- std::string S;
- if (Sym->isUndefined())
- S = ": reference to ";
- else if (Sym->isLazy())
- S = ": lazy definition of ";
- else if (Sym->isShared())
- S = ": shared definition of ";
- else if (Sym->isCommon())
- S = ": common definition of ";
+void elf::printTraceSymbol(const Symbol *sym) {
+ std::string s;
+ if (sym->isUndefined())
+ s = ": reference to ";
+ else if (sym->isLazy())
+ s = ": lazy definition of ";
+ else if (sym->isShared())
+ s = ": shared definition of ";
+ else if (sym->isCommon())
+ s = ": common definition of ";
else
- S = ": definition of ";
+ s = ": definition of ";
- message(toString(Sym->File) + S + Sym->getName());
+ message(toString(sym->file) + s + sym->getName());
}
-void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
- if (!Config->WarnSymbolOrdering)
+void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
+ if (!config->warnSymbolOrdering)
return;
// If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning
@@ -310,41 +310,41 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
//
// Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols,
// but we don't have to be compatible here.
- if (Sym->isUndefined() &&
- Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
+ if (sym->isUndefined() &&
+ config->unresolvedSymbols == UnresolvedPolicy::Ignore)
return;
- const InputFile *File = Sym->File;
- auto *D = dyn_cast<Defined>(Sym);
-
- auto Report = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); };
-
- if (Sym->isUndefined())
- Report(": unable to order undefined symbol: ");
- else if (Sym->isShared())
- Report(": unable to order shared symbol: ");
- else if (D && !D->Section)
- Report(": unable to order absolute symbol: ");
- else if (D && isa<OutputSection>(D->Section))
- Report(": unable to order synthetic symbol: ");
- else if (D && !D->Section->Repl->isLive())
- Report(": unable to order discarded symbol: ");
+ const InputFile *file = sym->file;
+ auto *d = dyn_cast<Defined>(sym);
+
+ auto report = [&](StringRef s) { warn(toString(file) + s + sym->getName()); };
+
+ if (sym->isUndefined())
+ report(": unable to order undefined symbol: ");
+ else if (sym->isShared())
+ report(": unable to order shared symbol: ");
+ else if (d && !d->section)
+ report(": unable to order absolute symbol: ");
+ else if (d && isa<OutputSection>(d->section))
+ report(": unable to order synthetic symbol: ");
+ else if (d && !d->section->repl->isLive())
+ report(": unable to order discarded symbol: ");
}
// Returns a symbol for an error message.
-std::string lld::toString(const Symbol &B) {
- if (Config->Demangle)
- if (Optional<std::string> S = demangleItanium(B.getName()))
- return *S;
- return B.getName();
+std::string lld::toString(const Symbol &b) {
+ if (config->demangle)
+ if (Optional<std::string> s = demangleItanium(b.getName()))
+ return *s;
+ return b.getName();
}
-static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
- if (VA == STV_DEFAULT)
- return VB;
- if (VB == STV_DEFAULT)
- return VA;
- return std::min(VA, VB);
+static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
+ if (va == STV_DEFAULT)
+ return vb;
+ if (vb == STV_DEFAULT)
+ return va;
+ return std::min(va, vb);
}
// Merge symbol properties.
@@ -352,70 +352,70 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
// When we have many symbols of the same name, we choose one of them,
// and that's the result of symbol resolution. However, symbols that
// were not chosen still affect some symbol properties.
-void Symbol::mergeProperties(const Symbol &Other) {
- if (Other.ExportDynamic)
- ExportDynamic = true;
- if (Other.IsUsedInRegularObj)
- IsUsedInRegularObj = true;
+void Symbol::mergeProperties(const Symbol &other) {
+ if (other.exportDynamic)
+ exportDynamic = true;
+ if (other.isUsedInRegularObj)
+ isUsedInRegularObj = true;
// DSO symbols do not affect visibility in the output.
- if (!Other.isShared())
- Visibility = getMinVisibility(Visibility, Other.Visibility);
+ if (!other.isShared())
+ visibility = getMinVisibility(visibility, other.visibility);
}
-void Symbol::resolve(const Symbol &Other) {
- mergeProperties(Other);
+void Symbol::resolve(const Symbol &other) {
+ mergeProperties(other);
if (isPlaceholder()) {
- replace(Other);
+ replace(other);
return;
}
- switch (Other.kind()) {
+ switch (other.kind()) {
case Symbol::UndefinedKind:
- resolveUndefined(cast<Undefined>(Other));
+ resolveUndefined(cast<Undefined>(other));
break;
case Symbol::CommonKind:
- resolveCommon(cast<CommonSymbol>(Other));
+ resolveCommon(cast<CommonSymbol>(other));
break;
case Symbol::DefinedKind:
- resolveDefined(cast<Defined>(Other));
+ resolveDefined(cast<Defined>(other));
break;
case Symbol::LazyArchiveKind:
- resolveLazy(cast<LazyArchive>(Other));
+ resolveLazy(cast<LazyArchive>(other));
break;
case Symbol::LazyObjectKind:
- resolveLazy(cast<LazyObject>(Other));
+ resolveLazy(cast<LazyObject>(other));
break;
case Symbol::SharedKind:
- resolveShared(cast<SharedSymbol>(Other));
+ resolveShared(cast<SharedSymbol>(other));
break;
case Symbol::PlaceholderKind:
llvm_unreachable("bad symbol kind");
}
}
-void Symbol::resolveUndefined(const Undefined &Other) {
+void Symbol::resolveUndefined(const Undefined &other) {
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
//
// If this is a non-weak defined symbol in a discarded section, override the
// existing undefined symbol for better error message later.
- if ((isShared() && Other.Visibility != STV_DEFAULT) ||
- (isUndefined() && Other.Binding != STB_WEAK && Other.DiscardedSecIdx)) {
- replace(Other);
+ if ((isShared() && other.visibility != STV_DEFAULT) ||
+ (isUndefined() && other.binding != STB_WEAK && other.discardedSecIdx)) {
+ replace(other);
return;
}
- if (Traced)
- printTraceSymbol(&Other);
+ if (traced)
+ printTraceSymbol(&other);
if (isLazy()) {
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
- if (Other.Binding == STB_WEAK) {
- Binding = STB_WEAK;
- Type = Other.Type;
+ if (other.binding == STB_WEAK) {
+ binding = STB_WEAK;
+ type = other.type;
return;
}
@@ -469,33 +469,33 @@ void Symbol::resolveUndefined(const Undefined &Other) {
// A forms group 0. B form group 1. C and D (including their member object
// files) form group 2. E forms group 3. I think that you can see how this
// group assignment rule simulates the traditional linker's semantics.
- bool Backref = Config->WarnBackrefs && Other.File &&
- File->GroupId < Other.File->GroupId;
+ bool backref = config->warnBackrefs && other.file &&
+ file->groupId < other.file->groupId;
fetch();
// We don't report backward references to weak symbols as they can be
// overridden later.
- if (Backref && !isWeak())
- warn("backward reference detected: " + Other.getName() + " in " +
- toString(Other.File) + " refers to " + toString(File));
+ if (backref && !isWeak())
+ warn("backward reference detected: " + other.getName() + " in " +
+ toString(other.file) + " refers to " + toString(file));
return;
}
// Undefined symbols in a SharedFile do not change the binding.
- if (dyn_cast_or_null<SharedFile>(Other.File))
+ if (dyn_cast_or_null<SharedFile>(other.file))
return;
if (isUndefined()) {
// The binding may "upgrade" from weak to non-weak.
- if (Other.Binding != STB_WEAK)
- Binding = Other.Binding;
- } else if (auto *S = dyn_cast<SharedSymbol>(this)) {
+ if (other.binding != STB_WEAK)
+ binding = other.binding;
+ } else if (auto *s = dyn_cast<SharedSymbol>(this)) {
// The binding of a SharedSymbol will be weak if there is at least one
// reference and all are weak. The binding has one opportunity to change to
// weak: if the first reference is weak.
- if (Other.Binding != STB_WEAK || !S->Referenced)
- Binding = Other.Binding;
- S->Referenced = true;
+ if (other.binding != STB_WEAK || !s->referenced)
+ binding = other.binding;
+ s->referenced = true;
}
}
@@ -505,73 +505,73 @@ void Symbol::resolveUndefined(const Undefined &Other) {
// FIXME: If users can transition to using
// .symver foo,foo@@@VER
// we can delete this hack.
-static int compareVersion(StringRef A, StringRef B) {
- bool X = A.contains("@@");
- bool Y = B.contains("@@");
- if (!X && Y)
+static int compareVersion(StringRef a, StringRef b) {
+ bool x = a.contains("@@");
+ bool y = b.contains("@@");
+ if (!x && y)
return 1;
- if (X && !Y)
+ if (x && !y)
return -1;
return 0;
}
// Compare two symbols. Return 1 if the new symbol should win, -1 if
// the new symbol should lose, or 0 if there is a conflict.
-int Symbol::compare(const Symbol *Other) const {
- assert(Other->isDefined() || Other->isCommon());
+int Symbol::compare(const Symbol *other) const {
+ assert(other->isDefined() || other->isCommon());
if (!isDefined() && !isCommon())
return 1;
- if (int Cmp = compareVersion(getName(), Other->getName()))
- return Cmp;
+ if (int cmp = compareVersion(getName(), other->getName()))
+ return cmp;
- if (Other->isWeak())
+ if (other->isWeak())
return -1;
if (isWeak())
return 1;
- if (isCommon() && Other->isCommon()) {
- if (Config->WarnCommon)
+ if (isCommon() && other->isCommon()) {
+ if (config->warnCommon)
warn("multiple common of " + getName());
return 0;
}
if (isCommon()) {
- if (Config->WarnCommon)
+ if (config->warnCommon)
warn("common " + getName() + " is overridden");
return 1;
}
- if (Other->isCommon()) {
- if (Config->WarnCommon)
+ if (other->isCommon()) {
+ if (config->warnCommon)
warn("common " + getName() + " is overridden");
return -1;
}
- auto *OldSym = cast<Defined>(this);
- auto *NewSym = cast<Defined>(Other);
+ auto *oldSym = cast<Defined>(this);
+ auto *newSym = cast<Defined>(other);
- if (Other->File && isa<BitcodeFile>(Other->File))
+ if (other->file && isa<BitcodeFile>(other->file))
return 0;
- if (!OldSym->Section && !NewSym->Section && OldSym->Value == NewSym->Value &&
- NewSym->Binding == STB_GLOBAL)
+ if (!oldSym->section && !newSym->section && oldSym->value == newSym->value &&
+ newSym->binding == STB_GLOBAL)
return -1;
return 0;
}
-static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
- InputSectionBase *ErrSec, uint64_t ErrOffset) {
- if (Config->AllowMultipleDefinition)
+static void reportDuplicate(Symbol *sym, InputFile *newFile,
+ InputSectionBase *errSec, uint64_t errOffset) {
+ if (config->allowMultipleDefinition)
return;
- Defined *D = cast<Defined>(Sym);
- if (!D->Section || !ErrSec) {
- error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
- toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
+ Defined *d = cast<Defined>(sym);
+ if (!d->section || !errSec) {
+ error("duplicate symbol: " + toString(*sym) + "\n>>> defined in " +
+ toString(sym->file) + "\n>>> defined in " + toString(newFile));
return;
}
@@ -582,75 +582,75 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
// >>> bar.o (/home/alice/src/bar.o)
// >>> defined at baz.c:563
// >>> baz.o in archive libbaz.a
- auto *Sec1 = cast<InputSectionBase>(D->Section);
- std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
- std::string Obj1 = Sec1->getObjMsg(D->Value);
- std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
- std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
-
- std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
- if (!Src1.empty())
- Msg += Src1 + "\n>>> ";
- Msg += Obj1 + "\n>>> defined at ";
- if (!Src2.empty())
- Msg += Src2 + "\n>>> ";
- Msg += Obj2;
- error(Msg);
+ auto *sec1 = cast<InputSectionBase>(d->section);
+ std::string src1 = sec1->getSrcMsg(*sym, d->value);
+ std::string obj1 = sec1->getObjMsg(d->value);
+ std::string src2 = errSec->getSrcMsg(*sym, errOffset);
+ std::string obj2 = errSec->getObjMsg(errOffset);
+
+ std::string msg = "duplicate symbol: " + toString(*sym) + "\n>>> defined at ";
+ if (!src1.empty())
+ msg += src1 + "\n>>> ";
+ msg += obj1 + "\n>>> defined at ";
+ if (!src2.empty())
+ msg += src2 + "\n>>> ";
+ msg += obj2;
+ error(msg);
}
-void Symbol::resolveCommon(const CommonSymbol &Other) {
- int Cmp = compare(&Other);
- if (Cmp < 0)
+void Symbol::resolveCommon(const CommonSymbol &other) {
+ int cmp = compare(&other);
+ if (cmp < 0)
return;
- if (Cmp > 0) {
- replace(Other);
+ if (cmp > 0) {
+ replace(other);
return;
}
- CommonSymbol *OldSym = cast<CommonSymbol>(this);
+ CommonSymbol *oldSym = cast<CommonSymbol>(this);
- OldSym->Alignment = std::max(OldSym->Alignment, Other.Alignment);
- if (OldSym->Size < Other.Size) {
- OldSym->File = Other.File;
- OldSym->Size = Other.Size;
+ oldSym->alignment = std::max(oldSym->alignment, other.alignment);
+ if (oldSym->size < other.size) {
+ oldSym->file = other.file;
+ oldSym->size = other.size;
}
}
-void Symbol::resolveDefined(const Defined &Other) {
- int Cmp = compare(&Other);
- if (Cmp > 0)
- replace(Other);
- else if (Cmp == 0)
- reportDuplicate(this, Other.File,
- dyn_cast_or_null<InputSectionBase>(Other.Section),
- Other.Value);
+void Symbol::resolveDefined(const Defined &other) {
+ int cmp = compare(&other);
+ if (cmp > 0)
+ replace(other);
+ else if (cmp == 0)
+ reportDuplicate(this, other.file,
+ dyn_cast_or_null<InputSectionBase>(other.section),
+ other.value);
}
-template <class LazyT> void Symbol::resolveLazy(const LazyT &Other) {
+template <class LazyT> void Symbol::resolveLazy(const LazyT &other) {
if (!isUndefined())
return;
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
if (isWeak()) {
- uint8_t Ty = Type;
- replace(Other);
- Type = Ty;
- Binding = STB_WEAK;
+ uint8_t ty = type;
+ replace(other);
+ type = ty;
+ binding = STB_WEAK;
return;
}
- Other.fetch();
+ other.fetch();
}
-void Symbol::resolveShared(const SharedSymbol &Other) {
- if (Visibility == STV_DEFAULT && (isUndefined() || isLazy())) {
+void Symbol::resolveShared(const SharedSymbol &other) {
+ if (visibility == STV_DEFAULT && (isUndefined() || isLazy())) {
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
- uint8_t Bind = Binding;
- replace(Other);
- Binding = Bind;
- cast<SharedSymbol>(this)->Referenced = true;
+ uint8_t bind = binding;
+ replace(other);
+ binding = bind;
+ cast<SharedSymbol>(this)->referenced = true;
}
}
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index f9b1fc6c4dc..d640495b0e0 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -44,11 +44,11 @@ namespace elf {
// and the linker doesn't use local symbol names for name resolution. So, we
// use this class to represents strings read from string tables.
struct StringRefZ {
- StringRefZ(const char *S) : Data(S), Size(-1) {}
- StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {}
+ StringRefZ(const char *s) : data(s), size(-1) {}
+ StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
- const char *Data;
- const uint32_t Size;
+ const char *data;
+ const uint32_t size;
};
// The base class for real symbol classes.
@@ -64,84 +64,84 @@ public:
LazyObjectKind,
};
- Kind kind() const { return static_cast<Kind>(SymbolKind); }
+ Kind kind() const { return static_cast<Kind>(symbolKind); }
// The file from which this symbol was created.
- InputFile *File;
+ InputFile *file;
protected:
- const char *NameData;
- mutable uint32_t NameSize;
+ const char *nameData;
+ mutable uint32_t nameSize;
public:
- uint32_t DynsymIndex = 0;
- uint32_t GotIndex = -1;
- uint32_t PltIndex = -1;
+ uint32_t dynsymIndex = 0;
+ uint32_t gotIndex = -1;
+ uint32_t pltIndex = -1;
- uint32_t GlobalDynIndex = -1;
+ uint32_t globalDynIndex = -1;
// This field is a index to the symbol's version definition.
- uint32_t VerdefIndex = -1;
+ uint32_t verdefIndex = -1;
// Version definition index.
- uint16_t VersionId;
+ uint16_t versionId;
// An index into the .branch_lt section on PPC64.
- uint16_t PPC64BranchltIndex = -1;
+ uint16_t ppc64BranchltIndex = -1;
// Symbol binding. This is not overwritten by replace() to track
// changes during resolution. In particular:
// - An undefined weak is still weak when it resolves to a shared library.
// - An undefined weak will not fetch archive members, but we have to
// remember it is weak.
- uint8_t Binding;
+ uint8_t binding;
// The following fields have the same meaning as the ELF symbol attributes.
- uint8_t Type; // symbol type
- uint8_t StOther; // st_other field value
+ uint8_t type; // symbol type
+ uint8_t stOther; // st_other field value
- uint8_t SymbolKind;
+ uint8_t symbolKind;
// Symbol visibility. This is the computed minimum visibility of all
// observed non-DSO symbols.
- unsigned Visibility : 2;
+ unsigned visibility : 2;
// True if the symbol was used for linking and thus need to be added to the
// output file's symbol table. This is true for all symbols except for
// unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that
// are unreferenced except by other bitcode objects.
- unsigned IsUsedInRegularObj : 1;
+ unsigned isUsedInRegularObj : 1;
// If this flag is true and the symbol has protected or default visibility, it
// will appear in .dynsym. This flag is set by interposable DSO symbols in
// executables, by most symbols in DSOs and executables built with
// --export-dynamic, and by dynamic lists.
- unsigned ExportDynamic : 1;
+ unsigned exportDynamic : 1;
// False if LTO shouldn't inline whatever this symbol points to. If a symbol
// is overwritten after LTO, LTO shouldn't inline the symbol because it
// doesn't know the final contents of the symbol.
- unsigned CanInline : 1;
+ unsigned canInline : 1;
// True if this symbol is specified by --trace-symbol option.
- unsigned Traced : 1;
+ unsigned traced : 1;
inline void replace(const Symbol &New);
bool includeInDynsym() const;
uint8_t computeBinding() const;
- bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
+ bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
- bool isUndefined() const { return SymbolKind == UndefinedKind; }
- bool isCommon() const { return SymbolKind == CommonKind; }
- bool isDefined() const { return SymbolKind == DefinedKind; }
- bool isShared() const { return SymbolKind == SharedKind; }
- bool isPlaceholder() const { return SymbolKind == PlaceholderKind; }
+ bool isUndefined() const { return symbolKind == UndefinedKind; }
+ bool isCommon() const { return symbolKind == CommonKind; }
+ bool isDefined() const { return symbolKind == DefinedKind; }
+ bool isShared() const { return symbolKind == SharedKind; }
+ bool isPlaceholder() const { return symbolKind == PlaceholderKind; }
- bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
+ bool isLocal() const { return binding == llvm::ELF::STB_LOCAL; }
bool isLazy() const {
- return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
+ return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind;
}
// True if this is an undefined weak symbol. This only works once
@@ -152,23 +152,23 @@ public:
}
StringRef getName() const {
- if (NameSize == (uint32_t)-1)
- NameSize = strlen(NameData);
- return {NameData, NameSize};
+ if (nameSize == (uint32_t)-1)
+ nameSize = strlen(nameData);
+ return {nameData, nameSize};
}
- void setName(StringRef S) {
- NameData = S.data();
- NameSize = S.size();
+ void setName(StringRef s) {
+ nameData = s.data();
+ nameSize = s.size();
}
void parseSymbolVersion();
- bool isInGot() const { return GotIndex != -1U; }
- bool isInPlt() const { return PltIndex != -1U; }
- bool isInPPC64Branchlt() const { return PPC64BranchltIndex != 0xffff; }
+ bool isInGot() const { return gotIndex != -1U; }
+ bool isInPlt() const { return pltIndex != -1U; }
+ bool isInPPC64Branchlt() const { return ppc64BranchltIndex != 0xffff; }
- uint64_t getVA(int64_t Addend = 0) const;
+ uint64_t getVA(int64_t addend = 0) const;
uint64_t getGotOffset() const;
uint64_t getGotVA() const;
@@ -193,8 +193,8 @@ public:
//
// For example, if "this" is an undefined symbol and a new symbol is
// a defined symbol, "this" is replaced with the new symbol.
- void mergeProperties(const Symbol &Other);
- void resolve(const Symbol &Other);
+ void mergeProperties(const Symbol &other);
+ void resolve(const Symbol &other);
// If this is a lazy symbol, fetch an input file and add the symbol
// in the file to the symbol table. Calling this function on
@@ -202,83 +202,83 @@ public:
void fetch() const;
private:
- static bool isExportDynamic(Kind K, uint8_t Visibility) {
- if (K == SharedKind)
- return Visibility == llvm::ELF::STV_DEFAULT;
- return Config->Shared || Config->ExportDynamic;
+ static bool isExportDynamic(Kind k, uint8_t visibility) {
+ if (k == SharedKind)
+ return visibility == llvm::ELF::STV_DEFAULT;
+ return config->shared || config->exportDynamic;
}
- void resolveUndefined(const Undefined &Other);
- void resolveCommon(const CommonSymbol &Other);
- void resolveDefined(const Defined &Other);
- template <class LazyT> void resolveLazy(const LazyT &Other);
- void resolveShared(const SharedSymbol &Other);
+ void resolveUndefined(const Undefined &other);
+ void resolveCommon(const CommonSymbol &other);
+ void resolveDefined(const Defined &other);
+ template <class LazyT> void resolveLazy(const LazyT &other);
+ void resolveShared(const SharedSymbol &other);
- int compare(const Symbol *Other) const;
+ int compare(const Symbol *other) const;
inline size_t getSymbolSize() const;
protected:
- Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type)
- : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
- Type(Type), StOther(StOther), SymbolKind(K), Visibility(StOther & 3),
- IsUsedInRegularObj(!File || File->kind() == InputFile::ObjKind),
- ExportDynamic(isExportDynamic(K, Visibility)), CanInline(false),
- Traced(false), NeedsPltAddr(false), IsInIplt(false), GotInIgot(false),
- IsPreemptible(false), Used(!Config->GcSections), NeedsTocRestore(false),
- ScriptDefined(false) {}
+ Symbol(Kind k, InputFile *file, StringRefZ name, uint8_t binding,
+ uint8_t stOther, uint8_t type)
+ : file(file), nameData(name.data), nameSize(name.size), binding(binding),
+ type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
+ isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
+ exportDynamic(isExportDynamic(k, visibility)), canInline(false),
+ traced(false), needsPltAddr(false), isInIplt(false), gotInIgot(false),
+ isPreemptible(false), used(!config->gcSections), needsTocRestore(false),
+ scriptDefined(false) {}
public:
// True the symbol should point to its PLT entry.
// For SharedSymbol only.
- unsigned NeedsPltAddr : 1;
+ unsigned needsPltAddr : 1;
// True if this symbol is in the Iplt sub-section of the Plt and the Igot
// sub-section of the .got.plt or .got.
- unsigned IsInIplt : 1;
+ unsigned isInIplt : 1;
// True if this symbol needs a GOT entry and its GOT entry is actually in
// Igot. This will be true only for certain non-preemptible ifuncs.
- unsigned GotInIgot : 1;
+ unsigned gotInIgot : 1;
// True if this symbol is preemptible at load time.
- unsigned IsPreemptible : 1;
+ unsigned isPreemptible : 1;
// True if an undefined or shared symbol is used from a live section.
- unsigned Used : 1;
+ unsigned used : 1;
// True if a call to this symbol needs to be followed by a restore of the
// PPC64 toc pointer.
- unsigned NeedsTocRestore : 1;
+ unsigned needsTocRestore : 1;
// True if this symbol is defined by a linker script.
- unsigned ScriptDefined : 1;
+ unsigned scriptDefined : 1;
// The partition whose dynamic symbol table contains this symbol's definition.
- uint8_t Partition = 1;
-
- bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
- bool isTls() const { return Type == llvm::ELF::STT_TLS; }
- bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
- bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
- bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
- bool isFile() const { return Type == llvm::ELF::STT_FILE; }
+ uint8_t partition = 1;
+
+ bool isSection() const { return type == llvm::ELF::STT_SECTION; }
+ bool isTls() const { return type == llvm::ELF::STT_TLS; }
+ bool isFunc() const { return type == llvm::ELF::STT_FUNC; }
+ bool isGnuIFunc() const { return type == llvm::ELF::STT_GNU_IFUNC; }
+ bool isObject() const { return type == llvm::ELF::STT_OBJECT; }
+ bool isFile() const { return type == llvm::ELF::STT_FILE; }
};
// Represents a symbol that is defined in the current output file.
class Defined : public Symbol {
public:
- Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section)
- : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value),
- Size(Size), Section(Section) {}
+ Defined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+ uint8_t type, uint64_t value, uint64_t size, SectionBase *section)
+ : Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
+ size(size), section(section) {}
- static bool classof(const Symbol *S) { return S->isDefined(); }
+ static bool classof(const Symbol *s) { return s->isDefined(); }
- uint64_t Value;
- uint64_t Size;
- SectionBase *Section;
+ uint64_t value;
+ uint64_t size;
+ SectionBase *section;
};
// Represents a common symbol.
@@ -304,40 +304,40 @@ public:
// section. (Therefore, the later passes don't see any CommonSymbols.)
class CommonSymbol : public Symbol {
public:
- CommonSymbol(InputFile *File, StringRefZ Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type, uint64_t Alignment, uint64_t Size)
- : Symbol(CommonKind, File, Name, Binding, StOther, Type),
- Alignment(Alignment), Size(Size) {}
+ CommonSymbol(InputFile *file, StringRefZ name, uint8_t binding,
+ uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
+ : Symbol(CommonKind, file, name, binding, stOther, type),
+ alignment(alignment), size(size) {}
- static bool classof(const Symbol *S) { return S->isCommon(); }
+ static bool classof(const Symbol *s) { return s->isCommon(); }
- uint32_t Alignment;
- uint64_t Size;
+ uint32_t alignment;
+ uint64_t size;
};
class Undefined : public Symbol {
public:
- Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, uint32_t DiscardedSecIdx = 0)
- : Symbol(UndefinedKind, File, Name, Binding, StOther, Type),
- DiscardedSecIdx(DiscardedSecIdx) {}
+ Undefined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+ uint8_t type, uint32_t discardedSecIdx = 0)
+ : Symbol(UndefinedKind, file, name, binding, stOther, type),
+ discardedSecIdx(discardedSecIdx) {}
- static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
+ static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
// The section index if in a discarded section, 0 otherwise.
- uint32_t DiscardedSecIdx;
+ uint32_t discardedSecIdx;
};
class SharedSymbol : public Symbol {
public:
- static bool classof(const Symbol *S) { return S->kind() == SharedKind; }
-
- SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
- uint32_t Alignment, uint32_t VerdefIndex)
- : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value),
- Size(Size), Alignment(Alignment) {
- this->VerdefIndex = VerdefIndex;
+ static bool classof(const Symbol *s) { return s->kind() == SharedKind; }
+
+ SharedSymbol(InputFile &file, StringRef name, uint8_t binding,
+ uint8_t stOther, uint8_t type, uint64_t value, uint64_t size,
+ uint32_t alignment, uint32_t verdefIndex)
+ : Symbol(SharedKind, &file, name, binding, stOther, type), value(value),
+ size(size), alignment(alignment) {
+ this->verdefIndex = verdefIndex;
// GNU ifunc is a mechanism to allow user-supplied functions to
// resolve PLT slot values at load-time. This is contrary to the
// regular symbol resolution scheme in which symbols are resolved just
@@ -354,20 +354,20 @@ public:
// For DSO symbols, we always call them through PLT slots anyway.
// So there's no difference between GNU ifunc and regular function
// symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
- if (this->Type == llvm::ELF::STT_GNU_IFUNC)
- this->Type = llvm::ELF::STT_FUNC;
+ if (this->type == llvm::ELF::STT_GNU_IFUNC)
+ this->type = llvm::ELF::STT_FUNC;
}
- SharedFile &getFile() const { return *cast<SharedFile>(File); }
+ SharedFile &getFile() const { return *cast<SharedFile>(file); }
- uint64_t Value; // st_value
- uint64_t Size; // st_size
- uint32_t Alignment;
+ uint64_t value; // st_value
+ uint64_t size; // st_size
+ uint32_t alignment;
// This is true if there has been at least one undefined reference to the
// symbol. The binding may change to STB_WEAK if the first undefined reference
// is weak.
- bool Referenced = false;
+ bool referenced = false;
};
// LazyArchive and LazyObject represent a symbols that is not yet in the link,
@@ -386,78 +386,78 @@ public:
// symbol.
class LazyArchive : public Symbol {
public:
- LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S)
- : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
+ LazyArchive(InputFile &file, const llvm::object::Archive::Symbol s)
+ : Symbol(LazyArchiveKind, &file, s.getName(), llvm::ELF::STB_GLOBAL,
llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE),
- Sym(S) {}
+ sym(s) {}
- static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
+ static bool classof(const Symbol *s) { return s->kind() == LazyArchiveKind; }
MemoryBufferRef getMemberBuffer();
- const llvm::object::Archive::Symbol Sym;
+ const llvm::object::Archive::Symbol sym;
};
// LazyObject symbols represents symbols in object files between
// --start-lib and --end-lib options.
class LazyObject : public Symbol {
public:
- LazyObject(InputFile &File, StringRef Name)
- : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
+ LazyObject(InputFile &file, StringRef name)
+ : Symbol(LazyObjectKind, &file, name, llvm::ELF::STB_GLOBAL,
llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE) {}
- static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
+ static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
};
// Some linker-generated symbols need to be created as
// Defined symbols.
struct ElfSym {
// __bss_start
- static Defined *Bss;
+ static Defined *bss;
// etext and _etext
- static Defined *Etext1;
- static Defined *Etext2;
+ static Defined *etext1;
+ static Defined *etext2;
// edata and _edata
- static Defined *Edata1;
- static Defined *Edata2;
+ static Defined *edata1;
+ static Defined *edata2;
// end and _end
- static Defined *End1;
- static Defined *End2;
+ static Defined *end1;
+ static Defined *end2;
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
// be at some offset from the base of the .got section, usually 0 or
// the end of the .got.
- static Defined *GlobalOffsetTable;
+ static Defined *globalOffsetTable;
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
- static Defined *MipsGp;
- static Defined *MipsGpDisp;
- static Defined *MipsLocalGp;
+ static Defined *mipsGp;
+ static Defined *mipsGpDisp;
+ static Defined *mipsLocalGp;
// __rel{,a}_iplt_{start,end} symbols.
- static Defined *RelaIpltStart;
- static Defined *RelaIpltEnd;
+ static Defined *relaIpltStart;
+ static Defined *relaIpltEnd;
// __global_pointer$ for RISC-V.
- static Defined *RISCVGlobalPointer;
+ static Defined *riscvGlobalPointer;
// _TLS_MODULE_BASE_ on targets that support TLSDESC.
- static Defined *TlsModuleBase;
+ static Defined *tlsModuleBase;
};
// A buffer class that is large enough to hold any Symbol-derived
// object. We allocate memory using this class and instantiate a symbol
// using the placement new.
union SymbolUnion {
- alignas(Defined) char A[sizeof(Defined)];
- alignas(CommonSymbol) char B[sizeof(CommonSymbol)];
- alignas(Undefined) char C[sizeof(Undefined)];
- alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
- alignas(LazyArchive) char E[sizeof(LazyArchive)];
- alignas(LazyObject) char F[sizeof(LazyObject)];
+ alignas(Defined) char a[sizeof(Defined)];
+ alignas(CommonSymbol) char b[sizeof(CommonSymbol)];
+ alignas(Undefined) char c[sizeof(Undefined)];
+ alignas(SharedSymbol) char d[sizeof(SharedSymbol)];
+ alignas(LazyArchive) char e[sizeof(LazyArchive)];
+ alignas(LazyObject) char f[sizeof(LazyObject)];
};
// It is important to keep the size of SymbolUnion small for performance and
@@ -482,7 +482,7 @@ static inline void assertSymbols() {
AssertSymbol<LazyObject>();
}
-void printTraceSymbol(const Symbol *Sym);
+void printTraceSymbol(const Symbol *sym);
size_t Symbol::getSymbolSize() const {
switch (kind()) {
@@ -515,39 +515,39 @@ void Symbol::replace(const Symbol &New) {
// non-TLS relocations, so there's a clear distinction between TLS
// and non-TLS symbols. It is an error if the same symbol is defined
// as a TLS symbol in one file and as a non-TLS symbol in other file.
- if (SymbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) {
- bool TlsMismatch = (Type == STT_TLS && New.Type != STT_TLS) ||
- (Type != STT_TLS && New.Type == STT_TLS);
- if (TlsMismatch)
+ if (symbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) {
+ bool tlsMismatch = (type == STT_TLS && New.type != STT_TLS) ||
+ (type != STT_TLS && New.type == STT_TLS);
+ if (tlsMismatch)
error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " +
- toString(New.File) + "\n>>> defined in " + toString(File));
+ toString(New.file) + "\n>>> defined in " + toString(file));
}
- Symbol Old = *this;
+ Symbol old = *this;
memcpy(this, &New, New.getSymbolSize());
- VersionId = Old.VersionId;
- Visibility = Old.Visibility;
- IsUsedInRegularObj = Old.IsUsedInRegularObj;
- ExportDynamic = Old.ExportDynamic;
- CanInline = Old.CanInline;
- Traced = Old.Traced;
- IsPreemptible = Old.IsPreemptible;
- ScriptDefined = Old.ScriptDefined;
- Partition = Old.Partition;
+ versionId = old.versionId;
+ visibility = old.visibility;
+ isUsedInRegularObj = old.isUsedInRegularObj;
+ exportDynamic = old.exportDynamic;
+ canInline = old.canInline;
+ traced = old.traced;
+ isPreemptible = old.isPreemptible;
+ scriptDefined = old.scriptDefined;
+ partition = old.partition;
// Symbol length is computed lazily. If we already know a symbol length,
// propagate it.
- if (NameData == Old.NameData && NameSize == 0 && Old.NameSize != 0)
- NameSize = Old.NameSize;
+ if (nameData == old.nameData && nameSize == 0 && old.nameSize != 0)
+ nameSize = old.nameSize;
// Print out a log message if --trace-symbol was specified.
// This is for debugging.
- if (Traced)
+ if (traced)
printTraceSymbol(this);
}
-void maybeWarnUnorderableSymbol(const Symbol *Sym);
+void maybeWarnUnorderableSymbol(const Symbol *sym);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 67b122dfdfc..8d1b55cf7f0 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -52,17 +52,17 @@ using llvm::support::endian::read32le;
using llvm::support::endian::write32le;
using llvm::support::endian::write64le;
-constexpr size_t MergeNoTailSection::NumShards;
+constexpr size_t MergeNoTailSection::numShards;
-static uint64_t readUint(uint8_t *Buf) {
- return Config->Is64 ? read64(Buf) : read32(Buf);
+static uint64_t readUint(uint8_t *buf) {
+ return config->is64 ? read64(buf) : read32(buf);
}
-static void writeUint(uint8_t *Buf, uint64_t Val) {
- if (Config->Is64)
- write64(Buf, Val);
+static void writeUint(uint8_t *buf, uint64_t val) {
+ if (config->is64)
+ write64(buf, val);
else
- write32(Buf, Val);
+ write32(buf, val);
}
// Returns an LLD version string.
@@ -70,12 +70,12 @@ static ArrayRef<uint8_t> getVersion() {
// Check LLD_VERSION first for ease of testing.
// You can get consistent output by using the environment variable.
// This is only for testing.
- StringRef S = getenv("LLD_VERSION");
- if (S.empty())
- S = Saver.save(Twine("Linker: ") + getLLDVersion());
+ StringRef s = getenv("LLD_VERSION");
+ if (s.empty())
+ s = Saver.save(Twine("Linker: ") + getLLDVersion());
// +1 to include the terminating '\0'.
- return {(const uint8_t *)S.data(), S.size() + 1};
+ return {(const uint8_t *)s.data(), s.size() + 1};
}
// Creates a .comment section containing LLD version info.
@@ -89,79 +89,79 @@ MergeInputSection *elf::createCommentSection() {
// .MIPS.abiflags section.
template <class ELFT>
-MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags)
+MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags flags)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ".MIPS.abiflags"),
- Flags(Flags) {
- this->Entsize = sizeof(Elf_Mips_ABIFlags);
+ flags(flags) {
+ this->entsize = sizeof(Elf_Mips_ABIFlags);
}
-template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *Buf) {
- memcpy(Buf, &Flags, sizeof(Flags));
+template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *buf) {
+ memcpy(buf, &flags, sizeof(flags));
}
template <class ELFT>
MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
- Elf_Mips_ABIFlags Flags = {};
- bool Create = false;
+ Elf_Mips_ABIFlags flags = {};
+ bool create = false;
- for (InputSectionBase *Sec : InputSections) {
- if (Sec->Type != SHT_MIPS_ABIFLAGS)
+ for (InputSectionBase *sec : inputSections) {
+ if (sec->type != SHT_MIPS_ABIFLAGS)
continue;
- Sec->markDead();
- Create = true;
+ sec->markDead();
+ create = true;
- std::string Filename = toString(Sec->File);
- const size_t Size = Sec->data().size();
+ std::string filename = toString(sec->file);
+ const size_t size = sec->data().size();
// Older version of BFD (such as the default FreeBSD linker) concatenate
// .MIPS.abiflags instead of merging. To allow for this case (or potential
// zero padding) we ignore everything after the first Elf_Mips_ABIFlags
- if (Size < sizeof(Elf_Mips_ABIFlags)) {
- error(Filename + ": invalid size of .MIPS.abiflags section: got " +
- Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
+ if (size < sizeof(Elf_Mips_ABIFlags)) {
+ error(filename + ": invalid size of .MIPS.abiflags section: got " +
+ Twine(size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
return nullptr;
}
- auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
- if (S->version != 0) {
- error(Filename + ": unexpected .MIPS.abiflags version " +
- Twine(S->version));
+ auto *s = reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->data().data());
+ if (s->version != 0) {
+ error(filename + ": unexpected .MIPS.abiflags version " +
+ Twine(s->version));
return nullptr;
}
// LLD checks ISA compatibility in calcMipsEFlags(). Here we just
// select the highest number of ISA/Rev/Ext.
- Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
- Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
- Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
- Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
- Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
- Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
- Flags.ases |= S->ases;
- Flags.flags1 |= S->flags1;
- Flags.flags2 |= S->flags2;
- Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, Filename);
+ flags.isa_level = std::max(flags.isa_level, s->isa_level);
+ flags.isa_rev = std::max(flags.isa_rev, s->isa_rev);
+ flags.isa_ext = std::max(flags.isa_ext, s->isa_ext);
+ flags.gpr_size = std::max(flags.gpr_size, s->gpr_size);
+ flags.cpr1_size = std::max(flags.cpr1_size, s->cpr1_size);
+ flags.cpr2_size = std::max(flags.cpr2_size, s->cpr2_size);
+ flags.ases |= s->ases;
+ flags.flags1 |= s->flags1;
+ flags.flags2 |= s->flags2;
+ flags.fp_abi = elf::getMipsFpAbiFlag(flags.fp_abi, s->fp_abi, filename);
};
- if (Create)
- return make<MipsAbiFlagsSection<ELFT>>(Flags);
+ if (create)
+ return make<MipsAbiFlagsSection<ELFT>>(flags);
return nullptr;
}
// .MIPS.options section.
template <class ELFT>
-MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo Reginfo)
+MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo reginfo)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"),
- Reginfo(Reginfo) {
- this->Entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
+ reginfo(reginfo) {
+ this->entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
}
-template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
- auto *Options = reinterpret_cast<Elf_Mips_Options *>(Buf);
- Options->kind = ODK_REGINFO;
- Options->size = getSize();
+template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) {
+ auto *options = reinterpret_cast<Elf_Mips_Options *>(buf);
+ options->kind = ODK_REGINFO;
+ options->size = getSize();
- if (!Config->Relocatable)
- Reginfo.ri_gp_value = In.MipsGot->getGp();
- memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
+ if (!config->relocatable)
+ reginfo.ri_gp_value = in.mipsGot->getGp();
+ memcpy(buf + sizeof(Elf_Mips_Options), &reginfo, sizeof(reginfo));
}
template <class ELFT>
@@ -170,55 +170,55 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
if (!ELFT::Is64Bits)
return nullptr;
- std::vector<InputSectionBase *> Sections;
- for (InputSectionBase *Sec : InputSections)
- if (Sec->Type == SHT_MIPS_OPTIONS)
- Sections.push_back(Sec);
+ std::vector<InputSectionBase *> sections;
+ for (InputSectionBase *sec : inputSections)
+ if (sec->type == SHT_MIPS_OPTIONS)
+ sections.push_back(sec);
- if (Sections.empty())
+ if (sections.empty())
return nullptr;
- Elf_Mips_RegInfo Reginfo = {};
- for (InputSectionBase *Sec : Sections) {
- Sec->markDead();
+ Elf_Mips_RegInfo reginfo = {};
+ for (InputSectionBase *sec : sections) {
+ sec->markDead();
- std::string Filename = toString(Sec->File);
- ArrayRef<uint8_t> D = Sec->data();
+ std::string filename = toString(sec->file);
+ ArrayRef<uint8_t> d = sec->data();
- while (!D.empty()) {
- if (D.size() < sizeof(Elf_Mips_Options)) {
- error(Filename + ": invalid size of .MIPS.options section");
+ while (!d.empty()) {
+ if (d.size() < sizeof(Elf_Mips_Options)) {
+ error(filename + ": invalid size of .MIPS.options section");
break;
}
- auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
- if (Opt->kind == ODK_REGINFO) {
- Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
- Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
+ auto *opt = reinterpret_cast<const Elf_Mips_Options *>(d.data());
+ if (opt->kind == ODK_REGINFO) {
+ reginfo.ri_gprmask |= opt->getRegInfo().ri_gprmask;
+ sec->getFile<ELFT>()->mipsGp0 = opt->getRegInfo().ri_gp_value;
break;
}
- if (!Opt->size)
- fatal(Filename + ": zero option descriptor size");
- D = D.slice(Opt->size);
+ if (!opt->size)
+ fatal(filename + ": zero option descriptor size");
+ d = d.slice(opt->size);
}
};
- return make<MipsOptionsSection<ELFT>>(Reginfo);
+ return make<MipsOptionsSection<ELFT>>(reginfo);
}
// MIPS .reginfo section.
template <class ELFT>
-MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
+MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo reginfo)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
- Reginfo(Reginfo) {
- this->Entsize = sizeof(Elf_Mips_RegInfo);
+ reginfo(reginfo) {
+ this->entsize = sizeof(Elf_Mips_RegInfo);
}
-template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
- if (!Config->Relocatable)
- Reginfo.ri_gp_value = In.MipsGot->getGp();
- memcpy(Buf, &Reginfo, sizeof(Reginfo));
+template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) {
+ if (!config->relocatable)
+ reginfo.ri_gp_value = in.mipsGot->getGp();
+ memcpy(buf, &reginfo, sizeof(reginfo));
}
template <class ELFT>
@@ -227,53 +227,53 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
if (ELFT::Is64Bits)
return nullptr;
- std::vector<InputSectionBase *> Sections;
- for (InputSectionBase *Sec : InputSections)
- if (Sec->Type == SHT_MIPS_REGINFO)
- Sections.push_back(Sec);
+ std::vector<InputSectionBase *> sections;
+ for (InputSectionBase *sec : inputSections)
+ if (sec->type == SHT_MIPS_REGINFO)
+ sections.push_back(sec);
- if (Sections.empty())
+ if (sections.empty())
return nullptr;
- Elf_Mips_RegInfo Reginfo = {};
- for (InputSectionBase *Sec : Sections) {
- Sec->markDead();
+ Elf_Mips_RegInfo reginfo = {};
+ for (InputSectionBase *sec : sections) {
+ sec->markDead();
- if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
- error(toString(Sec->File) + ": invalid size of .reginfo section");
+ if (sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
+ error(toString(sec->file) + ": invalid size of .reginfo section");
return nullptr;
}
- auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->data().data());
- Reginfo.ri_gprmask |= R->ri_gprmask;
- Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
+ auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->data().data());
+ reginfo.ri_gprmask |= r->ri_gprmask;
+ sec->getFile<ELFT>()->mipsGp0 = r->ri_gp_value;
};
- return make<MipsReginfoSection<ELFT>>(Reginfo);
+ return make<MipsReginfoSection<ELFT>>(reginfo);
}
InputSection *elf::createInterpSection() {
// StringSaver guarantees that the returned string ends with '\0'.
- StringRef S = Saver.save(Config->DynamicLinker);
- ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1};
+ StringRef s = Saver.save(config->dynamicLinker);
+ ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
- auto *Sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, Contents,
+ auto *sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents,
".interp");
- Sec->markLive();
- return Sec;
+ sec->markLive();
+ return sec;
}
-Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
- uint64_t Size, InputSectionBase &Section) {
- auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
- Value, Size, &Section);
- if (In.SymTab)
- In.SymTab->addSymbol(S);
- return S;
+Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
+ uint64_t size, InputSectionBase &section) {
+ auto *s = make<Defined>(section.file, name, STB_LOCAL, STV_DEFAULT, type,
+ value, size, &section);
+ if (in.symTab)
+ in.symTab->addSymbol(s);
+ return s;
}
static size_t getHashSize() {
- switch (Config->BuildId) {
+ switch (config->buildId) {
case BuildIdKind::Fast:
return 8;
case BuildIdKind::Md5:
@@ -282,7 +282,7 @@ static size_t getHashSize() {
case BuildIdKind::Sha1:
return 20;
case BuildIdKind::Hexstring:
- return Config->BuildIdVector.size();
+ return config->buildIdVector.size();
default:
llvm_unreachable("unknown BuildIdKind");
}
@@ -304,45 +304,45 @@ GnuPropertySection::GnuPropertySection()
: SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE, 4,
".note.gnu.property") {}
-void GnuPropertySection::writeTo(uint8_t *Buf) {
- uint32_t FeatureAndType = Config->EMachine == EM_AARCH64
+void GnuPropertySection::writeTo(uint8_t *buf) {
+ uint32_t featureAndType = config->emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;
- write32(Buf, 4); // Name size
- write32(Buf + 4, Config->Is64 ? 16 : 12); // Content size
- write32(Buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
- memcpy(Buf + 12, "GNU", 4); // Name string
- write32(Buf + 16, FeatureAndType); // Feature type
- write32(Buf + 20, 4); // Feature size
- write32(Buf + 24, Config->AndFeatures); // Feature flags
- if (Config->Is64)
- write32(Buf + 28, 0); // Padding
+ write32(buf, 4); // Name size
+ write32(buf + 4, config->is64 ? 16 : 12); // Content size
+ write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
+ memcpy(buf + 12, "GNU", 4); // Name string
+ write32(buf + 16, featureAndType); // Feature type
+ write32(buf + 20, 4); // Feature size
+ write32(buf + 24, config->andFeatures); // Feature flags
+ if (config->is64)
+ write32(buf + 28, 0); // Padding
}
-size_t GnuPropertySection::getSize() const { return Config->Is64 ? 32 : 28; }
+size_t GnuPropertySection::getSize() const { return config->is64 ? 32 : 28; }
BuildIdSection::BuildIdSection()
: SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
- HashSize(getHashSize()) {}
+ hashSize(getHashSize()) {}
-void BuildIdSection::writeTo(uint8_t *Buf) {
- write32(Buf, 4); // Name size
- write32(Buf + 4, HashSize); // Content size
- write32(Buf + 8, NT_GNU_BUILD_ID); // Type
- memcpy(Buf + 12, "GNU", 4); // Name string
- HashBuf = Buf + 16;
+void BuildIdSection::writeTo(uint8_t *buf) {
+ write32(buf, 4); // Name size
+ write32(buf + 4, hashSize); // Content size
+ write32(buf + 8, NT_GNU_BUILD_ID); // Type
+ memcpy(buf + 12, "GNU", 4); // Name string
+ hashBuf = buf + 16;
}
-void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
- assert(Buf.size() == HashSize);
- memcpy(HashBuf, Buf.data(), HashSize);
+void BuildIdSection::writeBuildId(ArrayRef<uint8_t> buf) {
+ assert(buf.size() == hashSize);
+ memcpy(hashBuf, buf.data(), hashSize);
}
-BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment)
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) {
- this->Bss = true;
- this->Size = Size;
+BssSection::BssSection(StringRef name, uint64_t size, uint32_t alignment)
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, alignment, name) {
+ this->bss = true;
+ this->size = size;
}
EhFrameSection::EhFrameSection()
@@ -352,48 +352,48 @@ EhFrameSection::EhFrameSection()
// CIE records from input object files are uniquified by their contents
// and where their relocations point to.
template <class ELFT, class RelTy>
-CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) {
- Symbol *Personality = nullptr;
- unsigned FirstRelI = Cie.FirstRelocation;
- if (FirstRelI != (unsigned)-1)
- Personality =
- &Cie.Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
+CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) {
+ Symbol *personality = nullptr;
+ unsigned firstRelI = cie.firstRelocation;
+ if (firstRelI != (unsigned)-1)
+ personality =
+ &cie.sec->template getFile<ELFT>()->getRelocTargetSym(rels[firstRelI]);
// Search for an existing CIE by CIE contents/relocation target pair.
- CieRecord *&Rec = CieMap[{Cie.data(), Personality}];
+ CieRecord *&rec = cieMap[{cie.data(), personality}];
// If not found, create a new one.
- if (!Rec) {
- Rec = make<CieRecord>();
- Rec->Cie = &Cie;
- CieRecords.push_back(Rec);
+ if (!rec) {
+ rec = make<CieRecord>();
+ rec->cie = &cie;
+ cieRecords.push_back(rec);
}
- return Rec;
+ return rec;
}
// There is one FDE per function. Returns true if a given FDE
// points to a live function.
template <class ELFT, class RelTy>
-bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
- auto *Sec = cast<EhInputSection>(Fde.Sec);
- unsigned FirstRelI = Fde.FirstRelocation;
+bool EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) {
+ auto *sec = cast<EhInputSection>(fde.sec);
+ unsigned firstRelI = fde.firstRelocation;
// An FDE should point to some function because FDEs are to describe
// functions. That's however not always the case due to an issue of
// ld.gold with -r. ld.gold may discard only functions and leave their
// corresponding FDEs, which results in creating bad .eh_frame sections.
// To deal with that, we ignore such FDEs.
- if (FirstRelI == (unsigned)-1)
+ if (firstRelI == (unsigned)-1)
return false;
- const RelTy &Rel = Rels[FirstRelI];
- Symbol &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel);
+ const RelTy &rel = rels[firstRelI];
+ Symbol &b = sec->template getFile<ELFT>()->getRelocTargetSym(rel);
// FDEs for garbage-collected or merged-by-ICF sections, or sections in
// another partition, are dead.
- if (auto *D = dyn_cast<Defined>(&B))
- if (SectionBase *Sec = D->Section)
- return Sec->Partition == Partition;
+ if (auto *d = dyn_cast<Defined>(&b))
+ if (SectionBase *sec = d->section)
+ return sec->partition == partition;
return false;
}
@@ -402,73 +402,73 @@ bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
// a list of FDEs. This function searches an existing CIE or create a new
// one and associates FDEs to the CIE.
template <class ELFT, class RelTy>
-void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
- OffsetToCie.clear();
- for (EhSectionPiece &Piece : Sec->Pieces) {
+void EhFrameSection::addSectionAux(EhInputSection *sec, ArrayRef<RelTy> rels) {
+ offsetToCie.clear();
+ for (EhSectionPiece &piece : sec->pieces) {
// The empty record is the end marker.
- if (Piece.Size == 4)
+ if (piece.size == 4)
return;
- size_t Offset = Piece.InputOff;
- uint32_t ID = read32(Piece.data().data() + 4);
- if (ID == 0) {
- OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels);
+ size_t offset = piece.inputOff;
+ uint32_t id = read32(piece.data().data() + 4);
+ if (id == 0) {
+ offsetToCie[offset] = addCie<ELFT>(piece, rels);
continue;
}
- uint32_t CieOffset = Offset + 4 - ID;
- CieRecord *Rec = OffsetToCie[CieOffset];
- if (!Rec)
- fatal(toString(Sec) + ": invalid CIE reference");
+ uint32_t cieOffset = offset + 4 - id;
+ CieRecord *rec = offsetToCie[cieOffset];
+ if (!rec)
+ fatal(toString(sec) + ": invalid CIE reference");
- if (!isFdeLive<ELFT>(Piece, Rels))
+ if (!isFdeLive<ELFT>(piece, rels))
continue;
- Rec->Fdes.push_back(&Piece);
- NumFdes++;
+ rec->fdes.push_back(&piece);
+ numFdes++;
}
}
-template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) {
- auto *Sec = cast<EhInputSection>(C);
- Sec->Parent = this;
+template <class ELFT> void EhFrameSection::addSection(InputSectionBase *c) {
+ auto *sec = cast<EhInputSection>(c);
+ sec->parent = this;
- Alignment = std::max(Alignment, Sec->Alignment);
- Sections.push_back(Sec);
+ alignment = std::max(alignment, sec->alignment);
+ sections.push_back(sec);
- for (auto *DS : Sec->DependentSections)
- DependentSections.push_back(DS);
+ for (auto *ds : sec->dependentSections)
+ dependentSections.push_back(ds);
- if (Sec->Pieces.empty())
+ if (sec->pieces.empty())
return;
- if (Sec->AreRelocsRela)
- addSectionAux<ELFT>(Sec, Sec->template relas<ELFT>());
+ if (sec->areRelocsRela)
+ addSectionAux<ELFT>(sec, sec->template relas<ELFT>());
else
- addSectionAux<ELFT>(Sec, Sec->template rels<ELFT>());
+ addSectionAux<ELFT>(sec, sec->template rels<ELFT>());
}
-static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
- memcpy(Buf, D.data(), D.size());
+static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
+ memcpy(buf, d.data(), d.size());
- size_t Aligned = alignTo(D.size(), Config->Wordsize);
+ size_t aligned = alignTo(d.size(), config->wordsize);
// Zero-clear trailing padding if it exists.
- memset(Buf + D.size(), 0, Aligned - D.size());
+ memset(buf + d.size(), 0, aligned - d.size());
// Fix the size field. -4 since size does not include the size field itself.
- write32(Buf, Aligned - 4);
+ write32(buf, aligned - 4);
}
void EhFrameSection::finalizeContents() {
- assert(!this->Size); // Not finalized.
- size_t Off = 0;
- for (CieRecord *Rec : CieRecords) {
- Rec->Cie->OutputOff = Off;
- Off += alignTo(Rec->Cie->Size, Config->Wordsize);
-
- for (EhSectionPiece *Fde : Rec->Fdes) {
- Fde->OutputOff = Off;
- Off += alignTo(Fde->Size, Config->Wordsize);
+ assert(!this->size); // Not finalized.
+ size_t off = 0;
+ for (CieRecord *rec : cieRecords) {
+ rec->cie->outputOff = off;
+ off += alignTo(rec->cie->size, config->wordsize);
+
+ for (EhSectionPiece *fde : rec->fdes) {
+ fde->outputOff = off;
+ off += alignTo(fde->size, config->wordsize);
}
}
@@ -476,376 +476,376 @@ void EhFrameSection::finalizeContents() {
// Call Frame Information records. glibc unwind-dw2-fde.c
// classify_object_over_fdes expects there is a CIE record length 0 as a
// terminator. Thus we add one unconditionally.
- Off += 4;
+ off += 4;
- this->Size = Off;
+ this->size = off;
}
// Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
// to get an FDE from an address to which FDE is applied. This function
// returns a list of such pairs.
std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
- uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
- std::vector<FdeData> Ret;
-
- uint64_t VA = getPartition().EhFrameHdr->getVA();
- for (CieRecord *Rec : CieRecords) {
- uint8_t Enc = getFdeEncoding(Rec->Cie);
- for (EhSectionPiece *Fde : Rec->Fdes) {
- uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
- uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
- if (!isInt<32>(Pc - VA))
- fatal(toString(Fde->Sec) + ": PC offset is too large: 0x" +
- Twine::utohexstr(Pc - VA));
- Ret.push_back({uint32_t(Pc - VA), uint32_t(FdeVA - VA)});
+ uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
+ std::vector<FdeData> ret;
+
+ uint64_t va = getPartition().ehFrameHdr->getVA();
+ for (CieRecord *rec : cieRecords) {
+ uint8_t enc = getFdeEncoding(rec->cie);
+ for (EhSectionPiece *fde : rec->fdes) {
+ uint64_t pc = getFdePc(buf, fde->outputOff, enc);
+ uint64_t fdeVA = getParent()->addr + fde->outputOff;
+ if (!isInt<32>(pc - va))
+ fatal(toString(fde->sec) + ": PC offset is too large: 0x" +
+ Twine::utohexstr(pc - va));
+ ret.push_back({uint32_t(pc - va), uint32_t(fdeVA - va)});
}
}
// Sort the FDE list by their PC and uniqueify. Usually there is only
// one FDE for a PC (i.e. function), but if ICF merges two functions
// into one, there can be more than one FDEs pointing to the address.
- auto Less = [](const FdeData &A, const FdeData &B) {
- return A.PcRel < B.PcRel;
+ auto less = [](const FdeData &a, const FdeData &b) {
+ return a.pcRel < b.pcRel;
};
- llvm::stable_sort(Ret, Less);
- auto Eq = [](const FdeData &A, const FdeData &B) {
- return A.PcRel == B.PcRel;
+ llvm::stable_sort(ret, less);
+ auto eq = [](const FdeData &a, const FdeData &b) {
+ return a.pcRel == b.pcRel;
};
- Ret.erase(std::unique(Ret.begin(), Ret.end(), Eq), Ret.end());
+ ret.erase(std::unique(ret.begin(), ret.end(), eq), ret.end());
- return Ret;
+ return ret;
}
-static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
- switch (Size) {
+static uint64_t readFdeAddr(uint8_t *buf, int size) {
+ switch (size) {
case DW_EH_PE_udata2:
- return read16(Buf);
+ return read16(buf);
case DW_EH_PE_sdata2:
- return (int16_t)read16(Buf);
+ return (int16_t)read16(buf);
case DW_EH_PE_udata4:
- return read32(Buf);
+ return read32(buf);
case DW_EH_PE_sdata4:
- return (int32_t)read32(Buf);
+ return (int32_t)read32(buf);
case DW_EH_PE_udata8:
case DW_EH_PE_sdata8:
- return read64(Buf);
+ return read64(buf);
case DW_EH_PE_absptr:
- return readUint(Buf);
+ return readUint(buf);
}
fatal("unknown FDE size encoding");
}
// Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to.
// We need it to create .eh_frame_hdr section.
-uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff,
- uint8_t Enc) const {
+uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
+ uint8_t enc) const {
// The starting address to which this FDE applies is
// stored at FDE + 8 byte.
- size_t Off = FdeOff + 8;
- uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf);
- if ((Enc & 0x70) == DW_EH_PE_absptr)
- return Addr;
- if ((Enc & 0x70) == DW_EH_PE_pcrel)
- return Addr + getParent()->Addr + Off;
+ size_t off = fdeOff + 8;
+ uint64_t addr = readFdeAddr(buf + off, enc & 0xf);
+ if ((enc & 0x70) == DW_EH_PE_absptr)
+ return addr;
+ if ((enc & 0x70) == DW_EH_PE_pcrel)
+ return addr + getParent()->addr + off;
fatal("unknown FDE size relative encoding");
}
-void EhFrameSection::writeTo(uint8_t *Buf) {
+void EhFrameSection::writeTo(uint8_t *buf) {
// Write CIE and FDE records.
- for (CieRecord *Rec : CieRecords) {
- size_t CieOffset = Rec->Cie->OutputOff;
- writeCieFde(Buf + CieOffset, Rec->Cie->data());
+ for (CieRecord *rec : cieRecords) {
+ size_t cieOffset = rec->cie->outputOff;
+ writeCieFde(buf + cieOffset, rec->cie->data());
- for (EhSectionPiece *Fde : Rec->Fdes) {
- size_t Off = Fde->OutputOff;
- writeCieFde(Buf + Off, Fde->data());
+ for (EhSectionPiece *fde : rec->fdes) {
+ size_t off = fde->outputOff;
+ writeCieFde(buf + off, fde->data());
// FDE's second word should have the offset to an associated CIE.
// Write it.
- write32(Buf + Off + 4, Off + 4 - CieOffset);
+ write32(buf + off + 4, off + 4 - cieOffset);
}
}
// Apply relocations. .eh_frame section contents are not contiguous
// in the output buffer, but relocateAlloc() still works because
// getOffset() takes care of discontiguous section pieces.
- for (EhInputSection *S : Sections)
- S->relocateAlloc(Buf, nullptr);
+ for (EhInputSection *s : sections)
+ s->relocateAlloc(buf, nullptr);
- if (getPartition().EhFrameHdr && getPartition().EhFrameHdr->getParent())
- getPartition().EhFrameHdr->write();
+ if (getPartition().ehFrameHdr && getPartition().ehFrameHdr->getParent())
+ getPartition().ehFrameHdr->write();
}
GotSection::GotSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".got") {
// PPC64 saves the ElfSym::GlobalOffsetTable .TOC. as the first entry in the
// .got. If there are no references to .TOC. in the symbol table,
// ElfSym::GlobalOffsetTable will not be defined and we won't need to save
// .TOC. in the .got. When it is defined, we increase NumEntries by the number
// of entries used to emit ElfSym::GlobalOffsetTable.
- if (ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt)
- NumEntries += Target->GotHeaderEntriesNum;
+ if (ElfSym::globalOffsetTable && !target->gotBaseSymInGotPlt)
+ numEntries += target->gotHeaderEntriesNum;
}
-void GotSection::addEntry(Symbol &Sym) {
- Sym.GotIndex = NumEntries;
- ++NumEntries;
+void GotSection::addEntry(Symbol &sym) {
+ sym.gotIndex = numEntries;
+ ++numEntries;
}
-bool GotSection::addDynTlsEntry(Symbol &Sym) {
- if (Sym.GlobalDynIndex != -1U)
+bool GotSection::addDynTlsEntry(Symbol &sym) {
+ if (sym.globalDynIndex != -1U)
return false;
- Sym.GlobalDynIndex = NumEntries;
+ sym.globalDynIndex = numEntries;
// Global Dynamic TLS entries take two GOT slots.
- NumEntries += 2;
+ numEntries += 2;
return true;
}
// Reserves TLS entries for a TLS module ID and a TLS block offset.
// In total it takes two GOT slots.
bool GotSection::addTlsIndex() {
- if (TlsIndexOff != uint32_t(-1))
+ if (tlsIndexOff != uint32_t(-1))
return false;
- TlsIndexOff = NumEntries * Config->Wordsize;
- NumEntries += 2;
+ tlsIndexOff = numEntries * config->wordsize;
+ numEntries += 2;
return true;
}
-uint64_t GotSection::getGlobalDynAddr(const Symbol &B) const {
- return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
+uint64_t GotSection::getGlobalDynAddr(const Symbol &b) const {
+ return this->getVA() + b.globalDynIndex * config->wordsize;
}
-uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const {
- return B.GlobalDynIndex * Config->Wordsize;
+uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
+ return b.globalDynIndex * config->wordsize;
}
void GotSection::finalizeContents() {
- Size = NumEntries * Config->Wordsize;
+ size = numEntries * config->wordsize;
}
bool GotSection::isNeeded() const {
// We need to emit a GOT even if it's empty if there's a relocation that is
// relative to GOT(such as GOTOFFREL).
- return NumEntries || HasGotOffRel;
+ return numEntries || hasGotOffRel;
}
-void GotSection::writeTo(uint8_t *Buf) {
+void GotSection::writeTo(uint8_t *buf) {
// Buf points to the start of this section's buffer,
// whereas InputSectionBase::relocateAlloc() expects its argument
// to point to the start of the output section.
- Target->writeGotHeader(Buf);
- relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
+ target->writeGotHeader(buf);
+ relocateAlloc(buf - outSecOff, buf - outSecOff + size);
}
-static uint64_t getMipsPageAddr(uint64_t Addr) {
- return (Addr + 0x8000) & ~0xffff;
+static uint64_t getMipsPageAddr(uint64_t addr) {
+ return (addr + 0x8000) & ~0xffff;
}
-static uint64_t getMipsPageCount(uint64_t Size) {
- return (Size + 0xfffe) / 0xffff + 1;
+static uint64_t getMipsPageCount(uint64_t size) {
+ return (size + 0xfffe) / 0xffff + 1;
}
MipsGotSection::MipsGotSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
".got") {}
-void MipsGotSection::addEntry(InputFile &File, Symbol &Sym, int64_t Addend,
- RelExpr Expr) {
- FileGot &G = getGot(File);
- if (Expr == R_MIPS_GOT_LOCAL_PAGE) {
- if (const OutputSection *OS = Sym.getOutputSection())
- G.PagesMap.insert({OS, {}});
+void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
+ RelExpr expr) {
+ FileGot &g = getGot(file);
+ if (expr == R_MIPS_GOT_LOCAL_PAGE) {
+ if (const OutputSection *os = sym.getOutputSection())
+ g.pagesMap.insert({os, {}});
else
- G.Local16.insert({{nullptr, getMipsPageAddr(Sym.getVA(Addend))}, 0});
- } else if (Sym.isTls())
- G.Tls.insert({&Sym, 0});
- else if (Sym.IsPreemptible && Expr == R_ABS)
- G.Relocs.insert({&Sym, 0});
- else if (Sym.IsPreemptible)
- G.Global.insert({&Sym, 0});
- else if (Expr == R_MIPS_GOT_OFF32)
- G.Local32.insert({{&Sym, Addend}, 0});
+ g.local16.insert({{nullptr, getMipsPageAddr(sym.getVA(addend))}, 0});
+ } else if (sym.isTls())
+ g.tls.insert({&sym, 0});
+ else if (sym.isPreemptible && expr == R_ABS)
+ g.relocs.insert({&sym, 0});
+ else if (sym.isPreemptible)
+ g.global.insert({&sym, 0});
+ else if (expr == R_MIPS_GOT_OFF32)
+ g.local32.insert({{&sym, addend}, 0});
else
- G.Local16.insert({{&Sym, Addend}, 0});
+ g.local16.insert({{&sym, addend}, 0});
}
-void MipsGotSection::addDynTlsEntry(InputFile &File, Symbol &Sym) {
- getGot(File).DynTlsSymbols.insert({&Sym, 0});
+void MipsGotSection::addDynTlsEntry(InputFile &file, Symbol &sym) {
+ getGot(file).dynTlsSymbols.insert({&sym, 0});
}
-void MipsGotSection::addTlsIndex(InputFile &File) {
- getGot(File).DynTlsSymbols.insert({nullptr, 0});
+void MipsGotSection::addTlsIndex(InputFile &file) {
+ getGot(file).dynTlsSymbols.insert({nullptr, 0});
}
size_t MipsGotSection::FileGot::getEntriesNum() const {
- return getPageEntriesNum() + Local16.size() + Global.size() + Relocs.size() +
- Tls.size() + DynTlsSymbols.size() * 2;
+ return getPageEntriesNum() + local16.size() + global.size() + relocs.size() +
+ tls.size() + dynTlsSymbols.size() * 2;
}
size_t MipsGotSection::FileGot::getPageEntriesNum() const {
- size_t Num = 0;
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &P : PagesMap)
- Num += P.second.Count;
- return Num;
+ size_t num = 0;
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &p : pagesMap)
+ num += p.second.count;
+ return num;
}
size_t MipsGotSection::FileGot::getIndexedEntriesNum() const {
- size_t Count = getPageEntriesNum() + Local16.size() + Global.size();
+ size_t count = getPageEntriesNum() + local16.size() + global.size();
// If there are relocation-only entries in the GOT, TLS entries
// are allocated after them. TLS entries should be addressable
// by 16-bit index so count both reloc-only and TLS entries.
- if (!Tls.empty() || !DynTlsSymbols.empty())
- Count += Relocs.size() + Tls.size() + DynTlsSymbols.size() * 2;
- return Count;
+ if (!tls.empty() || !dynTlsSymbols.empty())
+ count += relocs.size() + tls.size() + dynTlsSymbols.size() * 2;
+ return count;
}
-MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &F) {
- if (!F.MipsGotIndex.hasValue()) {
- Gots.emplace_back();
- Gots.back().File = &F;
- F.MipsGotIndex = Gots.size() - 1;
+MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &f) {
+ if (!f.mipsGotIndex.hasValue()) {
+ gots.emplace_back();
+ gots.back().file = &f;
+ f.mipsGotIndex = gots.size() - 1;
}
- return Gots[*F.MipsGotIndex];
+ return gots[*f.mipsGotIndex];
}
-uint64_t MipsGotSection::getPageEntryOffset(const InputFile *F,
- const Symbol &Sym,
- int64_t Addend) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- uint64_t Index = 0;
- if (const OutputSection *OutSec = Sym.getOutputSection()) {
- uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
- uint64_t SymAddr = getMipsPageAddr(Sym.getVA(Addend));
- Index = G.PagesMap.lookup(OutSec).FirstIndex + (SymAddr - SecAddr) / 0xffff;
+uint64_t MipsGotSection::getPageEntryOffset(const InputFile *f,
+ const Symbol &sym,
+ int64_t addend) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ uint64_t index = 0;
+ if (const OutputSection *outSec = sym.getOutputSection()) {
+ uint64_t secAddr = getMipsPageAddr(outSec->addr);
+ uint64_t symAddr = getMipsPageAddr(sym.getVA(addend));
+ index = g.pagesMap.lookup(outSec).firstIndex + (symAddr - secAddr) / 0xffff;
} else {
- Index = G.Local16.lookup({nullptr, getMipsPageAddr(Sym.getVA(Addend))});
+ index = g.local16.lookup({nullptr, getMipsPageAddr(sym.getVA(addend))});
}
- return Index * Config->Wordsize;
+ return index * config->wordsize;
}
-uint64_t MipsGotSection::getSymEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- Symbol *Sym = const_cast<Symbol *>(&S);
- if (Sym->isTls())
- return G.Tls.lookup(Sym) * Config->Wordsize;
- if (Sym->IsPreemptible)
- return G.Global.lookup(Sym) * Config->Wordsize;
- return G.Local16.lookup({Sym, Addend}) * Config->Wordsize;
+uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ Symbol *sym = const_cast<Symbol *>(&s);
+ if (sym->isTls())
+ return g.tls.lookup(sym) * config->wordsize;
+ if (sym->isPreemptible)
+ return g.global.lookup(sym) * config->wordsize;
+ return g.local16.lookup({sym, addend}) * config->wordsize;
}
-uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *F) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- return G.DynTlsSymbols.lookup(nullptr) * Config->Wordsize;
+uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *f) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ return g.dynTlsSymbols.lookup(nullptr) * config->wordsize;
}
-uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *F,
- const Symbol &S) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- Symbol *Sym = const_cast<Symbol *>(&S);
- return G.DynTlsSymbols.lookup(Sym) * Config->Wordsize;
+uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *f,
+ const Symbol &s) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ Symbol *sym = const_cast<Symbol *>(&s);
+ return g.dynTlsSymbols.lookup(sym) * config->wordsize;
}
const Symbol *MipsGotSection::getFirstGlobalEntry() const {
- if (Gots.empty())
+ if (gots.empty())
return nullptr;
- const FileGot &PrimGot = Gots.front();
- if (!PrimGot.Global.empty())
- return PrimGot.Global.front().first;
- if (!PrimGot.Relocs.empty())
- return PrimGot.Relocs.front().first;
+ const FileGot &primGot = gots.front();
+ if (!primGot.global.empty())
+ return primGot.global.front().first;
+ if (!primGot.relocs.empty())
+ return primGot.relocs.front().first;
return nullptr;
}
unsigned MipsGotSection::getLocalEntriesNum() const {
- if (Gots.empty())
- return HeaderEntriesNum;
- return HeaderEntriesNum + Gots.front().getPageEntriesNum() +
- Gots.front().Local16.size();
+ if (gots.empty())
+ return headerEntriesNum;
+ return headerEntriesNum + gots.front().getPageEntriesNum() +
+ gots.front().local16.size();
}
-bool MipsGotSection::tryMergeGots(FileGot &Dst, FileGot &Src, bool IsPrimary) {
- FileGot Tmp = Dst;
- set_union(Tmp.PagesMap, Src.PagesMap);
- set_union(Tmp.Local16, Src.Local16);
- set_union(Tmp.Global, Src.Global);
- set_union(Tmp.Relocs, Src.Relocs);
- set_union(Tmp.Tls, Src.Tls);
- set_union(Tmp.DynTlsSymbols, Src.DynTlsSymbols);
+bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) {
+ FileGot tmp = dst;
+ set_union(tmp.pagesMap, src.pagesMap);
+ set_union(tmp.local16, src.local16);
+ set_union(tmp.global, src.global);
+ set_union(tmp.relocs, src.relocs);
+ set_union(tmp.tls, src.tls);
+ set_union(tmp.dynTlsSymbols, src.dynTlsSymbols);
- size_t Count = IsPrimary ? HeaderEntriesNum : 0;
- Count += Tmp.getIndexedEntriesNum();
+ size_t count = isPrimary ? headerEntriesNum : 0;
+ count += tmp.getIndexedEntriesNum();
- if (Count * Config->Wordsize > Config->MipsGotSize)
+ if (count * config->wordsize > config->mipsGotSize)
return false;
- std::swap(Tmp, Dst);
+ std::swap(tmp, dst);
return true;
}
void MipsGotSection::finalizeContents() { updateAllocSize(); }
bool MipsGotSection::updateAllocSize() {
- Size = HeaderEntriesNum * Config->Wordsize;
- for (const FileGot &G : Gots)
- Size += G.getEntriesNum() * Config->Wordsize;
+ size = headerEntriesNum * config->wordsize;
+ for (const FileGot &g : gots)
+ size += g.getEntriesNum() * config->wordsize;
return false;
}
void MipsGotSection::build() {
- if (Gots.empty())
+ if (gots.empty())
return;
- std::vector<FileGot> MergedGots(1);
+ std::vector<FileGot> mergedGots(1);
// For each GOT move non-preemptible symbols from the `Global`
// to `Local16` list. Preemptible symbol might become non-preemptible
// one if, for example, it gets a related copy relocation.
- for (FileGot &Got : Gots) {
- for (auto &P: Got.Global)
- if (!P.first->IsPreemptible)
- Got.Local16.insert({{P.first, 0}, 0});
- Got.Global.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return !P.first->IsPreemptible;
+ for (FileGot &got : gots) {
+ for (auto &p: got.global)
+ if (!p.first->isPreemptible)
+ got.local16.insert({{p.first, 0}, 0});
+ got.global.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return !p.first->isPreemptible;
});
}
// For each GOT remove "reloc-only" entry if there is "global"
// entry for the same symbol. And add local entries which indexed
// using 32-bit value at the end of 16-bit entries.
- for (FileGot &Got : Gots) {
- Got.Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return Got.Global.count(P.first);
+ for (FileGot &got : gots) {
+ got.relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return got.global.count(p.first);
});
- set_union(Got.Local16, Got.Local32);
- Got.Local32.clear();
+ set_union(got.local16, got.local32);
+ got.local32.clear();
}
// Evaluate number of "reloc-only" entries in the resulting GOT.
// To do that put all unique "reloc-only" and "global" entries
// from all GOTs to the future primary GOT.
- FileGot *PrimGot = &MergedGots.front();
- for (FileGot &Got : Gots) {
- set_union(PrimGot->Relocs, Got.Global);
- set_union(PrimGot->Relocs, Got.Relocs);
- Got.Relocs.clear();
+ FileGot *primGot = &mergedGots.front();
+ for (FileGot &got : gots) {
+ set_union(primGot->relocs, got.global);
+ set_union(primGot->relocs, got.relocs);
+ got.relocs.clear();
}
// Evaluate number of "page" entries in each GOT.
- for (FileGot &Got : Gots) {
- for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
- Got.PagesMap) {
- const OutputSection *OS = P.first;
- uint64_t SecSize = 0;
- for (BaseCommand *Cmd : OS->SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
- for (InputSection *IS : ISD->Sections) {
- uint64_t Off = alignTo(SecSize, IS->Alignment);
- SecSize = Off + IS->getSize();
+ for (FileGot &got : gots) {
+ for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
+ got.pagesMap) {
+ const OutputSection *os = p.first;
+ uint64_t secSize = 0;
+ for (BaseCommand *cmd : os->sectionCommands) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
+ for (InputSection *isec : isd->sections) {
+ uint64_t off = alignTo(secSize, isec->alignment);
+ secSize = off + isec->getSize();
}
}
- P.second.Count = getMipsPageCount(SecSize);
+ p.second.count = getMipsPageCount(secSize);
}
}
@@ -854,128 +854,128 @@ void MipsGotSection::build() {
// the primary GOT can be accessed in the most effective way. If it
// is not possible, try to fill the last GOT in the list, and finally
// create a new GOT if both attempts failed.
- for (FileGot &SrcGot : Gots) {
- InputFile *File = SrcGot.File;
- if (tryMergeGots(MergedGots.front(), SrcGot, true)) {
- File->MipsGotIndex = 0;
+ for (FileGot &srcGot : gots) {
+ InputFile *file = srcGot.file;
+ if (tryMergeGots(mergedGots.front(), srcGot, true)) {
+ file->mipsGotIndex = 0;
} else {
// If this is the first time we failed to merge with the primary GOT,
// MergedGots.back() will also be the primary GOT. We must make sure not
// to try to merge again with IsPrimary=false, as otherwise, if the
// inputs are just right, we could allow the primary GOT to become 1 or 2
// words too big due to ignoring the header size.
- if (MergedGots.size() == 1 ||
- !tryMergeGots(MergedGots.back(), SrcGot, false)) {
- MergedGots.emplace_back();
- std::swap(MergedGots.back(), SrcGot);
+ if (mergedGots.size() == 1 ||
+ !tryMergeGots(mergedGots.back(), srcGot, false)) {
+ mergedGots.emplace_back();
+ std::swap(mergedGots.back(), srcGot);
}
- File->MipsGotIndex = MergedGots.size() - 1;
+ file->mipsGotIndex = mergedGots.size() - 1;
}
}
- std::swap(Gots, MergedGots);
+ std::swap(gots, mergedGots);
// Reduce number of "reloc-only" entries in the primary GOT
// by substracting "global" entries exist in the primary GOT.
- PrimGot = &Gots.front();
- PrimGot->Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return PrimGot->Global.count(P.first);
+ primGot = &gots.front();
+ primGot->relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return primGot->global.count(p.first);
});
// Calculate indexes for each GOT entry.
- size_t Index = HeaderEntriesNum;
- for (FileGot &Got : Gots) {
- Got.StartIndex = &Got == PrimGot ? 0 : Index;
- for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
- Got.PagesMap) {
+ size_t index = headerEntriesNum;
+ for (FileGot &got : gots) {
+ got.startIndex = &got == primGot ? 0 : index;
+ for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
+ got.pagesMap) {
// For each output section referenced by GOT page relocations calculate
// and save into PagesMap an upper bound of MIPS GOT entries required
// to store page addresses of local symbols. We assume the worst case -
// each 64kb page of the output section has at least one GOT relocation
// against it. And take in account the case when the section intersects
// page boundaries.
- P.second.FirstIndex = Index;
- Index += P.second.Count;
+ p.second.firstIndex = index;
+ index += p.second.count;
}
- for (auto &P: Got.Local16)
- P.second = Index++;
- for (auto &P: Got.Global)
- P.second = Index++;
- for (auto &P: Got.Relocs)
- P.second = Index++;
- for (auto &P: Got.Tls)
- P.second = Index++;
- for (auto &P: Got.DynTlsSymbols) {
- P.second = Index;
- Index += 2;
+ for (auto &p: got.local16)
+ p.second = index++;
+ for (auto &p: got.global)
+ p.second = index++;
+ for (auto &p: got.relocs)
+ p.second = index++;
+ for (auto &p: got.tls)
+ p.second = index++;
+ for (auto &p: got.dynTlsSymbols) {
+ p.second = index;
+ index += 2;
}
}
// Update Symbol::GotIndex field to use this
// value later in the `sortMipsSymbols` function.
- for (auto &P : PrimGot->Global)
- P.first->GotIndex = P.second;
- for (auto &P : PrimGot->Relocs)
- P.first->GotIndex = P.second;
+ for (auto &p : primGot->global)
+ p.first->gotIndex = p.second;
+ for (auto &p : primGot->relocs)
+ p.first->gotIndex = p.second;
// Create dynamic relocations.
- for (FileGot &Got : Gots) {
+ for (FileGot &got : gots) {
// Create dynamic relocations for TLS entries.
- for (std::pair<Symbol *, size_t> &P : Got.Tls) {
- Symbol *S = P.first;
- uint64_t Offset = P.second * Config->Wordsize;
- if (S->IsPreemptible)
- Main->RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
+ for (std::pair<Symbol *, size_t> &p : got.tls) {
+ Symbol *s = p.first;
+ uint64_t offset = p.second * config->wordsize;
+ if (s->isPreemptible)
+ mainPart->relaDyn->addReloc(target->tlsGotRel, this, offset, s);
}
- for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
- Symbol *S = P.first;
- uint64_t Offset = P.second * Config->Wordsize;
- if (S == nullptr) {
- if (!Config->Pic)
+ for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
+ Symbol *s = p.first;
+ uint64_t offset = p.second * config->wordsize;
+ if (s == nullptr) {
+ if (!config->isPic)
continue;
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
} else {
// When building a shared library we still need a dynamic relocation
// for the module index. Therefore only checking for
// S->IsPreemptible is not sufficient (this happens e.g. for
// thread-locals that have been marked as local through a linker script)
- if (!S->IsPreemptible && !Config->Pic)
+ if (!s->isPreemptible && !config->isPic)
continue;
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
// However, we can skip writing the TLS offset reloc for non-preemptible
// symbols since it is known even in shared libraries
- if (!S->IsPreemptible)
+ if (!s->isPreemptible)
continue;
- Offset += Config->Wordsize;
- Main->RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
+ offset += config->wordsize;
+ mainPart->relaDyn->addReloc(target->tlsOffsetRel, this, offset, s);
}
}
// Do not create dynamic relocations for non-TLS
// entries in the primary GOT.
- if (&Got == PrimGot)
+ if (&got == primGot)
continue;
// Dynamic relocations for "global" entries.
- for (const std::pair<Symbol *, size_t> &P : Got.Global) {
- uint64_t Offset = P.second * Config->Wordsize;
- Main->RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
+ for (const std::pair<Symbol *, size_t> &p : got.global) {
+ uint64_t offset = p.second * config->wordsize;
+ mainPart->relaDyn->addReloc(target->relativeRel, this, offset, p.first);
}
- if (!Config->Pic)
+ if (!config->isPic)
continue;
// Dynamic relocations for "local" entries in case of PIC.
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
- Got.PagesMap) {
- size_t PageCount = L.second.Count;
- for (size_t PI = 0; PI < PageCount; ++PI) {
- uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
- Main->RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
- int64_t(PI * 0x10000)});
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
+ got.pagesMap) {
+ size_t pageCount = l.second.count;
+ for (size_t pi = 0; pi < pageCount; ++pi) {
+ uint64_t offset = (l.second.firstIndex + pi) * config->wordsize;
+ mainPart->relaDyn->addReloc({target->relativeRel, this, offset, l.first,
+ int64_t(pi * 0x10000)});
}
}
- for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
- uint64_t Offset = P.second * Config->Wordsize;
- Main->RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
- P.first.first, P.first.second});
+ for (const std::pair<GotEntry, size_t> &p : got.local16) {
+ uint64_t offset = p.second * config->wordsize;
+ mainPart->relaDyn->addReloc({target->relativeRel, this, offset, true,
+ p.first.first, p.first.second});
}
}
}
@@ -983,20 +983,20 @@ void MipsGotSection::build() {
bool MipsGotSection::isNeeded() const {
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
- return !Config->Relocatable;
+ return !config->relocatable;
}
-uint64_t MipsGotSection::getGp(const InputFile *F) const {
+uint64_t MipsGotSection::getGp(const InputFile *f) const {
// For files without related GOT or files refer a primary GOT
// returns "common" _gp value. For secondary GOTs calculate
// individual _gp values.
- if (!F || !F->MipsGotIndex.hasValue() || *F->MipsGotIndex == 0)
- return ElfSym::MipsGp->getVA(0);
- return getVA() + Gots[*F->MipsGotIndex].StartIndex * Config->Wordsize +
+ if (!f || !f->mipsGotIndex.hasValue() || *f->mipsGotIndex == 0)
+ return ElfSym::mipsGp->getVA(0);
+ return getVA() + gots[*f->mipsGotIndex].startIndex * config->wordsize +
0x7ff0;
}
-void MipsGotSection::writeTo(uint8_t *Buf) {
+void MipsGotSection::writeTo(uint8_t *buf) {
// Set the MSB of the second GOT slot. This is not required by any
// MIPS ABI documentation, though.
//
@@ -1011,48 +1011,48 @@ void MipsGotSection::writeTo(uint8_t *Buf) {
// we've been doing this for years, it is probably a safe bet to
// keep doing this for now. We really need to revisit this to see
// if we had to do this.
- writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1));
- for (const FileGot &G : Gots) {
- auto Write = [&](size_t I, const Symbol *S, int64_t A) {
- uint64_t VA = A;
- if (S)
- VA = S->getVA(A);
- writeUint(Buf + I * Config->Wordsize, VA);
+ writeUint(buf + config->wordsize, (uint64_t)1 << (config->wordsize * 8 - 1));
+ for (const FileGot &g : gots) {
+ auto write = [&](size_t i, const Symbol *s, int64_t a) {
+ uint64_t va = a;
+ if (s)
+ va = s->getVA(a);
+ writeUint(buf + i * config->wordsize, va);
};
// Write 'page address' entries to the local part of the GOT.
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
- G.PagesMap) {
- size_t PageCount = L.second.Count;
- uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
- for (size_t PI = 0; PI < PageCount; ++PI)
- Write(L.second.FirstIndex + PI, nullptr, FirstPageAddr + PI * 0x10000);
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
+ g.pagesMap) {
+ size_t pageCount = l.second.count;
+ uint64_t firstPageAddr = getMipsPageAddr(l.first->addr);
+ for (size_t pi = 0; pi < pageCount; ++pi)
+ write(l.second.firstIndex + pi, nullptr, firstPageAddr + pi * 0x10000);
}
// Local, global, TLS, reloc-only entries.
// If TLS entry has a corresponding dynamic relocations, leave it
// initialized by zero. Write down adjusted TLS symbol's values otherwise.
// To calculate the adjustments use offsets for thread-local storage.
// https://www.linux-mips.org/wiki/NPTL
- for (const std::pair<GotEntry, size_t> &P : G.Local16)
- Write(P.second, P.first.first, P.first.second);
+ for (const std::pair<GotEntry, size_t> &p : g.local16)
+ write(p.second, p.first.first, p.first.second);
// Write VA to the primary GOT only. For secondary GOTs that
// will be done by REL32 dynamic relocations.
- if (&G == &Gots.front())
- for (const std::pair<const Symbol *, size_t> &P : G.Global)
- Write(P.second, P.first, 0);
- for (const std::pair<Symbol *, size_t> &P : G.Relocs)
- Write(P.second, P.first, 0);
- for (const std::pair<Symbol *, size_t> &P : G.Tls)
- Write(P.second, P.first, P.first->IsPreemptible ? 0 : -0x7000);
- for (const std::pair<Symbol *, size_t> &P : G.DynTlsSymbols) {
- if (P.first == nullptr && !Config->Pic)
- Write(P.second, nullptr, 1);
- else if (P.first && !P.first->IsPreemptible) {
+ if (&g == &gots.front())
+ for (const std::pair<const Symbol *, size_t> &p : g.global)
+ write(p.second, p.first, 0);
+ for (const std::pair<Symbol *, size_t> &p : g.relocs)
+ write(p.second, p.first, 0);
+ for (const std::pair<Symbol *, size_t> &p : g.tls)
+ write(p.second, p.first, p.first->isPreemptible ? 0 : -0x7000);
+ for (const std::pair<Symbol *, size_t> &p : g.dynTlsSymbols) {
+ if (p.first == nullptr && !config->isPic)
+ write(p.second, nullptr, 1);
+ else if (p.first && !p.first->isPreemptible) {
// If we are emitting PIC code with relocations we mustn't write
// anything to the GOT here. When using Elf_Rel relocations the value
// one will be treated as an addend and will cause crashes at runtime
- if (!Config->Pic)
- Write(P.second, nullptr, 1);
- Write(P.second + 1, P.first, -0x8000);
+ if (!config->isPic)
+ write(p.second, nullptr, 1);
+ write(p.second + 1, p.first, -0x8000);
}
}
}
@@ -1063,48 +1063,48 @@ void MipsGotSection::writeTo(uint8_t *Buf) {
// section. I don't know why we have a BSS style type for the section but it is
// consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
GotPltSection::GotPltSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".got.plt") {
- if (Config->EMachine == EM_PPC) {
- Name = ".plt";
- } else if (Config->EMachine == EM_PPC64) {
- Type = SHT_NOBITS;
- Name = ".plt";
+ if (config->emachine == EM_PPC) {
+ name = ".plt";
+ } else if (config->emachine == EM_PPC64) {
+ type = SHT_NOBITS;
+ name = ".plt";
}
}
-void GotPltSection::addEntry(Symbol &Sym) {
- assert(Sym.PltIndex == Entries.size());
- Entries.push_back(&Sym);
+void GotPltSection::addEntry(Symbol &sym) {
+ assert(sym.pltIndex == entries.size());
+ entries.push_back(&sym);
}
size_t GotPltSection::getSize() const {
- return (Target->GotPltHeaderEntriesNum + Entries.size()) * Config->Wordsize;
+ return (target->gotPltHeaderEntriesNum + entries.size()) * config->wordsize;
}
-void GotPltSection::writeTo(uint8_t *Buf) {
- Target->writeGotPltHeader(Buf);
- Buf += Target->GotPltHeaderEntriesNum * Config->Wordsize;
- for (const Symbol *B : Entries) {
- Target->writeGotPlt(Buf, *B);
- Buf += Config->Wordsize;
+void GotPltSection::writeTo(uint8_t *buf) {
+ target->writeGotPltHeader(buf);
+ buf += target->gotPltHeaderEntriesNum * config->wordsize;
+ for (const Symbol *b : entries) {
+ target->writeGotPlt(buf, *b);
+ buf += config->wordsize;
}
}
bool GotPltSection::isNeeded() const {
// We need to emit GOTPLT even if it's empty if there's a relocation relative
// to it.
- return !Entries.empty() || HasGotPltOffRel;
+ return !entries.empty() || hasGotPltOffRel;
}
static StringRef getIgotPltName() {
// On ARM the IgotPltSection is part of the GotSection.
- if (Config->EMachine == EM_ARM)
+ if (config->emachine == EM_ARM)
return ".got";
// On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
// needs to be named the same.
- if (Config->EMachine == EM_PPC64)
+ if (config->emachine == EM_PPC64)
return ".plt";
return ".got.plt";
@@ -1114,28 +1114,28 @@ static StringRef getIgotPltName() {
// with the IgotPltSection.
IgotPltSection::IgotPltSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
- Config->Wordsize, getIgotPltName()) {}
+ config->emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
+ config->wordsize, getIgotPltName()) {}
-void IgotPltSection::addEntry(Symbol &Sym) {
- assert(Sym.PltIndex == Entries.size());
- Entries.push_back(&Sym);
+void IgotPltSection::addEntry(Symbol &sym) {
+ assert(sym.pltIndex == entries.size());
+ entries.push_back(&sym);
}
size_t IgotPltSection::getSize() const {
- return Entries.size() * Config->Wordsize;
+ return entries.size() * config->wordsize;
}
-void IgotPltSection::writeTo(uint8_t *Buf) {
- for (const Symbol *B : Entries) {
- Target->writeIgotPlt(Buf, *B);
- Buf += Config->Wordsize;
+void IgotPltSection::writeTo(uint8_t *buf) {
+ for (const Symbol *b : entries) {
+ target->writeIgotPlt(buf, *b);
+ buf += config->wordsize;
}
}
-StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
- : SyntheticSection(Dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, Name),
- Dynamic(Dynamic) {
+StringTableSection::StringTableSection(StringRef name, bool dynamic)
+ : SyntheticSection(dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, name),
+ dynamic(dynamic) {
// ELF string tables start with a NUL byte.
addString("");
}
@@ -1144,80 +1144,80 @@ StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
// duplicates. It is optional because the name of global symbols are already
// uniqued and hashing them again has a big cost for a small value: uniquing
// them with some other string that happens to be the same.
-unsigned StringTableSection::addString(StringRef S, bool HashIt) {
- if (HashIt) {
- auto R = StringMap.insert(std::make_pair(S, this->Size));
- if (!R.second)
- return R.first->second;
+unsigned StringTableSection::addString(StringRef s, bool hashIt) {
+ if (hashIt) {
+ auto r = stringMap.insert(std::make_pair(s, this->size));
+ if (!r.second)
+ return r.first->second;
}
- unsigned Ret = this->Size;
- this->Size = this->Size + S.size() + 1;
- Strings.push_back(S);
- return Ret;
+ unsigned ret = this->size;
+ this->size = this->size + s.size() + 1;
+ strings.push_back(s);
+ return ret;
}
-void StringTableSection::writeTo(uint8_t *Buf) {
- for (StringRef S : Strings) {
- memcpy(Buf, S.data(), S.size());
- Buf[S.size()] = '\0';
- Buf += S.size() + 1;
+void StringTableSection::writeTo(uint8_t *buf) {
+ for (StringRef s : strings) {
+ memcpy(buf, s.data(), s.size());
+ buf[s.size()] = '\0';
+ buf += s.size() + 1;
}
}
// Returns the number of version definition entries. Because the first entry
// is for the version definition itself, it is the number of versioned symbols
// plus one. Note that we don't support multiple versions yet.
-static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
+static unsigned getVerDefNum() { return config->versionDefinitions.size() + 1; }
template <class ELFT>
DynamicSection<ELFT>::DynamicSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, config->wordsize,
".dynamic") {
- this->Entsize = ELFT::Is64Bits ? 16 : 8;
+ this->entsize = ELFT::Is64Bits ? 16 : 8;
// .dynamic section is not writable on MIPS and on Fuchsia OS
// which passes -z rodynamic.
// See "Special Section" in Chapter 4 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (Config->EMachine == EM_MIPS || Config->ZRodynamic)
- this->Flags = SHF_ALLOC;
+ if (config->emachine == EM_MIPS || config->zRodynamic)
+ this->flags = SHF_ALLOC;
}
template <class ELFT>
-void DynamicSection<ELFT>::add(int32_t Tag, std::function<uint64_t()> Fn) {
- Entries.push_back({Tag, Fn});
+void DynamicSection<ELFT>::add(int32_t tag, std::function<uint64_t()> fn) {
+ entries.push_back({tag, fn});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) {
- Entries.push_back({Tag, [=] { return Val; }});
+void DynamicSection<ELFT>::addInt(int32_t tag, uint64_t val) {
+ entries.push_back({tag, [=] { return val; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->getVA(0); }});
+void DynamicSection<ELFT>::addInSec(int32_t tag, InputSection *sec) {
+ entries.push_back({tag, [=] { return sec->getVA(0); }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
- size_t TagOffset = Entries.size() * Entsize;
- Entries.push_back(
- {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
+void DynamicSection<ELFT>::addInSecRelative(int32_t tag, InputSection *sec) {
+ size_t tagOffset = entries.size() * entsize;
+ entries.push_back(
+ {tag, [=] { return sec->getVA(0) - (getVA() + tagOffset); }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->Addr; }});
+void DynamicSection<ELFT>::addOutSec(int32_t tag, OutputSection *sec) {
+ entries.push_back({tag, [=] { return sec->addr; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addSize(int32_t Tag, OutputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->Size; }});
+void DynamicSection<ELFT>::addSize(int32_t tag, OutputSection *sec) {
+ entries.push_back({tag, [=] { return sec->size; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
- Entries.push_back({Tag, [=] { return Sym->getVA(); }});
+void DynamicSection<ELFT>::addSym(int32_t tag, Symbol *sym) {
+ entries.push_back({tag, [=] { return sym->getVA(); }});
}
// A Linker script may assign the RELA relocation sections to the same
@@ -1225,74 +1225,74 @@ void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
static uint64_t addPltRelSz() {
- size_t Size = In.RelaPlt->getSize();
- if (In.RelaIplt->getParent() == In.RelaPlt->getParent() &&
- In.RelaIplt->Name == In.RelaPlt->Name)
- Size += In.RelaIplt->getSize();
- return Size;
+ size_t size = in.relaPlt->getSize();
+ if (in.relaIplt->getParent() == in.relaPlt->getParent() &&
+ in.relaIplt->name == in.relaPlt->name)
+ size += in.relaIplt->getSize();
+ return size;
}
// Add remaining entries to complete .dynamic contents.
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
- elf::Partition &Part = getPartition();
- bool IsMain = Part.Name.empty();
+ elf::Partition &part = getPartition();
+ bool isMain = part.name.empty();
- for (StringRef S : Config->FilterList)
- addInt(DT_FILTER, Part.DynStrTab->addString(S));
- for (StringRef S : Config->AuxiliaryList)
- addInt(DT_AUXILIARY, Part.DynStrTab->addString(S));
+ for (StringRef s : config->filterList)
+ addInt(DT_FILTER, part.dynStrTab->addString(s));
+ for (StringRef s : config->auxiliaryList)
+ addInt(DT_AUXILIARY, part.dynStrTab->addString(s));
- if (!Config->Rpath.empty())
- addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
- Part.DynStrTab->addString(Config->Rpath));
+ if (!config->rpath.empty())
+ addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH,
+ part.dynStrTab->addString(config->rpath));
- for (SharedFile *File : SharedFiles)
- if (File->IsNeeded)
- addInt(DT_NEEDED, Part.DynStrTab->addString(File->SoName));
+ for (SharedFile *file : sharedFiles)
+ if (file->isNeeded)
+ addInt(DT_NEEDED, part.dynStrTab->addString(file->soName));
- if (IsMain) {
- if (!Config->SoName.empty())
- addInt(DT_SONAME, Part.DynStrTab->addString(Config->SoName));
+ if (isMain) {
+ if (!config->soName.empty())
+ addInt(DT_SONAME, part.dynStrTab->addString(config->soName));
} else {
- if (!Config->SoName.empty())
- addInt(DT_NEEDED, Part.DynStrTab->addString(Config->SoName));
- addInt(DT_SONAME, Part.DynStrTab->addString(Part.Name));
+ if (!config->soName.empty())
+ addInt(DT_NEEDED, part.dynStrTab->addString(config->soName));
+ addInt(DT_SONAME, part.dynStrTab->addString(part.name));
}
// Set DT_FLAGS and DT_FLAGS_1.
- uint32_t DtFlags = 0;
- uint32_t DtFlags1 = 0;
- if (Config->Bsymbolic)
- DtFlags |= DF_SYMBOLIC;
- if (Config->ZGlobal)
- DtFlags1 |= DF_1_GLOBAL;
- if (Config->ZInitfirst)
- DtFlags1 |= DF_1_INITFIRST;
- if (Config->ZInterpose)
- DtFlags1 |= DF_1_INTERPOSE;
- if (Config->ZNodefaultlib)
- DtFlags1 |= DF_1_NODEFLIB;
- if (Config->ZNodelete)
- DtFlags1 |= DF_1_NODELETE;
- if (Config->ZNodlopen)
- DtFlags1 |= DF_1_NOOPEN;
- if (Config->ZNow) {
- DtFlags |= DF_BIND_NOW;
- DtFlags1 |= DF_1_NOW;
- }
- if (Config->ZOrigin) {
- DtFlags |= DF_ORIGIN;
- DtFlags1 |= DF_1_ORIGIN;
- }
- if (!Config->ZText)
- DtFlags |= DF_TEXTREL;
- if (Config->HasStaticTlsModel)
- DtFlags |= DF_STATIC_TLS;
-
- if (DtFlags)
- addInt(DT_FLAGS, DtFlags);
- if (DtFlags1)
- addInt(DT_FLAGS_1, DtFlags1);
+ uint32_t dtFlags = 0;
+ uint32_t dtFlags1 = 0;
+ if (config->bsymbolic)
+ dtFlags |= DF_SYMBOLIC;
+ if (config->zGlobal)
+ dtFlags1 |= DF_1_GLOBAL;
+ if (config->zInitfirst)
+ dtFlags1 |= DF_1_INITFIRST;
+ if (config->zInterpose)
+ dtFlags1 |= DF_1_INTERPOSE;
+ if (config->zNodefaultlib)
+ dtFlags1 |= DF_1_NODEFLIB;
+ if (config->zNodelete)
+ dtFlags1 |= DF_1_NODELETE;
+ if (config->zNodlopen)
+ dtFlags1 |= DF_1_NOOPEN;
+ if (config->zNow) {
+ dtFlags |= DF_BIND_NOW;
+ dtFlags1 |= DF_1_NOW;
+ }
+ if (config->zOrigin) {
+ dtFlags |= DF_ORIGIN;
+ dtFlags1 |= DF_1_ORIGIN;
+ }
+ if (!config->zText)
+ dtFlags |= DF_TEXTREL;
+ if (config->hasStaticTlsModel)
+ dtFlags |= DF_STATIC_TLS;
+
+ if (dtFlags)
+ addInt(DT_FLAGS, dtFlags);
+ if (dtFlags1)
+ addInt(DT_FLAGS_1, dtFlags1);
// DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We
// need it for each process, so we don't write it for DSOs. The loader writes
@@ -1302,35 +1302,35 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
// systems (currently only Fuchsia OS) provide other means to give the
// debugger this information. Such systems may choose make .dynamic read-only.
// If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
- if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
+ if (!config->shared && !config->relocatable && !config->zRodynamic)
addInt(DT_DEBUG, 0);
- if (OutputSection *Sec = Part.DynStrTab->getParent())
- this->Link = Sec->SectionIndex;
+ if (OutputSection *sec = part.dynStrTab->getParent())
+ this->link = sec->sectionIndex;
- if (Part.RelaDyn->isNeeded()) {
- addInSec(Part.RelaDyn->DynamicTag, Part.RelaDyn);
- addSize(Part.RelaDyn->SizeDynamicTag, Part.RelaDyn->getParent());
+ if (part.relaDyn->isNeeded()) {
+ addInSec(part.relaDyn->dynamicTag, part.relaDyn);
+ addSize(part.relaDyn->sizeDynamicTag, part.relaDyn->getParent());
- bool IsRela = Config->IsRela;
- addInt(IsRela ? DT_RELAENT : DT_RELENT,
- IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
+ bool isRela = config->isRela;
+ addInt(isRela ? DT_RELAENT : DT_RELENT,
+ isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
// MIPS dynamic loader does not support RELCOUNT tag.
// The problem is in the tight relation between dynamic
// relocations and GOT. So do not emit this tag on MIPS.
- if (Config->EMachine != EM_MIPS) {
- size_t NumRelativeRels = Part.RelaDyn->getRelativeRelocCount();
- if (Config->ZCombreloc && NumRelativeRels)
- addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
+ if (config->emachine != EM_MIPS) {
+ size_t numRelativeRels = part.relaDyn->getRelativeRelocCount();
+ if (config->zCombreloc && numRelativeRels)
+ addInt(isRela ? DT_RELACOUNT : DT_RELCOUNT, numRelativeRels);
}
}
- if (Part.RelrDyn && !Part.RelrDyn->Relocs.empty()) {
- addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
- Part.RelrDyn);
- addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
- Part.RelrDyn->getParent());
- addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
+ if (part.relrDyn && !part.relrDyn->relocs.empty()) {
+ addInSec(config->useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
+ part.relrDyn);
+ addSize(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
+ part.relrDyn->getParent());
+ addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
sizeof(Elf_Relr));
}
// .rel[a].plt section usually consists of two parts, containing plt and
@@ -1339,250 +1339,250 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
// as RelaIplt have. And we still want to emit proper dynamic tags for that
// case, so here we always use RelaPlt as marker for the begining of
// .rel[a].plt section.
- if (IsMain && (In.RelaPlt->isNeeded() || In.RelaIplt->isNeeded())) {
- addInSec(DT_JMPREL, In.RelaPlt);
- Entries.push_back({DT_PLTRELSZ, addPltRelSz});
- switch (Config->EMachine) {
+ if (isMain && (in.relaPlt->isNeeded() || in.relaIplt->isNeeded())) {
+ addInSec(DT_JMPREL, in.relaPlt);
+ entries.push_back({DT_PLTRELSZ, addPltRelSz});
+ switch (config->emachine) {
case EM_MIPS:
- addInSec(DT_MIPS_PLTGOT, In.GotPlt);
+ addInSec(DT_MIPS_PLTGOT, in.gotPlt);
break;
case EM_SPARCV9:
- addInSec(DT_PLTGOT, In.Plt);
+ addInSec(DT_PLTGOT, in.plt);
break;
default:
- addInSec(DT_PLTGOT, In.GotPlt);
+ addInSec(DT_PLTGOT, in.gotPlt);
break;
}
- addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
+ addInt(DT_PLTREL, config->isRela ? DT_RELA : DT_REL);
}
- if (Config->EMachine == EM_AARCH64) {
- if (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+ if (config->emachine == EM_AARCH64) {
+ if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
addInt(DT_AARCH64_BTI_PLT, 0);
- if (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
+ if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
addInt(DT_AARCH64_PAC_PLT, 0);
}
- addInSec(DT_SYMTAB, Part.DynSymTab);
+ addInSec(DT_SYMTAB, part.dynSymTab);
addInt(DT_SYMENT, sizeof(Elf_Sym));
- addInSec(DT_STRTAB, Part.DynStrTab);
- addInt(DT_STRSZ, Part.DynStrTab->getSize());
- if (!Config->ZText)
+ addInSec(DT_STRTAB, part.dynStrTab);
+ addInt(DT_STRSZ, part.dynStrTab->getSize());
+ if (!config->zText)
addInt(DT_TEXTREL, 0);
- if (Part.GnuHashTab)
- addInSec(DT_GNU_HASH, Part.GnuHashTab);
- if (Part.HashTab)
- addInSec(DT_HASH, Part.HashTab);
-
- if (IsMain) {
- if (Out::PreinitArray) {
- addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
- addSize(DT_PREINIT_ARRAYSZ, Out::PreinitArray);
+ if (part.gnuHashTab)
+ addInSec(DT_GNU_HASH, part.gnuHashTab);
+ if (part.hashTab)
+ addInSec(DT_HASH, part.hashTab);
+
+ if (isMain) {
+ if (Out::preinitArray) {
+ addOutSec(DT_PREINIT_ARRAY, Out::preinitArray);
+ addSize(DT_PREINIT_ARRAYSZ, Out::preinitArray);
}
- if (Out::InitArray) {
- addOutSec(DT_INIT_ARRAY, Out::InitArray);
- addSize(DT_INIT_ARRAYSZ, Out::InitArray);
+ if (Out::initArray) {
+ addOutSec(DT_INIT_ARRAY, Out::initArray);
+ addSize(DT_INIT_ARRAYSZ, Out::initArray);
}
- if (Out::FiniArray) {
- addOutSec(DT_FINI_ARRAY, Out::FiniArray);
- addSize(DT_FINI_ARRAYSZ, Out::FiniArray);
+ if (Out::finiArray) {
+ addOutSec(DT_FINI_ARRAY, Out::finiArray);
+ addSize(DT_FINI_ARRAYSZ, Out::finiArray);
}
- if (Symbol *B = Symtab->find(Config->Init))
- if (B->isDefined())
- addSym(DT_INIT, B);
- if (Symbol *B = Symtab->find(Config->Fini))
- if (B->isDefined())
- addSym(DT_FINI, B);
+ if (Symbol *b = symtab->find(config->init))
+ if (b->isDefined())
+ addSym(DT_INIT, b);
+ if (Symbol *b = symtab->find(config->fini))
+ if (b->isDefined())
+ addSym(DT_FINI, b);
}
- bool HasVerNeed = SharedFile::VernauxNum != 0;
- if (HasVerNeed || Part.VerDef)
- addInSec(DT_VERSYM, Part.VerSym);
- if (Part.VerDef) {
- addInSec(DT_VERDEF, Part.VerDef);
+ bool hasVerNeed = SharedFile::vernauxNum != 0;
+ if (hasVerNeed || part.verDef)
+ addInSec(DT_VERSYM, part.verSym);
+ if (part.verDef) {
+ addInSec(DT_VERDEF, part.verDef);
addInt(DT_VERDEFNUM, getVerDefNum());
}
- if (HasVerNeed) {
- addInSec(DT_VERNEED, Part.VerNeed);
- unsigned NeedNum = 0;
- for (SharedFile *F : SharedFiles)
- if (!F->Vernauxs.empty())
- ++NeedNum;
- addInt(DT_VERNEEDNUM, NeedNum);
+ if (hasVerNeed) {
+ addInSec(DT_VERNEED, part.verNeed);
+ unsigned needNum = 0;
+ for (SharedFile *f : sharedFiles)
+ if (!f->vernauxs.empty())
+ ++needNum;
+ addInt(DT_VERNEEDNUM, needNum);
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
addInt(DT_MIPS_RLD_VERSION, 1);
addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
- addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
- addInt(DT_MIPS_SYMTABNO, Part.DynSymTab->getNumSymbols());
+ addInt(DT_MIPS_BASE_ADDRESS, target->getImageBase());
+ addInt(DT_MIPS_SYMTABNO, part.dynSymTab->getNumSymbols());
- add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });
+ add(DT_MIPS_LOCAL_GOTNO, [] { return in.mipsGot->getLocalEntriesNum(); });
- if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
- addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
+ if (const Symbol *b = in.mipsGot->getFirstGlobalEntry())
+ addInt(DT_MIPS_GOTSYM, b->dynsymIndex);
else
- addInt(DT_MIPS_GOTSYM, Part.DynSymTab->getNumSymbols());
- addInSec(DT_PLTGOT, In.MipsGot);
- if (In.MipsRldMap) {
- if (!Config->Pie)
- addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
+ addInt(DT_MIPS_GOTSYM, part.dynSymTab->getNumSymbols());
+ addInSec(DT_PLTGOT, in.mipsGot);
+ if (in.mipsRldMap) {
+ if (!config->pie)
+ addInSec(DT_MIPS_RLD_MAP, in.mipsRldMap);
// Store the offset to the .rld_map section
// relative to the address of the tag.
- addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap);
+ addInSecRelative(DT_MIPS_RLD_MAP_REL, in.mipsRldMap);
}
}
// DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent,
// glibc assumes the old-style BSS PLT layout which we don't support.
- if (Config->EMachine == EM_PPC)
- add(DT_PPC_GOT, [] { return In.Got->getVA(); });
+ if (config->emachine == EM_PPC)
+ add(DT_PPC_GOT, [] { return in.got->getVA(); });
// Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
- if (Config->EMachine == EM_PPC64 && In.Plt->isNeeded()) {
+ if (config->emachine == EM_PPC64 && in.plt->isNeeded()) {
// The Glink tag points to 32 bytes before the first lazy symbol resolution
// stub, which starts directly after the header.
- Entries.push_back({DT_PPC64_GLINK, [=] {
- unsigned Offset = Target->PltHeaderSize - 32;
- return In.Plt->getVA(0) + Offset;
+ entries.push_back({DT_PPC64_GLINK, [=] {
+ unsigned offset = target->pltHeaderSize - 32;
+ return in.plt->getVA(0) + offset;
}});
}
addInt(DT_NULL, 0);
- getParent()->Link = this->Link;
- this->Size = Entries.size() * this->Entsize;
+ getParent()->link = this->link;
+ this->size = entries.size() * this->entsize;
}
-template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
- auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *buf) {
+ auto *p = reinterpret_cast<Elf_Dyn *>(buf);
- for (std::pair<int32_t, std::function<uint64_t()>> &KV : Entries) {
- P->d_tag = KV.first;
- P->d_un.d_val = KV.second();
- ++P;
+ for (std::pair<int32_t, std::function<uint64_t()>> &kv : entries) {
+ p->d_tag = kv.first;
+ p->d_un.d_val = kv.second();
+ ++p;
}
}
uint64_t DynamicReloc::getOffset() const {
- return InputSec->getVA(OffsetInSec);
+ return inputSec->getVA(offsetInSec);
}
int64_t DynamicReloc::computeAddend() const {
- if (UseSymVA)
- return Sym->getVA(Addend);
- if (!OutputSec)
- return Addend;
+ if (useSymVA)
+ return sym->getVA(addend);
+ if (!outputSec)
+ return addend;
// See the comment in the DynamicReloc ctor.
- return getMipsPageAddr(OutputSec->Addr) + Addend;
+ return getMipsPageAddr(outputSec->addr) + addend;
}
-uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *SymTab) const {
- if (Sym && !UseSymVA)
- return SymTab->getSymbolIndex(Sym);
+uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
+ if (sym && !useSymVA)
+ return symTab->getSymbolIndex(sym);
return 0;
}
-RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type,
- int32_t DynamicTag,
- int32_t SizeDynamicTag)
- : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name),
- DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {}
+RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
+ int32_t dynamicTag,
+ int32_t sizeDynamicTag)
+ : SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
+ dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag) {}
-void RelocationBaseSection::addReloc(RelType DynType, InputSectionBase *IS,
- uint64_t OffsetInSec, Symbol *Sym) {
- addReloc({DynType, IS, OffsetInSec, false, Sym, 0});
+void RelocationBaseSection::addReloc(RelType dynType, InputSectionBase *isec,
+ uint64_t offsetInSec, Symbol *sym) {
+ addReloc({dynType, isec, offsetInSec, false, sym, 0});
}
-void RelocationBaseSection::addReloc(RelType DynType,
- InputSectionBase *InputSec,
- uint64_t OffsetInSec, Symbol *Sym,
- int64_t Addend, RelExpr Expr,
- RelType Type) {
+void RelocationBaseSection::addReloc(RelType dynType,
+ InputSectionBase *inputSec,
+ uint64_t offsetInSec, Symbol *sym,
+ int64_t addend, RelExpr expr,
+ RelType type) {
// Write the addends to the relocated address if required. We skip
// it if the written value would be zero.
- if (Config->WriteAddends && (Expr != R_ADDEND || Addend != 0))
- InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
- addReloc({DynType, InputSec, OffsetInSec, Expr != R_ADDEND, Sym, Addend});
+ if (config->writeAddends && (expr != R_ADDEND || addend != 0))
+ inputSec->relocations.push_back({expr, type, offsetInSec, addend, sym});
+ addReloc({dynType, inputSec, offsetInSec, expr != R_ADDEND, sym, addend});
}
-void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
- if (Reloc.Type == Target->RelativeRel)
- ++NumRelativeRelocs;
- Relocs.push_back(Reloc);
+void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
+ if (reloc.type == target->relativeRel)
+ ++numRelativeRelocs;
+ relocs.push_back(reloc);
}
void RelocationBaseSection::finalizeContents() {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
// relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
// case.
- if (SymTab && SymTab->getParent())
- getParent()->Link = SymTab->getParent()->SectionIndex;
+ if (symTab && symTab->getParent())
+ getParent()->link = symTab->getParent()->sectionIndex;
else
- getParent()->Link = 0;
+ getParent()->link = 0;
- if (In.RelaPlt == this)
- getParent()->Info = In.GotPlt->getParent()->SectionIndex;
- if (In.RelaIplt == this)
- getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
+ if (in.relaPlt == this)
+ getParent()->info = in.gotPlt->getParent()->sectionIndex;
+ if (in.relaIplt == this)
+ getParent()->info = in.igotPlt->getParent()->sectionIndex;
}
RelrBaseSection::RelrBaseSection()
: SyntheticSection(SHF_ALLOC,
- Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
- Config->Wordsize, ".relr.dyn") {}
+ config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
+ config->wordsize, ".relr.dyn") {}
template <class ELFT>
-static void encodeDynamicReloc(SymbolTableBaseSection *SymTab,
- typename ELFT::Rela *P,
- const DynamicReloc &Rel) {
- if (Config->IsRela)
- P->r_addend = Rel.computeAddend();
- P->r_offset = Rel.getOffset();
- P->setSymbolAndType(Rel.getSymIndex(SymTab), Rel.Type, Config->IsMips64EL);
+static void encodeDynamicReloc(SymbolTableBaseSection *symTab,
+ typename ELFT::Rela *p,
+ const DynamicReloc &rel) {
+ if (config->isRela)
+ p->r_addend = rel.computeAddend();
+ p->r_offset = rel.getOffset();
+ p->setSymbolAndType(rel.getSymIndex(symTab), rel.type, config->isMips64EL);
}
template <class ELFT>
-RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
- : RelocationBaseSection(Name, Config->IsRela ? SHT_RELA : SHT_REL,
- Config->IsRela ? DT_RELA : DT_REL,
- Config->IsRela ? DT_RELASZ : DT_RELSZ),
- Sort(Sort) {
- this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
+ : RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
+ config->isRela ? DT_RELA : DT_REL,
+ config->isRela ? DT_RELASZ : DT_RELSZ),
+ sort(sort) {
+ this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
-template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to
// place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset
// is to make results easier to read.
- if (Sort)
+ if (sort)
llvm::stable_sort(
- Relocs, [&](const DynamicReloc &A, const DynamicReloc &B) {
- return std::make_tuple(A.Type != Target->RelativeRel,
- A.getSymIndex(SymTab), A.getOffset()) <
- std::make_tuple(B.Type != Target->RelativeRel,
- B.getSymIndex(SymTab), B.getOffset());
+ relocs, [&](const DynamicReloc &a, const DynamicReloc &b) {
+ return std::make_tuple(a.type != target->relativeRel,
+ a.getSymIndex(symTab), a.getOffset()) <
+ std::make_tuple(b.type != target->relativeRel,
+ b.getSymIndex(symTab), b.getOffset());
});
- for (const DynamicReloc &Rel : Relocs) {
- encodeDynamicReloc<ELFT>(SymTab, reinterpret_cast<Elf_Rela *>(Buf), Rel);
- Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ for (const DynamicReloc &rel : relocs) {
+ encodeDynamicReloc<ELFT>(symTab, reinterpret_cast<Elf_Rela *>(buf), rel);
+ buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
}
template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
- StringRef Name)
+ StringRef name)
: RelocationBaseSection(
- Name, Config->IsRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
- Config->IsRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
- Config->IsRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
- this->Entsize = 1;
+ name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
+ config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
+ config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
+ this->entsize = 1;
}
template <class ELFT>
@@ -1632,32 +1632,32 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
// RELOCATION_GROUPED_BY_ADDEND_FLAG is not set) the r_addend delta for
// this relocation.
- size_t OldSize = RelocData.size();
+ size_t oldSize = relocData.size();
- RelocData = {'A', 'P', 'S', '2'};
- raw_svector_ostream OS(RelocData);
- auto Add = [&](int64_t V) { encodeSLEB128(V, OS); };
+ relocData = {'A', 'P', 'S', '2'};
+ raw_svector_ostream os(relocData);
+ auto add = [&](int64_t v) { encodeSLEB128(v, os); };
// The format header includes the number of relocations and the initial
// offset (we set this to zero because the first relocation group will
// perform the initial adjustment).
- Add(Relocs.size());
- Add(0);
+ add(relocs.size());
+ add(0);
- std::vector<Elf_Rela> Relatives, NonRelatives;
+ std::vector<Elf_Rela> relatives, nonRelatives;
- for (const DynamicReloc &Rel : Relocs) {
- Elf_Rela R;
- encodeDynamicReloc<ELFT>(getPartition().DynSymTab, &R, Rel);
+ for (const DynamicReloc &rel : relocs) {
+ Elf_Rela r;
+ encodeDynamicReloc<ELFT>(getPartition().dynSymTab, &r, rel);
- if (R.getType(Config->IsMips64EL) == Target->RelativeRel)
- Relatives.push_back(R);
+ if (r.getType(config->isMips64EL) == target->relativeRel)
+ relatives.push_back(r);
else
- NonRelatives.push_back(R);
+ nonRelatives.push_back(r);
}
- llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
- return A.r_offset < B.r_offset;
+ llvm::sort(relatives, [](const Elf_Rel &a, const Elf_Rel &b) {
+ return a.r_offset < b.r_offset;
});
// Try to find groups of relative relocations which are spaced one word
@@ -1666,108 +1666,108 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
// encoding, but each group will cost 7 bytes in addition to the offset from
// the previous group, so it is only profitable to do this for groups of
// size 8 or larger.
- std::vector<Elf_Rela> UngroupedRelatives;
- std::vector<std::vector<Elf_Rela>> RelativeGroups;
- for (auto I = Relatives.begin(), E = Relatives.end(); I != E;) {
- std::vector<Elf_Rela> Group;
+ std::vector<Elf_Rela> ungroupedRelatives;
+ std::vector<std::vector<Elf_Rela>> relativeGroups;
+ for (auto i = relatives.begin(), e = relatives.end(); i != e;) {
+ std::vector<Elf_Rela> group;
do {
- Group.push_back(*I++);
- } while (I != E && (I - 1)->r_offset + Config->Wordsize == I->r_offset);
+ group.push_back(*i++);
+ } while (i != e && (i - 1)->r_offset + config->wordsize == i->r_offset);
- if (Group.size() < 8)
- UngroupedRelatives.insert(UngroupedRelatives.end(), Group.begin(),
- Group.end());
+ if (group.size() < 8)
+ ungroupedRelatives.insert(ungroupedRelatives.end(), group.begin(),
+ group.end());
else
- RelativeGroups.emplace_back(std::move(Group));
+ relativeGroups.emplace_back(std::move(group));
}
- unsigned HasAddendIfRela =
- Config->IsRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
+ unsigned hasAddendIfRela =
+ config->isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
- uint64_t Offset = 0;
- uint64_t Addend = 0;
+ uint64_t offset = 0;
+ uint64_t addend = 0;
// Emit the run-length encoding for the groups of adjacent relative
// relocations. Each group is represented using two groups in the packed
// format. The first is used to set the current offset to the start of the
// group (and also encodes the first relocation), and the second encodes the
// remaining relocations.
- for (std::vector<Elf_Rela> &G : RelativeGroups) {
+ for (std::vector<Elf_Rela> &g : relativeGroups) {
// The first relocation in the group.
- Add(1);
- Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
- RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(G[0].r_offset - Offset);
- Add(Target->RelativeRel);
- if (Config->IsRela) {
- Add(G[0].r_addend - Addend);
- Addend = G[0].r_addend;
+ add(1);
+ add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
+ RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(g[0].r_offset - offset);
+ add(target->relativeRel);
+ if (config->isRela) {
+ add(g[0].r_addend - addend);
+ addend = g[0].r_addend;
}
// The remaining relocations.
- Add(G.size() - 1);
- Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
- RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(Config->Wordsize);
- Add(Target->RelativeRel);
- if (Config->IsRela) {
- for (auto I = G.begin() + 1, E = G.end(); I != E; ++I) {
- Add(I->r_addend - Addend);
- Addend = I->r_addend;
+ add(g.size() - 1);
+ add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
+ RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(config->wordsize);
+ add(target->relativeRel);
+ if (config->isRela) {
+ for (auto i = g.begin() + 1, e = g.end(); i != e; ++i) {
+ add(i->r_addend - addend);
+ addend = i->r_addend;
}
}
- Offset = G.back().r_offset;
+ offset = g.back().r_offset;
}
// Now the ungrouped relatives.
- if (!UngroupedRelatives.empty()) {
- Add(UngroupedRelatives.size());
- Add(RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(Target->RelativeRel);
- for (Elf_Rela &R : UngroupedRelatives) {
- Add(R.r_offset - Offset);
- Offset = R.r_offset;
- if (Config->IsRela) {
- Add(R.r_addend - Addend);
- Addend = R.r_addend;
+ if (!ungroupedRelatives.empty()) {
+ add(ungroupedRelatives.size());
+ add(RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(target->relativeRel);
+ for (Elf_Rela &r : ungroupedRelatives) {
+ add(r.r_offset - offset);
+ offset = r.r_offset;
+ if (config->isRela) {
+ add(r.r_addend - addend);
+ addend = r.r_addend;
}
}
}
// Finally the non-relative relocations.
- llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
- return A.r_offset < B.r_offset;
+ llvm::sort(nonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
+ return a.r_offset < b.r_offset;
});
- if (!NonRelatives.empty()) {
- Add(NonRelatives.size());
- Add(HasAddendIfRela);
- for (Elf_Rela &R : NonRelatives) {
- Add(R.r_offset - Offset);
- Offset = R.r_offset;
- Add(R.r_info);
- if (Config->IsRela) {
- Add(R.r_addend - Addend);
- Addend = R.r_addend;
+ if (!nonRelatives.empty()) {
+ add(nonRelatives.size());
+ add(hasAddendIfRela);
+ for (Elf_Rela &r : nonRelatives) {
+ add(r.r_offset - offset);
+ offset = r.r_offset;
+ add(r.r_info);
+ if (config->isRela) {
+ add(r.r_addend - addend);
+ addend = r.r_addend;
}
}
}
// Don't allow the section to shrink; otherwise the size of the section can
// oscillate infinitely.
- if (RelocData.size() < OldSize)
- RelocData.append(OldSize - RelocData.size(), 0);
+ if (relocData.size() < oldSize)
+ relocData.append(oldSize - relocData.size(), 0);
// Returns whether the section size changed. We need to keep recomputing both
// section layout and the contents of this section until the size converges
// because changing this section's size can affect section layout, which in
// turn can affect the sizes of the LEB-encoded integers stored in this
// section.
- return RelocData.size() != OldSize;
+ return relocData.size() != oldSize;
}
template <class ELFT> RelrSection<ELFT>::RelrSection() {
- this->Entsize = Config->Wordsize;
+ this->entsize = config->wordsize;
}
template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
@@ -1801,90 +1801,90 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
// even means address, odd means bitmap.
// 2. Just a simple list of addresses is a valid encoding.
- size_t OldSize = RelrRelocs.size();
- RelrRelocs.clear();
+ size_t oldSize = relrRelocs.size();
+ relrRelocs.clear();
// Same as Config->Wordsize but faster because this is a compile-time
// constant.
- const size_t Wordsize = sizeof(typename ELFT::uint);
+ const size_t wordsize = sizeof(typename ELFT::uint);
// Number of bits to use for the relocation offsets bitmap.
// Must be either 63 or 31.
- const size_t NBits = Wordsize * 8 - 1;
+ const size_t nBits = wordsize * 8 - 1;
// Get offsets for all relative relocations and sort them.
- std::vector<uint64_t> Offsets;
- for (const RelativeReloc &Rel : Relocs)
- Offsets.push_back(Rel.getOffset());
- llvm::sort(Offsets);
+ std::vector<uint64_t> offsets;
+ for (const RelativeReloc &rel : relocs)
+ offsets.push_back(rel.getOffset());
+ llvm::sort(offsets);
// For each leading relocation, find following ones that can be folded
// as a bitmap and fold them.
- for (size_t I = 0, E = Offsets.size(); I < E;) {
+ for (size_t i = 0, e = offsets.size(); i < e;) {
// Add a leading relocation.
- RelrRelocs.push_back(Elf_Relr(Offsets[I]));
- uint64_t Base = Offsets[I] + Wordsize;
- ++I;
+ relrRelocs.push_back(Elf_Relr(offsets[i]));
+ uint64_t base = offsets[i] + wordsize;
+ ++i;
// Find foldable relocations to construct bitmaps.
- while (I < E) {
- uint64_t Bitmap = 0;
+ while (i < e) {
+ uint64_t bitmap = 0;
- while (I < E) {
- uint64_t Delta = Offsets[I] - Base;
+ while (i < e) {
+ uint64_t delta = offsets[i] - base;
// If it is too far, it cannot be folded.
- if (Delta >= NBits * Wordsize)
+ if (delta >= nBits * wordsize)
break;
// If it is not a multiple of wordsize away, it cannot be folded.
- if (Delta % Wordsize)
+ if (delta % wordsize)
break;
// Fold it.
- Bitmap |= 1ULL << (Delta / Wordsize);
- ++I;
+ bitmap |= 1ULL << (delta / wordsize);
+ ++i;
}
- if (!Bitmap)
+ if (!bitmap)
break;
- RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
- Base += NBits * Wordsize;
+ relrRelocs.push_back(Elf_Relr((bitmap << 1) | 1));
+ base += nBits * wordsize;
}
}
- return RelrRelocs.size() != OldSize;
+ return relrRelocs.size() != oldSize;
}
-SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
- : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
- StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
- Config->Wordsize,
- StrTabSec.isDynamic() ? ".dynsym" : ".symtab"),
- StrTabSec(StrTabSec) {}
+SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &strTabSec)
+ : SyntheticSection(strTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
+ strTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
+ config->wordsize,
+ strTabSec.isDynamic() ? ".dynsym" : ".symtab"),
+ strTabSec(strTabSec) {}
// Orders symbols according to their positions in the GOT,
// in compliance with MIPS ABI rules.
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-static bool sortMipsSymbols(const SymbolTableEntry &L,
- const SymbolTableEntry &R) {
+static bool sortMipsSymbols(const SymbolTableEntry &l,
+ const SymbolTableEntry &r) {
// Sort entries related to non-local preemptible symbols by GOT indexes.
// All other entries go to the beginning of a dynsym in arbitrary order.
- if (L.Sym->isInGot() && R.Sym->isInGot())
- return L.Sym->GotIndex < R.Sym->GotIndex;
- if (!L.Sym->isInGot() && !R.Sym->isInGot())
+ if (l.sym->isInGot() && r.sym->isInGot())
+ return l.sym->gotIndex < r.sym->gotIndex;
+ if (!l.sym->isInGot() && !r.sym->isInGot())
return false;
- return !L.Sym->isInGot();
+ return !l.sym->isInGot();
}
void SymbolTableBaseSection::finalizeContents() {
- if (OutputSection *Sec = StrTabSec.getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = strTabSec.getParent())
+ getParent()->link = sec->sectionIndex;
- if (this->Type != SHT_DYNSYM) {
+ if (this->type != SHT_DYNSYM) {
sortSymTabSymbols();
return;
}
@@ -1894,21 +1894,21 @@ void SymbolTableBaseSection::finalizeContents() {
// Section's Info field has the index of the first non-local symbol.
// Because the first symbol entry is a null entry, 1 is the first.
- getParent()->Info = 1;
+ getParent()->info = 1;
- if (getPartition().GnuHashTab) {
+ if (getPartition().gnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
- getPartition().GnuHashTab->addSymbols(Symbols);
- } else if (Config->EMachine == EM_MIPS) {
- llvm::stable_sort(Symbols, sortMipsSymbols);
+ getPartition().gnuHashTab->addSymbols(symbols);
+ } else if (config->emachine == EM_MIPS) {
+ llvm::stable_sort(symbols, sortMipsSymbols);
}
// Only the main partition's dynsym indexes are stored in the symbols
// themselves. All other partitions use a lookup table.
- if (this == Main->DynSymTab) {
- size_t I = 0;
- for (const SymbolTableEntry &S : Symbols)
- S.Sym->DynsymIndex = ++I;
+ if (this == mainPart->dynSymTab) {
+ size_t i = 0;
+ for (const SymbolTableEntry &s : symbols)
+ s.sym->dynsymIndex = ++i;
}
}
@@ -1921,150 +1921,150 @@ void SymbolTableBaseSection::finalizeContents() {
// coming from.
void SymbolTableBaseSection::sortSymTabSymbols() {
// Move all local symbols before global symbols.
- auto E = std::stable_partition(
- Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
- return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
+ auto e = std::stable_partition(
+ symbols.begin(), symbols.end(), [](const SymbolTableEntry &s) {
+ return s.sym->isLocal() || s.sym->computeBinding() == STB_LOCAL;
});
- size_t NumLocals = E - Symbols.begin();
- getParent()->Info = NumLocals + 1;
+ size_t numLocals = e - symbols.begin();
+ getParent()->info = numLocals + 1;
// We want to group the local symbols by file. For that we rebuild the local
// part of the symbols vector. We do not need to care about the STT_FILE
// symbols, they are already naturally placed first in each group. That
// happens because STT_FILE is always the first symbol in the object and hence
// precede all other local symbols we add for a file.
- MapVector<InputFile *, std::vector<SymbolTableEntry>> Arr;
- for (const SymbolTableEntry &S : llvm::make_range(Symbols.begin(), E))
- Arr[S.Sym->File].push_back(S);
+ MapVector<InputFile *, std::vector<SymbolTableEntry>> arr;
+ for (const SymbolTableEntry &s : llvm::make_range(symbols.begin(), e))
+ arr[s.sym->file].push_back(s);
- auto I = Symbols.begin();
- for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &P : Arr)
- for (SymbolTableEntry &Entry : P.second)
- *I++ = Entry;
+ auto i = symbols.begin();
+ for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &p : arr)
+ for (SymbolTableEntry &entry : p.second)
+ *i++ = entry;
}
-void SymbolTableBaseSection::addSymbol(Symbol *B) {
+void SymbolTableBaseSection::addSymbol(Symbol *b) {
// Adding a local symbol to a .dynsym is a bug.
- assert(this->Type != SHT_DYNSYM || !B->isLocal());
+ assert(this->type != SHT_DYNSYM || !b->isLocal());
- bool HashIt = B->isLocal();
- Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
+ bool hashIt = b->isLocal();
+ symbols.push_back({b, strTabSec.addString(b->getName(), hashIt)});
}
-size_t SymbolTableBaseSection::getSymbolIndex(Symbol *Sym) {
- if (this == Main->DynSymTab)
- return Sym->DynsymIndex;
+size_t SymbolTableBaseSection::getSymbolIndex(Symbol *sym) {
+ if (this == mainPart->dynSymTab)
+ return sym->dynsymIndex;
// Initializes symbol lookup tables lazily. This is used only for -r,
// -emit-relocs and dynsyms in partitions other than the main one.
- llvm::call_once(OnceFlag, [&] {
- SymbolIndexMap.reserve(Symbols.size());
- size_t I = 0;
- for (const SymbolTableEntry &E : Symbols) {
- if (E.Sym->Type == STT_SECTION)
- SectionIndexMap[E.Sym->getOutputSection()] = ++I;
+ llvm::call_once(onceFlag, [&] {
+ symbolIndexMap.reserve(symbols.size());
+ size_t i = 0;
+ for (const SymbolTableEntry &e : symbols) {
+ if (e.sym->type == STT_SECTION)
+ sectionIndexMap[e.sym->getOutputSection()] = ++i;
else
- SymbolIndexMap[E.Sym] = ++I;
+ symbolIndexMap[e.sym] = ++i;
}
});
// Section symbols are mapped based on their output sections
// to maintain their semantics.
- if (Sym->Type == STT_SECTION)
- return SectionIndexMap.lookup(Sym->getOutputSection());
- return SymbolIndexMap.lookup(Sym);
+ if (sym->type == STT_SECTION)
+ return sectionIndexMap.lookup(sym->getOutputSection());
+ return symbolIndexMap.lookup(sym);
}
template <class ELFT>
-SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
- : SymbolTableBaseSection(StrTabSec) {
- this->Entsize = sizeof(Elf_Sym);
+SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &strTabSec)
+ : SymbolTableBaseSection(strTabSec) {
+ this->entsize = sizeof(Elf_Sym);
}
-static BssSection *getCommonSec(Symbol *Sym) {
- if (!Config->DefineCommon)
- if (auto *D = dyn_cast<Defined>(Sym))
- return dyn_cast_or_null<BssSection>(D->Section);
+static BssSection *getCommonSec(Symbol *sym) {
+ if (!config->defineCommon)
+ if (auto *d = dyn_cast<Defined>(sym))
+ return dyn_cast_or_null<BssSection>(d->section);
return nullptr;
}
-static uint32_t getSymSectionIndex(Symbol *Sym) {
- if (getCommonSec(Sym))
+static uint32_t getSymSectionIndex(Symbol *sym) {
+ if (getCommonSec(sym))
return SHN_COMMON;
- if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
+ if (!isa<Defined>(sym) || sym->needsPltAddr)
return SHN_UNDEF;
- if (const OutputSection *OS = Sym->getOutputSection())
- return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
- : OS->SectionIndex;
+ if (const OutputSection *os = sym->getOutputSection())
+ return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
+ : os->sectionIndex;
return SHN_ABS;
}
// Write the internal symbol table contents to the output symbol table.
-template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
+template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
// The first entry is a null entry as per the ELF spec.
- memset(Buf, 0, sizeof(Elf_Sym));
- Buf += sizeof(Elf_Sym);
+ memset(buf, 0, sizeof(Elf_Sym));
+ buf += sizeof(Elf_Sym);
- auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+ auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
- for (SymbolTableEntry &Ent : Symbols) {
- Symbol *Sym = Ent.Sym;
- bool IsDefinedHere = Type == SHT_SYMTAB || Sym->Partition == Partition;
+ for (SymbolTableEntry &ent : symbols) {
+ Symbol *sym = ent.sym;
+ bool isDefinedHere = type == SHT_SYMTAB || sym->partition == partition;
// Set st_info and st_other.
- ESym->st_other = 0;
- if (Sym->isLocal()) {
- ESym->setBindingAndType(STB_LOCAL, Sym->Type);
+ eSym->st_other = 0;
+ if (sym->isLocal()) {
+ eSym->setBindingAndType(STB_LOCAL, sym->type);
} else {
- ESym->setBindingAndType(Sym->computeBinding(), Sym->Type);
- ESym->setVisibility(Sym->Visibility);
+ eSym->setBindingAndType(sym->computeBinding(), sym->type);
+ eSym->setVisibility(sym->visibility);
}
// The 3 most significant bits of st_other are used by OpenPOWER ABI.
// See getPPC64GlobalEntryToLocalEntryOffset() for more details.
- if (Config->EMachine == EM_PPC64)
- ESym->st_other |= Sym->StOther & 0xe0;
+ if (config->emachine == EM_PPC64)
+ eSym->st_other |= sym->stOther & 0xe0;
- ESym->st_name = Ent.StrTabOffset;
- if (IsDefinedHere)
- ESym->st_shndx = getSymSectionIndex(Ent.Sym);
+ eSym->st_name = ent.strTabOffset;
+ if (isDefinedHere)
+ eSym->st_shndx = getSymSectionIndex(ent.sym);
else
- ESym->st_shndx = 0;
+ eSym->st_shndx = 0;
// Copy symbol size if it is a defined symbol. st_size is not significant
// for undefined symbols, so whether copying it or not is up to us if that's
// the case. We'll leave it as zero because by not setting a value, we can
// get the exact same outputs for two sets of input files that differ only
// in undefined symbol size in DSOs.
- if (ESym->st_shndx == SHN_UNDEF || !IsDefinedHere)
- ESym->st_size = 0;
+ if (eSym->st_shndx == SHN_UNDEF || !isDefinedHere)
+ eSym->st_size = 0;
else
- ESym->st_size = Sym->getSize();
+ eSym->st_size = sym->getSize();
// st_value is usually an address of a symbol, but that has a
// special meaining for uninstantiated common symbols (this can
// occur if -r is given).
- if (BssSection *CommonSec = getCommonSec(Ent.Sym))
- ESym->st_value = CommonSec->Alignment;
- else if (IsDefinedHere)
- ESym->st_value = Sym->getVA();
+ if (BssSection *commonSec = getCommonSec(ent.sym))
+ eSym->st_value = commonSec->alignment;
+ else if (isDefinedHere)
+ eSym->st_value = sym->getVA();
else
- ESym->st_value = 0;
+ eSym->st_value = 0;
- ++ESym;
+ ++eSym;
}
// On MIPS we need to mark symbol which has a PLT entry and requires
// pointer equality by STO_MIPS_PLT flag. That is necessary to help
// dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
// https://sourceware.org/ml/binutils/2008-07/txt00000.txt
- if (Config->EMachine == EM_MIPS) {
- auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+ if (config->emachine == EM_MIPS) {
+ auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
- for (SymbolTableEntry &Ent : Symbols) {
- Symbol *Sym = Ent.Sym;
- if (Sym->isInPlt() && Sym->NeedsPltAddr)
- ESym->st_other |= STO_MIPS_PLT;
+ for (SymbolTableEntry &ent : symbols) {
+ Symbol *sym = ent.sym;
+ if (sym->isInPlt() && sym->needsPltAddr)
+ eSym->st_other |= STO_MIPS_PLT;
if (isMicroMips()) {
// We already set the less-significant bit for symbols
// marked by the `STO_MIPS_MICROMIPS` flag and for microMIPS PLT
@@ -2073,36 +2073,36 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
// clear that bit for non-dynamic symbol table, so tools
// like `objdump` will be able to deal with a correct
// symbol position.
- if (Sym->isDefined() &&
- ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) {
- if (!StrTabSec.isDynamic())
- ESym->st_value &= ~1;
- ESym->st_other |= STO_MIPS_MICROMIPS;
+ if (sym->isDefined() &&
+ ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) {
+ if (!strTabSec.isDynamic())
+ eSym->st_value &= ~1;
+ eSym->st_other |= STO_MIPS_MICROMIPS;
}
}
- if (Config->Relocatable)
- if (auto *D = dyn_cast<Defined>(Sym))
- if (isMipsPIC<ELFT>(D))
- ESym->st_other |= STO_MIPS_PIC;
- ++ESym;
+ if (config->relocatable)
+ if (auto *d = dyn_cast<Defined>(sym))
+ if (isMipsPIC<ELFT>(d))
+ eSym->st_other |= STO_MIPS_PIC;
+ ++eSym;
}
}
}
SymtabShndxSection::SymtabShndxSection()
: SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndx") {
- this->Entsize = 4;
+ this->entsize = 4;
}
-void SymtabShndxSection::writeTo(uint8_t *Buf) {
+void SymtabShndxSection::writeTo(uint8_t *buf) {
// We write an array of 32 bit values, where each value has 1:1 association
// with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
// we need to write actual index, otherwise, we must write SHN_UNDEF(0).
- Buf += 4; // Ignore .symtab[0] entry.
- for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
- if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
- write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
- Buf += 4;
+ buf += 4; // Ignore .symtab[0] entry.
+ for (const SymbolTableEntry &entry : in.symTab->getSymbols()) {
+ if (getSymSectionIndex(entry.sym) == SHN_XINDEX)
+ write32(buf, entry.sym->getOutputSection()->sectionIndex);
+ buf += 4;
}
}
@@ -2112,19 +2112,19 @@ bool SymtabShndxSection::isNeeded() const {
// section. Problem is that we reveal the final section indices a bit too
// late, and we do not know them here. For simplicity, we just always create
// a .symtab_shndx section when the amount of output sections is huge.
- size_t Size = 0;
- for (BaseCommand *Base : Script->SectionCommands)
- if (isa<OutputSection>(Base))
- ++Size;
- return Size >= SHN_LORESERVE;
+ size_t size = 0;
+ for (BaseCommand *base : script->sectionCommands)
+ if (isa<OutputSection>(base))
+ ++size;
+ return size >= SHN_LORESERVE;
}
void SymtabShndxSection::finalizeContents() {
- getParent()->Link = In.SymTab->getParent()->SectionIndex;
+ getParent()->link = in.symTab->getParent()->sectionIndex;
}
size_t SymtabShndxSection::getSize() const {
- return In.SymTab->getNumSymbols() * 4;
+ return in.symTab->getNumSymbols() * 4;
}
// .hash and .gnu.hash sections contain on-disk hash tables that map
@@ -2159,45 +2159,45 @@ size_t SymtabShndxSection::getSize() const {
// about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a
// safe bet is to specify -hash-style=both for backward compatibilty.
GnuHashTableSection::GnuHashTableSection()
- : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
+ : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, config->wordsize, ".gnu.hash") {
}
void GnuHashTableSection::finalizeContents() {
- if (OutputSection *Sec = getPartition().DynSymTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = getPartition().dynSymTab->getParent())
+ getParent()->link = sec->sectionIndex;
// Computes bloom filter size in word size. We want to allocate 12
// bits for each symbol. It must be a power of two.
- if (Symbols.empty()) {
- MaskWords = 1;
+ if (symbols.empty()) {
+ maskWords = 1;
} else {
- uint64_t NumBits = Symbols.size() * 12;
- MaskWords = NextPowerOf2(NumBits / (Config->Wordsize * 8));
+ uint64_t numBits = symbols.size() * 12;
+ maskWords = NextPowerOf2(numBits / (config->wordsize * 8));
}
- Size = 16; // Header
- Size += Config->Wordsize * MaskWords; // Bloom filter
- Size += NBuckets * 4; // Hash buckets
- Size += Symbols.size() * 4; // Hash values
+ size = 16; // Header
+ size += config->wordsize * maskWords; // Bloom filter
+ size += nBuckets * 4; // Hash buckets
+ size += symbols.size() * 4; // Hash values
}
-void GnuHashTableSection::writeTo(uint8_t *Buf) {
+void GnuHashTableSection::writeTo(uint8_t *buf) {
// The output buffer is not guaranteed to be zero-cleared because we pre-
// fill executable sections with trap instructions. This is a precaution
// for that case, which happens only when -no-rosegment is given.
- memset(Buf, 0, Size);
+ memset(buf, 0, size);
// Write a header.
- write32(Buf, NBuckets);
- write32(Buf + 4, getPartition().DynSymTab->getNumSymbols() - Symbols.size());
- write32(Buf + 8, MaskWords);
- write32(Buf + 12, Shift2);
- Buf += 16;
+ write32(buf, nBuckets);
+ write32(buf + 4, getPartition().dynSymTab->getNumSymbols() - symbols.size());
+ write32(buf + 8, maskWords);
+ write32(buf + 12, Shift2);
+ buf += 16;
// Write a bloom filter and a hash table.
- writeBloomFilter(Buf);
- Buf += Config->Wordsize * MaskWords;
- writeHashTable(Buf);
+ writeBloomFilter(buf);
+ buf += config->wordsize * maskWords;
+ writeHashTable(buf);
}
// This function writes a 2-bit bloom filter. This bloom filter alone
@@ -2207,58 +2207,58 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
//
// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
-void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
- unsigned C = Config->Is64 ? 64 : 32;
- for (const Entry &Sym : Symbols) {
+void GnuHashTableSection::writeBloomFilter(uint8_t *buf) {
+ unsigned c = config->is64 ? 64 : 32;
+ for (const Entry &sym : symbols) {
// When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
// the word using bits [0:5] and [26:31].
- size_t I = (Sym.Hash / C) & (MaskWords - 1);
- uint64_t Val = readUint(Buf + I * Config->Wordsize);
- Val |= uint64_t(1) << (Sym.Hash % C);
- Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C);
- writeUint(Buf + I * Config->Wordsize, Val);
+ size_t i = (sym.hash / c) & (maskWords - 1);
+ uint64_t val = readUint(buf + i * config->wordsize);
+ val |= uint64_t(1) << (sym.hash % c);
+ val |= uint64_t(1) << ((sym.hash >> Shift2) % c);
+ writeUint(buf + i * config->wordsize, val);
}
}
-void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
- uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
- uint32_t OldBucket = -1;
- uint32_t *Values = Buckets + NBuckets;
- for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) {
+void GnuHashTableSection::writeHashTable(uint8_t *buf) {
+ uint32_t *buckets = reinterpret_cast<uint32_t *>(buf);
+ uint32_t oldBucket = -1;
+ uint32_t *values = buckets + nBuckets;
+ for (auto i = symbols.begin(), e = symbols.end(); i != e; ++i) {
// Write a hash value. It represents a sequence of chains that share the
// same hash modulo value. The last element of each chain is terminated by
// LSB 1.
- uint32_t Hash = I->Hash;
- bool IsLastInChain = (I + 1) == E || I->BucketIdx != (I + 1)->BucketIdx;
- Hash = IsLastInChain ? Hash | 1 : Hash & ~1;
- write32(Values++, Hash);
+ uint32_t hash = i->hash;
+ bool isLastInChain = (i + 1) == e || i->bucketIdx != (i + 1)->bucketIdx;
+ hash = isLastInChain ? hash | 1 : hash & ~1;
+ write32(values++, hash);
- if (I->BucketIdx == OldBucket)
+ if (i->bucketIdx == oldBucket)
continue;
// Write a hash bucket. Hash buckets contain indices in the following hash
// value table.
- write32(Buckets + I->BucketIdx,
- getPartition().DynSymTab->getSymbolIndex(I->Sym));
- OldBucket = I->BucketIdx;
+ write32(buckets + i->bucketIdx,
+ getPartition().dynSymTab->getSymbolIndex(i->sym));
+ oldBucket = i->bucketIdx;
}
}
-static uint32_t hashGnu(StringRef Name) {
- uint32_t H = 5381;
- for (uint8_t C : Name)
- H = (H << 5) + H + C;
- return H;
+static uint32_t hashGnu(StringRef name) {
+ uint32_t h = 5381;
+ for (uint8_t c : name)
+ h = (h << 5) + h + c;
+ return h;
}
// Add symbols to this symbol hash table. Note that this function
// destructively sort a given vector -- which is needed because
// GNU-style hash table places some sorting requirements.
-void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
+void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &v) {
// We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
// its type correctly.
- std::vector<SymbolTableEntry>::iterator Mid =
- std::stable_partition(V.begin(), V.end(), [&](const SymbolTableEntry &S) {
- return !S.Sym->isDefined() || S.Sym->Partition != Partition;
+ std::vector<SymbolTableEntry>::iterator mid =
+ std::stable_partition(v.begin(), v.end(), [&](const SymbolTableEntry &s) {
+ return !s.sym->isDefined() || s.sym->partition != partition;
});
// We chose load factor 4 for the on-disk hash table. For each hash
@@ -2270,143 +2270,143 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
// Android loader as of 2018 doesn't like a .gnu.hash containing such
// table. If that's the case, we create a hash table with one unused
// dummy slot.
- NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);
+ nBuckets = std::max<size_t>((v.end() - mid) / 4, 1);
- if (Mid == V.end())
+ if (mid == v.end())
return;
- for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
- Symbol *B = Ent.Sym;
- uint32_t Hash = hashGnu(B->getName());
- uint32_t BucketIdx = Hash % NBuckets;
- Symbols.push_back({B, Ent.StrTabOffset, Hash, BucketIdx});
+ for (SymbolTableEntry &ent : llvm::make_range(mid, v.end())) {
+ Symbol *b = ent.sym;
+ uint32_t hash = hashGnu(b->getName());
+ uint32_t bucketIdx = hash % nBuckets;
+ symbols.push_back({b, ent.strTabOffset, hash, bucketIdx});
}
- llvm::stable_sort(Symbols, [](const Entry &L, const Entry &R) {
- return L.BucketIdx < R.BucketIdx;
+ llvm::stable_sort(symbols, [](const Entry &l, const Entry &r) {
+ return l.bucketIdx < r.bucketIdx;
});
- V.erase(Mid, V.end());
- for (const Entry &Ent : Symbols)
- V.push_back({Ent.Sym, Ent.StrTabOffset});
+ v.erase(mid, v.end());
+ for (const Entry &ent : symbols)
+ v.push_back({ent.sym, ent.strTabOffset});
}
HashTableSection::HashTableSection()
: SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
- this->Entsize = 4;
+ this->entsize = 4;
}
void HashTableSection::finalizeContents() {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
- if (OutputSection *Sec = SymTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = symTab->getParent())
+ getParent()->link = sec->sectionIndex;
- unsigned NumEntries = 2; // nbucket and nchain.
- NumEntries += SymTab->getNumSymbols(); // The chain entries.
+ unsigned numEntries = 2; // nbucket and nchain.
+ numEntries += symTab->getNumSymbols(); // The chain entries.
// Create as many buckets as there are symbols.
- NumEntries += SymTab->getNumSymbols();
- this->Size = NumEntries * 4;
+ numEntries += symTab->getNumSymbols();
+ this->size = numEntries * 4;
}
-void HashTableSection::writeTo(uint8_t *Buf) {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+void HashTableSection::writeTo(uint8_t *buf) {
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// See comment in GnuHashTableSection::writeTo.
- memset(Buf, 0, Size);
+ memset(buf, 0, size);
- unsigned NumSymbols = SymTab->getNumSymbols();
+ unsigned numSymbols = symTab->getNumSymbols();
- uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
- write32(P++, NumSymbols); // nbucket
- write32(P++, NumSymbols); // nchain
+ uint32_t *p = reinterpret_cast<uint32_t *>(buf);
+ write32(p++, numSymbols); // nbucket
+ write32(p++, numSymbols); // nchain
- uint32_t *Buckets = P;
- uint32_t *Chains = P + NumSymbols;
+ uint32_t *buckets = p;
+ uint32_t *chains = p + numSymbols;
- for (const SymbolTableEntry &S : SymTab->getSymbols()) {
- Symbol *Sym = S.Sym;
- StringRef Name = Sym->getName();
- unsigned I = Sym->DynsymIndex;
- uint32_t Hash = hashSysV(Name) % NumSymbols;
- Chains[I] = Buckets[Hash];
- write32(Buckets + Hash, I);
+ for (const SymbolTableEntry &s : symTab->getSymbols()) {
+ Symbol *sym = s.sym;
+ StringRef name = sym->getName();
+ unsigned i = sym->dynsymIndex;
+ uint32_t hash = hashSysV(name) % numSymbols;
+ chains[i] = buckets[hash];
+ write32(buckets + hash, i);
}
}
// On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
// in the .glink section, rather then the typical .plt section.
-PltSection::PltSection(bool IsIplt)
+PltSection::PltSection(bool isIplt)
: SyntheticSection(
SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
- (Config->EMachine == EM_PPC || Config->EMachine == EM_PPC64)
+ (config->emachine == EM_PPC || config->emachine == EM_PPC64)
? ".glink"
: ".plt"),
- HeaderSize(!IsIplt || Config->ZRetpolineplt ? Target->PltHeaderSize : 0),
- IsIplt(IsIplt) {
+ headerSize(!isIplt || config->zRetpolineplt ? target->pltHeaderSize : 0),
+ isIplt(isIplt) {
// The PLT needs to be writable on SPARC as the dynamic linker will
// modify the instructions in the PLT entries.
- if (Config->EMachine == EM_SPARCV9)
- this->Flags |= SHF_WRITE;
+ if (config->emachine == EM_SPARCV9)
+ this->flags |= SHF_WRITE;
}
-void PltSection::writeTo(uint8_t *Buf) {
- if (Config->EMachine == EM_PPC) {
- writePPC32GlinkSection(Buf, Entries.size());
+void PltSection::writeTo(uint8_t *buf) {
+ if (config->emachine == EM_PPC) {
+ writePPC32GlinkSection(buf, entries.size());
return;
}
// At beginning of PLT or retpoline IPLT, we have code to call the dynamic
// linker to resolve dynsyms at runtime. Write such code.
- if (HeaderSize)
- Target->writePltHeader(Buf);
- size_t Off = HeaderSize;
+ if (headerSize)
+ target->writePltHeader(buf);
+ size_t off = headerSize;
- RelocationBaseSection *RelSec = IsIplt ? In.RelaIplt : In.RelaPlt;
+ RelocationBaseSection *relSec = isIplt ? in.relaIplt : in.relaPlt;
// The IPlt is immediately after the Plt, account for this in RelOff
- size_t PltOff = IsIplt ? In.Plt->getSize() : 0;
+ size_t pltOff = isIplt ? in.plt->getSize() : 0;
- for (size_t I = 0, E = Entries.size(); I != E; ++I) {
- const Symbol *B = Entries[I];
- unsigned RelOff = RelSec->Entsize * I + PltOff;
- uint64_t Got = B->getGotPltVA();
- uint64_t Plt = this->getVA() + Off;
- Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
- Off += Target->PltEntrySize;
+ for (size_t i = 0, e = entries.size(); i != e; ++i) {
+ const Symbol *b = entries[i];
+ unsigned relOff = relSec->entsize * i + pltOff;
+ uint64_t got = b->getGotPltVA();
+ uint64_t plt = this->getVA() + off;
+ target->writePlt(buf + off, got, plt, b->pltIndex, relOff);
+ off += target->pltEntrySize;
}
}
-template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
- Sym.PltIndex = Entries.size();
- Entries.push_back(&Sym);
+template <class ELFT> void PltSection::addEntry(Symbol &sym) {
+ sym.pltIndex = entries.size();
+ entries.push_back(&sym);
}
size_t PltSection::getSize() const {
- return HeaderSize + Entries.size() * Target->PltEntrySize;
+ return headerSize + entries.size() * target->pltEntrySize;
}
// Some architectures such as additional symbols in the PLT section. For
// example ARM uses mapping symbols to aid disassembly
void PltSection::addSymbols() {
// The PLT may have symbols defined for the Header, the IPLT has no header
- if (!IsIplt)
- Target->addPltHeaderSymbols(*this);
+ if (!isIplt)
+ target->addPltHeaderSymbols(*this);
- size_t Off = HeaderSize;
- for (size_t I = 0; I < Entries.size(); ++I) {
- Target->addPltSymbols(*this, Off);
- Off += Target->PltEntrySize;
+ size_t off = headerSize;
+ for (size_t i = 0; i < entries.size(); ++i) {
+ target->addPltSymbols(*this, off);
+ off += target->pltEntrySize;
}
}
// The string hash function for .gdb_index.
-static uint32_t computeGdbHash(StringRef S) {
- uint32_t H = 0;
- for (uint8_t C : S)
- H = H * 67 + toLower(C) - 113;
- return H;
+static uint32_t computeGdbHash(StringRef s) {
+ uint32_t h = 0;
+ for (uint8_t c : s)
+ h = h * 67 + toLower(c) - 113;
+ return h;
}
GdbIndexSection::GdbIndexSection()
@@ -2415,287 +2415,287 @@ GdbIndexSection::GdbIndexSection()
// Returns the desired size of an on-disk hash table for a .gdb_index section.
// There's a tradeoff between size and collision rate. We aim 75% utilization.
size_t GdbIndexSection::computeSymtabSize() const {
- return std::max<size_t>(NextPowerOf2(Symbols.size() * 4 / 3), 1024);
+ return std::max<size_t>(NextPowerOf2(symbols.size() * 4 / 3), 1024);
}
// Compute the output section size.
void GdbIndexSection::initOutputSize() {
- Size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
+ size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
- for (GdbChunk &Chunk : Chunks)
- Size += Chunk.CompilationUnits.size() * 16 + Chunk.AddressAreas.size() * 20;
+ for (GdbChunk &chunk : chunks)
+ size += chunk.compilationUnits.size() * 16 + chunk.addressAreas.size() * 20;
// Add the constant pool size if exists.
- if (!Symbols.empty()) {
- GdbSymbol &Sym = Symbols.back();
- Size += Sym.NameOff + Sym.Name.size() + 1;
+ if (!symbols.empty()) {
+ GdbSymbol &sym = symbols.back();
+ size += sym.nameOff + sym.name.size() + 1;
}
}
static std::vector<InputSection *> getDebugInfoSections() {
- std::vector<InputSection *> Ret;
- for (InputSectionBase *S : InputSections)
- if (InputSection *IS = dyn_cast<InputSection>(S))
- if (IS->Name == ".debug_info")
- Ret.push_back(IS);
- return Ret;
+ std::vector<InputSection *> ret;
+ for (InputSectionBase *s : inputSections)
+ if (InputSection *isec = dyn_cast<InputSection>(s))
+ if (isec->name == ".debug_info")
+ ret.push_back(isec);
+ return ret;
}
-static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
- std::vector<GdbIndexSection::CuEntry> Ret;
- for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units())
- Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
- return Ret;
+static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &dwarf) {
+ std::vector<GdbIndexSection::CuEntry> ret;
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units())
+ ret.push_back({cu->getOffset(), cu->getLength() + 4});
+ return ret;
}
static std::vector<GdbIndexSection::AddressEntry>
-readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
- std::vector<GdbIndexSection::AddressEntry> Ret;
-
- uint32_t CuIdx = 0;
- for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
- Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
- if (!Ranges) {
- error(toString(Sec) + ": " + toString(Ranges.takeError()));
+readAddressAreas(DWARFContext &dwarf, InputSection *sec) {
+ std::vector<GdbIndexSection::AddressEntry> ret;
+
+ uint32_t cuIdx = 0;
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units()) {
+ Expected<DWARFAddressRangesVector> ranges = cu->collectAddressRanges();
+ if (!ranges) {
+ error(toString(sec) + ": " + toString(ranges.takeError()));
return {};
}
- ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
- for (DWARFAddressRange &R : *Ranges) {
- if (R.SectionIndex == -1ULL)
+ ArrayRef<InputSectionBase *> sections = sec->file->getSections();
+ for (DWARFAddressRange &r : *ranges) {
+ if (r.SectionIndex == -1ULL)
continue;
- InputSectionBase *S = Sections[R.SectionIndex];
- if (!S || S == &InputSection::Discarded || !S->isLive())
+ InputSectionBase *s = sections[r.SectionIndex];
+ if (!s || s == &InputSection::discarded || !s->isLive())
continue;
// Range list with zero size has no effect.
- if (R.LowPC == R.HighPC)
+ if (r.LowPC == r.HighPC)
continue;
- auto *IS = cast<InputSection>(S);
- uint64_t Offset = IS->getOffsetInFile();
- Ret.push_back({IS, R.LowPC - Offset, R.HighPC - Offset, CuIdx});
+ auto *isec = cast<InputSection>(s);
+ uint64_t offset = isec->getOffsetInFile();
+ ret.push_back({isec, r.LowPC - offset, r.HighPC - offset, cuIdx});
}
- ++CuIdx;
+ ++cuIdx;
}
- return Ret;
+ return ret;
}
template <class ELFT>
static std::vector<GdbIndexSection::NameAttrEntry>
-readPubNamesAndTypes(const LLDDwarfObj<ELFT> &Obj,
- const std::vector<GdbIndexSection::CuEntry> &CUs) {
- const DWARFSection &PubNames = Obj.getGnuPubNamesSection();
- const DWARFSection &PubTypes = Obj.getGnuPubTypesSection();
-
- std::vector<GdbIndexSection::NameAttrEntry> Ret;
- for (const DWARFSection *Pub : {&PubNames, &PubTypes}) {
- DWARFDebugPubTable Table(Obj, *Pub, Config->IsLE, true);
- for (const DWARFDebugPubTable::Set &Set : Table.getData()) {
+readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
+ const std::vector<GdbIndexSection::CuEntry> &cUs) {
+ const DWARFSection &pubNames = obj.getGnuPubNamesSection();
+ const DWARFSection &pubTypes = obj.getGnuPubTypesSection();
+
+ std::vector<GdbIndexSection::NameAttrEntry> ret;
+ for (const DWARFSection *pub : {&pubNames, &pubTypes}) {
+ DWARFDebugPubTable table(obj, *pub, config->isLE, true);
+ for (const DWARFDebugPubTable::Set &set : table.getData()) {
// The value written into the constant pool is Kind << 24 | CuIndex. As we
// don't know how many compilation units precede this object to compute
// CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
// the number of preceding compilation units later.
- uint32_t I =
- lower_bound(CUs, Set.Offset,
- [](GdbIndexSection::CuEntry CU, uint32_t Offset) {
- return CU.CuOffset < Offset;
+ uint32_t i =
+ lower_bound(cUs, set.Offset,
+ [](GdbIndexSection::CuEntry cu, uint32_t offset) {
+ return cu.cuOffset < offset;
}) -
- CUs.begin();
- for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
- Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
- (Ent.Descriptor.toBits() << 24) | I});
+ cUs.begin();
+ for (const DWARFDebugPubTable::Entry &ent : set.Entries)
+ ret.push_back({{ent.Name, computeGdbHash(ent.Name)},
+ (ent.Descriptor.toBits() << 24) | i});
}
}
- return Ret;
+ return ret;
}
// Create a list of symbols from a given list of symbol names and types
// by uniquifying them by name.
static std::vector<GdbIndexSection::GdbSymbol>
-createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> NameAttrs,
- const std::vector<GdbIndexSection::GdbChunk> &Chunks) {
+createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> nameAttrs,
+ const std::vector<GdbIndexSection::GdbChunk> &chunks) {
using GdbSymbol = GdbIndexSection::GdbSymbol;
using NameAttrEntry = GdbIndexSection::NameAttrEntry;
// For each chunk, compute the number of compilation units preceding it.
- uint32_t CuIdx = 0;
- std::vector<uint32_t> CuIdxs(Chunks.size());
- for (uint32_t I = 0, E = Chunks.size(); I != E; ++I) {
- CuIdxs[I] = CuIdx;
- CuIdx += Chunks[I].CompilationUnits.size();
+ uint32_t cuIdx = 0;
+ std::vector<uint32_t> cuIdxs(chunks.size());
+ for (uint32_t i = 0, e = chunks.size(); i != e; ++i) {
+ cuIdxs[i] = cuIdx;
+ cuIdx += chunks[i].compilationUnits.size();
}
// The number of symbols we will handle in this function is of the order
// of millions for very large executables, so we use multi-threading to
// speed it up.
- size_t NumShards = 32;
- size_t Concurrency = 1;
+ size_t numShards = 32;
+ size_t concurrency = 1;
if (ThreadsEnabled)
- Concurrency =
- std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
+ concurrency =
+ std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
// A sharded map to uniquify symbols by name.
- std::vector<DenseMap<CachedHashStringRef, size_t>> Map(NumShards);
- size_t Shift = 32 - countTrailingZeros(NumShards);
+ std::vector<DenseMap<CachedHashStringRef, size_t>> map(numShards);
+ size_t shift = 32 - countTrailingZeros(numShards);
// Instantiate GdbSymbols while uniqufying them by name.
- std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
- parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
- uint32_t I = 0;
- for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
- for (const NameAttrEntry &Ent : Entries) {
- size_t ShardId = Ent.Name.hash() >> Shift;
- if ((ShardId & (Concurrency - 1)) != ThreadId)
+ std::vector<std::vector<GdbSymbol>> symbols(numShards);
+ parallelForEachN(0, concurrency, [&](size_t threadId) {
+ uint32_t i = 0;
+ for (ArrayRef<NameAttrEntry> entries : nameAttrs) {
+ for (const NameAttrEntry &ent : entries) {
+ size_t shardId = ent.name.hash() >> shift;
+ if ((shardId & (concurrency - 1)) != threadId)
continue;
- uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
- size_t &Idx = Map[ShardId][Ent.Name];
- if (Idx) {
- Symbols[ShardId][Idx - 1].CuVector.push_back(V);
+ uint32_t v = ent.cuIndexAndAttrs + cuIdxs[i];
+ size_t &idx = map[shardId][ent.name];
+ if (idx) {
+ symbols[shardId][idx - 1].cuVector.push_back(v);
continue;
}
- Idx = Symbols[ShardId].size() + 1;
- Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0});
+ idx = symbols[shardId].size() + 1;
+ symbols[shardId].push_back({ent.name, {v}, 0, 0});
}
- ++I;
+ ++i;
}
});
- size_t NumSymbols = 0;
- for (ArrayRef<GdbSymbol> V : Symbols)
- NumSymbols += V.size();
+ size_t numSymbols = 0;
+ for (ArrayRef<GdbSymbol> v : symbols)
+ numSymbols += v.size();
// The return type is a flattened vector, so we'll copy each vector
// contents to Ret.
- std::vector<GdbSymbol> Ret;
- Ret.reserve(NumSymbols);
- for (std::vector<GdbSymbol> &Vec : Symbols)
- for (GdbSymbol &Sym : Vec)
- Ret.push_back(std::move(Sym));
+ std::vector<GdbSymbol> ret;
+ ret.reserve(numSymbols);
+ for (std::vector<GdbSymbol> &vec : symbols)
+ for (GdbSymbol &sym : vec)
+ ret.push_back(std::move(sym));
// CU vectors and symbol names are adjacent in the output file.
// We can compute their offsets in the output file now.
- size_t Off = 0;
- for (GdbSymbol &Sym : Ret) {
- Sym.CuVectorOff = Off;
- Off += (Sym.CuVector.size() + 1) * 4;
+ size_t off = 0;
+ for (GdbSymbol &sym : ret) {
+ sym.cuVectorOff = off;
+ off += (sym.cuVector.size() + 1) * 4;
}
- for (GdbSymbol &Sym : Ret) {
- Sym.NameOff = Off;
- Off += Sym.Name.size() + 1;
+ for (GdbSymbol &sym : ret) {
+ sym.nameOff = off;
+ off += sym.name.size() + 1;
}
- return Ret;
+ return ret;
}
// Returns a newly-created .gdb_index section.
template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
- std::vector<InputSection *> Sections = getDebugInfoSections();
+ std::vector<InputSection *> sections = getDebugInfoSections();
// .debug_gnu_pub{names,types} are useless in executables.
// They are present in input object files solely for creating
// a .gdb_index. So we can remove them from the output.
- for (InputSectionBase *S : InputSections)
- if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
- S->markDead();
-
- std::vector<GdbChunk> Chunks(Sections.size());
- std::vector<std::vector<NameAttrEntry>> NameAttrs(Sections.size());
-
- parallelForEachN(0, Sections.size(), [&](size_t I) {
- ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
- DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File));
-
- Chunks[I].Sec = Sections[I];
- Chunks[I].CompilationUnits = readCuList(Dwarf);
- Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);
- NameAttrs[I] = readPubNamesAndTypes<ELFT>(
- static_cast<const LLDDwarfObj<ELFT> &>(Dwarf.getDWARFObj()),
- Chunks[I].CompilationUnits);
+ for (InputSectionBase *s : inputSections)
+ if (s->name == ".debug_gnu_pubnames" || s->name == ".debug_gnu_pubtypes")
+ s->markDead();
+
+ std::vector<GdbChunk> chunks(sections.size());
+ std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());
+
+ parallelForEachN(0, sections.size(), [&](size_t i) {
+ ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
+ DWARFContext dwarf(make_unique<LLDDwarfObj<ELFT>>(file));
+
+ chunks[i].sec = sections[i];
+ chunks[i].compilationUnits = readCuList(dwarf);
+ chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
+ nameAttrs[i] = readPubNamesAndTypes<ELFT>(
+ static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
+ chunks[i].compilationUnits);
});
- auto *Ret = make<GdbIndexSection>();
- Ret->Chunks = std::move(Chunks);
- Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
- Ret->initOutputSize();
- return Ret;
+ auto *ret = make<GdbIndexSection>();
+ ret->chunks = std::move(chunks);
+ ret->symbols = createSymbols(nameAttrs, ret->chunks);
+ ret->initOutputSize();
+ return ret;
}
-void GdbIndexSection::writeTo(uint8_t *Buf) {
+void GdbIndexSection::writeTo(uint8_t *buf) {
// Write the header.
- auto *Hdr = reinterpret_cast<GdbIndexHeader *>(Buf);
- uint8_t *Start = Buf;
- Hdr->Version = 7;
- Buf += sizeof(*Hdr);
+ auto *hdr = reinterpret_cast<GdbIndexHeader *>(buf);
+ uint8_t *start = buf;
+ hdr->version = 7;
+ buf += sizeof(*hdr);
// Write the CU list.
- Hdr->CuListOff = Buf - Start;
- for (GdbChunk &Chunk : Chunks) {
- for (CuEntry &Cu : Chunk.CompilationUnits) {
- write64le(Buf, Chunk.Sec->OutSecOff + Cu.CuOffset);
- write64le(Buf + 8, Cu.CuLength);
- Buf += 16;
+ hdr->cuListOff = buf - start;
+ for (GdbChunk &chunk : chunks) {
+ for (CuEntry &cu : chunk.compilationUnits) {
+ write64le(buf, chunk.sec->outSecOff + cu.cuOffset);
+ write64le(buf + 8, cu.cuLength);
+ buf += 16;
}
}
// Write the address area.
- Hdr->CuTypesOff = Buf - Start;
- Hdr->AddressAreaOff = Buf - Start;
- uint32_t CuOff = 0;
- for (GdbChunk &Chunk : Chunks) {
- for (AddressEntry &E : Chunk.AddressAreas) {
- uint64_t BaseAddr = E.Section->getVA(0);
- write64le(Buf, BaseAddr + E.LowAddress);
- write64le(Buf + 8, BaseAddr + E.HighAddress);
- write32le(Buf + 16, E.CuIndex + CuOff);
- Buf += 20;
+ hdr->cuTypesOff = buf - start;
+ hdr->addressAreaOff = buf - start;
+ uint32_t cuOff = 0;
+ for (GdbChunk &chunk : chunks) {
+ for (AddressEntry &e : chunk.addressAreas) {
+ uint64_t baseAddr = e.section->getVA(0);
+ write64le(buf, baseAddr + e.lowAddress);
+ write64le(buf + 8, baseAddr + e.highAddress);
+ write32le(buf + 16, e.cuIndex + cuOff);
+ buf += 20;
}
- CuOff += Chunk.CompilationUnits.size();
+ cuOff += chunk.compilationUnits.size();
}
// Write the on-disk open-addressing hash table containing symbols.
- Hdr->SymtabOff = Buf - Start;
- size_t SymtabSize = computeSymtabSize();
- uint32_t Mask = SymtabSize - 1;
+ hdr->symtabOff = buf - start;
+ size_t symtabSize = computeSymtabSize();
+ uint32_t mask = symtabSize - 1;
- for (GdbSymbol &Sym : Symbols) {
- uint32_t H = Sym.Name.hash();
- uint32_t I = H & Mask;
- uint32_t Step = ((H * 17) & Mask) | 1;
+ for (GdbSymbol &sym : symbols) {
+ uint32_t h = sym.name.hash();
+ uint32_t i = h & mask;
+ uint32_t step = ((h * 17) & mask) | 1;
- while (read32le(Buf + I * 8))
- I = (I + Step) & Mask;
+ while (read32le(buf + i * 8))
+ i = (i + step) & mask;
- write32le(Buf + I * 8, Sym.NameOff);
- write32le(Buf + I * 8 + 4, Sym.CuVectorOff);
+ write32le(buf + i * 8, sym.nameOff);
+ write32le(buf + i * 8 + 4, sym.cuVectorOff);
}
- Buf += SymtabSize * 8;
+ buf += symtabSize * 8;
// Write the string pool.
- Hdr->ConstantPoolOff = Buf - Start;
- parallelForEach(Symbols, [&](GdbSymbol &Sym) {
- memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
+ hdr->constantPoolOff = buf - start;
+ parallelForEach(symbols, [&](GdbSymbol &sym) {
+ memcpy(buf + sym.nameOff, sym.name.data(), sym.name.size());
});
// Write the CU vectors.
- for (GdbSymbol &Sym : Symbols) {
- write32le(Buf, Sym.CuVector.size());
- Buf += 4;
- for (uint32_t Val : Sym.CuVector) {
- write32le(Buf, Val);
- Buf += 4;
+ for (GdbSymbol &sym : symbols) {
+ write32le(buf, sym.cuVector.size());
+ buf += 4;
+ for (uint32_t val : sym.cuVector) {
+ write32le(buf, val);
+ buf += 4;
}
}
}
-bool GdbIndexSection::isNeeded() const { return !Chunks.empty(); }
+bool GdbIndexSection::isNeeded() const { return !chunks.empty(); }
EhFrameHeader::EhFrameHeader()
: SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
-void EhFrameHeader::writeTo(uint8_t *Buf) {
+void EhFrameHeader::writeTo(uint8_t *buf) {
// Unlike most sections, the EhFrameHeader section is written while writing
// another section, namely EhFrameSection, which calls the write() function
// below from its writeTo() function. This is necessary because the contents
@@ -2708,34 +2708,34 @@ void EhFrameHeader::writeTo(uint8_t *Buf) {
// the starting PC from where FDEs covers, and the FDE's address.
// It is sorted by PC.
void EhFrameHeader::write() {
- uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
+ uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
using FdeData = EhFrameSection::FdeData;
- std::vector<FdeData> Fdes = getPartition().EhFrame->getFdeData();
+ std::vector<FdeData> fdes = getPartition().ehFrame->getFdeData();
- Buf[0] = 1;
- Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
- Buf[2] = DW_EH_PE_udata4;
- Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
- write32(Buf + 4,
- getPartition().EhFrame->getParent()->Addr - this->getVA() - 4);
- write32(Buf + 8, Fdes.size());
- Buf += 12;
+ buf[0] = 1;
+ buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ buf[2] = DW_EH_PE_udata4;
+ buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
+ write32(buf + 4,
+ getPartition().ehFrame->getParent()->addr - this->getVA() - 4);
+ write32(buf + 8, fdes.size());
+ buf += 12;
- for (FdeData &Fde : Fdes) {
- write32(Buf, Fde.PcRel);
- write32(Buf + 4, Fde.FdeVARel);
- Buf += 8;
+ for (FdeData &fde : fdes) {
+ write32(buf, fde.pcRel);
+ write32(buf + 4, fde.fdeVARel);
+ buf += 8;
}
}
size_t EhFrameHeader::getSize() const {
// .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
- return 12 + getPartition().EhFrame->NumFdes * 8;
+ return 12 + getPartition().ehFrame->numFdes * 8;
}
bool EhFrameHeader::isNeeded() const {
- return isLive() && getPartition().EhFrame->isNeeded();
+ return isLive() && getPartition().ehFrame->isNeeded();
}
VersionDefinitionSection::VersionDefinitionSection()
@@ -2743,56 +2743,56 @@ VersionDefinitionSection::VersionDefinitionSection()
".gnu.version_d") {}
StringRef VersionDefinitionSection::getFileDefName() {
- if (!getPartition().Name.empty())
- return getPartition().Name;
- if (!Config->SoName.empty())
- return Config->SoName;
- return Config->OutputFile;
+ if (!getPartition().name.empty())
+ return getPartition().name;
+ if (!config->soName.empty())
+ return config->soName;
+ return config->outputFile;
}
void VersionDefinitionSection::finalizeContents() {
- FileDefNameOff = getPartition().DynStrTab->addString(getFileDefName());
- for (VersionDefinition &V : Config->VersionDefinitions)
- VerDefNameOffs.push_back(getPartition().DynStrTab->addString(V.Name));
+ fileDefNameOff = getPartition().dynStrTab->addString(getFileDefName());
+ for (VersionDefinition &v : config->versionDefinitions)
+ verDefNameOffs.push_back(getPartition().dynStrTab->addString(v.name));
- if (OutputSection *Sec = getPartition().DynStrTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = getPartition().dynStrTab->getParent())
+ getParent()->link = sec->sectionIndex;
// sh_info should be set to the number of definitions. This fact is missed in
// documentation, but confirmed by binutils community:
// https://sourceware.org/ml/binutils/2014-11/msg00355.html
- getParent()->Info = getVerDefNum();
+ getParent()->info = getVerDefNum();
}
-void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
- StringRef Name, size_t NameOff) {
- uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
+void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
+ StringRef name, size_t nameOff) {
+ uint16_t flags = index == 1 ? VER_FLG_BASE : 0;
// Write a verdef.
- write16(Buf, 1); // vd_version
- write16(Buf + 2, Flags); // vd_flags
- write16(Buf + 4, Index); // vd_ndx
- write16(Buf + 6, 1); // vd_cnt
- write32(Buf + 8, hashSysV(Name)); // vd_hash
- write32(Buf + 12, 20); // vd_aux
- write32(Buf + 16, 28); // vd_next
+ write16(buf, 1); // vd_version
+ write16(buf + 2, flags); // vd_flags
+ write16(buf + 4, index); // vd_ndx
+ write16(buf + 6, 1); // vd_cnt
+ write32(buf + 8, hashSysV(name)); // vd_hash
+ write32(buf + 12, 20); // vd_aux
+ write32(buf + 16, 28); // vd_next
// Write a veraux.
- write32(Buf + 20, NameOff); // vda_name
- write32(Buf + 24, 0); // vda_next
+ write32(buf + 20, nameOff); // vda_name
+ write32(buf + 24, 0); // vda_next
}
-void VersionDefinitionSection::writeTo(uint8_t *Buf) {
- writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
+void VersionDefinitionSection::writeTo(uint8_t *buf) {
+ writeOne(buf, 1, getFileDefName(), fileDefNameOff);
- auto NameOffIt = VerDefNameOffs.begin();
- for (VersionDefinition &V : Config->VersionDefinitions) {
- Buf += EntrySize;
- writeOne(Buf, V.Id, V.Name, *NameOffIt++);
+ auto nameOffIt = verDefNameOffs.begin();
+ for (VersionDefinition &v : config->versionDefinitions) {
+ buf += EntrySize;
+ writeOne(buf, v.id, v.name, *nameOffIt++);
}
// Need to terminate the last version definition.
- write32(Buf + 16, 0); // vd_next
+ write32(buf + 16, 0); // vd_next
}
size_t VersionDefinitionSection::getSize() const {
@@ -2803,49 +2803,49 @@ size_t VersionDefinitionSection::getSize() const {
VersionTableSection::VersionTableSection()
: SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
".gnu.version") {
- this->Entsize = 2;
+ this->entsize = 2;
}
void VersionTableSection::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field
// should be set, but Sun docs do. Also readelf relies on this field.
- getParent()->Link = getPartition().DynSymTab->getParent()->SectionIndex;
+ getParent()->link = getPartition().dynSymTab->getParent()->sectionIndex;
}
size_t VersionTableSection::getSize() const {
- return (getPartition().DynSymTab->getSymbols().size() + 1) * 2;
+ return (getPartition().dynSymTab->getSymbols().size() + 1) * 2;
}
-void VersionTableSection::writeTo(uint8_t *Buf) {
- Buf += 2;
- for (const SymbolTableEntry &S : getPartition().DynSymTab->getSymbols()) {
- write16(Buf, S.Sym->VersionId);
- Buf += 2;
+void VersionTableSection::writeTo(uint8_t *buf) {
+ buf += 2;
+ for (const SymbolTableEntry &s : getPartition().dynSymTab->getSymbols()) {
+ write16(buf, s.sym->versionId);
+ buf += 2;
}
}
bool VersionTableSection::isNeeded() const {
- return getPartition().VerDef || getPartition().VerNeed->isNeeded();
+ return getPartition().verDef || getPartition().verNeed->isNeeded();
}
-void elf::addVerneed(Symbol *SS) {
- auto &File = cast<SharedFile>(*SS->File);
- if (SS->VerdefIndex == VER_NDX_GLOBAL) {
- SS->VersionId = VER_NDX_GLOBAL;
+void elf::addVerneed(Symbol *ss) {
+ auto &file = cast<SharedFile>(*ss->file);
+ if (ss->verdefIndex == VER_NDX_GLOBAL) {
+ ss->versionId = VER_NDX_GLOBAL;
return;
}
- if (File.Vernauxs.empty())
- File.Vernauxs.resize(File.Verdefs.size());
+ if (file.vernauxs.empty())
+ file.vernauxs.resize(file.verdefs.size());
// Select a version identifier for the vernaux data structure, if we haven't
// already allocated one. The verdef identifiers cover the range
// [1..getVerDefNum()]; this causes the vernaux identifiers to start from
// getVerDefNum()+1.
- if (File.Vernauxs[SS->VerdefIndex] == 0)
- File.Vernauxs[SS->VerdefIndex] = ++SharedFile::VernauxNum + getVerDefNum();
+ if (file.vernauxs[ss->verdefIndex] == 0)
+ file.vernauxs[ss->verdefIndex] = ++SharedFile::vernauxNum + getVerDefNum();
- SS->VersionId = File.Vernauxs[SS->VerdefIndex];
+ ss->versionId = file.vernauxs[ss->verdefIndex];
}
template <class ELFT>
@@ -2854,107 +2854,107 @@ VersionNeedSection<ELFT>::VersionNeedSection()
".gnu.version_r") {}
template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
- for (SharedFile *F : SharedFiles) {
- if (F->Vernauxs.empty())
+ for (SharedFile *f : sharedFiles) {
+ if (f->vernauxs.empty())
continue;
- Verneeds.emplace_back();
- Verneed &VN = Verneeds.back();
- VN.NameStrTab = getPartition().DynStrTab->addString(F->SoName);
- for (unsigned I = 0; I != F->Vernauxs.size(); ++I) {
- if (F->Vernauxs[I] == 0)
+ verneeds.emplace_back();
+ Verneed &vn = verneeds.back();
+ vn.nameStrTab = getPartition().dynStrTab->addString(f->soName);
+ for (unsigned i = 0; i != f->vernauxs.size(); ++i) {
+ if (f->vernauxs[i] == 0)
continue;
- auto *Verdef =
- reinterpret_cast<const typename ELFT::Verdef *>(F->Verdefs[I]);
- VN.Vernauxs.push_back(
- {Verdef->vd_hash, F->Vernauxs[I],
- getPartition().DynStrTab->addString(F->getStringTable().data() +
- Verdef->getAux()->vda_name)});
+ auto *verdef =
+ reinterpret_cast<const typename ELFT::Verdef *>(f->verdefs[i]);
+ vn.vernauxs.push_back(
+ {verdef->vd_hash, f->vernauxs[i],
+ getPartition().dynStrTab->addString(f->getStringTable().data() +
+ verdef->getAux()->vda_name)});
}
}
- if (OutputSection *Sec = getPartition().DynStrTab->getParent())
- getParent()->Link = Sec->SectionIndex;
- getParent()->Info = Verneeds.size();
+ if (OutputSection *sec = getPartition().dynStrTab->getParent())
+ getParent()->link = sec->sectionIndex;
+ getParent()->info = verneeds.size();
}
-template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
+template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *buf) {
// The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
- auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
- auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Verneeds.size());
+ auto *verneed = reinterpret_cast<Elf_Verneed *>(buf);
+ auto *vernaux = reinterpret_cast<Elf_Vernaux *>(verneed + verneeds.size());
- for (auto &VN : Verneeds) {
+ for (auto &vn : verneeds) {
// Create an Elf_Verneed for this DSO.
- Verneed->vn_version = 1;
- Verneed->vn_cnt = VN.Vernauxs.size();
- Verneed->vn_file = VN.NameStrTab;
- Verneed->vn_aux =
- reinterpret_cast<char *>(Vernaux) - reinterpret_cast<char *>(Verneed);
- Verneed->vn_next = sizeof(Elf_Verneed);
- ++Verneed;
+ verneed->vn_version = 1;
+ verneed->vn_cnt = vn.vernauxs.size();
+ verneed->vn_file = vn.nameStrTab;
+ verneed->vn_aux =
+ reinterpret_cast<char *>(vernaux) - reinterpret_cast<char *>(verneed);
+ verneed->vn_next = sizeof(Elf_Verneed);
+ ++verneed;
// Create the Elf_Vernauxs for this Elf_Verneed.
- for (auto &VNA : VN.Vernauxs) {
- Vernaux->vna_hash = VNA.Hash;
- Vernaux->vna_flags = 0;
- Vernaux->vna_other = VNA.VerneedIndex;
- Vernaux->vna_name = VNA.NameStrTab;
- Vernaux->vna_next = sizeof(Elf_Vernaux);
- ++Vernaux;
+ for (auto &vna : vn.vernauxs) {
+ vernaux->vna_hash = vna.hash;
+ vernaux->vna_flags = 0;
+ vernaux->vna_other = vna.verneedIndex;
+ vernaux->vna_name = vna.nameStrTab;
+ vernaux->vna_next = sizeof(Elf_Vernaux);
+ ++vernaux;
}
- Vernaux[-1].vna_next = 0;
+ vernaux[-1].vna_next = 0;
}
- Verneed[-1].vn_next = 0;
+ verneed[-1].vn_next = 0;
}
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
- return Verneeds.size() * sizeof(Elf_Verneed) +
- SharedFile::VernauxNum * sizeof(Elf_Vernaux);
+ return verneeds.size() * sizeof(Elf_Verneed) +
+ SharedFile::vernauxNum * sizeof(Elf_Vernaux);
}
template <class ELFT> bool VersionNeedSection<ELFT>::isNeeded() const {
- return SharedFile::VernauxNum != 0;
+ return SharedFile::vernauxNum != 0;
}
-void MergeSyntheticSection::addSection(MergeInputSection *MS) {
- MS->Parent = this;
- Sections.push_back(MS);
- assert(Alignment == MS->Alignment || !(MS->Flags & SHF_STRINGS));
- Alignment = std::max(Alignment, MS->Alignment);
+void MergeSyntheticSection::addSection(MergeInputSection *ms) {
+ ms->parent = this;
+ sections.push_back(ms);
+ assert(alignment == ms->alignment || !(ms->flags & SHF_STRINGS));
+ alignment = std::max(alignment, ms->alignment);
}
-MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type,
- uint64_t Flags, uint32_t Alignment)
- : MergeSyntheticSection(Name, Type, Flags, Alignment),
- Builder(StringTableBuilder::RAW, Alignment) {}
+MergeTailSection::MergeTailSection(StringRef name, uint32_t type,
+ uint64_t flags, uint32_t alignment)
+ : MergeSyntheticSection(name, type, flags, alignment),
+ builder(StringTableBuilder::RAW, alignment) {}
-size_t MergeTailSection::getSize() const { return Builder.getSize(); }
+size_t MergeTailSection::getSize() const { return builder.getSize(); }
-void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }
+void MergeTailSection::writeTo(uint8_t *buf) { builder.write(buf); }
void MergeTailSection::finalizeContents() {
// Add all string pieces to the string table builder to create section
// contents.
- for (MergeInputSection *Sec : Sections)
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Builder.add(Sec->getData(I));
+ for (MergeInputSection *sec : sections)
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ builder.add(sec->getData(i));
// Fix the string table content. After this, the contents will never change.
- Builder.finalize();
+ builder.finalize();
// finalize() fixed tail-optimized strings, so we can now get
// offsets of strings. Get an offset for each string and save it
// to a corresponding StringPiece for easy access.
- for (MergeInputSection *Sec : Sections)
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
+ for (MergeInputSection *sec : sections)
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ sec->pieces[i].outputOff = builder.getOffset(sec->getData(i));
}
-void MergeNoTailSection::writeTo(uint8_t *Buf) {
- for (size_t I = 0; I < NumShards; ++I)
- Shards[I].write(Buf + ShardOffsets[I]);
+void MergeNoTailSection::writeTo(uint8_t *buf) {
+ for (size_t i = 0; i < numShards; ++i)
+ shards[i].write(buf + shardOffsets[i]);
}
// This function is very hot (i.e. it can take several seconds to finish)
@@ -2967,68 +2967,68 @@ void MergeNoTailSection::writeTo(uint8_t *Buf) {
// We do it in parallel.
void MergeNoTailSection::finalizeContents() {
// Initializes string table builders.
- for (size_t I = 0; I < NumShards; ++I)
- Shards.emplace_back(StringTableBuilder::RAW, Alignment);
+ for (size_t i = 0; i < numShards; ++i)
+ shards.emplace_back(StringTableBuilder::RAW, alignment);
// Concurrency level. Must be a power of 2 to avoid expensive modulo
// operations in the following tight loop.
- size_t Concurrency = 1;
+ size_t concurrency = 1;
if (ThreadsEnabled)
- Concurrency =
- std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
+ concurrency =
+ std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
// Add section pieces to the builders.
- parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
- for (MergeInputSection *Sec : Sections) {
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
- if (!Sec->Pieces[I].Live)
+ parallelForEachN(0, concurrency, [&](size_t threadId) {
+ for (MergeInputSection *sec : sections) {
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i) {
+ if (!sec->pieces[i].live)
continue;
- size_t ShardId = getShardId(Sec->Pieces[I].Hash);
- if ((ShardId & (Concurrency - 1)) == ThreadId)
- Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I));
+ size_t shardId = getShardId(sec->pieces[i].hash);
+ if ((shardId & (concurrency - 1)) == threadId)
+ sec->pieces[i].outputOff = shards[shardId].add(sec->getData(i));
}
}
});
// Compute an in-section offset for each shard.
- size_t Off = 0;
- for (size_t I = 0; I < NumShards; ++I) {
- Shards[I].finalizeInOrder();
- if (Shards[I].getSize() > 0)
- Off = alignTo(Off, Alignment);
- ShardOffsets[I] = Off;
- Off += Shards[I].getSize();
+ size_t off = 0;
+ for (size_t i = 0; i < numShards; ++i) {
+ shards[i].finalizeInOrder();
+ if (shards[i].getSize() > 0)
+ off = alignTo(off, alignment);
+ shardOffsets[i] = off;
+ off += shards[i].getSize();
}
- Size = Off;
+ size = off;
// So far, section pieces have offsets from beginning of shards, but
// we want offsets from beginning of the whole section. Fix them.
- parallelForEach(Sections, [&](MergeInputSection *Sec) {
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Sec->Pieces[I].OutputOff +=
- ShardOffsets[getShardId(Sec->Pieces[I].Hash)];
+ parallelForEach(sections, [&](MergeInputSection *sec) {
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ sec->pieces[i].outputOff +=
+ shardOffsets[getShardId(sec->pieces[i].hash)];
});
}
-static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
- uint32_t Type,
- uint64_t Flags,
- uint32_t Alignment) {
- bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2;
- if (ShouldTailMerge)
- return make<MergeTailSection>(Name, Type, Flags, Alignment);
- return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
+static MergeSyntheticSection *createMergeSynthetic(StringRef name,
+ uint32_t type,
+ uint64_t flags,
+ uint32_t alignment) {
+ bool shouldTailMerge = (flags & SHF_STRINGS) && config->optimize >= 2;
+ if (shouldTailMerge)
+ return make<MergeTailSection>(name, type, flags, alignment);
+ return make<MergeNoTailSection>(name, type, flags, alignment);
}
template <class ELFT> void elf::splitSections() {
// splitIntoPieces needs to be called on each MergeInputSection
// before calling finalizeContents().
- parallelForEach(InputSections, [](InputSectionBase *Sec) {
- if (auto *S = dyn_cast<MergeInputSection>(Sec))
- S->splitIntoPieces();
- else if (auto *Eh = dyn_cast<EhInputSection>(Sec))
- Eh->split<ELFT>();
+ parallelForEach(inputSections, [](InputSectionBase *sec) {
+ if (auto *s = dyn_cast<MergeInputSection>(sec))
+ s->splitIntoPieces();
+ else if (auto *eh = dyn_cast<EhInputSection>(sec))
+ eh->split<ELFT>();
});
}
@@ -3040,22 +3040,22 @@ template <class ELFT> void elf::splitSections() {
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
void elf::mergeSections() {
- std::vector<MergeSyntheticSection *> MergeSections;
- for (InputSectionBase *&S : InputSections) {
- MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
- if (!MS)
+ std::vector<MergeSyntheticSection *> mergeSections;
+ for (InputSectionBase *&s : inputSections) {
+ MergeInputSection *ms = dyn_cast<MergeInputSection>(s);
+ if (!ms)
continue;
// We do not want to handle sections that are not alive, so just remove
// them instead of trying to merge.
- if (!MS->isLive()) {
- S = nullptr;
+ if (!ms->isLive()) {
+ s = nullptr;
continue;
}
- StringRef OutsecName = getOutputSectionName(MS);
+ StringRef outsecName = getOutputSectionName(ms);
- auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
+ auto i = llvm::find_if(mergeSections, [=](MergeSyntheticSection *sec) {
// While we could create a single synthetic section for two different
// values of Entsize, it is better to take Entsize into consideration.
//
@@ -3066,55 +3066,55 @@ void elf::mergeSections() {
// section.
//
// SHF_STRINGS section with different alignments should not be merged.
- return Sec->Name == OutsecName && Sec->Flags == MS->Flags &&
- Sec->Entsize == MS->Entsize &&
- (Sec->Alignment == MS->Alignment || !(Sec->Flags & SHF_STRINGS));
+ return sec->name == outsecName && sec->flags == ms->flags &&
+ sec->entsize == ms->entsize &&
+ (sec->alignment == ms->alignment || !(sec->flags & SHF_STRINGS));
});
- if (I == MergeSections.end()) {
- MergeSyntheticSection *Syn =
- createMergeSynthetic(OutsecName, MS->Type, MS->Flags, MS->Alignment);
- MergeSections.push_back(Syn);
- I = std::prev(MergeSections.end());
- S = Syn;
- Syn->Entsize = MS->Entsize;
+ if (i == mergeSections.end()) {
+ MergeSyntheticSection *syn =
+ createMergeSynthetic(outsecName, ms->type, ms->flags, ms->alignment);
+ mergeSections.push_back(syn);
+ i = std::prev(mergeSections.end());
+ s = syn;
+ syn->entsize = ms->entsize;
} else {
- S = nullptr;
+ s = nullptr;
}
- (*I)->addSection(MS);
+ (*i)->addSection(ms);
}
- for (auto *MS : MergeSections)
- MS->finalizeContents();
+ for (auto *ms : mergeSections)
+ ms->finalizeContents();
- std::vector<InputSectionBase *> &V = InputSections;
- V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+ std::vector<InputSectionBase *> &v = inputSections;
+ v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
}
MipsRldMapSection::MipsRldMapSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".rld_map") {}
ARMExidxSyntheticSection::ARMExidxSyntheticSection()
: SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
- Config->Wordsize, ".ARM.exidx") {}
+ config->wordsize, ".ARM.exidx") {}
-static InputSection *findExidxSection(InputSection *IS) {
- for (InputSection *D : IS->DependentSections)
- if (D->Type == SHT_ARM_EXIDX)
- return D;
+static InputSection *findExidxSection(InputSection *isec) {
+ for (InputSection *d : isec->dependentSections)
+ if (d->type == SHT_ARM_EXIDX)
+ return d;
return nullptr;
}
-bool ARMExidxSyntheticSection::addSection(InputSection *IS) {
- if (IS->Type == SHT_ARM_EXIDX) {
- ExidxSections.push_back(IS);
+bool ARMExidxSyntheticSection::addSection(InputSection *isec) {
+ if (isec->type == SHT_ARM_EXIDX) {
+ exidxSections.push_back(isec);
return true;
}
- if ((IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) &&
- IS->getSize() > 0) {
- ExecutableSections.push_back(IS);
- if (Empty && findExidxSection(IS))
- Empty = false;
+ if ((isec->flags & SHF_ALLOC) && (isec->flags & SHF_EXECINSTR) &&
+ isec->getSize() > 0) {
+ executableSections.push_back(isec);
+ if (empty && findExidxSection(isec))
+ empty = false;
return false;
}
@@ -3123,9 +3123,9 @@ bool ARMExidxSyntheticSection::addSection(InputSection *IS) {
// and we would have to erase at a late stage relocations from merged entries.
// Given that exception tables are already position independent and a binary
// analyzer could derive the relocations we choose to erase the relocations.
- if (Config->EmitRelocs && IS->Type == SHT_REL)
- if (InputSectionBase *EX = IS->getRelocatedSection())
- if (isa<InputSection>(EX) && EX->Type == SHT_ARM_EXIDX)
+ if (config->emitRelocs && isec->type == SHT_REL)
+ if (InputSectionBase *ex = isec->getRelocatedSection())
+ if (isa<InputSection>(ex) && ex->type == SHT_ARM_EXIDX)
return true;
return false;
@@ -3133,8 +3133,8 @@ bool ARMExidxSyntheticSection::addSection(InputSection *IS) {
// References to .ARM.Extab Sections have bit 31 clear and are not the
// special EXIDX_CANTUNWIND bit-pattern.
-static bool isExtabRef(uint32_t Unwind) {
- return (Unwind & 0x80000000) == 0 && Unwind != 0x1;
+static bool isExtabRef(uint32_t unwind) {
+ return (unwind & 0x80000000) == 0 && unwind != 0x1;
}
// Return true if the .ARM.exidx section Cur can be merged into the .ARM.exidx
@@ -3142,18 +3142,18 @@ static bool isExtabRef(uint32_t Unwind) {
// unwinding instructions in Cur are identical to Prev. Linker generated
// EXIDX_CANTUNWIND entries are represented by nullptr as they do not have an
// InputSection.
-static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
+static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
struct ExidxEntry {
- ulittle32_t Fn;
- ulittle32_t Unwind;
+ ulittle32_t fn;
+ ulittle32_t unwind;
};
// Get the last table Entry from the previous .ARM.exidx section. If Prev is
// nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
- ExidxEntry PrevEntry = {ulittle32_t(0), ulittle32_t(1)};
- if (Prev)
- PrevEntry = Prev->getDataAs<ExidxEntry>().back();
- if (isExtabRef(PrevEntry.Unwind))
+ ExidxEntry prevEntry = {ulittle32_t(0), ulittle32_t(1)};
+ if (prev)
+ prevEntry = prev->getDataAs<ExidxEntry>().back();
+ if (isExtabRef(prevEntry.unwind))
return false;
// We consider the unwind instructions of an .ARM.exidx table entry
@@ -3165,11 +3165,11 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
// are identical is high.
// If Cur is nullptr then this is synthesized EXIDX_CANTUNWIND entry.
- if (Cur == nullptr)
- return PrevEntry.Unwind == 1;
+ if (cur == nullptr)
+ return prevEntry.unwind == 1;
- for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())
- if (isExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
+ for (const ExidxEntry entry : cur->getDataAs<ExidxEntry>())
+ if (isExtabRef(entry.unwind) || entry.unwind != prevEntry.unwind)
return false;
// All table entries in this .ARM.exidx Section can be merged into the
@@ -3187,51 +3187,51 @@ void ARMExidxSyntheticSection::finalizeContents() {
// Sort the executable sections that may or may not have associated
// .ARM.exidx sections by order of ascending address. This requires the
// relative positions of InputSections to be known.
- auto CompareByFilePosition = [](const InputSection *A,
- const InputSection *B) {
- OutputSection *AOut = A->getParent();
- OutputSection *BOut = B->getParent();
-
- if (AOut != BOut)
- return AOut->SectionIndex < BOut->SectionIndex;
- return A->OutSecOff < B->OutSecOff;
+ auto compareByFilePosition = [](const InputSection *a,
+ const InputSection *b) {
+ OutputSection *aOut = a->getParent();
+ OutputSection *bOut = b->getParent();
+
+ if (aOut != bOut)
+ return aOut->sectionIndex < bOut->sectionIndex;
+ return a->outSecOff < b->outSecOff;
};
- llvm::stable_sort(ExecutableSections, CompareByFilePosition);
- Sentinel = ExecutableSections.back();
+ llvm::stable_sort(executableSections, compareByFilePosition);
+ sentinel = executableSections.back();
// Optionally merge adjacent duplicate entries.
- if (Config->MergeArmExidx) {
- std::vector<InputSection *> SelectedSections;
- SelectedSections.reserve(ExecutableSections.size());
- SelectedSections.push_back(ExecutableSections[0]);
- size_t Prev = 0;
- for (size_t I = 1; I < ExecutableSections.size(); ++I) {
- InputSection *EX1 = findExidxSection(ExecutableSections[Prev]);
- InputSection *EX2 = findExidxSection(ExecutableSections[I]);
- if (!isDuplicateArmExidxSec(EX1, EX2)) {
- SelectedSections.push_back(ExecutableSections[I]);
- Prev = I;
+ if (config->mergeArmExidx) {
+ std::vector<InputSection *> selectedSections;
+ selectedSections.reserve(executableSections.size());
+ selectedSections.push_back(executableSections[0]);
+ size_t prev = 0;
+ for (size_t i = 1; i < executableSections.size(); ++i) {
+ InputSection *ex1 = findExidxSection(executableSections[prev]);
+ InputSection *ex2 = findExidxSection(executableSections[i]);
+ if (!isDuplicateArmExidxSec(ex1, ex2)) {
+ selectedSections.push_back(executableSections[i]);
+ prev = i;
}
}
- ExecutableSections = std::move(SelectedSections);
+ executableSections = std::move(selectedSections);
}
- size_t Offset = 0;
- Size = 0;
- for (InputSection *IS : ExecutableSections) {
- if (InputSection *D = findExidxSection(IS)) {
- D->OutSecOff = Offset;
- D->Parent = getParent();
- Offset += D->getSize();
+ size_t offset = 0;
+ size = 0;
+ for (InputSection *isec : executableSections) {
+ if (InputSection *d = findExidxSection(isec)) {
+ d->outSecOff = offset;
+ d->parent = getParent();
+ offset += d->getSize();
} else {
- Offset += 8;
+ offset += 8;
}
}
// Size includes Sentinel.
- Size = Offset + 8;
+ size = offset + 8;
}
InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
- return ExecutableSections.front();
+ return executableSections.front();
}
// To write the .ARM.exidx table from the ExecutableSections we have three cases
@@ -3243,75 +3243,75 @@ InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
// section is to terminate the address range of the previous entry.
// 3.) A trailing EXIDX_CANTUNWIND sentinel section is required at the end of
// the table to terminate the address range of the final entry.
-void ARMExidxSyntheticSection::writeTo(uint8_t *Buf) {
+void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
- const uint8_t CantUnwindData[8] = {0, 0, 0, 0, // PREL31 to target
+ const uint8_t cantUnwindData[8] = {0, 0, 0, 0, // PREL31 to target
1, 0, 0, 0}; // EXIDX_CANTUNWIND
- uint64_t Offset = 0;
- for (InputSection *IS : ExecutableSections) {
- assert(IS->getParent() != nullptr);
- if (InputSection *D = findExidxSection(IS)) {
- memcpy(Buf + Offset, D->data().data(), D->data().size());
- D->relocateAlloc(Buf, Buf + D->getSize());
- Offset += D->getSize();
+ uint64_t offset = 0;
+ for (InputSection *isec : executableSections) {
+ assert(isec->getParent() != nullptr);
+ if (InputSection *d = findExidxSection(isec)) {
+ memcpy(buf + offset, d->data().data(), d->data().size());
+ d->relocateAlloc(buf, buf + d->getSize());
+ offset += d->getSize();
} else {
// A Linker generated CANTUNWIND section.
- memcpy(Buf + Offset, CantUnwindData, sizeof(CantUnwindData));
- uint64_t S = IS->getVA();
- uint64_t P = getVA() + Offset;
- Target->relocateOne(Buf + Offset, R_ARM_PREL31, S - P);
- Offset += 8;
+ memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
+ uint64_t s = isec->getVA();
+ uint64_t p = getVA() + offset;
+ target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
+ offset += 8;
}
}
// Write Sentinel.
- memcpy(Buf + Offset, CantUnwindData, sizeof(CantUnwindData));
- uint64_t S = Sentinel->getVA(Sentinel->getSize());
- uint64_t P = getVA() + Offset;
- Target->relocateOne(Buf + Offset, R_ARM_PREL31, S - P);
- assert(Size == Offset + 8);
+ memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
+ uint64_t s = sentinel->getVA(sentinel->getSize());
+ uint64_t p = getVA() + offset;
+ target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
+ assert(size == offset + 8);
}
-bool ARMExidxSyntheticSection::classof(const SectionBase *D) {
- return D->kind() == InputSectionBase::Synthetic && D->Type == SHT_ARM_EXIDX;
+bool ARMExidxSyntheticSection::classof(const SectionBase *d) {
+ return d->kind() == InputSectionBase::Synthetic && d->type == SHT_ARM_EXIDX;
}
-ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
+ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
- Config->Wordsize, ".text.thunk") {
- this->Parent = OS;
- this->OutSecOff = Off;
+ config->wordsize, ".text.thunk") {
+ this->parent = os;
+ this->outSecOff = off;
}
-void ThunkSection::addThunk(Thunk *T) {
- Thunks.push_back(T);
- T->addSymbols(*this);
+void ThunkSection::addThunk(Thunk *t) {
+ thunks.push_back(t);
+ t->addSymbols(*this);
}
-void ThunkSection::writeTo(uint8_t *Buf) {
- for (Thunk *T : Thunks)
- T->writeTo(Buf + T->Offset);
+void ThunkSection::writeTo(uint8_t *buf) {
+ for (Thunk *t : thunks)
+ t->writeTo(buf + t->offset);
}
InputSection *ThunkSection::getTargetInputSection() const {
- if (Thunks.empty())
+ if (thunks.empty())
return nullptr;
- const Thunk *T = Thunks.front();
- return T->getTargetInputSection();
+ const Thunk *t = thunks.front();
+ return t->getTargetInputSection();
}
bool ThunkSection::assignOffsets() {
- uint64_t Off = 0;
- for (Thunk *T : Thunks) {
- Off = alignTo(Off, T->Alignment);
- T->setOffset(Off);
- uint32_t Size = T->size();
- T->getThunkTargetSym()->Size = Size;
- Off += Size;
+ uint64_t off = 0;
+ for (Thunk *t : thunks) {
+ off = alignTo(off, t->alignment);
+ t->setOffset(off);
+ uint32_t size = t->size();
+ t->getThunkTargetSym()->size = size;
+ off += size;
}
- bool Changed = Off != Size;
- Size = Off;
- return Changed;
+ bool changed = off != size;
+ size = off;
+ return changed;
}
PPC32Got2Section::PPC32Got2Section()
@@ -3320,10 +3320,10 @@ PPC32Got2Section::PPC32Got2Section()
bool PPC32Got2Section::isNeeded() const {
// See the comment below. This is not needed if there is no other
// InputSection.
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- for (InputSection *IS : ISD->Sections)
- if (IS != this)
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ for (InputSection *isec : isd->sections)
+ if (isec != this)
return true;
return false;
}
@@ -3333,14 +3333,14 @@ void PPC32Got2Section::finalizeContents() {
// .got2 . This function computes OutSecOff of each .got2 to be used in
// PPC32PltCallStub::writeTo(). The purpose of this empty synthetic section is
// to collect input sections named ".got2".
- uint32_t Offset = 0;
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- for (InputSection *IS : ISD->Sections) {
- if (IS == this)
+ uint32_t offset = 0;
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
+ for (InputSection *isec : isd->sections) {
+ if (isec == this)
continue;
- IS->File->PPC32Got2OutSecOff = Offset;
- Offset += (uint32_t)IS->getSize();
+ isec->file->ppc32Got2OutSecOff = offset;
+ offset += (uint32_t)isec->getSize();
}
}
}
@@ -3351,33 +3351,33 @@ void PPC32Got2Section::finalizeContents() {
// allocated and filled in by the dynamic linker.
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
+ config->isPic ? SHT_NOBITS : SHT_PROGBITS, 8,
".branch_lt") {}
-void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
- assert(Sym.PPC64BranchltIndex == 0xffff);
- Sym.PPC64BranchltIndex = Entries.size();
- Entries.push_back(&Sym);
+void PPC64LongBranchTargetSection::addEntry(Symbol &sym) {
+ assert(sym.ppc64BranchltIndex == 0xffff);
+ sym.ppc64BranchltIndex = entries.size();
+ entries.push_back(&sym);
}
size_t PPC64LongBranchTargetSection::getSize() const {
- return Entries.size() * 8;
+ return entries.size() * 8;
}
-void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
+void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
// If linking non-pic we have the final addresses of the targets and they get
// written to the table directly. For pic the dynamic linker will allocate
// the section and fill it it.
- if (Config->Pic)
+ if (config->isPic)
return;
- for (const Symbol *Sym : Entries) {
- assert(Sym->getVA());
+ for (const Symbol *sym : entries) {
+ assert(sym->getVA());
// Need calls to branch to the local entry-point since a long-branch
// must be a local-call.
- write64(Buf,
- Sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(Sym->StOther));
- Buf += 8;
+ write64(buf,
+ sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
+ buf += 8;
}
}
@@ -3388,85 +3388,85 @@ bool PPC64LongBranchTargetSection::isNeeded() const {
// only gets set to true once `finalizeSections()` is called after thunk
// creation. Becuase of this, if we don't create any long-branch thunks we end
// up with an empty .branch_lt section in the binary.
- return !Finalized || !Entries.empty();
+ return !finalized || !entries.empty();
}
RISCVSdataSection::RISCVSdataSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 1, ".sdata") {}
bool RISCVSdataSection::isNeeded() const {
- if (!ElfSym::RISCVGlobalPointer)
+ if (!ElfSym::riscvGlobalPointer)
return false;
// __global_pointer$ is defined relative to .sdata . If the section does not
// exist, create a dummy one.
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- for (InputSection *IS : ISD->Sections)
- if (IS != this)
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ for (InputSection *isec : isd->sections)
+ if (isec != this)
return false;
return true;
}
static uint8_t getAbiVersion() {
// MIPS non-PIC executable gets ABI version 1.
- if (Config->EMachine == EM_MIPS) {
- if (!Config->Pic && !Config->Relocatable &&
- (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
+ if (config->emachine == EM_MIPS) {
+ if (!config->isPic && !config->relocatable &&
+ (config->eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
return 1;
return 0;
}
- if (Config->EMachine == EM_AMDGPU) {
- uint8_t Ver = ObjectFiles[0]->ABIVersion;
- for (InputFile *File : makeArrayRef(ObjectFiles).slice(1))
- if (File->ABIVersion != Ver)
- error("incompatible ABI version: " + toString(File));
- return Ver;
+ if (config->emachine == EM_AMDGPU) {
+ uint8_t ver = objectFiles[0]->abiVersion;
+ for (InputFile *file : makeArrayRef(objectFiles).slice(1))
+ if (file->abiVersion != ver)
+ error("incompatible ABI version: " + toString(file));
+ return ver;
}
return 0;
}
-template <typename ELFT> void elf::writeEhdr(uint8_t *Buf, Partition &Part) {
+template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
// For executable segments, the trap instructions are written before writing
// the header. Setting Elf header bytes to zero ensures that any unused bytes
// in header are zero-cleared, instead of having trap instructions.
- memset(Buf, 0, sizeof(typename ELFT::Ehdr));
- memcpy(Buf, "\177ELF", 4);
+ memset(buf, 0, sizeof(typename ELFT::Ehdr));
+ memcpy(buf, "\177ELF", 4);
- auto *EHdr = reinterpret_cast<typename ELFT::Ehdr *>(Buf);
- EHdr->e_ident[EI_CLASS] = Config->Is64 ? ELFCLASS64 : ELFCLASS32;
- EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB;
- EHdr->e_ident[EI_VERSION] = EV_CURRENT;
- EHdr->e_ident[EI_OSABI] = Config->OSABI;
- EHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
- EHdr->e_machine = Config->EMachine;
- EHdr->e_version = EV_CURRENT;
- EHdr->e_flags = Config->EFlags;
- EHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
- EHdr->e_phnum = Part.Phdrs.size();
- EHdr->e_shentsize = sizeof(typename ELFT::Shdr);
+ auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
+ eHdr->e_ident[EI_CLASS] = config->is64 ? ELFCLASS64 : ELFCLASS32;
+ eHdr->e_ident[EI_DATA] = config->isLE ? ELFDATA2LSB : ELFDATA2MSB;
+ eHdr->e_ident[EI_VERSION] = EV_CURRENT;
+ eHdr->e_ident[EI_OSABI] = config->osabi;
+ eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
+ eHdr->e_machine = config->emachine;
+ eHdr->e_version = EV_CURRENT;
+ eHdr->e_flags = config->eflags;
+ eHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
+ eHdr->e_phnum = part.phdrs.size();
+ eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
- if (!Config->Relocatable) {
- EHdr->e_phoff = sizeof(typename ELFT::Ehdr);
- EHdr->e_phentsize = sizeof(typename ELFT::Phdr);
+ if (!config->relocatable) {
+ eHdr->e_phoff = sizeof(typename ELFT::Ehdr);
+ eHdr->e_phentsize = sizeof(typename ELFT::Phdr);
}
}
-template <typename ELFT> void elf::writePhdrs(uint8_t *Buf, Partition &Part) {
+template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) {
// Write the program header table.
- auto *HBuf = reinterpret_cast<typename ELFT::Phdr *>(Buf);
- for (PhdrEntry *P : Part.Phdrs) {
- HBuf->p_type = P->p_type;
- HBuf->p_flags = P->p_flags;
- HBuf->p_offset = P->p_offset;
- HBuf->p_vaddr = P->p_vaddr;
- HBuf->p_paddr = P->p_paddr;
- HBuf->p_filesz = P->p_filesz;
- HBuf->p_memsz = P->p_memsz;
- HBuf->p_align = P->p_align;
- ++HBuf;
+ auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
+ for (PhdrEntry *p : part.phdrs) {
+ hBuf->p_type = p->p_type;
+ hBuf->p_flags = p->p_flags;
+ hBuf->p_offset = p->p_offset;
+ hBuf->p_vaddr = p->p_vaddr;
+ hBuf->p_paddr = p->p_paddr;
+ hBuf->p_filesz = p->p_filesz;
+ hBuf->p_memsz = p->p_memsz;
+ hBuf->p_align = p->p_align;
+ ++hBuf;
}
}
@@ -3480,12 +3480,12 @@ size_t PartitionElfHeaderSection<ELFT>::getSize() const {
}
template <typename ELFT>
-void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *Buf) {
- writeEhdr<ELFT>(Buf, getPartition());
+void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *buf) {
+ writeEhdr<ELFT>(buf, getPartition());
// Loadable partitions are always ET_DYN.
- auto *EHdr = reinterpret_cast<typename ELFT::Ehdr *>(Buf);
- EHdr->e_type = ET_DYN;
+ auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
+ eHdr->e_type = ET_DYN;
}
template <typename ELFT>
@@ -3494,45 +3494,45 @@ PartitionProgramHeadersSection<ELFT>::PartitionProgramHeadersSection()
template <typename ELFT>
size_t PartitionProgramHeadersSection<ELFT>::getSize() const {
- return sizeof(typename ELFT::Phdr) * getPartition().Phdrs.size();
+ return sizeof(typename ELFT::Phdr) * getPartition().phdrs.size();
}
template <typename ELFT>
-void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *Buf) {
- writePhdrs<ELFT>(Buf, getPartition());
+void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *buf) {
+ writePhdrs<ELFT>(buf, getPartition());
}
PartitionIndexSection::PartitionIndexSection()
: SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".rodata") {}
size_t PartitionIndexSection::getSize() const {
- return 12 * (Partitions.size() - 1);
+ return 12 * (partitions.size() - 1);
}
void PartitionIndexSection::finalizeContents() {
- for (size_t I = 1; I != Partitions.size(); ++I)
- Partitions[I].NameStrTab = Main->DynStrTab->addString(Partitions[I].Name);
+ for (size_t i = 1; i != partitions.size(); ++i)
+ partitions[i].nameStrTab = mainPart->dynStrTab->addString(partitions[i].name);
}
-void PartitionIndexSection::writeTo(uint8_t *Buf) {
- uint64_t VA = getVA();
- for (size_t I = 1; I != Partitions.size(); ++I) {
- write32(Buf, Main->DynStrTab->getVA() + Partitions[I].NameStrTab - VA);
- write32(Buf + 4, Partitions[I].ElfHeader->getVA() - (VA + 4));
+void PartitionIndexSection::writeTo(uint8_t *buf) {
+ uint64_t va = getVA();
+ for (size_t i = 1; i != partitions.size(); ++i) {
+ write32(buf, mainPart->dynStrTab->getVA() + partitions[i].nameStrTab - va);
+ write32(buf + 4, partitions[i].elfHeader->getVA() - (va + 4));
- SyntheticSection *Next =
- I == Partitions.size() - 1 ? In.PartEnd : Partitions[I + 1].ElfHeader;
- write32(Buf + 8, Next->getVA() - Partitions[I].ElfHeader->getVA());
+ SyntheticSection *next =
+ i == partitions.size() - 1 ? in.partEnd : partitions[i + 1].elfHeader;
+ write32(buf + 8, next->getVA() - partitions[i].elfHeader->getVA());
- VA += 12;
- Buf += 12;
+ va += 12;
+ buf += 12;
}
}
-InStruct elf::In;
+InStruct elf::in;
-std::vector<Partition> elf::Partitions;
-Partition *elf::Main;
+std::vector<Partition> elf::partitions;
+Partition *elf::mainPart;
template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index ace9f26155a..ab2995554c4 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -37,15 +37,15 @@ class VersionNeedBaseSection;
class SyntheticSection : public InputSection {
public:
- SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
- StringRef Name)
- : InputSection(nullptr, Flags, Type, Alignment, {}, Name,
+ SyntheticSection(uint64_t flags, uint32_t type, uint32_t alignment,
+ StringRef name)
+ : InputSection(nullptr, flags, type, alignment, {}, name,
InputSectionBase::Synthetic) {
markLive();
}
virtual ~SyntheticSection() = default;
- virtual void writeTo(uint8_t *Buf) = 0;
+ virtual void writeTo(uint8_t *buf) = 0;
virtual size_t getSize() const = 0;
virtual void finalizeContents() {}
// If the section has the SHF_ALLOC flag and the size may be changed if
@@ -53,91 +53,91 @@ public:
virtual bool updateAllocSize() { return false; }
virtual bool isNeeded() const { return true; }
- static bool classof(const SectionBase *D) {
- return D->kind() == InputSectionBase::Synthetic;
+ static bool classof(const SectionBase *d) {
+ return d->kind() == InputSectionBase::Synthetic;
}
};
struct CieRecord {
- EhSectionPiece *Cie = nullptr;
- std::vector<EhSectionPiece *> Fdes;
+ EhSectionPiece *cie = nullptr;
+ std::vector<EhSectionPiece *> fdes;
};
// Section for .eh_frame.
class EhFrameSection final : public SyntheticSection {
public:
EhFrameSection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
- bool isNeeded() const override { return !Sections.empty(); }
- size_t getSize() const override { return Size; }
+ bool isNeeded() const override { return !sections.empty(); }
+ size_t getSize() const override { return size; }
- static bool classof(const SectionBase *D) {
- return SyntheticSection::classof(D) && D->Name == ".eh_frame";
+ static bool classof(const SectionBase *d) {
+ return SyntheticSection::classof(d) && d->name == ".eh_frame";
}
- template <class ELFT> void addSection(InputSectionBase *S);
+ template <class ELFT> void addSection(InputSectionBase *s);
- std::vector<EhInputSection *> Sections;
- size_t NumFdes = 0;
+ std::vector<EhInputSection *> sections;
+ size_t numFdes = 0;
struct FdeData {
- uint32_t PcRel;
- uint32_t FdeVARel;
+ uint32_t pcRel;
+ uint32_t fdeVARel;
};
std::vector<FdeData> getFdeData() const;
- ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; }
+ ArrayRef<CieRecord *> getCieRecords() const { return cieRecords; }
private:
// This is used only when parsing EhInputSection. We keep it here to avoid
// allocating one for each EhInputSection.
- llvm::DenseMap<size_t, CieRecord *> OffsetToCie;
+ llvm::DenseMap<size_t, CieRecord *> offsetToCie;
- uint64_t Size = 0;
+ uint64_t size = 0;
template <class ELFT, class RelTy>
- void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
+ void addSectionAux(EhInputSection *s, llvm::ArrayRef<RelTy> rels);
template <class ELFT, class RelTy>
- CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ CieRecord *addCie(EhSectionPiece &piece, ArrayRef<RelTy> rels);
template <class ELFT, class RelTy>
- bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ bool isFdeLive(EhSectionPiece &piece, ArrayRef<RelTy> rels);
- uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc) const;
+ uint64_t getFdePc(uint8_t *buf, size_t off, uint8_t enc) const;
- std::vector<CieRecord *> CieRecords;
+ std::vector<CieRecord *> cieRecords;
// CIE records are uniquified by their contents and personality functions.
- llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> CieMap;
+ llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> cieMap;
};
class GotSection : public SyntheticSection {
public:
GotSection();
- size_t getSize() const override { return Size; }
+ size_t getSize() const override { return size; }
void finalizeContents() override;
bool isNeeded() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
- void addEntry(Symbol &Sym);
- bool addDynTlsEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
+ bool addDynTlsEntry(Symbol &sym);
bool addTlsIndex();
- uint64_t getGlobalDynAddr(const Symbol &B) const;
- uint64_t getGlobalDynOffset(const Symbol &B) const;
+ uint64_t getGlobalDynAddr(const Symbol &b) const;
+ uint64_t getGlobalDynOffset(const Symbol &b) const;
- uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
- uint32_t getTlsIndexOff() const { return TlsIndexOff; }
+ uint64_t getTlsIndexVA() { return this->getVA() + tlsIndexOff; }
+ uint32_t getTlsIndexOff() const { return tlsIndexOff; }
// Flag to force GOT to be in output if we have relocations
// that relies on its address.
- bool HasGotOffRel = false;
+ bool hasGotOffRel = false;
protected:
- size_t NumEntries = 0;
- uint32_t TlsIndexOff = -1;
- uint64_t Size = 0;
+ size_t numEntries = 0;
+ uint32_t tlsIndexOff = -1;
+ uint64_t size = 0;
};
// .note.GNU-stack section.
@@ -145,31 +145,31 @@ class GnuStackSection : public SyntheticSection {
public:
GnuStackSection()
: SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
size_t getSize() const override { return 0; }
};
class GnuPropertySection : public SyntheticSection {
public:
GnuPropertySection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
};
// .note.gnu.build-id section.
class BuildIdSection : public SyntheticSection {
// First 16 bytes are a header.
- static const unsigned HeaderSize = 16;
+ static const unsigned headerSize = 16;
public:
- const size_t HashSize;
+ const size_t hashSize;
BuildIdSection();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return HeaderSize + HashSize; }
- void writeBuildId(llvm::ArrayRef<uint8_t> Buf);
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return headerSize + hashSize; }
+ void writeBuildId(llvm::ArrayRef<uint8_t> buf);
private:
- uint8_t *HashBuf;
+ uint8_t *hashBuf;
};
// BssSection is used to reserve space for copy relocations and common symbols.
@@ -178,22 +178,22 @@ private:
// respectively.
class BssSection final : public SyntheticSection {
public:
- BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);
+ BssSection(StringRef name, uint64_t size, uint32_t alignment);
void writeTo(uint8_t *) override {
llvm_unreachable("unexpected writeTo() call for SHT_NOBITS section");
}
- bool isNeeded() const override { return Size != 0; }
- size_t getSize() const override { return Size; }
+ bool isNeeded() const override { return size != 0; }
+ size_t getSize() const override { return size; }
- static bool classof(const SectionBase *S) { return S->Bss; }
- uint64_t Size;
+ static bool classof(const SectionBase *s) { return s->bss; }
+ uint64_t size;
};
class MipsGotSection final : public SyntheticSection {
public:
MipsGotSection();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
bool updateAllocSize() override;
void finalizeContents() override;
bool isNeeded() const override;
@@ -202,16 +202,16 @@ public:
// primary and optional multiple secondary GOTs.
void build();
- void addEntry(InputFile &File, Symbol &Sym, int64_t Addend, RelExpr Expr);
- void addDynTlsEntry(InputFile &File, Symbol &Sym);
- void addTlsIndex(InputFile &File);
+ void addEntry(InputFile &file, Symbol &sym, int64_t addend, RelExpr expr);
+ void addDynTlsEntry(InputFile &file, Symbol &sym);
+ void addTlsIndex(InputFile &file);
- uint64_t getPageEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const;
- uint64_t getSymEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const;
- uint64_t getGlobalDynOffset(const InputFile *F, const Symbol &S) const;
- uint64_t getTlsIndexOffset(const InputFile *F) const;
+ uint64_t getPageEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const;
+ uint64_t getSymEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const;
+ uint64_t getGlobalDynOffset(const InputFile *f, const Symbol &s) const;
+ uint64_t getTlsIndexOffset(const InputFile *f) const;
// Returns the symbol which corresponds to the first entry of the global part
// of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
@@ -224,7 +224,7 @@ public:
unsigned getLocalEntriesNum() const;
// Return _gp value for primary GOT (nullptr) or particular input file.
- uint64_t getGp(const InputFile *F = nullptr) const;
+ uint64_t getGp(const InputFile *f = nullptr) const;
private:
// MIPS GOT consists of three parts: local, global and tls. Each part
@@ -314,35 +314,35 @@ private:
// https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT
// Number of "Header" entries.
- static const unsigned HeaderEntriesNum = 2;
+ static const unsigned headerEntriesNum = 2;
- uint64_t Size = 0;
+ uint64_t size = 0;
// Symbol and addend.
using GotEntry = std::pair<Symbol *, int64_t>;
struct FileGot {
- InputFile *File = nullptr;
- size_t StartIndex = 0;
+ InputFile *file = nullptr;
+ size_t startIndex = 0;
struct PageBlock {
- size_t FirstIndex;
- size_t Count;
- PageBlock() : FirstIndex(0), Count(0) {}
+ size_t firstIndex;
+ size_t count;
+ PageBlock() : firstIndex(0), count(0) {}
};
// Map output sections referenced by MIPS GOT relocations
// to the description (index/count) "page" entries allocated
// for this section.
- llvm::SmallMapVector<const OutputSection *, PageBlock, 16> PagesMap;
+ llvm::SmallMapVector<const OutputSection *, PageBlock, 16> pagesMap;
// Maps from Symbol+Addend pair or just Symbol to the GOT entry index.
- llvm::MapVector<GotEntry, size_t> Local16;
- llvm::MapVector<GotEntry, size_t> Local32;
- llvm::MapVector<Symbol *, size_t> Global;
- llvm::MapVector<Symbol *, size_t> Relocs;
- llvm::MapVector<Symbol *, size_t> Tls;
+ llvm::MapVector<GotEntry, size_t> local16;
+ llvm::MapVector<GotEntry, size_t> local32;
+ llvm::MapVector<Symbol *, size_t> global;
+ llvm::MapVector<Symbol *, size_t> relocs;
+ llvm::MapVector<Symbol *, size_t> tls;
// Set of symbols referenced by dynamic TLS relocations.
- llvm::MapVector<Symbol *, size_t> DynTlsSymbols;
+ llvm::MapVector<Symbol *, size_t> dynTlsSymbols;
// Total number of all entries.
size_t getEntriesNum() const;
@@ -355,31 +355,31 @@ private:
// Container of GOT created for each input file.
// After building a final series of GOTs this container
// holds primary and secondary GOT's.
- std::vector<FileGot> Gots;
+ std::vector<FileGot> gots;
// Return (and create if necessary) `FileGot`.
- FileGot &getGot(InputFile &F);
+ FileGot &getGot(InputFile &f);
// Try to merge two GOTs. In case of success the `Dst` contains
// result of merging and the function returns true. In case of
// ovwerflow the `Dst` is unchanged and the function returns false.
- bool tryMergeGots(FileGot & Dst, FileGot & Src, bool IsPrimary);
+ bool tryMergeGots(FileGot & dst, FileGot & src, bool isPrimary);
};
class GotPltSection final : public SyntheticSection {
public:
GotPltSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
// Flag to force GotPlt to be in output if we have relocations
// that relies on its address.
- bool HasGotPltOffRel = false;
+ bool hasGotPltOffRel = false;
private:
- std::vector<const Symbol *> Entries;
+ std::vector<const Symbol *> entries;
};
// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
@@ -389,67 +389,67 @@ private:
class IgotPltSection final : public SyntheticSection {
public:
IgotPltSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
- bool isNeeded() const override { return !Entries.empty(); }
+ void writeTo(uint8_t *buf) override;
+ bool isNeeded() const override { return !entries.empty(); }
private:
- std::vector<const Symbol *> Entries;
+ std::vector<const Symbol *> entries;
};
class StringTableSection final : public SyntheticSection {
public:
- StringTableSection(StringRef Name, bool Dynamic);
- unsigned addString(StringRef S, bool HashIt = true);
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
- bool isDynamic() const { return Dynamic; }
+ StringTableSection(StringRef name, bool dynamic);
+ unsigned addString(StringRef s, bool hashIt = true);
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
+ bool isDynamic() const { return dynamic; }
private:
- const bool Dynamic;
+ const bool dynamic;
- uint64_t Size = 0;
+ uint64_t size = 0;
- llvm::DenseMap<StringRef, unsigned> StringMap;
- std::vector<StringRef> Strings;
+ llvm::DenseMap<StringRef, unsigned> stringMap;
+ std::vector<StringRef> strings;
};
class DynamicReloc {
public:
- DynamicReloc(RelType Type, const InputSectionBase *InputSec,
- uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend)
- : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
- UseSymVA(UseSymVA), Addend(Addend), OutputSec(nullptr) {}
+ DynamicReloc(RelType type, const InputSectionBase *inputSec,
+ uint64_t offsetInSec, bool useSymVA, Symbol *sym, int64_t addend)
+ : type(type), sym(sym), inputSec(inputSec), offsetInSec(offsetInSec),
+ useSymVA(useSymVA), addend(addend), outputSec(nullptr) {}
// This constructor records dynamic relocation settings used by MIPS
// multi-GOT implementation. It's to relocate addresses of 64kb pages
// lie inside the output section.
- DynamicReloc(RelType Type, const InputSectionBase *InputSec,
- uint64_t OffsetInSec, const OutputSection *OutputSec,
- int64_t Addend)
- : Type(Type), Sym(nullptr), InputSec(InputSec), OffsetInSec(OffsetInSec),
- UseSymVA(false), Addend(Addend), OutputSec(OutputSec) {}
+ DynamicReloc(RelType type, const InputSectionBase *inputSec,
+ uint64_t offsetInSec, const OutputSection *outputSec,
+ int64_t addend)
+ : type(type), sym(nullptr), inputSec(inputSec), offsetInSec(offsetInSec),
+ useSymVA(false), addend(addend), outputSec(outputSec) {}
uint64_t getOffset() const;
- uint32_t getSymIndex(SymbolTableBaseSection *SymTab) const;
+ uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
// Computes the addend of the dynamic relocation. Note that this is not the
// same as the Addend member variable as it also includes the symbol address
// if UseSymVA is true.
int64_t computeAddend() const;
- RelType Type;
+ RelType type;
- Symbol *Sym;
- const InputSectionBase *InputSec = nullptr;
- uint64_t OffsetInSec;
+ Symbol *sym;
+ const InputSectionBase *inputSec = nullptr;
+ uint64_t offsetInSec;
// If this member is true, the dynamic relocation will not be against the
// symbol but will instead be a relative relocation that simply adds the
// load address. This means we need to write the symbol virtual address
// plus the original addend as the final relocation addend.
- bool UseSymVA;
- int64_t Addend;
- const OutputSection *OutputSec;
+ bool useSymVA;
+ int64_t addend;
+ const OutputSection *outputSec;
};
template <class ELFT> class DynamicSection final : public SyntheticSection {
@@ -461,47 +461,47 @@ template <class ELFT> class DynamicSection final : public SyntheticSection {
using Elf_Sym = typename ELFT::Sym;
// finalizeContents() fills this vector with the section contents.
- std::vector<std::pair<int32_t, std::function<uint64_t()>>> Entries;
+ std::vector<std::pair<int32_t, std::function<uint64_t()>>> entries;
public:
DynamicSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
private:
- void add(int32_t Tag, std::function<uint64_t()> Fn);
- void addInt(int32_t Tag, uint64_t Val);
- void addInSec(int32_t Tag, InputSection *Sec);
- void addInSecRelative(int32_t Tag, InputSection *Sec);
- void addOutSec(int32_t Tag, OutputSection *Sec);
- void addSize(int32_t Tag, OutputSection *Sec);
- void addSym(int32_t Tag, Symbol *Sym);
-
- uint64_t Size = 0;
+ void add(int32_t tag, std::function<uint64_t()> fn);
+ void addInt(int32_t tag, uint64_t val);
+ void addInSec(int32_t tag, InputSection *sec);
+ void addInSecRelative(int32_t tag, InputSection *sec);
+ void addOutSec(int32_t tag, OutputSection *sec);
+ void addSize(int32_t tag, OutputSection *sec);
+ void addSym(int32_t tag, Symbol *sym);
+
+ uint64_t size = 0;
};
class RelocationBaseSection : public SyntheticSection {
public:
- RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag,
- int32_t SizeDynamicTag);
- void addReloc(RelType DynType, InputSectionBase *IS, uint64_t OffsetInSec,
- Symbol *Sym);
+ RelocationBaseSection(StringRef name, uint32_t type, int32_t dynamicTag,
+ int32_t sizeDynamicTag);
+ void addReloc(RelType dynType, InputSectionBase *isec, uint64_t offsetInSec,
+ Symbol *sym);
// Add a dynamic relocation that might need an addend. This takes care of
// writing the addend to the output section if needed.
- void addReloc(RelType DynType, InputSectionBase *InputSec,
- uint64_t OffsetInSec, Symbol *Sym, int64_t Addend, RelExpr Expr,
- RelType Type);
- void addReloc(const DynamicReloc &Reloc);
- bool isNeeded() const override { return !Relocs.empty(); }
- size_t getSize() const override { return Relocs.size() * this->Entsize; }
- size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
+ void addReloc(RelType dynType, InputSectionBase *inputSec,
+ uint64_t offsetInSec, Symbol *sym, int64_t addend, RelExpr expr,
+ RelType type);
+ void addReloc(const DynamicReloc &reloc);
+ bool isNeeded() const override { return !relocs.empty(); }
+ size_t getSize() const override { return relocs.size() * this->entsize; }
+ size_t getRelativeRelocCount() const { return numRelativeRelocs; }
void finalizeContents() override;
- int32_t DynamicTag, SizeDynamicTag;
- std::vector<DynamicReloc> Relocs;
+ int32_t dynamicTag, sizeDynamicTag;
+ std::vector<DynamicReloc> relocs;
protected:
- size_t NumRelativeRelocs = 0;
+ size_t numRelativeRelocs = 0;
};
template <class ELFT>
@@ -510,11 +510,11 @@ class RelocationSection final : public RelocationBaseSection {
using Elf_Rela = typename ELFT::Rela;
public:
- RelocationSection(StringRef Name, bool Sort);
- void writeTo(uint8_t *Buf) override;
+ RelocationSection(StringRef name, bool sort);
+ void writeTo(uint8_t *buf) override;
private:
- bool Sort;
+ bool sort;
};
template <class ELFT>
@@ -523,30 +523,30 @@ class AndroidPackedRelocationSection final : public RelocationBaseSection {
using Elf_Rela = typename ELFT::Rela;
public:
- AndroidPackedRelocationSection(StringRef Name);
+ AndroidPackedRelocationSection(StringRef name);
bool updateAllocSize() override;
- size_t getSize() const override { return RelocData.size(); }
- void writeTo(uint8_t *Buf) override {
- memcpy(Buf, RelocData.data(), RelocData.size());
+ size_t getSize() const override { return relocData.size(); }
+ void writeTo(uint8_t *buf) override {
+ memcpy(buf, relocData.data(), relocData.size());
}
private:
- SmallVector<char, 0> RelocData;
+ SmallVector<char, 0> relocData;
};
struct RelativeReloc {
- uint64_t getOffset() const { return InputSec->getVA(OffsetInSec); }
+ uint64_t getOffset() const { return inputSec->getVA(offsetInSec); }
- const InputSectionBase *InputSec;
- uint64_t OffsetInSec;
+ const InputSectionBase *inputSec;
+ uint64_t offsetInSec;
};
class RelrBaseSection : public SyntheticSection {
public:
RelrBaseSection();
- bool isNeeded() const override { return !Relocs.empty(); }
- std::vector<RelativeReloc> Relocs;
+ bool isNeeded() const override { return !relocs.empty(); }
+ std::vector<RelativeReloc> relocs;
};
// RelrSection is used to encode offsets for relative relocations.
@@ -560,41 +560,41 @@ public:
RelrSection();
bool updateAllocSize() override;
- size_t getSize() const override { return RelrRelocs.size() * this->Entsize; }
- void writeTo(uint8_t *Buf) override {
- memcpy(Buf, RelrRelocs.data(), getSize());
+ size_t getSize() const override { return relrRelocs.size() * this->entsize; }
+ void writeTo(uint8_t *buf) override {
+ memcpy(buf, relrRelocs.data(), getSize());
}
private:
- std::vector<Elf_Relr> RelrRelocs;
+ std::vector<Elf_Relr> relrRelocs;
};
struct SymbolTableEntry {
- Symbol *Sym;
- size_t StrTabOffset;
+ Symbol *sym;
+ size_t strTabOffset;
};
class SymbolTableBaseSection : public SyntheticSection {
public:
- SymbolTableBaseSection(StringTableSection &StrTabSec);
+ SymbolTableBaseSection(StringTableSection &strTabSec);
void finalizeContents() override;
- size_t getSize() const override { return getNumSymbols() * Entsize; }
- void addSymbol(Symbol *Sym);
- unsigned getNumSymbols() const { return Symbols.size() + 1; }
- size_t getSymbolIndex(Symbol *Sym);
- ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
+ size_t getSize() const override { return getNumSymbols() * entsize; }
+ void addSymbol(Symbol *sym);
+ unsigned getNumSymbols() const { return symbols.size() + 1; }
+ size_t getSymbolIndex(Symbol *sym);
+ ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }
protected:
void sortSymTabSymbols();
// A vector of symbols and their string table offsets.
- std::vector<SymbolTableEntry> Symbols;
+ std::vector<SymbolTableEntry> symbols;
- StringTableSection &StrTabSec;
+ StringTableSection &strTabSec;
- llvm::once_flag OnceFlag;
- llvm::DenseMap<Symbol *, size_t> SymbolIndexMap;
- llvm::DenseMap<OutputSection *, size_t> SectionIndexMap;
+ llvm::once_flag onceFlag;
+ llvm::DenseMap<Symbol *, size_t> symbolIndexMap;
+ llvm::DenseMap<OutputSection *, size_t> sectionIndexMap;
};
template <class ELFT>
@@ -602,15 +602,15 @@ class SymbolTableSection final : public SymbolTableBaseSection {
using Elf_Sym = typename ELFT::Sym;
public:
- SymbolTableSection(StringTableSection &StrTabSec);
- void writeTo(uint8_t *Buf) override;
+ SymbolTableSection(StringTableSection &strTabSec);
+ void writeTo(uint8_t *buf) override;
};
class SymtabShndxSection final : public SyntheticSection {
public:
SymtabShndxSection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
void finalizeContents() override;
@@ -622,42 +622,42 @@ class GnuHashTableSection final : public SyntheticSection {
public:
GnuHashTableSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
// Adds symbols to the hash table.
// Sorts the input to satisfy GNU hash section requirements.
- void addSymbols(std::vector<SymbolTableEntry> &Symbols);
+ void addSymbols(std::vector<SymbolTableEntry> &symbols);
private:
// See the comment in writeBloomFilter.
enum { Shift2 = 26 };
- void writeBloomFilter(uint8_t *Buf);
- void writeHashTable(uint8_t *Buf);
+ void writeBloomFilter(uint8_t *buf);
+ void writeHashTable(uint8_t *buf);
struct Entry {
- Symbol *Sym;
- size_t StrTabOffset;
- uint32_t Hash;
- uint32_t BucketIdx;
+ Symbol *sym;
+ size_t strTabOffset;
+ uint32_t hash;
+ uint32_t bucketIdx;
};
- std::vector<Entry> Symbols;
- size_t MaskWords;
- size_t NBuckets = 0;
- size_t Size = 0;
+ std::vector<Entry> symbols;
+ size_t maskWords;
+ size_t nBuckets = 0;
+ size_t size = 0;
};
class HashTableSection final : public SyntheticSection {
public:
HashTableSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
private:
- size_t Size = 0;
+ size_t size = 0;
};
// The PltSection is used for both the Plt and Iplt. The former usually has a
@@ -666,66 +666,66 @@ private:
// Target->IRelativeRel.
class PltSection : public SyntheticSection {
public:
- PltSection(bool IsIplt);
- void writeTo(uint8_t *Buf) override;
+ PltSection(bool isIplt);
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
- bool isNeeded() const override { return !Entries.empty(); }
+ bool isNeeded() const override { return !entries.empty(); }
void addSymbols();
- template <class ELFT> void addEntry(Symbol &Sym);
+ template <class ELFT> void addEntry(Symbol &sym);
- size_t HeaderSize;
+ size_t headerSize;
private:
- std::vector<const Symbol *> Entries;
- bool IsIplt;
+ std::vector<const Symbol *> entries;
+ bool isIplt;
};
class GdbIndexSection final : public SyntheticSection {
public:
struct AddressEntry {
- InputSection *Section;
- uint64_t LowAddress;
- uint64_t HighAddress;
- uint32_t CuIndex;
+ InputSection *section;
+ uint64_t lowAddress;
+ uint64_t highAddress;
+ uint32_t cuIndex;
};
struct CuEntry {
- uint64_t CuOffset;
- uint64_t CuLength;
+ uint64_t cuOffset;
+ uint64_t cuLength;
};
struct NameAttrEntry {
- llvm::CachedHashStringRef Name;
- uint32_t CuIndexAndAttrs;
+ llvm::CachedHashStringRef name;
+ uint32_t cuIndexAndAttrs;
};
struct GdbChunk {
- InputSection *Sec;
- std::vector<AddressEntry> AddressAreas;
- std::vector<CuEntry> CompilationUnits;
+ InputSection *sec;
+ std::vector<AddressEntry> addressAreas;
+ std::vector<CuEntry> compilationUnits;
};
struct GdbSymbol {
- llvm::CachedHashStringRef Name;
- std::vector<uint32_t> CuVector;
- uint32_t NameOff;
- uint32_t CuVectorOff;
+ llvm::CachedHashStringRef name;
+ std::vector<uint32_t> cuVector;
+ uint32_t nameOff;
+ uint32_t cuVectorOff;
};
GdbIndexSection();
template <typename ELFT> static GdbIndexSection *create();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
bool isNeeded() const override;
private:
struct GdbIndexHeader {
- llvm::support::ulittle32_t Version;
- llvm::support::ulittle32_t CuListOff;
- llvm::support::ulittle32_t CuTypesOff;
- llvm::support::ulittle32_t AddressAreaOff;
- llvm::support::ulittle32_t SymtabOff;
- llvm::support::ulittle32_t ConstantPoolOff;
+ llvm::support::ulittle32_t version;
+ llvm::support::ulittle32_t cuListOff;
+ llvm::support::ulittle32_t cuTypesOff;
+ llvm::support::ulittle32_t addressAreaOff;
+ llvm::support::ulittle32_t symtabOff;
+ llvm::support::ulittle32_t constantPoolOff;
};
void initOutputSize();
@@ -733,12 +733,12 @@ private:
// Each chunk contains information gathered from debug sections of a
// single object file.
- std::vector<GdbChunk> Chunks;
+ std::vector<GdbChunk> chunks;
// A symbol table for this .gdb_index section.
- std::vector<GdbSymbol> Symbols;
+ std::vector<GdbSymbol> symbols;
- size_t Size;
+ size_t size;
};
// --eh-frame-hdr option tells linker to construct a header for all the
@@ -754,7 +754,7 @@ class EhFrameHeader final : public SyntheticSection {
public:
EhFrameHeader();
void write();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
};
@@ -772,15 +772,15 @@ public:
VersionDefinitionSection();
void finalizeContents() override;
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
enum { EntrySize = 28 };
- void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
+ void writeOne(uint8_t *buf, uint32_t index, StringRef name, size_t nameOff);
StringRef getFileDefName();
- unsigned FileDefNameOff;
- std::vector<unsigned> VerDefNameOffs;
+ unsigned fileDefNameOff;
+ std::vector<unsigned> verDefNameOffs;
};
// The .gnu.version section specifies the required version of each symbol in the
@@ -794,7 +794,7 @@ public:
VersionTableSection();
void finalizeContents() override;
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
};
@@ -809,22 +809,22 @@ class VersionNeedSection final : public SyntheticSection {
using Elf_Vernaux = typename ELFT::Vernaux;
struct Vernaux {
- uint64_t Hash;
- uint32_t VerneedIndex;
- uint64_t NameStrTab;
+ uint64_t hash;
+ uint32_t verneedIndex;
+ uint64_t nameStrTab;
};
struct Verneed {
- uint64_t NameStrTab;
- std::vector<Vernaux> Vernauxs;
+ uint64_t nameStrTab;
+ std::vector<Vernaux> vernauxs;
};
- std::vector<Verneed> Verneeds;
+ std::vector<Verneed> verneeds;
public:
VersionNeedSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
};
@@ -835,36 +835,36 @@ public:
// attached to regular output sections.
class MergeSyntheticSection : public SyntheticSection {
public:
- void addSection(MergeInputSection *MS);
- std::vector<MergeInputSection *> Sections;
+ void addSection(MergeInputSection *ms);
+ std::vector<MergeInputSection *> sections;
protected:
- MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment)
- : SyntheticSection(Flags, Type, Alignment, Name) {}
+ MergeSyntheticSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment)
+ : SyntheticSection(flags, type, alignment, name) {}
};
class MergeTailSection final : public MergeSyntheticSection {
public:
- MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment);
+ MergeTailSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
private:
- llvm::StringTableBuilder Builder;
+ llvm::StringTableBuilder builder;
};
class MergeNoTailSection final : public MergeSyntheticSection {
public:
- MergeNoTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment)
- : MergeSyntheticSection(Name, Type, Flags, Alignment) {}
+ MergeNoTailSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment)
+ : MergeSyntheticSection(name, type, flags, alignment) {}
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
private:
@@ -873,18 +873,18 @@ private:
// because DenseMap also uses lower bits to determine a bucket ID.
// If we use lower bits, it significantly increases the probability of
// hash collisons.
- size_t getShardId(uint32_t Hash) {
- assert((Hash >> 31) == 0);
- return Hash >> (31 - llvm::countTrailingZeros(NumShards));
+ size_t getShardId(uint32_t hash) {
+ assert((hash >> 31) == 0);
+ return hash >> (31 - llvm::countTrailingZeros(numShards));
}
// Section size
- size_t Size;
+ size_t size;
// String table contents
- constexpr static size_t NumShards = 32;
- std::vector<llvm::StringTableBuilder> Shards;
- size_t ShardOffsets[NumShards];
+ constexpr static size_t numShards = 32;
+ std::vector<llvm::StringTableBuilder> shards;
+ size_t shardOffsets[numShards];
};
// .MIPS.abiflags section.
@@ -895,12 +895,12 @@ class MipsAbiFlagsSection final : public SyntheticSection {
public:
static MipsAbiFlagsSection *create();
- MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags);
+ MipsAbiFlagsSection(Elf_Mips_ABIFlags flags);
size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
- Elf_Mips_ABIFlags Flags;
+ Elf_Mips_ABIFlags flags;
};
// .MIPS.options section.
@@ -911,15 +911,15 @@ template <class ELFT> class MipsOptionsSection final : public SyntheticSection {
public:
static MipsOptionsSection *create();
- MipsOptionsSection(Elf_Mips_RegInfo Reginfo);
- void writeTo(uint8_t *Buf) override;
+ MipsOptionsSection(Elf_Mips_RegInfo reginfo);
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override {
return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
}
private:
- Elf_Mips_RegInfo Reginfo;
+ Elf_Mips_RegInfo reginfo;
};
// MIPS .reginfo section.
@@ -929,12 +929,12 @@ template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
public:
static MipsReginfoSection *create();
- MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
+ MipsReginfoSection(Elf_Mips_RegInfo reginfo);
size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
- Elf_Mips_RegInfo Reginfo;
+ Elf_Mips_RegInfo reginfo;
};
// This is a MIPS specific section to hold a space within the data segment
@@ -944,8 +944,8 @@ private:
class MipsRldMapSection : public SyntheticSection {
public:
MipsRldMapSection();
- size_t getSize() const override { return Config->Wordsize; }
- void writeTo(uint8_t *Buf) override {}
+ size_t getSize() const override { return config->wordsize; }
+ void writeTo(uint8_t *buf) override {}
};
// Representation of the combined .ARM.Exidx input sections. We process these
@@ -988,38 +988,38 @@ public:
// Add an input section to the ARMExidxSyntheticSection. Returns whether the
// section needs to be removed from the main input section list.
- bool addSection(InputSection *IS);
+ bool addSection(InputSection *isec);
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
- bool isNeeded() const override { return !Empty; }
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
+ bool isNeeded() const override { return !empty; }
// Sort and remove duplicate entries.
void finalizeContents() override;
InputSection *getLinkOrderDep() const;
- static bool classof(const SectionBase *D);
+ static bool classof(const SectionBase *d);
// Links to the ARMExidxSections so we can transfer the relocations once the
// layout is known.
- std::vector<InputSection *> ExidxSections;
+ std::vector<InputSection *> exidxSections;
private:
- size_t Size;
+ size_t size;
// Empty if ExecutableSections contains no dependent .ARM.exidx sections.
- bool Empty = true;
+ bool empty = true;
// Instead of storing pointers to the .ARM.exidx InputSections from
// InputObjects, we store pointers to the executable sections that need
// .ARM.exidx sections. We can then use the dependentSections of these to
// either find the .ARM.exidx section or know that we need to generate one.
- std::vector<InputSection *> ExecutableSections;
+ std::vector<InputSection *> executableSections;
// The executable InputSection with the highest address to use for the
// sentinel. We store separately from ExecutableSections as merging of
// duplicate entries may mean this InputSection is removed from
// ExecutableSections.
- InputSection *Sentinel = nullptr;
+ InputSection *sentinel = nullptr;
};
// A container for one or more linker generated thunks. Instances of these
@@ -1027,21 +1027,21 @@ private:
class ThunkSection : public SyntheticSection {
public:
// ThunkSection in OS, with desired OutSecOff of Off
- ThunkSection(OutputSection *OS, uint64_t Off);
+ ThunkSection(OutputSection *os, uint64_t off);
// Add a newly created Thunk to this container:
// Thunk is given offset from start of this InputSection
// Thunk defines a symbol in this InputSection that can be used as target
// of a relocation
- void addThunk(Thunk *T);
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
+ void addThunk(Thunk *t);
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
InputSection *getTargetInputSection() const;
bool assignOffsets();
private:
- std::vector<Thunk *> Thunks;
- size_t Size = 0;
+ std::vector<Thunk *> thunks;
+ size_t size = 0;
};
// Used to compute OutSecOff of .got2 in each object file. This is needed to
@@ -1052,7 +1052,7 @@ public:
size_t getSize() const override { return 0; }
bool isNeeded() const override;
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
};
// This section is used to store the addresses of functions that are called
@@ -1063,15 +1063,15 @@ public:
class PPC64LongBranchTargetSection final : public SyntheticSection {
public:
PPC64LongBranchTargetSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
- void finalizeContents() override { Finalized = true; }
+ void finalizeContents() override { finalized = true; }
private:
- std::vector<const Symbol *> Entries;
- bool Finalized = false;
+ std::vector<const Symbol *> entries;
+ bool finalized = false;
};
template <typename ELFT>
@@ -1079,7 +1079,7 @@ class PartitionElfHeaderSection : public SyntheticSection {
public:
PartitionElfHeaderSection();
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
template <typename ELFT>
@@ -1087,7 +1087,7 @@ class PartitionProgramHeadersSection : public SyntheticSection {
public:
PartitionProgramHeadersSection();
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
class PartitionIndexSection : public SyntheticSection {
@@ -1095,7 +1095,7 @@ public:
PartitionIndexSection();
size_t getSize() const override;
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
// Create a dummy .sdata for __global_pointer$ if .sdata does not exist.
@@ -1104,7 +1104,7 @@ public:
RISCVSdataSection();
size_t getSize() const override { return 0; }
bool isNeeded() const override;
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
};
InputSection *createInterpSection();
@@ -1112,75 +1112,75 @@ MergeInputSection *createCommentSection();
template <class ELFT> void splitSections();
void mergeSections();
-template <typename ELFT> void writeEhdr(uint8_t *Buf, Partition &Part);
-template <typename ELFT> void writePhdrs(uint8_t *Buf, Partition &Part);
+template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part);
+template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);
-Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
- uint64_t Size, InputSectionBase &Section);
+Defined *addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
+ uint64_t size, InputSectionBase &section);
-void addVerneed(Symbol *SS);
+void addVerneed(Symbol *ss);
// Linker generated per-partition sections.
struct Partition {
- StringRef Name;
- uint64_t NameStrTab;
-
- SyntheticSection *ElfHeader;
- SyntheticSection *ProgramHeaders;
- std::vector<PhdrEntry *> Phdrs;
-
- ARMExidxSyntheticSection *ARMExidx;
- BuildIdSection *BuildId;
- SyntheticSection *Dynamic;
- StringTableSection *DynStrTab;
- SymbolTableBaseSection *DynSymTab;
- EhFrameHeader *EhFrameHdr;
- EhFrameSection *EhFrame;
- GnuHashTableSection *GnuHashTab;
- HashTableSection *HashTab;
- RelocationBaseSection *RelaDyn;
- RelrBaseSection *RelrDyn;
- VersionDefinitionSection *VerDef;
- SyntheticSection *VerNeed;
- VersionTableSection *VerSym;
-
- unsigned getNumber() const { return this - &Partitions[0] + 1; }
+ StringRef name;
+ uint64_t nameStrTab;
+
+ SyntheticSection *elfHeader;
+ SyntheticSection *programHeaders;
+ std::vector<PhdrEntry *> phdrs;
+
+ ARMExidxSyntheticSection *armExidx;
+ BuildIdSection *buildId;
+ SyntheticSection *dynamic;
+ StringTableSection *dynStrTab;
+ SymbolTableBaseSection *dynSymTab;
+ EhFrameHeader *ehFrameHdr;
+ EhFrameSection *ehFrame;
+ GnuHashTableSection *gnuHashTab;
+ HashTableSection *hashTab;
+ RelocationBaseSection *relaDyn;
+ RelrBaseSection *relrDyn;
+ VersionDefinitionSection *verDef;
+ SyntheticSection *verNeed;
+ VersionTableSection *verSym;
+
+ unsigned getNumber() const { return this - &partitions[0] + 1; }
};
-extern Partition *Main;
+extern Partition *mainPart;
inline Partition &SectionBase::getPartition() const {
assert(isLive());
- return Partitions[Partition - 1];
+ return partitions[partition - 1];
}
// Linker generated sections which can be used as inputs and are not specific to
// a partition.
struct InStruct {
- InputSection *ARMAttributes;
- BssSection *Bss;
- BssSection *BssRelRo;
- GotSection *Got;
- GotPltSection *GotPlt;
- IgotPltSection *IgotPlt;
- PPC64LongBranchTargetSection *PPC64LongBranchTarget;
- MipsGotSection *MipsGot;
- MipsRldMapSection *MipsRldMap;
- SyntheticSection *PartEnd;
- SyntheticSection *PartIndex;
- PltSection *Plt;
- PltSection *Iplt;
- PPC32Got2Section *PPC32Got2;
- RISCVSdataSection *RISCVSdata;
- RelocationBaseSection *RelaPlt;
- RelocationBaseSection *RelaIplt;
- StringTableSection *ShStrTab;
- StringTableSection *StrTab;
- SymbolTableBaseSection *SymTab;
- SymtabShndxSection *SymTabShndx;
+ InputSection *armAttributes;
+ BssSection *bss;
+ BssSection *bssRelRo;
+ GotSection *got;
+ GotPltSection *gotPlt;
+ IgotPltSection *igotPlt;
+ PPC64LongBranchTargetSection *ppc64LongBranchTarget;
+ MipsGotSection *mipsGot;
+ MipsRldMapSection *mipsRldMap;
+ SyntheticSection *partEnd;
+ SyntheticSection *partIndex;
+ PltSection *plt;
+ PltSection *iplt;
+ PPC32Got2Section *ppc32Got2;
+ RISCVSdataSection *riscvSdata;
+ RelocationBaseSection *relaPlt;
+ RelocationBaseSection *relaIplt;
+ StringTableSection *shStrTab;
+ StringTableSection *strTab;
+ SymbolTableBaseSection *symTab;
+ SymtabShndxSection *symTabShndx;
};
-extern InStruct In;
+extern InStruct in;
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 373e9c3d731..d07478a5178 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -37,17 +37,17 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-const TargetInfo *elf::Target;
+const TargetInfo *elf::target;
-std::string lld::toString(RelType Type) {
- StringRef S = getELFRelocationTypeName(elf::Config->EMachine, Type);
- if (S == "Unknown")
- return ("Unknown (" + Twine(Type) + ")").str();
- return S;
+std::string lld::toString(RelType type) {
+ StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
+ if (s == "Unknown")
+ return ("Unknown (" + Twine(type) + ")").str();
+ return s;
}
TargetInfo *elf::getTarget() {
- switch (Config->EMachine) {
+ switch (config->emachine) {
case EM_386:
case EM_IAMCU:
return getX86TargetInfo();
@@ -62,7 +62,7 @@ TargetInfo *elf::getTarget() {
case EM_HEXAGON:
return getHexagonTargetInfo();
case EM_MIPS:
- switch (Config->EKind) {
+ switch (config->ekind) {
case ELF32LEKind:
return getMipsTargetInfo<ELF32LE>();
case ELF32BEKind:
@@ -90,29 +90,29 @@ TargetInfo *elf::getTarget() {
llvm_unreachable("unknown target machine");
}
-template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {
- for (InputSectionBase *D : InputSections) {
- auto *IS = cast<InputSection>(D);
- if (!IS->getParent())
+template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
+ for (InputSectionBase *d : inputSections) {
+ auto *isec = cast<InputSection>(d);
+ if (!isec->getParent())
continue;
- uint8_t *ISLoc = Out::BufferStart + IS->getParent()->Offset + IS->OutSecOff;
- if (ISLoc <= Loc && Loc < ISLoc + IS->getSize())
- return {IS, IS->template getLocation<ELFT>(Loc - ISLoc) + ": "};
+ uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
+ if (isecLoc <= loc && loc < isecLoc + isec->getSize())
+ return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
}
return {};
}
-ErrorPlace elf::getErrorPlace(const uint8_t *Loc) {
- switch (Config->EKind) {
+ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
+ switch (config->ekind) {
case ELF32LEKind:
- return getErrPlace<ELF32LE>(Loc);
+ return getErrPlace<ELF32LE>(loc);
case ELF32BEKind:
- return getErrPlace<ELF32BE>(Loc);
+ return getErrPlace<ELF32BE>(loc);
case ELF64LEKind:
- return getErrPlace<ELF64LE>(Loc);
+ return getErrPlace<ELF64LE>(loc);
case ELF64BEKind:
- return getErrPlace<ELF64BE>(Loc);
+ return getErrPlace<ELF64BE>(loc);
default:
llvm_unreachable("unknown ELF type");
}
@@ -120,62 +120,62 @@ ErrorPlace elf::getErrorPlace(const uint8_t *Loc) {
TargetInfo::~TargetInfo() {}
-int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
+int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
return 0;
}
-bool TargetInfo::usesOnlyLowPageBits(RelType Type) const { return false; }
+bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
-bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
+bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
return false;
}
-bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const {
+bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const {
llvm_unreachable("Target doesn't support split stacks.");
}
-bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
+bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
return true;
}
-void TargetInfo::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
- writeGotPlt(Buf, S);
+void TargetInfo::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
+ writeGotPlt(buf, s);
}
-RelExpr TargetInfo::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- return Expr;
+RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ return expr;
}
-void TargetInfo::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
uint64_t TargetInfo::getImageBase() const {
// Use -image-base if set. Fall back to the target default if not.
- if (Config->ImageBase)
- return *Config->ImageBase;
- return Config->Pic ? 0 : DefaultImageBase;
+ if (config->imageBase)
+ return *config->imageBase;
+ return config->isPic ? 0 : defaultImageBase;
}
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index e9cbacb8dd7..00c93a9c2e6 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -16,7 +16,7 @@
#include <array>
namespace lld {
-std::string toString(elf::RelType Type);
+std::string toString(elf::RelType type);
namespace elf {
class Defined;
@@ -26,39 +26,39 @@ class Symbol;
class TargetInfo {
public:
virtual uint32_t calcEFlags() const { return 0; }
- virtual RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const = 0;
- virtual RelType getDynRel(RelType Type) const { return 0; }
- virtual void writeGotPltHeader(uint8_t *Buf) const {}
- virtual void writeGotHeader(uint8_t *Buf) const {}
- virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
- virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
- virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
- virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; }
+ virtual RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const = 0;
+ virtual RelType getDynRel(RelType type) const { return 0; }
+ virtual void writeGotPltHeader(uint8_t *buf) const {}
+ virtual void writeGotHeader(uint8_t *buf) const {}
+ virtual void writeGotPlt(uint8_t *buf, const Symbol &s) const {};
+ virtual void writeIgotPlt(uint8_t *buf, const Symbol &s) const;
+ virtual int64_t getImplicitAddend(const uint8_t *buf, RelType type) const;
+ virtual int getTlsGdRelaxSkip(RelType type) const { return 1; }
// If lazy binding is supported, the first entry of the PLT has code
// to call the dynamic linker to resolve PLT entries the first time
// they are called. This function writes that code.
- virtual void writePltHeader(uint8_t *Buf) const {}
+ virtual void writePltHeader(uint8_t *buf) const {}
- virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {}
- virtual void addPltHeaderSymbols(InputSection &IS) const {}
- virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}
+ virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {}
+ virtual void addPltHeaderSymbols(InputSection &isec) const {}
+ virtual void addPltSymbols(InputSection &isec, uint64_t off) const {}
// Returns true if a relocation only uses the low bits of a value such that
// all those bits are in the same page. For example, if the relocation
// only uses the low 12 bits in a system with 4k pages. If this is true, the
// bits will always have the same value at runtime and we don't have to emit
// a dynamic relocation.
- virtual bool usesOnlyLowPageBits(RelType Type) const;
+ virtual bool usesOnlyLowPageBits(RelType type) const;
// Decide whether a Thunk is needed for the relocation from File
// targeting S.
- virtual bool needsThunk(RelExpr Expr, RelType RelocType,
- const InputFile *File, uint64_t BranchAddr,
- const Symbol &S) const;
+ virtual bool needsThunk(RelExpr expr, RelType relocType,
+ const InputFile *file, uint64_t branchAddr,
+ const Symbol &s) const;
// On systems with range extensions we place collections of Thunks at
// regular spacings that enable the majority of branches reach the Thunks.
@@ -70,71 +70,71 @@ public:
// to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
// The symbols st_other flags are needed on PowerPC64 for determining the
// offset to the split-stack prologue.
- virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const;
+ virtual bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const;
// Return true if we can reach Dst from Src with Relocation RelocType
- virtual bool inBranchRange(RelType Type, uint64_t Src,
- uint64_t Dst) const;
+ virtual bool inBranchRange(RelType type, uint64_t src,
+ uint64_t dst) const;
- virtual void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const = 0;
+ virtual void relocateOne(uint8_t *loc, RelType type, uint64_t val) const = 0;
virtual ~TargetInfo();
- unsigned DefaultCommonPageSize = 4096;
- unsigned DefaultMaxPageSize = 4096;
+ unsigned defaultCommonPageSize = 4096;
+ unsigned defaultMaxPageSize = 4096;
uint64_t getImageBase() const;
// True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
- bool GotBaseSymInGotPlt = true;
-
- RelType CopyRel;
- RelType GotRel;
- RelType NoneRel;
- RelType PltRel;
- RelType RelativeRel;
- RelType IRelativeRel;
- RelType SymbolicRel;
- RelType TlsDescRel;
- RelType TlsGotRel;
- RelType TlsModuleIndexRel;
- RelType TlsOffsetRel;
- unsigned PltEntrySize;
- unsigned PltHeaderSize;
+ bool gotBaseSymInGotPlt = true;
+
+ RelType copyRel;
+ RelType gotRel;
+ RelType noneRel;
+ RelType pltRel;
+ RelType relativeRel;
+ RelType iRelativeRel;
+ RelType symbolicRel;
+ RelType tlsDescRel;
+ RelType tlsGotRel;
+ RelType tlsModuleIndexRel;
+ RelType tlsOffsetRel;
+ unsigned pltEntrySize;
+ unsigned pltHeaderSize;
// At least on x86_64 positions 1 and 2 are used by the first plt entry
// to support lazy loading.
- unsigned GotPltHeaderEntriesNum = 3;
+ unsigned gotPltHeaderEntriesNum = 3;
// On PPC ELF V2 abi, the first entry in the .got is the .TOC.
- unsigned GotHeaderEntriesNum = 0;
+ unsigned gotHeaderEntriesNum = 0;
- bool NeedsThunks = false;
+ bool needsThunks = false;
// A 4-byte field corresponding to one or more trap instructions, used to pad
// executable OutputSections.
- std::array<uint8_t, 4> TrapInstr;
+ std::array<uint8_t, 4> trapInstr;
// If a target needs to rewrite calls to __morestack to instead call
// __morestack_non_split when a split-stack enabled caller calls a
// non-split-stack callee this will return true. Otherwise returns false.
- bool NeedsMoreStackNonSplit = true;
+ bool needsMoreStackNonSplit = true;
- virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const;
- virtual void relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
+ virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const;
+ virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const;
protected:
// On FreeBSD x86_64 the first page cannot be mmaped.
// On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
// installs that is 65536, so the first 15 pages cannot be used.
// Given that, the smallest value that can be used in here is 0x10000.
- uint64_t DefaultImageBase = 0x10000;
+ uint64_t defaultImageBase = 0x10000;
};
TargetInfo *getAArch64TargetInfo();
@@ -152,22 +152,22 @@ TargetInfo *getX86_64TargetInfo();
template <class ELFT> TargetInfo *getMipsTargetInfo();
struct ErrorPlace {
- InputSectionBase *IS;
- std::string Loc;
+ InputSectionBase *isec;
+ std::string loc;
};
// Returns input section and corresponding source string for the given location.
-ErrorPlace getErrorPlace(const uint8_t *Loc);
+ErrorPlace getErrorPlace(const uint8_t *loc);
-static inline std::string getErrorLocation(const uint8_t *Loc) {
- return getErrorPlace(Loc).Loc;
+static inline std::string getErrorLocation(const uint8_t *loc) {
+ return getErrorPlace(loc).loc;
}
-void writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries);
+void writePPC32GlinkSection(uint8_t *buf, size_t numEntries);
-bool tryRelaxPPC64TocIndirection(RelType Type, const Relocation &Rel,
- uint8_t *BufLoc);
-unsigned getPPCDFormOp(unsigned SecondaryOp);
+bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
+ uint8_t *bufLoc);
+unsigned getPPCDFormOp(unsigned secondaryOp);
// In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first
// is a global entry point (GEP) which typically is used to initialize the TOC
@@ -176,84 +176,84 @@ unsigned getPPCDFormOp(unsigned SecondaryOp);
// offset between GEP and LEP is encoded in a function's st_other flags.
// This function will return the offset (in bytes) from the global entry-point
// to the local entry-point.
-unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
+unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther);
// Returns true if a relocation is a small code model relocation that accesses
// the .toc section.
-bool isPPC64SmallCodeModelTocReloc(RelType Type);
+bool isPPC64SmallCodeModelTocReloc(RelType type);
uint64_t getPPC64TocBase();
-uint64_t getAArch64Page(uint64_t Expr);
+uint64_t getAArch64Page(uint64_t expr);
-extern const TargetInfo *Target;
+extern const TargetInfo *target;
TargetInfo *getTarget();
-template <class ELFT> bool isMipsPIC(const Defined *Sym);
+template <class ELFT> bool isMipsPIC(const Defined *sym);
-static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,
- int64_t Min, uint64_t Max) {
- ErrorPlace ErrPlace = getErrorPlace(Loc);
- StringRef Hint;
- if (ErrPlace.IS && ErrPlace.IS->Name.startswith(".debug"))
- Hint = "; consider recompiling with -fdebug-types-section to reduce size "
+static inline void reportRangeError(uint8_t *loc, RelType type, const Twine &v,
+ int64_t min, uint64_t max) {
+ ErrorPlace errPlace = getErrorPlace(loc);
+ StringRef hint;
+ if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
+ hint = "; consider recompiling with -fdebug-types-section to reduce size "
"of debug sections";
- errorOrWarn(ErrPlace.Loc + "relocation " + lld::toString(Type) +
- " out of range: " + V.str() + " is not in [" + Twine(Min).str() +
- ", " + Twine(Max).str() + "]" + Hint);
+ errorOrWarn(errPlace.loc + "relocation " + lld::toString(type) +
+ " out of range: " + v.str() + " is not in [" + Twine(min).str() +
+ ", " + Twine(max).str() + "]" + hint);
}
// Make sure that V can be represented as an N bit signed integer.
-inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) {
- if (V != llvm::SignExtend64(V, N))
- reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));
+inline void checkInt(uint8_t *loc, int64_t v, int n, RelType type) {
+ if (v != llvm::SignExtend64(v, n))
+ reportRangeError(loc, type, Twine(v), llvm::minIntN(n), llvm::maxIntN(n));
}
// Make sure that V can be represented as an N bit unsigned integer.
-inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
- if ((V >> N) != 0)
- reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N));
+inline void checkUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
+ if ((v >> n) != 0)
+ reportRangeError(loc, type, Twine(v), 0, llvm::maxUIntN(n));
}
// Make sure that V can be represented as an N bit signed or unsigned integer.
-inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
+inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
// For the error message we should cast V to a signed integer so that error
// messages show a small negative value rather than an extremely large one
- if (V != (uint64_t)llvm::SignExtend64(V, N) && (V >> N) != 0)
- reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
- llvm::maxUIntN(N));
+ if (v != (uint64_t)llvm::SignExtend64(v, n) && (v >> n) != 0)
+ reportRangeError(loc, type, Twine((int64_t)v), llvm::minIntN(n),
+ llvm::maxUIntN(n));
}
-inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) {
- if ((V & (N - 1)) != 0)
- error(getErrorLocation(Loc) + "improper alignment for relocation " +
- lld::toString(Type) + ": 0x" + llvm::utohexstr(V) +
- " is not aligned to " + Twine(N) + " bytes");
+inline void checkAlignment(uint8_t *loc, uint64_t v, int n, RelType type) {
+ if ((v & (n - 1)) != 0)
+ error(getErrorLocation(loc) + "improper alignment for relocation " +
+ lld::toString(type) + ": 0x" + llvm::utohexstr(v) +
+ " is not aligned to " + Twine(n) + " bytes");
}
// Endianness-aware read/write.
-inline uint16_t read16(const void *P) {
- return llvm::support::endian::read16(P, Config->Endianness);
+inline uint16_t read16(const void *p) {
+ return llvm::support::endian::read16(p, config->endianness);
}
-inline uint32_t read32(const void *P) {
- return llvm::support::endian::read32(P, Config->Endianness);
+inline uint32_t read32(const void *p) {
+ return llvm::support::endian::read32(p, config->endianness);
}
-inline uint64_t read64(const void *P) {
- return llvm::support::endian::read64(P, Config->Endianness);
+inline uint64_t read64(const void *p) {
+ return llvm::support::endian::read64(p, config->endianness);
}
-inline void write16(void *P, uint16_t V) {
- llvm::support::endian::write16(P, V, Config->Endianness);
+inline void write16(void *p, uint16_t v) {
+ llvm::support::endian::write16(p, v, config->endianness);
}
-inline void write32(void *P, uint32_t V) {
- llvm::support::endian::write32(P, V, Config->Endianness);
+inline void write32(void *p, uint32_t v) {
+ llvm::support::endian::write32(p, v, config->endianness);
}
-inline void write64(void *P, uint64_t V) {
- llvm::support::endian::write64(P, V, Config->Endianness);
+inline void write64(void *p, uint64_t v) {
+ llvm::support::endian::write64(p, v, config->endianness);
}
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 368c732b70c..2428fb80992 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -49,18 +49,18 @@ namespace {
// AArch64 long range Thunks
class AArch64ABSLongThunk final : public Thunk {
public:
- AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {}
+ AArch64ABSLongThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class AArch64ADRPThunk final : public Thunk {
public:
- AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {}
+ AArch64ADRPThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 12; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// Base class for ARM thunks.
@@ -73,19 +73,19 @@ public:
// if the target is in range, otherwise it creates a long thunk.
class ARMThunk : public Thunk {
public:
- ARMThunk(Symbol &Dest) : Thunk(Dest) {}
+ ARMThunk(Symbol &dest) : Thunk(dest) {}
bool getMayUseShortThunk();
uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
- void writeTo(uint8_t *Buf) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
// Returns the size of a long thunk.
virtual uint32_t sizeLong() = 0;
// Writes a long thunk to Buf.
- virtual void writeLong(uint8_t *Buf) = 0;
+ virtual void writeLong(uint8_t *buf) = 0;
private:
// This field tracks whether all previously considered layouts would allow
@@ -94,7 +94,7 @@ private:
// distance to the target. We do this because transitioning from long to short
// can create layout oscillations in certain corner cases which would prevent
// the layout from converging.
- bool MayUseShortThunk = true;
+ bool mayUseShortThunk = true;
};
// Base class for Thumb-2 thunks.
@@ -103,61 +103,61 @@ private:
// which has a range of 16MB.
class ThumbThunk : public Thunk {
public:
- ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
+ ThumbThunk(Symbol &dest) : Thunk(dest) { alignment = 2; }
bool getMayUseShortThunk();
uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
- void writeTo(uint8_t *Buf) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
// Returns the size of a long thunk.
virtual uint32_t sizeLong() = 0;
// Writes a long thunk to Buf.
- virtual void writeLong(uint8_t *Buf) = 0;
+ virtual void writeLong(uint8_t *buf) = 0;
private:
// See comment in ARMThunk above.
- bool MayUseShortThunk = true;
+ bool mayUseShortThunk = true;
};
// Specific ARM Thunk implementations. The naming convention is:
// Source State, TargetState, Target Requirement, ABS or PI, Range
class ARMV7ABSLongThunk final : public ARMThunk {
public:
- ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV7ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ARMV7PILongThunk final : public ARMThunk {
public:
- ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV7PILongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV7ABSLongThunk final : public ThumbThunk {
public:
- ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV7ABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 10; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV7PILongThunk final : public ThumbThunk {
public:
- ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV7PILongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// Implementations of Thunks for older Arm architectures that do not support
@@ -167,95 +167,95 @@ public:
// can result in a thunk
class ARMV5ABSLongThunk final : public ARMThunk {
public:
- ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV5ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 8; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
};
class ARMV5PILongThunk final : public ARMThunk {
public:
- ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV5PILongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
};
// Implementations of Thunks for Arm v6-M. Only Thumb instructions are permitted
class ThumbV6MABSLongThunk final : public ThumbThunk {
public:
- ThumbV6MABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV6MABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV6MPILongThunk final : public ThumbThunk {
public:
- ThumbV6MPILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV6MPILongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// MIPS LA25 thunk
class MipsThunk final : public Thunk {
public:
- MipsThunk(Symbol &Dest) : Thunk(Dest) {}
+ MipsThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
// microMIPS R2-R5 LA25 thunk
class MicroMipsThunk final : public Thunk {
public:
- MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {}
+ MicroMipsThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 14; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
// microMIPS R6 LA25 thunk
class MicroMipsR6Thunk final : public Thunk {
public:
- MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {}
+ MicroMipsR6Thunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 12; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
class PPC32PltCallStub final : public Thunk {
public:
- PPC32PltCallStub(const InputSection &IS, const Relocation &Rel, Symbol &Dest)
- : Thunk(Dest), Addend(Rel.Type == R_PPC_PLTREL24 ? Rel.Addend : 0),
- File(IS.File) {}
+ PPC32PltCallStub(const InputSection &isec, const Relocation &rel, Symbol &dest)
+ : Thunk(dest), addend(rel.type == R_PPC_PLTREL24 ? rel.addend : 0),
+ file(isec.file) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS, const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec, const Relocation &rel) const override;
private:
// For R_PPC_PLTREL24, this records the addend, which will be used to decide
// the offsets in the call stub.
- uint32_t Addend;
+ uint32_t addend;
// Records the call site of the call stub.
- const InputFile *File;
+ const InputFile *file;
};
// PPC64 Plt call stubs.
@@ -268,10 +268,10 @@ private:
// 3) Transfering control to the target function through an indirect branch.
class PPC64PltCallStub final : public Thunk {
public:
- PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {}
+ PPC64PltCallStub(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 20; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte
@@ -285,75 +285,75 @@ public:
class PPC64LongBranchThunk : public Thunk {
public:
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
protected:
- PPC64LongBranchThunk(Symbol &Dest) : Thunk(Dest) {}
+ PPC64LongBranchThunk(Symbol &dest) : Thunk(dest) {}
};
class PPC64PILongBranchThunk final : public PPC64LongBranchThunk {
public:
- PPC64PILongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
- assert(!Dest.IsPreemptible);
- if (Dest.isInPPC64Branchlt())
+ PPC64PILongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
+ assert(!dest.isPreemptible);
+ if (dest.isInPPC64Branchlt())
return;
- In.PPC64LongBranchTarget->addEntry(Dest);
- Main->RelaDyn->addReloc(
- {Target->RelativeRel, In.PPC64LongBranchTarget,
- Dest.getPPC64LongBranchOffset(), true, &Dest,
- getPPC64GlobalEntryToLocalEntryOffset(Dest.StOther)});
+ in.ppc64LongBranchTarget->addEntry(dest);
+ mainPart->relaDyn->addReloc(
+ {target->relativeRel, in.ppc64LongBranchTarget,
+ dest.getPPC64LongBranchOffset(), true, &dest,
+ getPPC64GlobalEntryToLocalEntryOffset(dest.stOther)});
}
};
class PPC64PDLongBranchThunk final : public PPC64LongBranchThunk {
public:
- PPC64PDLongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
- if (!Dest.isInPPC64Branchlt())
- In.PPC64LongBranchTarget->addEntry(Dest);
+ PPC64PDLongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
+ if (!dest.isInPPC64Branchlt())
+ in.ppc64LongBranchTarget->addEntry(dest);
}
};
} // end anonymous namespace
-Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
- InputSectionBase &Section) {
- Defined *D = addSyntheticLocal(Name, Type, Value, /*Size=*/0, Section);
- Syms.push_back(D);
- return D;
+Defined *Thunk::addSymbol(StringRef name, uint8_t type, uint64_t value,
+ InputSectionBase &section) {
+ Defined *d = addSyntheticLocal(name, type, value, /*Size=*/0, section);
+ syms.push_back(d);
+ return d;
}
-void Thunk::setOffset(uint64_t NewOffset) {
- for (Defined *D : Syms)
- D->Value = D->Value - Offset + NewOffset;
- Offset = NewOffset;
+void Thunk::setOffset(uint64_t newOffset) {
+ for (Defined *d : syms)
+ d->value = d->value - offset + newOffset;
+ offset = newOffset;
}
// AArch64 long range Thunks
-static uint64_t getAArch64ThunkDestVA(const Symbol &S) {
- uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
- return V;
+static uint64_t getAArch64ThunkDestVA(const Symbol &s) {
+ uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
+ return v;
}
-void AArch64ABSLongThunk::writeTo(uint8_t *Buf) {
- const uint8_t Data[] = {
+void AArch64ABSLongThunk::writeTo(uint8_t *buf) {
+ const uint8_t data[] = {
0x50, 0x00, 0x00, 0x58, // ldr x16, L0
0x00, 0x02, 0x1f, 0xd6, // br x16
0x00, 0x00, 0x00, 0x00, // L0: .xword S
0x00, 0x00, 0x00, 0x00,
};
- uint64_t S = getAArch64ThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 8, R_AARCH64_ABS64, S);
+ uint64_t s = getAArch64ThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 8, R_AARCH64_ABS64, s);
}
-void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__AArch64AbsLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$x", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 8, IS);
+void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__AArch64AbsLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$x", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 8, isec);
}
// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
@@ -361,263 +361,263 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
// clang and gcc do not support the large code model for position independent
// code so it is safe to use this for position independent thunks without
// worrying about the destination being more than 4Gb away.
-void AArch64ADRPThunk::writeTo(uint8_t *Buf) {
- const uint8_t Data[] = {
+void AArch64ADRPThunk::writeTo(uint8_t *buf) {
+ const uint8_t data[] = {
0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest)
0x10, 0x02, 0x00, 0x91, // add x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest)
0x00, 0x02, 0x1f, 0xd6, // br x16
};
- uint64_t S = getAArch64ThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(S) - getAArch64Page(P));
- Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S);
+ uint64_t s = getAArch64ThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(s) - getAArch64Page(p));
+ target->relocateOne(buf + 4, R_AARCH64_ADD_ABS_LO12_NC, s);
}
-void AArch64ADRPThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$x", STT_NOTYPE, 0, IS);
+void AArch64ADRPThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__AArch64ADRPThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$x", STT_NOTYPE, 0, isec);
}
// ARM Target Thunks
-static uint64_t getARMThunkDestVA(const Symbol &S) {
- uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
- return SignExtend64<32>(V);
+static uint64_t getARMThunkDestVA(const Symbol &s) {
+ uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
+ return SignExtend64<32>(v);
}
// This function returns true if the target is not Thumb and is within 2^26, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ARMThunk::getMayUseShortThunk() {
- if (!MayUseShortThunk)
+ if (!mayUseShortThunk)
return false;
- uint64_t S = getARMThunkDestVA(Destination);
- if (S & 1) {
- MayUseShortThunk = false;
+ uint64_t s = getARMThunkDestVA(destination);
+ if (s & 1) {
+ mayUseShortThunk = false;
return false;
}
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 8;
- MayUseShortThunk = llvm::isInt<26>(Offset);
- return MayUseShortThunk;
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 8;
+ mayUseShortThunk = llvm::isInt<26>(offset);
+ return mayUseShortThunk;
}
-void ARMThunk::writeTo(uint8_t *Buf) {
+void ARMThunk::writeTo(uint8_t *buf) {
if (!getMayUseShortThunk()) {
- writeLong(Buf);
+ writeLong(buf);
return;
}
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 8;
- const uint8_t Data[] = {
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 8;
+ const uint8_t data[] = {
0x00, 0x00, 0x00, 0xea, // b S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_JUMP24, Offset);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_JUMP24, offset);
}
-bool ARMThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
// This function returns true if the target is Thumb and is within 2^25, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ThumbThunk::getMayUseShortThunk() {
- if (!MayUseShortThunk)
+ if (!mayUseShortThunk)
return false;
- uint64_t S = getARMThunkDestVA(Destination);
- if ((S & 1) == 0) {
- MayUseShortThunk = false;
+ uint64_t s = getARMThunkDestVA(destination);
+ if ((s & 1) == 0) {
+ mayUseShortThunk = false;
return false;
}
- uint64_t P = getThunkTargetSym()->getVA() & ~1;
- int64_t Offset = S - P - 4;
- MayUseShortThunk = llvm::isInt<25>(Offset);
- return MayUseShortThunk;
+ uint64_t p = getThunkTargetSym()->getVA() & ~1;
+ int64_t offset = s - p - 4;
+ mayUseShortThunk = llvm::isInt<25>(offset);
+ return mayUseShortThunk;
}
-void ThumbThunk::writeTo(uint8_t *Buf) {
+void ThumbThunk::writeTo(uint8_t *buf) {
if (!getMayUseShortThunk()) {
- writeLong(Buf);
+ writeLong(buf);
return;
}
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 4;
- const uint8_t Data[] = {
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 4;
+ const uint8_t data[] = {
0x00, 0xf0, 0x00, 0xb0, // b.w S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_JUMP24, offset);
}
-bool ThumbThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ThumbThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// ARM branch relocations can't use BLX
- return Rel.Type != R_ARM_JUMP24 && Rel.Type != R_ARM_PC24 && Rel.Type != R_ARM_PLT32;
+ return rel.type != R_ARM_JUMP24 && rel.type != R_ARM_PC24 && rel.type != R_ARM_PLT32;
}
-void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV7ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
0x1c, 0xff, 0x2f, 0xe1, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_MOVW_ABS_NC, S);
- Target->relocateOne(Buf + 4, R_ARM_MOVT_ABS, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_MOVW_ABS_NC, s);
+ target->relocateOne(buf + 4, R_ARM_MOVT_ABS, s);
}
-void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
+void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMv7ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
}
-void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
0x60, 0x47, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_MOVW_ABS_NC, S);
- Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_ABS, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_MOVW_ABS_NC, s);
+ target->relocateOne(buf + 4, R_ARM_THM_MOVT_ABS, s);
}
-void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
+void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
}
-void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV7PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)
0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
0x1c, 0xff, 0x2f, 0xe1, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 16;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
- Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 16;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_MOVW_PREL_NC, offset);
+ target->relocateOne(buf + 4, R_ARM_MOVT_PREL, offset);
}
-void ARMV7PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
+void ARMV7PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMV7PILongThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
}
-void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ThumbV7PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
0xfc, 0x44, // L1: add ip, pc
0x60, 0x47, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- int64_t Offset = S - P - 12;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
- Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ int64_t offset = s - p - 12;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_MOVW_PREL_NC, offset);
+ target->relocateOne(buf + 4, R_ARM_THM_MOVT_PREL, offset);
}
-void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ThumbV7PILongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
+void ThumbV7PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ThumbV7PILongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
}
-void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV5ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc,#-4] ; L1
0x00, 0x00, 0x00, 0x00, // L1: .word S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 4, R_ARM_ABS32, getARMThunkDestVA(destination));
}
-void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 4, IS);
+void ARMV5ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMv5ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 4, isec);
}
-bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
-void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV5PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x04, 0xc0, 0x9f, 0xe5, // P: ldr ip, [pc,#4] ; L2
0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
0x1c, 0xff, 0x2f, 0xe1, // bx ip
0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
}
-void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 12, IS);
+void ARMV5PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMV5PILongThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 12, isec);
}
-bool ARMV5PILongThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMV5PILongThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
-void ThumbV6MABSLongThunk::writeLong(uint8_t *Buf) {
+void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
// Most Thumb instructions cannot access the high registers r8 - r15. As the
// only register we can corrupt is r12 we must instead spill a low register
// to the stack to use as a scratch register. We push r1 even though we
// don't need to get some space to use for the return address.
- const uint8_t Data[] = {
+ const uint8_t data[] = {
0x03, 0xb4, // push {r0, r1} ; Obtain scratch registers
0x01, 0x48, // ldr r0, [pc, #4] ; L1
0x01, 0x90, // str r0, [sp, #4] ; SP + 4 = S
0x01, 0xbd, // pop {r0, pc} ; restore r0 and branch to dest
0x00, 0x00, 0x00, 0x00 // L1: .word S
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 8, R_ARM_ABS32, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 8, R_ARM_ABS32, s);
}
-void ThumbV6MABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 8, IS);
+void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 8, isec);
}
-void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
+void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
// Most Thumb instructions cannot access the high registers r8 - r15. As the
// only register we can corrupt is ip (r12) we must instead spill a low
// register to the stack to use as a scratch register.
- const uint8_t Data[] = {
+ const uint8_t data[] = {
0x01, 0xb4, // P: push {r0} ; Obtain scratch register
0x02, 0x48, // ldr r0, [pc, #8] ; L2
0x84, 0x46, // mov ip, r0 ; high to low register
@@ -626,185 +626,185 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
0xc0, 0x46, // nop ; pad to 4-byte boundary
0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
}
-void ThumbV6MPILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv6MPILongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 12, IS);
+void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv6MPILongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 12, isec);
}
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
-void MipsThunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- write32(Buf, 0x3c190000); // lui $25, %hi(func)
- write32(Buf + 4, 0x08000000 | (S >> 2)); // j func
- write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
- write32(Buf + 12, 0x00000000); // nop
- Target->relocateOne(Buf, R_MIPS_HI16, S);
- Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
+void MipsThunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ write32(buf, 0x3c190000); // lui $25, %hi(func)
+ write32(buf + 4, 0x08000000 | (s >> 2)); // j func
+ write32(buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
+ write32(buf + 12, 0x00000000); // nop
+ target->relocateOne(buf, R_MIPS_HI16, s);
+ target->relocateOne(buf + 8, R_MIPS_LO16, s);
}
-void MipsThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__LA25Thunk_" + Destination.getName()), STT_FUNC, 0,
- IS);
+void MipsThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__LA25Thunk_" + destination.getName()), STT_FUNC, 0,
+ isec);
}
InputSection *MipsThunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
// Write microMIPS R2-R5 LA25 thunk code
// to call PIC function from the non-PIC one.
-void MicroMipsThunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- write16(Buf, 0x41b9); // lui $25, %hi(func)
- write16(Buf + 4, 0xd400); // j func
- write16(Buf + 8, 0x3339); // addiu $25, $25, %lo(func)
- write16(Buf + 12, 0x0c00); // nop
- Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
- Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S);
- Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S);
+void MicroMipsThunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ write16(buf, 0x41b9); // lui $25, %hi(func)
+ write16(buf + 4, 0xd400); // j func
+ write16(buf + 8, 0x3339); // addiu $25, $25, %lo(func)
+ write16(buf + 12, 0x0c00); // nop
+ target->relocateOne(buf, R_MICROMIPS_HI16, s);
+ target->relocateOne(buf + 4, R_MICROMIPS_26_S1, s);
+ target->relocateOne(buf + 8, R_MICROMIPS_LO16, s);
}
-void MicroMipsThunk::addSymbols(ThunkSection &IS) {
- Defined *D = addSymbol(
- Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
- D->StOther |= STO_MIPS_MICROMIPS;
+void MicroMipsThunk::addSymbols(ThunkSection &isec) {
+ Defined *d = addSymbol(
+ Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
+ d->stOther |= STO_MIPS_MICROMIPS;
}
InputSection *MicroMipsThunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
// Write microMIPS R6 LA25 thunk code
// to call PIC function from the non-PIC one.
-void MicroMipsR6Thunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- uint64_t P = getThunkTargetSym()->getVA();
- write16(Buf, 0x1320); // lui $25, %hi(func)
- write16(Buf + 4, 0x3339); // addiu $25, $25, %lo(func)
- write16(Buf + 8, 0x9400); // bc func
- Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
- Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S);
- Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12);
+void MicroMipsR6Thunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ uint64_t p = getThunkTargetSym()->getVA();
+ write16(buf, 0x1320); // lui $25, %hi(func)
+ write16(buf + 4, 0x3339); // addiu $25, $25, %lo(func)
+ write16(buf + 8, 0x9400); // bc func
+ target->relocateOne(buf, R_MICROMIPS_HI16, s);
+ target->relocateOne(buf + 4, R_MICROMIPS_LO16, s);
+ target->relocateOne(buf + 8, R_MICROMIPS_PC26_S1, s - p - 12);
}
-void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) {
- Defined *D = addSymbol(
- Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
- D->StOther |= STO_MIPS_MICROMIPS;
+void MicroMipsR6Thunk::addSymbols(ThunkSection &isec) {
+ Defined *d = addSymbol(
+ Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
+ d->stOther |= STO_MIPS_MICROMIPS;
}
InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
-void PPC32PltCallStub::writeTo(uint8_t *Buf) {
- if (!Config->Pic) {
- uint64_t VA = Destination.getGotPltVA();
- write32(Buf + 0, 0x3d600000 | (VA + 0x8000) >> 16); // lis r11,ha
- write32(Buf + 4, 0x816b0000 | (uint16_t)VA); // lwz r11,l(r11)
- write32(Buf + 8, 0x7d6903a6); // mtctr r11
- write32(Buf + 12, 0x4e800420); // bctr
+void PPC32PltCallStub::writeTo(uint8_t *buf) {
+ if (!config->isPic) {
+ uint64_t va = destination.getGotPltVA();
+ write32(buf + 0, 0x3d600000 | (va + 0x8000) >> 16); // lis r11,ha
+ write32(buf + 4, 0x816b0000 | (uint16_t)va); // lwz r11,l(r11)
+ write32(buf + 8, 0x7d6903a6); // mtctr r11
+ write32(buf + 12, 0x4e800420); // bctr
return;
}
- uint32_t Offset;
- if (Addend >= 0x8000) {
+ uint32_t offset;
+ if (addend >= 0x8000) {
// The stub loads an address relative to r30 (.got2+Addend). Addend is
// almost always 0x8000. The address of .got2 is different in another object
// file, so a stub cannot be shared.
- Offset = Destination.getGotPltVA() - (In.PPC32Got2->getParent()->getVA() +
- File->PPC32Got2OutSecOff + Addend);
+ offset = destination.getGotPltVA() - (in.ppc32Got2->getParent()->getVA() +
+ file->ppc32Got2OutSecOff + addend);
} else {
// The stub loads an address relative to _GLOBAL_OFFSET_TABLE_ (which is
// currently the address of .got).
- Offset = Destination.getGotPltVA() - In.Got->getVA();
+ offset = destination.getGotPltVA() - in.got->getVA();
}
- uint16_t HA = (Offset + 0x8000) >> 16, L = (uint16_t)Offset;
- if (HA == 0) {
- write32(Buf + 0, 0x817e0000 | L); // lwz r11,l(r30)
- write32(Buf + 4, 0x7d6903a6); // mtctr r11
- write32(Buf + 8, 0x4e800420); // bctr
- write32(Buf + 12, 0x60000000); // nop
+ uint16_t ha = (offset + 0x8000) >> 16, l = (uint16_t)offset;
+ if (ha == 0) {
+ write32(buf + 0, 0x817e0000 | l); // lwz r11,l(r30)
+ write32(buf + 4, 0x7d6903a6); // mtctr r11
+ write32(buf + 8, 0x4e800420); // bctr
+ write32(buf + 12, 0x60000000); // nop
} else {
- write32(Buf + 0, 0x3d7e0000 | HA); // addis r11,r30,ha
- write32(Buf + 4, 0x816b0000 | L); // lwz r11,l(r11)
- write32(Buf + 8, 0x7d6903a6); // mtctr r11
- write32(Buf + 12, 0x4e800420); // bctr
+ write32(buf + 0, 0x3d7e0000 | ha); // addis r11,r30,ha
+ write32(buf + 4, 0x816b0000 | l); // lwz r11,l(r11)
+ write32(buf + 8, 0x7d6903a6); // mtctr r11
+ write32(buf + 12, 0x4e800420); // bctr
}
}
-void PPC32PltCallStub::addSymbols(ThunkSection &IS) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- OS << format_hex_no_prefix(Addend, 8);
- if (!Config->Pic)
- OS << ".plt_call32.";
- else if (Addend >= 0x8000)
- OS << ".got2.plt_pic32.";
+void PPC32PltCallStub::addSymbols(ThunkSection &isec) {
+ std::string buf;
+ raw_string_ostream os(buf);
+ os << format_hex_no_prefix(addend, 8);
+ if (!config->isPic)
+ os << ".plt_call32.";
+ else if (addend >= 0x8000)
+ os << ".got2.plt_pic32.";
else
- OS << ".plt_pic32.";
- OS << Destination.getName();
- addSymbol(Saver.save(OS.str()), STT_FUNC, 0, IS);
+ os << ".plt_pic32.";
+ os << destination.getName();
+ addSymbol(Saver.save(os.str()), STT_FUNC, 0, isec);
}
-bool PPC32PltCallStub::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
- return !Config->Pic || (IS.File == File && Rel.Addend == Addend);
+bool PPC32PltCallStub::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
+ return !config->isPic || (isec.file == file && rel.addend == addend);
}
-static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
- uint16_t OffHa = (Offset + 0x8000) >> 16;
- uint16_t OffLo = Offset & 0xffff;
+static void writePPCLoadAndBranch(uint8_t *buf, int64_t offset) {
+ uint16_t offHa = (offset + 0x8000) >> 16;
+ uint16_t offLo = offset & 0xffff;
- write32(Buf + 0, 0x3d820000 | OffHa); // addis r12, r2, OffHa
- write32(Buf + 4, 0xe98c0000 | OffLo); // ld r12, OffLo(r12)
- write32(Buf + 8, 0x7d8903a6); // mtctr r12
- write32(Buf + 12, 0x4e800420); // bctr
+ write32(buf + 0, 0x3d820000 | offHa); // addis r12, r2, OffHa
+ write32(buf + 4, 0xe98c0000 | offLo); // ld r12, OffLo(r12)
+ write32(buf + 8, 0x7d8903a6); // mtctr r12
+ write32(buf + 12, 0x4e800420); // bctr
}
-void PPC64PltCallStub::writeTo(uint8_t *Buf) {
- int64_t Offset = Destination.getGotPltVA() - getPPC64TocBase();
+void PPC64PltCallStub::writeTo(uint8_t *buf) {
+ int64_t offset = destination.getGotPltVA() - getPPC64TocBase();
// Save the TOC pointer to the save-slot reserved in the call frame.
- write32(Buf + 0, 0xf8410018); // std r2,24(r1)
- writePPCLoadAndBranch(Buf + 4, Offset);
+ write32(buf + 0, 0xf8410018); // std r2,24(r1)
+ writePPCLoadAndBranch(buf + 4, offset);
}
-void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
- Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC,
- 0, IS);
- S->NeedsTocRestore = true;
+void PPC64PltCallStub::addSymbols(ThunkSection &isec) {
+ Defined *s = addSymbol(Saver.save("__plt_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ s->needsTocRestore = true;
}
-void PPC64LongBranchThunk::writeTo(uint8_t *Buf) {
- int64_t Offset = Destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
- writePPCLoadAndBranch(Buf, Offset);
+void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
+ int64_t offset = destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
+ writePPCLoadAndBranch(buf, offset);
}
-void PPC64LongBranchThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__long_branch_" + Destination.getName()), STT_FUNC, 0,
- IS);
+void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__long_branch_" + destination.getName()), STT_FUNC, 0,
+ isec);
}
-Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
+Thunk::Thunk(Symbol &d) : destination(d), offset(0) {}
Thunk::~Thunk() = default;
-static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
- if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
+static Thunk *addThunkAArch64(RelType type, Symbol &s) {
+ if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
fatal("unrecognized relocation type");
- if (Config->PicThunk)
- return make<AArch64ADRPThunk>(S);
- return make<AArch64ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<AArch64ADRPThunk>(s);
+ return make<AArch64ABSLongThunk>(s);
}
// Creates a thunk for Thumb-ARM interworking.
@@ -812,18 +812,18 @@ static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
// - MOVT and MOVW instructions cannot be used
// - Only Thumb relocation that can generate a Thunk is a BL, this can always
// be transformed into a BLX
-static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
- switch (Reloc) {
+static Thunk *addThunkPreArmv7(RelType reloc, Symbol &s) {
+ switch (reloc) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
case R_ARM_THM_CALL:
- if (Config->PicThunk)
- return make<ARMV5PILongThunk>(S);
- return make<ARMV5ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ARMV5PILongThunk>(s);
+ return make<ARMV5ABSLongThunk>(s);
}
- fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+ fatal("relocation " + toString(reloc) + " to " + toString(s) +
" not supported for Armv5 or Armv6 targets");
}
@@ -832,21 +832,21 @@ static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
// - MOVT and MOVW instructions cannot be used.
// - Only a limited number of instructions can access registers r8 and above
// - No interworking support is needed (all Thumb).
-static Thunk *addThunkV6M(RelType Reloc, Symbol &S) {
- switch (Reloc) {
+static Thunk *addThunkV6M(RelType reloc, Symbol &s) {
+ switch (reloc) {
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (Config->Pic)
- return make<ThumbV6MPILongThunk>(S);
- return make<ThumbV6MABSLongThunk>(S);
+ if (config->isPic)
+ return make<ThumbV6MPILongThunk>(s);
+ return make<ThumbV6MABSLongThunk>(s);
}
- fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+ fatal("relocation " + toString(reloc) + " to " + toString(s) +
" not supported for Armv6-M targets");
}
// Creates a thunk for Thumb-ARM interworking or branch range extension.
-static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
+static Thunk *addThunkArm(RelType reloc, Symbol &s) {
// Decide which Thunk is needed based on:
// Available instruction set
// - An Arm Thunk can only be used if Arm state is available.
@@ -863,72 +863,72 @@ static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
// can use in Thunks. The flags below are set by reading the BuildAttributes
// of the input objects. InputFiles.cpp contains the mapping from ARM
// architecture to flag.
- if (!Config->ARMHasMovtMovw) {
- if (!Config->ARMJ1J2BranchEncoding)
- return addThunkPreArmv7(Reloc, S);
- return addThunkV6M(Reloc, S);
+ if (!config->armHasMovtMovw) {
+ if (!config->armJ1J2BranchEncoding)
+ return addThunkPreArmv7(reloc, s);
+ return addThunkV6M(reloc, s);
}
- switch (Reloc) {
+ switch (reloc) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- if (Config->PicThunk)
- return make<ARMV7PILongThunk>(S);
- return make<ARMV7ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ARMV7PILongThunk>(s);
+ return make<ARMV7ABSLongThunk>(s);
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (Config->PicThunk)
- return make<ThumbV7PILongThunk>(S);
- return make<ThumbV7ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ThumbV7PILongThunk>(s);
+ return make<ThumbV7ABSLongThunk>(s);
}
fatal("unrecognized relocation type");
}
-static Thunk *addThunkMips(RelType Type, Symbol &S) {
- if ((S.StOther & STO_MIPS_MICROMIPS) && isMipsR6())
- return make<MicroMipsR6Thunk>(S);
- if (S.StOther & STO_MIPS_MICROMIPS)
- return make<MicroMipsThunk>(S);
- return make<MipsThunk>(S);
+static Thunk *addThunkMips(RelType type, Symbol &s) {
+ if ((s.stOther & STO_MIPS_MICROMIPS) && isMipsR6())
+ return make<MicroMipsR6Thunk>(s);
+ if (s.stOther & STO_MIPS_MICROMIPS)
+ return make<MicroMipsThunk>(s);
+ return make<MipsThunk>(s);
}
-static Thunk *addThunkPPC32(const InputSection &IS, const Relocation &Rel, Symbol &S) {
- assert((Rel.Type == R_PPC_REL24 || Rel.Type == R_PPC_PLTREL24) &&
+static Thunk *addThunkPPC32(const InputSection &isec, const Relocation &rel, Symbol &s) {
+ assert((rel.type == R_PPC_REL24 || rel.type == R_PPC_PLTREL24) &&
"unexpected relocation type for thunk");
- return make<PPC32PltCallStub>(IS, Rel, S);
+ return make<PPC32PltCallStub>(isec, rel, s);
}
-static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
- assert(Type == R_PPC64_REL24 && "unexpected relocation type for thunk");
- if (S.isInPlt())
- return make<PPC64PltCallStub>(S);
+static Thunk *addThunkPPC64(RelType type, Symbol &s) {
+ assert(type == R_PPC64_REL24 && "unexpected relocation type for thunk");
+ if (s.isInPlt())
+ return make<PPC64PltCallStub>(s);
- if (Config->PicThunk)
- return make<PPC64PILongBranchThunk>(S);
+ if (config->picThunk)
+ return make<PPC64PILongBranchThunk>(s);
- return make<PPC64PDLongBranchThunk>(S);
+ return make<PPC64PDLongBranchThunk>(s);
}
-Thunk *addThunk(const InputSection &IS, Relocation &Rel) {
- Symbol &S = *Rel.Sym;
+Thunk *addThunk(const InputSection &isec, Relocation &rel) {
+ Symbol &s = *rel.sym;
- if (Config->EMachine == EM_AARCH64)
- return addThunkAArch64(Rel.Type, S);
+ if (config->emachine == EM_AARCH64)
+ return addThunkAArch64(rel.type, s);
- if (Config->EMachine == EM_ARM)
- return addThunkArm(Rel.Type, S);
+ if (config->emachine == EM_ARM)
+ return addThunkArm(rel.type, s);
- if (Config->EMachine == EM_MIPS)
- return addThunkMips(Rel.Type, S);
+ if (config->emachine == EM_MIPS)
+ return addThunkMips(rel.type, s);
- if (Config->EMachine == EM_PPC)
- return addThunkPPC32(IS, Rel, S);
+ if (config->emachine == EM_PPC)
+ return addThunkPPC32(isec, rel, s);
- if (Config->EMachine == EM_PPC64)
- return addThunkPPC64(Rel.Type, S);
+ if (config->emachine == EM_PPC64)
+ return addThunkPPC64(rel.type, s);
llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC");
}
diff --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h
index 1785f775804..2d27ee5f6c3 100644
--- a/lld/ELF/Thunks.h
+++ b/lld/ELF/Thunks.h
@@ -27,20 +27,20 @@ class ThunkSection;
// Thunks are assigned to synthetic ThunkSections
class Thunk {
public:
- Thunk(Symbol &Destination);
+ Thunk(Symbol &destination);
virtual ~Thunk();
virtual uint32_t size() = 0;
- virtual void writeTo(uint8_t *Buf) = 0;
+ virtual void writeTo(uint8_t *buf) = 0;
// All Thunks must define at least one symbol, known as the thunk target
// symbol, so that we can redirect relocations to it. The thunk may define
// additional symbols, but these are never targets for relocations.
- virtual void addSymbols(ThunkSection &IS) = 0;
+ virtual void addSymbols(ThunkSection &isec) = 0;
- void setOffset(uint64_t Offset);
- Defined *addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
- InputSectionBase &Section);
+ void setOffset(uint64_t offset);
+ Defined *addSymbol(StringRef name, uint8_t type, uint64_t value,
+ InputSectionBase &section);
// Some Thunks must be placed immediately before their Target as they elide
// a branch and fall through to the first Symbol in the Target.
@@ -53,19 +53,19 @@ public:
return true;
}
- Defined *getThunkTargetSym() const { return Syms[0]; }
+ Defined *getThunkTargetSym() const { return syms[0]; }
// The alignment requirement for this Thunk, defaults to the size of the
// typical code section alignment.
- Symbol &Destination;
- llvm::SmallVector<Defined *, 3> Syms;
- uint64_t Offset = 0;
- uint32_t Alignment = 4;
+ Symbol &destination;
+ llvm::SmallVector<Defined *, 3> syms;
+ uint64_t offset = 0;
+ uint32_t alignment = 4;
};
// For a Relocation to symbol S create a Thunk to be added to a synthetic
// ThunkSection.
-Thunk *addThunk(const InputSection &IS, Relocation &Rel);
+Thunk *addThunk(const InputSection &isec, Relocation &rel);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 82010302ff7..b0457b6234d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -42,7 +42,7 @@ namespace {
// The writer writes a SymbolTable result to a file.
template <class ELFT> class Writer {
public:
- Writer() : Buffer(errorHandler().OutputBuffer) {}
+ Writer() : buffer(errorHandler().OutputBuffer) {}
using Elf_Shdr = typename ELFT::Shdr;
using Elf_Ehdr = typename ELFT::Ehdr;
using Elf_Phdr = typename ELFT::Phdr;
@@ -52,7 +52,7 @@ public:
private:
void copyLocalSymbols();
void addSectionSymbols();
- void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
+ void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> fn);
void sortSections();
void resolveShfLinkOrder();
void finalizeAddressDependentContent();
@@ -61,13 +61,13 @@ private:
void checkExecuteOnly();
void setReservedSymbolSections();
- std::vector<PhdrEntry *> createPhdrs(Partition &Part);
- void removeEmptyPTLoad(std::vector<PhdrEntry *> &PhdrEntry);
- void addPhdrForSection(Partition &Part, unsigned ShType, unsigned PType,
- unsigned PFlags);
+ std::vector<PhdrEntry *> createPhdrs(Partition &part);
+ void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrEntry);
+ void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
+ unsigned pFlags);
void assignFileOffsets();
void assignFileOffsetsBinary();
- void setPhdrs(Partition &Part);
+ void setPhdrs(Partition &part);
void checkSections();
void fixSectionAlignments();
void openFile();
@@ -77,34 +77,34 @@ private:
void writeSectionsBinary();
void writeBuildId();
- std::unique_ptr<FileOutputBuffer> &Buffer;
+ std::unique_ptr<FileOutputBuffer> &buffer;
void addRelIpltSymbols();
void addStartEndSymbols();
- void addStartStopSymbols(OutputSection *Sec);
+ void addStartStopSymbols(OutputSection *sec);
- uint64_t FileSize;
- uint64_t SectionHeaderOff;
+ uint64_t fileSize;
+ uint64_t sectionHeaderOff;
};
} // anonymous namespace
-static bool isSectionPrefix(StringRef Prefix, StringRef Name) {
- return Name.startswith(Prefix) || Name == Prefix.drop_back();
+static bool isSectionPrefix(StringRef prefix, StringRef name) {
+ return name.startswith(prefix) || name == prefix.drop_back();
}
-StringRef elf::getOutputSectionName(const InputSectionBase *S) {
- if (Config->Relocatable)
- return S->Name;
+StringRef elf::getOutputSectionName(const InputSectionBase *s) {
+ if (config->relocatable)
+ return s->name;
// This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want
// to emit .rela.text.foo as .rela.text.bar for consistency (this is not
// technically required, but not doing it is odd). This code guarantees that.
- if (auto *IS = dyn_cast<InputSection>(S)) {
- if (InputSectionBase *Rel = IS->getRelocatedSection()) {
- OutputSection *Out = Rel->getOutputSection();
- if (S->Type == SHT_RELA)
- return Saver.save(".rela" + Out->Name);
- return Saver.save(".rel" + Out->Name);
+ if (auto *isec = dyn_cast<InputSection>(s)) {
+ if (InputSectionBase *rel = isec->getRelocatedSection()) {
+ OutputSection *out = rel->getOutputSection();
+ if (s->type == SHT_RELA)
+ return Saver.save(".rela" + out->name);
+ return Saver.save(".rel" + out->name);
}
}
@@ -114,130 +114,130 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {
// When enabled, this allows identifying the hot code region (.text.hot) in
// the final binary which can be selectively mapped to huge pages or mlocked,
// for instance.
- if (Config->ZKeepTextSectionPrefix)
- for (StringRef V :
+ if (config->zKeepTextSectionPrefix)
+ for (StringRef v :
{".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})
- if (isSectionPrefix(V, S->Name))
- return V.drop_back();
+ if (isSectionPrefix(v, s->name))
+ return v.drop_back();
- for (StringRef V :
+ for (StringRef v :
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
- if (isSectionPrefix(V, S->Name))
- return V.drop_back();
+ if (isSectionPrefix(v, s->name))
+ return v.drop_back();
// CommonSection is identified as "COMMON" in linker scripts.
// By default, it should go to .bss section.
- if (S->Name == "COMMON")
+ if (s->name == "COMMON")
return ".bss";
- return S->Name;
+ return s->name;
}
static bool needsInterpSection() {
- return !SharedFiles.empty() && !Config->DynamicLinker.empty() &&
- Script->needsInterpSection();
+ return !sharedFiles.empty() && !config->dynamicLinker.empty() &&
+ script->needsInterpSection();
}
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
template <class ELFT>
-void Writer<ELFT>::removeEmptyPTLoad(std::vector<PhdrEntry *> &Phdrs) {
- llvm::erase_if(Phdrs, [&](const PhdrEntry *P) {
- if (P->p_type != PT_LOAD)
+void Writer<ELFT>::removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
+ llvm::erase_if(phdrs, [&](const PhdrEntry *p) {
+ if (p->p_type != PT_LOAD)
return false;
- if (!P->FirstSec)
+ if (!p->firstSec)
return true;
- uint64_t Size = P->LastSec->Addr + P->LastSec->Size - P->FirstSec->Addr;
- return Size == 0;
+ uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr;
+ return size == 0;
});
}
template <class ELFT> static void copySectionsIntoPartitions() {
- std::vector<InputSectionBase *> NewSections;
- for (unsigned Part = 2; Part != Partitions.size() + 1; ++Part) {
- for (InputSectionBase *S : InputSections) {
- if (!(S->Flags & SHF_ALLOC) || !S->isLive())
+ std::vector<InputSectionBase *> newSections;
+ for (unsigned part = 2; part != partitions.size() + 1; ++part) {
+ for (InputSectionBase *s : inputSections) {
+ if (!(s->flags & SHF_ALLOC) || !s->isLive())
continue;
- InputSectionBase *Copy;
- if (S->Type == SHT_NOTE)
- Copy = make<InputSection>(cast<InputSection>(*S));
- else if (auto *ES = dyn_cast<EhInputSection>(S))
- Copy = make<EhInputSection>(*ES);
+ InputSectionBase *copy;
+ if (s->type == SHT_NOTE)
+ copy = make<InputSection>(cast<InputSection>(*s));
+ else if (auto *es = dyn_cast<EhInputSection>(s))
+ copy = make<EhInputSection>(*es);
else
continue;
- Copy->Partition = Part;
- NewSections.push_back(Copy);
+ copy->partition = part;
+ newSections.push_back(copy);
}
}
- InputSections.insert(InputSections.end(), NewSections.begin(),
- NewSections.end());
+ inputSections.insert(inputSections.end(), newSections.begin(),
+ newSections.end());
}
template <class ELFT> static void combineEhSections() {
- for (InputSectionBase *&S : InputSections) {
+ for (InputSectionBase *&s : inputSections) {
// Ignore dead sections and the partition end marker (.part.end),
// whose partition number is out of bounds.
- if (!S->isLive() || S->Partition == 255)
+ if (!s->isLive() || s->partition == 255)
continue;
- Partition &Part = S->getPartition();
- if (auto *ES = dyn_cast<EhInputSection>(S)) {
- Part.EhFrame->addSection<ELFT>(ES);
- S = nullptr;
- } else if (S->kind() == SectionBase::Regular && Part.ARMExidx &&
- Part.ARMExidx->addSection(cast<InputSection>(S))) {
- S = nullptr;
+ Partition &part = s->getPartition();
+ if (auto *es = dyn_cast<EhInputSection>(s)) {
+ part.ehFrame->addSection<ELFT>(es);
+ s = nullptr;
+ } else if (s->kind() == SectionBase::Regular && part.armExidx &&
+ part.armExidx->addSection(cast<InputSection>(s))) {
+ s = nullptr;
}
}
- std::vector<InputSectionBase *> &V = InputSections;
- V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+ std::vector<InputSectionBase *> &v = inputSections;
+ v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
}
-static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
- uint64_t Val, uint8_t StOther = STV_HIDDEN,
- uint8_t Binding = STB_GLOBAL) {
- Symbol *S = Symtab->find(Name);
- if (!S || S->isDefined())
+static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
+ uint64_t val, uint8_t stOther = STV_HIDDEN,
+ uint8_t binding = STB_GLOBAL) {
+ Symbol *s = symtab->find(name);
+ if (!s || s->isDefined())
return nullptr;
- S->resolve(Defined{/*File=*/nullptr, Name, Binding, StOther, STT_NOTYPE, Val,
- /*Size=*/0, Sec});
- return cast<Defined>(S);
+ s->resolve(Defined{/*File=*/nullptr, name, binding, stOther, STT_NOTYPE, val,
+ /*Size=*/0, sec});
+ return cast<Defined>(s);
}
-static Defined *addAbsolute(StringRef Name) {
- Symbol *Sym = Symtab->addSymbol(Defined{nullptr, Name, STB_GLOBAL, STV_HIDDEN,
+static Defined *addAbsolute(StringRef name) {
+ Symbol *sym = symtab->addSymbol(Defined{nullptr, name, STB_GLOBAL, STV_HIDDEN,
STT_NOTYPE, 0, 0, nullptr});
- return cast<Defined>(Sym);
+ return cast<Defined>(sym);
}
// The linker is expected to define some symbols depending on
// the linking result. This function defines such symbols.
void elf::addReservedSymbols() {
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
// so that it points to an absolute address which by default is relative
// to GOT. Default offset is 0x7ff0.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- ElfSym::MipsGp = addAbsolute("_gp");
+ ElfSym::mipsGp = addAbsolute("_gp");
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
- if (Symtab->find("_gp_disp"))
- ElfSym::MipsGpDisp = addAbsolute("_gp_disp");
+ if (symtab->find("_gp_disp"))
+ ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
// pointer. This symbol is used in the code generated by .cpload pseudo-op
// in case of using -mno-shared option.
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
- if (Symtab->find("__gnu_local_gp"))
- ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");
- } else if (Config->EMachine == EM_PPC) {
+ if (symtab->find("__gnu_local_gp"))
+ ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
+ } else if (config->emachine == EM_PPC) {
// glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
// support Small Data Area, define it arbitrarily as 0.
addOptionalRegular("_SDA_BASE_", nullptr, 0, STV_HIDDEN);
@@ -251,62 +251,62 @@ void elf::addReservedSymbols() {
// the .got section.
// We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the
// correctness of some relocations depends on its value.
- StringRef GotSymName =
- (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
+ StringRef gotSymName =
+ (config->emachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
- if (Symbol *S = Symtab->find(GotSymName)) {
- if (S->isDefined()) {
- error(toString(S->File) + " cannot redefine linker defined symbol '" +
- GotSymName + "'");
+ if (Symbol *s = symtab->find(gotSymName)) {
+ if (s->isDefined()) {
+ error(toString(s->file) + " cannot redefine linker defined symbol '" +
+ gotSymName + "'");
return;
}
- uint64_t GotOff = 0;
- if (Config->EMachine == EM_PPC64)
- GotOff = 0x8000;
+ uint64_t gotOff = 0;
+ if (config->emachine == EM_PPC64)
+ gotOff = 0x8000;
- S->resolve(Defined{/*File=*/nullptr, GotSymName, STB_GLOBAL, STV_HIDDEN,
- STT_NOTYPE, GotOff, /*Size=*/0, Out::ElfHeader});
- ElfSym::GlobalOffsetTable = cast<Defined>(S);
+ s->resolve(Defined{/*File=*/nullptr, gotSymName, STB_GLOBAL, STV_HIDDEN,
+ STT_NOTYPE, gotOff, /*Size=*/0, Out::elfHeader});
+ ElfSym::globalOffsetTable = cast<Defined>(s);
}
// __ehdr_start is the location of ELF file headers. Note that we define
// this symbol unconditionally even when using a linker script, which
// differs from the behavior implemented by GNU linker which only define
// this symbol if ELF headers are in the memory mapped segment.
- addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__ehdr_start", Out::elfHeader, 0, STV_HIDDEN);
// __executable_start is not documented, but the expectation of at
// least the Android libc is that it points to the ELF header.
- addOptionalRegular("__executable_start", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__executable_start", Out::elfHeader, 0, STV_HIDDEN);
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
// each DSO. The address of the symbol doesn't matter as long as they are
// different in different DSOs, so we chose the start address of the DSO.
- addOptionalRegular("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__dso_handle", Out::elfHeader, 0, STV_HIDDEN);
// If linker script do layout we do not need to create any standart symbols.
- if (Script->HasSectionsCommand)
+ if (script->hasSectionsCommand)
return;
- auto Add = [](StringRef S, int64_t Pos) {
- return addOptionalRegular(S, Out::ElfHeader, Pos, STV_DEFAULT);
+ auto add = [](StringRef s, int64_t pos) {
+ return addOptionalRegular(s, Out::elfHeader, pos, STV_DEFAULT);
};
- ElfSym::Bss = Add("__bss_start", 0);
- ElfSym::End1 = Add("end", -1);
- ElfSym::End2 = Add("_end", -1);
- ElfSym::Etext1 = Add("etext", -1);
- ElfSym::Etext2 = Add("_etext", -1);
- ElfSym::Edata1 = Add("edata", -1);
- ElfSym::Edata2 = Add("_edata", -1);
+ ElfSym::bss = add("__bss_start", 0);
+ ElfSym::end1 = add("end", -1);
+ ElfSym::end2 = add("_end", -1);
+ ElfSym::etext1 = add("etext", -1);
+ ElfSym::etext2 = add("_etext", -1);
+ ElfSym::edata1 = add("edata", -1);
+ ElfSym::edata2 = add("_edata", -1);
}
-static OutputSection *findSection(StringRef Name, unsigned Partition = 1) {
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- if (Sec->Name == Name && Sec->Partition == Partition)
- return Sec;
+static OutputSection *findSection(StringRef name, unsigned partition = 1) {
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ if (sec->name == name && sec->partition == partition)
+ return sec;
return nullptr;
}
@@ -314,195 +314,195 @@ static OutputSection *findSection(StringRef Name, unsigned Partition = 1) {
template <class ELFT> static void createSyntheticSections() {
// Initialize all pointers with NULL. This is needed because
// you can call lld::elf::main more than once as a library.
- memset(&Out::First, 0, sizeof(Out));
+ memset(&Out::first, 0, sizeof(Out));
- auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
+ auto add = [](InputSectionBase *sec) { inputSections.push_back(sec); };
- In.ShStrTab = make<StringTableSection>(".shstrtab", false);
+ in.shStrTab = make<StringTableSection>(".shstrtab", false);
- Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
- Out::ProgramHeaders->Alignment = Config->Wordsize;
+ Out::programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
+ Out::programHeaders->alignment = config->wordsize;
- if (Config->Strip != StripPolicy::All) {
- In.StrTab = make<StringTableSection>(".strtab", false);
- In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
- In.SymTabShndx = make<SymtabShndxSection>();
+ if (config->strip != StripPolicy::All) {
+ in.strTab = make<StringTableSection>(".strtab", false);
+ in.symTab = make<SymbolTableSection<ELFT>>(*in.strTab);
+ in.symTabShndx = make<SymtabShndxSection>();
}
- In.Bss = make<BssSection>(".bss", 0, 1);
- Add(In.Bss);
+ in.bss = make<BssSection>(".bss", 0, 1);
+ add(in.bss);
// If there is a SECTIONS command and a .data.rel.ro section name use name
// .data.rel.ro.bss so that we match in the .data.rel.ro output section.
// This makes sure our relro is contiguous.
- bool HasDataRelRo =
- Script->HasSectionsCommand && findSection(".data.rel.ro", 0);
- In.BssRelRo =
- make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
- Add(In.BssRelRo);
+ bool hasDataRelRo =
+ script->hasSectionsCommand && findSection(".data.rel.ro", 0);
+ in.bssRelRo =
+ make<BssSection>(hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
+ add(in.bssRelRo);
// Add MIPS-specific sections.
- if (Config->EMachine == EM_MIPS) {
- if (!Config->Shared && Config->HasDynSymTab) {
- In.MipsRldMap = make<MipsRldMapSection>();
- Add(In.MipsRldMap);
+ if (config->emachine == EM_MIPS) {
+ if (!config->shared && config->hasDynSymTab) {
+ in.mipsRldMap = make<MipsRldMapSection>();
+ add(in.mipsRldMap);
}
- if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
- Add(Sec);
- if (auto *Sec = MipsOptionsSection<ELFT>::create())
- Add(Sec);
- if (auto *Sec = MipsReginfoSection<ELFT>::create())
- Add(Sec);
- }
-
- for (Partition &Part : Partitions) {
- auto Add = [&](InputSectionBase *Sec) {
- Sec->Partition = Part.getNumber();
- InputSections.push_back(Sec);
+ if (auto *sec = MipsAbiFlagsSection<ELFT>::create())
+ add(sec);
+ if (auto *sec = MipsOptionsSection<ELFT>::create())
+ add(sec);
+ if (auto *sec = MipsReginfoSection<ELFT>::create())
+ add(sec);
+ }
+
+ for (Partition &part : partitions) {
+ auto add = [&](InputSectionBase *sec) {
+ sec->partition = part.getNumber();
+ inputSections.push_back(sec);
};
- if (!Part.Name.empty()) {
- Part.ElfHeader = make<PartitionElfHeaderSection<ELFT>>();
- Part.ElfHeader->Name = Part.Name;
- Add(Part.ElfHeader);
+ if (!part.name.empty()) {
+ part.elfHeader = make<PartitionElfHeaderSection<ELFT>>();
+ part.elfHeader->name = part.name;
+ add(part.elfHeader);
- Part.ProgramHeaders = make<PartitionProgramHeadersSection<ELFT>>();
- Add(Part.ProgramHeaders);
+ part.programHeaders = make<PartitionProgramHeadersSection<ELFT>>();
+ add(part.programHeaders);
}
- if (Config->BuildId != BuildIdKind::None) {
- Part.BuildId = make<BuildIdSection>();
- Add(Part.BuildId);
+ if (config->buildId != BuildIdKind::None) {
+ part.buildId = make<BuildIdSection>();
+ add(part.buildId);
}
- Part.DynStrTab = make<StringTableSection>(".dynstr", true);
- Part.DynSymTab = make<SymbolTableSection<ELFT>>(*Part.DynStrTab);
- Part.Dynamic = make<DynamicSection<ELFT>>();
- if (Config->AndroidPackDynRelocs) {
- Part.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
- Config->IsRela ? ".rela.dyn" : ".rel.dyn");
+ part.dynStrTab = make<StringTableSection>(".dynstr", true);
+ part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
+ part.dynamic = make<DynamicSection<ELFT>>();
+ if (config->androidPackDynRelocs) {
+ part.relaDyn = make<AndroidPackedRelocationSection<ELFT>>(
+ config->isRela ? ".rela.dyn" : ".rel.dyn");
} else {
- Part.RelaDyn = make<RelocationSection<ELFT>>(
- Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
+ part.relaDyn = make<RelocationSection<ELFT>>(
+ config->isRela ? ".rela.dyn" : ".rel.dyn", config->zCombreloc);
}
if (needsInterpSection())
- Add(createInterpSection());
+ add(createInterpSection());
- if (Config->HasDynSymTab) {
- Part.DynSymTab = make<SymbolTableSection<ELFT>>(*Part.DynStrTab);
- Add(Part.DynSymTab);
+ if (config->hasDynSymTab) {
+ part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
+ add(part.dynSymTab);
- Part.VerSym = make<VersionTableSection>();
- Add(Part.VerSym);
+ part.verSym = make<VersionTableSection>();
+ add(part.verSym);
- if (!Config->VersionDefinitions.empty()) {
- Part.VerDef = make<VersionDefinitionSection>();
- Add(Part.VerDef);
+ if (!config->versionDefinitions.empty()) {
+ part.verDef = make<VersionDefinitionSection>();
+ add(part.verDef);
}
- Part.VerNeed = make<VersionNeedSection<ELFT>>();
- Add(Part.VerNeed);
+ part.verNeed = make<VersionNeedSection<ELFT>>();
+ add(part.verNeed);
- if (Config->GnuHash) {
- Part.GnuHashTab = make<GnuHashTableSection>();
- Add(Part.GnuHashTab);
+ if (config->gnuHash) {
+ part.gnuHashTab = make<GnuHashTableSection>();
+ add(part.gnuHashTab);
}
- if (Config->SysvHash) {
- Part.HashTab = make<HashTableSection>();
- Add(Part.HashTab);
+ if (config->sysvHash) {
+ part.hashTab = make<HashTableSection>();
+ add(part.hashTab);
}
- Add(Part.Dynamic);
- Add(Part.DynStrTab);
- Add(Part.RelaDyn);
+ add(part.dynamic);
+ add(part.dynStrTab);
+ add(part.relaDyn);
}
- if (Config->RelrPackDynRelocs) {
- Part.RelrDyn = make<RelrSection<ELFT>>();
- Add(Part.RelrDyn);
+ if (config->relrPackDynRelocs) {
+ part.relrDyn = make<RelrSection<ELFT>>();
+ add(part.relrDyn);
}
- if (!Config->Relocatable) {
- if (Config->EhFrameHdr) {
- Part.EhFrameHdr = make<EhFrameHeader>();
- Add(Part.EhFrameHdr);
+ if (!config->relocatable) {
+ if (config->ehFrameHdr) {
+ part.ehFrameHdr = make<EhFrameHeader>();
+ add(part.ehFrameHdr);
}
- Part.EhFrame = make<EhFrameSection>();
- Add(Part.EhFrame);
+ part.ehFrame = make<EhFrameSection>();
+ add(part.ehFrame);
}
- if (Config->EMachine == EM_ARM && !Config->Relocatable) {
+ if (config->emachine == EM_ARM && !config->relocatable) {
// The ARMExidxsyntheticsection replaces all the individual .ARM.exidx
// InputSections.
- Part.ARMExidx = make<ARMExidxSyntheticSection>();
- Add(Part.ARMExidx);
+ part.armExidx = make<ARMExidxSyntheticSection>();
+ add(part.armExidx);
}
}
- if (Partitions.size() != 1) {
+ if (partitions.size() != 1) {
// Create the partition end marker. This needs to be in partition number 255
// so that it is sorted after all other partitions. It also has other
// special handling (see createPhdrs() and combineEhSections()).
- In.PartEnd = make<BssSection>(".part.end", Config->MaxPageSize, 1);
- In.PartEnd->Partition = 255;
- Add(In.PartEnd);
+ in.partEnd = make<BssSection>(".part.end", config->maxPageSize, 1);
+ in.partEnd->partition = 255;
+ add(in.partEnd);
- In.PartIndex = make<PartitionIndexSection>();
- addOptionalRegular("__part_index_begin", In.PartIndex, 0);
- addOptionalRegular("__part_index_end", In.PartIndex,
- In.PartIndex->getSize());
- Add(In.PartIndex);
+ in.partIndex = make<PartitionIndexSection>();
+ addOptionalRegular("__part_index_begin", in.partIndex, 0);
+ addOptionalRegular("__part_index_end", in.partIndex,
+ in.partIndex->getSize());
+ add(in.partIndex);
}
// Add .got. MIPS' .got is so different from the other archs,
// it has its own class.
- if (Config->EMachine == EM_MIPS) {
- In.MipsGot = make<MipsGotSection>();
- Add(In.MipsGot);
+ if (config->emachine == EM_MIPS) {
+ in.mipsGot = make<MipsGotSection>();
+ add(in.mipsGot);
} else {
- In.Got = make<GotSection>();
- Add(In.Got);
+ in.got = make<GotSection>();
+ add(in.got);
}
- if (Config->EMachine == EM_PPC) {
- In.PPC32Got2 = make<PPC32Got2Section>();
- Add(In.PPC32Got2);
+ if (config->emachine == EM_PPC) {
+ in.ppc32Got2 = make<PPC32Got2Section>();
+ add(in.ppc32Got2);
}
- if (Config->EMachine == EM_PPC64) {
- In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>();
- Add(In.PPC64LongBranchTarget);
+ if (config->emachine == EM_PPC64) {
+ in.ppc64LongBranchTarget = make<PPC64LongBranchTargetSection>();
+ add(in.ppc64LongBranchTarget);
}
- if (Config->EMachine == EM_RISCV) {
- In.RISCVSdata = make<RISCVSdataSection>();
- Add(In.RISCVSdata);
+ if (config->emachine == EM_RISCV) {
+ in.riscvSdata = make<RISCVSdataSection>();
+ add(in.riscvSdata);
}
- In.GotPlt = make<GotPltSection>();
- Add(In.GotPlt);
- In.IgotPlt = make<IgotPltSection>();
- Add(In.IgotPlt);
+ in.gotPlt = make<GotPltSection>();
+ add(in.gotPlt);
+ in.igotPlt = make<IgotPltSection>();
+ add(in.igotPlt);
// _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
// it as a relocation and ensure the referenced section is created.
- if (ElfSym::GlobalOffsetTable && Config->EMachine != EM_MIPS) {
- if (Target->GotBaseSymInGotPlt)
- In.GotPlt->HasGotPltOffRel = true;
+ if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
+ if (target->gotBaseSymInGotPlt)
+ in.gotPlt->hasGotPltOffRel = true;
else
- In.Got->HasGotOffRel = true;
+ in.got->hasGotOffRel = true;
}
- if (Config->GdbIndex)
- Add(GdbIndexSection::create<ELFT>());
+ if (config->gdbIndex)
+ add(GdbIndexSection::create<ELFT>());
// We always need to add rel[a].plt to output if it has entries.
// Even for static linking it can contain R_[*]_IRELATIVE relocations.
- In.RelaPlt = make<RelocationSection<ELFT>>(
- Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
- Add(In.RelaPlt);
+ in.relaPlt = make<RelocationSection<ELFT>>(
+ config->isRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
+ add(in.relaPlt);
// The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
// that the IRelative relocations are processed last by the dynamic loader.
@@ -510,36 +510,36 @@ template <class ELFT> static void createSyntheticSections() {
// packing is enabled because that would cause a section type mismatch.
// However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
// we can get the desired behaviour by placing the iplt section in .rel.plt.
- In.RelaIplt = make<RelocationSection<ELFT>>(
- (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
+ in.relaIplt = make<RelocationSection<ELFT>>(
+ (config->emachine == EM_ARM && !config->androidPackDynRelocs)
? ".rel.dyn"
- : In.RelaPlt->Name,
+ : in.relaPlt->name,
false /*Sort*/);
- Add(In.RelaIplt);
+ add(in.relaIplt);
- In.Plt = make<PltSection>(false);
- Add(In.Plt);
- In.Iplt = make<PltSection>(true);
- Add(In.Iplt);
+ in.plt = make<PltSection>(false);
+ add(in.plt);
+ in.iplt = make<PltSection>(true);
+ add(in.iplt);
- if (Config->AndFeatures)
- Add(make<GnuPropertySection>());
+ if (config->andFeatures)
+ add(make<GnuPropertySection>());
// .note.GNU-stack is always added when we are creating a re-linkable
// object file. Other linkers are using the presence of this marker
// section to control the executable-ness of the stack area, but that
// is irrelevant these days. Stack area should always be non-executable
// by default. So we emit this section unconditionally.
- if (Config->Relocatable)
- Add(make<GnuStackSection>());
+ if (config->relocatable)
+ add(make<GnuStackSection>());
- if (In.SymTab)
- Add(In.SymTab);
- if (In.SymTabShndx)
- Add(In.SymTabShndx);
- Add(In.ShStrTab);
- if (In.StrTab)
- Add(In.StrTab);
+ if (in.symTab)
+ add(in.symTab);
+ if (in.symTabShndx)
+ add(in.symTabShndx);
+ add(in.shStrTab);
+ if (in.strTab)
+ add(in.strTab);
}
// The main function of the writer.
@@ -555,22 +555,22 @@ template <class ELFT> void Writer<ELFT>::run() {
// Some input sections that are used for exception handling need to be moved
// into synthetic sections. Do that now so that they aren't assigned to
// output sections in the usual way.
- if (!Config->Relocatable)
+ if (!config->relocatable)
combineEhSections<ELFT>();
// We want to process linker script commands. When SECTIONS command
// is given we let it create sections.
- Script->processSectionCommands();
+ script->processSectionCommands();
// Linker scripts controls how input sections are assigned to output sections.
// Input sections that were not handled by scripts are called "orphans", and
// they are assigned to output sections by the default rule. Process that.
- Script->addOrphanSections();
+ script->addOrphanSections();
- if (Config->Discard != DiscardPolicy::All)
+ if (config->discard != DiscardPolicy::All)
copyLocalSymbols();
- if (Config->CopyRelocs)
+ if (config->copyRelocs)
addSectionSymbols();
// Now that we have a complete set of output sections. This function
@@ -582,35 +582,35 @@ template <class ELFT> void Writer<ELFT>::run() {
if (errorCount())
return;
- Script->assignAddresses();
+ script->assignAddresses();
// If -compressed-debug-sections is specified, we need to compress
// .debug_* sections. Do it right now because it changes the size of
// output sections.
- for (OutputSection *Sec : OutputSections)
- Sec->maybeCompress<ELFT>();
+ for (OutputSection *sec : outputSections)
+ sec->maybeCompress<ELFT>();
- Script->allocateHeaders(Main->Phdrs);
+ script->allocateHeaders(mainPart->phdrs);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
// 0 sized region. This has to be done late since only after assignAddresses
// we know the size of the sections.
- for (Partition &Part : Partitions)
- removeEmptyPTLoad(Part.Phdrs);
+ for (Partition &part : partitions)
+ removeEmptyPTLoad(part.phdrs);
- if (!Config->OFormatBinary)
+ if (!config->oFormatBinary)
assignFileOffsets();
else
assignFileOffsetsBinary();
- for (Partition &Part : Partitions)
- setPhdrs(Part);
+ for (Partition &part : partitions)
+ setPhdrs(part);
- if (Config->Relocatable)
- for (OutputSection *Sec : OutputSections)
- Sec->Addr = 0;
+ if (config->relocatable)
+ for (OutputSection *sec : outputSections)
+ sec->addr = 0;
- if (Config->CheckSections)
+ if (config->checkSections)
checkSections();
// It does not make sense try to open the file if we have error already.
@@ -621,7 +621,7 @@ template <class ELFT> void Writer<ELFT>::run() {
if (errorCount())
return;
- if (!Config->OFormatBinary) {
+ if (!config->oFormatBinary) {
writeTrapInstr();
writeHeader();
writeSections();
@@ -641,20 +641,20 @@ template <class ELFT> void Writer<ELFT>::run() {
if (errorCount())
return;
- if (auto E = Buffer->commit())
- error("failed to write to the output file: " + toString(std::move(E)));
+ if (auto e = buffer->commit())
+ error("failed to write to the output file: " + toString(std::move(e)));
}
-static bool shouldKeepInSymtab(const Defined &Sym) {
- if (Sym.isSection())
+static bool shouldKeepInSymtab(const Defined &sym) {
+ if (sym.isSection())
return false;
- if (Config->Discard == DiscardPolicy::None)
+ if (config->discard == DiscardPolicy::None)
return true;
// If -emit-reloc is given, all symbols including local ones need to be
// copied because they may be referenced by relocations.
- if (Config->EmitRelocs)
+ if (config->emitRelocs)
return true;
// In ELF assembly .L symbols are normally discarded by the assembler.
@@ -662,62 +662,62 @@ static bool shouldKeepInSymtab(const Defined &Sym) {
// * --discard-locals is used.
// * The symbol is in a SHF_MERGE section, which is normally the reason for
// the assembler keeping the .L symbol.
- StringRef Name = Sym.getName();
- bool IsLocal = Name.startswith(".L") || Name.empty();
- if (!IsLocal)
+ StringRef name = sym.getName();
+ bool isLocal = name.startswith(".L") || name.empty();
+ if (!isLocal)
return true;
- if (Config->Discard == DiscardPolicy::Locals)
+ if (config->discard == DiscardPolicy::Locals)
return false;
- SectionBase *Sec = Sym.Section;
- return !Sec || !(Sec->Flags & SHF_MERGE);
+ SectionBase *sec = sym.section;
+ return !sec || !(sec->flags & SHF_MERGE);
}
-static bool includeInSymtab(const Symbol &B) {
- if (!B.isLocal() && !B.IsUsedInRegularObj)
+static bool includeInSymtab(const Symbol &b) {
+ if (!b.isLocal() && !b.isUsedInRegularObj)
return false;
- if (auto *D = dyn_cast<Defined>(&B)) {
+ if (auto *d = dyn_cast<Defined>(&b)) {
// Always include absolute symbols.
- SectionBase *Sec = D->Section;
- if (!Sec)
+ SectionBase *sec = d->section;
+ if (!sec)
return true;
- Sec = Sec->Repl;
+ sec = sec->repl;
// Exclude symbols pointing to garbage-collected sections.
- if (isa<InputSectionBase>(Sec) && !Sec->isLive())
+ if (isa<InputSectionBase>(sec) && !sec->isLive())
return false;
- if (auto *S = dyn_cast<MergeInputSection>(Sec))
- if (!S->getSectionPiece(D->Value)->Live)
+ if (auto *s = dyn_cast<MergeInputSection>(sec))
+ if (!s->getSectionPiece(d->value)->live)
return false;
return true;
}
- return B.Used;
+ return b.used;
}
// Local symbols are not in the linker's symbol table. This function scans
// each object file's symbol table to copy local symbols to the output.
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
- if (!In.SymTab)
+ if (!in.symTab)
return;
- for (InputFile *File : ObjectFiles) {
- ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
- for (Symbol *B : F->getLocalSymbols()) {
- if (!B->isLocal())
- fatal(toString(F) +
+ for (InputFile *file : objectFiles) {
+ ObjFile<ELFT> *f = cast<ObjFile<ELFT>>(file);
+ for (Symbol *b : f->getLocalSymbols()) {
+ if (!b->isLocal())
+ fatal(toString(f) +
": broken object: getLocalSymbols returns a non-local symbol");
- auto *DR = dyn_cast<Defined>(B);
+ auto *dr = dyn_cast<Defined>(b);
// No reason to keep local undefined symbol in symtab.
- if (!DR)
+ if (!dr)
continue;
- if (!includeInSymtab(*B))
+ if (!includeInSymtab(*b))
continue;
- if (!shouldKeepInSymtab(*DR))
+ if (!shouldKeepInSymtab(*dr))
continue;
- In.SymTab->addSymbol(B);
+ in.symTab->addSymbol(b);
}
}
}
@@ -727,33 +727,33 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
// referring to a section (that happens if the section is a synthetic one), we
// don't create a section symbol for that section.
template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
- for (BaseCommand *Base : Script->SectionCommands) {
- auto *Sec = dyn_cast<OutputSection>(Base);
- if (!Sec)
+ for (BaseCommand *base : script->sectionCommands) {
+ auto *sec = dyn_cast<OutputSection>(base);
+ if (!sec)
continue;
- auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- return !ISD->Sections.empty();
+ auto i = llvm::find_if(sec->sectionCommands, [](BaseCommand *base) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ return !isd->sections.empty();
return false;
});
- if (I == Sec->SectionCommands.end())
+ if (i == sec->sectionCommands.end())
continue;
- InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
+ InputSection *isec = cast<InputSectionDescription>(*i)->sections[0];
// Relocations are not using REL[A] section symbols.
- if (IS->Type == SHT_REL || IS->Type == SHT_RELA)
+ if (isec->type == SHT_REL || isec->type == SHT_RELA)
continue;
// Unlike other synthetic sections, mergeable output sections contain data
// copied from input sections, and there may be a relocation pointing to its
// contents if -r or -emit-reloc are given.
- if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE))
+ if (isa<SyntheticSection>(isec) && !(isec->flags & SHF_MERGE))
continue;
- auto *Sym =
- make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
- /*Value=*/0, /*Size=*/0, IS);
- In.SymTab->addSymbol(Sym);
+ auto *sym =
+ make<Defined>(isec->file, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
+ /*Value=*/0, /*Size=*/0, isec);
+ in.symTab->addSymbol(sym);
}
}
@@ -763,25 +763,25 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
//
// This function returns true if a section needs to be put into a
// PT_GNU_RELRO segment.
-static bool isRelroSection(const OutputSection *Sec) {
- if (!Config->ZRelro)
+static bool isRelroSection(const OutputSection *sec) {
+ if (!config->zRelro)
return false;
- uint64_t Flags = Sec->Flags;
+ uint64_t flags = sec->flags;
// Non-allocatable or non-writable sections don't need RELRO because
// they are not writable or not even mapped to memory in the first place.
// RELRO is for sections that are essentially read-only but need to
// be writable only at process startup to allow dynamic linker to
// apply relocations.
- if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
+ if (!(flags & SHF_ALLOC) || !(flags & SHF_WRITE))
return false;
// Once initialized, TLS data segments are used as data templates
// for a thread-local storage. For each new thread, runtime
// allocates memory for a TLS and copy templates there. No thread
// are supposed to use templates directly. Thus, it can be in RELRO.
- if (Flags & SHF_TLS)
+ if (flags & SHF_TLS)
return true;
// .init_array, .preinit_array and .fini_array contain pointers to
@@ -790,15 +790,15 @@ static bool isRelroSection(const OutputSection *Sec) {
// to change at runtime. But if you are an attacker, you could do
// interesting things by manipulating pointers in .fini_array, for
// example. So they are put into RELRO.
- uint32_t Type = Sec->Type;
- if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
- Type == SHT_PREINIT_ARRAY)
+ uint32_t type = sec->type;
+ if (type == SHT_INIT_ARRAY || type == SHT_FINI_ARRAY ||
+ type == SHT_PREINIT_ARRAY)
return true;
// .got contains pointers to external symbols. They are resolved by
// the dynamic linker when a module is loaded into memory, and after
// that they are not expected to change. So, it can be in RELRO.
- if (In.Got && Sec == In.Got->getParent())
+ if (in.got && sec == in.got->getParent())
return true;
// .toc is a GOT-ish section for PowerPC64. Their contents are accessed
@@ -806,30 +806,30 @@ static bool isRelroSection(const OutputSection *Sec) {
// for accessing .got as well, .got and .toc need to be close enough in the
// virtual address space. Usually, .toc comes just after .got. Since we place
// .got into RELRO, .toc needs to be placed into RELRO too.
- if (Sec->Name.equals(".toc"))
+ if (sec->name.equals(".toc"))
return true;
// .got.plt contains pointers to external function symbols. They are
// by default resolved lazily, so we usually cannot put it into RELRO.
// However, if "-z now" is given, the lazy symbol resolution is
// disabled, which enables us to put it into RELRO.
- if (Sec == In.GotPlt->getParent())
- return Config->ZNow;
+ if (sec == in.gotPlt->getParent())
+ return config->zNow;
// .dynamic section contains data for the dynamic linker, and
// there's no need to write to it at runtime, so it's better to put
// it into RELRO.
- if (Sec->Name == ".dynamic")
+ if (sec->name == ".dynamic")
return true;
// Sections with some special names are put into RELRO. This is a
// bit unfortunate because section names shouldn't be significant in
// ELF in spirit. But in reality many linker features depend on
// magic section names.
- StringRef S = Sec->Name;
- return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" ||
- S == ".dtors" || S == ".jcr" || S == ".eh_frame" ||
- S == ".openbsd.randomdata";
+ StringRef s = sec->name;
+ return s == ".data.rel.ro" || s == ".bss.rel.ro" || s == ".ctors" ||
+ s == ".dtors" || s == ".jcr" || s == ".eh_frame" ||
+ s == ".openbsd.randomdata";
}
// We compute a rank for each section. The rank indicates where the
@@ -863,41 +863,41 @@ enum RankFlags {
RF_MIPS_NOT_GOT = 1 << 0
};
-static unsigned getSectionRank(const OutputSection *Sec) {
- unsigned Rank = Sec->Partition * RF_PARTITION;
+static unsigned getSectionRank(const OutputSection *sec) {
+ unsigned rank = sec->partition * RF_PARTITION;
// We want to put section specified by -T option first, so we
// can start assigning VA starting from them later.
- if (Config->SectionStartMap.count(Sec->Name))
- return Rank;
- Rank |= RF_NOT_ADDR_SET;
+ if (config->sectionStartMap.count(sec->name))
+ return rank;
+ rank |= RF_NOT_ADDR_SET;
// Allocatable sections go first to reduce the total PT_LOAD size and
// so debug info doesn't change addresses in actual code.
- if (!(Sec->Flags & SHF_ALLOC))
- return Rank | RF_NOT_ALLOC;
+ if (!(sec->flags & SHF_ALLOC))
+ return rank | RF_NOT_ALLOC;
- if (Sec->Type == SHT_LLVM_PART_EHDR)
- return Rank;
- Rank |= RF_NOT_PART_EHDR;
+ if (sec->type == SHT_LLVM_PART_EHDR)
+ return rank;
+ rank |= RF_NOT_PART_EHDR;
- if (Sec->Type == SHT_LLVM_PART_PHDR)
- return Rank;
- Rank |= RF_NOT_PART_PHDR;
+ if (sec->type == SHT_LLVM_PART_PHDR)
+ return rank;
+ rank |= RF_NOT_PART_PHDR;
// Put .interp first because some loaders want to see that section
// on the first page of the executable file when loaded into memory.
- if (Sec->Name == ".interp")
- return Rank;
- Rank |= RF_NOT_INTERP;
+ if (sec->name == ".interp")
+ return rank;
+ rank |= RF_NOT_INTERP;
// Put .note sections (which make up one PT_NOTE) at the beginning so that
// they are likely to be included in a core file even if core file size is
// limited. In particular, we want a .note.gnu.build-id and a .note.tag to be
// included in a core to match core files with executables.
- if (Sec->Type == SHT_NOTE)
- return Rank;
- Rank |= RF_NOT_NOTE;
+ if (sec->type == SHT_NOTE)
+ return rank;
+ rank |= RF_NOT_NOTE;
// Sort sections based on their access permission in the following
// order: R, RX, RWX, RW. This order is based on the following
@@ -910,22 +910,22 @@ static unsigned getSectionRank(const OutputSection *Sec) {
// between .text and .data.
// * Writable sections come last, such that .bss lands at the very
// end of the last PT_LOAD.
- bool IsExec = Sec->Flags & SHF_EXECINSTR;
- bool IsWrite = Sec->Flags & SHF_WRITE;
+ bool isExec = sec->flags & SHF_EXECINSTR;
+ bool isWrite = sec->flags & SHF_WRITE;
- if (IsExec) {
- if (IsWrite)
- Rank |= RF_EXEC_WRITE;
+ if (isExec) {
+ if (isWrite)
+ rank |= RF_EXEC_WRITE;
else
- Rank |= RF_EXEC;
- } else if (IsWrite) {
- Rank |= RF_WRITE;
- } else if (Sec->Type == SHT_PROGBITS) {
+ rank |= RF_EXEC;
+ } else if (isWrite) {
+ rank |= RF_WRITE;
+ } else if (sec->type == SHT_PROGBITS) {
// Make non-executable and non-writable PROGBITS sections (e.g .rodata
// .eh_frame) closer to .text. They likely contain PC or GOT relative
// relocations and there could be relocation overflow if other huge sections
// (.dynstr .dynsym) were placed in between.
- Rank |= RF_RODATA;
+ rank |= RF_RODATA;
}
// Place RelRo sections first. After considering SHT_NOBITS below, the
@@ -933,8 +933,8 @@ static unsigned getSectionRank(const OutputSection *Sec) {
// where | marks where page alignment happens. An alternative ordering is
// PT_LOAD(.data | PT_GNU_RELRO( .data.rel.ro .bss.rel.ro) | .bss), but it may
// waste more bytes due to 2 alignment places.
- if (!isRelroSection(Sec))
- Rank |= RF_NOT_RELRO;
+ if (!isRelroSection(sec))
+ rank |= RF_NOT_RELRO;
// If we got here we know that both A and B are in the same PT_LOAD.
@@ -942,73 +942,73 @@ static unsigned getSectionRank(const OutputSection *Sec) {
// PT_LOAD, so stick TLS sections directly before the other RelRo R/W
// sections. Since p_filesz can be less than p_memsz, place NOBITS sections
// after PROGBITS.
- if (!(Sec->Flags & SHF_TLS))
- Rank |= RF_NOT_TLS;
+ if (!(sec->flags & SHF_TLS))
+ rank |= RF_NOT_TLS;
// Within TLS sections, or within other RelRo sections, or within non-RelRo
// sections, place non-NOBITS sections first.
- if (Sec->Type == SHT_NOBITS)
- Rank |= RF_BSS;
+ if (sec->type == SHT_NOBITS)
+ rank |= RF_BSS;
// Some architectures have additional ordering restrictions for sections
// within the same PT_LOAD.
- if (Config->EMachine == EM_PPC64) {
+ if (config->emachine == EM_PPC64) {
// PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections
// that we would like to make sure appear is a specific order to maximize
// their coverage by a single signed 16-bit offset from the TOC base
// pointer. Conversely, the special .tocbss section should be first among
// all SHT_NOBITS sections. This will put it next to the loaded special
// PPC64 sections (and, thus, within reach of the TOC base pointer).
- StringRef Name = Sec->Name;
- if (Name != ".tocbss")
- Rank |= RF_PPC_NOT_TOCBSS;
+ StringRef name = sec->name;
+ if (name != ".tocbss")
+ rank |= RF_PPC_NOT_TOCBSS;
- if (Name == ".toc1")
- Rank |= RF_PPC_TOCL;
+ if (name == ".toc1")
+ rank |= RF_PPC_TOCL;
- if (Name == ".toc")
- Rank |= RF_PPC_TOC;
+ if (name == ".toc")
+ rank |= RF_PPC_TOC;
- if (Name == ".got")
- Rank |= RF_PPC_GOT;
+ if (name == ".got")
+ rank |= RF_PPC_GOT;
- if (Name == ".branch_lt")
- Rank |= RF_PPC_BRANCH_LT;
+ if (name == ".branch_lt")
+ rank |= RF_PPC_BRANCH_LT;
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// All sections with SHF_MIPS_GPREL flag should be grouped together
// because data in these sections is addressable with a gp relative address.
- if (Sec->Flags & SHF_MIPS_GPREL)
- Rank |= RF_MIPS_GPREL;
+ if (sec->flags & SHF_MIPS_GPREL)
+ rank |= RF_MIPS_GPREL;
- if (Sec->Name != ".got")
- Rank |= RF_MIPS_NOT_GOT;
+ if (sec->name != ".got")
+ rank |= RF_MIPS_NOT_GOT;
}
- return Rank;
+ return rank;
}
-static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
- const OutputSection *A = cast<OutputSection>(ACmd);
- const OutputSection *B = cast<OutputSection>(BCmd);
+static bool compareSections(const BaseCommand *aCmd, const BaseCommand *bCmd) {
+ const OutputSection *a = cast<OutputSection>(aCmd);
+ const OutputSection *b = cast<OutputSection>(bCmd);
- if (A->SortRank != B->SortRank)
- return A->SortRank < B->SortRank;
+ if (a->sortRank != b->sortRank)
+ return a->sortRank < b->sortRank;
- if (!(A->SortRank & RF_NOT_ADDR_SET))
- return Config->SectionStartMap.lookup(A->Name) <
- Config->SectionStartMap.lookup(B->Name);
+ if (!(a->sortRank & RF_NOT_ADDR_SET))
+ return config->sectionStartMap.lookup(a->name) <
+ config->sectionStartMap.lookup(b->name);
return false;
}
-void PhdrEntry::add(OutputSection *Sec) {
- LastSec = Sec;
- if (!FirstSec)
- FirstSec = Sec;
- p_align = std::max(p_align, Sec->Alignment);
+void PhdrEntry::add(OutputSection *sec) {
+ lastSec = sec;
+ if (!firstSec)
+ firstSec = sec;
+ p_align = std::max(p_align, sec->alignment);
if (p_type == PT_LOAD)
- Sec->PtLoad = this;
+ sec->ptLoad = this;
}
// The beginning and the ending of .rel[a].plt section are marked
@@ -1018,39 +1018,39 @@ void PhdrEntry::add(OutputSection *Sec) {
// need these symbols, since IRELATIVE relocs are resolved through GOT
// and PLT. For details, see http://www.airs.com/blog/archives/403.
template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
- if (Config->Relocatable || needsInterpSection())
+ if (config->relocatable || needsInterpSection())
return;
// By default, __rela_iplt_{start,end} belong to a dummy section 0
// because .rela.plt might be empty and thus removed from output.
// We'll override Out::ElfHeader with In.RelaIplt later when we are
// sure that .rela.plt exists in output.
- ElfSym::RelaIpltStart = addOptionalRegular(
- Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
- Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
+ ElfSym::relaIpltStart = addOptionalRegular(
+ config->isRela ? "__rela_iplt_start" : "__rel_iplt_start",
+ Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
- ElfSym::RelaIpltEnd = addOptionalRegular(
- Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
- Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
+ ElfSym::relaIpltEnd = addOptionalRegular(
+ config->isRela ? "__rela_iplt_end" : "__rel_iplt_end",
+ Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
}
template <class ELFT>
void Writer<ELFT>::forEachRelSec(
- llvm::function_ref<void(InputSectionBase &)> Fn) {
+ llvm::function_ref<void(InputSectionBase &)> fn) {
// Scan all relocations. Each relocation goes through a series
// of tests to determine if it needs special treatment, such as
// creating GOT, PLT, copy relocations, etc.
// Note that relocations for non-alloc sections are directly
// processed by InputSection::relocateNonAlloc.
- for (InputSectionBase *IS : InputSections)
- if (IS->isLive() && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
- Fn(*IS);
- for (Partition &Part : Partitions) {
- for (EhInputSection *ES : Part.EhFrame->Sections)
- Fn(*ES);
- if (Part.ARMExidx && Part.ARMExidx->isLive())
- for (InputSection *Ex : Part.ARMExidx->ExidxSections)
- Fn(*Ex);
+ for (InputSectionBase *isec : inputSections)
+ if (isec->isLive() && isa<InputSection>(isec) && (isec->flags & SHF_ALLOC))
+ fn(*isec);
+ for (Partition &part : partitions) {
+ for (EhInputSection *es : part.ehFrame->sections)
+ fn(*es);
+ if (part.armExidx && part.armExidx->isLive())
+ for (InputSection *ex : part.armExidx->exidxSections)
+ fn(*ex);
}
}
@@ -1060,78 +1060,78 @@ void Writer<ELFT>::forEachRelSec(
// time any references to these symbols are processed and is equivalent to
// defining these symbols explicitly in the linker script.
template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
- if (ElfSym::GlobalOffsetTable) {
+ if (ElfSym::globalOffsetTable) {
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
// to the start of the .got or .got.plt section.
- InputSection *GotSection = In.GotPlt;
- if (!Target->GotBaseSymInGotPlt)
- GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
- : cast<InputSection>(In.Got);
- ElfSym::GlobalOffsetTable->Section = GotSection;
+ InputSection *gotSection = in.gotPlt;
+ if (!target->gotBaseSymInGotPlt)
+ gotSection = in.mipsGot ? cast<InputSection>(in.mipsGot)
+ : cast<InputSection>(in.got);
+ ElfSym::globalOffsetTable->section = gotSection;
}
// .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
- if (ElfSym::RelaIpltStart && In.RelaIplt->isNeeded()) {
- ElfSym::RelaIpltStart->Section = In.RelaIplt;
- ElfSym::RelaIpltEnd->Section = In.RelaIplt;
- ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
+ if (ElfSym::relaIpltStart && in.relaIplt->isNeeded()) {
+ ElfSym::relaIpltStart->section = in.relaIplt;
+ ElfSym::relaIpltEnd->section = in.relaIplt;
+ ElfSym::relaIpltEnd->value = in.relaIplt->getSize();
}
- PhdrEntry *Last = nullptr;
- PhdrEntry *LastRO = nullptr;
+ PhdrEntry *last = nullptr;
+ PhdrEntry *lastRO = nullptr;
- for (Partition &Part : Partitions) {
- for (PhdrEntry *P : Part.Phdrs) {
- if (P->p_type != PT_LOAD)
+ for (Partition &part : partitions) {
+ for (PhdrEntry *p : part.phdrs) {
+ if (p->p_type != PT_LOAD)
continue;
- Last = P;
- if (!(P->p_flags & PF_W))
- LastRO = P;
+ last = p;
+ if (!(p->p_flags & PF_W))
+ lastRO = p;
}
}
- if (LastRO) {
+ if (lastRO) {
// _etext is the first location after the last read-only loadable segment.
- if (ElfSym::Etext1)
- ElfSym::Etext1->Section = LastRO->LastSec;
- if (ElfSym::Etext2)
- ElfSym::Etext2->Section = LastRO->LastSec;
+ if (ElfSym::etext1)
+ ElfSym::etext1->section = lastRO->lastSec;
+ if (ElfSym::etext2)
+ ElfSym::etext2->section = lastRO->lastSec;
}
- if (Last) {
+ if (last) {
// _edata points to the end of the last mapped initialized section.
- OutputSection *Edata = nullptr;
- for (OutputSection *OS : OutputSections) {
- if (OS->Type != SHT_NOBITS)
- Edata = OS;
- if (OS == Last->LastSec)
+ OutputSection *edata = nullptr;
+ for (OutputSection *os : outputSections) {
+ if (os->type != SHT_NOBITS)
+ edata = os;
+ if (os == last->lastSec)
break;
}
- if (ElfSym::Edata1)
- ElfSym::Edata1->Section = Edata;
- if (ElfSym::Edata2)
- ElfSym::Edata2->Section = Edata;
+ if (ElfSym::edata1)
+ ElfSym::edata1->section = edata;
+ if (ElfSym::edata2)
+ ElfSym::edata2->section = edata;
// _end is the first location after the uninitialized data region.
- if (ElfSym::End1)
- ElfSym::End1->Section = Last->LastSec;
- if (ElfSym::End2)
- ElfSym::End2->Section = Last->LastSec;
+ if (ElfSym::end1)
+ ElfSym::end1->section = last->lastSec;
+ if (ElfSym::end2)
+ ElfSym::end2->section = last->lastSec;
}
- if (ElfSym::Bss)
- ElfSym::Bss->Section = findSection(".bss");
+ if (ElfSym::bss)
+ ElfSym::bss->section = findSection(".bss");
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
// be equal to the _gp symbol's value.
- if (ElfSym::MipsGp) {
+ if (ElfSym::mipsGp) {
// Find GP-relative section with the lowest address
// and use this address to calculate default _gp value.
- for (OutputSection *OS : OutputSections) {
- if (OS->Flags & SHF_MIPS_GPREL) {
- ElfSym::MipsGp->Section = OS;
- ElfSym::MipsGp->Value = 0x7ff0;
+ for (OutputSection *os : outputSections) {
+ if (os->flags & SHF_MIPS_GPREL) {
+ ElfSym::mipsGp->section = os;
+ ElfSym::mipsGp->value = 0x7ff0;
break;
}
}
@@ -1142,13 +1142,13 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
// The more branches in getSectionRank that match, the more similar they are.
// Since each branch corresponds to a bit flag, we can just use
// countLeadingZeros.
-static int getRankProximityAux(OutputSection *A, OutputSection *B) {
- return countLeadingZeros(A->SortRank ^ B->SortRank);
+static int getRankProximityAux(OutputSection *a, OutputSection *b) {
+ return countLeadingZeros(a->sortRank ^ b->sortRank);
}
-static int getRankProximity(OutputSection *A, BaseCommand *B) {
- auto *Sec = dyn_cast<OutputSection>(B);
- return (Sec && Sec->HasInputSections) ? getRankProximityAux(A, Sec) : -1;
+static int getRankProximity(OutputSection *a, BaseCommand *b) {
+ auto *sec = dyn_cast<OutputSection>(b);
+ return (sec && sec->hasInputSections) ? getRankProximityAux(a, sec) : -1;
}
// When placing orphan sections, we want to place them after symbol assignments
@@ -1165,9 +1165,9 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) {
// /* The RW PT_LOAD starts here*/
// rw_sec : { *(rw_sec) }
// would mean that the RW PT_LOAD would become unaligned.
-static bool shouldSkip(BaseCommand *Cmd) {
- if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
- return Assign->Name != ".";
+static bool shouldSkip(BaseCommand *cmd) {
+ if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
+ return assign->name != ".";
return false;
}
@@ -1175,132 +1175,132 @@ static bool shouldSkip(BaseCommand *Cmd) {
// characteristics with their neighbors as possible. For example, if
// both are rw, or both are tls.
static std::vector<BaseCommand *>::iterator
-findOrphanPos(std::vector<BaseCommand *>::iterator B,
- std::vector<BaseCommand *>::iterator E) {
- OutputSection *Sec = cast<OutputSection>(*E);
+findOrphanPos(std::vector<BaseCommand *>::iterator b,
+ std::vector<BaseCommand *>::iterator e) {
+ OutputSection *sec = cast<OutputSection>(*e);
// Find the first element that has as close a rank as possible.
- auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) {
- return getRankProximity(Sec, A) < getRankProximity(Sec, B);
+ auto i = std::max_element(b, e, [=](BaseCommand *a, BaseCommand *b) {
+ return getRankProximity(sec, a) < getRankProximity(sec, b);
});
- if (I == E)
- return E;
+ if (i == e)
+ return e;
// Consider all existing sections with the same proximity.
- int Proximity = getRankProximity(Sec, *I);
- for (; I != E; ++I) {
- auto *CurSec = dyn_cast<OutputSection>(*I);
- if (!CurSec || !CurSec->HasInputSections)
+ int proximity = getRankProximity(sec, *i);
+ for (; i != e; ++i) {
+ auto *curSec = dyn_cast<OutputSection>(*i);
+ if (!curSec || !curSec->hasInputSections)
continue;
- if (getRankProximity(Sec, CurSec) != Proximity ||
- Sec->SortRank < CurSec->SortRank)
+ if (getRankProximity(sec, curSec) != proximity ||
+ sec->sortRank < curSec->sortRank)
break;
}
- auto IsOutputSecWithInputSections = [](BaseCommand *Cmd) {
- auto *OS = dyn_cast<OutputSection>(Cmd);
- return OS && OS->HasInputSections;
+ auto isOutputSecWithInputSections = [](BaseCommand *cmd) {
+ auto *os = dyn_cast<OutputSection>(cmd);
+ return os && os->hasInputSections;
};
- auto J = std::find_if(llvm::make_reverse_iterator(I),
- llvm::make_reverse_iterator(B),
- IsOutputSecWithInputSections);
- I = J.base();
+ auto j = std::find_if(llvm::make_reverse_iterator(i),
+ llvm::make_reverse_iterator(b),
+ isOutputSecWithInputSections);
+ i = j.base();
// As a special case, if the orphan section is the last section, put
// it at the very end, past any other commands.
// This matches bfd's behavior and is convenient when the linker script fully
// specifies the start of the file, but doesn't care about the end (the non
// alloc sections for example).
- auto NextSec = std::find_if(I, E, IsOutputSecWithInputSections);
- if (NextSec == E)
- return E;
+ auto nextSec = std::find_if(i, e, isOutputSecWithInputSections);
+ if (nextSec == e)
+ return e;
- while (I != E && shouldSkip(*I))
- ++I;
- return I;
+ while (i != e && shouldSkip(*i))
+ ++i;
+ return i;
}
// Builds section order for handling --symbol-ordering-file.
static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
- DenseMap<const InputSectionBase *, int> SectionOrder;
+ DenseMap<const InputSectionBase *, int> sectionOrder;
// Use the rarely used option -call-graph-ordering-file to sort sections.
- if (!Config->CallGraphProfile.empty())
+ if (!config->callGraphProfile.empty())
return computeCallGraphProfileOrder();
- if (Config->SymbolOrderingFile.empty())
- return SectionOrder;
+ if (config->symbolOrderingFile.empty())
+ return sectionOrder;
struct SymbolOrderEntry {
- int Priority;
- bool Present;
+ int priority;
+ bool present;
};
// Build a map from symbols to their priorities. Symbols that didn't
// appear in the symbol ordering file have the lowest priority 0.
// All explicitly mentioned symbols have negative (higher) priorities.
- DenseMap<StringRef, SymbolOrderEntry> SymbolOrder;
- int Priority = -Config->SymbolOrderingFile.size();
- for (StringRef S : Config->SymbolOrderingFile)
- SymbolOrder.insert({S, {Priority++, false}});
+ DenseMap<StringRef, SymbolOrderEntry> symbolOrder;
+ int priority = -config->symbolOrderingFile.size();
+ for (StringRef s : config->symbolOrderingFile)
+ symbolOrder.insert({s, {priority++, false}});
// Build a map from sections to their priorities.
- auto AddSym = [&](Symbol &Sym) {
- auto It = SymbolOrder.find(Sym.getName());
- if (It == SymbolOrder.end())
+ auto addSym = [&](Symbol &sym) {
+ auto it = symbolOrder.find(sym.getName());
+ if (it == symbolOrder.end())
return;
- SymbolOrderEntry &Ent = It->second;
- Ent.Present = true;
+ SymbolOrderEntry &ent = it->second;
+ ent.present = true;
- maybeWarnUnorderableSymbol(&Sym);
+ maybeWarnUnorderableSymbol(&sym);
- if (auto *D = dyn_cast<Defined>(&Sym)) {
- if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
- int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)];
- Priority = std::min(Priority, Ent.Priority);
+ if (auto *d = dyn_cast<Defined>(&sym)) {
+ if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section)) {
+ int &priority = sectionOrder[cast<InputSectionBase>(sec->repl)];
+ priority = std::min(priority, ent.priority);
}
}
};
// We want both global and local symbols. We get the global ones from the
// symbol table and iterate the object files for the local ones.
- Symtab->forEachSymbol([&](Symbol *Sym) {
- if (!Sym->isLazy())
- AddSym(*Sym);
+ symtab->forEachSymbol([&](Symbol *sym) {
+ if (!sym->isLazy())
+ addSym(*sym);
});
- for (InputFile *File : ObjectFiles)
- for (Symbol *Sym : File->getSymbols())
- if (Sym->isLocal())
- AddSym(*Sym);
+ for (InputFile *file : objectFiles)
+ for (Symbol *sym : file->getSymbols())
+ if (sym->isLocal())
+ addSym(*sym);
- if (Config->WarnSymbolOrdering)
- for (auto OrderEntry : SymbolOrder)
- if (!OrderEntry.second.Present)
- warn("symbol ordering file: no such symbol: " + OrderEntry.first);
+ if (config->warnSymbolOrdering)
+ for (auto orderEntry : symbolOrder)
+ if (!orderEntry.second.present)
+ warn("symbol ordering file: no such symbol: " + orderEntry.first);
- return SectionOrder;
+ return sectionOrder;
}
// Sorts the sections in ISD according to the provided section order.
static void
-sortISDBySectionOrder(InputSectionDescription *ISD,
- const DenseMap<const InputSectionBase *, int> &Order) {
- std::vector<InputSection *> UnorderedSections;
- std::vector<std::pair<InputSection *, int>> OrderedSections;
- uint64_t UnorderedSize = 0;
-
- for (InputSection *IS : ISD->Sections) {
- auto I = Order.find(IS);
- if (I == Order.end()) {
- UnorderedSections.push_back(IS);
- UnorderedSize += IS->getSize();
+sortISDBySectionOrder(InputSectionDescription *isd,
+ const DenseMap<const InputSectionBase *, int> &order) {
+ std::vector<InputSection *> unorderedSections;
+ std::vector<std::pair<InputSection *, int>> orderedSections;
+ uint64_t unorderedSize = 0;
+
+ for (InputSection *isec : isd->sections) {
+ auto i = order.find(isec);
+ if (i == order.end()) {
+ unorderedSections.push_back(isec);
+ unorderedSize += isec->getSize();
continue;
}
- OrderedSections.push_back({IS, I->second});
+ orderedSections.push_back({isec, i->second});
}
- llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A,
- std::pair<InputSection *, int> B) {
- return A.second < B.second;
+ llvm::sort(orderedSections, [&](std::pair<InputSection *, int> a,
+ std::pair<InputSection *, int> b) {
+ return a.second < b.second;
});
// Find an insertion point for the ordered section list in the unordered
@@ -1330,46 +1330,46 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
// of the second block of cold code can call the hot code without a thunk. So
// we effectively double the amount of code that could potentially call into
// the hot code without a thunk.
- size_t InsPt = 0;
- if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
- uint64_t UnorderedPos = 0;
- for (; InsPt != UnorderedSections.size(); ++InsPt) {
- UnorderedPos += UnorderedSections[InsPt]->getSize();
- if (UnorderedPos > UnorderedSize / 2)
+ size_t insPt = 0;
+ if (target->getThunkSectionSpacing() && !orderedSections.empty()) {
+ uint64_t unorderedPos = 0;
+ for (; insPt != unorderedSections.size(); ++insPt) {
+ unorderedPos += unorderedSections[insPt]->getSize();
+ if (unorderedPos > unorderedSize / 2)
break;
}
}
- ISD->Sections.clear();
- for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt))
- ISD->Sections.push_back(IS);
- for (std::pair<InputSection *, int> P : OrderedSections)
- ISD->Sections.push_back(P.first);
- for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt))
- ISD->Sections.push_back(IS);
+ isd->sections.clear();
+ for (InputSection *isec : makeArrayRef(unorderedSections).slice(0, insPt))
+ isd->sections.push_back(isec);
+ for (std::pair<InputSection *, int> p : orderedSections)
+ isd->sections.push_back(p.first);
+ for (InputSection *isec : makeArrayRef(unorderedSections).slice(insPt))
+ isd->sections.push_back(isec);
}
-static void sortSection(OutputSection *Sec,
- const DenseMap<const InputSectionBase *, int> &Order) {
- StringRef Name = Sec->Name;
+static void sortSection(OutputSection *sec,
+ const DenseMap<const InputSectionBase *, int> &order) {
+ StringRef name = sec->name;
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
- if (Name == ".init_array" || Name == ".fini_array") {
- if (!Script->HasSectionsCommand)
- Sec->sortInitFini();
+ if (name == ".init_array" || name == ".fini_array") {
+ if (!script->hasSectionsCommand)
+ sec->sortInitFini();
return;
}
// Sort input sections by the special rule for .ctors and .dtors.
- if (Name == ".ctors" || Name == ".dtors") {
- if (!Script->HasSectionsCommand)
- Sec->sortCtorsDtors();
+ if (name == ".ctors" || name == ".dtors") {
+ if (!script->hasSectionsCommand)
+ sec->sortCtorsDtors();
return;
}
// Never sort these.
- if (Name == ".init" || Name == ".fini")
+ if (name == ".init" || name == ".fini")
return;
// .toc is allocated just after .got and is accessed using GOT-relative
@@ -1377,67 +1377,67 @@ static void sortSection(OutputSection *Sec,
// addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations.
// To reduce the risk of relocation overflow, .toc contents are sorted so that
// sections having smaller relocation offsets are at beginning of .toc
- if (Config->EMachine == EM_PPC64 && Name == ".toc") {
- if (Script->HasSectionsCommand)
+ if (config->emachine == EM_PPC64 && name == ".toc") {
+ if (script->hasSectionsCommand)
return;
- assert(Sec->SectionCommands.size() == 1);
- auto *ISD = cast<InputSectionDescription>(Sec->SectionCommands[0]);
- llvm::stable_sort(ISD->Sections,
- [](const InputSection *A, const InputSection *B) -> bool {
- return A->File->PPC64SmallCodeModelTocRelocs &&
- !B->File->PPC64SmallCodeModelTocRelocs;
+ assert(sec->sectionCommands.size() == 1);
+ auto *isd = cast<InputSectionDescription>(sec->sectionCommands[0]);
+ llvm::stable_sort(isd->sections,
+ [](const InputSection *a, const InputSection *b) -> bool {
+ return a->file->ppc64SmallCodeModelTocRelocs &&
+ !b->file->ppc64SmallCodeModelTocRelocs;
});
return;
}
// Sort input sections by priority using the list provided
// by --symbol-ordering-file.
- if (!Order.empty())
- for (BaseCommand *B : Sec->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- sortISDBySectionOrder(ISD, Order);
+ if (!order.empty())
+ for (BaseCommand *b : sec->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(b))
+ sortISDBySectionOrder(isd, order);
}
// If no layout was provided by linker script, we want to apply default
// sorting for special input sections. This also handles --symbol-ordering-file.
template <class ELFT> void Writer<ELFT>::sortInputSections() {
// Build the order once since it is expensive.
- DenseMap<const InputSectionBase *, int> Order = buildSectionOrder();
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- sortSection(Sec, Order);
+ DenseMap<const InputSectionBase *, int> order = buildSectionOrder();
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ sortSection(sec, order);
}
template <class ELFT> void Writer<ELFT>::sortSections() {
- Script->adjustSectionsBeforeSorting();
+ script->adjustSectionsBeforeSorting();
// Don't sort if using -r. It is not necessary and we want to preserve the
// relative order for SHF_LINK_ORDER sections.
- if (Config->Relocatable)
+ if (config->relocatable)
return;
sortInputSections();
- for (BaseCommand *Base : Script->SectionCommands) {
- auto *OS = dyn_cast<OutputSection>(Base);
- if (!OS)
+ for (BaseCommand *base : script->sectionCommands) {
+ auto *os = dyn_cast<OutputSection>(base);
+ if (!os)
continue;
- OS->SortRank = getSectionRank(OS);
+ os->sortRank = getSectionRank(os);
// We want to assign rude approximation values to OutSecOff fields
// to know the relative order of the input sections. We use it for
// sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
- uint64_t I = 0;
- for (InputSection *Sec : getInputSections(OS))
- Sec->OutSecOff = I++;
+ uint64_t i = 0;
+ for (InputSection *sec : getInputSections(os))
+ sec->outSecOff = i++;
}
- if (!Script->HasSectionsCommand) {
+ if (!script->hasSectionsCommand) {
// We know that all the OutputSections are contiguous in this case.
- auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
+ auto isSection = [](BaseCommand *base) { return isa<OutputSection>(base); };
std::stable_sort(
- llvm::find_if(Script->SectionCommands, IsSection),
- llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(),
+ llvm::find_if(script->sectionCommands, isSection),
+ llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(),
compareSections);
return;
}
@@ -1481,84 +1481,84 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
// after another commands. For the details, look at shouldSkip
// function.
- auto I = Script->SectionCommands.begin();
- auto E = Script->SectionCommands.end();
- auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- return Sec->SectionIndex == UINT32_MAX;
+ auto i = script->sectionCommands.begin();
+ auto e = script->sectionCommands.end();
+ auto nonScriptI = std::find_if(i, e, [](BaseCommand *base) {
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ return sec->sectionIndex == UINT32_MAX;
return false;
});
// Sort the orphan sections.
- std::stable_sort(NonScriptI, E, compareSections);
+ std::stable_sort(nonScriptI, e, compareSections);
// As a horrible special case, skip the first . assignment if it is before any
// section. We do this because it is common to set a load address by starting
// the script with ". = 0xabcd" and the expectation is that every section is
// after that.
- auto FirstSectionOrDotAssignment =
- std::find_if(I, E, [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
- if (FirstSectionOrDotAssignment != E &&
- isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
- ++FirstSectionOrDotAssignment;
- I = FirstSectionOrDotAssignment;
+ auto firstSectionOrDotAssignment =
+ std::find_if(i, e, [](BaseCommand *cmd) { return !shouldSkip(cmd); });
+ if (firstSectionOrDotAssignment != e &&
+ isa<SymbolAssignment>(**firstSectionOrDotAssignment))
+ ++firstSectionOrDotAssignment;
+ i = firstSectionOrDotAssignment;
- while (NonScriptI != E) {
- auto Pos = findOrphanPos(I, NonScriptI);
- OutputSection *Orphan = cast<OutputSection>(*NonScriptI);
+ while (nonScriptI != e) {
+ auto pos = findOrphanPos(i, nonScriptI);
+ OutputSection *orphan = cast<OutputSection>(*nonScriptI);
// As an optimization, find all sections with the same sort rank
// and insert them with one rotate.
- unsigned Rank = Orphan->SortRank;
- auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) {
- return cast<OutputSection>(Cmd)->SortRank != Rank;
+ unsigned rank = orphan->sortRank;
+ auto end = std::find_if(nonScriptI + 1, e, [=](BaseCommand *cmd) {
+ return cast<OutputSection>(cmd)->sortRank != rank;
});
- std::rotate(Pos, NonScriptI, End);
- NonScriptI = End;
+ std::rotate(pos, nonScriptI, end);
+ nonScriptI = end;
}
- Script->adjustSectionsAfterSorting();
+ script->adjustSectionsAfterSorting();
}
-static bool compareByFilePosition(InputSection *A, InputSection *B) {
- InputSection *LA = A->getLinkOrderDep();
- InputSection *LB = B->getLinkOrderDep();
- OutputSection *AOut = LA->getParent();
- OutputSection *BOut = LB->getParent();
+static bool compareByFilePosition(InputSection *a, InputSection *b) {
+ InputSection *la = a->getLinkOrderDep();
+ InputSection *lb = b->getLinkOrderDep();
+ OutputSection *aOut = la->getParent();
+ OutputSection *bOut = lb->getParent();
- if (AOut != BOut)
- return AOut->SectionIndex < BOut->SectionIndex;
- return LA->OutSecOff < LB->OutSecOff;
+ if (aOut != bOut)
+ return aOut->sectionIndex < bOut->sectionIndex;
+ return la->outSecOff < lb->outSecOff;
}
template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
- for (OutputSection *Sec : OutputSections) {
- if (!(Sec->Flags & SHF_LINK_ORDER))
+ for (OutputSection *sec : outputSections) {
+ if (!(sec->flags & SHF_LINK_ORDER))
continue;
// Link order may be distributed across several InputSectionDescriptions
// but sort must consider them all at once.
- std::vector<InputSection **> ScriptSections;
- std::vector<InputSection *> Sections;
- for (BaseCommand *Base : Sec->SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- for (InputSection *&IS : ISD->Sections) {
- ScriptSections.push_back(&IS);
- Sections.push_back(IS);
+ std::vector<InputSection **> scriptSections;
+ std::vector<InputSection *> sections;
+ for (BaseCommand *base : sec->sectionCommands) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
+ for (InputSection *&isec : isd->sections) {
+ scriptSections.push_back(&isec);
+ sections.push_back(isec);
}
}
}
// The ARM.exidx section use SHF_LINK_ORDER, but we have consolidated
// this processing inside the ARMExidxsyntheticsection::finalizeContents().
- if (!Config->Relocatable && Config->EMachine == EM_ARM &&
- Sec->Type == SHT_ARM_EXIDX)
+ if (!config->relocatable && config->emachine == EM_ARM &&
+ sec->type == SHT_ARM_EXIDX)
continue;
- llvm::stable_sort(Sections, compareByFilePosition);
+ llvm::stable_sort(sections, compareByFilePosition);
- for (int I = 0, N = Sections.size(); I < N; ++I)
- *ScriptSections[I] = Sections[I];
+ for (int i = 0, n = sections.size(); i < n; ++i)
+ *scriptSections[i] = sections[i];
}
}
@@ -1567,41 +1567,41 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
// addresses we must converge to a fixed point. We do that here. See the comment
// in Writer<ELFT>::finalizeSections().
template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
- ThunkCreator TC;
- AArch64Err843419Patcher A64P;
+ ThunkCreator tc;
+ AArch64Err843419Patcher a64p;
// For some targets, like x86, this loop iterates only once.
for (;;) {
- bool Changed = false;
+ bool changed = false;
- Script->assignAddresses();
+ script->assignAddresses();
- if (Target->NeedsThunks)
- Changed |= TC.createThunks(OutputSections);
+ if (target->needsThunks)
+ changed |= tc.createThunks(outputSections);
- if (Config->FixCortexA53Errata843419) {
- if (Changed)
- Script->assignAddresses();
- Changed |= A64P.createFixes();
+ if (config->fixCortexA53Errata843419) {
+ if (changed)
+ script->assignAddresses();
+ changed |= a64p.createFixes();
}
- if (In.MipsGot)
- In.MipsGot->updateAllocSize();
+ if (in.mipsGot)
+ in.mipsGot->updateAllocSize();
- for (Partition &Part : Partitions) {
- Changed |= Part.RelaDyn->updateAllocSize();
- if (Part.RelrDyn)
- Changed |= Part.RelrDyn->updateAllocSize();
+ for (Partition &part : partitions) {
+ changed |= part.relaDyn->updateAllocSize();
+ if (part.relrDyn)
+ changed |= part.relrDyn->updateAllocSize();
}
- if (!Changed)
+ if (!changed)
return;
}
}
-static void finalizeSynthetic(SyntheticSection *Sec) {
- if (Sec && Sec->isNeeded() && Sec->getParent())
- Sec->finalizeContents();
+static void finalizeSynthetic(SyntheticSection *sec) {
+ if (sec && sec->isNeeded() && sec->getParent())
+ sec->finalizeContents();
}
// In order to allow users to manipulate linker-synthesized sections,
@@ -1620,90 +1620,90 @@ static void removeUnusedSyntheticSections() {
// All input synthetic sections that can be empty are placed after
// all regular ones. We iterate over them all and exit at first
// non-synthetic.
- for (InputSectionBase *S : llvm::reverse(InputSections)) {
- SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
- if (!SS)
+ for (InputSectionBase *s : llvm::reverse(inputSections)) {
+ SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
+ if (!ss)
return;
- OutputSection *OS = SS->getParent();
- if (!OS || SS->isNeeded())
+ OutputSection *os = ss->getParent();
+ if (!os || ss->isNeeded())
continue;
// If we reach here, then SS is an unused synthetic section and we want to
// remove it from corresponding input section description of output section.
- for (BaseCommand *B : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- llvm::erase_if(ISD->Sections,
- [=](InputSection *IS) { return IS == SS; });
+ for (BaseCommand *b : os->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(b))
+ llvm::erase_if(isd->sections,
+ [=](InputSection *isec) { return isec == ss; });
}
}
// Returns true if a symbol can be replaced at load-time by a symbol
// with the same name defined in other ELF executable or DSO.
-static bool computeIsPreemptible(const Symbol &B) {
- assert(!B.isLocal());
+static bool computeIsPreemptible(const Symbol &b) {
+ assert(!b.isLocal());
// Only symbols that appear in dynsym can be preempted.
- if (!B.includeInDynsym())
+ if (!b.includeInDynsym())
return false;
// Only default visibility symbols can be preempted.
- if (B.Visibility != STV_DEFAULT)
+ if (b.visibility != STV_DEFAULT)
return false;
// At this point copy relocations have not been created yet, so any
// symbol that is not defined locally is preemptible.
- if (!B.isDefined())
+ if (!b.isDefined())
return true;
// If we have a dynamic list it specifies which local symbols are preemptible.
- if (Config->HasDynamicList)
+ if (config->hasDynamicList)
return false;
- if (!Config->Shared)
+ if (!config->shared)
return false;
// -Bsymbolic means that definitions are not preempted.
- if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc()))
+ if (config->bsymbolic || (config->bsymbolicFunctions && b.isFunc()))
return false;
return true;
}
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
- Out::PreinitArray = findSection(".preinit_array");
- Out::InitArray = findSection(".init_array");
- Out::FiniArray = findSection(".fini_array");
+ Out::preinitArray = findSection(".preinit_array");
+ Out::initArray = findSection(".init_array");
+ Out::finiArray = findSection(".fini_array");
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
// symbols for sections, so that the runtime can get the start and end
// addresses of each section by section name. Add such symbols.
- if (!Config->Relocatable) {
+ if (!config->relocatable) {
addStartEndSymbols();
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- addStartStopSymbols(Sec);
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ addStartStopSymbols(sec);
}
// Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type.
// It should be okay as no one seems to care about the type.
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
- if (Main->Dynamic->Parent)
- Symtab->addSymbol(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
+ if (mainPart->dynamic->parent)
+ symtab->addSymbol(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
STV_HIDDEN, STT_NOTYPE,
- /*Value=*/0, /*Size=*/0, Main->Dynamic});
+ /*Value=*/0, /*Size=*/0, mainPart->dynamic});
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
// RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined.
// This symbol should only be defined in an executable.
- if (Config->EMachine == EM_RISCV && !Config->Shared)
- ElfSym::RISCVGlobalPointer =
+ if (config->emachine == EM_RISCV && !config->shared)
+ ElfSym::riscvGlobalPointer =
addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800,
STV_DEFAULT, STB_GLOBAL);
- if (Config->EMachine == EM_X86_64) {
+ if (config->emachine == EM_X86_64) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
// way that:
//
@@ -1715,41 +1715,41 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// 2) is special cased in @tpoff computation. To satisfy 1), we define it as
// an absolute symbol of zero. This is different from GNU linkers which
// define _TLS_MODULE_BASE_ relative to the first TLS section.
- Symbol *S = Symtab->find("_TLS_MODULE_BASE_");
- if (S && S->isUndefined()) {
- S->resolve(Defined{/*File=*/nullptr, S->getName(), STB_GLOBAL, STV_HIDDEN,
+ Symbol *s = symtab->find("_TLS_MODULE_BASE_");
+ if (s && s->isUndefined()) {
+ s->resolve(Defined{/*File=*/nullptr, s->getName(), STB_GLOBAL, STV_HIDDEN,
STT_TLS, /*Value=*/0, 0,
/*Section=*/nullptr});
- ElfSym::TlsModuleBase = cast<Defined>(S);
+ ElfSym::tlsModuleBase = cast<Defined>(s);
}
}
// This responsible for splitting up .eh_frame section into
// pieces. The relocation scan uses those pieces, so this has to be
// earlier.
- for (Partition &Part : Partitions)
- finalizeSynthetic(Part.EhFrame);
+ for (Partition &part : partitions)
+ finalizeSynthetic(part.ehFrame);
- Symtab->forEachSymbol([](Symbol *S) {
- if (!S->IsPreemptible)
- S->IsPreemptible = computeIsPreemptible(*S);
+ symtab->forEachSymbol([](Symbol *s) {
+ if (!s->isPreemptible)
+ s->isPreemptible = computeIsPreemptible(*s);
});
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
- if (!Config->Relocatable) {
+ if (!config->relocatable) {
forEachRelSec(scanRelocations<ELFT>);
reportUndefinedSymbols<ELFT>();
}
addIRelativeRelocs();
- if (In.Plt && In.Plt->isNeeded())
- In.Plt->addSymbols();
- if (In.Iplt && In.Iplt->isNeeded())
- In.Iplt->addSymbols();
+ if (in.plt && in.plt->isNeeded())
+ in.plt->addSymbols();
+ if (in.iplt && in.iplt->isNeeded())
+ in.iplt->addSymbols();
- if (!Config->AllowShlibUndefined) {
+ if (!config->allowShlibUndefined) {
// Error on undefined symbols in a shared object, if all of its DT_NEEDED
// entires are seen. These cases would otherwise lead to runtime errors
// reported by the dynamic linker.
@@ -1757,53 +1757,53 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
// catch more cases. That is too much for us. Our approach resembles the one
// used in ld.gold, achieves a good balance to be useful but not too smart.
- for (SharedFile *File : SharedFiles)
- File->AllNeededIsKnown =
- llvm::all_of(File->DtNeeded, [&](StringRef Needed) {
- return Symtab->SoNames.count(Needed);
+ for (SharedFile *file : sharedFiles)
+ file->allNeededIsKnown =
+ llvm::all_of(file->dtNeeded, [&](StringRef needed) {
+ return symtab->soNames.count(needed);
});
- Symtab->forEachSymbol([](Symbol *Sym) {
- if (Sym->isUndefined() && !Sym->isWeak())
- if (auto *F = dyn_cast_or_null<SharedFile>(Sym->File))
- if (F->AllNeededIsKnown)
- error(toString(F) + ": undefined reference to " + toString(*Sym));
+ symtab->forEachSymbol([](Symbol *sym) {
+ if (sym->isUndefined() && !sym->isWeak())
+ if (auto *f = dyn_cast_or_null<SharedFile>(sym->file))
+ if (f->allNeededIsKnown)
+ error(toString(f) + ": undefined reference to " + toString(*sym));
});
}
// Now that we have defined all possible global symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
- Symtab->forEachSymbol([](Symbol *Sym) {
- if (!includeInSymtab(*Sym))
+ symtab->forEachSymbol([](Symbol *sym) {
+ if (!includeInSymtab(*sym))
return;
- if (In.SymTab)
- In.SymTab->addSymbol(Sym);
-
- if (Sym->includeInDynsym()) {
- Partitions[Sym->Partition - 1].DynSymTab->addSymbol(Sym);
- if (auto *File = dyn_cast_or_null<SharedFile>(Sym->File))
- if (File->IsNeeded && !Sym->isUndefined())
- addVerneed(Sym);
+ if (in.symTab)
+ in.symTab->addSymbol(sym);
+
+ if (sym->includeInDynsym()) {
+ partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
+ if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
+ if (file->isNeeded && !sym->isUndefined())
+ addVerneed(sym);
}
});
// We also need to scan the dynamic relocation tables of the other partitions
// and add any referenced symbols to the partition's dynsym.
- for (Partition &Part : MutableArrayRef<Partition>(Partitions).slice(1)) {
- DenseSet<Symbol *> Syms;
- for (const SymbolTableEntry &E : Part.DynSymTab->getSymbols())
- Syms.insert(E.Sym);
- for (DynamicReloc &Reloc : Part.RelaDyn->Relocs)
- if (Reloc.Sym && !Reloc.UseSymVA && Syms.insert(Reloc.Sym).second)
- Part.DynSymTab->addSymbol(Reloc.Sym);
+ for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
+ DenseSet<Symbol *> syms;
+ for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
+ syms.insert(e.sym);
+ for (DynamicReloc &reloc : part.relaDyn->relocs)
+ if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
+ part.dynSymTab->addSymbol(reloc.sym);
}
// Do not proceed if there was an undefined symbol.
if (errorCount())
return;
- if (In.MipsGot)
- In.MipsGot->build();
+ if (in.mipsGot)
+ in.mipsGot->build();
removeUnusedSyntheticSections();
@@ -1811,95 +1811,95 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Now that we have the final list, create a list of all the
// OutputSections for convenience.
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- OutputSections.push_back(Sec);
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ outputSections.push_back(sec);
// Prefer command line supplied address over other constraints.
- for (OutputSection *Sec : OutputSections) {
- auto I = Config->SectionStartMap.find(Sec->Name);
- if (I != Config->SectionStartMap.end())
- Sec->AddrExpr = [=] { return I->second; };
+ for (OutputSection *sec : outputSections) {
+ auto i = config->sectionStartMap.find(sec->name);
+ if (i != config->sectionStartMap.end())
+ sec->addrExpr = [=] { return i->second; };
}
// This is a bit of a hack. A value of 0 means undef, so we set it
// to 1 to make __ehdr_start defined. The section number is not
// particularly relevant.
- Out::ElfHeader->SectionIndex = 1;
+ Out::elfHeader->sectionIndex = 1;
- for (size_t I = 0, E = OutputSections.size(); I != E; ++I) {
- OutputSection *Sec = OutputSections[I];
- Sec->SectionIndex = I + 1;
- Sec->ShName = In.ShStrTab->addString(Sec->Name);
+ for (size_t i = 0, e = outputSections.size(); i != e; ++i) {
+ OutputSection *sec = outputSections[i];
+ sec->sectionIndex = i + 1;
+ sec->shName = in.shStrTab->addString(sec->name);
}
// Binary and relocatable output does not have PHDRS.
// The headers have to be created before finalize as that can influence the
// image base and the dynamic section on mips includes the image base.
- if (!Config->Relocatable && !Config->OFormatBinary) {
- for (Partition &Part : Partitions) {
- Part.Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs()
- : createPhdrs(Part);
- if (Config->EMachine == EM_ARM) {
+ if (!config->relocatable && !config->oFormatBinary) {
+ for (Partition &part : partitions) {
+ part.phdrs = script->hasPhdrsCommands() ? script->createPhdrs()
+ : createPhdrs(part);
+ if (config->emachine == EM_ARM) {
// PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
- addPhdrForSection(Part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
+ addPhdrForSection(part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// Add separate segments for MIPS-specific sections.
- addPhdrForSection(Part, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R);
- addPhdrForSection(Part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
- addPhdrForSection(Part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
+ addPhdrForSection(part, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R);
+ addPhdrForSection(part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
+ addPhdrForSection(part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
}
}
- Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Main->Phdrs.size();
+ Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
// Find the TLS segment. This happens before the section layout loop so that
// Android relocation packing can look up TLS symbol addresses. We only need
// to care about the main partition here because all TLS symbols were moved
// to the main partition (see MarkLive.cpp).
- for (PhdrEntry *P : Main->Phdrs)
- if (P->p_type == PT_TLS)
- Out::TlsPhdr = P;
+ for (PhdrEntry *p : mainPart->phdrs)
+ if (p->p_type == PT_TLS)
+ Out::tlsPhdr = p;
}
// Some symbols are defined in term of program headers. Now that we
// have the headers, we can find out which sections they point to.
setReservedSymbolSections();
- finalizeSynthetic(In.Bss);
- finalizeSynthetic(In.BssRelRo);
- finalizeSynthetic(In.SymTabShndx);
- finalizeSynthetic(In.ShStrTab);
- finalizeSynthetic(In.StrTab);
- finalizeSynthetic(In.Got);
- finalizeSynthetic(In.MipsGot);
- finalizeSynthetic(In.IgotPlt);
- finalizeSynthetic(In.GotPlt);
- finalizeSynthetic(In.RelaIplt);
- finalizeSynthetic(In.RelaPlt);
- finalizeSynthetic(In.Plt);
- finalizeSynthetic(In.Iplt);
- finalizeSynthetic(In.PPC32Got2);
- finalizeSynthetic(In.RISCVSdata);
- finalizeSynthetic(In.PartIndex);
+ finalizeSynthetic(in.bss);
+ finalizeSynthetic(in.bssRelRo);
+ finalizeSynthetic(in.symTabShndx);
+ finalizeSynthetic(in.shStrTab);
+ finalizeSynthetic(in.strTab);
+ finalizeSynthetic(in.got);
+ finalizeSynthetic(in.mipsGot);
+ finalizeSynthetic(in.igotPlt);
+ finalizeSynthetic(in.gotPlt);
+ finalizeSynthetic(in.relaIplt);
+ finalizeSynthetic(in.relaPlt);
+ finalizeSynthetic(in.plt);
+ finalizeSynthetic(in.iplt);
+ finalizeSynthetic(in.ppc32Got2);
+ finalizeSynthetic(in.riscvSdata);
+ finalizeSynthetic(in.partIndex);
// Dynamic section must be the last one in this list and dynamic
// symbol table section (DynSymTab) must be the first one.
- for (Partition &Part : Partitions) {
- finalizeSynthetic(Part.ARMExidx);
- finalizeSynthetic(Part.DynSymTab);
- finalizeSynthetic(Part.GnuHashTab);
- finalizeSynthetic(Part.HashTab);
- finalizeSynthetic(Part.VerDef);
- finalizeSynthetic(Part.RelaDyn);
- finalizeSynthetic(Part.RelrDyn);
- finalizeSynthetic(Part.EhFrameHdr);
- finalizeSynthetic(Part.VerSym);
- finalizeSynthetic(Part.VerNeed);
- finalizeSynthetic(Part.Dynamic);
- }
-
- if (!Script->HasSectionsCommand && !Config->Relocatable)
+ for (Partition &part : partitions) {
+ finalizeSynthetic(part.armExidx);
+ finalizeSynthetic(part.dynSymTab);
+ finalizeSynthetic(part.gnuHashTab);
+ finalizeSynthetic(part.hashTab);
+ finalizeSynthetic(part.verDef);
+ finalizeSynthetic(part.relaDyn);
+ finalizeSynthetic(part.relrDyn);
+ finalizeSynthetic(part.ehFrameHdr);
+ finalizeSynthetic(part.verSym);
+ finalizeSynthetic(part.verNeed);
+ finalizeSynthetic(part.dynamic);
+ }
+
+ if (!script->hasSectionsCommand && !config->relocatable)
fixSectionAlignments();
// SHFLinkOrder processing must be processed after relative section placements are
@@ -1930,28 +1930,28 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
finalizeAddressDependentContent();
// finalizeAddressDependentContent may have added local symbols to the static symbol table.
- finalizeSynthetic(In.SymTab);
- finalizeSynthetic(In.PPC64LongBranchTarget);
+ finalizeSynthetic(in.symTab);
+ finalizeSynthetic(in.ppc64LongBranchTarget);
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
- for (OutputSection *Sec : OutputSections)
- Sec->finalize();
+ for (OutputSection *sec : outputSections)
+ sec->finalize();
}
// Ensure data sections are not mixed with executable sections when
// -execute-only is used. -execute-only is a feature to make pages executable
// but not readable, and the feature is currently supported only on AArch64.
template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
- if (!Config->ExecuteOnly)
+ if (!config->executeOnly)
return;
- for (OutputSection *OS : OutputSections)
- if (OS->Flags & SHF_EXECINSTR)
- for (InputSection *IS : getInputSections(OS))
- if (!(IS->Flags & SHF_EXECINSTR))
- error("cannot place " + toString(IS) + " into " + toString(OS->Name) +
+ for (OutputSection *os : outputSections)
+ if (os->flags & SHF_EXECINSTR)
+ for (InputSection *isec : getInputSections(os))
+ if (!(isec->flags & SHF_EXECINSTR))
+ error("cannot place " + toString(isec) + " into " + toString(os->name) +
": -execute-only does not support intermingling data and code");
}
@@ -1976,24 +1976,24 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
// case, use the image base address as a last resort.
OutputSection *Default = findSection(".text");
if (!Default)
- Default = Out::ElfHeader;
+ Default = Out::elfHeader;
- auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
- if (OS) {
- addOptionalRegular(Start, OS, 0);
- addOptionalRegular(End, OS, -1);
+ auto define = [=](StringRef start, StringRef end, OutputSection *os) {
+ if (os) {
+ addOptionalRegular(start, os, 0);
+ addOptionalRegular(end, os, -1);
} else {
- addOptionalRegular(Start, Default, 0);
- addOptionalRegular(End, Default, 0);
+ addOptionalRegular(start, Default, 0);
+ addOptionalRegular(end, Default, 0);
}
};
- Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
- Define("__init_array_start", "__init_array_end", Out::InitArray);
- Define("__fini_array_start", "__fini_array_end", Out::FiniArray);
+ define("__preinit_array_start", "__preinit_array_end", Out::preinitArray);
+ define("__init_array_start", "__init_array_end", Out::initArray);
+ define("__fini_array_start", "__fini_array_end", Out::finiArray);
- if (OutputSection *Sec = findSection(".ARM.exidx"))
- Define("__exidx_start", "__exidx_end", Sec);
+ if (OutputSection *sec = findSection(".ARM.exidx"))
+ define("__exidx_start", "__exidx_end", sec);
}
// If a section name is valid as a C identifier (which is rare because of
@@ -2002,22 +2002,22 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
// respectively. This is not requested by the ELF standard, but GNU ld and
// gold provide the feature, and used by many programs.
template <class ELFT>
-void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
- StringRef S = Sec->Name;
- if (!isValidCIdentifier(S))
+void Writer<ELFT>::addStartStopSymbols(OutputSection *sec) {
+ StringRef s = sec->name;
+ if (!isValidCIdentifier(s))
return;
- addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_PROTECTED);
- addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_PROTECTED);
+ addOptionalRegular(Saver.save("__start_" + s), sec, 0, STV_PROTECTED);
+ addOptionalRegular(Saver.save("__stop_" + s), sec, -1, STV_PROTECTED);
}
-static bool needsPtLoad(OutputSection *Sec) {
- if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload)
+static bool needsPtLoad(OutputSection *sec) {
+ if (!(sec->flags & SHF_ALLOC) || sec->noload)
return false;
// Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
// responsible for allocating space for them, not the PT_LOAD that
// contains the TLS initialization image.
- if ((Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS)
+ if ((sec->flags & SHF_TLS) && sec->type == SHT_NOBITS)
return false;
return true;
}
@@ -2026,79 +2026,79 @@ static bool needsPtLoad(OutputSection *Sec) {
// linker scripts are designed for creating two PT_LOADs only, one RX and one
// RW. This means that there is no alignment in the RO to RX transition and we
// cannot create a PT_LOAD there.
-static uint64_t computeFlags(uint64_t Flags) {
- if (Config->Omagic)
+static uint64_t computeFlags(uint64_t flags) {
+ if (config->omagic)
return PF_R | PF_W | PF_X;
- if (Config->ExecuteOnly && (Flags & PF_X))
- return Flags & ~PF_R;
- if (Config->SingleRoRx && !(Flags & PF_W))
- return Flags | PF_X;
- return Flags;
+ if (config->executeOnly && (flags & PF_X))
+ return flags & ~PF_R;
+ if (config->singleRoRx && !(flags & PF_W))
+ return flags | PF_X;
+ return flags;
}
// Decide which program headers to create and which sections to include in each
// one.
template <class ELFT>
-std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &Part) {
- std::vector<PhdrEntry *> Ret;
- auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * {
- Ret.push_back(make<PhdrEntry>(Type, Flags));
- return Ret.back();
+std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
+ std::vector<PhdrEntry *> ret;
+ auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
+ ret.push_back(make<PhdrEntry>(type, flags));
+ return ret.back();
};
- unsigned PartNo = Part.getNumber();
- bool IsMain = PartNo == 1;
+ unsigned partNo = part.getNumber();
+ bool isMain = partNo == 1;
// The first phdr entry is PT_PHDR which describes the program header itself.
- if (IsMain)
- AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders);
+ if (isMain)
+ addHdr(PT_PHDR, PF_R)->add(Out::programHeaders);
else
- AddHdr(PT_PHDR, PF_R)->add(Part.ProgramHeaders->getParent());
+ addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
// PT_INTERP must be the second entry if exists.
- if (OutputSection *Cmd = findSection(".interp", PartNo))
- AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd);
+ if (OutputSection *cmd = findSection(".interp", partNo))
+ addHdr(PT_INTERP, cmd->getPhdrFlags())->add(cmd);
// Add the first PT_LOAD segment for regular output sections.
- uint64_t Flags = computeFlags(PF_R);
- PhdrEntry *Load = nullptr;
+ uint64_t flags = computeFlags(PF_R);
+ PhdrEntry *load = nullptr;
// Add the headers. We will remove them if they don't fit.
// In the other partitions the headers are ordinary sections, so they don't
// need to be added here.
- if (IsMain) {
- Load = AddHdr(PT_LOAD, Flags);
- Load->add(Out::ElfHeader);
- Load->add(Out::ProgramHeaders);
+ if (isMain) {
+ load = addHdr(PT_LOAD, flags);
+ load->add(Out::elfHeader);
+ load->add(Out::programHeaders);
}
// PT_GNU_RELRO includes all sections that should be marked as
// read-only by dynamic linker after proccessing relocations.
// Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
// an error message if more than one PT_GNU_RELRO PHDR is required.
- PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
- bool InRelroPhdr = false;
- OutputSection *RelroEnd = nullptr;
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Partition != PartNo || !needsPtLoad(Sec))
+ PhdrEntry *relRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
+ bool inRelroPhdr = false;
+ OutputSection *relroEnd = nullptr;
+ for (OutputSection *sec : outputSections) {
+ if (sec->partition != partNo || !needsPtLoad(sec))
continue;
- if (isRelroSection(Sec)) {
- InRelroPhdr = true;
- if (!RelroEnd)
- RelRo->add(Sec);
+ if (isRelroSection(sec)) {
+ inRelroPhdr = true;
+ if (!relroEnd)
+ relRo->add(sec);
else
- error("section: " + Sec->Name + " is not contiguous with other relro" +
+ error("section: " + sec->name + " is not contiguous with other relro" +
" sections");
- } else if (InRelroPhdr) {
- InRelroPhdr = false;
- RelroEnd = Sec;
+ } else if (inRelroPhdr) {
+ inRelroPhdr = false;
+ relroEnd = sec;
}
}
- for (OutputSection *Sec : OutputSections) {
- if (!(Sec->Flags & SHF_ALLOC))
+ for (OutputSection *sec : outputSections) {
+ if (!(sec->flags & SHF_ALLOC))
break;
- if (!needsPtLoad(Sec))
+ if (!needsPtLoad(sec))
continue;
// Normally, sections in partitions other than the current partition are
@@ -2107,9 +2107,9 @@ std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &Part) {
// partition so that a segment is created for it in the main partition,
// which will cause the dynamic loader to reserve space for the other
// partitions.
- if (Sec->Partition != PartNo) {
- if (IsMain && Sec->Partition == 255)
- AddHdr(PT_LOAD, computeFlags(Sec->getPhdrFlags()))->add(Sec);
+ if (sec->partition != partNo) {
+ if (isMain && sec->partition == 255)
+ addHdr(PT_LOAD, computeFlags(sec->getPhdrFlags()))->add(sec);
continue;
}
@@ -2120,127 +2120,127 @@ std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &Part) {
// region using AT or AT> linker script command, respectively. At the same
// time, we don't want to create a separate load segment for the headers,
// even if the first output section has an AT or AT> attribute.
- uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
- if (!Load ||
- ((Sec->LMAExpr ||
- (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) &&
- Load->LastSec != Out::ProgramHeaders) ||
- Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags ||
- Sec == RelroEnd) {
- Load = AddHdr(PT_LOAD, NewFlags);
- Flags = NewFlags;
+ uint64_t newFlags = computeFlags(sec->getPhdrFlags());
+ if (!load ||
+ ((sec->lmaExpr ||
+ (sec->lmaRegion && (sec->lmaRegion != load->firstSec->lmaRegion))) &&
+ load->lastSec != Out::programHeaders) ||
+ sec->memRegion != load->firstSec->memRegion || flags != newFlags ||
+ sec == relroEnd) {
+ load = addHdr(PT_LOAD, newFlags);
+ flags = newFlags;
}
- Load->add(Sec);
+ load->add(sec);
}
// Add a TLS segment if any.
- PhdrEntry *TlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
- for (OutputSection *Sec : OutputSections)
- if (Sec->Partition == PartNo && Sec->Flags & SHF_TLS)
- TlsHdr->add(Sec);
- if (TlsHdr->FirstSec)
- Ret.push_back(TlsHdr);
+ PhdrEntry *tlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
+ for (OutputSection *sec : outputSections)
+ if (sec->partition == partNo && sec->flags & SHF_TLS)
+ tlsHdr->add(sec);
+ if (tlsHdr->firstSec)
+ ret.push_back(tlsHdr);
// Add an entry for .dynamic.
- if (OutputSection *Sec = Part.Dynamic->getParent())
- AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
+ if (OutputSection *sec = part.dynamic->getParent())
+ addHdr(PT_DYNAMIC, sec->getPhdrFlags())->add(sec);
- if (RelRo->FirstSec)
- Ret.push_back(RelRo);
+ if (relRo->firstSec)
+ ret.push_back(relRo);
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
- if (Part.EhFrame->isNeeded() && Part.EhFrameHdr &&
- Part.EhFrame->getParent() && Part.EhFrameHdr->getParent())
- AddHdr(PT_GNU_EH_FRAME, Part.EhFrameHdr->getParent()->getPhdrFlags())
- ->add(Part.EhFrameHdr->getParent());
+ if (part.ehFrame->isNeeded() && part.ehFrameHdr &&
+ part.ehFrame->getParent() && part.ehFrameHdr->getParent())
+ addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
+ ->add(part.ehFrameHdr->getParent());
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
- if (OutputSection *Cmd = findSection(".openbsd.randomdata", PartNo))
- AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd);
+ if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
+ addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
// PT_GNU_STACK is a special section to tell the loader to make the
// pages for the stack non-executable. If you really want an executable
// stack, you can pass -z execstack, but that's not recommended for
// security reasons.
- unsigned Perm = PF_R | PF_W;
- if (Config->ZExecstack)
- Perm |= PF_X;
- AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
+ unsigned perm = PF_R | PF_W;
+ if (config->zExecstack)
+ perm |= PF_X;
+ addHdr(PT_GNU_STACK, perm)->p_memsz = config->zStackSize;
// PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
// is expected to perform W^X violations, such as calling mprotect(2) or
// mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
// OpenBSD.
- if (Config->ZWxneeded)
- AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
+ if (config->zWxneeded)
+ addHdr(PT_OPENBSD_WXNEEDED, PF_X);
// Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the
// same alignment.
- PhdrEntry *Note = nullptr;
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Partition != PartNo)
+ PhdrEntry *note = nullptr;
+ for (OutputSection *sec : outputSections) {
+ if (sec->partition != partNo)
continue;
- if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
- if (!Note || Sec->LMAExpr || Note->LastSec->Alignment != Sec->Alignment)
- Note = AddHdr(PT_NOTE, PF_R);
- Note->add(Sec);
+ if (sec->type == SHT_NOTE && (sec->flags & SHF_ALLOC)) {
+ if (!note || sec->lmaExpr || note->lastSec->alignment != sec->alignment)
+ note = addHdr(PT_NOTE, PF_R);
+ note->add(sec);
} else {
- Note = nullptr;
+ note = nullptr;
}
}
- return Ret;
+ return ret;
}
template <class ELFT>
-void Writer<ELFT>::addPhdrForSection(Partition &Part, unsigned ShType,
- unsigned PType, unsigned PFlags) {
- unsigned PartNo = Part.getNumber();
- auto I = llvm::find_if(OutputSections, [=](OutputSection *Cmd) {
- return Cmd->Partition == PartNo && Cmd->Type == ShType;
+void Writer<ELFT>::addPhdrForSection(Partition &part, unsigned shType,
+ unsigned pType, unsigned pFlags) {
+ unsigned partNo = part.getNumber();
+ auto i = llvm::find_if(outputSections, [=](OutputSection *cmd) {
+ return cmd->partition == partNo && cmd->type == shType;
});
- if (I == OutputSections.end())
+ if (i == outputSections.end())
return;
- PhdrEntry *Entry = make<PhdrEntry>(PType, PFlags);
- Entry->add(*I);
- Part.Phdrs.push_back(Entry);
+ PhdrEntry *entry = make<PhdrEntry>(pType, pFlags);
+ entry->add(*i);
+ part.phdrs.push_back(entry);
}
// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
// linker can set the permissions.
template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
- auto PageAlign = [](OutputSection *Cmd) {
- if (Cmd && !Cmd->AddrExpr)
- Cmd->AddrExpr = [=] {
- return alignTo(Script->getDot(), Config->MaxPageSize);
+ auto pageAlign = [](OutputSection *cmd) {
+ if (cmd && !cmd->addrExpr)
+ cmd->addrExpr = [=] {
+ return alignTo(script->getDot(), config->maxPageSize);
};
};
- for (Partition &Part : Partitions) {
- for (const PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && P->FirstSec)
- PageAlign(P->FirstSec);
+ for (Partition &part : partitions) {
+ for (const PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && p->firstSec)
+ pageAlign(p->firstSec);
- for (const PhdrEntry *P : Part.Phdrs) {
- if (P->p_type != PT_GNU_RELRO)
+ for (const PhdrEntry *p : part.phdrs) {
+ if (p->p_type != PT_GNU_RELRO)
continue;
- if (P->FirstSec)
- PageAlign(P->FirstSec);
+ if (p->firstSec)
+ pageAlign(p->firstSec);
// Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
// have to align it to a page.
- auto End = OutputSections.end();
- auto I = llvm::find(OutputSections, P->LastSec);
- if (I == End || (I + 1) == End)
+ auto end = outputSections.end();
+ auto i = llvm::find(outputSections, p->lastSec);
+ if (i == end || (i + 1) == end)
continue;
- OutputSection *Cmd = (*(I + 1));
- if (needsPtLoad(Cmd))
- PageAlign(Cmd);
+ OutputSection *cmd = (*(i + 1));
+ if (needsPtLoad(cmd))
+ pageAlign(cmd);
}
}
}
@@ -2248,78 +2248,78 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
// Compute an in-file position for a given section. The file offset must be the
// same with its virtual address modulo the page size, so that the loader can
// load executables without any address adjustment.
-static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) {
+static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
// File offsets are not significant for .bss sections. By convention, we keep
// section offsets monotonically increasing rather than setting to zero.
- if (OS->Type == SHT_NOBITS)
- return Off;
+ if (os->type == SHT_NOBITS)
+ return off;
// If the section is not in a PT_LOAD, we just have to align it.
- if (!OS->PtLoad)
- return alignTo(Off, OS->Alignment);
+ if (!os->ptLoad)
+ return alignTo(off, os->alignment);
// The first section in a PT_LOAD has to have congruent offset and address
// module the page size.
- OutputSection *First = OS->PtLoad->FirstSec;
- if (OS == First) {
- uint64_t Alignment = std::max<uint64_t>(OS->Alignment, Config->MaxPageSize);
- return alignTo(Off, Alignment, OS->Addr);
+ OutputSection *first = os->ptLoad->firstSec;
+ if (os == first) {
+ uint64_t alignment = std::max<uint64_t>(os->alignment, config->maxPageSize);
+ return alignTo(off, alignment, os->addr);
}
// If two sections share the same PT_LOAD the file offset is calculated
// using this formula: Off2 = Off1 + (VA2 - VA1).
- return First->Offset + OS->Addr - First->Addr;
+ return first->offset + os->addr - first->addr;
}
// Set an in-file position to a given section and returns the end position of
// the section.
-static uint64_t setFileOffset(OutputSection *OS, uint64_t Off) {
- Off = computeFileOffset(OS, Off);
- OS->Offset = Off;
+static uint64_t setFileOffset(OutputSection *os, uint64_t off) {
+ off = computeFileOffset(os, off);
+ os->offset = off;
- if (OS->Type == SHT_NOBITS)
- return Off;
- return Off + OS->Size;
+ if (os->type == SHT_NOBITS)
+ return off;
+ return off + os->size;
}
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
- uint64_t Off = 0;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Flags & SHF_ALLOC)
- Off = setFileOffset(Sec, Off);
- FileSize = alignTo(Off, Config->Wordsize);
+ uint64_t off = 0;
+ for (OutputSection *sec : outputSections)
+ if (sec->flags & SHF_ALLOC)
+ off = setFileOffset(sec, off);
+ fileSize = alignTo(off, config->wordsize);
}
-static std::string rangeToString(uint64_t Addr, uint64_t Len) {
- return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
+static std::string rangeToString(uint64_t addr, uint64_t len) {
+ return "[0x" + utohexstr(addr) + ", 0x" + utohexstr(addr + len - 1) + "]";
}
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
- uint64_t Off = 0;
- Off = setFileOffset(Out::ElfHeader, Off);
- Off = setFileOffset(Out::ProgramHeaders, Off);
-
- PhdrEntry *LastRX = nullptr;
- for (Partition &Part : Partitions)
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
- LastRX = P;
-
- for (OutputSection *Sec : OutputSections) {
- Off = setFileOffset(Sec, Off);
- if (Script->HasSectionsCommand)
+ uint64_t off = 0;
+ off = setFileOffset(Out::elfHeader, off);
+ off = setFileOffset(Out::programHeaders, off);
+
+ PhdrEntry *lastRX = nullptr;
+ for (Partition &part : partitions)
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
+ lastRX = p;
+
+ for (OutputSection *sec : outputSections) {
+ off = setFileOffset(sec, off);
+ if (script->hasSectionsCommand)
continue;
// If this is a last section of the last executable segment and that
// segment is the last loadable segment, align the offset of the
// following section to avoid loading non-segments parts of the file.
- if (LastRX && LastRX->LastSec == Sec)
- Off = alignTo(Off, Config->CommonPageSize);
+ if (lastRX && lastRX->lastSec == sec)
+ off = alignTo(off, config->commonPageSize);
}
- SectionHeaderOff = alignTo(Off, Config->Wordsize);
- FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
+ sectionHeaderOff = alignTo(off, config->wordsize);
+ fileSize = sectionHeaderOff + (outputSections.size() + 1) * sizeof(Elf_Shdr);
// Our logic assumes that sections have rising VA within the same segment.
// With use of linker scripts it is possible to violate this rule and get file
@@ -2330,49 +2330,49 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
// backwards, so we have to allow doing that to support linking them. We
// perform non-critical checks for overlaps in checkSectionOverlap(), but here
// we want to prevent file size overflows because it would crash the linker.
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Type == SHT_NOBITS)
+ for (OutputSection *sec : outputSections) {
+ if (sec->type == SHT_NOBITS)
continue;
- if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
- error("unable to place section " + Sec->Name + " at file offset " +
- rangeToString(Sec->Offset, Sec->Size) +
+ if ((sec->offset > fileSize) || (sec->offset + sec->size > fileSize))
+ error("unable to place section " + sec->name + " at file offset " +
+ rangeToString(sec->offset, sec->size) +
"; check your linker script for overflows");
}
}
// Finalize the program headers. We call this function after we assign
// file offsets and VAs to all sections.
-template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &Part) {
- for (PhdrEntry *P : Part.Phdrs) {
- OutputSection *First = P->FirstSec;
- OutputSection *Last = P->LastSec;
+template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &part) {
+ for (PhdrEntry *p : part.phdrs) {
+ OutputSection *first = p->firstSec;
+ OutputSection *last = p->lastSec;
- if (First) {
- P->p_filesz = Last->Offset - First->Offset;
- if (Last->Type != SHT_NOBITS)
- P->p_filesz += Last->Size;
+ if (first) {
+ p->p_filesz = last->offset - first->offset;
+ if (last->type != SHT_NOBITS)
+ p->p_filesz += last->size;
- P->p_memsz = Last->Addr + Last->Size - First->Addr;
- P->p_offset = First->Offset;
- P->p_vaddr = First->Addr;
+ p->p_memsz = last->addr + last->size - first->addr;
+ p->p_offset = first->offset;
+ p->p_vaddr = first->addr;
// File offsets in partitions other than the main partition are relative
// to the offset of the ELF headers. Perform that adjustment now.
- if (Part.ElfHeader)
- P->p_offset -= Part.ElfHeader->getParent()->Offset;
+ if (part.elfHeader)
+ p->p_offset -= part.elfHeader->getParent()->offset;
- if (!P->HasLMA)
- P->p_paddr = First->getLMA();
+ if (!p->hasLMA)
+ p->p_paddr = first->getLMA();
}
- if (P->p_type == PT_LOAD) {
- P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);
- } else if (P->p_type == PT_GNU_RELRO) {
- P->p_align = 1;
+ if (p->p_type == PT_LOAD) {
+ p->p_align = std::max<uint64_t>(p->p_align, config->maxPageSize);
+ } else if (p->p_type == PT_GNU_RELRO) {
+ p->p_align = 1;
// The glibc dynamic loader rounds the size down, so we need to round up
// to protect the last page. This is a no-op on FreeBSD which always
// rounds up.
- P->p_memsz = alignTo(P->p_memsz, Config->CommonPageSize);
+ p->p_memsz = alignTo(p->p_memsz, config->commonPageSize);
}
}
}
@@ -2380,37 +2380,37 @@ template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &Part) {
// A helper struct for checkSectionOverlap.
namespace {
struct SectionOffset {
- OutputSection *Sec;
- uint64_t Offset;
+ OutputSection *sec;
+ uint64_t offset;
};
} // namespace
// Check whether sections overlap for a specific address range (file offsets,
// load and virtual adresses).
-static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
- bool IsVirtualAddr) {
- llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) {
- return A.Offset < B.Offset;
+static void checkOverlap(StringRef name, std::vector<SectionOffset> &sections,
+ bool isVirtualAddr) {
+ llvm::sort(sections, [=](const SectionOffset &a, const SectionOffset &b) {
+ return a.offset < b.offset;
});
// Finding overlap is easy given a vector is sorted by start position.
// If an element starts before the end of the previous element, they overlap.
- for (size_t I = 1, End = Sections.size(); I < End; ++I) {
- SectionOffset A = Sections[I - 1];
- SectionOffset B = Sections[I];
- if (B.Offset >= A.Offset + A.Sec->Size)
+ for (size_t i = 1, end = sections.size(); i < end; ++i) {
+ SectionOffset a = sections[i - 1];
+ SectionOffset b = sections[i];
+ if (b.offset >= a.offset + a.sec->size)
continue;
// If both sections are in OVERLAY we allow the overlapping of virtual
// addresses, because it is what OVERLAY was designed for.
- if (IsVirtualAddr && A.Sec->InOverlay && B.Sec->InOverlay)
+ if (isVirtualAddr && a.sec->inOverlay && b.sec->inOverlay)
continue;
- errorOrWarn("section " + A.Sec->Name + " " + Name +
- " range overlaps with " + B.Sec->Name + "\n>>> " + A.Sec->Name +
- " range is " + rangeToString(A.Offset, A.Sec->Size) + "\n>>> " +
- B.Sec->Name + " range is " +
- rangeToString(B.Offset, B.Sec->Size));
+ errorOrWarn("section " + a.sec->name + " " + name +
+ " range overlaps with " + b.sec->name + "\n>>> " + a.sec->name +
+ " range is " + rangeToString(a.offset, a.sec->size) + "\n>>> " +
+ b.sec->name + " range is " +
+ rangeToString(b.offset, b.sec->size));
}
}
@@ -2421,11 +2421,11 @@ static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
// ranges and the virtual address ranges don't overlap
template <class ELFT> void Writer<ELFT>::checkSections() {
// First, check that section's VAs fit in available address space for target.
- for (OutputSection *OS : OutputSections)
- if ((OS->Addr + OS->Size < OS->Addr) ||
- (!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
- errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
- " of size 0x" + utohexstr(OS->Size) +
+ for (OutputSection *os : outputSections)
+ if ((os->addr + os->size < os->addr) ||
+ (!ELFT::Is64Bits && os->addr + os->size > UINT32_MAX))
+ errorOrWarn("section " + os->name + " at 0x" + utohexstr(os->addr) +
+ " of size 0x" + utohexstr(os->size) +
" exceeds available address space");
// Check for overlapping file offsets. In this case we need to skip any
@@ -2433,17 +2433,17 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
// the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
// binary is specified only add SHF_ALLOC sections are added to the output
// file so we skip any non-allocated sections in that case.
- std::vector<SectionOffset> FileOffs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&
- (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
- FileOffs.push_back({Sec, Sec->Offset});
- checkOverlap("file", FileOffs, false);
+ std::vector<SectionOffset> fileOffs;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && sec->type != SHT_NOBITS &&
+ (!config->oFormatBinary || (sec->flags & SHF_ALLOC)))
+ fileOffs.push_back({sec, sec->offset});
+ checkOverlap("file", fileOffs, false);
// When linking with -r there is no need to check for overlapping virtual/load
// addresses since those addresses will only be assigned when the final
// executable/shared object is created.
- if (Config->Relocatable)
+ if (config->relocatable)
return;
// Checking for overlapping virtual and load addresses only needs to take
@@ -2451,20 +2451,20 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
// Furthermore, we also need to skip SHF_TLS sections since these will be
// mapped to other addresses at runtime and can therefore have overlapping
// ranges in the file.
- std::vector<SectionOffset> VMAs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
- VMAs.push_back({Sec, Sec->Addr});
- checkOverlap("virtual address", VMAs, true);
+ std::vector<SectionOffset> vmas;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
+ vmas.push_back({sec, sec->addr});
+ checkOverlap("virtual address", vmas, true);
// Finally, check that the load addresses don't overlap. This will usually be
// the same as the virtual addresses but can be different when using a linker
// script with AT().
- std::vector<SectionOffset> LMAs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
- LMAs.push_back({Sec, Sec->getLMA()});
- checkOverlap("load address", LMAs, false);
+ std::vector<SectionOffset> lmas;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
+ lmas.push_back({sec, sec->getLMA()});
+ checkOverlap("load address", lmas, false);
}
// The entry point address is chosen in the following ways.
@@ -2477,45 +2477,45 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
// 6. the address 0.
static uint64_t getEntryAddr() {
// Case 1, 2 or 3
- if (Symbol *B = Symtab->find(Config->Entry))
- return B->getVA();
+ if (Symbol *b = symtab->find(config->entry))
+ return b->getVA();
// Case 4
- uint64_t Addr;
- if (to_integer(Config->Entry, Addr))
- return Addr;
+ uint64_t addr;
+ if (to_integer(config->entry, addr))
+ return addr;
// Case 5
- if (OutputSection *Sec = findSection(".text")) {
- if (Config->WarnMissingEntry)
- warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
- utohexstr(Sec->Addr));
- return Sec->Addr;
+ if (OutputSection *sec = findSection(".text")) {
+ if (config->warnMissingEntry)
+ warn("cannot find entry symbol " + config->entry + "; defaulting to 0x" +
+ utohexstr(sec->addr));
+ return sec->addr;
}
// Case 6
- if (Config->WarnMissingEntry)
- warn("cannot find entry symbol " + Config->Entry +
+ if (config->warnMissingEntry)
+ warn("cannot find entry symbol " + config->entry +
"; not setting start address");
return 0;
}
static uint16_t getELFType() {
- if (Config->Pic)
+ if (config->isPic)
return ET_DYN;
- if (Config->Relocatable)
+ if (config->relocatable)
return ET_REL;
return ET_EXEC;
}
template <class ELFT> void Writer<ELFT>::writeHeader() {
- writeEhdr<ELFT>(Out::BufferStart, *Main);
- writePhdrs<ELFT>(Out::BufferStart + sizeof(Elf_Ehdr), *Main);
+ writeEhdr<ELFT>(Out::bufferStart, *mainPart);
+ writePhdrs<ELFT>(Out::bufferStart + sizeof(Elf_Ehdr), *mainPart);
- auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Out::BufferStart);
- EHdr->e_type = getELFType();
- EHdr->e_entry = getEntryAddr();
- EHdr->e_shoff = SectionHeaderOff;
+ auto *eHdr = reinterpret_cast<Elf_Ehdr *>(Out::bufferStart);
+ eHdr->e_type = getELFType();
+ eHdr->e_entry = getEntryAddr();
+ eHdr->e_shoff = sectionHeaderOff;
// Write the section header table.
//
@@ -2526,58 +2526,58 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// the value. The sentinel values and fields are:
// e_shnum = 0, SHdrs[0].sh_size = number of sections.
// e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index.
- auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Out::BufferStart + EHdr->e_shoff);
- size_t Num = OutputSections.size() + 1;
- if (Num >= SHN_LORESERVE)
- SHdrs->sh_size = Num;
+ auto *sHdrs = reinterpret_cast<Elf_Shdr *>(Out::bufferStart + eHdr->e_shoff);
+ size_t num = outputSections.size() + 1;
+ if (num >= SHN_LORESERVE)
+ sHdrs->sh_size = num;
else
- EHdr->e_shnum = Num;
+ eHdr->e_shnum = num;
- uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
- if (StrTabIndex >= SHN_LORESERVE) {
- SHdrs->sh_link = StrTabIndex;
- EHdr->e_shstrndx = SHN_XINDEX;
+ uint32_t strTabIndex = in.shStrTab->getParent()->sectionIndex;
+ if (strTabIndex >= SHN_LORESERVE) {
+ sHdrs->sh_link = strTabIndex;
+ eHdr->e_shstrndx = SHN_XINDEX;
} else {
- EHdr->e_shstrndx = StrTabIndex;
+ eHdr->e_shstrndx = strTabIndex;
}
- for (OutputSection *Sec : OutputSections)
- Sec->writeHeaderTo<ELFT>(++SHdrs);
+ for (OutputSection *sec : outputSections)
+ sec->writeHeaderTo<ELFT>(++sHdrs);
}
// Open a result file.
template <class ELFT> void Writer<ELFT>::openFile() {
- uint64_t MaxSize = Config->Is64 ? INT64_MAX : UINT32_MAX;
- if (FileSize != size_t(FileSize) || MaxSize < FileSize) {
- error("output file too large: " + Twine(FileSize) + " bytes");
+ uint64_t maxSize = config->is64 ? INT64_MAX : UINT32_MAX;
+ if (fileSize != size_t(fileSize) || maxSize < fileSize) {
+ error("output file too large: " + Twine(fileSize) + " bytes");
return;
}
- unlinkAsync(Config->OutputFile);
- unsigned Flags = 0;
- if (!Config->Relocatable)
- Flags = FileOutputBuffer::F_executable;
- Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
- FileOutputBuffer::create(Config->OutputFile, FileSize, Flags);
+ unlinkAsync(config->outputFile);
+ unsigned flags = 0;
+ if (!config->relocatable)
+ flags = FileOutputBuffer::F_executable;
+ Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
+ FileOutputBuffer::create(config->outputFile, fileSize, flags);
- if (!BufferOrErr) {
- error("failed to open " + Config->OutputFile + ": " +
- llvm::toString(BufferOrErr.takeError()));
+ if (!bufferOrErr) {
+ error("failed to open " + config->outputFile + ": " +
+ llvm::toString(bufferOrErr.takeError()));
return;
}
- Buffer = std::move(*BufferOrErr);
- Out::BufferStart = Buffer->getBufferStart();
+ buffer = std::move(*bufferOrErr);
+ Out::bufferStart = buffer->getBufferStart();
}
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
- for (OutputSection *Sec : OutputSections)
- if (Sec->Flags & SHF_ALLOC)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
+ for (OutputSection *sec : outputSections)
+ if (sec->flags & SHF_ALLOC)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
}
-static void fillTrap(uint8_t *I, uint8_t *End) {
- for (; I + 4 <= End; I += 4)
- memcpy(I, &Target->TrapInstr, 4);
+static void fillTrap(uint8_t *i, uint8_t *end) {
+ for (; i + 4 <= end; i += 4)
+ memcpy(i, &target->trapInstr, 4);
}
// Fill the last page of executable segments with trap instructions
@@ -2587,29 +2587,29 @@ static void fillTrap(uint8_t *I, uint8_t *End) {
// We'll leave other pages in segments as-is because the rest will be
// overwritten by output sections.
template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
- if (Script->HasSectionsCommand)
+ if (script->hasSectionsCommand)
return;
- for (Partition &Part : Partitions) {
+ for (Partition &part : partitions) {
// Fill the last page.
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
- fillTrap(Out::BufferStart + alignDown(P->FirstSec->Offset + P->p_filesz,
- Config->CommonPageSize),
- Out::BufferStart + alignTo(P->FirstSec->Offset + P->p_filesz,
- Config->CommonPageSize));
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
+ fillTrap(Out::bufferStart + alignDown(p->firstSec->offset + p->p_filesz,
+ config->commonPageSize),
+ Out::bufferStart + alignTo(p->firstSec->offset + p->p_filesz,
+ config->commonPageSize));
// Round up the file size of the last segment to the page boundary iff it is
// an executable segment to ensure that other tools don't accidentally
// trim the instruction padding (e.g. when stripping the file).
- PhdrEntry *Last = nullptr;
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD)
- Last = P;
+ PhdrEntry *last = nullptr;
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD)
+ last = p;
- if (Last && (Last->p_flags & PF_X))
- Last->p_memsz = Last->p_filesz =
- alignTo(Last->p_filesz, Config->CommonPageSize);
+ if (last && (last->p_flags & PF_X))
+ last->p_memsz = last->p_filesz =
+ alignTo(last->p_filesz, config->commonPageSize);
}
}
@@ -2618,26 +2618,26 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
// In -r or -emit-relocs mode, write the relocation sections first as in
// ELf_Rel targets we might find out that we need to modify the relocated
// section while doing it.
- for (OutputSection *Sec : OutputSections)
- if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
+ for (OutputSection *sec : outputSections)
+ if (sec->type == SHT_REL || sec->type == SHT_RELA)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
- for (OutputSection *Sec : OutputSections)
- if (Sec->Type != SHT_REL && Sec->Type != SHT_RELA)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
+ for (OutputSection *sec : outputSections)
+ if (sec->type != SHT_REL && sec->type != SHT_RELA)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
}
// Split one uint8 array into small pieces of uint8 arrays.
-static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
- size_t ChunkSize) {
- std::vector<ArrayRef<uint8_t>> Ret;
- while (Arr.size() > ChunkSize) {
- Ret.push_back(Arr.take_front(ChunkSize));
- Arr = Arr.drop_front(ChunkSize);
+static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> arr,
+ size_t chunkSize) {
+ std::vector<ArrayRef<uint8_t>> ret;
+ while (arr.size() > chunkSize) {
+ ret.push_back(arr.take_front(chunkSize));
+ arr = arr.drop_front(chunkSize);
}
- if (!Arr.empty())
- Ret.push_back(Arr);
- return Ret;
+ if (!arr.empty())
+ ret.push_back(arr);
+ return ret;
}
// Computes a hash value of Data using a given hash function.
@@ -2645,61 +2645,61 @@ static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
// chunks, compute a hash for each chunk, and then compute a hash value
// of the hash values.
static void
-computeHash(llvm::MutableArrayRef<uint8_t> HashBuf,
- llvm::ArrayRef<uint8_t> Data,
- std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
- std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
- std::vector<uint8_t> Hashes(Chunks.size() * HashBuf.size());
+computeHash(llvm::MutableArrayRef<uint8_t> hashBuf,
+ llvm::ArrayRef<uint8_t> data,
+ std::function<void(uint8_t *dest, ArrayRef<uint8_t> arr)> hashFn) {
+ std::vector<ArrayRef<uint8_t>> chunks = split(data, 1024 * 1024);
+ std::vector<uint8_t> hashes(chunks.size() * hashBuf.size());
// Compute hash values.
- parallelForEachN(0, Chunks.size(), [&](size_t I) {
- HashFn(Hashes.data() + I * HashBuf.size(), Chunks[I]);
+ parallelForEachN(0, chunks.size(), [&](size_t i) {
+ hashFn(hashes.data() + i * hashBuf.size(), chunks[i]);
});
// Write to the final output buffer.
- HashFn(HashBuf.data(), Hashes);
+ hashFn(hashBuf.data(), hashes);
}
template <class ELFT> void Writer<ELFT>::writeBuildId() {
- if (!Main->BuildId || !Main->BuildId->getParent())
+ if (!mainPart->buildId || !mainPart->buildId->getParent())
return;
- if (Config->BuildId == BuildIdKind::Hexstring) {
- for (Partition &Part : Partitions)
- Part.BuildId->writeBuildId(Config->BuildIdVector);
+ if (config->buildId == BuildIdKind::Hexstring) {
+ for (Partition &part : partitions)
+ part.buildId->writeBuildId(config->buildIdVector);
return;
}
// Compute a hash of all sections of the output file.
- size_t HashSize = Main->BuildId->HashSize;
- std::vector<uint8_t> BuildId(HashSize);
- llvm::ArrayRef<uint8_t> Buf{Out::BufferStart, size_t(FileSize)};
+ size_t hashSize = mainPart->buildId->hashSize;
+ std::vector<uint8_t> buildId(hashSize);
+ llvm::ArrayRef<uint8_t> buf{Out::bufferStart, size_t(fileSize)};
- switch (Config->BuildId) {
+ switch (config->buildId) {
case BuildIdKind::Fast:
- computeHash(BuildId, Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- write64le(Dest, xxHash64(Arr));
+ computeHash(buildId, buf, [](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ write64le(dest, xxHash64(arr));
});
break;
case BuildIdKind::Md5:
- computeHash(BuildId, Buf, [&](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- memcpy(Dest, MD5::hash(Arr).data(), HashSize);
+ computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ memcpy(dest, MD5::hash(arr).data(), hashSize);
});
break;
case BuildIdKind::Sha1:
- computeHash(BuildId, Buf, [&](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- memcpy(Dest, SHA1::hash(Arr).data(), HashSize);
+ computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ memcpy(dest, SHA1::hash(arr).data(), hashSize);
});
break;
case BuildIdKind::Uuid:
- if (auto EC = llvm::getRandomBytes(BuildId.data(), HashSize))
- error("entropy source failure: " + EC.message());
+ if (auto ec = llvm::getRandomBytes(buildId.data(), hashSize))
+ error("entropy source failure: " + ec.message());
break;
default:
llvm_unreachable("unknown BuildIdKind");
}
- for (Partition &Part : Partitions)
- Part.BuildId->writeBuildId(BuildId);
+ for (Partition &part : partitions)
+ part.buildId->writeBuildId(buildId);
}
template void elf::writeResult<ELF32LE>();
diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h
index 276cf3d64b7..784fba9c75a 100644
--- a/lld/ELF/Writer.h
+++ b/lld/ELF/Writer.h
@@ -25,8 +25,8 @@ template <class ELFT> void writeResult();
// Each contains type, access flags and range of output sections that will be
// placed in it.
struct PhdrEntry {
- PhdrEntry(unsigned Type, unsigned Flags) : p_type(Type), p_flags(Flags) {}
- void add(OutputSection *Sec);
+ PhdrEntry(unsigned type, unsigned flags) : p_type(type), p_flags(flags) {}
+ void add(OutputSection *sec);
uint64_t p_paddr = 0;
uint64_t p_vaddr = 0;
@@ -37,22 +37,22 @@ struct PhdrEntry {
uint32_t p_type = 0;
uint32_t p_flags = 0;
- OutputSection *FirstSec = nullptr;
- OutputSection *LastSec = nullptr;
- bool HasLMA = false;
+ OutputSection *firstSec = nullptr;
+ OutputSection *lastSec = nullptr;
+ bool hasLMA = false;
- uint64_t LMAOffset = 0;
+ uint64_t lmaOffset = 0;
};
void addReservedSymbols();
-llvm::StringRef getOutputSectionName(const InputSectionBase *S);
+llvm::StringRef getOutputSectionName(const InputSectionBase *s);
template <class ELFT> uint32_t calcMipsEFlags();
-uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
- llvm::StringRef FileName);
+uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
+ llvm::StringRef fileName);
-bool isMipsN32Abi(const InputFile *F);
+bool isMipsN32Abi(const InputFile *f);
bool isMicroMips();
bool isMipsR6();
} // namespace elf
OpenPOWER on IntegriCloud