[llvm-objcopy][ELF] Add OriginalType & OriginalFlags

`llvm::objcopy:🧝:*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
This commit is contained in:
Fangrui Song 2019-11-01 13:49:42 -07:00
parent 03bf229bd4
commit ade55d0787
2 changed files with 26 additions and 23 deletions

View File

@ -1009,7 +1009,7 @@ void GnuDebugLinkSection::init(StringRef File) {
Size = alignTo(FileName.size() + 1, 4) + 4; Size = alignTo(FileName.size() + 1, 4) + 4;
// The CRC32 will only be aligned if we align the whole section. // The CRC32 will only be aligned if we align the whole section.
Align = 4; Align = 4;
Type = ELF::SHT_PROGBITS; Type = OriginalType = ELF::SHT_PROGBITS;
Name = ".gnu_debuglink"; Name = ".gnu_debuglink";
// For sections not found in segments, OriginalOffset is only used to // For sections not found in segments, OriginalOffset is only used to
// establish the order that sections should go in. By using the maximum // establish the order that sections should go in. By using the maximum
@ -1521,8 +1521,8 @@ template <class ELFT> void ELFBuilder<ELFT>::readSectionHeaders() {
} }
auto &Sec = makeSection(Shdr); auto &Sec = makeSection(Shdr);
Sec.Name = unwrapOrError(ElfFile.getSectionName(&Shdr)); Sec.Name = unwrapOrError(ElfFile.getSectionName(&Shdr));
Sec.Type = Shdr.sh_type; Sec.Type = Sec.OriginalType = Shdr.sh_type;
Sec.Flags = Shdr.sh_flags; Sec.Flags = Sec.OriginalFlags = Shdr.sh_flags;
Sec.Addr = Shdr.sh_addr; Sec.Addr = Shdr.sh_addr;
Sec.Offset = Shdr.sh_offset; Sec.Offset = Shdr.sh_offset;
Sec.OriginalOffset = Shdr.sh_offset; Sec.OriginalOffset = Shdr.sh_offset;

View File

@ -384,10 +384,13 @@ public:
std::string Name; std::string Name;
Segment *ParentSegment = nullptr; Segment *ParentSegment = nullptr;
uint64_t HeaderOffset; uint64_t HeaderOffset;
uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
uint32_t Index; uint32_t Index;
bool HasSymbol = false; bool HasSymbol = false;
uint64_t OriginalFlags = 0;
uint64_t OriginalType = ELF::SHT_NULL;
uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
uint64_t Addr = 0; uint64_t Addr = 0;
uint64_t Align = 1; uint64_t Align = 1;
uint32_t EntrySize = 0; uint32_t EntrySize = 0;
@ -490,7 +493,7 @@ public:
OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data) OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)
: Data(std::begin(Data), std::end(Data)) { : Data(std::begin(Data), std::end(Data)) {
Name = SecName.str(); Name = SecName.str();
Type = ELF::SHT_PROGBITS; Type = OriginalType = ELF::SHT_PROGBITS;
Size = Data.size(); Size = Data.size();
OriginalOffset = std::numeric_limits<uint64_t>::max(); OriginalOffset = std::numeric_limits<uint64_t>::max();
} }
@ -498,9 +501,9 @@ public:
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags,
uint64_t SecOff) { uint64_t SecOff) {
Name = SecName.str(); Name = SecName.str();
Type = ELF::SHT_PROGBITS; Type = OriginalType = ELF::SHT_PROGBITS;
Addr = SecAddr; Addr = SecAddr;
Flags = SecFlags; Flags = OriginalFlags = SecFlags;
OriginalOffset = SecOff; OriginalOffset = SecOff;
} }
@ -530,7 +533,7 @@ public:
void accept(MutableSectionVisitor &Visitor) override; void accept(MutableSectionVisitor &Visitor) override;
static bool classof(const SectionBase *S) { static bool classof(const SectionBase *S) {
return (S->Flags & ELF::SHF_COMPRESSED) || return (S->OriginalFlags & ELF::SHF_COMPRESSED) ||
(StringRef(S->Name).startswith(".zdebug")); (StringRef(S->Name).startswith(".zdebug"));
} }
}; };
@ -543,7 +546,7 @@ public:
: SectionBase(Sec) { : SectionBase(Sec) {
Size = Sec.getDecompressedSize(); Size = Sec.getDecompressedSize();
Align = Sec.getDecompressedAlign(); Align = Sec.getDecompressedAlign();
Flags = (Flags & ~ELF::SHF_COMPRESSED); Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED);
if (StringRef(Name).startswith(".zdebug")) if (StringRef(Name).startswith(".zdebug"))
Name = "." + Name.substr(2); Name = "." + Name.substr(2);
} }
@ -567,7 +570,7 @@ class StringTableSection : public SectionBase {
public: public:
StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) { StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) {
Type = ELF::SHT_STRTAB; Type = OriginalType = ELF::SHT_STRTAB;
} }
void addString(StringRef Name); void addString(StringRef Name);
@ -577,9 +580,9 @@ public:
void accept(MutableSectionVisitor &Visitor) override; void accept(MutableSectionVisitor &Visitor) override;
static bool classof(const SectionBase *S) { static bool classof(const SectionBase *S) {
if (S->Flags & ELF::SHF_ALLOC) if (S->OriginalFlags & ELF::SHF_ALLOC)
return false; return false;
return S->Type == ELF::SHT_STRTAB; return S->OriginalType == ELF::SHT_STRTAB;
} }
}; };
@ -648,7 +651,7 @@ public:
Name = ".symtab_shndx"; Name = ".symtab_shndx";
Align = 4; Align = 4;
EntrySize = 4; EntrySize = 4;
Type = ELF::SHT_SYMTAB_SHNDX; Type = OriginalType = ELF::SHT_SYMTAB_SHNDX;
} }
}; };
@ -666,7 +669,7 @@ protected:
using SymPtr = std::unique_ptr<Symbol>; using SymPtr = std::unique_ptr<Symbol>;
public: public:
SymbolTableSection() { Type = ELF::SHT_SYMTAB; } SymbolTableSection() { Type = OriginalType = ELF::SHT_SYMTAB; }
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t Value, uint8_t Visibility, uint16_t Shndx,
@ -695,7 +698,7 @@ public:
const DenseMap<SectionBase *, SectionBase *> &FromTo) override; const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
static bool classof(const SectionBase *S) { 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; } void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
static bool classof(const SectionBase *S) { 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<SectionBase *, SectionBase *> &FromTo) override; const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
static bool classof(const SectionBase *S) { static bool classof(const SectionBase *S) {
if (S->Flags & ELF::SHF_ALLOC) if (S->OriginalFlags & ELF::SHF_ALLOC)
return false; 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<SectionBase *, SectionBase *> &FromTo) override; const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
static bool classof(const SectionBase *S) { 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<uint8_t> Data) : Section(Data) {} explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {}
static bool classof(const SectionBase *S) { 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<uint8_t> Data) : Section(Data) {} explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {}
static bool classof(const SectionBase *S) { 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<bool(const SectionBase *)> ToRemove) override; function_ref<bool(const SectionBase *)> ToRemove) override;
static bool classof(const SectionBase *S) { static bool classof(const SectionBase *S) {
if (!(S->Flags & ELF::SHF_ALLOC)) if (!(S->OriginalFlags & ELF::SHF_ALLOC))
return false; return false;
return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA; return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA;
} }
}; };