Go to the documentation of this file.
11 #include <unordered_set>
17 : Segname(SegName), Sectname(SectName),
18 CanonicalName((
Twine(SegName) +
Twine(
',') + SectName).str()) {}
21 : Segname(SegName), Sectname(SectName),
22 CanonicalName((
Twine(SegName) +
Twine(
',') + SectName).str()),
41 static constexpr
char TextSegmentName[] =
"__TEXT";
46 case MachO::LC_CODE_SIGNATURE:
49 case MachO::LC_SEGMENT:
54 case MachO::LC_SEGMENT_64:
59 case MachO::LC_SYMTAB:
62 case MachO::LC_DYSYMTAB:
65 case MachO::LC_DYLD_INFO:
66 case MachO::LC_DYLD_INFO_ONLY:
69 case MachO::LC_DATA_IN_CODE:
72 case MachO::LC_LINKER_OPTIMIZATION_HINT:
75 case MachO::LC_FUNCTION_STARTS:
78 case MachO::LC_DYLIB_CODE_SIGN_DRS:
81 case MachO::LC_DYLD_CHAINED_FIXUPS:
84 case MachO::LC_DYLD_EXPORTS_TRIE:
93 auto It = std::stable_partition(
95 [&](
const LoadCommand &LC) { return !ToRemove(LC); });
107 auto It = std::stable_partition(
109 [&](
const std::unique_ptr<Section> &Sec) { return !ToRemove(Sec); });
110 for (
auto I = LC.Sections.begin(), End = It;
I != End; ++
I) {
111 OldIndexToSection[(*I)->Index] =
I->get();
112 (*I)->Index = NextSectionIndex++;
114 LC.Sections.erase(It, LC.Sections.end());
117 auto IsDead = [&](
const std::unique_ptr<SymbolEntry> &
S) ->
bool {
118 std::optional<uint32_t>
Section =
S->section();
125 DeadSymbols.
insert(Sym.get());
128 for (
const std::unique_ptr<Section> &Sec : LC.Sections)
130 if (R.Symbol && *R.Symbol && DeadSymbols.
count(*R.Symbol))
132 "symbol '%s' defined in section with index "
133 "'%u' cannot be removed because it is "
134 "referenced by a relocation in section '%s'",
135 (*R.Symbol)->Name.c_str(),
136 *((*R.Symbol)->section()),
137 Sec->CanonicalName.c_str());
141 S->n_sect = OldIndexToSection[
S->n_sect]->Index;
151 switch (MLC.load_command_data.cmd) {
152 case MachO::LC_SEGMENT:
154 static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +
155 MLC.segment_command_data.vmsize);
157 case MachO::LC_SEGMENT_64:
159 MLC.segment_command_64_data.vmsize);
168 template <
typename SegmentType>
172 assert(SegName.
size() <=
sizeof(Seg.segname) &&
"too long segment name");
173 memset(&Seg, 0,
sizeof(SegmentType));
175 strncpy(Seg.segname, SegName.
data(), SegName.
size());
180 Seg.vmaddr = SegVMAddr;
181 Seg.vmsize = SegVMSize;
189 MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);
192 MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);
206 switch (MLC.load_command_data.cmd) {
207 case MachO::LC_SEGMENT:
209 case MachO::LC_SEGMENT_64:
218 switch (MLC.load_command_data.cmd) {
219 case MachO::LC_SEGMENT:
220 return MLC.segment_command_data.vmaddr;
221 case MachO::LC_SEGMENT_64:
222 return MLC.segment_command_64_data.vmaddr;
std::optional< size_t > DyLdInfoCommandIndex
The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
This is an optimization pass for GlobalISel generic memory operations.
std::optional< size_t > LinkerOptimizationHintCommandIndex
The index of LC_LINKER_OPTIMIZATIN_HINT load command if present.
std::optional< size_t > SymTabCommandIndex
The index of LC_SYMTAB load command if present.
static void constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType, StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize)
The location of the symbol table inside the binary is described by LC_SYMTAB load command.
ReachingDefAnalysis InstSet & ToRemove
static ErrorSuccess success()
Create a success value.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void removeSymbols(function_ref< bool(const std::unique_ptr< SymbolEntry > &)> ToRemove)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
std::optional< size_t > DySymTabCommandIndex
The index LC_DYSYMTAB load command if present.
std::optional< size_t > DylibCodeSignDRsIndex
The index of LC_DYLIB_CODE_SIGN_DRS load command if present.
uint64_t nextAvailableSegmentAddress() const
Error removeLoadCommands(function_ref< bool(const LoadCommand &)> ToRemove)
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
void updateLoadCommandIndexes()
std::optional< size_t > FunctionStartsCommandIndex
The index LC_FUNCTION_STARTS load command if present.
std::optional< StringRef > getSegmentName() const
An efficient, type-erasing, non-owning reference to a callable.
Error removeSections(function_ref< bool(const std::unique_ptr< Section > &)> ToRemove)
std::vector< LoadCommand > LoadCommands
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
std::optional< uint64_t > getSegmentVMAddr() const
MachO::macho_load_command MachOLoadCommand
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const SymbolEntry * getSymbolByIndex(uint32_t Index) const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::optional< size_t > DataInCodeCommandIndex
The index LC_DATA_IN_CODE load command if present.
StringRef - Represent a constant reference to a string, i.e.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
static StringRef extractSegmentName(const char *SegName)
Extracts a segment name from a string which is possibly non-null-terminated.
constexpr size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Lightweight error class with error context and mandatory checking.
std::optional< size_t > TextSegmentCommandIndex
The index of the LC_SEGMENT or LC_SEGMENT_64 load command corresponding to the __TEXT segment.
std::optional< size_t > ChainedFixupsCommandIndex
The index LC_DYLD_CHAINED_FIXUPS load command if present.
Section(StringRef SegName, StringRef SectName)
std::vector< std::unique_ptr< SymbolEntry > > Symbols
std::optional< size_t > ExportsTrieCommandIndex
The index LC_DYLD_EXPORTS_TRIE load command if present.
std::optional< size_t > CodeSignatureCommandIndex
The index of LC_CODE_SIGNATURE load command if present.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.