From 136d27ab4de0c1d5dedfecc32a9857be78fa0648 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 11 Jul 2019 05:40:30 +0000 Subject: [PATCH] [Coding style change][lld] Rename variables for non-ELF ports This patch does the same thing as r365595 to other subdirectories, which completes the naming style change for the entire lld directory. With this, the naming style conversion is complete for lld. Differential Revision: https://reviews.llvm.org/D64473 llvm-svn: 365730 --- lld/COFF/Chunks.cpp | 806 +++++++------- lld/COFF/Chunks.h | 350 +++--- lld/COFF/Config.h | 226 ++-- lld/COFF/DLL.cpp | 564 +++++----- lld/COFF/DLL.h | 52 +- lld/COFF/DebugTypes.cpp | 192 ++-- lld/COFF/DebugTypes.h | 24 +- lld/COFF/Driver.cpp | 1798 +++++++++++++++---------------- lld/COFF/Driver.h | 96 +- lld/COFF/DriverUtils.cpp | 924 ++++++++-------- lld/COFF/ICF.cpp | 270 ++--- lld/COFF/ICF.h | 2 +- lld/COFF/InputFiles.cpp | 806 +++++++------- lld/COFF/InputFiles.h | 182 ++-- lld/COFF/LTO.cpp | 126 +-- lld/COFF/LTO.h | 8 +- lld/COFF/MapFile.cpp | 102 +- lld/COFF/MapFile.h | 2 +- lld/COFF/MarkLive.cpp | 58 +- lld/COFF/MarkLive.h | 2 +- lld/COFF/MinGW.cpp | 88 +- lld/COFF/MinGW.h | 16 +- lld/COFF/PDB.cpp | 1756 +++++++++++++++--------------- lld/COFF/PDB.h | 12 +- lld/COFF/SymbolTable.cpp | 702 ++++++------ lld/COFF/SymbolTable.h | 68 +- lld/COFF/Symbols.cpp | 100 +- lld/COFF/Symbols.h | 228 ++-- lld/COFF/TypeMerger.h | 34 +- lld/COFF/Writer.cpp | 1916 ++++++++++++++++----------------- lld/COFF/Writer.h | 52 +- lld/Common/Args.cpp | 76 +- lld/Common/ErrorHandler.cpp | 110 +- lld/Common/Filesystem.cpp | 42 +- lld/Common/Memory.cpp | 12 +- lld/Common/Reproduce.cpp | 50 +- lld/Common/Strings.cpp | 92 +- lld/Common/Threads.cpp | 2 +- lld/Common/Timer.cpp | 54 +- lld/ELF/AArch64ErrataFix.cpp | 16 +- lld/ELF/Driver.cpp | 24 +- lld/ELF/DriverUtils.cpp | 12 +- lld/ELF/ICF.cpp | 2 +- lld/ELF/InputFiles.cpp | 18 +- lld/ELF/InputSection.cpp | 4 +- lld/ELF/MarkLive.cpp | 4 +- lld/ELF/Relocations.cpp | 8 +- lld/ELF/ScriptParser.cpp | 6 +- lld/ELF/SyntheticSections.cpp | 8 +- lld/ELF/Thunks.cpp | 32 +- lld/ELF/Writer.cpp | 10 +- lld/MinGW/Driver.cpp | 350 +++--- lld/include/lld/Common/Args.h | 12 +- lld/include/lld/Common/Driver.h | 20 +- lld/include/lld/Common/ErrorHandler.h | 90 +- lld/include/lld/Common/Filesystem.h | 4 +- lld/include/lld/Common/Memory.h | 18 +- lld/include/lld/Common/Reproduce.h | 6 +- lld/include/lld/Common/Strings.h | 16 +- lld/include/lld/Common/Threads.h | 28 +- lld/include/lld/Common/Timer.h | 22 +- lld/lib/Driver/DarwinLdDriver.cpp | 24 +- lld/tools/lld/lld.cpp | 88 +- lld/wasm/Config.h | 84 +- lld/wasm/Driver.cpp | 690 ++++++------ lld/wasm/InputChunks.cpp | 290 ++--- lld/wasm/InputChunks.h | 154 +-- lld/wasm/InputEvent.h | 30 +- lld/wasm/InputFiles.cpp | 562 +++++----- lld/wasm/InputFiles.h | 120 +-- lld/wasm/InputGlobal.h | 28 +- lld/wasm/LTO.cpp | 148 +-- lld/wasm/LTO.h | 8 +- lld/wasm/MarkLive.cpp | 122 +-- lld/wasm/OutputSections.cpp | 230 ++-- lld/wasm/OutputSections.h | 84 +- lld/wasm/OutputSegment.h | 36 +- lld/wasm/Relocations.cpp | 68 +- lld/wasm/Relocations.h | 2 +- lld/wasm/SymbolTable.cpp | 750 ++++++------- lld/wasm/SymbolTable.h | 98 +- lld/wasm/Symbols.cpp | 302 +++--- lld/wasm/Symbols.h | 334 +++--- lld/wasm/SyntheticSections.cpp | 690 ++++++------ lld/wasm/SyntheticSections.h | 206 ++-- lld/wasm/Writer.cpp | 804 +++++++------- lld/wasm/WriterUtils.cpp | 198 ++-- lld/wasm/WriterUtils.h | 48 +- 88 files changed, 9454 insertions(+), 9454 deletions(-) diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 4bad91d..374751a 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -29,27 +29,27 @@ using llvm::support::ulittle32_t; namespace lld { namespace coff { -SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) - : Chunk(SectionKind), File(F), Header(H), Repl(this) { +SectionChunk::SectionChunk(ObjFile *f, const coff_section *h) + : Chunk(SectionKind), file(f), header(h), repl(this) { // Initialize Relocs. - setRelocs(File->getCOFFObj()->getRelocations(Header)); + setRelocs(file->getCOFFObj()->getRelocations(header)); // Initialize SectionName. - StringRef SectionName; - if (Expected E = File->getCOFFObj()->getSectionName(Header)) - SectionName = *E; - SectionNameData = SectionName.data(); - SectionNameSize = SectionName.size(); + StringRef sectionName; + if (Expected e = file->getCOFFObj()->getSectionName(header)) + sectionName = *e; + sectionNameData = sectionName.data(); + sectionNameSize = sectionName.size(); - setAlignment(Header->getAlignment()); + setAlignment(header->getAlignment()); - HasData = !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); + hasData = !(header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); // If linker GC is disabled, every chunk starts out alive. If linker GC is // enabled, treat non-comdat sections as roots. Generally optimized object // files will be built with -ffunction-sections or /Gy, so most things worth // stripping will be in a comdat. - Live = !Config->DoGC || !isCOMDAT(); + live = !config->doGC || !isCOMDAT(); } // SectionChunk is one of the most frequently allocated classes, so it is @@ -57,173 +57,173 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) // below is the size of this class on x64 platforms. static_assert(sizeof(SectionChunk) <= 88, "SectionChunk grew unexpectedly"); -static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); } -static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); } -static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); } -static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); } -static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); } +static void add16(uint8_t *p, int16_t v) { write16le(p, read16le(p) + v); } +static void add32(uint8_t *p, int32_t v) { write32le(p, read32le(p) + v); } +static void add64(uint8_t *p, int64_t v) { write64le(p, read64le(p) + v); } +static void or16(uint8_t *p, uint16_t v) { write16le(p, read16le(p) | v); } +static void or32(uint8_t *p, uint32_t v) { write32le(p, read32le(p) | v); } // Verify that given sections are appropriate targets for SECREL // relocations. This check is relaxed because unfortunately debug // sections have section-relative relocations against absolute symbols. -static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) { - if (OS) +static bool checkSecRel(const SectionChunk *sec, OutputSection *os) { + if (os) return true; - if (Sec->isCodeView()) + if (sec->isCodeView()) return false; error("SECREL relocation cannot be applied to absolute symbols"); return false; } -static void applySecRel(const SectionChunk *Sec, uint8_t *Off, - OutputSection *OS, uint64_t S) { - if (!checkSecRel(Sec, OS)) +static void applySecRel(const SectionChunk *sec, uint8_t *off, + OutputSection *os, uint64_t s) { + if (!checkSecRel(sec, os)) return; - uint64_t SecRel = S - OS->getRVA(); - if (SecRel > UINT32_MAX) { - error("overflow in SECREL relocation in section: " + Sec->getSectionName()); + uint64_t secRel = s - os->getRVA(); + if (secRel > UINT32_MAX) { + error("overflow in SECREL relocation in section: " + sec->getSectionName()); return; } - add32(Off, SecRel); + add32(off, secRel); } -static void applySecIdx(uint8_t *Off, OutputSection *OS) { +static void applySecIdx(uint8_t *off, OutputSection *os) { // Absolute symbol doesn't have section index, but section index relocation // against absolute symbol should be resolved to one plus the last output // section index. This is required for compatibility with MSVC. - if (OS) - add16(Off, OS->SectionIndex); + if (os) + add16(off, os->sectionIndex); else - add16(Off, DefinedAbsolute::NumOutputSections + 1); -} - -void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, - uint64_t S, uint64_t P) const { - switch (Type) { - case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break; - case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break; - case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break; - case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break; - case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break; - case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break; - case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break; - case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break; - case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break; - case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break; - case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break; + add16(off, DefinedAbsolute::numOutputSections + 1); +} + +void SectionChunk::applyRelX64(uint8_t *off, uint16_t type, OutputSection *os, + uint64_t s, uint64_t p) const { + switch (type) { + case IMAGE_REL_AMD64_ADDR32: add32(off, s + config->imageBase); break; + case IMAGE_REL_AMD64_ADDR64: add64(off, s + config->imageBase); break; + case IMAGE_REL_AMD64_ADDR32NB: add32(off, s); break; + case IMAGE_REL_AMD64_REL32: add32(off, s - p - 4); break; + case IMAGE_REL_AMD64_REL32_1: add32(off, s - p - 5); break; + case IMAGE_REL_AMD64_REL32_2: add32(off, s - p - 6); break; + case IMAGE_REL_AMD64_REL32_3: add32(off, s - p - 7); break; + case IMAGE_REL_AMD64_REL32_4: add32(off, s - p - 8); break; + case IMAGE_REL_AMD64_REL32_5: add32(off, s - p - 9); break; + case IMAGE_REL_AMD64_SECTION: applySecIdx(off, os); break; + case IMAGE_REL_AMD64_SECREL: applySecRel(this, off, os, s); break; default: - error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + - toString(File)); + error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " + + toString(file)); } } -void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, - uint64_t S, uint64_t P) const { - switch (Type) { +void SectionChunk::applyRelX86(uint8_t *off, uint16_t type, OutputSection *os, + uint64_t s, uint64_t p) const { + switch (type) { case IMAGE_REL_I386_ABSOLUTE: break; - case IMAGE_REL_I386_DIR32: add32(Off, S + Config->ImageBase); break; - case IMAGE_REL_I386_DIR32NB: add32(Off, S); break; - case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break; - case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break; - case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break; + case IMAGE_REL_I386_DIR32: add32(off, s + config->imageBase); break; + case IMAGE_REL_I386_DIR32NB: add32(off, s); break; + case IMAGE_REL_I386_REL32: add32(off, s - p - 4); break; + case IMAGE_REL_I386_SECTION: applySecIdx(off, os); break; + case IMAGE_REL_I386_SECREL: applySecRel(this, off, os, s); break; default: - error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + - toString(File)); + error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " + + toString(file)); } } -static void applyMOV(uint8_t *Off, uint16_t V) { - write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf)); - write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff)); +static void applyMOV(uint8_t *off, uint16_t v) { + write16le(off, (read16le(off) & 0xfbf0) | ((v & 0x800) >> 1) | ((v >> 12) & 0xf)); + write16le(off + 2, (read16le(off + 2) & 0x8f00) | ((v & 0x700) << 4) | (v & 0xff)); } -static uint16_t readMOV(uint8_t *Off, bool MOVT) { - uint16_t Op1 = read16le(Off); - if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240)) - error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") + +static uint16_t readMOV(uint8_t *off, bool movt) { + uint16_t op1 = read16le(off); + if ((op1 & 0xfbf0) != (movt ? 0xf2c0 : 0xf240)) + error("unexpected instruction in " + Twine(movt ? "MOVT" : "MOVW") + " instruction in MOV32T relocation"); - uint16_t Op2 = read16le(Off + 2); - if ((Op2 & 0x8000) != 0) - error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") + + uint16_t op2 = read16le(off + 2); + if ((op2 & 0x8000) != 0) + error("unexpected instruction in " + Twine(movt ? "MOVT" : "MOVW") + " instruction in MOV32T relocation"); - return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) | - ((Op1 & 0x000f) << 12); + return (op2 & 0x00ff) | ((op2 >> 4) & 0x0700) | ((op1 << 1) & 0x0800) | + ((op1 & 0x000f) << 12); } -void applyMOV32T(uint8_t *Off, uint32_t V) { - uint16_t ImmW = readMOV(Off, false); // read MOVW operand - uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand - uint32_t Imm = ImmW | (ImmT << 16); - V += Imm; // add the immediate offset - applyMOV(Off, V); // set MOVW operand - applyMOV(Off + 4, V >> 16); // set MOVT operand +void applyMOV32T(uint8_t *off, uint32_t v) { + uint16_t immW = readMOV(off, false); // read MOVW operand + uint16_t immT = readMOV(off + 4, true); // read MOVT operand + uint32_t imm = immW | (immT << 16); + v += imm; // add the immediate offset + applyMOV(off, v); // set MOVW operand + applyMOV(off + 4, v >> 16); // set MOVT operand } -static void applyBranch20T(uint8_t *Off, int32_t V) { - if (!isInt<21>(V)) +static void applyBranch20T(uint8_t *off, int32_t v) { + if (!isInt<21>(v)) error("relocation out of range"); - uint32_t S = V < 0 ? 1 : 0; - uint32_t J1 = (V >> 19) & 1; - uint32_t J2 = (V >> 18) & 1; - or16(Off, (S << 10) | ((V >> 12) & 0x3f)); - or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); + uint32_t s = v < 0 ? 1 : 0; + uint32_t j1 = (v >> 19) & 1; + uint32_t j2 = (v >> 18) & 1; + or16(off, (s << 10) | ((v >> 12) & 0x3f)); + or16(off + 2, (j1 << 13) | (j2 << 11) | ((v >> 1) & 0x7ff)); } -void applyBranch24T(uint8_t *Off, int32_t V) { - if (!isInt<25>(V)) +void applyBranch24T(uint8_t *off, int32_t v) { + if (!isInt<25>(v)) error("relocation out of range"); - uint32_t S = V < 0 ? 1 : 0; - uint32_t J1 = ((~V >> 23) & 1) ^ S; - uint32_t J2 = ((~V >> 22) & 1) ^ S; - or16(Off, (S << 10) | ((V >> 12) & 0x3ff)); + uint32_t s = v < 0 ? 1 : 0; + uint32_t j1 = ((~v >> 23) & 1) ^ s; + uint32_t j2 = ((~v >> 22) & 1) ^ s; + or16(off, (s << 10) | ((v >> 12) & 0x3ff)); // Clear out the J1 and J2 bits which may be set. - write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); + write16le(off + 2, (read16le(off + 2) & 0xd000) | (j1 << 13) | (j2 << 11) | ((v >> 1) & 0x7ff)); } -void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, - uint64_t S, uint64_t P) const { +void SectionChunk::applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, + uint64_t s, uint64_t p) const { // Pointer to thumb code must have the LSB set. - uint64_t SX = S; - if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)) - SX |= 1; - switch (Type) { - case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break; - case IMAGE_REL_ARM_ADDR32NB: add32(Off, SX); break; - case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, SX + Config->ImageBase); break; - case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break; - case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break; - case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, SX - P - 4); break; - case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break; - case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break; - case IMAGE_REL_ARM_REL32: add32(Off, SX - P - 4); break; + uint64_t sx = s; + if (os && (os->header.Characteristics & IMAGE_SCN_MEM_EXECUTE)) + sx |= 1; + switch (type) { + case IMAGE_REL_ARM_ADDR32: add32(off, sx + config->imageBase); break; + case IMAGE_REL_ARM_ADDR32NB: add32(off, sx); break; + case IMAGE_REL_ARM_MOV32T: applyMOV32T(off, sx + config->imageBase); break; + case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(off, sx - p - 4); break; + case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(off, sx - p - 4); break; + case IMAGE_REL_ARM_BLX23T: applyBranch24T(off, sx - p - 4); break; + case IMAGE_REL_ARM_SECTION: applySecIdx(off, os); break; + case IMAGE_REL_ARM_SECREL: applySecRel(this, off, os, s); break; + case IMAGE_REL_ARM_REL32: add32(off, sx - p - 4); break; default: - error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + - toString(File)); + error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " + + toString(file)); } } // Interpret the existing immediate value as a byte offset to the // target symbol, then update the instruction with the immediate as // the page offset from the current instruction to the target. -void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) { - uint32_t Orig = read32le(Off); - uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC); - S += Imm; - Imm = (S >> Shift) - (P >> Shift); - uint32_t ImmLo = (Imm & 0x3) << 29; - uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; - uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); - write32le(Off, (Orig & ~Mask) | ImmLo | ImmHi); +void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift) { + uint32_t orig = read32le(off); + uint64_t imm = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC); + s += imm; + imm = (s >> shift) - (p >> shift); + uint32_t immLo = (imm & 0x3) << 29; + uint32_t immHi = (imm & 0x1FFFFC) << 3; + uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3); + write32le(off, (orig & ~mask) | immLo | immHi); } // Update the immediate field in a AARCH64 ldr, str, and add instruction. // Optionally limit the range of the written immediate by one or more bits // (RangeLimit). -void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) { - uint32_t Orig = read32le(Off); - Imm += (Orig >> 10) & 0xFFF; - Orig &= ~(0xFFF << 10); - write32le(Off, Orig | ((Imm & (0xFFF >> RangeLimit)) << 10)); +void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit) { + uint32_t orig = read32le(off); + imm += (orig >> 10) & 0xFFF; + orig &= ~(0xFFF << 10); + write32le(off, orig | ((imm & (0xFFF >> rangeLimit)) << 10)); } // Add the 12 bit page offset to the existing immediate. @@ -234,178 +234,178 @@ void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) { // Even if larger loads/stores have a larger range, limit the // effective offset to 12 bit, since it is intended to be a // page offset. -static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) { - uint32_t Orig = read32le(Off); - uint32_t Size = Orig >> 30; +static void applyArm64Ldr(uint8_t *off, uint64_t imm) { + uint32_t orig = read32le(off); + uint32_t size = orig >> 30; // 0x04000000 indicates SIMD/FP registers // 0x00800000 indicates 128 bit - if ((Orig & 0x4800000) == 0x4800000) - Size += 4; - if ((Imm & ((1 << Size) - 1)) != 0) + if ((orig & 0x4800000) == 0x4800000) + size += 4; + if ((imm & ((1 << size) - 1)) != 0) error("misaligned ldr/str offset"); - applyArm64Imm(Off, Imm >> Size, Size); + applyArm64Imm(off, imm >> size, size); } -static void applySecRelLow12A(const SectionChunk *Sec, uint8_t *Off, - OutputSection *OS, uint64_t S) { - if (checkSecRel(Sec, OS)) - applyArm64Imm(Off, (S - OS->getRVA()) & 0xfff, 0); +static void applySecRelLow12A(const SectionChunk *sec, uint8_t *off, + OutputSection *os, uint64_t s) { + if (checkSecRel(sec, os)) + applyArm64Imm(off, (s - os->getRVA()) & 0xfff, 0); } -static void applySecRelHigh12A(const SectionChunk *Sec, uint8_t *Off, - OutputSection *OS, uint64_t S) { - if (!checkSecRel(Sec, OS)) +static void applySecRelHigh12A(const SectionChunk *sec, uint8_t *off, + OutputSection *os, uint64_t s) { + if (!checkSecRel(sec, os)) return; - uint64_t SecRel = (S - OS->getRVA()) >> 12; - if (0xfff < SecRel) { + uint64_t secRel = (s - os->getRVA()) >> 12; + if (0xfff < secRel) { error("overflow in SECREL_HIGH12A relocation in section: " + - Sec->getSectionName()); + sec->getSectionName()); return; } - applyArm64Imm(Off, SecRel & 0xfff, 0); + applyArm64Imm(off, secRel & 0xfff, 0); } -static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off, - OutputSection *OS, uint64_t S) { - if (checkSecRel(Sec, OS)) - applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff); +static void applySecRelLdr(const SectionChunk *sec, uint8_t *off, + OutputSection *os, uint64_t s) { + if (checkSecRel(sec, os)) + applyArm64Ldr(off, (s - os->getRVA()) & 0xfff); } -void applyArm64Branch26(uint8_t *Off, int64_t V) { - if (!isInt<28>(V)) +void applyArm64Branch26(uint8_t *off, int64_t v) { + if (!isInt<28>(v)) error("relocation out of range"); - or32(Off, (V & 0x0FFFFFFC) >> 2); + or32(off, (v & 0x0FFFFFFC) >> 2); } -static void applyArm64Branch19(uint8_t *Off, int64_t V) { - if (!isInt<21>(V)) +static void applyArm64Branch19(uint8_t *off, int64_t v) { + if (!isInt<21>(v)) error("relocation out of range"); - or32(Off, (V & 0x001FFFFC) << 3); + or32(off, (v & 0x001FFFFC) << 3); } -static void applyArm64Branch14(uint8_t *Off, int64_t V) { - if (!isInt<16>(V)) +static void applyArm64Branch14(uint8_t *off, int64_t v) { + if (!isInt<16>(v)) error("relocation out of range"); - or32(Off, (V & 0x0000FFFC) << 3); -} - -void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, - uint64_t S, uint64_t P) const { - switch (Type) { - case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break; - case IMAGE_REL_ARM64_REL21: applyArm64Addr(Off, S, P, 0); break; - case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break; - case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; - case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(Off, S - P); break; - case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(Off, S - P); break; - case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(Off, S - P); break; - case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; - case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break; - case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; - case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break; - case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, Off, OS, S); break; - case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break; - case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break; - case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break; - case IMAGE_REL_ARM64_REL32: add32(Off, S - P - 4); break; + or32(off, (v & 0x0000FFFC) << 3); +} + +void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os, + uint64_t s, uint64_t p) const { + switch (type) { + case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(off, s, p, 12); break; + case IMAGE_REL_ARM64_REL21: applyArm64Addr(off, s, p, 0); break; + case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(off, s & 0xfff, 0); break; + case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(off, s & 0xfff); break; + case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(off, s - p); break; + case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(off, s - p); break; + case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(off, s - p); break; + case IMAGE_REL_ARM64_ADDR32: add32(off, s + config->imageBase); break; + case IMAGE_REL_ARM64_ADDR32NB: add32(off, s); break; + case IMAGE_REL_ARM64_ADDR64: add64(off, s + config->imageBase); break; + case IMAGE_REL_ARM64_SECREL: applySecRel(this, off, os, s); break; + case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, off, os, s); break; + case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, off, os, s); break; + case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, off, os, s); break; + case IMAGE_REL_ARM64_SECTION: applySecIdx(off, os); break; + case IMAGE_REL_ARM64_REL32: add32(off, s - p - 4); break; default: - error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + - toString(File)); + error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " + + toString(file)); } } -static void maybeReportRelocationToDiscarded(const SectionChunk *FromChunk, - Defined *Sym, - const coff_relocation &Rel) { +static void maybeReportRelocationToDiscarded(const SectionChunk *fromChunk, + Defined *sym, + const coff_relocation &rel) { // Don't report these errors when the relocation comes from a debug info // section or in mingw mode. MinGW mode object files (built by GCC) can // have leftover sections with relocations against discarded comdat // sections. Such sections are left as is, with relocations untouched. - if (FromChunk->isCodeView() || FromChunk->isDWARF() || Config->MinGW) + if (fromChunk->isCodeView() || fromChunk->isDWARF() || config->mingw) return; // Get the name of the symbol. If it's null, it was discarded early, so we // have to go back to the object file. - ObjFile *File = FromChunk->File; - StringRef Name; - if (Sym) { - Name = Sym->getName(); + ObjFile *file = fromChunk->file; + StringRef name; + if (sym) { + name = sym->getName(); } else { - COFFSymbolRef COFFSym = - check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex)); - File->getCOFFObj()->getSymbolName(COFFSym, Name); + COFFSymbolRef coffSym = + check(file->getCOFFObj()->getSymbol(rel.SymbolTableIndex)); + file->getCOFFObj()->getSymbolName(coffSym, name); } - std::vector SymbolLocations = - getSymbolLocations(File, Rel.SymbolTableIndex); + std::vector symbolLocations = + getSymbolLocations(file, rel.SymbolTableIndex); - std::string Out; - llvm::raw_string_ostream OS(Out); - OS << "relocation against symbol in discarded section: " + Name; - for (const std::string &S : SymbolLocations) - OS << S; - error(OS.str()); + std::string out; + llvm::raw_string_ostream os(out); + os << "relocation against symbol in discarded section: " + name; + for (const std::string &s : symbolLocations) + os << s; + error(os.str()); } -void SectionChunk::writeTo(uint8_t *Buf) const { - if (!HasData) +void SectionChunk::writeTo(uint8_t *buf) const { + if (!hasData) return; // Copy section contents from source object file to output file. - ArrayRef A = getContents(); - if (!A.empty()) - memcpy(Buf, A.data(), A.size()); + ArrayRef a = getContents(); + if (!a.empty()) + memcpy(buf, a.data(), a.size()); // Apply relocations. - size_t InputSize = getSize(); - for (size_t I = 0, E = RelocsSize; I < E; I++) { - const coff_relocation &Rel = RelocsData[I]; + size_t inputSize = getSize(); + for (size_t i = 0, e = relocsSize; i < e; i++) { + const coff_relocation &rel = relocsData[i]; // Check for an invalid relocation offset. This check isn't perfect, because // we don't have the relocation size, which is only known after checking the // machine and relocation type. As a result, a relocation may overwrite the // beginning of the following input section. - if (Rel.VirtualAddress >= InputSize) { + if (rel.VirtualAddress >= inputSize) { error("relocation points beyond the end of its parent section"); continue; } - uint8_t *Off = Buf + Rel.VirtualAddress; + uint8_t *off = buf + rel.VirtualAddress; - auto *Sym = - dyn_cast_or_null(File->getSymbol(Rel.SymbolTableIndex)); + auto *sym = + dyn_cast_or_null(file->getSymbol(rel.SymbolTableIndex)); // Get the output section of the symbol for this relocation. The output // section is needed to compute SECREL and SECTION relocations used in debug // info. - Chunk *C = Sym ? Sym->getChunk() : nullptr; - OutputSection *OS = C ? C->getOutputSection() : nullptr; + Chunk *c = sym ? sym->getChunk() : nullptr; + OutputSection *os = c ? c->getOutputSection() : nullptr; // Skip the relocation if it refers to a discarded section, and diagnose it // as an error if appropriate. If a symbol was discarded early, it may be // null. If it was discarded late, the output section will be null, unless // it was an absolute or synthetic symbol. - if (!Sym || - (!OS && !isa(Sym) && !isa(Sym))) { - maybeReportRelocationToDiscarded(this, Sym, Rel); + if (!sym || + (!os && !isa(sym) && !isa(sym))) { + maybeReportRelocationToDiscarded(this, sym, rel); continue; } - uint64_t S = Sym->getRVA(); + uint64_t s = sym->getRVA(); // Compute the RVA of the relocation for relative relocations. - uint64_t P = RVA + Rel.VirtualAddress; - switch (Config->Machine) { + uint64_t p = rva + rel.VirtualAddress; + switch (config->machine) { case AMD64: - applyRelX64(Off, Rel.Type, OS, S, P); + applyRelX64(off, rel.Type, os, s, p); break; case I386: - applyRelX86(Off, Rel.Type, OS, S, P); + applyRelX86(off, rel.Type, os, s, p); break; case ARMNT: - applyRelARM(Off, Rel.Type, OS, S, P); + applyRelARM(off, rel.Type, os, s, p); break; case ARM64: - applyRelARM64(Off, Rel.Type, OS, S, P); + applyRelARM64(off, rel.Type, os, s, p); break; default: llvm_unreachable("unknown machine type"); @@ -413,32 +413,32 @@ void SectionChunk::writeTo(uint8_t *Buf) const { } } -void SectionChunk::addAssociative(SectionChunk *Child) { +void SectionChunk::addAssociative(SectionChunk *child) { // Insert this child at the head of the list. - assert(Child->AssocChildren == nullptr && + assert(child->assocChildren == nullptr && "associated sections cannot have their own associated children"); - Child->AssocChildren = AssocChildren; - AssocChildren = Child; + child->assocChildren = assocChildren; + assocChildren = child; } -static uint8_t getBaserelType(const coff_relocation &Rel) { - switch (Config->Machine) { +static uint8_t getBaserelType(const coff_relocation &rel) { + switch (config->machine) { case AMD64: - if (Rel.Type == IMAGE_REL_AMD64_ADDR64) + if (rel.Type == IMAGE_REL_AMD64_ADDR64) return IMAGE_REL_BASED_DIR64; return IMAGE_REL_BASED_ABSOLUTE; case I386: - if (Rel.Type == IMAGE_REL_I386_DIR32) + if (rel.Type == IMAGE_REL_I386_DIR32) return IMAGE_REL_BASED_HIGHLOW; return IMAGE_REL_BASED_ABSOLUTE; case ARMNT: - if (Rel.Type == IMAGE_REL_ARM_ADDR32) + if (rel.Type == IMAGE_REL_ARM_ADDR32) return IMAGE_REL_BASED_HIGHLOW; - if (Rel.Type == IMAGE_REL_ARM_MOV32T) + if (rel.Type == IMAGE_REL_ARM_MOV32T) return IMAGE_REL_BASED_ARM_MOV32T; return IMAGE_REL_BASED_ABSOLUTE; case ARM64: - if (Rel.Type == IMAGE_REL_ARM64_ADDR64) + if (rel.Type == IMAGE_REL_ARM64_ADDR64) return IMAGE_REL_BASED_DIR64; return IMAGE_REL_BASED_ABSOLUTE; default: @@ -450,16 +450,16 @@ static uint8_t getBaserelType(const coff_relocation &Rel) { // Collect all locations that contain absolute addresses, which need to be // fixed by the loader if load-time relocation is needed. // Only called when base relocation is enabled. -void SectionChunk::getBaserels(std::vector *Res) { - for (size_t I = 0, E = RelocsSize; I < E; I++) { - const coff_relocation &Rel = RelocsData[I]; - uint8_t Ty = getBaserelType(Rel); - if (Ty == IMAGE_REL_BASED_ABSOLUTE) +void SectionChunk::getBaserels(std::vector *res) { + for (size_t i = 0, e = relocsSize; i < e; i++) { + const coff_relocation &rel = relocsData[i]; + uint8_t ty = getBaserelType(rel); + if (ty == IMAGE_REL_BASED_ABSOLUTE) continue; - Symbol *Target = File->getSymbol(Rel.SymbolTableIndex); - if (!Target || isa(Target)) + Symbol *target = file->getSymbol(rel.SymbolTableIndex); + if (!target || isa(target)) continue; - Res->emplace_back(RVA + Rel.VirtualAddress, Ty); + res->emplace_back(rva + rel.VirtualAddress, ty); } } @@ -470,7 +470,7 @@ void SectionChunk::getBaserels(std::vector *Res) { // another DLL) This returns the size the relocation is supposed to update, // in bits, or 0 if the relocation cannot be handled as a runtime pseudo // relocation. -static int getRuntimePseudoRelocSize(uint16_t Type) { +static int getRuntimePseudoRelocSize(uint16_t type) { // Relocations that either contain an absolute address, or a plain // relative offset, since the runtime pseudo reloc implementation // adds 8/16/32/64 bit values to a memory address. @@ -496,9 +496,9 @@ static int getRuntimePseudoRelocSize(uint16_t Type) { // the image, or temporarily changed at runtime with VirtualProtect. // Since this only operates on direct address values, it doesn't work for // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations. - switch (Config->Machine) { + switch (config->machine) { case AMD64: - switch (Type) { + switch (type) { case IMAGE_REL_AMD64_ADDR64: return 64; case IMAGE_REL_AMD64_ADDR32: @@ -513,7 +513,7 @@ static int getRuntimePseudoRelocSize(uint16_t Type) { return 0; } case I386: - switch (Type) { + switch (type) { case IMAGE_REL_I386_DIR32: case IMAGE_REL_I386_REL32: return 32; @@ -521,14 +521,14 @@ static int getRuntimePseudoRelocSize(uint16_t Type) { return 0; } case ARMNT: - switch (Type) { + switch (type) { case IMAGE_REL_ARM_ADDR32: return 32; default: return 0; } case ARM64: - switch (Type) { + switch (type) { case IMAGE_REL_ARM64_ADDR64: return 64; case IMAGE_REL_ARM64_ADDR32: @@ -547,48 +547,48 @@ static int getRuntimePseudoRelocSize(uint16_t Type) { // to a module local variable, which turned out to actually need to be // imported from another DLL). void SectionChunk::getRuntimePseudoRelocs( - std::vector &Res) { - for (const coff_relocation &Rel : getRelocs()) { - auto *Target = - dyn_cast_or_null(File->getSymbol(Rel.SymbolTableIndex)); - if (!Target || !Target->IsRuntimePseudoReloc) + std::vector &res) { + for (const coff_relocation &rel : getRelocs()) { + auto *target = + dyn_cast_or_null(file->getSymbol(rel.SymbolTableIndex)); + if (!target || !target->isRuntimePseudoReloc) continue; - int SizeInBits = getRuntimePseudoRelocSize(Rel.Type); - if (SizeInBits == 0) { - error("unable to automatically import from " + Target->getName() + + int sizeInBits = getRuntimePseudoRelocSize(rel.Type); + if (sizeInBits == 0) { + error("unable to automatically import from " + target->getName() + " with relocation type " + - File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " + - toString(File)); + file->getCOFFObj()->getRelocationTypeName(rel.Type) + " in " + + toString(file)); continue; } // SizeInBits is used to initialize the Flags field; currently no // other flags are defined. - Res.emplace_back( - RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits)); + res.emplace_back( + RuntimePseudoReloc(target, this, rel.VirtualAddress, sizeInBits)); } } bool SectionChunk::isCOMDAT() const { - return Header->Characteristics & IMAGE_SCN_LNK_COMDAT; + return header->Characteristics & IMAGE_SCN_LNK_COMDAT; } void SectionChunk::printDiscardedMessage() const { // Removed by dead-stripping. If it's removed by ICF, ICF already // printed out the name, so don't repeat that here. - if (Sym && this == Repl) - message("Discarded " + Sym->getName()); + if (sym && this == repl) + message("Discarded " + sym->getName()); } StringRef SectionChunk::getDebugName() const { - if (Sym) - return Sym->getName(); + if (sym) + return sym->getName(); return ""; } ArrayRef SectionChunk::getContents() const { - ArrayRef A; - cantFail(File->getCOFFObj()->getSectionContents(Header, A)); - return A; + ArrayRef a; + cantFail(file->getCOFFObj()->getSectionContents(header, a)); + return a; } ArrayRef SectionChunk::consumeDebugMagic() { @@ -596,57 +596,57 @@ ArrayRef SectionChunk::consumeDebugMagic() { return consumeDebugMagic(getContents(), getSectionName()); } -ArrayRef SectionChunk::consumeDebugMagic(ArrayRef Data, - StringRef SectionName) { - if (Data.empty()) +ArrayRef SectionChunk::consumeDebugMagic(ArrayRef data, + StringRef sectionName) { + if (data.empty()) return {}; // First 4 bytes are section magic. - if (Data.size() < 4) - fatal("the section is too short: " + SectionName); + if (data.size() < 4) + fatal("the section is too short: " + sectionName); - if (!SectionName.startswith(".debug$")) - fatal("invalid section: " + SectionName); + if (!sectionName.startswith(".debug$")) + fatal("invalid section: " + sectionName); - uint32_t Magic = support::endian::read32le(Data.data()); - uint32_t ExpectedMagic = SectionName == ".debug$H" + uint32_t magic = support::endian::read32le(data.data()); + uint32_t expectedMagic = sectionName == ".debug$H" ? DEBUG_HASHES_SECTION_MAGIC : DEBUG_SECTION_MAGIC; - if (Magic != ExpectedMagic) { - warn("ignoring section " + SectionName + " with unrecognized magic 0x" + - utohexstr(Magic)); + if (magic != expectedMagic) { + warn("ignoring section " + sectionName + " with unrecognized magic 0x" + + utohexstr(magic)); return {}; } - return Data.slice(4); + return data.slice(4); } -SectionChunk *SectionChunk::findByName(ArrayRef Sections, - StringRef Name) { - for (SectionChunk *C : Sections) - if (C->getSectionName() == Name) - return C; +SectionChunk *SectionChunk::findByName(ArrayRef sections, + StringRef name) { + for (SectionChunk *c : sections) + if (c->getSectionName() == name) + return c; return nullptr; } -void SectionChunk::replace(SectionChunk *Other) { - P2Align = std::max(P2Align, Other->P2Align); - Other->Repl = Repl; - Other->Live = false; +void SectionChunk::replace(SectionChunk *other) { + p2Align = std::max(p2Align, other->p2Align); + other->repl = repl; + other->live = false; } uint32_t SectionChunk::getSectionNumber() const { - DataRefImpl R; - R.p = reinterpret_cast(Header); - SectionRef S(R, File->getCOFFObj()); - return S.getIndex() + 1; + DataRefImpl r; + r.p = reinterpret_cast(header); + SectionRef s(r, file->getCOFFObj()); + return s.getIndex() + 1; } -CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) { +CommonChunk::CommonChunk(const COFFSymbolRef s) : sym(s) { // The value of a common symbol is its size. Align all common symbols smaller // than 32 bytes naturally, i.e. round the size up to the next power of two. // This is what MSVC link.exe does. - setAlignment(std::min(32U, uint32_t(PowerOf2Ceil(Sym.getValue())))); - HasData = false; + setAlignment(std::min(32U, uint32_t(PowerOf2Ceil(sym.getValue())))); + hasData = false; } uint32_t CommonChunk::getOutputCharacteristics() const { @@ -654,139 +654,139 @@ uint32_t CommonChunk::getOutputCharacteristics() const { IMAGE_SCN_MEM_WRITE; } -void StringChunk::writeTo(uint8_t *Buf) const { - memcpy(Buf, Str.data(), Str.size()); - Buf[Str.size()] = '\0'; +void StringChunk::writeTo(uint8_t *buf) const { + memcpy(buf, str.data(), str.size()); + buf[str.size()] = '\0'; } -ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImportThunkChunk(S) { +ImportThunkChunkX64::ImportThunkChunkX64(Defined *s) : ImportThunkChunk(s) { // Intel Optimization Manual says that all branch targets // should be 16-byte aligned. MSVC linker does this too. setAlignment(16); } -void ImportThunkChunkX64::writeTo(uint8_t *Buf) const { - memcpy(Buf, ImportThunkX86, sizeof(ImportThunkX86)); +void ImportThunkChunkX64::writeTo(uint8_t *buf) const { + memcpy(buf, importThunkX86, sizeof(importThunkX86)); // The first two bytes is a JMP instruction. Fill its operand. - write32le(Buf + 2, ImpSymbol->getRVA() - RVA - getSize()); + write32le(buf + 2, impSymbol->getRVA() - rva - getSize()); } -void ImportThunkChunkX86::getBaserels(std::vector *Res) { - Res->emplace_back(getRVA() + 2); +void ImportThunkChunkX86::getBaserels(std::vector *res) { + res->emplace_back(getRVA() + 2); } -void ImportThunkChunkX86::writeTo(uint8_t *Buf) const { - memcpy(Buf, ImportThunkX86, sizeof(ImportThunkX86)); +void ImportThunkChunkX86::writeTo(uint8_t *buf) const { + memcpy(buf, importThunkX86, sizeof(importThunkX86)); // The first two bytes is a JMP instruction. Fill its operand. - write32le(Buf + 2, - ImpSymbol->getRVA() + Config->ImageBase); + write32le(buf + 2, + impSymbol->getRVA() + config->imageBase); } -void ImportThunkChunkARM::getBaserels(std::vector *Res) { - Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T); +void ImportThunkChunkARM::getBaserels(std::vector *res) { + res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T); } -void ImportThunkChunkARM::writeTo(uint8_t *Buf) const { - memcpy(Buf, ImportThunkARM, sizeof(ImportThunkARM)); +void ImportThunkChunkARM::writeTo(uint8_t *buf) const { + memcpy(buf, importThunkARM, sizeof(importThunkARM)); // Fix mov.w and mov.t operands. - applyMOV32T(Buf, ImpSymbol->getRVA() + Config->ImageBase); + applyMOV32T(buf, impSymbol->getRVA() + config->imageBase); } -void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { - int64_t Off = ImpSymbol->getRVA() & 0xfff; - memcpy(Buf, ImportThunkARM64, sizeof(ImportThunkARM64)); - applyArm64Addr(Buf, ImpSymbol->getRVA(), RVA, 12); - applyArm64Ldr(Buf + 4, Off); +void ImportThunkChunkARM64::writeTo(uint8_t *buf) const { + int64_t off = impSymbol->getRVA() & 0xfff; + memcpy(buf, importThunkARM64, sizeof(importThunkARM64)); + applyArm64Addr(buf, impSymbol->getRVA(), rva, 12); + applyArm64Ldr(buf + 4, off); } // A Thumb2, PIC, non-interworking range extension thunk. -const uint8_t ArmThunk[] = { +const uint8_t armThunk[] = { 0x40, 0xf2, 0x00, 0x0c, // P: movw ip,:lower16:S - (P + (L1-P) + 4) 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4) 0xe7, 0x44, // L1: add pc, ip }; size_t RangeExtensionThunkARM::getSize() const { - assert(Config->Machine == ARMNT); - return sizeof(ArmThunk); + assert(config->machine == ARMNT); + return sizeof(armThunk); } -void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const { - assert(Config->Machine == ARMNT); - uint64_t Offset = Target->getRVA() - RVA - 12; - memcpy(Buf, ArmThunk, sizeof(ArmThunk)); - applyMOV32T(Buf, uint32_t(Offset)); +void RangeExtensionThunkARM::writeTo(uint8_t *buf) const { + assert(config->machine == ARMNT); + uint64_t offset = target->getRVA() - rva - 12; + memcpy(buf, armThunk, sizeof(armThunk)); + applyMOV32T(buf, uint32_t(offset)); } // A position independent ARM64 adrp+add thunk, with a maximum range of // +/- 4 GB, which is enough for any PE-COFF. -const uint8_t Arm64Thunk[] = { +const uint8_t arm64Thunk[] = { 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest 0x00, 0x02, 0x1f, 0xd6, // br x16 }; size_t RangeExtensionThunkARM64::getSize() const { - assert(Config->Machine == ARM64); - return sizeof(Arm64Thunk); + assert(config->machine == ARM64); + return sizeof(arm64Thunk); } -void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const { - assert(Config->Machine == ARM64); - memcpy(Buf, Arm64Thunk, sizeof(Arm64Thunk)); - applyArm64Addr(Buf + 0, Target->getRVA(), RVA, 12); - applyArm64Imm(Buf + 4, Target->getRVA() & 0xfff, 0); +void RangeExtensionThunkARM64::writeTo(uint8_t *buf) const { + assert(config->machine == ARM64); + memcpy(buf, arm64Thunk, sizeof(arm64Thunk)); + applyArm64Addr(buf + 0, target->getRVA(), rva, 12); + applyArm64Imm(buf + 4, target->getRVA() & 0xfff, 0); } -void LocalImportChunk::getBaserels(std::vector *Res) { - Res->emplace_back(getRVA()); +void LocalImportChunk::getBaserels(std::vector *res) { + res->emplace_back(getRVA()); } -size_t LocalImportChunk::getSize() const { return Config->Wordsize; } +size_t LocalImportChunk::getSize() const { return config->wordsize; } -void LocalImportChunk::writeTo(uint8_t *Buf) const { - if (Config->is64()) { - write64le(Buf, Sym->getRVA() + Config->ImageBase); +void LocalImportChunk::writeTo(uint8_t *buf) const { + if (config->is64()) { + write64le(buf, sym->getRVA() + config->imageBase); } else { - write32le(Buf, Sym->getRVA() + Config->ImageBase); + write32le(buf, sym->getRVA() + config->imageBase); } } -void RVATableChunk::writeTo(uint8_t *Buf) const { - ulittle32_t *Begin = reinterpret_cast(Buf); - size_t Cnt = 0; - for (const ChunkAndOffset &CO : Syms) - Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset; - std::sort(Begin, Begin + Cnt); - assert(std::unique(Begin, Begin + Cnt) == Begin + Cnt && +void RVATableChunk::writeTo(uint8_t *buf) const { + ulittle32_t *begin = reinterpret_cast(buf); + size_t cnt = 0; + for (const ChunkAndOffset &co : syms) + begin[cnt++] = co.inputChunk->getRVA() + co.offset; + std::sort(begin, begin + cnt); + assert(std::unique(begin, begin + cnt) == begin + cnt && "RVA tables should be de-duplicated"); } // MinGW specific, for the "automatic import of variables from DLLs" feature. size_t PseudoRelocTableChunk::getSize() const { - if (Relocs.empty()) + if (relocs.empty()) return 0; - return 12 + 12 * Relocs.size(); + return 12 + 12 * relocs.size(); } // MinGW specific. -void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const { - if (Relocs.empty()) +void PseudoRelocTableChunk::writeTo(uint8_t *buf) const { + if (relocs.empty()) return; - ulittle32_t *Table = reinterpret_cast(Buf); + ulittle32_t *table = reinterpret_cast(buf); // This is the list header, to signal the runtime pseudo relocation v2 // format. - Table[0] = 0; - Table[1] = 0; - Table[2] = 1; - - size_t Idx = 3; - for (const RuntimePseudoReloc &RPR : Relocs) { - Table[Idx + 0] = RPR.Sym->getRVA(); - Table[Idx + 1] = RPR.Target->getRVA() + RPR.TargetOffset; - Table[Idx + 2] = RPR.Flags; - Idx += 3; + table[0] = 0; + table[1] = 0; + table[2] = 1; + + size_t idx = 3; + for (const RuntimePseudoReloc &rpr : relocs) { + table[idx + 0] = rpr.sym->getRVA(); + table[idx + 1] = rpr.target->getRVA() + rpr.targetOffset; + table[idx + 2] = rpr.flags; + idx += 3; } } @@ -829,26 +829,26 @@ void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const { // // Usually we have a lot of relocations for each page, so the number of // bytes for one .reloc entry is close to 2 bytes on average. -BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) { +BaserelChunk::BaserelChunk(uint32_t page, Baserel *begin, Baserel *end) { // Block header consists of 4 byte page RVA and 4 byte block size. // Each entry is 2 byte. Last entry may be padding. - Data.resize(alignTo((End - Begin) * 2 + 8, 4)); - uint8_t *P = Data.data(); - write32le(P, Page); - write32le(P + 4, Data.size()); - P += 8; - for (Baserel *I = Begin; I != End; ++I) { - write16le(P, (I->Type << 12) | (I->RVA - Page)); - P += 2; + data.resize(alignTo((end - begin) * 2 + 8, 4)); + uint8_t *p = data.data(); + write32le(p, page); + write32le(p + 4, data.size()); + p += 8; + for (Baserel *i = begin; i != end; ++i) { + write16le(p, (i->type << 12) | (i->rva - page)); + p += 2; } } -void BaserelChunk::writeTo(uint8_t *Buf) const { - memcpy(Buf, Data.data(), Data.size()); +void BaserelChunk::writeTo(uint8_t *buf) const { + memcpy(buf, data.data(), data.size()); } uint8_t Baserel::getDefaultType() { - switch (Config->Machine) { + switch (config->machine) { case AMD64: case ARM64: return IMAGE_REL_BASED_DIR64; @@ -860,38 +860,38 @@ uint8_t Baserel::getDefaultType() { } } -MergeChunk *MergeChunk::Instances[Log2MaxSectionAlignment + 1] = {}; +MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {}; -MergeChunk::MergeChunk(uint32_t Alignment) - : Builder(StringTableBuilder::RAW, Alignment) { - setAlignment(Alignment); +MergeChunk::MergeChunk(uint32_t alignment) + : builder(StringTableBuilder::RAW, alignment) { + setAlignment(alignment); } -void MergeChunk::addSection(SectionChunk *C) { - assert(isPowerOf2_32(C->getAlignment())); - uint8_t P2Align = llvm::Log2_32(C->getAlignment()); - assert(P2Align < array_lengthof(Instances)); - auto *&MC = Instances[P2Align]; - if (!MC) - MC = make(C->getAlignment()); - MC->Sections.push_back(C); +void MergeChunk::addSection(SectionChunk *c) { + assert(isPowerOf2_32(c->getAlignment())); + uint8_t p2Align = llvm::Log2_32(c->getAlignment()); + assert(p2Align < array_lengthof(instances)); + auto *&mc = instances[p2Align]; + if (!mc) + mc = make(c->getAlignment()); + mc->sections.push_back(c); } void MergeChunk::finalizeContents() { - assert(!Finalized && "should only finalize once"); - for (SectionChunk *C : Sections) - if (C->Live) - Builder.add(toStringRef(C->getContents())); - Builder.finalize(); - Finalized = true; + assert(!finalized && "should only finalize once"); + for (SectionChunk *c : sections) + if (c->live) + builder.add(toStringRef(c->getContents())); + builder.finalize(); + finalized = true; } void MergeChunk::assignSubsectionRVAs() { - for (SectionChunk *C : Sections) { - if (!C->Live) + for (SectionChunk *c : sections) { + if (!c->live) continue; - size_t Off = Builder.getOffset(toStringRef(C->getContents())); - C->setRVA(RVA + Off); + size_t off = builder.getOffset(toStringRef(c->getContents())); + c->setRVA(rva + off); } } @@ -900,21 +900,21 @@ uint32_t MergeChunk::getOutputCharacteristics() const { } size_t MergeChunk::getSize() const { - return Builder.getSize(); + return builder.getSize(); } -void MergeChunk::writeTo(uint8_t *Buf) const { - Builder.write(Buf); +void MergeChunk::writeTo(uint8_t *buf) const { + builder.write(buf); } // MinGW specific. -size_t AbsolutePointerChunk::getSize() const { return Config->Wordsize; } +size_t AbsolutePointerChunk::getSize() const { return config->wordsize; } -void AbsolutePointerChunk::writeTo(uint8_t *Buf) const { - if (Config->is64()) { - write64le(Buf, Value); +void AbsolutePointerChunk::writeTo(uint8_t *buf) const { + if (config->is64()) { + write64le(buf, value); } else { - write32le(Buf, Value); + write32le(buf, value); } } diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 625a092..6bb629f 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -40,10 +40,10 @@ class RuntimePseudoReloc; class Symbol; // Mask for permissions (discardable, writable, readable, executable, etc). -const uint32_t PermMask = 0xFE000000; +const uint32_t permMask = 0xFE000000; // Mask for section types (code, data, bss). -const uint32_t TypeMask = 0x000000E0; +const uint32_t typeMask = 0x000000E0; // The log base 2 of the largest section alignment, which is log2(8192), or 13. enum : unsigned { Log2MaxSectionAlignment = 13 }; @@ -55,23 +55,23 @@ enum : unsigned { Log2MaxSectionAlignment = 13 }; class Chunk { public: enum Kind : uint8_t { SectionKind, OtherKind, ImportThunkKind }; - Kind kind() const { return ChunkKind; } + Kind kind() const { return chunkKind; } // Returns the size of this chunk (even if this is a common or BSS.) size_t getSize() const; // Returns chunk alignment in power of two form. Value values are powers of // two from 1 to 8192. - uint32_t getAlignment() const { return 1U << P2Align; } + uint32_t getAlignment() const { return 1U << p2Align; } // Update the chunk section alignment measured in bytes. Internally alignment // is stored in log2. - void setAlignment(uint32_t Align) { + void setAlignment(uint32_t align) { // Treat zero byte alignment as 1 byte alignment. - Align = Align ? Align : 1; - assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2"); - P2Align = llvm::Log2_32(Align); - assert(P2Align <= Log2MaxSectionAlignment && + align = align ? align : 1; + assert(llvm::isPowerOf2_32(align) && "alignment is not a power of 2"); + p2Align = llvm::Log2_32(align); + assert(p2Align <= Log2MaxSectionAlignment && "impossible requested alignment"); } @@ -79,15 +79,15 @@ public: // beginning of the file. Because this function may use RVA values // of other chunks for relocations, you need to set them properly // before calling this function. - void writeTo(uint8_t *Buf) const; + void writeTo(uint8_t *buf) const; // The writer sets and uses the addresses. In practice, PE images cannot be // larger than 2GB. Chunks are always laid as part of the image, so Chunk RVAs // can be stored with 32 bits. - uint32_t getRVA() const { return RVA; } - void setRVA(uint64_t V) { - RVA = (uint32_t)V; - assert(RVA == V && "RVA truncated"); + uint32_t getRVA() const { return rva; } + void setRVA(uint64_t v) { + rva = (uint32_t)v; + assert(rva == v && "RVA truncated"); } // Returns readable/writable/executable bits. @@ -99,13 +99,13 @@ public: // An output section has pointers to chunks in the section, and each // chunk has a back pointer to an output section. - void setOutputSectionIdx(uint16_t O) { OSIdx = O; } - uint16_t getOutputSectionIdx() const { return OSIdx; } + void setOutputSectionIdx(uint16_t o) { osidx = o; } + uint16_t getOutputSectionIdx() const { return osidx; } OutputSection *getOutputSection() const; // Windows-specific. // Collect all locations that contain absolute addresses for base relocations. - void getBaserels(std::vector *Res); + void getBaserels(std::vector *res); // Returns a human-readable name of this chunk. Chunks are unnamed chunks of // bytes, so this is used only for logging or debugging. @@ -117,28 +117,28 @@ public: bool isHotPatchable() const; protected: - Chunk(Kind K = OtherKind) : ChunkKind(K), HasData(true), P2Align(0) {} + Chunk(Kind k = OtherKind) : chunkKind(k), hasData(true), p2Align(0) {} - const Kind ChunkKind; + const Kind chunkKind; public: // Returns true if this has non-zero data. BSS chunks return // false. If false is returned, the space occupied by this chunk // will be filled with zeros. Corresponds to the // IMAGE_SCN_CNT_UNINITIALIZED_DATA section characteristic bit. - uint8_t HasData : 1; + uint8_t hasData : 1; public: // The alignment of this chunk, stored in log2 form. The writer uses the // value. - uint8_t P2Align : 7; + uint8_t p2Align : 7; // The output section index for this chunk. The first valid section number is // one. - uint16_t OSIdx = 0; + uint16_t osidx = 0; // The RVA of this chunk in the output. The writer sets a value. - uint32_t RVA = 0; + uint32_t rva = 0; }; class NonSectionChunk : public Chunk { @@ -154,7 +154,7 @@ public: // beginning of the file. Because this function may use RVA values // of other chunks for relocations, you need to set them properly // before calling this function. - virtual void writeTo(uint8_t *Buf) const {} + virtual void writeTo(uint8_t *buf) const {} // Returns the section name if this is a section chunk. // It is illegal to call this function on non-section chunks. @@ -164,16 +164,16 @@ public: // Windows-specific. // Collect all locations that contain absolute addresses for base relocations. - virtual void getBaserels(std::vector *Res) {} + virtual void getBaserels(std::vector *res) {} // Returns a human-readable name of this chunk. Chunks are unnamed chunks of // bytes, so this is used only for logging or debugging. virtual StringRef getDebugName() const { return ""; } - static bool classof(const Chunk *C) { return C->kind() != SectionKind; } + static bool classof(const Chunk *c) { return c->kind() != SectionKind; } protected: - NonSectionChunk(Kind K = OtherKind) : Chunk(K) {} + NonSectionChunk(Kind k = OtherKind) : Chunk(k) {} }; // A chunk corresponding a section of an input file. @@ -187,41 +187,41 @@ public: std::random_access_iterator_tag, Symbol *> { friend SectionChunk; - ObjFile *File; + ObjFile *file; - symbol_iterator(ObjFile *File, const coff_relocation *I) - : symbol_iterator::iterator_adaptor_base(I), File(File) {} + symbol_iterator(ObjFile *file, const coff_relocation *i) + : symbol_iterator::iterator_adaptor_base(i), file(file) {} public: symbol_iterator() = default; - Symbol *operator*() const { return File->getSymbol(I->SymbolTableIndex); } + Symbol *operator*() const { return file->getSymbol(I->SymbolTableIndex); } }; - SectionChunk(ObjFile *File, const coff_section *Header); - static bool classof(const Chunk *C) { return C->kind() == SectionKind; } - size_t getSize() const { return Header->SizeOfRawData; } + SectionChunk(ObjFile *file, const coff_section *header); + static bool classof(const Chunk *c) { return c->kind() == SectionKind; } + size_t getSize() const { return header->SizeOfRawData; } ArrayRef getContents() const; - void writeTo(uint8_t *Buf) const; + void writeTo(uint8_t *buf) const; uint32_t getOutputCharacteristics() const { - return Header->Characteristics & (PermMask | TypeMask); + return header->Characteristics & (permMask | typeMask); } StringRef getSectionName() const { - return StringRef(SectionNameData, SectionNameSize); + return StringRef(sectionNameData, sectionNameSize); } - void getBaserels(std::vector *Res); + void getBaserels(std::vector *res); bool isCOMDAT() const; - void applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, - uint64_t P) const; - void applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, - uint64_t P) const; - void applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, - uint64_t P) const; - void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, - uint64_t P) const; + void applyRelX64(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s, + uint64_t p) const; + void applyRelX86(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s, + uint64_t p) const; + void applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s, + uint64_t p) const; + void applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s, + uint64_t p) const; - void getRuntimePseudoRelocs(std::vector &Res); + void getRuntimePseudoRelocs(std::vector &res); // Called if the garbage collector decides to not include this chunk // in a final output. It's supposed to print out a log message to stdout. @@ -229,7 +229,7 @@ public: // Adds COMDAT associative sections to this COMDAT section. A chunk // and its children are treated as a group by the garbage collector. - void addAssociative(SectionChunk *Child); + void addAssociative(SectionChunk *child); StringRef getDebugName() const; @@ -246,19 +246,19 @@ public: // Allow iteration over the bodies of this chunk's relocated symbols. llvm::iterator_range symbols() const { - return llvm::make_range(symbol_iterator(File, RelocsData), - symbol_iterator(File, RelocsData + RelocsSize)); + return llvm::make_range(symbol_iterator(file, relocsData), + symbol_iterator(file, relocsData + relocsSize)); } ArrayRef getRelocs() const { - return llvm::makeArrayRef(RelocsData, RelocsSize); + return llvm::makeArrayRef(relocsData, relocsSize); } // Reloc setter used by ARM range extension thunk insertion. - void setRelocs(ArrayRef NewRelocs) { - RelocsData = NewRelocs.data(); - RelocsSize = NewRelocs.size(); - assert(RelocsSize == NewRelocs.size() && "reloc size truncation"); + void setRelocs(ArrayRef newRelocs) { + relocsData = newRelocs.data(); + relocsSize = newRelocs.size(); + assert(relocsSize == newRelocs.size() && "reloc size truncation"); } // Single linked list iterator for associated comdat children. @@ -267,26 +267,26 @@ public: AssociatedIterator, std::forward_iterator_tag, SectionChunk> { public: AssociatedIterator() = default; - AssociatedIterator(SectionChunk *Head) : Cur(Head) {} - AssociatedIterator &operator=(const AssociatedIterator &R) { - Cur = R.Cur; + AssociatedIterator(SectionChunk *head) : cur(head) {} + AssociatedIterator &operator=(const AssociatedIterator &r) { + cur = r.cur; return *this; } - bool operator==(const AssociatedIterator &R) const { return Cur == R.Cur; } - const SectionChunk &operator*() const { return *Cur; } - SectionChunk &operator*() { return *Cur; } + bool operator==(const AssociatedIterator &r) const { return cur == r.cur; } + const SectionChunk &operator*() const { return *cur; } + SectionChunk &operator*() { return *cur; } AssociatedIterator &operator++() { - Cur = Cur->AssocChildren; + cur = cur->assocChildren; return *this; } private: - SectionChunk *Cur = nullptr; + SectionChunk *cur = nullptr; }; // Allow iteration over the associated child chunks for this section. llvm::iterator_range children() const { - return llvm::make_range(AssociatedIterator(AssocChildren), + return llvm::make_range(AssociatedIterator(assocChildren), AssociatedIterator(nullptr)); } @@ -295,56 +295,56 @@ public: ArrayRef consumeDebugMagic(); - static ArrayRef consumeDebugMagic(ArrayRef Data, - StringRef SectionName); + static ArrayRef consumeDebugMagic(ArrayRef data, + StringRef sectionName); - static SectionChunk *findByName(ArrayRef Sections, - StringRef Name); + static SectionChunk *findByName(ArrayRef sections, + StringRef name); // The file that this chunk was created from. - ObjFile *File; + ObjFile *file; // Pointer to the COFF section header in the input file. - const coff_section *Header; + const coff_section *header; // The COMDAT leader symbol if this is a COMDAT chunk. - DefinedRegular *Sym = nullptr; + DefinedRegular *sym = nullptr; // The CRC of the contents as described in the COFF spec 4.5.5. // Auxiliary Format 5: Section Definitions. Used for ICF. - uint32_t Checksum = 0; + uint32_t checksum = 0; // Used by the garbage collector. - bool Live; + bool live; // Whether this section needs to be kept distinct from other sections during // ICF. This is set by the driver using address-significance tables. - bool KeepUnique = false; + bool keepUnique = false; // The COMDAT selection if this is a COMDAT chunk. - llvm::COFF::COMDATType Selection = (llvm::COFF::COMDATType)0; + llvm::COFF::COMDATType selection = (llvm::COFF::COMDATType)0; // A pointer pointing to a replacement for this chunk. // Initially it points to "this" object. If this chunk is merged // with other chunk by ICF, it points to another chunk, // and this chunk is considered as dead. - SectionChunk *Repl; + SectionChunk *repl; private: - SectionChunk *AssocChildren = nullptr; + SectionChunk *assocChildren = nullptr; // Used for ICF (Identical COMDAT Folding) - void replace(SectionChunk *Other); - uint32_t Class[2] = {0, 0}; + void replace(SectionChunk *other); + uint32_t eqClass[2] = {0, 0}; // Relocations for this section. Size is stored below. - const coff_relocation *RelocsData; + const coff_relocation *relocsData; // Section name string. Size is stored below. - const char *SectionNameData; + const char *sectionNameData; - uint32_t RelocsSize = 0; - uint32_t SectionNameSize = 0; + uint32_t relocsSize = 0; + uint32_t sectionNameSize = 0; }; // Inline methods to implement faux-virtual dispatch for SectionChunk. @@ -364,11 +364,11 @@ inline uint32_t Chunk::getOutputCharacteristics() const { ->getOutputCharacteristics(); } -inline void Chunk::writeTo(uint8_t *Buf) const { +inline void Chunk::writeTo(uint8_t *buf) const { if (isa(this)) - static_cast(this)->writeTo(Buf); + static_cast(this)->writeTo(buf); else - static_cast(this)->writeTo(Buf); + static_cast(this)->writeTo(buf); } inline StringRef Chunk::getSectionName() const { @@ -378,11 +378,11 @@ inline StringRef Chunk::getSectionName() const { return static_cast(this)->getSectionName(); } -inline void Chunk::getBaserels(std::vector *Res) { +inline void Chunk::getBaserels(std::vector *res) { if (isa(this)) - static_cast(this)->getBaserels(Res); + static_cast(this)->getBaserels(res); else - static_cast(this)->getBaserels(Res); + static_cast(this)->getBaserels(res); } inline StringRef Chunk::getDebugName() const { @@ -403,58 +403,58 @@ inline StringRef Chunk::getDebugName() const { // on the offsets assigned by the StringTableBuilder. class MergeChunk : public NonSectionChunk { public: - MergeChunk(uint32_t Alignment); - static void addSection(SectionChunk *C); + MergeChunk(uint32_t alignment); + static void addSection(SectionChunk *c); void finalizeContents(); void assignSubsectionRVAs(); uint32_t getOutputCharacteristics() const override; StringRef getSectionName() const override { return ".rdata"; } size_t getSize() const override; - void writeTo(uint8_t *Buf) const override; + void writeTo(uint8_t *buf) const override; - static MergeChunk *Instances[Log2MaxSectionAlignment + 1]; - std::vector Sections; + static MergeChunk *instances[Log2MaxSectionAlignment + 1]; + std::vector sections; private: - llvm::StringTableBuilder Builder; - bool Finalized = false; + llvm::StringTableBuilder builder; + bool finalized = false; }; // A chunk for common symbols. Common chunks don't have actual data. class CommonChunk : public NonSectionChunk { public: - CommonChunk(const COFFSymbolRef Sym); - size_t getSize() const override { return Sym.getValue(); } + CommonChunk(const COFFSymbolRef sym); + size_t getSize() const override { return sym.getValue(); } uint32_t getOutputCharacteristics() const override; StringRef getSectionName() const override { return ".bss"; } private: - const COFFSymbolRef Sym; + const COFFSymbolRef sym; }; // A chunk for linker-created strings. class StringChunk : public NonSectionChunk { public: - explicit StringChunk(StringRef S) : Str(S) {} - size_t getSize() const override { return Str.size() + 1; } - void writeTo(uint8_t *Buf) const override; + explicit StringChunk(StringRef s) : str(s) {} + size_t getSize() const override { return str.size() + 1; } + void writeTo(uint8_t *buf) const override; private: - StringRef Str; + StringRef str; }; -static const uint8_t ImportThunkX86[] = { +static const uint8_t importThunkX86[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0 }; -static const uint8_t ImportThunkARM[] = { +static const uint8_t importThunkARM[] = { 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip] }; -static const uint8_t ImportThunkARM64[] = { +static const uint8_t importThunkARM64[] = { 0x10, 0x00, 0x00, 0x90, // adrp x16, #0 0x10, 0x02, 0x40, 0xf9, // ldr x16, [x16] 0x00, 0x02, 0x1f, 0xd6, // br x16 @@ -465,83 +465,83 @@ static const uint8_t ImportThunkARM64[] = { // contents will be a JMP instruction to some __imp_ symbol. class ImportThunkChunk : public NonSectionChunk { public: - ImportThunkChunk(Defined *S) - : NonSectionChunk(ImportThunkKind), ImpSymbol(S) {} - static bool classof(const Chunk *C) { return C->kind() == ImportThunkKind; } + ImportThunkChunk(Defined *s) + : NonSectionChunk(ImportThunkKind), impSymbol(s) {} + static bool classof(const Chunk *c) { return c->kind() == ImportThunkKind; } protected: - Defined *ImpSymbol; + Defined *impSymbol; }; class ImportThunkChunkX64 : public ImportThunkChunk { public: - explicit ImportThunkChunkX64(Defined *S); - size_t getSize() const override { return sizeof(ImportThunkX86); } - void writeTo(uint8_t *Buf) const override; + explicit ImportThunkChunkX64(Defined *s); + size_t getSize() const override { return sizeof(importThunkX86); } + void writeTo(uint8_t *buf) const override; }; class ImportThunkChunkX86 : public ImportThunkChunk { public: - explicit ImportThunkChunkX86(Defined *S) : ImportThunkChunk(S) {} - size_t getSize() const override { return sizeof(ImportThunkX86); } - void getBaserels(std::vector *Res) override; - void writeTo(uint8_t *Buf) const override; + explicit ImportThunkChunkX86(Defined *s) : ImportThunkChunk(s) {} + size_t getSize() const override { return sizeof(importThunkX86); } + void getBaserels(std::vector *res) override; + void writeTo(uint8_t *buf) const override; }; class ImportThunkChunkARM : public ImportThunkChunk { public: - explicit ImportThunkChunkARM(Defined *S) : ImportThunkChunk(S) {} - size_t getSize() const override { return sizeof(ImportThunkARM); } - void getBaserels(std::vector *Res) override; - void writeTo(uint8_t *Buf) const override; + explicit ImportThunkChunkARM(Defined *s) : ImportThunkChunk(s) {} + size_t getSize() const override { return sizeof(importThunkARM); } + void getBaserels(std::vector *res) override; + void writeTo(uint8_t *buf) const override; }; class ImportThunkChunkARM64 : public ImportThunkChunk { public: - explicit ImportThunkChunkARM64(Defined *S) : ImportThunkChunk(S) {} - size_t getSize() const override { return sizeof(ImportThunkARM64); } - void writeTo(uint8_t *Buf) const override; + explicit ImportThunkChunkARM64(Defined *s) : ImportThunkChunk(s) {} + size_t getSize() const override { return sizeof(importThunkARM64); } + void writeTo(uint8_t *buf) const override; }; class RangeExtensionThunkARM : public NonSectionChunk { public: - explicit RangeExtensionThunkARM(Defined *T) : Target(T) {} + explicit RangeExtensionThunkARM(Defined *t) : target(t) {} size_t getSize() const override; - void writeTo(uint8_t *Buf) const override; + void writeTo(uint8_t *buf) const override; - Defined *Target; + Defined *target; }; class RangeExtensionThunkARM64 : public NonSectionChunk { public: - explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {} + explicit RangeExtensionThunkARM64(Defined *t) : target(t) {} size_t getSize() const override; - void writeTo(uint8_t *Buf) const override; + void writeTo(uint8_t *buf) const override; - Defined *Target; + Defined *target; }; // Windows-specific. // See comments for DefinedLocalImport class. class LocalImportChunk : public NonSectionChunk { public: - explicit LocalImportChunk(Defined *S) : Sym(S) { - setAlignment(Config->Wordsize); + explicit LocalImportChunk(Defined *s) : sym(s) { + setAlignment(config->wordsize); } size_t getSize() const override; - void getBaserels(std::vector *Res) override; - void writeTo(uint8_t *Buf) const override; + void getBaserels(std::vector *res) override; + void writeTo(uint8_t *buf) const override; private: - Defined *Sym; + Defined *sym; }; // Duplicate RVAs are not allowed in RVA tables, so unique symbols by chunk and // offset into the chunk. Order does not matter as the RVA table will be sorted // later. struct ChunkAndOffset { - Chunk *InputChunk; - uint32_t Offset; + Chunk *inputChunk; + uint32_t offset; struct DenseMapInfo { static ChunkAndOffset getEmptyKey() { @@ -550,12 +550,12 @@ struct ChunkAndOffset { static ChunkAndOffset getTombstoneKey() { return {llvm::DenseMapInfo::getTombstoneKey(), 0}; } - static unsigned getHashValue(const ChunkAndOffset &CO) { + static unsigned getHashValue(const ChunkAndOffset &co) { return llvm::DenseMapInfo>::getHashValue( - {CO.InputChunk, CO.Offset}); + {co.inputChunk, co.offset}); } - static bool isEqual(const ChunkAndOffset &LHS, const ChunkAndOffset &RHS) { - return LHS.InputChunk == RHS.InputChunk && LHS.Offset == RHS.Offset; + static bool isEqual(const ChunkAndOffset &lhs, const ChunkAndOffset &rhs) { + return lhs.inputChunk == rhs.inputChunk && lhs.offset == rhs.offset; } }; }; @@ -565,12 +565,12 @@ using SymbolRVASet = llvm::DenseSet; // Table which contains symbol RVAs. Used for /safeseh and /guard:cf. class RVATableChunk : public NonSectionChunk { public: - explicit RVATableChunk(SymbolRVASet S) : Syms(std::move(S)) {} - size_t getSize() const override { return Syms.size() * 4; } - void writeTo(uint8_t *Buf) const override; + explicit RVATableChunk(SymbolRVASet s) : syms(std::move(s)) {} + size_t getSize() const override { return syms.size() * 4; } + void writeTo(uint8_t *buf) const override; private: - SymbolRVASet Syms; + SymbolRVASet syms; }; // Windows-specific. @@ -578,22 +578,22 @@ private: // See the PE/COFF spec 5.6 for details. class BaserelChunk : public NonSectionChunk { public: - BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End); - size_t getSize() const override { return Data.size(); } - void writeTo(uint8_t *Buf) const override; + BaserelChunk(uint32_t page, Baserel *begin, Baserel *end); + size_t getSize() const override { return data.size(); } + void writeTo(uint8_t *buf) const override; private: - std::vector Data; + std::vector data; }; class Baserel { public: - Baserel(uint32_t V, uint8_t Ty) : RVA(V), Type(Ty) {} - explicit Baserel(uint32_t V) : Baserel(V, getDefaultType()) {} + Baserel(uint32_t v, uint8_t ty) : rva(v), type(ty) {} + explicit Baserel(uint32_t v) : Baserel(v, getDefaultType()) {} uint8_t getDefaultType(); - uint32_t RVA; - uint8_t Type; + uint32_t rva; + uint8_t type; }; // This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a @@ -604,7 +604,7 @@ class EmptyChunk : public NonSectionChunk { public: EmptyChunk() {} size_t getSize() const override { return 0; } - void writeTo(uint8_t *Buf) const override {} + void writeTo(uint8_t *buf) const override {} }; // MinGW specific, for the "automatic import of variables from DLLs" feature. @@ -615,15 +615,15 @@ public: // code. class PseudoRelocTableChunk : public NonSectionChunk { public: - PseudoRelocTableChunk(std::vector &Relocs) - : Relocs(std::move(Relocs)) { + PseudoRelocTableChunk(std::vector &relocs) + : relocs(std::move(relocs)) { setAlignment(4); } size_t getSize() const override; - void writeTo(uint8_t *Buf) const override; + void writeTo(uint8_t *buf) const override; private: - std::vector Relocs; + std::vector relocs; }; // MinGW specific; information about one individual location in the image @@ -631,48 +631,48 @@ private: // one individual element in the PseudoRelocTableChunk table. class RuntimePseudoReloc { public: - RuntimePseudoReloc(Defined *Sym, SectionChunk *Target, uint32_t TargetOffset, - int Flags) - : Sym(Sym), Target(Target), TargetOffset(TargetOffset), Flags(Flags) {} + RuntimePseudoReloc(Defined *sym, SectionChunk *target, uint32_t targetOffset, + int flags) + : sym(sym), target(target), targetOffset(targetOffset), flags(flags) {} - Defined *Sym; - SectionChunk *Target; - uint32_t TargetOffset; + Defined *sym; + SectionChunk *target; + uint32_t targetOffset; // The Flags field contains the size of the relocation, in bits. No other // flags are currently defined. - int Flags; + int flags; }; // MinGW specific. A Chunk that contains one pointer-sized absolute value. class AbsolutePointerChunk : public NonSectionChunk { public: - AbsolutePointerChunk(uint64_t Value) : Value(Value) { + AbsolutePointerChunk(uint64_t value) : value(value) { setAlignment(getSize()); } size_t getSize() const override; - void writeTo(uint8_t *Buf) const override; + void writeTo(uint8_t *buf) const override; private: - uint64_t Value; + uint64_t value; }; // Return true if this file has the hotpatch flag set to true in the S_COMPILE3 // record in codeview debug info. Also returns true for some thunks synthesized // by the linker. inline bool Chunk::isHotPatchable() const { - if (auto *SC = dyn_cast(this)) - return SC->File->HotPatchable; + if (auto *sc = dyn_cast(this)) + return sc->file->hotPatchable; else if (isa(this)) return true; return false; } -void applyMOV32T(uint8_t *Off, uint32_t V); -void applyBranch24T(uint8_t *Off, int32_t V); +void applyMOV32T(uint8_t *off, uint32_t v); +void applyBranch24T(uint8_t *off, int32_t v); -void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift); -void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit); -void applyArm64Branch26(uint8_t *Off, int64_t V); +void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift); +void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit); +void applyArm64Branch26(uint8_t *off, int64_t v); } // namespace coff } // namespace lld diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 76ef16a..b099cd4 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -38,30 +38,30 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386; // Represents an /export option. struct Export { - StringRef Name; // N in /export:N or /export:E=N - StringRef ExtName; // E in /export:E=N - Symbol *Sym = nullptr; - uint16_t Ordinal = 0; - bool Noname = false; - bool Data = false; - bool Private = false; - bool Constant = false; + StringRef name; // N in /export:N or /export:E=N + StringRef extName; // E in /export:E=N + Symbol *sym = nullptr; + uint16_t ordinal = 0; + bool noname = false; + bool data = false; + bool isPrivate = false; + bool constant = false; // If an export is a form of /export:foo=dllname.bar, that means // that foo should be exported as an alias to bar in the DLL. // ForwardTo is set to "dllname.bar" part. Usually empty. - StringRef ForwardTo; - StringChunk *ForwardChunk = nullptr; + StringRef forwardTo; + StringChunk *forwardChunk = nullptr; // True if this /export option was in .drectves section. - bool Directives = false; - StringRef SymbolName; - StringRef ExportName; // Name in DLL - - bool operator==(const Export &E) { - return (Name == E.Name && ExtName == E.ExtName && - Ordinal == E.Ordinal && Noname == E.Noname && - Data == E.Data && Private == E.Private); + bool directives = false; + StringRef symbolName; + StringRef exportName; // Name in DLL + + bool operator==(const Export &e) { + return (name == e.name && extName == e.extName && + ordinal == e.ordinal && noname == e.noname && + data == e.data && isPrivate == e.isPrivate); } }; @@ -81,137 +81,137 @@ enum class GuardCFLevel { // Global configuration. struct Configuration { enum ManifestKind { SideBySide, Embed, No }; - bool is64() { return Machine == AMD64 || Machine == ARM64; } - - llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN; - size_t Wordsize; - bool Verbose = false; - WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; - Symbol *Entry = nullptr; - bool NoEntry = false; - std::string OutputFile; - std::string ImportName; - bool Demangle = true; - bool DoGC = true; - bool DoICF = true; - bool TailMerge; - bool Relocatable = true; - bool ForceMultiple = false; - bool ForceMultipleRes = false; - bool ForceUnresolved = false; - bool Debug = false; - bool DebugDwarf = false; - bool DebugGHashes = false; - bool DebugSymtab = false; - bool ShowTiming = false; - bool ShowSummary = false; - unsigned DebugTypes = static_cast(DebugType::None); - std::vector NatvisFiles; - llvm::SmallString<128> PDBAltPath; - llvm::SmallString<128> PDBPath; - llvm::SmallString<128> PDBSourcePath; - std::vector Argv; + bool is64() { return machine == AMD64 || machine == ARM64; } + + llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN; + size_t wordsize; + bool verbose = false; + WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; + Symbol *entry = nullptr; + bool noEntry = false; + std::string outputFile; + std::string importName; + bool demangle = true; + bool doGC = true; + bool doICF = true; + bool tailMerge; + bool relocatable = true; + bool forceMultiple = false; + bool forceMultipleRes = false; + bool forceUnresolved = false; + bool debug = false; + bool debugDwarf = false; + bool debugGHashes = false; + bool debugSymtab = false; + bool showTiming = false; + bool showSummary = false; + unsigned debugTypes = static_cast(DebugType::None); + std::vector natvisFiles; + llvm::SmallString<128> pdbAltPath; + llvm::SmallString<128> pdbPath; + llvm::SmallString<128> pdbSourcePath; + std::vector argv; // Symbols in this set are considered as live by the garbage collector. - std::vector GCRoot; + std::vector gCRoot; - std::set NoDefaultLibs; - bool NoDefaultLibAll = false; + std::set noDefaultLibs; + bool noDefaultLibAll = false; // True if we are creating a DLL. - bool DLL = false; - StringRef Implib; - std::vector Exports; - std::set DelayLoads; - std::map DLLOrder; - Symbol *DelayLoadHelper = nullptr; + bool dll = false; + StringRef implib; + std::vector exports; + std::set delayLoads; + std::map dllOrder; + Symbol *delayLoadHelper = nullptr; - bool SaveTemps = false; + bool saveTemps = false; // /guard:cf - GuardCFLevel GuardCF = GuardCFLevel::Off; + GuardCFLevel guardCF = GuardCFLevel::Off; // Used for SafeSEH. - Symbol *SEHTable = nullptr; - Symbol *SEHCount = nullptr; + Symbol *sehTable = nullptr; + Symbol *sehCount = nullptr; // Used for /opt:lldlto=N - unsigned LTOO = 2; + unsigned ltoo = 2; // Used for /opt:lldltojobs=N - unsigned ThinLTOJobs = 0; + unsigned thinLTOJobs = 0; // Used for /opt:lldltopartitions=N - unsigned LTOPartitions = 1; + unsigned ltoPartitions = 1; // Used for /opt:lldltocache=path - StringRef LTOCache; + StringRef ltoCache; // Used for /opt:lldltocachepolicy=policy - llvm::CachePruningPolicy LTOCachePolicy; + llvm::CachePruningPolicy ltoCachePolicy; // Used for /merge:from=to (e.g. /merge:.rdata=.text) - std::map Merge; + std::map merge; // Used for /section=.name,{DEKPRSW} to set section attributes. - std::map Section; + std::map section; // Options for manifest files. - ManifestKind Manifest = No; - int ManifestID = 1; - StringRef ManifestDependency; - bool ManifestUAC = true; - std::vector ManifestInput; - StringRef ManifestLevel = "'asInvoker'"; - StringRef ManifestUIAccess = "'false'"; - StringRef ManifestFile; + ManifestKind manifest = No; + int manifestID = 1; + StringRef manifestDependency; + bool manifestUAC = true; + std::vector manifestInput; + StringRef manifestLevel = "'asInvoker'"; + StringRef manifestUIAccess = "'false'"; + StringRef manifestFile; // Used for /aligncomm. - std::map AlignComm; + std::map alignComm; // Used for /failifmismatch. - std::map> MustMatch; + std::map> mustMatch; // Used for /alternatename. - std::map AlternateNames; + std::map alternateNames; // Used for /order. - llvm::StringMap Order; + llvm::StringMap order; // Used for /lldmap. - std::string MapFile; - - uint64_t ImageBase = -1; - uint64_t FileAlign = 512; - uint64_t StackReserve = 1024 * 1024; - uint64_t StackCommit = 4096; - uint64_t HeapReserve = 1024 * 1024; - uint64_t HeapCommit = 4096; - uint32_t MajorImageVersion = 0; - uint32_t MinorImageVersion = 0; - uint32_t MajorOSVersion = 6; - uint32_t MinorOSVersion = 0; - uint32_t Timestamp = 0; - uint32_t FunctionPadMin = 0; - bool DynamicBase = true; - bool AllowBind = true; - bool NxCompat = true; - bool AllowIsolation = true; - bool TerminalServerAware = true; - bool LargeAddressAware = false; - bool HighEntropyVA = false; - bool AppContainer = false; - bool MinGW = false; - bool WarnMissingOrderSymbol = true; - bool WarnLocallyDefinedImported = true; - bool WarnDebugInfoUnusable = true; - bool Incremental = true; - bool IntegrityCheck = false; - bool KillAt = false; - bool Repro = false; - bool SwaprunCD = false; - bool SwaprunNet = false; + std::string mapFile; + + uint64_t imageBase = -1; + uint64_t fileAlign = 512; + uint64_t stackReserve = 1024 * 1024; + uint64_t stackCommit = 4096; + uint64_t heapReserve = 1024 * 1024; + uint64_t heapCommit = 4096; + uint32_t majorImageVersion = 0; + uint32_t minorImageVersion = 0; + uint32_t majorOSVersion = 6; + uint32_t minorOSVersion = 0; + uint32_t timestamp = 0; + uint32_t functionPadMin = 0; + bool dynamicBase = true; + bool allowBind = true; + bool nxCompat = true; + bool allowIsolation = true; + bool terminalServerAware = true; + bool largeAddressAware = false; + bool highEntropyVA = false; + bool appContainer = false; + bool mingw = false; + bool warnMissingOrderSymbol = true; + bool warnLocallyDefinedImported = true; + bool warnDebugInfoUnusable = true; + bool incremental = true; + bool integrityCheck = false; + bool killAt = false; + bool repro = false; + bool swaprunCD = false; + bool swaprunNet = false; }; -extern Configuration *Config; +extern Configuration *config; } // namespace coff } // namespace lld diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp index 769f02e..bdc5bcb 100644 --- a/lld/COFF/DLL.cpp +++ b/lld/COFF/DLL.cpp @@ -37,41 +37,41 @@ namespace { // A chunk for the import descriptor table. class HintNameChunk : public NonSectionChunk { public: - HintNameChunk(StringRef N, uint16_t H) : Name(N), Hint(H) {} + HintNameChunk(StringRef n, uint16_t h) : name(n), hint(h) {} size_t getSize() const override { // Starts with 2 byte Hint field, followed by a null-terminated string, // ends with 0 or 1 byte padding. - return alignTo(Name.size() + 3, 2); + return alignTo(name.size() + 3, 2); } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, getSize()); - write16le(Buf, Hint); - memcpy(Buf + 2, Name.data(), Name.size()); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, getSize()); + write16le(buf, hint); + memcpy(buf + 2, name.data(), name.size()); } private: - StringRef Name; - uint16_t Hint; + StringRef name; + uint16_t hint; }; // A chunk for the import descriptor table. class LookupChunk : public NonSectionChunk { public: - explicit LookupChunk(Chunk *C) : HintName(C) { - setAlignment(Config->Wordsize); + explicit LookupChunk(Chunk *c) : hintName(c) { + setAlignment(config->wordsize); } - size_t getSize() const override { return Config->Wordsize; } + size_t getSize() const override { return config->wordsize; } - void writeTo(uint8_t *Buf) const override { - if (Config->is64()) - write64le(Buf, HintName->getRVA()); + void writeTo(uint8_t *buf) const override { + if (config->is64()) + write64le(buf, hintName->getRVA()); else - write32le(Buf, HintName->getRVA()); + write32le(buf, hintName->getRVA()); } - Chunk *HintName; + Chunk *hintName; }; // A chunk for the import descriptor table. @@ -79,82 +79,82 @@ public: // See Microsoft PE/COFF spec 7.1. Import Header for details. class OrdinalOnlyChunk : public NonSectionChunk { public: - explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { - setAlignment(Config->Wordsize); + explicit OrdinalOnlyChunk(uint16_t v) : ordinal(v) { + setAlignment(config->wordsize); } - size_t getSize() const override { return Config->Wordsize; } + size_t getSize() const override { return config->wordsize; } - void writeTo(uint8_t *Buf) const override { + void writeTo(uint8_t *buf) const override { // An import-by-ordinal slot has MSB 1 to indicate that // this is import-by-ordinal (and not import-by-name). - if (Config->is64()) { - write64le(Buf, (1ULL << 63) | Ordinal); + if (config->is64()) { + write64le(buf, (1ULL << 63) | ordinal); } else { - write32le(Buf, (1ULL << 31) | Ordinal); + write32le(buf, (1ULL << 31) | ordinal); } } - uint16_t Ordinal; + uint16_t ordinal; }; // A chunk for the import descriptor table. class ImportDirectoryChunk : public NonSectionChunk { public: - explicit ImportDirectoryChunk(Chunk *N) : DLLName(N) {} + explicit ImportDirectoryChunk(Chunk *n) : dllName(n) {} size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, getSize()); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, getSize()); - auto *E = (coff_import_directory_table_entry *)(Buf); - E->ImportLookupTableRVA = LookupTab->getRVA(); - E->NameRVA = DLLName->getRVA(); - E->ImportAddressTableRVA = AddressTab->getRVA(); + auto *e = (coff_import_directory_table_entry *)(buf); + e->ImportLookupTableRVA = lookupTab->getRVA(); + e->NameRVA = dllName->getRVA(); + e->ImportAddressTableRVA = addressTab->getRVA(); } - Chunk *DLLName; - Chunk *LookupTab; - Chunk *AddressTab; + Chunk *dllName; + Chunk *lookupTab; + Chunk *addressTab; }; // A chunk representing null terminator in the import table. // Contents of this chunk is always null bytes. class NullChunk : public NonSectionChunk { public: - explicit NullChunk(size_t N) : Size(N) { HasData = false; } - size_t getSize() const override { return Size; } + explicit NullChunk(size_t n) : size(n) { hasData = false; } + size_t getSize() const override { return size; } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, Size); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, size); } private: - size_t Size; + size_t size; }; static std::vector> -binImports(const std::vector &Imports) { +binImports(const std::vector &imports) { // Group DLL-imported symbols by DLL name because that's how // symbols are layed out in the import descriptor table. - auto Less = [](const std::string &A, const std::string &B) { - return Config->DLLOrder[A] < Config->DLLOrder[B]; + auto less = [](const std::string &a, const std::string &b) { + return config->dllOrder[a] < config->dllOrder[b]; }; std::map, - bool(*)(const std::string &, const std::string &)> M(Less); - for (DefinedImportData *Sym : Imports) - M[Sym->getDLLName().lower()].push_back(Sym); + bool(*)(const std::string &, const std::string &)> m(less); + for (DefinedImportData *sym : imports) + m[sym->getDLLName().lower()].push_back(sym); - std::vector> V; - for (auto &KV : M) { + std::vector> v; + for (auto &kv : m) { // Sort symbols by name for each group. - std::vector &Syms = KV.second; - std::sort(Syms.begin(), Syms.end(), - [](DefinedImportData *A, DefinedImportData *B) { - return A->getName() < B->getName(); + std::vector &syms = kv.second; + std::sort(syms.begin(), syms.end(), + [](DefinedImportData *a, DefinedImportData *b) { + return a->getName() < b->getName(); }); - V.push_back(std::move(Syms)); + v.push_back(std::move(syms)); } - return V; + return v; } // Export table @@ -163,34 +163,34 @@ binImports(const std::vector &Imports) { // A chunk for the delay import descriptor table etnry. class DelayDirectoryChunk : public NonSectionChunk { public: - explicit DelayDirectoryChunk(Chunk *N) : DLLName(N) {} + explicit DelayDirectoryChunk(Chunk *n) : dllName(n) {} size_t getSize() const override { return sizeof(delay_import_directory_table_entry); } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, getSize()); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, getSize()); - auto *E = (delay_import_directory_table_entry *)(Buf); - E->Attributes = 1; - E->Name = DLLName->getRVA(); - E->ModuleHandle = ModuleHandle->getRVA(); - E->DelayImportAddressTable = AddressTab->getRVA(); - E->DelayImportNameTable = NameTab->getRVA(); + auto *e = (delay_import_directory_table_entry *)(buf); + e->Attributes = 1; + e->Name = dllName->getRVA(); + e->ModuleHandle = moduleHandle->getRVA(); + e->DelayImportAddressTable = addressTab->getRVA(); + e->DelayImportNameTable = nameTab->getRVA(); } - Chunk *DLLName; - Chunk *ModuleHandle; - Chunk *AddressTab; - Chunk *NameTab; + Chunk *dllName; + Chunk *moduleHandle; + Chunk *addressTab; + Chunk *nameTab; }; // Initial contents for delay-loaded functions. // This code calls __delayLoadHelper2 function to resolve a symbol // and then overwrites its jump table slot with the result // for subsequent function calls. -static const uint8_t ThunkX64[] = { +static const uint8_t thunkX64[] = { 0x51, // push rcx 0x52, // push rdx 0x41, 0x50, // push r8 @@ -215,7 +215,7 @@ static const uint8_t ThunkX64[] = { 0xFF, 0xE0, // jmp rax }; -static const uint8_t ThunkX86[] = { +static const uint8_t thunkX86[] = { 0x51, // push ecx 0x52, // push edx 0x68, 0, 0, 0, 0, // push offset ___imp__ @@ -226,7 +226,7 @@ static const uint8_t ThunkX86[] = { 0xFF, 0xE0, // jmp eax }; -static const uint8_t ThunkARM[] = { +static const uint8_t thunkARM[] = { 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 __imp_ 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 __imp_ 0x2d, 0xe9, 0x0f, 0x48, // push.w {r0, r1, r2, r3, r11, lr} @@ -242,7 +242,7 @@ static const uint8_t ThunkARM[] = { 0x60, 0x47, // bx ip }; -static const uint8_t ThunkARM64[] = { +static const uint8_t thunkARM64[] = { 0x11, 0x00, 0x00, 0x90, // adrp x17, #0 __imp_ 0x31, 0x02, 0x00, 0x91, // add x17, x17, #0 :lo12:__imp_ 0xfd, 0x7b, 0xb3, 0xa9, // stp x29, x30, [sp, #-208]! @@ -275,117 +275,117 @@ static const uint8_t ThunkARM64[] = { // A chunk for the delay import thunk. class ThunkChunkX64 : public NonSectionChunk { public: - ThunkChunkX64(Defined *I, Chunk *D, Defined *H) - : Imp(I), Desc(D), Helper(H) {} + ThunkChunkX64(Defined *i, Chunk *d, Defined *h) + : imp(i), desc(d), helper(h) {} - size_t getSize() const override { return sizeof(ThunkX64); } + size_t getSize() const override { return sizeof(thunkX64); } - void writeTo(uint8_t *Buf) const override { - memcpy(Buf, ThunkX64, sizeof(ThunkX64)); - write32le(Buf + 36, Imp->getRVA() - RVA - 40); - write32le(Buf + 43, Desc->getRVA() - RVA - 47); - write32le(Buf + 48, Helper->getRVA() - RVA - 52); + void writeTo(uint8_t *buf) const override { + memcpy(buf, thunkX64, sizeof(thunkX64)); + write32le(buf + 36, imp->getRVA() - rva - 40); + write32le(buf + 43, desc->getRVA() - rva - 47); + write32le(buf + 48, helper->getRVA() - rva - 52); } - Defined *Imp = nullptr; - Chunk *Desc = nullptr; - Defined *Helper = nullptr; + Defined *imp = nullptr; + Chunk *desc = nullptr; + Defined *helper = nullptr; }; class ThunkChunkX86 : public NonSectionChunk { public: - ThunkChunkX86(Defined *I, Chunk *D, Defined *H) - : Imp(I), Desc(D), Helper(H) {} + ThunkChunkX86(Defined *i, Chunk *d, Defined *h) + : imp(i), desc(d), helper(h) {} - size_t getSize() const override { return sizeof(ThunkX86); } + size_t getSize() const override { return sizeof(thunkX86); } - void writeTo(uint8_t *Buf) const override { - memcpy(Buf, ThunkX86, sizeof(ThunkX86)); - write32le(Buf + 3, Imp->getRVA() + Config->ImageBase); - write32le(Buf + 8, Desc->getRVA() + Config->ImageBase); - write32le(Buf + 13, Helper->getRVA() - RVA - 17); + void writeTo(uint8_t *buf) const override { + memcpy(buf, thunkX86, sizeof(thunkX86)); + write32le(buf + 3, imp->getRVA() + config->imageBase); + write32le(buf + 8, desc->getRVA() + config->imageBase); + write32le(buf + 13, helper->getRVA() - rva - 17); } - void getBaserels(std::vector *Res) override { - Res->emplace_back(RVA + 3); - Res->emplace_back(RVA + 8); + void getBaserels(std::vector *res) override { + res->emplace_back(rva + 3); + res->emplace_back(rva + 8); } - Defined *Imp = nullptr; - Chunk *Desc = nullptr; - Defined *Helper = nullptr; + Defined *imp = nullptr; + Chunk *desc = nullptr; + Defined *helper = nullptr; }; class ThunkChunkARM : public NonSectionChunk { public: - ThunkChunkARM(Defined *I, Chunk *D, Defined *H) - : Imp(I), Desc(D), Helper(H) {} + ThunkChunkARM(Defined *i, Chunk *d, Defined *h) + : imp(i), desc(d), helper(h) {} - size_t getSize() const override { return sizeof(ThunkARM); } + size_t getSize() const override { return sizeof(thunkARM); } - void writeTo(uint8_t *Buf) const override { - memcpy(Buf, ThunkARM, sizeof(ThunkARM)); - applyMOV32T(Buf + 0, Imp->getRVA() + Config->ImageBase); - applyMOV32T(Buf + 22, Desc->getRVA() + Config->ImageBase); - applyBranch24T(Buf + 30, Helper->getRVA() - RVA - 34); + void writeTo(uint8_t *buf) const override { + memcpy(buf, thunkARM, sizeof(thunkARM)); + applyMOV32T(buf + 0, imp->getRVA() + config->imageBase); + applyMOV32T(buf + 22, desc->getRVA() + config->imageBase); + applyBranch24T(buf + 30, helper->getRVA() - rva - 34); } - void getBaserels(std::vector *Res) override { - Res->emplace_back(RVA + 0, IMAGE_REL_BASED_ARM_MOV32T); - Res->emplace_back(RVA + 22, IMAGE_REL_BASED_ARM_MOV32T); + void getBaserels(std::vector *res) override { + res->emplace_back(rva + 0, IMAGE_REL_BASED_ARM_MOV32T); + res->emplace_back(rva + 22, IMAGE_REL_BASED_ARM_MOV32T); } - Defined *Imp = nullptr; - Chunk *Desc = nullptr; - Defined *Helper = nullptr; + Defined *imp = nullptr; + Chunk *desc = nullptr; + Defined *helper = nullptr; }; class ThunkChunkARM64 : public NonSectionChunk { public: - ThunkChunkARM64(Defined *I, Chunk *D, Defined *H) - : Imp(I), Desc(D), Helper(H) {} - - size_t getSize() const override { return sizeof(ThunkARM64); } - - void writeTo(uint8_t *Buf) const override { - memcpy(Buf, ThunkARM64, sizeof(ThunkARM64)); - applyArm64Addr(Buf + 0, Imp->getRVA(), RVA + 0, 12); - applyArm64Imm(Buf + 4, Imp->getRVA() & 0xfff, 0); - applyArm64Addr(Buf + 52, Desc->getRVA(), RVA + 52, 12); - applyArm64Imm(Buf + 56, Desc->getRVA() & 0xfff, 0); - applyArm64Branch26(Buf + 60, Helper->getRVA() - RVA - 60); + ThunkChunkARM64(Defined *i, Chunk *d, Defined *h) + : imp(i), desc(d), helper(h) {} + + size_t getSize() const override { return sizeof(thunkARM64); } + + void writeTo(uint8_t *buf) const override { + memcpy(buf, thunkARM64, sizeof(thunkARM64)); + applyArm64Addr(buf + 0, imp->getRVA(), rva + 0, 12); + applyArm64Imm(buf + 4, imp->getRVA() & 0xfff, 0); + applyArm64Addr(buf + 52, desc->getRVA(), rva + 52, 12); + applyArm64Imm(buf + 56, desc->getRVA() & 0xfff, 0); + applyArm64Branch26(buf + 60, helper->getRVA() - rva - 60); } - Defined *Imp = nullptr; - Chunk *Desc = nullptr; - Defined *Helper = nullptr; + Defined *imp = nullptr; + Chunk *desc = nullptr; + Defined *helper = nullptr; }; // A chunk for the import descriptor table. class DelayAddressChunk : public NonSectionChunk { public: - explicit DelayAddressChunk(Chunk *C) : Thunk(C) { - setAlignment(Config->Wordsize); + explicit DelayAddressChunk(Chunk *c) : thunk(c) { + setAlignment(config->wordsize); } - size_t getSize() const override { return Config->Wordsize; } + size_t getSize() const override { return config->wordsize; } - void writeTo(uint8_t *Buf) const override { - if (Config->is64()) { - write64le(Buf, Thunk->getRVA() + Config->ImageBase); + void writeTo(uint8_t *buf) const override { + if (config->is64()) { + write64le(buf, thunk->getRVA() + config->imageBase); } else { - uint32_t Bit = 0; + uint32_t bit = 0; // Pointer to thumb code must have the LSB set, so adjust it. - if (Config->Machine == ARMNT) - Bit = 1; - write32le(Buf, (Thunk->getRVA() + Config->ImageBase) | Bit); + if (config->machine == ARMNT) + bit = 1; + write32le(buf, (thunk->getRVA() + config->imageBase) | bit); } } - void getBaserels(std::vector *Res) override { - Res->emplace_back(RVA); + void getBaserels(std::vector *res) override { + res->emplace_back(rva); } - Chunk *Thunk; + Chunk *thunk; }; // Export table @@ -394,248 +394,248 @@ public: // A chunk for the export descriptor table. class ExportDirectoryChunk : public NonSectionChunk { public: - ExportDirectoryChunk(int I, int J, Chunk *D, Chunk *A, Chunk *N, Chunk *O) - : MaxOrdinal(I), NameTabSize(J), DLLName(D), AddressTab(A), NameTab(N), - OrdinalTab(O) {} + ExportDirectoryChunk(int i, int j, Chunk *d, Chunk *a, Chunk *n, Chunk *o) + : maxOrdinal(i), nameTabSize(j), dllName(d), addressTab(a), nameTab(n), + ordinalTab(o) {} size_t getSize() const override { return sizeof(export_directory_table_entry); } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, getSize()); - - auto *E = (export_directory_table_entry *)(Buf); - E->NameRVA = DLLName->getRVA(); - E->OrdinalBase = 0; - E->AddressTableEntries = MaxOrdinal + 1; - E->NumberOfNamePointers = NameTabSize; - E->ExportAddressTableRVA = AddressTab->getRVA(); - E->NamePointerRVA = NameTab->getRVA(); - E->OrdinalTableRVA = OrdinalTab->getRVA(); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, getSize()); + + auto *e = (export_directory_table_entry *)(buf); + e->NameRVA = dllName->getRVA(); + e->OrdinalBase = 0; + e->AddressTableEntries = maxOrdinal + 1; + e->NumberOfNamePointers = nameTabSize; + e->ExportAddressTableRVA = addressTab->getRVA(); + e->NamePointerRVA = nameTab->getRVA(); + e->OrdinalTableRVA = ordinalTab->getRVA(); } - uint16_t MaxOrdinal; - uint16_t NameTabSize; - Chunk *DLLName; - Chunk *AddressTab; - Chunk *NameTab; - Chunk *OrdinalTab; + uint16_t maxOrdinal; + uint16_t nameTabSize; + Chunk *dllName; + Chunk *addressTab; + Chunk *nameTab; + Chunk *ordinalTab; }; class AddressTableChunk : public NonSectionChunk { public: - explicit AddressTableChunk(size_t MaxOrdinal) : Size(MaxOrdinal + 1) {} - size_t getSize() const override { return Size * 4; } + explicit AddressTableChunk(size_t maxOrdinal) : size(maxOrdinal + 1) {} + size_t getSize() const override { return size * 4; } - void writeTo(uint8_t *Buf) const override { - memset(Buf, 0, getSize()); + void writeTo(uint8_t *buf) const override { + memset(buf, 0, getSize()); - for (const Export &E : Config->Exports) { - uint8_t *P = Buf + E.Ordinal * 4; - uint32_t Bit = 0; + for (const Export &e : config->exports) { + uint8_t *p = buf + e.ordinal * 4; + uint32_t bit = 0; // Pointer to thumb code must have the LSB set, so adjust it. - if (Config->Machine == ARMNT && !E.Data) - Bit = 1; - if (E.ForwardChunk) { - write32le(P, E.ForwardChunk->getRVA() | Bit); + if (config->machine == ARMNT && !e.data) + bit = 1; + if (e.forwardChunk) { + write32le(p, e.forwardChunk->getRVA() | bit); } else { - write32le(P, cast(E.Sym)->getRVA() | Bit); + write32le(p, cast(e.sym)->getRVA() | bit); } } } private: - size_t Size; + size_t size; }; class NamePointersChunk : public NonSectionChunk { public: - explicit NamePointersChunk(std::vector &V) : Chunks(V) {} - size_t getSize() const override { return Chunks.size() * 4; } + explicit NamePointersChunk(std::vector &v) : chunks(v) {} + size_t getSize() const override { return chunks.size() * 4; } - void writeTo(uint8_t *Buf) const override { - for (Chunk *C : Chunks) { - write32le(Buf, C->getRVA()); - Buf += 4; + void writeTo(uint8_t *buf) const override { + for (Chunk *c : chunks) { + write32le(buf, c->getRVA()); + buf += 4; } } private: - std::vector Chunks; + std::vector chunks; }; class ExportOrdinalChunk : public NonSectionChunk { public: - explicit ExportOrdinalChunk(size_t I) : Size(I) {} - size_t getSize() const override { return Size * 2; } + explicit ExportOrdinalChunk(size_t i) : size(i) {} + size_t getSize() const override { return size * 2; } - void writeTo(uint8_t *Buf) const override { - for (Export &E : Config->Exports) { - if (E.Noname) + void writeTo(uint8_t *buf) const override { + for (Export &e : config->exports) { + if (e.noname) continue; - write16le(Buf, E.Ordinal); - Buf += 2; + write16le(buf, e.ordinal); + buf += 2; } } private: - size_t Size; + size_t size; }; } // anonymous namespace void IdataContents::create() { - std::vector> V = binImports(Imports); + std::vector> v = binImports(imports); // Create .idata contents for each DLL. - for (std::vector &Syms : V) { + for (std::vector &syms : v) { // Create lookup and address tables. If they have external names, // we need to create HintName chunks to store the names. // If they don't (if they are import-by-ordinals), we store only // ordinal values to the table. - size_t Base = Lookups.size(); - for (DefinedImportData *S : Syms) { - uint16_t Ord = S->getOrdinal(); - if (S->getExternalName().empty()) { - Lookups.push_back(make(Ord)); - Addresses.push_back(make(Ord)); + size_t base = lookups.size(); + for (DefinedImportData *s : syms) { + uint16_t ord = s->getOrdinal(); + if (s->getExternalName().empty()) { + lookups.push_back(make(ord)); + addresses.push_back(make(ord)); continue; } - auto *C = make(S->getExternalName(), Ord); - Lookups.push_back(make(C)); - Addresses.push_back(make(C)); - Hints.push_back(C); + auto *c = make(s->getExternalName(), ord); + lookups.push_back(make(c)); + addresses.push_back(make(c)); + hints.push_back(c); } // Terminate with null values. - Lookups.push_back(make(Config->Wordsize)); - Addresses.push_back(make(Config->Wordsize)); + lookups.push_back(make(config->wordsize)); + addresses.push_back(make(config->wordsize)); - for (int I = 0, E = Syms.size(); I < E; ++I) - Syms[I]->setLocation(Addresses[Base + I]); + for (int i = 0, e = syms.size(); i < e; ++i) + syms[i]->setLocation(addresses[base + i]); // Create the import table header. - DLLNames.push_back(make(Syms[0]->getDLLName())); - auto *Dir = make(DLLNames.back()); - Dir->LookupTab = Lookups[Base]; - Dir->AddressTab = Addresses[Base]; - Dirs.push_back(Dir); + dllNames.push_back(make(syms[0]->getDLLName())); + auto *dir = make(dllNames.back()); + dir->lookupTab = lookups[base]; + dir->addressTab = addresses[base]; + dirs.push_back(dir); } // Add null terminator. - Dirs.push_back(make(sizeof(ImportDirectoryTableEntry))); + dirs.push_back(make(sizeof(ImportDirectoryTableEntry))); } std::vector DelayLoadContents::getChunks() { - std::vector V; - V.insert(V.end(), Dirs.begin(), Dirs.end()); - V.insert(V.end(), Names.begin(), Names.end()); - V.insert(V.end(), HintNames.begin(), HintNames.end()); - V.insert(V.end(), DLLNames.begin(), DLLNames.end()); - return V; + std::vector v; + v.insert(v.end(), dirs.begin(), dirs.end()); + v.insert(v.end(), names.begin(), names.end()); + v.insert(v.end(), hintNames.begin(), hintNames.end()); + v.insert(v.end(), dllNames.begin(), dllNames.end()); + return v; } std::vector DelayLoadContents::getDataChunks() { - std::vector V; - V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end()); - V.insert(V.end(), Addresses.begin(), Addresses.end()); - return V; + std::vector v; + v.insert(v.end(), moduleHandles.begin(), moduleHandles.end()); + v.insert(v.end(), addresses.begin(), addresses.end()); + return v; } uint64_t DelayLoadContents::getDirSize() { - return Dirs.size() * sizeof(delay_import_directory_table_entry); + return dirs.size() * sizeof(delay_import_directory_table_entry); } -void DelayLoadContents::create(Defined *H) { - Helper = H; - std::vector> V = binImports(Imports); +void DelayLoadContents::create(Defined *h) { + helper = h; + std::vector> v = binImports(imports); // Create .didat contents for each DLL. - for (std::vector &Syms : V) { + for (std::vector &syms : v) { // Create the delay import table header. - DLLNames.push_back(make(Syms[0]->getDLLName())); - auto *Dir = make(DLLNames.back()); - - size_t Base = Addresses.size(); - for (DefinedImportData *S : Syms) { - Chunk *T = newThunkChunk(S, Dir); - auto *A = make(T); - Addresses.push_back(A); - Thunks.push_back(T); - StringRef ExtName = S->getExternalName(); - if (ExtName.empty()) { - Names.push_back(make(S->getOrdinal())); + dllNames.push_back(make(syms[0]->getDLLName())); + auto *dir = make(dllNames.back()); + + size_t base = addresses.size(); + for (DefinedImportData *s : syms) { + Chunk *t = newThunkChunk(s, dir); + auto *a = make(t); + addresses.push_back(a); + thunks.push_back(t); + StringRef extName = s->getExternalName(); + if (extName.empty()) { + names.push_back(make(s->getOrdinal())); } else { - auto *C = make(ExtName, 0); - Names.push_back(make(C)); - HintNames.push_back(C); + auto *c = make(extName, 0); + names.push_back(make(c)); + hintNames.push_back(c); } } // Terminate with null values. - Addresses.push_back(make(8)); - Names.push_back(make(8)); + addresses.push_back(make(8)); + names.push_back(make(8)); - for (int I = 0, E = Syms.size(); I < E; ++I) - Syms[I]->setLocation(Addresses[Base + I]); - auto *MH = make(8); - MH->setAlignment(8); - ModuleHandles.push_back(MH); + for (int i = 0, e = syms.size(); i < e; ++i) + syms[i]->setLocation(addresses[base + i]); + auto *mh = make(8); + mh->setAlignment(8); + moduleHandles.push_back(mh); // Fill the delay import table header fields. - Dir->ModuleHandle = MH; - Dir->AddressTab = Addresses[Base]; - Dir->NameTab = Names[Base]; - Dirs.push_back(Dir); + dir->moduleHandle = mh; + dir->addressTab = addresses[base]; + dir->nameTab = names[base]; + dirs.push_back(dir); } // Add null terminator. - Dirs.push_back(make(sizeof(delay_import_directory_table_entry))); + dirs.push_back(make(sizeof(delay_import_directory_table_entry))); } -Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) { - switch (Config->Machine) { +Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *s, Chunk *dir) { + switch (config->machine) { case AMD64: - return make(S, Dir, Helper); + return make(s, dir, helper); case I386: - return make(S, Dir, Helper); + return make(s, dir, helper); case ARMNT: - return make(S, Dir, Helper); + return make(s, dir, helper); case ARM64: - return make(S, Dir, Helper); + return make(s, dir, helper); default: llvm_unreachable("unsupported machine type"); } } EdataContents::EdataContents() { - uint16_t MaxOrdinal = 0; - for (Export &E : Config->Exports) - MaxOrdinal = std::max(MaxOrdinal, E.Ordinal); - - auto *DLLName = make(sys::path::filename(Config->OutputFile)); - auto *AddressTab = make(MaxOrdinal); - std::vector Names; - for (Export &E : Config->Exports) - if (!E.Noname) - Names.push_back(make(E.ExportName)); - - std::vector Forwards; - for (Export &E : Config->Exports) { - if (E.ForwardTo.empty()) + uint16_t maxOrdinal = 0; + for (Export &e : config->exports) + maxOrdinal = std::max(maxOrdinal, e.ordinal); + + auto *dllName = make(sys::path::filename(config->outputFile)); + auto *addressTab = make(maxOrdinal); + std::vector names; + for (Export &e : config->exports) + if (!e.noname) + names.push_back(make(e.exportName)); + + std::vector forwards; + for (Export &e : config->exports) { + if (e.forwardTo.empty()) continue; - E.ForwardChunk = make(E.ForwardTo); - Forwards.push_back(E.ForwardChunk); + e.forwardChunk = make(e.forwardTo); + forwards.push_back(e.forwardChunk); } - auto *NameTab = make(Names); - auto *OrdinalTab = make(Names.size()); - auto *Dir = make(MaxOrdinal, Names.size(), DLLName, - AddressTab, NameTab, OrdinalTab); - Chunks.push_back(Dir); - Chunks.push_back(DLLName); - Chunks.push_back(AddressTab); - Chunks.push_back(NameTab); - Chunks.push_back(OrdinalTab); - Chunks.insert(Chunks.end(), Names.begin(), Names.end()); - Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end()); + auto *nameTab = make(names); + auto *ordinalTab = make(names.size()); + auto *dir = make(maxOrdinal, names.size(), dllName, + addressTab, nameTab, ordinalTab); + chunks.push_back(dir); + chunks.push_back(dllName); + chunks.push_back(addressTab); + chunks.push_back(nameTab); + chunks.push_back(ordinalTab); + chunks.insert(chunks.end(), names.begin(), names.end()); + chunks.insert(chunks.end(), forwards.begin(), forwards.end()); } } // namespace coff diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h index 4ad0298..7f37138 100644 --- a/lld/COFF/DLL.h +++ b/lld/COFF/DLL.h @@ -21,45 +21,45 @@ namespace coff { // call create() to populate the chunk vectors. class IdataContents { public: - void add(DefinedImportData *Sym) { Imports.push_back(Sym); } - bool empty() { return Imports.empty(); } + void add(DefinedImportData *sym) { imports.push_back(sym); } + bool empty() { return imports.empty(); } void create(); - std::vector Imports; - std::vector Dirs; - std::vector Lookups; - std::vector Addresses; - std::vector Hints; - std::vector DLLNames; + std::vector imports; + std::vector dirs; + std::vector lookups; + std::vector addresses; + std::vector hints; + std::vector dllNames; }; // Windows-specific. // DelayLoadContents creates all chunks for the delay-load DLL import table. class DelayLoadContents { public: - void add(DefinedImportData *Sym) { Imports.push_back(Sym); } - bool empty() { return Imports.empty(); } - void create(Defined *Helper); + void add(DefinedImportData *sym) { imports.push_back(sym); } + bool empty() { return imports.empty(); } + void create(Defined *helper); std::vector getChunks(); std::vector getDataChunks(); - ArrayRef getCodeChunks() { return Thunks; } + ArrayRef getCodeChunks() { return thunks; } - uint64_t getDirRVA() { return Dirs[0]->getRVA(); } + uint64_t getDirRVA() { return dirs[0]->getRVA(); } uint64_t getDirSize(); private: - Chunk *newThunkChunk(DefinedImportData *S, Chunk *Dir); + Chunk *newThunkChunk(DefinedImportData *s, Chunk *dir); - Defined *Helper; - std::vector Imports; - std::vector Dirs; - std::vector ModuleHandles; - std::vector Addresses; - std::vector Names; - std::vector HintNames; - std::vector Thunks; - std::vector DLLNames; + Defined *helper; + std::vector imports; + std::vector dirs; + std::vector moduleHandles; + std::vector addresses; + std::vector names; + std::vector hintNames; + std::vector thunks; + std::vector dllNames; }; // Windows-specific. @@ -67,11 +67,11 @@ private: class EdataContents { public: EdataContents(); - std::vector Chunks; + std::vector chunks; - uint64_t getRVA() { return Chunks[0]->getRVA(); } + uint64_t getRVA() { return chunks[0]->getRVA(); } uint64_t getSize() { - return Chunks.back()->getRVA() + Chunks.back()->getSize() - getRVA(); + return chunks.back()->getRVA() + chunks.back()->getSize() - getRVA(); } }; diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp index 770de80..78c1c78 100644 --- a/lld/COFF/DebugTypes.cpp +++ b/lld/COFF/DebugTypes.cpp @@ -32,40 +32,40 @@ namespace { // before any dependent OBJ. class TypeServerSource : public TpiSource { public: - explicit TypeServerSource(MemoryBufferRef M, llvm::pdb::NativeSession *S) - : TpiSource(PDB, nullptr), Session(S), MB(M) {} + explicit TypeServerSource(MemoryBufferRef m, llvm::pdb::NativeSession *s) + : TpiSource(PDB, nullptr), session(s), mb(m) {} // Queue a PDB type server for loading in the COFF Driver - static void enqueue(const ObjFile *DependentFile, - const TypeServer2Record &TS); + static void enqueue(const ObjFile *dependentFile, + const TypeServer2Record &ts); // Create an instance - static Expected getInstance(MemoryBufferRef M); + static Expected getInstance(MemoryBufferRef m); // Fetch the PDB instance loaded for a corresponding dependent OBJ. static Expected - findFromFile(const ObjFile *DependentFile); + findFromFile(const ObjFile *dependentFile); static std::map> - Instances; + instances; // The interface to the PDB (if it was opened successfully) - std::unique_ptr Session; + std::unique_ptr session; private: - MemoryBufferRef MB; + MemoryBufferRef mb; }; // This class represents the debug type stream of an OBJ file that depends on a // PDB type server (see TypeServerSource). class UseTypeServerSource : public TpiSource { public: - UseTypeServerSource(const ObjFile *F, const TypeServer2Record *TS) - : TpiSource(UsingPDB, F), TypeServerDependency(*TS) {} + UseTypeServerSource(const ObjFile *f, const TypeServer2Record *ts) + : TpiSource(UsingPDB, f), typeServerDependency(*ts) {} // Information about the PDB type server dependency, that needs to be loaded // in before merging this OBJ. - TypeServer2Record TypeServerDependency; + TypeServer2Record typeServerDependency; }; // This class represents the debug type stream of a Microsoft precompiled @@ -74,76 +74,76 @@ public: // such files, clang does not. class PrecompSource : public TpiSource { public: - PrecompSource(const ObjFile *F) : TpiSource(PCH, F) {} + PrecompSource(const ObjFile *f) : TpiSource(PCH, f) {} }; // This class represents the debug type stream of an OBJ file that depends on a // Microsoft precompiled headers OBJ (see PrecompSource). class UsePrecompSource : public TpiSource { public: - UsePrecompSource(const ObjFile *F, const PrecompRecord *Precomp) - : TpiSource(UsingPCH, F), PrecompDependency(*Precomp) {} + UsePrecompSource(const ObjFile *f, const PrecompRecord *precomp) + : TpiSource(UsingPCH, f), precompDependency(*precomp) {} // Information about the Precomp OBJ dependency, that needs to be loaded in // before merging this OBJ. - PrecompRecord PrecompDependency; + PrecompRecord precompDependency; }; } // namespace static std::vector> GC; -TpiSource::TpiSource(TpiKind K, const ObjFile *F) : Kind(K), File(F) { +TpiSource::TpiSource(TpiKind k, const ObjFile *f) : kind(k), file(f) { GC.push_back(std::unique_ptr(this)); } -TpiSource *lld::coff::makeTpiSource(const ObjFile *F) { - return new TpiSource(TpiSource::Regular, F); +TpiSource *lld::coff::makeTpiSource(const ObjFile *f) { + return new TpiSource(TpiSource::Regular, f); } -TpiSource *lld::coff::makeUseTypeServerSource(const ObjFile *F, - const TypeServer2Record *TS) { - TypeServerSource::enqueue(F, *TS); - return new UseTypeServerSource(F, TS); +TpiSource *lld::coff::makeUseTypeServerSource(const ObjFile *f, + const TypeServer2Record *ts) { + TypeServerSource::enqueue(f, *ts); + return new UseTypeServerSource(f, ts); } -TpiSource *lld::coff::makePrecompSource(const ObjFile *F) { - return new PrecompSource(F); +TpiSource *lld::coff::makePrecompSource(const ObjFile *f) { + return new PrecompSource(f); } -TpiSource *lld::coff::makeUsePrecompSource(const ObjFile *F, - const PrecompRecord *Precomp) { - return new UsePrecompSource(F, Precomp); +TpiSource *lld::coff::makeUsePrecompSource(const ObjFile *f, + const PrecompRecord *precomp) { + return new UsePrecompSource(f, precomp); } namespace lld { namespace coff { template <> -const PrecompRecord &retrieveDependencyInfo(const TpiSource *Source) { - assert(Source->Kind == TpiSource::UsingPCH); - return ((const UsePrecompSource *)Source)->PrecompDependency; +const PrecompRecord &retrieveDependencyInfo(const TpiSource *source) { + assert(source->kind == TpiSource::UsingPCH); + return ((const UsePrecompSource *)source)->precompDependency; } template <> -const TypeServer2Record &retrieveDependencyInfo(const TpiSource *Source) { - assert(Source->Kind == TpiSource::UsingPDB); - return ((const UseTypeServerSource *)Source)->TypeServerDependency; +const TypeServer2Record &retrieveDependencyInfo(const TpiSource *source) { + assert(source->kind == TpiSource::UsingPDB); + return ((const UseTypeServerSource *)source)->typeServerDependency; } } // namespace coff } // namespace lld std::map> - TypeServerSource::Instances; + TypeServerSource::instances; // Make a PDB path assuming the PDB is in the same folder as the OBJ -static std::string getPdbBaseName(const ObjFile *File, StringRef TSPath) { - StringRef LocalPath = - !File->ParentName.empty() ? File->ParentName : File->getName(); - SmallString<128> Path = sys::path::parent_path(LocalPath); +static std::string getPdbBaseName(const ObjFile *file, StringRef tSPath) { + StringRef localPath = + !file->parentName.empty() ? file->parentName : file->getName(); + SmallString<128> path = sys::path::parent_path(localPath); // Currently, type server PDBs are only created by MSVC cl, which only runs // on Windows, so we can assume type server paths are Windows style. - sys::path::append(Path, sys::path::filename(TSPath, sys::path::Style::windows)); - return Path.str(); + sys::path::append(path, sys::path::filename(tSPath, sys::path::Style::windows)); + return path.str(); } // The casing of the PDB path stamped in the OBJ can differ from the actual path @@ -158,80 +158,80 @@ static std::string normalizePdbPath(StringRef path) { } // If existing, return the actual PDB path on disk. -static Optional findPdbPath(StringRef PDBPath, - const ObjFile *DependentFile) { +static Optional findPdbPath(StringRef pdbPath, + const ObjFile *dependentFile) { // Ensure the file exists before anything else. In some cases, if the path // points to a removable device, Driver::enqueuePath() would fail with an // error (EAGAIN, "resource unavailable try again") which we want to skip // silently. - if (llvm::sys::fs::exists(PDBPath)) - return normalizePdbPath(PDBPath); - std::string Ret = getPdbBaseName(DependentFile, PDBPath); - if (llvm::sys::fs::exists(Ret)) - return normalizePdbPath(Ret); + if (llvm::sys::fs::exists(pdbPath)) + return normalizePdbPath(pdbPath); + std::string ret = getPdbBaseName(dependentFile, pdbPath); + if (llvm::sys::fs::exists(ret)) + return normalizePdbPath(ret); return None; } // Fetch the PDB instance that was already loaded by the COFF Driver. Expected -TypeServerSource::findFromFile(const ObjFile *DependentFile) { - const TypeServer2Record &TS = - retrieveDependencyInfo(DependentFile->DebugTypesObj); +TypeServerSource::findFromFile(const ObjFile *dependentFile) { + const TypeServer2Record &ts = + retrieveDependencyInfo(dependentFile->debugTypesObj); - Optional P = findPdbPath(TS.Name, DependentFile); - if (!P) - return createFileError(TS.Name, errorCodeToError(std::error_code( + Optional p = findPdbPath(ts.Name, dependentFile); + if (!p) + return createFileError(ts.Name, errorCodeToError(std::error_code( ENOENT, std::generic_category()))); - auto It = TypeServerSource::Instances.find(*P); + auto it = TypeServerSource::instances.find(*p); // The PDB file exists on disk, at this point we expect it to have been // inserted in the map by TypeServerSource::loadPDB() - assert(It != TypeServerSource::Instances.end()); + assert(it != TypeServerSource::instances.end()); - std::pair &PDB = It->second; + std::pair &pdb = it->second; - if (!PDB.second) + if (!pdb.second) return createFileError( - *P, createStringError(inconvertibleErrorCode(), PDB.first.c_str())); + *p, createStringError(inconvertibleErrorCode(), pdb.first.c_str())); - pdb::PDBFile &PDBFile = (PDB.second)->Session->getPDBFile(); - pdb::InfoStream &Info = cantFail(PDBFile.getPDBInfoStream()); + pdb::PDBFile &pdbFile = (pdb.second)->session->getPDBFile(); + pdb::InfoStream &info = cantFail(pdbFile.getPDBInfoStream()); // Just because a file with a matching name was found doesn't mean it can be // used. The GUID must match between the PDB header and the OBJ // TypeServer2 record. The 'Age' is used by MSVC incremental compilation. - if (Info.getGuid() != TS.getGuid()) + if (info.getGuid() != ts.getGuid()) return createFileError( - TS.Name, + ts.Name, make_error(pdb::pdb_error_code::signature_out_of_date)); - return PDB.second; + return pdb.second; } // FIXME: Temporary interface until PDBLinker::maybeMergeTypeServerPDB() is // moved here. Expected -lld::coff::findTypeServerSource(const ObjFile *F) { - Expected TS = TypeServerSource::findFromFile(F); - if (!TS) - return TS.takeError(); - return TS.get()->Session.get(); +lld::coff::findTypeServerSource(const ObjFile *f) { + Expected ts = TypeServerSource::findFromFile(f); + if (!ts) + return ts.takeError(); + return ts.get()->session.get(); } // Queue a PDB type server for loading in the COFF Driver -void TypeServerSource::enqueue(const ObjFile *DependentFile, - const TypeServer2Record &TS) { +void TypeServerSource::enqueue(const ObjFile *dependentFile, + const TypeServer2Record &ts) { // Start by finding where the PDB is located (either the record path or next // to the OBJ file) - Optional P = findPdbPath(TS.Name, DependentFile); - if (!P) + Optional p = findPdbPath(ts.Name, dependentFile); + if (!p) return; - auto It = TypeServerSource::Instances.emplace( - *P, std::pair{}); - if (!It.second) + auto it = TypeServerSource::instances.emplace( + *p, std::pair{}); + if (!it.second) return; // another OBJ already scheduled this PDB for load - Driver->enqueuePath(*P, false); + driver->enqueuePath(*p, false); } // Create an instance of TypeServerSource or an error string if the PDB couldn't @@ -239,30 +239,30 @@ void TypeServerSource::enqueue(const ObjFile *DependentFile, // will be merged in. NOTE - a PDB load failure is not a link error: some // debug info will simply be missing from the final PDB - that is the default // accepted behavior. -void lld::coff::loadTypeServerSource(llvm::MemoryBufferRef M) { - std::string Path = normalizePdbPath(M.getBufferIdentifier()); +void lld::coff::loadTypeServerSource(llvm::MemoryBufferRef m) { + std::string path = normalizePdbPath(m.getBufferIdentifier()); - Expected TS = TypeServerSource::getInstance(M); - if (!TS) - TypeServerSource::Instances[Path] = {toString(TS.takeError()), nullptr}; + Expected ts = TypeServerSource::getInstance(m); + if (!ts) + TypeServerSource::instances[path] = {toString(ts.takeError()), nullptr}; else - TypeServerSource::Instances[Path] = {{}, *TS}; + TypeServerSource::instances[path] = {{}, *ts}; } -Expected TypeServerSource::getInstance(MemoryBufferRef M) { - std::unique_ptr ISession; - Error Err = pdb::NativeSession::createFromPdb( - MemoryBuffer::getMemBuffer(M, false), ISession); - if (Err) - return std::move(Err); +Expected TypeServerSource::getInstance(MemoryBufferRef m) { + std::unique_ptr iSession; + Error err = pdb::NativeSession::createFromPdb( + MemoryBuffer::getMemBuffer(m, false), iSession); + if (err) + return std::move(err); - std::unique_ptr Session( - static_cast(ISession.release())); + std::unique_ptr session( + static_cast(iSession.release())); - pdb::PDBFile &PDBFile = Session->getPDBFile(); - Expected Info = PDBFile.getPDBInfoStream(); + pdb::PDBFile &pdbFile = session->getPDBFile(); + Expected info = pdbFile.getPDBInfoStream(); // All PDB Files should have an Info stream. - if (!Info) - return Info.takeError(); - return new TypeServerSource(M, Session.release()); + if (!info) + return info.takeError(); + return new TypeServerSource(m, session.release()); } diff --git a/lld/COFF/DebugTypes.h b/lld/COFF/DebugTypes.h index cb03aba..e37c727 100644 --- a/lld/COFF/DebugTypes.h +++ b/lld/COFF/DebugTypes.h @@ -31,28 +31,28 @@ class TpiSource { public: enum TpiKind { Regular, PCH, UsingPCH, PDB, UsingPDB }; - TpiSource(TpiKind K, const ObjFile *F); + TpiSource(TpiKind k, const ObjFile *f); virtual ~TpiSource() {} - const TpiKind Kind; - const ObjFile *File; + const TpiKind kind; + const ObjFile *file; }; -TpiSource *makeTpiSource(const ObjFile *F); -TpiSource *makeUseTypeServerSource(const ObjFile *F, - const llvm::codeview::TypeServer2Record *TS); -TpiSource *makePrecompSource(const ObjFile *F); -TpiSource *makeUsePrecompSource(const ObjFile *F, - const llvm::codeview::PrecompRecord *Precomp); +TpiSource *makeTpiSource(const ObjFile *f); +TpiSource *makeUseTypeServerSource(const ObjFile *f, + const llvm::codeview::TypeServer2Record *ts); +TpiSource *makePrecompSource(const ObjFile *f); +TpiSource *makeUsePrecompSource(const ObjFile *f, + const llvm::codeview::PrecompRecord *precomp); -void loadTypeServerSource(llvm::MemoryBufferRef M); +void loadTypeServerSource(llvm::MemoryBufferRef m); // Temporary interface to get the dependency -template const T &retrieveDependencyInfo(const TpiSource *Source); +template const T &retrieveDependencyInfo(const TpiSource *source); // Temporary interface until we move PDBLinker::maybeMergeTypeServerPDB here llvm::Expected -findTypeServerSource(const ObjFile *F); +findTypeServerSource(const ObjFile *f); } // namespace coff } // namespace lld diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 24937ab..be9072b 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -54,54 +54,54 @@ using llvm::sys::Process; namespace lld { namespace coff { -static Timer InputFileTimer("Input File Reading", Timer::root()); +static Timer inputFileTimer("Input File Reading", Timer::root()); -Configuration *Config; -LinkerDriver *Driver; +Configuration *config; +LinkerDriver *driver; -bool link(ArrayRef Args, bool CanExitEarly, raw_ostream &Diag) { - errorHandler().LogName = args::getFilenameWithoutExe(Args[0]); - errorHandler().ErrorOS = &Diag; - errorHandler().ColorDiagnostics = Diag.has_colors(); - errorHandler().ErrorLimitExceededMsg = +bool link(ArrayRef args, bool canExitEarly, raw_ostream &diag) { + errorHandler().logName = args::getFilenameWithoutExe(args[0]); + errorHandler().errorOS = &diag; + errorHandler().colorDiagnostics = diag.has_colors(); + errorHandler().errorLimitExceededMsg = "too many errors emitted, stopping now" " (use /errorlimit:0 to see all errors)"; - errorHandler().ExitEarly = CanExitEarly; - Config = make(); + errorHandler().exitEarly = canExitEarly; + config = make(); - Symtab = make(); + symtab = make(); - Driver = make(); - Driver->link(Args); + driver = make(); + driver->link(args); // Call exit() if we can to avoid calling destructors. - if (CanExitEarly) + if (canExitEarly) exitLld(errorCount() ? 1 : 0); freeArena(); - ObjFile::Instances.clear(); - ImportFile::Instances.clear(); - BitcodeFile::Instances.clear(); - memset(MergeChunk::Instances, 0, sizeof(MergeChunk::Instances)); + ObjFile::instances.clear(); + ImportFile::instances.clear(); + BitcodeFile::instances.clear(); + memset(MergeChunk::instances, 0, sizeof(MergeChunk::instances)); return !errorCount(); } // Drop directory components and replace extension with ".exe" or ".dll". -static std::string getOutputPath(StringRef Path) { - auto P = Path.find_last_of("\\/"); - StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1); - const char* E = Config->DLL ? ".dll" : ".exe"; - return (S.substr(0, S.rfind('.')) + E).str(); +static std::string getOutputPath(StringRef path) { + auto p = path.find_last_of("\\/"); + StringRef s = (p == StringRef::npos) ? path : path.substr(p + 1); + const char* e = config->dll ? ".dll" : ".exe"; + return (s.substr(0, s.rfind('.')) + e).str(); } // Returns true if S matches /crtend.?\.o$/. -static bool isCrtend(StringRef S) { - if (!S.endswith(".o")) +static bool isCrtend(StringRef s) { + if (!s.endswith(".o")) return false; - S = S.drop_back(2); - if (S.endswith("crtend")) + s = s.drop_back(2); + if (s.endswith("crtend")) return true; - return !S.empty() && S.drop_back().endswith("crtend"); + return !s.empty() && s.drop_back().endswith("crtend"); } // ErrorOr is not default constructible, so it cannot be used as the type @@ -113,257 +113,257 @@ using MBErrPair = std::pair, std::error_code>; // Create a std::future that opens and maps a file using the best strategy for // the host platform. -static std::future createFutureForFile(std::string Path) { +static std::future createFutureForFile(std::string path) { #if _WIN32 // On Windows, file I/O is relatively slow so it is best to do this // asynchronously. auto Strategy = std::launch::async; #else - auto Strategy = std::launch::deferred; + auto strategy = std::launch::deferred; #endif - return std::async(Strategy, [=]() { - auto MBOrErr = MemoryBuffer::getFile(Path, + return std::async(strategy, [=]() { + auto mbOrErr = MemoryBuffer::getFile(path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); - if (!MBOrErr) - return MBErrPair{nullptr, MBOrErr.getError()}; - return MBErrPair{std::move(*MBOrErr), std::error_code()}; + if (!mbOrErr) + return MBErrPair{nullptr, mbOrErr.getError()}; + return MBErrPair{std::move(*mbOrErr), std::error_code()}; }); } // Symbol names are mangled by prepending "_" on x86. -static StringRef mangle(StringRef Sym) { - assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN); - if (Config->Machine == I386) - return Saver.save("_" + Sym); - return Sym; +static StringRef mangle(StringRef sym) { + assert(config->machine != IMAGE_FILE_MACHINE_UNKNOWN); + if (config->machine == I386) + return saver.save("_" + sym); + return sym; } -static bool findUnderscoreMangle(StringRef Sym) { - Symbol *S = Symtab->findMangle(mangle(Sym)); - return S && !isa(S); +static bool findUnderscoreMangle(StringRef sym) { + Symbol *s = symtab->findMangle(mangle(sym)); + return s && !isa(s); } -MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr MB) { - MemoryBufferRef MBRef = *MB; - make>(std::move(MB)); // take ownership +MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr mb) { + MemoryBufferRef mbref = *mb; + make>(std::move(mb)); // take ownership - if (Driver->Tar) - Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()), - MBRef.getBuffer()); - return MBRef; + if (driver->tar) + driver->tar->append(relativeToRoot(mbref.getBufferIdentifier()), + mbref.getBuffer()); + return mbref; } -void LinkerDriver::addBuffer(std::unique_ptr MB, - bool WholeArchive) { - StringRef Filename = MB->getBufferIdentifier(); +void LinkerDriver::addBuffer(std::unique_ptr mb, + bool wholeArchive) { + StringRef filename = mb->getBufferIdentifier(); - MemoryBufferRef MBRef = takeBuffer(std::move(MB)); - FilePaths.push_back(Filename); + MemoryBufferRef mbref = takeBuffer(std::move(mb)); + filePaths.push_back(filename); // File type is detected by contents, not by file extension. - switch (identify_magic(MBRef.getBuffer())) { + switch (identify_magic(mbref.getBuffer())) { case file_magic::windows_resource: - Resources.push_back(MBRef); + resources.push_back(mbref); break; case file_magic::archive: - if (WholeArchive) { - std::unique_ptr File = - CHECK(Archive::create(MBRef), Filename + ": failed to parse archive"); + if (wholeArchive) { + std::unique_ptr file = + CHECK(Archive::create(mbref), filename + ": failed to parse archive"); - for (MemoryBufferRef M : getArchiveMembers(File.get())) - addArchiveBuffer(M, "", Filename, 0); + for (MemoryBufferRef m : getArchiveMembers(file.get())) + addArchiveBuffer(m, "", filename, 0); return; } - Symtab->addFile(make(MBRef)); + symtab->addFile(make(mbref)); break; case file_magic::bitcode: - Symtab->addFile(make(MBRef, "", 0)); + symtab->addFile(make(mbref, "", 0)); break; case file_magic::coff_object: case file_magic::coff_import_library: - Symtab->addFile(make(MBRef)); + symtab->addFile(make(mbref)); break; case file_magic::pdb: - loadTypeServerSource(MBRef); + loadTypeServerSource(mbref); break; case file_magic::coff_cl_gl_object: - error(Filename + ": is not a native COFF file. Recompile without /GL"); + error(filename + ": is not a native COFF file. Recompile without /GL"); break; case file_magic::pecoff_executable: - if (Filename.endswith_lower(".dll")) { - error(Filename + ": bad file type. Did you specify a DLL instead of an " + if (filename.endswith_lower(".dll")) { + error(filename + ": bad file type. Did you specify a DLL instead of an " "import library?"); break; } LLVM_FALLTHROUGH; default: - error(MBRef.getBufferIdentifier() + ": unknown file type"); + error(mbref.getBufferIdentifier() + ": unknown file type"); break; } } -void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) { - auto Future = - std::make_shared>(createFutureForFile(Path)); - std::string PathStr = Path; +void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) { + auto future = + std::make_shared>(createFutureForFile(path)); + std::string pathStr = path; enqueueTask([=]() { - auto MBOrErr = Future->get(); - if (MBOrErr.second) { - std::string Msg = - "could not open '" + PathStr + "': " + MBOrErr.second.message(); + auto mbOrErr = future->get(); + if (mbOrErr.second) { + std::string msg = + "could not open '" + pathStr + "': " + mbOrErr.second.message(); // Check if the filename is a typo for an option flag. OptTable thinks // that all args that are not known options and that start with / are // filenames, but e.g. `/nodefaultlibs` is more likely a typo for // the option `/nodefaultlib` than a reference to a file in the root // directory. - std::string Nearest; - if (COFFOptTable().findNearest(PathStr, Nearest) > 1) - error(Msg); + std::string nearest; + if (COFFOptTable().findNearest(pathStr, nearest) > 1) + error(msg); else - error(Msg + "; did you mean '" + Nearest + "'"); + error(msg + "; did you mean '" + nearest + "'"); } else - Driver->addBuffer(std::move(MBOrErr.first), WholeArchive); + driver->addBuffer(std::move(mbOrErr.first), wholeArchive); }); } -void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName, - StringRef ParentName, - uint64_t OffsetInArchive) { - file_magic Magic = identify_magic(MB.getBuffer()); - if (Magic == file_magic::coff_import_library) { - InputFile *Imp = make(MB); - Imp->ParentName = ParentName; - Symtab->addFile(Imp); +void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, + StringRef parentName, + uint64_t offsetInArchive) { + file_magic magic = identify_magic(mb.getBuffer()); + if (magic == file_magic::coff_import_library) { + InputFile *imp = make(mb); + imp->parentName = parentName; + symtab->addFile(imp); return; } - InputFile *Obj; - if (Magic == file_magic::coff_object) { - Obj = make(MB); - } else if (Magic == file_magic::bitcode) { - Obj = make(MB, ParentName, OffsetInArchive); + InputFile *obj; + if (magic == file_magic::coff_object) { + obj = make(mb); + } else if (magic == file_magic::bitcode) { + obj = make(mb, parentName, offsetInArchive); } else { - error("unknown file type: " + MB.getBufferIdentifier()); + error("unknown file type: " + mb.getBufferIdentifier()); return; } - Obj->ParentName = ParentName; - Symtab->addFile(Obj); - log("Loaded " + toString(Obj) + " for " + SymName); + obj->parentName = parentName; + symtab->addFile(obj); + log("Loaded " + toString(obj) + " for " + symName); } -void LinkerDriver::enqueueArchiveMember(const Archive::Child &C, - StringRef SymName, - StringRef ParentName) { +void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, + StringRef symName, + StringRef parentName) { - auto ReportBufferError = [=](Error &&E, - StringRef ChildName) { + auto reportBufferError = [=](Error &&e, + StringRef childName) { fatal("could not get the buffer for the member defining symbol " + - SymName + ": " + ParentName + "(" + ChildName + "): " + - toString(std::move(E))); + symName + ": " + parentName + "(" + childName + "): " + + toString(std::move(e))); }; - if (!C.getParent()->isThin()) { - uint64_t OffsetInArchive = C.getChildOffset(); - Expected MBOrErr = C.getMemoryBufferRef(); - if (!MBOrErr) - ReportBufferError(MBOrErr.takeError(), check(C.getFullName())); - MemoryBufferRef MB = MBOrErr.get(); + if (!c.getParent()->isThin()) { + uint64_t offsetInArchive = c.getChildOffset(); + Expected mbOrErr = c.getMemoryBufferRef(); + if (!mbOrErr) + reportBufferError(mbOrErr.takeError(), check(c.getFullName())); + MemoryBufferRef mb = mbOrErr.get(); enqueueTask([=]() { - Driver->addArchiveBuffer(MB, SymName, ParentName, OffsetInArchive); + driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive); }); return; } - std::string ChildName = CHECK( - C.getFullName(), + std::string childName = CHECK( + c.getFullName(), "could not get the filename for the member defining symbol " + - SymName); - auto Future = std::make_shared>( - createFutureForFile(ChildName)); + symName); + auto future = std::make_shared>( + createFutureForFile(childName)); enqueueTask([=]() { - auto MBOrErr = Future->get(); - if (MBOrErr.second) - ReportBufferError(errorCodeToError(MBOrErr.second), ChildName); - Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName, - ParentName, /* OffsetInArchive */ 0); + auto mbOrErr = future->get(); + if (mbOrErr.second) + reportBufferError(errorCodeToError(mbOrErr.second), childName); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName, + parentName, /* OffsetInArchive */ 0); }); } -static bool isDecorated(StringRef Sym) { - return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") || - (!Config->MinGW && Sym.contains('@')); +static bool isDecorated(StringRef sym) { + return sym.startswith("@") || sym.contains("@@") || sym.startswith("?") || + (!config->mingw && sym.contains('@')); } // Parses .drectve section contents and returns a list of files // specified by /defaultlib. -void LinkerDriver::parseDirectives(InputFile *File) { - StringRef S = File->getDirectives(); - if (S.empty()) +void LinkerDriver::parseDirectives(InputFile *file) { + StringRef s = file->getDirectives(); + if (s.empty()) return; - log("Directives: " + toString(File) + ": " + S); + log("Directives: " + toString(file) + ": " + s); - ArgParser Parser; + ArgParser parser; // .drectve is always tokenized using Windows shell rules. // /EXPORT: option can appear too many times, processing in fastpath. - opt::InputArgList Args; - std::vector Exports; - std::tie(Args, Exports) = Parser.parseDirectives(S); + opt::InputArgList args; + std::vector exports; + std::tie(args, exports) = parser.parseDirectives(s); - for (StringRef E : Exports) { + for (StringRef e : exports) { // If a common header file contains dllexported function // declarations, many object files may end up with having the // same /EXPORT options. In order to save cost of parsing them, // we dedup them first. - if (!DirectivesExports.insert(E).second) + if (!directivesExports.insert(e).second) continue; - Export Exp = parseExport(E); - if (Config->Machine == I386 && Config->MinGW) { - if (!isDecorated(Exp.Name)) - Exp.Name = Saver.save("_" + Exp.Name); - if (!Exp.ExtName.empty() && !isDecorated(Exp.ExtName)) - Exp.ExtName = Saver.save("_" + Exp.ExtName); + Export exp = parseExport(e); + if (config->machine == I386 && config->mingw) { + if (!isDecorated(exp.name)) + exp.name = saver.save("_" + exp.name); + if (!exp.extName.empty() && !isDecorated(exp.extName)) + exp.extName = saver.save("_" + exp.extName); } - Exp.Directives = true; - Config->Exports.push_back(Exp); + exp.directives = true; + config->exports.push_back(exp); } - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_aligncomm: - parseAligncomm(Arg->getValue()); + parseAligncomm(arg->getValue()); break; case OPT_alternatename: - parseAlternateName(Arg->getValue()); + parseAlternateName(arg->getValue()); break; case OPT_defaultlib: - if (Optional Path = findLib(Arg->getValue())) - enqueuePath(*Path, false); + if (Optional path = findLib(arg->getValue())) + enqueuePath(*path, false); break; case OPT_entry: - Config->Entry = addUndefined(mangle(Arg->getValue())); + config->entry = addUndefined(mangle(arg->getValue())); break; case OPT_failifmismatch: - checkFailIfMismatch(Arg->getValue(), File); + checkFailIfMismatch(arg->getValue(), file); break; case OPT_incl: - addUndefined(Arg->getValue()); + addUndefined(arg->getValue()); break; case OPT_merge: - parseMerge(Arg->getValue()); + parseMerge(arg->getValue()); break; case OPT_nodefaultlib: - Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()).lower()); + config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower()); break; case OPT_section: - parseSection(Arg->getValue()); + parseSection(arg->getValue()); break; case OPT_subsystem: - parseSubsystem(Arg->getValue(), &Config->Subsystem, - &Config->MajorOSVersion, &Config->MinorOSVersion); + parseSubsystem(arg->getValue(), &config->subsystem, + &config->majorOSVersion, &config->minorOSVersion); break; // Only add flags here that link.exe accepts in // `#pragma comment(linker, "/flag")`-generated sections. @@ -372,138 +372,138 @@ void LinkerDriver::parseDirectives(InputFile *File) { case OPT_throwingnew: break; default: - error(Arg->getSpelling() + " is not allowed in .drectve"); + error(arg->getSpelling() + " is not allowed in .drectve"); } } } // Find file from search paths. You can omit ".obj", this function takes // care of that. Note that the returned path is not guaranteed to exist. -StringRef LinkerDriver::doFindFile(StringRef Filename) { - bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos); - if (HasPathSep) - return Filename; - bool HasExt = Filename.contains('.'); - for (StringRef Dir : SearchPaths) { - SmallString<128> Path = Dir; - sys::path::append(Path, Filename); - if (sys::fs::exists(Path.str())) - return Saver.save(Path.str()); - if (!HasExt) { - Path.append(".obj"); - if (sys::fs::exists(Path.str())) - return Saver.save(Path.str()); +StringRef LinkerDriver::doFindFile(StringRef filename) { + bool hasPathSep = (filename.find_first_of("/\\") != StringRef::npos); + if (hasPathSep) + return filename; + bool hasExt = filename.contains('.'); + for (StringRef dir : searchPaths) { + SmallString<128> path = dir; + sys::path::append(path, filename); + if (sys::fs::exists(path.str())) + return saver.save(path.str()); + if (!hasExt) { + path.append(".obj"); + if (sys::fs::exists(path.str())) + return saver.save(path.str()); } } - return Filename; + return filename; } -static Optional getUniqueID(StringRef Path) { - sys::fs::UniqueID Ret; - if (sys::fs::getUniqueID(Path, Ret)) +static Optional getUniqueID(StringRef path) { + sys::fs::UniqueID ret; + if (sys::fs::getUniqueID(path, ret)) return None; - return Ret; + return ret; } // Resolves a file path. This never returns the same path // (in that case, it returns None). -Optional LinkerDriver::findFile(StringRef Filename) { - StringRef Path = doFindFile(Filename); +Optional LinkerDriver::findFile(StringRef filename) { + StringRef path = doFindFile(filename); - if (Optional ID = getUniqueID(Path)) { - bool Seen = !VisitedFiles.insert(*ID).second; - if (Seen) + if (Optional id = getUniqueID(path)) { + bool seen = !visitedFiles.insert(*id).second; + if (seen) return None; } - if (Path.endswith_lower(".lib")) - VisitedLibs.insert(sys::path::filename(Path)); - return Path; + if (path.endswith_lower(".lib")) + visitedLibs.insert(sys::path::filename(path)); + return path; } // MinGW specific. If an embedded directive specified to link to // foo.lib, but it isn't found, try libfoo.a instead. -StringRef LinkerDriver::doFindLibMinGW(StringRef Filename) { - if (Filename.contains('/') || Filename.contains('\\')) - return Filename; - - SmallString<128> S = Filename; - sys::path::replace_extension(S, ".a"); - StringRef LibName = Saver.save("lib" + S.str()); - return doFindFile(LibName); +StringRef LinkerDriver::doFindLibMinGW(StringRef filename) { + if (filename.contains('/') || filename.contains('\\')) + return filename; + + SmallString<128> s = filename; + sys::path::replace_extension(s, ".a"); + StringRef libName = saver.save("lib" + s.str()); + return doFindFile(libName); } // Find library file from search path. -StringRef LinkerDriver::doFindLib(StringRef Filename) { +StringRef LinkerDriver::doFindLib(StringRef filename) { // Add ".lib" to Filename if that has no file extension. - bool HasExt = Filename.contains('.'); - if (!HasExt) - Filename = Saver.save(Filename + ".lib"); - StringRef Ret = doFindFile(Filename); + bool hasExt = filename.contains('.'); + if (!hasExt) + filename = saver.save(filename + ".lib"); + StringRef ret = doFindFile(filename); // For MinGW, if the find above didn't turn up anything, try // looking for a MinGW formatted library name. - if (Config->MinGW && Ret == Filename) - return doFindLibMinGW(Filename); - return Ret; + if (config->mingw && ret == filename) + return doFindLibMinGW(filename); + return ret; } // Resolves a library path. /nodefaultlib options are taken into // consideration. This never returns the same path (in that case, // it returns None). -Optional LinkerDriver::findLib(StringRef Filename) { - if (Config->NoDefaultLibAll) +Optional LinkerDriver::findLib(StringRef filename) { + if (config->noDefaultLibAll) return None; - if (!VisitedLibs.insert(Filename.lower()).second) + if (!visitedLibs.insert(filename.lower()).second) return None; - StringRef Path = doFindLib(Filename); - if (Config->NoDefaultLibs.count(Path.lower())) + StringRef path = doFindLib(filename); + if (config->noDefaultLibs.count(path.lower())) return None; - if (Optional ID = getUniqueID(Path)) - if (!VisitedFiles.insert(*ID).second) + if (Optional id = getUniqueID(path)) + if (!visitedFiles.insert(*id).second) return None; - return Path; + return path; } // Parses LIB environment which contains a list of search paths. void LinkerDriver::addLibSearchPaths() { - Optional EnvOpt = Process::GetEnv("LIB"); - if (!EnvOpt.hasValue()) + Optional envOpt = Process::GetEnv("LIB"); + if (!envOpt.hasValue()) return; - StringRef Env = Saver.save(*EnvOpt); - while (!Env.empty()) { - StringRef Path; - std::tie(Path, Env) = Env.split(';'); - SearchPaths.push_back(Path); + StringRef env = saver.save(*envOpt); + while (!env.empty()) { + StringRef path; + std::tie(path, env) = env.split(';'); + searchPaths.push_back(path); } } -Symbol *LinkerDriver::addUndefined(StringRef Name) { - Symbol *B = Symtab->addUndefined(Name); - if (!B->IsGCRoot) { - B->IsGCRoot = true; - Config->GCRoot.push_back(B); +Symbol *LinkerDriver::addUndefined(StringRef name) { + Symbol *b = symtab->addUndefined(name); + if (!b->isGCRoot) { + b->isGCRoot = true; + config->gCRoot.push_back(b); } - return B; + return b; } -StringRef LinkerDriver::mangleMaybe(Symbol *S) { +StringRef LinkerDriver::mangleMaybe(Symbol *s) { // If the plain symbol name has already been resolved, do nothing. - Undefined *Unmangled = dyn_cast(S); - if (!Unmangled) + Undefined *unmangled = dyn_cast(s); + if (!unmangled) return ""; // Otherwise, see if a similar, mangled symbol exists in the symbol table. - Symbol *Mangled = Symtab->findMangle(Unmangled->getName()); - if (!Mangled) + Symbol *mangled = symtab->findMangle(unmangled->getName()); + if (!mangled) return ""; // If we find a similar mangled symbol, make this an alias to it and return // its name. - log(Unmangled->getName() + " aliased to " + Mangled->getName()); - Unmangled->WeakAlias = Symtab->addUndefined(Mangled->getName()); - return Mangled->getName(); + log(unmangled->getName() + " aliased to " + mangled->getName()); + unmangled->weakAlias = symtab->addUndefined(mangled->getName()); + return mangled->getName(); } // Windows specific -- find default entry point name. @@ -512,15 +512,15 @@ StringRef LinkerDriver::mangleMaybe(Symbol *S) { // each of which corresponds to a user-defined "main" function. This function // infers an entry point from a user-defined "main" function. StringRef LinkerDriver::findDefaultEntry() { - assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN && + assert(config->subsystem != IMAGE_SUBSYSTEM_UNKNOWN && "must handle /subsystem before calling this"); - if (Config->MinGW) - return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI + if (config->mingw) + return mangle(config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? "WinMainCRTStartup" : "mainCRTStartup"); - if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { + if (config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { if (findUnderscoreMangle("wWinMain")) { if (!findUnderscoreMangle("WinMain")) return mangle("wWinMainCRTStartup"); @@ -537,44 +537,44 @@ StringRef LinkerDriver::findDefaultEntry() { } WindowsSubsystem LinkerDriver::inferSubsystem() { - if (Config->DLL) + if (config->dll) return IMAGE_SUBSYSTEM_WINDOWS_GUI; - if (Config->MinGW) + if (config->mingw) return IMAGE_SUBSYSTEM_WINDOWS_CUI; // Note that link.exe infers the subsystem from the presence of these // functions even if /entry: or /nodefaultlib are passed which causes them // to not be called. - bool HaveMain = findUnderscoreMangle("main"); - bool HaveWMain = findUnderscoreMangle("wmain"); - bool HaveWinMain = findUnderscoreMangle("WinMain"); - bool HaveWWinMain = findUnderscoreMangle("wWinMain"); - if (HaveMain || HaveWMain) { - if (HaveWinMain || HaveWWinMain) { - warn(std::string("found ") + (HaveMain ? "main" : "wmain") + " and " + - (HaveWinMain ? "WinMain" : "wWinMain") + + bool haveMain = findUnderscoreMangle("main"); + bool haveWMain = findUnderscoreMangle("wmain"); + bool haveWinMain = findUnderscoreMangle("WinMain"); + bool haveWWinMain = findUnderscoreMangle("wWinMain"); + if (haveMain || haveWMain) { + if (haveWinMain || haveWWinMain) { + warn(std::string("found ") + (haveMain ? "main" : "wmain") + " and " + + (haveWinMain ? "WinMain" : "wWinMain") + "; defaulting to /subsystem:console"); } return IMAGE_SUBSYSTEM_WINDOWS_CUI; } - if (HaveWinMain || HaveWWinMain) + if (haveWinMain || haveWWinMain) return IMAGE_SUBSYSTEM_WINDOWS_GUI; return IMAGE_SUBSYSTEM_UNKNOWN; } static uint64_t getDefaultImageBase() { - if (Config->is64()) - return Config->DLL ? 0x180000000 : 0x140000000; - return Config->DLL ? 0x10000000 : 0x400000; + if (config->is64()) + return config->dll ? 0x180000000 : 0x140000000; + return config->dll ? 0x10000000 : 0x400000; } -static std::string createResponseFile(const opt::InputArgList &Args, - ArrayRef FilePaths, - ArrayRef SearchPaths) { - SmallString<0> Data; - raw_svector_ostream OS(Data); +static std::string createResponseFile(const opt::InputArgList &args, + ArrayRef filePaths, + ArrayRef searchPaths) { + SmallString<0> data; + raw_svector_ostream os(data); - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_linkrepro: case OPT_INPUT: case OPT_defaultlib: @@ -589,34 +589,34 @@ static std::string createResponseFile(const opt::InputArgList &Args, case OPT_implib: case OPT_pdb: case OPT_out: - OS << Arg->getSpelling() << sys::path::filename(Arg->getValue()) << "\n"; + os << arg->getSpelling() << sys::path::filename(arg->getValue()) << "\n"; break; default: - OS << toString(*Arg) << "\n"; + os << toString(*arg) << "\n"; } } - for (StringRef Path : SearchPaths) { - std::string RelPath = relativeToRoot(Path); - OS << "/libpath:" << quote(RelPath) << "\n"; + for (StringRef path : searchPaths) { + std::string relPath = relativeToRoot(path); + os << "/libpath:" << quote(relPath) << "\n"; } - for (StringRef Path : FilePaths) - OS << quote(relativeToRoot(Path)) << "\n"; + for (StringRef path : filePaths) + os << quote(relativeToRoot(path)) << "\n"; - return Data.str(); + return data.str(); } enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab }; -static DebugKind parseDebugKind(const opt::InputArgList &Args) { - auto *A = Args.getLastArg(OPT_debug, OPT_debug_opt); - if (!A) +static DebugKind parseDebugKind(const opt::InputArgList &args) { + auto *a = args.getLastArg(OPT_debug, OPT_debug_opt); + if (!a) return DebugKind::None; - if (A->getNumValues() == 0) + if (a->getNumValues() == 0) return DebugKind::Full; - DebugKind Debug = StringSwitch(A->getValue()) + DebugKind debug = StringSwitch(a->getValue()) .CaseLower("none", DebugKind::None) .CaseLower("full", DebugKind::Full) .CaseLower("fastlink", DebugKind::FastLink) @@ -626,68 +626,68 @@ static DebugKind parseDebugKind(const opt::InputArgList &Args) { .CaseLower("symtab", DebugKind::Symtab) .Default(DebugKind::Unknown); - if (Debug == DebugKind::FastLink) { + if (debug == DebugKind::FastLink) { warn("/debug:fastlink unsupported; using /debug:full"); return DebugKind::Full; } - if (Debug == DebugKind::Unknown) { - error("/debug: unknown option: " + Twine(A->getValue())); + if (debug == DebugKind::Unknown) { + error("/debug: unknown option: " + Twine(a->getValue())); return DebugKind::None; } - return Debug; + return debug; } -static unsigned parseDebugTypes(const opt::InputArgList &Args) { - unsigned DebugTypes = static_cast(DebugType::None); +static unsigned parseDebugTypes(const opt::InputArgList &args) { + unsigned debugTypes = static_cast(DebugType::None); - if (auto *A = Args.getLastArg(OPT_debugtype)) { - SmallVector Types; - StringRef(A->getValue()) - .split(Types, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); + if (auto *a = args.getLastArg(OPT_debugtype)) { + SmallVector types; + StringRef(a->getValue()) + .split(types, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); - for (StringRef Type : Types) { - unsigned V = StringSwitch(Type.lower()) + for (StringRef type : types) { + unsigned v = StringSwitch(type.lower()) .Case("cv", static_cast(DebugType::CV)) .Case("pdata", static_cast(DebugType::PData)) .Case("fixup", static_cast(DebugType::Fixup)) .Default(0); - if (V == 0) { - warn("/debugtype: unknown option '" + Type + "'"); + if (v == 0) { + warn("/debugtype: unknown option '" + type + "'"); continue; } - DebugTypes |= V; + debugTypes |= v; } - return DebugTypes; + return debugTypes; } // Default debug types - DebugTypes = static_cast(DebugType::CV); - if (Args.hasArg(OPT_driver)) - DebugTypes |= static_cast(DebugType::PData); - if (Args.hasArg(OPT_profile)) - DebugTypes |= static_cast(DebugType::Fixup); + debugTypes = static_cast(DebugType::CV); + if (args.hasArg(OPT_driver)) + debugTypes |= static_cast(DebugType::PData); + if (args.hasArg(OPT_profile)) + debugTypes |= static_cast(DebugType::Fixup); - return DebugTypes; + return debugTypes; } -static std::string getMapFile(const opt::InputArgList &Args) { - auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file); - if (!Arg) +static std::string getMapFile(const opt::InputArgList &args) { + auto *arg = args.getLastArg(OPT_lldmap, OPT_lldmap_file); + if (!arg) return ""; - if (Arg->getOption().getID() == OPT_lldmap_file) - return Arg->getValue(); + if (arg->getOption().getID() == OPT_lldmap_file) + return arg->getValue(); - assert(Arg->getOption().getID() == OPT_lldmap); - StringRef OutFile = Config->OutputFile; - return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str(); + assert(arg->getOption().getID() == OPT_lldmap); + StringRef outFile = config->outputFile; + return (outFile.substr(0, outFile.rfind('.')) + ".map").str(); } static std::string getImplibPath() { - if (!Config->Implib.empty()) - return Config->Implib; - SmallString<128> Out = StringRef(Config->OutputFile); - sys::path::replace_extension(Out, ".lib"); - return Out.str(); + if (!config->implib.empty()) + return config->implib; + SmallString<128> out = StringRef(config->outputFile); + sys::path::replace_extension(out, ".lib"); + return out.str(); } // @@ -698,226 +698,226 @@ static std::string getImplibPath() { // LINK | {value} | {value}.{.dll/.exe} | {output name} // LIB | {value} | {value}.dll | {output name}.dll // -static std::string getImportName(bool AsLib) { - SmallString<128> Out; +static std::string getImportName(bool asLib) { + SmallString<128> out; - if (Config->ImportName.empty()) { - Out.assign(sys::path::filename(Config->OutputFile)); - if (AsLib) - sys::path::replace_extension(Out, ".dll"); + if (config->importName.empty()) { + out.assign(sys::path::filename(config->outputFile)); + if (asLib) + sys::path::replace_extension(out, ".dll"); } else { - Out.assign(Config->ImportName); - if (!sys::path::has_extension(Out)) - sys::path::replace_extension(Out, - (Config->DLL || AsLib) ? ".dll" : ".exe"); + out.assign(config->importName); + if (!sys::path::has_extension(out)) + sys::path::replace_extension(out, + (config->dll || asLib) ? ".dll" : ".exe"); } - return Out.str(); + return out.str(); } -static void createImportLibrary(bool AsLib) { - std::vector Exports; - for (Export &E1 : Config->Exports) { - COFFShortExport E2; - E2.Name = E1.Name; - E2.SymbolName = E1.SymbolName; - E2.ExtName = E1.ExtName; - E2.Ordinal = E1.Ordinal; - E2.Noname = E1.Noname; - E2.Data = E1.Data; - E2.Private = E1.Private; - E2.Constant = E1.Constant; - Exports.push_back(E2); - } - - auto HandleError = [](Error &&E) { - handleAllErrors(std::move(E), - [](ErrorInfoBase &EIB) { error(EIB.message()); }); +static void createImportLibrary(bool asLib) { + std::vector exports; + for (Export &e1 : config->exports) { + COFFShortExport e2; + e2.Name = e1.name; + e2.SymbolName = e1.symbolName; + e2.ExtName = e1.extName; + e2.Ordinal = e1.ordinal; + e2.Noname = e1.noname; + e2.Data = e1.data; + e2.Private = e1.isPrivate; + e2.Constant = e1.constant; + exports.push_back(e2); + } + + auto handleError = [](Error &&e) { + handleAllErrors(std::move(e), + [](ErrorInfoBase &eib) { error(eib.message()); }); }; - std::string LibName = getImportName(AsLib); - std::string Path = getImplibPath(); + std::string libName = getImportName(asLib); + std::string path = getImplibPath(); - if (!Config->Incremental) { - HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, - Config->MinGW)); + if (!config->incremental) { + handleError(writeImportLibrary(libName, path, exports, config->machine, + config->mingw)); return; } // If the import library already exists, replace it only if the contents // have changed. - ErrorOr> OldBuf = MemoryBuffer::getFile( - Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); - if (!OldBuf) { - HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, - Config->MinGW)); + ErrorOr> oldBuf = MemoryBuffer::getFile( + path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); + if (!oldBuf) { + handleError(writeImportLibrary(libName, path, exports, config->machine, + config->mingw)); return; } - SmallString<128> TmpName; - if (std::error_code EC = - sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName)) - fatal("cannot create temporary file for import library " + Path + ": " + - EC.message()); + SmallString<128> tmpName; + if (std::error_code ec = + sys::fs::createUniqueFile(path + ".tmp-%%%%%%%%.lib", tmpName)) + fatal("cannot create temporary file for import library " + path + ": " + + ec.message()); - if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine, - Config->MinGW)) { - HandleError(std::move(E)); + if (Error e = writeImportLibrary(libName, tmpName, exports, config->machine, + config->mingw)) { + handleError(std::move(e)); return; } - std::unique_ptr NewBuf = check(MemoryBuffer::getFile( - TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); - if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) { - OldBuf->reset(); - HandleError(errorCodeToError(sys::fs::rename(TmpName, Path))); + std::unique_ptr newBuf = check(MemoryBuffer::getFile( + tmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); + if ((*oldBuf)->getBuffer() != newBuf->getBuffer()) { + oldBuf->reset(); + handleError(errorCodeToError(sys::fs::rename(tmpName, path))); } else { - sys::fs::remove(TmpName); + sys::fs::remove(tmpName); } } -static void parseModuleDefs(StringRef Path) { - std::unique_ptr MB = CHECK( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); - COFFModuleDefinition M = check(parseCOFFModuleDefinition( - MB->getMemBufferRef(), Config->Machine, Config->MinGW)); - - if (Config->OutputFile.empty()) - Config->OutputFile = Saver.save(M.OutputFile); - Config->ImportName = Saver.save(M.ImportName); - if (M.ImageBase) - Config->ImageBase = M.ImageBase; - if (M.StackReserve) - Config->StackReserve = M.StackReserve; - if (M.StackCommit) - Config->StackCommit = M.StackCommit; - if (M.HeapReserve) - Config->HeapReserve = M.HeapReserve; - if (M.HeapCommit) - Config->HeapCommit = M.HeapCommit; - if (M.MajorImageVersion) - Config->MajorImageVersion = M.MajorImageVersion; - if (M.MinorImageVersion) - Config->MinorImageVersion = M.MinorImageVersion; - if (M.MajorOSVersion) - Config->MajorOSVersion = M.MajorOSVersion; - if (M.MinorOSVersion) - Config->MinorOSVersion = M.MinorOSVersion; - - for (COFFShortExport E1 : M.Exports) { - Export E2; +static void parseModuleDefs(StringRef path) { + std::unique_ptr mb = CHECK( + MemoryBuffer::getFile(path, -1, false, true), "could not open " + path); + COFFModuleDefinition m = check(parseCOFFModuleDefinition( + mb->getMemBufferRef(), config->machine, config->mingw)); + + if (config->outputFile.empty()) + config->outputFile = saver.save(m.OutputFile); + config->importName = saver.save(m.ImportName); + if (m.ImageBase) + config->imageBase = m.ImageBase; + if (m.StackReserve) + config->stackReserve = m.StackReserve; + if (m.StackCommit) + config->stackCommit = m.StackCommit; + if (m.HeapReserve) + config->heapReserve = m.HeapReserve; + if (m.HeapCommit) + config->heapCommit = m.HeapCommit; + if (m.MajorImageVersion) + config->majorImageVersion = m.MajorImageVersion; + if (m.MinorImageVersion) + config->minorImageVersion = m.MinorImageVersion; + if (m.MajorOSVersion) + config->majorOSVersion = m.MajorOSVersion; + if (m.MinorOSVersion) + config->minorOSVersion = m.MinorOSVersion; + + for (COFFShortExport e1 : m.Exports) { + Export e2; // In simple cases, only Name is set. Renamed exports are parsed // and set as "ExtName = Name". If Name has the form "OtherDll.Func", // it shouldn't be a normal exported function but a forward to another // DLL instead. This is supported by both MS and GNU linkers. - if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) { - E2.Name = Saver.save(E1.ExtName); - E2.ForwardTo = Saver.save(E1.Name); - Config->Exports.push_back(E2); + if (e1.ExtName != e1.Name && StringRef(e1.Name).contains('.')) { + e2.name = saver.save(e1.ExtName); + e2.forwardTo = saver.save(e1.Name); + config->exports.push_back(e2); continue; } - E2.Name = Saver.save(E1.Name); - E2.ExtName = Saver.save(E1.ExtName); - E2.Ordinal = E1.Ordinal; - E2.Noname = E1.Noname; - E2.Data = E1.Data; - E2.Private = E1.Private; - E2.Constant = E1.Constant; - Config->Exports.push_back(E2); + e2.name = saver.save(e1.Name); + e2.extName = saver.save(e1.ExtName); + e2.ordinal = e1.Ordinal; + e2.noname = e1.Noname; + e2.data = e1.Data; + e2.isPrivate = e1.Private; + e2.constant = e1.Constant; + config->exports.push_back(e2); } } -void LinkerDriver::enqueueTask(std::function Task) { - TaskQueue.push_back(std::move(Task)); +void LinkerDriver::enqueueTask(std::function task) { + taskQueue.push_back(std::move(task)); } bool LinkerDriver::run() { - ScopedTimer T(InputFileTimer); + ScopedTimer t(inputFileTimer); - bool DidWork = !TaskQueue.empty(); - while (!TaskQueue.empty()) { - TaskQueue.front()(); - TaskQueue.pop_front(); + bool didWork = !taskQueue.empty(); + while (!taskQueue.empty()) { + taskQueue.front()(); + taskQueue.pop_front(); } - return DidWork; + return didWork; } // Parse an /order file. If an option is given, the linker places // COMDAT sections in the same order as their names appear in the // given file. -static void parseOrderFile(StringRef Arg) { +static void parseOrderFile(StringRef arg) { // For some reason, the MSVC linker requires a filename to be // preceded by "@". - if (!Arg.startswith("@")) { + if (!arg.startswith("@")) { error("malformed /order option: '@' missing"); return; } // Get a list of all comdat sections for error checking. - DenseSet Set; - for (Chunk *C : Symtab->getChunks()) - if (auto *Sec = dyn_cast(C)) - if (Sec->Sym) - Set.insert(Sec->Sym->getName()); + DenseSet set; + for (Chunk *c : symtab->getChunks()) + if (auto *sec = dyn_cast(c)) + if (sec->sym) + set.insert(sec->sym->getName()); // Open a file. - StringRef Path = Arg.substr(1); - std::unique_ptr MB = CHECK( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); + StringRef path = arg.substr(1); + std::unique_ptr mb = CHECK( + MemoryBuffer::getFile(path, -1, false, true), "could not open " + path); // Parse a file. An order file contains one symbol per line. // All symbols that were not present in a given order file are // considered to have the lowest priority 0 and are placed at // end of an output section. - for (std::string S : args::getLines(MB->getMemBufferRef())) { - if (Config->Machine == I386 && !isDecorated(S)) - S = "_" + S; + for (std::string s : args::getLines(mb->getMemBufferRef())) { + if (config->machine == I386 && !isDecorated(s)) + s = "_" + s; - if (Set.count(S) == 0) { - if (Config->WarnMissingOrderSymbol) - warn("/order:" + Arg + ": missing symbol: " + S + " [LNK4037]"); + if (set.count(s) == 0) { + if (config->warnMissingOrderSymbol) + warn("/order:" + arg + ": missing symbol: " + s + " [LNK4037]"); } else - Config->Order[S] = INT_MIN + Config->Order.size(); + config->order[s] = INT_MIN + config->order.size(); } } -static void markAddrsig(Symbol *S) { - if (auto *D = dyn_cast_or_null(S)) - if (SectionChunk *C = dyn_cast_or_null(D->getChunk())) - C->KeepUnique = true; +static void markAddrsig(Symbol *s) { + if (auto *d = dyn_cast_or_null(s)) + if (SectionChunk *c = dyn_cast_or_null(d->getChunk())) + c->keepUnique = true; } static void findKeepUniqueSections() { // Exported symbols could be address-significant in other executables or DSOs, // so we conservatively mark them as address-significant. - for (Export &R : Config->Exports) - markAddrsig(R.Sym); + for (Export &r : config->exports) + markAddrsig(r.sym); // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. - for (ObjFile *Obj : ObjFile::Instances) { - ArrayRef Syms = Obj->getSymbols(); - if (Obj->AddrsigSec) { - ArrayRef Contents; + for (ObjFile *obj : ObjFile::instances) { + ArrayRef syms = obj->getSymbols(); + if (obj->addrsigSec) { + ArrayRef contents; cantFail( - Obj->getCOFFObj()->getSectionContents(Obj->AddrsigSec, Contents)); - 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(Obj) + ": could not decode addrsig section: " + Err); - if (SymIndex >= Syms.size()) - fatal(toString(Obj) + ": invalid symbol index in addrsig section"); - markAddrsig(Syms[SymIndex]); - Cur += Size; + obj->getCOFFObj()->getSectionContents(obj->addrsigSec, contents)); + 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(obj) + ": could not decode addrsig section: " + err); + if (symIndex >= syms.size()) + fatal(toString(obj) + ": invalid symbol index in addrsig section"); + 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); } } } @@ -928,14 +928,14 @@ static void findKeepUniqueSections() { // binary). // lld only supports %_PDB% and %_EXT% and warns on references to all other env // vars. -static void parsePDBAltPath(StringRef AltPath) { - SmallString<128> Buf; - StringRef PDBBasename = - sys::path::filename(Config->PDBPath, sys::path::Style::windows); - StringRef BinaryExtension = - sys::path::extension(Config->OutputFile, sys::path::Style::windows); - if (!BinaryExtension.empty()) - BinaryExtension = BinaryExtension.substr(1); // %_EXT% does not include '.'. +static void parsePDBAltPath(StringRef altPath) { + SmallString<128> buf; + StringRef pdbBasename = + sys::path::filename(config->pdbPath, sys::path::Style::windows); + StringRef binaryExtension = + sys::path::extension(config->outputFile, sys::path::Style::windows); + if (!binaryExtension.empty()) + binaryExtension = binaryExtension.substr(1); // %_EXT% does not include '.'. // Invariant: // +--------- Cursor ('a...' might be the empty string). @@ -943,34 +943,34 @@ static void parsePDBAltPath(StringRef AltPath) { // | | +- SecondMark // v v v // a...%...%... - size_t Cursor = 0; - while (Cursor < AltPath.size()) { - size_t FirstMark, SecondMark; - if ((FirstMark = AltPath.find('%', Cursor)) == StringRef::npos || - (SecondMark = AltPath.find('%', FirstMark + 1)) == StringRef::npos) { + size_t cursor = 0; + while (cursor < altPath.size()) { + size_t firstMark, secondMark; + if ((firstMark = altPath.find('%', cursor)) == StringRef::npos || + (secondMark = altPath.find('%', firstMark + 1)) == StringRef::npos) { // Didn't find another full fragment, treat rest of string as literal. - Buf.append(AltPath.substr(Cursor)); + buf.append(altPath.substr(cursor)); break; } // Found a full fragment. Append text in front of first %, and interpret // text between first and second % as variable name. - Buf.append(AltPath.substr(Cursor, FirstMark - Cursor)); - StringRef Var = AltPath.substr(FirstMark, SecondMark - FirstMark + 1); - if (Var.equals_lower("%_pdb%")) - Buf.append(PDBBasename); - else if (Var.equals_lower("%_ext%")) - Buf.append(BinaryExtension); + buf.append(altPath.substr(cursor, firstMark - cursor)); + StringRef var = altPath.substr(firstMark, secondMark - firstMark + 1); + if (var.equals_lower("%_pdb%")) + buf.append(pdbBasename); + else if (var.equals_lower("%_ext%")) + buf.append(binaryExtension); else { warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " + - Var + " as literal"); - Buf.append(Var); + var + " as literal"); + buf.append(var); } - Cursor = SecondMark + 1; + cursor = secondMark + 1; } - Config->PDBAltPath = Buf; + config->pdbAltPath = buf; } /// Check that at most one resource obj file was used. @@ -983,19 +983,19 @@ static void diagnoseMultipleResourceObjFiles() { // LNK4078, mirror that. The normal use of resource files is to give the // linker many .res files, which are then converted to a single resource obj // file internally, so this is not a big restriction in practice. - ObjFile *ResourceObjFile = nullptr; - for (ObjFile *F : ObjFile::Instances) { - if (!F->IsResourceObjFile) + ObjFile *resourceObjFile = nullptr; + for (ObjFile *f : ObjFile::instances) { + if (!f->isResourceObjFile) continue; - if (!ResourceObjFile) { - ResourceObjFile = F; + if (!resourceObjFile) { + resourceObjFile = f; continue; } - error(toString(F) + + error(toString(f) + ": more than one resource obj file not allowed, already got " + - toString(ResourceObjFile)); + toString(resourceObjFile)); } } @@ -1005,39 +1005,39 @@ static void diagnoseMultipleResourceObjFiles() { // explicitly specified. The automatic behavior can be disabled using the // -exclude-all-symbols option, so that lld-link behaves like link.exe rather // than MinGW in the case that nothing is explicitly exported. -void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &Args) { - if (!Config->DLL) +void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) { + if (!config->dll) return; - if (!Args.hasArg(OPT_export_all_symbols)) { - if (!Config->Exports.empty()) + if (!args.hasArg(OPT_export_all_symbols)) { + if (!config->exports.empty()) return; - if (Args.hasArg(OPT_exclude_all_symbols)) + if (args.hasArg(OPT_exclude_all_symbols)) return; } - AutoExporter Exporter; + AutoExporter exporter; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) - if (Optional Path = doFindFile(Arg->getValue())) - Exporter.addWholeArchive(*Path); + for (auto *arg : args.filtered(OPT_wholearchive_file)) + if (Optional path = doFindFile(arg->getValue())) + exporter.addWholeArchive(*path); - Symtab->forEachSymbol([&](Symbol *S) { - auto *Def = dyn_cast(S); - if (!Exporter.shouldExport(Def)) + symtab->forEachSymbol([&](Symbol *s) { + auto *def = dyn_cast(s); + if (!exporter.shouldExport(def)) return; - Export E; - E.Name = Def->getName(); - E.Sym = Def; - if (Chunk *C = Def->getChunk()) - if (!(C->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) - E.Data = true; - Config->Exports.push_back(E); + Export e; + e.name = def->getName(); + e.sym = def; + if (Chunk *c = def->getChunk()) + if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) + e.data = true; + config->exports.push_back(e); }); } -void LinkerDriver::link(ArrayRef ArgsArr) { +void LinkerDriver::link(ArrayRef argsArr) { // Needed for LTO. InitializeAllTargetInfos(); InitializeAllTargets(); @@ -1047,306 +1047,306 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // If the first command line argument is "/lib", link.exe acts like lib.exe. // We call our own implementation of lib.exe that understands bitcode files. - if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) { - if (llvm::libDriverMain(ArgsArr.slice(1)) != 0) + if (argsArr.size() > 1 && StringRef(argsArr[1]).equals_lower("/lib")) { + if (llvm::libDriverMain(argsArr.slice(1)) != 0) fatal("lib failed"); return; } // Parse command line options. - ArgParser Parser; - opt::InputArgList Args = Parser.parseLINK(ArgsArr); + ArgParser parser; + opt::InputArgList args = parser.parseLINK(argsArr); // Parse and evaluate -mllvm options. - std::vector V; - V.push_back("lld-link (LLVM option parsing)"); - for (auto *Arg : Args.filtered(OPT_mllvm)) - V.push_back(Arg->getValue()); - cl::ParseCommandLineOptions(V.size(), V.data()); + std::vector v; + v.push_back("lld-link (LLVM option parsing)"); + for (auto *arg : args.filtered(OPT_mllvm)) + v.push_back(arg->getValue()); + cl::ParseCommandLineOptions(v.size(), v.data()); // Handle /errorlimit early, because error() depends on it. - if (auto *Arg = Args.getLastArg(OPT_errorlimit)) { - int N = 20; - StringRef S = Arg->getValue(); - if (S.getAsInteger(10, N)) - error(Arg->getSpelling() + " number expected, but got " + S); - errorHandler().ErrorLimit = N; + if (auto *arg = args.getLastArg(OPT_errorlimit)) { + int n = 20; + StringRef s = arg->getValue(); + if (s.getAsInteger(10, n)) + error(arg->getSpelling() + " number expected, but got " + s); + errorHandler().errorLimit = n; } // Handle /help - if (Args.hasArg(OPT_help)) { - printHelp(ArgsArr[0]); + if (args.hasArg(OPT_help)) { + printHelp(argsArr[0]); return; } - lld::ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_threads_no, true); + lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, true); - if (Args.hasArg(OPT_show_timing)) - Config->ShowTiming = true; + if (args.hasArg(OPT_show_timing)) + config->showTiming = true; - Config->ShowSummary = Args.hasArg(OPT_summary); + config->showSummary = args.hasArg(OPT_summary); - ScopedTimer T(Timer::root()); + ScopedTimer t(Timer::root()); // Handle --version, which is an lld extension. This option is a bit odd // because it doesn't start with "/", but we deliberately chose "--" to // avoid conflict with /version and for compatibility with clang-cl. - if (Args.hasArg(OPT_dash_dash_version)) { + if (args.hasArg(OPT_dash_dash_version)) { outs() << getLLDVersion() << "\n"; return; } // Handle /lldmingw early, since it can potentially affect how other // options are handled. - Config->MinGW = Args.hasArg(OPT_lldmingw); + config->mingw = args.hasArg(OPT_lldmingw); - if (auto *Arg = Args.getLastArg(OPT_linkrepro)) { - SmallString<64> Path = StringRef(Arg->getValue()); - sys::path::append(Path, "repro.tar"); + if (auto *arg = args.getLastArg(OPT_linkrepro)) { + SmallString<64> path = StringRef(arg->getValue()); + sys::path::append(path, "repro.tar"); - Expected> ErrOrWriter = - TarWriter::create(Path, "repro"); + Expected> errOrWriter = + TarWriter::create(path, "repro"); - if (ErrOrWriter) { - Tar = std::move(*ErrOrWriter); + if (errOrWriter) { + tar = std::move(*errOrWriter); } else { - error("/linkrepro: failed to open " + Path + ": " + - toString(ErrOrWriter.takeError())); + error("/linkrepro: failed to open " + path + ": " + + toString(errOrWriter.takeError())); } } - if (!Args.hasArg(OPT_INPUT)) { - if (Args.hasArg(OPT_deffile)) - Config->NoEntry = true; + if (!args.hasArg(OPT_INPUT)) { + if (args.hasArg(OPT_deffile)) + config->noEntry = true; else fatal("no input files"); } // Construct search path list. - SearchPaths.push_back(""); - for (auto *Arg : Args.filtered(OPT_libpath)) - SearchPaths.push_back(Arg->getValue()); + searchPaths.push_back(""); + for (auto *arg : args.filtered(OPT_libpath)) + searchPaths.push_back(arg->getValue()); addLibSearchPaths(); // Handle /ignore - for (auto *Arg : Args.filtered(OPT_ignore)) { - SmallVector Vec; - StringRef(Arg->getValue()).split(Vec, ','); - for (StringRef S : Vec) { - if (S == "4037") - Config->WarnMissingOrderSymbol = false; - else if (S == "4099") - Config->WarnDebugInfoUnusable = false; - else if (S == "4217") - Config->WarnLocallyDefinedImported = false; + for (auto *arg : args.filtered(OPT_ignore)) { + SmallVector vec; + StringRef(arg->getValue()).split(vec, ','); + for (StringRef s : vec) { + if (s == "4037") + config->warnMissingOrderSymbol = false; + else if (s == "4099") + config->warnDebugInfoUnusable = false; + else if (s == "4217") + config->warnLocallyDefinedImported = false; // Other warning numbers are ignored. } } // Handle /out - if (auto *Arg = Args.getLastArg(OPT_out)) - Config->OutputFile = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_out)) + config->outputFile = arg->getValue(); // Handle /verbose - if (Args.hasArg(OPT_verbose)) - Config->Verbose = true; - errorHandler().Verbose = Config->Verbose; + if (args.hasArg(OPT_verbose)) + config->verbose = true; + errorHandler().verbose = config->verbose; // Handle /force or /force:unresolved - if (Args.hasArg(OPT_force, OPT_force_unresolved)) - Config->ForceUnresolved = true; + if (args.hasArg(OPT_force, OPT_force_unresolved)) + config->forceUnresolved = true; // Handle /force or /force:multiple - if (Args.hasArg(OPT_force, OPT_force_multiple)) - Config->ForceMultiple = true; + if (args.hasArg(OPT_force, OPT_force_multiple)) + config->forceMultiple = true; // Handle /force or /force:multipleres - if (Args.hasArg(OPT_force, OPT_force_multipleres)) - Config->ForceMultipleRes = true; + if (args.hasArg(OPT_force, OPT_force_multipleres)) + config->forceMultipleRes = true; // Handle /debug - DebugKind Debug = parseDebugKind(Args); - if (Debug == DebugKind::Full || Debug == DebugKind::Dwarf || - Debug == DebugKind::GHash) { - Config->Debug = true; - Config->Incremental = true; + DebugKind debug = parseDebugKind(args); + if (debug == DebugKind::Full || debug == DebugKind::Dwarf || + debug == DebugKind::GHash) { + config->debug = true; + config->incremental = true; } // Handle /demangle - Config->Demangle = Args.hasFlag(OPT_demangle, OPT_demangle_no); + config->demangle = args.hasFlag(OPT_demangle, OPT_demangle_no); // Handle /debugtype - Config->DebugTypes = parseDebugTypes(Args); + config->debugTypes = parseDebugTypes(args); // Handle /pdb - bool ShouldCreatePDB = - (Debug == DebugKind::Full || Debug == DebugKind::GHash); - if (ShouldCreatePDB) { - if (auto *Arg = Args.getLastArg(OPT_pdb)) - Config->PDBPath = Arg->getValue(); - if (auto *Arg = Args.getLastArg(OPT_pdbaltpath)) - Config->PDBAltPath = Arg->getValue(); - if (Args.hasArg(OPT_natvis)) - Config->NatvisFiles = Args.getAllArgValues(OPT_natvis); + bool shouldCreatePDB = + (debug == DebugKind::Full || debug == DebugKind::GHash); + if (shouldCreatePDB) { + if (auto *arg = args.getLastArg(OPT_pdb)) + config->pdbPath = arg->getValue(); + if (auto *arg = args.getLastArg(OPT_pdbaltpath)) + config->pdbAltPath = arg->getValue(); + if (args.hasArg(OPT_natvis)) + config->natvisFiles = args.getAllArgValues(OPT_natvis); - if (auto *Arg = Args.getLastArg(OPT_pdb_source_path)) - Config->PDBSourcePath = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_pdb_source_path)) + config->pdbSourcePath = arg->getValue(); } // Handle /noentry - if (Args.hasArg(OPT_noentry)) { - if (Args.hasArg(OPT_dll)) - Config->NoEntry = true; + if (args.hasArg(OPT_noentry)) { + if (args.hasArg(OPT_dll)) + config->noEntry = true; else error("/noentry must be specified with /dll"); } // Handle /dll - if (Args.hasArg(OPT_dll)) { - Config->DLL = true; - Config->ManifestID = 2; + if (args.hasArg(OPT_dll)) { + config->dll = true; + config->manifestID = 2; } // Handle /dynamicbase and /fixed. We can't use hasFlag for /dynamicbase // because we need to explicitly check whether that option or its inverse was // present in the argument list in order to handle /fixed. - auto *DynamicBaseArg = Args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no); - if (DynamicBaseArg && - DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) - Config->DynamicBase = false; + auto *dynamicBaseArg = args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no); + if (dynamicBaseArg && + dynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) + config->dynamicBase = false; // MSDN claims "/FIXED:NO is the default setting for a DLL, and /FIXED is the // default setting for any other project type.", but link.exe defaults to // /FIXED:NO for exe outputs as well. Match behavior, not docs. - bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false); - if (Fixed) { - if (DynamicBaseArg && - DynamicBaseArg->getOption().getID() == OPT_dynamicbase) { + bool fixed = args.hasFlag(OPT_fixed, OPT_fixed_no, false); + if (fixed) { + if (dynamicBaseArg && + dynamicBaseArg->getOption().getID() == OPT_dynamicbase) { error("/fixed must not be specified with /dynamicbase"); } else { - Config->Relocatable = false; - Config->DynamicBase = false; + config->relocatable = false; + config->dynamicBase = false; } } // Handle /appcontainer - Config->AppContainer = - Args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false); + config->appContainer = + args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false); // Handle /machine - if (auto *Arg = Args.getLastArg(OPT_machine)) { - Config->Machine = getMachineType(Arg->getValue()); - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) - fatal(Twine("unknown /machine argument: ") + Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_machine)) { + config->machine = getMachineType(arg->getValue()); + if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) + fatal(Twine("unknown /machine argument: ") + arg->getValue()); } // Handle /nodefaultlib: - for (auto *Arg : Args.filtered(OPT_nodefaultlib)) - Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()).lower()); + for (auto *arg : args.filtered(OPT_nodefaultlib)) + config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower()); // Handle /nodefaultlib - if (Args.hasArg(OPT_nodefaultlib_all)) - Config->NoDefaultLibAll = true; + if (args.hasArg(OPT_nodefaultlib_all)) + config->noDefaultLibAll = true; // Handle /base - if (auto *Arg = Args.getLastArg(OPT_base)) - parseNumbers(Arg->getValue(), &Config->ImageBase); + if (auto *arg = args.getLastArg(OPT_base)) + parseNumbers(arg->getValue(), &config->imageBase); // Handle /filealign - if (auto *Arg = Args.getLastArg(OPT_filealign)) { - parseNumbers(Arg->getValue(), &Config->FileAlign); - if (!isPowerOf2_64(Config->FileAlign)) - error("/filealign: not a power of two: " + Twine(Config->FileAlign)); + if (auto *arg = args.getLastArg(OPT_filealign)) { + parseNumbers(arg->getValue(), &config->fileAlign); + if (!isPowerOf2_64(config->fileAlign)) + error("/filealign: not a power of two: " + Twine(config->fileAlign)); } // Handle /stack - if (auto *Arg = Args.getLastArg(OPT_stack)) - parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); + if (auto *arg = args.getLastArg(OPT_stack)) + parseNumbers(arg->getValue(), &config->stackReserve, &config->stackCommit); // Handle /guard:cf - if (auto *Arg = Args.getLastArg(OPT_guard)) - parseGuard(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_guard)) + parseGuard(arg->getValue()); // Handle /heap - if (auto *Arg = Args.getLastArg(OPT_heap)) - parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit); + if (auto *arg = args.getLastArg(OPT_heap)) + parseNumbers(arg->getValue(), &config->heapReserve, &config->heapCommit); // Handle /version - if (auto *Arg = Args.getLastArg(OPT_version)) - parseVersion(Arg->getValue(), &Config->MajorImageVersion, - &Config->MinorImageVersion); + if (auto *arg = args.getLastArg(OPT_version)) + parseVersion(arg->getValue(), &config->majorImageVersion, + &config->minorImageVersion); // Handle /subsystem - if (auto *Arg = Args.getLastArg(OPT_subsystem)) - parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion, - &Config->MinorOSVersion); + if (auto *arg = args.getLastArg(OPT_subsystem)) + parseSubsystem(arg->getValue(), &config->subsystem, &config->majorOSVersion, + &config->minorOSVersion); // Handle /timestamp - if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) { - if (Arg->getOption().getID() == OPT_repro) { - Config->Timestamp = 0; - Config->Repro = true; + if (llvm::opt::Arg *arg = args.getLastArg(OPT_timestamp, OPT_repro)) { + if (arg->getOption().getID() == OPT_repro) { + config->timestamp = 0; + config->repro = true; } else { - Config->Repro = false; - StringRef Value(Arg->getValue()); - if (Value.getAsInteger(0, Config->Timestamp)) - fatal(Twine("invalid timestamp: ") + Value + + config->repro = false; + StringRef value(arg->getValue()); + if (value.getAsInteger(0, config->timestamp)) + fatal(Twine("invalid timestamp: ") + value + ". Expected 32-bit integer"); } } else { - Config->Repro = false; - Config->Timestamp = time(nullptr); + config->repro = false; + config->timestamp = time(nullptr); } // Handle /alternatename - for (auto *Arg : Args.filtered(OPT_alternatename)) - parseAlternateName(Arg->getValue()); + for (auto *arg : args.filtered(OPT_alternatename)) + parseAlternateName(arg->getValue()); // Handle /include - for (auto *Arg : Args.filtered(OPT_incl)) - addUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_incl)) + addUndefined(arg->getValue()); // Handle /implib - if (auto *Arg = Args.getLastArg(OPT_implib)) - Config->Implib = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_implib)) + config->implib = arg->getValue(); // Handle /opt. - bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile); - unsigned ICFLevel = - Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on - unsigned TailMerge = 1; - for (auto *Arg : Args.filtered(OPT_opt)) { - std::string Str = StringRef(Arg->getValue()).lower(); - SmallVector Vec; - StringRef(Str).split(Vec, ','); - for (StringRef S : Vec) { - if (S == "ref") { - DoGC = true; - } else if (S == "noref") { - DoGC = false; - } else if (S == "icf" || S.startswith("icf=")) { - ICFLevel = 2; - } else if (S == "noicf") { - ICFLevel = 0; - } else if (S == "lldtailmerge") { - TailMerge = 2; - } else if (S == "nolldtailmerge") { - TailMerge = 0; - } else if (S.startswith("lldlto=")) { - StringRef OptLevel = S.substr(7); - if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3) - error("/opt:lldlto: invalid optimization level: " + OptLevel); - } else if (S.startswith("lldltojobs=")) { - StringRef Jobs = S.substr(11); - if (Jobs.getAsInteger(10, Config->ThinLTOJobs) || - Config->ThinLTOJobs == 0) - error("/opt:lldltojobs: invalid job count: " + Jobs); - } else if (S.startswith("lldltopartitions=")) { - StringRef N = S.substr(17); - if (N.getAsInteger(10, Config->LTOPartitions) || - Config->LTOPartitions == 0) - error("/opt:lldltopartitions: invalid partition count: " + N); - } else if (S != "lbr" && S != "nolbr") - error("/opt: unknown option: " + S); + bool doGC = debug == DebugKind::None || args.hasArg(OPT_profile); + unsigned icfLevel = + args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on + unsigned tailMerge = 1; + for (auto *arg : args.filtered(OPT_opt)) { + std::string str = StringRef(arg->getValue()).lower(); + SmallVector vec; + StringRef(str).split(vec, ','); + for (StringRef s : vec) { + if (s == "ref") { + doGC = true; + } else if (s == "noref") { + doGC = false; + } else if (s == "icf" || s.startswith("icf=")) { + icfLevel = 2; + } else if (s == "noicf") { + icfLevel = 0; + } else if (s == "lldtailmerge") { + tailMerge = 2; + } else if (s == "nolldtailmerge") { + tailMerge = 0; + } else if (s.startswith("lldlto=")) { + StringRef optLevel = s.substr(7); + if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3) + error("/opt:lldlto: invalid optimization level: " + optLevel); + } else if (s.startswith("lldltojobs=")) { + StringRef jobs = s.substr(11); + if (jobs.getAsInteger(10, config->thinLTOJobs) || + config->thinLTOJobs == 0) + error("/opt:lldltojobs: invalid job count: " + jobs); + } else if (s.startswith("lldltopartitions=")) { + StringRef n = s.substr(17); + if (n.getAsInteger(10, config->ltoPartitions) || + config->ltoPartitions == 0) + error("/opt:lldltopartitions: invalid partition count: " + n); + } else if (s != "lbr" && s != "nolbr") + error("/opt: unknown option: " + s); } } @@ -1355,37 +1355,37 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // FIXME: LLD only implements "limited" ICF, i.e. it only merges identical // code. If the user passes /OPT:ICF explicitly, LLD should merge identical // comdat readonly data. - if (ICFLevel == 1 && !DoGC) - ICFLevel = 0; - Config->DoGC = DoGC; - Config->DoICF = ICFLevel > 0; - Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2; + if (icfLevel == 1 && !doGC) + icfLevel = 0; + config->doGC = doGC; + config->doICF = icfLevel > 0; + config->tailMerge = (tailMerge == 1 && config->doICF) || tailMerge == 2; // Handle /lldsavetemps - if (Args.hasArg(OPT_lldsavetemps)) - Config->SaveTemps = true; + if (args.hasArg(OPT_lldsavetemps)) + config->saveTemps = true; // Handle /kill-at - if (Args.hasArg(OPT_kill_at)) - Config->KillAt = true; + if (args.hasArg(OPT_kill_at)) + config->killAt = true; // Handle /lldltocache - if (auto *Arg = Args.getLastArg(OPT_lldltocache)) - Config->LTOCache = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_lldltocache)) + config->ltoCache = arg->getValue(); // Handle /lldsavecachepolicy - if (auto *Arg = Args.getLastArg(OPT_lldltocachepolicy)) - Config->LTOCachePolicy = CHECK( - parseCachePruningPolicy(Arg->getValue()), - Twine("/lldltocachepolicy: invalid cache policy: ") + Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_lldltocachepolicy)) + config->ltoCachePolicy = CHECK( + parseCachePruningPolicy(arg->getValue()), + Twine("/lldltocachepolicy: invalid cache policy: ") + arg->getValue()); // Handle /failifmismatch - for (auto *Arg : Args.filtered(OPT_failifmismatch)) - checkFailIfMismatch(Arg->getValue(), nullptr); + for (auto *arg : args.filtered(OPT_failifmismatch)) + checkFailIfMismatch(arg->getValue(), nullptr); // Handle /merge - for (auto *Arg : Args.filtered(OPT_merge)) - parseMerge(Arg->getValue()); + for (auto *arg : args.filtered(OPT_merge)) + parseMerge(arg->getValue()); // Add default section merging rules after user rules. User rules take // precedence, but we will emit a warning if there is a conflict. @@ -1395,128 +1395,128 @@ void LinkerDriver::link(ArrayRef ArgsArr) { parseMerge(".xdata=.rdata"); parseMerge(".bss=.data"); - if (Config->MinGW) { + if (config->mingw) { parseMerge(".ctors=.rdata"); parseMerge(".dtors=.rdata"); parseMerge(".CRT=.rdata"); } // Handle /section - for (auto *Arg : Args.filtered(OPT_section)) - parseSection(Arg->getValue()); + for (auto *arg : args.filtered(OPT_section)) + parseSection(arg->getValue()); // Handle /aligncomm - for (auto *Arg : Args.filtered(OPT_aligncomm)) - parseAligncomm(Arg->getValue()); + for (auto *arg : args.filtered(OPT_aligncomm)) + parseAligncomm(arg->getValue()); // Handle /manifestdependency. This enables /manifest unless /manifest:no is // also passed. - if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) { - Config->ManifestDependency = Arg->getValue(); - Config->Manifest = Configuration::SideBySide; + if (auto *arg = args.getLastArg(OPT_manifestdependency)) { + config->manifestDependency = arg->getValue(); + config->manifest = Configuration::SideBySide; } // Handle /manifest and /manifest: - if (auto *Arg = Args.getLastArg(OPT_manifest, OPT_manifest_colon)) { - if (Arg->getOption().getID() == OPT_manifest) - Config->Manifest = Configuration::SideBySide; + if (auto *arg = args.getLastArg(OPT_manifest, OPT_manifest_colon)) { + if (arg->getOption().getID() == OPT_manifest) + config->manifest = Configuration::SideBySide; else - parseManifest(Arg->getValue()); + parseManifest(arg->getValue()); } // Handle /manifestuac - if (auto *Arg = Args.getLastArg(OPT_manifestuac)) - parseManifestUAC(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_manifestuac)) + parseManifestUAC(arg->getValue()); // Handle /manifestfile - if (auto *Arg = Args.getLastArg(OPT_manifestfile)) - Config->ManifestFile = Arg->getValue(); + if (auto *arg = args.getLastArg(OPT_manifestfile)) + config->manifestFile = arg->getValue(); // Handle /manifestinput - for (auto *Arg : Args.filtered(OPT_manifestinput)) - Config->ManifestInput.push_back(Arg->getValue()); + for (auto *arg : args.filtered(OPT_manifestinput)) + config->manifestInput.push_back(arg->getValue()); - if (!Config->ManifestInput.empty() && - Config->Manifest != Configuration::Embed) { + if (!config->manifestInput.empty() && + config->manifest != Configuration::Embed) { fatal("/manifestinput: requires /manifest:embed"); } // Handle miscellaneous boolean flags. - Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); - Config->AllowIsolation = - Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); - Config->Incremental = - Args.hasFlag(OPT_incremental, OPT_incremental_no, - !Config->DoGC && !Config->DoICF && !Args.hasArg(OPT_order) && - !Args.hasArg(OPT_profile)); - Config->IntegrityCheck = - Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); - Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); - for (auto *Arg : Args.filtered(OPT_swaprun)) - parseSwaprun(Arg->getValue()); - Config->TerminalServerAware = - !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); - Config->DebugDwarf = Debug == DebugKind::Dwarf; - Config->DebugGHashes = Debug == DebugKind::GHash; - Config->DebugSymtab = Debug == DebugKind::Symtab; - - Config->MapFile = getMapFile(Args); - - if (Config->Incremental && Args.hasArg(OPT_profile)) { + config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); + config->allowIsolation = + args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); + config->incremental = + args.hasFlag(OPT_incremental, OPT_incremental_no, + !config->doGC && !config->doICF && !args.hasArg(OPT_order) && + !args.hasArg(OPT_profile)); + config->integrityCheck = + args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); + config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); + for (auto *arg : args.filtered(OPT_swaprun)) + parseSwaprun(arg->getValue()); + config->terminalServerAware = + !config->dll && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); + config->debugDwarf = debug == DebugKind::Dwarf; + config->debugGHashes = debug == DebugKind::GHash; + config->debugSymtab = debug == DebugKind::Symtab; + + config->mapFile = getMapFile(args); + + if (config->incremental && args.hasArg(OPT_profile)) { warn("ignoring '/incremental' due to '/profile' specification"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Args.hasArg(OPT_order)) { + if (config->incremental && args.hasArg(OPT_order)) { warn("ignoring '/incremental' due to '/order' specification"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Config->DoGC) { + if (config->incremental && config->doGC) { warn("ignoring '/incremental' because REF is enabled; use '/opt:noref' to " "disable"); - Config->Incremental = false; + config->incremental = false; } - if (Config->Incremental && Config->DoICF) { + if (config->incremental && config->doICF) { warn("ignoring '/incremental' because ICF is enabled; use '/opt:noicf' to " "disable"); - Config->Incremental = false; + config->incremental = false; } if (errorCount()) return; - std::set WholeArchives; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) - if (Optional Path = doFindFile(Arg->getValue())) - if (Optional ID = getUniqueID(*Path)) - WholeArchives.insert(*ID); + std::set wholeArchives; + for (auto *arg : args.filtered(OPT_wholearchive_file)) + if (Optional path = doFindFile(arg->getValue())) + if (Optional id = getUniqueID(*path)) + wholeArchives.insert(*id); // A predicate returning true if a given path is an argument for // /wholearchive:, or /wholearchive is enabled globally. // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj" // needs to be handled as "/wholearchive:foo.obj foo.obj". - auto IsWholeArchive = [&](StringRef Path) -> bool { - if (Args.hasArg(OPT_wholearchive_flag)) + auto isWholeArchive = [&](StringRef path) -> bool { + if (args.hasArg(OPT_wholearchive_flag)) return true; - if (Optional ID = getUniqueID(Path)) - return WholeArchives.count(*ID); + if (Optional id = getUniqueID(path)) + return wholeArchives.count(*id); return false; }; // Create a list of input files. Files can be given as arguments // for /defaultlib option. - for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) - if (Optional Path = findFile(Arg->getValue())) - enqueuePath(*Path, IsWholeArchive(*Path)); + for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file)) + if (Optional path = findFile(arg->getValue())) + enqueuePath(*path, isWholeArchive(*path)); - for (auto *Arg : Args.filtered(OPT_defaultlib)) - if (Optional Path = findLib(Arg->getValue())) - enqueuePath(*Path, false); + for (auto *arg : args.filtered(OPT_defaultlib)) + if (Optional path = findLib(arg->getValue())) + enqueuePath(*path, false); // Windows specific -- Create a resource file containing a manifest file. - if (Config->Manifest == Configuration::Embed) + if (config->manifest == Configuration::Embed) addBuffer(createManifestRes(), false); // Read all input files given via the command line. @@ -1527,61 +1527,61 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // We should have inferred a machine type by now from the input files, but if // not we assume x64. - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { + if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) { warn("/machine is not specified. x64 is assumed"); - Config->Machine = AMD64; + config->machine = AMD64; } - Config->Wordsize = Config->is64() ? 8 : 4; + config->wordsize = config->is64() ? 8 : 4; // Handle /functionpadmin - for (auto *Arg : Args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) - parseFunctionPadMin(Arg, Config->Machine); + for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) + parseFunctionPadMin(arg, config->machine); // Input files can be Windows resource files (.res files). We use // WindowsResource to convert resource files to a regular COFF file, // then link the resulting file normally. - if (!Resources.empty()) - Symtab->addFile(make(convertResToCOFF(Resources))); + if (!resources.empty()) + symtab->addFile(make(convertResToCOFF(resources))); - if (Tar) - Tar->append("response.txt", - createResponseFile(Args, FilePaths, - ArrayRef(SearchPaths).slice(1))); + if (tar) + tar->append("response.txt", + createResponseFile(args, filePaths, + ArrayRef(searchPaths).slice(1))); // Handle /largeaddressaware - Config->LargeAddressAware = Args.hasFlag( - OPT_largeaddressaware, OPT_largeaddressaware_no, Config->is64()); + config->largeAddressAware = args.hasFlag( + OPT_largeaddressaware, OPT_largeaddressaware_no, config->is64()); // Handle /highentropyva - Config->HighEntropyVA = - Config->is64() && - Args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true); + config->highEntropyVA = + config->is64() && + args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true); - if (!Config->DynamicBase && - (Config->Machine == ARMNT || Config->Machine == ARM64)) + if (!config->dynamicBase && + (config->machine == ARMNT || config->machine == ARM64)) error("/dynamicbase:no is not compatible with " + - machineToStr(Config->Machine)); + machineToStr(config->machine)); // Handle /export - for (auto *Arg : Args.filtered(OPT_export)) { - Export E = parseExport(Arg->getValue()); - if (Config->Machine == I386) { - if (!isDecorated(E.Name)) - E.Name = Saver.save("_" + E.Name); - if (!E.ExtName.empty() && !isDecorated(E.ExtName)) - E.ExtName = Saver.save("_" + E.ExtName); + for (auto *arg : args.filtered(OPT_export)) { + Export e = parseExport(arg->getValue()); + if (config->machine == I386) { + if (!isDecorated(e.name)) + e.name = saver.save("_" + e.name); + if (!e.extName.empty() && !isDecorated(e.extName)) + e.extName = saver.save("_" + e.extName); } - Config->Exports.push_back(E); + config->exports.push_back(e); } // Handle /def - if (auto *Arg = Args.getLastArg(OPT_deffile)) { + if (auto *arg = args.getLastArg(OPT_deffile)) { // parseModuleDefs mutates Config object. - parseModuleDefs(Arg->getValue()); + parseModuleDefs(arg->getValue()); } // Handle generation of import library from a def file. - if (!Args.hasArg(OPT_INPUT)) { + if (!args.hasArg(OPT_INPUT)) { fixupExports(); createImportLibrary(/*AsLib=*/true); return; @@ -1590,101 +1590,101 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Windows specific -- if no /subsystem is given, we need to infer // that from entry point name. Must happen before /entry handling, // and after the early return when just writing an import library. - if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { - Config->Subsystem = inferSubsystem(); - if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) + if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { + config->subsystem = inferSubsystem(); + if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) fatal("subsystem must be defined"); } // Handle /entry and /dll - if (auto *Arg = Args.getLastArg(OPT_entry)) { - Config->Entry = addUndefined(mangle(Arg->getValue())); - } else if (!Config->Entry && !Config->NoEntry) { - if (Args.hasArg(OPT_dll)) { - StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12" + if (auto *arg = args.getLastArg(OPT_entry)) { + config->entry = addUndefined(mangle(arg->getValue())); + } else if (!config->entry && !config->noEntry) { + if (args.hasArg(OPT_dll)) { + StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12" : "_DllMainCRTStartup"; - Config->Entry = addUndefined(S); + config->entry = addUndefined(s); } else { // Windows specific -- If entry point name is not given, we need to // infer that from user-defined entry name. - StringRef S = findDefaultEntry(); - if (S.empty()) + StringRef s = findDefaultEntry(); + if (s.empty()) fatal("entry point must be defined"); - Config->Entry = addUndefined(S); - log("Entry name inferred: " + S); + config->entry = addUndefined(s); + log("Entry name inferred: " + s); } } // Handle /delayload - for (auto *Arg : Args.filtered(OPT_delayload)) { - Config->DelayLoads.insert(StringRef(Arg->getValue()).lower()); - if (Config->Machine == I386) { - Config->DelayLoadHelper = addUndefined("___delayLoadHelper2@8"); + for (auto *arg : args.filtered(OPT_delayload)) { + config->delayLoads.insert(StringRef(arg->getValue()).lower()); + if (config->machine == I386) { + config->delayLoadHelper = addUndefined("___delayLoadHelper2@8"); } else { - Config->DelayLoadHelper = addUndefined("__delayLoadHelper2"); + config->delayLoadHelper = addUndefined("__delayLoadHelper2"); } } // Set default image name if neither /out or /def set it. - if (Config->OutputFile.empty()) { - Config->OutputFile = - getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue()); + if (config->outputFile.empty()) { + config->outputFile = + getOutputPath((*args.filtered(OPT_INPUT).begin())->getValue()); } // Fail early if an output file is not writable. - if (auto E = tryCreateFile(Config->OutputFile)) { - error("cannot open output file " + Config->OutputFile + ": " + E.message()); + if (auto e = tryCreateFile(config->outputFile)) { + error("cannot open output file " + config->outputFile + ": " + e.message()); return; } - if (ShouldCreatePDB) { + if (shouldCreatePDB) { // Put the PDB next to the image if no /pdb flag was passed. - if (Config->PDBPath.empty()) { - Config->PDBPath = Config->OutputFile; - sys::path::replace_extension(Config->PDBPath, ".pdb"); + if (config->pdbPath.empty()) { + config->pdbPath = config->outputFile; + sys::path::replace_extension(config->pdbPath, ".pdb"); } // The embedded PDB path should be the absolute path to the PDB if no // /pdbaltpath flag was passed. - if (Config->PDBAltPath.empty()) { - Config->PDBAltPath = Config->PDBPath; + if (config->pdbAltPath.empty()) { + config->pdbAltPath = config->pdbPath; // It's important to make the path absolute and remove dots. This path // will eventually be written into the PE header, and certain Microsoft // tools won't work correctly if these assumptions are not held. - sys::fs::make_absolute(Config->PDBAltPath); - sys::path::remove_dots(Config->PDBAltPath); + sys::fs::make_absolute(config->pdbAltPath); + sys::path::remove_dots(config->pdbAltPath); } else { // Don't do this earlier, so that Config->OutputFile is ready. - parsePDBAltPath(Config->PDBAltPath); + parsePDBAltPath(config->pdbAltPath); } } // Set default image base if /base is not given. - if (Config->ImageBase == uint64_t(-1)) - Config->ImageBase = getDefaultImageBase(); - - Symtab->addSynthetic(mangle("__ImageBase"), nullptr); - if (Config->Machine == I386) { - Symtab->addAbsolute("___safe_se_handler_table", 0); - Symtab->addAbsolute("___safe_se_handler_count", 0); - } - - Symtab->addAbsolute(mangle("__guard_fids_count"), 0); - Symtab->addAbsolute(mangle("__guard_fids_table"), 0); - Symtab->addAbsolute(mangle("__guard_flags"), 0); - Symtab->addAbsolute(mangle("__guard_iat_count"), 0); - Symtab->addAbsolute(mangle("__guard_iat_table"), 0); - Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); - Symtab->addAbsolute(mangle("__guard_longjmp_table"), 0); + if (config->imageBase == uint64_t(-1)) + config->imageBase = getDefaultImageBase(); + + symtab->addSynthetic(mangle("__ImageBase"), nullptr); + if (config->machine == I386) { + symtab->addAbsolute("___safe_se_handler_table", 0); + symtab->addAbsolute("___safe_se_handler_count", 0); + } + + symtab->addAbsolute(mangle("__guard_fids_count"), 0); + symtab->addAbsolute(mangle("__guard_fids_table"), 0); + symtab->addAbsolute(mangle("__guard_flags"), 0); + symtab->addAbsolute(mangle("__guard_iat_count"), 0); + symtab->addAbsolute(mangle("__guard_iat_table"), 0); + symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); + symtab->addAbsolute(mangle("__guard_longjmp_table"), 0); // Needed for MSVC 2017 15.5 CRT. - Symtab->addAbsolute(mangle("__enclave_config"), 0); + symtab->addAbsolute(mangle("__enclave_config"), 0); - if (Config->MinGW) { - Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0); - Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0); - Symtab->addAbsolute(mangle("__CTOR_LIST__"), 0); - Symtab->addAbsolute(mangle("__DTOR_LIST__"), 0); + if (config->mingw) { + symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0); + symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0); + symtab->addAbsolute(mangle("__CTOR_LIST__"), 0); + symtab->addAbsolute(mangle("__DTOR_LIST__"), 0); } // This code may add new undefined symbols to the link, which may enqueue more @@ -1693,33 +1693,33 @@ void LinkerDriver::link(ArrayRef ArgsArr) { do { // Windows specific -- if entry point is not found, // search for its mangled names. - if (Config->Entry) - mangleMaybe(Config->Entry); + if (config->entry) + mangleMaybe(config->entry); // Windows specific -- Make sure we resolve all dllexported symbols. - for (Export &E : Config->Exports) { - if (!E.ForwardTo.empty()) + for (Export &e : config->exports) { + if (!e.forwardTo.empty()) continue; - E.Sym = addUndefined(E.Name); - if (!E.Directives) - E.SymbolName = mangleMaybe(E.Sym); + e.sym = addUndefined(e.name); + if (!e.directives) + e.symbolName = mangleMaybe(e.sym); } // Add weak aliases. Weak aliases is a mechanism to give remaining // undefined symbols final chance to be resolved successfully. - for (auto Pair : Config->AlternateNames) { - StringRef From = Pair.first; - StringRef To = Pair.second; - Symbol *Sym = Symtab->find(From); - if (!Sym) + for (auto pair : config->alternateNames) { + StringRef from = pair.first; + StringRef to = pair.second; + Symbol *sym = symtab->find(from); + if (!sym) continue; - if (auto *U = dyn_cast(Sym)) - if (!U->WeakAlias) - U->WeakAlias = Symtab->addUndefined(To); + if (auto *u = dyn_cast(sym)) + if (!u->weakAlias) + u->weakAlias = symtab->addUndefined(to); } // Windows specific -- if __load_config_used can be resolved, resolve it. - if (Symtab->findUnderscore("_load_config_used")) + if (symtab->findUnderscore("_load_config_used")) addUndefined(mangle("_load_config_used")); } while (run()); @@ -1728,18 +1728,18 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files. - Symtab->addCombinedLTOObjects(); + symtab->addCombinedLTOObjects(); run(); - if (Args.hasArg(OPT_include_optional)) { + if (args.hasArg(OPT_include_optional)) { // Handle /includeoptional - for (auto *Arg : Args.filtered(OPT_include_optional)) - if (dyn_cast_or_null(Symtab->find(Arg->getValue()))) - addUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_include_optional)) + if (dyn_cast_or_null(symtab->find(arg->getValue()))) + addUndefined(arg->getValue()); while (run()); } - if (Config->MinGW) { + if (config->mingw) { // Load any further object files that might be needed for doing automatic // imports. // @@ -1753,28 +1753,28 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // normal object file as well (although that won't be used for the // actual autoimport later on). If this pass adds new undefined references, // we won't iterate further to resolve them. - Symtab->loadMinGWAutomaticImports(); + symtab->loadMinGWAutomaticImports(); run(); } // Make sure we have resolved all symbols. - Symtab->reportRemainingUndefines(); + symtab->reportRemainingUndefines(); if (errorCount()) return; // Handle /safeseh. - if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { - for (ObjFile *File : ObjFile::Instances) - if (!File->hasSafeSEH()) - error("/safeseh: " + File->getName() + " is not compatible with SEH"); + if (args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { + for (ObjFile *file : ObjFile::instances) + if (!file->hasSafeSEH()) + error("/safeseh: " + file->getName() + " is not compatible with SEH"); if (errorCount()) return; } - if (Config->MinGW) { + if (config->mingw) { // In MinGW, all symbols are automatically exported if no symbols // are chosen to be exported. - maybeExportMinGWSymbols(Args); + maybeExportMinGWSymbols(args); // Make sure the crtend.o object is the last object file. This object // file can contain terminating section chunks that need to be placed @@ -1782,12 +1782,12 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // order provided on the command line, while lld will pull in needed // files from static libraries only after the last object file on the // command line. - for (auto I = ObjFile::Instances.begin(), E = ObjFile::Instances.end(); - I != E; I++) { - ObjFile *File = *I; - if (isCrtend(File->getName())) { - ObjFile::Instances.erase(I); - ObjFile::Instances.push_back(File); + for (auto i = ObjFile::instances.begin(), e = ObjFile::instances.end(); + i != e; i++) { + ObjFile *file = *i; + if (isCrtend(file->getName())) { + ObjFile::instances.erase(i); + ObjFile::instances.push_back(file); break; } } @@ -1795,58 +1795,58 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. - if (!Config->Exports.empty() || Config->DLL) { + if (!config->exports.empty() || config->dll) { fixupExports(); createImportLibrary(/*AsLib=*/false); assignExportOrdinals(); } // Handle /output-def (MinGW specific). - if (auto *Arg = Args.getLastArg(OPT_output_def)) - writeDefFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_output_def)) + writeDefFile(arg->getValue()); // Set extra alignment for .comm symbols - for (auto Pair : Config->AlignComm) { - StringRef Name = Pair.first; - uint32_t Alignment = Pair.second; + for (auto pair : config->alignComm) { + StringRef name = pair.first; + uint32_t alignment = pair.second; - Symbol *Sym = Symtab->find(Name); - if (!Sym) { - warn("/aligncomm symbol " + Name + " not found"); + Symbol *sym = symtab->find(name); + if (!sym) { + warn("/aligncomm symbol " + name + " not found"); continue; } // If the symbol isn't common, it must have been replaced with a regular // symbol, which will carry its own alignment. - auto *DC = dyn_cast(Sym); - if (!DC) + auto *dc = dyn_cast(sym); + if (!dc) continue; - CommonChunk *C = DC->getChunk(); - C->setAlignment(std::max(C->getAlignment(), Alignment)); + CommonChunk *c = dc->getChunk(); + c->setAlignment(std::max(c->getAlignment(), alignment)); } // Windows specific -- Create a side-by-side manifest file. - if (Config->Manifest == Configuration::SideBySide) + if (config->manifest == Configuration::SideBySide) createSideBySideManifest(); // Handle /order. We want to do this at this moment because we // need a complete list of comdat sections to warn on nonexistent // functions. - if (auto *Arg = Args.getLastArg(OPT_order)) - parseOrderFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_order)) + parseOrderFile(arg->getValue()); // Identify unreferenced COMDAT sections. - if (Config->DoGC) - markLive(Symtab->getChunks()); + if (config->doGC) + markLive(symtab->getChunks()); // Needs to happen after the last call to addFile(). diagnoseMultipleResourceObjFiles(); // Identify identical COMDAT sections to merge them. - if (Config->DoICF) { + if (config->doICF) { findKeepUniqueSections(); - doICF(Symtab->getChunks()); + doICF(symtab->getChunks()); } // Write the result. @@ -1854,7 +1854,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Stop early so we can print the results. Timer::root().stop(); - if (Config->ShowTiming) + if (config->showTiming) Timer::root().print(); } diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index 1e93531..6100c3c 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -30,7 +30,7 @@ namespace lld { namespace coff { class LinkerDriver; -extern LinkerDriver *Driver; +extern LinkerDriver *driver; using llvm::COFF::MachineTypes; using llvm::COFF::WindowsSubsystem; @@ -44,71 +44,71 @@ public: class ArgParser { public: // Concatenate LINK environment variable and given arguments and parse them. - llvm::opt::InputArgList parseLINK(std::vector Args); + llvm::opt::InputArgList parseLINK(std::vector args); // Tokenizes a given string and then parses as command line options. - llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); } + llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); } // Tokenizes a given string and then parses as command line options in // .drectve section. /EXPORT options are returned in second element // to be processed in fastpath. std::pair> - parseDirectives(StringRef S); + parseDirectives(StringRef s); private: // Parses command line options. - llvm::opt::InputArgList parse(llvm::ArrayRef Args); + llvm::opt::InputArgList parse(llvm::ArrayRef args); - std::vector tokenize(StringRef S); + std::vector tokenize(StringRef s); - COFFOptTable Table; + COFFOptTable table; }; class LinkerDriver { public: - void link(llvm::ArrayRef Args); + void link(llvm::ArrayRef args); // Used by the resolver to parse .drectve section contents. - void parseDirectives(InputFile *File); + void parseDirectives(InputFile *file); // Used by ArchiveFile to enqueue members. - void enqueueArchiveMember(const Archive::Child &C, StringRef SymName, - StringRef ParentName); + void enqueueArchiveMember(const Archive::Child &c, StringRef symName, + StringRef parentName); - MemoryBufferRef takeBuffer(std::unique_ptr MB); + MemoryBufferRef takeBuffer(std::unique_ptr mb); - void enqueuePath(StringRef Path, bool WholeArchive); + void enqueuePath(StringRef path, bool wholeArchive); private: - std::unique_ptr Tar; // for /linkrepro + std::unique_ptr tar; // for /linkrepro // Opens a file. Path has to be resolved already. - MemoryBufferRef openFile(StringRef Path); + MemoryBufferRef openFile(StringRef path); // Searches a file from search paths. - Optional findFile(StringRef Filename); - Optional findLib(StringRef Filename); - StringRef doFindFile(StringRef Filename); - StringRef doFindLib(StringRef Filename); - StringRef doFindLibMinGW(StringRef Filename); + Optional findFile(StringRef filename); + Optional findLib(StringRef filename); + StringRef doFindFile(StringRef filename); + StringRef doFindLib(StringRef filename); + StringRef doFindLibMinGW(StringRef filename); // Parses LIB environment which contains a list of search paths. void addLibSearchPaths(); // Library search path. The first element is always "" (current directory). - std::vector SearchPaths; + std::vector searchPaths; - void maybeExportMinGWSymbols(const llvm::opt::InputArgList &Args); + void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args); // We don't want to add the same file more than once. // Files are uniquified by their filesystem and file number. - std::set VisitedFiles; + std::set visitedFiles; - std::set VisitedLibs; + std::set visitedLibs; - Symbol *addUndefined(StringRef Sym); + Symbol *addUndefined(StringRef sym); - StringRef mangleMaybe(Symbol *S); + StringRef mangleMaybe(Symbol *s); // Windows specific -- "main" is not the only main function in Windows. // You can choose one from these four -- {w,}{WinMain,main}. @@ -120,36 +120,36 @@ private: StringRef findDefaultEntry(); WindowsSubsystem inferSubsystem(); - void addBuffer(std::unique_ptr MB, bool WholeArchive); - void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName, - StringRef ParentName, uint64_t OffsetInArchive); + void addBuffer(std::unique_ptr mb, bool wholeArchive); + void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName, + StringRef parentName, uint64_t offsetInArchive); - void enqueueTask(std::function Task); + void enqueueTask(std::function task); bool run(); - std::list> TaskQueue; - std::vector FilePaths; - std::vector Resources; + std::list> taskQueue; + std::vector filePaths; + std::vector resources; - llvm::StringSet<> DirectivesExports; + llvm::StringSet<> directivesExports; }; // Functions below this line are defined in DriverUtils.cpp. -void printHelp(const char *Argv0); +void printHelp(const char *argv0); // Parses a string in the form of "[,]". -void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr); +void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr); -void parseGuard(StringRef Arg); +void parseGuard(StringRef arg); // Parses a string in the form of "[.]". // Minor's default value is 0. -void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor); +void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor); // Parses a string in the form of "[,[.]]". -void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, - uint32_t *Minor); +void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, + uint32_t *minor); void parseAlternateName(StringRef); void parseMerge(StringRef); @@ -157,23 +157,23 @@ void parseSection(StringRef); void parseAligncomm(StringRef); // Parses a string in the form of "[:]" -void parseFunctionPadMin(llvm::opt::Arg *A, llvm::COFF::MachineTypes Machine); +void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine); // Parses a string in the form of "EMBED[,=]|NO". -void parseManifest(StringRef Arg); +void parseManifest(StringRef arg); // Parses a string in the form of "level=|uiAccess=" -void parseManifestUAC(StringRef Arg); +void parseManifestUAC(StringRef arg); // Parses a string in the form of "cd|net[,(cd|net)]*" -void parseSwaprun(StringRef Arg); +void parseSwaprun(StringRef arg); // Create a resource file containing a manifest XML. std::unique_ptr createManifestRes(); void createSideBySideManifest(); // Used for dllexported symbols. -Export parseExport(StringRef Arg); +Export parseExport(StringRef arg); void fixupExports(); void assignExportOrdinals(); @@ -181,12 +181,12 @@ void assignExportOrdinals(); // if value matches previous values for the key. // This feature used in the directive section to reject // incompatible objects. -void checkFailIfMismatch(StringRef Arg, InputFile *Source); +void checkFailIfMismatch(StringRef arg, InputFile *source); // Convert Windows resource files (.res files) to a .obj file. -MemoryBufferRef convertResToCOFF(ArrayRef MBs); +MemoryBufferRef convertResToCOFF(ArrayRef mbs); -void runMSVCLinker(std::string Rsp, ArrayRef Objects); +void runMSVCLinker(std::string rsp, ArrayRef objects); // Create enum with OPT_xxx values for each option in Options.td enum { diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index 02357ff..59bdaec 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -47,75 +47,75 @@ const uint16_t RT_MANIFEST = 24; class Executor { public: - explicit Executor(StringRef S) : Prog(Saver.save(S)) {} - void add(StringRef S) { Args.push_back(Saver.save(S)); } - void add(std::string &S) { Args.push_back(Saver.save(S)); } - void add(Twine S) { Args.push_back(Saver.save(S)); } - void add(const char *S) { Args.push_back(Saver.save(S)); } + explicit Executor(StringRef s) : prog(saver.save(s)) {} + void add(StringRef s) { args.push_back(saver.save(s)); } + void add(std::string &s) { args.push_back(saver.save(s)); } + void add(Twine s) { args.push_back(saver.save(s)); } + void add(const char *s) { args.push_back(saver.save(s)); } void run() { - ErrorOr ExeOrErr = sys::findProgramByName(Prog); - if (auto EC = ExeOrErr.getError()) - fatal("unable to find " + Prog + " in PATH: " + EC.message()); - StringRef Exe = Saver.save(*ExeOrErr); - Args.insert(Args.begin(), Exe); + ErrorOr exeOrErr = sys::findProgramByName(prog); + if (auto ec = exeOrErr.getError()) + fatal("unable to find " + prog + " in PATH: " + ec.message()); + StringRef exe = saver.save(*exeOrErr); + args.insert(args.begin(), exe); - if (sys::ExecuteAndWait(Args[0], Args) != 0) + if (sys::ExecuteAndWait(args[0], args) != 0) fatal("ExecuteAndWait failed: " + - llvm::join(Args.begin(), Args.end(), " ")); + llvm::join(args.begin(), args.end(), " ")); } private: - StringRef Prog; - std::vector Args; + StringRef prog; + std::vector args; }; } // anonymous namespace // Parses a string in the form of "[,]". -void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) { - StringRef S1, S2; - std::tie(S1, S2) = Arg.split(','); - if (S1.getAsInteger(0, *Addr)) - fatal("invalid number: " + S1); - if (Size && !S2.empty() && S2.getAsInteger(0, *Size)) - fatal("invalid number: " + S2); +void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) { + StringRef s1, s2; + std::tie(s1, s2) = arg.split(','); + if (s1.getAsInteger(0, *addr)) + fatal("invalid number: " + s1); + if (size && !s2.empty() && s2.getAsInteger(0, *size)) + fatal("invalid number: " + s2); } // Parses a string in the form of "[.]". // If second number is not present, Minor is set to 0. -void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) { - StringRef S1, S2; - std::tie(S1, S2) = Arg.split('.'); - if (S1.getAsInteger(0, *Major)) - fatal("invalid number: " + S1); - *Minor = 0; - if (!S2.empty() && S2.getAsInteger(0, *Minor)) - fatal("invalid number: " + S2); -} - -void parseGuard(StringRef FullArg) { - SmallVector SplitArgs; - FullArg.split(SplitArgs, ","); - for (StringRef Arg : SplitArgs) { - if (Arg.equals_lower("no")) - Config->GuardCF = GuardCFLevel::Off; - else if (Arg.equals_lower("nolongjmp")) - Config->GuardCF = GuardCFLevel::NoLongJmp; - else if (Arg.equals_lower("cf") || Arg.equals_lower("longjmp")) - Config->GuardCF = GuardCFLevel::Full; +void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor) { + StringRef s1, s2; + std::tie(s1, s2) = arg.split('.'); + if (s1.getAsInteger(0, *major)) + fatal("invalid number: " + s1); + *minor = 0; + if (!s2.empty() && s2.getAsInteger(0, *minor)) + fatal("invalid number: " + s2); +} + +void parseGuard(StringRef fullArg) { + SmallVector splitArgs; + fullArg.split(splitArgs, ","); + for (StringRef arg : splitArgs) { + if (arg.equals_lower("no")) + config->guardCF = GuardCFLevel::Off; + else if (arg.equals_lower("nolongjmp")) + config->guardCF = GuardCFLevel::NoLongJmp; + else if (arg.equals_lower("cf") || arg.equals_lower("longjmp")) + config->guardCF = GuardCFLevel::Full; else - fatal("invalid argument to /guard: " + Arg); + fatal("invalid argument to /guard: " + arg); } } // Parses a string in the form of "[,[.]]". -void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, - uint32_t *Minor) { - StringRef SysStr, Ver; - std::tie(SysStr, Ver) = Arg.split(','); - std::string SysStrLower = SysStr.lower(); - *Sys = StringSwitch(SysStrLower) +void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, + uint32_t *minor) { + StringRef sysStr, ver; + std::tie(sysStr, ver) = arg.split(','); + std::string sysStrLower = sysStr.lower(); + *sys = StringSwitch(sysStrLower) .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI) .Case("default", IMAGE_SUBSYSTEM_UNKNOWN) @@ -127,217 +127,217 @@ void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI) .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI) .Default(IMAGE_SUBSYSTEM_UNKNOWN); - if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN && SysStrLower != "default") - fatal("unknown subsystem: " + SysStr); - if (!Ver.empty()) - parseVersion(Ver, Major, Minor); + if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default") + fatal("unknown subsystem: " + sysStr); + if (!ver.empty()) + parseVersion(ver, major, minor); } // Parse a string of the form of "=". // Results are directly written to Config. -void parseAlternateName(StringRef S) { - StringRef From, To; - std::tie(From, To) = S.split('='); - if (From.empty() || To.empty()) - fatal("/alternatename: invalid argument: " + S); - auto It = Config->AlternateNames.find(From); - if (It != Config->AlternateNames.end() && It->second != To) - fatal("/alternatename: conflicts: " + S); - Config->AlternateNames.insert(It, std::make_pair(From, To)); +void parseAlternateName(StringRef s) { + StringRef from, to; + std::tie(from, to) = s.split('='); + if (from.empty() || to.empty()) + fatal("/alternatename: invalid argument: " + s); + auto it = config->alternateNames.find(from); + if (it != config->alternateNames.end() && it->second != to) + fatal("/alternatename: conflicts: " + s); + config->alternateNames.insert(it, std::make_pair(from, to)); } // Parse a string of the form of "=". // Results are directly written to Config. -void parseMerge(StringRef S) { - StringRef From, To; - std::tie(From, To) = S.split('='); - if (From.empty() || To.empty()) - fatal("/merge: invalid argument: " + S); - if (From == ".rsrc" || To == ".rsrc") +void parseMerge(StringRef s) { + StringRef from, to; + std::tie(from, to) = s.split('='); + if (from.empty() || to.empty()) + fatal("/merge: invalid argument: " + s); + if (from == ".rsrc" || to == ".rsrc") fatal("/merge: cannot merge '.rsrc' with any section"); - if (From == ".reloc" || To == ".reloc") + if (from == ".reloc" || to == ".reloc") fatal("/merge: cannot merge '.reloc' with any section"); - auto Pair = Config->Merge.insert(std::make_pair(From, To)); - bool Inserted = Pair.second; - if (!Inserted) { - StringRef Existing = Pair.first->second; - if (Existing != To) - warn(S + ": already merged into " + Existing); + auto pair = config->merge.insert(std::make_pair(from, to)); + bool inserted = pair.second; + if (!inserted) { + StringRef existing = pair.first->second; + if (existing != to) + warn(s + ": already merged into " + existing); } } -static uint32_t parseSectionAttributes(StringRef S) { - uint32_t Ret = 0; - for (char C : S.lower()) { - switch (C) { +static uint32_t parseSectionAttributes(StringRef s) { + uint32_t ret = 0; + for (char c : s.lower()) { + switch (c) { case 'd': - Ret |= IMAGE_SCN_MEM_DISCARDABLE; + ret |= IMAGE_SCN_MEM_DISCARDABLE; break; case 'e': - Ret |= IMAGE_SCN_MEM_EXECUTE; + ret |= IMAGE_SCN_MEM_EXECUTE; break; case 'k': - Ret |= IMAGE_SCN_MEM_NOT_CACHED; + ret |= IMAGE_SCN_MEM_NOT_CACHED; break; case 'p': - Ret |= IMAGE_SCN_MEM_NOT_PAGED; + ret |= IMAGE_SCN_MEM_NOT_PAGED; break; case 'r': - Ret |= IMAGE_SCN_MEM_READ; + ret |= IMAGE_SCN_MEM_READ; break; case 's': - Ret |= IMAGE_SCN_MEM_SHARED; + ret |= IMAGE_SCN_MEM_SHARED; break; case 'w': - Ret |= IMAGE_SCN_MEM_WRITE; + ret |= IMAGE_SCN_MEM_WRITE; break; default: - fatal("/section: invalid argument: " + S); + fatal("/section: invalid argument: " + s); } } - return Ret; + return ret; } // Parses /section option argument. -void parseSection(StringRef S) { - StringRef Name, Attrs; - std::tie(Name, Attrs) = S.split(','); - if (Name.empty() || Attrs.empty()) - fatal("/section: invalid argument: " + S); - Config->Section[Name] = parseSectionAttributes(Attrs); +void parseSection(StringRef s) { + StringRef name, attrs; + std::tie(name, attrs) = s.split(','); + if (name.empty() || attrs.empty()) + fatal("/section: invalid argument: " + s); + config->section[name] = parseSectionAttributes(attrs); } // Parses /aligncomm option argument. -void parseAligncomm(StringRef S) { - StringRef Name, Align; - std::tie(Name, Align) = S.split(','); - if (Name.empty() || Align.empty()) { - error("/aligncomm: invalid argument: " + S); +void parseAligncomm(StringRef s) { + StringRef name, align; + std::tie(name, align) = s.split(','); + if (name.empty() || align.empty()) { + error("/aligncomm: invalid argument: " + s); return; } - int V; - if (Align.getAsInteger(0, V)) { - error("/aligncomm: invalid argument: " + S); + int v; + if (align.getAsInteger(0, v)) { + error("/aligncomm: invalid argument: " + s); return; } - Config->AlignComm[Name] = std::max(Config->AlignComm[Name], 1 << V); + config->alignComm[name] = std::max(config->alignComm[name], 1 << v); } // Parses /functionpadmin option argument. -void parseFunctionPadMin(llvm::opt::Arg *A, llvm::COFF::MachineTypes Machine) { - StringRef Arg = A->getNumValues() ? A->getValue() : ""; - if (!Arg.empty()) { +void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine) { + StringRef arg = a->getNumValues() ? a->getValue() : ""; + if (!arg.empty()) { // Optional padding in bytes is given. - if (Arg.getAsInteger(0, Config->FunctionPadMin)) - error("/functionpadmin: invalid argument: " + Arg); + if (arg.getAsInteger(0, config->functionPadMin)) + error("/functionpadmin: invalid argument: " + arg); return; } // No optional argument given. // Set default padding based on machine, similar to link.exe. // There is no default padding for ARM platforms. - if (Machine == I386) { - Config->FunctionPadMin = 5; - } else if (Machine == AMD64) { - Config->FunctionPadMin = 6; + if (machine == I386) { + config->functionPadMin = 5; + } else if (machine == AMD64) { + config->functionPadMin = 6; } else { - error("/functionpadmin: invalid argument for this machine: " + Arg); + error("/functionpadmin: invalid argument for this machine: " + arg); } } // Parses a string in the form of "EMBED[,=]|NO". // Results are directly written to Config. -void parseManifest(StringRef Arg) { - if (Arg.equals_lower("no")) { - Config->Manifest = Configuration::No; +void parseManifest(StringRef arg) { + if (arg.equals_lower("no")) { + config->manifest = Configuration::No; return; } - if (!Arg.startswith_lower("embed")) - fatal("invalid option " + Arg); - Config->Manifest = Configuration::Embed; - Arg = Arg.substr(strlen("embed")); - if (Arg.empty()) + if (!arg.startswith_lower("embed")) + fatal("invalid option " + arg); + config->manifest = Configuration::Embed; + arg = arg.substr(strlen("embed")); + if (arg.empty()) return; - if (!Arg.startswith_lower(",id=")) - fatal("invalid option " + Arg); - Arg = Arg.substr(strlen(",id=")); - if (Arg.getAsInteger(0, Config->ManifestID)) - fatal("invalid option " + Arg); + if (!arg.startswith_lower(",id=")) + fatal("invalid option " + arg); + arg = arg.substr(strlen(",id=")); + if (arg.getAsInteger(0, config->manifestID)) + fatal("invalid option " + arg); } // Parses a string in the form of "level=|uiAccess=|NO". // Results are directly written to Config. -void parseManifestUAC(StringRef Arg) { - if (Arg.equals_lower("no")) { - Config->ManifestUAC = false; +void parseManifestUAC(StringRef arg) { + if (arg.equals_lower("no")) { + config->manifestUAC = false; return; } for (;;) { - Arg = Arg.ltrim(); - if (Arg.empty()) + arg = arg.ltrim(); + if (arg.empty()) return; - if (Arg.startswith_lower("level=")) { - Arg = Arg.substr(strlen("level=")); - std::tie(Config->ManifestLevel, Arg) = Arg.split(" "); + if (arg.startswith_lower("level=")) { + arg = arg.substr(strlen("level=")); + std::tie(config->manifestLevel, arg) = arg.split(" "); continue; } - if (Arg.startswith_lower("uiaccess=")) { - Arg = Arg.substr(strlen("uiaccess=")); - std::tie(Config->ManifestUIAccess, Arg) = Arg.split(" "); + if (arg.startswith_lower("uiaccess=")) { + arg = arg.substr(strlen("uiaccess=")); + std::tie(config->manifestUIAccess, arg) = arg.split(" "); continue; } - fatal("invalid option " + Arg); + fatal("invalid option " + arg); } } // Parses a string in the form of "cd|net[,(cd|net)]*" // Results are directly written to Config. -void parseSwaprun(StringRef Arg) { +void parseSwaprun(StringRef arg) { do { - StringRef Swaprun, NewArg; - std::tie(Swaprun, NewArg) = Arg.split(','); - if (Swaprun.equals_lower("cd")) - Config->SwaprunCD = true; - else if (Swaprun.equals_lower("net")) - Config->SwaprunNet = true; - else if (Swaprun.empty()) + StringRef swaprun, newArg; + std::tie(swaprun, newArg) = arg.split(','); + if (swaprun.equals_lower("cd")) + config->swaprunCD = true; + else if (swaprun.equals_lower("net")) + config->swaprunNet = true; + else if (swaprun.empty()) error("/swaprun: missing argument"); else - error("/swaprun: invalid argument: " + Swaprun); + error("/swaprun: invalid argument: " + swaprun); // To catch trailing commas, e.g. `/spawrun:cd,` - if (NewArg.empty() && Arg.endswith(",")) + if (newArg.empty() && arg.endswith(",")) error("/swaprun: missing argument"); - Arg = NewArg; - } while (!Arg.empty()); + arg = newArg; + } while (!arg.empty()); } // An RAII temporary file class that automatically removes a temporary file. namespace { class TemporaryFile { public: - TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") { - SmallString<128> S; - if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S)) - fatal("cannot create a temporary file: " + EC.message()); - Path = S.str(); - - if (!Contents.empty()) { - std::error_code EC; - raw_fd_ostream OS(Path, EC, sys::fs::F_None); - if (EC) - fatal("failed to open " + Path + ": " + EC.message()); - OS << Contents; + TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") { + SmallString<128> s; + if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s)) + fatal("cannot create a temporary file: " + ec.message()); + path = s.str(); + + if (!contents.empty()) { + std::error_code ec; + raw_fd_ostream os(path, ec, sys::fs::F_None); + if (ec) + fatal("failed to open " + path + ": " + ec.message()); + os << contents; } } - TemporaryFile(TemporaryFile &&Obj) { - std::swap(Path, Obj.Path); + TemporaryFile(TemporaryFile &&obj) { + std::swap(path, obj.path); } ~TemporaryFile() { - if (Path.empty()) + if (path.empty()) return; - if (sys::fs::remove(Path)) - fatal("failed to remove " + Path); + if (sys::fs::remove(path)) + fatal("failed to remove " + path); } // Returns a memory buffer of this temporary file. @@ -346,389 +346,389 @@ public: // is called (you cannot remove an opened file on Windows.) std::unique_ptr getMemoryBuffer() { // IsVolatileSize=true forces MemoryBuffer to not use mmap(). - return CHECK(MemoryBuffer::getFile(Path, /*FileSize=*/-1, + return CHECK(MemoryBuffer::getFile(path, /*FileSize=*/-1, /*RequiresNullTerminator=*/false, /*IsVolatileSize=*/true), - "could not open " + Path); + "could not open " + path); } - std::string Path; + std::string path; }; } static std::string createDefaultXml() { - std::string Ret; - raw_string_ostream OS(Ret); + std::string ret; + raw_string_ostream os(ret); // Emit the XML. Note that we do *not* verify that the XML attributes are // syntactically correct. This is intentional for link.exe compatibility. - OS << "\n" + os << "\n" << "\n"; - if (Config->ManifestUAC) { - OS << " \n" + if (config->manifestUAC) { + os << " \n" << " \n" << " \n" - << " \n" + << " \n" << " \n" << " \n" << " \n"; } - if (!Config->ManifestDependency.empty()) { - OS << " \n" + if (!config->manifestDependency.empty()) { + os << " \n" << " \n" - << " ManifestDependency << " />\n" + << " manifestDependency << " />\n" << " \n" << " \n"; } - OS << "\n"; - return OS.str(); + os << "\n"; + return os.str(); } -static std::string createManifestXmlWithInternalMt(StringRef DefaultXml) { - std::unique_ptr DefaultXmlCopy = - MemoryBuffer::getMemBufferCopy(DefaultXml); +static std::string createManifestXmlWithInternalMt(StringRef defaultXml) { + std::unique_ptr defaultXmlCopy = + MemoryBuffer::getMemBufferCopy(defaultXml); - windows_manifest::WindowsManifestMerger Merger; - if (auto E = Merger.merge(*DefaultXmlCopy.get())) + windows_manifest::WindowsManifestMerger merger; + if (auto e = merger.merge(*defaultXmlCopy.get())) fatal("internal manifest tool failed on default xml: " + - toString(std::move(E))); + toString(std::move(e))); - for (StringRef Filename : Config->ManifestInput) { - std::unique_ptr Manifest = - check(MemoryBuffer::getFile(Filename)); - if (auto E = Merger.merge(*Manifest.get())) - fatal("internal manifest tool failed on file " + Filename + ": " + - toString(std::move(E))); + for (StringRef filename : config->manifestInput) { + std::unique_ptr manifest = + check(MemoryBuffer::getFile(filename)); + if (auto e = merger.merge(*manifest.get())) + fatal("internal manifest tool failed on file " + filename + ": " + + toString(std::move(e))); } - return Merger.getMergedManifest().get()->getBuffer(); + return merger.getMergedManifest().get()->getBuffer(); } -static std::string createManifestXmlWithExternalMt(StringRef DefaultXml) { +static std::string createManifestXmlWithExternalMt(StringRef defaultXml) { // Create the default manifest file as a temporary file. TemporaryFile Default("defaultxml", "manifest"); - std::error_code EC; - raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text); - if (EC) - fatal("failed to open " + Default.Path + ": " + EC.message()); - OS << DefaultXml; - OS.close(); + std::error_code ec; + raw_fd_ostream os(Default.path, ec, sys::fs::F_Text); + if (ec) + fatal("failed to open " + Default.path + ": " + ec.message()); + os << defaultXml; + os.close(); // Merge user-supplied manifests if they are given. Since libxml2 is not // enabled, we must shell out to Microsoft's mt.exe tool. - TemporaryFile User("user", "manifest"); + TemporaryFile user("user", "manifest"); - Executor E("mt.exe"); - E.add("/manifest"); - E.add(Default.Path); - for (StringRef Filename : Config->ManifestInput) { - E.add("/manifest"); - E.add(Filename); + Executor e("mt.exe"); + e.add("/manifest"); + e.add(Default.path); + for (StringRef filename : config->manifestInput) { + e.add("/manifest"); + e.add(filename); } - E.add("/nologo"); - E.add("/out:" + StringRef(User.Path)); - E.run(); + e.add("/nologo"); + e.add("/out:" + StringRef(user.path)); + e.run(); - return CHECK(MemoryBuffer::getFile(User.Path), "could not open " + User.Path) + return CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path) .get() ->getBuffer(); } static std::string createManifestXml() { - std::string DefaultXml = createDefaultXml(); - if (Config->ManifestInput.empty()) - return DefaultXml; + std::string defaultXml = createDefaultXml(); + if (config->manifestInput.empty()) + return defaultXml; if (windows_manifest::isAvailable()) - return createManifestXmlWithInternalMt(DefaultXml); + return createManifestXmlWithInternalMt(defaultXml); - return createManifestXmlWithExternalMt(DefaultXml); + return createManifestXmlWithExternalMt(defaultXml); } static std::unique_ptr -createMemoryBufferForManifestRes(size_t ManifestSize) { - size_t ResSize = alignTo( +createMemoryBufferForManifestRes(size_t manifestSize) { + size_t resSize = alignTo( object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE + sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + - sizeof(object::WinResHeaderSuffix) + ManifestSize, + sizeof(object::WinResHeaderSuffix) + manifestSize, object::WIN_RES_DATA_ALIGNMENT); - return WritableMemoryBuffer::getNewMemBuffer(ResSize, Config->OutputFile + + return WritableMemoryBuffer::getNewMemBuffer(resSize, config->outputFile + ".manifest.res"); } -static void writeResFileHeader(char *&Buf) { - memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic)); - Buf += sizeof(COFF::WinResMagic); - memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE); - Buf += object::WIN_RES_NULL_ENTRY_SIZE; +static void writeResFileHeader(char *&buf) { + memcpy(buf, COFF::WinResMagic, sizeof(COFF::WinResMagic)); + buf += sizeof(COFF::WinResMagic); + memset(buf, 0, object::WIN_RES_NULL_ENTRY_SIZE); + buf += object::WIN_RES_NULL_ENTRY_SIZE; } -static void writeResEntryHeader(char *&Buf, size_t ManifestSize) { +static void writeResEntryHeader(char *&buf, size_t manifestSize) { // Write the prefix. - auto *Prefix = reinterpret_cast(Buf); - Prefix->DataSize = ManifestSize; - Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) + + auto *prefix = reinterpret_cast(buf); + prefix->DataSize = manifestSize; + prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + sizeof(object::WinResHeaderSuffix); - Buf += sizeof(object::WinResHeaderPrefix); + buf += sizeof(object::WinResHeaderPrefix); // Write the Type/Name IDs. - auto *IDs = reinterpret_cast(Buf); - IDs->setType(RT_MANIFEST); - IDs->setName(Config->ManifestID); - Buf += sizeof(object::WinResIDs); + auto *iDs = reinterpret_cast(buf); + iDs->setType(RT_MANIFEST); + iDs->setName(config->manifestID); + buf += sizeof(object::WinResIDs); // Write the suffix. - auto *Suffix = reinterpret_cast(Buf); - Suffix->DataVersion = 0; - Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE; - Suffix->Language = SUBLANG_ENGLISH_US; - Suffix->Version = 0; - Suffix->Characteristics = 0; - Buf += sizeof(object::WinResHeaderSuffix); + auto *suffix = reinterpret_cast(buf); + suffix->DataVersion = 0; + suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE; + suffix->Language = SUBLANG_ENGLISH_US; + suffix->Version = 0; + suffix->Characteristics = 0; + buf += sizeof(object::WinResHeaderSuffix); } // Create a resource file containing a manifest XML. std::unique_ptr createManifestRes() { - std::string Manifest = createManifestXml(); + std::string manifest = createManifestXml(); - std::unique_ptr Res = - createMemoryBufferForManifestRes(Manifest.size()); + std::unique_ptr res = + createMemoryBufferForManifestRes(manifest.size()); - char *Buf = Res->getBufferStart(); - writeResFileHeader(Buf); - writeResEntryHeader(Buf, Manifest.size()); + char *buf = res->getBufferStart(); + writeResFileHeader(buf); + writeResEntryHeader(buf, manifest.size()); // Copy the manifest data into the .res file. - std::copy(Manifest.begin(), Manifest.end(), Buf); - return std::move(Res); + std::copy(manifest.begin(), manifest.end(), buf); + return std::move(res); } void createSideBySideManifest() { - std::string Path = Config->ManifestFile; - if (Path == "") - Path = Config->OutputFile + ".manifest"; - std::error_code EC; - raw_fd_ostream Out(Path, EC, sys::fs::F_Text); - if (EC) - fatal("failed to create manifest: " + EC.message()); - Out << createManifestXml(); + std::string path = config->manifestFile; + if (path == "") + path = config->outputFile + ".manifest"; + std::error_code ec; + raw_fd_ostream out(path, ec, sys::fs::F_Text); + if (ec) + fatal("failed to create manifest: " + ec.message()); + out << createManifestXml(); } // Parse a string in the form of // "[=][,@ordinal[,NONAME]][,DATA][,PRIVATE]" // or "=.". // Used for parsing /export arguments. -Export parseExport(StringRef Arg) { - Export E; - StringRef Rest; - std::tie(E.Name, Rest) = Arg.split(","); - if (E.Name.empty()) +Export parseExport(StringRef arg) { + Export e; + StringRef rest; + std::tie(e.name, rest) = arg.split(","); + if (e.name.empty()) goto err; - if (E.Name.contains('=')) { - StringRef X, Y; - std::tie(X, Y) = E.Name.split("="); + if (e.name.contains('=')) { + StringRef x, y; + std::tie(x, y) = e.name.split("="); // If "=.". - if (Y.contains(".")) { - E.Name = X; - E.ForwardTo = Y; - return E; + if (y.contains(".")) { + e.name = x; + e.forwardTo = y; + return e; } - E.ExtName = X; - E.Name = Y; - if (E.Name.empty()) + e.extName = x; + e.name = y; + if (e.name.empty()) goto err; } // If "=[,@ordinal[,NONAME]][,DATA][,PRIVATE]" - while (!Rest.empty()) { - StringRef Tok; - std::tie(Tok, Rest) = Rest.split(","); - if (Tok.equals_lower("noname")) { - if (E.Ordinal == 0) + while (!rest.empty()) { + StringRef tok; + std::tie(tok, rest) = rest.split(","); + if (tok.equals_lower("noname")) { + if (e.ordinal == 0) goto err; - E.Noname = true; + e.noname = true; continue; } - if (Tok.equals_lower("data")) { - E.Data = true; + if (tok.equals_lower("data")) { + e.data = true; continue; } - if (Tok.equals_lower("constant")) { - E.Constant = true; + if (tok.equals_lower("constant")) { + e.constant = true; continue; } - if (Tok.equals_lower("private")) { - E.Private = true; + if (tok.equals_lower("private")) { + e.isPrivate = true; continue; } - if (Tok.startswith("@")) { - int32_t Ord; - if (Tok.substr(1).getAsInteger(0, Ord)) + if (tok.startswith("@")) { + int32_t ord; + if (tok.substr(1).getAsInteger(0, ord)) goto err; - if (Ord <= 0 || 65535 < Ord) + if (ord <= 0 || 65535 < ord) goto err; - E.Ordinal = Ord; + e.ordinal = ord; continue; } goto err; } - return E; + return e; err: - fatal("invalid /export: " + Arg); + fatal("invalid /export: " + arg); } -static StringRef undecorate(StringRef Sym) { - if (Config->Machine != I386) - return Sym; +static StringRef undecorate(StringRef sym) { + if (config->machine != I386) + return sym; // In MSVC mode, a fully decorated stdcall function is exported // as-is with the leading underscore (with type IMPORT_NAME). // In MinGW mode, a decorated stdcall function gets the underscore // removed, just like normal cdecl functions. - if (Sym.startswith("_") && Sym.contains('@') && !Config->MinGW) - return Sym; - return Sym.startswith("_") ? Sym.substr(1) : Sym; + if (sym.startswith("_") && sym.contains('@') && !config->mingw) + return sym; + return sym.startswith("_") ? sym.substr(1) : sym; } // Convert stdcall/fastcall style symbols into unsuffixed symbols, // with or without a leading underscore. (MinGW specific.) -static StringRef killAt(StringRef Sym, bool Prefix) { - if (Sym.empty()) - return Sym; +static StringRef killAt(StringRef sym, bool prefix) { + if (sym.empty()) + return sym; // Strip any trailing stdcall suffix - Sym = Sym.substr(0, Sym.find('@', 1)); - if (!Sym.startswith("@")) { - if (Prefix && !Sym.startswith("_")) - return Saver.save("_" + Sym); - return Sym; + sym = sym.substr(0, sym.find('@', 1)); + if (!sym.startswith("@")) { + if (prefix && !sym.startswith("_")) + return saver.save("_" + sym); + return sym; } // For fastcall, remove the leading @ and replace it with an // underscore, if prefixes are used. - Sym = Sym.substr(1); - if (Prefix) - Sym = Saver.save("_" + Sym); - return Sym; + sym = sym.substr(1); + if (prefix) + sym = saver.save("_" + sym); + return sym; } // Performs error checking on all /export arguments. // It also sets ordinals. void fixupExports() { // Symbol ordinals must be unique. - std::set Ords; - for (Export &E : Config->Exports) { - if (E.Ordinal == 0) + std::set ords; + for (Export &e : config->exports) { + if (e.ordinal == 0) continue; - if (!Ords.insert(E.Ordinal).second) - fatal("duplicate export ordinal: " + E.Name); + if (!ords.insert(e.ordinal).second) + fatal("duplicate export ordinal: " + e.name); } - for (Export &E : Config->Exports) { - if (!E.ForwardTo.empty()) { - E.ExportName = undecorate(E.Name); + for (Export &e : config->exports) { + if (!e.forwardTo.empty()) { + e.exportName = undecorate(e.name); } else { - E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + e.exportName = undecorate(e.extName.empty() ? e.name : e.extName); } } - if (Config->KillAt && Config->Machine == I386) { - for (Export &E : Config->Exports) { - E.Name = killAt(E.Name, true); - E.ExportName = killAt(E.ExportName, false); - E.ExtName = killAt(E.ExtName, true); - E.SymbolName = killAt(E.SymbolName, true); + if (config->killAt && config->machine == I386) { + for (Export &e : config->exports) { + e.name = killAt(e.name, true); + e.exportName = killAt(e.exportName, false); + e.extName = killAt(e.extName, true); + e.symbolName = killAt(e.symbolName, true); } } // Uniquefy by name. - DenseMap Map(Config->Exports.size()); - std::vector V; - for (Export &E : Config->Exports) { - auto Pair = Map.insert(std::make_pair(E.ExportName, &E)); - bool Inserted = Pair.second; - if (Inserted) { - V.push_back(E); + DenseMap map(config->exports.size()); + std::vector v; + for (Export &e : config->exports) { + auto pair = map.insert(std::make_pair(e.exportName, &e)); + bool inserted = pair.second; + if (inserted) { + v.push_back(e); continue; } - Export *Existing = Pair.first->second; - if (E == *Existing || E.Name != Existing->Name) + Export *existing = pair.first->second; + if (e == *existing || e.name != existing->name) continue; - warn("duplicate /export option: " + E.Name); + warn("duplicate /export option: " + e.name); } - Config->Exports = std::move(V); + config->exports = std::move(v); // Sort by name. - std::sort(Config->Exports.begin(), Config->Exports.end(), - [](const Export &A, const Export &B) { - return A.ExportName < B.ExportName; + std::sort(config->exports.begin(), config->exports.end(), + [](const Export &a, const Export &b) { + return a.exportName < b.exportName; }); } void assignExportOrdinals() { // Assign unique ordinals if default (= 0). - uint16_t Max = 0; - for (Export &E : Config->Exports) - Max = std::max(Max, E.Ordinal); - for (Export &E : Config->Exports) - if (E.Ordinal == 0) - E.Ordinal = ++Max; + uint16_t max = 0; + for (Export &e : config->exports) + max = std::max(max, e.ordinal); + for (Export &e : config->exports) + if (e.ordinal == 0) + e.ordinal = ++max; } // Parses a string in the form of "key=value" and check // if value matches previous values for the same key. -void checkFailIfMismatch(StringRef Arg, InputFile *Source) { - StringRef K, V; - std::tie(K, V) = Arg.split('='); - if (K.empty() || V.empty()) - fatal("/failifmismatch: invalid argument: " + Arg); - std::pair Existing = Config->MustMatch[K]; - if (!Existing.first.empty() && V != Existing.first) { - std::string SourceStr = Source ? toString(Source) : "cmd-line"; - std::string ExistingStr = - Existing.second ? toString(Existing.second) : "cmd-line"; - fatal("/failifmismatch: mismatch detected for '" + K + "':\n>>> " + - ExistingStr + " has value " + Existing.first + "\n>>> " + SourceStr + - " has value " + V); - } - Config->MustMatch[K] = {V, Source}; +void checkFailIfMismatch(StringRef arg, InputFile *source) { + StringRef k, v; + std::tie(k, v) = arg.split('='); + if (k.empty() || v.empty()) + fatal("/failifmismatch: invalid argument: " + arg); + std::pair existing = config->mustMatch[k]; + if (!existing.first.empty() && v != existing.first) { + std::string sourceStr = source ? toString(source) : "cmd-line"; + std::string existingStr = + existing.second ? toString(existing.second) : "cmd-line"; + fatal("/failifmismatch: mismatch detected for '" + k + "':\n>>> " + + existingStr + " has value " + existing.first + "\n>>> " + sourceStr + + " has value " + v); + } + config->mustMatch[k] = {v, source}; } // Convert Windows resource files (.res files) to a .obj file. // Does what cvtres.exe does, but in-process and cross-platform. -MemoryBufferRef convertResToCOFF(ArrayRef MBs) { - object::WindowsResourceParser Parser; +MemoryBufferRef convertResToCOFF(ArrayRef mbs) { + object::WindowsResourceParser parser; - for (MemoryBufferRef MB : MBs) { - std::unique_ptr Bin = check(object::createBinary(MB)); - object::WindowsResource *RF = dyn_cast(Bin.get()); - if (!RF) + for (MemoryBufferRef mb : mbs) { + std::unique_ptr bin = check(object::createBinary(mb)); + object::WindowsResource *rf = dyn_cast(bin.get()); + if (!rf) fatal("cannot compile non-resource file as resource"); - std::vector Duplicates; - if (auto EC = Parser.parse(RF, Duplicates)) - fatal(toString(std::move(EC))); + std::vector duplicates; + if (auto ec = parser.parse(rf, duplicates)) + fatal(toString(std::move(ec))); - for (const auto &DupeDiag : Duplicates) - if (Config->ForceMultipleRes) - warn(DupeDiag); + for (const auto &dupeDiag : duplicates) + if (config->forceMultipleRes) + warn(dupeDiag); else - error(DupeDiag); + error(dupeDiag); } - Expected> E = - llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser, - Config->Timestamp); - if (!E) - fatal("failed to write .res to COFF: " + toString(E.takeError())); + Expected> e = + llvm::object::writeWindowsResourceCOFF(config->machine, parser, + config->timestamp); + if (!e) + fatal("failed to write .res to COFF: " + toString(e.takeError())); - MemoryBufferRef MBRef = **E; - make>(std::move(*E)); // take ownership - return MBRef; + MemoryBufferRef mbref = **e; + make>(std::move(*e)); // take ownership + return mbref; } // Create OptTable @@ -739,7 +739,7 @@ MemoryBufferRef convertResToCOFF(ArrayRef MBs) { #undef PREFIX // Create table mapping all options defined in Options.td -static const llvm::opt::OptTable::Info InfoTable[] = { +static const llvm::opt::OptTable::Info infoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \ X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, @@ -747,36 +747,36 @@ static const llvm::opt::OptTable::Info InfoTable[] = { #undef OPTION }; -COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {} +COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {} // 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) { - errorHandler().ColorDiagnostics = true; - } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { - errorHandler().ColorDiagnostics = false; + if (arg->getOption().getID() == OPT_color_diagnostics) { + errorHandler().colorDiagnostics = true; + } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { + errorHandler().colorDiagnostics = false; } else { - StringRef S = Arg->getValue(); - if (S == "always") - errorHandler().ColorDiagnostics = true; - else if (S == "never") - errorHandler().ColorDiagnostics = false; - 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") + StringRef s = arg->getValue(); + if (s == "always") + errorHandler().colorDiagnostics = true; + else if (s == "never") + errorHandler().colorDiagnostics = false; + 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") return cl::TokenizeWindowsCommandLine; return cl::TokenizeGNUCommandLine; } @@ -785,111 +785,111 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { } // Parses a given list of options. -opt::InputArgList ArgParser::parse(ArrayRef Argv) { +opt::InputArgList ArgParser::parse(ArrayRef argv) { // Make InputArgList from string vectors. - unsigned MissingIndex; - unsigned MissingCount; + unsigned missingIndex; + unsigned missingCount; // 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 = Table.ParseArgs(Argv, MissingIndex, MissingCount); + opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount); // Expand response files (arguments in the form of @) // and then parse the argument again. - SmallVector ExpandedArgv(Argv.data(), - Argv.data() + Argv.size()); - cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), ExpandedArgv); - Args = Table.ParseArgs(makeArrayRef(ExpandedArgv).drop_front(), MissingIndex, - MissingCount); + SmallVector expandedArgv(argv.data(), + argv.data() + argv.size()); + cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv); + args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex, + missingCount); // Print the real command line if response files are expanded. - if (Args.hasArg(OPT_verbose) && Argv.size() != ExpandedArgv.size()) { - std::string Msg = "Command line:"; - for (const char *S : ExpandedArgv) - Msg += " " + std::string(S); - message(Msg); + if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) { + std::string msg = "Command line:"; + for (const char *s : expandedArgv) + msg += " " + std::string(s); + message(msg); } // Save the command line after response file expansion so we can write it to // the PDB if necessary. - Config->Argv = {ExpandedArgv.begin(), ExpandedArgv.end()}; + config->argv = {expandedArgv.begin(), expandedArgv.end()}; // Handle /WX early since it converts missing argument warnings to errors. - errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false); + errorHandler().fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false); - if (MissingCount) - fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); + if (missingCount) + fatal(Twine(args.getArgString(missingIndex)) + ": missing argument"); - handleColorDiagnostics(Args); + handleColorDiagnostics(args); - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) { - std::string Nearest; - if (Table.findNearest(Arg->getAsString(Args), Nearest) > 1) - warn("ignoring unknown argument '" + Arg->getAsString(Args) + "'"); + for (auto *arg : args.filtered(OPT_UNKNOWN)) { + std::string nearest; + if (table.findNearest(arg->getAsString(args), nearest) > 1) + warn("ignoring unknown argument '" + arg->getAsString(args) + "'"); else - warn("ignoring unknown argument '" + Arg->getAsString(Args) + - "', did you mean '" + Nearest + "'"); + warn("ignoring unknown argument '" + arg->getAsString(args) + + "', did you mean '" + nearest + "'"); } - if (Args.hasArg(OPT_lib)) + if (args.hasArg(OPT_lib)) warn("ignoring /lib since it's not the first argument"); - return Args; + return args; } // Tokenizes and parses a given string as command line in .drective section. // /EXPORT options are processed in fastpath. std::pair> -ArgParser::parseDirectives(StringRef S) { - std::vector Exports; - SmallVector Rest; +ArgParser::parseDirectives(StringRef s) { + std::vector exports; + SmallVector rest; - for (StringRef Tok : tokenize(S)) { - if (Tok.startswith_lower("/export:") || Tok.startswith_lower("-export:")) - Exports.push_back(Tok.substr(strlen("/export:"))); + for (StringRef tok : tokenize(s)) { + if (tok.startswith_lower("/export:") || tok.startswith_lower("-export:")) + exports.push_back(tok.substr(strlen("/export:"))); else - Rest.push_back(Tok.data()); + rest.push_back(tok.data()); } // Make InputArgList from unparsed string vectors. - unsigned MissingIndex; - unsigned MissingCount; + unsigned missingIndex; + unsigned missingCount; - opt::InputArgList Args = Table.ParseArgs(Rest, MissingIndex, MissingCount); + opt::InputArgList args = table.ParseArgs(rest, missingIndex, missingCount); - if (MissingCount) - fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) - warn("ignoring unknown argument: " + Arg->getAsString(Args)); - return {std::move(Args), std::move(Exports)}; + if (missingCount) + fatal(Twine(args.getArgString(missingIndex)) + ": missing argument"); + for (auto *arg : args.filtered(OPT_UNKNOWN)) + warn("ignoring unknown argument: " + arg->getAsString(args)); + return {std::move(args), std::move(exports)}; } // link.exe has an interesting feature. If LINK or _LINK_ environment // variables exist, their contents are handled as command line strings. // So you can pass extra arguments using them. -opt::InputArgList ArgParser::parseLINK(std::vector Argv) { +opt::InputArgList ArgParser::parseLINK(std::vector argv) { // Concatenate LINK env and command line arguments, and then parse them. - if (Optional S = Process::GetEnv("LINK")) { - std::vector V = tokenize(*S); - Argv.insert(std::next(Argv.begin()), V.begin(), V.end()); + if (Optional s = Process::GetEnv("LINK")) { + std::vector v = tokenize(*s); + argv.insert(std::next(argv.begin()), v.begin(), v.end()); } - if (Optional S = Process::GetEnv("_LINK_")) { - std::vector V = tokenize(*S); - Argv.insert(std::next(Argv.begin()), V.begin(), V.end()); + if (Optional s = Process::GetEnv("_LINK_")) { + std::vector v = tokenize(*s); + argv.insert(std::next(argv.begin()), v.begin(), v.end()); } - return parse(Argv); + return parse(argv); } -std::vector ArgParser::tokenize(StringRef S) { - SmallVector Tokens; - cl::TokenizeWindowsCommandLine(S, Saver, Tokens); - return std::vector(Tokens.begin(), Tokens.end()); +std::vector ArgParser::tokenize(StringRef s) { + SmallVector tokens; + cl::TokenizeWindowsCommandLine(s, saver, tokens); + return std::vector(tokens.begin(), tokens.end()); } -void printHelp(const char *Argv0) { +void printHelp(const char *argv0) { COFFOptTable().PrintHelp(outs(), - (std::string(Argv0) + " [options] file...").c_str(), + (std::string(argv0) + " [options] file...").c_str(), "LLVM Linker", false); } diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index 7e105dd..2b2818d 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -37,32 +37,32 @@ using namespace llvm; namespace lld { namespace coff { -static Timer ICFTimer("ICF", Timer::root()); +static Timer icfTimer("ICF", Timer::root()); class ICF { public: - void run(ArrayRef V); + void run(ArrayRef v); private: - void segregate(size_t Begin, size_t End, bool Constant); + void segregate(size_t begin, size_t end, bool constant); - bool assocEquals(const SectionChunk *A, const SectionChunk *B); + bool assocEquals(const SectionChunk *a, const SectionChunk *b); - bool equalsConstant(const SectionChunk *A, const SectionChunk *B); - bool equalsVariable(const SectionChunk *A, const SectionChunk *B); + bool equalsConstant(const SectionChunk *a, const SectionChunk *b); + bool equalsVariable(const SectionChunk *a, const SectionChunk *b); - bool isEligible(SectionChunk *C); + bool isEligible(SectionChunk *c); - 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, - std::function Fn); + void forEachClassRange(size_t begin, size_t end, + std::function fn); - void forEachClass(std::function Fn); + void forEachClass(std::function fn); - std::vector Chunks; - int Cnt = 0; - std::atomic Repeat = {false}; + std::vector chunks; + int cnt = 0; + std::atomic repeat = {false}; }; // Returns true if section S is subject of ICF. @@ -76,144 +76,144 @@ private: // merge read-only sections in a couple of cases where the address of the // section is insignificant to the user program and the behaviour matches that // of the Visual C++ linker. -bool ICF::isEligible(SectionChunk *C) { +bool ICF::isEligible(SectionChunk *c) { // Non-comdat chunks, dead chunks, and writable chunks are not elegible. - bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE; - if (!C->isCOMDAT() || !C->Live || Writable) + bool writable = c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE; + if (!c->isCOMDAT() || !c->live || writable) return false; // Code sections are eligible. - if (C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) + if (c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) return true; // .pdata and .xdata unwind info sections are eligible. - StringRef OutSecName = C->getSectionName().split('$').first; - if (OutSecName == ".pdata" || OutSecName == ".xdata") + StringRef outSecName = c->getSectionName().split('$').first; + if (outSecName == ".pdata" || outSecName == ".xdata") return true; // So are vtables. - if (C->Sym && C->Sym->getName().startswith("??_7")) + if (c->sym && c->sym->getName().startswith("??_7")) return true; // Anything else not in an address-significance table is eligible. - return !C->KeepUnique; + return !c->keepUnique; } // Split an equivalence class into smaller classes. -void ICF::segregate(size_t Begin, size_t End, bool Constant) { - while (Begin < End) { +void ICF::segregate(size_t begin, size_t end, bool constant) { + while (begin < end) { // Divide [Begin, End) into two. Let Mid be the start index of the // second group. - auto Bound = std::stable_partition( - Chunks.begin() + Begin + 1, Chunks.begin() + End, [&](SectionChunk *S) { - if (Constant) - return equalsConstant(Chunks[Begin], S); - return equalsVariable(Chunks[Begin], S); + auto bound = std::stable_partition( + chunks.begin() + begin + 1, chunks.begin() + end, [&](SectionChunk *s) { + if (constant) + return equalsConstant(chunks[begin], s); + return equalsVariable(chunks[begin], s); }); - size_t Mid = Bound - Chunks.begin(); + size_t mid = bound - chunks.begin(); // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an // equivalence class ID because every group ends with a unique index. - for (size_t I = Begin; I < Mid; ++I) - Chunks[I]->Class[(Cnt + 1) % 2] = Mid; + for (size_t i = begin; i < mid; ++i) + chunks[i]->eqClass[(cnt + 1) % 2] = 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; } } // Returns true if two sections' associative children are equal. -bool ICF::assocEquals(const SectionChunk *A, const SectionChunk *B) { - auto ChildClasses = [&](const SectionChunk *SC) { - std::vector Classes; - for (const SectionChunk &C : SC->children()) - if (!C.getSectionName().startswith(".debug") && - C.getSectionName() != ".gfids$y" && C.getSectionName() != ".gljmp$y") - Classes.push_back(C.Class[Cnt % 2]); - return Classes; +bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) { + auto childClasses = [&](const SectionChunk *sc) { + std::vector classes; + for (const SectionChunk &c : sc->children()) + if (!c.getSectionName().startswith(".debug") && + c.getSectionName() != ".gfids$y" && c.getSectionName() != ".gljmp$y") + classes.push_back(c.eqClass[cnt % 2]); + return classes; }; - return ChildClasses(A) == ChildClasses(B); + return childClasses(a) == childClasses(b); } // Compare "non-moving" part of two sections, namely everything // except relocation targets. -bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { - if (A->RelocsSize != B->RelocsSize) +bool ICF::equalsConstant(const SectionChunk *a, const SectionChunk *b) { + if (a->relocsSize != b->relocsSize) return false; // Compare relocations. - auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { - if (R1.Type != R2.Type || - R1.VirtualAddress != R2.VirtualAddress) { + auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) { + if (r1.Type != r2.Type || + r1.VirtualAddress != r2.VirtualAddress) { return false; } - Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex); - Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex); - if (B1 == B2) + Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex); + Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex); + if (b1 == b2) return true; - if (auto *D1 = dyn_cast(B1)) - if (auto *D2 = dyn_cast(B2)) - return D1->getValue() == D2->getValue() && - D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; + if (auto *d1 = dyn_cast(b1)) + if (auto *d2 = dyn_cast(b2)) + return d1->getValue() == d2->getValue() && + d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2]; return false; }; - if (!std::equal(A->getRelocs().begin(), A->getRelocs().end(), - B->getRelocs().begin(), Eq)) + if (!std::equal(a->getRelocs().begin(), a->getRelocs().end(), + b->getRelocs().begin(), eq)) return false; // Compare section attributes and contents. - return A->getOutputCharacteristics() == B->getOutputCharacteristics() && - A->getSectionName() == B->getSectionName() && - A->Header->SizeOfRawData == B->Header->SizeOfRawData && - A->Checksum == B->Checksum && A->getContents() == B->getContents() && - assocEquals(A, B); + return a->getOutputCharacteristics() == b->getOutputCharacteristics() && + a->getSectionName() == b->getSectionName() && + a->header->SizeOfRawData == b->header->SizeOfRawData && + a->checksum == b->checksum && a->getContents() == b->getContents() && + assocEquals(a, b); } // Compare "moving" part of two sections, namely relocation targets. -bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) { +bool ICF::equalsVariable(const SectionChunk *a, const SectionChunk *b) { // Compare relocations. - auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { - Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex); - Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex); - if (B1 == B2) + auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) { + Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex); + Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex); + if (b1 == b2) return true; - if (auto *D1 = dyn_cast(B1)) - if (auto *D2 = dyn_cast(B2)) - return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; + if (auto *d1 = dyn_cast(b1)) + if (auto *d2 = dyn_cast(b2)) + return d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2]; return false; }; - return std::equal(A->getRelocs().begin(), A->getRelocs().end(), - B->getRelocs().begin(), Eq) && - assocEquals(A, B); + return std::equal(a->getRelocs().begin(), a->getRelocs().end(), + b->getRelocs().begin(), eq) && + assocEquals(a, b); } // Find the first Chunk after Begin that has a different class from Begin. -size_t ICF::findBoundary(size_t Begin, size_t End) { - for (size_t I = Begin + 1; I < End; ++I) - if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2]) - return I; - return End; +size_t ICF::findBoundary(size_t begin, size_t end) { + for (size_t i = begin + 1; i < end; ++i) + if (chunks[begin]->eqClass[cnt % 2] != chunks[i]->eqClass[cnt % 2]) + return i; + return end; } -void ICF::forEachClassRange(size_t Begin, size_t End, - std::function Fn) { - while (Begin < End) { - size_t Mid = findBoundary(Begin, End); - Fn(Begin, Mid); - Begin = Mid; +void ICF::forEachClassRange(size_t begin, size_t end, + std::function fn) { + while (begin < end) { + size_t mid = findBoundary(begin, end); + fn(begin, mid); + begin = mid; } } // Call Fn on each class group. -void ICF::forEachClass(std::function Fn) { +void ICF::forEachClass(std::function fn) { // If the number of sections are too small to use threading, // call Fn sequentially. - if (Chunks.size() < 1024) { - forEachClassRange(0, Chunks.size(), Fn); - ++Cnt; + if (chunks.size() < 1024) { + forEachClassRange(0, chunks.size(), fn); + ++cnt; return; } @@ -221,97 +221,97 @@ void ICF::forEachClass(std::function Fn) { // 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 = Chunks.size() / NumShards; - size_t Boundaries[NumShards + 1]; - Boundaries[0] = 0; - Boundaries[NumShards] = Chunks.size(); - parallelForEachN(1, NumShards, [&](size_t I) { - Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size()); + const size_t numShards = 256; + size_t step = chunks.size() / numShards; + size_t boundaries[numShards + 1]; + boundaries[0] = 0; + boundaries[numShards] = chunks.size(); + parallelForEachN(1, numShards, [&](size_t i) { + boundaries[i] = findBoundary((i - 1) * step, chunks.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; } // Merge identical COMDAT sections. // Two sections are considered the same if their section headers, // contents and relocations are all the same. -void ICF::run(ArrayRef Vec) { - ScopedTimer T(ICFTimer); +void ICF::run(ArrayRef vec) { + ScopedTimer t(icfTimer); // Collect only mergeable sections and group by hash value. - uint32_t NextId = 1; - for (Chunk *C : Vec) { - if (auto *SC = dyn_cast(C)) { - if (isEligible(SC)) - Chunks.push_back(SC); + uint32_t nextId = 1; + for (Chunk *c : vec) { + if (auto *sc = dyn_cast(c)) { + if (isEligible(sc)) + chunks.push_back(sc); else - SC->Class[0] = NextId++; + sc->eqClass[0] = nextId++; } } // Make sure that ICF doesn't merge sections that are being handled by string // tail merging. - for (MergeChunk *MC : MergeChunk::Instances) - if (MC) - for (SectionChunk *SC : MC->Sections) - SC->Class[0] = NextId++; + for (MergeChunk *mc : MergeChunk::instances) + if (mc) + for (SectionChunk *sc : mc->sections) + sc->eqClass[0] = nextId++; // Initially, we use hash values to partition sections. - parallelForEach(Chunks, [&](SectionChunk *SC) { - SC->Class[0] = xxHash64(SC->getContents()); + parallelForEach(chunks, [&](SectionChunk *sc) { + sc->eqClass[0] = xxHash64(sc->getContents()); }); // Combine the hashes of the sections referenced by each section into its // hash. - for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { - parallelForEach(Chunks, [&](SectionChunk *SC) { - uint32_t Hash = SC->Class[Cnt % 2]; - for (Symbol *B : SC->symbols()) - if (auto *Sym = dyn_cast_or_null(B)) - Hash += Sym->getChunk()->Class[Cnt % 2]; + for (unsigned cnt = 0; cnt != 2; ++cnt) { + parallelForEach(chunks, [&](SectionChunk *sc) { + uint32_t hash = sc->eqClass[cnt % 2]; + for (Symbol *b : sc->symbols()) + if (auto *sym = dyn_cast_or_null(b)) + hash += sym->getChunk()->eqClass[cnt % 2]; // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31); + sc->eqClass[(cnt + 1) % 2] = hash | (1U << 31); }); } // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. - llvm::stable_sort(Chunks, [](const SectionChunk *A, const SectionChunk *B) { - return A->Class[0] < B->Class[0]; + llvm::stable_sort(chunks, [](const SectionChunk *a, const SectionChunk *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 in the same classs. - forEachClass([&](size_t Begin, size_t End) { - if (End - Begin == 1) + forEachClass([&](size_t begin, size_t end) { + if (end - begin == 1) return; - log("Selected " + Chunks[Begin]->getDebugName()); - for (size_t I = Begin + 1; I < End; ++I) { - log(" Removed " + Chunks[I]->getDebugName()); - Chunks[Begin]->replace(Chunks[I]); + log("Selected " + chunks[begin]->getDebugName()); + for (size_t i = begin + 1; i < end; ++i) { + log(" Removed " + chunks[i]->getDebugName()); + chunks[begin]->replace(chunks[i]); } }); } // Entry point to ICF. -void doICF(ArrayRef Chunks) { ICF().run(Chunks); } +void doICF(ArrayRef chunks) { ICF().run(chunks); } } // namespace coff } // namespace lld diff --git a/lld/COFF/ICF.h b/lld/COFF/ICF.h index f692c8a..0b3c8fa 100644 --- a/lld/COFF/ICF.h +++ b/lld/COFF/ICF.h @@ -17,7 +17,7 @@ namespace coff { class Chunk; -void doICF(ArrayRef Chunks); +void doICF(ArrayRef chunks); } // namespace coff } // namespace lld diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index aac3b40..6737db8 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -49,80 +49,80 @@ using llvm::support::ulittle32_t; namespace lld { namespace coff { -std::vector ObjFile::Instances; -std::vector ImportFile::Instances; -std::vector BitcodeFile::Instances; +std::vector ObjFile::instances; +std::vector ImportFile::instances; +std::vector BitcodeFile::instances; /// Checks that Source is compatible with being a weak alias to Target. /// If Source is Undefined and has no weak alias set, makes it a weak /// alias to Target. -static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F, - Symbol *Source, Symbol *Target) { - if (auto *U = dyn_cast(Source)) { - if (U->WeakAlias && U->WeakAlias != Target) { +static void checkAndSetWeakAlias(SymbolTable *symtab, InputFile *f, + Symbol *source, Symbol *target) { + if (auto *u = dyn_cast(source)) { + if (u->weakAlias && u->weakAlias != target) { // Weak aliases as produced by GCC are named in the form // .weak.., where is the name // of another symbol emitted near the weak symbol. // Just use the definition from the first object file that defined // this weak symbol. - if (Config->MinGW) + if (config->mingw) return; - Symtab->reportDuplicate(Source, F); + symtab->reportDuplicate(source, f); } - U->WeakAlias = Target; + u->weakAlias = target; } } -ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} +ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {} void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. - File = CHECK(Archive::create(MB), this); + file = CHECK(Archive::create(mb), this); // Read the symbol table to construct Lazy objects. - for (const Archive::Symbol &Sym : File->symbols()) - Symtab->addLazy(this, Sym); + for (const Archive::Symbol &sym : file->symbols()) + symtab->addLazy(this, sym); } // Returns a buffer pointing to a member file containing a given symbol. -void ArchiveFile::addMember(const Archive::Symbol *Sym) { - const Archive::Child &C = - CHECK(Sym->getMember(), - "could not get the member for symbol " + Sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol *sym) { + const Archive::Child &c = + CHECK(sym->getMember(), + "could not get the member for symbol " + sym->getName()); // Return an empty buffer if we have already returned the same buffer. - if (!Seen.insert(C.getChildOffset()).second) + if (!seen.insert(c.getChildOffset()).second) return; - Driver->enqueueArchiveMember(C, Sym->getName(), getName()); + driver->enqueueArchiveMember(c, sym->getName(), getName()); } -std::vector getArchiveMembers(Archive *File) { - std::vector V; - Error Err = Error::success(); - for (const ErrorOr &COrErr : File->children(Err)) { - Archive::Child C = - CHECK(COrErr, - File->getFileName() + ": could not get the child of the archive"); - MemoryBufferRef MBRef = - CHECK(C.getMemoryBufferRef(), - File->getFileName() + +std::vector getArchiveMembers(Archive *file) { + std::vector v; + Error err = Error::success(); + for (const ErrorOr &cOrErr : file->children(err)) { + Archive::Child c = + CHECK(cOrErr, + file->getFileName() + ": could not get the child of the archive"); + MemoryBufferRef mbref = + CHECK(c.getMemoryBufferRef(), + file->getFileName() + ": could not get the buffer for a child of the archive"); - V.push_back(MBRef); + v.push_back(mbref); } - if (Err) - fatal(File->getFileName() + - ": Archive::children failed: " + toString(std::move(Err))); - return V; + if (err) + fatal(file->getFileName() + + ": Archive::children failed: " + toString(std::move(err))); + return v; } void ObjFile::parse() { // Parse a memory buffer as a COFF file. - std::unique_ptr Bin = CHECK(createBinary(MB), this); + std::unique_ptr bin = CHECK(createBinary(mb), this); - if (auto *Obj = dyn_cast(Bin.get())) { - Bin.release(); - COFFObj.reset(Obj); + if (auto *obj = dyn_cast(bin.get())) { + bin.release(); + coffObj.reset(obj); } else { fatal(toString(this) + " is not a COFF file"); } @@ -134,11 +134,11 @@ void ObjFile::parse() { initializeDependencies(); } -const coff_section* ObjFile::getSection(uint32_t I) { - const coff_section *Sec; - if (auto EC = COFFObj->getSection(I, Sec)) - fatal("getSection failed: #" + Twine(I) + ": " + EC.message()); - return Sec; +const coff_section* ObjFile::getSection(uint32_t i) { + const coff_section *sec; + if (auto ec = coffObj->getSection(i, sec)) + fatal("getSection failed: #" + Twine(i) + ": " + ec.message()); + return sec; } // We set SectionChunk pointers in the SparseChunks vector to this value @@ -147,42 +147,42 @@ const coff_section* ObjFile::getSection(uint32_t I) { // an associative section definition together with the parent comdat's leader, // we set the pointer to either nullptr (to mark the section as discarded) or a // valid SectionChunk for that section. -static SectionChunk *const PendingComdat = reinterpret_cast(1); +static SectionChunk *const pendingComdat = reinterpret_cast(1); void ObjFile::initializeChunks() { - uint32_t NumSections = COFFObj->getNumberOfSections(); - Chunks.reserve(NumSections); - SparseChunks.resize(NumSections + 1); - for (uint32_t I = 1; I < NumSections + 1; ++I) { - const coff_section *Sec = getSection(I); - if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT) - SparseChunks[I] = PendingComdat; + uint32_t numSections = coffObj->getNumberOfSections(); + chunks.reserve(numSections); + sparseChunks.resize(numSections + 1); + for (uint32_t i = 1; i < numSections + 1; ++i) { + const coff_section *sec = getSection(i); + if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT) + sparseChunks[i] = pendingComdat; else - SparseChunks[I] = readSection(I, nullptr, ""); + sparseChunks[i] = readSection(i, nullptr, ""); } } -SectionChunk *ObjFile::readSection(uint32_t SectionNumber, - const coff_aux_section_definition *Def, - StringRef LeaderName) { - const coff_section *Sec = getSection(SectionNumber); +SectionChunk *ObjFile::readSection(uint32_t sectionNumber, + const coff_aux_section_definition *def, + StringRef leaderName) { + const coff_section *sec = getSection(sectionNumber); - StringRef Name; - if (Expected E = COFFObj->getSectionName(Sec)) - Name = *E; + StringRef name; + if (Expected e = coffObj->getSectionName(sec)) + name = *e; else - fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " + - toString(E.takeError())); + fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " + + toString(e.takeError())); - if (Name == ".drectve") { - ArrayRef Data; - cantFail(COFFObj->getSectionContents(Sec, Data)); - Directives = StringRef((const char *)Data.data(), Data.size()); + if (name == ".drectve") { + ArrayRef data; + cantFail(coffObj->getSectionContents(sec, data)); + directives = StringRef((const char *)data.data(), data.size()); return nullptr; } - if (Name == ".llvm_addrsig") { - AddrsigSec = Sec; + if (name == ".llvm_addrsig") { + addrsigSec = sec; return nullptr; } @@ -197,166 +197,166 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, // and then write it to a separate .pdb file. // Ignore DWARF debug info unless /debug is given. - if (!Config->Debug && Name.startswith(".debug_")) + if (!config->debug && name.startswith(".debug_")) return nullptr; - if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) + if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) return nullptr; - auto *C = make(this, Sec); - if (Def) - C->Checksum = Def->CheckSum; + auto *c = make(this, sec); + if (def) + c->checksum = def->CheckSum; // link.exe uses the presence of .rsrc$01 for LNK4078, so match that. - if (Name == ".rsrc$01") - IsResourceObjFile = true; + if (name == ".rsrc$01") + isResourceObjFile = true; // CodeView sections are stored to a different vector because they are not // linked in the regular manner. - if (C->isCodeView()) - DebugChunks.push_back(C); - else if (Name == ".gfids$y") - GuardFidChunks.push_back(C); - else if (Name == ".gljmp$y") - GuardLJmpChunks.push_back(C); - else if (Name == ".sxdata") - SXDataChunks.push_back(C); - else if (Config->TailMerge && Sec->NumberOfRelocations == 0 && - Name == ".rdata" && LeaderName.startswith("??_C@")) + if (c->isCodeView()) + debugChunks.push_back(c); + else if (name == ".gfids$y") + guardFidChunks.push_back(c); + else if (name == ".gljmp$y") + guardLJmpChunks.push_back(c); + else if (name == ".sxdata") + sXDataChunks.push_back(c); + else if (config->tailMerge && sec->NumberOfRelocations == 0 && + name == ".rdata" && leaderName.startswith("??_C@")) // COFF sections that look like string literal sections (i.e. no // relocations, in .rdata, leader symbol name matches the MSVC name mangling // for string literals) are subject to string tail merging. - MergeChunk::addSection(C); + MergeChunk::addSection(c); else - Chunks.push_back(C); + chunks.push_back(c); - return C; + return c; } void ObjFile::readAssociativeDefinition( - COFFSymbolRef Sym, const coff_aux_section_definition *Def) { - readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj())); + COFFSymbolRef sym, const coff_aux_section_definition *def) { + readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj())); } -void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym, - const coff_aux_section_definition *Def, - uint32_t ParentIndex) { - SectionChunk *Parent = SparseChunks[ParentIndex]; - int32_t SectionNumber = Sym.getSectionNumber(); - - auto Diag = [&]() { - StringRef Name, ParentName; - COFFObj->getSymbolName(Sym, Name); - - const coff_section *ParentSec = getSection(ParentIndex); - if (Expected E = COFFObj->getSectionName(ParentSec)) - ParentName = *E; - error(toString(this) + ": associative comdat " + Name + " (sec " + - Twine(SectionNumber) + ") has invalid reference to section " + - ParentName + " (sec " + Twine(ParentIndex) + ")"); +void ObjFile::readAssociativeDefinition(COFFSymbolRef sym, + const coff_aux_section_definition *def, + uint32_t parentIndex) { + SectionChunk *parent = sparseChunks[parentIndex]; + int32_t sectionNumber = sym.getSectionNumber(); + + auto diag = [&]() { + StringRef name, parentName; + coffObj->getSymbolName(sym, name); + + const coff_section *parentSec = getSection(parentIndex); + if (Expected e = coffObj->getSectionName(parentSec)) + parentName = *e; + error(toString(this) + ": associative comdat " + name + " (sec " + + Twine(sectionNumber) + ") has invalid reference to section " + + parentName + " (sec " + Twine(parentIndex) + ")"); }; - if (Parent == PendingComdat) { + if (parent == pendingComdat) { // This can happen if an associative comdat refers to another associative // comdat that appears after it (invalid per COFF spec) or to a section // without any symbols. - Diag(); + diag(); return; } // Check whether the parent is prevailing. If it is, so are we, and we read // the section; otherwise mark it as discarded. - if (Parent) { - SectionChunk *C = readSection(SectionNumber, Def, ""); - SparseChunks[SectionNumber] = C; - if (C) { - C->Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE; - Parent->addAssociative(C); + if (parent) { + SectionChunk *c = readSection(sectionNumber, def, ""); + sparseChunks[sectionNumber] = c; + if (c) { + c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE; + parent->addAssociative(c); } } else { - SparseChunks[SectionNumber] = nullptr; + sparseChunks[sectionNumber] = nullptr; } } void ObjFile::recordPrevailingSymbolForMingw( - COFFSymbolRef Sym, DenseMap &PrevailingSectionMap) { + COFFSymbolRef sym, DenseMap &prevailingSectionMap) { // For comdat symbols in executable sections, where this is the copy // of the section chunk we actually include instead of discarding it, // add the symbol to a map to allow using it for implicitly // associating .[px]data$ sections to it. - int32_t SectionNumber = Sym.getSectionNumber(); - SectionChunk *SC = SparseChunks[SectionNumber]; - if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); + int32_t sectionNumber = sym.getSectionNumber(); + SectionChunk *sc = sparseChunks[sectionNumber]; + if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { + StringRef name; + coffObj->getSymbolName(sym, name); if (getMachineType() == I386) - Name.consume_front("_"); - PrevailingSectionMap[Name] = SectionNumber; + name.consume_front("_"); + prevailingSectionMap[name] = sectionNumber; } } void ObjFile::maybeAssociateSEHForMingw( - COFFSymbolRef Sym, const coff_aux_section_definition *Def, - const DenseMap &PrevailingSectionMap) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$") || - Name.consume_front(".eh_frame$")) { + COFFSymbolRef sym, const coff_aux_section_definition *def, + const DenseMap &prevailingSectionMap) { + StringRef name; + coffObj->getSymbolName(sym, name); + if (name.consume_front(".pdata$") || name.consume_front(".xdata$") || + name.consume_front(".eh_frame$")) { // For MinGW, treat .[px]data$ and .eh_frame$ as implicitly // associative to the symbol . - auto ParentSym = PrevailingSectionMap.find(Name); - if (ParentSym != PrevailingSectionMap.end()) - readAssociativeDefinition(Sym, Def, ParentSym->second); + auto parentSym = prevailingSectionMap.find(name); + if (parentSym != prevailingSectionMap.end()) + readAssociativeDefinition(sym, def, parentSym->second); } } -Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { - SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; - if (Sym.isExternal()) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - if (SC) - return Symtab->addRegular(this, Name, Sym.getGeneric(), SC); +Symbol *ObjFile::createRegular(COFFSymbolRef sym) { + SectionChunk *sc = sparseChunks[sym.getSectionNumber()]; + if (sym.isExternal()) { + StringRef name; + coffObj->getSymbolName(sym, name); + if (sc) + return symtab->addRegular(this, name, sym.getGeneric(), sc); // For MinGW symbols named .weak.* that point to a discarded section, // don't create an Undefined symbol. If nothing ever refers to the symbol, // everything should be fine. If something actually refers to the symbol // (e.g. the undefined weak alias), linking will fail due to undefined // references at the end. - if (Config->MinGW && Name.startswith(".weak.")) + if (config->mingw && name.startswith(".weak.")) return nullptr; - return Symtab->addUndefined(Name, this, false); + return symtab->addUndefined(name, this, false); } - if (SC) + if (sc) return make(this, /*Name*/ "", /*IsCOMDAT*/ false, - /*IsExternal*/ false, Sym.getGeneric(), SC); + /*IsExternal*/ false, sym.getGeneric(), sc); return nullptr; } void ObjFile::initializeSymbols() { - uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); - Symbols.resize(NumSymbols); - - SmallVector, 8> WeakAliases; - std::vector PendingIndexes; - PendingIndexes.reserve(NumSymbols); - - DenseMap PrevailingSectionMap; - std::vector ComdatDefs( - COFFObj->getNumberOfSections() + 1); - - for (uint32_t I = 0; I < NumSymbols; ++I) { - COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); - bool PrevailingComdat; - if (COFFSym.isUndefined()) { - Symbols[I] = createUndefined(COFFSym); - } else if (COFFSym.isWeakExternal()) { - Symbols[I] = createUndefined(COFFSym); - uint32_t TagIndex = COFFSym.getAux()->TagIndex; - WeakAliases.emplace_back(Symbols[I], TagIndex); - } else if (Optional OptSym = - createDefined(COFFSym, ComdatDefs, PrevailingComdat)) { - Symbols[I] = *OptSym; - if (Config->MinGW && PrevailingComdat) - recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap); + uint32_t numSymbols = coffObj->getNumberOfSymbols(); + symbols.resize(numSymbols); + + SmallVector, 8> weakAliases; + std::vector pendingIndexes; + pendingIndexes.reserve(numSymbols); + + DenseMap prevailingSectionMap; + std::vector comdatDefs( + coffObj->getNumberOfSections() + 1); + + for (uint32_t i = 0; i < numSymbols; ++i) { + COFFSymbolRef coffSym = check(coffObj->getSymbol(i)); + bool prevailingComdat; + if (coffSym.isUndefined()) { + symbols[i] = createUndefined(coffSym); + } else if (coffSym.isWeakExternal()) { + symbols[i] = createUndefined(coffSym); + uint32_t tagIndex = coffSym.getAux()->TagIndex; + weakAliases.emplace_back(symbols[i], tagIndex); + } else if (Optional optSym = + createDefined(coffSym, comdatDefs, prevailingComdat)) { + symbols[i] = *optSym; + if (config->mingw && prevailingComdat) + recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap); } else { // createDefined() returns None if a symbol belongs to a section that // was pending at the point when the symbol was read. This can happen in @@ -366,71 +366,71 @@ void ObjFile::initializeSymbols() { // In both of these cases, we can expect the section to be resolved by // the time we finish visiting the remaining symbols in the symbol // table. So we postpone the handling of this symbol until that time. - PendingIndexes.push_back(I); + pendingIndexes.push_back(i); } - I += COFFSym.getNumberOfAuxSymbols(); + i += coffSym.getNumberOfAuxSymbols(); } - for (uint32_t I : PendingIndexes) { - COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); - if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) { - if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) - readAssociativeDefinition(Sym, Def); - else if (Config->MinGW) - maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap); + for (uint32_t i : pendingIndexes) { + COFFSymbolRef sym = check(coffObj->getSymbol(i)); + if (const coff_aux_section_definition *def = sym.getSectionDefinition()) { + if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) + readAssociativeDefinition(sym, def); + else if (config->mingw) + maybeAssociateSEHForMingw(sym, def, prevailingSectionMap); } - if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - log("comdat section " + Name + + if (sparseChunks[sym.getSectionNumber()] == pendingComdat) { + StringRef name; + coffObj->getSymbolName(sym, name); + log("comdat section " + name + " without leader and unassociated, discarding"); continue; } - Symbols[I] = createRegular(Sym); + symbols[i] = createRegular(sym); } - for (auto &KV : WeakAliases) { - Symbol *Sym = KV.first; - uint32_t Idx = KV.second; - checkAndSetWeakAlias(Symtab, this, Sym, Symbols[Idx]); + for (auto &kv : weakAliases) { + Symbol *sym = kv.first; + uint32_t idx = kv.second; + checkAndSetWeakAlias(symtab, this, sym, symbols[idx]); } } -Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - return Symtab->addUndefined(Name, this, Sym.isWeakExternal()); +Symbol *ObjFile::createUndefined(COFFSymbolRef sym) { + StringRef name; + coffObj->getSymbolName(sym, name); + return symtab->addUndefined(name, this, sym.isWeakExternal()); } -void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, - bool &Prevailing, DefinedRegular *Leader) { - if (Prevailing) +void ObjFile::handleComdatSelection(COFFSymbolRef sym, COMDATType &selection, + bool &prevailing, DefinedRegular *leader) { + if (prevailing) return; // There's already an existing comdat for this symbol: `Leader`. // Use the comdats's selection field to determine if the new // symbol in `Sym` should be discarded, produce a duplicate symbol // error, etc. - SectionChunk *LeaderChunk = nullptr; - COMDATType LeaderSelection = IMAGE_COMDAT_SELECT_ANY; + SectionChunk *leaderChunk = nullptr; + COMDATType leaderSelection = IMAGE_COMDAT_SELECT_ANY; - if (Leader->Data) { - LeaderChunk = Leader->getChunk(); - LeaderSelection = LeaderChunk->Selection; + if (leader->data) { + leaderChunk = leader->getChunk(); + leaderSelection = leaderChunk->selection; } else { // FIXME: comdats from LTO files don't know their selection; treat them // as "any". - Selection = LeaderSelection; + selection = leaderSelection; } - if ((Selection == IMAGE_COMDAT_SELECT_ANY && - LeaderSelection == IMAGE_COMDAT_SELECT_LARGEST) || - (Selection == IMAGE_COMDAT_SELECT_LARGEST && - LeaderSelection == IMAGE_COMDAT_SELECT_ANY)) { + if ((selection == IMAGE_COMDAT_SELECT_ANY && + leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) || + (selection == IMAGE_COMDAT_SELECT_LARGEST && + leaderSelection == IMAGE_COMDAT_SELECT_ANY)) { // cl.exe picks "any" for vftables when building with /GR- and // "largest" when building with /GR. To be able to link object files // compiled with each flag, "any" and "largest" are merged as "largest". - LeaderSelection = Selection = IMAGE_COMDAT_SELECT_LARGEST; + leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST; } // Other than that, comdat selections must match. This is a bit more @@ -440,18 +440,18 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, // Making this symmetric independent of which selection is seen first // seems better though. // (This behavior matches ModuleLinker::getComdatResult().) - if (Selection != LeaderSelection) { - log(("conflicting comdat type for " + toString(*Leader) + ": " + - Twine((int)LeaderSelection) + " in " + toString(Leader->getFile()) + - " and " + Twine((int)Selection) + " in " + toString(this)) + if (selection != leaderSelection) { + log(("conflicting comdat type for " + toString(*leader) + ": " + + Twine((int)leaderSelection) + " in " + toString(leader->getFile()) + + " and " + Twine((int)selection) + " in " + toString(this)) .str()); - Symtab->reportDuplicate(Leader, this); + symtab->reportDuplicate(leader, this); return; } - switch (Selection) { + switch (selection) { case IMAGE_COMDAT_SELECT_NODUPLICATES: - Symtab->reportDuplicate(Leader, this); + symtab->reportDuplicate(leader, this); break; case IMAGE_COMDAT_SELECT_ANY: @@ -459,17 +459,17 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, break; case IMAGE_COMDAT_SELECT_SAME_SIZE: - if (LeaderChunk->getSize() != getSection(Sym)->SizeOfRawData) - Symtab->reportDuplicate(Leader, this); + if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) + symtab->reportDuplicate(leader, this); break; case IMAGE_COMDAT_SELECT_EXACT_MATCH: { - SectionChunk NewChunk(this, getSection(Sym)); + SectionChunk newChunk(this, getSection(sym)); // link.exe only compares section contents here and doesn't complain // if the two comdat sections have e.g. different alignment. // Match that. - if (LeaderChunk->getContents() != NewChunk.getContents()) - Symtab->reportDuplicate(Leader, this); + if (leaderChunk->getContents() != newChunk.getContents()) + symtab->reportDuplicate(leader, this); break; } @@ -481,20 +481,20 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, llvm_unreachable("createDefined not called for associative comdats"); case IMAGE_COMDAT_SELECT_LARGEST: - if (LeaderChunk->getSize() < getSection(Sym)->SizeOfRawData) { + if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) { // Replace the existing comdat symbol with the new one. - StringRef Name; - COFFObj->getSymbolName(Sym, Name); + StringRef name; + coffObj->getSymbolName(sym, name); // FIXME: This is incorrect: With /opt:noref, the previous sections // make it into the final executable as well. Correct handling would // be to undo reading of the whole old section that's being replaced, // or doing one pass that determines what the final largest comdat // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading // only the largest one. - replaceSymbol(Leader, this, Name, /*IsCOMDAT*/ true, - /*IsExternal*/ true, Sym.getGeneric(), + replaceSymbol(leader, this, name, /*IsCOMDAT*/ true, + /*IsExternal*/ true, sym.getGeneric(), nullptr); - Prevailing = true; + prevailing = true; } break; @@ -504,50 +504,50 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, } Optional ObjFile::createDefined( - COFFSymbolRef Sym, - std::vector &ComdatDefs, - bool &Prevailing) { - Prevailing = false; - auto GetName = [&]() { - StringRef S; - COFFObj->getSymbolName(Sym, S); - return S; + COFFSymbolRef sym, + std::vector &comdatDefs, + bool &prevailing) { + prevailing = false; + auto getName = [&]() { + StringRef s; + coffObj->getSymbolName(sym, s); + return s; }; - if (Sym.isCommon()) { - auto *C = make(Sym); - Chunks.push_back(C); - return Symtab->addCommon(this, GetName(), Sym.getValue(), Sym.getGeneric(), - C); + if (sym.isCommon()) { + auto *c = make(sym); + chunks.push_back(c); + return symtab->addCommon(this, getName(), sym.getValue(), sym.getGeneric(), + c); } - if (Sym.isAbsolute()) { - StringRef Name = GetName(); + if (sym.isAbsolute()) { + StringRef name = getName(); // Skip special symbols. - if (Name == "@comp.id") + if (name == "@comp.id") return nullptr; - if (Name == "@feat.00") { - Feat00Flags = Sym.getValue(); + if (name == "@feat.00") { + feat00Flags = sym.getValue(); return nullptr; } - if (Sym.isExternal()) - return Symtab->addAbsolute(Name, Sym); - return make(Name, Sym); + if (sym.isExternal()) + return symtab->addAbsolute(name, sym); + return make(name, sym); } - int32_t SectionNumber = Sym.getSectionNumber(); - if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) + int32_t sectionNumber = sym.getSectionNumber(); + if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) return nullptr; - if (llvm::COFF::isReservedSectionNumber(SectionNumber)) - fatal(toString(this) + ": " + GetName() + - " should not refer to special section " + Twine(SectionNumber)); + if (llvm::COFF::isReservedSectionNumber(sectionNumber)) + fatal(toString(this) + ": " + getName() + + " should not refer to special section " + Twine(sectionNumber)); - if ((uint32_t)SectionNumber >= SparseChunks.size()) - fatal(toString(this) + ": " + GetName() + - " should not refer to non-existent section " + Twine(SectionNumber)); + if ((uint32_t)sectionNumber >= sparseChunks.size()) + fatal(toString(this) + ": " + getName() + + " should not refer to non-existent section " + Twine(sectionNumber)); // Comdat handling. // A comdat symbol consists of two symbol table entries. @@ -560,65 +560,65 @@ Optional ObjFile::createDefined( // symbol entry it reads ComdatDefs and then sets it back to nullptr. // Handle comdat leader. - if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { - ComdatDefs[SectionNumber] = nullptr; - DefinedRegular *Leader; + if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) { + comdatDefs[sectionNumber] = nullptr; + DefinedRegular *leader; - if (Sym.isExternal()) { - std::tie(Leader, Prevailing) = - Symtab->addComdat(this, GetName(), Sym.getGeneric()); + if (sym.isExternal()) { + std::tie(leader, prevailing) = + symtab->addComdat(this, getName(), sym.getGeneric()); } else { - Leader = make(this, /*Name*/ "", /*IsCOMDAT*/ false, - /*IsExternal*/ false, Sym.getGeneric()); - Prevailing = true; + leader = make(this, /*Name*/ "", /*IsCOMDAT*/ false, + /*IsExternal*/ false, sym.getGeneric()); + prevailing = true; } - if (Def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES || + if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES || // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either. - Def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) { - fatal("unknown comdat type " + std::to_string((int)Def->Selection) + - " for " + GetName() + " in " + toString(this)); + def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) { + fatal("unknown comdat type " + std::to_string((int)def->Selection) + + " for " + getName() + " in " + toString(this)); } - COMDATType Selection = (COMDATType)Def->Selection; + COMDATType selection = (COMDATType)def->Selection; - if (Leader->IsCOMDAT) - handleComdatSelection(Sym, Selection, Prevailing, Leader); + if (leader->isCOMDAT) + handleComdatSelection(sym, selection, prevailing, leader); - if (Prevailing) { - SectionChunk *C = readSection(SectionNumber, Def, GetName()); - SparseChunks[SectionNumber] = C; - C->Sym = cast(Leader); - C->Selection = Selection; - cast(Leader)->Data = &C->Repl; + if (prevailing) { + SectionChunk *c = readSection(sectionNumber, def, getName()); + sparseChunks[sectionNumber] = c; + c->sym = cast(leader); + c->selection = selection; + cast(leader)->data = &c->repl; } else { - SparseChunks[SectionNumber] = nullptr; + sparseChunks[sectionNumber] = nullptr; } - return Leader; + return leader; } // Prepare to handle the comdat leader symbol by setting the section's // ComdatDefs pointer if we encounter a non-associative comdat. - if (SparseChunks[SectionNumber] == PendingComdat) { - if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) { - if (Def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE) - ComdatDefs[SectionNumber] = Def; + if (sparseChunks[sectionNumber] == pendingComdat) { + if (const coff_aux_section_definition *def = sym.getSectionDefinition()) { + if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE) + comdatDefs[sectionNumber] = def; } return None; } - return createRegular(Sym); + return createRegular(sym); } MachineTypes ObjFile::getMachineType() { - if (COFFObj) - return static_cast(COFFObj->getMachine()); + if (coffObj) + return static_cast(coffObj->getMachine()); return IMAGE_FILE_MACHINE_UNKNOWN; } -ArrayRef ObjFile::getDebugSection(StringRef SecName) { - if (SectionChunk *Sec = SectionChunk::findByName(DebugChunks, SecName)) - return Sec->consumeDebugMagic(); +ArrayRef ObjFile::getDebugSection(StringRef secName) { + if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName)) + return sec->consumeDebugMagic(); return {}; } @@ -628,43 +628,43 @@ ArrayRef ObjFile::getDebugSection(StringRef SecName) { // PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is // currently used to initialize the HotPatchable member. void ObjFile::initializeFlags() { - ArrayRef Data = getDebugSection(".debug$S"); - if (Data.empty()) + ArrayRef data = getDebugSection(".debug$S"); + if (data.empty()) return; - DebugSubsectionArray Subsections; + DebugSubsectionArray subsections; - BinaryStreamReader Reader(Data, support::little); - ExitOnError ExitOnErr; - ExitOnErr(Reader.readArray(Subsections, Data.size())); + BinaryStreamReader reader(data, support::little); + ExitOnError exitOnErr; + exitOnErr(reader.readArray(subsections, data.size())); - for (const DebugSubsectionRecord &SS : Subsections) { - if (SS.kind() != DebugSubsectionKind::Symbols) + for (const DebugSubsectionRecord &ss : subsections) { + if (ss.kind() != DebugSubsectionKind::Symbols) continue; - unsigned Offset = 0; + unsigned offset = 0; // Only parse the first two records. We are only looking for S_OBJNAME // and S_COMPILE3, and they usually appear at the beginning of the // stream. - for (unsigned I = 0; I < 2; ++I) { - Expected Sym = readSymbolFromStream(SS.getRecordData(), Offset); - if (!Sym) { - consumeError(Sym.takeError()); + for (unsigned i = 0; i < 2; ++i) { + Expected sym = readSymbolFromStream(ss.getRecordData(), offset); + if (!sym) { + consumeError(sym.takeError()); return; } - if (Sym->kind() == SymbolKind::S_COMPILE3) { - auto CS = - cantFail(SymbolDeserializer::deserializeAs(Sym.get())); - HotPatchable = - (CS.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None; + if (sym->kind() == SymbolKind::S_COMPILE3) { + auto cs = + cantFail(SymbolDeserializer::deserializeAs(sym.get())); + hotPatchable = + (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None; } - if (Sym->kind() == SymbolKind::S_OBJNAME) { - auto ObjName = cantFail(SymbolDeserializer::deserializeAs( - Sym.get())); - PCHSignature = ObjName.Signature; + if (sym->kind() == SymbolKind::S_OBJNAME) { + auto objName = cantFail(SymbolDeserializer::deserializeAs( + sym.get())); + pchSignature = objName.Signature; } - Offset += Sym->length(); + offset += sym->length(); } } } @@ -677,112 +677,112 @@ void ObjFile::initializeFlags() { // DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular // output even with /Yc and /Yu and with /Zi. void ObjFile::initializeDependencies() { - if (!Config->Debug) + if (!config->debug) return; - bool IsPCH = false; + bool isPCH = false; - ArrayRef Data = getDebugSection(".debug$P"); - if (!Data.empty()) - IsPCH = true; + ArrayRef data = getDebugSection(".debug$P"); + if (!data.empty()) + isPCH = true; else - Data = getDebugSection(".debug$T"); + data = getDebugSection(".debug$T"); - if (Data.empty()) + if (data.empty()) return; - CVTypeArray Types; - BinaryStreamReader Reader(Data, support::little); - cantFail(Reader.readArray(Types, Reader.getLength())); + CVTypeArray types; + BinaryStreamReader reader(data, support::little); + cantFail(reader.readArray(types, reader.getLength())); - CVTypeArray::Iterator FirstType = Types.begin(); - if (FirstType == Types.end()) + CVTypeArray::Iterator firstType = types.begin(); + if (firstType == types.end()) return; - DebugTypes.emplace(Types); + debugTypes.emplace(types); - if (IsPCH) { - DebugTypesObj = makePrecompSource(this); + if (isPCH) { + debugTypesObj = makePrecompSource(this); return; } - if (FirstType->kind() == LF_TYPESERVER2) { - TypeServer2Record TS = cantFail( - TypeDeserializer::deserializeAs(FirstType->data())); - DebugTypesObj = makeUseTypeServerSource(this, &TS); + if (firstType->kind() == LF_TYPESERVER2) { + TypeServer2Record ts = cantFail( + TypeDeserializer::deserializeAs(firstType->data())); + debugTypesObj = makeUseTypeServerSource(this, &ts); return; } - if (FirstType->kind() == LF_PRECOMP) { - PrecompRecord Precomp = cantFail( - TypeDeserializer::deserializeAs(FirstType->data())); - DebugTypesObj = makeUsePrecompSource(this, &Precomp); + if (firstType->kind() == LF_PRECOMP) { + PrecompRecord precomp = cantFail( + TypeDeserializer::deserializeAs(firstType->data())); + debugTypesObj = makeUsePrecompSource(this, &precomp); return; } - DebugTypesObj = makeTpiSource(this); + debugTypesObj = makeTpiSource(this); } -StringRef ltrim1(StringRef S, const char *Chars) { - if (!S.empty() && strchr(Chars, S[0])) - return S.substr(1); - return S; +StringRef ltrim1(StringRef s, const char *chars) { + if (!s.empty() && strchr(chars, s[0])) + return s.substr(1); + return s; } void ImportFile::parse() { - const char *Buf = MB.getBufferStart(); - const auto *Hdr = reinterpret_cast(Buf); + const char *buf = mb.getBufferStart(); + const auto *hdr = reinterpret_cast(buf); // Check if the total size is valid. - if (MB.getBufferSize() != sizeof(*Hdr) + Hdr->SizeOfData) + if (mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData) fatal("broken import library"); // Read names and create an __imp_ symbol. - StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr))); - StringRef ImpName = Saver.save("__imp_" + Name); - const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1; - DLLName = StringRef(NameStart); - StringRef ExtName; - switch (Hdr->getNameType()) { + StringRef name = saver.save(StringRef(buf + sizeof(*hdr))); + StringRef impName = saver.save("__imp_" + name); + const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1; + dllName = StringRef(nameStart); + StringRef extName; + switch (hdr->getNameType()) { case IMPORT_ORDINAL: - ExtName = ""; + extName = ""; break; case IMPORT_NAME: - ExtName = Name; + extName = name; break; case IMPORT_NAME_NOPREFIX: - ExtName = ltrim1(Name, "?@_"); + extName = ltrim1(name, "?@_"); break; case IMPORT_NAME_UNDECORATE: - ExtName = ltrim1(Name, "?@_"); - ExtName = ExtName.substr(0, ExtName.find('@')); + extName = ltrim1(name, "?@_"); + extName = extName.substr(0, extName.find('@')); break; } - this->Hdr = Hdr; - ExternalName = ExtName; + this->hdr = hdr; + externalName = extName; - ImpSym = Symtab->addImportData(ImpName, this); + impSym = symtab->addImportData(impName, this); // If this was a duplicate, we logged an error but may continue; // in this case, ImpSym is nullptr. - if (!ImpSym) + if (!impSym) return; - if (Hdr->getType() == llvm::COFF::IMPORT_CONST) - static_cast(Symtab->addImportData(Name, this)); + if (hdr->getType() == llvm::COFF::IMPORT_CONST) + static_cast(symtab->addImportData(name, this)); // If type is function, we need to create a thunk which jump to an // address pointed by the __imp_ symbol. (This allows you to call // DLL functions just like regular non-DLL functions.) - if (Hdr->getType() == llvm::COFF::IMPORT_CODE) - ThunkSym = Symtab->addImportThunk( - Name, cast_or_null(ImpSym), Hdr->Machine); + if (hdr->getType() == llvm::COFF::IMPORT_CODE) + thunkSym = symtab->addImportThunk( + name, cast_or_null(impSym), hdr->Machine); } -BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, - uint64_t OffsetInArchive) - : InputFile(BitcodeKind, MB) { - std::string Path = MB.getBufferIdentifier().str(); +BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, + uint64_t offsetInArchive) + : InputFile(BitcodeKind, mb) { + std::string path = mb.getBufferIdentifier().str(); // ThinLTO assumes that all MemoryBufferRefs given to it have a unique // name. If two archives define two members with the same name, this @@ -790,53 +790,53 @@ 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. - MemoryBufferRef MBRef( - MB.getBuffer(), - Saver.save(ArchiveName + Path + - (ArchiveName.empty() ? "" : utostr(OffsetInArchive)))); + MemoryBufferRef mbref( + mb.getBuffer(), + saver.save(archiveName + path + + (archiveName.empty() ? "" : utostr(offsetInArchive)))); - Obj = check(lto::InputFile::create(MBRef)); + obj = check(lto::InputFile::create(mbref)); } void BitcodeFile::parse() { - std::vector> Comdat(Obj->getComdatTable().size()); - for (size_t I = 0; I != Obj->getComdatTable().size(); ++I) + std::vector> comdat(obj->getComdatTable().size()); + for (size_t i = 0; i != obj->getComdatTable().size(); ++i) // FIXME: lto::InputFile doesn't keep enough data to do correct comdat // selection handling. - Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I])); - for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) { - StringRef SymName = Saver.save(ObjSym.getName()); - int ComdatIndex = ObjSym.getComdatIndex(); - Symbol *Sym; - if (ObjSym.isUndefined()) { - Sym = Symtab->addUndefined(SymName, this, false); - } else if (ObjSym.isCommon()) { - Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize()); - } else if (ObjSym.isWeak() && ObjSym.isIndirect()) { + comdat[i] = symtab->addComdat(this, saver.save(obj->getComdatTable()[i])); + for (const lto::InputFile::Symbol &objSym : obj->symbols()) { + StringRef symName = saver.save(objSym.getName()); + int comdatIndex = objSym.getComdatIndex(); + Symbol *sym; + if (objSym.isUndefined()) { + sym = symtab->addUndefined(symName, this, false); + } else if (objSym.isCommon()) { + sym = symtab->addCommon(this, symName, objSym.getCommonSize()); + } else if (objSym.isWeak() && objSym.isIndirect()) { // Weak external. - Sym = Symtab->addUndefined(SymName, this, true); - std::string Fallback = ObjSym.getCOFFWeakExternalFallback(); - Symbol *Alias = Symtab->addUndefined(Saver.save(Fallback)); - checkAndSetWeakAlias(Symtab, this, Sym, Alias); - } else if (ComdatIndex != -1) { - if (SymName == Obj->getComdatTable()[ComdatIndex]) - Sym = Comdat[ComdatIndex].first; - else if (Comdat[ComdatIndex].second) - Sym = Symtab->addRegular(this, SymName); + sym = symtab->addUndefined(symName, this, true); + std::string fallback = objSym.getCOFFWeakExternalFallback(); + Symbol *alias = symtab->addUndefined(saver.save(fallback)); + checkAndSetWeakAlias(symtab, this, sym, alias); + } else if (comdatIndex != -1) { + if (symName == obj->getComdatTable()[comdatIndex]) + sym = comdat[comdatIndex].first; + else if (comdat[comdatIndex].second) + sym = symtab->addRegular(this, symName); else - Sym = Symtab->addUndefined(SymName, this, false); + sym = symtab->addUndefined(symName, this, false); } else { - Sym = Symtab->addRegular(this, SymName); + sym = symtab->addRegular(this, symName); } - Symbols.push_back(Sym); - if (ObjSym.isUsed()) - Config->GCRoot.push_back(Sym); + symbols.push_back(sym); + if (objSym.isUsed()) + config->gCRoot.push_back(sym); } - Directives = Obj->getCOFFLinkerOpts(); + directives = obj->getCOFFLinkerOpts(); } MachineTypes BitcodeFile::getMachineType() { - switch (Triple(Obj->getTargetTriple()).getArch()) { + switch (Triple(obj->getTargetTriple()).getArch()) { case Triple::x86_64: return AMD64; case Triple::x86: @@ -853,18 +853,18 @@ MachineTypes BitcodeFile::getMachineType() { } // namespace lld // Returns the last element of a path, which is supposed to be a filename. -static StringRef getBasename(StringRef Path) { - return sys::path::filename(Path, sys::path::Style::windows); +static StringRef getBasename(StringRef path) { + return sys::path::filename(path, sys::path::Style::windows); } // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". -std::string lld::toString(const coff::InputFile *File) { - if (!File) +std::string lld::toString(const coff::InputFile *file) { + if (!file) return ""; - if (File->ParentName.empty() || File->kind() == coff::InputFile::ImportKind) - return File->getName(); + if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind) + return file->getName(); - return (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + + return (getBasename(file->parentName) + "(" + getBasename(file->getName()) + ")") .str(); } diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 22017f7..bd2698f 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -32,7 +32,7 @@ class DbiModuleDescriptorBuilder; namespace lld { namespace coff { -std::vector getArchiveMembers(llvm::object::Archive *File); +std::vector getArchiveMembers(llvm::object::Archive *file); using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN; using llvm::COFF::MachineTypes; @@ -57,11 +57,11 @@ class TpiSource; class InputFile { public: enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind }; - Kind kind() const { return FileKind; } + Kind kind() const { return fileKind; } virtual ~InputFile() {} // Returns the filename. - StringRef getName() const { return MB.getBufferIdentifier(); } + StringRef getName() const { return mb.getBufferIdentifier(); } // Reads a file (the constructor doesn't do that). virtual void parse() = 0; @@ -69,118 +69,118 @@ public: // Returns the CPU type this file was compiled to. virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; } - MemoryBufferRef MB; + MemoryBufferRef mb; // An archive file name if this file is created from an archive. - StringRef ParentName; + StringRef parentName; // Returns .drectve section contents if exist. - StringRef getDirectives() { return Directives; } + StringRef getDirectives() { return directives; } protected: - InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} + InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {} - StringRef Directives; + StringRef directives; private: - const Kind FileKind; + const Kind fileKind; }; // .lib or .a file. class ArchiveFile : public InputFile { public: - explicit ArchiveFile(MemoryBufferRef M); - static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } + explicit ArchiveFile(MemoryBufferRef m); + static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; } void parse() override; // Enqueues an archive member load for the given symbol. If we've already // enqueued a load for the same archive member, this function does nothing, // which ensures that we don't load the same member more than once. - void addMember(const Archive::Symbol *Sym); + void addMember(const Archive::Symbol *sym); private: - std::unique_ptr File; - llvm::DenseSet Seen; + std::unique_ptr file; + llvm::DenseSet seen; }; // .obj or .o file. This may be a member of an archive file. class ObjFile : public InputFile { public: - explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } + explicit ObjFile(MemoryBufferRef m) : InputFile(ObjectKind, m) {} + static bool classof(const InputFile *f) { return f->kind() == ObjectKind; } void parse() override; MachineTypes getMachineType() override; - ArrayRef getChunks() { return Chunks; } - ArrayRef getDebugChunks() { return DebugChunks; } - ArrayRef getSXDataChunks() { return SXDataChunks; } - ArrayRef getGuardFidChunks() { return GuardFidChunks; } - ArrayRef getGuardLJmpChunks() { return GuardLJmpChunks; } - ArrayRef getSymbols() { return Symbols; } + ArrayRef getChunks() { return chunks; } + ArrayRef getDebugChunks() { return debugChunks; } + ArrayRef getSXDataChunks() { return sXDataChunks; } + ArrayRef getGuardFidChunks() { return guardFidChunks; } + ArrayRef getGuardLJmpChunks() { return guardLJmpChunks; } + ArrayRef getSymbols() { return symbols; } - ArrayRef getDebugSection(StringRef SecName); + ArrayRef getDebugSection(StringRef secName); // Returns a Symbol object for the SymbolIndex'th symbol in the // underlying object file. - Symbol *getSymbol(uint32_t SymbolIndex) { - return Symbols[SymbolIndex]; + Symbol *getSymbol(uint32_t symbolIndex) { + return symbols[symbolIndex]; } // Returns the underlying COFF file. - COFFObjectFile *getCOFFObj() { return COFFObj.get(); } + COFFObjectFile *getCOFFObj() { return coffObj.get(); } // Add a symbol for a range extension thunk. Return the new symbol table // index. This index can be used to modify a relocation. - uint32_t addRangeThunkSymbol(Symbol *Thunk) { - Symbols.push_back(Thunk); - return Symbols.size() - 1; + uint32_t addRangeThunkSymbol(Symbol *thunk) { + symbols.push_back(thunk); + return symbols.size() - 1; } - static std::vector Instances; + static std::vector instances; // Flags in the absolute @feat.00 symbol if it is present. These usually // indicate if an object was compiled with certain security features enabled // like stack guard, safeseh, /guard:cf, or other things. - uint32_t Feat00Flags = 0; + uint32_t feat00Flags = 0; // True if this object file is compatible with SEH. COFF-specific and // x86-only. COFF spec 5.10.1. The .sxdata section. - bool hasSafeSEH() { return Feat00Flags & 0x1; } + bool hasSafeSEH() { return feat00Flags & 0x1; } // True if this file was compiled with /guard:cf. - bool hasGuardCF() { return Feat00Flags & 0x800; } + bool hasGuardCF() { return feat00Flags & 0x800; } // Pointer to the PDB module descriptor builder. Various debug info records // will reference object files by "module index", which is here. Things like // source files and section contributions are also recorded here. Will be null // if we are not producing a PDB. - llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr; + llvm::pdb::DbiModuleDescriptorBuilder *moduleDBI = nullptr; - const coff_section *AddrsigSec = nullptr; + const coff_section *addrsigSec = nullptr; // When using Microsoft precompiled headers, this is the PCH's key. // The same key is used by both the precompiled object, and objects using the // precompiled object. Any difference indicates out-of-date objects. - llvm::Optional PCHSignature; + llvm::Optional pchSignature; // Whether this is an object file created from .res files. - bool IsResourceObjFile = false; + bool isResourceObjFile = false; // Whether this file was compiled with /hotpatch. - bool HotPatchable = false; + bool hotPatchable = false; // Whether the object was already merged into the final PDB. - bool MergedIntoPDB = false; + bool mergedIntoPDB = false; // If the OBJ has a .debug$T stream, this tells how it will be handled. - TpiSource *DebugTypesObj = nullptr; + TpiSource *debugTypesObj = nullptr; // The .debug$T stream if there's one. - llvm::Optional DebugTypes; + llvm::Optional debugTypes; private: - const coff_section* getSection(uint32_t I); - const coff_section *getSection(COFFSymbolRef Sym) { - return getSection(Sym.getSectionNumber()); + const coff_section* getSection(uint32_t i); + const coff_section *getSection(COFFSymbolRef sym) { + return getSection(sym.getSectionNumber()); } void initializeChunks(); @@ -189,26 +189,26 @@ private: void initializeDependencies(); SectionChunk * - readSection(uint32_t SectionNumber, - const llvm::object::coff_aux_section_definition *Def, - StringRef LeaderName); + readSection(uint32_t sectionNumber, + const llvm::object::coff_aux_section_definition *def, + StringRef leaderName); void readAssociativeDefinition( - COFFSymbolRef COFFSym, - const llvm::object::coff_aux_section_definition *Def); + COFFSymbolRef coffSym, + const llvm::object::coff_aux_section_definition *def); void readAssociativeDefinition( - COFFSymbolRef COFFSym, - const llvm::object::coff_aux_section_definition *Def, - uint32_t ParentSection); + COFFSymbolRef coffSym, + const llvm::object::coff_aux_section_definition *def, + uint32_t parentSection); void recordPrevailingSymbolForMingw( - COFFSymbolRef COFFSym, - llvm::DenseMap &PrevailingSectionMap); + COFFSymbolRef coffSym, + llvm::DenseMap &prevailingSectionMap); void maybeAssociateSEHForMingw( - COFFSymbolRef Sym, const llvm::object::coff_aux_section_definition *Def, - const llvm::DenseMap &PrevailingSectionMap); + COFFSymbolRef sym, const llvm::object::coff_aux_section_definition *def, + const llvm::DenseMap &prevailingSectionMap); // Given a new symbol Sym with comdat selection Selection, if the new // symbol is not (yet) Prevailing and the existing comdat leader set to @@ -216,48 +216,48 @@ private: // match the existing symbol and its selection. If either old or new // symbol have selection IMAGE_COMDAT_SELECT_LARGEST, Sym might replace // the existing leader. In that case, Prevailing is set to true. - void handleComdatSelection(COFFSymbolRef Sym, - llvm::COFF::COMDATType &Selection, - bool &Prevailing, DefinedRegular *Leader); + void handleComdatSelection(COFFSymbolRef sym, + llvm::COFF::COMDATType &selection, + bool &prevailing, DefinedRegular *leader); llvm::Optional - createDefined(COFFSymbolRef Sym, + createDefined(COFFSymbolRef sym, std::vector - &ComdatDefs, - bool &PrevailingComdat); - Symbol *createRegular(COFFSymbolRef Sym); - Symbol *createUndefined(COFFSymbolRef Sym); + &comdatDefs, + bool &prevailingComdat); + Symbol *createRegular(COFFSymbolRef sym); + Symbol *createUndefined(COFFSymbolRef sym); - std::unique_ptr COFFObj; + std::unique_ptr coffObj; // List of all chunks defined by this file. This includes both section // chunks and non-section chunks for common symbols. - std::vector Chunks; + std::vector chunks; // CodeView debug info sections. - std::vector DebugChunks; + std::vector debugChunks; // Chunks containing symbol table indices of exception handlers. Only used for // 32-bit x86. - std::vector SXDataChunks; + std::vector sXDataChunks; // Chunks containing symbol table indices of address taken symbols and longjmp // targets. These are not linked into the final binary when /guard:cf is set. - std::vector GuardFidChunks; - std::vector GuardLJmpChunks; + std::vector guardFidChunks; + std::vector guardLJmpChunks; // This vector contains the same chunks as Chunks, but they are // indexed such that you can get a SectionChunk by section index. // Nonexistent section indices are filled with null pointers. // (Because section number is 1-based, the first slot is always a // null pointer.) - std::vector SparseChunks; + std::vector sparseChunks; // This vector contains a list of all symbols defined or referenced by this // file. They are indexed such that you can get a Symbol by symbol // index. Nonexistent indices (which are occupied by auxiliary // symbols in the real symbol table) are filled with null pointers. - std::vector Symbols; + std::vector symbols; }; // This type represents import library members that contain DLL names @@ -265,23 +265,23 @@ private: // for details about the format. class ImportFile : public InputFile { public: - explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {} + explicit ImportFile(MemoryBufferRef m) : InputFile(ImportKind, m) {} - static bool classof(const InputFile *F) { return F->kind() == ImportKind; } + static bool classof(const InputFile *f) { return f->kind() == ImportKind; } - static std::vector Instances; + static std::vector instances; - Symbol *ImpSym = nullptr; - Symbol *ThunkSym = nullptr; - std::string DLLName; + Symbol *impSym = nullptr; + Symbol *thunkSym = nullptr; + std::string dllName; private: void parse() override; public: - StringRef ExternalName; - const coff_import_header *Hdr; - Chunk *Location = nullptr; + StringRef externalName; + const coff_import_header *hdr; + Chunk *location = nullptr; // We want to eliminate dllimported symbols if no one actually refers them. // These "Live" bits are used to keep track of which import library members @@ -291,29 +291,29 @@ public: // symbols provided by this import library member. We also track whether the // imported symbol is used separately from whether the thunk is used in order // to avoid creating unnecessary thunks. - bool Live = !Config->DoGC; - bool ThunkLive = !Config->DoGC; + bool live = !config->doGC; + bool thunkLive = !config->doGC; }; // Used for LTO. class BitcodeFile : public InputFile { public: - BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, - uint64_t OffsetInArchive); - static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } - ArrayRef getSymbols() { return Symbols; } + BitcodeFile(MemoryBufferRef mb, StringRef archiveName, + uint64_t offsetInArchive); + static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } + ArrayRef getSymbols() { return symbols; } MachineTypes getMachineType() override; - static std::vector Instances; - std::unique_ptr Obj; + static std::vector instances; + std::unique_ptr obj; private: void parse() override; - std::vector Symbols; + std::vector symbols; }; } // namespace coff -std::string toString(const coff::InputFile *File); +std::string toString(const coff::InputFile *file); } // namespace lld #endif diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index bfbfc24..86ec1ef 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -42,112 +42,112 @@ using namespace lld; using namespace lld::coff; static std::unique_ptr createLTO() { - lto::Config C; - C.Options = initTargetOptionsFromCodeGenFlags(); + lto::Config c; + c.Options = initTargetOptionsFromCodeGenFlags(); // Always emit a section per function/datum with LTO. LLVM LTO should get most // of the benefit of linker GC, but there are still opportunities for ICF. - C.Options.FunctionSections = true; - C.Options.DataSections = true; + c.Options.FunctionSections = true; + c.Options.DataSections = true; // Use static reloc model on 32-bit x86 because it usually results in more // compact code, and because there are also known code generation bugs when // using the PIC model (see PR34306). - if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386) - C.RelocModel = Reloc::Static; + if (config->machine == COFF::IMAGE_FILE_MACHINE_I386) + c.RelocModel = Reloc::Static; else - C.RelocModel = Reloc::PIC_; - C.DisableVerify = true; - C.DiagHandler = diagnosticHandler; - C.OptLevel = Config->LTOO; - C.CPU = getCPUStr(); - C.MAttrs = getMAttrs(); - C.CGOptLevel = args::getCGOptLevel(Config->LTOO); - - if (Config->SaveTemps) - checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".", + c.RelocModel = Reloc::PIC_; + c.DisableVerify = true; + c.DiagHandler = diagnosticHandler; + c.OptLevel = config->ltoo; + c.CPU = getCPUStr(); + c.MAttrs = getMAttrs(); + c.CGOptLevel = args::getCGOptLevel(config->ltoo); + + if (config->saveTemps) + checkError(c.addSaveTemps(std::string(config->outputFile) + ".", /*UseInputModulePath*/ true)); - lto::ThinBackend Backend; - if (Config->ThinLTOJobs != 0) - Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); - return llvm::make_unique(std::move(C), Backend, - Config->LTOPartitions); + lto::ThinBackend backend; + if (config->thinLTOJobs != 0) + backend = lto::createInProcessThinBackend(config->thinLTOJobs); + return llvm::make_unique(std::move(c), backend, + config->ltoPartitions); } -BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} +BitcodeCompiler::BitcodeCompiler() : ltoObj(createLTO()) {} BitcodeCompiler::~BitcodeCompiler() = default; -static void undefine(Symbol *S) { replaceSymbol(S, S->getName()); } +static void undefine(Symbol *s) { replaceSymbol(s, s->getName()); } -void BitcodeCompiler::add(BitcodeFile &F) { - lto::InputFile &Obj = *F.Obj; - unsigned SymNum = 0; - std::vector SymBodies = F.getSymbols(); - std::vector Resols(SymBodies.size()); +void BitcodeCompiler::add(BitcodeFile &f) { + lto::InputFile &obj = *f.obj; + unsigned symNum = 0; + std::vector symBodies = f.getSymbols(); + std::vector resols(symBodies.size()); // Provide a resolution to the LTO API for each symbol. - for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { - Symbol *Sym = SymBodies[SymNum]; - lto::SymbolResolution &R = Resols[SymNum]; - ++SymNum; + for (const lto::InputFile::Symbol &objSym : obj.symbols()) { + Symbol *sym = symBodies[symNum]; + lto::SymbolResolution &r = resols[symNum]; + ++symNum; // 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->getFile() == &F; - R.VisibleToRegularObj = Sym->IsUsedInRegularObj; - if (R.Prevailing) - undefine(Sym); + r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f; + r.VisibleToRegularObj = sym->isUsedInRegularObj; + if (r.Prevailing) + undefine(sym); } - checkError(LTOObj->add(std::move(F.Obj), Resols)); + checkError(ltoObj->add(std::move(f.obj), resols)); } // Merge all the bitcode files we have seen, codegen the result // and return the resulting objects. std::vector BitcodeCompiler::compile() { - unsigned MaxTasks = LTOObj->getMaxTasks(); - Buf.resize(MaxTasks); - Files.resize(MaxTasks); + unsigned maxTasks = ltoObj->getMaxTasks(); + buf.resize(maxTasks); + files.resize(maxTasks); // The /lldltocache 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->LTOCache.empty()) - Cache = check(lto::localCache( - Config->LTOCache, [&](size_t Task, std::unique_ptr MB) { - Files[Task] = std::move(MB); + lto::NativeObjectCache cache; + if (!config->ltoCache.empty()) + cache = check(lto::localCache( + config->ltoCache, [&](size_t task, std::unique_ptr mb) { + files[task] = std::move(mb); })); - checkError(LTOObj->run( - [&](size_t Task) { + checkError(ltoObj->run( + [&](size_t task) { return llvm::make_unique( - llvm::make_unique(Buf[Task])); + llvm::make_unique(buf[task])); }, - Cache)); + cache)); - if (!Config->LTOCache.empty()) - pruneCache(Config->LTOCache, Config->LTOCachePolicy); + if (!config->ltoCache.empty()) + pruneCache(config->ltoCache, config->ltoCachePolicy); - std::vector Ret; - for (unsigned I = 0; I != MaxTasks; ++I) { - if (Buf[I].empty()) + std::vector ret; + for (unsigned i = 0; i != maxTasks; ++i) { + if (buf[i].empty()) continue; - if (Config->SaveTemps) { - if (I == 0) - saveBuffer(Buf[I], Config->OutputFile + ".lto.obj"); + if (config->saveTemps) { + if (i == 0) + saveBuffer(buf[i], config->outputFile + ".lto.obj"); else - saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.obj"); + saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.obj"); } - Ret.emplace_back(Buf[I].data(), Buf[I].size()); + ret.emplace_back(buf[i].data(), buf[i].size()); } - for (std::unique_ptr &File : Files) - if (File) - Ret.push_back(File->getBuffer()); + for (std::unique_ptr &file : files) + if (file) + ret.push_back(file->getBuffer()); - return Ret; + return ret; } diff --git a/lld/COFF/LTO.h b/lld/COFF/LTO.h index 222945c..10a1063 100644 --- a/lld/COFF/LTO.h +++ b/lld/COFF/LTO.h @@ -42,13 +42,13 @@ public: BitcodeCompiler(); ~BitcodeCompiler(); - void add(BitcodeFile &F); + void add(BitcodeFile &f); std::vector compile(); private: - std::unique_ptr LTOObj; - std::vector> Buf; - std::vector> Files; + std::unique_ptr ltoObj; + std::vector> buf; + std::vector> files; }; } } diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp index aade7ad..57a12b8 100644 --- a/lld/COFF/MapFile.cpp +++ b/lld/COFF/MapFile.cpp @@ -35,90 +35,90 @@ using namespace lld::coff; using SymbolMapTy = DenseMap>; -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 Addr, uint64_t Size, - uint64_t Align) { - OS << format("%08llx %08llx %5lld ", Addr, Size, Align); +static void writeHeader(raw_ostream &os, uint64_t addr, uint64_t size, + uint64_t align) { + os << format("%08llx %08llx %5lld ", addr, size, align); } // Returns a list of all symbols that we want to print out. static std::vector getSymbols() { - std::vector V; - for (ObjFile *File : ObjFile::Instances) - for (Symbol *B : File->getSymbols()) - if (auto *Sym = dyn_cast_or_null(B)) - if (Sym && !Sym->getCOFFSymbol().isSectionDefinition()) - V.push_back(Sym); - return V; + std::vector v; + for (ObjFile *file : ObjFile::instances) + for (Symbol *b : file->getSymbols()) + if (auto *sym = dyn_cast_or_null(b)) + if (sym && !sym->getCOFFSymbol().isSectionDefinition()) + v.push_back(sym); + return v; } // Returns a map from sections to their symbols. -static SymbolMapTy getSectionSyms(ArrayRef Syms) { - SymbolMapTy Ret; - for (DefinedRegular *S : Syms) - Ret[S->getChunk()].push_back(S); +static SymbolMapTy getSectionSyms(ArrayRef syms) { + SymbolMapTy ret; + for (DefinedRegular *s : syms) + ret[s->getChunk()].push_back(s); // Sort symbols by address. - for (auto &It : Ret) { - SmallVectorImpl &V = It.second; - std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) { - return A->getRVA() < B->getRVA(); + for (auto &it : ret) { + SmallVectorImpl &v = it.second; + std::sort(v.begin(), v.end(), [](DefinedRegular *a, DefinedRegular *b) { + return a->getRVA() < b->getRVA(); }); } - return Ret; + return ret; } // Construct a map from symbols to their stringified representations. static DenseMap -getSymbolStrings(ArrayRef Syms) { - std::vector Str(Syms.size()); - parallelForEachN((size_t)0, Syms.size(), [&](size_t I) { - raw_string_ostream OS(Str[I]); - writeHeader(OS, Syms[I]->getRVA(), 0, 0); - OS << Indent16 << toString(*Syms[I]); +getSymbolStrings(ArrayRef syms) { + std::vector str(syms.size()); + parallelForEachN((size_t)0, syms.size(), [&](size_t i) { + raw_string_ostream os(str[i]); + writeHeader(os, syms[i]->getRVA(), 0, 0); + os << indent16 << toString(*syms[i]); }); - DenseMap Ret; - for (size_t I = 0, E = Syms.size(); I < E; ++I) - Ret[Syms[I]] = std::move(Str[I]); - return Ret; + DenseMap ret; + for (size_t i = 0, e = syms.size(); i < e; ++i) + ret[syms[i]] = std::move(str[i]); + return ret; } -void coff::writeMapFile(ArrayRef OutputSections) { - if (Config->MapFile.empty()) +void coff::writeMapFile(ArrayRef outputSections) { + if (config->mapFile.empty()) return; - std::error_code EC; - raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None); - if (EC) - fatal("cannot open " + Config->MapFile + ": " + EC.message()); + std::error_code ec; + raw_fd_ostream os(config->mapFile, ec, sys::fs::F_None); + if (ec) + fatal("cannot open " + config->mapFile + ": " + ec.message()); // Collect symbol info that we want to print out. - std::vector Syms = getSymbols(); - SymbolMapTy SectionSyms = getSectionSyms(Syms); - DenseMap SymStr = getSymbolStrings(Syms); + std::vector syms = getSymbols(); + SymbolMapTy sectionSyms = getSectionSyms(syms); + DenseMap symStr = getSymbolStrings(syms); // Print out the header line. - OS << "Address Size Align Out In Symbol\n"; + os << "Address Size Align Out In Symbol\n"; // Print out file contents. - for (OutputSection *Sec : OutputSections) { - writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize); - OS << Sec->Name << '\n'; + for (OutputSection *sec : outputSections) { + writeHeader(os, sec->getRVA(), sec->getVirtualSize(), /*Align=*/pageSize); + os << sec->name << '\n'; - for (Chunk *C : Sec->Chunks) { - auto *SC = dyn_cast(C); - if (!SC) + for (Chunk *c : sec->chunks) { + auto *sc = dyn_cast(c); + if (!sc) continue; - writeHeader(OS, SC->getRVA(), SC->getSize(), SC->getAlignment()); - OS << Indent8 << SC->File->getName() << ":(" << SC->getSectionName() + writeHeader(os, sc->getRVA(), sc->getSize(), sc->getAlignment()); + os << indent8 << sc->file->getName() << ":(" << sc->getSectionName() << ")\n"; - for (DefinedRegular *Sym : SectionSyms[SC]) - OS << SymStr[Sym] << '\n'; + for (DefinedRegular *sym : sectionSyms[sc]) + os << symStr[sym] << '\n'; } } } diff --git a/lld/COFF/MapFile.h b/lld/COFF/MapFile.h index f702dc6..2bf01bd 100644 --- a/lld/COFF/MapFile.h +++ b/lld/COFF/MapFile.h @@ -14,7 +14,7 @@ namespace lld { namespace coff { class OutputSection; -void writeMapFile(llvm::ArrayRef OutputSections); +void writeMapFile(llvm::ArrayRef outputSections); } } diff --git a/lld/COFF/MarkLive.cpp b/lld/COFF/MarkLive.cpp index 50e41ba..0543d0e 100644 --- a/lld/COFF/MarkLive.cpp +++ b/lld/COFF/MarkLive.cpp @@ -15,57 +15,57 @@ namespace lld { namespace coff { -static Timer GCTimer("GC", Timer::root()); +static Timer gCTimer("GC", Timer::root()); // Set live bit on for each reachable chunk. Unmarked (unreachable) // COMDAT chunks will be ignored by Writer, so they will be excluded // from the final output. -void markLive(ArrayRef Chunks) { - ScopedTimer T(GCTimer); +void markLive(ArrayRef chunks) { + ScopedTimer t(gCTimer); // We build up a worklist of sections which have been marked as live. We only // push into the worklist when we discover an unmarked section, and we mark // as we push, so sections never appear twice in the list. - SmallVector Worklist; + SmallVector worklist; // COMDAT section chunks are dead by default. Add non-COMDAT chunks. - for (Chunk *C : Chunks) - if (auto *SC = dyn_cast(C)) - if (SC->Live) - Worklist.push_back(SC); + for (Chunk *c : chunks) + if (auto *sc = dyn_cast(c)) + if (sc->live) + worklist.push_back(sc); - auto Enqueue = [&](SectionChunk *C) { - if (C->Live) + auto enqueue = [&](SectionChunk *c) { + if (c->live) return; - C->Live = true; - Worklist.push_back(C); + c->live = true; + worklist.push_back(c); }; - auto AddSym = [&](Symbol *B) { - if (auto *Sym = dyn_cast(B)) - Enqueue(Sym->getChunk()); - else if (auto *Sym = dyn_cast(B)) - Sym->File->Live = true; - else if (auto *Sym = dyn_cast(B)) - Sym->WrappedSym->File->Live = Sym->WrappedSym->File->ThunkLive = true; + auto addSym = [&](Symbol *b) { + if (auto *sym = dyn_cast(b)) + enqueue(sym->getChunk()); + else if (auto *sym = dyn_cast(b)) + sym->file->live = true; + else if (auto *sym = dyn_cast(b)) + sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true; }; // Add GC root chunks. - for (Symbol *B : Config->GCRoot) - AddSym(B); + for (Symbol *b : config->gCRoot) + addSym(b); - while (!Worklist.empty()) { - SectionChunk *SC = Worklist.pop_back_val(); - assert(SC->Live && "We mark as live when pushing onto the worklist!"); + while (!worklist.empty()) { + SectionChunk *sc = worklist.pop_back_val(); + assert(sc->live && "We mark as live when pushing onto the worklist!"); // Mark all symbols listed in the relocation table for this section. - for (Symbol *B : SC->symbols()) - if (B) - AddSym(B); + for (Symbol *b : sc->symbols()) + if (b) + addSym(b); // Mark associative sections if any. - for (SectionChunk &C : SC->children()) - Enqueue(&C); + for (SectionChunk &c : sc->children()) + enqueue(&c); } } diff --git a/lld/COFF/MarkLive.h b/lld/COFF/MarkLive.h index 9c584dc..e4e4c31 100644 --- a/lld/COFF/MarkLive.h +++ b/lld/COFF/MarkLive.h @@ -17,7 +17,7 @@ namespace coff { class Chunk; -void markLive(ArrayRef Chunks); +void markLive(ArrayRef chunks); } // namespace coff } // namespace lld diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp index 9d3815d..2ca8ca0 100644 --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -19,7 +19,7 @@ using namespace llvm; using namespace llvm::COFF; AutoExporter::AutoExporter() { - ExcludeLibs = { + excludeLibs = { "libgcc", "libgcc_s", "libstdc++", @@ -41,12 +41,12 @@ AutoExporter::AutoExporter() { "libucrtbase", }; - ExcludeObjects = { + excludeObjects = { "crt0.o", "crt1.o", "crt1u.o", "crt2.o", "crt2u.o", "dllcrt1.o", "dllcrt2.o", "gcrt0.o", "gcrt1.o", "gcrt2.o", "crtbegin.o", "crtend.o", }; - ExcludeSymbolPrefixes = { + excludeSymbolPrefixes = { // Import symbols "__imp_", "__IMPORT_DESCRIPTOR_", @@ -59,13 +59,13 @@ AutoExporter::AutoExporter() { ".", }; - ExcludeSymbolSuffixes = { + excludeSymbolSuffixes = { "_iname", "_NULL_THUNK_DATA", }; - if (Config->Machine == I386) { - ExcludeSymbols = { + if (config->machine == I386) { + excludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", "__pei386_runtime_relocator", "_do_pseudo_reloc", @@ -80,9 +80,9 @@ AutoExporter::AutoExporter() { "_DllEntryPoint@12", "_DllMainCRTStartup@12", }; - ExcludeSymbolPrefixes.insert("__head_"); + excludeSymbolPrefixes.insert("__head_"); } else { - ExcludeSymbols = { + excludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", "_pei386_runtime_relocator", "do_pseudo_reloc", @@ -97,70 +97,70 @@ AutoExporter::AutoExporter() { "DllEntryPoint", "DllMainCRTStartup", }; - ExcludeSymbolPrefixes.insert("_head_"); + excludeSymbolPrefixes.insert("_head_"); } } -void AutoExporter::addWholeArchive(StringRef Path) { - StringRef LibName = sys::path::filename(Path); +void AutoExporter::addWholeArchive(StringRef path) { + StringRef libName = sys::path::filename(path); // Drop the file extension, to match the processing below. - LibName = LibName.substr(0, LibName.rfind('.')); - ExcludeLibs.erase(LibName); + libName = libName.substr(0, libName.rfind('.')); + excludeLibs.erase(libName); } -bool AutoExporter::shouldExport(Defined *Sym) const { - if (!Sym || !Sym->isLive() || !Sym->getChunk()) +bool AutoExporter::shouldExport(Defined *sym) const { + if (!sym || !sym->isLive() || !sym->getChunk()) return false; // Only allow the symbol kinds that make sense to export; in particular, // disallow import symbols. - if (!isa(Sym) && !isa(Sym)) + if (!isa(sym) && !isa(sym)) return false; - if (ExcludeSymbols.count(Sym->getName())) + if (excludeSymbols.count(sym->getName())) return false; - for (StringRef Prefix : ExcludeSymbolPrefixes.keys()) - if (Sym->getName().startswith(Prefix)) + for (StringRef prefix : excludeSymbolPrefixes.keys()) + if (sym->getName().startswith(prefix)) return false; - for (StringRef Suffix : ExcludeSymbolSuffixes.keys()) - if (Sym->getName().endswith(Suffix)) + for (StringRef suffix : excludeSymbolSuffixes.keys()) + if (sym->getName().endswith(suffix)) return false; // If a corresponding __imp_ symbol exists and is defined, don't export it. - if (Symtab->find(("__imp_" + Sym->getName()).str())) + if (symtab->find(("__imp_" + sym->getName()).str())) return false; // Check that file is non-null before dereferencing it, symbols not // originating in regular object files probably shouldn't be exported. - if (!Sym->getFile()) + if (!sym->getFile()) return false; - StringRef LibName = sys::path::filename(Sym->getFile()->ParentName); + StringRef libName = sys::path::filename(sym->getFile()->parentName); // Drop the file extension. - LibName = LibName.substr(0, LibName.rfind('.')); - if (!LibName.empty()) - return !ExcludeLibs.count(LibName); + libName = libName.substr(0, libName.rfind('.')); + if (!libName.empty()) + return !excludeLibs.count(libName); - StringRef FileName = sys::path::filename(Sym->getFile()->getName()); - return !ExcludeObjects.count(FileName); + StringRef fileName = sys::path::filename(sym->getFile()->getName()); + return !excludeObjects.count(fileName); } -void coff::writeDefFile(StringRef Name) { - std::error_code EC; - raw_fd_ostream OS(Name, EC, sys::fs::F_None); - if (EC) - fatal("cannot open " + Name + ": " + EC.message()); - - OS << "EXPORTS\n"; - for (Export &E : Config->Exports) { - OS << " " << E.ExportName << " " - << "@" << E.Ordinal; - if (auto *Def = dyn_cast_or_null(E.Sym)) { - if (Def && Def->getChunk() && - !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) - OS << " DATA"; +void coff::writeDefFile(StringRef name) { + std::error_code ec; + raw_fd_ostream os(name, ec, sys::fs::F_None); + if (ec) + fatal("cannot open " + name + ": " + ec.message()); + + os << "EXPORTS\n"; + for (Export &e : config->exports) { + os << " " << e.exportName << " " + << "@" << e.ordinal; + if (auto *def = dyn_cast_or_null(e.sym)) { + if (def && def->getChunk() && + !(def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) + os << " DATA"; } - OS << "\n"; + os << "\n"; } } diff --git a/lld/COFF/MinGW.h b/lld/COFF/MinGW.h index fde9eeb..578a277 100644 --- a/lld/COFF/MinGW.h +++ b/lld/COFF/MinGW.h @@ -22,18 +22,18 @@ class AutoExporter { public: AutoExporter(); - void addWholeArchive(StringRef Path); + void addWholeArchive(StringRef path); - llvm::StringSet<> ExcludeSymbols; - llvm::StringSet<> ExcludeSymbolPrefixes; - llvm::StringSet<> ExcludeSymbolSuffixes; - llvm::StringSet<> ExcludeLibs; - llvm::StringSet<> ExcludeObjects; + llvm::StringSet<> excludeSymbols; + llvm::StringSet<> excludeSymbolPrefixes; + llvm::StringSet<> excludeSymbolSuffixes; + llvm::StringSet<> excludeLibs; + llvm::StringSet<> excludeObjects; - bool shouldExport(Defined *Sym) const; + bool shouldExport(Defined *sym) const; }; -void writeDefFile(StringRef Name); +void writeDefFile(StringRef name); } // namespace coff } // namespace lld diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 6d3bf64..d024f75 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -66,16 +66,16 @@ using namespace llvm::codeview; using llvm::object::coff_section; -static ExitOnError ExitOnErr; +static ExitOnError exitOnErr; -static Timer TotalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root()); +static Timer totalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root()); -static Timer AddObjectsTimer("Add Objects", TotalPdbLinkTimer); -static Timer TypeMergingTimer("Type Merging", AddObjectsTimer); -static Timer SymbolMergingTimer("Symbol Merging", AddObjectsTimer); -static Timer GlobalsLayoutTimer("Globals Stream Layout", TotalPdbLinkTimer); -static Timer TpiStreamLayoutTimer("TPI Stream Layout", TotalPdbLinkTimer); -static Timer DiskCommitTimer("Commit to Disk", TotalPdbLinkTimer); +static Timer addObjectsTimer("Add Objects", totalPdbLinkTimer); +static Timer typeMergingTimer("Type Merging", addObjectsTimer); +static Timer symbolMergingTimer("Symbol Merging", addObjectsTimer); +static Timer globalsLayoutTimer("Globals Stream Layout", totalPdbLinkTimer); +static Timer tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer); +static Timer diskCommitTimer("Commit to Disk", totalPdbLinkTimer); namespace { class DebugSHandler; @@ -84,16 +84,16 @@ class PDBLinker { friend DebugSHandler; public: - PDBLinker(SymbolTable *Symtab) - : Alloc(), Symtab(Symtab), Builder(Alloc), TMerger(Alloc) { + PDBLinker(SymbolTable *symtab) + : alloc(), symtab(symtab), builder(alloc), tMerger(alloc) { // This isn't strictly necessary, but link.exe usually puts an empty string // as the first "valid" string in the string table, so we do the same in // order to maintain as much byte-for-byte compatibility as possible. - PDBStrTab.insert(""); + pdbStrTab.insert(""); } /// Emit the basic PDB structure: initial streams, headers, etc. - void initialize(llvm::codeview::DebugInfo *BuildId); + void initialize(llvm::codeview::DebugInfo *buildId); /// Add natvis files specified on the command line. void addNatvisFiles(); @@ -102,12 +102,12 @@ public: void addObjectsToPDB(); /// Link info for each import file in the symbol table into the PDB. - void addImportFilesToPDB(ArrayRef OutputSections); + void addImportFilesToPDB(ArrayRef outputSections); /// Link CodeView from a single object file into the target (output) PDB. /// When a precompiled headers object is linked, its TPI map might be provided /// externally. - void addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap = nullptr); + void addObjFile(ObjFile *file, CVIndexMap *externIndexMap = nullptr); /// Produce a mapping from the type and item indices used in the object /// file to those in the destination PDB. @@ -120,16 +120,16 @@ public: /// If the object does not use a type server PDB (compiled with /Z7), we merge /// all the type and item records from the .debug$S stream and fill in the /// caller-provided ObjectIndexMap. - Expected mergeDebugT(ObjFile *File, - CVIndexMap *ObjectIndexMap); + Expected mergeDebugT(ObjFile *file, + CVIndexMap *objectIndexMap); /// Reads and makes available a PDB. - Expected maybeMergeTypeServerPDB(ObjFile *File); + Expected maybeMergeTypeServerPDB(ObjFile *file); /// Merges a precompiled headers TPI map into the current TPI map. The /// precompiled headers object will also be loaded and remapped in the /// process. - Error mergeInPrecompHeaderObj(ObjFile *File, CVIndexMap *ObjectIndexMap); + Error mergeInPrecompHeaderObj(ObjFile *file, CVIndexMap *objectIndexMap); /// Reads and makes available a precompiled headers object. /// @@ -140,87 +140,87 @@ public: /// /// If the precompiled headers object was already loaded, this function will /// simply return its (remapped) TPI map. - Expected aquirePrecompObj(ObjFile *File); + Expected aquirePrecompObj(ObjFile *file); /// Adds a precompiled headers object signature -> TPI mapping. std::pair - registerPrecompiledHeaders(uint32_t Signature); + registerPrecompiledHeaders(uint32_t signature); - void mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap, - std::vector &StringTableRefs, - BinaryStreamRef SymData); + void mergeSymbolRecords(ObjFile *file, const CVIndexMap &indexMap, + std::vector &stringTableRefs, + BinaryStreamRef symData); /// Add the section map and section contributions to the PDB. - void addSections(ArrayRef OutputSections, - ArrayRef SectionTable); + void addSections(ArrayRef outputSections, + ArrayRef sectionTable); /// Write the PDB to disk and store the Guid generated for it in *Guid. - void commit(codeview::GUID *Guid); + void commit(codeview::GUID *guid); // Print statistics regarding the final PDB void printStats(); private: - BumpPtrAllocator Alloc; + BumpPtrAllocator alloc; - SymbolTable *Symtab; + SymbolTable *symtab; - pdb::PDBFileBuilder Builder; + pdb::PDBFileBuilder builder; - TypeMerger TMerger; + TypeMerger tMerger; /// PDBs use a single global string table for filenames in the file checksum /// table. - DebugStringTableSubsection PDBStrTab; + DebugStringTableSubsection pdbStrTab; - llvm::SmallString<128> NativePath; + llvm::SmallString<128> nativePath; - std::vector SectionMap; + std::vector sectionMap; /// Type index mappings of type server PDBs that we've loaded so far. - std::map TypeServerIndexMappings; + std::map typeServerIndexMappings; /// Type index mappings of precompiled objects type map that we've loaded so /// far. - std::map PrecompTypeIndexMappings; + std::map precompTypeIndexMappings; // For statistics - uint64_t GlobalSymbols = 0; - uint64_t ModuleSymbols = 0; - uint64_t PublicSymbols = 0; + uint64_t globalSymbols = 0; + uint64_t moduleSymbols = 0; + uint64_t publicSymbols = 0; }; class DebugSHandler { - PDBLinker &Linker; + PDBLinker &linker; /// The object file whose .debug$S sections we're processing. - ObjFile &File; + ObjFile &file; /// The result of merging type indices. - const CVIndexMap &IndexMap; + const CVIndexMap &indexMap; /// The DEBUG_S_STRINGTABLE subsection. These strings are referred to by /// index from other records in the .debug$S section. All of these strings /// need to be added to the global PDB string table, and all references to /// these strings need to have their indices re-written to refer to the /// global PDB string table. - DebugStringTableSubsectionRef CVStrTab; + DebugStringTableSubsectionRef cVStrTab; /// The DEBUG_S_FILECHKSMS subsection. As above, these are referred to /// by other records in the .debug$S section and need to be merged into the /// PDB. - DebugChecksumsSubsectionRef Checksums; + DebugChecksumsSubsectionRef checksums; /// The DEBUG_S_INLINEELINES subsection. There can be only one of these per /// object file. - DebugInlineeLinesSubsectionRef InlineeLines; + DebugInlineeLinesSubsectionRef inlineeLines; /// The DEBUG_S_FRAMEDATA subsection(s). There can be more than one of /// these and they need not appear in any specific order. However, they /// contain string table references which need to be re-written, so we /// collect them all here and re-write them after all subsections have been /// discovered and processed. - std::vector NewFpoFrames; + std::vector newFpoFrames; /// Pointers to raw memory that we determine have string table references /// that need to be re-written. We first process all .debug$S subsections @@ -228,16 +228,16 @@ class DebugSHandler { /// up this list as we go. At the end, we use the string table (which must /// have been discovered by now else it is an error) to re-write these /// references. - std::vector StringTableReferences; + std::vector stringTableReferences; public: - DebugSHandler(PDBLinker &Linker, ObjFile &File, const CVIndexMap &IndexMap) - : Linker(Linker), File(File), IndexMap(IndexMap) {} + DebugSHandler(PDBLinker &linker, ObjFile &file, const CVIndexMap &indexMap) + : linker(linker), file(file), indexMap(indexMap) {} - void handleDebugS(lld::coff::SectionChunk &DebugS); + void handleDebugS(lld::coff::SectionChunk &debugS); std::shared_ptr - mergeInlineeLines(DebugChecksumsSubsection *NewChecksums); + mergeInlineeLines(DebugChecksumsSubsection *newChecksums); void finish(); }; @@ -246,7 +246,7 @@ public: // Visual Studio's debugger requires absolute paths in various places in the // PDB to work without additional configuration: // https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box -static void pdbMakeAbsolute(SmallVectorImpl &FileName) { +static void pdbMakeAbsolute(SmallVectorImpl &fileName) { // The default behavior is to produce paths that are valid within the context // of the machine that you perform the link on. If the linker is running on // a POSIX system, we will output absolute POSIX paths. If the linker is @@ -254,16 +254,16 @@ static void pdbMakeAbsolute(SmallVectorImpl &FileName) { // user desires any other kind of behavior, they should explicitly pass // /pdbsourcepath, in which case we will treat the exact string the user // passed in as the gospel and not normalize, canonicalize it. - if (sys::path::is_absolute(FileName, sys::path::Style::windows) || - sys::path::is_absolute(FileName, sys::path::Style::posix)) + if (sys::path::is_absolute(fileName, sys::path::Style::windows) || + sys::path::is_absolute(fileName, sys::path::Style::posix)) return; // It's not absolute in any path syntax. Relative paths necessarily refer to // the local file system, so we can make it native without ending up with a // nonsensical path. - if (Config->PDBSourcePath.empty()) { - sys::path::native(FileName); - sys::fs::make_absolute(FileName); + if (config->pdbSourcePath.empty()) { + sys::path::native(fileName); + sys::fs::make_absolute(fileName); return; } @@ -271,238 +271,238 @@ static void pdbMakeAbsolute(SmallVectorImpl &FileName) { // Since PDB's are more of a Windows thing, we make this conservative and only // decide that it's a unix path if we're fairly certain. Specifically, if // it starts with a forward slash. - SmallString<128> AbsoluteFileName = Config->PDBSourcePath; - sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/") + SmallString<128> absoluteFileName = config->pdbSourcePath; + sys::path::Style guessedStyle = absoluteFileName.startswith("/") ? sys::path::Style::posix : sys::path::Style::windows; - sys::path::append(AbsoluteFileName, GuessedStyle, FileName); - sys::path::native(AbsoluteFileName, GuessedStyle); - sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle); + sys::path::append(absoluteFileName, guessedStyle, fileName); + sys::path::native(absoluteFileName, guessedStyle); + sys::path::remove_dots(absoluteFileName, true, guessedStyle); - FileName = std::move(AbsoluteFileName); + fileName = std::move(absoluteFileName); } // A COFF .debug$H section is currently a clang extension. This function checks // if a .debug$H section is in a format that we expect / understand, so that we // can ignore any sections which are coincidentally also named .debug$H but do // not contain a format we recognize. -static bool canUseDebugH(ArrayRef DebugH) { - if (DebugH.size() < sizeof(object::debug_h_header)) +static bool canUseDebugH(ArrayRef debugH) { + if (debugH.size() < sizeof(object::debug_h_header)) return false; - auto *Header = - reinterpret_cast(DebugH.data()); - DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); - return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && - Header->Version == 0 && - Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) && - (DebugH.size() % 8 == 0); + auto *header = + reinterpret_cast(debugH.data()); + debugH = debugH.drop_front(sizeof(object::debug_h_header)); + return header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && + header->Version == 0 && + header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) && + (debugH.size() % 8 == 0); } -static Optional> getDebugH(ObjFile *File) { - SectionChunk *Sec = - SectionChunk::findByName(File->getDebugChunks(), ".debug$H"); - if (!Sec) +static Optional> getDebugH(ObjFile *file) { + SectionChunk *sec = + SectionChunk::findByName(file->getDebugChunks(), ".debug$H"); + if (!sec) return llvm::None; - ArrayRef Contents = Sec->getContents(); - if (!canUseDebugH(Contents)) + ArrayRef contents = sec->getContents(); + if (!canUseDebugH(contents)) return None; - return Contents; + return contents; } static ArrayRef -getHashesFromDebugH(ArrayRef DebugH) { - assert(canUseDebugH(DebugH)); +getHashesFromDebugH(ArrayRef debugH) { + assert(canUseDebugH(debugH)); - DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); - uint32_t Count = DebugH.size() / sizeof(GloballyHashedType); - return {reinterpret_cast(DebugH.data()), Count}; + debugH = debugH.drop_front(sizeof(object::debug_h_header)); + uint32_t count = debugH.size() / sizeof(GloballyHashedType); + return {reinterpret_cast(debugH.data()), count}; } -static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, - TypeCollection &TypeTable) { +static void addTypeInfo(pdb::TpiStreamBuilder &tpiBuilder, + TypeCollection &typeTable) { // Start the TPI or IPI stream header. - TpiBuilder.setVersionHeader(pdb::PdbTpiV80); + tpiBuilder.setVersionHeader(pdb::PdbTpiV80); // Flatten the in memory type table and hash each type. - TypeTable.ForEachRecord([&](TypeIndex TI, const CVType &Type) { - auto Hash = pdb::hashTypeRecord(Type); - if (auto E = Hash.takeError()) + typeTable.ForEachRecord([&](TypeIndex ti, const CVType &type) { + auto hash = pdb::hashTypeRecord(type); + if (auto e = hash.takeError()) fatal("type hashing error"); - TpiBuilder.addTypeRecord(Type.RecordData, *Hash); + tpiBuilder.addTypeRecord(type.RecordData, *hash); }); } Expected -PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) { - ScopedTimer T(TypeMergingTimer); +PDBLinker::mergeDebugT(ObjFile *file, CVIndexMap *objectIndexMap) { + ScopedTimer t(typeMergingTimer); - if (!File->DebugTypesObj) - return *ObjectIndexMap; // no Types stream + if (!file->debugTypesObj) + return *objectIndexMap; // no Types stream // Precompiled headers objects need to save the index map for further // reference by other objects which use the precompiled headers. - if (File->DebugTypesObj->Kind == TpiSource::PCH) { - uint32_t PCHSignature = File->PCHSignature.getValueOr(0); - if (PCHSignature == 0) + if (file->debugTypesObj->kind == TpiSource::PCH) { + uint32_t pchSignature = file->pchSignature.getValueOr(0); + if (pchSignature == 0) fatal("No signature found for the precompiled headers OBJ (" + - File->getName() + ")"); + file->getName() + ")"); // When a precompiled headers object comes first on the command-line, we // update the mapping here. Otherwise, if an object referencing the // precompiled headers object comes first, the mapping is created in // aquirePrecompObj(), thus we would skip this block. - if (!ObjectIndexMap->IsPrecompiledTypeMap) { - auto R = registerPrecompiledHeaders(PCHSignature); - if (R.second) + if (!objectIndexMap->isPrecompiledTypeMap) { + auto r = registerPrecompiledHeaders(pchSignature); + if (r.second) fatal( "A precompiled headers OBJ with the same signature was already " "provided! (" + - File->getName() + ")"); + file->getName() + ")"); - ObjectIndexMap = &R.first; + objectIndexMap = &r.first; } } - if (File->DebugTypesObj->Kind == TpiSource::UsingPDB) { + if (file->debugTypesObj->kind == TpiSource::UsingPDB) { // Look through type servers. If we've already seen this type server, // don't merge any type information. - return maybeMergeTypeServerPDB(File); + return maybeMergeTypeServerPDB(file); } - CVTypeArray &Types = *File->DebugTypes; + CVTypeArray &types = *file->debugTypes; - if (File->DebugTypesObj->Kind == TpiSource::UsingPCH) { + if (file->debugTypesObj->kind == TpiSource::UsingPCH) { // This object was compiled with /Yu, so process the corresponding // precompiled headers object (/Yc) first. Some type indices in the current // object are referencing data in the precompiled headers object, so we need // both to be loaded. - Error E = mergeInPrecompHeaderObj(File, ObjectIndexMap); - if (E) - return std::move(E); + Error e = mergeInPrecompHeaderObj(file, objectIndexMap); + if (e) + return std::move(e); // Drop LF_PRECOMP record from the input stream, as it has been replaced // with the precompiled headers Type stream in the mergeInPrecompHeaderObj() // call above. Note that we can't just call Types.drop_front(), as we // explicitly want to rebase the stream. - CVTypeArray::Iterator FirstType = Types.begin(); - Types.setUnderlyingStream( - Types.getUnderlyingStream().drop_front(FirstType->RecordData.size())); + CVTypeArray::Iterator firstType = types.begin(); + types.setUnderlyingStream( + types.getUnderlyingStream().drop_front(firstType->RecordData.size())); } // Fill in the temporary, caller-provided ObjectIndexMap. - if (Config->DebugGHashes) { - ArrayRef Hashes; - std::vector OwnedHashes; - if (Optional> DebugH = getDebugH(File)) - Hashes = getHashesFromDebugH(*DebugH); + if (config->debugGHashes) { + ArrayRef hashes; + std::vector ownedHashes; + if (Optional> debugH = getDebugH(file)) + hashes = getHashesFromDebugH(*debugH); else { - OwnedHashes = GloballyHashedType::hashTypes(Types); - Hashes = OwnedHashes; + ownedHashes = GloballyHashedType::hashTypes(types); + hashes = ownedHashes; } - if (auto Err = mergeTypeAndIdRecords( - TMerger.GlobalIDTable, TMerger.GlobalTypeTable, - ObjectIndexMap->TPIMap, Types, Hashes, File->PCHSignature)) + if (auto err = mergeTypeAndIdRecords( + tMerger.globalIDTable, tMerger.globalTypeTable, + objectIndexMap->tpiMap, types, hashes, file->pchSignature)) fatal("codeview::mergeTypeAndIdRecords failed: " + - toString(std::move(Err))); + toString(std::move(err))); } else { - if (auto Err = mergeTypeAndIdRecords(TMerger.IDTable, TMerger.TypeTable, - ObjectIndexMap->TPIMap, Types, - File->PCHSignature)) + if (auto err = mergeTypeAndIdRecords(tMerger.iDTable, tMerger.typeTable, + objectIndexMap->tpiMap, types, + file->pchSignature)) fatal("codeview::mergeTypeAndIdRecords failed: " + - toString(std::move(Err))); + toString(std::move(err))); } - return *ObjectIndexMap; + return *objectIndexMap; } -Expected PDBLinker::maybeMergeTypeServerPDB(ObjFile *File) { - Expected PDBSession = findTypeServerSource(File); - if (!PDBSession) - return PDBSession.takeError(); +Expected PDBLinker::maybeMergeTypeServerPDB(ObjFile *file) { + Expected pdbSession = findTypeServerSource(file); + if (!pdbSession) + return pdbSession.takeError(); - pdb::PDBFile &PDBFile = PDBSession.get()->getPDBFile(); - pdb::InfoStream &Info = cantFail(PDBFile.getPDBInfoStream()); + pdb::PDBFile &pdbFile = pdbSession.get()->getPDBFile(); + pdb::InfoStream &info = cantFail(pdbFile.getPDBInfoStream()); - auto It = TypeServerIndexMappings.emplace(Info.getGuid(), CVIndexMap()); - CVIndexMap &IndexMap = It.first->second; - if (!It.second) - return IndexMap; // already merged + auto it = typeServerIndexMappings.emplace(info.getGuid(), CVIndexMap()); + CVIndexMap &indexMap = it.first->second; + if (!it.second) + return indexMap; // already merged // Mark this map as a type server map. - IndexMap.IsTypeServerMap = true; - - Expected ExpectedTpi = PDBFile.getPDBTpiStream(); - if (auto E = ExpectedTpi.takeError()) - fatal("Type server does not have TPI stream: " + toString(std::move(E))); - pdb::TpiStream *MaybeIpi = nullptr; - if (PDBFile.hasPDBIpiStream()) { - Expected ExpectedIpi = PDBFile.getPDBIpiStream(); - if (auto E = ExpectedIpi.takeError()) - fatal("Error getting type server IPI stream: " + toString(std::move(E))); - MaybeIpi = &*ExpectedIpi; + indexMap.isTypeServerMap = true; + + Expected expectedTpi = pdbFile.getPDBTpiStream(); + if (auto e = expectedTpi.takeError()) + fatal("Type server does not have TPI stream: " + toString(std::move(e))); + pdb::TpiStream *maybeIpi = nullptr; + if (pdbFile.hasPDBIpiStream()) { + Expected expectedIpi = pdbFile.getPDBIpiStream(); + if (auto e = expectedIpi.takeError()) + fatal("Error getting type server IPI stream: " + toString(std::move(e))); + maybeIpi = &*expectedIpi; } - if (Config->DebugGHashes) { + if (config->debugGHashes) { // PDBs do not actually store global hashes, so when merging a type server // PDB we have to synthesize global hashes. To do this, we first synthesize // global hashes for the TPI stream, since it is independent, then we // synthesize hashes for the IPI stream, using the hashes for the TPI stream // as inputs. - auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray()); - Optional EndPrecomp; + auto tpiHashes = GloballyHashedType::hashTypes(expectedTpi->typeArray()); + Optional endPrecomp; // Merge TPI first, because the IPI stream will reference type indices. - if (auto Err = - mergeTypeRecords(TMerger.GlobalTypeTable, IndexMap.TPIMap, - ExpectedTpi->typeArray(), TpiHashes, EndPrecomp)) - fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); + if (auto err = + mergeTypeRecords(tMerger.globalTypeTable, indexMap.tpiMap, + expectedTpi->typeArray(), tpiHashes, endPrecomp)) + fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err))); // Merge IPI. - if (MaybeIpi) { - auto IpiHashes = - GloballyHashedType::hashIds(MaybeIpi->typeArray(), TpiHashes); - if (auto Err = - mergeIdRecords(TMerger.GlobalIDTable, IndexMap.TPIMap, - IndexMap.IPIMap, MaybeIpi->typeArray(), IpiHashes)) - fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + if (maybeIpi) { + auto ipiHashes = + GloballyHashedType::hashIds(maybeIpi->typeArray(), tpiHashes); + if (auto err = + mergeIdRecords(tMerger.globalIDTable, indexMap.tpiMap, + indexMap.ipiMap, maybeIpi->typeArray(), ipiHashes)) + fatal("codeview::mergeIdRecords failed: " + toString(std::move(err))); } } else { // Merge TPI first, because the IPI stream will reference type indices. - if (auto Err = mergeTypeRecords(TMerger.TypeTable, IndexMap.TPIMap, - ExpectedTpi->typeArray())) - fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); + if (auto err = mergeTypeRecords(tMerger.typeTable, indexMap.tpiMap, + expectedTpi->typeArray())) + fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err))); // Merge IPI. - if (MaybeIpi) { - if (auto Err = mergeIdRecords(TMerger.IDTable, IndexMap.TPIMap, - IndexMap.IPIMap, MaybeIpi->typeArray())) - fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + if (maybeIpi) { + if (auto err = mergeIdRecords(tMerger.iDTable, indexMap.tpiMap, + indexMap.ipiMap, maybeIpi->typeArray())) + fatal("codeview::mergeIdRecords failed: " + toString(std::move(err))); } } - return IndexMap; + return indexMap; } -Error PDBLinker::mergeInPrecompHeaderObj(ObjFile *File, - CVIndexMap *ObjectIndexMap) { - const PrecompRecord &Precomp = - retrieveDependencyInfo(File->DebugTypesObj); +Error PDBLinker::mergeInPrecompHeaderObj(ObjFile *file, + CVIndexMap *objectIndexMap) { + const PrecompRecord &precomp = + retrieveDependencyInfo(file->debugTypesObj); - Expected E = aquirePrecompObj(File); - if (!E) - return E.takeError(); + Expected e = aquirePrecompObj(file); + if (!e) + return e.takeError(); - const CVIndexMap &PrecompIndexMap = *E; - assert(PrecompIndexMap.IsPrecompiledTypeMap); + const CVIndexMap &precompIndexMap = *e; + assert(precompIndexMap.isPrecompiledTypeMap); - if (PrecompIndexMap.TPIMap.empty()) + if (precompIndexMap.tpiMap.empty()) return Error::success(); - assert(Precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex); - assert(Precomp.getTypesCount() <= PrecompIndexMap.TPIMap.size()); + assert(precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex); + assert(precomp.getTypesCount() <= precompIndexMap.tpiMap.size()); // Use the previously remapped index map from the precompiled headers. - ObjectIndexMap->TPIMap.append(PrecompIndexMap.TPIMap.begin(), - PrecompIndexMap.TPIMap.begin() + - Precomp.getTypesCount()); + objectIndexMap->tpiMap.append(precompIndexMap.tpiMap.begin(), + precompIndexMap.tpiMap.begin() + + precomp.getTypesCount()); return Error::success(); } @@ -515,103 +515,103 @@ static bool equals_path(StringRef path1, StringRef path2) { } // Find by name an OBJ provided on the command line -static ObjFile *findObjByName(StringRef FileNameOnly) { - SmallString<128> CurrentPath; +static ObjFile *findObjByName(StringRef fileNameOnly) { + SmallString<128> currentPath; - for (ObjFile *F : ObjFile::Instances) { - StringRef CurrentFileName = sys::path::filename(F->getName()); + for (ObjFile *f : ObjFile::instances) { + StringRef currentFileName = sys::path::filename(f->getName()); // Compare based solely on the file name (link.exe behavior) - if (equals_path(CurrentFileName, FileNameOnly)) - return F; + if (equals_path(currentFileName, fileNameOnly)) + return f; } return nullptr; } std::pair -PDBLinker::registerPrecompiledHeaders(uint32_t Signature) { - auto Insertion = PrecompTypeIndexMappings.insert({Signature, CVIndexMap()}); - CVIndexMap &IndexMap = Insertion.first->second; - if (!Insertion.second) - return {IndexMap, true}; +PDBLinker::registerPrecompiledHeaders(uint32_t signature) { + auto insertion = precompTypeIndexMappings.insert({signature, CVIndexMap()}); + CVIndexMap &indexMap = insertion.first->second; + if (!insertion.second) + return {indexMap, true}; // Mark this map as a precompiled types map. - IndexMap.IsPrecompiledTypeMap = true; - return {IndexMap, false}; + indexMap.isPrecompiledTypeMap = true; + return {indexMap, false}; } -Expected PDBLinker::aquirePrecompObj(ObjFile *File) { - const PrecompRecord &Precomp = - retrieveDependencyInfo(File->DebugTypesObj); +Expected PDBLinker::aquirePrecompObj(ObjFile *file) { + const PrecompRecord &precomp = + retrieveDependencyInfo(file->debugTypesObj); // First, check if we already loaded the precompiled headers object with this // signature. Return the type index mapping if we've already seen it. - auto R = registerPrecompiledHeaders(Precomp.getSignature()); - if (R.second) - return R.first; + auto r = registerPrecompiledHeaders(precomp.getSignature()); + if (r.second) + return r.first; - CVIndexMap &IndexMap = R.first; + CVIndexMap &indexMap = r.first; // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly, // the paths embedded in the OBJs are in the Windows format. - SmallString<128> PrecompFileName = sys::path::filename( - Precomp.getPrecompFilePath(), sys::path::Style::windows); + SmallString<128> precompFileName = sys::path::filename( + precomp.getPrecompFilePath(), sys::path::Style::windows); // link.exe requires that a precompiled headers object must always be provided // on the command-line, even if that's not necessary. - auto PrecompFile = findObjByName(PrecompFileName); - if (!PrecompFile) + auto precompFile = findObjByName(precompFileName); + if (!precompFile) return createFileError( - PrecompFileName.str(), + precompFileName.str(), make_error(pdb::pdb_error_code::external_cmdline_ref)); - addObjFile(PrecompFile, &IndexMap); + addObjFile(precompFile, &indexMap); - if (!PrecompFile->PCHSignature) - fatal(PrecompFile->getName() + " is not a precompiled headers object"); + if (!precompFile->pchSignature) + fatal(precompFile->getName() + " is not a precompiled headers object"); - if (Precomp.getSignature() != PrecompFile->PCHSignature.getValueOr(0)) + if (precomp.getSignature() != precompFile->pchSignature.getValueOr(0)) return createFileError( - Precomp.getPrecompFilePath().str(), + precomp.getPrecompFilePath().str(), make_error(pdb::pdb_error_code::signature_out_of_date)); - return IndexMap; + return indexMap; } -static bool remapTypeIndex(TypeIndex &TI, ArrayRef TypeIndexMap) { - if (TI.isSimple()) +static bool remapTypeIndex(TypeIndex &ti, ArrayRef typeIndexMap) { + if (ti.isSimple()) return true; - if (TI.toArrayIndex() >= TypeIndexMap.size()) + if (ti.toArrayIndex() >= typeIndexMap.size()) return false; - TI = TypeIndexMap[TI.toArrayIndex()]; + ti = typeIndexMap[ti.toArrayIndex()]; return true; } -static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind, - MutableArrayRef RecordBytes, - const CVIndexMap &IndexMap, - ArrayRef TypeRefs) { - MutableArrayRef Contents = - RecordBytes.drop_front(sizeof(RecordPrefix)); - for (const TiReference &Ref : TypeRefs) { - unsigned ByteSize = Ref.Count * sizeof(TypeIndex); - if (Contents.size() < Ref.Offset + ByteSize) +static void remapTypesInSymbolRecord(ObjFile *file, SymbolKind symKind, + MutableArrayRef recordBytes, + const CVIndexMap &indexMap, + ArrayRef typeRefs) { + MutableArrayRef contents = + recordBytes.drop_front(sizeof(RecordPrefix)); + for (const TiReference &ref : typeRefs) { + unsigned byteSize = ref.Count * sizeof(TypeIndex); + if (contents.size() < ref.Offset + byteSize) fatal("symbol record too short"); // This can be an item index or a type index. Choose the appropriate map. - ArrayRef TypeOrItemMap = IndexMap.TPIMap; - bool IsItemIndex = Ref.Kind == TiRefKind::IndexRef; - if (IsItemIndex && IndexMap.IsTypeServerMap) - TypeOrItemMap = IndexMap.IPIMap; - - MutableArrayRef TIs( - reinterpret_cast(Contents.data() + Ref.Offset), Ref.Count); - for (TypeIndex &TI : TIs) { - if (!remapTypeIndex(TI, TypeOrItemMap)) { - log("ignoring symbol record of kind 0x" + utohexstr(SymKind) + " in " + - File->getName() + " with bad " + (IsItemIndex ? "item" : "type") + - " index 0x" + utohexstr(TI.getIndex())); - TI = TypeIndex(SimpleTypeKind::NotTranslated); + ArrayRef typeOrItemMap = indexMap.tpiMap; + bool isItemIndex = ref.Kind == TiRefKind::IndexRef; + if (isItemIndex && indexMap.isTypeServerMap) + typeOrItemMap = indexMap.ipiMap; + + MutableArrayRef tIs( + reinterpret_cast(contents.data() + ref.Offset), ref.Count); + for (TypeIndex &ti : tIs) { + if (!remapTypeIndex(ti, typeOrItemMap)) { + log("ignoring symbol record of kind 0x" + utohexstr(symKind) + " in " + + file->getName() + " with bad " + (isItemIndex ? "item" : "type") + + " index 0x" + utohexstr(ti.getIndex())); + ti = TypeIndex(SimpleTypeKind::NotTranslated); continue; } } @@ -619,26 +619,26 @@ static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind, } static void -recordStringTableReferenceAtOffset(MutableArrayRef Contents, - uint32_t Offset, - std::vector &StrTableRefs) { - Contents = - Contents.drop_front(Offset).take_front(sizeof(support::ulittle32_t)); - ulittle32_t *Index = reinterpret_cast(Contents.data()); - StrTableRefs.push_back(Index); +recordStringTableReferenceAtOffset(MutableArrayRef contents, + uint32_t offset, + std::vector &strTableRefs) { + contents = + contents.drop_front(offset).take_front(sizeof(support::ulittle32_t)); + ulittle32_t *index = reinterpret_cast(contents.data()); + strTableRefs.push_back(index); } static void -recordStringTableReferences(SymbolKind Kind, MutableArrayRef Contents, - std::vector &StrTableRefs) { +recordStringTableReferences(SymbolKind kind, MutableArrayRef contents, + std::vector &strTableRefs) { // For now we only handle S_FILESTATIC, but we may need the same logic for // S_DEFRANGE and S_DEFRANGE_SUBFIELD. However, I cannot seem to generate any // PDBs that contain these types of records, so because of the uncertainty // they are omitted here until we can prove that it's necessary. - switch (Kind) { + switch (kind) { case SymbolKind::S_FILESTATIC: // FileStaticSym::ModFileOffset - recordStringTableReferenceAtOffset(Contents, 8, StrTableRefs); + recordStringTableReferenceAtOffset(contents, 8, strTableRefs); break; case SymbolKind::S_DEFRANGE: case SymbolKind::S_DEFRANGE_SUBFIELD: @@ -650,21 +650,21 @@ recordStringTableReferences(SymbolKind Kind, MutableArrayRef Contents, } } -static SymbolKind symbolKind(ArrayRef RecordData) { - const RecordPrefix *Prefix = - reinterpret_cast(RecordData.data()); - return static_cast(uint16_t(Prefix->RecordKind)); +static SymbolKind symbolKind(ArrayRef recordData) { + const RecordPrefix *prefix = + reinterpret_cast(recordData.data()); + return static_cast(uint16_t(prefix->RecordKind)); } /// MSVC translates S_PROC_ID_END to S_END, and S_[LG]PROC32_ID to S_[LG]PROC32 -static void translateIdSymbols(MutableArrayRef &RecordData, - TypeCollection &IDTable) { - RecordPrefix *Prefix = reinterpret_cast(RecordData.data()); +static void translateIdSymbols(MutableArrayRef &recordData, + TypeCollection &iDTable) { + RecordPrefix *prefix = reinterpret_cast(recordData.data()); - SymbolKind Kind = symbolKind(RecordData); + SymbolKind kind = symbolKind(recordData); - if (Kind == SymbolKind::S_PROC_ID_END) { - Prefix->RecordKind = SymbolKind::S_END; + if (kind == SymbolKind::S_PROC_ID_END) { + prefix->RecordKind = SymbolKind::S_END; return; } @@ -673,89 +673,89 @@ static void translateIdSymbols(MutableArrayRef &RecordData, // to the PDB file's ID stream index space, but we need to convert this to a // symbol that refers to the type stream index space. So we remap again from // ID index space to type index space. - if (Kind == SymbolKind::S_GPROC32_ID || Kind == SymbolKind::S_LPROC32_ID) { - SmallVector Refs; - auto Content = RecordData.drop_front(sizeof(RecordPrefix)); - CVSymbol Sym(RecordData); - discoverTypeIndicesInSymbol(Sym, Refs); - assert(Refs.size() == 1); - assert(Refs.front().Count == 1); - - TypeIndex *TI = - reinterpret_cast(Content.data() + Refs[0].Offset); + if (kind == SymbolKind::S_GPROC32_ID || kind == SymbolKind::S_LPROC32_ID) { + SmallVector refs; + auto content = recordData.drop_front(sizeof(RecordPrefix)); + CVSymbol sym(recordData); + discoverTypeIndicesInSymbol(sym, refs); + assert(refs.size() == 1); + assert(refs.front().Count == 1); + + TypeIndex *ti = + reinterpret_cast(content.data() + refs[0].Offset); // `TI` is the index of a FuncIdRecord or MemberFuncIdRecord which lives in // the IPI stream, whose `FunctionType` member refers to the TPI stream. // Note that LF_FUNC_ID and LF_MEMFUNC_ID have the same record layout, and // in both cases we just need the second type index. - if (!TI->isSimple() && !TI->isNoneType()) { - CVType FuncIdData = IDTable.getType(*TI); - SmallVector Indices; - discoverTypeIndices(FuncIdData, Indices); - assert(Indices.size() == 2); - *TI = Indices[1]; + if (!ti->isSimple() && !ti->isNoneType()) { + CVType funcIdData = iDTable.getType(*ti); + SmallVector indices; + discoverTypeIndices(funcIdData, indices); + assert(indices.size() == 2); + *ti = indices[1]; } - Kind = (Kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32 + kind = (kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32 : SymbolKind::S_LPROC32; - Prefix->RecordKind = uint16_t(Kind); + prefix->RecordKind = uint16_t(kind); } } /// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned. /// The object file may not be aligned. static MutableArrayRef -copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef &AlignedMem) { - size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb)); - assert(Size >= 4 && "record too short"); - assert(Size <= MaxRecordLength && "record too long"); - assert(AlignedMem.size() >= Size && "didn't preallocate enough"); +copyAndAlignSymbol(const CVSymbol &sym, MutableArrayRef &alignedMem) { + size_t size = alignTo(sym.length(), alignOf(CodeViewContainer::Pdb)); + assert(size >= 4 && "record too short"); + assert(size <= MaxRecordLength && "record too long"); + assert(alignedMem.size() >= size && "didn't preallocate enough"); // Copy the symbol record and zero out any padding bytes. - MutableArrayRef NewData = AlignedMem.take_front(Size); - AlignedMem = AlignedMem.drop_front(Size); - memcpy(NewData.data(), Sym.data().data(), Sym.length()); - memset(NewData.data() + Sym.length(), 0, Size - Sym.length()); + MutableArrayRef newData = alignedMem.take_front(size); + alignedMem = alignedMem.drop_front(size); + memcpy(newData.data(), sym.data().data(), sym.length()); + memset(newData.data() + sym.length(), 0, size - sym.length()); // Update the record prefix length. It should point to the beginning of the // next record. - auto *Prefix = reinterpret_cast(NewData.data()); - Prefix->RecordLen = Size - 2; - return NewData; + auto *prefix = reinterpret_cast(newData.data()); + prefix->RecordLen = size - 2; + return newData; } struct ScopeRecord { - ulittle32_t PtrParent; - ulittle32_t PtrEnd; + ulittle32_t ptrParent; + ulittle32_t ptrEnd; }; struct SymbolScope { - ScopeRecord *OpeningRecord; - uint32_t ScopeOffset; + ScopeRecord *openingRecord; + uint32_t scopeOffset; }; -static void scopeStackOpen(SmallVectorImpl &Stack, - uint32_t CurOffset, CVSymbol &Sym) { - assert(symbolOpensScope(Sym.kind())); - SymbolScope S; - S.ScopeOffset = CurOffset; - S.OpeningRecord = const_cast( - reinterpret_cast(Sym.content().data())); - S.OpeningRecord->PtrParent = Stack.empty() ? 0 : Stack.back().ScopeOffset; - Stack.push_back(S); +static void scopeStackOpen(SmallVectorImpl &stack, + uint32_t curOffset, CVSymbol &sym) { + assert(symbolOpensScope(sym.kind())); + SymbolScope s; + s.scopeOffset = curOffset; + s.openingRecord = const_cast( + reinterpret_cast(sym.content().data())); + s.openingRecord->ptrParent = stack.empty() ? 0 : stack.back().scopeOffset; + stack.push_back(s); } -static void scopeStackClose(SmallVectorImpl &Stack, - uint32_t CurOffset, InputFile *File) { - if (Stack.empty()) { - warn("symbol scopes are not balanced in " + File->getName()); +static void scopeStackClose(SmallVectorImpl &stack, + uint32_t curOffset, InputFile *file) { + if (stack.empty()) { + warn("symbol scopes are not balanced in " + file->getName()); return; } - SymbolScope S = Stack.pop_back_val(); - S.OpeningRecord->PtrEnd = CurOffset; + SymbolScope s = stack.pop_back_val(); + s.openingRecord->ptrEnd = curOffset; } -static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) { - switch (Sym.kind()) { +static bool symbolGoesInModuleStream(const CVSymbol &sym, bool isGlobalScope) { + switch (sym.kind()) { case SymbolKind::S_GDATA32: case SymbolKind::S_CONSTANT: // We really should not be seeing S_PROCREF and S_LPROCREF in the first place @@ -767,7 +767,7 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) { return false; // S_UDT records go in the module stream if it is not a global S_UDT. case SymbolKind::S_UDT: - return !IsGlobalScope; + return !isGlobalScope; // S_GDATA32 does not go in the module stream, but S_LDATA32 does. case SymbolKind::S_LDATA32: default: @@ -775,8 +775,8 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) { } } -static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) { - switch (Sym.kind()) { +static bool symbolGoesInGlobalsStream(const CVSymbol &sym, bool isGlobalScope) { + switch (sym.kind()) { case SymbolKind::S_CONSTANT: case SymbolKind::S_GDATA32: // S_LDATA32 goes in both the module stream and the globals stream. @@ -791,36 +791,36 @@ static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) { return true; // S_UDT records go in the globals stream if it is a global S_UDT. case SymbolKind::S_UDT: - return IsGlobalScope; + return isGlobalScope; default: return false; } } -static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex, - unsigned SymOffset, const CVSymbol &Sym) { - switch (Sym.kind()) { +static void addGlobalSymbol(pdb::GSIStreamBuilder &builder, uint16_t modIndex, + unsigned symOffset, const CVSymbol &sym) { + switch (sym.kind()) { case SymbolKind::S_CONSTANT: case SymbolKind::S_UDT: case SymbolKind::S_GDATA32: case SymbolKind::S_LDATA32: case SymbolKind::S_PROCREF: case SymbolKind::S_LPROCREF: - Builder.addGlobalSymbol(Sym); + builder.addGlobalSymbol(sym); break; case SymbolKind::S_GPROC32: case SymbolKind::S_LPROC32: { - SymbolRecordKind K = SymbolRecordKind::ProcRefSym; - if (Sym.kind() == SymbolKind::S_LPROC32) - K = SymbolRecordKind::LocalProcRef; - ProcRefSym PS(K); - PS.Module = ModIndex; + SymbolRecordKind k = SymbolRecordKind::ProcRefSym; + if (sym.kind() == SymbolKind::S_LPROC32) + k = SymbolRecordKind::LocalProcRef; + ProcRefSym ps(k); + ps.Module = modIndex; // For some reason, MSVC seems to add one to this value. - ++PS.Module; - PS.Name = getSymbolName(Sym); - PS.SumName = 0; - PS.SymOffset = SymOffset; - Builder.addGlobalSymbol(PS); + ++ps.Module; + ps.Name = getSymbolName(sym); + ps.SumName = 0; + ps.SymOffset = symOffset; + builder.addGlobalSymbol(ps); break; } default: @@ -828,219 +828,219 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex, } } -void PDBLinker::mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap, - std::vector &StringTableRefs, - BinaryStreamRef SymData) { - ArrayRef SymsBuffer; - cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer)); - SmallVector Scopes; +void PDBLinker::mergeSymbolRecords(ObjFile *file, const CVIndexMap &indexMap, + std::vector &stringTableRefs, + BinaryStreamRef symData) { + ArrayRef symsBuffer; + cantFail(symData.readBytes(0, symData.getLength(), symsBuffer)); + SmallVector scopes; // Iterate every symbol to check if any need to be realigned, and if so, how // much space we need to allocate for them. - bool NeedsRealignment = false; - unsigned TotalRealignedSize = 0; - auto EC = forEachCodeViewRecord( - SymsBuffer, [&](CVSymbol Sym) -> llvm::Error { - unsigned RealignedSize = - alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb)); - NeedsRealignment |= RealignedSize != Sym.length(); - TotalRealignedSize += RealignedSize; + bool needsRealignment = false; + unsigned totalRealignedSize = 0; + auto ec = forEachCodeViewRecord( + symsBuffer, [&](CVSymbol sym) -> llvm::Error { + unsigned realignedSize = + alignTo(sym.length(), alignOf(CodeViewContainer::Pdb)); + needsRealignment |= realignedSize != sym.length(); + totalRealignedSize += realignedSize; return Error::success(); }); // If any of the symbol record lengths was corrupt, ignore them all, warn // about it, and move on. - if (EC) { - warn("corrupt symbol records in " + File->getName()); - consumeError(std::move(EC)); + if (ec) { + warn("corrupt symbol records in " + file->getName()); + consumeError(std::move(ec)); return; } // If any symbol needed realignment, allocate enough contiguous memory for // them all. Typically symbol subsections are small enough that this will not // cause fragmentation. - MutableArrayRef AlignedSymbolMem; - if (NeedsRealignment) { - void *AlignedData = - Alloc.Allocate(TotalRealignedSize, alignOf(CodeViewContainer::Pdb)); - AlignedSymbolMem = makeMutableArrayRef( - reinterpret_cast(AlignedData), TotalRealignedSize); + MutableArrayRef alignedSymbolMem; + if (needsRealignment) { + void *alignedData = + alloc.Allocate(totalRealignedSize, alignOf(CodeViewContainer::Pdb)); + alignedSymbolMem = makeMutableArrayRef( + reinterpret_cast(alignedData), totalRealignedSize); } // Iterate again, this time doing the real work. - unsigned CurSymOffset = File->ModuleDBI->getNextSymbolOffset(); - ArrayRef BulkSymbols; + unsigned curSymOffset = file->moduleDBI->getNextSymbolOffset(); + ArrayRef bulkSymbols; cantFail(forEachCodeViewRecord( - SymsBuffer, [&](CVSymbol Sym) -> llvm::Error { + symsBuffer, [&](CVSymbol sym) -> llvm::Error { // Align the record if required. - MutableArrayRef RecordBytes; - if (NeedsRealignment) { - RecordBytes = copyAndAlignSymbol(Sym, AlignedSymbolMem); - Sym = CVSymbol(RecordBytes); + MutableArrayRef recordBytes; + if (needsRealignment) { + recordBytes = copyAndAlignSymbol(sym, alignedSymbolMem); + sym = CVSymbol(recordBytes); } else { // Otherwise, we can actually mutate the symbol directly, since we // copied it to apply relocations. - RecordBytes = makeMutableArrayRef( - const_cast(Sym.data().data()), Sym.length()); + recordBytes = makeMutableArrayRef( + const_cast(sym.data().data()), sym.length()); } // Discover type index references in the record. Skip it if we don't // know where they are. - SmallVector TypeRefs; - if (!discoverTypeIndicesInSymbol(Sym, TypeRefs)) { + SmallVector typeRefs; + if (!discoverTypeIndicesInSymbol(sym, typeRefs)) { log("ignoring unknown symbol record with kind 0x" + - utohexstr(Sym.kind())); + utohexstr(sym.kind())); return Error::success(); } // Re-map all the type index references. - remapTypesInSymbolRecord(File, Sym.kind(), RecordBytes, IndexMap, - TypeRefs); + remapTypesInSymbolRecord(file, sym.kind(), recordBytes, indexMap, + typeRefs); // An object file may have S_xxx_ID symbols, but these get converted to // "real" symbols in a PDB. - translateIdSymbols(RecordBytes, TMerger.getIDTable()); - Sym = CVSymbol(RecordBytes); + translateIdSymbols(recordBytes, tMerger.getIDTable()); + sym = CVSymbol(recordBytes); // If this record refers to an offset in the object file's string table, // add that item to the global PDB string table and re-write the index. - recordStringTableReferences(Sym.kind(), RecordBytes, StringTableRefs); + recordStringTableReferences(sym.kind(), recordBytes, stringTableRefs); // Fill in "Parent" and "End" fields by maintaining a stack of scopes. - if (symbolOpensScope(Sym.kind())) - scopeStackOpen(Scopes, CurSymOffset, Sym); - else if (symbolEndsScope(Sym.kind())) - scopeStackClose(Scopes, CurSymOffset, File); + if (symbolOpensScope(sym.kind())) + scopeStackOpen(scopes, curSymOffset, sym); + else if (symbolEndsScope(sym.kind())) + scopeStackClose(scopes, curSymOffset, file); // Add the symbol to the globals stream if necessary. Do this before // adding the symbol to the module since we may need to get the next // symbol offset, and writing to the module's symbol stream will update // that offset. - if (symbolGoesInGlobalsStream(Sym, Scopes.empty())) { - addGlobalSymbol(Builder.getGsiBuilder(), - File->ModuleDBI->getModuleIndex(), CurSymOffset, Sym); - ++GlobalSymbols; + if (symbolGoesInGlobalsStream(sym, scopes.empty())) { + addGlobalSymbol(builder.getGsiBuilder(), + file->moduleDBI->getModuleIndex(), curSymOffset, sym); + ++globalSymbols; } - if (symbolGoesInModuleStream(Sym, Scopes.empty())) { + if (symbolGoesInModuleStream(sym, scopes.empty())) { // Add symbols to the module in bulk. If this symbol is contiguous // with the previous run of symbols to add, combine the ranges. If // not, close the previous range of symbols and start a new one. - if (Sym.data().data() == BulkSymbols.end()) { - BulkSymbols = makeArrayRef(BulkSymbols.data(), - BulkSymbols.size() + Sym.length()); + if (sym.data().data() == bulkSymbols.end()) { + bulkSymbols = makeArrayRef(bulkSymbols.data(), + bulkSymbols.size() + sym.length()); } else { - File->ModuleDBI->addSymbolsInBulk(BulkSymbols); - BulkSymbols = RecordBytes; + file->moduleDBI->addSymbolsInBulk(bulkSymbols); + bulkSymbols = recordBytes; } - CurSymOffset += Sym.length(); - ++ModuleSymbols; + curSymOffset += sym.length(); + ++moduleSymbols; } return Error::success(); })); // Add any remaining symbols we've accumulated. - File->ModuleDBI->addSymbolsInBulk(BulkSymbols); + file->moduleDBI->addSymbolsInBulk(bulkSymbols); } // Allocate memory for a .debug$S / .debug$F section and relocate it. -static ArrayRef relocateDebugChunk(BumpPtrAllocator &Alloc, - SectionChunk &DebugChunk) { - uint8_t *Buffer = Alloc.Allocate(DebugChunk.getSize()); - assert(DebugChunk.getOutputSectionIdx() == 0 && +static ArrayRef relocateDebugChunk(BumpPtrAllocator &alloc, + SectionChunk &debugChunk) { + uint8_t *buffer = alloc.Allocate(debugChunk.getSize()); + assert(debugChunk.getOutputSectionIdx() == 0 && "debug sections should not be in output sections"); - DebugChunk.writeTo(Buffer); - return makeArrayRef(Buffer, DebugChunk.getSize()); + debugChunk.writeTo(buffer); + return makeArrayRef(buffer, debugChunk.getSize()); } -static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) { - OutputSection *OS = C ? C->getOutputSection() : nullptr; - pdb::SectionContrib SC; - memset(&SC, 0, sizeof(SC)); - SC.ISect = OS ? OS->SectionIndex : llvm::pdb::kInvalidStreamIndex; - SC.Off = C && OS ? C->getRVA() - OS->getRVA() : 0; - SC.Size = C ? C->getSize() : -1; - if (auto *SecChunk = dyn_cast_or_null(C)) { - SC.Characteristics = SecChunk->Header->Characteristics; - SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); - ArrayRef Contents = SecChunk->getContents(); - JamCRC CRC(0); - ArrayRef CharContents = makeArrayRef( - reinterpret_cast(Contents.data()), Contents.size()); - CRC.update(CharContents); - SC.DataCrc = CRC.getCRC(); +static pdb::SectionContrib createSectionContrib(const Chunk *c, uint32_t modi) { + OutputSection *os = c ? c->getOutputSection() : nullptr; + pdb::SectionContrib sc; + memset(&sc, 0, sizeof(sc)); + sc.ISect = os ? os->sectionIndex : llvm::pdb::kInvalidStreamIndex; + sc.Off = c && os ? c->getRVA() - os->getRVA() : 0; + sc.Size = c ? c->getSize() : -1; + if (auto *secChunk = dyn_cast_or_null(c)) { + sc.Characteristics = secChunk->header->Characteristics; + sc.Imod = secChunk->file->moduleDBI->getModuleIndex(); + ArrayRef contents = secChunk->getContents(); + JamCRC crc(0); + ArrayRef charContents = makeArrayRef( + reinterpret_cast(contents.data()), contents.size()); + crc.update(charContents); + sc.DataCrc = crc.getCRC(); } else { - SC.Characteristics = OS ? OS->Header.Characteristics : 0; - SC.Imod = Modi; + sc.Characteristics = os ? os->header.Characteristics : 0; + sc.Imod = modi; } - SC.RelocCrc = 0; // FIXME + sc.RelocCrc = 0; // FIXME - return SC; + return sc; } static uint32_t -translateStringTableIndex(uint32_t ObjIndex, - const DebugStringTableSubsectionRef &ObjStrTable, - DebugStringTableSubsection &PdbStrTable) { - auto ExpectedString = ObjStrTable.getString(ObjIndex); - if (!ExpectedString) { +translateStringTableIndex(uint32_t objIndex, + const DebugStringTableSubsectionRef &objStrTable, + DebugStringTableSubsection &pdbStrTable) { + auto expectedString = objStrTable.getString(objIndex); + if (!expectedString) { warn("Invalid string table reference"); - consumeError(ExpectedString.takeError()); + consumeError(expectedString.takeError()); return 0; } - return PdbStrTable.insert(*ExpectedString); + return pdbStrTable.insert(*expectedString); } -void DebugSHandler::handleDebugS(lld::coff::SectionChunk &DebugS) { - DebugSubsectionArray Subsections; +void DebugSHandler::handleDebugS(lld::coff::SectionChunk &debugS) { + DebugSubsectionArray subsections; - ArrayRef RelocatedDebugContents = SectionChunk::consumeDebugMagic( - relocateDebugChunk(Linker.Alloc, DebugS), DebugS.getSectionName()); + ArrayRef relocatedDebugContents = SectionChunk::consumeDebugMagic( + relocateDebugChunk(linker.alloc, debugS), debugS.getSectionName()); - BinaryStreamReader Reader(RelocatedDebugContents, support::little); - ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); + BinaryStreamReader reader(relocatedDebugContents, support::little); + exitOnErr(reader.readArray(subsections, relocatedDebugContents.size())); - for (const DebugSubsectionRecord &SS : Subsections) { + for (const DebugSubsectionRecord &ss : subsections) { // Ignore subsections with the 'ignore' bit. Some versions of the Visual C++ // runtime have subsections with this bit set. - if (uint32_t(SS.kind()) & codeview::SubsectionIgnoreFlag) + if (uint32_t(ss.kind()) & codeview::SubsectionIgnoreFlag) continue; - switch (SS.kind()) { + switch (ss.kind()) { case DebugSubsectionKind::StringTable: { - assert(!CVStrTab.valid() && + assert(!cVStrTab.valid() && "Encountered multiple string table subsections!"); - ExitOnErr(CVStrTab.initialize(SS.getRecordData())); + exitOnErr(cVStrTab.initialize(ss.getRecordData())); break; } case DebugSubsectionKind::FileChecksums: - assert(!Checksums.valid() && + assert(!checksums.valid() && "Encountered multiple checksum subsections!"); - ExitOnErr(Checksums.initialize(SS.getRecordData())); + exitOnErr(checksums.initialize(ss.getRecordData())); break; case DebugSubsectionKind::Lines: // We can add the relocated line table directly to the PDB without // modification because the file checksum offsets will stay the same. - File.ModuleDBI->addDebugSubsection(SS); + file.moduleDBI->addDebugSubsection(ss); break; case DebugSubsectionKind::InlineeLines: - assert(!InlineeLines.valid() && + assert(!inlineeLines.valid() && "Encountered multiple inlinee lines subsections!"); - ExitOnErr(InlineeLines.initialize(SS.getRecordData())); + exitOnErr(inlineeLines.initialize(ss.getRecordData())); break; case DebugSubsectionKind::FrameData: { // We need to re-write string table indices here, so save off all // frame data subsections until we've processed the entire list of // subsections so that we can be sure we have the string table. - DebugFrameDataSubsectionRef FDS; - ExitOnErr(FDS.initialize(SS.getRecordData())); - NewFpoFrames.push_back(std::move(FDS)); + DebugFrameDataSubsectionRef fds; + exitOnErr(fds.initialize(ss.getRecordData())); + newFpoFrames.push_back(std::move(fds)); break; } case DebugSubsectionKind::Symbols: { - Linker.mergeSymbolRecords(&File, IndexMap, StringTableReferences, - SS.getRecordData()); + linker.mergeSymbolRecords(&file, indexMap, stringTableReferences, + ss.getRecordData()); break; } @@ -1063,69 +1063,69 @@ void DebugSHandler::handleDebugS(lld::coff::SectionChunk &DebugS) { default: warn("ignoring unknown debug$S subsection kind 0x" + - utohexstr(uint32_t(SS.kind())) + " in file " + toString(&File)); + utohexstr(uint32_t(ss.kind())) + " in file " + toString(&file)); break; } } } static Expected -getFileName(const DebugStringTableSubsectionRef &Strings, - const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { - auto Iter = Checksums.getArray().at(FileID); - if (Iter == Checksums.getArray().end()) +getFileName(const DebugStringTableSubsectionRef &strings, + const DebugChecksumsSubsectionRef &checksums, uint32_t fileID) { + auto iter = checksums.getArray().at(fileID); + if (iter == checksums.getArray().end()) return make_error(cv_error_code::no_records); - uint32_t Offset = Iter->FileNameOffset; - return Strings.getString(Offset); + uint32_t offset = iter->FileNameOffset; + return strings.getString(offset); } std::shared_ptr -DebugSHandler::mergeInlineeLines(DebugChecksumsSubsection *NewChecksums) { - auto NewInlineeLines = std::make_shared( - *NewChecksums, InlineeLines.hasExtraFiles()); - - for (const InlineeSourceLine &Line : InlineeLines) { - TypeIndex Inlinee = Line.Header->Inlinee; - uint32_t FileID = Line.Header->FileID; - uint32_t SourceLine = Line.Header->SourceLineNum; - - ArrayRef TypeOrItemMap = - IndexMap.IsTypeServerMap ? IndexMap.IPIMap : IndexMap.TPIMap; - if (!remapTypeIndex(Inlinee, TypeOrItemMap)) { - log("ignoring inlinee line record in " + File.getName() + - " with bad inlinee index 0x" + utohexstr(Inlinee.getIndex())); +DebugSHandler::mergeInlineeLines(DebugChecksumsSubsection *newChecksums) { + auto newInlineeLines = std::make_shared( + *newChecksums, inlineeLines.hasExtraFiles()); + + for (const InlineeSourceLine &line : inlineeLines) { + TypeIndex inlinee = line.Header->Inlinee; + uint32_t fileID = line.Header->FileID; + uint32_t sourceLine = line.Header->SourceLineNum; + + ArrayRef typeOrItemMap = + indexMap.isTypeServerMap ? indexMap.ipiMap : indexMap.tpiMap; + if (!remapTypeIndex(inlinee, typeOrItemMap)) { + log("ignoring inlinee line record in " + file.getName() + + " with bad inlinee index 0x" + utohexstr(inlinee.getIndex())); continue; } - SmallString<128> Filename = - ExitOnErr(getFileName(CVStrTab, Checksums, FileID)); - pdbMakeAbsolute(Filename); - NewInlineeLines->addInlineSite(Inlinee, Filename, SourceLine); + SmallString<128> filename = + exitOnErr(getFileName(cVStrTab, checksums, fileID)); + pdbMakeAbsolute(filename); + newInlineeLines->addInlineSite(inlinee, filename, sourceLine); - if (InlineeLines.hasExtraFiles()) { - for (uint32_t ExtraFileId : Line.ExtraFiles) { - Filename = ExitOnErr(getFileName(CVStrTab, Checksums, ExtraFileId)); - pdbMakeAbsolute(Filename); - NewInlineeLines->addExtraFile(Filename); + if (inlineeLines.hasExtraFiles()) { + for (uint32_t extraFileId : line.ExtraFiles) { + filename = exitOnErr(getFileName(cVStrTab, checksums, extraFileId)); + pdbMakeAbsolute(filename); + newInlineeLines->addExtraFile(filename); } } } - return NewInlineeLines; + return newInlineeLines; } void DebugSHandler::finish() { - pdb::DbiStreamBuilder &DbiBuilder = Linker.Builder.getDbiBuilder(); + pdb::DbiStreamBuilder &dbiBuilder = linker.builder.getDbiBuilder(); // We should have seen all debug subsections across the entire object file now // which means that if a StringTable subsection and Checksums subsection were // present, now is the time to handle them. - if (!CVStrTab.valid()) { - if (Checksums.valid()) + if (!cVStrTab.valid()) { + if (checksums.valid()) fatal(".debug$S sections with a checksums subsection must also contain a " "string table subsection"); - if (!StringTableReferences.empty()) + if (!stringTableReferences.empty()) warn("No StringTable subsection was encountered, but there are string " "table references"); return; @@ -1133,231 +1133,231 @@ void DebugSHandler::finish() { // Rewrite string table indices in the Fpo Data and symbol records to refer to // the global PDB string table instead of the object file string table. - for (DebugFrameDataSubsectionRef &FDS : NewFpoFrames) { - const ulittle32_t *Reloc = FDS.getRelocPtr(); - for (codeview::FrameData FD : FDS) { - FD.RvaStart += *Reloc; - FD.FrameFunc = - translateStringTableIndex(FD.FrameFunc, CVStrTab, Linker.PDBStrTab); - DbiBuilder.addNewFpoData(FD); + for (DebugFrameDataSubsectionRef &fds : newFpoFrames) { + const ulittle32_t *reloc = fds.getRelocPtr(); + for (codeview::FrameData fd : fds) { + fd.RvaStart += *reloc; + fd.FrameFunc = + translateStringTableIndex(fd.FrameFunc, cVStrTab, linker.pdbStrTab); + dbiBuilder.addNewFpoData(fd); } } - for (ulittle32_t *Ref : StringTableReferences) - *Ref = translateStringTableIndex(*Ref, CVStrTab, Linker.PDBStrTab); + for (ulittle32_t *ref : stringTableReferences) + *ref = translateStringTableIndex(*ref, cVStrTab, linker.pdbStrTab); // Make a new file checksum table that refers to offsets in the PDB-wide // string table. Generally the string table subsection appears after the // checksum table, so we have to do this after looping over all the // subsections. - auto NewChecksums = make_unique(Linker.PDBStrTab); - for (FileChecksumEntry &FC : Checksums) { - SmallString<128> Filename = - ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); - pdbMakeAbsolute(Filename); - ExitOnErr(DbiBuilder.addModuleSourceFile(*File.ModuleDBI, Filename)); - NewChecksums->addChecksum(Filename, FC.Kind, FC.Checksum); + auto newChecksums = make_unique(linker.pdbStrTab); + for (FileChecksumEntry &fc : checksums) { + SmallString<128> filename = + exitOnErr(cVStrTab.getString(fc.FileNameOffset)); + pdbMakeAbsolute(filename); + exitOnErr(dbiBuilder.addModuleSourceFile(*file.moduleDBI, filename)); + newChecksums->addChecksum(filename, fc.Kind, fc.Checksum); } // Rewrite inlinee item indices if present. - if (InlineeLines.valid()) - File.ModuleDBI->addDebugSubsection(mergeInlineeLines(NewChecksums.get())); + if (inlineeLines.valid()) + file.moduleDBI->addDebugSubsection(mergeInlineeLines(newChecksums.get())); - File.ModuleDBI->addDebugSubsection(std::move(NewChecksums)); + file.moduleDBI->addDebugSubsection(std::move(newChecksums)); } -void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { - if (File->MergedIntoPDB) +void PDBLinker::addObjFile(ObjFile *file, CVIndexMap *externIndexMap) { + if (file->mergedIntoPDB) return; - File->MergedIntoPDB = true; + file->mergedIntoPDB = true; // Before we can process symbol substreams from .debug$S, we need to process // type information, file checksums, and the string table. Add type info to // the PDB first, so that we can get the map from object file type and item // indices to PDB type and item indices. - CVIndexMap ObjectIndexMap; - auto IndexMapResult = - mergeDebugT(File, ExternIndexMap ? ExternIndexMap : &ObjectIndexMap); + CVIndexMap objectIndexMap; + auto indexMapResult = + mergeDebugT(file, externIndexMap ? externIndexMap : &objectIndexMap); // If the .debug$T sections fail to merge, assume there is no debug info. - if (!IndexMapResult) { - if (!Config->WarnDebugInfoUnusable) { - consumeError(IndexMapResult.takeError()); + if (!indexMapResult) { + if (!config->warnDebugInfoUnusable) { + consumeError(indexMapResult.takeError()); return; } - warn("Cannot use debug info for '" + toString(File) + "' [LNK4099]\n" + + warn("Cannot use debug info for '" + toString(file) + "' [LNK4099]\n" + ">>> failed to load reference " + - StringRef(toString(IndexMapResult.takeError()))); + StringRef(toString(indexMapResult.takeError()))); return; } - ScopedTimer T(SymbolMergingTimer); + ScopedTimer t(symbolMergingTimer); - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - DebugSHandler DSH(*this, *File, *IndexMapResult); + pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder(); + DebugSHandler dsh(*this, *file, *indexMapResult); // Now do all live .debug$S and .debug$F sections. - for (SectionChunk *DebugChunk : File->getDebugChunks()) { - if (!DebugChunk->Live || DebugChunk->getSize() == 0) + for (SectionChunk *debugChunk : file->getDebugChunks()) { + if (!debugChunk->live || debugChunk->getSize() == 0) continue; - if (DebugChunk->getSectionName() == ".debug$S") { - DSH.handleDebugS(*DebugChunk); + if (debugChunk->getSectionName() == ".debug$S") { + dsh.handleDebugS(*debugChunk); continue; } - if (DebugChunk->getSectionName() == ".debug$F") { - ArrayRef RelocatedDebugContents = - relocateDebugChunk(Alloc, *DebugChunk); + if (debugChunk->getSectionName() == ".debug$F") { + ArrayRef relocatedDebugContents = + relocateDebugChunk(alloc, *debugChunk); - FixedStreamArray FpoRecords; - BinaryStreamReader Reader(RelocatedDebugContents, support::little); - uint32_t Count = RelocatedDebugContents.size() / sizeof(object::FpoData); - ExitOnErr(Reader.readArray(FpoRecords, Count)); + FixedStreamArray fpoRecords; + BinaryStreamReader reader(relocatedDebugContents, support::little); + uint32_t count = relocatedDebugContents.size() / sizeof(object::FpoData); + exitOnErr(reader.readArray(fpoRecords, count)); // These are already relocated and don't refer to the string table, so we // can just copy it. - for (const object::FpoData &FD : FpoRecords) - DbiBuilder.addOldFpoData(FD); + for (const object::FpoData &fd : fpoRecords) + dbiBuilder.addOldFpoData(fd); continue; } } // Do any post-processing now that all .debug$S sections have been processed. - DSH.finish(); + dsh.finish(); } // Add a module descriptor for every object file. We need to put an absolute // path to the object into the PDB. If this is a plain object, we make its // path absolute. If it's an object in an archive, we make the archive path // absolute. -static void createModuleDBI(pdb::PDBFileBuilder &Builder) { - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - SmallString<128> ObjName; +static void createModuleDBI(pdb::PDBFileBuilder &builder) { + pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder(); + SmallString<128> objName; - for (ObjFile *File : ObjFile::Instances) { + for (ObjFile *file : ObjFile::instances) { - bool InArchive = !File->ParentName.empty(); - ObjName = InArchive ? File->ParentName : File->getName(); - pdbMakeAbsolute(ObjName); - StringRef ModName = InArchive ? File->getName() : StringRef(ObjName); + bool inArchive = !file->parentName.empty(); + objName = inArchive ? file->parentName : file->getName(); + pdbMakeAbsolute(objName); + StringRef modName = inArchive ? file->getName() : StringRef(objName); - File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(ModName)); - File->ModuleDBI->setObjFileName(ObjName); + file->moduleDBI = &exitOnErr(dbiBuilder.addModuleInfo(modName)); + file->moduleDBI->setObjFileName(objName); - ArrayRef Chunks = File->getChunks(); - uint32_t Modi = File->ModuleDBI->getModuleIndex(); + ArrayRef chunks = file->getChunks(); + uint32_t modi = file->moduleDBI->getModuleIndex(); - for (Chunk *C : Chunks) { - auto *SecChunk = dyn_cast(C); - if (!SecChunk || !SecChunk->Live) + for (Chunk *c : chunks) { + auto *secChunk = dyn_cast(c); + if (!secChunk || !secChunk->live) continue; - pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi); - File->ModuleDBI->setFirstSectionContrib(SC); + pdb::SectionContrib sc = createSectionContrib(secChunk, modi); + file->moduleDBI->setFirstSectionContrib(sc); break; } } } -static PublicSym32 createPublic(Defined *Def) { - PublicSym32 Pub(SymbolKind::S_PUB32); - Pub.Name = Def->getName(); - if (auto *D = dyn_cast(Def)) { - if (D->getCOFFSymbol().isFunctionDefinition()) - Pub.Flags = PublicSymFlags::Function; - } else if (isa(Def)) { - Pub.Flags = PublicSymFlags::Function; +static PublicSym32 createPublic(Defined *def) { + PublicSym32 pub(SymbolKind::S_PUB32); + pub.Name = def->getName(); + if (auto *d = dyn_cast(def)) { + if (d->getCOFFSymbol().isFunctionDefinition()) + pub.Flags = PublicSymFlags::Function; + } else if (isa(def)) { + pub.Flags = PublicSymFlags::Function; } - OutputSection *OS = Def->getChunk()->getOutputSection(); - assert(OS && "all publics should be in final image"); - Pub.Offset = Def->getRVA() - OS->getRVA(); - Pub.Segment = OS->SectionIndex; - return Pub; + OutputSection *os = def->getChunk()->getOutputSection(); + assert(os && "all publics should be in final image"); + pub.Offset = def->getRVA() - os->getRVA(); + pub.Segment = os->sectionIndex; + return pub; } // Add all object files to the PDB. Merge .debug$T sections into IpiData and // TpiData. void PDBLinker::addObjectsToPDB() { - ScopedTimer T1(AddObjectsTimer); + ScopedTimer t1(addObjectsTimer); - createModuleDBI(Builder); + createModuleDBI(builder); - for (ObjFile *File : ObjFile::Instances) - addObjFile(File); + for (ObjFile *file : ObjFile::instances) + addObjFile(file); - Builder.getStringTableBuilder().setStrings(PDBStrTab); - T1.stop(); + builder.getStringTableBuilder().setStrings(pdbStrTab); + t1.stop(); // Construct TPI and IPI stream contents. - ScopedTimer T2(TpiStreamLayoutTimer); - addTypeInfo(Builder.getTpiBuilder(), TMerger.getTypeTable()); - addTypeInfo(Builder.getIpiBuilder(), TMerger.getIDTable()); - T2.stop(); + ScopedTimer t2(tpiStreamLayoutTimer); + addTypeInfo(builder.getTpiBuilder(), tMerger.getTypeTable()); + addTypeInfo(builder.getIpiBuilder(), tMerger.getIDTable()); + t2.stop(); - ScopedTimer T3(GlobalsLayoutTimer); + ScopedTimer t3(globalsLayoutTimer); // Compute the public and global symbols. - auto &GsiBuilder = Builder.getGsiBuilder(); - std::vector Publics; - Symtab->forEachSymbol([&Publics](Symbol *S) { + auto &gsiBuilder = builder.getGsiBuilder(); + std::vector publics; + symtab->forEachSymbol([&publics](Symbol *s) { // Only emit defined, live symbols that have a chunk. - auto *Def = dyn_cast(S); - if (Def && Def->isLive() && Def->getChunk()) - Publics.push_back(createPublic(Def)); + auto *def = dyn_cast(s); + if (def && def->isLive() && def->getChunk()) + publics.push_back(createPublic(def)); }); - if (!Publics.empty()) { - PublicSymbols = Publics.size(); + if (!publics.empty()) { + publicSymbols = publics.size(); // Sort the public symbols and add them to the stream. - parallelSort(Publics, [](const PublicSym32 &L, const PublicSym32 &R) { - return L.Name < R.Name; + parallelSort(publics, [](const PublicSym32 &l, const PublicSym32 &r) { + return l.Name < r.Name; }); - for (const PublicSym32 &Pub : Publics) - GsiBuilder.addPublicSymbol(Pub); + for (const PublicSym32 &pub : publics) + gsiBuilder.addPublicSymbol(pub); } } void PDBLinker::printStats() { - if (!Config->ShowSummary) + if (!config->showSummary) return; - SmallString<256> Buffer; - raw_svector_ostream Stream(Buffer); + SmallString<256> buffer; + raw_svector_ostream stream(buffer); - Stream << center_justify("Summary", 80) << '\n' + stream << center_justify("Summary", 80) << '\n' << std::string(80, '-') << '\n'; - auto Print = [&](uint64_t V, StringRef S) { - Stream << format_decimal(V, 15) << " " << S << '\n'; + auto print = [&](uint64_t v, StringRef s) { + stream << format_decimal(v, 15) << " " << s << '\n'; }; - Print(ObjFile::Instances.size(), + print(ObjFile::instances.size(), "Input OBJ files (expanded from all cmd-line inputs)"); - Print(TypeServerIndexMappings.size(), "PDB type server dependencies"); - Print(PrecompTypeIndexMappings.size(), "Precomp OBJ dependencies"); - Print(TMerger.getTypeTable().size() + TMerger.getIDTable().size(), + print(typeServerIndexMappings.size(), "PDB type server dependencies"); + print(precompTypeIndexMappings.size(), "Precomp OBJ dependencies"); + print(tMerger.getTypeTable().size() + tMerger.getIDTable().size(), "Merged TPI records"); - Print(PDBStrTab.size(), "Output PDB strings"); - Print(GlobalSymbols, "Global symbol records"); - Print(ModuleSymbols, "Module symbol records"); - Print(PublicSymbols, "Public symbol records"); + print(pdbStrTab.size(), "Output PDB strings"); + print(globalSymbols, "Global symbol records"); + print(moduleSymbols, "Module symbol records"); + print(publicSymbols, "Public symbol records"); - message(Buffer); + message(buffer); } void PDBLinker::addNatvisFiles() { - for (StringRef File : Config->NatvisFiles) { - ErrorOr> DataOrErr = - MemoryBuffer::getFile(File); - if (!DataOrErr) { - warn("Cannot open input file: " + File); + for (StringRef file : config->natvisFiles) { + ErrorOr> dataOrErr = + MemoryBuffer::getFile(file); + if (!dataOrErr) { + warn("Cannot open input file: " + file); continue; } - Builder.addInjectedSource(File, std::move(*DataOrErr)); + builder.addInjectedSource(file, std::move(*dataOrErr)); } } -static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) { - switch (Machine) { +static codeview::CPUType toCodeViewMachine(COFF::MachineTypes machine) { + switch (machine) { case COFF::IMAGE_FILE_MACHINE_AMD64: return codeview::CPUType::X64; case COFF::IMAGE_FILE_MACHINE_ARM: @@ -1376,329 +1376,329 @@ static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) { // Mimic MSVC which surrounds arguments containing whitespace with quotes. // Double double-quotes are handled, so that the resulting string can be // executed again on the cmd-line. -static std::string quote(ArrayRef Args) { - std::string R; - R.reserve(256); - for (StringRef A : Args) { - if (!R.empty()) - R.push_back(' '); - bool HasWS = A.find(' ') != StringRef::npos; - bool HasQ = A.find('"') != StringRef::npos; - if (HasWS || HasQ) - R.push_back('"'); - if (HasQ) { - SmallVector S; - A.split(S, '"'); - R.append(join(S, "\"\"")); +static std::string quote(ArrayRef args) { + std::string r; + r.reserve(256); + for (StringRef a : args) { + if (!r.empty()) + r.push_back(' '); + bool hasWS = a.find(' ') != StringRef::npos; + bool hasQ = a.find('"') != StringRef::npos; + if (hasWS || hasQ) + r.push_back('"'); + if (hasQ) { + SmallVector s; + a.split(s, '"'); + r.append(join(s, "\"\"")); } else { - R.append(A); + r.append(a); } - if (HasWS || HasQ) - R.push_back('"'); + if (hasWS || hasQ) + r.push_back('"'); } - return R; + return r; } -static void fillLinkerVerRecord(Compile3Sym &CS) { - CS.Machine = toCodeViewMachine(Config->Machine); +static void fillLinkerVerRecord(Compile3Sym &cs) { + cs.Machine = toCodeViewMachine(config->machine); // Interestingly, if we set the string to 0.0.0.0, then when trying to view // local variables WinDbg emits an error that private symbols are not present. // By setting this to a valid MSVC linker version string, local variables are // displayed properly. As such, even though it is not representative of // LLVM's version information, we need this for compatibility. - CS.Flags = CompileSym3Flags::None; - CS.VersionBackendBuild = 25019; - CS.VersionBackendMajor = 14; - CS.VersionBackendMinor = 10; - CS.VersionBackendQFE = 0; + cs.Flags = CompileSym3Flags::None; + cs.VersionBackendBuild = 25019; + cs.VersionBackendMajor = 14; + cs.VersionBackendMinor = 10; + cs.VersionBackendQFE = 0; // MSVC also sets the frontend to 0.0.0.0 since this is specifically for the // linker module (which is by definition a backend), so we don't need to do // anything here. Also, it seems we can use "LLVM Linker" for the linker name // without any problems. Only the backend version has to be hardcoded to a // magic number. - CS.VersionFrontendBuild = 0; - CS.VersionFrontendMajor = 0; - CS.VersionFrontendMinor = 0; - CS.VersionFrontendQFE = 0; - CS.Version = "LLVM Linker"; - CS.setLanguage(SourceLanguage::Link); + cs.VersionFrontendBuild = 0; + cs.VersionFrontendMajor = 0; + cs.VersionFrontendMinor = 0; + cs.VersionFrontendQFE = 0; + cs.Version = "LLVM Linker"; + cs.setLanguage(SourceLanguage::Link); } -static void addCommonLinkerModuleSymbols(StringRef Path, - pdb::DbiModuleDescriptorBuilder &Mod, - BumpPtrAllocator &Allocator) { - ObjNameSym ONS(SymbolRecordKind::ObjNameSym); - EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); - Compile3Sym CS(SymbolRecordKind::Compile3Sym); - fillLinkerVerRecord(CS); +static void addCommonLinkerModuleSymbols(StringRef path, + pdb::DbiModuleDescriptorBuilder &mod, + BumpPtrAllocator &allocator) { + ObjNameSym ons(SymbolRecordKind::ObjNameSym); + EnvBlockSym ebs(SymbolRecordKind::EnvBlockSym); + Compile3Sym cs(SymbolRecordKind::Compile3Sym); + fillLinkerVerRecord(cs); - ONS.Name = "* Linker *"; - ONS.Signature = 0; + ons.Name = "* Linker *"; + ons.Signature = 0; - ArrayRef Args = makeArrayRef(Config->Argv).drop_front(); - std::string ArgStr = quote(Args); - EBS.Fields.push_back("cwd"); + ArrayRef args = makeArrayRef(config->argv).drop_front(); + std::string argStr = quote(args); + ebs.Fields.push_back("cwd"); SmallString<64> cwd; - if (Config->PDBSourcePath.empty()) + if (config->pdbSourcePath.empty()) sys::fs::current_path(cwd); else - cwd = Config->PDBSourcePath; - EBS.Fields.push_back(cwd); - EBS.Fields.push_back("exe"); - SmallString<64> exe = Config->Argv[0]; + cwd = config->pdbSourcePath; + ebs.Fields.push_back(cwd); + ebs.Fields.push_back("exe"); + SmallString<64> exe = config->argv[0]; pdbMakeAbsolute(exe); - EBS.Fields.push_back(exe); - EBS.Fields.push_back("pdb"); - EBS.Fields.push_back(Path); - EBS.Fields.push_back("cmd"); - EBS.Fields.push_back(ArgStr); - Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( - ONS, Allocator, CodeViewContainer::Pdb)); - Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( - CS, Allocator, CodeViewContainer::Pdb)); - Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( - EBS, Allocator, CodeViewContainer::Pdb)); + ebs.Fields.push_back(exe); + ebs.Fields.push_back("pdb"); + ebs.Fields.push_back(path); + ebs.Fields.push_back("cmd"); + ebs.Fields.push_back(argStr); + mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + ons, allocator, CodeViewContainer::Pdb)); + mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + cs, allocator, CodeViewContainer::Pdb)); + mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + ebs, allocator, CodeViewContainer::Pdb)); } -static void addLinkerModuleCoffGroup(PartialSection *Sec, - pdb::DbiModuleDescriptorBuilder &Mod, - OutputSection &OS, - BumpPtrAllocator &Allocator) { +static void addLinkerModuleCoffGroup(PartialSection *sec, + pdb::DbiModuleDescriptorBuilder &mod, + OutputSection &os, + BumpPtrAllocator &allocator) { // If there's a section, there's at least one chunk - assert(!Sec->Chunks.empty()); - const Chunk *firstChunk = *Sec->Chunks.begin(); - const Chunk *lastChunk = *Sec->Chunks.rbegin(); + assert(!sec->chunks.empty()); + const Chunk *firstChunk = *sec->chunks.begin(); + const Chunk *lastChunk = *sec->chunks.rbegin(); // Emit COFF group - CoffGroupSym CGS(SymbolRecordKind::CoffGroupSym); - CGS.Name = Sec->Name; - CGS.Segment = OS.SectionIndex; - CGS.Offset = firstChunk->getRVA() - OS.getRVA(); - CGS.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA(); - CGS.Characteristics = Sec->Characteristics; + CoffGroupSym cgs(SymbolRecordKind::CoffGroupSym); + cgs.Name = sec->name; + cgs.Segment = os.sectionIndex; + cgs.Offset = firstChunk->getRVA() - os.getRVA(); + cgs.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA(); + cgs.Characteristics = sec->characteristics; // Somehow .idata sections & sections groups in the debug symbol stream have // the "write" flag set. However the section header for the corresponding // .idata section doesn't have it. - if (CGS.Name.startswith(".idata")) - CGS.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE; + if (cgs.Name.startswith(".idata")) + cgs.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE; - Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( - CGS, Allocator, CodeViewContainer::Pdb)); + mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + cgs, allocator, CodeViewContainer::Pdb)); } -static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, - OutputSection &OS, - BumpPtrAllocator &Allocator) { - SectionSym Sym(SymbolRecordKind::SectionSym); - Sym.Alignment = 12; // 2^12 = 4KB - Sym.Characteristics = OS.Header.Characteristics; - Sym.Length = OS.getVirtualSize(); - Sym.Name = OS.Name; - Sym.Rva = OS.getRVA(); - Sym.SectionNumber = OS.SectionIndex; - Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( - Sym, Allocator, CodeViewContainer::Pdb)); +static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &mod, + OutputSection &os, + BumpPtrAllocator &allocator) { + SectionSym sym(SymbolRecordKind::SectionSym); + sym.Alignment = 12; // 2^12 = 4KB + sym.Characteristics = os.header.Characteristics; + sym.Length = os.getVirtualSize(); + sym.Name = os.name; + sym.Rva = os.getRVA(); + sym.SectionNumber = os.sectionIndex; + mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + sym, allocator, CodeViewContainer::Pdb)); // Skip COFF groups in MinGW because it adds a significant footprint to the // PDB, due to each function being in its own section - if (Config->MinGW) + if (config->mingw) return; // Output COFF groups for individual chunks of this section. - for (PartialSection *Sec : OS.ContribSections) { - addLinkerModuleCoffGroup(Sec, Mod, OS, Allocator); + for (PartialSection *sec : os.contribSections) { + addLinkerModuleCoffGroup(sec, mod, os, allocator); } } // Add all import files as modules to the PDB. -void PDBLinker::addImportFilesToPDB(ArrayRef OutputSections) { - if (ImportFile::Instances.empty()) +void PDBLinker::addImportFilesToPDB(ArrayRef outputSections) { + if (ImportFile::instances.empty()) return; - std::map DllToModuleDbi; + std::map dllToModuleDbi; - for (ImportFile *File : ImportFile::Instances) { - if (!File->Live) + for (ImportFile *file : ImportFile::instances) { + if (!file->live) continue; - if (!File->ThunkSym) + if (!file->thunkSym) continue; - if (!File->ThunkLive) + if (!file->thunkLive) continue; - std::string DLL = StringRef(File->DLLName).lower(); - llvm::pdb::DbiModuleDescriptorBuilder *&Mod = DllToModuleDbi[DLL]; - if (!Mod) { - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - SmallString<128> LibPath = File->ParentName; - pdbMakeAbsolute(LibPath); - sys::path::native(LibPath); + std::string dll = StringRef(file->dllName).lower(); + llvm::pdb::DbiModuleDescriptorBuilder *&mod = dllToModuleDbi[dll]; + if (!mod) { + pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder(); + SmallString<128> libPath = file->parentName; + pdbMakeAbsolute(libPath); + sys::path::native(libPath); // Name modules similar to MSVC's link.exe. // The first module is the simple dll filename - llvm::pdb::DbiModuleDescriptorBuilder &FirstMod = - ExitOnErr(DbiBuilder.addModuleInfo(File->DLLName)); - FirstMod.setObjFileName(LibPath); - pdb::SectionContrib SC = + llvm::pdb::DbiModuleDescriptorBuilder &firstMod = + exitOnErr(dbiBuilder.addModuleInfo(file->dllName)); + firstMod.setObjFileName(libPath); + pdb::SectionContrib sc = createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex); - FirstMod.setFirstSectionContrib(SC); + firstMod.setFirstSectionContrib(sc); // The second module is where the import stream goes. - Mod = &ExitOnErr(DbiBuilder.addModuleInfo("Import:" + File->DLLName)); - Mod->setObjFileName(LibPath); + mod = &exitOnErr(dbiBuilder.addModuleInfo("Import:" + file->dllName)); + mod->setObjFileName(libPath); } - DefinedImportThunk *Thunk = cast(File->ThunkSym); - Chunk *ThunkChunk = Thunk->getChunk(); - OutputSection *ThunkOS = ThunkChunk->getOutputSection(); + DefinedImportThunk *thunk = cast(file->thunkSym); + Chunk *thunkChunk = thunk->getChunk(); + OutputSection *thunkOS = thunkChunk->getOutputSection(); - ObjNameSym ONS(SymbolRecordKind::ObjNameSym); - Compile3Sym CS(SymbolRecordKind::Compile3Sym); - Thunk32Sym TS(SymbolRecordKind::Thunk32Sym); - ScopeEndSym ES(SymbolRecordKind::ScopeEndSym); + ObjNameSym ons(SymbolRecordKind::ObjNameSym); + Compile3Sym cs(SymbolRecordKind::Compile3Sym); + Thunk32Sym ts(SymbolRecordKind::Thunk32Sym); + ScopeEndSym es(SymbolRecordKind::ScopeEndSym); - ONS.Name = File->DLLName; - ONS.Signature = 0; + ons.Name = file->dllName; + ons.Signature = 0; - fillLinkerVerRecord(CS); + fillLinkerVerRecord(cs); - TS.Name = Thunk->getName(); - TS.Parent = 0; - TS.End = 0; - TS.Next = 0; - TS.Thunk = ThunkOrdinal::Standard; - TS.Length = ThunkChunk->getSize(); - TS.Segment = ThunkOS->SectionIndex; - TS.Offset = ThunkChunk->getRVA() - ThunkOS->getRVA(); + ts.Name = thunk->getName(); + ts.Parent = 0; + ts.End = 0; + ts.Next = 0; + ts.Thunk = ThunkOrdinal::Standard; + ts.Length = thunkChunk->getSize(); + ts.Segment = thunkOS->sectionIndex; + ts.Offset = thunkChunk->getRVA() - thunkOS->getRVA(); - Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( - ONS, Alloc, CodeViewContainer::Pdb)); - Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( - CS, Alloc, CodeViewContainer::Pdb)); + mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( + ons, alloc, CodeViewContainer::Pdb)); + mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( + cs, alloc, CodeViewContainer::Pdb)); - SmallVector Scopes; - CVSymbol NewSym = codeview::SymbolSerializer::writeOneSymbol( - TS, Alloc, CodeViewContainer::Pdb); - scopeStackOpen(Scopes, Mod->getNextSymbolOffset(), NewSym); + SmallVector scopes; + CVSymbol newSym = codeview::SymbolSerializer::writeOneSymbol( + ts, alloc, CodeViewContainer::Pdb); + scopeStackOpen(scopes, mod->getNextSymbolOffset(), newSym); - Mod->addSymbol(NewSym); + mod->addSymbol(newSym); - NewSym = codeview::SymbolSerializer::writeOneSymbol(ES, Alloc, + newSym = codeview::SymbolSerializer::writeOneSymbol(es, alloc, CodeViewContainer::Pdb); - scopeStackClose(Scopes, Mod->getNextSymbolOffset(), File); + scopeStackClose(scopes, mod->getNextSymbolOffset(), file); - Mod->addSymbol(NewSym); + mod->addSymbol(newSym); - pdb::SectionContrib SC = - createSectionContrib(Thunk->getChunk(), Mod->getModuleIndex()); - Mod->setFirstSectionContrib(SC); + pdb::SectionContrib sc = + createSectionContrib(thunk->getChunk(), mod->getModuleIndex()); + mod->setFirstSectionContrib(sc); } } // Creates a PDB file. -void coff::createPDB(SymbolTable *Symtab, - ArrayRef OutputSections, - ArrayRef SectionTable, - llvm::codeview::DebugInfo *BuildId) { - ScopedTimer T1(TotalPdbLinkTimer); - PDBLinker PDB(Symtab); - - PDB.initialize(BuildId); - PDB.addObjectsToPDB(); - PDB.addImportFilesToPDB(OutputSections); - PDB.addSections(OutputSections, SectionTable); - PDB.addNatvisFiles(); - - ScopedTimer T2(DiskCommitTimer); - codeview::GUID Guid; - PDB.commit(&Guid); - memcpy(&BuildId->PDB70.Signature, &Guid, 16); - - T2.stop(); - T1.stop(); - PDB.printStats(); +void coff::createPDB(SymbolTable *symtab, + ArrayRef outputSections, + ArrayRef sectionTable, + llvm::codeview::DebugInfo *buildId) { + ScopedTimer t1(totalPdbLinkTimer); + PDBLinker pdb(symtab); + + pdb.initialize(buildId); + pdb.addObjectsToPDB(); + pdb.addImportFilesToPDB(outputSections); + pdb.addSections(outputSections, sectionTable); + pdb.addNatvisFiles(); + + ScopedTimer t2(diskCommitTimer); + codeview::GUID guid; + pdb.commit(&guid); + memcpy(&buildId->PDB70.Signature, &guid, 16); + + t2.stop(); + t1.stop(); + pdb.printStats(); } -void PDBLinker::initialize(llvm::codeview::DebugInfo *BuildId) { - ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize +void PDBLinker::initialize(llvm::codeview::DebugInfo *buildId) { + exitOnErr(builder.initialize(4096)); // 4096 is blocksize - BuildId->Signature.CVSignature = OMF::Signature::PDB70; + buildId->Signature.CVSignature = OMF::Signature::PDB70; // Signature is set to a hash of the PDB contents when the PDB is done. - memset(BuildId->PDB70.Signature, 0, 16); - BuildId->PDB70.Age = 1; + memset(buildId->PDB70.Signature, 0, 16); + buildId->PDB70.Age = 1; // Create streams in MSF for predefined streams, namely // PDB, TPI, DBI and IPI. - for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I) - ExitOnErr(Builder.getMsfBuilder().addStream(0)); + for (int i = 0; i < (int)pdb::kSpecialStreamCount; ++i) + exitOnErr(builder.getMsfBuilder().addStream(0)); // Add an Info stream. - auto &InfoBuilder = Builder.getInfoBuilder(); - InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); - InfoBuilder.setHashPDBContentsToGUID(true); + auto &infoBuilder = builder.getInfoBuilder(); + infoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); + infoBuilder.setHashPDBContentsToGUID(true); // Add an empty DBI stream. - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - DbiBuilder.setAge(BuildId->PDB70.Age); - DbiBuilder.setVersionHeader(pdb::PdbDbiV70); - DbiBuilder.setMachineType(Config->Machine); + pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder(); + dbiBuilder.setAge(buildId->PDB70.Age); + dbiBuilder.setVersionHeader(pdb::PdbDbiV70); + dbiBuilder.setMachineType(config->machine); // Technically we are not link.exe 14.11, but there are known cases where // debugging tools on Windows expect Microsoft-specific version numbers or // they fail to work at all. Since we know we produce PDBs that are // compatible with LINK 14.11, we set that version number here. - DbiBuilder.setBuildNumber(14, 11); + dbiBuilder.setBuildNumber(14, 11); } -void PDBLinker::addSections(ArrayRef OutputSections, - ArrayRef SectionTable) { +void PDBLinker::addSections(ArrayRef outputSections, + ArrayRef sectionTable) { // It's not entirely clear what this is, but the * Linker * module uses it. - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - NativePath = Config->PDBPath; - pdbMakeAbsolute(NativePath); - uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); - auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); - LinkerModule.setPdbFilePathNI(PdbFilePathNI); - addCommonLinkerModuleSymbols(NativePath, LinkerModule, Alloc); + pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder(); + nativePath = config->pdbPath; + pdbMakeAbsolute(nativePath); + uint32_t pdbFilePathNI = dbiBuilder.addECName(nativePath); + auto &linkerModule = exitOnErr(dbiBuilder.addModuleInfo("* Linker *")); + linkerModule.setPdbFilePathNI(pdbFilePathNI); + addCommonLinkerModuleSymbols(nativePath, linkerModule, alloc); // Add section contributions. They must be ordered by ascending RVA. - for (OutputSection *OS : OutputSections) { - addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc); - for (Chunk *C : OS->Chunks) { - pdb::SectionContrib SC = - createSectionContrib(C, LinkerModule.getModuleIndex()); - Builder.getDbiBuilder().addSectionContrib(SC); + for (OutputSection *os : outputSections) { + addLinkerModuleSectionSymbol(linkerModule, *os, alloc); + for (Chunk *c : os->chunks) { + pdb::SectionContrib sc = + createSectionContrib(c, linkerModule.getModuleIndex()); + builder.getDbiBuilder().addSectionContrib(sc); } } // The * Linker * first section contrib is only used along with /INCREMENTAL, // to provide trampolines thunks for incremental function patching. Set this // as "unused" because LLD doesn't support /INCREMENTAL link. - pdb::SectionContrib SC = + pdb::SectionContrib sc = createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex); - LinkerModule.setFirstSectionContrib(SC); + linkerModule.setFirstSectionContrib(sc); // Add Section Map stream. - ArrayRef Sections = { - (const object::coff_section *)SectionTable.data(), - SectionTable.size() / sizeof(object::coff_section)}; - SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); - DbiBuilder.setSectionMap(SectionMap); + ArrayRef sections = { + (const object::coff_section *)sectionTable.data(), + sectionTable.size() / sizeof(object::coff_section)}; + sectionMap = pdb::DbiStreamBuilder::createSectionMap(sections); + dbiBuilder.setSectionMap(sectionMap); // Add COFF section header stream. - ExitOnErr( - DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable)); + exitOnErr( + dbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, sectionTable)); } -void PDBLinker::commit(codeview::GUID *Guid) { +void PDBLinker::commit(codeview::GUID *guid) { // Write to a file. - ExitOnErr(Builder.commit(Config->PDBPath, Guid)); + exitOnErr(builder.commit(config->pdbPath, guid)); } static uint32_t getSecrelReloc() { - switch (Config->Machine) { + switch (config->machine) { case AMD64: return COFF::IMAGE_REL_AMD64_SECREL; case I386: @@ -1717,78 +1717,78 @@ static uint32_t getSecrelReloc() { // that are used to interpret the line table, and the offset of Addr in the line // table are stored in the output arguments. Returns whether a line table was // found. -static bool findLineTable(const SectionChunk *C, uint32_t Addr, - DebugStringTableSubsectionRef &CVStrTab, - DebugChecksumsSubsectionRef &Checksums, - DebugLinesSubsectionRef &Lines, - uint32_t &OffsetInLinetable) { - ExitOnError ExitOnErr; - uint32_t SecrelReloc = getSecrelReloc(); - - for (SectionChunk *DbgC : C->File->getDebugChunks()) { - if (DbgC->getSectionName() != ".debug$S") +static bool findLineTable(const SectionChunk *c, uint32_t addr, + DebugStringTableSubsectionRef &cVStrTab, + DebugChecksumsSubsectionRef &checksums, + DebugLinesSubsectionRef &lines, + uint32_t &offsetInLinetable) { + ExitOnError exitOnErr; + uint32_t secrelReloc = getSecrelReloc(); + + for (SectionChunk *dbgC : c->file->getDebugChunks()) { + if (dbgC->getSectionName() != ".debug$S") continue; // Build a mapping of SECREL relocations in DbgC that refer to C. - DenseMap Secrels; - for (const coff_relocation &R : DbgC->getRelocs()) { - if (R.Type != SecrelReloc) + DenseMap secrels; + for (const coff_relocation &r : dbgC->getRelocs()) { + if (r.Type != secrelReloc) continue; - if (auto *S = dyn_cast_or_null( - C->File->getSymbols()[R.SymbolTableIndex])) - if (S->getChunk() == C) - Secrels[R.VirtualAddress] = S->getValue(); + if (auto *s = dyn_cast_or_null( + c->file->getSymbols()[r.SymbolTableIndex])) + if (s->getChunk() == c) + secrels[r.VirtualAddress] = s->getValue(); } - ArrayRef Contents = - SectionChunk::consumeDebugMagic(DbgC->getContents(), ".debug$S"); - DebugSubsectionArray Subsections; - BinaryStreamReader Reader(Contents, support::little); - ExitOnErr(Reader.readArray(Subsections, Contents.size())); + ArrayRef contents = + SectionChunk::consumeDebugMagic(dbgC->getContents(), ".debug$S"); + DebugSubsectionArray subsections; + BinaryStreamReader reader(contents, support::little); + exitOnErr(reader.readArray(subsections, contents.size())); - for (const DebugSubsectionRecord &SS : Subsections) { - switch (SS.kind()) { + for (const DebugSubsectionRecord &ss : subsections) { + switch (ss.kind()) { case DebugSubsectionKind::StringTable: { - assert(!CVStrTab.valid() && + assert(!cVStrTab.valid() && "Encountered multiple string table subsections!"); - ExitOnErr(CVStrTab.initialize(SS.getRecordData())); + exitOnErr(cVStrTab.initialize(ss.getRecordData())); break; } case DebugSubsectionKind::FileChecksums: - assert(!Checksums.valid() && + assert(!checksums.valid() && "Encountered multiple checksum subsections!"); - ExitOnErr(Checksums.initialize(SS.getRecordData())); + exitOnErr(checksums.initialize(ss.getRecordData())); break; case DebugSubsectionKind::Lines: { - ArrayRef Bytes; - auto Ref = SS.getRecordData(); - ExitOnErr(Ref.readLongestContiguousChunk(0, Bytes)); - size_t OffsetInDbgC = Bytes.data() - DbgC->getContents().data(); + ArrayRef bytes; + auto ref = ss.getRecordData(); + exitOnErr(ref.readLongestContiguousChunk(0, bytes)); + size_t offsetInDbgC = bytes.data() - dbgC->getContents().data(); // Check whether this line table refers to C. - auto I = Secrels.find(OffsetInDbgC); - if (I == Secrels.end()) + auto i = secrels.find(offsetInDbgC); + if (i == secrels.end()) break; // Check whether this line table covers Addr in C. - DebugLinesSubsectionRef LinesTmp; - ExitOnErr(LinesTmp.initialize(BinaryStreamReader(Ref))); - uint32_t OffsetInC = I->second + LinesTmp.header()->RelocOffset; - if (Addr < OffsetInC || Addr >= OffsetInC + LinesTmp.header()->CodeSize) + DebugLinesSubsectionRef linesTmp; + exitOnErr(linesTmp.initialize(BinaryStreamReader(ref))); + uint32_t offsetInC = i->second + linesTmp.header()->RelocOffset; + if (addr < offsetInC || addr >= offsetInC + linesTmp.header()->CodeSize) break; - assert(!Lines.header() && + assert(!lines.header() && "Encountered multiple line tables for function!"); - ExitOnErr(Lines.initialize(BinaryStreamReader(Ref))); - OffsetInLinetable = Addr - OffsetInC; + exitOnErr(lines.initialize(BinaryStreamReader(ref))); + offsetInLinetable = addr - offsetInC; break; } default: break; } - if (CVStrTab.valid() && Checksums.valid() && Lines.header()) + if (cVStrTab.valid() && checksums.valid() && lines.header()) return true; } } @@ -1799,38 +1799,38 @@ static bool findLineTable(const SectionChunk *C, uint32_t Addr, // Use CodeView line tables to resolve a file and line number for the given // offset into the given chunk and return them, or {"", 0} if a line table was // not found. -std::pair coff::getFileLine(const SectionChunk *C, - uint32_t Addr) { - ExitOnError ExitOnErr; +std::pair coff::getFileLine(const SectionChunk *c, + uint32_t addr) { + ExitOnError exitOnErr; - DebugStringTableSubsectionRef CVStrTab; - DebugChecksumsSubsectionRef Checksums; - DebugLinesSubsectionRef Lines; - uint32_t OffsetInLinetable; + DebugStringTableSubsectionRef cVStrTab; + DebugChecksumsSubsectionRef checksums; + DebugLinesSubsectionRef lines; + uint32_t offsetInLinetable; - if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable)) + if (!findLineTable(c, addr, cVStrTab, checksums, lines, offsetInLinetable)) return {"", 0}; - Optional NameIndex; - Optional LineNumber; - for (LineColumnEntry &Entry : Lines) { - for (const LineNumberEntry &LN : Entry.LineNumbers) { - LineInfo LI(LN.Flags); - if (LN.Offset > OffsetInLinetable) { - if (!NameIndex) { - NameIndex = Entry.NameIndex; - LineNumber = LI.getStartLine(); + Optional nameIndex; + Optional lineNumber; + for (LineColumnEntry &entry : lines) { + for (const LineNumberEntry &ln : entry.LineNumbers) { + LineInfo li(ln.Flags); + if (ln.Offset > offsetInLinetable) { + if (!nameIndex) { + nameIndex = entry.NameIndex; + lineNumber = li.getStartLine(); } - StringRef Filename = - ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex)); - return {Filename, *LineNumber}; + StringRef filename = + exitOnErr(getFileName(cVStrTab, checksums, *nameIndex)); + return {filename, *lineNumber}; } - NameIndex = Entry.NameIndex; - LineNumber = LI.getStartLine(); + nameIndex = entry.NameIndex; + lineNumber = li.getStartLine(); } } - if (!NameIndex) + if (!nameIndex) return {"", 0}; - StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex)); - return {Filename, *LineNumber}; + StringRef filename = exitOnErr(getFileName(cVStrTab, checksums, *nameIndex)); + return {filename, *lineNumber}; } diff --git a/lld/COFF/PDB.h b/lld/COFF/PDB.h index d954e09..3ac1adc 100644 --- a/lld/COFF/PDB.h +++ b/lld/COFF/PDB.h @@ -24,13 +24,13 @@ class OutputSection; class SectionChunk; class SymbolTable; -void createPDB(SymbolTable *Symtab, - llvm::ArrayRef OutputSections, - llvm::ArrayRef SectionTable, - llvm::codeview::DebugInfo *BuildId); +void createPDB(SymbolTable *symtab, + llvm::ArrayRef outputSections, + llvm::ArrayRef sectionTable, + llvm::codeview::DebugInfo *buildId); -std::pair getFileLine(const SectionChunk *C, - uint32_t Addr); +std::pair getFileLine(const SectionChunk *c, + uint32_t addr); } } diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 023b401..a6c4bc5 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -26,168 +26,168 @@ using namespace llvm; namespace lld { namespace coff { -static Timer LTOTimer("LTO", Timer::root()); +static Timer ltoTimer("LTO", Timer::root()); -SymbolTable *Symtab; +SymbolTable *symtab; -void SymbolTable::addFile(InputFile *File) { - log("Reading " + toString(File)); - File->parse(); +void SymbolTable::addFile(InputFile *file) { + log("Reading " + toString(file)); + file->parse(); - MachineTypes MT = File->getMachineType(); - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { - Config->Machine = MT; - } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { - error(toString(File) + ": machine type " + machineToStr(MT) + - " conflicts with " + machineToStr(Config->Machine)); + MachineTypes mt = file->getMachineType(); + if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) { + config->machine = mt; + } else if (mt != IMAGE_FILE_MACHINE_UNKNOWN && config->machine != mt) { + error(toString(file) + ": machine type " + machineToStr(mt) + + " conflicts with " + machineToStr(config->machine)); return; } - if (auto *F = dyn_cast(File)) { - ObjFile::Instances.push_back(F); - } else if (auto *F = dyn_cast(File)) { - BitcodeFile::Instances.push_back(F); - } else if (auto *F = dyn_cast(File)) { - ImportFile::Instances.push_back(F); + if (auto *f = dyn_cast(file)) { + ObjFile::instances.push_back(f); + } else if (auto *f = dyn_cast(file)) { + BitcodeFile::instances.push_back(f); + } else if (auto *f = dyn_cast(file)) { + ImportFile::instances.push_back(f); } - Driver->parseDirectives(File); + driver->parseDirectives(file); } -static void errorOrWarn(const Twine &S) { - if (Config->ForceUnresolved) - warn(S); +static void errorOrWarn(const Twine &s) { + if (config->forceUnresolved) + warn(s); else - error(S); + error(s); } // Returns the symbol in SC whose value is <= Addr that is closest to Addr. // This is generally the global variable or function whose definition contains // Addr. -static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) { - DefinedRegular *Candidate = nullptr; +static Symbol *getSymbol(SectionChunk *sc, uint32_t addr) { + DefinedRegular *candidate = nullptr; - for (Symbol *S : SC->File->getSymbols()) { - auto *D = dyn_cast_or_null(S); - if (!D || D->getChunk() != SC || D->getValue() > Addr || - (Candidate && D->getValue() < Candidate->getValue())) + for (Symbol *s : sc->file->getSymbols()) { + auto *d = dyn_cast_or_null(s); + if (!d || d->getChunk() != sc || d->getValue() > addr || + (candidate && d->getValue() < candidate->getValue())) continue; - Candidate = D; + candidate = d; } - return Candidate; + return candidate; } // Given a file and the index of a symbol in that file, returns a description // of all references to that symbol from that file. If no debug information is // available, returns just the name of the file, else one string per actual // reference as described in the debug info. -std::vector getSymbolLocations(ObjFile *File, uint32_t SymIndex) { +std::vector getSymbolLocations(ObjFile *file, uint32_t symIndex) { struct Location { - Symbol *Sym; - std::pair FileLine; + Symbol *sym; + std::pair fileLine; }; - std::vector Locations; + std::vector locations; - for (Chunk *C : File->getChunks()) { - auto *SC = dyn_cast(C); - if (!SC) + for (Chunk *c : file->getChunks()) { + auto *sc = dyn_cast(c); + if (!sc) continue; - for (const coff_relocation &R : SC->getRelocs()) { - if (R.SymbolTableIndex != SymIndex) + for (const coff_relocation &r : sc->getRelocs()) { + if (r.SymbolTableIndex != symIndex) continue; - std::pair FileLine = - getFileLine(SC, R.VirtualAddress); - Symbol *Sym = getSymbol(SC, R.VirtualAddress); - if (!FileLine.first.empty() || Sym) - Locations.push_back({Sym, FileLine}); + std::pair fileLine = + getFileLine(sc, r.VirtualAddress); + Symbol *sym = getSymbol(sc, r.VirtualAddress); + if (!fileLine.first.empty() || sym) + locations.push_back({sym, fileLine}); } } - if (Locations.empty()) - return std::vector({"\n>>> referenced by " + toString(File)}); + if (locations.empty()) + return std::vector({"\n>>> referenced by " + toString(file)}); - std::vector SymbolLocations(Locations.size()); - size_t I = 0; - for (Location Loc : Locations) { - llvm::raw_string_ostream OS(SymbolLocations[I++]); - OS << "\n>>> referenced by "; - if (!Loc.FileLine.first.empty()) - OS << Loc.FileLine.first << ":" << Loc.FileLine.second + std::vector symbolLocations(locations.size()); + size_t i = 0; + for (Location loc : locations) { + llvm::raw_string_ostream os(symbolLocations[i++]); + os << "\n>>> referenced by "; + if (!loc.fileLine.first.empty()) + os << loc.fileLine.first << ":" << loc.fileLine.second << "\n>>> "; - OS << toString(File); - if (Loc.Sym) - OS << ":(" << toString(*Loc.Sym) << ')'; + os << toString(file); + if (loc.sym) + os << ":(" << toString(*loc.sym) << ')'; } - return SymbolLocations; + return symbolLocations; } // For an undefined symbol, stores all files referencing it and the index of // the undefined symbol in each file. struct UndefinedDiag { - Symbol *Sym; + Symbol *sym; struct File { - ObjFile *OFile; - uint64_t SymIndex; + ObjFile *oFile; + uint64_t symIndex; }; - std::vector Files; + std::vector files; }; -static void reportUndefinedSymbol(const UndefinedDiag &UndefDiag) { - std::string Out; - llvm::raw_string_ostream OS(Out); - OS << "undefined symbol: " << toString(*UndefDiag.Sym); - - const size_t MaxUndefReferences = 10; - size_t I = 0, NumRefs = 0; - for (const UndefinedDiag::File &Ref : UndefDiag.Files) { - std::vector SymbolLocations = - getSymbolLocations(Ref.OFile, Ref.SymIndex); - NumRefs += SymbolLocations.size(); - for (const std::string &S : SymbolLocations) { - if (I >= MaxUndefReferences) +static void reportUndefinedSymbol(const UndefinedDiag &undefDiag) { + std::string out; + llvm::raw_string_ostream os(out); + os << "undefined symbol: " << toString(*undefDiag.sym); + + const size_t maxUndefReferences = 10; + size_t i = 0, numRefs = 0; + for (const UndefinedDiag::File &ref : undefDiag.files) { + std::vector symbolLocations = + getSymbolLocations(ref.oFile, ref.symIndex); + numRefs += symbolLocations.size(); + for (const std::string &s : symbolLocations) { + if (i >= maxUndefReferences) break; - OS << S; - I++; + os << s; + i++; } } - if (I < NumRefs) - OS << "\n>>> referenced " << NumRefs - I << " more times"; - errorOrWarn(OS.str()); + if (i < numRefs) + os << "\n>>> referenced " << numRefs - i << " more times"; + errorOrWarn(os.str()); } void SymbolTable::loadMinGWAutomaticImports() { - for (auto &I : SymMap) { - Symbol *Sym = I.second; - auto *Undef = dyn_cast(Sym); - if (!Undef) + for (auto &i : symMap) { + Symbol *sym = i.second; + auto *undef = dyn_cast(sym); + if (!undef) continue; - if (!Sym->IsUsedInRegularObj) + if (!sym->isUsedInRegularObj) continue; - StringRef Name = Undef->getName(); + StringRef name = undef->getName(); - if (Name.startswith("__imp_")) + if (name.startswith("__imp_")) continue; // If we have an undefined symbol, but we have a Lazy representing a // symbol we could load from file, make sure to load that. - Lazy *L = dyn_cast_or_null(find(("__imp_" + Name).str())); - if (!L || L->PendingArchiveLoad) + Lazy *l = dyn_cast_or_null(find(("__imp_" + name).str())); + if (!l || l->pendingArchiveLoad) continue; - log("Loading lazy " + L->getName() + " from " + L->File->getName() + + log("Loading lazy " + l->getName() + " from " + l->file->getName() + " for automatic import"); - L->PendingArchiveLoad = true; - L->File->addMember(&L->Sym); + l->pendingArchiveLoad = true; + l->file->addMember(&l->sym); } } -bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) { - if (Name.startswith("__imp_")) +bool SymbolTable::handleMinGWAutomaticImport(Symbol *sym, StringRef name) { + if (name.startswith("__imp_")) return false; - Defined *Imp = dyn_cast_or_null(find(("__imp_" + Name).str())); - if (!Imp) + Defined *imp = dyn_cast_or_null(find(("__imp_" + name).str())); + if (!imp) return false; // Replace the reference directly to a variable with a reference @@ -196,406 +196,406 @@ bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) { // will add runtime pseudo relocations for every relocation against // this Symbol. The runtime pseudo relocation framework expects the // reference itself to point at the IAT entry. - size_t ImpSize = 0; - if (isa(Imp)) { - log("Automatically importing " + Name + " from " + - cast(Imp)->getDLLName()); - ImpSize = sizeof(DefinedImportData); - } else if (isa(Imp)) { - log("Automatically importing " + Name + " from " + - toString(cast(Imp)->File)); - ImpSize = sizeof(DefinedRegular); + size_t impSize = 0; + if (isa(imp)) { + log("Automatically importing " + name + " from " + + cast(imp)->getDLLName()); + impSize = sizeof(DefinedImportData); + } else if (isa(imp)) { + log("Automatically importing " + name + " from " + + toString(cast(imp)->file)); + impSize = sizeof(DefinedRegular); } else { - warn("unable to automatically import " + Name + " from " + Imp->getName() + - " from " + toString(cast(Imp)->File) + + warn("unable to automatically import " + name + " from " + imp->getName() + + " from " + toString(cast(imp)->file) + "; unexpected symbol type"); return false; } - Sym->replaceKeepingName(Imp, ImpSize); - Sym->IsRuntimePseudoReloc = true; + sym->replaceKeepingName(imp, impSize); + sym->isRuntimePseudoReloc = true; // There may exist symbols named .refptr. which only consist // of a single pointer to . If it turns out is // automatically imported, we don't need to keep the .refptr. // pointer at all, but redirect all accesses to it to the IAT entry // for __imp_ instead, and drop the whole .refptr. chunk. - DefinedRegular *Refptr = - dyn_cast_or_null(find((".refptr." + Name).str())); - if (Refptr && Refptr->getChunk()->getSize() == Config->Wordsize) { - SectionChunk *SC = dyn_cast_or_null(Refptr->getChunk()); - if (SC && SC->getRelocs().size() == 1 && *SC->symbols().begin() == Sym) { - log("Replacing .refptr." + Name + " with " + Imp->getName()); - Refptr->getChunk()->Live = false; - Refptr->replaceKeepingName(Imp, ImpSize); + DefinedRegular *refptr = + dyn_cast_or_null(find((".refptr." + name).str())); + if (refptr && refptr->getChunk()->getSize() == config->wordsize) { + SectionChunk *sc = dyn_cast_or_null(refptr->getChunk()); + if (sc && sc->getRelocs().size() == 1 && *sc->symbols().begin() == sym) { + log("Replacing .refptr." + name + " with " + imp->getName()); + refptr->getChunk()->live = false; + refptr->replaceKeepingName(imp, impSize); } } return true; } void SymbolTable::reportRemainingUndefines() { - SmallPtrSet Undefs; - DenseMap LocalImports; + SmallPtrSet undefs; + DenseMap localImports; - for (auto &I : SymMap) { - Symbol *Sym = I.second; - auto *Undef = dyn_cast(Sym); - if (!Undef) + for (auto &i : symMap) { + Symbol *sym = i.second; + auto *undef = dyn_cast(sym); + if (!undef) continue; - if (!Sym->IsUsedInRegularObj) + if (!sym->isUsedInRegularObj) continue; - StringRef Name = Undef->getName(); + StringRef name = undef->getName(); // A weak alias may have been resolved, so check for that. - if (Defined *D = Undef->getWeakAlias()) { + if (Defined *d = undef->getWeakAlias()) { // We want to replace Sym with D. However, we can't just blindly // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an // internal symbol, and internal symbols are stored as "unparented" // Symbols. For that reason we need to check which type of symbol we // are dealing with and copy the correct number of bytes. - if (isa(D)) - memcpy(Sym, D, sizeof(DefinedRegular)); - else if (isa(D)) - memcpy(Sym, D, sizeof(DefinedAbsolute)); + if (isa(d)) + memcpy(sym, d, sizeof(DefinedRegular)); + else if (isa(d)) + memcpy(sym, d, sizeof(DefinedAbsolute)); else - memcpy(Sym, D, sizeof(SymbolUnion)); + memcpy(sym, d, sizeof(SymbolUnion)); continue; } // If we can resolve a symbol by removing __imp_ prefix, do that. // This odd rule is for compatibility with MSVC linker. - if (Name.startswith("__imp_")) { - Symbol *Imp = find(Name.substr(strlen("__imp_"))); - if (Imp && isa(Imp)) { - auto *D = cast(Imp); - replaceSymbol(Sym, Name, D); - LocalImportChunks.push_back(cast(Sym)->getChunk()); - LocalImports[Sym] = D; + if (name.startswith("__imp_")) { + Symbol *imp = find(name.substr(strlen("__imp_"))); + if (imp && isa(imp)) { + auto *d = cast(imp); + replaceSymbol(sym, name, d); + localImportChunks.push_back(cast(sym)->getChunk()); + localImports[sym] = d; continue; } } // We don't want to report missing Microsoft precompiled headers symbols. // A proper message will be emitted instead in PDBLinker::aquirePrecompObj - if (Name.contains("_PchSym_")) + if (name.contains("_PchSym_")) continue; - if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name)) + if (config->mingw && handleMinGWAutomaticImport(sym, name)) continue; // Remaining undefined symbols are not fatal if /force is specified. // They are replaced with dummy defined symbols. - if (Config->ForceUnresolved) - replaceSymbol(Sym, Name, 0); - Undefs.insert(Sym); + if (config->forceUnresolved) + replaceSymbol(sym, name, 0); + undefs.insert(sym); } - if (Undefs.empty() && LocalImports.empty()) + if (undefs.empty() && localImports.empty()) return; - for (Symbol *B : Config->GCRoot) { - if (Undefs.count(B)) - errorOrWarn(": undefined symbol: " + toString(*B)); - if (Config->WarnLocallyDefinedImported) - if (Symbol *Imp = LocalImports.lookup(B)) - warn(": locally defined symbol imported: " + toString(*Imp) + - " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); + for (Symbol *b : config->gCRoot) { + if (undefs.count(b)) + errorOrWarn(": undefined symbol: " + toString(*b)); + if (config->warnLocallyDefinedImported) + if (Symbol *imp = localImports.lookup(b)) + warn(": locally defined symbol imported: " + toString(*imp) + + " (defined in " + toString(imp->getFile()) + ") [LNK4217]"); } - std::vector UndefDiags; - DenseMap FirstDiag; + std::vector undefDiags; + DenseMap firstDiag; - for (ObjFile *File : ObjFile::Instances) { - size_t SymIndex = (size_t)-1; - for (Symbol *Sym : File->getSymbols()) { - ++SymIndex; - if (!Sym) + for (ObjFile *file : ObjFile::instances) { + size_t symIndex = (size_t)-1; + for (Symbol *sym : file->getSymbols()) { + ++symIndex; + if (!sym) continue; - if (Undefs.count(Sym)) { - auto it = FirstDiag.find(Sym); - if (it == FirstDiag.end()) { - FirstDiag[Sym] = UndefDiags.size(); - UndefDiags.push_back({Sym, {{File, SymIndex}}}); + if (undefs.count(sym)) { + auto it = firstDiag.find(sym); + if (it == firstDiag.end()) { + firstDiag[sym] = undefDiags.size(); + undefDiags.push_back({sym, {{file, symIndex}}}); } else { - UndefDiags[it->second].Files.push_back({File, SymIndex}); + undefDiags[it->second].files.push_back({file, symIndex}); } } - if (Config->WarnLocallyDefinedImported) - if (Symbol *Imp = LocalImports.lookup(Sym)) - warn(toString(File) + - ": locally defined symbol imported: " + toString(*Imp) + - " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); + if (config->warnLocallyDefinedImported) + if (Symbol *imp = localImports.lookup(sym)) + warn(toString(file) + + ": locally defined symbol imported: " + toString(*imp) + + " (defined in " + toString(imp->getFile()) + ") [LNK4217]"); } } - for (const UndefinedDiag& UndefDiag : UndefDiags) - reportUndefinedSymbol(UndefDiag); + for (const UndefinedDiag& undefDiag : undefDiags) + reportUndefinedSymbol(undefDiag); } -std::pair SymbolTable::insert(StringRef Name) { - bool Inserted = false; - Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; - if (!Sym) { - Sym = reinterpret_cast(make()); - Sym->IsUsedInRegularObj = false; - Sym->PendingArchiveLoad = false; - Inserted = true; +std::pair SymbolTable::insert(StringRef name) { + bool inserted = false; + Symbol *&sym = symMap[CachedHashStringRef(name)]; + if (!sym) { + sym = reinterpret_cast(make()); + sym->isUsedInRegularObj = false; + sym->pendingArchiveLoad = false; + inserted = true; } - return {Sym, Inserted}; + return {sym, inserted}; } -std::pair SymbolTable::insert(StringRef Name, InputFile *File) { - std::pair Result = insert(Name); - if (!File || !isa(File)) - Result.first->IsUsedInRegularObj = true; - return Result; +std::pair SymbolTable::insert(StringRef name, InputFile *file) { + std::pair result = insert(name); + if (!file || !isa(file)) + result.first->isUsedInRegularObj = true; + return result; } -Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, - bool IsWeakAlias) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, F); - if (WasInserted || (isa(S) && IsWeakAlias)) { - replaceSymbol(S, Name); - return S; +Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f, + bool isWeakAlias) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, f); + if (wasInserted || (isa(s) && isWeakAlias)) { + replaceSymbol(s, name); + return s; } - if (auto *L = dyn_cast(S)) { - if (!S->PendingArchiveLoad) { - S->PendingArchiveLoad = true; - L->File->addMember(&L->Sym); + if (auto *l = dyn_cast(s)) { + if (!s->pendingArchiveLoad) { + s->pendingArchiveLoad = true; + l->file->addMember(&l->sym); } } - return S; + return s; } -void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { - StringRef Name = Sym.getName(); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - if (WasInserted) { - replaceSymbol(S, F, Sym); +void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { + StringRef name = sym.getName(); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + if (wasInserted) { + replaceSymbol(s, f, sym); return; } - auto *U = dyn_cast(S); - if (!U || U->WeakAlias || S->PendingArchiveLoad) + auto *u = dyn_cast(s); + if (!u || u->weakAlias || s->pendingArchiveLoad) return; - S->PendingArchiveLoad = true; - F->addMember(&Sym); + s->pendingArchiveLoad = true; + f->addMember(&sym); } -void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { - std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " + - toString(Existing->getFile()) + " and in " + - toString(NewFile); +void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) { + std::string msg = "duplicate symbol: " + toString(*existing) + " in " + + toString(existing->getFile()) + " and in " + + toString(newFile); - if (Config->ForceMultiple) - warn(Msg); + if (config->forceMultiple) + warn(msg); else - error(Msg); + error(msg); } -Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, nullptr); - S->IsUsedInRegularObj = true; - if (WasInserted || isa(S) || isa(S)) - replaceSymbol(S, N, Sym); - else if (!isa(S)) - reportDuplicate(S, nullptr); - return S; +Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, nullptr); + s->isUsedInRegularObj = true; + if (wasInserted || isa(s) || isa(s)) + replaceSymbol(s, n, sym); + else if (!isa(s)) + reportDuplicate(s, nullptr); + return s; } -Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, nullptr); - S->IsUsedInRegularObj = true; - if (WasInserted || isa(S) || isa(S)) - replaceSymbol(S, N, VA); - else if (!isa(S)) - reportDuplicate(S, nullptr); - return S; +Symbol *SymbolTable::addAbsolute(StringRef n, uint64_t va) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, nullptr); + s->isUsedInRegularObj = true; + if (wasInserted || isa(s) || isa(s)) + replaceSymbol(s, n, va); + else if (!isa(s)) + reportDuplicate(s, nullptr); + return s; } -Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, nullptr); - S->IsUsedInRegularObj = true; - if (WasInserted || isa(S) || isa(S)) - replaceSymbol(S, N, C); - else if (!isa(S)) - reportDuplicate(S, nullptr); - return S; +Symbol *SymbolTable::addSynthetic(StringRef n, Chunk *c) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, nullptr); + s->isUsedInRegularObj = true; + if (wasInserted || isa(s) || isa(s)) + replaceSymbol(s, n, c); + else if (!isa(s)) + reportDuplicate(s, nullptr); + return s; } -Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, - const coff_symbol_generic *Sym, - SectionChunk *C) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, F); - if (WasInserted || !isa(S)) - replaceSymbol(S, F, N, /*IsCOMDAT*/ false, - /*IsExternal*/ true, Sym, C); +Symbol *SymbolTable::addRegular(InputFile *f, StringRef n, + const coff_symbol_generic *sym, + SectionChunk *c) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, f); + if (wasInserted || !isa(s)) + replaceSymbol(s, f, n, /*IsCOMDAT*/ false, + /*IsExternal*/ true, sym, c); else - reportDuplicate(S, F); - return S; + reportDuplicate(s, f); + return s; } std::pair -SymbolTable::addComdat(InputFile *F, StringRef N, - const coff_symbol_generic *Sym) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, F); - if (WasInserted || !isa(S)) { - replaceSymbol(S, F, N, /*IsCOMDAT*/ true, - /*IsExternal*/ true, Sym, nullptr); - return {cast(S), true}; +SymbolTable::addComdat(InputFile *f, StringRef n, + const coff_symbol_generic *sym) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, f); + if (wasInserted || !isa(s)) { + replaceSymbol(s, f, n, /*IsCOMDAT*/ true, + /*IsExternal*/ true, sym, nullptr); + return {cast(s), true}; } - auto *ExistingSymbol = cast(S); - if (!ExistingSymbol->IsCOMDAT) - reportDuplicate(S, F); - return {ExistingSymbol, false}; + auto *existingSymbol = cast(s); + if (!existingSymbol->isCOMDAT) + reportDuplicate(s, f); + return {existingSymbol, false}; } -Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, - const coff_symbol_generic *Sym, CommonChunk *C) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, F); - if (WasInserted || !isa(S)) - replaceSymbol(S, F, N, Size, Sym, C); - else if (auto *DC = dyn_cast(S)) - if (Size > DC->getSize()) - replaceSymbol(S, F, N, Size, Sym, C); - return S; +Symbol *SymbolTable::addCommon(InputFile *f, StringRef n, uint64_t size, + const coff_symbol_generic *sym, CommonChunk *c) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, f); + if (wasInserted || !isa(s)) + replaceSymbol(s, f, n, size, sym, c); + else if (auto *dc = dyn_cast(s)) + if (size > dc->getSize()) + replaceSymbol(s, f, n, size, sym, c); + return s; } -Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(N, nullptr); - S->IsUsedInRegularObj = true; - if (WasInserted || isa(S) || isa(S)) { - replaceSymbol(S, N, F); - return S; +Symbol *SymbolTable::addImportData(StringRef n, ImportFile *f) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(n, nullptr); + s->isUsedInRegularObj = true; + if (wasInserted || isa(s) || isa(s)) { + replaceSymbol(s, n, f); + return s; } - reportDuplicate(S, F); + reportDuplicate(s, f); return nullptr; } -Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, - uint16_t Machine) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, nullptr); - S->IsUsedInRegularObj = true; - if (WasInserted || isa(S) || isa(S)) { - replaceSymbol(S, Name, ID, Machine); - return S; +Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id, + uint16_t machine) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, nullptr); + s->isUsedInRegularObj = true; + if (wasInserted || isa(s) || isa(s)) { + replaceSymbol(s, name, id, machine); + return s; } - reportDuplicate(S, ID->File); + reportDuplicate(s, id->file); return nullptr; } std::vector SymbolTable::getChunks() { - std::vector Res; - for (ObjFile *File : ObjFile::Instances) { - ArrayRef V = File->getChunks(); - Res.insert(Res.end(), V.begin(), V.end()); + std::vector res; + for (ObjFile *file : ObjFile::instances) { + ArrayRef v = file->getChunks(); + res.insert(res.end(), v.begin(), v.end()); } - return Res; + return res; } -Symbol *SymbolTable::find(StringRef Name) { - return SymMap.lookup(CachedHashStringRef(Name)); +Symbol *SymbolTable::find(StringRef name) { + return symMap.lookup(CachedHashStringRef(name)); } -Symbol *SymbolTable::findUnderscore(StringRef Name) { - if (Config->Machine == I386) - return find(("_" + Name).str()); - return find(Name); +Symbol *SymbolTable::findUnderscore(StringRef name) { + if (config->machine == I386) + return find(("_" + name).str()); + return find(name); } // Return all symbols that start with Prefix, possibly ignoring the first // character of Prefix or the first character symbol. -std::vector SymbolTable::getSymsWithPrefix(StringRef Prefix) { - std::vector Syms; - for (auto Pair : SymMap) { - StringRef Name = Pair.first.val(); - if (Name.startswith(Prefix) || Name.startswith(Prefix.drop_front()) || - Name.drop_front().startswith(Prefix) || - Name.drop_front().startswith(Prefix.drop_front())) { - Syms.push_back(Pair.second); +std::vector SymbolTable::getSymsWithPrefix(StringRef prefix) { + std::vector syms; + for (auto pair : symMap) { + StringRef name = pair.first.val(); + if (name.startswith(prefix) || name.startswith(prefix.drop_front()) || + name.drop_front().startswith(prefix) || + name.drop_front().startswith(prefix.drop_front())) { + syms.push_back(pair.second); } } - return Syms; + return syms; } -Symbol *SymbolTable::findMangle(StringRef Name) { - if (Symbol *Sym = find(Name)) - if (!isa(Sym)) - return Sym; +Symbol *SymbolTable::findMangle(StringRef name) { + if (Symbol *sym = find(name)) + if (!isa(sym)) + return sym; // Efficient fuzzy string lookup is impossible with a hash table, so iterate // the symbol table once and collect all possibly matching symbols into this // vector. Then compare each possibly matching symbol with each possible // mangling. - std::vector Syms = getSymsWithPrefix(Name); - auto FindByPrefix = [&Syms](const Twine &T) -> Symbol * { - std::string Prefix = T.str(); - for (auto *S : Syms) - if (S->getName().startswith(Prefix)) - return S; + std::vector syms = getSymsWithPrefix(name); + auto findByPrefix = [&syms](const Twine &t) -> Symbol * { + std::string prefix = t.str(); + for (auto *s : syms) + if (s->getName().startswith(prefix)) + return s; return nullptr; }; // For non-x86, just look for C++ functions. - if (Config->Machine != I386) - return FindByPrefix("?" + Name + "@@Y"); + if (config->machine != I386) + return findByPrefix("?" + name + "@@Y"); - if (!Name.startswith("_")) + if (!name.startswith("_")) return nullptr; // Search for x86 stdcall function. - if (Symbol *S = FindByPrefix(Name + "@")) - return S; + if (Symbol *s = findByPrefix(name + "@")) + return s; // Search for x86 fastcall function. - if (Symbol *S = FindByPrefix("@" + Name.substr(1) + "@")) - return S; + if (Symbol *s = findByPrefix("@" + name.substr(1) + "@")) + return s; // Search for x86 vectorcall function. - if (Symbol *S = FindByPrefix(Name.substr(1) + "@@")) - return S; + if (Symbol *s = findByPrefix(name.substr(1) + "@@")) + return s; // Search for x86 C++ non-member function. - return FindByPrefix("?" + Name.substr(1) + "@@Y"); + return findByPrefix("?" + name.substr(1) + "@@Y"); } -Symbol *SymbolTable::addUndefined(StringRef Name) { - return addUndefined(Name, nullptr, false); +Symbol *SymbolTable::addUndefined(StringRef name) { + return addUndefined(name, nullptr, false); } std::vector SymbolTable::compileBitcodeFiles() { - LTO.reset(new BitcodeCompiler); - for (BitcodeFile *F : BitcodeFile::Instances) - LTO->add(*F); - return LTO->compile(); + lto.reset(new BitcodeCompiler); + for (BitcodeFile *f : BitcodeFile::instances) + lto->add(*f); + return lto->compile(); } void SymbolTable::addCombinedLTOObjects() { - if (BitcodeFile::Instances.empty()) + if (BitcodeFile::instances.empty()) return; - ScopedTimer T(LTOTimer); - for (StringRef Object : compileBitcodeFiles()) { - auto *Obj = make(MemoryBufferRef(Object, "lto.tmp")); - Obj->parse(); - ObjFile::Instances.push_back(Obj); + ScopedTimer t(ltoTimer); + for (StringRef object : compileBitcodeFiles()) { + auto *obj = make(MemoryBufferRef(object, "lto.tmp")); + obj->parse(); + ObjFile::instances.push_back(obj); } } diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 05417cf..75bd393 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -47,7 +47,7 @@ class Symbol; // There is one add* function per symbol type. class SymbolTable { public: - void addFile(InputFile *File); + void addFile(InputFile *file); // Try to resolve any undefined symbols and update the symbol table // accordingly, then print an error message for any remaining undefined @@ -55,20 +55,20 @@ public: void reportRemainingUndefines(); void loadMinGWAutomaticImports(); - bool handleMinGWAutomaticImport(Symbol *Sym, StringRef Name); + bool handleMinGWAutomaticImport(Symbol *sym, StringRef name); // Returns a list of chunks of selected symbols. std::vector getChunks(); // Returns a symbol for a given name. Returns a nullptr if not found. - Symbol *find(StringRef Name); - Symbol *findUnderscore(StringRef Name); + Symbol *find(StringRef name); + Symbol *findUnderscore(StringRef name); // Occasionally we have to resolve an undefined symbol to its // mangled symbol. This function tries to find a mangled name // for U from the symbol table, and if found, set the symbol as // a weak alias for U. - Symbol *findMangle(StringRef Name); + Symbol *findMangle(StringRef name); // Build a set of COFF objects representing the combined contents of // BitcodeFiles and add them to the symbol table. Called after all files are @@ -77,53 +77,53 @@ public: std::vector compileBitcodeFiles(); // Creates an Undefined symbol for a given name. - Symbol *addUndefined(StringRef Name); + Symbol *addUndefined(StringRef name); - Symbol *addSynthetic(StringRef N, Chunk *C); - Symbol *addAbsolute(StringRef N, uint64_t VA); + Symbol *addSynthetic(StringRef n, Chunk *c); + Symbol *addAbsolute(StringRef n, uint64_t va); - Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias); - void addLazy(ArchiveFile *F, const Archive::Symbol Sym); - Symbol *addAbsolute(StringRef N, COFFSymbolRef S); - Symbol *addRegular(InputFile *F, StringRef N, - const llvm::object::coff_symbol_generic *S = nullptr, - SectionChunk *C = nullptr); + Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias); + void addLazy(ArchiveFile *f, const Archive::Symbol sym); + Symbol *addAbsolute(StringRef n, COFFSymbolRef s); + Symbol *addRegular(InputFile *f, StringRef n, + const llvm::object::coff_symbol_generic *s = nullptr, + SectionChunk *c = nullptr); std::pair - addComdat(InputFile *F, StringRef N, - const llvm::object::coff_symbol_generic *S = nullptr); - Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size, - const llvm::object::coff_symbol_generic *S = nullptr, - CommonChunk *C = nullptr); - Symbol *addImportData(StringRef N, ImportFile *F); - Symbol *addImportThunk(StringRef Name, DefinedImportData *S, - uint16_t Machine); + addComdat(InputFile *f, StringRef n, + const llvm::object::coff_symbol_generic *s = nullptr); + Symbol *addCommon(InputFile *f, StringRef n, uint64_t size, + const llvm::object::coff_symbol_generic *s = nullptr, + CommonChunk *c = nullptr); + Symbol *addImportData(StringRef n, ImportFile *f); + Symbol *addImportThunk(StringRef name, DefinedImportData *s, + uint16_t machine); - void reportDuplicate(Symbol *Existing, InputFile *NewFile); + void reportDuplicate(Symbol *existing, InputFile *newFile); // A list of chunks which to be added to .rdata. - std::vector LocalImportChunks; + std::vector localImportChunks; // Iterates symbols in non-determinstic hash table order. - template void forEachSymbol(T Callback) { - for (auto &Pair : SymMap) - Callback(Pair.second); + template void forEachSymbol(T callback) { + for (auto &pair : symMap) + callback(pair.second); } private: /// Inserts symbol if not already present. - std::pair insert(StringRef Name); + std::pair insert(StringRef name); /// Same as insert(Name), but also sets IsUsedInRegularObj. - std::pair insert(StringRef Name, InputFile *F); + std::pair insert(StringRef name, InputFile *f); - std::vector getSymsWithPrefix(StringRef Prefix); + std::vector getSymsWithPrefix(StringRef prefix); - llvm::DenseMap SymMap; - std::unique_ptr LTO; + llvm::DenseMap symMap; + std::unique_ptr lto; }; -extern SymbolTable *Symtab; +extern SymbolTable *symtab; -std::vector getSymbolLocations(ObjFile *File, uint32_t SymIndex); +std::vector getSymbolLocations(ObjFile *file, uint32_t symIndex); } // namespace coff } // namespace lld diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index a23429e..3583d4c 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -24,11 +24,11 @@ static_assert(sizeof(SymbolUnion) <= 48, "symbols should be optimized for memory usage"); // Returns a symbol name for an error message. -std::string lld::toString(coff::Symbol &B) { - if (Config->Demangle) - if (Optional S = lld::demangleMSVC(B.getName())) - return *S; - return B.getName(); +std::string lld::toString(coff::Symbol &b) { + if (config->demangle) + if (Optional s = lld::demangleMSVC(b.getName())) + return *s; + return b.getName(); } namespace lld { @@ -42,75 +42,75 @@ StringRef Symbol::getName() { // name. Object files contain lots of non-external symbols, and creating // StringRefs for them (which involves lots of strlen() on the string table) // is a waste of time. - if (NameData == nullptr) { - auto *D = cast(this); - StringRef NameStr; - cast(D->File)->getCOFFObj()->getSymbolName(D->Sym, NameStr); - NameData = NameStr.data(); - NameSize = NameStr.size(); - assert(NameSize == NameStr.size() && "name length truncated"); + if (nameData == nullptr) { + auto *d = cast(this); + StringRef nameStr; + cast(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr); + nameData = nameStr.data(); + nameSize = nameStr.size(); + assert(nameSize == nameStr.size() && "name length truncated"); } - return StringRef(NameData, NameSize); + return StringRef(nameData, nameSize); } InputFile *Symbol::getFile() { - if (auto *Sym = dyn_cast(this)) - return Sym->File; - if (auto *Sym = dyn_cast(this)) - return Sym->File; + if (auto *sym = dyn_cast(this)) + return sym->file; + if (auto *sym = dyn_cast(this)) + return sym->file; return nullptr; } bool Symbol::isLive() const { - if (auto *R = dyn_cast(this)) - return R->getChunk()->Live; - if (auto *Imp = dyn_cast(this)) - return Imp->File->Live; - if (auto *Imp = dyn_cast(this)) - return Imp->WrappedSym->File->ThunkLive; + if (auto *r = dyn_cast(this)) + return r->getChunk()->live; + if (auto *imp = dyn_cast(this)) + return imp->file->live; + if (auto *imp = dyn_cast(this)) + return imp->wrappedSym->file->thunkLive; // Assume any other kind of symbol is live. return true; } // MinGW specific. -void Symbol::replaceKeepingName(Symbol *Other, size_t Size) { - StringRef OrigName = getName(); - memcpy(this, Other, Size); - NameData = OrigName.data(); - NameSize = OrigName.size(); +void Symbol::replaceKeepingName(Symbol *other, size_t size) { + StringRef origName = getName(); + memcpy(this, other, size); + nameData = origName.data(); + nameSize = origName.size(); } COFFSymbolRef DefinedCOFF::getCOFFSymbol() { - size_t SymSize = cast(File)->getCOFFObj()->getSymbolTableEntrySize(); - if (SymSize == sizeof(coff_symbol16)) - return COFFSymbolRef(reinterpret_cast(Sym)); - assert(SymSize == sizeof(coff_symbol32)); - return COFFSymbolRef(reinterpret_cast(Sym)); + size_t symSize = cast(file)->getCOFFObj()->getSymbolTableEntrySize(); + if (symSize == sizeof(coff_symbol16)) + return COFFSymbolRef(reinterpret_cast(sym)); + assert(symSize == sizeof(coff_symbol32)); + return COFFSymbolRef(reinterpret_cast(sym)); } -uint16_t DefinedAbsolute::NumOutputSections; +uint16_t DefinedAbsolute::numOutputSections; -static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { - if (Machine == AMD64) - return make(S); - if (Machine == I386) - return make(S); - if (Machine == ARM64) - return make(S); - assert(Machine == ARMNT); - return make(S); +static Chunk *makeImportThunk(DefinedImportData *s, uint16_t machine) { + if (machine == AMD64) + return make(s); + if (machine == I386) + return make(s); + if (machine == ARM64) + return make(s); + assert(machine == ARMNT); + return make(s); } -DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, - uint16_t Machine) - : Defined(DefinedImportThunkKind, Name), WrappedSym(S), - Data(makeImportThunk(S, Machine)) {} +DefinedImportThunk::DefinedImportThunk(StringRef name, DefinedImportData *s, + uint16_t machine) + : Defined(DefinedImportThunkKind, name), wrappedSym(s), + data(makeImportThunk(s, machine)) {} Defined *Undefined::getWeakAlias() { // A weak alias may be a weak alias to another symbol, so check recursively. - for (Symbol *A = WeakAlias; A; A = cast(A)->WeakAlias) - if (auto *D = dyn_cast(A)) - return D; + for (Symbol *a = weakAlias; a; a = cast(a)->weakAlias) + if (auto *d = dyn_cast(a)) + return d; return nullptr; } } // namespace coff diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 53e45a8..86cd4f5 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -57,12 +57,12 @@ public: LastDefinedKind = DefinedSyntheticKind, }; - Kind kind() const { return static_cast(SymbolKind); } + Kind kind() const { return static_cast(symbolKind); } // Returns the symbol name. StringRef getName(); - void replaceKeepingName(Symbol *Other, size_t Size); + void replaceKeepingName(Symbol *other, size_t size); // Returns the file from which this symbol was created. InputFile *getFile(); @@ -73,50 +73,50 @@ public: protected: friend SymbolTable; - explicit Symbol(Kind K, StringRef N = "") - : SymbolKind(K), IsExternal(true), IsCOMDAT(false), - WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false), - IsRuntimePseudoReloc(false), NameSize(N.size()), - NameData(N.empty() ? nullptr : N.data()) {} + explicit Symbol(Kind k, StringRef n = "") + : symbolKind(k), isExternal(true), isCOMDAT(false), + writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false), + isRuntimePseudoReloc(false), nameSize(n.size()), + nameData(n.empty() ? nullptr : n.data()) {} - const unsigned SymbolKind : 8; - unsigned IsExternal : 1; + const unsigned symbolKind : 8; + unsigned isExternal : 1; public: // This bit is used by the \c DefinedRegular subclass. - unsigned IsCOMDAT : 1; + unsigned isCOMDAT : 1; // This bit is used by Writer::createSymbolAndStringTable() to prevent // symbols from being written to the symbol table more than once. - unsigned WrittenToSymtab : 1; + unsigned writtenToSymtab : 1; // True if this symbol was referenced by a regular (non-bitcode) object. - unsigned IsUsedInRegularObj : 1; + unsigned isUsedInRegularObj : 1; // True if we've seen both a lazy and an undefined symbol with this symbol // name, which means that we have enqueued an archive member load and should // not load any more archive members to resolve the same symbol. - unsigned PendingArchiveLoad : 1; + unsigned pendingArchiveLoad : 1; /// True if we've already added this symbol to the list of GC roots. - unsigned IsGCRoot : 1; + unsigned isGCRoot : 1; - unsigned IsRuntimePseudoReloc : 1; + unsigned isRuntimePseudoReloc : 1; protected: // Symbol name length. Assume symbol lengths fit in a 32-bit integer. - uint32_t NameSize; + uint32_t nameSize; - const char *NameData; + const char *nameData; }; // The base class for any defined symbols, including absolute symbols, // etc. class Defined : public Symbol { public: - Defined(Kind K, StringRef N) : Symbol(K, N) {} + Defined(Kind k, StringRef n) : Symbol(k, n) {} - static bool classof(const Symbol *S) { return S->kind() <= LastDefinedKind; } + static bool classof(const Symbol *s) { return s->kind() <= LastDefinedKind; } // Returns the RVA (relative virtual address) of this symbol. The // writer sets and uses RVAs. @@ -135,114 +135,114 @@ class DefinedCOFF : public Defined { friend Symbol; public: - DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S) - : Defined(K, N), File(F), Sym(S) {} + DefinedCOFF(Kind k, InputFile *f, StringRef n, const coff_symbol_generic *s) + : Defined(k, n), file(f), sym(s) {} - static bool classof(const Symbol *S) { - return S->kind() <= LastDefinedCOFFKind; + static bool classof(const Symbol *s) { + return s->kind() <= LastDefinedCOFFKind; } - InputFile *getFile() { return File; } + InputFile *getFile() { return file; } COFFSymbolRef getCOFFSymbol(); - InputFile *File; + InputFile *file; protected: - const coff_symbol_generic *Sym; + const coff_symbol_generic *sym; }; // Regular defined symbols read from object file symbol tables. class DefinedRegular : public DefinedCOFF { public: - DefinedRegular(InputFile *F, StringRef N, bool IsCOMDAT, - bool IsExternal = false, - const coff_symbol_generic *S = nullptr, - SectionChunk *C = nullptr) - : DefinedCOFF(DefinedRegularKind, F, N, S), Data(C ? &C->Repl : nullptr) { - this->IsExternal = IsExternal; - this->IsCOMDAT = IsCOMDAT; + DefinedRegular(InputFile *f, StringRef n, bool isCOMDAT, + bool isExternal = false, + const coff_symbol_generic *s = nullptr, + SectionChunk *c = nullptr) + : DefinedCOFF(DefinedRegularKind, f, n, s), data(c ? &c->repl : nullptr) { + this->isExternal = isExternal; + this->isCOMDAT = isCOMDAT; } - static bool classof(const Symbol *S) { - return S->kind() == DefinedRegularKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedRegularKind; } - uint64_t getRVA() const { return (*Data)->getRVA() + Sym->Value; } - SectionChunk *getChunk() const { return *Data; } - uint32_t getValue() const { return Sym->Value; } + uint64_t getRVA() const { return (*data)->getRVA() + sym->Value; } + SectionChunk *getChunk() const { return *data; } + uint32_t getValue() const { return sym->Value; } - SectionChunk **Data; + SectionChunk **data; }; class DefinedCommon : public DefinedCOFF { public: - DefinedCommon(InputFile *F, StringRef N, uint64_t Size, - const coff_symbol_generic *S = nullptr, - CommonChunk *C = nullptr) - : DefinedCOFF(DefinedCommonKind, F, N, S), Data(C), Size(Size) { - this->IsExternal = true; + DefinedCommon(InputFile *f, StringRef n, uint64_t size, + const coff_symbol_generic *s = nullptr, + CommonChunk *c = nullptr) + : DefinedCOFF(DefinedCommonKind, f, n, s), data(c), size(size) { + this->isExternal = true; } - static bool classof(const Symbol *S) { - return S->kind() == DefinedCommonKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedCommonKind; } - uint64_t getRVA() { return Data->getRVA(); } - CommonChunk *getChunk() { return Data; } + uint64_t getRVA() { return data->getRVA(); } + CommonChunk *getChunk() { return data; } private: friend SymbolTable; - uint64_t getSize() const { return Size; } - CommonChunk *Data; - uint64_t Size; + uint64_t getSize() const { return size; } + CommonChunk *data; + uint64_t size; }; // Absolute symbols. class DefinedAbsolute : public Defined { public: - DefinedAbsolute(StringRef N, COFFSymbolRef S) - : Defined(DefinedAbsoluteKind, N), VA(S.getValue()) { - IsExternal = S.isExternal(); + DefinedAbsolute(StringRef n, COFFSymbolRef s) + : Defined(DefinedAbsoluteKind, n), va(s.getValue()) { + isExternal = s.isExternal(); } - DefinedAbsolute(StringRef N, uint64_t V) - : Defined(DefinedAbsoluteKind, N), VA(V) {} + DefinedAbsolute(StringRef n, uint64_t v) + : Defined(DefinedAbsoluteKind, n), va(v) {} - static bool classof(const Symbol *S) { - return S->kind() == DefinedAbsoluteKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedAbsoluteKind; } - uint64_t getRVA() { return VA - Config->ImageBase; } - void setVA(uint64_t V) { VA = V; } + uint64_t getRVA() { return va - config->imageBase; } + void setVA(uint64_t v) { va = v; } // Section index relocations against absolute symbols resolve to // this 16 bit number, and it is the largest valid section index // plus one. This variable keeps it. - static uint16_t NumOutputSections; + static uint16_t numOutputSections; private: - uint64_t VA; + uint64_t va; }; // This symbol is used for linker-synthesized symbols like __ImageBase and // __safe_se_handler_table. class DefinedSynthetic : public Defined { public: - explicit DefinedSynthetic(StringRef Name, Chunk *C) - : Defined(DefinedSyntheticKind, Name), C(C) {} + explicit DefinedSynthetic(StringRef name, Chunk *c) + : Defined(DefinedSyntheticKind, name), c(c) {} - static bool classof(const Symbol *S) { - return S->kind() == DefinedSyntheticKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedSyntheticKind; } // A null chunk indicates that this is __ImageBase. Otherwise, this is some // other synthesized chunk, like SEHTableChunk. - uint32_t getRVA() { return C ? C->getRVA() : 0; } - Chunk *getChunk() { return C; } + uint32_t getRVA() { return c ? c->getRVA() : 0; } + Chunk *getChunk() { return c; } private: - Chunk *C; + Chunk *c; }; // This class represents a symbol defined in an archive file. It is @@ -252,32 +252,32 @@ private: // the same name, it will ask the Lazy to load a file. class Lazy : public Symbol { public: - Lazy(ArchiveFile *F, const Archive::Symbol S) - : Symbol(LazyKind, S.getName()), File(F), Sym(S) {} + Lazy(ArchiveFile *f, const Archive::Symbol s) + : Symbol(LazyKind, s.getName()), file(f), sym(s) {} - static bool classof(const Symbol *S) { return S->kind() == LazyKind; } + static bool classof(const Symbol *s) { return s->kind() == LazyKind; } - ArchiveFile *File; + ArchiveFile *file; private: friend SymbolTable; private: - const Archive::Symbol Sym; + const Archive::Symbol sym; }; // Undefined symbols. class Undefined : public Symbol { public: - explicit Undefined(StringRef N) : Symbol(UndefinedKind, N) {} + explicit Undefined(StringRef n) : Symbol(UndefinedKind, n) {} - static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; } + static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; } // An undefined symbol can have a fallback symbol which gives an // undefined symbol a second chance if it would remain undefined. // If it remains undefined, it'll be replaced with whatever the // Alias pointer points to. - Symbol *WeakAlias = nullptr; + Symbol *weakAlias = nullptr; // If this symbol is external weak, try to resolve it to a defined // symbol by searching the chain of fallback symbols. Returns the symbol if @@ -293,23 +293,23 @@ public: // table in an output. The former has "__imp_" prefix. class DefinedImportData : public Defined { public: - DefinedImportData(StringRef N, ImportFile *F) - : Defined(DefinedImportDataKind, N), File(F) { + DefinedImportData(StringRef n, ImportFile *f) + : Defined(DefinedImportDataKind, n), file(f) { } - static bool classof(const Symbol *S) { - return S->kind() == DefinedImportDataKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedImportDataKind; } - uint64_t getRVA() { return File->Location->getRVA(); } - Chunk *getChunk() { return File->Location; } - void setLocation(Chunk *AddressTable) { File->Location = AddressTable; } + uint64_t getRVA() { return file->location->getRVA(); } + Chunk *getChunk() { return file->location; } + void setLocation(Chunk *addressTable) { file->location = addressTable; } - StringRef getDLLName() { return File->DLLName; } - StringRef getExternalName() { return File->ExternalName; } - uint16_t getOrdinal() { return File->Hdr->OrdinalHint; } + StringRef getDLLName() { return file->dllName; } + StringRef getExternalName() { return file->externalName; } + uint16_t getOrdinal() { return file->hdr->OrdinalHint; } - ImportFile *File; + ImportFile *file; }; // This class represents a symbol for a jump table entry which jumps @@ -319,19 +319,19 @@ public: // a regular name. A function pointer is given as a DefinedImportData. class DefinedImportThunk : public Defined { public: - DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine); + DefinedImportThunk(StringRef name, DefinedImportData *s, uint16_t machine); - static bool classof(const Symbol *S) { - return S->kind() == DefinedImportThunkKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedImportThunkKind; } - uint64_t getRVA() { return Data->getRVA(); } - Chunk *getChunk() { return Data; } + uint64_t getRVA() { return data->getRVA(); } + Chunk *getChunk() { return data; } - DefinedImportData *WrappedSym; + DefinedImportData *wrappedSym; private: - Chunk *Data; + Chunk *data; }; // If you have a symbol "foo" in your object file, a symbol name @@ -341,18 +341,18 @@ private: // This is here just for compatibility with MSVC. class DefinedLocalImport : public Defined { public: - DefinedLocalImport(StringRef N, Defined *S) - : Defined(DefinedLocalImportKind, N), Data(make(S)) {} + DefinedLocalImport(StringRef n, Defined *s) + : Defined(DefinedLocalImportKind, n), data(make(s)) {} - static bool classof(const Symbol *S) { - return S->kind() == DefinedLocalImportKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedLocalImportKind; } - uint64_t getRVA() { return Data->getRVA(); } - Chunk *getChunk() { return Data; } + uint64_t getRVA() { return data->getRVA(); } + Chunk *getChunk() { return data; } private: - LocalImportChunk *Data; + LocalImportChunk *data; }; inline uint64_t Defined::getRVA() { @@ -405,19 +405,19 @@ inline Chunk *Defined::getChunk() { // object. We allocate memory using this class and instantiate a symbol // using the placement new. union SymbolUnion { - alignas(DefinedRegular) char A[sizeof(DefinedRegular)]; - alignas(DefinedCommon) char B[sizeof(DefinedCommon)]; - alignas(DefinedAbsolute) char C[sizeof(DefinedAbsolute)]; - alignas(DefinedSynthetic) char D[sizeof(DefinedSynthetic)]; - alignas(Lazy) char E[sizeof(Lazy)]; - alignas(Undefined) char F[sizeof(Undefined)]; - alignas(DefinedImportData) char G[sizeof(DefinedImportData)]; - alignas(DefinedImportThunk) char H[sizeof(DefinedImportThunk)]; - alignas(DefinedLocalImport) char I[sizeof(DefinedLocalImport)]; + alignas(DefinedRegular) char a[sizeof(DefinedRegular)]; + alignas(DefinedCommon) char b[sizeof(DefinedCommon)]; + alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)]; + alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)]; + alignas(Lazy) char e[sizeof(Lazy)]; + alignas(Undefined) char f[sizeof(Undefined)]; + alignas(DefinedImportData) char g[sizeof(DefinedImportData)]; + alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)]; + alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)]; }; template -void replaceSymbol(Symbol *S, ArgT &&... Arg) { +void replaceSymbol(Symbol *s, ArgT &&... arg) { static_assert(std::is_trivially_destructible(), "Symbol types must be trivially destructible"); static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); @@ -425,11 +425,11 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) { "SymbolUnion not aligned enough"); assert(static_cast(static_cast(nullptr)) == nullptr && "Not a Symbol"); - new (S) T(std::forward(Arg)...); + new (s) T(std::forward(arg)...); } } // namespace coff -std::string toString(coff::Symbol &B); +std::string toString(coff::Symbol &b); } // namespace lld #endif diff --git a/lld/COFF/TypeMerger.h b/lld/COFF/TypeMerger.h index 6580770..e2cfe66 100644 --- a/lld/COFF/TypeMerger.h +++ b/lld/COFF/TypeMerger.h @@ -19,44 +19,44 @@ namespace coff { class TypeMerger { public: - TypeMerger(llvm::BumpPtrAllocator &Alloc) - : TypeTable(Alloc), IDTable(Alloc), GlobalTypeTable(Alloc), - GlobalIDTable(Alloc) {} + TypeMerger(llvm::BumpPtrAllocator &alloc) + : typeTable(alloc), iDTable(alloc), globalTypeTable(alloc), + globalIDTable(alloc) {} /// Get the type table or the global type table if /DEBUG:GHASH is enabled. inline llvm::codeview::TypeCollection &getTypeTable() { - if (Config->DebugGHashes) - return GlobalTypeTable; - return TypeTable; + if (config->debugGHashes) + return globalTypeTable; + return typeTable; } /// Get the ID table or the global ID table if /DEBUG:GHASH is enabled. inline llvm::codeview::TypeCollection &getIDTable() { - if (Config->DebugGHashes) - return GlobalIDTable; - return IDTable; + if (config->debugGHashes) + return globalIDTable; + return iDTable; } /// Type records that will go into the PDB TPI stream. - llvm::codeview::MergingTypeTableBuilder TypeTable; + llvm::codeview::MergingTypeTableBuilder typeTable; /// Item records that will go into the PDB IPI stream. - llvm::codeview::MergingTypeTableBuilder IDTable; + llvm::codeview::MergingTypeTableBuilder iDTable; /// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH) - llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable; + llvm::codeview::GlobalTypeTableBuilder globalTypeTable; /// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH) - llvm::codeview::GlobalTypeTableBuilder GlobalIDTable; + llvm::codeview::GlobalTypeTableBuilder globalIDTable; }; /// Map from type index and item index in a type server PDB to the /// corresponding index in the destination PDB. struct CVIndexMap { - llvm::SmallVector TPIMap; - llvm::SmallVector IPIMap; - bool IsTypeServerMap = false; - bool IsPrecompiledTypeMap = false; + llvm::SmallVector tpiMap; + llvm::SmallVector ipiMap; + bool isTypeServerMap = false; + bool isPrecompiledTypeMap = false; }; } // namespace coff diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 64ed0a1..46b1af0 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -63,105 +63,105 @@ align 8, db 0 $ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin $ xxd -i /tmp/DOSProgram.bin */ -static unsigned char DOSProgram[] = { +static unsigned char dosProgram[] = { 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x24, 0x00, 0x00 }; -static_assert(sizeof(DOSProgram) % 8 == 0, +static_assert(sizeof(dosProgram) % 8 == 0, "DOSProgram size must be multiple of 8"); -static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram); -static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8"); +static const int dosStubSize = sizeof(dos_header) + sizeof(dosProgram); +static_assert(dosStubSize % 8 == 0, "DOSStub size must be multiple of 8"); -static const int NumberOfDataDirectory = 16; +static const int numberOfDataDirectory = 16; // Global vector of all output sections. After output sections are finalized, // this can be indexed by Chunk::getOutputSection. -static std::vector OutputSections; +static std::vector outputSections; OutputSection *Chunk::getOutputSection() const { - return OSIdx == 0 ? nullptr : OutputSections[OSIdx - 1]; + return osidx == 0 ? nullptr : outputSections[osidx - 1]; } namespace { class DebugDirectoryChunk : public NonSectionChunk { public: - DebugDirectoryChunk(const std::vector &R, bool WriteRepro) - : Records(R), WriteRepro(WriteRepro) {} + DebugDirectoryChunk(const std::vector &r, bool writeRepro) + : records(r), writeRepro(writeRepro) {} size_t getSize() const override { - return (Records.size() + int(WriteRepro)) * sizeof(debug_directory); + return (records.size() + int(writeRepro)) * sizeof(debug_directory); } - void writeTo(uint8_t *B) const override { - auto *D = reinterpret_cast(B); + void writeTo(uint8_t *b) const override { + auto *d = reinterpret_cast(b); - for (const Chunk *Record : Records) { - OutputSection *OS = Record->getOutputSection(); - uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA()); - fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(), - Record->getRVA(), Offs); - ++D; + for (const Chunk *record : records) { + OutputSection *os = record->getOutputSection(); + uint64_t offs = os->getFileOff() + (record->getRVA() - os->getRVA()); + fillEntry(d, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, record->getSize(), + record->getRVA(), offs); + ++d; } - if (WriteRepro) { + if (writeRepro) { // FIXME: The COFF spec allows either a 0-sized entry to just say // "the timestamp field is really a hash", or a 4-byte size field // followed by that many bytes containing a longer hash (with the // lowest 4 bytes usually being the timestamp in little-endian order). // Consider storing the full 8 bytes computed by xxHash64 here. - fillEntry(D, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0); + fillEntry(d, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0); } } - void setTimeDateStamp(uint32_t TimeDateStamp) { - for (support::ulittle32_t *TDS : TimeDateStamps) - *TDS = TimeDateStamp; + void setTimeDateStamp(uint32_t timeDateStamp) { + for (support::ulittle32_t *tds : timeDateStamps) + *tds = timeDateStamp; } private: - void fillEntry(debug_directory *D, COFF::DebugType DebugType, size_t Size, - uint64_t RVA, uint64_t Offs) const { - D->Characteristics = 0; - D->TimeDateStamp = 0; - D->MajorVersion = 0; - D->MinorVersion = 0; - D->Type = DebugType; - D->SizeOfData = Size; - D->AddressOfRawData = RVA; - D->PointerToRawData = Offs; - - TimeDateStamps.push_back(&D->TimeDateStamp); - } - - mutable std::vector TimeDateStamps; - const std::vector &Records; - bool WriteRepro; + void fillEntry(debug_directory *d, COFF::DebugType debugType, size_t size, + uint64_t rva, uint64_t offs) const { + d->Characteristics = 0; + d->TimeDateStamp = 0; + d->MajorVersion = 0; + d->MinorVersion = 0; + d->Type = debugType; + d->SizeOfData = size; + d->AddressOfRawData = rva; + d->PointerToRawData = offs; + + timeDateStamps.push_back(&d->TimeDateStamp); + } + + mutable std::vector timeDateStamps; + const std::vector &records; + bool writeRepro; }; class CVDebugRecordChunk : public NonSectionChunk { public: size_t getSize() const override { - return sizeof(codeview::DebugInfo) + Config->PDBAltPath.size() + 1; + return sizeof(codeview::DebugInfo) + config->pdbAltPath.size() + 1; } - void writeTo(uint8_t *B) const override { + void writeTo(uint8_t *b) const override { // Save off the DebugInfo entry to backfill the file signature (build id) // in Writer::writeBuildId - BuildId = reinterpret_cast(B); + buildId = reinterpret_cast(b); // variable sized field (PDB Path) - char *P = reinterpret_cast(B + sizeof(*BuildId)); - if (!Config->PDBAltPath.empty()) - memcpy(P, Config->PDBAltPath.data(), Config->PDBAltPath.size()); - P[Config->PDBAltPath.size()] = '\0'; + char *p = reinterpret_cast(b + sizeof(*buildId)); + if (!config->pdbAltPath.empty()) + memcpy(p, config->pdbAltPath.data(), config->pdbAltPath.size()); + p[config->pdbAltPath.size()] = '\0'; } - mutable codeview::DebugInfo *BuildId = nullptr; + mutable codeview::DebugInfo *buildId = nullptr; }; // PartialSection represents a group of chunks that contribute to an @@ -169,15 +169,15 @@ public: // characteristics constitutes the OutputSection. class PartialSectionKey { public: - StringRef Name; - unsigned Characteristics; + StringRef name; + unsigned characteristics; - bool operator<(const PartialSectionKey &Other) const { - int C = Name.compare(Other.Name); - if (C == 1) + bool operator<(const PartialSectionKey &other) const { + int c = name.compare(other.name); + if (c == 1) return false; - if (C == 0) - return Characteristics < Other.Characteristics; + if (c == 0) + return characteristics < other.characteristics; return true; } }; @@ -185,7 +185,7 @@ public: // The writer writes a SymbolTable result to a file. class Writer { public: - Writer() : Buffer(errorHandler().OutputBuffer) {} + Writer() : buffer(errorHandler().outputBuffer) {} void run(); private: @@ -202,72 +202,72 @@ private: void removeEmptySections(); void assignOutputSectionIndices(); void createSymbolAndStringTable(); - void openFile(StringRef OutputPath); + void openFile(StringRef outputPath); template void writeHeader(); void createSEHTable(); void createRuntimePseudoRelocs(); void insertCtorDtorSymbols(); void createGuardCFTables(); - void markSymbolsForRVATable(ObjFile *File, - ArrayRef SymIdxChunks, - SymbolRVASet &TableSymbols); - void maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym, - StringRef CountSym); + void markSymbolsForRVATable(ObjFile *file, + ArrayRef symIdxChunks, + SymbolRVASet &tableSymbols); + void maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym, + StringRef countSym); void setSectionPermissions(); void writeSections(); void writeBuildId(); void sortExceptionTable(); - void sortCRTSectionChunks(std::vector &Chunks); + void sortCRTSectionChunks(std::vector &chunks); void addSyntheticIdata(); - void fixPartialSectionChars(StringRef Name, uint32_t Chars); + void fixPartialSectionChars(StringRef name, uint32_t chars); bool fixGnuImportChunks(); - PartialSection *createPartialSection(StringRef Name, uint32_t OutChars); - PartialSection *findPartialSection(StringRef Name, uint32_t OutChars); + PartialSection *createPartialSection(StringRef name, uint32_t outChars); + PartialSection *findPartialSection(StringRef name, uint32_t outChars); - llvm::Optional createSymbol(Defined *D); - size_t addEntryToStringTable(StringRef Str); + llvm::Optional createSymbol(Defined *d); + size_t addEntryToStringTable(StringRef str); - OutputSection *findSection(StringRef Name); + OutputSection *findSection(StringRef name); void addBaserels(); - void addBaserelBlocks(std::vector &V); + void addBaserelBlocks(std::vector &v); uint32_t getSizeOfInitializedData(); - std::unique_ptr &Buffer; - std::map PartialSections; - std::vector Strtab; - std::vector OutputSymtab; - IdataContents Idata; - Chunk *ImportTableStart = nullptr; - uint64_t ImportTableSize = 0; - Chunk *IATStart = nullptr; - uint64_t IATSize = 0; - DelayLoadContents DelayIdata; - EdataContents Edata; - bool SetNoSEHCharacteristic = false; - - DebugDirectoryChunk *DebugDirectory = nullptr; - std::vector DebugRecords; - CVDebugRecordChunk *BuildId = nullptr; - ArrayRef SectionTable; - - uint64_t FileSize; - uint32_t PointerToSymbolTable = 0; - uint64_t SizeOfImage; - uint64_t SizeOfHeaders; - - OutputSection *TextSec; - OutputSection *RdataSec; - OutputSection *BuildidSec; - OutputSection *DataSec; - OutputSection *PdataSec; - OutputSection *IdataSec; - OutputSection *EdataSec; - OutputSection *DidatSec; - OutputSection *RsrcSec; - OutputSection *RelocSec; - OutputSection *CtorsSec; - OutputSection *DtorsSec; + std::unique_ptr &buffer; + std::map partialSections; + std::vector strtab; + std::vector outputSymtab; + IdataContents idata; + Chunk *importTableStart = nullptr; + uint64_t importTableSize = 0; + Chunk *iatStart = nullptr; + uint64_t iatSize = 0; + DelayLoadContents delayIdata; + EdataContents edata; + bool setNoSEHCharacteristic = false; + + DebugDirectoryChunk *debugDirectory = nullptr; + std::vector debugRecords; + CVDebugRecordChunk *buildId = nullptr; + ArrayRef sectionTable; + + uint64_t fileSize; + uint32_t pointerToSymbolTable = 0; + uint64_t sizeOfImage; + uint64_t sizeOfHeaders; + + OutputSection *textSec; + OutputSection *rdataSec; + OutputSection *buildidSec; + OutputSection *dataSec; + OutputSection *pdataSec; + OutputSection *idataSec; + OutputSection *edataSec; + OutputSection *didatSec; + OutputSection *rsrcSec; + OutputSection *relocSec; + OutputSection *ctorsSec; + OutputSection *dtorsSec; // The first and last .pdata sections in the output file. // @@ -278,57 +278,57 @@ private: // are entirely linker-generated we can keep track of their locations using // the chunks that the linker creates. All .pdata chunks come from input // files, so we need to keep track of them separately. - Chunk *FirstPdata = nullptr; - Chunk *LastPdata; + Chunk *firstPdata = nullptr; + Chunk *lastPdata; }; } // anonymous namespace namespace lld { namespace coff { -static Timer CodeLayoutTimer("Code Layout", Timer::root()); -static Timer DiskCommitTimer("Commit Output File", Timer::root()); +static Timer codeLayoutTimer("Code Layout", Timer::root()); +static Timer diskCommitTimer("Commit Output File", Timer::root()); void writeResult() { Writer().run(); } -void OutputSection::addChunk(Chunk *C) { - Chunks.push_back(C); +void OutputSection::addChunk(Chunk *c) { + chunks.push_back(c); } -void OutputSection::insertChunkAtStart(Chunk *C) { - Chunks.insert(Chunks.begin(), C); +void OutputSection::insertChunkAtStart(Chunk *c) { + chunks.insert(chunks.begin(), c); } -void OutputSection::setPermissions(uint32_t C) { - Header.Characteristics &= ~PermMask; - Header.Characteristics |= C; +void OutputSection::setPermissions(uint32_t c) { + header.Characteristics &= ~permMask; + header.Characteristics |= c; } -void OutputSection::merge(OutputSection *Other) { - Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end()); - Other->Chunks.clear(); - ContribSections.insert(ContribSections.end(), Other->ContribSections.begin(), - Other->ContribSections.end()); - Other->ContribSections.clear(); +void OutputSection::merge(OutputSection *other) { + chunks.insert(chunks.end(), other->chunks.begin(), other->chunks.end()); + other->chunks.clear(); + contribSections.insert(contribSections.end(), other->contribSections.begin(), + other->contribSections.end()); + other->contribSections.clear(); } // Write the section header to a given buffer. -void OutputSection::writeHeaderTo(uint8_t *Buf) { - auto *Hdr = reinterpret_cast(Buf); - *Hdr = Header; - if (StringTableOff) { +void OutputSection::writeHeaderTo(uint8_t *buf) { + auto *hdr = reinterpret_cast(buf); + *hdr = header; + if (stringTableOff) { // If name is too long, write offset into the string table as a name. - sprintf(Hdr->Name, "/%d", StringTableOff); + sprintf(hdr->Name, "/%d", stringTableOff); } else { - assert(!Config->Debug || Name.size() <= COFF::NameSize || - (Hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0); - strncpy(Hdr->Name, Name.data(), - std::min(Name.size(), (size_t)COFF::NameSize)); + assert(!config->debug || name.size() <= COFF::NameSize || + (hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0); + strncpy(hdr->Name, name.data(), + std::min(name.size(), (size_t)COFF::NameSize)); } } -void OutputSection::addContributingPartialSection(PartialSection *Sec) { - ContribSections.push_back(Sec); +void OutputSection::addContributingPartialSection(PartialSection *sec) { + contribSections.push_back(sec); } } // namespace coff @@ -336,27 +336,27 @@ void OutputSection::addContributingPartialSection(PartialSection *Sec) { // Check whether the target address S is in range from a relocation // of type RelType at address P. -static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) { - if (Config->Machine == ARMNT) { - int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; - switch (RelType) { +static bool isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin) { + if (config->machine == ARMNT) { + int64_t diff = AbsoluteDifference(s, p + 4) + margin; + switch (relType) { case IMAGE_REL_ARM_BRANCH20T: - return isInt<21>(Diff); + return isInt<21>(diff); case IMAGE_REL_ARM_BRANCH24T: case IMAGE_REL_ARM_BLX23T: - return isInt<25>(Diff); + return isInt<25>(diff); default: return true; } - } else if (Config->Machine == ARM64) { - int64_t Diff = AbsoluteDifference(S, P) + Margin; - switch (RelType) { + } else if (config->machine == ARM64) { + int64_t diff = AbsoluteDifference(s, p) + margin; + switch (relType) { case IMAGE_REL_ARM64_BRANCH26: - return isInt<28>(Diff); + return isInt<28>(diff); case IMAGE_REL_ARM64_BRANCH19: - return isInt<21>(Diff); + return isInt<21>(diff); case IMAGE_REL_ARM64_BRANCH14: - return isInt<16>(Diff); + return isInt<16>(diff); default: return true; } @@ -368,25 +368,25 @@ static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) { // Return the last thunk for the given target if it is in range, // or create a new one. static std::pair -getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, - uint16_t Type, int Margin) { - Defined *&LastThunk = LastThunks[Target->getRVA()]; - if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin)) - return {LastThunk, false}; - Chunk *C; - switch (Config->Machine) { +getThunk(DenseMap &lastThunks, Defined *target, uint64_t p, + uint16_t type, int margin) { + Defined *&lastThunk = lastThunks[target->getRVA()]; + if (lastThunk && isInRange(type, lastThunk->getRVA(), p, margin)) + return {lastThunk, false}; + Chunk *c; + switch (config->machine) { case ARMNT: - C = make(Target); + c = make(target); break; case ARM64: - C = make(Target); + c = make(target); break; default: llvm_unreachable("Unexpected architecture"); } - Defined *D = make("", C); - LastThunk = D; - return {D, true}; + Defined *d = make("", c); + lastThunk = d; + return {d, true}; } // This checks all relocations, and for any relocation which isn't in range @@ -400,124 +400,124 @@ getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, // After adding thunks, we verify that all relocations are in range (with // no extra margin requirements). If this failed, we restart (throwing away // the previously created thunks) and retry with a wider margin. -static bool createThunks(OutputSection *OS, int Margin) { - bool AddressesChanged = false; - DenseMap LastThunks; - DenseMap, uint32_t> ThunkSymtabIndices; - size_t ThunksSize = 0; +static bool createThunks(OutputSection *os, int margin) { + bool addressesChanged = false; + DenseMap lastThunks; + DenseMap, uint32_t> thunkSymtabIndices; + size_t thunksSize = 0; // Recheck Chunks.size() each iteration, since we can insert more // elements into it. - for (size_t I = 0; I != OS->Chunks.size(); ++I) { - SectionChunk *SC = dyn_cast_or_null(OS->Chunks[I]); - if (!SC) + for (size_t i = 0; i != os->chunks.size(); ++i) { + SectionChunk *sc = dyn_cast_or_null(os->chunks[i]); + if (!sc) continue; - size_t ThunkInsertionSpot = I + 1; + size_t thunkInsertionSpot = i + 1; // Try to get a good enough estimate of where new thunks will be placed. // Offset this by the size of the new thunks added so far, to make the // estimate slightly better. - size_t ThunkInsertionRVA = SC->getRVA() + SC->getSize() + ThunksSize; - ObjFile *File = SC->File; - std::vector> RelocReplacements; - ArrayRef OriginalRelocs = - File->getCOFFObj()->getRelocations(SC->Header); - for (size_t J = 0, E = OriginalRelocs.size(); J < E; ++J) { - const coff_relocation &Rel = OriginalRelocs[J]; - Symbol *RelocTarget = File->getSymbol(Rel.SymbolTableIndex); + size_t thunkInsertionRVA = sc->getRVA() + sc->getSize() + thunksSize; + ObjFile *file = sc->file; + std::vector> relocReplacements; + ArrayRef originalRelocs = + file->getCOFFObj()->getRelocations(sc->header); + for (size_t j = 0, e = originalRelocs.size(); j < e; ++j) { + const coff_relocation &rel = originalRelocs[j]; + Symbol *relocTarget = file->getSymbol(rel.SymbolTableIndex); // The estimate of the source address P should be pretty accurate, // but we don't know whether the target Symbol address should be // offset by ThunkSize or not (or by some of ThunksSize but not all of // it), giving us some uncertainty once we have added one thunk. - uint64_t P = SC->getRVA() + Rel.VirtualAddress + ThunksSize; + uint64_t p = sc->getRVA() + rel.VirtualAddress + thunksSize; - Defined *Sym = dyn_cast_or_null(RelocTarget); - if (!Sym) + Defined *sym = dyn_cast_or_null(relocTarget); + if (!sym) continue; - uint64_t S = Sym->getRVA(); + uint64_t s = sym->getRVA(); - if (isInRange(Rel.Type, S, P, Margin)) + if (isInRange(rel.Type, s, p, margin)) continue; // If the target isn't in range, hook it up to an existing or new // thunk. - Defined *Thunk; - bool WasNew; - std::tie(Thunk, WasNew) = getThunk(LastThunks, Sym, P, Rel.Type, Margin); - if (WasNew) { - Chunk *ThunkChunk = Thunk->getChunk(); - ThunkChunk->setRVA( - ThunkInsertionRVA); // Estimate of where it will be located. - OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk); - ThunkInsertionSpot++; - ThunksSize += ThunkChunk->getSize(); - ThunkInsertionRVA += ThunkChunk->getSize(); - AddressesChanged = true; + Defined *thunk; + bool wasNew; + std::tie(thunk, wasNew) = getThunk(lastThunks, sym, p, rel.Type, margin); + if (wasNew) { + Chunk *thunkChunk = thunk->getChunk(); + thunkChunk->setRVA( + thunkInsertionRVA); // Estimate of where it will be located. + os->chunks.insert(os->chunks.begin() + thunkInsertionSpot, thunkChunk); + thunkInsertionSpot++; + thunksSize += thunkChunk->getSize(); + thunkInsertionRVA += thunkChunk->getSize(); + addressesChanged = true; } // To redirect the relocation, add a symbol to the parent object file's // symbol table, and replace the relocation symbol table index with the // new index. - auto Insertion = ThunkSymtabIndices.insert({{File, Thunk}, ~0U}); - uint32_t &ThunkSymbolIndex = Insertion.first->second; - if (Insertion.second) - ThunkSymbolIndex = File->addRangeThunkSymbol(Thunk); - RelocReplacements.push_back({J, ThunkSymbolIndex}); + auto insertion = thunkSymtabIndices.insert({{file, thunk}, ~0U}); + uint32_t &thunkSymbolIndex = insertion.first->second; + if (insertion.second) + thunkSymbolIndex = file->addRangeThunkSymbol(thunk); + relocReplacements.push_back({j, thunkSymbolIndex}); } // Get a writable copy of this section's relocations so they can be // modified. If the relocations point into the object file, allocate new // memory. Otherwise, this must be previously allocated memory that can be // modified in place. - ArrayRef CurRelocs = SC->getRelocs(); - MutableArrayRef NewRelocs; - if (OriginalRelocs.data() == CurRelocs.data()) { - NewRelocs = makeMutableArrayRef( - BAlloc.Allocate(OriginalRelocs.size()), - OriginalRelocs.size()); + ArrayRef curRelocs = sc->getRelocs(); + MutableArrayRef newRelocs; + if (originalRelocs.data() == curRelocs.data()) { + newRelocs = makeMutableArrayRef( + bAlloc.Allocate(originalRelocs.size()), + originalRelocs.size()); } else { - NewRelocs = makeMutableArrayRef( - const_cast(CurRelocs.data()), CurRelocs.size()); + newRelocs = makeMutableArrayRef( + const_cast(curRelocs.data()), curRelocs.size()); } // Copy each relocation, but replace the symbol table indices which need // thunks. - auto NextReplacement = RelocReplacements.begin(); - auto EndReplacement = RelocReplacements.end(); - for (size_t I = 0, E = OriginalRelocs.size(); I != E; ++I) { - NewRelocs[I] = OriginalRelocs[I]; - if (NextReplacement != EndReplacement && NextReplacement->first == I) { - NewRelocs[I].SymbolTableIndex = NextReplacement->second; - ++NextReplacement; + auto nextReplacement = relocReplacements.begin(); + auto endReplacement = relocReplacements.end(); + for (size_t i = 0, e = originalRelocs.size(); i != e; ++i) { + newRelocs[i] = originalRelocs[i]; + if (nextReplacement != endReplacement && nextReplacement->first == i) { + newRelocs[i].SymbolTableIndex = nextReplacement->second; + ++nextReplacement; } } - SC->setRelocs(NewRelocs); + sc->setRelocs(newRelocs); } - return AddressesChanged; + return addressesChanged; } // Verify that all relocations are in range, with no extra margin requirements. -static bool verifyRanges(const std::vector Chunks) { - for (Chunk *C : Chunks) { - SectionChunk *SC = dyn_cast_or_null(C); - if (!SC) +static bool verifyRanges(const std::vector chunks) { + for (Chunk *c : chunks) { + SectionChunk *sc = dyn_cast_or_null(c); + if (!sc) continue; - ArrayRef Relocs = SC->getRelocs(); - for (size_t J = 0, E = Relocs.size(); J < E; ++J) { - const coff_relocation &Rel = Relocs[J]; - Symbol *RelocTarget = SC->File->getSymbol(Rel.SymbolTableIndex); + ArrayRef relocs = sc->getRelocs(); + for (size_t j = 0, e = relocs.size(); j < e; ++j) { + const coff_relocation &rel = relocs[j]; + Symbol *relocTarget = sc->file->getSymbol(rel.SymbolTableIndex); - Defined *Sym = dyn_cast_or_null(RelocTarget); - if (!Sym) + Defined *sym = dyn_cast_or_null(relocTarget); + if (!sym) continue; - uint64_t P = SC->getRVA() + Rel.VirtualAddress; - uint64_t S = Sym->getRVA(); + uint64_t p = sc->getRVA() + rel.VirtualAddress; + uint64_t s = sym->getRVA(); - if (!isInRange(Rel.Type, S, P, 0)) + if (!isInRange(rel.Type, s, p, 0)) return false; } } @@ -527,68 +527,68 @@ static bool verifyRanges(const std::vector Chunks) { // Assign addresses and add thunks if necessary. void Writer::finalizeAddresses() { assignAddresses(); - if (Config->Machine != ARMNT && Config->Machine != ARM64) + if (config->machine != ARMNT && config->machine != ARM64) return; - size_t OrigNumChunks = 0; - for (OutputSection *Sec : OutputSections) { - Sec->OrigChunks = Sec->Chunks; - OrigNumChunks += Sec->Chunks.size(); + size_t origNumChunks = 0; + for (OutputSection *sec : outputSections) { + sec->origChunks = sec->chunks; + origNumChunks += sec->chunks.size(); } - int Pass = 0; - int Margin = 1024 * 100; + int pass = 0; + int margin = 1024 * 100; while (true) { // First check whether we need thunks at all, or if the previous pass of // adding them turned out ok. - bool RangesOk = true; - size_t NumChunks = 0; - for (OutputSection *Sec : OutputSections) { - if (!verifyRanges(Sec->Chunks)) { - RangesOk = false; + bool rangesOk = true; + size_t numChunks = 0; + for (OutputSection *sec : outputSections) { + if (!verifyRanges(sec->chunks)) { + rangesOk = false; break; } - NumChunks += Sec->Chunks.size(); + numChunks += sec->chunks.size(); } - if (RangesOk) { - if (Pass > 0) - log("Added " + Twine(NumChunks - OrigNumChunks) + " thunks with " + - "margin " + Twine(Margin) + " in " + Twine(Pass) + " passes"); + if (rangesOk) { + if (pass > 0) + log("Added " + Twine(numChunks - origNumChunks) + " thunks with " + + "margin " + Twine(margin) + " in " + Twine(pass) + " passes"); return; } - if (Pass >= 10) - fatal("adding thunks hasn't converged after " + Twine(Pass) + " passes"); + if (pass >= 10) + fatal("adding thunks hasn't converged after " + Twine(pass) + " passes"); - if (Pass > 0) { + if (pass > 0) { // If the previous pass didn't work out, reset everything back to the // original conditions before retrying with a wider margin. This should // ideally never happen under real circumstances. - for (OutputSection *Sec : OutputSections) - Sec->Chunks = Sec->OrigChunks; - Margin *= 2; + for (OutputSection *sec : outputSections) + sec->chunks = sec->origChunks; + margin *= 2; } // Try adding thunks everywhere where it is needed, with a margin // to avoid things going out of range due to the added thunks. - bool AddressesChanged = false; - for (OutputSection *Sec : OutputSections) - AddressesChanged |= createThunks(Sec, Margin); + bool addressesChanged = false; + for (OutputSection *sec : outputSections) + addressesChanged |= createThunks(sec, margin); // If the verification above thought we needed thunks, we should have // added some. - assert(AddressesChanged); + assert(addressesChanged); // Recalculate the layout for the whole image (and verify the ranges at // the start of the next round). assignAddresses(); - Pass++; + pass++; } } // The main function of the writer. void Writer::run() { - ScopedTimer T1(CodeLayoutTimer); + ScopedTimer t1(codeLayoutTimer); createImportTables(); createSections(); @@ -603,12 +603,12 @@ void Writer::run() { setSectionPermissions(); createSymbolAndStringTable(); - if (FileSize > UINT32_MAX) - fatal("image size (" + Twine(FileSize) + ") " + + if (fileSize > UINT32_MAX) + fatal("image size (" + Twine(fileSize) + ") " + "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")"); - openFile(Config->OutputFile); - if (Config->is64()) { + openFile(config->outputFile); + if (config->is64()) { writeHeader(); } else { writeHeader(); @@ -616,58 +616,58 @@ void Writer::run() { writeSections(); sortExceptionTable(); - T1.stop(); + t1.stop(); - if (!Config->PDBPath.empty() && Config->Debug) { - assert(BuildId); - createPDB(Symtab, OutputSections, SectionTable, BuildId->BuildId); + if (!config->pdbPath.empty() && config->debug) { + assert(buildId); + createPDB(symtab, outputSections, sectionTable, buildId->buildId); } writeBuildId(); - writeMapFile(OutputSections); + writeMapFile(outputSections); - ScopedTimer T2(DiskCommitTimer); - if (auto E = Buffer->commit()) - fatal("failed to write the output file: " + toString(std::move(E))); + ScopedTimer t2(diskCommitTimer); + if (auto e = buffer->commit()) + fatal("failed to write the output file: " + toString(std::move(e))); } -static StringRef getOutputSectionName(StringRef Name) { - StringRef S = Name.split('$').first; +static StringRef getOutputSectionName(StringRef name) { + StringRef s = name.split('$').first; // Treat a later period as a separator for MinGW, for sections like // ".ctors.01234". - return S.substr(0, S.find('.', 1)); + return s.substr(0, s.find('.', 1)); } // For /order. -static void sortBySectionOrder(std::vector &Chunks) { - auto GetPriority = [](const Chunk *C) { - if (auto *Sec = dyn_cast(C)) - if (Sec->Sym) - return Config->Order.lookup(Sec->Sym->getName()); +static void sortBySectionOrder(std::vector &chunks) { + auto getPriority = [](const Chunk *c) { + if (auto *sec = dyn_cast(c)) + if (sec->sym) + return config->order.lookup(sec->sym->getName()); return 0; }; - llvm::stable_sort(Chunks, [=](const Chunk *A, const Chunk *B) { - return GetPriority(A) < GetPriority(B); + llvm::stable_sort(chunks, [=](const Chunk *a, const Chunk *b) { + return getPriority(a) < getPriority(b); }); } // Change the characteristics of existing PartialSections that belong to the // section Name to Chars. -void Writer::fixPartialSectionChars(StringRef Name, uint32_t Chars) { - for (auto It : PartialSections) { - PartialSection *PSec = It.second; - StringRef CurName = PSec->Name; - if (!CurName.consume_front(Name) || - (!CurName.empty() && !CurName.startswith("$"))) +void Writer::fixPartialSectionChars(StringRef name, uint32_t chars) { + for (auto it : partialSections) { + PartialSection *pSec = it.second; + StringRef curName = pSec->name; + if (!curName.consume_front(name) || + (!curName.empty() && !curName.startswith("$"))) continue; - if (PSec->Characteristics == Chars) + if (pSec->characteristics == chars) continue; - PartialSection *DestSec = createPartialSection(PSec->Name, Chars); - DestSec->Chunks.insert(DestSec->Chunks.end(), PSec->Chunks.begin(), - PSec->Chunks.end()); - PSec->Chunks.clear(); + PartialSection *destSec = createPartialSection(pSec->name, chars); + destSec->chunks.insert(destSec->chunks.end(), pSec->chunks.begin(), + pSec->chunks.end()); + pSec->chunks.clear(); } } @@ -682,249 +682,249 @@ void Writer::fixPartialSectionChars(StringRef Name, uint32_t Chars) { // to be grouped by library, and sorted alphabetically within each library // (which makes sure the header comes first and the trailer last). bool Writer::fixGnuImportChunks() { - uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; // Make sure all .idata$* section chunks are mapped as RDATA in order to // be sorted into the same sections as our own synthesized .idata chunks. - fixPartialSectionChars(".idata", RDATA); + fixPartialSectionChars(".idata", rdata); - bool HasIdata = false; + bool hasIdata = false; // Sort all .idata$* chunks, grouping chunks from the same library, // with alphabetical ordering of the object fils within a library. - for (auto It : PartialSections) { - PartialSection *PSec = It.second; - if (!PSec->Name.startswith(".idata")) + for (auto it : partialSections) { + PartialSection *pSec = it.second; + if (!pSec->name.startswith(".idata")) continue; - if (!PSec->Chunks.empty()) - HasIdata = true; - llvm::stable_sort(PSec->Chunks, [&](Chunk *S, Chunk *T) { - SectionChunk *SC1 = dyn_cast_or_null(S); - SectionChunk *SC2 = dyn_cast_or_null(T); - if (!SC1 || !SC2) { + if (!pSec->chunks.empty()) + hasIdata = true; + llvm::stable_sort(pSec->chunks, [&](Chunk *s, Chunk *t) { + SectionChunk *sc1 = dyn_cast_or_null(s); + SectionChunk *sc2 = dyn_cast_or_null(t); + if (!sc1 || !sc2) { // if SC1, order them ascending. If SC2 or both null, // S is not less than T. - return SC1 != nullptr; + return sc1 != nullptr; } // Make a string with "libraryname/objectfile" for sorting, achieving // both grouping by library and sorting of objects within a library, // at once. - std::string Key1 = - (SC1->File->ParentName + "/" + SC1->File->getName()).str(); - std::string Key2 = - (SC2->File->ParentName + "/" + SC2->File->getName()).str(); - return Key1 < Key2; + std::string key1 = + (sc1->file->parentName + "/" + sc1->file->getName()).str(); + std::string key2 = + (sc2->file->parentName + "/" + sc2->file->getName()).str(); + return key1 < key2; }); } - return HasIdata; + return hasIdata; } // Add generated idata chunks, for imported symbols and DLLs, and a // terminator in .idata$2. void Writer::addSyntheticIdata() { - uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; - Idata.create(); + uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + idata.create(); // Add the .idata content in the right section groups, to allow // chunks from other linked in object files to be grouped together. // See Microsoft PE/COFF spec 5.4 for details. - auto Add = [&](StringRef N, std::vector &V) { - PartialSection *PSec = createPartialSection(N, RDATA); - PSec->Chunks.insert(PSec->Chunks.end(), V.begin(), V.end()); + auto add = [&](StringRef n, std::vector &v) { + PartialSection *pSec = createPartialSection(n, rdata); + pSec->chunks.insert(pSec->chunks.end(), v.begin(), v.end()); }; // The loader assumes a specific order of data. // Add each type in the correct order. - Add(".idata$2", Idata.Dirs); - Add(".idata$4", Idata.Lookups); - Add(".idata$5", Idata.Addresses); - Add(".idata$6", Idata.Hints); - Add(".idata$7", Idata.DLLNames); + add(".idata$2", idata.dirs); + add(".idata$4", idata.lookups); + add(".idata$5", idata.addresses); + add(".idata$6", idata.hints); + add(".idata$7", idata.dllNames); } // Locate the first Chunk and size of the import directory list and the // IAT. void Writer::locateImportTables() { - uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; - if (PartialSection *ImportDirs = findPartialSection(".idata$2", RDATA)) { - if (!ImportDirs->Chunks.empty()) - ImportTableStart = ImportDirs->Chunks.front(); - for (Chunk *C : ImportDirs->Chunks) - ImportTableSize += C->getSize(); + if (PartialSection *importDirs = findPartialSection(".idata$2", rdata)) { + if (!importDirs->chunks.empty()) + importTableStart = importDirs->chunks.front(); + for (Chunk *c : importDirs->chunks) + importTableSize += c->getSize(); } - if (PartialSection *ImportAddresses = findPartialSection(".idata$5", RDATA)) { - if (!ImportAddresses->Chunks.empty()) - IATStart = ImportAddresses->Chunks.front(); - for (Chunk *C : ImportAddresses->Chunks) - IATSize += C->getSize(); + if (PartialSection *importAddresses = findPartialSection(".idata$5", rdata)) { + if (!importAddresses->chunks.empty()) + iatStart = importAddresses->chunks.front(); + for (Chunk *c : importAddresses->chunks) + iatSize += c->getSize(); } } // Create output section objects and add them to OutputSections. void Writer::createSections() { // First, create the builtin sections. - const uint32_t DATA = IMAGE_SCN_CNT_INITIALIZED_DATA; - const uint32_t BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA; - const uint32_t CODE = IMAGE_SCN_CNT_CODE; - const uint32_t DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE; - const uint32_t R = IMAGE_SCN_MEM_READ; - const uint32_t W = IMAGE_SCN_MEM_WRITE; - const uint32_t X = IMAGE_SCN_MEM_EXECUTE; - - SmallDenseMap, OutputSection *> Sections; - auto CreateSection = [&](StringRef Name, uint32_t OutChars) { - OutputSection *&Sec = Sections[{Name, OutChars}]; - if (!Sec) { - Sec = make(Name, OutChars); - OutputSections.push_back(Sec); + const uint32_t data = IMAGE_SCN_CNT_INITIALIZED_DATA; + const uint32_t bss = IMAGE_SCN_CNT_UNINITIALIZED_DATA; + const uint32_t code = IMAGE_SCN_CNT_CODE; + const uint32_t discardable = IMAGE_SCN_MEM_DISCARDABLE; + const uint32_t r = IMAGE_SCN_MEM_READ; + const uint32_t w = IMAGE_SCN_MEM_WRITE; + const uint32_t x = IMAGE_SCN_MEM_EXECUTE; + + SmallDenseMap, OutputSection *> sections; + auto createSection = [&](StringRef name, uint32_t outChars) { + OutputSection *&sec = sections[{name, outChars}]; + if (!sec) { + sec = make(name, outChars); + outputSections.push_back(sec); } - return Sec; + return sec; }; // Try to match the section order used by link.exe. - TextSec = CreateSection(".text", CODE | R | X); - CreateSection(".bss", BSS | R | W); - RdataSec = CreateSection(".rdata", DATA | R); - BuildidSec = CreateSection(".buildid", DATA | R); - DataSec = CreateSection(".data", DATA | R | W); - PdataSec = CreateSection(".pdata", DATA | R); - IdataSec = CreateSection(".idata", DATA | R); - EdataSec = CreateSection(".edata", DATA | R); - DidatSec = CreateSection(".didat", DATA | R); - RsrcSec = CreateSection(".rsrc", DATA | R); - RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R); - CtorsSec = CreateSection(".ctors", DATA | R | W); - DtorsSec = CreateSection(".dtors", DATA | R | W); + textSec = createSection(".text", code | r | x); + createSection(".bss", bss | r | w); + rdataSec = createSection(".rdata", data | r); + buildidSec = createSection(".buildid", data | r); + dataSec = createSection(".data", data | r | w); + pdataSec = createSection(".pdata", data | r); + idataSec = createSection(".idata", data | r); + edataSec = createSection(".edata", data | r); + didatSec = createSection(".didat", data | r); + rsrcSec = createSection(".rsrc", data | r); + relocSec = createSection(".reloc", data | discardable | r); + ctorsSec = createSection(".ctors", data | r | w); + dtorsSec = createSection(".dtors", data | r | w); // Then bin chunks by name and output characteristics. - for (Chunk *C : Symtab->getChunks()) { - auto *SC = dyn_cast(C); - if (SC && !SC->Live) { - if (Config->Verbose) - SC->printDiscardedMessage(); + for (Chunk *c : symtab->getChunks()) { + auto *sc = dyn_cast(c); + if (sc && !sc->live) { + if (config->verbose) + sc->printDiscardedMessage(); continue; } - StringRef Name = C->getSectionName(); + StringRef name = c->getSectionName(); // On MinGW, comdat groups are formed by putting the comdat group name // after the '$' in the section name. Such a section name suffix shouldn't // imply separate alphabetical sorting of those section chunks though. - if (Config->MinGW && SC && SC->isCOMDAT()) - Name = Name.split('$').first; - PartialSection *PSec = createPartialSection(Name, - C->getOutputCharacteristics()); - PSec->Chunks.push_back(C); + if (config->mingw && sc && sc->isCOMDAT()) + name = name.split('$').first; + PartialSection *pSec = createPartialSection(name, + c->getOutputCharacteristics()); + pSec->chunks.push_back(c); } - fixPartialSectionChars(".rsrc", DATA | R); + fixPartialSectionChars(".rsrc", data | r); // Even in non MinGW cases, we might need to link against GNU import // libraries. - bool HasIdata = fixGnuImportChunks(); - if (!Idata.empty()) - HasIdata = true; + bool hasIdata = fixGnuImportChunks(); + if (!idata.empty()) + hasIdata = true; - if (HasIdata) + if (hasIdata) addSyntheticIdata(); // Process an /order option. - if (!Config->Order.empty()) - for (auto It : PartialSections) - sortBySectionOrder(It.second->Chunks); + if (!config->order.empty()) + for (auto it : partialSections) + sortBySectionOrder(it.second->chunks); - if (HasIdata) + if (hasIdata) locateImportTables(); // Then create an OutputSection for each section. // '$' and all following characters in input section names are // discarded when determining output section. So, .text$foo // contributes to .text, for example. See PE/COFF spec 3.2. - for (auto It : PartialSections) { - PartialSection *PSec = It.second; - StringRef Name = getOutputSectionName(PSec->Name); - uint32_t OutChars = PSec->Characteristics; + for (auto it : partialSections) { + PartialSection *pSec = it.second; + StringRef name = getOutputSectionName(pSec->name); + uint32_t outChars = pSec->characteristics; - if (Name == ".CRT") { + if (name == ".CRT") { // In link.exe, there is a special case for the I386 target where .CRT // sections are treated as if they have output characteristics DATA | R if // their characteristics are DATA | R | W. This implements the same // special case for all architectures. - OutChars = DATA | R; + outChars = data | r; - log("Processing section " + PSec->Name + " -> " + Name); + log("Processing section " + pSec->name + " -> " + name); - sortCRTSectionChunks(PSec->Chunks); + sortCRTSectionChunks(pSec->chunks); } - OutputSection *Sec = CreateSection(Name, OutChars); - for (Chunk *C : PSec->Chunks) - Sec->addChunk(C); + OutputSection *sec = createSection(name, outChars); + for (Chunk *c : pSec->chunks) + sec->addChunk(c); - Sec->addContributingPartialSection(PSec); + sec->addContributingPartialSection(pSec); } // Finally, move some output sections to the end. - auto SectionOrder = [&](const OutputSection *S) { + auto sectionOrder = [&](const OutputSection *s) { // Move DISCARDABLE (or non-memory-mapped) sections to the end of file // because the loader cannot handle holes. Stripping can remove other // discardable ones than .reloc, which is first of them (created early). - if (S->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) return 2; // .rsrc should come at the end of the non-discardable sections because its // size may change by the Win32 UpdateResources() function, causing // subsequent sections to move (see https://crbug.com/827082). - if (S == RsrcSec) + if (s == rsrcSec) return 1; return 0; }; - llvm::stable_sort(OutputSections, - [&](const OutputSection *S, const OutputSection *T) { - return SectionOrder(S) < SectionOrder(T); + llvm::stable_sort(outputSections, + [&](const OutputSection *s, const OutputSection *t) { + return sectionOrder(s) < sectionOrder(t); }); } void Writer::createMiscChunks() { - for (MergeChunk *P : MergeChunk::Instances) { - if (P) { - P->finalizeContents(); - RdataSec->addChunk(P); + for (MergeChunk *p : MergeChunk::instances) { + if (p) { + p->finalizeContents(); + rdataSec->addChunk(p); } } // Create thunks for locally-dllimported symbols. - if (!Symtab->LocalImportChunks.empty()) { - for (Chunk *C : Symtab->LocalImportChunks) - RdataSec->addChunk(C); + if (!symtab->localImportChunks.empty()) { + for (Chunk *c : symtab->localImportChunks) + rdataSec->addChunk(c); } // Create Debug Information Chunks - OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec; - if (Config->Debug || Config->Repro) { - DebugDirectory = make(DebugRecords, Config->Repro); - DebugInfoSec->addChunk(DebugDirectory); + OutputSection *debugInfoSec = config->mingw ? buildidSec : rdataSec; + if (config->debug || config->repro) { + debugDirectory = make(debugRecords, config->repro); + debugInfoSec->addChunk(debugDirectory); } - if (Config->Debug) { + if (config->debug) { // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We // output a PDB no matter what, and this chunk provides the only means of // allowing a debugger to match a PDB and an executable. So we need it even // if we're ultimately not going to write CodeView data to the PDB. - BuildId = make(); - DebugRecords.push_back(BuildId); + buildId = make(); + debugRecords.push_back(buildId); - for (Chunk *C : DebugRecords) - DebugInfoSec->addChunk(C); + for (Chunk *c : debugRecords) + debugInfoSec->addChunk(c); } // Create SEH table. x86-only. - if (Config->Machine == I386) + if (config->machine == I386) createSEHTable(); // Create /guard:cf tables if requested. - if (Config->GuardCF != GuardCFLevel::Off) + if (config->guardCF != GuardCFLevel::Off) createGuardCFTables(); - if (Config->MinGW) { + if (config->mingw) { createRuntimePseudoRelocs(); insertCtorDtorSymbols(); @@ -939,123 +939,123 @@ void Writer::createImportTables() { // Initialize DLLOrder so that import entries are ordered in // the same order as in the command line. (That affects DLL // initialization order, and this ordering is MSVC-compatible.) - for (ImportFile *File : ImportFile::Instances) { - if (!File->Live) + for (ImportFile *file : ImportFile::instances) { + if (!file->live) continue; - std::string DLL = StringRef(File->DLLName).lower(); - if (Config->DLLOrder.count(DLL) == 0) - Config->DLLOrder[DLL] = Config->DLLOrder.size(); - - if (File->ImpSym && !isa(File->ImpSym)) - fatal(toString(*File->ImpSym) + " was replaced"); - DefinedImportData *ImpSym = cast_or_null(File->ImpSym); - if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) { - if (!File->ThunkSym) - fatal("cannot delay-load " + toString(File) + - " due to import of data: " + toString(*ImpSym)); - DelayIdata.add(ImpSym); + std::string dll = StringRef(file->dllName).lower(); + if (config->dllOrder.count(dll) == 0) + config->dllOrder[dll] = config->dllOrder.size(); + + if (file->impSym && !isa(file->impSym)) + fatal(toString(*file->impSym) + " was replaced"); + DefinedImportData *impSym = cast_or_null(file->impSym); + if (config->delayLoads.count(StringRef(file->dllName).lower())) { + if (!file->thunkSym) + fatal("cannot delay-load " + toString(file) + + " due to import of data: " + toString(*impSym)); + delayIdata.add(impSym); } else { - Idata.add(ImpSym); + idata.add(impSym); } } } void Writer::appendImportThunks() { - if (ImportFile::Instances.empty()) + if (ImportFile::instances.empty()) return; - for (ImportFile *File : ImportFile::Instances) { - if (!File->Live) + for (ImportFile *file : ImportFile::instances) { + if (!file->live) continue; - if (!File->ThunkSym) + if (!file->thunkSym) continue; - if (!isa(File->ThunkSym)) - fatal(toString(*File->ThunkSym) + " was replaced"); - DefinedImportThunk *Thunk = cast(File->ThunkSym); - if (File->ThunkLive) - TextSec->addChunk(Thunk->getChunk()); + if (!isa(file->thunkSym)) + fatal(toString(*file->thunkSym) + " was replaced"); + DefinedImportThunk *thunk = cast(file->thunkSym); + if (file->thunkLive) + textSec->addChunk(thunk->getChunk()); } - if (!DelayIdata.empty()) { - Defined *Helper = cast(Config->DelayLoadHelper); - DelayIdata.create(Helper); - for (Chunk *C : DelayIdata.getChunks()) - DidatSec->addChunk(C); - for (Chunk *C : DelayIdata.getDataChunks()) - DataSec->addChunk(C); - for (Chunk *C : DelayIdata.getCodeChunks()) - TextSec->addChunk(C); + if (!delayIdata.empty()) { + Defined *helper = cast(config->delayLoadHelper); + delayIdata.create(helper); + for (Chunk *c : delayIdata.getChunks()) + didatSec->addChunk(c); + for (Chunk *c : delayIdata.getDataChunks()) + dataSec->addChunk(c); + for (Chunk *c : delayIdata.getCodeChunks()) + textSec->addChunk(c); } } void Writer::createExportTable() { - if (Config->Exports.empty()) + if (config->exports.empty()) return; - for (Chunk *C : Edata.Chunks) - EdataSec->addChunk(C); + for (Chunk *c : edata.chunks) + edataSec->addChunk(c); } void Writer::removeUnusedSections() { // Remove sections that we can be sure won't get content, to avoid // allocating space for their section headers. - auto IsUnused = [this](OutputSection *S) { - if (S == RelocSec) + auto isUnused = [this](OutputSection *s) { + if (s == relocSec) return false; // This section is populated later. // MergeChunks have zero size at this point, as their size is finalized // later. Only remove sections that have no Chunks at all. - return S->Chunks.empty(); + return s->chunks.empty(); }; - OutputSections.erase( - std::remove_if(OutputSections.begin(), OutputSections.end(), IsUnused), - OutputSections.end()); + outputSections.erase( + std::remove_if(outputSections.begin(), outputSections.end(), isUnused), + outputSections.end()); } // The Windows loader doesn't seem to like empty sections, // so we remove them if any. void Writer::removeEmptySections() { - auto IsEmpty = [](OutputSection *S) { return S->getVirtualSize() == 0; }; - OutputSections.erase( - std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty), - OutputSections.end()); + auto isEmpty = [](OutputSection *s) { return s->getVirtualSize() == 0; }; + outputSections.erase( + std::remove_if(outputSections.begin(), outputSections.end(), isEmpty), + outputSections.end()); } void Writer::assignOutputSectionIndices() { // Assign final output section indices, and assign each chunk to its output // section. - uint32_t Idx = 1; - for (OutputSection *OS : OutputSections) { - OS->SectionIndex = Idx; - for (Chunk *C : OS->Chunks) - C->setOutputSectionIdx(Idx); - ++Idx; + uint32_t idx = 1; + for (OutputSection *os : outputSections) { + os->sectionIndex = idx; + for (Chunk *c : os->chunks) + c->setOutputSectionIdx(idx); + ++idx; } // Merge chunks are containers of chunks, so assign those an output section // too. - for (MergeChunk *MC : MergeChunk::Instances) - if (MC) - for (SectionChunk *SC : MC->Sections) - if (SC && SC->Live) - SC->setOutputSectionIdx(MC->getOutputSectionIdx()); + for (MergeChunk *mc : MergeChunk::instances) + if (mc) + for (SectionChunk *sc : mc->sections) + if (sc && sc->live) + sc->setOutputSectionIdx(mc->getOutputSectionIdx()); } -size_t Writer::addEntryToStringTable(StringRef Str) { - assert(Str.size() > COFF::NameSize); - size_t OffsetOfEntry = Strtab.size() + 4; // +4 for the size field - Strtab.insert(Strtab.end(), Str.begin(), Str.end()); - Strtab.push_back('\0'); - return OffsetOfEntry; +size_t Writer::addEntryToStringTable(StringRef str) { + assert(str.size() > COFF::NameSize); + size_t offsetOfEntry = strtab.size() + 4; // +4 for the size field + strtab.insert(strtab.end(), str.begin(), str.end()); + strtab.push_back('\0'); + return offsetOfEntry; } -Optional Writer::createSymbol(Defined *Def) { - coff_symbol16 Sym; - switch (Def->kind()) { +Optional Writer::createSymbol(Defined *def) { + coff_symbol16 sym; + switch (def->kind()) { case Symbol::DefinedAbsoluteKind: - Sym.Value = Def->getRVA(); - Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; + sym.Value = def->getRVA(); + sym.SectionNumber = IMAGE_SYM_ABSOLUTE; break; case Symbol::DefinedSyntheticKind: // Relative symbols are unrepresentable in a COFF symbol table. @@ -1063,38 +1063,38 @@ Optional Writer::createSymbol(Defined *Def) { default: { // Don't write symbols that won't be written to the output to the symbol // table. - Chunk *C = Def->getChunk(); - if (!C) + Chunk *c = def->getChunk(); + if (!c) return None; - OutputSection *OS = C->getOutputSection(); - if (!OS) + OutputSection *os = c->getOutputSection(); + if (!os) return None; - Sym.Value = Def->getRVA() - OS->getRVA(); - Sym.SectionNumber = OS->SectionIndex; + sym.Value = def->getRVA() - os->getRVA(); + sym.SectionNumber = os->sectionIndex; break; } } - StringRef Name = Def->getName(); - if (Name.size() > COFF::NameSize) { - Sym.Name.Offset.Zeroes = 0; - Sym.Name.Offset.Offset = addEntryToStringTable(Name); + StringRef name = def->getName(); + if (name.size() > COFF::NameSize) { + sym.Name.Offset.Zeroes = 0; + sym.Name.Offset.Offset = addEntryToStringTable(name); } else { - memset(Sym.Name.ShortName, 0, COFF::NameSize); - memcpy(Sym.Name.ShortName, Name.data(), Name.size()); + memset(sym.Name.ShortName, 0, COFF::NameSize); + memcpy(sym.Name.ShortName, name.data(), name.size()); } - if (auto *D = dyn_cast(Def)) { - COFFSymbolRef Ref = D->getCOFFSymbol(); - Sym.Type = Ref.getType(); - Sym.StorageClass = Ref.getStorageClass(); + if (auto *d = dyn_cast(def)) { + COFFSymbolRef ref = d->getCOFFSymbol(); + sym.Type = ref.getType(); + sym.StorageClass = ref.getStorageClass(); } else { - Sym.Type = IMAGE_SYM_TYPE_NULL; - Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; + sym.Type = IMAGE_SYM_TYPE_NULL; + sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; } - Sym.NumberOfAuxSymbols = 0; - return Sym; + sym.NumberOfAuxSymbols = 0; + return sym; } void Writer::createSymbolAndStringTable() { @@ -1106,120 +1106,120 @@ void Writer::createSymbolAndStringTable() { // solution where discardable sections have long names preserved and // non-discardable sections have their names truncated, to ensure that any // section which is mapped at runtime also has its name mapped at runtime. - for (OutputSection *Sec : OutputSections) { - if (Sec->Name.size() <= COFF::NameSize) + for (OutputSection *sec : outputSections) { + if (sec->name.size() <= COFF::NameSize) continue; - if ((Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0) + if ((sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0) continue; - Sec->setStringTableOff(addEntryToStringTable(Sec->Name)); + sec->setStringTableOff(addEntryToStringTable(sec->name)); } - if (Config->DebugDwarf || Config->DebugSymtab) { - for (ObjFile *File : ObjFile::Instances) { - for (Symbol *B : File->getSymbols()) { - auto *D = dyn_cast_or_null(B); - if (!D || D->WrittenToSymtab) + if (config->debugDwarf || config->debugSymtab) { + for (ObjFile *file : ObjFile::instances) { + for (Symbol *b : file->getSymbols()) { + auto *d = dyn_cast_or_null(b); + if (!d || d->writtenToSymtab) continue; - D->WrittenToSymtab = true; + d->writtenToSymtab = true; - if (Optional Sym = createSymbol(D)) - OutputSymtab.push_back(*Sym); + if (Optional sym = createSymbol(d)) + outputSymtab.push_back(*sym); } } } - if (OutputSymtab.empty() && Strtab.empty()) + if (outputSymtab.empty() && strtab.empty()) return; // We position the symbol table to be adjacent to the end of the last section. - uint64_t FileOff = FileSize; - PointerToSymbolTable = FileOff; - FileOff += OutputSymtab.size() * sizeof(coff_symbol16); - FileOff += 4 + Strtab.size(); - FileSize = alignTo(FileOff, Config->FileAlign); + uint64_t fileOff = fileSize; + pointerToSymbolTable = fileOff; + fileOff += outputSymtab.size() * sizeof(coff_symbol16); + fileOff += 4 + strtab.size(); + fileSize = alignTo(fileOff, config->fileAlign); } void Writer::mergeSections() { - if (!PdataSec->Chunks.empty()) { - FirstPdata = PdataSec->Chunks.front(); - LastPdata = PdataSec->Chunks.back(); + if (!pdataSec->chunks.empty()) { + firstPdata = pdataSec->chunks.front(); + lastPdata = pdataSec->chunks.back(); } - for (auto &P : Config->Merge) { - StringRef ToName = P.second; - if (P.first == ToName) + for (auto &p : config->merge) { + StringRef toName = p.second; + if (p.first == toName) continue; - StringSet<> Names; + StringSet<> names; while (1) { - if (!Names.insert(ToName).second) - fatal("/merge: cycle found for section '" + P.first + "'"); - auto I = Config->Merge.find(ToName); - if (I == Config->Merge.end()) + if (!names.insert(toName).second) + fatal("/merge: cycle found for section '" + p.first + "'"); + auto i = config->merge.find(toName); + if (i == config->merge.end()) break; - ToName = I->second; + toName = i->second; } - OutputSection *From = findSection(P.first); - OutputSection *To = findSection(ToName); - if (!From) + OutputSection *from = findSection(p.first); + OutputSection *to = findSection(toName); + if (!from) continue; - if (!To) { - From->Name = ToName; + if (!to) { + from->name = toName; continue; } - To->merge(From); + to->merge(from); } } // Visits all sections to assign incremental, non-overlapping RVAs and // file offsets. void Writer::assignAddresses() { - SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) + - sizeof(data_directory) * NumberOfDataDirectory + - sizeof(coff_section) * OutputSections.size(); - SizeOfHeaders += - Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); - SizeOfHeaders = alignTo(SizeOfHeaders, Config->FileAlign); - uint64_t RVA = PageSize; // The first page is kept unmapped. - FileSize = SizeOfHeaders; - - for (OutputSection *Sec : OutputSections) { - if (Sec == RelocSec) + sizeOfHeaders = dosStubSize + sizeof(PEMagic) + sizeof(coff_file_header) + + sizeof(data_directory) * numberOfDataDirectory + + sizeof(coff_section) * outputSections.size(); + sizeOfHeaders += + config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); + sizeOfHeaders = alignTo(sizeOfHeaders, config->fileAlign); + uint64_t rva = pageSize; // The first page is kept unmapped. + fileSize = sizeOfHeaders; + + for (OutputSection *sec : outputSections) { + if (sec == relocSec) addBaserels(); - uint64_t RawSize = 0, VirtualSize = 0; - Sec->Header.VirtualAddress = RVA; + uint64_t rawSize = 0, virtualSize = 0; + sec->header.VirtualAddress = rva; // If /FUNCTIONPADMIN is used, functions are padded in order to create a // hotpatchable image. - const bool IsCodeSection = - (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE) && - (Sec->Header.Characteristics & IMAGE_SCN_MEM_READ) && - (Sec->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE); - uint32_t Padding = IsCodeSection ? Config->FunctionPadMin : 0; - - for (Chunk *C : Sec->Chunks) { - if (Padding && C->isHotPatchable()) - VirtualSize += Padding; - VirtualSize = alignTo(VirtualSize, C->getAlignment()); - C->setRVA(RVA + VirtualSize); - VirtualSize += C->getSize(); - if (C->HasData) - RawSize = alignTo(VirtualSize, Config->FileAlign); + const bool isCodeSection = + (sec->header.Characteristics & IMAGE_SCN_CNT_CODE) && + (sec->header.Characteristics & IMAGE_SCN_MEM_READ) && + (sec->header.Characteristics & IMAGE_SCN_MEM_EXECUTE); + uint32_t padding = isCodeSection ? config->functionPadMin : 0; + + for (Chunk *c : sec->chunks) { + if (padding && c->isHotPatchable()) + virtualSize += padding; + virtualSize = alignTo(virtualSize, c->getAlignment()); + c->setRVA(rva + virtualSize); + virtualSize += c->getSize(); + if (c->hasData) + rawSize = alignTo(virtualSize, config->fileAlign); } - if (VirtualSize > UINT32_MAX) - error("section larger than 4 GiB: " + Sec->Name); - Sec->Header.VirtualSize = VirtualSize; - Sec->Header.SizeOfRawData = RawSize; - if (RawSize != 0) - Sec->Header.PointerToRawData = FileSize; - RVA += alignTo(VirtualSize, PageSize); - FileSize += alignTo(RawSize, Config->FileAlign); + if (virtualSize > UINT32_MAX) + error("section larger than 4 GiB: " + sec->name); + sec->header.VirtualSize = virtualSize; + sec->header.SizeOfRawData = rawSize; + if (rawSize != 0) + sec->header.PointerToRawData = fileSize; + rva += alignTo(virtualSize, pageSize); + fileSize += alignTo(rawSize, config->fileAlign); } - SizeOfImage = alignTo(RVA, PageSize); + sizeOfImage = alignTo(rva, pageSize); // Assign addresses to sections in MergeChunks. - for (MergeChunk *MC : MergeChunk::Instances) - if (MC) - MC->assignSubsectionRVAs(); + for (MergeChunk *mc : MergeChunk::instances) + if (mc) + mc->assignSubsectionRVAs(); } template void Writer::writeHeader() { @@ -1228,249 +1228,249 @@ template void Writer::writeHeader() { // under DOS, that program gets run (usually to just print an error message). // When run under Windows, the loader looks at AddressOfNewExeHeader and uses // the PE header instead. - uint8_t *Buf = Buffer->getBufferStart(); - auto *DOS = reinterpret_cast(Buf); - Buf += sizeof(dos_header); - DOS->Magic[0] = 'M'; - DOS->Magic[1] = 'Z'; - DOS->UsedBytesInTheLastPage = DOSStubSize % 512; - DOS->FileSizeInPages = divideCeil(DOSStubSize, 512); - DOS->HeaderSizeInParagraphs = sizeof(dos_header) / 16; - - DOS->AddressOfRelocationTable = sizeof(dos_header); - DOS->AddressOfNewExeHeader = DOSStubSize; + uint8_t *buf = buffer->getBufferStart(); + auto *dos = reinterpret_cast(buf); + buf += sizeof(dos_header); + dos->Magic[0] = 'M'; + dos->Magic[1] = 'Z'; + dos->UsedBytesInTheLastPage = dosStubSize % 512; + dos->FileSizeInPages = divideCeil(dosStubSize, 512); + dos->HeaderSizeInParagraphs = sizeof(dos_header) / 16; + + dos->AddressOfRelocationTable = sizeof(dos_header); + dos->AddressOfNewExeHeader = dosStubSize; // Write DOS program. - memcpy(Buf, DOSProgram, sizeof(DOSProgram)); - Buf += sizeof(DOSProgram); + memcpy(buf, dosProgram, sizeof(dosProgram)); + buf += sizeof(dosProgram); // Write PE magic - memcpy(Buf, PEMagic, sizeof(PEMagic)); - Buf += sizeof(PEMagic); + memcpy(buf, PEMagic, sizeof(PEMagic)); + buf += sizeof(PEMagic); // Write COFF header - auto *COFF = reinterpret_cast(Buf); - Buf += sizeof(*COFF); - COFF->Machine = Config->Machine; - COFF->NumberOfSections = OutputSections.size(); - COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; - if (Config->LargeAddressAware) - COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE; - if (!Config->is64()) - COFF->Characteristics |= IMAGE_FILE_32BIT_MACHINE; - if (Config->DLL) - COFF->Characteristics |= IMAGE_FILE_DLL; - if (!Config->Relocatable) - COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED; - if (Config->SwaprunCD) - COFF->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP; - if (Config->SwaprunNet) - COFF->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP; - COFF->SizeOfOptionalHeader = - sizeof(PEHeaderTy) + sizeof(data_directory) * NumberOfDataDirectory; + auto *coff = reinterpret_cast(buf); + buf += sizeof(*coff); + coff->Machine = config->machine; + coff->NumberOfSections = outputSections.size(); + coff->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; + if (config->largeAddressAware) + coff->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE; + if (!config->is64()) + coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE; + if (config->dll) + coff->Characteristics |= IMAGE_FILE_DLL; + if (!config->relocatable) + coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED; + if (config->swaprunCD) + coff->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP; + if (config->swaprunNet) + coff->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP; + coff->SizeOfOptionalHeader = + sizeof(PEHeaderTy) + sizeof(data_directory) * numberOfDataDirectory; // Write PE header - auto *PE = reinterpret_cast(Buf); - Buf += sizeof(*PE); - PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32; + auto *pe = reinterpret_cast(buf); + buf += sizeof(*pe); + pe->Magic = config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32; // If {Major,Minor}LinkerVersion is left at 0.0, then for some // reason signing the resulting PE file with Authenticode produces a // signature that fails to validate on Windows 7 (but is OK on 10). // Set it to 14.0, which is what VS2015 outputs, and which avoids // that problem. - PE->MajorLinkerVersion = 14; - PE->MinorLinkerVersion = 0; - - PE->ImageBase = Config->ImageBase; - PE->SectionAlignment = PageSize; - PE->FileAlignment = Config->FileAlign; - PE->MajorImageVersion = Config->MajorImageVersion; - PE->MinorImageVersion = Config->MinorImageVersion; - PE->MajorOperatingSystemVersion = Config->MajorOSVersion; - PE->MinorOperatingSystemVersion = Config->MinorOSVersion; - PE->MajorSubsystemVersion = Config->MajorOSVersion; - PE->MinorSubsystemVersion = Config->MinorOSVersion; - PE->Subsystem = Config->Subsystem; - PE->SizeOfImage = SizeOfImage; - PE->SizeOfHeaders = SizeOfHeaders; - if (!Config->NoEntry) { - Defined *Entry = cast(Config->Entry); - PE->AddressOfEntryPoint = Entry->getRVA(); + pe->MajorLinkerVersion = 14; + pe->MinorLinkerVersion = 0; + + pe->ImageBase = config->imageBase; + pe->SectionAlignment = pageSize; + pe->FileAlignment = config->fileAlign; + pe->MajorImageVersion = config->majorImageVersion; + pe->MinorImageVersion = config->minorImageVersion; + pe->MajorOperatingSystemVersion = config->majorOSVersion; + pe->MinorOperatingSystemVersion = config->minorOSVersion; + pe->MajorSubsystemVersion = config->majorOSVersion; + pe->MinorSubsystemVersion = config->minorOSVersion; + pe->Subsystem = config->subsystem; + pe->SizeOfImage = sizeOfImage; + pe->SizeOfHeaders = sizeOfHeaders; + if (!config->noEntry) { + Defined *entry = cast(config->entry); + pe->AddressOfEntryPoint = entry->getRVA(); // Pointer to thumb code must have the LSB set, so adjust it. - if (Config->Machine == ARMNT) - PE->AddressOfEntryPoint |= 1; - } - PE->SizeOfStackReserve = Config->StackReserve; - PE->SizeOfStackCommit = Config->StackCommit; - PE->SizeOfHeapReserve = Config->HeapReserve; - PE->SizeOfHeapCommit = Config->HeapCommit; - if (Config->AppContainer) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER; - if (Config->DynamicBase) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; - if (Config->HighEntropyVA) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; - if (!Config->AllowBind) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND; - if (Config->NxCompat) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; - if (!Config->AllowIsolation) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; - if (Config->GuardCF != GuardCFLevel::Off) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF; - if (Config->IntegrityCheck) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; - if (SetNoSEHCharacteristic) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; - if (Config->TerminalServerAware) - PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; - PE->NumberOfRvaAndSize = NumberOfDataDirectory; - if (TextSec->getVirtualSize()) { - PE->BaseOfCode = TextSec->getRVA(); - PE->SizeOfCode = TextSec->getRawSize(); - } - PE->SizeOfInitializedData = getSizeOfInitializedData(); + if (config->machine == ARMNT) + pe->AddressOfEntryPoint |= 1; + } + pe->SizeOfStackReserve = config->stackReserve; + pe->SizeOfStackCommit = config->stackCommit; + pe->SizeOfHeapReserve = config->heapReserve; + pe->SizeOfHeapCommit = config->heapCommit; + if (config->appContainer) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER; + if (config->dynamicBase) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; + if (config->highEntropyVA) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; + if (!config->allowBind) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND; + if (config->nxCompat) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; + if (!config->allowIsolation) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; + if (config->guardCF != GuardCFLevel::Off) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF; + if (config->integrityCheck) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; + if (setNoSEHCharacteristic) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; + if (config->terminalServerAware) + pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; + pe->NumberOfRvaAndSize = numberOfDataDirectory; + if (textSec->getVirtualSize()) { + pe->BaseOfCode = textSec->getRVA(); + pe->SizeOfCode = textSec->getRawSize(); + } + pe->SizeOfInitializedData = getSizeOfInitializedData(); // Write data directory - auto *Dir = reinterpret_cast(Buf); - Buf += sizeof(*Dir) * NumberOfDataDirectory; - if (!Config->Exports.empty()) { - Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA(); - Dir[EXPORT_TABLE].Size = Edata.getSize(); - } - if (ImportTableStart) { - Dir[IMPORT_TABLE].RelativeVirtualAddress = ImportTableStart->getRVA(); - Dir[IMPORT_TABLE].Size = ImportTableSize; - } - if (IATStart) { - Dir[IAT].RelativeVirtualAddress = IATStart->getRVA(); - Dir[IAT].Size = IATSize; - } - if (RsrcSec->getVirtualSize()) { - Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA(); - Dir[RESOURCE_TABLE].Size = RsrcSec->getVirtualSize(); - } - if (FirstPdata) { - Dir[EXCEPTION_TABLE].RelativeVirtualAddress = FirstPdata->getRVA(); - Dir[EXCEPTION_TABLE].Size = - LastPdata->getRVA() + LastPdata->getSize() - FirstPdata->getRVA(); - } - if (RelocSec->getVirtualSize()) { - Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = RelocSec->getRVA(); - Dir[BASE_RELOCATION_TABLE].Size = RelocSec->getVirtualSize(); - } - if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { - if (Defined *B = dyn_cast(Sym)) { - Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA(); - Dir[TLS_TABLE].Size = Config->is64() + auto *dir = reinterpret_cast(buf); + buf += sizeof(*dir) * numberOfDataDirectory; + if (!config->exports.empty()) { + dir[EXPORT_TABLE].RelativeVirtualAddress = edata.getRVA(); + dir[EXPORT_TABLE].Size = edata.getSize(); + } + if (importTableStart) { + dir[IMPORT_TABLE].RelativeVirtualAddress = importTableStart->getRVA(); + dir[IMPORT_TABLE].Size = importTableSize; + } + if (iatStart) { + dir[IAT].RelativeVirtualAddress = iatStart->getRVA(); + dir[IAT].Size = iatSize; + } + if (rsrcSec->getVirtualSize()) { + dir[RESOURCE_TABLE].RelativeVirtualAddress = rsrcSec->getRVA(); + dir[RESOURCE_TABLE].Size = rsrcSec->getVirtualSize(); + } + if (firstPdata) { + dir[EXCEPTION_TABLE].RelativeVirtualAddress = firstPdata->getRVA(); + dir[EXCEPTION_TABLE].Size = + lastPdata->getRVA() + lastPdata->getSize() - firstPdata->getRVA(); + } + if (relocSec->getVirtualSize()) { + dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA(); + dir[BASE_RELOCATION_TABLE].Size = relocSec->getVirtualSize(); + } + if (Symbol *sym = symtab->findUnderscore("_tls_used")) { + if (Defined *b = dyn_cast(sym)) { + dir[TLS_TABLE].RelativeVirtualAddress = b->getRVA(); + dir[TLS_TABLE].Size = config->is64() ? sizeof(object::coff_tls_directory64) : sizeof(object::coff_tls_directory32); } } - if (DebugDirectory) { - Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA(); - Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize(); + if (debugDirectory) { + dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA(); + dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize(); } - if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) { - if (auto *B = dyn_cast(Sym)) { - SectionChunk *SC = B->getChunk(); - assert(B->getRVA() >= SC->getRVA()); - uint64_t OffsetInChunk = B->getRVA() - SC->getRVA(); - if (!SC->HasData || OffsetInChunk + 4 > SC->getSize()) + if (Symbol *sym = symtab->findUnderscore("_load_config_used")) { + if (auto *b = dyn_cast(sym)) { + SectionChunk *sc = b->getChunk(); + assert(b->getRVA() >= sc->getRVA()); + uint64_t offsetInChunk = b->getRVA() - sc->getRVA(); + if (!sc->hasData || offsetInChunk + 4 > sc->getSize()) fatal("_load_config_used is malformed"); - ArrayRef SecContents = SC->getContents(); - uint32_t LoadConfigSize = - *reinterpret_cast(&SecContents[OffsetInChunk]); - if (OffsetInChunk + LoadConfigSize > SC->getSize()) + ArrayRef secContents = sc->getContents(); + uint32_t loadConfigSize = + *reinterpret_cast(&secContents[offsetInChunk]); + if (offsetInChunk + loadConfigSize > sc->getSize()) fatal("_load_config_used is too large"); - Dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = B->getRVA(); - Dir[LOAD_CONFIG_TABLE].Size = LoadConfigSize; + dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA(); + dir[LOAD_CONFIG_TABLE].Size = loadConfigSize; } } - if (!DelayIdata.empty()) { - Dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress = - DelayIdata.getDirRVA(); - Dir[DELAY_IMPORT_DESCRIPTOR].Size = DelayIdata.getDirSize(); + if (!delayIdata.empty()) { + dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress = + delayIdata.getDirRVA(); + dir[DELAY_IMPORT_DESCRIPTOR].Size = delayIdata.getDirSize(); } // Write section table - for (OutputSection *Sec : OutputSections) { - Sec->writeHeaderTo(Buf); - Buf += sizeof(coff_section); + for (OutputSection *sec : outputSections) { + sec->writeHeaderTo(buf); + buf += sizeof(coff_section); } - SectionTable = ArrayRef( - Buf - OutputSections.size() * sizeof(coff_section), Buf); + sectionTable = ArrayRef( + buf - outputSections.size() * sizeof(coff_section), buf); - if (OutputSymtab.empty() && Strtab.empty()) + if (outputSymtab.empty() && strtab.empty()) return; - COFF->PointerToSymbolTable = PointerToSymbolTable; - uint32_t NumberOfSymbols = OutputSymtab.size(); - COFF->NumberOfSymbols = NumberOfSymbols; - auto *SymbolTable = reinterpret_cast( - Buffer->getBufferStart() + COFF->PointerToSymbolTable); - for (size_t I = 0; I != NumberOfSymbols; ++I) - SymbolTable[I] = OutputSymtab[I]; + coff->PointerToSymbolTable = pointerToSymbolTable; + uint32_t numberOfSymbols = outputSymtab.size(); + coff->NumberOfSymbols = numberOfSymbols; + auto *symbolTable = reinterpret_cast( + buffer->getBufferStart() + coff->PointerToSymbolTable); + for (size_t i = 0; i != numberOfSymbols; ++i) + symbolTable[i] = outputSymtab[i]; // Create the string table, it follows immediately after the symbol table. // The first 4 bytes is length including itself. - Buf = reinterpret_cast(&SymbolTable[NumberOfSymbols]); - write32le(Buf, Strtab.size() + 4); - if (!Strtab.empty()) - memcpy(Buf + 4, Strtab.data(), Strtab.size()); + buf = reinterpret_cast(&symbolTable[numberOfSymbols]); + write32le(buf, strtab.size() + 4); + if (!strtab.empty()) + memcpy(buf + 4, strtab.data(), strtab.size()); } -void Writer::openFile(StringRef Path) { - Buffer = CHECK( - FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable), - "failed to open " + Path); +void Writer::openFile(StringRef path) { + buffer = CHECK( + FileOutputBuffer::create(path, fileSize, FileOutputBuffer::F_executable), + "failed to open " + path); } void Writer::createSEHTable() { // Set the no SEH characteristic on x86 binaries unless we find exception // handlers. - SetNoSEHCharacteristic = true; + setNoSEHCharacteristic = true; - SymbolRVASet Handlers; - for (ObjFile *File : ObjFile::Instances) { + SymbolRVASet handlers; + for (ObjFile *file : ObjFile::instances) { // FIXME: We should error here instead of earlier unless /safeseh:no was // passed. - if (!File->hasSafeSEH()) + if (!file->hasSafeSEH()) return; - markSymbolsForRVATable(File, File->getSXDataChunks(), Handlers); + markSymbolsForRVATable(file, file->getSXDataChunks(), handlers); } // Remove the "no SEH" characteristic if all object files were built with // safeseh, we found some exception handlers, and there is a load config in // the object. - SetNoSEHCharacteristic = - Handlers.empty() || !Symtab->findUnderscore("_load_config_used"); + setNoSEHCharacteristic = + handlers.empty() || !symtab->findUnderscore("_load_config_used"); - maybeAddRVATable(std::move(Handlers), "__safe_se_handler_table", + maybeAddRVATable(std::move(handlers), "__safe_se_handler_table", "__safe_se_handler_count"); } // Add a symbol to an RVA set. Two symbols may have the same RVA, but an RVA set // cannot contain duplicates. Therefore, the set is uniqued by Chunk and the // symbol's offset into that Chunk. -static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) { - Chunk *C = S->getChunk(); - if (auto *SC = dyn_cast(C)) - C = SC->Repl; // Look through ICF replacement. - uint32_t Off = S->getRVA() - (C ? C->getRVA() : 0); - RVASet.insert({C, Off}); +static void addSymbolToRVASet(SymbolRVASet &rvaSet, Defined *s) { + Chunk *c = s->getChunk(); + if (auto *sc = dyn_cast(c)) + c = sc->repl; // Look through ICF replacement. + uint32_t off = s->getRVA() - (c ? c->getRVA() : 0); + rvaSet.insert({c, off}); } // Given a symbol, add it to the GFIDs table if it is a live, defined, function // symbol in an executable section. -static void maybeAddAddressTakenFunction(SymbolRVASet &AddressTakenSyms, - Symbol *S) { - if (!S) +static void maybeAddAddressTakenFunction(SymbolRVASet &addressTakenSyms, + Symbol *s) { + if (!s) return; - switch (S->kind()) { + switch (s->kind()) { case Symbol::DefinedLocalImportKind: case Symbol::DefinedImportDataKind: // Defines an __imp_ pointer, so it is data, so it is ignored. @@ -1491,19 +1491,19 @@ static void maybeAddAddressTakenFunction(SymbolRVASet &AddressTakenSyms, case Symbol::DefinedImportThunkKind: // Thunks are always code, include them. - addSymbolToRVASet(AddressTakenSyms, cast(S)); + addSymbolToRVASet(addressTakenSyms, cast(s)); break; case Symbol::DefinedRegularKind: { // This is a regular, defined, symbol from a COFF file. Mark the symbol as // address taken if the symbol type is function and it's in an executable // section. - auto *D = cast(S); - if (D->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) { - SectionChunk *SC = dyn_cast(D->getChunk()); - if (SC && SC->Live && - SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) - addSymbolToRVASet(AddressTakenSyms, D); + auto *d = cast(s); + if (d->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) { + SectionChunk *sc = dyn_cast(d->getChunk()); + if (sc && sc->live && + sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) + addSymbolToRVASet(addressTakenSyms, d); } break; } @@ -1512,23 +1512,23 @@ static void maybeAddAddressTakenFunction(SymbolRVASet &AddressTakenSyms, // Visit all relocations from all section contributions of this object file and // mark the relocation target as address-taken. -static void markSymbolsWithRelocations(ObjFile *File, - SymbolRVASet &UsedSymbols) { - for (Chunk *C : File->getChunks()) { +static void markSymbolsWithRelocations(ObjFile *file, + SymbolRVASet &usedSymbols) { + for (Chunk *c : file->getChunks()) { // We only care about live section chunks. Common chunks and other chunks // don't generally contain relocations. - SectionChunk *SC = dyn_cast(C); - if (!SC || !SC->Live) + SectionChunk *sc = dyn_cast(c); + if (!sc || !sc->live) continue; - for (const coff_relocation &Reloc : SC->getRelocs()) { - if (Config->Machine == I386 && Reloc.Type == COFF::IMAGE_REL_I386_REL32) + for (const coff_relocation &reloc : sc->getRelocs()) { + if (config->machine == I386 && reloc.Type == COFF::IMAGE_REL_I386_REL32) // Ignore relative relocations on x86. On x86_64 they can't be ignored // since they're also used to compute absolute addresses. continue; - Symbol *Ref = SC->File->getSymbol(Reloc.SymbolTableIndex); - maybeAddAddressTakenFunction(UsedSymbols, Ref); + Symbol *ref = sc->file->getSymbol(reloc.SymbolTableIndex); + maybeAddAddressTakenFunction(usedSymbols, ref); } } } @@ -1537,89 +1537,89 @@ static void markSymbolsWithRelocations(ObjFile *File, // address-taken functions. It is sorted and uniqued, just like the safe SEH // table. void Writer::createGuardCFTables() { - SymbolRVASet AddressTakenSyms; - SymbolRVASet LongJmpTargets; - for (ObjFile *File : ObjFile::Instances) { + SymbolRVASet addressTakenSyms; + SymbolRVASet longJmpTargets; + for (ObjFile *file : ObjFile::instances) { // If the object was compiled with /guard:cf, the address taken symbols // are in .gfids$y sections, and the longjmp targets are in .gljmp$y // sections. If the object was not compiled with /guard:cf, we assume there // were no setjmp targets, and that all code symbols with relocations are // possibly address-taken. - if (File->hasGuardCF()) { - markSymbolsForRVATable(File, File->getGuardFidChunks(), AddressTakenSyms); - markSymbolsForRVATable(File, File->getGuardLJmpChunks(), LongJmpTargets); + if (file->hasGuardCF()) { + markSymbolsForRVATable(file, file->getGuardFidChunks(), addressTakenSyms); + markSymbolsForRVATable(file, file->getGuardLJmpChunks(), longJmpTargets); } else { - markSymbolsWithRelocations(File, AddressTakenSyms); + markSymbolsWithRelocations(file, addressTakenSyms); } } // Mark the image entry as address-taken. - if (Config->Entry) - maybeAddAddressTakenFunction(AddressTakenSyms, Config->Entry); + if (config->entry) + maybeAddAddressTakenFunction(addressTakenSyms, config->entry); // Mark exported symbols in executable sections as address-taken. - for (Export &E : Config->Exports) - maybeAddAddressTakenFunction(AddressTakenSyms, E.Sym); + for (Export &e : config->exports) + maybeAddAddressTakenFunction(addressTakenSyms, e.sym); // Ensure sections referenced in the gfid table are 16-byte aligned. - for (const ChunkAndOffset &C : AddressTakenSyms) - if (C.InputChunk->getAlignment() < 16) - C.InputChunk->setAlignment(16); + for (const ChunkAndOffset &c : addressTakenSyms) + if (c.inputChunk->getAlignment() < 16) + c.inputChunk->setAlignment(16); - maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table", + maybeAddRVATable(std::move(addressTakenSyms), "__guard_fids_table", "__guard_fids_count"); // Add the longjmp target table unless the user told us not to. - if (Config->GuardCF == GuardCFLevel::Full) - maybeAddRVATable(std::move(LongJmpTargets), "__guard_longjmp_table", + if (config->guardCF == GuardCFLevel::Full) + maybeAddRVATable(std::move(longJmpTargets), "__guard_longjmp_table", "__guard_longjmp_count"); // Set __guard_flags, which will be used in the load config to indicate that // /guard:cf was enabled. - uint32_t GuardFlags = uint32_t(coff_guard_flags::CFInstrumented) | + uint32_t guardFlags = uint32_t(coff_guard_flags::CFInstrumented) | uint32_t(coff_guard_flags::HasFidTable); - if (Config->GuardCF == GuardCFLevel::Full) - GuardFlags |= uint32_t(coff_guard_flags::HasLongJmpTable); - Symbol *FlagSym = Symtab->findUnderscore("__guard_flags"); - cast(FlagSym)->setVA(GuardFlags); + if (config->guardCF == GuardCFLevel::Full) + guardFlags |= uint32_t(coff_guard_flags::HasLongJmpTable); + Symbol *flagSym = symtab->findUnderscore("__guard_flags"); + cast(flagSym)->setVA(guardFlags); } // Take a list of input sections containing symbol table indices and add those // symbols to an RVA table. The challenge is that symbol RVAs are not known and // depend on the table size, so we can't directly build a set of integers. -void Writer::markSymbolsForRVATable(ObjFile *File, - ArrayRef SymIdxChunks, - SymbolRVASet &TableSymbols) { - for (SectionChunk *C : SymIdxChunks) { +void Writer::markSymbolsForRVATable(ObjFile *file, + ArrayRef symIdxChunks, + SymbolRVASet &tableSymbols) { + for (SectionChunk *c : symIdxChunks) { // Skip sections discarded by linker GC. This comes up when a .gfids section // is associated with something like a vtable and the vtable is discarded. // In this case, the associated gfids section is discarded, and we don't // mark the virtual member functions as address-taken by the vtable. - if (!C->Live) + if (!c->live) continue; // Validate that the contents look like symbol table indices. - ArrayRef Data = C->getContents(); - if (Data.size() % 4 != 0) { - warn("ignoring " + C->getSectionName() + - " symbol table index section in object " + toString(File)); + ArrayRef data = c->getContents(); + if (data.size() % 4 != 0) { + warn("ignoring " + c->getSectionName() + + " symbol table index section in object " + toString(file)); continue; } // Read each symbol table index and check if that symbol was included in the // final link. If so, add it to the table symbol set. - ArrayRef SymIndices( - reinterpret_cast(Data.data()), Data.size() / 4); - ArrayRef ObjSymbols = File->getSymbols(); - for (uint32_t SymIndex : SymIndices) { - if (SymIndex >= ObjSymbols.size()) { + ArrayRef symIndices( + reinterpret_cast(data.data()), data.size() / 4); + ArrayRef objSymbols = file->getSymbols(); + for (uint32_t symIndex : symIndices) { + if (symIndex >= objSymbols.size()) { warn("ignoring invalid symbol table index in section " + - C->getSectionName() + " in object " + toString(File)); + c->getSectionName() + " in object " + toString(file)); continue; } - if (Symbol *S = ObjSymbols[SymIndex]) { - if (S->isLive()) - addSymbolToRVASet(TableSymbols, cast(S)); + if (Symbol *s = objSymbols[symIndex]) { + if (s->isLive()) + addSymbolToRVASet(tableSymbols, cast(s)); } } } @@ -1628,18 +1628,18 @@ void Writer::markSymbolsForRVATable(ObjFile *File, // Replace the absolute table symbol with a synthetic symbol pointing to // TableChunk so that we can emit base relocations for it and resolve section // relative relocations. -void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym, - StringRef CountSym) { - if (TableSymbols.empty()) +void Writer::maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym, + StringRef countSym) { + if (tableSymbols.empty()) return; - RVATableChunk *TableChunk = make(std::move(TableSymbols)); - RdataSec->addChunk(TableChunk); + RVATableChunk *tableChunk = make(std::move(tableSymbols)); + rdataSec->addChunk(tableChunk); - Symbol *T = Symtab->findUnderscore(TableSym); - Symbol *C = Symtab->findUnderscore(CountSym); - replaceSymbol(T, T->getName(), TableChunk); - cast(C)->setVA(TableChunk->getSize() / 4); + Symbol *t = symtab->findUnderscore(tableSym); + Symbol *c = symtab->findUnderscore(countSym); + replaceSymbol(t, t->getName(), tableChunk); + cast(c)->setVA(tableChunk->getSize() / 4); } // MinGW specific. Gather all relocations that are imported from a DLL even @@ -1647,26 +1647,26 @@ void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym, // uses for fixing them up, and provide the synthetic symbols that the // runtime uses for finding the table. void Writer::createRuntimePseudoRelocs() { - std::vector Rels; + std::vector rels; - for (Chunk *C : Symtab->getChunks()) { - auto *SC = dyn_cast(C); - if (!SC || !SC->Live) + for (Chunk *c : symtab->getChunks()) { + auto *sc = dyn_cast(c); + if (!sc || !sc->live) continue; - SC->getRuntimePseudoRelocs(Rels); + sc->getRuntimePseudoRelocs(rels); } - if (!Rels.empty()) - log("Writing " + Twine(Rels.size()) + " runtime pseudo relocations"); - PseudoRelocTableChunk *Table = make(Rels); - RdataSec->addChunk(Table); - EmptyChunk *EndOfList = make(); - RdataSec->addChunk(EndOfList); + if (!rels.empty()) + log("Writing " + Twine(rels.size()) + " runtime pseudo relocations"); + PseudoRelocTableChunk *table = make(rels); + rdataSec->addChunk(table); + EmptyChunk *endOfList = make(); + rdataSec->addChunk(endOfList); - Symbol *HeadSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__"); - Symbol *EndSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__"); - replaceSymbol(HeadSym, HeadSym->getName(), Table); - replaceSymbol(EndSym, EndSym->getName(), EndOfList); + Symbol *headSym = symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__"); + Symbol *endSym = symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__"); + replaceSymbol(headSym, headSym->getName(), table); + replaceSymbol(endSym, endSym->getName(), endOfList); } // MinGW specific. @@ -1675,32 +1675,32 @@ void Writer::createRuntimePseudoRelocs() { // There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__ // and __DTOR_LIST__ respectively. void Writer::insertCtorDtorSymbols() { - AbsolutePointerChunk *CtorListHead = make(-1); - AbsolutePointerChunk *CtorListEnd = make(0); - AbsolutePointerChunk *DtorListHead = make(-1); - AbsolutePointerChunk *DtorListEnd = make(0); - CtorsSec->insertChunkAtStart(CtorListHead); - CtorsSec->addChunk(CtorListEnd); - DtorsSec->insertChunkAtStart(DtorListHead); - DtorsSec->addChunk(DtorListEnd); - - Symbol *CtorListSym = Symtab->findUnderscore("__CTOR_LIST__"); - Symbol *DtorListSym = Symtab->findUnderscore("__DTOR_LIST__"); - replaceSymbol(CtorListSym, CtorListSym->getName(), - CtorListHead); - replaceSymbol(DtorListSym, DtorListSym->getName(), - DtorListHead); + AbsolutePointerChunk *ctorListHead = make(-1); + AbsolutePointerChunk *ctorListEnd = make(0); + AbsolutePointerChunk *dtorListHead = make(-1); + AbsolutePointerChunk *dtorListEnd = make(0); + ctorsSec->insertChunkAtStart(ctorListHead); + ctorsSec->addChunk(ctorListEnd); + dtorsSec->insertChunkAtStart(dtorListHead); + dtorsSec->addChunk(dtorListEnd); + + Symbol *ctorListSym = symtab->findUnderscore("__CTOR_LIST__"); + Symbol *dtorListSym = symtab->findUnderscore("__DTOR_LIST__"); + replaceSymbol(ctorListSym, ctorListSym->getName(), + ctorListHead); + replaceSymbol(dtorListSym, dtorListSym->getName(), + dtorListHead); } // Handles /section options to allow users to overwrite // section attributes. void Writer::setSectionPermissions() { - for (auto &P : Config->Section) { - StringRef Name = P.first; - uint32_t Perm = P.second; - for (OutputSection *Sec : OutputSections) - if (Sec->Name == Name) - Sec->setPermissions(Perm); + for (auto &p : config->section) { + StringRef name = p.first; + uint32_t perm = p.second; + for (OutputSection *sec : outputSections) + if (sec->name == name) + sec->setPermissions(perm); } } @@ -1708,18 +1708,18 @@ void Writer::setSectionPermissions() { void Writer::writeSections() { // Record the number of sections to apply section index relocations // against absolute symbols. See applySecIdx in Chunks.cpp.. - DefinedAbsolute::NumOutputSections = OutputSections.size(); + DefinedAbsolute::numOutputSections = outputSections.size(); - uint8_t *Buf = Buffer->getBufferStart(); - for (OutputSection *Sec : OutputSections) { - uint8_t *SecBuf = Buf + Sec->getFileOff(); + uint8_t *buf = buffer->getBufferStart(); + for (OutputSection *sec : outputSections) { + uint8_t *secBuf = buf + sec->getFileOff(); // Fill gaps between functions in .text with INT3 instructions // instead of leaving as NUL bytes (which can be interpreted as // ADD instructions). - if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE) - memset(SecBuf, 0xCC, Sec->getRawSize()); - parallelForEach(Sec->Chunks, [&](Chunk *C) { - C->writeTo(SecBuf + C->getRVA() - Sec->getRVA()); + if (sec->header.Characteristics & IMAGE_SCN_CNT_CODE) + memset(secBuf, 0xCC, sec->getRawSize()); + parallelForEach(sec->chunks, [&](Chunk *c) { + c->writeTo(secBuf + c->getRVA() - sec->getRVA()); }); } } @@ -1731,8 +1731,8 @@ void Writer::writeBuildId() { // 2) In all cases, the PE COFF file header also contains a timestamp. // For reproducibility, instead of a timestamp we want to use a hash of the // PE contents. - if (Config->Debug) { - assert(BuildId && "BuildId is not set!"); + if (config->debug) { + assert(buildId && "BuildId is not set!"); // BuildId->BuildId was filled in when the PDB was written. } @@ -1740,65 +1740,65 @@ void Writer::writeBuildId() { // "timestamp" in the COFF file header, and the ones in the coff debug // directory. Now we can hash the file and write that hash to the various // timestamp fields in the file. - StringRef OutputFileData( - reinterpret_cast(Buffer->getBufferStart()), - Buffer->getBufferSize()); + StringRef outputFileData( + reinterpret_cast(buffer->getBufferStart()), + buffer->getBufferSize()); - uint32_t Timestamp = Config->Timestamp; - uint64_t Hash = 0; - bool GenerateSyntheticBuildId = - Config->MinGW && Config->Debug && Config->PDBPath.empty(); + uint32_t timestamp = config->timestamp; + uint64_t hash = 0; + bool generateSyntheticBuildId = + config->mingw && config->debug && config->pdbPath.empty(); - if (Config->Repro || GenerateSyntheticBuildId) - Hash = xxHash64(OutputFileData); + if (config->repro || generateSyntheticBuildId) + hash = xxHash64(outputFileData); - if (Config->Repro) - Timestamp = static_cast(Hash); + if (config->repro) + timestamp = static_cast(hash); - if (GenerateSyntheticBuildId) { + if (generateSyntheticBuildId) { // For MinGW builds without a PDB file, we still generate a build id // to allow associating a crash dump to the executable. - BuildId->BuildId->PDB70.CVSignature = OMF::Signature::PDB70; - BuildId->BuildId->PDB70.Age = 1; - memcpy(BuildId->BuildId->PDB70.Signature, &Hash, 8); + buildId->buildId->PDB70.CVSignature = OMF::Signature::PDB70; + buildId->buildId->PDB70.Age = 1; + memcpy(buildId->buildId->PDB70.Signature, &hash, 8); // xxhash only gives us 8 bytes, so put some fixed data in the other half. - memcpy(&BuildId->BuildId->PDB70.Signature[8], "LLD PDB.", 8); + memcpy(&buildId->buildId->PDB70.Signature[8], "LLD PDB.", 8); } - if (DebugDirectory) - DebugDirectory->setTimeDateStamp(Timestamp); + if (debugDirectory) + debugDirectory->setTimeDateStamp(timestamp); - uint8_t *Buf = Buffer->getBufferStart(); - Buf += DOSStubSize + sizeof(PEMagic); - object::coff_file_header *CoffHeader = - reinterpret_cast(Buf); - CoffHeader->TimeDateStamp = Timestamp; + uint8_t *buf = buffer->getBufferStart(); + buf += dosStubSize + sizeof(PEMagic); + object::coff_file_header *coffHeader = + reinterpret_cast(buf); + coffHeader->TimeDateStamp = timestamp; } // Sort .pdata section contents according to PE/COFF spec 5.5. void Writer::sortExceptionTable() { - if (!FirstPdata) + if (!firstPdata) return; // We assume .pdata contains function table entries only. - auto BufAddr = [&](Chunk *C) { - OutputSection *OS = C->getOutputSection(); - return Buffer->getBufferStart() + OS->getFileOff() + C->getRVA() - - OS->getRVA(); + auto bufAddr = [&](Chunk *c) { + OutputSection *os = c->getOutputSection(); + return buffer->getBufferStart() + os->getFileOff() + c->getRVA() - + os->getRVA(); }; - uint8_t *Begin = BufAddr(FirstPdata); - uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize(); - if (Config->Machine == AMD64) { - struct Entry { ulittle32_t Begin, End, Unwind; }; + uint8_t *begin = bufAddr(firstPdata); + uint8_t *end = bufAddr(lastPdata) + lastPdata->getSize(); + if (config->machine == AMD64) { + struct Entry { ulittle32_t begin, end, unwind; }; parallelSort( - MutableArrayRef((Entry *)Begin, (Entry *)End), - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); + MutableArrayRef((Entry *)begin, (Entry *)end), + [](const Entry &a, const Entry &b) { return a.begin < b.begin; }); return; } - if (Config->Machine == ARMNT || Config->Machine == ARM64) { - struct Entry { ulittle32_t Begin, Unwind; }; + if (config->machine == ARMNT || config->machine == ARM64) { + struct Entry { ulittle32_t begin, unwind; }; parallelSort( - MutableArrayRef((Entry *)Begin, (Entry *)End), - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); + MutableArrayRef((Entry *)begin, (Entry *)end), + [](const Entry &a, const Entry &b) { return a.begin < b.begin; }); return; } errs() << "warning: don't know how to handle .pdata.\n"; @@ -1818,92 +1818,92 @@ void Writer::sortExceptionTable() { // pointers in the order that they are listed in the object file (top to // bottom), otherwise global objects might not be initialized in the // correct order. -void Writer::sortCRTSectionChunks(std::vector &Chunks) { - auto SectionChunkOrder = [](const Chunk *A, const Chunk *B) { - auto SA = dyn_cast(A); - auto SB = dyn_cast(B); - assert(SA && SB && "Non-section chunks in CRT section!"); +void Writer::sortCRTSectionChunks(std::vector &chunks) { + auto sectionChunkOrder = [](const Chunk *a, const Chunk *b) { + auto sa = dyn_cast(a); + auto sb = dyn_cast(b); + assert(sa && sb && "Non-section chunks in CRT section!"); - StringRef SAObj = SA->File->MB.getBufferIdentifier(); - StringRef SBObj = SB->File->MB.getBufferIdentifier(); + StringRef sAObj = sa->file->mb.getBufferIdentifier(); + StringRef sBObj = sb->file->mb.getBufferIdentifier(); - return SAObj == SBObj && SA->getSectionNumber() < SB->getSectionNumber(); + return sAObj == sBObj && sa->getSectionNumber() < sb->getSectionNumber(); }; - llvm::stable_sort(Chunks, SectionChunkOrder); + llvm::stable_sort(chunks, sectionChunkOrder); - if (Config->Verbose) { - for (auto &C : Chunks) { - auto SC = dyn_cast(C); - log(" " + SC->File->MB.getBufferIdentifier().str() + - ", SectionID: " + Twine(SC->getSectionNumber())); + if (config->verbose) { + for (auto &c : chunks) { + auto sc = dyn_cast(c); + log(" " + sc->file->mb.getBufferIdentifier().str() + + ", SectionID: " + Twine(sc->getSectionNumber())); } } } -OutputSection *Writer::findSection(StringRef Name) { - for (OutputSection *Sec : OutputSections) - if (Sec->Name == Name) - return Sec; +OutputSection *Writer::findSection(StringRef name) { + for (OutputSection *sec : outputSections) + if (sec->name == name) + return sec; return nullptr; } uint32_t Writer::getSizeOfInitializedData() { - uint32_t Res = 0; - for (OutputSection *S : OutputSections) - if (S->Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) - Res += S->getRawSize(); - return Res; + uint32_t res = 0; + for (OutputSection *s : outputSections) + if (s->header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) + res += s->getRawSize(); + return res; } // Add base relocations to .reloc section. void Writer::addBaserels() { - if (!Config->Relocatable) + if (!config->relocatable) return; - RelocSec->Chunks.clear(); - std::vector V; - for (OutputSection *Sec : OutputSections) { - if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + relocSec->chunks.clear(); + std::vector v; + for (OutputSection *sec : outputSections) { + if (sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) continue; // Collect all locations for base relocations. - for (Chunk *C : Sec->Chunks) - C->getBaserels(&V); + for (Chunk *c : sec->chunks) + c->getBaserels(&v); // Add the addresses to .reloc section. - if (!V.empty()) - addBaserelBlocks(V); - V.clear(); + if (!v.empty()) + addBaserelBlocks(v); + v.clear(); } } // Add addresses to .reloc section. Note that addresses are grouped by page. -void Writer::addBaserelBlocks(std::vector &V) { - const uint32_t Mask = ~uint32_t(PageSize - 1); - uint32_t Page = V[0].RVA & Mask; - size_t I = 0, J = 1; - for (size_t E = V.size(); J < E; ++J) { - uint32_t P = V[J].RVA & Mask; - if (P == Page) +void Writer::addBaserelBlocks(std::vector &v) { + const uint32_t mask = ~uint32_t(pageSize - 1); + uint32_t page = v[0].rva & mask; + size_t i = 0, j = 1; + for (size_t e = v.size(); j < e; ++j) { + uint32_t p = v[j].rva & mask; + if (p == page) continue; - RelocSec->addChunk(make(Page, &V[I], &V[0] + J)); - I = J; - Page = P; + relocSec->addChunk(make(page, &v[i], &v[0] + j)); + i = j; + page = p; } - if (I == J) + if (i == j) return; - RelocSec->addChunk(make(Page, &V[I], &V[0] + J)); + relocSec->addChunk(make(page, &v[i], &v[0] + j)); } -PartialSection *Writer::createPartialSection(StringRef Name, - uint32_t OutChars) { - PartialSection *&PSec = PartialSections[{Name, OutChars}]; - if (PSec) - return PSec; - PSec = make(Name, OutChars); - return PSec; +PartialSection *Writer::createPartialSection(StringRef name, + uint32_t outChars) { + PartialSection *&pSec = partialSections[{name, outChars}]; + if (pSec) + return pSec; + pSec = make(name, outChars); + return pSec; } -PartialSection *Writer::findPartialSection(StringRef Name, uint32_t OutChars) { - auto It = PartialSections.find({Name, OutChars}); - if (It != PartialSections.end()) - return It->second; +PartialSection *Writer::findPartialSection(StringRef name, uint32_t outChars) { + auto it = partialSections.find({name, outChars}); + if (it != partialSections.end()) + return it->second; return nullptr; } diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h index 8fd97cb..96389df 100644 --- a/lld/COFF/Writer.h +++ b/lld/COFF/Writer.h @@ -18,17 +18,17 @@ namespace lld { namespace coff { -static const int PageSize = 4096; +static const int pageSize = 4096; void writeResult(); class PartialSection { public: - PartialSection(StringRef N, uint32_t Chars) - : Name(N), Characteristics(Chars) {} - StringRef Name; - unsigned Characteristics; - std::vector Chunks; + PartialSection(StringRef n, uint32_t chars) + : name(n), characteristics(chars) {} + StringRef name; + unsigned characteristics; + std::vector chunks; }; // OutputSection represents a section in an output file. It's a @@ -38,45 +38,45 @@ public: // non-overlapping file offsets and RVAs. class OutputSection { public: - OutputSection(llvm::StringRef N, uint32_t Chars) : Name(N) { - Header.Characteristics = Chars; + OutputSection(llvm::StringRef n, uint32_t chars) : name(n) { + header.Characteristics = chars; } - void addChunk(Chunk *C); - void insertChunkAtStart(Chunk *C); - void merge(OutputSection *Other); - void setPermissions(uint32_t C); - uint64_t getRVA() { return Header.VirtualAddress; } - uint64_t getFileOff() { return Header.PointerToRawData; } - void writeHeaderTo(uint8_t *Buf); - void addContributingPartialSection(PartialSection *Sec); + void addChunk(Chunk *c); + void insertChunkAtStart(Chunk *c); + void merge(OutputSection *other); + void setPermissions(uint32_t c); + uint64_t getRVA() { return header.VirtualAddress; } + uint64_t getFileOff() { return header.PointerToRawData; } + void writeHeaderTo(uint8_t *buf); + void addContributingPartialSection(PartialSection *sec); // Returns the size of this section in an executable memory image. // This may be smaller than the raw size (the raw size is multiple // of disk sector size, so there may be padding at end), or may be // larger (if that's the case, the loader reserves spaces after end // of raw data). - uint64_t getVirtualSize() { return Header.VirtualSize; } + uint64_t getVirtualSize() { return header.VirtualSize; } // Returns the size of the section in the output file. - uint64_t getRawSize() { return Header.SizeOfRawData; } + uint64_t getRawSize() { return header.SizeOfRawData; } // Set offset into the string table storing this section name. // Used only when the name is longer than 8 bytes. - void setStringTableOff(uint32_t V) { StringTableOff = V; } + void setStringTableOff(uint32_t v) { stringTableOff = v; } // N.B. The section index is one based. - uint32_t SectionIndex = 0; + uint32_t sectionIndex = 0; - llvm::StringRef Name; - llvm::object::coff_section Header = {}; + llvm::StringRef name; + llvm::object::coff_section header = {}; - std::vector Chunks; - std::vector OrigChunks; + std::vector chunks; + std::vector origChunks; - std::vector ContribSections; + std::vector contribSections; private: - uint32_t StringTableOff = 0; + uint32_t stringTableOff = 0; }; } // namespace coff diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp index 0691189..4ea3a43 100644 --- a/lld/Common/Args.cpp +++ b/lld/Common/Args.cpp @@ -19,64 +19,64 @@ using namespace lld; // TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode // function metadata. -CodeGenOpt::Level lld::args::getCGOptLevel(int OptLevelLTO) { - if (OptLevelLTO == 3) +CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) { + if (optLevelLTO == 3) return CodeGenOpt::Aggressive; - assert(OptLevelLTO < 3); + assert(optLevelLTO < 3); return CodeGenOpt::Default; } -int64_t lld::args::getInteger(opt::InputArgList &Args, unsigned Key, +int64_t lld::args::getInteger(opt::InputArgList &args, unsigned key, int64_t Default) { - auto *A = Args.getLastArg(Key); - if (!A) + auto *a = args.getLastArg(key); + if (!a) return Default; - int64_t V; - if (to_integer(A->getValue(), V, 10)) - return V; + int64_t v; + if (to_integer(a->getValue(), v, 10)) + return v; - StringRef Spelling = Args.getArgString(A->getIndex()); - error(Spelling + ": number expected, but got '" + A->getValue() + "'"); + StringRef spelling = args.getArgString(a->getIndex()); + error(spelling + ": number expected, but got '" + a->getValue() + "'"); return 0; } -std::vector lld::args::getStrings(opt::InputArgList &Args, int Id) { - std::vector V; - for (auto *Arg : Args.filtered(Id)) - V.push_back(Arg->getValue()); - return V; +std::vector lld::args::getStrings(opt::InputArgList &args, int id) { + std::vector v; + for (auto *arg : args.filtered(id)) + v.push_back(arg->getValue()); + return v; } -uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id, - StringRef Key, uint64_t Default) { - for (auto *Arg : Args.filtered_reverse(Id)) { - std::pair KV = StringRef(Arg->getValue()).split('='); - if (KV.first == Key) { - uint64_t Result = Default; - if (!to_integer(KV.second, Result)) - error("invalid " + Key + ": " + KV.second); - return Result; +uint64_t lld::args::getZOptionValue(opt::InputArgList &args, int id, + StringRef key, uint64_t Default) { + for (auto *arg : args.filtered_reverse(id)) { + std::pair kv = StringRef(arg->getValue()).split('='); + if (kv.first == key) { + uint64_t result = Default; + if (!to_integer(kv.second, result)) + error("invalid " + key + ": " + kv.second); + return result; } } return Default; } -std::vector lld::args::getLines(MemoryBufferRef MB) { - SmallVector Arr; - MB.getBuffer().split(Arr, '\n'); +std::vector lld::args::getLines(MemoryBufferRef mb) { + SmallVector arr; + mb.getBuffer().split(arr, '\n'); - std::vector Ret; - for (StringRef S : Arr) { - S = S.trim(); - if (!S.empty() && S[0] != '#') - Ret.push_back(S); + std::vector ret; + for (StringRef s : arr) { + s = s.trim(); + if (!s.empty() && s[0] != '#') + ret.push_back(s); } - return Ret; + return ret; } -StringRef lld::args::getFilenameWithoutExe(StringRef Path) { - if (Path.endswith_lower(".exe")) - return sys::path::stem(Path); - return sys::path::filename(Path); +StringRef lld::args::getFilenameWithoutExe(StringRef path) { + if (path.endswith_lower(".exe")) + return sys::path::stem(path); + return sys::path::filename(path); } diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp index 7c68353..f5d3eb4 100644 --- a/lld/Common/ErrorHandler.cpp +++ b/lld/Common/ErrorHandler.cpp @@ -26,29 +26,29 @@ using namespace lld; // The functions defined in this file can be called from multiple threads, // but outs() or errs() are not thread-safe. We protect them using a mutex. -static std::mutex Mu; +static std::mutex mu; // Prints "\n" or does nothing, depending on Msg contents of // the previous call of this function. -static void newline(raw_ostream *ErrorOS, const Twine &Msg) { +static void newline(raw_ostream *errorOS, const Twine &msg) { // True if the previous error message contained "\n". // We want to separate multi-line error messages with a newline. - static bool Flag; + static bool flag; - if (Flag) - *ErrorOS << "\n"; - Flag = StringRef(Msg.str()).contains('\n'); + if (flag) + *errorOS << "\n"; + flag = StringRef(msg.str()).contains('\n'); } ErrorHandler &lld::errorHandler() { - static ErrorHandler Handler; - return Handler; + static ErrorHandler handler; + return handler; } -void lld::exitLld(int Val) { +void lld::exitLld(int val) { // Delete any temporary file, while keeping the memory mapping open. - if (errorHandler().OutputBuffer) - errorHandler().OutputBuffer->discard(); + if (errorHandler().outputBuffer) + errorHandler().outputBuffer->discard(); // Dealloc/destroy ManagedStatic variables before calling // _exit(). In a non-LTO build, this is a nop. In an LTO @@ -57,87 +57,87 @@ void lld::exitLld(int Val) { outs().flush(); errs().flush(); - _exit(Val); + _exit(val); } -void lld::diagnosticHandler(const DiagnosticInfo &DI) { - SmallString<128> S; - raw_svector_ostream OS(S); - DiagnosticPrinterRawOStream DP(OS); - DI.print(DP); - switch (DI.getSeverity()) { +void lld::diagnosticHandler(const DiagnosticInfo &di) { + SmallString<128> s; + raw_svector_ostream os(s); + DiagnosticPrinterRawOStream dp(os); + di.print(dp); + switch (di.getSeverity()) { case DS_Error: - error(S); + error(s); break; case DS_Warning: - warn(S); + warn(s); break; case DS_Remark: case DS_Note: - message(S); + message(s); break; } } -void lld::checkError(Error E) { - handleAllErrors(std::move(E), - [&](ErrorInfoBase &EIB) { error(EIB.message()); }); +void lld::checkError(Error e) { + handleAllErrors(std::move(e), + [&](ErrorInfoBase &eib) { error(eib.message()); }); } -void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { - *ErrorOS << LogName << ": "; - if (ColorDiagnostics) { - ErrorOS->changeColor(C, true); - *ErrorOS << S; - ErrorOS->resetColor(); +void ErrorHandler::print(StringRef s, raw_ostream::Colors c) { + *errorOS << logName << ": "; + if (colorDiagnostics) { + errorOS->changeColor(c, true); + *errorOS << s; + errorOS->resetColor(); } else { - *ErrorOS << S; + *errorOS << s; } } -void ErrorHandler::log(const Twine &Msg) { - if (Verbose) { - std::lock_guard Lock(Mu); - *ErrorOS << LogName << ": " << Msg << "\n"; +void ErrorHandler::log(const Twine &msg) { + if (verbose) { + std::lock_guard lock(mu); + *errorOS << logName << ": " << msg << "\n"; } } -void ErrorHandler::message(const Twine &Msg) { - std::lock_guard Lock(Mu); - outs() << Msg << "\n"; +void ErrorHandler::message(const Twine &msg) { + std::lock_guard lock(mu); + outs() << msg << "\n"; outs().flush(); } -void ErrorHandler::warn(const Twine &Msg) { - if (FatalWarnings) { - error(Msg); +void ErrorHandler::warn(const Twine &msg) { + if (fatalWarnings) { + error(msg); return; } - std::lock_guard Lock(Mu); - newline(ErrorOS, Msg); + std::lock_guard lock(mu); + newline(errorOS, msg); print("warning: ", raw_ostream::MAGENTA); - *ErrorOS << Msg << "\n"; + *errorOS << msg << "\n"; } -void ErrorHandler::error(const Twine &Msg) { - std::lock_guard Lock(Mu); - newline(ErrorOS, Msg); +void ErrorHandler::error(const Twine &msg) { + std::lock_guard lock(mu); + newline(errorOS, msg); - if (ErrorLimit == 0 || ErrorCount < ErrorLimit) { + if (errorLimit == 0 || errorCount < errorLimit) { print("error: ", raw_ostream::RED); - *ErrorOS << Msg << "\n"; - } else if (ErrorCount == ErrorLimit) { + *errorOS << msg << "\n"; + } else if (errorCount == errorLimit) { print("error: ", raw_ostream::RED); - *ErrorOS << ErrorLimitExceededMsg << "\n"; - if (ExitEarly) + *errorOS << errorLimitExceededMsg << "\n"; + if (exitEarly) exitLld(1); } - ++ErrorCount; + ++errorCount; } -void ErrorHandler::fatal(const Twine &Msg) { - error(Msg); +void ErrorHandler::fatal(const Twine &msg) { + error(msg); exitLld(1); } diff --git a/lld/Common/Filesystem.cpp b/lld/Common/Filesystem.cpp index 6484286..0b47ac7 100644 --- a/lld/Common/Filesystem.cpp +++ b/lld/Common/Filesystem.cpp @@ -38,43 +38,43 @@ using namespace lld; // // This function spawns a background thread to remove the file. // The calling thread returns almost immediately. -void lld::unlinkAsync(StringRef Path) { +void lld::unlinkAsync(StringRef path) { // Removing a file is async on windows. #if defined(_WIN32) sys::fs::remove(Path); #else - if (!ThreadsEnabled || !sys::fs::exists(Path) || - !sys::fs::is_regular_file(Path)) + if (!threadsEnabled || !sys::fs::exists(path) || + !sys::fs::is_regular_file(path)) return; // We cannot just remove path from a different thread because we are now going // to create path as a new file. // Instead we open the file and unlink it on this thread. The unlink is fast // since the open fd guarantees that it is not removing the last reference. - int FD; - std::error_code EC = sys::fs::openFileForRead(Path, FD); - sys::fs::remove(Path); + int fd; + std::error_code ec = sys::fs::openFileForRead(path, fd); + sys::fs::remove(path); - if (EC) + if (ec) return; // close and therefore remove TempPath in background. - std::mutex M; - std::condition_variable CV; - bool Started = false; - std::thread([&, FD] { + std::mutex m; + std::condition_variable cv; + bool started = false; + std::thread([&, fd] { { - std::lock_guard L(M); - Started = true; - CV.notify_all(); + std::lock_guard l(m); + started = true; + cv.notify_all(); } - ::close(FD); + ::close(fd); }).detach(); // GLIBC 2.26 and earlier have race condition that crashes an entire process // if the main thread calls exit(2) while other thread is starting up. - std::unique_lock L(M); - CV.wait(L, [&] { return Started; }); + std::unique_lock l(m); + cv.wait(l, [&] { return started; }); #endif } @@ -90,10 +90,10 @@ void lld::unlinkAsync(StringRef Path) { // FileOutputBuffer doesn't touch a desitnation file until commit() // is called. We use that class without calling commit() to predict // if the given file is writable. -std::error_code lld::tryCreateFile(StringRef Path) { - if (Path.empty()) +std::error_code lld::tryCreateFile(StringRef path) { + if (path.empty()) return std::error_code(); - if (Path == "-") + if (path == "-") return std::error_code(); - return errorToErrorCode(FileOutputBuffer::create(Path, 1).takeError()); + return errorToErrorCode(FileOutputBuffer::create(path, 1).takeError()); } diff --git a/lld/Common/Memory.cpp b/lld/Common/Memory.cpp index 5a6ead4..c53e1d3 100644 --- a/lld/Common/Memory.cpp +++ b/lld/Common/Memory.cpp @@ -11,12 +11,12 @@ using namespace llvm; using namespace lld; -BumpPtrAllocator lld::BAlloc; -StringSaver lld::Saver{BAlloc}; -std::vector lld::SpecificAllocBase::Instances; +BumpPtrAllocator lld::bAlloc; +StringSaver lld::saver{bAlloc}; +std::vector lld::SpecificAllocBase::instances; void lld::freeArena() { - for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) - Alloc->reset(); - BAlloc.Reset(); + for (SpecificAllocBase *alloc : SpecificAllocBase::instances) + alloc->reset(); + bAlloc.Reset(); } diff --git a/lld/Common/Reproduce.cpp b/lld/Common/Reproduce.cpp index c34a809..24210c4 100644 --- a/lld/Common/Reproduce.cpp +++ b/lld/Common/Reproduce.cpp @@ -21,41 +21,41 @@ using namespace llvm::sys; // assuming that the current directory is "/home/john/bar". // Returned string is a forward slash separated path even on Windows to avoid // a mess with backslash-as-escape and backslash-as-path-separator. -std::string lld::relativeToRoot(StringRef Path) { - SmallString<128> Abs = Path; - if (fs::make_absolute(Abs)) - return Path; - path::remove_dots(Abs, /*remove_dot_dot=*/true); +std::string lld::relativeToRoot(StringRef path) { + SmallString<128> abs = path; + if (fs::make_absolute(abs)) + return path; + path::remove_dots(abs, /*remove_dot_dot=*/true); // This is Windows specific. root_name() returns a drive letter // (e.g. "c:") or a UNC name (//net). We want to keep it as part // of the result. - SmallString<128> Res; - StringRef Root = path::root_name(Abs); - if (Root.endswith(":")) - Res = Root.drop_back(); - else if (Root.startswith("//")) - Res = Root.substr(2); + SmallString<128> res; + StringRef root = path::root_name(abs); + if (root.endswith(":")) + res = root.drop_back(); + else if (root.startswith("//")) + res = root.substr(2); - path::append(Res, path::relative_path(Abs)); - return path::convert_to_slash(Res); + path::append(res, path::relative_path(abs)); + return path::convert_to_slash(res); } // Quote a given string if it contains a space character. -std::string lld::quote(StringRef S) { - if (S.contains(' ')) - return ("\"" + S + "\"").str(); - return S; +std::string lld::quote(StringRef s) { + if (s.contains(' ')) + return ("\"" + s + "\"").str(); + return s; } // Converts an Arg to a string representation suitable for a response file. // To show an Arg in a diagnostic, use Arg::getAsString() instead. -std::string lld::toString(const opt::Arg &Arg) { - std::string K = Arg.getSpelling(); - if (Arg.getNumValues() == 0) - return K; - std::string V = quote(Arg.getValue()); - if (Arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) - return K + V; - return K + " " + V; +std::string lld::toString(const opt::Arg &arg) { + std::string k = arg.getSpelling(); + if (arg.getNumValues() == 0) + return k; + std::string v = quote(arg.getValue()); + if (arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) + return k + v; + return k + " " + v; } diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp index afd5bd39..0bf0662 100644 --- a/lld/Common/Strings.cpp +++ b/lld/Common/Strings.cpp @@ -19,85 +19,85 @@ using namespace llvm; using namespace lld; // Returns the demangled C++ symbol name for Name. -Optional lld::demangleItanium(StringRef Name) { +Optional lld::demangleItanium(StringRef name) { // itaniumDemangle can be used to demangle strings other than symbol // names which do not necessarily start with "_Z". Name can be // either a C or C++ symbol. Don't call itaniumDemangle if the name // does not look like a C++ symbol name to avoid getting unexpected // result for a C symbol that happens to match a mangled type name. - if (!Name.startswith("_Z")) + if (!name.startswith("_Z")) return None; - char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); - if (!Buf) + char *buf = itaniumDemangle(name.str().c_str(), nullptr, nullptr, nullptr); + if (!buf) return None; - std::string S(Buf); - free(Buf); - return S; + std::string s(buf); + free(buf); + return s; } -Optional lld::demangleMSVC(StringRef Name) { - std::string Prefix; - if (Name.consume_front("__imp_")) - Prefix = "__declspec(dllimport) "; +Optional lld::demangleMSVC(StringRef name) { + std::string prefix; + if (name.consume_front("__imp_")) + prefix = "__declspec(dllimport) "; // Demangle only C++ names. - if (!Name.startswith("?")) + if (!name.startswith("?")) return None; - char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); - if (!Buf) + char *buf = microsoftDemangle(name.str().c_str(), nullptr, nullptr, nullptr); + if (!buf) return None; - std::string S(Buf); - free(Buf); - return Prefix + S; + std::string s(buf); + free(buf); + return prefix + s; } -StringMatcher::StringMatcher(ArrayRef Pat) { - for (StringRef S : Pat) { - Expected Pat = GlobPattern::create(S); - if (!Pat) - error(toString(Pat.takeError())); +StringMatcher::StringMatcher(ArrayRef pat) { + for (StringRef s : pat) { + Expected pat = GlobPattern::create(s); + if (!pat) + error(toString(pat.takeError())); else - Patterns.push_back(*Pat); + patterns.push_back(*pat); } } -bool StringMatcher::match(StringRef S) const { - for (const GlobPattern &Pat : Patterns) - if (Pat.match(S)) +bool StringMatcher::match(StringRef s) const { + for (const GlobPattern &pat : patterns) + if (pat.match(s)) return true; return false; } // Converts a hex string (e.g. "deadbeef") to a vector. -std::vector lld::parseHex(StringRef S) { - std::vector Hex; - while (!S.empty()) { - StringRef B = S.substr(0, 2); - S = S.substr(2); - uint8_t H; - if (!to_integer(B, H, 16)) { - error("not a hexadecimal value: " + B); +std::vector lld::parseHex(StringRef s) { + std::vector hex; + while (!s.empty()) { + StringRef b = s.substr(0, 2); + s = s.substr(2); + uint8_t h; + if (!to_integer(b, h, 16)) { + error("not a hexadecimal value: " + b); return {}; } - Hex.push_back(H); + hex.push_back(h); } - return Hex; + return hex; } // Returns true if S is valid as a C language identifier. -bool lld::isValidCIdentifier(StringRef S) { - return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && - std::all_of(S.begin() + 1, S.end(), - [](char C) { return C == '_' || isAlnum(C); }); +bool lld::isValidCIdentifier(StringRef s) { + return !s.empty() && (isAlpha(s[0]) || s[0] == '_') && + std::all_of(s.begin() + 1, s.end(), + [](char c) { return c == '_' || isAlnum(c); }); } // Write the contents of the a buffer to a file -void lld::saveBuffer(StringRef Buffer, const Twine &Path) { - std::error_code EC; - raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); - if (EC) - error("cannot create " + Path + ": " + EC.message()); - OS << Buffer; +void lld::saveBuffer(StringRef buffer, const Twine &path) { + std::error_code ec; + raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::F_None); + if (ec) + error("cannot create " + path + ": " + ec.message()); + os << buffer; } diff --git a/lld/Common/Threads.cpp b/lld/Common/Threads.cpp index 5e0af28..af04972 100644 --- a/lld/Common/Threads.cpp +++ b/lld/Common/Threads.cpp @@ -8,4 +8,4 @@ #include "lld/Common/Threads.h" -bool lld::ThreadsEnabled = true; +bool lld::threadsEnabled = true; diff --git a/lld/Common/Timer.cpp b/lld/Common/Timer.cpp index 3086253..4b7d110 100644 --- a/lld/Common/Timer.cpp +++ b/lld/Common/Timer.cpp @@ -13,43 +13,43 @@ using namespace lld; using namespace llvm; -ScopedTimer::ScopedTimer(Timer &T) : T(&T) { T.start(); } +ScopedTimer::ScopedTimer(Timer &t) : t(&t) { t.start(); } void ScopedTimer::stop() { - if (!T) + if (!t) return; - T->stop(); - T = nullptr; + t->stop(); + t = nullptr; } ScopedTimer::~ScopedTimer() { stop(); } -Timer::Timer(llvm::StringRef Name) : Name(Name), Parent(nullptr) {} -Timer::Timer(llvm::StringRef Name, Timer &Parent) - : Name(Name), Parent(&Parent) {} +Timer::Timer(llvm::StringRef name) : name(name), parent(nullptr) {} +Timer::Timer(llvm::StringRef name, Timer &parent) + : name(name), parent(&parent) {} void Timer::start() { - if (Parent && Total.count() == 0) - Parent->Children.push_back(this); - StartTime = std::chrono::high_resolution_clock::now(); + if (parent && total.count() == 0) + parent->children.push_back(this); + startTime = std::chrono::high_resolution_clock::now(); } void Timer::stop() { - Total += (std::chrono::high_resolution_clock::now() - StartTime); + total += (std::chrono::high_resolution_clock::now() - startTime); } Timer &Timer::root() { - static Timer RootTimer("Total Link Time"); - return RootTimer; + static Timer rootTimer("Total Link Time"); + return rootTimer; } void Timer::print() { - double TotalDuration = static_cast(root().millis()); + double totalDuration = static_cast(root().millis()); // We want to print the grand total under all the intermediate phases, so we // print all children first, then print the total under that. - for (const auto &Child : Children) - Child->print(1, TotalDuration); + for (const auto &child : children) + child->print(1, totalDuration); message(std::string(49, '-')); @@ -58,22 +58,22 @@ void Timer::print() { double Timer::millis() const { return std::chrono::duration_cast>( - Total) + total) .count(); } -void Timer::print(int Depth, double TotalDuration, bool Recurse) const { - double P = 100.0 * millis() / TotalDuration; +void Timer::print(int depth, double totalDuration, bool recurse) const { + double p = 100.0 * millis() / totalDuration; - SmallString<32> Str; - llvm::raw_svector_ostream Stream(Str); - std::string S = std::string(Depth * 2, ' ') + Name + std::string(":"); - Stream << format("%-30s%5d ms (%5.1f%%)", S.c_str(), (int)millis(), P); + SmallString<32> str; + llvm::raw_svector_ostream stream(str); + std::string s = std::string(depth * 2, ' ') + name + std::string(":"); + stream << format("%-30s%5d ms (%5.1f%%)", s.c_str(), (int)millis(), p); - message(Str); + message(str); - if (Recurse) { - for (const auto &Child : Children) - Child->print(Depth + 1, TotalDuration); + if (recurse) { + for (const auto &child : children) + child->print(depth + 1, totalDuration); } } diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp index e72e25c..7473ab6 100644 --- a/lld/ELF/AArch64ErrataFix.cpp +++ b/lld/ELF/AArch64ErrataFix.cpp @@ -398,9 +398,9 @@ lld::elf::Patch843419Section::Patch843419Section(InputSection *p, uint64_t off) patchee(p), patcheeOffset(off) { this->parent = p->getParent(); patchSym = addSyntheticLocal( - Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0, + saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0, getSize(), *this); - addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this); + addSyntheticLocal(saver.save("$x"), STT_NOTYPE, 0, 0, *this); } uint64_t lld::elf::Patch843419Section::getLDSTAddr() const { @@ -485,8 +485,8 @@ void AArch64Err843419Patcher::init() { void AArch64Err843419Patcher::insertPatches( InputSectionDescription &isd, std::vector &patches) { uint64_t isecLimit; - uint64_t prevISLimit = isd.sections.front()->outSecOff; - uint64_t patchUpperBound = prevISLimit + target->getThunkSectionSpacing(); + uint64_t prevIsecLimit = isd.sections.front()->outSecOff; + uint64_t patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing(); uint64_t outSecAddr = isd.sections.front()->getParent()->addr; // Set the OutSecOff of patches to the place where we want to insert them. @@ -498,14 +498,14 @@ void AArch64Err843419Patcher::insertPatches( isecLimit = isec->outSecOff + isec->getSize(); if (isecLimit > patchUpperBound) { while (patchIt != patchEnd) { - if ((*patchIt)->getLDSTAddr() - outSecAddr >= prevISLimit) + if ((*patchIt)->getLDSTAddr() - outSecAddr >= prevIsecLimit) break; - (*patchIt)->outSecOff = prevISLimit; + (*patchIt)->outSecOff = prevIsecLimit; ++patchIt; } - patchUpperBound = prevISLimit + target->getThunkSectionSpacing(); + patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing(); } - prevISLimit = isecLimit; + prevIsecLimit = isecLimit; } for (; patchIt != patchEnd; ++patchIt) { (*patchIt)->outSecOff = isecLimit; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 77ef2ba..f4f52b4 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -76,13 +76,13 @@ static void readConfigs(opt::InputArgList &args); bool elf::link(ArrayRef args, bool canExitEarly, raw_ostream &error) { - errorHandler().LogName = args::getFilenameWithoutExe(args[0]); - errorHandler().ErrorLimitExceededMsg = + 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(); @@ -399,7 +399,7 @@ void LinkerDriver::main(ArrayRef argsArr) { 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); + errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20); checkZOptions(args); // Handle -help @@ -783,10 +783,10 @@ static void parseClangOption(StringRef opt, const Twine &msg) { // Initializes Config members by the command line options. static void readConfigs(opt::InputArgList &args) { - errorHandler().Verbose = args.hasArg(OPT_verbose); - errorHandler().FatalWarnings = + 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); + threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true); config->allowMultipleDefinition = args.hasFlag(OPT_allow_multiple_definition, @@ -939,7 +939,7 @@ static void readConfigs(opt::InputArgList &args) { // Parse LTO options. if (auto *arg = args.getLastArg(OPT_plugin_opt_mcpu_eq)) - parseClangOption(Saver.save("-mcpu=" + StringRef(arg->getValue())), + parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())), arg->getSpelling()); for (auto *arg : args.filtered(OPT_plugin_opt)) @@ -1579,8 +1579,8 @@ static std::vector addWrappedSymbols(opt::InputArgList &args) { if (!sym) continue; - Symbol *real = addUndefined(Saver.save("__real_" + name)); - Symbol *wrap = addUndefined(Saver.save("__wrap_" + name)); + 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 diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp index 4abccc1..87f0aa2 100644 --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -59,15 +59,15 @@ static void handleColorDiagnostics(opt::InputArgList &args) { if (!arg) return; if (arg->getOption().getID() == OPT_color_diagnostics) { - errorHandler().ColorDiagnostics = true; + errorHandler().colorDiagnostics = true; } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { - errorHandler().ColorDiagnostics = false; + errorHandler().colorDiagnostics = false; } else { StringRef s = arg->getValue(); if (s == "always") - errorHandler().ColorDiagnostics = true; + errorHandler().colorDiagnostics = true; else if (s == "never") - errorHandler().ColorDiagnostics = false; + errorHandler().colorDiagnostics = false; else if (s != "auto") error("unknown option: --color-diagnostics=" + s); } @@ -101,7 +101,7 @@ static void concatLTOPluginOptions(SmallVectorImpl &args) { 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()); + v.push_back(saver.save(s + "=" + args[i + 1]).data()); ++i; } else { v.push_back(args[i]); @@ -124,7 +124,7 @@ opt::InputArgList ELFOptTable::parse(ArrayRef argv) { // Expand response files (arguments in the form of @) // and then parse the argument again. - cl::ExpandResponseFiles(Saver, getQuotingStyle(args), vec); + cl::ExpandResponseFiles(saver, getQuotingStyle(args), vec); concatLTOPluginOptions(vec); args = this->ParseArgs(vec, missingIndex, missingCount); diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index fa64b9e..8b01d06 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -392,7 +392,7 @@ template void ICF::forEachClass(llvm::function_ref fn) { // If threading is disabled or the number of sections are // too small to use threading, call Fn sequentially. - if (!ThreadsEnabled || sections.size() < 1024) { + if (!threadsEnabled || sections.size() < 1024) { forEachClassRange(0, sections.size(), fn); ++cnt; return; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 7f0ec2c..919012f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -92,7 +92,7 @@ Optional 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); + path = saver.save(config->chroot + path); log(path); @@ -1366,7 +1366,7 @@ template void SharedFile::parse() { reinterpret_cast(verdefs[idx])->getAux()->vda_name; versionedNameBuffer.clear(); name = (name + "@" + verName).toStringRef(versionedNameBuffer); - symtab->addSymbol(SharedSymbol{*this, Saver.save(name), sym.getBinding(), + symtab->addSymbol(SharedSymbol{*this, saver.save(name), sym.getBinding(), sym.st_other, sym.getType(), sym.st_value, sym.st_size, alignment, idx}); } @@ -1432,8 +1432,8 @@ BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, // 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 " + + ? saver.save(path) + : saver.save(archiveName + "(" + path + " at " + utostr(offsetInArchive) + ")"); MemoryBufferRef mbref(mb.getBuffer(), name); @@ -1460,7 +1460,7 @@ template static Symbol *createBitcodeSymbol(const std::vector &keptComdats, const lto::InputFile::Symbol &objSym, BitcodeFile &f) { - StringRef name = Saver.save(objSym.getName()); + 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()); @@ -1513,11 +1513,11 @@ void BinaryFile::parse() { if (!isAlnum(s[i])) s[i] = '_'; - symtab->addSymbol(Defined{nullptr, Saver.save(s + "_start"), STB_GLOBAL, + 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, + 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, + symtab->addSymbol(Defined{nullptr, saver.save(s + "_size"), STB_GLOBAL, STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr}); } @@ -1566,7 +1566,7 @@ template void LazyObjFile::parse() { 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; } diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index a2cbefb..1ca520c 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -148,7 +148,7 @@ void InputSectionBase::uncompress() const { { static std::mutex mu; std::lock_guard lock(mu); - uncompressedBuf = BAlloc.Allocate(size); + uncompressedBuf = bAlloc.Allocate(size); } if (Error e = zlib::uncompress(toStringRef(rawData), uncompressedBuf, size)) @@ -231,7 +231,7 @@ void InputSectionBase::parseCompressedHeader() { // Restore the original section name. // (e.g. ".zdebug_info" -> ".debug_info") - name = Saver.save("." + name.substr(2)); + name = saver.save("." + name.substr(2)); return; } diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 1058c97..36b847f 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -260,8 +260,8 @@ template void MarkLive::run() { 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); + cNamedSections[saver.save("__start_" + sec->name)].push_back(sec); + cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec); } } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 654ed2f1..cd71961 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1639,18 +1639,18 @@ void ThunkCreator::createInitialThunkSections( lastThunkLowerBound = isdEnd - thunkSectionSpacing; uint32_t isecLimit; - uint32_t prevISLimit = isdBegin; + uint32_t prevIsecLimit = 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; + addThunkSection(os, isd, prevIsecLimit); + thunkUpperBound = prevIsecLimit + thunkSectionSpacing; } if (isecLimit > lastThunkLowerBound) break; - prevISLimit = isecLimit; + prevIsecLimit = isecLimit; } addThunkSection(os, isd, isecLimit); }); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 9076a1c..e227d0b 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -280,7 +280,7 @@ void ScriptParser::addFile(StringRef s) { SmallString<128> pathData; StringRef path = (config->sysroot + s).toStringRef(pathData); if (sys::fs::exists(path)) { - driver->addFile(Saver.save(path), /*WithLOption=*/false); + driver->addFile(saver.save(path), /*WithLOption=*/false); return; } } @@ -291,7 +291,7 @@ void ScriptParser::addFile(StringRef s) { 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)); @@ -299,7 +299,7 @@ void ScriptParser::addFile(StringRef s) { driver->addFile(s, /*WithLOption=*/false); } else { if (Optional path = findFromSearchPaths(s)) - driver->addFile(Saver.save(*path), /*WithLOption=*/true); + driver->addFile(saver.save(*path), /*WithLOption=*/true); else setError("unable to find " + s); } diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 8d1b55c..918849b 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -72,7 +72,7 @@ static ArrayRef getVersion() { // This is only for testing. StringRef s = getenv("LLD_VERSION"); if (s.empty()) - s = Saver.save(Twine("Linker: ") + getLLDVersion()); + s = saver.save(Twine("Linker: ") + getLLDVersion()); // +1 to include the terminating '\0'. return {(const uint8_t *)s.data(), s.size() + 1}; @@ -254,7 +254,7 @@ MipsReginfoSection *MipsReginfoSection::create() { InputSection *elf::createInterpSection() { // StringSaver guarantees that the returned string ends with '\0'. - StringRef s = Saver.save(config->dynamicLinker); + StringRef s = saver.save(config->dynamicLinker); ArrayRef contents = {(const uint8_t *)s.data(), s.size() + 1}; auto *sec = make(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents, @@ -2530,7 +2530,7 @@ createSymbols(ArrayRef> nameAttrs, // speed it up. size_t numShards = 32; size_t concurrency = 1; - if (ThreadsEnabled) + if (threadsEnabled) concurrency = std::min(PowerOf2Floor(hardware_concurrency()), numShards); @@ -2973,7 +2973,7 @@ void MergeNoTailSection::finalizeContents() { // Concurrency level. Must be a power of 2 to avoid expensive modulo // operations in the following tight loop. size_t concurrency = 1; - if (ThreadsEnabled) + if (threadsEnabled) concurrency = std::min(PowerOf2Floor(hardware_concurrency()), numShards); diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 2428fb8..33a3c87 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -350,7 +350,7 @@ void AArch64ABSLongThunk::writeTo(uint8_t *buf) { } void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__AArch64AbsLongThunk_" + destination.getName()), + addSymbol(saver.save("__AArch64AbsLongThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$x", STT_NOTYPE, 0, isec); addSymbol("$d", STT_NOTYPE, 8, isec); @@ -376,7 +376,7 @@ void AArch64ADRPThunk::writeTo(uint8_t *buf) { } void AArch64ADRPThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__AArch64ADRPThunk_" + destination.getName()), STT_FUNC, + addSymbol(saver.save("__AArch64ADRPThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$x", STT_NOTYPE, 0, isec); } @@ -476,7 +476,7 @@ void ARMV7ABSLongThunk::writeLong(uint8_t *buf) { } void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__ARMv7ABSLongThunk_" + destination.getName()), + addSymbol(saver.save("__ARMv7ABSLongThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$a", STT_NOTYPE, 0, isec); } @@ -494,7 +494,7 @@ void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) { } void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + destination.getName()), + addSymbol(saver.save("__Thumbv7ABSLongThunk_" + destination.getName()), STT_FUNC, 1, isec); addSymbol("$t", STT_NOTYPE, 0, isec); } @@ -515,7 +515,7 @@ void ARMV7PILongThunk::writeLong(uint8_t *buf) { } void ARMV7PILongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__ARMV7PILongThunk_" + destination.getName()), STT_FUNC, + addSymbol(saver.save("__ARMV7PILongThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$a", STT_NOTYPE, 0, isec); } @@ -536,7 +536,7 @@ void ThumbV7PILongThunk::writeLong(uint8_t *buf) { } void ThumbV7PILongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__ThumbV7PILongThunk_" + destination.getName()), + addSymbol(saver.save("__ThumbV7PILongThunk_" + destination.getName()), STT_FUNC, 1, isec); addSymbol("$t", STT_NOTYPE, 0, isec); } @@ -551,7 +551,7 @@ void ARMV5ABSLongThunk::writeLong(uint8_t *buf) { } void ARMV5ABSLongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__ARMv5ABSLongThunk_" + destination.getName()), + addSymbol(saver.save("__ARMv5ABSLongThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$a", STT_NOTYPE, 0, isec); addSymbol("$d", STT_NOTYPE, 4, isec); @@ -577,7 +577,7 @@ void ARMV5PILongThunk::writeLong(uint8_t *buf) { } void ARMV5PILongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__ARMV5PILongThunk_" + destination.getName()), STT_FUNC, + addSymbol(saver.save("__ARMV5PILongThunk_" + destination.getName()), STT_FUNC, 0, isec); addSymbol("$a", STT_NOTYPE, 0, isec); addSymbol("$d", STT_NOTYPE, 12, isec); @@ -607,7 +607,7 @@ void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) { } void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + destination.getName()), + addSymbol(saver.save("__Thumbv6MABSLongThunk_" + destination.getName()), STT_FUNC, 1, isec); addSymbol("$t", STT_NOTYPE, 0, isec); addSymbol("$d", STT_NOTYPE, 8, isec); @@ -633,7 +633,7 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *buf) { } void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__Thumbv6MPILongThunk_" + destination.getName()), + addSymbol(saver.save("__Thumbv6MPILongThunk_" + destination.getName()), STT_FUNC, 1, isec); addSymbol("$t", STT_NOTYPE, 0, isec); addSymbol("$d", STT_NOTYPE, 12, isec); @@ -651,7 +651,7 @@ void MipsThunk::writeTo(uint8_t *buf) { } void MipsThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__LA25Thunk_" + destination.getName()), STT_FUNC, 0, + addSymbol(saver.save("__LA25Thunk_" + destination.getName()), STT_FUNC, 0, isec); } @@ -675,7 +675,7 @@ void MicroMipsThunk::writeTo(uint8_t *buf) { void MicroMipsThunk::addSymbols(ThunkSection &isec) { Defined *d = addSymbol( - Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec); + saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec); d->stOther |= STO_MIPS_MICROMIPS; } @@ -699,7 +699,7 @@ void MicroMipsR6Thunk::writeTo(uint8_t *buf) { void MicroMipsR6Thunk::addSymbols(ThunkSection &isec) { Defined *d = addSymbol( - Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec); + saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec); d->stOther |= STO_MIPS_MICROMIPS; } @@ -754,7 +754,7 @@ void PPC32PltCallStub::addSymbols(ThunkSection &isec) { else os << ".plt_pic32."; os << destination.getName(); - addSymbol(Saver.save(os.str()), STT_FUNC, 0, isec); + addSymbol(saver.save(os.str()), STT_FUNC, 0, isec); } bool PPC32PltCallStub::isCompatibleWith(const InputSection &isec, @@ -780,7 +780,7 @@ void PPC64PltCallStub::writeTo(uint8_t *buf) { } void PPC64PltCallStub::addSymbols(ThunkSection &isec) { - Defined *s = addSymbol(Saver.save("__plt_" + destination.getName()), STT_FUNC, + Defined *s = addSymbol(saver.save("__plt_" + destination.getName()), STT_FUNC, 0, isec); s->needsTocRestore = true; } @@ -791,7 +791,7 @@ void PPC64LongBranchThunk::writeTo(uint8_t *buf) { } void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) { - addSymbol(Saver.save("__long_branch_" + destination.getName()), STT_FUNC, 0, + addSymbol(saver.save("__long_branch_" + destination.getName()), STT_FUNC, 0, isec); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b0457b6..bd7ddd5 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 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; @@ -103,8 +103,8 @@ StringRef elf::getOutputSectionName(const InputSectionBase *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); + return saver.save(".rela" + out->name); + return saver.save(".rel" + out->name); } } @@ -2006,8 +2006,8 @@ void Writer::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) { diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index 62d8982..24e18aa 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -65,7 +65,7 @@ enum { #undef PREFIX // Create table mapping all options defined in Options.td -static const opt::OptTable::Info InfoTable[] = { +static const opt::OptTable::Info infoTable[] = { #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}, @@ -76,14 +76,14 @@ static const opt::OptTable::Info InfoTable[] = { namespace { class MinGWOptTable : public opt::OptTable { public: - MinGWOptTable() : OptTable(InfoTable, false) {} - opt::InputArgList parse(ArrayRef Argv); + MinGWOptTable() : OptTable(infoTable, false) {} + opt::InputArgList parse(ArrayRef argv); }; } // namespace -static void printHelp(const char *Argv0) { +static void printHelp(const char *argv0) { MinGWOptTable().PrintHelp( - outs(), (std::string(Argv0) + " [options] file...").c_str(), "lld", + outs(), (std::string(argv0) + " [options] file...").c_str(), "lld", false /*ShowHidden*/, true /*ShowAllAliases*/); outs() << "\n"; } @@ -94,58 +94,58 @@ static cl::TokenizerCallback getQuotingStyle() { return cl::TokenizeGNUCommandLine; } -opt::InputArgList MinGWOptTable::parse(ArrayRef Argv) { - unsigned MissingIndex; - unsigned MissingCount; +opt::InputArgList MinGWOptTable::parse(ArrayRef argv) { + unsigned missingIndex; + unsigned missingCount; - SmallVector Vec(Argv.data(), Argv.data() + Argv.size()); - cl::ExpandResponseFiles(Saver, getQuotingStyle(), Vec); - opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); + SmallVector vec(argv.data(), argv.data() + argv.size()); + cl::ExpandResponseFiles(saver, getQuotingStyle(), vec); + opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount); - if (MissingCount) - fatal(StringRef(Args.getArgString(MissingIndex)) + ": missing argument"); - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) - fatal("unknown argument: " + Arg->getAsString(Args)); - return Args; + if (missingCount) + fatal(StringRef(args.getArgString(missingIndex)) + ": missing argument"); + for (auto *arg : args.filtered(OPT_UNKNOWN)) + fatal("unknown argument: " + arg->getAsString(args)); + return args; } // Find a file by concatenating given paths. -static Optional findFile(StringRef Path1, const Twine &Path2) { - SmallString<128> S; - sys::path::append(S, Path1, Path2); - if (sys::fs::exists(S)) - return S.str().str(); +static Optional findFile(StringRef path1, const Twine &path2) { + SmallString<128> s; + sys::path::append(s, path1, path2); + if (sys::fs::exists(s)) + return s.str().str(); return None; } // This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths. static std::string -searchLibrary(StringRef Name, ArrayRef SearchPaths, bool BStatic) { - if (Name.startswith(":")) { - for (StringRef Dir : SearchPaths) - if (Optional S = findFile(Dir, Name.substr(1))) - return *S; - fatal("unable to find library -l" + Name); +searchLibrary(StringRef name, ArrayRef searchPaths, bool bStatic) { + if (name.startswith(":")) { + for (StringRef dir : searchPaths) + if (Optional s = findFile(dir, name.substr(1))) + return *s; + fatal("unable to find library -l" + name); } - for (StringRef Dir : SearchPaths) { - if (!BStatic) - if (Optional S = findFile(Dir, "lib" + Name + ".dll.a")) - return *S; - if (Optional S = findFile(Dir, "lib" + Name + ".a")) - return *S; + for (StringRef dir : searchPaths) { + if (!bStatic) + if (Optional s = findFile(dir, "lib" + name + ".dll.a")) + return *s; + if (Optional s = findFile(dir, "lib" + name + ".a")) + return *s; } - fatal("unable to find library -l" + Name); + fatal("unable to find library -l" + name); } // Convert Unix-ish command line arguments to Windows-ish ones and // then call coff::link. -bool mingw::link(ArrayRef ArgsArr, raw_ostream &Diag) { - MinGWOptTable Parser; - opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); +bool mingw::link(ArrayRef argsArr, raw_ostream &diag) { + MinGWOptTable parser; + opt::InputArgList args = parser.parse(argsArr.slice(1)); - if (Args.hasArg(OPT_help)) { - printHelp(ArgsArr[0]); + if (args.hasArg(OPT_help)) { + printHelp(argsArr[0]); return true; } @@ -154,199 +154,199 @@ bool mingw::link(ArrayRef ArgsArr, raw_ostream &Diag) { // still the newest version in March 2017) or earlier to recognize LLD as // a GNU compatible linker. As long as an output for the -v option // contains "GNU" or "with BFD", they recognize us as GNU-compatible. - if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version)) + if (args.hasArg(OPT_v) || args.hasArg(OPT_version)) message(getLLDVersion() + " (compatible with GNU linkers)"); // 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) && !Args.hasArg(OPT_l)) + if (args.hasArg(OPT_v) && !args.hasArg(OPT_INPUT) && !args.hasArg(OPT_l)) return true; - if (Args.hasArg(OPT_version)) + if (args.hasArg(OPT_version)) return true; - if (!Args.hasArg(OPT_INPUT) && !Args.hasArg(OPT_l)) + if (!args.hasArg(OPT_INPUT) && !args.hasArg(OPT_l)) fatal("no input files"); - std::vector LinkArgs; - auto Add = [&](const Twine &S) { LinkArgs.push_back(S.str()); }; + std::vector linkArgs; + auto add = [&](const Twine &s) { linkArgs.push_back(s.str()); }; - Add("lld-link"); - Add("-lldmingw"); + add("lld-link"); + add("-lldmingw"); - if (auto *A = Args.getLastArg(OPT_entry)) { - StringRef S = A->getValue(); - if (Args.getLastArgValue(OPT_m) == "i386pe" && S.startswith("_")) - Add("-entry:" + S.substr(1)); + if (auto *a = args.getLastArg(OPT_entry)) { + StringRef s = a->getValue(); + if (args.getLastArgValue(OPT_m) == "i386pe" && s.startswith("_")) + add("-entry:" + s.substr(1)); else - Add("-entry:" + S); + add("-entry:" + s); } - if (Args.hasArg(OPT_major_os_version, OPT_minor_os_version, + if (args.hasArg(OPT_major_os_version, OPT_minor_os_version, OPT_major_subsystem_version, OPT_minor_subsystem_version)) { - auto *MajOSVer = Args.getLastArg(OPT_major_os_version); - auto *MinOSVer = Args.getLastArg(OPT_minor_os_version); - auto *MajSubSysVer = Args.getLastArg(OPT_major_subsystem_version); - auto *MinSubSysVer = Args.getLastArg(OPT_minor_subsystem_version); - if (MajOSVer && MajSubSysVer && - StringRef(MajOSVer->getValue()) != StringRef(MajSubSysVer->getValue())) + auto *majOSVer = args.getLastArg(OPT_major_os_version); + auto *minOSVer = args.getLastArg(OPT_minor_os_version); + auto *majSubSysVer = args.getLastArg(OPT_major_subsystem_version); + auto *minSubSysVer = args.getLastArg(OPT_minor_subsystem_version); + if (majOSVer && majSubSysVer && + StringRef(majOSVer->getValue()) != StringRef(majSubSysVer->getValue())) warn("--major-os-version and --major-subsystem-version set to differing " "versions, not supported"); - if (MinOSVer && MinSubSysVer && - StringRef(MinOSVer->getValue()) != StringRef(MinSubSysVer->getValue())) + if (minOSVer && minSubSysVer && + StringRef(minOSVer->getValue()) != StringRef(minSubSysVer->getValue())) warn("--minor-os-version and --minor-subsystem-version set to differing " "versions, not supported"); - StringRef SubSys = Args.getLastArgValue(OPT_subs, "default"); - StringRef Major = MajOSVer ? MajOSVer->getValue() - : MajSubSysVer ? MajSubSysVer->getValue() : "6"; - StringRef Minor = MinOSVer ? MinOSVer->getValue() - : MinSubSysVer ? MinSubSysVer->getValue() : ""; - StringRef Sep = Minor.empty() ? "" : "."; - Add("-subsystem:" + SubSys + "," + Major + Sep + Minor); - } else if (auto *A = Args.getLastArg(OPT_subs)) { - Add("-subsystem:" + StringRef(A->getValue())); + StringRef subSys = args.getLastArgValue(OPT_subs, "default"); + StringRef major = majOSVer ? majOSVer->getValue() + : majSubSysVer ? majSubSysVer->getValue() : "6"; + StringRef minor = minOSVer ? minOSVer->getValue() + : minSubSysVer ? minSubSysVer->getValue() : ""; + StringRef sep = minor.empty() ? "" : "."; + add("-subsystem:" + subSys + "," + major + sep + minor); + } else if (auto *a = args.getLastArg(OPT_subs)) { + add("-subsystem:" + StringRef(a->getValue())); } - if (auto *A = Args.getLastArg(OPT_out_implib)) - Add("-implib:" + StringRef(A->getValue())); - if (auto *A = Args.getLastArg(OPT_stack)) - Add("-stack:" + StringRef(A->getValue())); - if (auto *A = Args.getLastArg(OPT_output_def)) - Add("-output-def:" + StringRef(A->getValue())); - if (auto *A = Args.getLastArg(OPT_image_base)) - Add("-base:" + StringRef(A->getValue())); - if (auto *A = Args.getLastArg(OPT_map)) - Add("-lldmap:" + StringRef(A->getValue())); - - if (auto *A = Args.getLastArg(OPT_o)) - Add("-out:" + StringRef(A->getValue())); - else if (Args.hasArg(OPT_shared)) - Add("-out:a.dll"); + if (auto *a = args.getLastArg(OPT_out_implib)) + add("-implib:" + StringRef(a->getValue())); + if (auto *a = args.getLastArg(OPT_stack)) + add("-stack:" + StringRef(a->getValue())); + if (auto *a = args.getLastArg(OPT_output_def)) + add("-output-def:" + StringRef(a->getValue())); + if (auto *a = args.getLastArg(OPT_image_base)) + add("-base:" + StringRef(a->getValue())); + if (auto *a = args.getLastArg(OPT_map)) + add("-lldmap:" + StringRef(a->getValue())); + + if (auto *a = args.getLastArg(OPT_o)) + add("-out:" + StringRef(a->getValue())); + else if (args.hasArg(OPT_shared)) + add("-out:a.dll"); else - Add("-out:a.exe"); - - if (auto *A = Args.getLastArg(OPT_pdb)) { - Add("-debug"); - StringRef V = A->getValue(); - if (!V.empty()) - Add("-pdb:" + V); - } else if (Args.hasArg(OPT_strip_debug)) { - Add("-debug:symtab"); - } else if (!Args.hasArg(OPT_strip_all)) { - Add("-debug:dwarf"); + add("-out:a.exe"); + + if (auto *a = args.getLastArg(OPT_pdb)) { + add("-debug"); + StringRef v = a->getValue(); + if (!v.empty()) + add("-pdb:" + v); + } else if (args.hasArg(OPT_strip_debug)) { + add("-debug:symtab"); + } else if (!args.hasArg(OPT_strip_all)) { + add("-debug:dwarf"); } - if (Args.hasArg(OPT_shared)) - Add("-dll"); - if (Args.hasArg(OPT_verbose)) - Add("-verbose"); - if (Args.hasArg(OPT_exclude_all_symbols)) - Add("-exclude-all-symbols"); - if (Args.hasArg(OPT_export_all_symbols)) - Add("-export-all-symbols"); - if (Args.hasArg(OPT_large_address_aware)) - Add("-largeaddressaware"); - if (Args.hasArg(OPT_kill_at)) - Add("-kill-at"); - if (Args.hasArg(OPT_appcontainer)) - Add("-appcontainer"); - - if (Args.getLastArgValue(OPT_m) != "thumb2pe" && - Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) - Add("-dynamicbase:no"); - - if (Args.hasFlag(OPT_no_insert_timestamp, OPT_insert_timestamp, false)) - Add("-timestamp:0"); - - if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false)) - Add("-opt:ref"); + if (args.hasArg(OPT_shared)) + add("-dll"); + if (args.hasArg(OPT_verbose)) + add("-verbose"); + if (args.hasArg(OPT_exclude_all_symbols)) + add("-exclude-all-symbols"); + if (args.hasArg(OPT_export_all_symbols)) + add("-export-all-symbols"); + if (args.hasArg(OPT_large_address_aware)) + add("-largeaddressaware"); + if (args.hasArg(OPT_kill_at)) + add("-kill-at"); + if (args.hasArg(OPT_appcontainer)) + add("-appcontainer"); + + if (args.getLastArgValue(OPT_m) != "thumb2pe" && + args.getLastArgValue(OPT_m) != "arm64pe" && !args.hasArg(OPT_dynamicbase)) + add("-dynamicbase:no"); + + if (args.hasFlag(OPT_no_insert_timestamp, OPT_insert_timestamp, false)) + add("-timestamp:0"); + + if (args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false)) + add("-opt:ref"); else - Add("-opt:noref"); - - if (auto *A = Args.getLastArg(OPT_icf)) { - StringRef S = A->getValue(); - if (S == "all") - Add("-opt:icf"); - else if (S == "safe" || S == "none") - Add("-opt:noicf"); + add("-opt:noref"); + + if (auto *a = args.getLastArg(OPT_icf)) { + StringRef s = a->getValue(); + if (s == "all") + add("-opt:icf"); + else if (s == "safe" || s == "none") + add("-opt:noicf"); else - fatal("unknown parameter: --icf=" + S); + fatal("unknown parameter: --icf=" + s); } else { - Add("-opt:noicf"); + add("-opt:noicf"); } - if (auto *A = Args.getLastArg(OPT_m)) { - StringRef S = A->getValue(); - if (S == "i386pe") - Add("-machine:x86"); - else if (S == "i386pep") - Add("-machine:x64"); - else if (S == "thumb2pe") - Add("-machine:arm"); - else if (S == "arm64pe") - Add("-machine:arm64"); + if (auto *a = args.getLastArg(OPT_m)) { + StringRef s = a->getValue(); + if (s == "i386pe") + add("-machine:x86"); + else if (s == "i386pep") + add("-machine:x64"); + else if (s == "thumb2pe") + add("-machine:arm"); + else if (s == "arm64pe") + add("-machine:arm64"); else - fatal("unknown parameter: -m" + S); + fatal("unknown parameter: -m" + s); } - for (auto *A : Args.filtered(OPT_mllvm)) - Add("-mllvm:" + StringRef(A->getValue())); + for (auto *a : args.filtered(OPT_mllvm)) + add("-mllvm:" + StringRef(a->getValue())); - for (auto *A : Args.filtered(OPT_Xlink)) - Add(A->getValue()); + for (auto *a : args.filtered(OPT_Xlink)) + add(a->getValue()); - if (Args.getLastArgValue(OPT_m) == "i386pe") - Add("-alternatename:__image_base__=___ImageBase"); + if (args.getLastArgValue(OPT_m) == "i386pe") + add("-alternatename:__image_base__=___ImageBase"); else - Add("-alternatename:__image_base__=__ImageBase"); + add("-alternatename:__image_base__=__ImageBase"); - for (auto *A : Args.filtered(OPT_require_defined)) - Add("-include:" + StringRef(A->getValue())); - for (auto *A : Args.filtered(OPT_undefined)) - Add("-includeoptional:" + StringRef(A->getValue())); + for (auto *a : args.filtered(OPT_require_defined)) + add("-include:" + StringRef(a->getValue())); + for (auto *a : args.filtered(OPT_undefined)) + add("-includeoptional:" + StringRef(a->getValue())); - std::vector SearchPaths; - for (auto *A : Args.filtered(OPT_L)) { - SearchPaths.push_back(A->getValue()); - Add("-libpath:" + StringRef(A->getValue())); + std::vector searchPaths; + for (auto *a : args.filtered(OPT_L)) { + searchPaths.push_back(a->getValue()); + add("-libpath:" + StringRef(a->getValue())); } - StringRef Prefix = ""; - bool Static = false; - for (auto *A : Args) { - switch (A->getOption().getID()) { + StringRef prefix = ""; + bool isStatic = false; + for (auto *a : args) { + switch (a->getOption().getID()) { case OPT_INPUT: - if (StringRef(A->getValue()).endswith_lower(".def")) - Add("-def:" + StringRef(A->getValue())); + if (StringRef(a->getValue()).endswith_lower(".def")) + add("-def:" + StringRef(a->getValue())); else - Add(Prefix + StringRef(A->getValue())); + add(prefix + StringRef(a->getValue())); break; case OPT_l: - Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static)); + add(prefix + searchLibrary(a->getValue(), searchPaths, isStatic)); break; case OPT_whole_archive: - Prefix = "-wholearchive:"; + prefix = "-wholearchive:"; break; case OPT_no_whole_archive: - Prefix = ""; + prefix = ""; break; case OPT_Bstatic: - Static = true; + isStatic = true; break; case OPT_Bdynamic: - Static = false; + isStatic = false; break; } } - if (Args.hasArg(OPT_verbose) || Args.hasArg(OPT__HASH_HASH_HASH)) - outs() << llvm::join(LinkArgs, " ") << "\n"; + if (args.hasArg(OPT_verbose) || args.hasArg(OPT__HASH_HASH_HASH)) + outs() << llvm::join(linkArgs, " ") << "\n"; - if (Args.hasArg(OPT__HASH_HASH_HASH)) + if (args.hasArg(OPT__HASH_HASH_HASH)) return true; // Repack vector of strings to vector of const char pointers for coff::link. - std::vector Vec; - for (const std::string &S : LinkArgs) - Vec.push_back(S.c_str()); - return coff::link(Vec, true); + std::vector vec; + for (const std::string &s : linkArgs) + vec.push_back(s.c_str()); + return coff::link(vec, true); } diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h index cf8002d..b3c8686 100644 --- a/lld/include/lld/Common/Args.h +++ b/lld/include/lld/Common/Args.h @@ -23,19 +23,19 @@ class InputArgList; namespace lld { namespace args { -llvm::CodeGenOpt::Level getCGOptLevel(int OptLevelLTO); +llvm::CodeGenOpt::Level getCGOptLevel(int optLevelLTO); -int64_t getInteger(llvm::opt::InputArgList &Args, unsigned Key, +int64_t getInteger(llvm::opt::InputArgList &args, unsigned key, int64_t Default); -std::vector getStrings(llvm::opt::InputArgList &Args, int Id); +std::vector getStrings(llvm::opt::InputArgList &args, int id); -uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key, +uint64_t getZOptionValue(llvm::opt::InputArgList &args, int id, StringRef key, uint64_t Default); -std::vector getLines(MemoryBufferRef MB); +std::vector getLines(MemoryBufferRef mb); -StringRef getFilenameWithoutExe(StringRef Path); +StringRef getFilenameWithoutExe(StringRef path); } // namespace args } // namespace lld diff --git a/lld/include/lld/Common/Driver.h b/lld/include/lld/Common/Driver.h index 745ef72..e559595 100644 --- a/lld/include/lld/Common/Driver.h +++ b/lld/include/lld/Common/Driver.h @@ -14,28 +14,28 @@ namespace lld { namespace coff { -bool link(llvm::ArrayRef Args, bool CanExitEarly, - llvm::raw_ostream &Diag = llvm::errs()); +bool link(llvm::ArrayRef args, bool canExitEarly, + llvm::raw_ostream &diag = llvm::errs()); } namespace mingw { -bool link(llvm::ArrayRef Args, - llvm::raw_ostream &Diag = llvm::errs()); +bool link(llvm::ArrayRef args, + llvm::raw_ostream &diag = llvm::errs()); } namespace elf { -bool link(llvm::ArrayRef Args, bool CanExitEarly, - llvm::raw_ostream &Diag = llvm::errs()); +bool link(llvm::ArrayRef args, bool canExitEarly, + llvm::raw_ostream &diag = llvm::errs()); } namespace mach_o { -bool link(llvm::ArrayRef Args, bool CanExitEarly, - llvm::raw_ostream &Diag = llvm::errs()); +bool link(llvm::ArrayRef args, bool canExitEarly, + llvm::raw_ostream &diag = llvm::errs()); } namespace wasm { -bool link(llvm::ArrayRef Args, bool CanExitEarly, - llvm::raw_ostream &Diag = llvm::errs()); +bool link(llvm::ArrayRef args, bool canExitEarly, + llvm::raw_ostream &diag = llvm::errs()); } } diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h index bd9c257..3467fdc 100644 --- a/lld/include/lld/Common/ErrorHandler.h +++ b/lld/include/lld/Common/ErrorHandler.h @@ -82,74 +82,74 @@ namespace lld { class ErrorHandler { public: - uint64_t ErrorCount = 0; - uint64_t ErrorLimit = 20; - StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now"; - StringRef LogName = "lld"; - llvm::raw_ostream *ErrorOS = &llvm::errs(); - bool ColorDiagnostics = llvm::errs().has_colors(); - bool ExitEarly = true; - bool FatalWarnings = false; - bool Verbose = false; - - void error(const Twine &Msg); - LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); - void log(const Twine &Msg); - void message(const Twine &Msg); - void warn(const Twine &Msg); - - std::unique_ptr OutputBuffer; + uint64_t errorCount = 0; + uint64_t errorLimit = 20; + StringRef errorLimitExceededMsg = "too many errors emitted, stopping now"; + StringRef logName = "lld"; + llvm::raw_ostream *errorOS = &llvm::errs(); + bool colorDiagnostics = llvm::errs().has_colors(); + bool exitEarly = true; + bool fatalWarnings = false; + bool verbose = false; + + void error(const Twine &msg); + LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg); + void log(const Twine &msg); + void message(const Twine &msg); + void warn(const Twine &msg); + + std::unique_ptr outputBuffer; private: - void print(StringRef S, raw_ostream::Colors C); + void print(StringRef s, raw_ostream::Colors c); }; /// Returns the default error handler. ErrorHandler &errorHandler(); -inline void error(const Twine &Msg) { errorHandler().error(Msg); } -inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) { - errorHandler().fatal(Msg); +inline void error(const Twine &msg) { errorHandler().error(msg); } +inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg) { + errorHandler().fatal(msg); } -inline void log(const Twine &Msg) { errorHandler().log(Msg); } -inline void message(const Twine &Msg) { errorHandler().message(Msg); } -inline void warn(const Twine &Msg) { errorHandler().warn(Msg); } -inline uint64_t errorCount() { return errorHandler().ErrorCount; } +inline void log(const Twine &msg) { errorHandler().log(msg); } +inline void message(const Twine &msg) { errorHandler().message(msg); } +inline void warn(const Twine &msg) { errorHandler().warn(msg); } +inline uint64_t errorCount() { return errorHandler().errorCount; } -LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); +LLVM_ATTRIBUTE_NORETURN void exitLld(int val); -void diagnosticHandler(const llvm::DiagnosticInfo &DI); -void checkError(Error E); +void diagnosticHandler(const llvm::DiagnosticInfo &di); +void checkError(Error e); // check functions are convenient functions to strip errors // from error-or-value objects. -template T check(ErrorOr E) { - if (auto EC = E.getError()) - fatal(EC.message()); - return std::move(*E); +template T check(ErrorOr e) { + if (auto ec = e.getError()) + fatal(ec.message()); + return std::move(*e); } -template T check(Expected E) { - if (!E) - fatal(llvm::toString(E.takeError())); - return std::move(*E); +template T check(Expected e) { + if (!e) + fatal(llvm::toString(e.takeError())); + return std::move(*e); } template -T check2(ErrorOr E, llvm::function_ref Prefix) { - if (auto EC = E.getError()) - fatal(Prefix() + ": " + EC.message()); - return std::move(*E); +T check2(ErrorOr e, llvm::function_ref prefix) { + if (auto ec = e.getError()) + fatal(prefix() + ": " + ec.message()); + return std::move(*e); } template -T check2(Expected E, llvm::function_ref Prefix) { - if (!E) - fatal(Prefix() + ": " + toString(E.takeError())); - return std::move(*E); +T check2(Expected e, llvm::function_ref prefix) { + if (!e) + fatal(prefix() + ": " + toString(e.takeError())); + return std::move(*e); } -inline std::string toString(const Twine &S) { return S.str(); } +inline std::string toString(const Twine &s) { return s.str(); } // To evaluate the second argument lazily, we use C macro. #define CHECK(E, S) check2((E), [&] { return toString(S); }) diff --git a/lld/include/lld/Common/Filesystem.h b/lld/include/lld/Common/Filesystem.h index 4411870..63a0f55 100644 --- a/lld/include/lld/Common/Filesystem.h +++ b/lld/include/lld/Common/Filesystem.h @@ -13,8 +13,8 @@ #include namespace lld { -void unlinkAsync(StringRef Path); -std::error_code tryCreateFile(StringRef Path); +void unlinkAsync(StringRef path); +std::error_code tryCreateFile(StringRef path); } // namespace lld #endif diff --git a/lld/include/lld/Common/Memory.h b/lld/include/lld/Common/Memory.h index 78f6e24..41d8f15 100644 --- a/lld/include/lld/Common/Memory.h +++ b/lld/include/lld/Common/Memory.h @@ -28,30 +28,30 @@ namespace lld { // Use this arena if your object doesn't have a destructor. -extern llvm::BumpPtrAllocator BAlloc; -extern llvm::StringSaver Saver; +extern llvm::BumpPtrAllocator bAlloc; +extern llvm::StringSaver saver; void freeArena(); // These two classes are hack to keep track of all // SpecificBumpPtrAllocator instances. struct SpecificAllocBase { - SpecificAllocBase() { Instances.push_back(this); } + SpecificAllocBase() { instances.push_back(this); } virtual ~SpecificAllocBase() = default; virtual void reset() = 0; - static std::vector Instances; + static std::vector instances; }; template struct SpecificAlloc : public SpecificAllocBase { - void reset() override { Alloc.DestroyAll(); } - llvm::SpecificBumpPtrAllocator Alloc; + void reset() override { alloc.DestroyAll(); } + llvm::SpecificBumpPtrAllocator alloc; }; // Use this arena if your object has a destructor. // Your destructor will be invoked from freeArena(). -template T *make(U &&... Args) { - static SpecificAlloc Alloc; - return new (Alloc.Alloc.Allocate()) T(std::forward(Args)...); +template T *make(U &&... args) { + static SpecificAlloc alloc; + return new (alloc.alloc.Allocate()) T(std::forward(args)...); } } // namespace lld diff --git a/lld/include/lld/Common/Reproduce.h b/lld/include/lld/Common/Reproduce.h index 3ebd11d..734d9e4 100644 --- a/lld/include/lld/Common/Reproduce.h +++ b/lld/include/lld/Common/Reproduce.h @@ -22,13 +22,13 @@ namespace lld { // Makes a given pathname an absolute path first, and then remove // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", // assuming that the current directory is "/home/john/bar". -std::string relativeToRoot(StringRef Path); +std::string relativeToRoot(StringRef path); // Quote a given string if it contains a space character. -std::string quote(StringRef S); +std::string quote(StringRef s); // Returns the string form of the given argument. -std::string toString(const llvm::opt::Arg &Arg); +std::string toString(const llvm::opt::Arg &arg); } #endif diff --git a/lld/include/lld/Common/Strings.h b/lld/include/lld/Common/Strings.h index efc9245..ded22dd 100644 --- a/lld/include/lld/Common/Strings.h +++ b/lld/include/lld/Common/Strings.h @@ -19,25 +19,25 @@ namespace lld { // Returns a demangled C++ symbol name. If Name is not a mangled // name, it returns Optional::None. -llvm::Optional demangleItanium(llvm::StringRef Name); -llvm::Optional demangleMSVC(llvm::StringRef S); +llvm::Optional demangleItanium(llvm::StringRef name); +llvm::Optional demangleMSVC(llvm::StringRef s); -std::vector parseHex(llvm::StringRef S); -bool isValidCIdentifier(llvm::StringRef S); +std::vector parseHex(llvm::StringRef s); +bool isValidCIdentifier(llvm::StringRef s); // Write the contents of the a buffer to a file -void saveBuffer(llvm::StringRef Buffer, const llvm::Twine &Path); +void saveBuffer(llvm::StringRef buffer, const llvm::Twine &path); // This class represents multiple glob patterns. class StringMatcher { public: StringMatcher() = default; - explicit StringMatcher(llvm::ArrayRef Pat); + explicit StringMatcher(llvm::ArrayRef pat); - bool match(llvm::StringRef S) const; + bool match(llvm::StringRef s) const; private: - std::vector Patterns; + std::vector patterns; }; } // namespace lld diff --git a/lld/include/lld/Common/Threads.h b/lld/include/lld/Common/Threads.h index fba0e93..7834130 100644 --- a/lld/include/lld/Common/Threads.h +++ b/lld/include/lld/Common/Threads.h @@ -63,28 +63,28 @@ namespace lld { -extern bool ThreadsEnabled; +extern bool threadsEnabled; -template void parallelForEach(R &&Range, FuncTy Fn) { - if (ThreadsEnabled) - for_each(llvm::parallel::par, std::begin(Range), std::end(Range), Fn); +template void parallelForEach(R &&range, FuncTy fn) { + if (threadsEnabled) + for_each(llvm::parallel::par, std::begin(range), std::end(range), fn); else - for_each(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn); + for_each(llvm::parallel::seq, std::begin(range), std::end(range), fn); } -inline void parallelForEachN(size_t Begin, size_t End, - llvm::function_ref Fn) { - if (ThreadsEnabled) - for_each_n(llvm::parallel::par, Begin, End, Fn); +inline void parallelForEachN(size_t begin, size_t end, + llvm::function_ref fn) { + if (threadsEnabled) + for_each_n(llvm::parallel::par, begin, end, fn); else - for_each_n(llvm::parallel::seq, Begin, End, Fn); + for_each_n(llvm::parallel::seq, begin, end, fn); } -template void parallelSort(R &&Range, FuncTy Fn) { - if (ThreadsEnabled) - sort(llvm::parallel::par, std::begin(Range), std::end(Range), Fn); +template void parallelSort(R &&range, FuncTy fn) { + if (threadsEnabled) + sort(llvm::parallel::par, std::begin(range), std::end(range), fn); else - sort(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn); + sort(llvm::parallel::seq, std::begin(range), std::end(range), fn); } } // namespace lld diff --git a/lld/include/lld/Common/Timer.h b/lld/include/lld/Common/Timer.h index e2b6951..4a298b0 100644 --- a/lld/include/lld/Common/Timer.h +++ b/lld/include/lld/Common/Timer.h @@ -21,18 +21,18 @@ namespace lld { class Timer; struct ScopedTimer { - explicit ScopedTimer(Timer &T); + explicit ScopedTimer(Timer &t); ~ScopedTimer(); void stop(); - Timer *T = nullptr; + Timer *t = nullptr; }; class Timer { public: - Timer(llvm::StringRef Name, Timer &Parent); + Timer(llvm::StringRef name, Timer &parent); static Timer &root(); @@ -43,14 +43,14 @@ public: double millis() const; private: - explicit Timer(llvm::StringRef Name); - void print(int Depth, double TotalDuration, bool Recurse = true) const; - - std::chrono::time_point StartTime; - std::chrono::nanoseconds Total; - std::vector Children; - std::string Name; - Timer *Parent; + explicit Timer(llvm::StringRef name); + void print(int depth, double totalDuration, bool recurse = true) const; + + std::chrono::time_point startTime; + std::chrono::nanoseconds total; + std::vector children; + std::string name; + Timer *parent; }; } // namespace lld diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index f0cb513..8646d86 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -333,8 +333,8 @@ bool parse(llvm::ArrayRef args, MachOLinkingContext &ctx) { Twine(unknownArg->getAsString(parsedArgs))); } - errorHandler().Verbose = parsedArgs.hasArg(OPT_v); - errorHandler().ErrorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20); + errorHandler().verbose = parsedArgs.hasArg(OPT_v); + errorHandler().errorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20); // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static ) llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE; @@ -637,7 +637,7 @@ bool parse(llvm::ArrayRef args, MachOLinkingContext &ctx) { // Now that we've constructed the final set of search paths, print out those // search paths in verbose mode. - if (errorHandler().Verbose) { + if (errorHandler().verbose) { message("Library search paths:"); for (auto path : ctx.searchDirs()) { message(" " + path); @@ -1145,13 +1145,13 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) { /// This is where the link is actually performed. bool link(llvm::ArrayRef args, bool CanExitEarly, raw_ostream &Error) { - errorHandler().LogName = args::getFilenameWithoutExe(args[0]); - errorHandler().ErrorLimitExceededMsg = + 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(); MachOLinkingContext ctx; if (!parse(args, ctx)) @@ -1196,9 +1196,9 @@ bool link(llvm::ArrayRef args, bool CanExitEarly, if (auto ec = pm.runOnFile(*merged)) { // FIXME: This should be passed to logAllUnhandledErrors but it needs // to be passed a Twine instead of a string. - *errorHandler().ErrorOS << "Failed to run passes on file '" + *errorHandler().errorOS << "Failed to run passes on file '" << ctx.outputPath() << "': "; - logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS, + logAllUnhandledErrors(std::move(ec), *errorHandler().errorOS, std::string()); return false; } @@ -1210,9 +1210,9 @@ bool link(llvm::ArrayRef args, bool CanExitEarly, if (auto ec = ctx.writeFile(*merged)) { // FIXME: This should be passed to logAllUnhandledErrors but it needs // to be passed a Twine instead of a string. - *errorHandler().ErrorOS << "Failed to write file '" << ctx.outputPath() + *errorHandler().errorOS << "Failed to write file '" << ctx.outputPath() << "': "; - logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS, + logAllUnhandledErrors(std::move(ec), *errorHandler().errorOS, std::string()); return false; } diff --git a/lld/tools/lld/lld.cpp b/lld/tools/lld/lld.cpp index cd0eaf7..278447c 100644 --- a/lld/tools/lld/lld.cpp +++ b/lld/tools/lld/lld.cpp @@ -49,13 +49,13 @@ enum Flavor { Wasm, // -flavor wasm }; -LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) { - errs() << S << "\n"; +LLVM_ATTRIBUTE_NORETURN static void die(const Twine &s) { + errs() << s << "\n"; exit(1); } -static Flavor getFlavor(StringRef S) { - return StringSwitch(S) +static Flavor getFlavor(StringRef s) { + return StringSwitch(s) .CasesLower("ld", "ld.lld", "gnu", Gnu) .CasesLower("wasm", "ld-wasm", Wasm) .CaseLower("link", WinLink) @@ -69,29 +69,29 @@ static cl::TokenizerCallback getDefaultQuotingStyle() { return cl::TokenizeGNUCommandLine; } -static bool isPETargetName(StringRef S) { - return S == "i386pe" || S == "i386pep" || S == "thumb2pe" || S == "arm64pe"; +static bool isPETargetName(StringRef s) { + return s == "i386pe" || s == "i386pep" || s == "thumb2pe" || s == "arm64pe"; } -static bool isPETarget(std::vector &V) { - for (auto It = V.begin(); It + 1 != V.end(); ++It) { - if (StringRef(*It) != "-m") +static bool isPETarget(std::vector &v) { + for (auto it = v.begin(); it + 1 != v.end(); ++it) { + if (StringRef(*it) != "-m") continue; - return isPETargetName(*(It + 1)); + return isPETargetName(*(it + 1)); } // Expand response files (arguments in the form of @) // to allow detecting the -m argument from arguments in them. - SmallVector ExpandedArgs(V.data(), V.data() + V.size()); - cl::ExpandResponseFiles(Saver, getDefaultQuotingStyle(), ExpandedArgs); - for (auto It = ExpandedArgs.begin(); It + 1 != ExpandedArgs.end(); ++It) { - if (StringRef(*It) != "-m") + SmallVector expandedArgs(v.data(), v.data() + v.size()); + cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), expandedArgs); + for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) { + if (StringRef(*it) != "-m") continue; - return isPETargetName(*(It + 1)); + return isPETargetName(*(it + 1)); } return false; } -static Flavor parseProgname(StringRef Progname) { +static Flavor parseProgname(StringRef progname) { #if __APPLE__ // Use Darwin driver for "ld" on Darwin. if (Progname == "ld") @@ -100,36 +100,36 @@ static Flavor parseProgname(StringRef Progname) { #if LLVM_ON_UNIX // Use GNU driver for "ld" on other Unix-like system. - if (Progname == "ld") + if (progname == "ld") return Gnu; #endif // Progname may be something like "lld-gnu". Parse it. - SmallVector V; - Progname.split(V, "-"); - for (StringRef S : V) - if (Flavor F = getFlavor(S)) - return F; + SmallVector v; + progname.split(v, "-"); + for (StringRef s : v) + if (Flavor f = getFlavor(s)) + return f; return Invalid; } -static Flavor parseFlavor(std::vector &V) { +static Flavor parseFlavor(std::vector &v) { // Parse -flavor option. - if (V.size() > 1 && V[1] == StringRef("-flavor")) { - if (V.size() <= 2) + if (v.size() > 1 && v[1] == StringRef("-flavor")) { + if (v.size() <= 2) die("missing arg value for '-flavor'"); - Flavor F = getFlavor(V[2]); - if (F == Invalid) - die("Unknown flavor: " + StringRef(V[2])); - V.erase(V.begin() + 1, V.begin() + 3); - return F; + Flavor f = getFlavor(v[2]); + if (f == Invalid) + die("Unknown flavor: " + StringRef(v[2])); + v.erase(v.begin() + 1, v.begin() + 3); + return f; } // Deduct the flavor from argv[0]. - StringRef Arg0 = path::filename(V[0]); - if (Arg0.endswith_lower(".exe")) - Arg0 = Arg0.drop_back(4); - return parseProgname(Arg0); + StringRef arg0 = path::filename(v[0]); + if (arg0.endswith_lower(".exe")) + arg0 = arg0.drop_back(4); + return parseProgname(arg0); } // If this function returns true, lld calls _exit() so that it quickly @@ -142,21 +142,21 @@ static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; } /// Universal linker main(). This linker emulates the gnu, darwin, or /// windows linker based on the argv[0] or -flavor option. -int main(int Argc, const char **Argv) { - InitLLVM X(Argc, Argv); +int main(int argc, const char **argv) { + InitLLVM x(argc, argv); - std::vector Args(Argv, Argv + Argc); - switch (parseFlavor(Args)) { + std::vector args(argv, argv + argc); + switch (parseFlavor(args)) { case Gnu: - if (isPETarget(Args)) - return !mingw::link(Args); - return !elf::link(Args, canExitEarly()); + if (isPETarget(args)) + return !mingw::link(args); + return !elf::link(args, canExitEarly()); case WinLink: - return !coff::link(Args, canExitEarly()); + return !coff::link(args, canExitEarly()); case Darwin: - return !mach_o::link(Args, canExitEarly()); + return !mach_o::link(args, canExitEarly()); case Wasm: - return !wasm::link(Args, canExitEarly()); + return !wasm::link(args, canExitEarly()); default: die("lld is a generic driver.\n" "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index b6304485..e502b2f 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -22,58 +22,58 @@ namespace wasm { // and such fields have the same name as the corresponding options. // Most fields are initialized by the driver. struct Configuration { - bool AllowUndefined; - bool CheckFeatures; - bool CompressRelocations; - bool Demangle; - bool DisableVerify; - bool EmitRelocs; - bool ExportAll; - bool ExportDynamic; - bool ExportTable; - bool GcSections; - bool ImportMemory; - bool SharedMemory; - bool PassiveSegments; - bool ImportTable; - bool MergeDataSegments; - bool Pie; - bool PrintGcSections; - bool Relocatable; - bool SaveTemps; - bool Shared; - bool StripAll; - bool StripDebug; - bool StackFirst; - bool Trace; - uint32_t GlobalBase; - uint32_t InitialMemory; - uint32_t MaxMemory; - uint32_t ZStackSize; - unsigned LTOPartitions; - unsigned LTOO; - unsigned Optimize; - unsigned ThinLTOJobs; + bool allowUndefined; + bool checkFeatures; + bool compressRelocations; + bool demangle; + bool disableVerify; + bool emitRelocs; + bool exportAll; + bool exportDynamic; + bool exportTable; + bool gcSections; + bool importMemory; + bool sharedMemory; + bool passiveSegments; + bool importTable; + bool mergeDataSegments; + bool pie; + bool printGcSections; + bool relocatable; + bool saveTemps; + bool shared; + bool stripAll; + bool stripDebug; + bool stackFirst; + bool trace; + uint32_t globalBase; + uint32_t initialMemory; + uint32_t maxMemory; + uint32_t zStackSize; + unsigned ltoPartitions; + unsigned ltoo; + unsigned optimize; + unsigned thinLTOJobs; - llvm::StringRef Entry; - llvm::StringRef OutputFile; - llvm::StringRef ThinLTOCacheDir; + llvm::StringRef entry; + llvm::StringRef outputFile; + llvm::StringRef thinLTOCacheDir; - llvm::StringSet<> AllowUndefinedSymbols; - llvm::StringSet<> ExportedSymbols; - std::vector SearchPaths; - llvm::CachePruningPolicy ThinLTOCachePolicy; - llvm::Optional> Features; + llvm::StringSet<> allowUndefinedSymbols; + llvm::StringSet<> exportedSymbols; + std::vector searchPaths; + llvm::CachePruningPolicy thinLTOCachePolicy; + llvm::Optional> features; // The following config options do not directly correspond to any // particualr command line options. // True if we are creating position-independent code. - bool Pic; + bool isPic; }; // The only instance of Configuration struct. -extern Configuration *Config; +extern Configuration *config; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index a3852d4..d190dba 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -40,7 +40,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -Configuration *lld::wasm::Config; +Configuration *lld::wasm::config; namespace { @@ -65,39 +65,39 @@ static void initLLVM() { class LinkerDriver { public: - void link(ArrayRef ArgsArr); + void link(ArrayRef argsArr); private: - void createFiles(opt::InputArgList &Args); - void addFile(StringRef Path); - void addLibrary(StringRef Name); + void createFiles(opt::InputArgList &args); + void addFile(StringRef path); + void addLibrary(StringRef name); // True if we are in --whole-archive and --no-whole-archive. - bool InWholeArchive = false; + bool inWholeArchive = false; - std::vector Files; + std::vector files; }; } // anonymous namespace -bool lld::wasm::link(ArrayRef Args, bool CanExitEarly, - raw_ostream &Error) { - errorHandler().LogName = args::getFilenameWithoutExe(Args[0]); - errorHandler().ErrorOS = &Error; - errorHandler().ColorDiagnostics = Error.has_colors(); - errorHandler().ErrorLimitExceededMsg = +bool lld::wasm::link(ArrayRef args, bool canExitEarly, + raw_ostream &error) { + errorHandler().logName = args::getFilenameWithoutExe(args[0]); + errorHandler().errorOS = &error; + errorHandler().colorDiagnostics = error.has_colors(); + errorHandler().errorLimitExceededMsg = "too many errors emitted, stopping now (use " "-error-limit=0 to see all errors)"; - Config = make(); - Symtab = make(); + config = make(); + symtab = make(); initLLVM(); - LinkerDriver().link(Args); + LinkerDriver().link(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(); @@ -110,7 +110,7 @@ bool lld::wasm::link(ArrayRef Args, bool CanExitEarly, #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}, @@ -121,57 +121,57 @@ static const opt::OptTable::Info OptInfo[] = { namespace { class WasmOptTable : public llvm::opt::OptTable { public: - WasmOptTable() : OptTable(OptInfo) {} - opt::InputArgList parse(ArrayRef Argv); + WasmOptTable() : OptTable(optInfo) {} + opt::InputArgList parse(ArrayRef argv); }; } // namespace // 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) { - errorHandler().ColorDiagnostics = true; - } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { - errorHandler().ColorDiagnostics = false; + if (arg->getOption().getID() == OPT_color_diagnostics) { + errorHandler().colorDiagnostics = true; + } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { + errorHandler().colorDiagnostics = false; } else { - StringRef S = Arg->getValue(); - if (S == "always") - errorHandler().ColorDiagnostics = true; - else if (S == "never") - errorHandler().ColorDiagnostics = false; - else if (S != "auto") - error("unknown option: --color-diagnostics=" + S); + StringRef s = arg->getValue(); + if (s == "always") + errorHandler().colorDiagnostics = true; + else if (s == "never") + errorHandler().colorDiagnostics = false; + else if (s != "auto") + error("unknown option: --color-diagnostics=" + s); } } // Find a file by concatenating given paths. -static Optional findFile(StringRef Path1, const Twine &Path2) { - SmallString<128> S; - path::append(S, Path1, Path2); - if (fs::exists(S)) - return S.str().str(); +static Optional findFile(StringRef path1, const Twine &path2) { + SmallString<128> s; + path::append(s, path1, path2); + if (fs::exists(s)) + return s.str().str(); return None; } -opt::InputArgList WasmOptTable::parse(ArrayRef Argv) { - SmallVector Vec(Argv.data(), Argv.data() + Argv.size()); +opt::InputArgList WasmOptTable::parse(ArrayRef argv) { + SmallVector vec(argv.data(), argv.data() + argv.size()); - unsigned MissingIndex; - unsigned MissingCount; + unsigned missingIndex; + unsigned missingCount; // Expand response files (arguments in the form of @) - cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec); + cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, vec); - opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); + opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount); - handleColorDiagnostics(Args); - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) - error("unknown argument: " + Arg->getAsString(Args)); - return Args; + handleColorDiagnostics(args); + for (auto *arg : args.filtered(OPT_UNKNOWN)) + error("unknown argument: " + arg->getAsString(args)); + return args; } // Currently we allow a ".imports" to live alongside a library. This can @@ -181,189 +181,189 @@ opt::InputArgList WasmOptTable::parse(ArrayRef Argv) { // In the long run this information would be better stored as a symbol // attribute/flag in the object file itself. // See: https://github.com/WebAssembly/tool-conventions/issues/35 -static void readImportFile(StringRef Filename) { - if (Optional Buf = readFile(Filename)) - for (StringRef Sym : args::getLines(*Buf)) - Config->AllowUndefinedSymbols.insert(Sym); +static void readImportFile(StringRef filename) { + if (Optional buf = readFile(filename)) + for (StringRef sym : args::getLines(*buf)) + config->allowUndefinedSymbols.insert(sym); } // Returns slices of MB by parsing MB as an archive file. // Each slice consists of a member file in the archive. -std::vector static getArchiveMembers(MemoryBufferRef MB) { - std::unique_ptr File = - CHECK(Archive::create(MB), - MB.getBufferIdentifier() + ": failed to parse archive"); - - std::vector V; - Error Err = Error::success(); - for (const ErrorOr &COrErr : File->children(Err)) { - Archive::Child C = - CHECK(COrErr, MB.getBufferIdentifier() + +std::vector static getArchiveMembers(MemoryBufferRef mb) { + std::unique_ptr file = + CHECK(Archive::create(mb), + mb.getBufferIdentifier() + ": failed to parse archive"); + + std::vector v; + Error err = Error::success(); + for (const ErrorOr &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"); - V.push_back(MBRef); + v.push_back(mbref); } - 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 &MB : File->takeThinBuffers()) - make>(std::move(MB)); + for (std::unique_ptr &mb : file->takeThinBuffers()) + make>(std::move(mb)); - return V; + return v; } -void LinkerDriver::addFile(StringRef Path) { - Optional Buffer = readFile(Path); - if (!Buffer.hasValue()) +void LinkerDriver::addFile(StringRef path) { + Optional buffer = readFile(path); + if (!buffer.hasValue()) return; - MemoryBufferRef MBRef = *Buffer; + MemoryBufferRef mbref = *buffer; - switch (identify_magic(MBRef.getBuffer())) { + switch (identify_magic(mbref.getBuffer())) { case file_magic::archive: { - SmallString<128> ImportFile = Path; - path::replace_extension(ImportFile, ".imports"); - if (fs::exists(ImportFile)) - readImportFile(ImportFile.str()); + SmallString<128> importFile = path; + path::replace_extension(importFile, ".imports"); + if (fs::exists(importFile)) + readImportFile(importFile.str()); // Handle -whole-archive. - if (InWholeArchive) { - for (MemoryBufferRef &M : getArchiveMembers(MBRef)) - Files.push_back(createObjectFile(M, Path)); + if (inWholeArchive) { + for (MemoryBufferRef &m : getArchiveMembers(mbref)) + files.push_back(createObjectFile(m, path)); return; } - std::unique_ptr File = - CHECK(Archive::create(MBRef), Path + ": failed to parse archive"); + std::unique_ptr file = + CHECK(Archive::create(mbref), path + ": failed to parse archive"); - if (!File->isEmpty() && !File->hasSymbolTable()) { - error(MBRef.getBufferIdentifier() + + if (!file->isEmpty() && !file->hasSymbolTable()) { + error(mbref.getBufferIdentifier() + ": archive has no index; run ranlib to add one"); } - Files.push_back(make(MBRef)); + files.push_back(make(mbref)); return; } case file_magic::bitcode: case file_magic::wasm_object: - Files.push_back(createObjectFile(MBRef)); + files.push_back(createObjectFile(mbref)); break; default: - error("unknown file type: " + MBRef.getBufferIdentifier()); + error("unknown file type: " + mbref.getBufferIdentifier()); } } // Add a given library by searching it from input search paths. -void LinkerDriver::addLibrary(StringRef Name) { - for (StringRef Dir : Config->SearchPaths) { - if (Optional S = findFile(Dir, "lib" + Name + ".a")) { - addFile(*S); +void LinkerDriver::addLibrary(StringRef name) { + for (StringRef dir : config->searchPaths) { + if (Optional s = findFile(dir, "lib" + name + ".a")) { + addFile(*s); return; } } - error("unable to find library -l" + Name); + error("unable to find library -l" + name); } -void LinkerDriver::createFiles(opt::InputArgList &Args) { - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { +void LinkerDriver::createFiles(opt::InputArgList &args) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_l: - addLibrary(Arg->getValue()); + addLibrary(arg->getValue()); break; case OPT_INPUT: - addFile(Arg->getValue()); + addFile(arg->getValue()); break; case OPT_whole_archive: - InWholeArchive = true; + inWholeArchive = true; break; case OPT_no_whole_archive: - InWholeArchive = false; + inWholeArchive = false; break; } } } -static StringRef getEntry(opt::InputArgList &Args) { - auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); - if (!Arg) { - if (Args.hasArg(OPT_relocatable)) +static StringRef getEntry(opt::InputArgList &args) { + auto *arg = args.getLastArg(OPT_entry, OPT_no_entry); + if (!arg) { + if (args.hasArg(OPT_relocatable)) return ""; - if (Args.hasArg(OPT_shared)) + if (args.hasArg(OPT_shared)) return "__wasm_call_ctors"; return "_start"; } - if (Arg->getOption().getID() == OPT_no_entry) + if (arg->getOption().getID() == OPT_no_entry) return ""; - return Arg->getValue(); + return arg->getValue(); } // Initializes Config members by the command line options. -static void readConfigs(opt::InputArgList &Args) { - Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); - Config->CheckFeatures = - Args.hasFlag(OPT_check_features, OPT_no_check_features, true); - Config->CompressRelocations = Args.hasArg(OPT_compress_relocations); - Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); - Config->DisableVerify = Args.hasArg(OPT_disable_verify); - Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); - Config->Entry = getEntry(Args); - Config->ExportAll = Args.hasArg(OPT_export_all); - Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic, +static void readConfigs(opt::InputArgList &args) { + config->allowUndefined = args.hasArg(OPT_allow_undefined); + config->checkFeatures = + args.hasFlag(OPT_check_features, OPT_no_check_features, true); + config->compressRelocations = args.hasArg(OPT_compress_relocations); + config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true); + config->disableVerify = args.hasArg(OPT_disable_verify); + config->emitRelocs = args.hasArg(OPT_emit_relocs); + config->entry = getEntry(args); + config->exportAll = args.hasArg(OPT_export_all); + config->exportDynamic = args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); - Config->ExportTable = Args.hasArg(OPT_export_table); - errorHandler().FatalWarnings = - Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); - Config->ImportMemory = Args.hasArg(OPT_import_memory); - Config->SharedMemory = Args.hasArg(OPT_shared_memory); + config->exportTable = args.hasArg(OPT_export_table); + errorHandler().fatalWarnings = + args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); + config->importMemory = args.hasArg(OPT_import_memory); + config->sharedMemory = args.hasArg(OPT_shared_memory); // TODO: Make passive segments the default with shared memory - Config->PassiveSegments = - Args.hasFlag(OPT_passive_segments, OPT_active_segments, false); - Config->ImportTable = Args.hasArg(OPT_import_table); - Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); - Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); - Config->Optimize = args::getInteger(Args, OPT_O, 0); - Config->OutputFile = Args.getLastArgValue(OPT_o); - Config->Relocatable = Args.hasArg(OPT_relocatable); - Config->GcSections = - Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable); - Config->MergeDataSegments = - Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, - !Config->Relocatable); - Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false); - Config->PrintGcSections = - Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); - Config->SaveTemps = Args.hasArg(OPT_save_temps); - Config->SearchPaths = args::getStrings(Args, OPT_L); - Config->Shared = Args.hasArg(OPT_shared); - Config->StripAll = Args.hasArg(OPT_strip_all); - Config->StripDebug = Args.hasArg(OPT_strip_debug); - Config->StackFirst = Args.hasArg(OPT_stack_first); - Config->Trace = Args.hasArg(OPT_trace); - Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); - Config->ThinLTOCachePolicy = CHECK( - parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), + config->passiveSegments = + args.hasFlag(OPT_passive_segments, OPT_active_segments, false); + config->importTable = args.hasArg(OPT_import_table); + config->ltoo = args::getInteger(args, OPT_lto_O, 2); + config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); + config->optimize = args::getInteger(args, OPT_O, 0); + config->outputFile = args.getLastArgValue(OPT_o); + config->relocatable = args.hasArg(OPT_relocatable); + config->gcSections = + args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable); + config->mergeDataSegments = + args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, + !config->relocatable); + config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false); + config->printGcSections = + args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); + config->saveTemps = args.hasArg(OPT_save_temps); + config->searchPaths = args::getStrings(args, OPT_L); + config->shared = args.hasArg(OPT_shared); + config->stripAll = args.hasArg(OPT_strip_all); + config->stripDebug = args.hasArg(OPT_strip_debug); + config->stackFirst = args.hasArg(OPT_stack_first); + config->trace = args.hasArg(OPT_trace); + 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->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); - errorHandler().Verbose = Args.hasArg(OPT_verbose); - LLVM_DEBUG(errorHandler().Verbose = true); - ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); - - Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); - Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); - Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0); - Config->ZStackSize = - args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); - - if (auto *Arg = Args.getLastArg(OPT_features)) { - Config->Features = + config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u); + errorHandler().verbose = args.hasArg(OPT_verbose); + LLVM_DEBUG(errorHandler().verbose = true); + threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true); + + config->initialMemory = args::getInteger(args, OPT_initial_memory, 0); + config->globalBase = args::getInteger(args, OPT_global_base, 1024); + config->maxMemory = args::getInteger(args, OPT_max_memory, 0); + config->zStackSize = + args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize); + + if (auto *arg = args.getLastArg(OPT_features)) { + config->features = llvm::Optional>(std::vector()); - for (StringRef S : Arg->getValues()) - Config->Features->push_back(S); + for (StringRef s : arg->getValues()) + config->features->push_back(s); } } @@ -372,183 +372,183 @@ static void readConfigs(opt::InputArgList &Args) { // This function initialize such members. See Config.h for the details // of these values. static void setConfigs() { - Config->Pic = Config->Pie || Config->Shared; + config->isPic = config->pie || config->shared; - if (Config->Pic) { - if (Config->ExportTable) + if (config->isPic) { + if (config->exportTable) error("-shared/-pie is incompatible with --export-table"); - Config->ImportTable = true; + config->importTable = true; } - if (Config->Shared) { - Config->ImportMemory = true; - Config->ExportDynamic = true; - Config->AllowUndefined = true; + if (config->shared) { + config->importMemory = true; + config->exportDynamic = true; + config->allowUndefined = true; } } // Some command line options or some combinations of them are not allowed. // This function checks for such errors. -static void checkOptions(opt::InputArgList &Args) { - if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations) +static void checkOptions(opt::InputArgList &args) { + if (!config->stripDebug && !config->stripAll && config->compressRelocations) error("--compress-relocations is incompatible with output debug" " information. Please pass --strip-debug or --strip-all"); - 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->Pie && Config->Shared) + if (config->pie && config->shared) error("-shared and -pie may not be used together"); - if (Config->OutputFile.empty()) + if (config->outputFile.empty()) error("no output file specified"); - if (Config->ImportTable && Config->ExportTable) + if (config->importTable && config->exportTable) error("--import-table and --export-table may not be used together"); - if (Config->Relocatable) { - if (!Config->Entry.empty()) + if (config->relocatable) { + if (!config->entry.empty()) error("entry point specified for relocatable output file"); - if (Config->GcSections) + if (config->gcSections) error("-r and --gc-sections may not be used together"); - if (Config->CompressRelocations) + if (config->compressRelocations) error("-r -and --compress-relocations may not be used together"); - if (Args.hasArg(OPT_undefined)) + if (args.hasArg(OPT_undefined)) error("-r -and --undefined may not be used together"); - if (Config->Pie) + if (config->pie) error("-r and -pie may not be used together"); } } // Force Sym to be entered in the output. Used for -u or equivalent. -static Symbol *handleUndefined(StringRef Name) { - Symbol *Sym = Symtab->find(Name); - if (!Sym) +static Symbol *handleUndefined(StringRef name) { + Symbol *sym = symtab->find(name); + if (!sym) return nullptr; // Since symbol S 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 (auto *LazySym = dyn_cast(Sym)) - LazySym->fetch(); + if (auto *lazySym = dyn_cast(sym)) + lazySym->fetch(); - return Sym; + return sym; } static UndefinedGlobal * -createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) { - auto *Sym = - cast(Symtab->addUndefinedGlobal(Name, Name, - DefaultModule, 0, - nullptr, Type)); - Config->AllowUndefinedSymbols.insert(Sym->getName()); - Sym->IsUsedInRegularObj = true; - return Sym; +createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) { + auto *sym = + cast(symtab->addUndefinedGlobal(name, name, + defaultModule, 0, + nullptr, type)); + config->allowUndefinedSymbols.insert(sym->getName()); + sym->isUsedInRegularObj = true; + return sym; } // Create ABI-defined synthetic symbols static void createSyntheticSymbols() { - static WasmSignature NullSignature = {{}, {}}; - static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false}; - static llvm::wasm::WasmGlobalType MutableGlobalTypeI32 = {WASM_TYPE_I32, + static WasmSignature nullSignature = {{}, {}}; + static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false}; + static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32, true}; - if (!Config->Relocatable) { - WasmSym::CallCtors = Symtab->addSyntheticFunction( + if (!config->relocatable) { + WasmSym::callCtors = symtab->addSyntheticFunction( "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, - make(NullSignature, "__wasm_call_ctors")); + make(nullSignature, "__wasm_call_ctors")); - if (Config->PassiveSegments) { + if (config->passiveSegments) { // Passive segments are used to avoid memory being reinitialized on each // thread's instantiation. These passive segments are initialized and // dropped in __wasm_init_memory, which is the first function called from // __wasm_call_ctors. - WasmSym::InitMemory = Symtab->addSyntheticFunction( + WasmSym::initMemory = symtab->addSyntheticFunction( "__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN, - make(NullSignature, "__wasm_init_memory")); + make(nullSignature, "__wasm_init_memory")); } - if (Config->Pic) { + if (config->isPic) { // For PIC code we create a synthetic function __wasm_apply_relocs which // is called from __wasm_call_ctors before the user-level constructors. - WasmSym::ApplyRelocs = Symtab->addSyntheticFunction( + WasmSym::applyRelocs = symtab->addSyntheticFunction( "__wasm_apply_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, - make(NullSignature, "__wasm_apply_relocs")); + make(nullSignature, "__wasm_apply_relocs")); } } // The __stack_pointer is imported in the shared library case, and exported // in the non-shared (executable) case. - if (Config->Shared) { - WasmSym::StackPointer = - createUndefinedGlobal("__stack_pointer", &MutableGlobalTypeI32); + if (config->shared) { + WasmSym::stackPointer = + createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32); } else { - llvm::wasm::WasmGlobal Global; - Global.Type = {WASM_TYPE_I32, true}; - Global.InitExpr.Value.Int32 = 0; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.SymbolName = "__stack_pointer"; - auto *StackPointer = make(Global, nullptr); - StackPointer->Live = true; + llvm::wasm::WasmGlobal global; + global.Type = {WASM_TYPE_I32, true}; + global.InitExpr.Value.Int32 = 0; + global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + global.SymbolName = "__stack_pointer"; + auto *stackPointer = make(global, nullptr); + stackPointer->live = true; // For non-PIC code // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global // spec proposal is implemented in all major browsers. // See: https://github.com/WebAssembly/mutable-global - WasmSym::StackPointer = Symtab->addSyntheticGlobal( - "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); - WasmSym::DataEnd = Symtab->addOptionalDataSymbol("__data_end"); - WasmSym::GlobalBase = Symtab->addOptionalDataSymbol("__global_base"); - WasmSym::HeapBase = Symtab->addOptionalDataSymbol("__heap_base"); + WasmSym::stackPointer = symtab->addSyntheticGlobal( + "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, stackPointer); + WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end"); + WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base"); + WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base"); } - if (Config->Pic) { + if (config->isPic) { // For PIC code, we import two global variables (__memory_base and // __table_base) from the environment and use these as the offset at // which to load our static data and function table. // See: // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md - WasmSym::MemoryBase = - createUndefinedGlobal("__memory_base", &GlobalTypeI32); - WasmSym::TableBase = createUndefinedGlobal("__table_base", &GlobalTypeI32); - WasmSym::MemoryBase->markLive(); - WasmSym::TableBase->markLive(); + WasmSym::memoryBase = + createUndefinedGlobal("__memory_base", &globalTypeI32); + WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32); + WasmSym::memoryBase->markLive(); + WasmSym::tableBase->markLive(); } - WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol( + WasmSym::dsoHandle = symtab->addSyntheticDataSymbol( "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN); } // Reconstructs command line arguments so that so that you can re-run // the same command with the same inputs. This is for --reproduce. -static std::string createResponseFile(const opt::InputArgList &Args) { - SmallString<0> Data; - raw_svector_ostream OS(Data); +static std::string createResponseFile(const opt::InputArgList &args) { + SmallString<0> data; + raw_svector_ostream os(data); // 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(relativeToRoot(Arg->getValue())) << "\n"; + os << quote(relativeToRoot(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; default: - OS << toString(*Arg) << "\n"; + os << toString(*arg) << "\n"; } } - return Data.str(); + return data.str(); } // The --wrap option is a feature to rename symbols so that you can write @@ -560,13 +560,13 @@ static std::string createResponseFile(const opt::InputArgList &Args) { // // This data structure is instantiated for each -wrap option. struct WrappedSymbol { - Symbol *Sym; - Symbol *Real; - Symbol *Wrap; + Symbol *sym; + Symbol *real; + Symbol *wrap; }; -static Symbol *addUndefined(StringRef Name) { - return Symtab->addUndefinedFunction(Name, "", "", 0, nullptr, nullptr, false); +static Symbol *addUndefined(StringRef name) { + return symtab->addUndefinedFunction(name, "", "", 0, nullptr, nullptr, false); } // Handles -wrap option. @@ -574,34 +574,34 @@ static Symbol *addUndefined(StringRef Name) { // 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 addWrappedSymbols(opt::InputArgList &Args) { - std::vector V; - DenseSet Seen; +static std::vector addWrappedSymbols(opt::InputArgList &args) { + std::vector v; + DenseSet 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; - Real->IsUsedInRegularObj = false; + sym->isUsedInRegularObj = true; + wrap->isUsedInRegularObj = true; + real->isUsedInRegularObj = false; } - return V; + return v; } // Do renaming for -wrap by updating pointers to symbols. @@ -609,158 +609,158 @@ static std::vector 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 Wrapped) { - DenseMap Map; - for (const WrappedSymbol &W : Wrapped) { - Map[W.Sym] = W.Wrap; - Map[W.Real] = W.Sym; +static void wrapSymbols(ArrayRef wrapped) { + DenseMap map; + for (const WrappedSymbol &w : wrapped) { + map[w.sym] = w.wrap; + map[w.real] = w.sym; } // Update pointers in input files. - parallelForEach(Symtab->ObjectFiles, [&](InputFile *File) { - MutableArrayRef 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(symtab->objectFiles, [&](InputFile *file) { + MutableArrayRef 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); } -void LinkerDriver::link(ArrayRef ArgsArr) { - WasmOptTable Parser; - opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); +void LinkerDriver::link(ArrayRef argsArr) { + WasmOptTable parser; + opt::InputArgList args = parser.parse(argsArr.slice(1)); // Handle --help - if (Args.hasArg(OPT_help)) { - Parser.PrintHelp(outs(), - (std::string(ArgsArr[0]) + " [options] file...").c_str(), + if (args.hasArg(OPT_help)) { + parser.PrintHelp(outs(), + (std::string(argsArr[0]) + " [options] file...").c_str(), "LLVM Linker", false); return; } // Handle --version - if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) { + if (args.hasArg(OPT_version) || args.hasArg(OPT_v)) { outs() << getLLDVersion() << "\n"; return; } // Handle --reproduce - if (auto *Arg = Args.getLastArg(OPT_reproduce)) { - StringRef Path = Arg->getValue(); - Expected> 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"); + if (auto *arg = args.getLastArg(OPT_reproduce)) { + StringRef path = arg->getValue(); + Expected> 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())); } } // Parse and evaluate -mllvm options. - std::vector V; - V.push_back("wasm-ld (LLVM option parsing)"); - for (auto *Arg : Args.filtered(OPT_mllvm)) - V.push_back(Arg->getValue()); - cl::ParseCommandLineOptions(V.size(), V.data()); + std::vector v; + v.push_back("wasm-ld (LLVM option parsing)"); + for (auto *arg : args.filtered(OPT_mllvm)) + v.push_back(arg->getValue()); + cl::ParseCommandLineOptions(v.size(), v.data()); - errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); + errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20); - readConfigs(Args); + readConfigs(args); setConfigs(); - checkOptions(Args); + checkOptions(args); - if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) - readImportFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_allow_undefined_file)) + readImportFile(arg->getValue()); - if (!Args.hasArg(OPT_INPUT)) { + if (!args.hasArg(OPT_INPUT)) { error("no input files"); return; } // Handle --trace-symbol. - for (auto *Arg : Args.filtered(OPT_trace_symbol)) - Symtab->trace(Arg->getValue()); + for (auto *arg : args.filtered(OPT_trace_symbol)) + symtab->trace(arg->getValue()); - for (auto *Arg : Args.filtered(OPT_export)) - Config->ExportedSymbols.insert(Arg->getValue()); + for (auto *arg : args.filtered(OPT_export)) + config->exportedSymbols.insert(arg->getValue()); - if (!Config->Relocatable) + if (!config->relocatable) createSyntheticSymbols(); - createFiles(Args); + createFiles(args); if (errorCount()) return; // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. - for (InputFile *F : Files) - Symtab->addFile(F); + for (InputFile *f : files) + symtab->addFile(f); if (errorCount()) return; // Handle the `--undefined ` options. - for (auto *Arg : Args.filtered(OPT_undefined)) - handleUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_undefined)) + handleUndefined(arg->getValue()); // Handle the `--export ` options // This works like --undefined but also exports the symbol if its found - for (auto *Arg : Args.filtered(OPT_export)) - handleUndefined(Arg->getValue()); - - Symbol *EntrySym = nullptr; - if (!Config->Relocatable && !Config->Entry.empty()) { - EntrySym = handleUndefined(Config->Entry); - if (EntrySym && EntrySym->isDefined()) - EntrySym->ForceExport = true; + for (auto *arg : args.filtered(OPT_export)) + handleUndefined(arg->getValue()); + + Symbol *entrySym = nullptr; + if (!config->relocatable && !config->entry.empty()) { + entrySym = handleUndefined(config->entry); + if (entrySym && entrySym->isDefined()) + entrySym->forceExport = true; else error("entry symbol not defined (pass --no-entry to supress): " + - Config->Entry); + config->entry); } if (errorCount()) return; // Create wrapped symbols for -wrap option. - std::vector Wrapped = addWrappedSymbols(Args); + std::vector wrapped = addWrappedSymbols(args); // Do link-time optimization if given files are LLVM bitcode files. // This compiles bitcode files into real object files. - Symtab->addCombinedLTOObject(); + symtab->addCombinedLTOObject(); if (errorCount()) return; // Resolve any variant symbols that were created due to signature // mismatchs. - Symtab->handleSymbolVariants(); + symtab->handleSymbolVariants(); if (errorCount()) return; // Apply symbol renames for -wrap. - if (!Wrapped.empty()) - wrapSymbols(Wrapped); - - for (auto *Arg : Args.filtered(OPT_export)) { - Symbol *Sym = Symtab->find(Arg->getValue()); - if (Sym && Sym->isDefined()) - Sym->ForceExport = true; - else if (!Config->AllowUndefined) + if (!wrapped.empty()) + wrapSymbols(wrapped); + + for (auto *arg : args.filtered(OPT_export)) { + Symbol *sym = symtab->find(arg->getValue()); + if (sym && sym->isDefined()) + sym->forceExport = true; + else if (!config->allowUndefined) error(Twine("symbol exported via --export not found: ") + - Arg->getValue()); + arg->getValue()); } - if (!Config->Relocatable) { + if (!config->relocatable) { // Add synthetic dummies for weak undefined functions. Must happen // after LTO otherwise functions may not yet have signatures. - Symtab->handleWeakUndefines(); + symtab->handleWeakUndefines(); } - if (EntrySym) - EntrySym->setHidden(false); + if (entrySym) + entrySym->setHidden(false); if (errorCount()) return; diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index cb62f96..d37b58a 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -22,8 +22,8 @@ using namespace llvm::support::endian; using namespace lld; using namespace lld::wasm; -StringRef lld::relocTypeToString(uint8_t RelocType) { - switch (RelocType) { +StringRef lld::relocTypeToString(uint8_t relocType) { + switch (relocType) { #define WASM_RELOC(NAME, REL) \ case REL: \ return #NAME; @@ -33,67 +33,67 @@ StringRef lld::relocTypeToString(uint8_t RelocType) { llvm_unreachable("unknown reloc type"); } -std::string lld::toString(const InputChunk *C) { - return (toString(C->File) + ":(" + C->getName() + ")").str(); +std::string lld::toString(const InputChunk *c) { + return (toString(c->file) + ":(" + c->getName() + ")").str(); } StringRef InputChunk::getComdatName() const { - uint32_t Index = getComdat(); - if (Index == UINT32_MAX) + uint32_t index = getComdat(); + if (index == UINT32_MAX) return StringRef(); - return File->getWasmObj()->linkingData().Comdats[Index]; + return file->getWasmObj()->linkingData().Comdats[index]; } void InputChunk::verifyRelocTargets() const { - for (const WasmRelocation &Rel : Relocations) { - uint32_t ExistingValue; - unsigned BytesRead = 0; - uint32_t Offset = Rel.Offset - getInputSectionOffset(); - const uint8_t *Loc = data().data() + Offset; - switch (Rel.Type) { + for (const WasmRelocation &rel : relocations) { + uint32_t existingValue; + unsigned bytesRead = 0; + uint32_t offset = rel.Offset - getInputSectionOffset(); + const uint8_t *loc = data().data() + offset; + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - ExistingValue = decodeULEB128(Loc, &BytesRead); + existingValue = decodeULEB128(loc, &bytesRead); break; case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - ExistingValue = static_cast(decodeSLEB128(Loc, &BytesRead)); + existingValue = static_cast(decodeSLEB128(loc, &bytesRead)); break; case R_WASM_TABLE_INDEX_I32: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: case R_WASM_SECTION_OFFSET_I32: - ExistingValue = static_cast(read32le(Loc)); + existingValue = static_cast(read32le(loc)); break; default: llvm_unreachable("unknown relocation type"); } - if (BytesRead && BytesRead != 5) + if (bytesRead && bytesRead != 5) warn("expected LEB at relocation site be 5-byte padded"); - if (Rel.Type != R_WASM_GLOBAL_INDEX_LEB) { - uint32_t ExpectedValue = File->calcExpectedValue(Rel); - if (ExpectedValue != ExistingValue) - warn("unexpected existing value for " + relocTypeToString(Rel.Type) + - ": existing=" + Twine(ExistingValue) + - " expected=" + Twine(ExpectedValue)); + if (rel.Type != R_WASM_GLOBAL_INDEX_LEB) { + uint32_t expectedValue = file->calcExpectedValue(rel); + if (expectedValue != existingValue) + warn("unexpected existing value for " + relocTypeToString(rel.Type) + + ": existing=" + Twine(existingValue) + + " expected=" + Twine(expectedValue)); } } } // Copy this input chunk to an mmap'ed output file and apply relocations. -void InputChunk::writeTo(uint8_t *Buf) const { +void InputChunk::writeTo(uint8_t *buf) const { // Copy contents - memcpy(Buf + OutputOffset, data().data(), data().size()); + memcpy(buf + outputOffset, data().data(), data().size()); // Apply relocations - if (Relocations.empty()) + if (relocations.empty()) return; #ifndef NDEBUG @@ -101,38 +101,38 @@ void InputChunk::writeTo(uint8_t *Buf) const { #endif LLVM_DEBUG(dbgs() << "applying relocations: " << getName() - << " count=" << Relocations.size() << "\n"); - int32_t Off = OutputOffset - getInputSectionOffset(); - - for (const WasmRelocation &Rel : Relocations) { - uint8_t *Loc = Buf + Rel.Offset + Off; - uint32_t Value = File->calcNewValue(Rel); - LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(Rel.Type)); - if (Rel.Type != R_WASM_TYPE_INDEX_LEB) - LLVM_DEBUG(dbgs() << " sym=" << File->getSymbols()[Rel.Index]->getName()); - LLVM_DEBUG(dbgs() << " addend=" << Rel.Addend << " index=" << Rel.Index - << " value=" << Value << " offset=" << Rel.Offset + << " count=" << relocations.size() << "\n"); + int32_t off = outputOffset - getInputSectionOffset(); + + for (const WasmRelocation &rel : relocations) { + uint8_t *loc = buf + rel.Offset + off; + uint32_t value = file->calcNewValue(rel); + LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(rel.Type)); + if (rel.Type != R_WASM_TYPE_INDEX_LEB) + LLVM_DEBUG(dbgs() << " sym=" << file->getSymbols()[rel.Index]->getName()); + LLVM_DEBUG(dbgs() << " addend=" << rel.Addend << " index=" << rel.Index + << " value=" << value << " offset=" << rel.Offset << "\n"); - switch (Rel.Type) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - encodeULEB128(Value, Loc, 5); + encodeULEB128(value, loc, 5); break; case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - encodeSLEB128(static_cast(Value), Loc, 5); + encodeSLEB128(static_cast(value), loc, 5); break; case R_WASM_TABLE_INDEX_I32: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: case R_WASM_SECTION_OFFSET_I32: - write32le(Loc, Value); + write32le(loc, value); break; default: llvm_unreachable("unknown relocation type"); @@ -143,59 +143,59 @@ void InputChunk::writeTo(uint8_t *Buf) const { // Copy relocation entries to a given output stream. // This function is used only when a user passes "-r". For a regular link, // we consume relocations instead of copying them to an output file. -void InputChunk::writeRelocations(raw_ostream &OS) const { - if (Relocations.empty()) +void InputChunk::writeRelocations(raw_ostream &os) const { + if (relocations.empty()) return; - int32_t Off = OutputOffset - getInputSectionOffset(); - LLVM_DEBUG(dbgs() << "writeRelocations: " << File->getName() - << " offset=" << Twine(Off) << "\n"); + int32_t off = outputOffset - getInputSectionOffset(); + LLVM_DEBUG(dbgs() << "writeRelocations: " << file->getName() + << " offset=" << Twine(off) << "\n"); - for (const WasmRelocation &Rel : Relocations) { - writeUleb128(OS, Rel.Type, "reloc type"); - writeUleb128(OS, Rel.Offset + Off, "reloc offset"); - writeUleb128(OS, File->calcNewIndex(Rel), "reloc index"); + for (const WasmRelocation &rel : relocations) { + writeUleb128(os, rel.Type, "reloc type"); + writeUleb128(os, rel.Offset + off, "reloc offset"); + writeUleb128(os, file->calcNewIndex(rel), "reloc index"); - if (relocTypeHasAddend(Rel.Type)) - writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend"); + if (relocTypeHasAddend(rel.Type)) + writeSleb128(os, file->calcNewAddend(rel), "reloc addend"); } } -void InputFunction::setFunctionIndex(uint32_t Index) { +void InputFunction::setFunctionIndex(uint32_t index) { LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName() - << " -> " << Index << "\n"); + << " -> " << index << "\n"); assert(!hasFunctionIndex()); - FunctionIndex = Index; + functionIndex = index; } -void InputFunction::setTableIndex(uint32_t Index) { +void InputFunction::setTableIndex(uint32_t index) { LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> " - << Index << "\n"); + << index << "\n"); assert(!hasTableIndex()); - TableIndex = Index; + tableIndex = index; } // Write a relocation value without padding and return the number of bytes // witten. -static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel, - uint32_t Value) { - switch (Rel.Type) { +static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel, + uint32_t value) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - return encodeULEB128(Value, Buf); + return encodeULEB128(value, buf); case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: - return encodeSLEB128(static_cast(Value), Buf); + return encodeSLEB128(static_cast(value), buf); default: llvm_unreachable("unexpected relocation type"); } } -static unsigned getRelocWidthPadded(const WasmRelocation &Rel) { - switch (Rel.Type) { +static unsigned getRelocWidthPadded(const WasmRelocation &rel) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: @@ -209,9 +209,9 @@ static unsigned getRelocWidthPadded(const WasmRelocation &Rel) { } } -static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) { - uint8_t Buf[5]; - return writeCompressedReloc(Buf, Rel, Value); +static unsigned getRelocWidth(const WasmRelocation &rel, uint32_t value) { + uint8_t buf[5]; + return writeCompressedReloc(buf, rel, value); } // Relocations of type LEB and SLEB in the code section are padded to 5 bytes @@ -225,124 +225,124 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) { // This function only computes the final output size. It must be called // before getSize() is used to calculate of layout of the code section. void InputFunction::calculateSize() { - if (!File || !Config->CompressRelocations) + if (!file || !config->compressRelocations) return; LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n"); - const uint8_t *SecStart = File->CodeSection->Content.data(); - const uint8_t *FuncStart = SecStart + getInputSectionOffset(); - uint32_t FunctionSizeLength; - decodeULEB128(FuncStart, &FunctionSizeLength); + const uint8_t *secStart = file->codeSection->Content.data(); + const uint8_t *funcStart = secStart + getInputSectionOffset(); + uint32_t functionSizeLength; + decodeULEB128(funcStart, &functionSizeLength); - uint32_t Start = getInputSectionOffset(); - uint32_t End = Start + Function->Size; + uint32_t start = getInputSectionOffset(); + uint32_t end = start + function->Size; - uint32_t LastRelocEnd = Start + FunctionSizeLength; - for (const WasmRelocation &Rel : Relocations) { - LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n"); - CompressedFuncSize += Rel.Offset - LastRelocEnd; - CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel)); - LastRelocEnd = Rel.Offset + getRelocWidthPadded(Rel); + uint32_t lastRelocEnd = start + functionSizeLength; + for (const WasmRelocation &rel : relocations) { + LLVM_DEBUG(dbgs() << " region: " << (rel.Offset - lastRelocEnd) << "\n"); + compressedFuncSize += rel.Offset - lastRelocEnd; + compressedFuncSize += getRelocWidth(rel, file->calcNewValue(rel)); + lastRelocEnd = rel.Offset + getRelocWidthPadded(rel); } - LLVM_DEBUG(dbgs() << " final region: " << (End - LastRelocEnd) << "\n"); - CompressedFuncSize += End - LastRelocEnd; + LLVM_DEBUG(dbgs() << " final region: " << (end - lastRelocEnd) << "\n"); + compressedFuncSize += end - lastRelocEnd; // Now we know how long the resulting function is we can add the encoding // of its length - uint8_t Buf[5]; - CompressedSize = CompressedFuncSize + encodeULEB128(CompressedFuncSize, Buf); + uint8_t buf[5]; + compressedSize = compressedFuncSize + encodeULEB128(compressedFuncSize, buf); - LLVM_DEBUG(dbgs() << " calculateSize orig: " << Function->Size << "\n"); - LLVM_DEBUG(dbgs() << " calculateSize new: " << CompressedSize << "\n"); + LLVM_DEBUG(dbgs() << " calculateSize orig: " << function->Size << "\n"); + LLVM_DEBUG(dbgs() << " calculateSize new: " << compressedSize << "\n"); } // Override the default writeTo method so that we can (optionally) write the // compressed version of the function. -void InputFunction::writeTo(uint8_t *Buf) const { - if (!File || !Config->CompressRelocations) - return InputChunk::writeTo(Buf); +void InputFunction::writeTo(uint8_t *buf) const { + if (!file || !config->compressRelocations) + return InputChunk::writeTo(buf); - Buf += OutputOffset; - uint8_t *Orig = Buf; - (void)Orig; + buf += outputOffset; + uint8_t *orig = buf; + (void)orig; - const uint8_t *SecStart = File->CodeSection->Content.data(); - const uint8_t *FuncStart = SecStart + getInputSectionOffset(); - const uint8_t *End = FuncStart + Function->Size; - uint32_t Count; - decodeULEB128(FuncStart, &Count); - FuncStart += Count; + const uint8_t *secStart = file->codeSection->Content.data(); + const uint8_t *funcStart = secStart + getInputSectionOffset(); + const uint8_t *end = funcStart + function->Size; + uint32_t count; + decodeULEB128(funcStart, &count); + funcStart += count; LLVM_DEBUG(dbgs() << "write func: " << getName() << "\n"); - Buf += encodeULEB128(CompressedFuncSize, Buf); - const uint8_t *LastRelocEnd = FuncStart; - for (const WasmRelocation &Rel : Relocations) { - unsigned ChunkSize = (SecStart + Rel.Offset) - LastRelocEnd; - LLVM_DEBUG(dbgs() << " write chunk: " << ChunkSize << "\n"); - memcpy(Buf, LastRelocEnd, ChunkSize); - Buf += ChunkSize; - Buf += writeCompressedReloc(Buf, Rel, File->calcNewValue(Rel)); - LastRelocEnd = SecStart + Rel.Offset + getRelocWidthPadded(Rel); + buf += encodeULEB128(compressedFuncSize, buf); + const uint8_t *lastRelocEnd = funcStart; + for (const WasmRelocation &rel : relocations) { + unsigned chunkSize = (secStart + rel.Offset) - lastRelocEnd; + LLVM_DEBUG(dbgs() << " write chunk: " << chunkSize << "\n"); + memcpy(buf, lastRelocEnd, chunkSize); + buf += chunkSize; + buf += writeCompressedReloc(buf, rel, file->calcNewValue(rel)); + lastRelocEnd = secStart + rel.Offset + getRelocWidthPadded(rel); } - unsigned ChunkSize = End - LastRelocEnd; - LLVM_DEBUG(dbgs() << " write final chunk: " << ChunkSize << "\n"); - memcpy(Buf, LastRelocEnd, ChunkSize); - LLVM_DEBUG(dbgs() << " total: " << (Buf + ChunkSize - Orig) << "\n"); + unsigned chunkSize = end - lastRelocEnd; + LLVM_DEBUG(dbgs() << " write final chunk: " << chunkSize << "\n"); + memcpy(buf, lastRelocEnd, chunkSize); + LLVM_DEBUG(dbgs() << " total: " << (buf + chunkSize - orig) << "\n"); } // Generate code to apply relocations to the data section at runtime. // This is only called when generating shared libaries (PIC) where address are // not known at static link time. -void InputSegment::generateRelocationCode(raw_ostream &OS) const { +void InputSegment::generateRelocationCode(raw_ostream &os) const { LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName() - << " count=" << Relocations.size() << "\n"); + << " count=" << relocations.size() << "\n"); // TODO(sbc): Encode the relocations in the data section and write a loop // here to apply them. - uint32_t SegmentVA = OutputSeg->StartVA + OutputSegmentOffset; - for (const WasmRelocation &Rel : Relocations) { - uint32_t Offset = Rel.Offset - getInputSectionOffset(); - uint32_t OutputOffset = SegmentVA + Offset; + uint32_t segmentVA = outputSeg->startVA + outputSegmentOffset; + for (const WasmRelocation &rel : relocations) { + uint32_t offset = rel.Offset - getInputSectionOffset(); + uint32_t outputOffset = segmentVA + offset; - LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(Rel.Type) - << " addend=" << Rel.Addend << " index=" << Rel.Index - << " output offset=" << OutputOffset << "\n"); + LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type) + << " addend=" << rel.Addend << " index=" << rel.Index + << " output offset=" << outputOffset << "\n"); // Get __memory_base - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, WasmSym::MemoryBase->getGlobalIndex(), "memory_base"); + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base"); // Add the offset of the relocation - writeU8(OS, WASM_OPCODE_I32_CONST, "I32_CONST"); - writeSleb128(OS, OutputOffset, "offset"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + writeU8(os, WASM_OPCODE_I32_CONST, "I32_CONST"); + writeSleb128(os, outputOffset, "offset"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); - Symbol *Sym = File->getSymbol(Rel); + Symbol *sym = file->getSymbol(rel); // Now figure out what we want to store - if (Sym->hasGOTIndex()) { - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, Sym->getGOTIndex(), "global index"); - if (Rel.Addend) { - writeU8(OS, WASM_OPCODE_I32_CONST, "CONST"); - writeSleb128(OS, Rel.Addend, "addend"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + if (sym->hasGOTIndex()) { + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, sym->getGOTIndex(), "global index"); + if (rel.Addend) { + writeU8(os, WASM_OPCODE_I32_CONST, "CONST"); + writeSleb128(os, rel.Addend, "addend"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); } } else { - const GlobalSymbol* BaseSymbol = WasmSym::MemoryBase; - if (Rel.Type == R_WASM_TABLE_INDEX_I32) - BaseSymbol = WasmSym::TableBase; - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, BaseSymbol->getGlobalIndex(), "base"); - writeU8(OS, WASM_OPCODE_I32_CONST, "CONST"); - writeSleb128(OS, File->calcNewValue(Rel), "offset"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + const GlobalSymbol* baseSymbol = WasmSym::memoryBase; + if (rel.Type == R_WASM_TABLE_INDEX_I32) + baseSymbol = WasmSym::tableBase; + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, baseSymbol->getGlobalIndex(), "base"); + writeU8(os, WASM_OPCODE_I32_CONST, "CONST"); + writeSleb128(os, file->calcNewValue(rel), "offset"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); } // Store that value at the virtual address - writeU8(OS, WASM_OPCODE_I32_STORE, "I32_STORE"); - writeUleb128(OS, 2, "align"); - writeUleb128(OS, 0, "offset"); + writeU8(os, WASM_OPCODE_I32_STORE, "I32_STORE"); + writeUleb128(os, 2, "align"); + writeUleb128(os, 0, "offset"); } } diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h index b8e4c32..2d3eb40 100644 --- a/lld/wasm/InputChunks.h +++ b/lld/wasm/InputChunks.h @@ -37,15 +37,15 @@ class InputChunk { public: enum Kind { DataSegment, Function, SyntheticFunction, Section }; - Kind kind() const { return SectionKind; } + Kind kind() const { return sectionKind; } virtual uint32_t getSize() const { return data().size(); } virtual uint32_t getInputSize() const { return getSize(); }; - virtual void writeTo(uint8_t *SectionStart) const; + virtual void writeTo(uint8_t *sectionStart) const; - ArrayRef getRelocations() const { return Relocations; } - void setRelocations(ArrayRef Rs) { Relocations = Rs; } + ArrayRef getRelocations() const { return relocations; } + void setRelocations(ArrayRef rs) { relocations = rs; } virtual StringRef getName() const = 0; virtual StringRef getDebugName() const = 0; @@ -53,23 +53,23 @@ public: StringRef getComdatName() const; virtual uint32_t getInputSectionOffset() const = 0; - size_t getNumRelocations() const { return Relocations.size(); } - void writeRelocations(llvm::raw_ostream &OS) const; + size_t getNumRelocations() const { return relocations.size(); } + void writeRelocations(llvm::raw_ostream &os) const; - ObjFile *File; - int32_t OutputOffset = 0; + ObjFile *file; + int32_t outputOffset = 0; // Signals that the section is part of the output. The garbage collector, // and COMDAT handling can set a sections' Live bit. // If GC is disabled, all sections start out as live by default. - unsigned Live : 1; + unsigned live : 1; // Signals the chunk was discarded by COMDAT handling. - unsigned Discarded : 1; + unsigned discarded : 1; protected: - InputChunk(ObjFile *F, Kind K) - : File(F), Live(!Config->GcSections), Discarded(false), SectionKind(K) {} + InputChunk(ObjFile *f, Kind k) + : file(f), live(!config->gcSections), discarded(false), sectionKind(k) {} virtual ~InputChunk() = default; virtual ArrayRef data() const = 0; @@ -77,8 +77,8 @@ protected: // This is performed only debug builds as an extra sanity check. void verifyRelocTargets() const; - ArrayRef Relocations; - Kind SectionKind; + ArrayRef relocations; + Kind sectionKind; }; // Represents a WebAssembly data segment which can be included as part of @@ -91,65 +91,65 @@ protected: // each global variable. class InputSegment : public InputChunk { public: - InputSegment(const WasmSegment &Seg, ObjFile *F) - : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {} + InputSegment(const WasmSegment &seg, ObjFile *f) + : InputChunk(f, InputChunk::DataSegment), segment(seg) {} - static bool classof(const InputChunk *C) { return C->kind() == DataSegment; } + static bool classof(const InputChunk *c) { return c->kind() == DataSegment; } - void generateRelocationCode(raw_ostream &OS) const; + void generateRelocationCode(raw_ostream &os) const; - uint32_t getAlignment() const { return Segment.Data.Alignment; } - StringRef getName() const override { return Segment.Data.Name; } + uint32_t getAlignment() const { return segment.Data.Alignment; } + StringRef getName() const override { return segment.Data.Name; } StringRef getDebugName() const override { return StringRef(); } - uint32_t getComdat() const override { return Segment.Data.Comdat; } + uint32_t getComdat() const override { return segment.Data.Comdat; } uint32_t getInputSectionOffset() const override { - return Segment.SectionOffset; + return segment.SectionOffset; } - const OutputSegment *OutputSeg = nullptr; - int32_t OutputSegmentOffset = 0; + const OutputSegment *outputSeg = nullptr; + int32_t outputSegmentOffset = 0; protected: - ArrayRef data() const override { return Segment.Data.Content; } + ArrayRef data() const override { return segment.Data.Content; } - const WasmSegment &Segment; + const WasmSegment &segment; }; // Represents a single wasm function within and input file. These are // combined to create the final output CODE section. class InputFunction : public InputChunk { public: - InputFunction(const WasmSignature &S, const WasmFunction *Func, ObjFile *F) - : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} + InputFunction(const WasmSignature &s, const WasmFunction *func, ObjFile *f) + : InputChunk(f, InputChunk::Function), signature(s), function(func) {} - static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::Function || - C->kind() == InputChunk::SyntheticFunction; + static bool classof(const InputChunk *c) { + return c->kind() == InputChunk::Function || + c->kind() == InputChunk::SyntheticFunction; } - void writeTo(uint8_t *SectionStart) const override; - StringRef getName() const override { return Function->SymbolName; } - StringRef getDebugName() const override { return Function->DebugName; } - uint32_t getComdat() const override { return Function->Comdat; } + void writeTo(uint8_t *sectionStart) const override; + StringRef getName() const override { return function->SymbolName; } + StringRef getDebugName() const override { return function->DebugName; } + uint32_t getComdat() const override { return function->Comdat; } uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); } - uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; } + uint32_t getFunctionCodeOffset() const { return function->CodeOffset; } uint32_t getSize() const override { - if (Config->CompressRelocations && File) { - assert(CompressedSize); - return CompressedSize; + if (config->compressRelocations && file) { + assert(compressedSize); + return compressedSize; } return data().size(); } - uint32_t getInputSize() const override { return Function->Size; } - uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); } - bool hasFunctionIndex() const { return FunctionIndex.hasValue(); } - void setFunctionIndex(uint32_t Index); + uint32_t getInputSize() const override { return function->Size; } + uint32_t getFunctionIndex() const { return functionIndex.getValue(); } + bool hasFunctionIndex() const { return functionIndex.hasValue(); } + void setFunctionIndex(uint32_t index); uint32_t getInputSectionOffset() const override { - return Function->CodeSectionOffset; + return function->CodeSectionOffset; } - uint32_t getTableIndex() const { return TableIndex.getValue(); } - bool hasTableIndex() const { return TableIndex.hasValue(); } - void setTableIndex(uint32_t Index); + uint32_t getTableIndex() const { return tableIndex.getValue(); } + bool hasTableIndex() const { return tableIndex.hasValue(); } + void setTableIndex(uint32_t index); // The size of a given input function can depend on the values of the // LEB relocations within it. This finalizeContents method is called after @@ -157,76 +157,76 @@ public: // called. void calculateSize(); - const WasmSignature &Signature; + const WasmSignature &signature; protected: ArrayRef data() const override { - assert(!Config->CompressRelocations); - return File->CodeSection->Content.slice(getInputSectionOffset(), - Function->Size); + assert(!config->compressRelocations); + return file->codeSection->Content.slice(getInputSectionOffset(), + function->Size); } - const WasmFunction *Function; - llvm::Optional FunctionIndex; - llvm::Optional TableIndex; - uint32_t CompressedFuncSize = 0; - uint32_t CompressedSize = 0; + const WasmFunction *function; + llvm::Optional functionIndex; + llvm::Optional tableIndex; + uint32_t compressedFuncSize = 0; + uint32_t compressedSize = 0; }; class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, StringRef Name, - StringRef DebugName = {}) - : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) { - SectionKind = InputChunk::SyntheticFunction; + SyntheticFunction(const WasmSignature &s, StringRef name, + StringRef debugName = {}) + : InputFunction(s, nullptr, nullptr), name(name), debugName(debugName) { + sectionKind = InputChunk::SyntheticFunction; } - static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::SyntheticFunction; + static bool classof(const InputChunk *c) { + return c->kind() == InputChunk::SyntheticFunction; } - StringRef getName() const override { return Name; } - StringRef getDebugName() const override { return DebugName; } + StringRef getName() const override { return name; } + StringRef getDebugName() const override { return debugName; } uint32_t getComdat() const override { return UINT32_MAX; } - void setBody(ArrayRef Body_) { Body = Body_; } + void setBody(ArrayRef body_) { body = body_; } protected: - ArrayRef data() const override { return Body; } + ArrayRef data() const override { return body; } - StringRef Name; - StringRef DebugName; - ArrayRef Body; + StringRef name; + StringRef debugName; + ArrayRef body; }; // Represents a single Wasm Section within an input file. class InputSection : public InputChunk { public: - InputSection(const WasmSection &S, ObjFile *F) - : InputChunk(F, InputChunk::Section), Section(S) { - assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM); + InputSection(const WasmSection &s, ObjFile *f) + : InputChunk(f, InputChunk::Section), section(s) { + assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM); } - StringRef getName() const override { return Section.Name; } + StringRef getName() const override { return section.Name; } StringRef getDebugName() const override { return StringRef(); } uint32_t getComdat() const override { return UINT32_MAX; } - OutputSection *OutputSec = nullptr; + OutputSection *outputSec = nullptr; protected: - ArrayRef data() const override { return Section.Content; } + ArrayRef data() const override { return section.Content; } // Offset within the input section. This is only zero since this chunk // type represents an entire input section, not part of one. uint32_t getInputSectionOffset() const override { return 0; } - const WasmSection &Section; + const WasmSection §ion; }; } // namespace wasm std::string toString(const wasm::InputChunk *); -StringRef relocTypeToString(uint8_t RelocType); +StringRef relocTypeToString(uint8_t relocType); } // namespace lld diff --git a/lld/wasm/InputEvent.h b/lld/wasm/InputEvent.h index 52afc930..98cfdf7 100644 --- a/lld/wasm/InputEvent.h +++ b/lld/wasm/InputEvent.h @@ -28,33 +28,33 @@ namespace wasm { // form the final EVENTS section. class InputEvent { public: - InputEvent(const WasmSignature &S, const WasmEvent &E, ObjFile *F) - : File(F), Event(E), Signature(S), Live(!Config->GcSections) {} + InputEvent(const WasmSignature &s, const WasmEvent &e, ObjFile *f) + : file(f), event(e), signature(s), live(!config->gcSections) {} - StringRef getName() const { return Event.SymbolName; } - const WasmEventType &getType() const { return Event.Type; } + StringRef getName() const { return event.SymbolName; } + const WasmEventType &getType() const { return event.Type; } - uint32_t getEventIndex() const { return EventIndex.getValue(); } - bool hasEventIndex() const { return EventIndex.hasValue(); } - void setEventIndex(uint32_t Index) { + uint32_t getEventIndex() const { return eventIndex.getValue(); } + bool hasEventIndex() const { return eventIndex.hasValue(); } + void setEventIndex(uint32_t index) { assert(!hasEventIndex()); - EventIndex = Index; + eventIndex = index; } - ObjFile *File; - WasmEvent Event; - const WasmSignature &Signature; + ObjFile *file; + WasmEvent event; + const WasmSignature &signature; - bool Live = false; + bool live = false; protected: - llvm::Optional EventIndex; + llvm::Optional eventIndex; }; } // namespace wasm -inline std::string toString(const wasm::InputEvent *E) { - return (toString(E->File) + ":(" + E->getName() + ")").str(); +inline std::string toString(const wasm::InputEvent *e) { + return (toString(e->file) + ":(" + e->getName() + ")").str(); } } // namespace lld diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index b3e41a4..b5233cf 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -29,77 +29,77 @@ using namespace llvm; using namespace llvm::object; using namespace llvm::wasm; -std::unique_ptr lld::wasm::Tar; +std::unique_ptr lld::wasm::tar; -Optional lld::wasm::readFile(StringRef Path) { - log("Loading: " + Path); +Optional lld::wasm::readFile(StringRef path) { + log("Loading: " + path); - auto MBOrErr = MemoryBuffer::getFile(Path); - if (auto EC = MBOrErr.getError()) { - error("cannot open " + Path + ": " + EC.message()); + auto mbOrErr = MemoryBuffer::getFile(path); + if (auto ec = mbOrErr.getError()) { + error("cannot open " + path + ": " + ec.message()); return None; } - std::unique_ptr &MB = *MBOrErr; - MemoryBufferRef MBRef = MB->getMemBufferRef(); - make>(std::move(MB)); // take MB ownership + std::unique_ptr &mb = *mbOrErr; + MemoryBufferRef mbref = mb->getMemBufferRef(); + make>(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; } -InputFile *lld::wasm::createObjectFile(MemoryBufferRef MB, - StringRef ArchiveName) { - file_magic Magic = identify_magic(MB.getBuffer()); - if (Magic == file_magic::wasm_object) { - std::unique_ptr Bin = - CHECK(createBinary(MB), MB.getBufferIdentifier()); - auto *Obj = cast(Bin.get()); - if (Obj->isSharedObject()) - return make(MB); - return make(MB, ArchiveName); +InputFile *lld::wasm::createObjectFile(MemoryBufferRef mb, + StringRef archiveName) { + file_magic magic = identify_magic(mb.getBuffer()); + if (magic == file_magic::wasm_object) { + std::unique_ptr bin = + CHECK(createBinary(mb), mb.getBufferIdentifier()); + auto *obj = cast(bin.get()); + if (obj->isSharedObject()) + return make(mb); + return make(mb, archiveName); } - if (Magic == file_magic::bitcode) - return make(MB, ArchiveName); + if (magic == file_magic::bitcode) + return make(mb, archiveName); - fatal("unknown file type: " + MB.getBufferIdentifier()); + fatal("unknown file type: " + mb.getBufferIdentifier()); } void ObjFile::dumpInfo() const { log("info for: " + toString(this) + - "\n Symbols : " + Twine(Symbols.size()) + - "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) + - "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()) + - "\n Event Imports : " + Twine(WasmObj->getNumImportedEvents())); + "\n Symbols : " + Twine(symbols.size()) + + "\n Function Imports : " + Twine(wasmObj->getNumImportedFunctions()) + + "\n Global Imports : " + Twine(wasmObj->getNumImportedGlobals()) + + "\n Event Imports : " + Twine(wasmObj->getNumImportedEvents())); } // Relocations contain either symbol or type indices. This function takes a // relocation and returns relocated index (i.e. translates from the input // symbol/type space to the output symbol/type space). -uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { - assert(TypeIsUsed[Reloc.Index]); - return TypeMap[Reloc.Index]; +uint32_t ObjFile::calcNewIndex(const WasmRelocation &reloc) const { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) { + assert(typeIsUsed[reloc.Index]); + return typeMap[reloc.Index]; } - const Symbol *Sym = Symbols[Reloc.Index]; - if (auto *SS = dyn_cast(Sym)) - Sym = SS->getOutputSectionSymbol(); - return Sym->getOutputSymbolIndex(); + const Symbol *sym = symbols[reloc.Index]; + if (auto *ss = dyn_cast(sym)) + sym = ss->getOutputSectionSymbol(); + return sym->getOutputSymbolIndex(); } // Relocations can contain addend for combined sections. This function takes a // relocation and returns updated addend by offset in the output section. -uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const { - switch (Reloc.Type) { +uint32_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const { + switch (reloc.Type) { case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: - return Reloc.Addend; + return reloc.Addend; case R_WASM_SECTION_OFFSET_I32: - return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; + return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend; default: llvm_unreachable("unexpected relocation type"); } @@ -108,42 +108,42 @@ uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const { // Calculate the value we expect to find at the relocation location. // This is used as a sanity check before applying a relocation to a given // location. It is useful for catching bugs in the compiler and linker. -uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { - switch (Reloc.Type) { +uint32_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - return TableEntries[Sym.Info.ElementIndex]; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + return tableEntries[sym.Info.ElementIndex]; } case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_REL_SLEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - if (Sym.isUndefined()) + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + if (sym.isUndefined()) return 0; - const WasmSegment &Segment = - WasmObj->dataSegments()[Sym.Info.DataRef.Segment]; - return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset + - Reloc.Addend; + const WasmSegment &segment = + wasmObj->dataSegments()[sym.Info.DataRef.Segment]; + return segment.Data.Offset.Value.Int32 + sym.Info.DataRef.Offset + + reloc.Addend; } case R_WASM_FUNCTION_OFFSET_I32: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - InputFunction *F = - Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()]; - return F->getFunctionInputOffset() + F->getFunctionCodeOffset() + - Reloc.Addend; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + InputFunction *f = + functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()]; + return f->getFunctionInputOffset() + f->getFunctionCodeOffset() + + reloc.Addend; } case R_WASM_SECTION_OFFSET_I32: - return Reloc.Addend; + return reloc.Addend; case R_WASM_TYPE_INDEX_LEB: - return Reloc.Index; + return reloc.Index; case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - return Sym.Info.ElementIndex; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + return sym.Info.ElementIndex; } default: llvm_unreachable("unknown relocation type"); @@ -151,115 +151,115 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { } // Translate from the relocation's index into the final linked output value. -uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const { - const Symbol* Sym = nullptr; - if (Reloc.Type != R_WASM_TYPE_INDEX_LEB) { - Sym = Symbols[Reloc.Index]; +uint32_t ObjFile::calcNewValue(const WasmRelocation &reloc) const { + const Symbol* sym = nullptr; + if (reloc.Type != R_WASM_TYPE_INDEX_LEB) { + sym = symbols[reloc.Index]; // We can end up with relocations against non-live symbols. For example // in debug sections. - if ((isa(Sym) || isa(Sym)) && !Sym->isLive()) + if ((isa(sym) || isa(sym)) && !sym->isLive()) return 0; } - switch (Reloc.Type) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: - if (Config->Pic && !getFunctionSymbol(Reloc.Index)->hasTableIndex()) + if (config->isPic && !getFunctionSymbol(reloc.Index)->hasTableIndex()) return 0; - return getFunctionSymbol(Reloc.Index)->getTableIndex(); + return getFunctionSymbol(reloc.Index)->getTableIndex(); case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - if (isa(Sym)) + if (isa(sym)) return 0; - return cast(Sym)->getVirtualAddress() + Reloc.Addend; + return cast(sym)->getVirtualAddress() + reloc.Addend; case R_WASM_TYPE_INDEX_LEB: - return TypeMap[Reloc.Index]; + return typeMap[reloc.Index]; case R_WASM_FUNCTION_INDEX_LEB: - return getFunctionSymbol(Reloc.Index)->getFunctionIndex(); + return getFunctionSymbol(reloc.Index)->getFunctionIndex(); case R_WASM_GLOBAL_INDEX_LEB: - if (auto GS = dyn_cast(Sym)) - return GS->getGlobalIndex(); - return Sym->getGOTIndex(); + if (auto gs = dyn_cast(sym)) + return gs->getGlobalIndex(); + return sym->getGOTIndex(); case R_WASM_EVENT_INDEX_LEB: - return getEventSymbol(Reloc.Index)->getEventIndex(); + return getEventSymbol(reloc.Index)->getEventIndex(); case R_WASM_FUNCTION_OFFSET_I32: { - auto *F = cast(Sym); - return F->Function->OutputOffset + F->Function->getFunctionCodeOffset() + - Reloc.Addend; + auto *f = cast(sym); + return f->function->outputOffset + f->function->getFunctionCodeOffset() + + reloc.Addend; } case R_WASM_SECTION_OFFSET_I32: - return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; + return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend; default: llvm_unreachable("unknown relocation type"); } } template -static void setRelocs(const std::vector &Chunks, - const WasmSection *Section) { - if (!Section) +static void setRelocs(const std::vector &chunks, + const WasmSection *section) { + if (!section) return; - ArrayRef Relocs = Section->Relocations; - assert(std::is_sorted(Relocs.begin(), Relocs.end(), - [](const WasmRelocation &R1, const WasmRelocation &R2) { - return R1.Offset < R2.Offset; + ArrayRef relocs = section->Relocations; + assert(std::is_sorted(relocs.begin(), relocs.end(), + [](const WasmRelocation &r1, const WasmRelocation &r2) { + return r1.Offset < r2.Offset; })); assert(std::is_sorted( - Chunks.begin(), Chunks.end(), [](InputChunk *C1, InputChunk *C2) { - return C1->getInputSectionOffset() < C2->getInputSectionOffset(); + chunks.begin(), chunks.end(), [](InputChunk *c1, InputChunk *c2) { + return c1->getInputSectionOffset() < c2->getInputSectionOffset(); })); - auto RelocsNext = Relocs.begin(); - auto RelocsEnd = Relocs.end(); - auto RelocLess = [](const WasmRelocation &R, uint32_t Val) { - return R.Offset < Val; + auto relocsNext = relocs.begin(); + auto relocsEnd = relocs.end(); + auto relocLess = [](const WasmRelocation &r, uint32_t val) { + return r.Offset < val; }; - for (InputChunk *C : Chunks) { - auto RelocsStart = std::lower_bound(RelocsNext, RelocsEnd, - C->getInputSectionOffset(), RelocLess); - RelocsNext = std::lower_bound( - RelocsStart, RelocsEnd, C->getInputSectionOffset() + C->getInputSize(), - RelocLess); - C->setRelocations(ArrayRef(RelocsStart, RelocsNext)); + for (InputChunk *c : chunks) { + auto relocsStart = std::lower_bound(relocsNext, relocsEnd, + c->getInputSectionOffset(), relocLess); + relocsNext = std::lower_bound( + relocsStart, relocsEnd, c->getInputSectionOffset() + c->getInputSize(), + relocLess); + c->setRelocations(ArrayRef(relocsStart, relocsNext)); } } -void ObjFile::parse(bool IgnoreComdats) { +void ObjFile::parse(bool ignoreComdats) { // Parse a memory buffer as a wasm file. LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); - std::unique_ptr Bin = CHECK(createBinary(MB), toString(this)); + std::unique_ptr bin = CHECK(createBinary(mb), toString(this)); - auto *Obj = dyn_cast(Bin.get()); - if (!Obj) + auto *obj = dyn_cast(bin.get()); + if (!obj) fatal(toString(this) + ": not a wasm file"); - if (!Obj->isRelocatableObject()) + if (!obj->isRelocatableObject()) fatal(toString(this) + ": not a relocatable wasm file"); - Bin.release(); - WasmObj.reset(Obj); + bin.release(); + wasmObj.reset(obj); // Build up a map of function indices to table indices for use when // verifying the existing table index relocations - uint32_t TotalFunctions = - WasmObj->getNumImportedFunctions() + WasmObj->functions().size(); - TableEntries.resize(TotalFunctions); - for (const WasmElemSegment &Seg : WasmObj->elements()) { - if (Seg.Offset.Opcode != WASM_OPCODE_I32_CONST) + uint32_t totalFunctions = + wasmObj->getNumImportedFunctions() + wasmObj->functions().size(); + tableEntries.resize(totalFunctions); + for (const WasmElemSegment &seg : wasmObj->elements()) { + if (seg.Offset.Opcode != WASM_OPCODE_I32_CONST) fatal(toString(this) + ": invalid table elements"); - uint32_t Offset = Seg.Offset.Value.Int32; - for (uint32_t Index = 0; Index < Seg.Functions.size(); Index++) { + uint32_t offset = seg.Offset.Value.Int32; + for (uint32_t index = 0; index < seg.Functions.size(); index++) { - uint32_t FunctionIndex = Seg.Functions[Index]; - TableEntries[FunctionIndex] = Offset + Index; + uint32_t functionIndex = seg.Functions[index]; + tableEntries[functionIndex] = offset + index; } } - uint32_t SectionIndex = 0; + uint32_t sectionIndex = 0; // Bool for each symbol, true if called directly. This allows us to implement // a weaker form of signature checking where undefined functions that are not @@ -267,185 +267,185 @@ void ObjFile::parse(bool IgnoreComdats) { // function's signature. We cannot do this for directly called functions // because those signatures are checked at validation times. // See https://bugs.llvm.org/show_bug.cgi?id=40412 - std::vector IsCalledDirectly(WasmObj->getNumberOfSymbols(), false); - for (const SectionRef &Sec : WasmObj->sections()) { - const WasmSection &Section = WasmObj->getWasmSection(Sec); + std::vector isCalledDirectly(wasmObj->getNumberOfSymbols(), false); + for (const SectionRef &sec : wasmObj->sections()) { + const WasmSection §ion = wasmObj->getWasmSection(sec); // Wasm objects can have at most one code and one data section. - if (Section.Type == WASM_SEC_CODE) { - assert(!CodeSection); - CodeSection = &Section; - } else if (Section.Type == WASM_SEC_DATA) { - assert(!DataSection); - DataSection = &Section; - } else if (Section.Type == WASM_SEC_CUSTOM) { - CustomSections.emplace_back(make(Section, this)); - CustomSections.back()->setRelocations(Section.Relocations); - CustomSectionsByIndex[SectionIndex] = CustomSections.back(); + if (section.Type == WASM_SEC_CODE) { + assert(!codeSection); + codeSection = §ion; + } else if (section.Type == WASM_SEC_DATA) { + assert(!dataSection); + dataSection = §ion; + } else if (section.Type == WASM_SEC_CUSTOM) { + customSections.emplace_back(make(section, this)); + customSections.back()->setRelocations(section.Relocations); + customSectionsByIndex[sectionIndex] = customSections.back(); } - SectionIndex++; + sectionIndex++; // Scans relocations to dermine determine if a function symbol is called // directly - for (const WasmRelocation &Reloc : Section.Relocations) - if (Reloc.Type == R_WASM_FUNCTION_INDEX_LEB) - IsCalledDirectly[Reloc.Index] = true; + for (const WasmRelocation &reloc : section.Relocations) + if (reloc.Type == R_WASM_FUNCTION_INDEX_LEB) + isCalledDirectly[reloc.Index] = true; } - TypeMap.resize(getWasmObj()->types().size()); - TypeIsUsed.resize(getWasmObj()->types().size(), false); + typeMap.resize(getWasmObj()->types().size()); + typeIsUsed.resize(getWasmObj()->types().size(), false); - ArrayRef Comdats = WasmObj->linkingData().Comdats; - for (StringRef Comdat : Comdats) { - bool IsNew = IgnoreComdats || Symtab->addComdat(Comdat); - KeptComdats.push_back(IsNew); + ArrayRef comdats = wasmObj->linkingData().Comdats; + for (StringRef comdat : comdats) { + bool isNew = ignoreComdats || symtab->addComdat(comdat); + keptComdats.push_back(isNew); } // Populate `Segments`. - for (const WasmSegment &S : WasmObj->dataSegments()) { - auto* Seg = make(S, this); - Seg->Discarded = isExcludedByComdat(Seg); - Segments.emplace_back(Seg); + for (const WasmSegment &s : wasmObj->dataSegments()) { + auto* seg = make(s, this); + seg->discarded = isExcludedByComdat(seg); + segments.emplace_back(seg); } - setRelocs(Segments, DataSection); + setRelocs(segments, dataSection); // Populate `Functions`. - ArrayRef Funcs = WasmObj->functions(); - ArrayRef FuncTypes = WasmObj->functionTypes(); - ArrayRef Types = WasmObj->types(); - Functions.reserve(Funcs.size()); - - for (size_t I = 0, E = Funcs.size(); I != E; ++I) { - auto* Func = make(Types[FuncTypes[I]], &Funcs[I], this); - Func->Discarded = isExcludedByComdat(Func); - Functions.emplace_back(Func); + ArrayRef funcs = wasmObj->functions(); + ArrayRef funcTypes = wasmObj->functionTypes(); + ArrayRef types = wasmObj->types(); + functions.reserve(funcs.size()); + + for (size_t i = 0, e = funcs.size(); i != e; ++i) { + auto* func = make(types[funcTypes[i]], &funcs[i], this); + func->discarded = isExcludedByComdat(func); + functions.emplace_back(func); } - setRelocs(Functions, CodeSection); + setRelocs(functions, codeSection); // Populate `Globals`. - for (const WasmGlobal &G : WasmObj->globals()) - Globals.emplace_back(make(G, this)); + for (const WasmGlobal &g : wasmObj->globals()) + globals.emplace_back(make(g, this)); // Populate `Events`. - for (const WasmEvent &E : WasmObj->events()) - Events.emplace_back(make(Types[E.Type.SigIndex], E, this)); + for (const WasmEvent &e : wasmObj->events()) + events.emplace_back(make(types[e.Type.SigIndex], e, this)); // Populate `Symbols` based on the WasmSymbols in the object. - Symbols.reserve(WasmObj->getNumberOfSymbols()); - for (const SymbolRef &Sym : WasmObj->symbols()) { - const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl()); - if (WasmSym.isDefined()) { + symbols.reserve(wasmObj->getNumberOfSymbols()); + for (const SymbolRef &sym : wasmObj->symbols()) { + const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl()); + if (wasmSym.isDefined()) { // createDefined may fail if the symbol is comdat excluded in which case // we fall back to creating an undefined symbol - if (Symbol *D = createDefined(WasmSym)) { - Symbols.push_back(D); + if (Symbol *d = createDefined(wasmSym)) { + symbols.push_back(d); continue; } } - size_t Idx = Symbols.size(); - Symbols.push_back(createUndefined(WasmSym, IsCalledDirectly[Idx])); + size_t idx = symbols.size(); + symbols.push_back(createUndefined(wasmSym, isCalledDirectly[idx])); } } -bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const { - uint32_t C = Chunk->getComdat(); - if (C == UINT32_MAX) +bool ObjFile::isExcludedByComdat(InputChunk *chunk) const { + uint32_t c = chunk->getComdat(); + if (c == UINT32_MAX) return false; - return !KeptComdats[C]; + return !keptComdats[c]; } -FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const { - return cast(Symbols[Index]); +FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t index) const { + return cast(symbols[index]); } -GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const { - return cast(Symbols[Index]); +GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t index) const { + return cast(symbols[index]); } -EventSymbol *ObjFile::getEventSymbol(uint32_t Index) const { - return cast(Symbols[Index]); +EventSymbol *ObjFile::getEventSymbol(uint32_t index) const { + return cast(symbols[index]); } -SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const { - return cast(Symbols[Index]); +SectionSymbol *ObjFile::getSectionSymbol(uint32_t index) const { + return cast(symbols[index]); } -DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const { - return cast(Symbols[Index]); +DataSymbol *ObjFile::getDataSymbol(uint32_t index) const { + return cast(symbols[index]); } -Symbol *ObjFile::createDefined(const WasmSymbol &Sym) { - StringRef Name = Sym.Info.Name; - uint32_t Flags = Sym.Info.Flags; +Symbol *ObjFile::createDefined(const WasmSymbol &sym) { + StringRef name = sym.Info.Name; + uint32_t flags = sym.Info.Flags; - switch (Sym.Info.Kind) { + switch (sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: { - InputFunction *Func = - Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()]; - if (Func->Discarded) + InputFunction *func = + functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()]; + if (func->discarded) return nullptr; - if (Sym.isBindingLocal()) - return make(Name, Flags, this, Func); - return Symtab->addDefinedFunction(Name, Flags, this, Func); + if (sym.isBindingLocal()) + return make(name, flags, this, func); + return symtab->addDefinedFunction(name, flags, this, func); } case WASM_SYMBOL_TYPE_DATA: { - InputSegment *Seg = Segments[Sym.Info.DataRef.Segment]; - if (Seg->Discarded) + InputSegment *seg = segments[sym.Info.DataRef.Segment]; + if (seg->discarded) return nullptr; - uint32_t Offset = Sym.Info.DataRef.Offset; - uint32_t Size = Sym.Info.DataRef.Size; + uint32_t offset = sym.Info.DataRef.Offset; + uint32_t size = sym.Info.DataRef.Size; - if (Sym.isBindingLocal()) - return make(Name, Flags, this, Seg, Offset, Size); - return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size); + if (sym.isBindingLocal()) + return make(name, flags, this, seg, offset, size); + return symtab->addDefinedData(name, flags, this, seg, offset, size); } case WASM_SYMBOL_TYPE_GLOBAL: { - InputGlobal *Global = - Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()]; - if (Sym.isBindingLocal()) - return make(Name, Flags, this, Global); - return Symtab->addDefinedGlobal(Name, Flags, this, Global); + InputGlobal *global = + globals[sym.Info.ElementIndex - wasmObj->getNumImportedGlobals()]; + if (sym.isBindingLocal()) + return make(name, flags, this, global); + return symtab->addDefinedGlobal(name, flags, this, global); } case WASM_SYMBOL_TYPE_SECTION: { - InputSection *Section = CustomSectionsByIndex[Sym.Info.ElementIndex]; - assert(Sym.isBindingLocal()); - return make(Flags, Section, this); + InputSection *section = customSectionsByIndex[sym.Info.ElementIndex]; + assert(sym.isBindingLocal()); + return make(flags, section, this); } case WASM_SYMBOL_TYPE_EVENT: { - InputEvent *Event = - Events[Sym.Info.ElementIndex - WasmObj->getNumImportedEvents()]; - if (Sym.isBindingLocal()) - return make(Name, Flags, this, Event); - return Symtab->addDefinedEvent(Name, Flags, this, Event); + InputEvent *event = + events[sym.Info.ElementIndex - wasmObj->getNumImportedEvents()]; + if (sym.isBindingLocal()) + return make(name, flags, this, event); + return symtab->addDefinedEvent(name, flags, this, event); } } llvm_unreachable("unknown symbol kind"); } -Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly) { - StringRef Name = Sym.Info.Name; - uint32_t Flags = Sym.Info.Flags; +Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) { + StringRef name = sym.Info.Name; + uint32_t flags = sym.Info.Flags; - switch (Sym.Info.Kind) { + switch (sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - if (Sym.isBindingLocal()) - return make(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.Signature, IsCalledDirectly); - return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.Signature, IsCalledDirectly); + if (sym.isBindingLocal()) + return make(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.Signature, isCalledDirectly); + return symtab->addUndefinedFunction(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.Signature, isCalledDirectly); case WASM_SYMBOL_TYPE_DATA: - if (Sym.isBindingLocal()) - return make(Name, Flags, this); - return Symtab->addUndefinedData(Name, Flags, this); + if (sym.isBindingLocal()) + return make(name, flags, this); + return symtab->addUndefinedData(name, flags, this); case WASM_SYMBOL_TYPE_GLOBAL: - if (Sym.isBindingLocal()) - return make(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.GlobalType); - return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.GlobalType); + if (sym.isBindingLocal()) + return make(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.GlobalType); + return symtab->addUndefinedGlobal(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.GlobalType); case WASM_SYMBOL_TYPE_SECTION: llvm_unreachable("section symbols cannot be undefined"); } @@ -455,41 +455,41 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly) { void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); - File = CHECK(Archive::create(MB), toString(this)); + file = CHECK(Archive::create(mb), toString(this)); // Read the symbol table to construct Lazy symbols. - int Count = 0; - for (const Archive::Symbol &Sym : File->symbols()) { - Symtab->addLazy(this, &Sym); - ++Count; + int count = 0; + for (const Archive::Symbol &sym : file->symbols()) { + symtab->addLazy(this, &sym); + ++count; } - LLVM_DEBUG(dbgs() << "Read " << Count << " symbols\n"); + LLVM_DEBUG(dbgs() << "Read " << count << " symbols\n"); } -void ArchiveFile::addMember(const Archive::Symbol *Sym) { - const Archive::Child &C = - CHECK(Sym->getMember(), - "could not get the member for symbol " + Sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol *sym) { + const Archive::Child &c = + CHECK(sym->getMember(), + "could not get the member for symbol " + sym->getName()); // Don't try to load the same member twice (this can happen when members // mutually reference each other). - if (!Seen.insert(C.getChildOffset()).second) + if (!seen.insert(c.getChildOffset()).second) return; - LLVM_DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n"); + LLVM_DEBUG(dbgs() << "loading lazy: " << sym->getName() << "\n"); LLVM_DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); - MemoryBufferRef MB = - CHECK(C.getMemoryBufferRef(), + MemoryBufferRef mb = + CHECK(c.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + - Sym->getName()); + sym->getName()); - InputFile *Obj = createObjectFile(MB, getName()); - Symtab->addFile(Obj); + InputFile *obj = createObjectFile(mb, getName()); + symtab->addFile(obj); } -static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { - switch (GvVisibility) { +static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) { + switch (gvVisibility) { case GlobalValue::DefaultVisibility: return WASM_SYMBOL_VISIBILITY_DEFAULT; case GlobalValue::HiddenVisibility: @@ -499,52 +499,52 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { llvm_unreachable("unknown visibility"); } -static Symbol *createBitcodeSymbol(const std::vector &KeptComdats, - const lto::InputFile::Symbol &ObjSym, - BitcodeFile &F) { - StringRef Name = Saver.save(ObjSym.getName()); +static Symbol *createBitcodeSymbol(const std::vector &keptComdats, + const lto::InputFile::Symbol &objSym, + BitcodeFile &f) { + StringRef name = saver.save(objSym.getName()); - uint32_t Flags = ObjSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0; - Flags |= mapVisibility(ObjSym.getVisibility()); + uint32_t flags = objSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0; + flags |= mapVisibility(objSym.getVisibility()); - int C = ObjSym.getComdatIndex(); - bool ExcludedByComdat = C != -1 && !KeptComdats[C]; + int c = objSym.getComdatIndex(); + bool excludedByComdat = c != -1 && !keptComdats[c]; - if (ObjSym.isUndefined() || ExcludedByComdat) { - if (ObjSym.isExecutable()) - return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F, + if (objSym.isUndefined() || excludedByComdat) { + if (objSym.isExecutable()) + return symtab->addUndefinedFunction(name, name, defaultModule, flags, &f, nullptr, true); - return Symtab->addUndefinedData(Name, Flags, &F); + return symtab->addUndefinedData(name, flags, &f); } - if (ObjSym.isExecutable()) - return Symtab->addDefinedFunction(Name, Flags, &F, nullptr); - return Symtab->addDefinedData(Name, Flags, &F, nullptr, 0, 0); + if (objSym.isExecutable()) + return symtab->addDefinedFunction(name, flags, &f, nullptr); + return symtab->addDefinedData(name, flags, &f, nullptr, 0, 0); } void BitcodeFile::parse() { - Obj = check(lto::InputFile::create(MemoryBufferRef( - MB.getBuffer(), Saver.save(ArchiveName + MB.getBufferIdentifier())))); - Triple T(Obj->getTargetTriple()); - if (T.getArch() != Triple::wasm32) { - error(toString(MB.getBufferIdentifier()) + ": machine type must be wasm32"); + obj = check(lto::InputFile::create(MemoryBufferRef( + mb.getBuffer(), saver.save(archiveName + mb.getBufferIdentifier())))); + Triple t(obj->getTargetTriple()); + if (t.getArch() != Triple::wasm32) { + error(toString(mb.getBufferIdentifier()) + ": machine type must be wasm32"); return; } - std::vector KeptComdats; - for (StringRef S : Obj->getComdatTable()) - KeptComdats.push_back(Symtab->addComdat(S)); + std::vector keptComdats; + for (StringRef s : obj->getComdatTable()) + keptComdats.push_back(symtab->addComdat(s)); - for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) - Symbols.push_back(createBitcodeSymbol(KeptComdats, ObjSym, *this)); + for (const lto::InputFile::Symbol &objSym : obj->symbols()) + symbols.push_back(createBitcodeSymbol(keptComdats, objSym, *this)); } // Returns a string in the format of "foo.o" or "foo.a(bar.o)". -std::string lld::toString(const wasm::InputFile *File) { - if (!File) +std::string lld::toString(const wasm::InputFile *file) { + if (!file) return ""; - if (File->ArchiveName.empty()) - return File->getName(); + if (file->archiveName.empty()) + return file->getName(); - return (File->ArchiveName + "(" + File->getName() + ")").str(); + return (file->archiveName + "(" + file->getName() + ")").str(); } diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h index 57d36a8..2b25906 100644 --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -35,7 +35,7 @@ class InputSection; // If --reproduce option is given, all input files are written // to this tar archive. -extern std::unique_ptr Tar; +extern std::unique_ptr tar; class InputFile { public: @@ -49,129 +49,129 @@ public: virtual ~InputFile() {} // Returns the filename. - StringRef getName() const { return MB.getBufferIdentifier(); } + StringRef getName() const { return mb.getBufferIdentifier(); } - Kind kind() const { return FileKind; } + Kind kind() const { return fileKind; } // An archive file name if this file is created from an archive. - StringRef ArchiveName; + StringRef archiveName; - ArrayRef getSymbols() const { return Symbols; } + ArrayRef getSymbols() const { return symbols; } - MutableArrayRef getMutableSymbols() { return Symbols; } + MutableArrayRef getMutableSymbols() { return symbols; } protected: - InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} - MemoryBufferRef MB; + InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {} + MemoryBufferRef mb; // List of all symbols referenced or defined by this file. - std::vector Symbols; + std::vector symbols; private: - const Kind FileKind; + const Kind fileKind; }; // .a file (ar archive) class ArchiveFile : public InputFile { public: - explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } + explicit ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {} + static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; } - void addMember(const llvm::object::Archive::Symbol *Sym); + void addMember(const llvm::object::Archive::Symbol *sym); void parse(); private: - std::unique_ptr File; - llvm::DenseSet Seen; + std::unique_ptr file; + llvm::DenseSet seen; }; // .o file (wasm object file) class ObjFile : public InputFile { public: - explicit ObjFile(MemoryBufferRef M, StringRef ArchiveName) - : InputFile(ObjectKind, M) { - this->ArchiveName = ArchiveName; + explicit ObjFile(MemoryBufferRef m, StringRef archiveName) + : InputFile(ObjectKind, m) { + this->archiveName = archiveName; } - static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } + static bool classof(const InputFile *f) { return f->kind() == ObjectKind; } - void parse(bool IgnoreComdats = false); + void parse(bool ignoreComdats = false); // Returns the underlying wasm file. - const WasmObjectFile *getWasmObj() const { return WasmObj.get(); } + const WasmObjectFile *getWasmObj() const { return wasmObj.get(); } void dumpInfo() const; - uint32_t calcNewIndex(const WasmRelocation &Reloc) const; - uint32_t calcNewValue(const WasmRelocation &Reloc) const; - uint32_t calcNewAddend(const WasmRelocation &Reloc) const; - uint32_t calcExpectedValue(const WasmRelocation &Reloc) const; - Symbol *getSymbol(const WasmRelocation &Reloc) const { - return Symbols[Reloc.Index]; + uint32_t calcNewIndex(const WasmRelocation &reloc) const; + uint32_t calcNewValue(const WasmRelocation &reloc) const; + uint32_t calcNewAddend(const WasmRelocation &reloc) const; + uint32_t calcExpectedValue(const WasmRelocation &reloc) const; + Symbol *getSymbol(const WasmRelocation &reloc) const { + return symbols[reloc.Index]; }; - const WasmSection *CodeSection = nullptr; - const WasmSection *DataSection = nullptr; + const WasmSection *codeSection = nullptr; + const WasmSection *dataSection = nullptr; // Maps input type indices to output type indices - std::vector TypeMap; - std::vector TypeIsUsed; + std::vector typeMap; + std::vector typeIsUsed; // Maps function indices to table indices - std::vector TableEntries; - std::vector KeptComdats; - std::vector Segments; - std::vector Functions; - std::vector Globals; - std::vector Events; - std::vector CustomSections; - llvm::DenseMap CustomSectionsByIndex; - - Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; } - FunctionSymbol *getFunctionSymbol(uint32_t Index) const; - DataSymbol *getDataSymbol(uint32_t Index) const; - GlobalSymbol *getGlobalSymbol(uint32_t Index) const; - SectionSymbol *getSectionSymbol(uint32_t Index) const; - EventSymbol *getEventSymbol(uint32_t Index) const; + std::vector tableEntries; + std::vector keptComdats; + std::vector segments; + std::vector functions; + std::vector globals; + std::vector events; + std::vector customSections; + llvm::DenseMap customSectionsByIndex; + + Symbol *getSymbol(uint32_t index) const { return symbols[index]; } + FunctionSymbol *getFunctionSymbol(uint32_t index) const; + DataSymbol *getDataSymbol(uint32_t index) const; + GlobalSymbol *getGlobalSymbol(uint32_t index) const; + SectionSymbol *getSectionSymbol(uint32_t index) const; + EventSymbol *getEventSymbol(uint32_t index) const; private: - Symbol *createDefined(const WasmSymbol &Sym); - Symbol *createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly); + Symbol *createDefined(const WasmSymbol &sym); + Symbol *createUndefined(const WasmSymbol &sym, bool isCalledDirectly); - bool isExcludedByComdat(InputChunk *Chunk) const; + bool isExcludedByComdat(InputChunk *chunk) const; - std::unique_ptr WasmObj; + std::unique_ptr wasmObj; }; // .so file. class SharedFile : public InputFile { public: - explicit SharedFile(MemoryBufferRef M) : InputFile(SharedKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == SharedKind; } + explicit SharedFile(MemoryBufferRef m) : InputFile(SharedKind, m) {} + static bool classof(const InputFile *f) { return f->kind() == SharedKind; } }; // .bc file class BitcodeFile : public InputFile { public: - explicit BitcodeFile(MemoryBufferRef M, StringRef ArchiveName) - : InputFile(BitcodeKind, M) { - this->ArchiveName = ArchiveName; + explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName) + : InputFile(BitcodeKind, m) { + this->archiveName = archiveName; } - static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } + static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } void parse(); - std::unique_ptr Obj; + std::unique_ptr obj; }; // Will report a fatal() error if the input buffer is not a valid bitcode // or wasm object file. -InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = ""); +InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = ""); // Opens a given file. -llvm::Optional readFile(StringRef Path); +llvm::Optional readFile(StringRef path); } // namespace wasm -std::string toString(const wasm::InputFile *File); +std::string toString(const wasm::InputFile *file); } // namespace lld diff --git a/lld/wasm/InputGlobal.h b/lld/wasm/InputGlobal.h index e008d2ec..89cde84 100644 --- a/lld/wasm/InputGlobal.h +++ b/lld/wasm/InputGlobal.h @@ -22,32 +22,32 @@ namespace wasm { // combined to form the final GLOBALS section. class InputGlobal { public: - InputGlobal(const WasmGlobal &G, ObjFile *F) - : File(F), Global(G), Live(!Config->GcSections) {} + InputGlobal(const WasmGlobal &g, ObjFile *f) + : file(f), global(g), live(!config->gcSections) {} - StringRef getName() const { return Global.SymbolName; } - const WasmGlobalType &getType() const { return Global.Type; } + StringRef getName() const { return global.SymbolName; } + const WasmGlobalType &getType() const { return global.Type; } - uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); } - bool hasGlobalIndex() const { return GlobalIndex.hasValue(); } - void setGlobalIndex(uint32_t Index) { + uint32_t getGlobalIndex() const { return globalIndex.getValue(); } + bool hasGlobalIndex() const { return globalIndex.hasValue(); } + void setGlobalIndex(uint32_t index) { assert(!hasGlobalIndex()); - GlobalIndex = Index; + globalIndex = index; } - ObjFile *File; - WasmGlobal Global; + ObjFile *file; + WasmGlobal global; - bool Live = false; + bool live = false; protected: - llvm::Optional GlobalIndex; + llvm::Optional globalIndex; }; } // namespace wasm -inline std::string toString(const wasm::InputGlobal *G) { - return (toString(G->File) + ":(" + G->getName() + ")").str(); +inline std::string toString(const wasm::InputGlobal *g) { + return (toString(g->file) + ":(" + g->getName() + ")").str(); } } // namespace lld diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 0c42e0e..fa48f4d 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -40,127 +40,127 @@ using namespace lld; using namespace lld::wasm; static std::unique_ptr createLTO() { - lto::Config C; - C.Options = initTargetOptionsFromCodeGenFlags(); + lto::Config c; + c.Options = initTargetOptionsFromCodeGenFlags(); // Always emit a section per function/data with LTO. - C.Options.FunctionSections = true; - C.Options.DataSections = true; - - C.DisableVerify = Config->DisableVerify; - C.DiagHandler = diagnosticHandler; - C.OptLevel = Config->LTOO; - C.MAttrs = getMAttrs(); - C.CGOptLevel = args::getCGOptLevel(Config->LTOO); - - if (Config->Relocatable) - C.RelocModel = None; - else if (Config->Pic) - C.RelocModel = Reloc::PIC_; + c.Options.FunctionSections = true; + c.Options.DataSections = true; + + c.DisableVerify = config->disableVerify; + c.DiagHandler = diagnosticHandler; + c.OptLevel = config->ltoo; + c.MAttrs = getMAttrs(); + c.CGOptLevel = args::getCGOptLevel(config->ltoo); + + if (config->relocatable) + c.RelocModel = None; + else if (config->isPic) + c.RelocModel = Reloc::PIC_; else - C.RelocModel = Reloc::Static; + c.RelocModel = Reloc::Static; - if (Config->SaveTemps) - checkError(C.addSaveTemps(Config->OutputFile.str() + ".", + if (config->saveTemps) + checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath*/ true)); - lto::ThinBackend Backend; - if (Config->ThinLTOJobs != -1U) - Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); - return llvm::make_unique(std::move(C), Backend, - Config->LTOPartitions); + lto::ThinBackend backend; + if (config->thinLTOJobs != -1U) + backend = lto::createInProcessThinBackend(config->thinLTOJobs); + return llvm::make_unique(std::move(c), backend, + config->ltoPartitions); } -BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} +BitcodeCompiler::BitcodeCompiler() : ltoObj(createLTO()) {} BitcodeCompiler::~BitcodeCompiler() = default; -static void undefine(Symbol *S) { - if (auto F = dyn_cast(S)) - replaceSymbol(F, F->getName(), F->getName(), - DefaultModule, 0, - F->getFile(), F->Signature); - else if (isa(S)) - replaceSymbol(S, S->getName(), 0, S->getFile()); +static void undefine(Symbol *s) { + if (auto f = dyn_cast(s)) + replaceSymbol(f, f->getName(), f->getName(), + defaultModule, 0, + f->getFile(), f->signature); + else if (isa(s)) + replaceSymbol(s, s->getName(), 0, s->getFile()); else llvm_unreachable("unexpected symbol kind"); } -void BitcodeCompiler::add(BitcodeFile &F) { - lto::InputFile &Obj = *F.Obj; - unsigned SymNum = 0; - ArrayRef Syms = F.getSymbols(); - std::vector Resols(Syms.size()); +void BitcodeCompiler::add(BitcodeFile &f) { + lto::InputFile &obj = *f.obj; + unsigned symNum = 0; + ArrayRef syms = f.getSymbols(); + std::vector resols(syms.size()); // Provide a resolution to the LTO API for each symbol. - for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { - Symbol *Sym = Syms[SymNum]; - lto::SymbolResolution &R = Resols[SymNum]; - ++SymNum; + for (const lto::InputFile::Symbol &objSym : obj.symbols()) { + Symbol *sym = syms[symNum]; + lto::SymbolResolution &r = resols[symNum]; + ++symNum; // 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->getFile() == &F; - R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || - (R.Prevailing && Sym->isExported()); - if (R.Prevailing) - undefine(Sym); + r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f; + r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj || + (r.Prevailing && sym->isExported()); + if (r.Prevailing) + undefine(sym); // 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)); } // Merge all the bitcode files we have seen, codegen the result // and return the resulting objects. std::vector 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 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 mb) { + files[task] = std::move(mb); })); - checkError(LTOObj->run( - [&](size_t Task) { + checkError(ltoObj->run( + [&](size_t task) { return llvm::make_unique( - llvm::make_unique(Buf[Task])); + llvm::make_unique(buf[task])); }, - Cache)); + cache)); - if (!Config->ThinLTOCacheDir.empty()) - pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy); + if (!config->thinLTOCacheDir.empty()) + pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy); - std::vector Ret; - for (unsigned I = 0; I != MaxTasks; ++I) { - if (Buf[I].empty()) + std::vector ret; + for (unsigned i = 0; i != maxTasks; ++i) { + if (buf[i].empty()) continue; - if (Config->SaveTemps) { - if (I == 0) - saveBuffer(Buf[I], Config->OutputFile + ".lto.o"); + if (config->saveTemps) { + if (i == 0) + saveBuffer(buf[i], config->outputFile + ".lto.o"); else - saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o"); + saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o"); } - Ret.emplace_back(Buf[I].data(), Buf[I].size()); + ret.emplace_back(buf[i].data(), buf[i].size()); } - for (std::unique_ptr &File : Files) - if (File) - Ret.push_back(File->getBuffer()); + for (std::unique_ptr &file : files) + if (file) + ret.push_back(file->getBuffer()); - return Ret; + return ret; } diff --git a/lld/wasm/LTO.h b/lld/wasm/LTO.h index 37fea7a..9c1e178 100644 --- a/lld/wasm/LTO.h +++ b/lld/wasm/LTO.h @@ -43,13 +43,13 @@ public: BitcodeCompiler(); ~BitcodeCompiler(); - void add(BitcodeFile &F); + void add(BitcodeFile &f); std::vector compile(); private: - std::unique_ptr LTOObj; - std::vector> Buf; - std::vector> Files; + std::unique_ptr ltoObj; + std::vector> buf; + std::vector> files; }; } // namespace wasm } // namespace lld diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 0826492..703daf2 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -32,68 +32,68 @@ using namespace llvm; using namespace llvm::wasm; void lld::wasm::markLive() { - if (!Config->GcSections) + if (!config->gcSections) return; LLVM_DEBUG(dbgs() << "markLive\n"); - SmallVector Q; + SmallVector q; - std::function Enqueue = [&](Symbol *Sym) { - if (!Sym || Sym->isLive()) + std::function enqueue = [&](Symbol *sym) { + if (!sym || sym->isLive()) return; - LLVM_DEBUG(dbgs() << "markLive: " << Sym->getName() << "\n"); - Sym->markLive(); - if (InputChunk *Chunk = Sym->getChunk()) - Q.push_back(Chunk); + LLVM_DEBUG(dbgs() << "markLive: " << sym->getName() << "\n"); + sym->markLive(); + if (InputChunk *chunk = sym->getChunk()) + q.push_back(chunk); // The ctor functions are all referenced by the synthetic CallCtors // function. However, this function does not contain relocations so we // have to manually mark the ctors as live if CallCtors itself is live. - if (Sym == WasmSym::CallCtors) { - if (Config->PassiveSegments) - Enqueue(WasmSym::InitMemory); - if (Config->Pic) - Enqueue(WasmSym::ApplyRelocs); - for (const ObjFile *Obj : Symtab->ObjectFiles) { - const WasmLinkingData &L = Obj->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) { - auto* InitSym = Obj->getFunctionSymbol(F.Symbol); - if (!InitSym->isDiscarded()) - Enqueue(InitSym); + if (sym == WasmSym::callCtors) { + if (config->passiveSegments) + enqueue(WasmSym::initMemory); + if (config->isPic) + enqueue(WasmSym::applyRelocs); + for (const ObjFile *obj : symtab->objectFiles) { + const WasmLinkingData &l = obj->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) { + auto* initSym = obj->getFunctionSymbol(f.Symbol); + if (!initSym->isDiscarded()) + enqueue(initSym); } } } }; // Add GC root symbols. - if (!Config->Entry.empty()) - Enqueue(Symtab->find(Config->Entry)); + if (!config->entry.empty()) + enqueue(symtab->find(config->entry)); // We need to preserve any exported symbol - for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->isExported()) - Enqueue(Sym); + for (Symbol *sym : symtab->getSymbols()) + if (sym->isExported()) + enqueue(sym); // For relocatable output, we need to preserve all the ctor functions - if (Config->Relocatable) { - for (const ObjFile *Obj : Symtab->ObjectFiles) { - const WasmLinkingData &L = Obj->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) - Enqueue(Obj->getFunctionSymbol(F.Symbol)); + if (config->relocatable) { + for (const ObjFile *obj : symtab->objectFiles) { + const WasmLinkingData &l = obj->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) + enqueue(obj->getFunctionSymbol(f.Symbol)); } } - if (Config->Pic) - Enqueue(WasmSym::CallCtors); + if (config->isPic) + enqueue(WasmSym::callCtors); // Follow relocations to mark all reachable chunks. - while (!Q.empty()) { - InputChunk *C = Q.pop_back_val(); + while (!q.empty()) { + InputChunk *c = q.pop_back_val(); - for (const WasmRelocation Reloc : C->getRelocations()) { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) + for (const WasmRelocation reloc : c->getRelocations()) { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) continue; - Symbol *Sym = C->File->getSymbol(Reloc.Index); + Symbol *sym = c->file->getSymbol(reloc.Index); // If the function has been assigned the special index zero in the table, // the relocation doesn't pull in the function body, since the function @@ -102,38 +102,38 @@ void lld::wasm::markLive() { // zero is only reachable via "call", not via "call_indirect". The stub // functions used for weak-undefined symbols have this behaviour (compare // equal to null pointer, only reachable via direct call). - if (Reloc.Type == R_WASM_TABLE_INDEX_SLEB || - Reloc.Type == R_WASM_TABLE_INDEX_I32) { - auto *FuncSym = cast(Sym); - if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0) + if (reloc.Type == R_WASM_TABLE_INDEX_SLEB || + reloc.Type == R_WASM_TABLE_INDEX_I32) { + auto *funcSym = cast(sym); + if (funcSym->hasTableIndex() && funcSym->getTableIndex() == 0) continue; } - Enqueue(Sym); + enqueue(sym); } } // Report garbage-collected sections. - if (Config->PrintGcSections) { - for (const ObjFile *Obj : Symtab->ObjectFiles) { - for (InputChunk *C : Obj->Functions) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputChunk *C : Obj->Segments) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputGlobal *G : Obj->Globals) - if (!G->Live) - message("removing unused section " + toString(G)); - for (InputEvent *E : Obj->Events) - if (!E->Live) - message("removing unused section " + toString(E)); + if (config->printGcSections) { + for (const ObjFile *obj : symtab->objectFiles) { + for (InputChunk *c : obj->functions) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputChunk *c : obj->segments) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputGlobal *g : obj->globals) + if (!g->live) + message("removing unused section " + toString(g)); + for (InputEvent *e : obj->events) + if (!e->live) + message("removing unused section " + toString(e)); } - for (InputChunk *C : Symtab->SyntheticFunctions) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputGlobal *G : Symtab->SyntheticGlobals) - if (!G->Live) - message("removing unused section " + toString(G)); + for (InputChunk *c : symtab->syntheticFunctions) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputGlobal *g : symtab->syntheticGlobals) + if (!g->live) + message("removing unused section " + toString(g)); } } diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index d5434b1..c019d89 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -23,8 +23,8 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static StringRef sectionTypeToString(uint32_t SectionType) { - switch (SectionType) { +static StringRef sectionTypeToString(uint32_t sectionType) { + switch (sectionType) { case WASM_SEC_CUSTOM: return "CUSTOM"; case WASM_SEC_TYPE: @@ -59,192 +59,192 @@ static StringRef sectionTypeToString(uint32_t SectionType) { } // Returns a string, e.g. "FUNCTION(.text)". -std::string lld::toString(const OutputSection &Sec) { - if (!Sec.Name.empty()) - return (Sec.getSectionName() + "(" + Sec.Name + ")").str(); - return Sec.getSectionName(); +std::string lld::toString(const OutputSection &sec) { + if (!sec.name.empty()) + return (sec.getSectionName() + "(" + sec.name + ")").str(); + return sec.getSectionName(); } StringRef OutputSection::getSectionName() const { - return sectionTypeToString(Type); + return sectionTypeToString(type); } -void OutputSection::createHeader(size_t BodySize) { - raw_string_ostream OS(Header); - debugWrite(OS.tell(), "section type [" + getSectionName() + "]"); - encodeULEB128(Type, OS); - writeUleb128(OS, BodySize, "section size"); - OS.flush(); - log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + +void OutputSection::createHeader(size_t bodySize) { + raw_string_ostream os(header); + debugWrite(os.tell(), "section type [" + getSectionName() + "]"); + encodeULEB128(type, os); + writeUleb128(os, bodySize, "section size"); + os.flush(); + log("createHeader: " + toString(*this) + " body=" + Twine(bodySize) + " total=" + Twine(getSize())); } void CodeSection::finalizeContents() { - raw_string_ostream OS(CodeSectionHeader); - writeUleb128(OS, Functions.size(), "function count"); - OS.flush(); - BodySize = CodeSectionHeader.size(); - - for (InputFunction *Func : Functions) { - Func->OutputOffset = BodySize; - Func->calculateSize(); - BodySize += Func->getSize(); + raw_string_ostream os(codeSectionHeader); + writeUleb128(os, functions.size(), "function count"); + os.flush(); + bodySize = codeSectionHeader.size(); + + for (InputFunction *func : functions) { + func->outputOffset = bodySize; + func->calculateSize(); + bodySize += func->getSize(); } - createHeader(BodySize); + createHeader(bodySize); } -void CodeSection::writeTo(uint8_t *Buf) { +void CodeSection::writeTo(uint8_t *buf) { log("writing " + toString(*this)); log(" size=" + Twine(getSize())); - log(" headersize=" + Twine(Header.size())); - log(" codeheadersize=" + Twine(CodeSectionHeader.size())); - Buf += Offset; + log(" headersize=" + Twine(header.size())); + log(" codeheadersize=" + Twine(codeSectionHeader.size())); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); // Write code section headers - memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); + memcpy(buf, codeSectionHeader.data(), codeSectionHeader.size()); // Write code section bodies - for (const InputChunk *Chunk : Functions) - Chunk->writeTo(Buf); + for (const InputChunk *chunk : functions) + chunk->writeTo(buf); } uint32_t CodeSection::getNumRelocations() const { - uint32_t Count = 0; - for (const InputChunk *Func : Functions) - Count += Func->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const InputChunk *func : functions) + count += func->getNumRelocations(); + return count; } -void CodeSection::writeRelocations(raw_ostream &OS) const { - for (const InputChunk *C : Functions) - C->writeRelocations(OS); +void CodeSection::writeRelocations(raw_ostream &os) const { + for (const InputChunk *c : functions) + c->writeRelocations(os); } void DataSection::finalizeContents() { - raw_string_ostream OS(DataSectionHeader); + raw_string_ostream os(dataSectionHeader); - writeUleb128(OS, Segments.size(), "data segment count"); - OS.flush(); - BodySize = DataSectionHeader.size(); + writeUleb128(os, segments.size(), "data segment count"); + os.flush(); + bodySize = dataSectionHeader.size(); - assert((!Config->Pic || Segments.size() <= 1) && + assert((!config->isPic || segments.size() <= 1) && "Currenly only a single data segment is supported in PIC mode"); - for (OutputSegment *Segment : Segments) { - raw_string_ostream OS(Segment->Header); - writeUleb128(OS, Segment->InitFlags, "init flags"); - if (Segment->InitFlags & WASM_SEGMENT_HAS_MEMINDEX) - writeUleb128(OS, 0, "memory index"); - if ((Segment->InitFlags & WASM_SEGMENT_IS_PASSIVE) == 0) { - WasmInitExpr InitExpr; - if (Config->Pic) { - InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - InitExpr.Value.Global = WasmSym::MemoryBase->getGlobalIndex(); + for (OutputSegment *segment : segments) { + raw_string_ostream os(segment->header); + writeUleb128(os, segment->initFlags, "init flags"); + if (segment->initFlags & WASM_SEGMENT_HAS_MEMINDEX) + writeUleb128(os, 0, "memory index"); + if ((segment->initFlags & WASM_SEGMENT_IS_PASSIVE) == 0) { + WasmInitExpr initExpr; + if (config->isPic) { + initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Value.Global = WasmSym::memoryBase->getGlobalIndex(); } else { - InitExpr.Opcode = WASM_OPCODE_I32_CONST; - InitExpr.Value.Int32 = Segment->StartVA; + initExpr.Opcode = WASM_OPCODE_I32_CONST; + initExpr.Value.Int32 = segment->startVA; } - writeInitExpr(OS, InitExpr); + writeInitExpr(os, initExpr); } - writeUleb128(OS, Segment->Size, "segment size"); - OS.flush(); + writeUleb128(os, segment->size, "segment size"); + os.flush(); - Segment->SectionOffset = BodySize; - BodySize += Segment->Header.size() + Segment->Size; - log("Data segment: size=" + Twine(Segment->Size) + ", startVA=" + - Twine::utohexstr(Segment->StartVA) + ", name=" + Segment->Name); + segment->sectionOffset = bodySize; + bodySize += segment->header.size() + segment->size; + log("Data segment: size=" + Twine(segment->size) + ", startVA=" + + Twine::utohexstr(segment->startVA) + ", name=" + segment->name); - for (InputSegment *InputSeg : Segment->InputSegments) - InputSeg->OutputOffset = Segment->SectionOffset + Segment->Header.size() + - InputSeg->OutputSegmentOffset; + for (InputSegment *inputSeg : segment->inputSegments) + inputSeg->outputOffset = segment->sectionOffset + segment->header.size() + + inputSeg->outputSegmentOffset; } - createHeader(BodySize); + createHeader(bodySize); } -void DataSection::writeTo(uint8_t *Buf) { +void DataSection::writeTo(uint8_t *buf) { log("writing " + toString(*this) + " size=" + Twine(getSize()) + - " body=" + Twine(BodySize)); - Buf += Offset; + " body=" + Twine(bodySize)); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); // Write data section headers - memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); + memcpy(buf, dataSectionHeader.data(), dataSectionHeader.size()); - for (const OutputSegment *Segment : Segments) { + for (const OutputSegment *segment : segments) { // Write data segment header - uint8_t *SegStart = Buf + Segment->SectionOffset; - memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); + uint8_t *segStart = buf + segment->sectionOffset; + memcpy(segStart, segment->header.data(), segment->header.size()); // Write segment data payload - for (const InputChunk *Chunk : Segment->InputSegments) - Chunk->writeTo(Buf); + for (const InputChunk *chunk : segment->inputSegments) + chunk->writeTo(buf); } } uint32_t DataSection::getNumRelocations() const { - uint32_t Count = 0; - for (const OutputSegment *Seg : Segments) - for (const InputChunk *InputSeg : Seg->InputSegments) - Count += InputSeg->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const OutputSegment *seg : segments) + for (const InputChunk *inputSeg : seg->inputSegments) + count += inputSeg->getNumRelocations(); + return count; } -void DataSection::writeRelocations(raw_ostream &OS) const { - for (const OutputSegment *Seg : Segments) - for (const InputChunk *C : Seg->InputSegments) - C->writeRelocations(OS); +void DataSection::writeRelocations(raw_ostream &os) const { + for (const OutputSegment *seg : segments) + for (const InputChunk *c : seg->inputSegments) + c->writeRelocations(os); } void CustomSection::finalizeContents() { - raw_string_ostream OS(NameData); - encodeULEB128(Name.size(), OS); - OS << Name; - OS.flush(); - - for (InputSection *Section : InputSections) { - Section->OutputOffset = PayloadSize; - Section->OutputSec = this; - PayloadSize += Section->getSize(); + raw_string_ostream os(nameData); + encodeULEB128(name.size(), os); + os << name; + os.flush(); + + for (InputSection *section : inputSections) { + section->outputOffset = payloadSize; + section->outputSec = this; + payloadSize += section->getSize(); } - createHeader(PayloadSize + NameData.size()); + createHeader(payloadSize + nameData.size()); } -void CustomSection::writeTo(uint8_t *Buf) { +void CustomSection::writeTo(uint8_t *buf) { log("writing " + toString(*this) + " size=" + Twine(getSize()) + - " chunks=" + Twine(InputSections.size())); + " chunks=" + Twine(inputSections.size())); - assert(Offset); - Buf += Offset; + assert(offset); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); - memcpy(Buf, NameData.data(), NameData.size()); - Buf += NameData.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); + memcpy(buf, nameData.data(), nameData.size()); + buf += nameData.size(); // Write custom sections payload - for (const InputSection *Section : InputSections) - Section->writeTo(Buf); + for (const InputSection *section : inputSections) + section->writeTo(buf); } uint32_t CustomSection::getNumRelocations() const { - uint32_t Count = 0; - for (const InputSection *InputSect : InputSections) - Count += InputSect->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const InputSection *inputSect : inputSections) + count += inputSect->getNumRelocations(); + return count; } -void CustomSection::writeRelocations(raw_ostream &OS) const { - for (const InputSection *S : InputSections) - S->writeRelocations(OS); +void CustomSection::writeRelocations(raw_ostream &os) const { + for (const InputSection *s : inputSections) + s->writeRelocations(os); } diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h index 3045ed7..6b1c2a2 100644 --- a/lld/wasm/OutputSections.h +++ b/lld/wasm/OutputSections.h @@ -20,7 +20,7 @@ namespace lld { namespace wasm { class OutputSection; } -std::string toString(const wasm::OutputSection &Section); +std::string toString(const wasm::OutputSection §ion); namespace wasm { @@ -28,67 +28,67 @@ class OutputSegment; class OutputSection { public: - OutputSection(uint32_t Type, std::string Name = "") - : Type(Type), Name(Name) {} + OutputSection(uint32_t type, std::string name = "") + : type(type), name(name) {} virtual ~OutputSection() = default; StringRef getSectionName() const; - void setOffset(size_t NewOffset) { - log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); - Offset = NewOffset; + void setOffset(size_t newOffset) { + log("setOffset: " + toString(*this) + ": " + Twine(newOffset)); + offset = newOffset; } - void createHeader(size_t BodySize); + void createHeader(size_t bodySize); virtual bool isNeeded() const { return true; } virtual size_t getSize() const = 0; - virtual void writeTo(uint8_t *Buf) = 0; + virtual void writeTo(uint8_t *buf) = 0; virtual void finalizeContents() = 0; virtual uint32_t getNumRelocations() const { return 0; } - virtual void writeRelocations(raw_ostream &OS) const {} + virtual void writeRelocations(raw_ostream &os) const {} - std::string Header; - uint32_t Type; - uint32_t SectionIndex = UINT32_MAX; - std::string Name; - OutputSectionSymbol *SectionSym = nullptr; + std::string header; + uint32_t type; + uint32_t sectionIndex = UINT32_MAX; + std::string name; + OutputSectionSymbol *sectionSym = nullptr; protected: - size_t Offset = 0; + size_t offset = 0; }; class CodeSection : public OutputSection { public: - explicit CodeSection(ArrayRef Functions) - : OutputSection(llvm::wasm::WASM_SEC_CODE), Functions(Functions) {} + explicit CodeSection(ArrayRef functions) + : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {} - size_t getSize() const override { return Header.size() + BodySize; } - void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return header.size() + bodySize; } + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; - bool isNeeded() const override { return Functions.size() > 0; } + void writeRelocations(raw_ostream &os) const override; + bool isNeeded() const override { return functions.size() > 0; } void finalizeContents() override; protected: - ArrayRef Functions; - std::string CodeSectionHeader; - size_t BodySize = 0; + ArrayRef functions; + std::string codeSectionHeader; + size_t bodySize = 0; }; class DataSection : public OutputSection { public: - explicit DataSection(ArrayRef Segments) - : OutputSection(llvm::wasm::WASM_SEC_DATA), Segments(Segments) {} + explicit DataSection(ArrayRef segments) + : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {} - size_t getSize() const override { return Header.size() + BodySize; } - void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return header.size() + bodySize; } + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; - bool isNeeded() const override { return Segments.size() > 0; } + void writeRelocations(raw_ostream &os) const override; + bool isNeeded() const override { return segments.size() > 0; } void finalizeContents() override; protected: - ArrayRef Segments; - std::string DataSectionHeader; - size_t BodySize = 0; + ArrayRef segments; + std::string dataSectionHeader; + size_t bodySize = 0; }; // Represents a custom section in the output file. Wasm custom sections are @@ -100,21 +100,21 @@ protected: // separately and are instead synthesized by the linker. class CustomSection : public OutputSection { public: - CustomSection(std::string Name, ArrayRef InputSections) - : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, Name), - InputSections(InputSections) {} + CustomSection(std::string name, ArrayRef inputSections) + : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name), + inputSections(inputSections) {} size_t getSize() const override { - return Header.size() + NameData.size() + PayloadSize; + return header.size() + nameData.size() + payloadSize; } - void writeTo(uint8_t *Buf) override; + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; + void writeRelocations(raw_ostream &os) const override; void finalizeContents() override; protected: - size_t PayloadSize = 0; - ArrayRef InputSections; - std::string NameData; + size_t payloadSize = 0; + ArrayRef inputSections; + std::string nameData; }; } // namespace wasm diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h index a9679c1..14142fbd 100644 --- a/lld/wasm/OutputSegment.h +++ b/lld/wasm/OutputSegment.h @@ -20,30 +20,30 @@ class InputSegment; class OutputSegment { public: - OutputSegment(StringRef N, uint32_t Index) : Name(N), Index(Index) {} - - void addInputSegment(InputSegment *InSeg) { - Alignment = std::max(Alignment, InSeg->getAlignment()); - InputSegments.push_back(InSeg); - Size = llvm::alignTo(Size, 1ULL << InSeg->getAlignment()); - InSeg->OutputSeg = this; - InSeg->OutputSegmentOffset = Size; - Size += InSeg->getSize(); + OutputSegment(StringRef n, uint32_t index) : name(n), index(index) {} + + void addInputSegment(InputSegment *inSeg) { + alignment = std::max(alignment, inSeg->getAlignment()); + inputSegments.push_back(inSeg); + size = llvm::alignTo(size, 1ULL << inSeg->getAlignment()); + inSeg->outputSeg = this; + inSeg->outputSegmentOffset = size; + size += inSeg->getSize(); } - StringRef Name; - const uint32_t Index; - uint32_t InitFlags = 0; - uint32_t SectionOffset = 0; - uint32_t Alignment = 0; - uint32_t StartVA = 0; - std::vector InputSegments; + StringRef name; + const uint32_t index; + uint32_t initFlags = 0; + uint32_t sectionOffset = 0; + uint32_t alignment = 0; + uint32_t startVA = 0; + std::vector inputSegments; // Sum of the size of the all the input segments - uint32_t Size = 0; + uint32_t size = 0; // Segment header - std::string Header; + std::string header; }; } // namespace wasm diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp index faedd00..e39f698 100644 --- a/lld/wasm/Relocations.cpp +++ b/lld/wasm/Relocations.cpp @@ -17,69 +17,69 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static bool requiresGOTAccess(const Symbol *Sym) { - return Config->Pic && !Sym->isHidden() && !Sym->isLocal(); +static bool requiresGOTAccess(const Symbol *sym) { + return config->isPic && !sym->isHidden() && !sym->isLocal(); } -static bool allowUndefined(const Symbol* Sym) { +static bool allowUndefined(const Symbol* sym) { // Historically --allow-undefined doesn't work for data symbols since we don't // have any way to represent these as imports in the final binary. The idea // behind allowing undefined symbols is to allow importing these symbols from // the embedder and we can't do this for data symbols (at least not without // compiling with -fPIC) - if (isa(Sym)) + if (isa(sym)) return false; - return (Config->AllowUndefined || - Config->AllowUndefinedSymbols.count(Sym->getName()) != 0); + return (config->allowUndefined || + config->allowUndefinedSymbols.count(sym->getName()) != 0); } -static void reportUndefined(const Symbol* Sym) { - assert(Sym->isUndefined()); - assert(!Sym->isWeak()); - if (!allowUndefined(Sym)) - error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym)); +static void reportUndefined(const Symbol* sym) { + assert(sym->isUndefined()); + assert(!sym->isWeak()); + if (!allowUndefined(sym)) + error(toString(sym->getFile()) + ": undefined symbol: " + toString(*sym)); } -void lld::wasm::scanRelocations(InputChunk *Chunk) { - if (!Chunk->Live) +void lld::wasm::scanRelocations(InputChunk *chunk) { + if (!chunk->live) return; - ObjFile *File = Chunk->File; - ArrayRef Types = File->getWasmObj()->types(); - for (const WasmRelocation &Reloc : Chunk->getRelocations()) { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { + ObjFile *file = chunk->file; + ArrayRef types = file->getWasmObj()->types(); + for (const WasmRelocation &reloc : chunk->getRelocations()) { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) { // Mark target type as live - File->TypeMap[Reloc.Index] = - Out.TypeSec->registerType(Types[Reloc.Index]); - File->TypeIsUsed[Reloc.Index] = true; + file->typeMap[reloc.Index] = + out.typeSec->registerType(types[reloc.Index]); + file->typeIsUsed[reloc.Index] = true; continue; } // Other relocation types all have a corresponding symbol - Symbol *Sym = File->getSymbols()[Reloc.Index]; + Symbol *sym = file->getSymbols()[reloc.Index]; - switch (Reloc.Type) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: - if (requiresGOTAccess(Sym)) + if (requiresGOTAccess(sym)) break; - Out.ElemSec->addEntry(cast(Sym)); + out.elemSec->addEntry(cast(sym)); break; case R_WASM_GLOBAL_INDEX_LEB: - if (!isa(Sym)) - Out.ImportSec->addGOTEntry(Sym); + if (!isa(sym)) + out.importSec->addGOTEntry(sym); break; } - if (Config->Pic) { - switch (Reloc.Type) { + if (config->isPic) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_LEB: // Certain relocation types can't be used when building PIC output, // since they would require absolute symbol addresses at link time. - error(toString(File) + ": relocation " + relocTypeToString(Reloc.Type) + - " cannot be used against symbol " + toString(*Sym) + + error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) + + " cannot be used against symbol " + toString(*sym) + "; recompile with -fPIC"); break; case R_WASM_TABLE_INDEX_I32: @@ -87,14 +87,14 @@ void lld::wasm::scanRelocations(InputChunk *Chunk) { // These relocation types are only present in the data section and // will be converted into code by `generateRelocationCode`. This code // requires the symbols to have GOT entires. - if (requiresGOTAccess(Sym)) - Out.ImportSec->addGOTEntry(Sym); + if (requiresGOTAccess(sym)) + out.importSec->addGOTEntry(sym); break; } } else { // Report undefined symbols - if (Sym->isUndefined() && !Config->Relocatable && !Sym->isWeak()) - reportUndefined(Sym); + if (sym->isUndefined() && !config->relocatable && !sym->isWeak()) + reportUndefined(sym); } } diff --git a/lld/wasm/Relocations.h b/lld/wasm/Relocations.h index 09a632cc..02787f5 100644 --- a/lld/wasm/Relocations.h +++ b/lld/wasm/Relocations.h @@ -14,7 +14,7 @@ namespace wasm { class InputChunk; -void scanRelocations(InputChunk *Chunk); +void scanRelocations(InputChunk *chunk); } // namespace wasm } // namespace lld diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index 35ceed6..b618125 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -24,37 +24,37 @@ using namespace llvm::object; using namespace lld; using namespace lld::wasm; -SymbolTable *lld::wasm::Symtab; +SymbolTable *lld::wasm::symtab; -void SymbolTable::addFile(InputFile *File) { - log("Processing: " + toString(File)); +void SymbolTable::addFile(InputFile *file) { + log("Processing: " + toString(file)); // .a file - if (auto *F = dyn_cast(File)) { - F->parse(); + if (auto *f = dyn_cast(file)) { + f->parse(); return; } // .so file - if (auto *F = dyn_cast(File)) { - SharedFiles.push_back(F); + if (auto *f = dyn_cast(file)) { + sharedFiles.push_back(f); return; } - if (Config->Trace) - message(toString(File)); + if (config->trace) + message(toString(file)); // LLVM bitcode file - if (auto *F = dyn_cast(File)) { - F->parse(); - BitcodeFiles.push_back(F); + if (auto *f = dyn_cast(file)) { + f->parse(); + bitcodeFiles.push_back(f); return; } // Regular object file - auto *F = cast(File); - F->parse(false); - ObjectFiles.push_back(F); + auto *f = cast(file); + f->parse(false); + objectFiles.push_back(f); } // This function is where all the optimizations of link-time @@ -65,512 +65,512 @@ void SymbolTable::addFile(InputFile *File) { // Because all bitcode files that the program consists of are passed // to the compiler at once, it can do whole-program optimization. void SymbolTable::addCombinedLTOObject() { - if (BitcodeFiles.empty()) + if (bitcodeFiles.empty()) return; // Compile bitcode files and replace bitcode symbols. - LTO.reset(new BitcodeCompiler); - for (BitcodeFile *F : BitcodeFiles) - LTO->add(*F); - - for (StringRef Filename : LTO->compile()) { - auto *Obj = make(MemoryBufferRef(Filename, "lto.tmp"), ""); - Obj->parse(true); - ObjectFiles.push_back(Obj); + lto.reset(new BitcodeCompiler); + for (BitcodeFile *f : bitcodeFiles) + lto->add(*f); + + for (StringRef filename : lto->compile()) { + auto *obj = make(MemoryBufferRef(filename, "lto.tmp"), ""); + obj->parse(true); + objectFiles.push_back(obj); } } -Symbol *SymbolTable::find(StringRef Name) { - auto It = SymMap.find(CachedHashStringRef(Name)); - if (It == SymMap.end() || It->second == -1) +Symbol *SymbolTable::find(StringRef name) { + auto it = symMap.find(CachedHashStringRef(name)); + if (it == symMap.end() || it->second == -1) return nullptr; - return SymVector[It->second]; + return symVector[it->second]; } -void SymbolTable::replace(StringRef Name, Symbol* Sym) { - auto It = SymMap.find(CachedHashStringRef(Name)); - SymVector[It->second] = Sym; +void SymbolTable::replace(StringRef name, Symbol* sym) { + auto it = symMap.find(CachedHashStringRef(name)); + symVector[it->second] = sym; } -std::pair SymbolTable::insertName(StringRef Name) { - bool Trace = false; - auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()}); - int &SymIndex = P.first->second; - bool IsNew = P.second; - if (SymIndex == -1) { - SymIndex = SymVector.size(); - Trace = true; - IsNew = true; +std::pair SymbolTable::insertName(StringRef name) { + bool trace = false; + auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()}); + int &symIndex = p.first->second; + bool isNew = p.second; + if (symIndex == -1) { + symIndex = symVector.size(); + trace = true; + isNew = true; } - if (!IsNew) - return {SymVector[SymIndex], false}; + if (!isNew) + return {symVector[symIndex], false}; - Symbol *Sym = reinterpret_cast(make()); - Sym->IsUsedInRegularObj = false; - Sym->CanInline = true; - Sym->Traced = Trace; - SymVector.emplace_back(Sym); - return {Sym, true}; + Symbol *sym = reinterpret_cast(make()); + sym->isUsedInRegularObj = false; + sym->canInline = true; + sym->traced = trace; + symVector.emplace_back(sym); + return {sym, true}; } -std::pair SymbolTable::insert(StringRef Name, - const InputFile *File) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insertName(Name); +std::pair SymbolTable::insert(StringRef name, + const InputFile *file) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insertName(name); - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + if (!file || file->kind() == InputFile::ObjectKind) + s->isUsedInRegularObj = true; - return {S, WasInserted}; + return {s, wasInserted}; } -static void reportTypeError(const Symbol *Existing, const InputFile *File, - llvm::wasm::WasmSymbolType Type) { - error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + - toString(Existing->getWasmType()) + " in " + - toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + - " in " + toString(File)); +static void reportTypeError(const Symbol *existing, const InputFile *file, + llvm::wasm::WasmSymbolType type) { + error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " + + toString(existing->getWasmType()) + " in " + + toString(existing->getFile()) + "\n>>> defined as " + toString(type) + + " in " + toString(file)); } // Check the type of new symbol matches that of the symbol is replacing. // Returns true if the function types match, false is there is a singature // mismatch. -static bool signatureMatches(FunctionSymbol *Existing, - const WasmSignature *NewSig) { - const WasmSignature *OldSig = Existing->Signature; +static bool signatureMatches(FunctionSymbol *existing, + const WasmSignature *newSig) { + const WasmSignature *oldSig = existing->signature; // If either function is missing a signature (this happend for bitcode // symbols) then assume they match. Any mismatch will be reported later // when the LTO objects are added. - if (!NewSig || !OldSig) + if (!newSig || !oldSig) return true; - return *NewSig == *OldSig; + return *newSig == *oldSig; } -static void checkGlobalType(const Symbol *Existing, const InputFile *File, - const WasmGlobalType *NewType) { - if (!isa(Existing)) { - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL); +static void checkGlobalType(const Symbol *existing, const InputFile *file, + const WasmGlobalType *newType) { + if (!isa(existing)) { + reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL); return; } - const WasmGlobalType *OldType = cast(Existing)->getGlobalType(); - if (*NewType != *OldType) { - error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " + - toString(*OldType) + " in " + toString(Existing->getFile()) + - "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); + const WasmGlobalType *oldType = cast(existing)->getGlobalType(); + if (*newType != *oldType) { + error("Global type mismatch: " + existing->getName() + "\n>>> defined as " + + toString(*oldType) + " in " + toString(existing->getFile()) + + "\n>>> defined as " + toString(*newType) + " in " + toString(file)); } } -static void checkEventType(const Symbol *Existing, const InputFile *File, - const WasmEventType *NewType, - const WasmSignature *NewSig) { - auto ExistingEvent = dyn_cast(Existing); - if (!isa(Existing)) { - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); +static void checkEventType(const Symbol *existing, const InputFile *file, + const WasmEventType *newType, + const WasmSignature *newSig) { + auto existingEvent = dyn_cast(existing); + if (!isa(existing)) { + reportTypeError(existing, file, WASM_SYMBOL_TYPE_EVENT); return; } - const WasmEventType *OldType = cast(Existing)->getEventType(); - const WasmSignature *OldSig = ExistingEvent->Signature; - if (NewType->Attribute != OldType->Attribute) - error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + - toString(*OldType) + " in " + toString(Existing->getFile()) + - "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); - if (*NewSig != *OldSig) - warn("Event signature mismatch: " + Existing->getName() + - "\n>>> defined as " + toString(*OldSig) + " in " + - toString(Existing->getFile()) + "\n>>> defined as " + - toString(*NewSig) + " in " + toString(File)); + const WasmEventType *oldType = cast(existing)->getEventType(); + const WasmSignature *oldSig = existingEvent->signature; + if (newType->Attribute != oldType->Attribute) + error("Event type mismatch: " + existing->getName() + "\n>>> defined as " + + toString(*oldType) + " in " + toString(existing->getFile()) + + "\n>>> defined as " + toString(*newType) + " in " + toString(file)); + if (*newSig != *oldSig) + warn("Event signature mismatch: " + existing->getName() + + "\n>>> defined as " + toString(*oldSig) + " in " + + toString(existing->getFile()) + "\n>>> defined as " + + toString(*newSig) + " in " + toString(file)); } -static void checkDataType(const Symbol *Existing, const InputFile *File) { - if (!isa(Existing)) - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); +static void checkDataType(const Symbol *existing, const InputFile *file) { + if (!isa(existing)) + reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA); } -DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, - uint32_t Flags, - InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); - assert(!find(Name)); - SyntheticFunctions.emplace_back(Function); - return replaceSymbol(insertName(Name).first, Name, - Flags, nullptr, Function); +DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name, + uint32_t flags, + InputFunction *function) { + LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << name << "\n"); + assert(!find(name)); + syntheticFunctions.emplace_back(function); + return replaceSymbol(insertName(name).first, name, + flags, nullptr, function); } // Adds an optional, linker generated, data symbols. The symbol will only be // added if there is an undefine reference to it, or if it is explictly exported // via the --export flag. Otherwise we don't add the symbol and return nullptr. -DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value, - uint32_t Flags) { - Symbol *S = find(Name); - if (!S && (Config->ExportAll || Config->ExportedSymbols.count(Name) != 0)) - S = insertName(Name).first; - else if (!S || S->isDefined()) +DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name, uint32_t value, + uint32_t flags) { + Symbol *s = find(name); + if (!s && (config->exportAll || config->exportedSymbols.count(name) != 0)) + s = insertName(name).first; + else if (!s || s->isDefined()) return nullptr; - LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n"); - auto *rtn = replaceSymbol(S, Name, Flags); - rtn->setVirtualAddress(Value); - rtn->Referenced = true; + LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << name << "\n"); + auto *rtn = replaceSymbol(s, name, flags); + rtn->setVirtualAddress(value); + rtn->referenced = true; return rtn; } -DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, - uint32_t Flags) { - LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); - assert(!find(Name)); - return replaceSymbol(insertName(Name).first, Name, Flags); +DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef name, + uint32_t flags) { + LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << name << "\n"); + assert(!find(name)); + return replaceSymbol(insertName(name).first, name, flags); } -DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, - InputGlobal *Global) { - LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global +DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags, + InputGlobal *global) { + LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << name << " -> " << global << "\n"); - assert(!find(Name)); - SyntheticGlobals.emplace_back(Global); - return replaceSymbol(insertName(Name).first, Name, Flags, - nullptr, Global); + assert(!find(name)); + syntheticGlobals.emplace_back(global); + return replaceSymbol(insertName(name).first, name, flags, + nullptr, global); } -static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, - uint32_t NewFlags) { +static bool shouldReplace(const Symbol *existing, InputFile *newFile, + uint32_t newFlags) { // If existing symbol is undefined, replace it. - if (!Existing->isDefined()) { + if (!existing->isDefined()) { LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " - << Existing->getName() << "\n"); + << existing->getName() << "\n"); return true; } // Now we have two defined symbols. If the new one is weak, we can ignore it. - if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { + if ((newFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); return false; } // If the existing symbol is weak, we should replace it. - if (Existing->isWeak()) { + if (existing->isWeak()) { LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); return true; } // Neither symbol is week. They conflict. - error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + - toString(Existing->getFile()) + "\n>>> defined in " + - toString(NewFile)); + error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " + + toString(existing->getFile()) + "\n>>> defined in " + + toString(newFile)); return true; } -Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, - InputFile *File, - InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" - << (Function ? toString(Function->Signature) : "none") +Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags, + InputFile *file, + InputFunction *function) { + LLVM_DEBUG(dbgs() << "addDefinedFunction: " << name << " [" + << (function ? toString(function->signature) : "none") << "]\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&](Symbol *Sym) { + auto replaceSym = [&](Symbol *sym) { // If the new defined function doesn't have signture (i.e. bitcode // functions) but the old symbol does, then preserve the old signature - const WasmSignature *OldSig = S->getSignature(); - auto* NewSym = replaceSymbol(Sym, Name, Flags, File, Function); - if (!NewSym->Signature) - NewSym->Signature = OldSig; + const WasmSignature *oldSig = s->getSignature(); + auto* newSym = replaceSymbol(sym, name, flags, file, function); + if (!newSym->signature) + newSym->signature = oldSig; }; - if (WasInserted || S->isLazy()) { - ReplaceSym(S); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(s); + return s; } - auto ExistingFunction = dyn_cast(S); - if (!ExistingFunction) { - reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION); - return S; + auto existingFunction = dyn_cast(s); + if (!existingFunction) { + reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION); + return s; } - bool CheckSig = true; - if (auto UD = dyn_cast(ExistingFunction)) - CheckSig = UD->IsCalledDirectly; + bool checkSig = true; + if (auto ud = dyn_cast(existingFunction)) + checkSig = ud->isCalledDirectly; - if (CheckSig && Function && !signatureMatches(ExistingFunction, &Function->Signature)) { - Symbol* Variant; - if (getFunctionVariant(S, &Function->Signature, File, &Variant)) + if (checkSig && function && !signatureMatches(existingFunction, &function->signature)) { + Symbol* variant; + if (getFunctionVariant(s, &function->signature, file, &variant)) // New variant, always replace - ReplaceSym(Variant); - else if (shouldReplace(S, File, Flags)) + replaceSym(variant); + else if (shouldReplace(s, file, flags)) // Variant already exists, replace it after checking shouldReplace - ReplaceSym(Variant); + replaceSym(variant); // This variant we found take the place in the symbol table as the primary // variant. - replace(Name, Variant); - return Variant; + replace(name, variant); + return variant; } // Existing function with matching signature. - if (shouldReplace(S, File, Flags)) - ReplaceSym(S); + if (shouldReplace(s, file, flags)) + replaceSym(s); - return S; + return s; } -Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, - InputFile *File, InputSegment *Segment, - uint32_t Address, uint32_t Size) { - LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address +Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags, + InputFile *file, InputSegment *segment, + uint32_t address, uint32_t size) { + LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol(S, Name, Flags, File, Segment, Address, Size); + auto replaceSym = [&]() { + replaceSymbol(s, name, flags, file, segment, address, size); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkDataType(S, File); + checkDataType(s, file); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, - InputFile *File, InputGlobal *Global) { - LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); +Symbol *SymbolTable::addDefinedGlobal(StringRef name, uint32_t flags, + InputFile *file, InputGlobal *global) { + LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol(S, Name, Flags, File, Global); + auto replaceSym = [&]() { + replaceSymbol(s, name, flags, file, global); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkGlobalType(S, File, &Global->getType()); + checkGlobalType(s, file, &global->getType()); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, - InputFile *File, InputEvent *Event) { - LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); +Symbol *SymbolTable::addDefinedEvent(StringRef name, uint32_t flags, + InputFile *file, InputEvent *event) { + LLVM_DEBUG(dbgs() << "addDefinedEvent:" << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol(S, Name, Flags, File, Event); + auto replaceSym = [&]() { + replaceSymbol(s, name, flags, file, event); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkEventType(S, File, &Event->getType(), &Event->Signature); + checkEventType(s, file, &event->getType(), &event->signature); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, - uint32_t Flags, InputFile *File, - const WasmSignature *Sig, - bool IsCalledDirectly) { - LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" - << (Sig ? toString(*Sig) : "none") - << "] IsCalledDirectly:" << IsCalledDirectly << "\n"); +Symbol *SymbolTable::addUndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, + uint32_t flags, InputFile *file, + const WasmSignature *sig, + bool isCalledDirectly) { + LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " [" + << (sig ? toString(*sig) : "none") + << "] IsCalledDirectly:" << isCalledDirectly << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - auto ReplaceSym = [&]() { - replaceSymbol(S, Name, ImportName, ImportModule, Flags, - File, Sig, IsCalledDirectly); + auto replaceSym = [&]() { + replaceSymbol(s, name, importName, importModule, flags, + file, sig, isCalledDirectly); }; - if (WasInserted) - ReplaceSym(); - else if (auto *Lazy = dyn_cast(S)) - Lazy->fetch(); + if (wasInserted) + replaceSym(); + else if (auto *lazy = dyn_cast(s)) + lazy->fetch(); else { - auto ExistingFunction = dyn_cast(S); - if (!ExistingFunction) { - reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION); - return S; + auto existingFunction = dyn_cast(s); + if (!existingFunction) { + reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION); + return s; } - if (!ExistingFunction->Signature && Sig) - ExistingFunction->Signature = Sig; - if (IsCalledDirectly && !signatureMatches(ExistingFunction, Sig)) - if (getFunctionVariant(S, Sig, File, &S)) - ReplaceSym(); + if (!existingFunction->signature && sig) + existingFunction->signature = sig; + if (isCalledDirectly && !signatureMatches(existingFunction, sig)) + if (getFunctionVariant(s, sig, file, &s)) + replaceSym(); } - return S; + return s; } -Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, - InputFile *File) { - LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); +Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags, + InputFile *file) { + LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - if (WasInserted) - replaceSymbol(S, Name, Flags, File); - else if (auto *Lazy = dyn_cast(S)) - Lazy->fetch(); - else if (S->isDefined()) - checkDataType(S, File); - return S; + if (wasInserted) + replaceSymbol(s, name, flags, file); + else if (auto *lazy = dyn_cast(s)) + lazy->fetch(); + else if (s->isDefined()) + checkDataType(s, file); + return s; } -Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, - const WasmGlobalType *Type) { - LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); +Symbol *SymbolTable::addUndefinedGlobal(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, + const WasmGlobalType *type) { + LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - if (WasInserted) - replaceSymbol(S, Name, ImportName, ImportModule, Flags, - File, Type); - else if (auto *Lazy = dyn_cast(S)) - Lazy->fetch(); - else if (S->isDefined()) - checkGlobalType(S, File, Type); - return S; + if (wasInserted) + replaceSymbol(s, name, importName, importModule, flags, + file, type); + else if (auto *lazy = dyn_cast(s)) + lazy->fetch(); + else if (s->isDefined()) + checkGlobalType(s, file, type); + return s; } -void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { - LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); - StringRef Name = Sym->getName(); +void SymbolTable::addLazy(ArchiveFile *file, const Archive::Symbol *sym) { + LLVM_DEBUG(dbgs() << "addLazy: " << sym->getName() << "\n"); + StringRef name = sym->getName(); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insertName(Name); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insertName(name); - if (WasInserted) { - replaceSymbol(S, Name, 0, File, *Sym); + if (wasInserted) { + replaceSymbol(s, name, 0, file, *sym); return; } - if (!S->isUndefined()) + if (!s->isUndefined()) return; // The existing symbol is undefined, load a new one from the archive, // unless the the existing symbol is weak in which case replace the undefined // symbols with a LazySymbol. - if (S->isWeak()) { - const WasmSignature *OldSig = nullptr; + if (s->isWeak()) { + const WasmSignature *oldSig = nullptr; // In the case of an UndefinedFunction we need to preserve the expected // signature. - if (auto *F = dyn_cast(S)) - OldSig = F->Signature; + if (auto *f = dyn_cast(s)) + oldSig = f->signature; LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n"); - auto NewSym = replaceSymbol(S, Name, WASM_SYMBOL_BINDING_WEAK, - File, *Sym); - NewSym->Signature = OldSig; + auto newSym = replaceSymbol(s, name, WASM_SYMBOL_BINDING_WEAK, + file, *sym); + newSym->signature = oldSig; return; } LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); - File->addMember(Sym); + file->addMember(sym); } -bool SymbolTable::addComdat(StringRef Name) { - return ComdatGroups.insert(CachedHashStringRef(Name)).second; +bool SymbolTable::addComdat(StringRef name) { + return comdatGroups.insert(CachedHashStringRef(name)).second; } // The new signature doesn't match. Create a variant to the symbol with the // signature encoded in the name and return that instead. These symbols are // then unified later in handleSymbolVariants. -bool SymbolTable::getFunctionVariant(Symbol* Sym, const WasmSignature *Sig, - const InputFile *File, Symbol **Out) { - LLVM_DEBUG(dbgs() << "getFunctionVariant: " << Sym->getName() << " -> " - << " " << toString(*Sig) << "\n"); - Symbol *Variant = nullptr; +bool SymbolTable::getFunctionVariant(Symbol* sym, const WasmSignature *sig, + const InputFile *file, Symbol **out) { + LLVM_DEBUG(dbgs() << "getFunctionVariant: " << sym->getName() << " -> " + << " " << toString(*sig) << "\n"); + Symbol *variant = nullptr; // Linear search through symbol variants. Should never be more than two // or three entries here. - auto &Variants = SymVariants[CachedHashStringRef(Sym->getName())]; - if (Variants.empty()) - Variants.push_back(Sym); + auto &variants = symVariants[CachedHashStringRef(sym->getName())]; + if (variants.empty()) + variants.push_back(sym); - for (Symbol* V : Variants) { - if (*V->getSignature() == *Sig) { - Variant = V; + for (Symbol* v : variants) { + if (*v->getSignature() == *sig) { + variant = v; break; } } - bool WasAdded = !Variant; - if (WasAdded) { + bool wasAdded = !variant; + if (wasAdded) { // Create a new variant; LLVM_DEBUG(dbgs() << "added new variant\n"); - Variant = reinterpret_cast(make()); - Variants.push_back(Variant); + variant = reinterpret_cast(make()); + variants.push_back(variant); } else { - LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*Variant) << "\n"); - assert(*Variant->getSignature() == *Sig); + LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n"); + assert(*variant->getSignature() == *sig); } - *Out = Variant; - return WasAdded; + *out = variant; + return wasAdded; } // Set a flag for --trace-symbol so that we can print out a log message // if a new symbol with the same name is inserted into the symbol table. -void SymbolTable::trace(StringRef Name) { - SymMap.insert({CachedHashStringRef(Name), -1}); +void SymbolTable::trace(StringRef name) { + symMap.insert({CachedHashStringRef(name), -1}); } -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 &OrigIdx = SymMap[CachedHashStringRef(Sym->getName())]; - int &RealIdx= SymMap[CachedHashStringRef(Real->getName())]; - int &WrapIdx = SymMap[CachedHashStringRef(Wrap->getName())]; - LLVM_DEBUG(dbgs() << "wrap: " << Sym->getName() << "\n"); + int &origIdx = symMap[CachedHashStringRef(sym->getName())]; + int &realIdx= symMap[CachedHashStringRef(real->getName())]; + int &wrapIdx = symMap[CachedHashStringRef(wrap->getName())]; + LLVM_DEBUG(dbgs() << "wrap: " << sym->getName() << "\n"); // Anyone looking up __real symbols should get the original - RealIdx = OrigIdx; + realIdx = origIdx; // Anyone looking up the original should get the __wrap symbol - OrigIdx = WrapIdx; + origIdx = wrapIdx; } -static const uint8_t UnreachableFn[] = { +static const uint8_t unreachableFn[] = { 0x03 /* ULEB length */, 0x00 /* ULEB num locals */, 0x00 /* opcode unreachable */, 0x0b /* opcode end */ }; @@ -579,15 +579,15 @@ static const uint8_t UnreachableFn[] = { // This is used by handleWeakUndefines in order to generate a callable // equivalent of an undefined function and also handleSymbolVariants for // undefined functions that don't match the signature of the definition. -InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym, - const WasmSignature &Sig, - StringRef DebugName) { - auto *Func = make(Sig, Sym->getName(), DebugName); - Func->setBody(UnreachableFn); - SyntheticFunctions.emplace_back(Func); - replaceSymbol(Sym, Sym->getName(), Sym->getFlags(), nullptr, - Func); - return Func; +InputFunction *SymbolTable::replaceWithUnreachable(Symbol *sym, + const WasmSignature &sig, + StringRef debugName) { + auto *func = make(sig, sym->getName(), debugName); + func->setBody(unreachableFn); + syntheticFunctions.emplace_back(func); + replaceSymbol(sym, sym->getName(), sym->getFlags(), nullptr, + func); + return func; } // For weak undefined functions, there may be "call" instructions that reference @@ -595,41 +595,41 @@ InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym, // will abort at runtime, so that relocations can still provided an operand to // the call instruction that passes Wasm validation. void SymbolTable::handleWeakUndefines() { - for (Symbol *Sym : getSymbols()) { - if (!Sym->isUndefWeak()) + for (Symbol *sym : getSymbols()) { + if (!sym->isUndefWeak()) continue; - const WasmSignature *Sig = Sym->getSignature(); - if (!Sig) { + const WasmSignature *sig = sym->getSignature(); + if (!sig) { // It is possible for undefined functions not to have a signature (eg. if // added via "--undefined"), but weak undefined ones do have a signature. // Lazy symbols may not be functions and therefore Sig can still be null // in some circumstantce. - assert(!isa(Sym)); + assert(!isa(sym)); continue; } // Add a synthetic dummy for weak undefined functions. These dummies will // be GC'd if not used as the target of any "call" instructions. - StringRef DebugName = Saver.save("undefined:" + toString(*Sym)); - InputFunction* Func = replaceWithUnreachable(Sym, *Sig, DebugName); + StringRef debugName = saver.save("undefined:" + toString(*sym)); + InputFunction* func = replaceWithUnreachable(sym, *sig, debugName); // Ensure it compares equal to the null pointer, and so that table relocs // don't pull in the stub body (only call-operand relocs should do that). - Func->setTableIndex(0); + func->setTableIndex(0); // Hide our dummy to prevent export. - Sym->setHidden(true); + sym->setHidden(true); } } -static void reportFunctionSignatureMismatch(StringRef SymName, - FunctionSymbol *A, - FunctionSymbol *B, bool IsError) { - std::string msg = ("function signature mismatch: " + SymName + - "\n>>> defined as " + toString(*A->Signature) + " in " + - toString(A->getFile()) + "\n>>> defined as " + - toString(*B->Signature) + " in " + toString(B->getFile())) +static void reportFunctionSignatureMismatch(StringRef symName, + FunctionSymbol *a, + FunctionSymbol *b, bool isError) { + std::string msg = ("function signature mismatch: " + symName + + "\n>>> defined as " + toString(*a->signature) + " in " + + toString(a->getFile()) + "\n>>> defined as " + + toString(*b->signature) + " in " + toString(b->getFile())) .str(); - if (IsError) + if (isError) error(msg); else warn(msg); @@ -638,26 +638,26 @@ static void reportFunctionSignatureMismatch(StringRef SymName, // Remove any variant symbols that were created due to function signature // mismatches. void SymbolTable::handleSymbolVariants() { - for (auto Pair : SymVariants) { + for (auto pair : symVariants) { // Push the initial symbol onto the list of variants. - StringRef SymName = Pair.first.val(); - std::vector &Variants = Pair.second; + StringRef symName = pair.first.val(); + std::vector &variants = pair.second; #ifndef NDEBUG - LLVM_DEBUG(dbgs() << "symbol with (" << Variants.size() - << ") variants: " << SymName << "\n"); - for (auto *S: Variants) { - auto *F = cast(S); - LLVM_DEBUG(dbgs() << " variant: " + F->getName() << " " - << toString(*F->Signature) << "\n"); + LLVM_DEBUG(dbgs() << "symbol with (" << variants.size() + << ") variants: " << symName << "\n"); + for (auto *s: variants) { + auto *f = cast(s); + LLVM_DEBUG(dbgs() << " variant: " + f->getName() << " " + << toString(*f->signature) << "\n"); } #endif // Find the one definition. - DefinedFunction *Defined = nullptr; - for (auto *Symbol : Variants) { - if (auto F = dyn_cast(Symbol)) { - Defined = F; + DefinedFunction *defined = nullptr; + for (auto *symbol : variants) { + if (auto f = dyn_cast(symbol)) { + defined = f; break; } } @@ -665,19 +665,19 @@ void SymbolTable::handleSymbolVariants() { // If there are no definitions, and the undefined symbols disagree on // the signature, there is not we can do since we don't know which one // to use as the signature on the import. - if (!Defined) { - reportFunctionSignatureMismatch(SymName, - cast(Variants[0]), - cast(Variants[1]), true); + if (!defined) { + reportFunctionSignatureMismatch(symName, + cast(variants[0]), + cast(variants[1]), true); return; } - for (auto *Symbol : Variants) { - if (Symbol != Defined) { - auto *F = cast(Symbol); - reportFunctionSignatureMismatch(SymName, F, Defined, false); - StringRef DebugName = Saver.save("unreachable:" + toString(*F)); - replaceWithUnreachable(F, *F->Signature, DebugName); + for (auto *symbol : variants) { + if (symbol != defined) { + auto *f = cast(symbol); + reportFunctionSignatureMismatch(symName, f, defined, false); + StringRef debugName = saver.save("unreachable:" + toString(*f)); + replaceWithUnreachable(f, *f->signature, debugName); } } } diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index d98d327..33f02dd 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -35,89 +35,89 @@ class InputSegment; // There 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 addFile(InputFile *File); + void addFile(InputFile *file); void addCombinedLTOObject(); - ArrayRef getSymbols() const { return SymVector; } + ArrayRef getSymbols() const { return symVector; } - Symbol *find(StringRef Name); + Symbol *find(StringRef name); - void replace(StringRef Name, Symbol* Sym); + void replace(StringRef name, Symbol* sym); - void trace(StringRef Name); + void trace(StringRef name); - Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, - InputFunction *Function); - Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File, - InputSegment *Segment, uint32_t Address, - uint32_t Size); - Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *G); - Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *E); + Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file, + InputFunction *function); + Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file, + InputSegment *segment, uint32_t address, + uint32_t size); + Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *g); + Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *e); - Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, const WasmSignature *Signature, - bool IsCalledDirectly); - Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); - Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, const WasmGlobalType *Type); + Symbol *addUndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, const WasmSignature *signature, + bool isCalledDirectly); + Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file); + Symbol *addUndefinedGlobal(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, const WasmGlobalType *type); - void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym); + void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym); - bool addComdat(StringRef Name); + bool addComdat(StringRef name); - DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); - DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, - InputGlobal *Global); - DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags, - InputFunction *Function); - DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value = 0, - uint32_t Flags = 0); + DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags); + DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags, + InputGlobal *global); + DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags, + InputFunction *function); + DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0, + uint32_t flags = 0); void handleSymbolVariants(); void handleWeakUndefines(); - std::vector ObjectFiles; - std::vector SharedFiles; - std::vector BitcodeFiles; - std::vector SyntheticFunctions; - std::vector SyntheticGlobals; + std::vector objectFiles; + std::vector sharedFiles; + std::vector bitcodeFiles; + std::vector syntheticFunctions; + std::vector syntheticGlobals; private: - std::pair insert(StringRef Name, const InputFile *File); - std::pair insertName(StringRef Name); + std::pair insert(StringRef name, const InputFile *file); + std::pair insertName(StringRef name); - bool getFunctionVariant(Symbol* Sym, const WasmSignature *Sig, - const InputFile *File, Symbol **Out); - InputFunction *replaceWithUnreachable(Symbol *Sym, const WasmSignature &Sig, - StringRef DebugName); + bool getFunctionVariant(Symbol* sym, const WasmSignature *sig, + const InputFile *file, Symbol **out); + InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig, + StringRef debugName); // Maps symbol names to index into the SymVector. -1 means that symbols // is to not yet in the vector but it should have tracing enabled if it is // ever added. - llvm::DenseMap SymMap; - std::vector SymVector; + llvm::DenseMap symMap; + std::vector symVector; // For certain symbols types, e.g. function symbols, we allow for muliple // variants of the same symbol with different signatures. - llvm::DenseMap> SymVariants; + llvm::DenseMap> symVariants; // 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 set // is used to uniquify them. - llvm::DenseSet ComdatGroups; + llvm::DenseSet comdatGroups; // For LTO. - std::unique_ptr LTO; + std::unique_ptr lto; }; -extern SymbolTable *Symtab; +extern SymbolTable *symtab; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 941f500..61868f3 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -24,16 +24,16 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -DefinedFunction *WasmSym::CallCtors; -DefinedFunction *WasmSym::InitMemory; -DefinedFunction *WasmSym::ApplyRelocs; -DefinedData *WasmSym::DsoHandle; -DefinedData *WasmSym::DataEnd; -DefinedData *WasmSym::GlobalBase; -DefinedData *WasmSym::HeapBase; -GlobalSymbol *WasmSym::StackPointer; -UndefinedGlobal *WasmSym::TableBase; -UndefinedGlobal *WasmSym::MemoryBase; +DefinedFunction *WasmSym::callCtors; +DefinedFunction *WasmSym::initMemory; +DefinedFunction *WasmSym::applyRelocs; +DefinedData *WasmSym::dsoHandle; +DefinedData *WasmSym::dataEnd; +DefinedData *WasmSym::globalBase; +DefinedData *WasmSym::heapBase; +GlobalSymbol *WasmSym::stackPointer; +UndefinedGlobal *WasmSym::tableBase; +UndefinedGlobal *WasmSym::memoryBase; WasmSymbolType Symbol::getWasmType() const { if (isa(this)) @@ -50,248 +50,248 @@ WasmSymbolType Symbol::getWasmType() const { } const WasmSignature *Symbol::getSignature() const { - if (auto* F = dyn_cast(this)) - return F->Signature; - if (auto *L = dyn_cast(this)) - return L->Signature; + if (auto* f = dyn_cast(this)) + return f->signature; + if (auto *l = dyn_cast(this)) + return l->signature; return nullptr; } InputChunk *Symbol::getChunk() const { - if (auto *F = dyn_cast(this)) - return F->Function; - if (auto *D = dyn_cast(this)) - return D->Segment; + if (auto *f = dyn_cast(this)) + return f->function; + if (auto *d = dyn_cast(this)) + return d->segment; return nullptr; } bool Symbol::isDiscarded() const { - if (InputChunk *C = getChunk()) - return C->Discarded; + if (InputChunk *c = getChunk()) + return c->discarded; return false; } bool Symbol::isLive() const { - if (auto *G = dyn_cast(this)) - return G->Global->Live; - if (auto *E = dyn_cast(this)) - return E->Event->Live; - if (InputChunk *C = getChunk()) - return C->Live; - return Referenced; + if (auto *g = dyn_cast(this)) + return g->global->live; + if (auto *e = dyn_cast(this)) + return e->event->live; + if (InputChunk *c = getChunk()) + return c->live; + return referenced; } void Symbol::markLive() { assert(!isDiscarded()); - if (auto *G = dyn_cast(this)) - G->Global->Live = true; - if (auto *E = dyn_cast(this)) - E->Event->Live = true; - if (InputChunk *C = getChunk()) - C->Live = true; - Referenced = true; + if (auto *g = dyn_cast(this)) + g->global->live = true; + if (auto *e = dyn_cast(this)) + e->event->live = true; + if (InputChunk *c = getChunk()) + c->live = true; + referenced = true; } uint32_t Symbol::getOutputSymbolIndex() const { - assert(OutputSymbolIndex != INVALID_INDEX); - return OutputSymbolIndex; + assert(outputSymbolIndex != INVALID_INDEX); + return outputSymbolIndex; } -void Symbol::setOutputSymbolIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index +void Symbol::setOutputSymbolIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << name << " -> " << index << "\n"); - assert(OutputSymbolIndex == INVALID_INDEX); - OutputSymbolIndex = Index; + assert(outputSymbolIndex == INVALID_INDEX); + outputSymbolIndex = index; } -void Symbol::setGOTIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setGOTIndex " << Name << " -> " << Index << "\n"); - assert(GOTIndex == INVALID_INDEX); +void Symbol::setGOTIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setGOTIndex " << name << " -> " << index << "\n"); + assert(gotIndex == INVALID_INDEX); // Any symbol that is assigned a GOT entry must be exported othewise the // dynamic linker won't be able create the entry that contains it. - ForceExport = true; - GOTIndex = Index; + forceExport = true; + gotIndex = index; } bool Symbol::isWeak() const { - return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; + return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; } bool Symbol::isLocal() const { - return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; + return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; } bool Symbol::isHidden() const { - return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; + return (flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; } -void Symbol::setHidden(bool IsHidden) { - LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n"); - Flags &= ~WASM_SYMBOL_VISIBILITY_MASK; - if (IsHidden) - Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; +void Symbol::setHidden(bool isHidden) { + LLVM_DEBUG(dbgs() << "setHidden: " << name << " -> " << isHidden << "\n"); + flags &= ~WASM_SYMBOL_VISIBILITY_MASK; + if (isHidden) + flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; else - Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; + flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } bool Symbol::isExported() const { if (!isDefined() || isLocal()) return false; - if (ForceExport || Config->ExportAll) + if (forceExport || config->exportAll) return true; - if (Config->ExportDynamic && !isHidden()) + if (config->exportDynamic && !isHidden()) return true; - return Flags & WASM_SYMBOL_EXPORTED; + return flags & WASM_SYMBOL_EXPORTED; } uint32_t FunctionSymbol::getFunctionIndex() const { - if (auto *F = dyn_cast(this)) - return F->Function->getFunctionIndex(); - assert(FunctionIndex != INVALID_INDEX); - return FunctionIndex; + if (auto *f = dyn_cast(this)) + return f->function->getFunctionIndex(); + assert(functionIndex != INVALID_INDEX); + return functionIndex; } -void FunctionSymbol::setFunctionIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n"); - assert(FunctionIndex == INVALID_INDEX); - FunctionIndex = Index; +void FunctionSymbol::setFunctionIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setFunctionIndex " << name << " -> " << index << "\n"); + assert(functionIndex == INVALID_INDEX); + functionIndex = index; } bool FunctionSymbol::hasFunctionIndex() const { - if (auto *F = dyn_cast(this)) - return F->Function->hasFunctionIndex(); - return FunctionIndex != INVALID_INDEX; + if (auto *f = dyn_cast(this)) + return f->function->hasFunctionIndex(); + return functionIndex != INVALID_INDEX; } uint32_t FunctionSymbol::getTableIndex() const { - if (auto *F = dyn_cast(this)) - return F->Function->getTableIndex(); - assert(TableIndex != INVALID_INDEX); - return TableIndex; + if (auto *f = dyn_cast(this)) + return f->function->getTableIndex(); + assert(tableIndex != INVALID_INDEX); + return tableIndex; } bool FunctionSymbol::hasTableIndex() const { - if (auto *F = dyn_cast(this)) - return F->Function->hasTableIndex(); - return TableIndex != INVALID_INDEX; + if (auto *f = dyn_cast(this)) + return f->function->hasTableIndex(); + return tableIndex != INVALID_INDEX; } -void FunctionSymbol::setTableIndex(uint32_t Index) { +void FunctionSymbol::setTableIndex(uint32_t index) { // For imports, we set the table index here on the Symbol; for defined // functions we set the index on the InputFunction so that we don't export // the same thing twice (keeps the table size down). - if (auto *F = dyn_cast(this)) { - F->Function->setTableIndex(Index); + if (auto *f = dyn_cast(this)) { + f->function->setTableIndex(index); return; } - LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); - assert(TableIndex == INVALID_INDEX); - TableIndex = Index; + LLVM_DEBUG(dbgs() << "setTableIndex " << name << " -> " << index << "\n"); + assert(tableIndex == INVALID_INDEX); + tableIndex = index; } -DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, - InputFunction *Function) - : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, - Function ? &Function->Signature : nullptr), - Function(Function) {} +DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f, + InputFunction *function) + : FunctionSymbol(name, DefinedFunctionKind, flags, f, + function ? &function->signature : nullptr), + function(function) {} uint32_t DefinedData::getVirtualAddress() const { LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); - if (Segment) - return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset; - return Offset; + if (segment) + return segment->outputSeg->startVA + segment->outputSegmentOffset + offset; + return offset; } -void DefinedData::setVirtualAddress(uint32_t Value) { - LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); - assert(!Segment); - Offset = Value; +void DefinedData::setVirtualAddress(uint32_t value) { + LLVM_DEBUG(dbgs() << "setVirtualAddress " << name << " -> " << value << "\n"); + assert(!segment); + offset = value; } uint32_t DefinedData::getOutputSegmentOffset() const { LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); - return Segment->OutputSegmentOffset + Offset; + return segment->outputSegmentOffset + offset; } uint32_t DefinedData::getOutputSegmentIndex() const { LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n"); - return Segment->OutputSeg->Index; + return segment->outputSeg->index; } uint32_t GlobalSymbol::getGlobalIndex() const { - if (auto *F = dyn_cast(this)) - return F->Global->getGlobalIndex(); - assert(GlobalIndex != INVALID_INDEX); - return GlobalIndex; + if (auto *f = dyn_cast(this)) + return f->global->getGlobalIndex(); + assert(globalIndex != INVALID_INDEX); + return globalIndex; } -void GlobalSymbol::setGlobalIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n"); - assert(GlobalIndex == INVALID_INDEX); - GlobalIndex = Index; +void GlobalSymbol::setGlobalIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setGlobalIndex " << name << " -> " << index << "\n"); + assert(globalIndex == INVALID_INDEX); + globalIndex = index; } bool GlobalSymbol::hasGlobalIndex() const { - if (auto *F = dyn_cast(this)) - return F->Global->hasGlobalIndex(); - return GlobalIndex != INVALID_INDEX; + if (auto *f = dyn_cast(this)) + return f->global->hasGlobalIndex(); + return globalIndex != INVALID_INDEX; } -DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *Global) - : GlobalSymbol(Name, DefinedGlobalKind, Flags, File, - Global ? &Global->getType() : nullptr), - Global(Global) {} +DefinedGlobal::DefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *global) + : GlobalSymbol(name, DefinedGlobalKind, flags, file, + global ? &global->getType() : nullptr), + global(global) {} uint32_t EventSymbol::getEventIndex() const { - if (auto *F = dyn_cast(this)) - return F->Event->getEventIndex(); - assert(EventIndex != INVALID_INDEX); - return EventIndex; + if (auto *f = dyn_cast(this)) + return f->event->getEventIndex(); + assert(eventIndex != INVALID_INDEX); + return eventIndex; } -void EventSymbol::setEventIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setEventIndex " << Name << " -> " << Index << "\n"); - assert(EventIndex == INVALID_INDEX); - EventIndex = Index; +void EventSymbol::setEventIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setEventIndex " << name << " -> " << index << "\n"); + assert(eventIndex == INVALID_INDEX); + eventIndex = index; } bool EventSymbol::hasEventIndex() const { - if (auto *F = dyn_cast(this)) - return F->Event->hasEventIndex(); - return EventIndex != INVALID_INDEX; + if (auto *f = dyn_cast(this)) + return f->event->hasEventIndex(); + return eventIndex != INVALID_INDEX; } -DefinedEvent::DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *Event) - : EventSymbol(Name, DefinedEventKind, Flags, File, - Event ? &Event->getType() : nullptr, - Event ? &Event->Signature : nullptr), - Event(Event) {} +DefinedEvent::DefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *event) + : EventSymbol(name, DefinedEventKind, flags, file, + event ? &event->getType() : nullptr, + event ? &event->signature : nullptr), + event(event) {} const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const { - assert(Section->OutputSec && Section->OutputSec->SectionSym); - return Section->OutputSec->SectionSym; + assert(section->outputSec && section->outputSec->sectionSym); + return section->outputSec->sectionSym; } -void LazySymbol::fetch() { cast(File)->addMember(&ArchiveSymbol); } +void LazySymbol::fetch() { cast(file)->addMember(&archiveSymbol); } -std::string lld::toString(const wasm::Symbol &Sym) { - return lld::maybeDemangleSymbol(Sym.getName()); +std::string lld::toString(const wasm::Symbol &sym) { + return lld::maybeDemangleSymbol(sym.getName()); } -std::string lld::maybeDemangleSymbol(StringRef Name) { - if (Config->Demangle) - if (Optional S = demangleItanium(Name)) - return *S; - return Name; +std::string lld::maybeDemangleSymbol(StringRef name) { + if (config->demangle) + if (Optional s = demangleItanium(name)) + return *s; + return name; } -std::string lld::toString(wasm::Symbol::Kind Kind) { - switch (Kind) { +std::string lld::toString(wasm::Symbol::Kind kind) { + switch (kind) { case wasm::Symbol::DefinedFunctionKind: return "DefinedFunction"; case wasm::Symbol::DefinedDataKind: @@ -317,24 +317,24 @@ std::string lld::toString(wasm::Symbol::Kind Kind) { } -void lld::wasm::printTraceSymbolUndefined(StringRef Name, const InputFile* File) { - message(toString(File) + ": reference to " + Name); +void lld::wasm::printTraceSymbolUndefined(StringRef name, const InputFile* file) { + message(toString(file) + ": reference to " + name); } // Print out a log message for --trace-symbol. -void lld::wasm::printTraceSymbol(Symbol *Sym) { +void lld::wasm::printTraceSymbol(Symbol *sym) { // Undefined symbols are traced via printTraceSymbolUndefined - if (Sym->isUndefined()) + if (sym->isUndefined()) return; - std::string S; - if (Sym->isLazy()) - S = ": lazy definition of "; + std::string s; + if (sym->isLazy()) + s = ": lazy definition of "; else - S = ": definition of "; + s = ": definition of "; - message(toString(Sym->getFile()) + S + Sym->getName()); + message(toString(sym->getFile()) + s + sym->getName()); } -const char *lld::wasm::DefaultModule = "env"; -const char *lld::wasm::FunctionTableName = "__indirect_function_table"; +const char *lld::wasm::defaultModule = "env"; +const char *lld::wasm::functionTableName = "__indirect_function_table"; diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index cb46913..499a265 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -20,10 +20,10 @@ namespace wasm { // Shared string constants // The default module name to use for symbol imports. -extern const char *DefaultModule; +extern const char *defaultModule; // The name under which to import or export the wasm table. -extern const char *FunctionTableName; +extern const char *functionTableName; using llvm::wasm::WasmSymbolType; @@ -54,16 +54,16 @@ public: LazyKind, }; - Kind kind() const { return SymbolKind; } + Kind kind() const { return symbolKind; } bool isDefined() const { return !isLazy() && !isUndefined(); } bool isUndefined() const { - return SymbolKind == UndefinedFunctionKind || - SymbolKind == UndefinedDataKind || SymbolKind == UndefinedGlobalKind; + return symbolKind == UndefinedFunctionKind || + symbolKind == UndefinedDataKind || symbolKind == UndefinedGlobalKind; } - bool isLazy() const { return SymbolKind == LazyKind; } + bool isLazy() const { return symbolKind == LazyKind; } bool isLocal() const; bool isWeak() const; @@ -80,12 +80,12 @@ public: } // Returns the symbol name. - StringRef getName() const { return Name; } + StringRef getName() const { return name; } // Returns the file from which this symbol was created. - InputFile *getFile() const { return File; } + InputFile *getFile() const { return file; } - uint32_t getFlags() const { return Flags; } + uint32_t getFlags() const { return flags; } InputChunk *getChunk() const; @@ -97,120 +97,120 @@ public: // final image. void markLive(); - void setHidden(bool IsHidden); + void setHidden(bool isHidden); // Get/set the index in the output symbol table. This is only used for // relocatable output. uint32_t getOutputSymbolIndex() const; - void setOutputSymbolIndex(uint32_t Index); + void setOutputSymbolIndex(uint32_t index); WasmSymbolType getWasmType() const; bool isExported() const; const WasmSignature* getSignature() const; - bool isInGOT() const { return GOTIndex != INVALID_INDEX; } + bool isInGOT() const { return gotIndex != INVALID_INDEX; } uint32_t getGOTIndex() const { - assert(GOTIndex != INVALID_INDEX); - return GOTIndex; + assert(gotIndex != INVALID_INDEX); + return gotIndex; } - void setGOTIndex(uint32_t Index); - bool hasGOTIndex() const { return GOTIndex != INVALID_INDEX; } + void setGOTIndex(uint32_t index); + bool hasGOTIndex() const { return gotIndex != INVALID_INDEX; } protected: - Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) - : Name(Name), File(F), Flags(Flags), SymbolKind(K), - Referenced(!Config->GcSections), IsUsedInRegularObj(false), - ForceExport(false), CanInline(false), Traced(false) {} - - StringRef Name; - InputFile *File; - uint32_t Flags; - uint32_t OutputSymbolIndex = INVALID_INDEX; - uint32_t GOTIndex = INVALID_INDEX; - Kind SymbolKind; + Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f) + : name(name), file(f), flags(flags), symbolKind(k), + referenced(!config->gcSections), isUsedInRegularObj(false), + forceExport(false), canInline(false), traced(false) {} + + StringRef name; + InputFile *file; + uint32_t flags; + uint32_t outputSymbolIndex = INVALID_INDEX; + uint32_t gotIndex = INVALID_INDEX; + Kind symbolKind; public: - bool Referenced : 1; + bool referenced : 1; // 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. - bool IsUsedInRegularObj : 1; + bool isUsedInRegularObj : 1; // True if ths symbol is explicity marked for export (i.e. via the -e/--export // command line flag) - bool ForceExport : 1; + bool forceExport : 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. - bool CanInline : 1; + bool canInline : 1; // True if this symbol is specified by --trace-symbol option. - bool Traced : 1; + bool traced : 1; }; class FunctionSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedFunctionKind || - S->kind() == UndefinedFunctionKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedFunctionKind || + s->kind() == UndefinedFunctionKind; } // Get/set the table index - void setTableIndex(uint32_t Index); + void setTableIndex(uint32_t index); uint32_t getTableIndex() const; bool hasTableIndex() const; // Get/set the function index uint32_t getFunctionIndex() const; - void setFunctionIndex(uint32_t Index); + void setFunctionIndex(uint32_t index); bool hasFunctionIndex() const; - const WasmSignature *Signature; + const WasmSignature *signature; protected: - FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmSignature *Sig) - : Symbol(Name, K, Flags, F), Signature(Sig) {} + FunctionSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmSignature *sig) + : Symbol(name, k, flags, f), signature(sig) {} - uint32_t TableIndex = INVALID_INDEX; - uint32_t FunctionIndex = INVALID_INDEX; + uint32_t tableIndex = INVALID_INDEX; + uint32_t functionIndex = INVALID_INDEX; }; class DefinedFunction : public FunctionSymbol { public: - DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, - InputFunction *Function); + DefinedFunction(StringRef name, uint32_t flags, InputFile *f, + InputFunction *function); - static bool classof(const Symbol *S) { - return S->kind() == DefinedFunctionKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedFunctionKind; } - InputFunction *Function; + InputFunction *function; }; class UndefinedFunction : public FunctionSymbol { public: - UndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File = nullptr, - const WasmSignature *Type = nullptr, - bool IsCalledDirectly = true) - : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type), - ImportName(ImportName), ImportModule(ImportModule), IsCalledDirectly(IsCalledDirectly) {} - - static bool classof(const Symbol *S) { - return S->kind() == UndefinedFunctionKind; + UndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file = nullptr, + const WasmSignature *type = nullptr, + bool isCalledDirectly = true) + : FunctionSymbol(name, UndefinedFunctionKind, flags, file, type), + importName(importName), importModule(importModule), isCalledDirectly(isCalledDirectly) {} + + static bool classof(const Symbol *s) { + return s->kind() == UndefinedFunctionKind; } - StringRef ImportName; - StringRef ImportModule; - bool IsCalledDirectly; + StringRef importName; + StringRef importModule; + bool isCalledDirectly; }; // Section symbols for output sections are different from those for input @@ -218,128 +218,128 @@ public: // rather than an InputSection. class OutputSectionSymbol : public Symbol { public: - OutputSectionSymbol(const OutputSection *S) + OutputSectionSymbol(const OutputSection *s) : Symbol("", OutputSectionKind, llvm::wasm::WASM_SYMBOL_BINDING_LOCAL, nullptr), - Section(S) {} + section(s) {} - static bool classof(const Symbol *S) { - return S->kind() == OutputSectionKind; + static bool classof(const Symbol *s) { + return s->kind() == OutputSectionKind; } - const OutputSection *Section; + const OutputSection *section; }; class SectionSymbol : public Symbol { public: - SectionSymbol(uint32_t Flags, const InputSection *S, InputFile *F = nullptr) - : Symbol("", SectionKind, Flags, F), Section(S) {} + SectionSymbol(uint32_t flags, const InputSection *s, InputFile *f = nullptr) + : Symbol("", SectionKind, flags, f), section(s) {} - static bool classof(const Symbol *S) { return S->kind() == SectionKind; } + static bool classof(const Symbol *s) { return s->kind() == SectionKind; } const OutputSectionSymbol *getOutputSectionSymbol() const; - const InputSection *Section; + const InputSection *section; }; class DataSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedDataKind || S->kind() == UndefinedDataKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedDataKind || s->kind() == UndefinedDataKind; } protected: - DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) - : Symbol(Name, K, Flags, F) {} + DataSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f) + : Symbol(name, k, flags, f) {} }; class DefinedData : public DataSymbol { public: // Constructor for regular data symbols originating from input files. - DefinedData(StringRef Name, uint32_t Flags, InputFile *F, - InputSegment *Segment, uint32_t Offset, uint32_t Size) - : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment), - Offset(Offset), Size(Size) {} + DefinedData(StringRef name, uint32_t flags, InputFile *f, + InputSegment *segment, uint32_t offset, uint32_t size) + : DataSymbol(name, DefinedDataKind, flags, f), segment(segment), + offset(offset), size(size) {} // Constructor for linker synthetic data symbols. - DefinedData(StringRef Name, uint32_t Flags) - : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {} + DefinedData(StringRef name, uint32_t flags) + : DataSymbol(name, DefinedDataKind, flags, nullptr) {} - static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedDataKind; } // Returns the output virtual address of a defined data symbol. uint32_t getVirtualAddress() const; - void setVirtualAddress(uint32_t VA); + void setVirtualAddress(uint32_t va); // Returns the offset of a defined data symbol within its OutputSegment. uint32_t getOutputSegmentOffset() const; uint32_t getOutputSegmentIndex() const; - uint32_t getSize() const { return Size; } + uint32_t getSize() const { return size; } - InputSegment *Segment = nullptr; + InputSegment *segment = nullptr; protected: - uint32_t Offset = 0; - uint32_t Size = 0; + uint32_t offset = 0; + uint32_t size = 0; }; class UndefinedData : public DataSymbol { public: - UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr) - : DataSymbol(Name, UndefinedDataKind, Flags, File) {} - static bool classof(const Symbol *S) { - return S->kind() == UndefinedDataKind; + UndefinedData(StringRef name, uint32_t flags, InputFile *file = nullptr) + : DataSymbol(name, UndefinedDataKind, flags, file) {} + static bool classof(const Symbol *s) { + return s->kind() == UndefinedDataKind; } }; class GlobalSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedGlobalKind || s->kind() == UndefinedGlobalKind; } - const WasmGlobalType *getGlobalType() const { return GlobalType; } + const WasmGlobalType *getGlobalType() const { return globalType; } // Get/set the global index uint32_t getGlobalIndex() const; - void setGlobalIndex(uint32_t Index); + void setGlobalIndex(uint32_t index); bool hasGlobalIndex() const; protected: - GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmGlobalType *GlobalType) - : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {} + GlobalSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmGlobalType *globalType) + : Symbol(name, k, flags, f), globalType(globalType) {} - const WasmGlobalType *GlobalType; - uint32_t GlobalIndex = INVALID_INDEX; + const WasmGlobalType *globalType; + uint32_t globalIndex = INVALID_INDEX; }; class DefinedGlobal : public GlobalSymbol { public: - DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *Global); + DefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *global); - static bool classof(const Symbol *S) { - return S->kind() == DefinedGlobalKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedGlobalKind; } - InputGlobal *Global; + InputGlobal *global; }; class UndefinedGlobal : public GlobalSymbol { public: - UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule, - uint32_t Flags, InputFile *File = nullptr, - const WasmGlobalType *Type = nullptr) - : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type), - ImportName(ImportName), ImportModule(ImportModule) {} - - static bool classof(const Symbol *S) { - return S->kind() == UndefinedGlobalKind; + UndefinedGlobal(StringRef name, StringRef importName, StringRef importModule, + uint32_t flags, InputFile *file = nullptr, + const WasmGlobalType *type = nullptr) + : GlobalSymbol(name, UndefinedGlobalKind, flags, file, type), + importName(importName), importModule(importModule) {} + + static bool classof(const Symbol *s) { + return s->kind() == UndefinedGlobalKind; } - StringRef ImportName; - StringRef ImportModule; + StringRef importName; + StringRef importModule; }; // Wasm events are features that suspend the current execution and transfer the @@ -356,34 +356,34 @@ public: // are used, and has name '__cpp_exception' for linking. class EventSymbol : public Symbol { public: - static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; } - const WasmEventType *getEventType() const { return EventType; } + const WasmEventType *getEventType() const { return eventType; } // Get/set the event index uint32_t getEventIndex() const; - void setEventIndex(uint32_t Index); + void setEventIndex(uint32_t index); bool hasEventIndex() const; - const WasmSignature *Signature; + const WasmSignature *signature; protected: - EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmEventType *EventType, const WasmSignature *Sig) - : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {} + EventSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmEventType *eventType, const WasmSignature *sig) + : Symbol(name, k, flags, f), signature(sig), eventType(eventType) {} - const WasmEventType *EventType; - uint32_t EventIndex = INVALID_INDEX; + const WasmEventType *eventType; + uint32_t eventIndex = INVALID_INDEX; }; class DefinedEvent : public EventSymbol { public: - DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *Event); + DefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *event); - static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; } - InputEvent *Event; + InputEvent *event; }; // LazySymbol represents a symbol that is not yet in the link, but we know where @@ -397,11 +397,11 @@ public: // symbols into consideration. class LazySymbol : public Symbol { public: - LazySymbol(StringRef Name, uint32_t Flags, InputFile *File, - const llvm::object::Archive::Symbol &Sym) - : Symbol(Name, LazyKind, Flags, File), ArchiveSymbol(Sym) {} + LazySymbol(StringRef name, uint32_t flags, InputFile *file, + const llvm::object::Archive::Symbol &sym) + : Symbol(name, LazyKind, flags, file), archiveSymbol(sym) {} - static bool classof(const Symbol *S) { return S->kind() == LazyKind; } + static bool classof(const Symbol *s) { return s->kind() == LazyKind; } void fetch(); // Lazy symbols can have a signature because they can replace an @@ -409,71 +409,71 @@ public: // signture. // TODO(sbc): This repetition of the signature field is inelegant. Revisit // the use of class hierarchy to represent symbol taxonomy. - const WasmSignature *Signature = nullptr; + const WasmSignature *signature = nullptr; private: - llvm::object::Archive::Symbol ArchiveSymbol; + llvm::object::Archive::Symbol archiveSymbol; }; // linker-generated symbols struct WasmSym { // __global_base // Symbol marking the start of the global section. - static DefinedData *GlobalBase; + static DefinedData *globalBase; // __stack_pointer // Global that holds the address of the top of the explicit value stack in // linear memory. - static GlobalSymbol *StackPointer; + static GlobalSymbol *stackPointer; // __data_end // Symbol marking the end of the data and bss. - static DefinedData *DataEnd; + static DefinedData *dataEnd; // __heap_base // Symbol marking the end of the data, bss and explicit stack. Any linear // memory following this address is not used by the linked code and can // therefore be used as a backing store for brk()/malloc() implementations. - static DefinedData *HeapBase; + static DefinedData *heapBase; // __wasm_call_ctors // Function that directly calls all ctors in priority order. - static DefinedFunction *CallCtors; + static DefinedFunction *callCtors; // __wasm_init_memory // Function that initializes passive data segments post-instantiation. - static DefinedFunction *InitMemory; + static DefinedFunction *initMemory; // __wasm_apply_relocs // Function that applies relocations to data segment post-instantiation. - static DefinedFunction *ApplyRelocs; + static DefinedFunction *applyRelocs; // __dso_handle // Symbol used in calls to __cxa_atexit to determine current DLL - static DefinedData *DsoHandle; + static DefinedData *dsoHandle; // __table_base // Used in PIC code for offset of indirect function table - static UndefinedGlobal *TableBase; + static UndefinedGlobal *tableBase; // __memory_base // Used in PIC code for offset of global data - static UndefinedGlobal *MemoryBase; + static UndefinedGlobal *memoryBase; }; // 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(DefinedFunction) char A[sizeof(DefinedFunction)]; - alignas(DefinedData) char B[sizeof(DefinedData)]; - alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)]; - alignas(DefinedEvent) char D[sizeof(DefinedEvent)]; - alignas(LazySymbol) char E[sizeof(LazySymbol)]; - alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)]; - alignas(UndefinedData) char G[sizeof(UndefinedData)]; - alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)]; - alignas(SectionSymbol) char I[sizeof(SectionSymbol)]; + alignas(DefinedFunction) char a[sizeof(DefinedFunction)]; + alignas(DefinedData) char b[sizeof(DefinedData)]; + alignas(DefinedGlobal) char c[sizeof(DefinedGlobal)]; + alignas(DefinedEvent) char d[sizeof(DefinedEvent)]; + alignas(LazySymbol) char e[sizeof(LazySymbol)]; + alignas(UndefinedFunction) char f[sizeof(UndefinedFunction)]; + alignas(UndefinedData) char g[sizeof(UndefinedData)]; + alignas(UndefinedGlobal) char h[sizeof(UndefinedGlobal)]; + alignas(SectionSymbol) char i[sizeof(SectionSymbol)]; }; // It is important to keep the size of SymbolUnion small for performance and @@ -481,11 +481,11 @@ union SymbolUnion { // UndefinedFunction on a 64-bit system. static_assert(sizeof(SymbolUnion) <= 96, "SymbolUnion too large"); -void printTraceSymbol(Symbol *Sym); -void printTraceSymbolUndefined(StringRef Name, const InputFile* File); +void printTraceSymbol(Symbol *sym); +void printTraceSymbolUndefined(StringRef name, const InputFile* file); template -T *replaceSymbol(Symbol *S, ArgT &&... Arg) { +T *replaceSymbol(Symbol *s, ArgT &&... arg) { static_assert(std::is_trivially_destructible(), "Symbol types must be trivially destructible"); static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); @@ -494,28 +494,28 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) { assert(static_cast(static_cast(nullptr)) == nullptr && "Not a Symbol"); - Symbol SymCopy = *S; + Symbol symCopy = *s; - T *S2 = new (S) T(std::forward(Arg)...); - S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj; - S2->ForceExport = SymCopy.ForceExport; - S2->CanInline = SymCopy.CanInline; - S2->Traced = SymCopy.Traced; + T *s2 = new (s) T(std::forward(arg)...); + s2->isUsedInRegularObj = symCopy.isUsedInRegularObj; + s2->forceExport = symCopy.forceExport; + s2->canInline = symCopy.canInline; + s2->traced = symCopy.traced; // Print out a log message if --trace-symbol was specified. // This is for debugging. - if (S2->Traced) - printTraceSymbol(S2); + if (s2->traced) + printTraceSymbol(s2); - return S2; + return s2; } } // namespace wasm // Returns a symbol name for an error message. -std::string toString(const wasm::Symbol &Sym); -std::string toString(wasm::Symbol::Kind Kind); -std::string maybeDemangleSymbol(StringRef Name); +std::string toString(const wasm::Symbol &sym); +std::string toString(wasm::Symbol::Kind kind); +std::string maybeDemangleSymbol(StringRef name); } // namespace lld diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index 8e8a0a1..020d2c0 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -25,7 +25,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -OutStruct lld::wasm::Out; +OutStruct lld::wasm::out; namespace { @@ -36,512 +36,512 @@ namespace { // of the parent section. class SubSection { public: - explicit SubSection(uint32_t Type) : Type(Type) {} + explicit SubSection(uint32_t type) : type(type) {} - void writeTo(raw_ostream &To) { - OS.flush(); - writeUleb128(To, Type, "subsection type"); - writeUleb128(To, Body.size(), "subsection size"); - To.write(Body.data(), Body.size()); + void writeTo(raw_ostream &to) { + os.flush(); + writeUleb128(to, type, "subsection type"); + writeUleb128(to, body.size(), "subsection size"); + to.write(body.data(), body.size()); } private: - uint32_t Type; - std::string Body; + uint32_t type; + std::string body; public: - raw_string_ostream OS{Body}; + raw_string_ostream os{body}; }; } // namespace void DylinkSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, MemSize, "MemSize"); - writeUleb128(OS, MemAlign, "MemAlign"); - writeUleb128(OS, Out.ElemSec->numEntries(), "TableSize"); - writeUleb128(OS, 0, "TableAlign"); - writeUleb128(OS, Symtab->SharedFiles.size(), "Needed"); - for (auto *SO : Symtab->SharedFiles) - writeStr(OS, llvm::sys::path::filename(SO->getName()), "so name"); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, memSize, "MemSize"); + writeUleb128(os, memAlign, "MemAlign"); + writeUleb128(os, out.elemSec->numEntries(), "TableSize"); + writeUleb128(os, 0, "TableAlign"); + writeUleb128(os, symtab->sharedFiles.size(), "Needed"); + for (auto *so : symtab->sharedFiles) + writeStr(os, llvm::sys::path::filename(so->getName()), "so name"); } -uint32_t TypeSection::registerType(const WasmSignature &Sig) { - auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); - if (Pair.second) { - LLVM_DEBUG(llvm::dbgs() << "type " << toString(Sig) << "\n"); - Types.push_back(&Sig); +uint32_t TypeSection::registerType(const WasmSignature &sig) { + auto pair = typeIndices.insert(std::make_pair(sig, types.size())); + if (pair.second) { + LLVM_DEBUG(llvm::dbgs() << "type " << toString(sig) << "\n"); + types.push_back(&sig); } - return Pair.first->second; + return pair.first->second; } -uint32_t TypeSection::lookupType(const WasmSignature &Sig) { - auto It = TypeIndices.find(Sig); - if (It == TypeIndices.end()) { - error("type not found: " + toString(Sig)); +uint32_t TypeSection::lookupType(const WasmSignature &sig) { + auto it = typeIndices.find(sig); + if (it == typeIndices.end()) { + error("type not found: " + toString(sig)); return 0; } - return It->second; + return it->second; } void TypeSection::writeBody() { - writeUleb128(BodyOutputStream, Types.size(), "type count"); - for (const WasmSignature *Sig : Types) - writeSig(BodyOutputStream, *Sig); + writeUleb128(bodyOutputStream, types.size(), "type count"); + for (const WasmSignature *sig : types) + writeSig(bodyOutputStream, *sig); } uint32_t ImportSection::getNumImports() const { - assert(IsSealed); - uint32_t NumImports = ImportedSymbols.size() + GOTSymbols.size(); - if (Config->ImportMemory) - ++NumImports; - if (Config->ImportTable) - ++NumImports; - return NumImports; + assert(isSealed); + uint32_t numImports = importedSymbols.size() + gotSymbols.size(); + if (config->importMemory) + ++numImports; + if (config->importTable) + ++numImports; + return numImports; } -void ImportSection::addGOTEntry(Symbol *Sym) { - assert(!IsSealed); - if (Sym->hasGOTIndex()) +void ImportSection::addGOTEntry(Symbol *sym) { + assert(!isSealed); + if (sym->hasGOTIndex()) return; - Sym->setGOTIndex(NumImportedGlobals++); - GOTSymbols.push_back(Sym); + sym->setGOTIndex(numImportedGlobals++); + gotSymbols.push_back(sym); } -void ImportSection::addImport(Symbol *Sym) { - assert(!IsSealed); - ImportedSymbols.emplace_back(Sym); - if (auto *F = dyn_cast(Sym)) - F->setFunctionIndex(NumImportedFunctions++); - else if (auto *G = dyn_cast(Sym)) - G->setGlobalIndex(NumImportedGlobals++); +void ImportSection::addImport(Symbol *sym) { + assert(!isSealed); + importedSymbols.emplace_back(sym); + if (auto *f = dyn_cast(sym)) + f->setFunctionIndex(numImportedFunctions++); + else if (auto *g = dyn_cast(sym)) + g->setGlobalIndex(numImportedGlobals++); else - cast(Sym)->setEventIndex(NumImportedEvents++); + cast(sym)->setEventIndex(numImportedEvents++); } void ImportSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, getNumImports(), "import count"); - - if (Config->ImportMemory) { - WasmImport Import; - Import.Module = DefaultModule; - Import.Field = "memory"; - Import.Kind = WASM_EXTERNAL_MEMORY; - Import.Memory.Flags = 0; - Import.Memory.Initial = Out.MemorySec->NumMemoryPages; - if (Out.MemorySec->MaxMemoryPages != 0 || Config->SharedMemory) { - Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; - Import.Memory.Maximum = Out.MemorySec->MaxMemoryPages; + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, getNumImports(), "import count"); + + if (config->importMemory) { + WasmImport import; + import.Module = defaultModule; + import.Field = "memory"; + import.Kind = WASM_EXTERNAL_MEMORY; + import.Memory.Flags = 0; + import.Memory.Initial = out.memorySec->numMemoryPages; + if (out.memorySec->maxMemoryPages != 0 || config->sharedMemory) { + import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; + import.Memory.Maximum = out.memorySec->maxMemoryPages; } - if (Config->SharedMemory) - Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; - writeImport(OS, Import); + if (config->sharedMemory) + import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; + writeImport(os, import); } - if (Config->ImportTable) { - uint32_t TableSize = Out.ElemSec->ElemOffset + Out.ElemSec->numEntries(); - WasmImport Import; - Import.Module = DefaultModule; - Import.Field = FunctionTableName; - Import.Kind = WASM_EXTERNAL_TABLE; - Import.Table.ElemType = WASM_TYPE_FUNCREF; - Import.Table.Limits = {0, TableSize, 0}; - writeImport(OS, Import); + if (config->importTable) { + uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); + WasmImport import; + import.Module = defaultModule; + import.Field = functionTableName; + import.Kind = WASM_EXTERNAL_TABLE; + import.Table.ElemType = WASM_TYPE_FUNCREF; + import.Table.Limits = {0, tableSize, 0}; + writeImport(os, import); } - for (const Symbol *Sym : ImportedSymbols) { - WasmImport Import; - if (auto *F = dyn_cast(Sym)) { - Import.Field = F->ImportName; - Import.Module = F->ImportModule; - } else if (auto *G = dyn_cast(Sym)) { - Import.Field = G->ImportName; - Import.Module = G->ImportModule; + for (const Symbol *sym : importedSymbols) { + WasmImport import; + if (auto *f = dyn_cast(sym)) { + import.Field = f->importName; + import.Module = f->importModule; + } else if (auto *g = dyn_cast(sym)) { + import.Field = g->importName; + import.Module = g->importModule; } else { - Import.Field = Sym->getName(); - Import.Module = DefaultModule; + import.Field = sym->getName(); + import.Module = defaultModule; } - if (auto *FunctionSym = dyn_cast(Sym)) { - Import.Kind = WASM_EXTERNAL_FUNCTION; - Import.SigIndex = Out.TypeSec->lookupType(*FunctionSym->Signature); - } else if (auto *GlobalSym = dyn_cast(Sym)) { - Import.Kind = WASM_EXTERNAL_GLOBAL; - Import.Global = *GlobalSym->getGlobalType(); + if (auto *functionSym = dyn_cast(sym)) { + import.Kind = WASM_EXTERNAL_FUNCTION; + import.SigIndex = out.typeSec->lookupType(*functionSym->signature); + } else if (auto *globalSym = dyn_cast(sym)) { + import.Kind = WASM_EXTERNAL_GLOBAL; + import.Global = *globalSym->getGlobalType(); } else { - auto *EventSym = cast(Sym); - Import.Kind = WASM_EXTERNAL_EVENT; - Import.Event.Attribute = EventSym->getEventType()->Attribute; - Import.Event.SigIndex = Out.TypeSec->lookupType(*EventSym->Signature); + auto *eventSym = cast(sym); + import.Kind = WASM_EXTERNAL_EVENT; + import.Event.Attribute = eventSym->getEventType()->Attribute; + import.Event.SigIndex = out.typeSec->lookupType(*eventSym->signature); } - writeImport(OS, Import); + writeImport(os, import); } - for (const Symbol *Sym : GOTSymbols) { - WasmImport Import; - Import.Kind = WASM_EXTERNAL_GLOBAL; - Import.Global = {WASM_TYPE_I32, true}; - if (isa(Sym)) - Import.Module = "GOT.mem"; + for (const Symbol *sym : gotSymbols) { + WasmImport import; + import.Kind = WASM_EXTERNAL_GLOBAL; + import.Global = {WASM_TYPE_I32, true}; + if (isa(sym)) + import.Module = "GOT.mem"; else - Import.Module = "GOT.func"; - Import.Field = Sym->getName(); - writeImport(OS, Import); + import.Module = "GOT.func"; + import.Field = sym->getName(); + writeImport(os, import); } } void FunctionSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, InputFunctions.size(), "function count"); - for (const InputFunction *Func : InputFunctions) - writeUleb128(OS, Out.TypeSec->lookupType(Func->Signature), "sig index"); + writeUleb128(os, inputFunctions.size(), "function count"); + for (const InputFunction *func : inputFunctions) + writeUleb128(os, out.typeSec->lookupType(func->signature), "sig index"); } -void FunctionSection::addFunction(InputFunction *Func) { - if (!Func->Live) +void FunctionSection::addFunction(InputFunction *func) { + if (!func->live) return; - uint32_t FunctionIndex = - Out.ImportSec->getNumImportedFunctions() + InputFunctions.size(); - InputFunctions.emplace_back(Func); - Func->setFunctionIndex(FunctionIndex); + uint32_t functionIndex = + out.importSec->getNumImportedFunctions() + inputFunctions.size(); + inputFunctions.emplace_back(func); + func->setFunctionIndex(functionIndex); } void TableSection::writeBody() { - uint32_t TableSize = Out.ElemSec->ElemOffset + Out.ElemSec->numEntries(); + uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); - raw_ostream &OS = BodyOutputStream; - writeUleb128(OS, 1, "table count"); - WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; - writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits}); + raw_ostream &os = bodyOutputStream; + writeUleb128(os, 1, "table count"); + WasmLimits limits = {WASM_LIMITS_FLAG_HAS_MAX, tableSize, tableSize}; + writeTableType(os, WasmTable{WASM_TYPE_FUNCREF, limits}); } void MemorySection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - bool HasMax = MaxMemoryPages != 0 || Config->SharedMemory; - writeUleb128(OS, 1, "memory count"); - unsigned Flags = 0; - if (HasMax) - Flags |= WASM_LIMITS_FLAG_HAS_MAX; - if (Config->SharedMemory) - Flags |= WASM_LIMITS_FLAG_IS_SHARED; - writeUleb128(OS, Flags, "memory limits flags"); - writeUleb128(OS, NumMemoryPages, "initial pages"); - if (HasMax) - writeUleb128(OS, MaxMemoryPages, "max pages"); + raw_ostream &os = bodyOutputStream; + + bool hasMax = maxMemoryPages != 0 || config->sharedMemory; + writeUleb128(os, 1, "memory count"); + unsigned flags = 0; + if (hasMax) + flags |= WASM_LIMITS_FLAG_HAS_MAX; + if (config->sharedMemory) + flags |= WASM_LIMITS_FLAG_IS_SHARED; + writeUleb128(os, flags, "memory limits flags"); + writeUleb128(os, numMemoryPages, "initial pages"); + if (hasMax) + writeUleb128(os, maxMemoryPages, "max pages"); } void GlobalSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, numGlobals(), "global count"); - for (const InputGlobal *G : InputGlobals) - writeGlobal(OS, G->Global); - for (const DefinedData *Sym : DefinedFakeGlobals) { - WasmGlobal Global; - Global.Type = {WASM_TYPE_I32, false}; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); - writeGlobal(OS, Global); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, numGlobals(), "global count"); + for (const InputGlobal *g : inputGlobals) + writeGlobal(os, g->global); + for (const DefinedData *sym : definedFakeGlobals) { + WasmGlobal global; + global.Type = {WASM_TYPE_I32, false}; + global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + global.InitExpr.Value.Int32 = sym->getVirtualAddress(); + writeGlobal(os, global); } } -void GlobalSection::addGlobal(InputGlobal *Global) { - if (!Global->Live) +void GlobalSection::addGlobal(InputGlobal *global) { + if (!global->live) return; - uint32_t GlobalIndex = - Out.ImportSec->getNumImportedGlobals() + InputGlobals.size(); - LLVM_DEBUG(dbgs() << "addGlobal: " << GlobalIndex << "\n"); - Global->setGlobalIndex(GlobalIndex); - Out.GlobalSec->InputGlobals.push_back(Global); + uint32_t globalIndex = + out.importSec->getNumImportedGlobals() + inputGlobals.size(); + LLVM_DEBUG(dbgs() << "addGlobal: " << globalIndex << "\n"); + global->setGlobalIndex(globalIndex); + out.globalSec->inputGlobals.push_back(global); } void EventSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, InputEvents.size(), "event count"); - for (InputEvent *E : InputEvents) { - E->Event.Type.SigIndex = Out.TypeSec->lookupType(E->Signature); - writeEvent(OS, E->Event); + writeUleb128(os, inputEvents.size(), "event count"); + for (InputEvent *e : inputEvents) { + e->event.Type.SigIndex = out.typeSec->lookupType(e->signature); + writeEvent(os, e->event); } } -void EventSection::addEvent(InputEvent *Event) { - if (!Event->Live) +void EventSection::addEvent(InputEvent *event) { + if (!event->live) return; - uint32_t EventIndex = - Out.ImportSec->getNumImportedEvents() + InputEvents.size(); - LLVM_DEBUG(dbgs() << "addEvent: " << EventIndex << "\n"); - Event->setEventIndex(EventIndex); - InputEvents.push_back(Event); + uint32_t eventIndex = + out.importSec->getNumImportedEvents() + inputEvents.size(); + LLVM_DEBUG(dbgs() << "addEvent: " << eventIndex << "\n"); + event->setEventIndex(eventIndex); + inputEvents.push_back(event); } void ExportSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, Exports.size(), "export count"); - for (const WasmExport &Export : Exports) - writeExport(OS, Export); + writeUleb128(os, exports.size(), "export count"); + for (const WasmExport &export_ : exports) + writeExport(os, export_); } -void ElemSection::addEntry(FunctionSymbol *Sym) { - if (Sym->hasTableIndex()) +void ElemSection::addEntry(FunctionSymbol *sym) { + if (sym->hasTableIndex()) return; - Sym->setTableIndex(ElemOffset + IndirectFunctions.size()); - IndirectFunctions.emplace_back(Sym); + sym->setTableIndex(elemOffset + indirectFunctions.size()); + indirectFunctions.emplace_back(sym); } void ElemSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, 1, "segment count"); - writeUleb128(OS, 0, "table index"); - WasmInitExpr InitExpr; - if (Config->Pic) { - InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex(); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, 1, "segment count"); + writeUleb128(os, 0, "table index"); + WasmInitExpr initExpr; + if (config->isPic) { + initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Value.Global = WasmSym::tableBase->getGlobalIndex(); } else { - InitExpr.Opcode = WASM_OPCODE_I32_CONST; - InitExpr.Value.Int32 = ElemOffset; + initExpr.Opcode = WASM_OPCODE_I32_CONST; + initExpr.Value.Int32 = elemOffset; } - writeInitExpr(OS, InitExpr); - writeUleb128(OS, IndirectFunctions.size(), "elem count"); - - uint32_t TableIndex = ElemOffset; - for (const FunctionSymbol *Sym : IndirectFunctions) { - assert(Sym->getTableIndex() == TableIndex); - writeUleb128(OS, Sym->getFunctionIndex(), "function index"); - ++TableIndex; + writeInitExpr(os, initExpr); + writeUleb128(os, indirectFunctions.size(), "elem count"); + + uint32_t tableIndex = elemOffset; + for (const FunctionSymbol *sym : indirectFunctions) { + assert(sym->getTableIndex() == tableIndex); + writeUleb128(os, sym->getFunctionIndex(), "function index"); + ++tableIndex; } } void DataCountSection::writeBody() { - writeUleb128(BodyOutputStream, NumSegments, "data count"); + writeUleb128(bodyOutputStream, numSegments, "data count"); } bool DataCountSection::isNeeded() const { - return NumSegments && Config->PassiveSegments; + return numSegments && config->passiveSegments; } -static uint32_t getWasmFlags(const Symbol *Sym) { - uint32_t Flags = 0; - if (Sym->isLocal()) - Flags |= WASM_SYMBOL_BINDING_LOCAL; - if (Sym->isWeak()) - Flags |= WASM_SYMBOL_BINDING_WEAK; - if (Sym->isHidden()) - Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; - if (Sym->isUndefined()) - Flags |= WASM_SYMBOL_UNDEFINED; - if (auto *F = dyn_cast(Sym)) { - if (F->getName() != F->ImportName) - Flags |= WASM_SYMBOL_EXPLICIT_NAME; - } else if (auto *G = dyn_cast(Sym)) { - if (G->getName() != G->ImportName) - Flags |= WASM_SYMBOL_EXPLICIT_NAME; +static uint32_t getWasmFlags(const Symbol *sym) { + uint32_t flags = 0; + if (sym->isLocal()) + flags |= WASM_SYMBOL_BINDING_LOCAL; + if (sym->isWeak()) + flags |= WASM_SYMBOL_BINDING_WEAK; + if (sym->isHidden()) + flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; + if (sym->isUndefined()) + flags |= WASM_SYMBOL_UNDEFINED; + if (auto *f = dyn_cast(sym)) { + if (f->getName() != f->importName) + flags |= WASM_SYMBOL_EXPLICIT_NAME; + } else if (auto *g = dyn_cast(sym)) { + if (g->getName() != g->importName) + flags |= WASM_SYMBOL_EXPLICIT_NAME; } - return Flags; + return flags; } void LinkingSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, WasmMetadataVersion, "Version"); - - if (!SymtabEntries.empty()) { - SubSection Sub(WASM_SYMBOL_TABLE); - writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); - - for (const Symbol *Sym : SymtabEntries) { - assert(Sym->isDefined() || Sym->isUndefined()); - WasmSymbolType Kind = Sym->getWasmType(); - uint32_t Flags = getWasmFlags(Sym); - - writeU8(Sub.OS, Kind, "sym kind"); - writeUleb128(Sub.OS, Flags, "sym flags"); - - if (auto *F = dyn_cast(Sym)) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (auto *G = dyn_cast(Sym)) { - writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (auto *E = dyn_cast(Sym)) { - writeUleb128(Sub.OS, E->getEventIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (isa(Sym)) { - writeStr(Sub.OS, Sym->getName(), "sym name"); - if (auto *DataSym = dyn_cast(Sym)) { - writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); - writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, WasmMetadataVersion, "Version"); + + if (!symtabEntries.empty()) { + SubSection sub(WASM_SYMBOL_TABLE); + writeUleb128(sub.os, symtabEntries.size(), "num symbols"); + + for (const Symbol *sym : symtabEntries) { + assert(sym->isDefined() || sym->isUndefined()); + WasmSymbolType kind = sym->getWasmType(); + uint32_t flags = getWasmFlags(sym); + + writeU8(sub.os, kind, "sym kind"); + writeUleb128(sub.os, flags, "sym flags"); + + if (auto *f = dyn_cast(sym)) { + writeUleb128(sub.os, f->getFunctionIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (auto *g = dyn_cast(sym)) { + writeUleb128(sub.os, g->getGlobalIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (auto *e = dyn_cast(sym)) { + writeUleb128(sub.os, e->getEventIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (isa(sym)) { + writeStr(sub.os, sym->getName(), "sym name"); + if (auto *dataSym = dyn_cast(sym)) { + writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index"); + writeUleb128(sub.os, dataSym->getOutputSegmentOffset(), "data offset"); - writeUleb128(Sub.OS, DataSym->getSize(), "data size"); + writeUleb128(sub.os, dataSym->getSize(), "data size"); } } else { - auto *S = cast(Sym); - writeUleb128(Sub.OS, S->Section->SectionIndex, "sym section index"); + auto *s = cast(sym); + writeUleb128(sub.os, s->section->sectionIndex, "sym section index"); } } - Sub.writeTo(OS); + sub.writeTo(os); } - if (DataSegments.size()) { - SubSection Sub(WASM_SEGMENT_INFO); - writeUleb128(Sub.OS, DataSegments.size(), "num data segments"); - for (const OutputSegment *S : DataSegments) { - writeStr(Sub.OS, S->Name, "segment name"); - writeUleb128(Sub.OS, S->Alignment, "alignment"); - writeUleb128(Sub.OS, 0, "flags"); + if (dataSegments.size()) { + SubSection sub(WASM_SEGMENT_INFO); + writeUleb128(sub.os, dataSegments.size(), "num data segments"); + for (const OutputSegment *s : dataSegments) { + writeStr(sub.os, s->name, "segment name"); + writeUleb128(sub.os, s->alignment, "alignment"); + writeUleb128(sub.os, 0, "flags"); } - Sub.writeTo(OS); + sub.writeTo(os); } - if (!InitFunctions.empty()) { - SubSection Sub(WASM_INIT_FUNCS); - writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); - for (const WasmInitEntry &F : InitFunctions) { - writeUleb128(Sub.OS, F.Priority, "priority"); - writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); + if (!initFunctions.empty()) { + SubSection sub(WASM_INIT_FUNCS); + writeUleb128(sub.os, initFunctions.size(), "num init functions"); + for (const WasmInitEntry &f : initFunctions) { + writeUleb128(sub.os, f.priority, "priority"); + writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index"); } - Sub.writeTo(OS); + sub.writeTo(os); } struct ComdatEntry { - unsigned Kind; - uint32_t Index; + unsigned kind; + uint32_t index; }; - std::map> Comdats; + std::map> comdats; - for (const InputFunction *F : Out.FunctionSec->InputFunctions) { - StringRef Comdat = F->getComdatName(); - if (!Comdat.empty()) - Comdats[Comdat].emplace_back( - ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); + for (const InputFunction *f : out.functionSec->inputFunctions) { + StringRef comdat = f->getComdatName(); + if (!comdat.empty()) + comdats[comdat].emplace_back( + ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()}); } - for (uint32_t I = 0; I < DataSegments.size(); ++I) { - const auto &InputSegments = DataSegments[I]->InputSegments; - if (InputSegments.empty()) + for (uint32_t i = 0; i < dataSegments.size(); ++i) { + const auto &inputSegments = dataSegments[i]->inputSegments; + if (inputSegments.empty()) continue; - StringRef Comdat = InputSegments[0]->getComdatName(); + StringRef comdat = inputSegments[0]->getComdatName(); #ifndef NDEBUG - for (const InputSegment *IS : InputSegments) - assert(IS->getComdatName() == Comdat); + for (const InputSegment *isec : inputSegments) + assert(isec->getComdatName() == comdat); #endif - if (!Comdat.empty()) - Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); + if (!comdat.empty()) + comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i}); } - if (!Comdats.empty()) { - SubSection Sub(WASM_COMDAT_INFO); - writeUleb128(Sub.OS, Comdats.size(), "num comdats"); - for (const auto &C : Comdats) { - writeStr(Sub.OS, C.first, "comdat name"); - writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use - writeUleb128(Sub.OS, C.second.size(), "num entries"); - for (const ComdatEntry &Entry : C.second) { - writeU8(Sub.OS, Entry.Kind, "entry kind"); - writeUleb128(Sub.OS, Entry.Index, "entry index"); + if (!comdats.empty()) { + SubSection sub(WASM_COMDAT_INFO); + writeUleb128(sub.os, comdats.size(), "num comdats"); + for (const auto &c : comdats) { + writeStr(sub.os, c.first, "comdat name"); + writeUleb128(sub.os, 0, "comdat flags"); // flags for future use + writeUleb128(sub.os, c.second.size(), "num entries"); + for (const ComdatEntry &entry : c.second) { + writeU8(sub.os, entry.kind, "entry kind"); + writeUleb128(sub.os, entry.index, "entry index"); } } - Sub.writeTo(OS); + sub.writeTo(os); } } -void LinkingSection::addToSymtab(Symbol *Sym) { - Sym->setOutputSymbolIndex(SymtabEntries.size()); - SymtabEntries.emplace_back(Sym); +void LinkingSection::addToSymtab(Symbol *sym) { + sym->setOutputSymbolIndex(symtabEntries.size()); + symtabEntries.emplace_back(sym); } unsigned NameSection::numNames() const { - unsigned NumNames = Out.ImportSec->getNumImportedFunctions(); - for (const InputFunction *F : Out.FunctionSec->InputFunctions) - if (!F->getName().empty() || !F->getDebugName().empty()) - ++NumNames; + unsigned numNames = out.importSec->getNumImportedFunctions(); + for (const InputFunction *f : out.functionSec->inputFunctions) + if (!f->getName().empty() || !f->getDebugName().empty()) + ++numNames; - return NumNames; + return numNames; } // Create the custom "name" section containing debug symbol names. void NameSection::writeBody() { - SubSection Sub(WASM_NAMES_FUNCTION); - writeUleb128(Sub.OS, numNames(), "name count"); + SubSection sub(WASM_NAMES_FUNCTION); + writeUleb128(sub.os, numNames(), "name count"); // Names must appear in function index order. As it happens ImportedSymbols // and InputFunctions are numbered in order with imported functions coming // first. - for (const Symbol *S : Out.ImportSec->ImportedSymbols) { - if (auto *F = dyn_cast(S)) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); - writeStr(Sub.OS, toString(*S), "symbol name"); + for (const Symbol *s : out.importSec->importedSymbols) { + if (auto *f = dyn_cast(s)) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + writeStr(sub.os, toString(*s), "symbol name"); } } - for (const InputFunction *F : Out.FunctionSec->InputFunctions) { - if (!F->getName().empty()) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); - if (!F->getDebugName().empty()) { - writeStr(Sub.OS, F->getDebugName(), "symbol name"); + for (const InputFunction *f : out.functionSec->inputFunctions) { + if (!f->getName().empty()) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + if (!f->getDebugName().empty()) { + writeStr(sub.os, f->getDebugName(), "symbol name"); } else { - writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name"); + writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); } } } - Sub.writeTo(BodyOutputStream); + sub.writeTo(bodyOutputStream); } -void ProducersSection::addInfo(const WasmProducerInfo &Info) { - for (auto &Producers : - {std::make_pair(&Info.Languages, &Languages), - std::make_pair(&Info.Tools, &Tools), std::make_pair(&Info.SDKs, &SDKs)}) - for (auto &Producer : *Producers.first) - if (Producers.second->end() == - llvm::find_if(*Producers.second, - [&](std::pair Seen) { - return Seen.first == Producer.first; +void ProducersSection::addInfo(const WasmProducerInfo &info) { + for (auto &producers : + {std::make_pair(&info.Languages, &languages), + std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)}) + for (auto &producer : *producers.first) + if (producers.second->end() == + llvm::find_if(*producers.second, + [&](std::pair seen) { + return seen.first == producer.first; })) - Producers.second->push_back(Producer); + producers.second->push_back(producer); } void ProducersSection::writeBody() { - auto &OS = BodyOutputStream; - writeUleb128(OS, fieldCount(), "field count"); - for (auto &Field : - {std::make_pair("language", Languages), - std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) { - if (Field.second.empty()) + auto &os = bodyOutputStream; + writeUleb128(os, fieldCount(), "field count"); + for (auto &field : + {std::make_pair("language", languages), + std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) { + if (field.second.empty()) continue; - writeStr(OS, Field.first, "field name"); - writeUleb128(OS, Field.second.size(), "number of entries"); - for (auto &Entry : Field.second) { - writeStr(OS, Entry.first, "producer name"); - writeStr(OS, Entry.second, "producer version"); + writeStr(os, field.first, "field name"); + writeUleb128(os, field.second.size(), "number of entries"); + for (auto &entry : field.second) { + writeStr(os, entry.first, "producer name"); + writeStr(os, entry.second, "producer version"); } } } void TargetFeaturesSection::writeBody() { - SmallVector Emitted(Features.begin(), Features.end()); - llvm::sort(Emitted); - auto &OS = BodyOutputStream; - writeUleb128(OS, Emitted.size(), "feature count"); - for (auto &Feature : Emitted) { - writeU8(OS, WASM_FEATURE_PREFIX_USED, "feature used prefix"); - writeStr(OS, Feature, "feature name"); + SmallVector emitted(features.begin(), features.end()); + llvm::sort(emitted); + auto &os = bodyOutputStream; + writeUleb128(os, emitted.size(), "feature count"); + for (auto &feature : emitted) { + writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix"); + writeStr(os, feature, "feature name"); } } void RelocSection::writeBody() { - uint32_t Count = Sec->getNumRelocations(); - assert(Sec->SectionIndex != UINT32_MAX); - writeUleb128(BodyOutputStream, Sec->SectionIndex, "reloc section"); - writeUleb128(BodyOutputStream, Count, "reloc count"); - Sec->writeRelocations(BodyOutputStream); + uint32_t count = sec->getNumRelocations(); + assert(sec->sectionIndex != UINT32_MAX); + writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section"); + writeUleb128(bodyOutputStream, count, "reloc count"); + sec->writeRelocations(bodyOutputStream); } diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h index c2a9c4b..1d3b8b7 100644 --- a/lld/wasm/SyntheticSections.h +++ b/lld/wasm/SyntheticSections.h @@ -29,41 +29,41 @@ namespace wasm { // An init entry to be written to either the synthetic init func or the // linking metadata. struct WasmInitEntry { - const FunctionSymbol *Sym; - uint32_t Priority; + const FunctionSymbol *sym; + uint32_t priority; }; class SyntheticSection : public OutputSection { public: - SyntheticSection(uint32_t Type, std::string Name = "") - : OutputSection(Type, Name), BodyOutputStream(Body) { - if (!Name.empty()) - writeStr(BodyOutputStream, Name, "section name"); + SyntheticSection(uint32_t type, std::string name = "") + : OutputSection(type, name), bodyOutputStream(body) { + if (!name.empty()) + writeStr(bodyOutputStream, name, "section name"); } - void writeTo(uint8_t *Buf) override { - assert(Offset); + void writeTo(uint8_t *buf) override { + assert(offset); log("writing " + toString(*this)); - memcpy(Buf + Offset, Header.data(), Header.size()); - memcpy(Buf + Offset + Header.size(), Body.data(), Body.size()); + memcpy(buf + offset, header.data(), header.size()); + memcpy(buf + offset + header.size(), body.data(), body.size()); } - size_t getSize() const override { return Header.size() + Body.size(); } + size_t getSize() const override { return header.size() + body.size(); } virtual void writeBody() {} void finalizeContents() override { writeBody(); - BodyOutputStream.flush(); - createHeader(Body.size()); + bodyOutputStream.flush(); + createHeader(body.size()); } - raw_ostream &getStream() { return BodyOutputStream; } + raw_ostream &getStream() { return bodyOutputStream; } - std::string Body; + std::string body; protected: - llvm::raw_string_ostream BodyOutputStream; + llvm::raw_string_ostream bodyOutputStream; }; // Create the custom "dylink" section containing information for the dynamic @@ -73,25 +73,25 @@ protected: class DylinkSection : public SyntheticSection { public: DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink") {} - bool isNeeded() const override { return Config->Pic; } + bool isNeeded() const override { return config->isPic; } void writeBody() override; - uint32_t MemAlign = 0; - uint32_t MemSize = 0; + uint32_t memAlign = 0; + uint32_t memSize = 0; }; class TypeSection : public SyntheticSection { public: TypeSection() : SyntheticSection(llvm::wasm::WASM_SEC_TYPE) {} - bool isNeeded() const override { return Types.size() > 0; }; + bool isNeeded() const override { return types.size() > 0; }; void writeBody() override; - uint32_t registerType(const WasmSignature &Sig); - uint32_t lookupType(const WasmSignature &Sig); + uint32_t registerType(const WasmSignature &sig); + uint32_t lookupType(const WasmSignature &sig); protected: - std::vector Types; - llvm::DenseMap TypeIndices; + std::vector types; + llvm::DenseMap typeIndices; }; class ImportSection : public SyntheticSection { @@ -99,42 +99,42 @@ public: ImportSection() : SyntheticSection(llvm::wasm::WASM_SEC_IMPORT) {} bool isNeeded() const override { return getNumImports() > 0; } void writeBody() override; - void addImport(Symbol *Sym); - void addGOTEntry(Symbol *Sym); - void seal() { IsSealed = true; } + void addImport(Symbol *sym); + void addGOTEntry(Symbol *sym); + void seal() { isSealed = true; } uint32_t getNumImports() const; uint32_t getNumImportedGlobals() const { - assert(IsSealed); - return NumImportedGlobals; + assert(isSealed); + return numImportedGlobals; } uint32_t getNumImportedFunctions() const { - assert(IsSealed); - return NumImportedFunctions; + assert(isSealed); + return numImportedFunctions; } uint32_t getNumImportedEvents() const { - assert(IsSealed); - return NumImportedEvents; + assert(isSealed); + return numImportedEvents; } - std::vector ImportedSymbols; + std::vector importedSymbols; protected: - bool IsSealed = false; - unsigned NumImportedGlobals = 0; - unsigned NumImportedFunctions = 0; - unsigned NumImportedEvents = 0; - std::vector GOTSymbols; + bool isSealed = false; + unsigned numImportedGlobals = 0; + unsigned numImportedFunctions = 0; + unsigned numImportedEvents = 0; + std::vector gotSymbols; }; class FunctionSection : public SyntheticSection { public: FunctionSection() : SyntheticSection(llvm::wasm::WASM_SEC_FUNCTION) {} - bool isNeeded() const override { return InputFunctions.size() > 0; }; + bool isNeeded() const override { return inputFunctions.size() > 0; }; void writeBody() override; - void addFunction(InputFunction *Func); + void addFunction(InputFunction *func); - std::vector InputFunctions; + std::vector inputFunctions; protected: }; @@ -143,11 +143,11 @@ class MemorySection : public SyntheticSection { public: MemorySection() : SyntheticSection(llvm::wasm::WASM_SEC_MEMORY) {} - bool isNeeded() const override { return !Config->ImportMemory; } + bool isNeeded() const override { return !config->importMemory; } void writeBody() override; - uint32_t NumMemoryPages = 0; - uint32_t MaxMemoryPages = 0; + uint32_t numMemoryPages = 0; + uint32_t maxMemoryPages = 0; }; class TableSection : public SyntheticSection { @@ -163,7 +163,7 @@ public: // no address-taken function will fail at validation time since it is // a validation error to include a call_indirect instruction if there // is not table. - return !Config->ImportTable; + return !config->importTable; } void writeBody() override; @@ -173,14 +173,14 @@ class GlobalSection : public SyntheticSection { public: GlobalSection() : SyntheticSection(llvm::wasm::WASM_SEC_GLOBAL) {} uint32_t numGlobals() const { - return InputGlobals.size() + DefinedFakeGlobals.size(); + return inputGlobals.size() + definedFakeGlobals.size(); } bool isNeeded() const override { return numGlobals() > 0; } void writeBody() override; - void addGlobal(InputGlobal *Global); + void addGlobal(InputGlobal *global); - std::vector DefinedFakeGlobals; - std::vector InputGlobals; + std::vector definedFakeGlobals; + std::vector inputGlobals; }; // The event section contains a list of declared wasm events associated with the @@ -197,66 +197,66 @@ class EventSection : public SyntheticSection { public: EventSection() : SyntheticSection(llvm::wasm::WASM_SEC_EVENT) {} void writeBody() override; - bool isNeeded() const override { return InputEvents.size() > 0; } - void addEvent(InputEvent *Event); + bool isNeeded() const override { return inputEvents.size() > 0; } + void addEvent(InputEvent *event); - std::vector InputEvents; + std::vector inputEvents; }; class ExportSection : public SyntheticSection { public: ExportSection() : SyntheticSection(llvm::wasm::WASM_SEC_EXPORT) {} - bool isNeeded() const override { return Exports.size() > 0; } + bool isNeeded() const override { return exports.size() > 0; } void writeBody() override; - std::vector Exports; + std::vector exports; }; class ElemSection : public SyntheticSection { public: - ElemSection(uint32_t Offset) - : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), ElemOffset(Offset) {} - bool isNeeded() const override { return IndirectFunctions.size() > 0; }; + ElemSection(uint32_t offset) + : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), elemOffset(offset) {} + bool isNeeded() const override { return indirectFunctions.size() > 0; }; void writeBody() override; - void addEntry(FunctionSymbol *Sym); - uint32_t numEntries() const { return IndirectFunctions.size(); } - uint32_t ElemOffset; + void addEntry(FunctionSymbol *sym); + uint32_t numEntries() const { return indirectFunctions.size(); } + uint32_t elemOffset; protected: - std::vector IndirectFunctions; + std::vector indirectFunctions; }; class DataCountSection : public SyntheticSection { public: - DataCountSection(uint32_t NumSegments) + DataCountSection(uint32_t numSegments) : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT), - NumSegments(NumSegments) {} + numSegments(numSegments) {} bool isNeeded() const override; void writeBody() override; protected: - uint32_t NumSegments; + uint32_t numSegments; }; // Create the custom "linking" section containing linker metadata. // This is only created when relocatable output is requested. class LinkingSection : public SyntheticSection { public: - LinkingSection(const std::vector &InitFunctions, - const std::vector &DataSegments) + LinkingSection(const std::vector &initFunctions, + const std::vector &dataSegments) : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"), - InitFunctions(InitFunctions), DataSegments(DataSegments) {} + initFunctions(initFunctions), dataSegments(dataSegments) {} bool isNeeded() const override { - return Config->Relocatable || Config->EmitRelocs; + return config->relocatable || config->emitRelocs; } void writeBody() override; - void addToSymtab(Symbol *Sym); + void addToSymtab(Symbol *sym); protected: - std::vector SymtabEntries; - llvm::StringMap SectionSymbolIndices; - const std::vector &InitFunctions; - const std::vector &DataSegments; + std::vector symtabEntries; + llvm::StringMap sectionSymbolIndices; + const std::vector &initFunctions; + const std::vector &dataSegments; }; // Create the custom "name" section containing debug symbol names. @@ -264,7 +264,7 @@ class NameSection : public SyntheticSection { public: NameSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name") {} bool isNeeded() const override { - return !Config->StripDebug && !Config->StripAll && numNames() > 0; + return !config->stripDebug && !config->stripAll && numNames() > 0; } void writeBody() override; unsigned numNames() const; @@ -275,18 +275,18 @@ public: ProducersSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "producers") {} bool isNeeded() const override { - return !Config->StripAll && fieldCount() > 0; + return !config->stripAll && fieldCount() > 0; } void writeBody() override; - void addInfo(const llvm::wasm::WasmProducerInfo &Info); + void addInfo(const llvm::wasm::WasmProducerInfo &info); protected: int fieldCount() const { - return int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty()); + return int(!languages.empty()) + int(!tools.empty()) + int(!sDKs.empty()); } - SmallVector, 8> Languages; - SmallVector, 8> Tools; - SmallVector, 8> SDKs; + SmallVector, 8> languages; + SmallVector, 8> tools; + SmallVector, 8> sDKs; }; class TargetFeaturesSection : public SyntheticSection { @@ -294,44 +294,44 @@ public: TargetFeaturesSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "target_features") {} bool isNeeded() const override { - return !Config->StripAll && Features.size() > 0; + return !config->stripAll && features.size() > 0; } void writeBody() override; - llvm::SmallSet Features; + llvm::SmallSet features; }; class RelocSection : public SyntheticSection { public: - RelocSection(StringRef Name, OutputSection *Sec) - : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, Name), Sec(Sec) {} + RelocSection(StringRef name, OutputSection *sec) + : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, name), sec(sec) {} void writeBody() override; - bool isNeeded() const override { return Sec->getNumRelocations() > 0; }; + bool isNeeded() const override { return sec->getNumRelocations() > 0; }; protected: - OutputSection *Sec; + OutputSection *sec; }; // Linker generated output sections struct OutStruct { - DylinkSection *DylinkSec; - TypeSection *TypeSec; - FunctionSection *FunctionSec; - ImportSection *ImportSec; - TableSection *TableSec; - MemorySection *MemorySec; - GlobalSection *GlobalSec; - EventSection *EventSec; - ExportSection *ExportSec; - ElemSection *ElemSec; - DataCountSection *DataCountSec; - LinkingSection *LinkingSec; - NameSection *NameSec; - ProducersSection *ProducersSec; - TargetFeaturesSection *TargetFeaturesSec; + DylinkSection *dylinkSec; + TypeSection *typeSec; + FunctionSection *functionSec; + ImportSection *importSec; + TableSection *tableSec; + MemorySection *memorySec; + GlobalSection *globalSec; + EventSection *eventSec; + ExportSection *exportSec; + ElemSection *elemSec; + DataCountSection *dataCountSec; + LinkingSection *linkingSec; + NameSection *nameSec; + ProducersSection *producersSec; + TargetFeaturesSection *targetFeaturesSec; }; -extern OutStruct Out; +extern OutStruct out; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 5fabd97..11c4b91 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -42,7 +42,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static constexpr int StackAlignment = 16; +static constexpr int stackAlignment = 16; namespace { @@ -71,7 +71,7 @@ private: void layoutMemory(); void createHeader(); - void addSection(OutputSection *Sec); + void addSection(OutputSection *sec); void addSections(); @@ -85,56 +85,56 @@ private: void writeHeader(); void writeSections(); - uint64_t FileSize = 0; - uint32_t TableBase = 0; + uint64_t fileSize = 0; + uint32_t tableBase = 0; - std::vector InitFunctions; - llvm::StringMap> CustomSectionMapping; + std::vector initFunctions; + llvm::StringMap> customSectionMapping; // Elements that are used to construct the final output - std::string Header; - std::vector OutputSections; + std::string header; + std::vector outputSections; - std::unique_ptr Buffer; + std::unique_ptr buffer; - std::vector Segments; - llvm::SmallDenseMap SegmentMap; + std::vector segments; + llvm::SmallDenseMap segmentMap; }; } // anonymous namespace void Writer::calculateCustomSections() { log("calculateCustomSections"); - bool StripDebug = Config->StripDebug || Config->StripAll; - for (ObjFile *File : Symtab->ObjectFiles) { - for (InputSection *Section : File->CustomSections) { - StringRef Name = Section->getName(); + bool stripDebug = config->stripDebug || config->stripAll; + for (ObjFile *file : symtab->objectFiles) { + for (InputSection *section : file->customSections) { + StringRef name = section->getName(); // These custom sections are known the linker and synthesized rather than // blindly copied - if (Name == "linking" || Name == "name" || Name == "producers" || - Name == "target_features" || Name.startswith("reloc.")) + if (name == "linking" || name == "name" || name == "producers" || + name == "target_features" || name.startswith("reloc.")) continue; // .. or it is a debug section - if (StripDebug && Name.startswith(".debug_")) + if (stripDebug && name.startswith(".debug_")) continue; - CustomSectionMapping[Name].push_back(Section); + customSectionMapping[name].push_back(section); } } } void Writer::createCustomSections() { log("createCustomSections"); - for (auto &Pair : CustomSectionMapping) { - StringRef Name = Pair.first(); - LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); - - OutputSection *Sec = make(Name, Pair.second); - if (Config->Relocatable || Config->EmitRelocs) { - auto *Sym = make(Sec); - Out.LinkingSec->addToSymtab(Sym); - Sec->SectionSym = Sym; + for (auto &pair : customSectionMapping) { + StringRef name = pair.first(); + LLVM_DEBUG(dbgs() << "createCustomSection: " << name << "\n"); + + OutputSection *sec = make(name, pair.second); + if (config->relocatable || config->emitRelocs) { + auto *sym = make(sec); + out.linkingSec->addToSymtab(sym); + sec->sectionSym = sym; } - addSection(Sec); + addSection(sec); } } @@ -143,47 +143,47 @@ void Writer::createCustomSections() { void Writer::createRelocSections() { log("createRelocSections"); // Don't use iterator here since we are adding to OutputSection - size_t OrigSize = OutputSections.size(); - for (size_t I = 0; I < OrigSize; I++) { - LLVM_DEBUG(dbgs() << "check section " << I << "\n"); - OutputSection *Sec = OutputSections[I]; + size_t origSize = outputSections.size(); + for (size_t i = 0; i < origSize; i++) { + LLVM_DEBUG(dbgs() << "check section " << i << "\n"); + OutputSection *sec = outputSections[i]; // Count the number of needed sections. - uint32_t Count = Sec->getNumRelocations(); - if (!Count) + uint32_t count = sec->getNumRelocations(); + if (!count) continue; - StringRef Name; - if (Sec->Type == WASM_SEC_DATA) - Name = "reloc.DATA"; - else if (Sec->Type == WASM_SEC_CODE) - Name = "reloc.CODE"; - else if (Sec->Type == WASM_SEC_CUSTOM) - Name = Saver.save("reloc." + Sec->Name); + StringRef name; + if (sec->type == WASM_SEC_DATA) + name = "reloc.DATA"; + else if (sec->type == WASM_SEC_CODE) + name = "reloc.CODE"; + else if (sec->type == WASM_SEC_CUSTOM) + name = saver.save("reloc." + sec->name); else llvm_unreachable( "relocations only supported for code, data, or custom sections"); - addSection(make(Name, Sec)); + addSection(make(name, sec)); } } void Writer::populateProducers() { - for (ObjFile *File : Symtab->ObjectFiles) { - const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); - Out.ProducersSec->addInfo(Info); + for (ObjFile *file : symtab->objectFiles) { + const WasmProducerInfo &info = file->getWasmObj()->getProducerInfo(); + out.producersSec->addInfo(info); } } void Writer::writeHeader() { - memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); + memcpy(buffer->getBufferStart(), header.data(), header.size()); } void Writer::writeSections() { - uint8_t *Buf = Buffer->getBufferStart(); - parallelForEach(OutputSections, [Buf](OutputSection *S) { - assert(S->isNeeded()); - S->writeTo(Buf); + uint8_t *buf = buffer->getBufferStart(); + parallelForEach(outputSections, [buf](OutputSection *s) { + assert(s->isNeeded()); + s->writeTo(buf); }); } @@ -201,100 +201,100 @@ void Writer::writeSections() { // rather than overwriting global data, but also increases code size since all // static data loads and stores requires larger offsets. void Writer::layoutMemory() { - uint32_t MemoryPtr = 0; + uint32_t memoryPtr = 0; - auto PlaceStack = [&]() { - if (Config->Relocatable || Config->Shared) + auto placeStack = [&]() { + if (config->relocatable || config->shared) return; - MemoryPtr = alignTo(MemoryPtr, StackAlignment); - if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) - error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); - log("mem: stack size = " + Twine(Config->ZStackSize)); - log("mem: stack base = " + Twine(MemoryPtr)); - MemoryPtr += Config->ZStackSize; - auto *SP = cast(WasmSym::StackPointer); - SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; - log("mem: stack top = " + Twine(MemoryPtr)); + memoryPtr = alignTo(memoryPtr, stackAlignment); + if (config->zStackSize != alignTo(config->zStackSize, stackAlignment)) + error("stack size must be " + Twine(stackAlignment) + "-byte aligned"); + log("mem: stack size = " + Twine(config->zStackSize)); + log("mem: stack base = " + Twine(memoryPtr)); + memoryPtr += config->zStackSize; + auto *sp = cast(WasmSym::stackPointer); + sp->global->global.InitExpr.Value.Int32 = memoryPtr; + log("mem: stack top = " + Twine(memoryPtr)); }; - if (Config->StackFirst) { - PlaceStack(); + if (config->stackFirst) { + placeStack(); } else { - MemoryPtr = Config->GlobalBase; - log("mem: global base = " + Twine(Config->GlobalBase)); + memoryPtr = config->globalBase; + log("mem: global base = " + Twine(config->globalBase)); } - if (WasmSym::GlobalBase) - WasmSym::GlobalBase->setVirtualAddress(Config->GlobalBase); + if (WasmSym::globalBase) + WasmSym::globalBase->setVirtualAddress(config->globalBase); - uint32_t DataStart = MemoryPtr; + uint32_t dataStart = memoryPtr; // Arbitrarily set __dso_handle handle to point to the start of the data // segments. - if (WasmSym::DsoHandle) - WasmSym::DsoHandle->setVirtualAddress(DataStart); + if (WasmSym::dsoHandle) + WasmSym::dsoHandle->setVirtualAddress(dataStart); - Out.DylinkSec->MemAlign = 0; - for (OutputSegment *Seg : Segments) { - Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment); - MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); - Seg->StartVA = MemoryPtr; - log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, - MemoryPtr, Seg->Size, Seg->Alignment)); - MemoryPtr += Seg->Size; + out.dylinkSec->memAlign = 0; + for (OutputSegment *seg : segments) { + out.dylinkSec->memAlign = std::max(out.dylinkSec->memAlign, seg->alignment); + memoryPtr = alignTo(memoryPtr, 1ULL << seg->alignment); + seg->startVA = memoryPtr; + log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name, + memoryPtr, seg->size, seg->alignment)); + memoryPtr += seg->size; } // TODO: Add .bss space here. - if (WasmSym::DataEnd) - WasmSym::DataEnd->setVirtualAddress(MemoryPtr); + if (WasmSym::dataEnd) + WasmSym::dataEnd->setVirtualAddress(memoryPtr); - log("mem: static data = " + Twine(MemoryPtr - DataStart)); + log("mem: static data = " + Twine(memoryPtr - dataStart)); - if (Config->Shared) { - Out.DylinkSec->MemSize = MemoryPtr; + if (config->shared) { + out.dylinkSec->memSize = memoryPtr; return; } - if (!Config->StackFirst) - PlaceStack(); + if (!config->stackFirst) + placeStack(); // Set `__heap_base` to directly follow the end of the stack or global data. // The fact that this comes last means that a malloc/brk implementation // can grow the heap at runtime. - log("mem: heap base = " + Twine(MemoryPtr)); - if (WasmSym::HeapBase) - WasmSym::HeapBase->setVirtualAddress(MemoryPtr); + log("mem: heap base = " + Twine(memoryPtr)); + if (WasmSym::heapBase) + WasmSym::heapBase->setVirtualAddress(memoryPtr); - if (Config->InitialMemory != 0) { - if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) + if (config->initialMemory != 0) { + if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize)) error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); - if (MemoryPtr > Config->InitialMemory) - error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); + if (memoryPtr > config->initialMemory) + error("initial memory too small, " + Twine(memoryPtr) + " bytes needed"); else - MemoryPtr = Config->InitialMemory; + memoryPtr = config->initialMemory; } - Out.DylinkSec->MemSize = MemoryPtr; - Out.MemorySec->NumMemoryPages = - alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; - log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages)); + out.dylinkSec->memSize = memoryPtr; + out.memorySec->numMemoryPages = + alignTo(memoryPtr, WasmPageSize) / WasmPageSize; + log("mem: total pages = " + Twine(out.memorySec->numMemoryPages)); // Check max if explicitly supplied or required by shared memory - if (Config->MaxMemory != 0 || Config->SharedMemory) { - if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) + if (config->maxMemory != 0 || config->sharedMemory) { + if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize)) error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); - if (MemoryPtr > Config->MaxMemory) - error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); - Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize; - log("mem: max pages = " + Twine(Out.MemorySec->MaxMemoryPages)); + if (memoryPtr > config->maxMemory) + error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed"); + out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize; + log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages)); } } -void Writer::addSection(OutputSection *Sec) { - if (!Sec->isNeeded()) +void Writer::addSection(OutputSection *sec) { + if (!sec->isNeeded()) return; - log("addSection: " + toString(*Sec)); - Sec->SectionIndex = OutputSections.size(); - OutputSections.push_back(Sec); + log("addSection: " + toString(*sec)); + sec->sectionIndex = outputSections.size(); + outputSections.push_back(sec); } // If a section name is valid as a C identifier (which is rare because of @@ -302,227 +302,227 @@ void Writer::addSection(OutputSection *Sec) { // __stop_ symbols. They are at beginning and end of the section, // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. -static void addStartStopSymbols(const OutputSegment *Seg) { - StringRef Name = Seg->Name; - if (!isValidCIdentifier(Name)) +static void addStartStopSymbols(const OutputSegment *seg) { + StringRef name = seg->name; + if (!isValidCIdentifier(name)) return; - LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << Name << "\n"); - uint32_t Start = Seg->StartVA; - uint32_t Stop = Start + Seg->Size; - Symtab->addOptionalDataSymbol(Saver.save("__start_" + Name), Start); - Symtab->addOptionalDataSymbol(Saver.save("__stop_" + Name), Stop); + LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << name << "\n"); + uint32_t start = seg->startVA; + uint32_t stop = start + seg->size; + symtab->addOptionalDataSymbol(saver.save("__start_" + name), start); + symtab->addOptionalDataSymbol(saver.save("__stop_" + name), stop); } void Writer::addSections() { - addSection(Out.DylinkSec); - addSection(Out.TypeSec); - addSection(Out.ImportSec); - addSection(Out.FunctionSec); - addSection(Out.TableSec); - addSection(Out.MemorySec); - addSection(Out.GlobalSec); - addSection(Out.EventSec); - addSection(Out.ExportSec); - addSection(Out.ElemSec); - addSection(Out.DataCountSec); - - addSection(make(Out.FunctionSec->InputFunctions)); - addSection(make(Segments)); + addSection(out.dylinkSec); + addSection(out.typeSec); + addSection(out.importSec); + addSection(out.functionSec); + addSection(out.tableSec); + addSection(out.memorySec); + addSection(out.globalSec); + addSection(out.eventSec); + addSection(out.exportSec); + addSection(out.elemSec); + addSection(out.dataCountSec); + + addSection(make(out.functionSec->inputFunctions)); + addSection(make(segments)); createCustomSections(); - addSection(Out.LinkingSec); - if (Config->EmitRelocs || Config->Relocatable) { + addSection(out.linkingSec); + if (config->emitRelocs || config->relocatable) { createRelocSections(); } - addSection(Out.NameSec); - addSection(Out.ProducersSec); - addSection(Out.TargetFeaturesSec); + addSection(out.nameSec); + addSection(out.producersSec); + addSection(out.targetFeaturesSec); } void Writer::finalizeSections() { - for (OutputSection *S : OutputSections) { - S->setOffset(FileSize); - S->finalizeContents(); - FileSize += S->getSize(); + for (OutputSection *s : outputSections) { + s->setOffset(fileSize); + s->finalizeContents(); + fileSize += s->getSize(); } } void Writer::populateTargetFeatures() { - StringMap Used; - StringMap Required; - StringMap Disallowed; + StringMap used; + StringMap required; + StringMap disallowed; // Only infer used features if user did not specify features - bool InferFeatures = !Config->Features.hasValue(); + bool inferFeatures = !config->features.hasValue(); - if (!InferFeatures) { - for (auto &Feature : Config->Features.getValue()) - Out.TargetFeaturesSec->Features.insert(Feature); + if (!inferFeatures) { + for (auto &feature : config->features.getValue()) + out.targetFeaturesSec->features.insert(feature); // No need to read or check features - if (!Config->CheckFeatures) + if (!config->checkFeatures) return; } // Find the sets of used, required, and disallowed features - for (ObjFile *File : Symtab->ObjectFiles) { - StringRef FileName(File->getName()); - for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { - switch (Feature.Prefix) { + for (ObjFile *file : symtab->objectFiles) { + StringRef fileName(file->getName()); + for (auto &feature : file->getWasmObj()->getTargetFeatures()) { + switch (feature.Prefix) { case WASM_FEATURE_PREFIX_USED: - Used.insert({Feature.Name, FileName}); + used.insert({feature.Name, fileName}); break; case WASM_FEATURE_PREFIX_REQUIRED: - Used.insert({Feature.Name, FileName}); - Required.insert({Feature.Name, FileName}); + used.insert({feature.Name, fileName}); + required.insert({feature.Name, fileName}); break; case WASM_FEATURE_PREFIX_DISALLOWED: - Disallowed.insert({Feature.Name, FileName}); + disallowed.insert({feature.Name, fileName}); break; default: error("Unrecognized feature policy prefix " + - std::to_string(Feature.Prefix)); + std::to_string(feature.Prefix)); } } } - if (InferFeatures) - Out.TargetFeaturesSec->Features.insert(Used.keys().begin(), - Used.keys().end()); + if (inferFeatures) + out.targetFeaturesSec->features.insert(used.keys().begin(), + used.keys().end()); - if (Out.TargetFeaturesSec->Features.count("atomics") && - !Config->SharedMemory) { - if (InferFeatures) - error(Twine("'atomics' feature is used by ") + Used["atomics"] + + if (out.targetFeaturesSec->features.count("atomics") && + !config->sharedMemory) { + if (inferFeatures) + error(Twine("'atomics' feature is used by ") + used["atomics"] + ", so --shared-memory must be used"); else error("'atomics' feature is used, so --shared-memory must be used"); } - if (!Config->CheckFeatures) + if (!config->checkFeatures) return; - if (Disallowed.count("atomics") && Config->SharedMemory) - error("'atomics' feature is disallowed by " + Disallowed["atomics"] + + if (disallowed.count("atomics") && config->sharedMemory) + error("'atomics' feature is disallowed by " + disallowed["atomics"] + ", so --shared-memory must not be used"); - if (!Used.count("bulk-memory") && Config->PassiveSegments) + if (!used.count("bulk-memory") && config->passiveSegments) error("'bulk-memory' feature must be used in order to emit passive " "segments"); // Validate that used features are allowed in output - if (!InferFeatures) { - for (auto &Feature : Used.keys()) { - if (!Out.TargetFeaturesSec->Features.count(Feature)) - error(Twine("Target feature '") + Feature + "' used by " + - Used[Feature] + " is not allowed."); + if (!inferFeatures) { + for (auto &feature : used.keys()) { + if (!out.targetFeaturesSec->features.count(feature)) + error(Twine("Target feature '") + feature + "' used by " + + used[feature] + " is not allowed."); } } // Validate the required and disallowed constraints for each file - for (ObjFile *File : Symtab->ObjectFiles) { - StringRef FileName(File->getName()); - SmallSet ObjectFeatures; - for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { - if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) + for (ObjFile *file : symtab->objectFiles) { + StringRef fileName(file->getName()); + SmallSet objectFeatures; + for (auto &feature : file->getWasmObj()->getTargetFeatures()) { + if (feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) continue; - ObjectFeatures.insert(Feature.Name); - if (Disallowed.count(Feature.Name)) - error(Twine("Target feature '") + Feature.Name + "' used in " + - FileName + " is disallowed by " + Disallowed[Feature.Name] + + objectFeatures.insert(feature.Name); + if (disallowed.count(feature.Name)) + error(Twine("Target feature '") + feature.Name + "' used in " + + fileName + " is disallowed by " + disallowed[feature.Name] + ". Use --no-check-features to suppress."); } - for (auto &Feature : Required.keys()) { - if (!ObjectFeatures.count(Feature)) - error(Twine("Missing target feature '") + Feature + "' in " + FileName + - ", required by " + Required[Feature] + + for (auto &feature : required.keys()) { + if (!objectFeatures.count(feature)) + error(Twine("Missing target feature '") + feature + "' in " + fileName + + ", required by " + required[feature] + ". Use --no-check-features to suppress."); } } } void Writer::calculateImports() { - for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isUndefined()) + for (Symbol *sym : symtab->getSymbols()) { + if (!sym->isUndefined()) continue; - if (Sym->isWeak() && !Config->Relocatable) + if (sym->isWeak() && !config->relocatable) continue; - if (!Sym->isLive()) + if (!sym->isLive()) continue; - if (!Sym->IsUsedInRegularObj) + if (!sym->isUsedInRegularObj) continue; // We don't generate imports for data symbols. They however can be imported // as GOT entries. - if (isa(Sym)) + if (isa(sym)) continue; - LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); - Out.ImportSec->addImport(Sym); + LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n"); + out.importSec->addImport(sym); } } void Writer::calculateExports() { - if (Config->Relocatable) + if (config->relocatable) return; - if (!Config->Relocatable && !Config->ImportMemory) - Out.ExportSec->Exports.push_back( + if (!config->relocatable && !config->importMemory) + out.exportSec->exports.push_back( WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); - if (!Config->Relocatable && Config->ExportTable) - Out.ExportSec->Exports.push_back( - WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); + if (!config->relocatable && config->exportTable) + out.exportSec->exports.push_back( + WasmExport{functionTableName, WASM_EXTERNAL_TABLE, 0}); - unsigned FakeGlobalIndex = Out.ImportSec->getNumImportedGlobals() + - Out.GlobalSec->InputGlobals.size(); + unsigned fakeGlobalIndex = out.importSec->getNumImportedGlobals() + + out.globalSec->inputGlobals.size(); - for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isExported()) + for (Symbol *sym : symtab->getSymbols()) { + if (!sym->isExported()) continue; - if (!Sym->isLive()) + if (!sym->isLive()) continue; - StringRef Name = Sym->getName(); - WasmExport Export; - if (auto *F = dyn_cast(Sym)) { - Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; - } else if (auto *G = dyn_cast(Sym)) { + StringRef name = sym->getName(); + WasmExport export_; + if (auto *f = dyn_cast(sym)) { + export_ = {name, WASM_EXTERNAL_FUNCTION, f->getFunctionIndex()}; + } else if (auto *g = dyn_cast(sym)) { // TODO(sbc): Remove this check once to mutable global proposal is // implement in all major browsers. // See: https://github.com/WebAssembly/mutable-global - if (G->getGlobalType()->Mutable) { + if (g->getGlobalType()->Mutable) { // Only the __stack_pointer should ever be create as mutable. - assert(G == WasmSym::StackPointer); + assert(g == WasmSym::stackPointer); continue; } - Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; - } else if (auto *E = dyn_cast(Sym)) { - Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()}; + export_ = {name, WASM_EXTERNAL_GLOBAL, g->getGlobalIndex()}; + } else if (auto *e = dyn_cast(sym)) { + export_ = {name, WASM_EXTERNAL_EVENT, e->getEventIndex()}; } else { - auto *D = cast(Sym); - Out.GlobalSec->DefinedFakeGlobals.emplace_back(D); - Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; + auto *d = cast(sym); + out.globalSec->definedFakeGlobals.emplace_back(d); + export_ = {name, WASM_EXTERNAL_GLOBAL, fakeGlobalIndex++}; } - LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); - Out.ExportSec->Exports.push_back(Export); + LLVM_DEBUG(dbgs() << "Export: " << name << "\n"); + out.exportSec->exports.push_back(export_); } } void Writer::populateSymtab() { - if (!Config->Relocatable && !Config->EmitRelocs) + if (!config->relocatable && !config->emitRelocs) return; - for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->IsUsedInRegularObj && Sym->isLive()) - Out.LinkingSec->addToSymtab(Sym); + for (Symbol *sym : symtab->getSymbols()) + if (sym->isUsedInRegularObj && sym->isLive()) + out.linkingSec->addToSymtab(sym); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); - for (Symbol *Sym : File->getSymbols()) - if (Sym->isLocal() && !isa(Sym) && Sym->isLive()) - Out.LinkingSec->addToSymtab(Sym); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Local symtab entries: " << file->getName() << "\n"); + for (Symbol *sym : file->getSymbols()) + if (sym->isLocal() && !isa(sym) && sym->isLive()) + out.linkingSec->addToSymtab(sym); } } @@ -534,152 +534,152 @@ void Writer::calculateTypes() { // 4. The signatures of all imported events // 5. The signatures of all defined events - for (ObjFile *File : Symtab->ObjectFiles) { - ArrayRef Types = File->getWasmObj()->types(); - for (uint32_t I = 0; I < Types.size(); I++) - if (File->TypeIsUsed[I]) - File->TypeMap[I] = Out.TypeSec->registerType(Types[I]); + for (ObjFile *file : symtab->objectFiles) { + ArrayRef types = file->getWasmObj()->types(); + for (uint32_t i = 0; i < types.size(); i++) + if (file->typeIsUsed[i]) + file->typeMap[i] = out.typeSec->registerType(types[i]); } - for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) { - if (auto *F = dyn_cast(Sym)) - Out.TypeSec->registerType(*F->Signature); - else if (auto *E = dyn_cast(Sym)) - Out.TypeSec->registerType(*E->Signature); + for (const Symbol *sym : out.importSec->importedSymbols) { + if (auto *f = dyn_cast(sym)) + out.typeSec->registerType(*f->signature); + else if (auto *e = dyn_cast(sym)) + out.typeSec->registerType(*e->signature); } - for (const InputFunction *F : Out.FunctionSec->InputFunctions) - Out.TypeSec->registerType(F->Signature); + for (const InputFunction *f : out.functionSec->inputFunctions) + out.typeSec->registerType(f->signature); - for (const InputEvent *E : Out.EventSec->InputEvents) - Out.TypeSec->registerType(E->Signature); + for (const InputEvent *e : out.eventSec->inputEvents) + out.typeSec->registerType(e->signature); } static void scanRelocations() { - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n"); - for (InputChunk *Chunk : File->Functions) - scanRelocations(Chunk); - for (InputChunk *Chunk : File->Segments) - scanRelocations(Chunk); - for (auto &P : File->CustomSections) - scanRelocations(P); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "scanRelocations: " << file->getName() << "\n"); + for (InputChunk *chunk : file->functions) + scanRelocations(chunk); + for (InputChunk *chunk : file->segments) + scanRelocations(chunk); + for (auto &p : file->customSections) + scanRelocations(p); } } void Writer::assignIndexes() { // Seal the import section, since other index spaces such as function and // global are effected by the number of imports. - Out.ImportSec->seal(); + out.importSec->seal(); - for (InputFunction *Func : Symtab->SyntheticFunctions) - Out.FunctionSec->addFunction(Func); + for (InputFunction *func : symtab->syntheticFunctions) + out.functionSec->addFunction(func); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); - for (InputFunction *Func : File->Functions) - Out.FunctionSec->addFunction(Func); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Functions: " << file->getName() << "\n"); + for (InputFunction *func : file->functions) + out.functionSec->addFunction(func); } - for (InputGlobal *Global : Symtab->SyntheticGlobals) - Out.GlobalSec->addGlobal(Global); + for (InputGlobal *global : symtab->syntheticGlobals) + out.globalSec->addGlobal(global); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); - for (InputGlobal *Global : File->Globals) - Out.GlobalSec->addGlobal(Global); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Globals: " << file->getName() << "\n"); + for (InputGlobal *global : file->globals) + out.globalSec->addGlobal(global); } - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n"); - for (InputEvent *Event : File->Events) - Out.EventSec->addEvent(Event); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Events: " << file->getName() << "\n"); + for (InputEvent *event : file->events) + out.eventSec->addEvent(event); } } -static StringRef getOutputDataSegmentName(StringRef Name) { +static StringRef getOutputDataSegmentName(StringRef name) { // With PIC code we currently only support a single data segment since // we only have a single __memory_base to use as our base address. - if (Config->Pic) + if (config->isPic) return ".data"; - if (!Config->MergeDataSegments) - return Name; - if (Name.startswith(".text.")) + if (!config->mergeDataSegments) + return name; + if (name.startswith(".text.")) return ".text"; - if (Name.startswith(".data.")) + if (name.startswith(".data.")) return ".data"; - if (Name.startswith(".bss.")) + if (name.startswith(".bss.")) return ".bss"; - if (Name.startswith(".rodata.")) + if (name.startswith(".rodata.")) return ".rodata"; - return Name; + return name; } void Writer::createOutputSegments() { - for (ObjFile *File : Symtab->ObjectFiles) { - for (InputSegment *Segment : File->Segments) { - if (!Segment->Live) + for (ObjFile *file : symtab->objectFiles) { + for (InputSegment *segment : file->segments) { + if (!segment->live) continue; - StringRef Name = getOutputDataSegmentName(Segment->getName()); - OutputSegment *&S = SegmentMap[Name]; - if (S == nullptr) { - LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); - S = make(Name, Segments.size()); - if (Config->PassiveSegments) - S->InitFlags = WASM_SEGMENT_IS_PASSIVE; - Segments.push_back(S); + StringRef name = getOutputDataSegmentName(segment->getName()); + OutputSegment *&s = segmentMap[name]; + if (s == nullptr) { + LLVM_DEBUG(dbgs() << "new segment: " << name << "\n"); + s = make(name, segments.size()); + if (config->passiveSegments) + s->initFlags = WASM_SEGMENT_IS_PASSIVE; + segments.push_back(s); } - S->addInputSegment(Segment); - LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); + s->addInputSegment(segment); + LLVM_DEBUG(dbgs() << "added data: " << name << ": " << s->size << "\n"); } } } -static void createFunction(DefinedFunction *Func, StringRef BodyContent) { - std::string FunctionBody; +static void createFunction(DefinedFunction *func, StringRef bodyContent) { + std::string functionBody; { - raw_string_ostream OS(FunctionBody); - writeUleb128(OS, BodyContent.size(), "function size"); - OS << BodyContent; + raw_string_ostream os(functionBody); + writeUleb128(os, bodyContent.size(), "function size"); + os << bodyContent; } - ArrayRef Body = arrayRefFromStringRef(Saver.save(FunctionBody)); - cast(Func->Function)->setBody(Body); + ArrayRef body = arrayRefFromStringRef(saver.save(functionBody)); + cast(func->function)->setBody(body); } void Writer::createInitMemoryFunction() { LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); // initialize passive data segments - for (const OutputSegment *S : Segments) { - if (S->InitFlags & WASM_SEGMENT_IS_PASSIVE) { + for (const OutputSegment *s : segments) { + if (s->initFlags & WASM_SEGMENT_IS_PASSIVE) { // destination address - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, S->StartVA, "destination address"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, s->startVA, "destination address"); // source segment offset - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, 0, "segment offset"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, 0, "segment offset"); // memory region size - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, S->Size, "memory region size"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, s->size, "memory region size"); // memory.init instruction - writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); - writeUleb128(OS, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT"); - writeUleb128(OS, S->Index, "segment index immediate"); - writeU8(OS, 0, "memory index immediate"); + writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); + writeUleb128(os, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT"); + writeUleb128(os, s->index, "segment index immediate"); + writeU8(os, 0, "memory index immediate"); // data.drop instruction - writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); - writeUleb128(OS, WASM_OPCODE_DATA_DROP, "DATA.DROP"); - writeUleb128(OS, S->Index, "segment index immediate"); + writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); + writeUleb128(os, WASM_OPCODE_DATA_DROP, "DATA.DROP"); + writeUleb128(os, s->index, "segment index immediate"); } } - writeU8(OS, WASM_OPCODE_END, "END"); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::InitMemory, BodyContent); + createFunction(WasmSym::initMemory, bodyContent); } // For -shared (PIC) output, we create create a synthetic function which will @@ -689,109 +689,109 @@ void Writer::createInitMemoryFunction() { void Writer::createApplyRelocationsFunction() { LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n"); // First write the body's contents to a string. - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); - for (const OutputSegment *Seg : Segments) - for (const InputSegment *InSeg : Seg->InputSegments) - InSeg->generateRelocationCode(OS); - writeU8(OS, WASM_OPCODE_END, "END"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); + for (const OutputSegment *seg : segments) + for (const InputSegment *inSeg : seg->inputSegments) + inSeg->generateRelocationCode(os); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::ApplyRelocs, BodyContent); + createFunction(WasmSym::applyRelocs, bodyContent); } // Create synthetic "__wasm_call_ctors" function based on ctor functions // in input object. void Writer::createCallCtorsFunction() { - if (!WasmSym::CallCtors->isLive()) + if (!WasmSym::callCtors->isLive()) return; // First write the body's contents to a string. - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); - if (Config->PassiveSegments) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, WasmSym::InitMemory->getFunctionIndex(), + if (config->passiveSegments) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, WasmSym::initMemory->getFunctionIndex(), "function index"); } - if (Config->Pic) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(), + if (config->isPic) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, WasmSym::applyRelocs->getFunctionIndex(), "function index"); } // Call constructors - for (const WasmInitEntry &F : InitFunctions) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); + for (const WasmInitEntry &f : initFunctions) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, f.sym->getFunctionIndex(), "function index"); } - writeU8(OS, WASM_OPCODE_END, "END"); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::CallCtors, BodyContent); + createFunction(WasmSym::callCtors, bodyContent); } // Populate InitFunctions vector with init functions from all input objects. // This is then used either when creating the output linking section or to // synthesize the "__wasm_call_ctors" function. void Writer::calculateInitFunctions() { - if (!Config->Relocatable && !WasmSym::CallCtors->isLive()) + if (!config->relocatable && !WasmSym::callCtors->isLive()) return; - for (ObjFile *File : Symtab->ObjectFiles) { - const WasmLinkingData &L = File->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) { - FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); + for (ObjFile *file : symtab->objectFiles) { + const WasmLinkingData &l = file->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) { + FunctionSymbol *sym = file->getFunctionSymbol(f.Symbol); // comdat exclusions can cause init functions be discarded. - if (Sym->isDiscarded()) + if (sym->isDiscarded()) continue; - assert(Sym->isLive()); - if (*Sym->Signature != WasmSignature{{}, {}}) - error("invalid signature for init func: " + toString(*Sym)); - InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); + assert(sym->isLive()); + if (*sym->signature != WasmSignature{{}, {}}) + error("invalid signature for init func: " + toString(*sym)); + initFunctions.emplace_back(WasmInitEntry{sym, f.Priority}); } } // Sort in order of priority (lowest first) so that they are called // in the correct order. - llvm::stable_sort(InitFunctions, - [](const WasmInitEntry &L, const WasmInitEntry &R) { - return L.Priority < R.Priority; + llvm::stable_sort(initFunctions, + [](const WasmInitEntry &l, const WasmInitEntry &r) { + return l.priority < r.priority; }); } void Writer::createSyntheticSections() { - Out.DylinkSec = make(); - Out.TypeSec = make(); - Out.ImportSec = make(); - Out.FunctionSec = make(); - Out.TableSec = make(); - Out.MemorySec = make(); - Out.GlobalSec = make(); - Out.EventSec = make(); - Out.ExportSec = make(); - Out.ElemSec = make(TableBase); - Out.DataCountSec = make(Segments.size()); - Out.LinkingSec = make(InitFunctions, Segments); - Out.NameSec = make(); - Out.ProducersSec = make(); - Out.TargetFeaturesSec = make(); + out.dylinkSec = make(); + out.typeSec = make(); + out.importSec = make(); + out.functionSec = make(); + out.tableSec = make(); + out.memorySec = make(); + out.globalSec = make(); + out.eventSec = make(); + out.exportSec = make(); + out.elemSec = make(tableBase); + out.dataCountSec = make(segments.size()); + out.linkingSec = make(initFunctions, segments); + out.nameSec = make(); + out.producersSec = make(); + out.targetFeaturesSec = make(); } void Writer::run() { - if (Config->Relocatable || Config->Pic) - Config->GlobalBase = 0; + if (config->relocatable || config->isPic) + config->globalBase = 0; // For PIC code the table base is assigned dynamically by the loader. // For non-PIC, we start at 1 so that accessing table index 0 always traps. - if (!Config->Pic) - TableBase = 1; + if (!config->isPic) + tableBase = 1; log("-- createOutputSegments"); createOutputSegments(); @@ -806,11 +806,11 @@ void Writer::run() { log("-- layoutMemory"); layoutMemory(); - if (!Config->Relocatable) { + if (!config->relocatable) { // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols // This has to be done after memory layout is performed. - for (const OutputSegment *Seg : Segments) - addStartStopSymbols(Seg); + for (const OutputSegment *seg : segments) + addStartStopSymbols(seg); } log("-- scanRelocations"); @@ -820,11 +820,11 @@ void Writer::run() { log("-- calculateInitFunctions"); calculateInitFunctions(); - if (!Config->Relocatable) { + if (!config->relocatable) { // Create linker synthesized functions - if (Config->PassiveSegments) + if (config->passiveSegments) createInitMemoryFunction(); - if (Config->Pic) + if (config->isPic) createApplyRelocationsFunction(); createCallCtorsFunction(); } @@ -840,16 +840,16 @@ void Writer::run() { log("-- addSections"); addSections(); - if (errorHandler().Verbose) { - log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size())); - log("Defined Globals : " + Twine(Out.GlobalSec->InputGlobals.size())); - log("Defined Events : " + Twine(Out.EventSec->InputEvents.size())); + if (errorHandler().verbose) { + log("Defined Functions: " + Twine(out.functionSec->inputFunctions.size())); + log("Defined Globals : " + Twine(out.globalSec->inputGlobals.size())); + log("Defined Events : " + Twine(out.eventSec->inputEvents.size())); log("Function Imports : " + - Twine(Out.ImportSec->getNumImportedFunctions())); - log("Global Imports : " + Twine(Out.ImportSec->getNumImportedGlobals())); - log("Event Imports : " + Twine(Out.ImportSec->getNumImportedEvents())); - for (ObjFile *File : Symtab->ObjectFiles) - File->dumpInfo(); + Twine(out.importSec->getNumImportedFunctions())); + log("Global Imports : " + Twine(out.importSec->getNumImportedGlobals())); + log("Event Imports : " + Twine(out.importSec->getNumImportedEvents())); + for (ObjFile *file : symtab->objectFiles) + file->dumpInfo(); } createHeader(); @@ -868,31 +868,31 @@ void Writer::run() { if (errorCount()) return; - if (Error E = Buffer->commit()) - fatal("failed to write the output file: " + toString(std::move(E))); + if (Error e = buffer->commit()) + fatal("failed to write the output file: " + toString(std::move(e))); } // Open a result file. void Writer::openFile() { - log("writing: " + Config->OutputFile); + log("writing: " + config->outputFile); - Expected> BufferOrErr = - FileOutputBuffer::create(Config->OutputFile, FileSize, + Expected> bufferOrErr = + FileOutputBuffer::create(config->outputFile, fileSize, FileOutputBuffer::F_executable); - if (!BufferOrErr) - error("failed to open " + Config->OutputFile + ": " + - toString(BufferOrErr.takeError())); + if (!bufferOrErr) + error("failed to open " + config->outputFile + ": " + + toString(bufferOrErr.takeError())); else - Buffer = std::move(*BufferOrErr); + buffer = std::move(*bufferOrErr); } void Writer::createHeader() { - raw_string_ostream OS(Header); - writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); - writeU32(OS, WasmVersion, "wasm version"); - OS.flush(); - FileSize += Header.size(); + raw_string_ostream os(header); + writeBytes(os, WasmMagic, sizeof(WasmMagic), "wasm magic"); + writeU32(os, WasmVersion, "wasm version"); + os.flush(); + fileSize += header.size(); } void lld::wasm::writeResult() { Writer().run(); } diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp index 198c1b9..d45f6a4 100644 --- a/lld/wasm/WriterUtils.cpp +++ b/lld/wasm/WriterUtils.cpp @@ -19,159 +19,159 @@ using namespace llvm::wasm; namespace lld { -void wasm::debugWrite(uint64_t Offset, const Twine &Msg) { - LLVM_DEBUG(dbgs() << format(" | %08lld: ", Offset) << Msg << "\n"); +void wasm::debugWrite(uint64_t offset, const Twine &msg) { + LLVM_DEBUG(dbgs() << format(" | %08lld: ", offset) << msg << "\n"); } -void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); - encodeULEB128(Number, OS); +void wasm::writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]"); + encodeULEB128(number, os); } -void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); - encodeSLEB128(Number, OS); +void wasm::writeSleb128(raw_ostream &os, int32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]"); + encodeSLEB128(number, os); } -void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count, - const Twine &Msg) { - debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]"); - OS.write(Bytes, Count); +void wasm::writeBytes(raw_ostream &os, const char *bytes, size_t count, + const Twine &msg) { + debugWrite(os.tell(), msg + " [data[" + Twine(count) + "]]"); + os.write(bytes, count); } -void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) { - debugWrite(OS.tell(), - Msg + " [str[" + Twine(String.size()) + "]: " + String + "]"); - encodeULEB128(String.size(), OS); - OS.write(String.data(), String.size()); +void wasm::writeStr(raw_ostream &os, StringRef string, const Twine &msg) { + debugWrite(os.tell(), + msg + " [str[" + Twine(string.size()) + "]: " + string + "]"); + encodeULEB128(string.size(), os); + os.write(string.data(), string.size()); } -void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) { - debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]"); - OS << Byte; +void wasm::writeU8(raw_ostream &os, uint8_t byte, const Twine &msg) { + debugWrite(os.tell(), msg + " [0x" + utohexstr(byte) + "]"); + os << byte; } -void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]"); - support::endian::write(OS, Number, support::little); +void wasm::writeU32(raw_ostream &os, uint32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[0x" + utohexstr(number) + "]"); + support::endian::write(os, number, support::little); } -void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) { - writeU8(OS, static_cast(Type), - Msg + "[type: " + toString(Type) + "]"); +void wasm::writeValueType(raw_ostream &os, ValType type, const Twine &msg) { + writeU8(os, static_cast(type), + msg + "[type: " + toString(type) + "]"); } -void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) { - writeU8(OS, WASM_TYPE_FUNC, "signature type"); - writeUleb128(OS, Sig.Params.size(), "param Count"); - for (ValType ParamType : Sig.Params) { - writeValueType(OS, ParamType, "param type"); +void wasm::writeSig(raw_ostream &os, const WasmSignature &sig) { + writeU8(os, WASM_TYPE_FUNC, "signature type"); + writeUleb128(os, sig.Params.size(), "param Count"); + for (ValType paramType : sig.Params) { + writeValueType(os, paramType, "param type"); } - writeUleb128(OS, Sig.Returns.size(), "result Count"); - if (Sig.Returns.size()) { - writeValueType(OS, Sig.Returns[0], "result type"); + writeUleb128(os, sig.Returns.size(), "result Count"); + if (sig.Returns.size()) { + writeValueType(os, sig.Returns[0], "result type"); } } -void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) { - writeU8(OS, InitExpr.Opcode, "opcode"); - switch (InitExpr.Opcode) { +void wasm::writeInitExpr(raw_ostream &os, const WasmInitExpr &initExpr) { + writeU8(os, initExpr.Opcode, "opcode"); + switch (initExpr.Opcode) { case WASM_OPCODE_I32_CONST: - writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)"); + writeSleb128(os, initExpr.Value.Int32, "literal (i32)"); break; case WASM_OPCODE_I64_CONST: - writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)"); + writeSleb128(os, initExpr.Value.Int64, "literal (i64)"); break; case WASM_OPCODE_GLOBAL_GET: - writeUleb128(OS, InitExpr.Value.Global, "literal (global index)"); + writeUleb128(os, initExpr.Value.Global, "literal (global index)"); break; default: - fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode)); + fatal("unknown opcode in init expr: " + Twine(initExpr.Opcode)); } - writeU8(OS, WASM_OPCODE_END, "opcode:end"); + writeU8(os, WASM_OPCODE_END, "opcode:end"); } -void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) { - writeU8(OS, Limits.Flags, "limits flags"); - writeUleb128(OS, Limits.Initial, "limits initial"); - if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) - writeUleb128(OS, Limits.Maximum, "limits max"); +void wasm::writeLimits(raw_ostream &os, const WasmLimits &limits) { + writeU8(os, limits.Flags, "limits flags"); + writeUleb128(os, limits.Initial, "limits initial"); + if (limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) + writeUleb128(os, limits.Maximum, "limits max"); } -void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) { +void wasm::writeGlobalType(raw_ostream &os, const WasmGlobalType &type) { // TODO: Update WasmGlobalType to use ValType and remove this cast. - writeValueType(OS, ValType(Type.Type), "global type"); - writeU8(OS, Type.Mutable, "global mutable"); + writeValueType(os, ValType(type.Type), "global type"); + writeU8(os, type.Mutable, "global mutable"); } -void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { - writeGlobalType(OS, Global.Type); - writeInitExpr(OS, Global.InitExpr); +void wasm::writeGlobal(raw_ostream &os, const WasmGlobal &global) { + writeGlobalType(os, global.Type); + writeInitExpr(os, global.InitExpr); } -void wasm::writeEventType(raw_ostream &OS, const WasmEventType &Type) { - writeUleb128(OS, Type.Attribute, "event attribute"); - writeUleb128(OS, Type.SigIndex, "sig index"); +void wasm::writeEventType(raw_ostream &os, const WasmEventType &type) { + writeUleb128(os, type.Attribute, "event attribute"); + writeUleb128(os, type.SigIndex, "sig index"); } -void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) { - writeEventType(OS, Event.Type); +void wasm::writeEvent(raw_ostream &os, const WasmEvent &event) { + writeEventType(os, event.Type); } -void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) { - writeU8(OS, WASM_TYPE_FUNCREF, "table type"); - writeLimits(OS, Type.Limits); +void wasm::writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type) { + writeU8(os, WASM_TYPE_FUNCREF, "table type"); + writeLimits(os, type.Limits); } -void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { - writeStr(OS, Import.Module, "import module name"); - writeStr(OS, Import.Field, "import field name"); - writeU8(OS, Import.Kind, "import kind"); - switch (Import.Kind) { +void wasm::writeImport(raw_ostream &os, const WasmImport &import) { + writeStr(os, import.Module, "import module name"); + writeStr(os, import.Field, "import field name"); + writeU8(os, import.Kind, "import kind"); + switch (import.Kind) { case WASM_EXTERNAL_FUNCTION: - writeUleb128(OS, Import.SigIndex, "import sig index"); + writeUleb128(os, import.SigIndex, "import sig index"); break; case WASM_EXTERNAL_GLOBAL: - writeGlobalType(OS, Import.Global); + writeGlobalType(os, import.Global); break; case WASM_EXTERNAL_EVENT: - writeEventType(OS, Import.Event); + writeEventType(os, import.Event); break; case WASM_EXTERNAL_MEMORY: - writeLimits(OS, Import.Memory); + writeLimits(os, import.Memory); break; case WASM_EXTERNAL_TABLE: - writeTableType(OS, Import.Table); + writeTableType(os, import.Table); break; default: - fatal("unsupported import type: " + Twine(Import.Kind)); + fatal("unsupported import type: " + Twine(import.Kind)); } } -void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) { - writeStr(OS, Export.Name, "export name"); - writeU8(OS, Export.Kind, "export kind"); - switch (Export.Kind) { +void wasm::writeExport(raw_ostream &os, const WasmExport &export_) { + writeStr(os, export_.Name, "export name"); + writeU8(os, export_.Kind, "export kind"); + switch (export_.Kind) { case WASM_EXTERNAL_FUNCTION: - writeUleb128(OS, Export.Index, "function index"); + writeUleb128(os, export_.Index, "function index"); break; case WASM_EXTERNAL_GLOBAL: - writeUleb128(OS, Export.Index, "global index"); + writeUleb128(os, export_.Index, "global index"); break; case WASM_EXTERNAL_MEMORY: - writeUleb128(OS, Export.Index, "memory index"); + writeUleb128(os, export_.Index, "memory index"); break; case WASM_EXTERNAL_TABLE: - writeUleb128(OS, Export.Index, "table index"); + writeUleb128(os, export_.Index, "table index"); break; default: - fatal("unsupported export type: " + Twine(Export.Kind)); + fatal("unsupported export type: " + Twine(export_.Kind)); } } } // namespace lld -std::string lld::toString(ValType Type) { - switch (Type) { +std::string lld::toString(ValType type) { + switch (type) { case ValType::I32: return "i32"; case ValType::I64: @@ -188,28 +188,28 @@ std::string lld::toString(ValType Type) { llvm_unreachable("Invalid wasm::ValType"); } -std::string lld::toString(const WasmSignature &Sig) { - SmallString<128> S("("); - for (ValType Type : Sig.Params) { - if (S.size() != 1) - S += ", "; - S += toString(Type); +std::string lld::toString(const WasmSignature &sig) { + SmallString<128> s("("); + for (ValType type : sig.Params) { + if (s.size() != 1) + s += ", "; + s += toString(type); } - S += ") -> "; - if (Sig.Returns.empty()) - S += "void"; + s += ") -> "; + if (sig.Returns.empty()) + s += "void"; else - S += toString(Sig.Returns[0]); - return S.str(); + s += toString(sig.Returns[0]); + return s.str(); } -std::string lld::toString(const WasmGlobalType &Type) { - return (Type.Mutable ? "var " : "const ") + - toString(static_cast(Type.Type)); +std::string lld::toString(const WasmGlobalType &type) { + return (type.Mutable ? "var " : "const ") + + toString(static_cast(type.Type)); } -std::string lld::toString(const WasmEventType &Type) { - if (Type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION) +std::string lld::toString(const WasmEventType &type) { + if (type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION) return "exception"; return "unknown"; } diff --git a/lld/wasm/WriterUtils.h b/lld/wasm/WriterUtils.h index 389f997..2d4eaf9 100644 --- a/lld/wasm/WriterUtils.h +++ b/lld/wasm/WriterUtils.h @@ -16,50 +16,50 @@ namespace lld { namespace wasm { -void debugWrite(uint64_t Offset, const Twine &Msg); +void debugWrite(uint64_t offset, const Twine &msg); -void writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg); +void writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg); -void writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg); +void writeSleb128(raw_ostream &os, int32_t number, const Twine &msg); -void writeBytes(raw_ostream &OS, const char *Bytes, size_t count, - const Twine &Msg); +void writeBytes(raw_ostream &os, const char *bytes, size_t count, + const Twine &msg); -void writeStr(raw_ostream &OS, StringRef String, const Twine &Msg); +void writeStr(raw_ostream &os, StringRef string, const Twine &msg); -void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg); +void writeU8(raw_ostream &os, uint8_t byte, const Twine &msg); -void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg); +void writeU32(raw_ostream &os, uint32_t number, const Twine &msg); -void writeValueType(raw_ostream &OS, llvm::wasm::ValType Type, - const Twine &Msg); +void writeValueType(raw_ostream &os, llvm::wasm::ValType type, + const Twine &msg); -void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig); +void writeSig(raw_ostream &os, const llvm::wasm::WasmSignature &sig); -void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr); +void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr); -void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); +void writeLimits(raw_ostream &os, const llvm::wasm::WasmLimits &limits); -void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type); +void writeGlobalType(raw_ostream &os, const llvm::wasm::WasmGlobalType &type); -void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); +void writeGlobal(raw_ostream &os, const llvm::wasm::WasmGlobal &global); -void writeEventType(raw_ostream &OS, const llvm::wasm::WasmEventType &Type); +void writeEventType(raw_ostream &os, const llvm::wasm::WasmEventType &type); -void writeEvent(raw_ostream &OS, const llvm::wasm::WasmEvent &Event); +void writeEvent(raw_ostream &os, const llvm::wasm::WasmEvent &event); -void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type); +void writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type); -void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); +void writeImport(raw_ostream &os, const llvm::wasm::WasmImport &import); -void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export); +void writeExport(raw_ostream &os, const llvm::wasm::WasmExport &export_); } // namespace wasm -std::string toString(llvm::wasm::ValType Type); -std::string toString(const llvm::wasm::WasmSignature &Sig); -std::string toString(const llvm::wasm::WasmGlobalType &Type); -std::string toString(const llvm::wasm::WasmEventType &Type); +std::string toString(llvm::wasm::ValType type); +std::string toString(const llvm::wasm::WasmSignature &sig); +std::string toString(const llvm::wasm::WasmGlobalType &type); +std::string toString(const llvm::wasm::WasmEventType &type); } // namespace lld -- 2.7.4