aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objcopy/ELF/Object.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2019-04-30 11:02:09 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2019-04-30 11:02:09 +0000
commit67f590e2867ace532b2a5d9212c4a43bcd7b9557 (patch)
tree81891dae507a5f201b7016cb7db21443a9018bc7 /llvm/tools/llvm-objcopy/ELF/Object.cpp
parent648a8cfe70f9cfd507f8bd566c24919510d17270 (diff)
downloadllvm-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.cpp33
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 "