1//===- Object.cpp ---------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "Object.h" 10#include "llvm/ADT/DenseSet.h" 11#include <algorithm> 12 13namespace llvm { 14namespace objcopy { 15namespace coff { 16 17using namespace object; 18 19void Object::addSymbols(ArrayRef<Symbol> NewSymbols) { 20 for (Symbol S : NewSymbols) { 21 S.UniqueId = NextSymbolUniqueId++; 22 Symbols.emplace_back(S); 23 } 24 updateSymbols(); 25} 26 27void Object::updateSymbols() { 28 SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size()); 29 for (Symbol &Sym : Symbols) 30 SymbolMap[Sym.UniqueId] = &Sym; 31} 32 33const Symbol *Object::findSymbol(size_t UniqueId) const { 34 auto It = SymbolMap.find(UniqueId); 35 if (It == SymbolMap.end()) 36 return nullptr; 37 return It->second; 38} 39 40void Object::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) { 41 Symbols.erase( 42 std::remove_if(std::begin(Symbols), std::end(Symbols), 43 [ToRemove](const Symbol &Sym) { return ToRemove(Sym); }), 44 std::end(Symbols)); 45 updateSymbols(); 46} 47 48Error Object::markSymbols() { 49 for (Symbol &Sym : Symbols) 50 Sym.Referenced = false; 51 for (const Section &Sec : Sections) { 52 for (const Relocation &R : Sec.Relocs) { 53 auto It = SymbolMap.find(R.Target); 54 if (It == SymbolMap.end()) 55 return createStringError(object_error::invalid_symbol_index, 56 "relocation target %zu not found", R.Target); 57 It->second->Referenced = true; 58 } 59 } 60 return Error::success(); 61} 62 63void Object::addSections(ArrayRef<Section> NewSections) { 64 for (Section S : NewSections) { 65 S.UniqueId = NextSectionUniqueId++; 66 Sections.emplace_back(S); 67 } 68 updateSections(); 69} 70 71void Object::updateSections() { 72 SectionMap = DenseMap<ssize_t, Section *>(Sections.size()); 73 size_t Index = 1; 74 for (Section &S : Sections) { 75 SectionMap[S.UniqueId] = &S; 76 S.Index = Index++; 77 } 78} 79 80const Section *Object::findSection(ssize_t UniqueId) const { 81 auto It = SectionMap.find(UniqueId); 82 if (It == SectionMap.end()) 83 return nullptr; 84 return It->second; 85} 86 87void Object::removeSections(function_ref<bool(const Section &)> ToRemove) { 88 DenseSet<ssize_t> AssociatedSections; 89 auto RemoveAssociated = [&AssociatedSections](const Section &Sec) { 90 return AssociatedSections.count(Sec.UniqueId) == 1; 91 }; 92 do { 93 DenseSet<ssize_t> RemovedSections; 94 Sections.erase( 95 std::remove_if(std::begin(Sections), std::end(Sections), 96 [ToRemove, &RemovedSections](const Section &Sec) { 97 bool Remove = ToRemove(Sec); 98 if (Remove) 99 RemovedSections.insert(Sec.UniqueId); 100 return Remove; 101 }), 102 std::end(Sections)); 103 // Remove all symbols referring to the removed sections. 104 AssociatedSections.clear(); 105 Symbols.erase( 106 std::remove_if( 107 std::begin(Symbols), std::end(Symbols), 108 [&RemovedSections, &AssociatedSections](const Symbol &Sym) { 109 // If there are sections that are associative to a removed 110 // section, 111 // remove those as well as nothing will include them (and we can't 112 // leave them dangling). 113 if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) == 114 1) 115 AssociatedSections.insert(Sym.TargetSectionId); 116 return RemovedSections.count(Sym.TargetSectionId) == 1; 117 }), 118 std::end(Symbols)); 119 ToRemove = RemoveAssociated; 120 } while (!AssociatedSections.empty()); 121 updateSections(); 122 updateSymbols(); 123} 124 125void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) { 126 for (Section &Sec : Sections) { 127 if (ToTruncate(Sec)) { 128 Sec.clearContents(); 129 Sec.Relocs.clear(); 130 Sec.Header.SizeOfRawData = 0; 131 } 132 } 133} 134 135} // end namespace coff 136} // end namespace objcopy 137} // end namespace llvm 138