From ade55d07871040d0e75b94e3d3a1eaecbd704d36 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Nov 2019 13:49:42 -0700 Subject: [PATCH] [llvm-objcopy][ELF] Add OriginalType & OriginalFlags `llvm::objcopy::elf::*Section::classof` matches Type and Flags, yet Type and Flags are mutable (by setSectionFlagsAndTypes and upcoming --only-keep-debug feature). Add OriginalType & OriginalFlags to be used in classof, to prevent classof results from changing. Reviewed By: jakehehrlich, jhenderson, alexshap Differential Revision: https://reviews.llvm.org/D69739 --- llvm/tools/llvm-objcopy/ELF/Object.cpp | 6 ++-- llvm/tools/llvm-objcopy/ELF/Object.h | 43 ++++++++++++++------------ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp index bbf7ff3ae327..4798c8fed6e1 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -1009,7 +1009,7 @@ void GnuDebugLinkSection::init(StringRef File) { Size = alignTo(FileName.size() + 1, 4) + 4; // The CRC32 will only be aligned if we align the whole section. Align = 4; - Type = ELF::SHT_PROGBITS; + Type = OriginalType = ELF::SHT_PROGBITS; Name = ".gnu_debuglink"; // For sections not found in segments, OriginalOffset is only used to // establish the order that sections should go in. By using the maximum @@ -1521,8 +1521,8 @@ template void ELFBuilder::readSectionHeaders() { } auto &Sec = makeSection(Shdr); Sec.Name = unwrapOrError(ElfFile.getSectionName(&Shdr)); - Sec.Type = Shdr.sh_type; - Sec.Flags = Shdr.sh_flags; + Sec.Type = Sec.OriginalType = Shdr.sh_type; + Sec.Flags = Sec.OriginalFlags = Shdr.sh_flags; Sec.Addr = Shdr.sh_addr; Sec.Offset = Shdr.sh_offset; Sec.OriginalOffset = Shdr.sh_offset; diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h index eeacb014e4dc..70cfc92921a9 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/tools/llvm-objcopy/ELF/Object.h @@ -384,10 +384,13 @@ public: std::string Name; Segment *ParentSegment = nullptr; uint64_t HeaderOffset; - uint64_t OriginalOffset = std::numeric_limits::max(); uint32_t Index; bool HasSymbol = false; + uint64_t OriginalFlags = 0; + uint64_t OriginalType = ELF::SHT_NULL; + uint64_t OriginalOffset = std::numeric_limits::max(); + uint64_t Addr = 0; uint64_t Align = 1; uint32_t EntrySize = 0; @@ -490,7 +493,7 @@ public: OwnedDataSection(StringRef SecName, ArrayRef Data) : Data(std::begin(Data), std::end(Data)) { Name = SecName.str(); - Type = ELF::SHT_PROGBITS; + Type = OriginalType = ELF::SHT_PROGBITS; Size = Data.size(); OriginalOffset = std::numeric_limits::max(); } @@ -498,9 +501,9 @@ public: OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff) { Name = SecName.str(); - Type = ELF::SHT_PROGBITS; + Type = OriginalType = ELF::SHT_PROGBITS; Addr = SecAddr; - Flags = SecFlags; + Flags = OriginalFlags = SecFlags; OriginalOffset = SecOff; } @@ -530,7 +533,7 @@ public: void accept(MutableSectionVisitor &Visitor) override; static bool classof(const SectionBase *S) { - return (S->Flags & ELF::SHF_COMPRESSED) || + return (S->OriginalFlags & ELF::SHF_COMPRESSED) || (StringRef(S->Name).startswith(".zdebug")); } }; @@ -543,7 +546,7 @@ public: : SectionBase(Sec) { Size = Sec.getDecompressedSize(); Align = Sec.getDecompressedAlign(); - Flags = (Flags & ~ELF::SHF_COMPRESSED); + Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED); if (StringRef(Name).startswith(".zdebug")) Name = "." + Name.substr(2); } @@ -567,7 +570,7 @@ class StringTableSection : public SectionBase { public: StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) { - Type = ELF::SHT_STRTAB; + Type = OriginalType = ELF::SHT_STRTAB; } void addString(StringRef Name); @@ -577,9 +580,9 @@ public: void accept(MutableSectionVisitor &Visitor) override; static bool classof(const SectionBase *S) { - if (S->Flags & ELF::SHF_ALLOC) + if (S->OriginalFlags & ELF::SHF_ALLOC) return false; - return S->Type == ELF::SHT_STRTAB; + return S->OriginalType == ELF::SHT_STRTAB; } }; @@ -648,7 +651,7 @@ public: Name = ".symtab_shndx"; Align = 4; EntrySize = 4; - Type = ELF::SHT_SYMTAB_SHNDX; + Type = OriginalType = ELF::SHT_SYMTAB_SHNDX; } }; @@ -666,7 +669,7 @@ protected: using SymPtr = std::unique_ptr; public: - SymbolTableSection() { Type = ELF::SHT_SYMTAB; } + SymbolTableSection() { Type = OriginalType = ELF::SHT_SYMTAB; } void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, @@ -695,7 +698,7 @@ public: const DenseMap &FromTo) override; static bool classof(const SectionBase *S) { - return S->Type == ELF::SHT_SYMTAB; + return S->OriginalType == ELF::SHT_SYMTAB; } }; @@ -724,7 +727,7 @@ public: void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } static bool classof(const SectionBase *S) { - return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA; + return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; } }; @@ -762,9 +765,9 @@ public: const DenseMap &FromTo) override; static bool classof(const SectionBase *S) { - if (S->Flags & ELF::SHF_ALLOC) + if (S->OriginalFlags & ELF::SHF_ALLOC) return false; - return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA; + return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; } }; @@ -799,7 +802,7 @@ public: const DenseMap &FromTo) override; static bool classof(const SectionBase *S) { - return S->Type == ELF::SHT_GROUP; + return S->OriginalType == ELF::SHT_GROUP; } }; @@ -808,7 +811,7 @@ public: explicit DynamicSymbolTableSection(ArrayRef Data) : Section(Data) {} static bool classof(const SectionBase *S) { - return S->Type == ELF::SHT_DYNSYM; + return S->OriginalType == ELF::SHT_DYNSYM; } }; @@ -817,7 +820,7 @@ public: explicit DynamicSection(ArrayRef Data) : Section(Data) {} static bool classof(const SectionBase *S) { - return S->Type == ELF::SHT_DYNAMIC; + return S->OriginalType == ELF::SHT_DYNAMIC; } }; @@ -838,9 +841,9 @@ public: function_ref ToRemove) override; static bool classof(const SectionBase *S) { - if (!(S->Flags & ELF::SHF_ALLOC)) + if (!(S->OriginalFlags & ELF::SHF_ALLOC)) return false; - return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA; + return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; } };