1 //===- COFFObject.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 //===----------------------------------------------------------------------===//
9 #include "COFFObject.h"
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 return SymbolMap
.lookup(UniqueId
);
37 Error
Object::removeSymbols(
38 function_ref
<Expected
<bool>(const Symbol
&)> ToRemove
) {
39 Error Errs
= Error::success();
40 llvm::erase_if(Symbols
, [ToRemove
, &Errs
](const Symbol
&Sym
) {
41 Expected
<bool> ShouldRemove
= ToRemove(Sym
);
43 Errs
= joinErrors(std::move(Errs
), ShouldRemove
.takeError());
53 Error
Object::markSymbols() {
54 for (Symbol
&Sym
: Symbols
)
55 Sym
.Referenced
= false;
56 for (const Section
&Sec
: Sections
) {
57 for (const Relocation
&R
: Sec
.Relocs
) {
58 auto It
= SymbolMap
.find(R
.Target
);
59 if (It
== SymbolMap
.end())
60 return createStringError(object_error::invalid_symbol_index
,
61 "relocation target %zu not found", R
.Target
);
62 It
->second
->Referenced
= true;
65 return Error::success();
68 void Object::addSections(ArrayRef
<Section
> NewSections
) {
69 for (Section S
: NewSections
) {
70 S
.UniqueId
= NextSectionUniqueId
++;
71 Sections
.emplace_back(S
);
76 void Object::updateSections() {
77 SectionMap
= DenseMap
<ssize_t
, Section
*>(Sections
.size());
79 for (Section
&S
: Sections
) {
80 SectionMap
[S
.UniqueId
] = &S
;
85 const Section
*Object::findSection(ssize_t UniqueId
) const {
86 return SectionMap
.lookup(UniqueId
);
89 void Object::removeSections(function_ref
<bool(const Section
&)> ToRemove
) {
90 DenseSet
<ssize_t
> AssociatedSections
;
91 auto RemoveAssociated
= [&AssociatedSections
](const Section
&Sec
) {
92 return AssociatedSections
.contains(Sec
.UniqueId
);
95 DenseSet
<ssize_t
> RemovedSections
;
96 llvm::erase_if(Sections
, [ToRemove
, &RemovedSections
](const Section
&Sec
) {
97 bool Remove
= ToRemove(Sec
);
99 RemovedSections
.insert(Sec
.UniqueId
);
102 // Remove all symbols referring to the removed sections.
103 AssociatedSections
.clear();
105 Symbols
, [&RemovedSections
, &AssociatedSections
](const Symbol
&Sym
) {
106 // If there are sections that are associative to a removed
108 // remove those as well as nothing will include them (and we can't
109 // leave them dangling).
110 if (RemovedSections
.contains(Sym
.AssociativeComdatTargetSectionId
))
111 AssociatedSections
.insert(Sym
.TargetSectionId
);
112 return RemovedSections
.contains(Sym
.TargetSectionId
);
114 ToRemove
= RemoveAssociated
;
115 } while (!AssociatedSections
.empty());
120 void Object::truncateSections(function_ref
<bool(const Section
&)> ToTruncate
) {
121 for (Section
&Sec
: Sections
) {
122 if (ToTruncate(Sec
)) {
125 Sec
.Header
.SizeOfRawData
= 0;
130 } // end namespace coff
131 } // end namespace objcopy
132 } // end namespace llvm