1 //===- Object.cpp ---------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/DenseSet.h"
17 using namespace object
;
19 void Object::addSymbols(ArrayRef
<Symbol
> NewSymbols
) {
20 for (Symbol S
: NewSymbols
) {
21 S
.UniqueId
= NextSymbolUniqueId
++;
22 Symbols
.emplace_back(S
);
27 void Object::updateSymbols() {
28 SymbolMap
= DenseMap
<size_t, Symbol
*>(Symbols
.size());
29 for (Symbol
&Sym
: Symbols
)
30 SymbolMap
[Sym
.UniqueId
] = &Sym
;
33 const Symbol
*Object::findSymbol(size_t UniqueId
) const {
34 auto It
= SymbolMap
.find(UniqueId
);
35 if (It
== SymbolMap
.end())
40 void Object::removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) {
42 std::remove_if(std::begin(Symbols
), std::end(Symbols
),
43 [ToRemove
](const Symbol
&Sym
) { return ToRemove(Sym
); }),
48 Error
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;
60 return Error::success();
63 void Object::addSections(ArrayRef
<Section
> NewSections
) {
64 for (Section S
: NewSections
) {
65 S
.UniqueId
= NextSectionUniqueId
++;
66 Sections
.emplace_back(S
);
71 void Object::updateSections() {
72 SectionMap
= DenseMap
<ssize_t
, Section
*>(Sections
.size());
74 for (Section
&S
: Sections
) {
75 SectionMap
[S
.UniqueId
] = &S
;
80 const Section
*Object::findSection(ssize_t UniqueId
) const {
81 auto It
= SectionMap
.find(UniqueId
);
82 if (It
== SectionMap
.end())
87 void 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;
93 DenseSet
<ssize_t
> RemovedSections
;
95 std::remove_if(std::begin(Sections
), std::end(Sections
),
96 [ToRemove
, &RemovedSections
](const Section
&Sec
) {
97 bool Remove
= ToRemove(Sec
);
99 RemovedSections
.insert(Sec
.UniqueId
);
103 // Remove all symbols referring to the removed sections.
104 AssociatedSections
.clear();
107 std::begin(Symbols
), std::end(Symbols
),
108 [&RemovedSections
, &AssociatedSections
](const Symbol
&Sym
) {
109 // If there are sections that are associative to a removed
111 // remove those as well as nothing will include them (and we can't
112 // leave them dangling).
113 if (RemovedSections
.count(Sym
.AssociativeComdatTargetSectionId
) ==
115 AssociatedSections
.insert(Sym
.TargetSectionId
);
116 return RemovedSections
.count(Sym
.TargetSectionId
) == 1;
119 ToRemove
= RemoveAssociated
;
120 } while (!AssociatedSections
.empty());
125 void Object::truncateSections(function_ref
<bool(const Section
&)> ToTruncate
) {
126 for (Section
&Sec
: Sections
) {
127 if (ToTruncate(Sec
)) {
130 Sec
.Header
.SizeOfRawData
= 0;
135 } // end namespace coff
136 } // end namespace objcopy
137 } // end namespace llvm