diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-04-30 11:02:09 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-04-30 11:02:09 +0000 |
commit | 67f590e2867ace532b2a5d9212c4a43bcd7b9557 (patch) | |
tree | 81891dae507a5f201b7016cb7db21443a9018bc7 /llvm/tools/llvm-objcopy/ELF/Object.cpp | |
parent | 648a8cfe70f9cfd507f8bd566c24919510d17270 (diff) | |
download | llvm-67f590e2867ace532b2a5d9212c4a43bcd7b9557.zip llvm-67f590e2867ace532b2a5d9212c4a43bcd7b9557.tar.gz llvm-67f590e2867ace532b2a5d9212c4a43bcd7b9557.tar.bz2 |
[llvm-objcopy] - Check dynamic relocation sections for broken references.
This is a fix for https://bugs.llvm.org/show_bug.cgi?id=41371.
Currently, it is possible to break the sh_link field of the dynamic relocation section
by removing the section it refers to. The patch fixes an issue and adds 2 test cases.
One of them shows that it does not seem possible to break the sh_info field.
I added an assert to verify this.
Differential revision: https://reviews.llvm.org/D60825
llvm-svn: 359552
Diffstat (limited to 'llvm/tools/llvm-objcopy/ELF/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/Object.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp index 3830f92..60163b6 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -680,12 +680,33 @@ void DynamicRelocationSection::accept(SectionVisitor &Visitor) const { } void DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) { - Visitor.visit(*this); -} - -Error Section::removeSectionReferences(bool AllowBrokenDependency, - function_ref<bool(const SectionBase *)> ToRemove) { - if (ToRemove(LinkSection)) { + Visitor.visit(*this);
+}
+
+Error DynamicRelocationSection::removeSectionReferences(
+ bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {
+ if (ToRemove(Symbols)) {
+ if (!AllowBrokenLinks)
+ return createStringError(
+ llvm::errc::invalid_argument,
+ "Symbol table %s cannot be removed because it is "
+ "referenced by the relocation section %s.",
+ Symbols->Name.data(), this->Name.data());
+ Symbols = nullptr;
+ }
+
+ // SecToApplyRel contains a section referenced by sh_info field. It keeps
+ // a section to which the relocation section applies. When we remove any
+ // sections we also remove their relocation sections. Since we do that much
+ // earlier, this assert should never be triggered.
+ assert(!SecToApplyRel || !ToRemove(SecToApplyRel));
+
+ return Error::success();
+}
+
+Error Section::removeSectionReferences(bool AllowBrokenDependency,
+ function_ref<bool(const SectionBase *)> ToRemove) {
+ if (ToRemove(LinkSection)) {
if (!AllowBrokenDependency) return createStringError(llvm::errc::invalid_argument, "Section %s cannot be removed because it is " |