Index: COFF/Chunks.h =================================================================== --- COFF/Chunks.h +++ COFF/Chunks.h @@ -54,7 +54,7 @@ // doesn't even have actual data (if common or bss). class Chunk { public: - enum Kind : uint8_t { SectionKind, OtherKind }; + enum Kind : uint8_t { SectionKind, OtherKind, ImportThunkKind }; Kind kind() const { return ChunkKind; } // Returns the size of this chunk (even if this is a common or BSS.) @@ -167,19 +167,14 @@ // Collect all locations that contain absolute addresses for base relocations. virtual void getBaserels(std::vector *Res) {} - // 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. - virtual bool isHotPatchable() const { return false; } - // 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() == OtherKind; } + static bool classof(const Chunk *C) { return C->kind() != SectionKind; } protected: - NonSectionChunk() : Chunk(OtherKind) {} + NonSectionChunk(Kind K = OtherKind) : Chunk(K) {} }; // A chunk corresponding a section of an input file. @@ -250,8 +245,6 @@ return getSectionName().startswith(".debug_") || getSectionName() == ".eh_frame"; } - bool isHotPatchable() const { return File->HotPatchable; } - // Allow iteration over the bodies of this chunk's relocated symbols. llvm::iterator_range symbols() const { return llvm::make_range(symbol_iterator(File, RelocsData), @@ -379,13 +372,6 @@ static_cast(this)->writeTo(Buf); } -inline bool Chunk::isHotPatchable() const { - if (isa(this)) - return static_cast(this)->isHotPatchable(); - else - return static_cast(this)->isHotPatchable(); -} - inline StringRef Chunk::getSectionName() const { if (isa(this)) return static_cast(this)->getSectionName(); @@ -478,57 +464,44 @@ // Windows-specific. // A chunk for DLL import jump table entry. In a final output, its // contents will be a JMP instruction to some __imp_ symbol. -class ImportThunkChunkX64 : public NonSectionChunk { +class ImportThunkChunk : public NonSectionChunk { +public: + ImportThunkChunk(Defined *S) + : NonSectionChunk(ImportThunkKind), ImpSymbol(S) {} + static bool classof(const Chunk *C) { return C->kind() == ImportThunkKind; } + +protected: + 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; - - bool isHotPatchable() const override { return true; } - -private: - Defined *ImpSymbol; }; -class ImportThunkChunkX86 : public NonSectionChunk { +class ImportThunkChunkX86 : public ImportThunkChunk { public: - explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) { - } + 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; - - bool isHotPatchable() const override { return true; } - -private: - Defined *ImpSymbol; }; -class ImportThunkChunkARM : public NonSectionChunk { +class ImportThunkChunkARM : public ImportThunkChunk { public: - explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) { - } + 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; - - bool isHotPatchable() const override { return true; } - -private: - Defined *ImpSymbol; }; -class ImportThunkChunkARM64 : public NonSectionChunk { +class ImportThunkChunkARM64 : public ImportThunkChunk { public: - explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) { - } + explicit ImportThunkChunkARM64(Defined *S) : ImportThunkChunk(S) {} size_t getSize() const override { return sizeof(ImportThunkARM64); } void writeTo(uint8_t *Buf) const override; - - bool isHotPatchable() const override { return true; } - -private: - Defined *ImpSymbol; }; class RangeExtensionThunkARM : public NonSectionChunk { @@ -684,6 +657,17 @@ 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; + else if (isa(this)) + return true; + return false; +} + void applyMOV32T(uint8_t *Off, uint32_t V); void applyBranch24T(uint8_t *Off, int32_t V); Index: COFF/Chunks.cpp =================================================================== --- COFF/Chunks.cpp +++ COFF/Chunks.cpp @@ -649,7 +649,7 @@ Buf[Str.size()] = '\0'; } -ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(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);