diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy/COFF/Object.cpp')
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Object.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp index e58e161e7d2..e19cea6aa9d 100644 --- a/llvm/tools/llvm-objcopy/COFF/Object.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Object.h" +#include "llvm/ADT/DenseSet.h" #include <algorithm> namespace llvm { @@ -64,6 +65,68 @@ Error Object::markSymbols() { return Error::success(); } +void Object::addSections(ArrayRef<Section> NewSections) { + for (Section S : NewSections) { + S.UniqueId = NextSectionUniqueId++; + Sections.emplace_back(S); + } + updateSections(); +} + +void Object::updateSections() { + SectionMap = DenseMap<ssize_t, Section *>(Sections.size()); + size_t Index = 1; + for (Section &S : Sections) { + SectionMap[S.UniqueId] = &S; + S.Index = Index++; + } +} + +const Section *Object::findSection(ssize_t UniqueId) const { + auto It = SectionMap.find(UniqueId); + if (It == SectionMap.end()) + return nullptr; + return It->second; +} + +void Object::removeSections(function_ref<bool(const Section &)> ToRemove) { + DenseSet<ssize_t> AssociatedSections; + auto RemoveAssociated = [&AssociatedSections](const Section &Sec) { + return AssociatedSections.count(Sec.UniqueId) == 1; + }; + do { + DenseSet<ssize_t> RemovedSections; + Sections.erase( + std::remove_if(std::begin(Sections), std::end(Sections), + [ToRemove, &RemovedSections](const Section &Sec) { + bool Remove = ToRemove(Sec); + if (Remove) + RemovedSections.insert(Sec.UniqueId); + return Remove; + }), + std::end(Sections)); + // Remove all symbols referring to the removed sections. + AssociatedSections.clear(); + Symbols.erase( + std::remove_if( + std::begin(Symbols), std::end(Symbols), + [&RemovedSections, &AssociatedSections](const Symbol &Sym) { + // If there are sections that are associative to a removed + // section, + // remove those as well as nothing will include them (and we can't + // leave them dangling). + if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) == + 1) + AssociatedSections.insert(Sym.TargetSectionId); + return RemovedSections.count(Sym.TargetSectionId) == 1; + }), + std::end(Symbols)); + ToRemove = RemoveAssociated; + } while (!AssociatedSections.empty()); + updateSections(); + updateSymbols(); +} + } // end namespace coff } // end namespace objcopy } // end namespace llvm |

