LLVM: lib/ObjCopy/MachO/MachOObject.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12#include <unordered_set>

13

14using namespace llvm;

16

18 : Segname(SegName), Sectname(SectName),

19 CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {}

20

22 : Segname(SegName), Sectname(SectName),

23 CanonicalName((Twine(SegName) + Twine(',') + SectName).str()),

25

27 assert(Index < Symbols.size() && "invalid symbol index");

28 return Symbols[Index].get();

29}

30

34}

35

38 Callable(*Sym);

39

40

41 auto ExternalBegin = std::stable_partition(

43 [](const auto &Sym) { return Sym->isLocalSymbol(); });

44 std::stable_partition(ExternalBegin, std::end(Symbols), [](const auto &Sym) {

45 return Sym->isUndefinedSymbol();

46 });

47}

48

52}

53

55 static constexpr char TextSegmentName[] = "__TEXT";

56

60 case MachO::LC_CODE_SIGNATURE:

62 break;

63 case MachO::LC_SEGMENT:

65 TextSegmentName)

67 break;

68 case MachO::LC_SEGMENT_64:

70 TextSegmentName)

72 break;

73 case MachO::LC_SYMTAB:

75 break;

76 case MachO::LC_DYSYMTAB:

78 break;

79 case MachO::LC_DYLD_INFO:

80 case MachO::LC_DYLD_INFO_ONLY:

82 break;

83 case MachO::LC_DATA_IN_CODE:

85 break;

86 case MachO::LC_LINKER_OPTIMIZATION_HINT:

88 break;

89 case MachO::LC_FUNCTION_STARTS:

91 break;

92 case MachO::LC_DYLIB_CODE_SIGN_DRS:

94 break;

95 case MachO::LC_DYLD_CHAINED_FIXUPS:

97 break;

98 case MachO::LC_DYLD_EXPORTS_TRIE:

100 break;

101 case MachO::LC_ENCRYPTION_INFO:

102 case MachO::LC_ENCRYPTION_INFO_64:

104 break;

105 }

106 }

107}

108

111 auto It = std::stable_partition(

113 [&](const LoadCommand &LC) { return !ToRemove(LC); });

115

118}

119

123 uint32_t NextSectionIndex = 1;

125 auto It = std::stable_partition(

126 std::begin(LC.Sections), std::end(LC.Sections),

127 [&](const std::unique_ptr

&Sec) { return !ToRemove(Sec); });

128 for (auto I = LC.Sections.begin(), End = It; I != End; ++I) {

129 OldIndexToSection[(*I)->Index] = I->get();

130 (*I)->Index = NextSectionIndex++;

131 }

132 LC.Sections.erase(It, LC.Sections.end());

133 }

134

135 auto IsDead = [&](const std::unique_ptr &S) -> bool {

136 std::optional<uint32_t> Section = S->section();

138 };

139

144

146 for (const std::unique_ptr

&Sec : LC.Sections)

148 if (R.Symbol && *R.Symbol && DeadSymbols.count(*R.Symbol))

150 "symbol '%s' defined in section with index "

151 "'%u' cannot be removed because it is "

152 "referenced by a relocation in section '%s'",

153 (*R.Symbol)->Name.c_str(),

154 *((*R.Symbol)->section()),

155 Sec->CanonicalName.c_str());

158 if (S->section())

159 S->n_sect = OldIndexToSection[S->n_sect]->Index;

161}

162

169 switch (MLC.load_command_data.cmd) {

170 case MachO::LC_SEGMENT:

172 static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +

173 MLC.segment_command_data.vmsize);

174 break;

175 case MachO::LC_SEGMENT_64:

176 Addr = std::max(Addr, MLC.segment_command_64_data.vmaddr +

177 MLC.segment_command_64_data.vmsize);

178 break;

179 default:

180 continue;

181 }

182 }

184}

185

186template

187static void

190 assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name");

191 memset(&Seg, 0, sizeof(SegmentType));

192 Seg.cmd = CmdType;

193 strncpy(Seg.segname, SegName.data(), SegName.size());

194 Seg.maxprot |=

196 Seg.initprot |=

198 Seg.vmaddr = SegVMAddr;

199 Seg.vmsize = SegVMSize;

200}

201

207 MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);

208 else

210 MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);

211

214}

215

216

220}

221

224 switch (MLC.load_command_data.cmd) {

225 case MachO::LC_SEGMENT:

227 case MachO::LC_SEGMENT_64:

229 default:

230 return std::nullopt;

231 }

232}

233

236 switch (MLC.load_command_data.cmd) {

237 case MachO::LC_SEGMENT:

238 return MLC.segment_command_data.vmaddr;

239 case MachO::LC_SEGMENT_64:

240 return MLC.segment_command_64_data.vmaddr;

241 default:

242 return std::nullopt;

243 }

244}

ReachingDefAnalysis InstSet & ToRemove

static void constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType, StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize)

static StringRef extractSegmentName(const char *SegName)

Extracts a segment name from a string which is possibly non-null-terminated.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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...

MachO::macho_load_command MachOLoadCommand

std::optional< StringRef > getSegmentName() const

std::optional< uint64_t > getSegmentVMAddr() const

std::optional< size_t > FunctionStartsCommandIndex

The index LC_FUNCTION_STARTS load command if present.

void updateLoadCommandIndexes()

Error removeLoadCommands(function_ref< bool(const LoadCommand &)> ToRemove)

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)

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 > EncryptionInfoCommandIndex

The index of the LC_ENCRYPTION_INFO or LC_ENCRYPTION_INFO_64 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

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...

std::optional< size_t > LinkerOptimizationHintCommandIndex

The index of LC_LINKER_OPTIMIZATIN_HINT load command if present.

Section(StringRef SegName, StringRef SectName)

The location of the symbol table inside the binary is described by LC_SYMTAB load command.

void updateSymbols(function_ref< void(SymbolEntry &)> Callable)

const SymbolEntry * getSymbolByIndex(uint32_t Index) const

std::vector< std::unique_ptr< SymbolEntry > > Symbols

void removeSymbols(function_ref< bool(const std::unique_ptr< SymbolEntry > &)> ToRemove)