LLVM: lib/ObjCopy/MachO/MachOObject.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
11
12using namespace llvm;
14
18
23
28
33
36 Callable(*Sym);
37
38
39 auto ExternalBegin = std::stable_partition(
41 [](const auto &Sym) { return Sym->isLocalSymbol(); });
42 std::stable_partition(ExternalBegin, std::end(Symbols), [](const auto &Sym) {
43 return !Sym->isUndefinedSymbol();
44 });
45}
46
51
53 static constexpr char TextSegmentName[] = "__TEXT";
54
58 case MachO::LC_CODE_SIGNATURE:
60 break;
61 case MachO::LC_SEGMENT:
63 TextSegmentName)
65 break;
66 case MachO::LC_SEGMENT_64:
68 TextSegmentName)
70 break;
71 case MachO::LC_SYMTAB:
73 break;
74 case MachO::LC_DYSYMTAB:
76 break;
77 case MachO::LC_DYLD_INFO:
78 case MachO::LC_DYLD_INFO_ONLY:
80 break;
81 case MachO::LC_DATA_IN_CODE:
83 break;
84 case MachO::LC_LINKER_OPTIMIZATION_HINT:
86 break;
87 case MachO::LC_FUNCTION_STARTS:
89 break;
90 case MachO::LC_DYLIB_CODE_SIGN_DRS:
92 break;
93 case MachO::LC_DYLD_CHAINED_FIXUPS:
95 break;
96 case MachO::LC_DYLD_EXPORTS_TRIE:
98 break;
99 }
100 }
101}
102
105 auto It = std::stable_partition(
107 [&](const LoadCommand &LC) { return !ToRemove(LC); });
109
112}
113
117 uint32_t NextSectionIndex = 1;
119 auto It = std::stable_partition(
120 std::begin(LC.Sections), std::end(LC.Sections),
121 [&](const std::unique_ptr
122 for (auto I = LC.Sections.begin(), End = It; I != End; ++I) {
123 OldIndexToSection[(*I)->Index] = I->get();
124 (*I)->Index = NextSectionIndex++;
125 }
126 LC.Sections.erase(It, LC.Sections.end());
127 }
128
129 auto IsDead = [&](const std::unique_ptr &S) -> bool {
130 std::optional<uint32_t> Section = S->section();
132 };
133
135 for (const std::unique_ptr &Sym : SymTable.Symbols)
137 DeadSymbols.insert(Sym.get());
138
140 for (const std::unique_ptr
142 if (R.Symbol && *R.Symbol && DeadSymbols.count(*R.Symbol))
144 "symbol '%s' defined in section with index "
145 "'%u' cannot be removed because it is "
146 "referenced by a relocation in section '%s'",
147 (*R.Symbol)->Name.c_str(),
148 *((*R.Symbol)->section()),
149 Sec->CanonicalName.c_str());
151 for (std::unique_ptr &S : SymTable.Symbols)
152 if (S->section())
153 S->n_sect = OldIndexToSection[S->n_sect]->Index;
155}
156
163 switch (MLC.load_command_data.cmd) {
164 case MachO::LC_SEGMENT:
165 Addr = std::max(Addr,
166 static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +
167 MLC.segment_command_data.vmsize);
168 break;
169 case MachO::LC_SEGMENT_64:
170 Addr = std::max(Addr, MLC.segment_command_64_data.vmaddr +
171 MLC.segment_command_64_data.vmsize);
172 break;
173 default:
174 continue;
175 }
176 }
177 return Addr;
178}
179
180template
181static void
184 assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name");
185 memset(&Seg, 0, sizeof(SegmentType));
186 Seg.cmd = CmdType;
187 strncpy(Seg.segname, SegName.data(), SegName.size());
188 Seg.maxprot |=
190 Seg.initprot |=
192 Seg.vmaddr = SegVMAddr;
193 Seg.vmsize = SegVMSize;
194}
195
201 MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);
202 else
204 MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);
205
208}
209
210
215
218 switch (MLC.load_command_data.cmd) {
219 case MachO::LC_SEGMENT:
221 case MachO::LC_SEGMENT_64:
223 default:
224 return std::nullopt;
225 }
226}
227
230 switch (MLC.load_command_data.cmd) {
231 case MachO::LC_SEGMENT:
232 return MLC.segment_command_data.vmaddr;
233 case MachO::LC_SEGMENT_64:
234 return MLC.segment_command_64_data.vmaddr;
235 default:
236 return std::nullopt;
237 }
238}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static void constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType, StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize)
Definition MachOObject.cpp:182
static StringRef extractSegmentName(const char *SegName)
Extracts a segment name from a string which is possibly non-null-terminated.
Definition MachOObject.cpp:211
This file defines the SmallPtrSet class.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
An efficient, type-erasing, non-owning reference to a callable.
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
size_t strnlen(const char *S, size_t MaxLen) asm("llvm_zos_strnlen")
MachO::macho_load_command MachOLoadCommand
std::optional< StringRef > getSegmentName() const
Definition MachOObject.cpp:216
std::optional< uint64_t > getSegmentVMAddr() const
Definition MachOObject.cpp:228
std::optional< size_t > FunctionStartsCommandIndex
The index LC_FUNCTION_STARTS load command if present.
void updateLoadCommandIndexes()
Definition MachOObject.cpp:52
Error removeLoadCommands(function_ref< bool(const LoadCommand &)> ToRemove)
Definition MachOObject.cpp:103
std::optional< size_t > ChainedFixupsCommandIndex
The index LC_DYLD_CHAINED_FIXUPS load command if present.
std::optional< size_t > ExportsTrieCommandIndex
The index LC_DYLD_EXPORTS_TRIE load command if present.
Error removeSections(function_ref< bool(const std::unique_ptr< Section > &)> ToRemove)
Definition MachOObject.cpp:114
std::optional< size_t > DylibCodeSignDRsIndex
The index of LC_DYLIB_CODE_SIGN_DRS load command if present.
std::optional< size_t > SymTabCommandIndex
The index of LC_SYMTAB load command if present.
std::optional< size_t > DyLdInfoCommandIndex
The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
std::vector< LoadCommand > LoadCommands
std::optional< size_t > DataInCodeCommandIndex
The index LC_DATA_IN_CODE load command if present.
std::optional< size_t > DySymTabCommandIndex
The index LC_DYSYMTAB load command if present.
std::optional< size_t > TextSegmentCommandIndex
The index of the LC_SEGMENT or LC_SEGMENT_64 load command corresponding to the __TEXT segment.
uint64_t nextAvailableSegmentAddress() const
Definition MachOObject.cpp:157
std::optional< size_t > CodeSignatureCommandIndex
The index of LC_CODE_SIGNATURE load command if present.
LoadCommand & addSegment(StringRef SegName, uint64_t SegVMSize)
Creates a new segment load command in the object and returns a reference to the newly created load co...
Definition MachOObject.cpp:196
std::optional< size_t > LinkerOptimizationHintCommandIndex
The index of LC_LINKER_OPTIMIZATIN_HINT load command if present.
Section(StringRef SegName, StringRef SectName)
Definition MachOObject.cpp:15
std::string CanonicalName
The location of the symbol table inside the binary is described by LC_SYMTAB load command.
void updateSymbols(function_ref< void(SymbolEntry &)> Callable)
Definition MachOObject.cpp:34
const SymbolEntry * getSymbolByIndex(uint32_t Index) const
Definition MachOObject.cpp:24
std::vector< std::unique_ptr< SymbolEntry > > Symbols
void removeSymbols(function_ref< bool(const std::unique_ptr< SymbolEntry > &)> ToRemove)
Definition MachOObject.cpp:47