20 void MachOReader::readHeader(
Object &
O)
const {
30 template <
typename SectionType>
32 StringRef SegName(Sec.segname, strnlen(Sec.segname,
sizeof(Sec.segname)));
33 StringRef SectName(Sec.sectname, strnlen(Sec.sectname,
sizeof(Sec.sectname)));
38 S.OriginalOffset = Sec.offset;
40 S.RelOff = Sec.reloff;
41 S.NReloc = Sec.nreloc;
43 S.Reserved1 = Sec.reserved1;
44 S.Reserved2 = Sec.reserved2;
59 template <
typename SectionType,
typename SegmentType>
63 std::vector<std::unique_ptr<Section>> Sections;
64 for (
auto Curr =
reinterpret_cast<const SectionType *
>(LoadCmd.
Ptr +
88 return Data.takeError();
94 S.Relocations.reserve(
S.NReloc);
107 S.Relocations.push_back(R);
110 assert(
S.NReloc ==
S.Relocations.size() &&
111 "Incorrect number of relocations");
119 static constexpr
char TextSegmentName[] =
"__TEXT";
122 switch (LoadCmd.C.cmd) {
123 case MachO::LC_CODE_SIGNATURE:
124 O.CodeSignatureCommandIndex =
O.LoadCommands.size();
126 case MachO::LC_SEGMENT:
130 if (
StringRef(
reinterpret_cast<const char *
>(
133 O.TextSegmentCommandIndex =
O.LoadCommands.size();
135 if (
Expected<std::vector<std::unique_ptr<Section>>> Sections =
136 extractSections<MachO::section, MachO::segment_command>(
137 LoadCmd, MachOObj, NextSectionIndex))
140 return Sections.takeError();
142 case MachO::LC_SEGMENT_64:
146 if (
StringRef(
reinterpret_cast<const char *
>(
149 O.TextSegmentCommandIndex =
O.LoadCommands.size();
151 if (
Expected<std::vector<std::unique_ptr<Section>>> Sections =
152 extractSections<MachO::section_64, MachO::segment_command_64>(
153 LoadCmd, MachOObj, NextSectionIndex))
156 return Sections.takeError();
158 case MachO::LC_SYMTAB:
159 O.SymTabCommandIndex =
O.LoadCommands.size();
161 case MachO::LC_DYSYMTAB:
162 O.DySymTabCommandIndex =
O.LoadCommands.size();
164 case MachO::LC_DYLD_INFO:
165 case MachO::LC_DYLD_INFO_ONLY:
166 O.DyLdInfoCommandIndex =
O.LoadCommands.size();
168 case MachO::LC_DATA_IN_CODE:
169 O.DataInCodeCommandIndex =
O.LoadCommands.size();
171 case MachO::LC_LINKER_OPTIMIZATION_HINT:
172 O.LinkerOptimizationHintCommandIndex =
O.LoadCommands.size();
174 case MachO::LC_FUNCTION_STARTS:
175 O.FunctionStartsCommandIndex =
O.LoadCommands.size();
177 case MachO::LC_DYLD_EXPORTS_TRIE:
178 O.ExportsTrieCommandIndex =
O.LoadCommands.size();
180 case MachO::LC_DYLD_CHAINED_FIXUPS:
181 O.ChainedFixupsCommandIndex =
O.LoadCommands.size();
184 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
185 case MachO::LCName: \
186 memcpy((void *)&(LC.MachOLoadCommand.LCStruct##_data), LoadCmd.Ptr, \
187 sizeof(MachO::LCStruct)); \
188 if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost) \
189 MachO::swapStruct(LC.MachOLoadCommand.LCStruct##_data); \
190 if (LoadCmd.C.cmdsize > sizeof(MachO::LCStruct)) \
191 LC.Payload = ArrayRef<uint8_t>( \
192 reinterpret_cast<uint8_t *>(const_cast<char *>(LoadCmd.Ptr)) + \
193 sizeof(MachO::LCStruct), \
194 LoadCmd.C.cmdsize - sizeof(MachO::LCStruct)); \
197 switch (LoadCmd.C.cmd) {
205 reinterpret_cast<uint8_t *
>(
const_cast<char *
>(LoadCmd.Ptr)) +
209 #include "llvm/BinaryFormat/MachO.def"
216 template <
typename nlist_t>
219 "n_strx exceeds the size of the string table");
229 void MachOReader::readSymbolTable(
Object &
O)
const {
235 Symbol.getRawDataRefImpl()))
237 Symbol.getRawDataRefImpl())));
239 O.SymTable.Symbols.push_back(std::make_unique<SymbolEntry>(SE));
243 void MachOReader::setSymbolInRelocationInfo(
Object &
O)
const {
244 std::vector<const Section *> Sections;
245 for (
auto &LC :
O.LoadCommands)
246 for (std::unique_ptr<Section> &Sec : LC.
Sections)
247 Sections.push_back(Sec.get());
250 for (std::unique_ptr<Section> &Sec : LC.
Sections)
251 for (
auto &Reloc : Sec->Relocations)
252 if (!Reloc.Scattered && !Reloc.IsAddend) {
256 Reloc.Symbol =
O.SymTable.getSymbolByIndex(SymbolNum);
260 assert(SymbolNum >= 1 && SymbolNum <= Sections.size() &&
261 "Invalid section index.");
262 Reloc.Sec = Sections[SymbolNum - 1];
267 void MachOReader::readRebaseInfo(
Object &
O)
const {
271 void MachOReader::readBindInfo(
Object &
O)
const {
275 void MachOReader::readWeakBindInfo(
Object &
O)
const {
279 void MachOReader::readLazyBindInfo(
Object &
O)
const {
283 void MachOReader::readExportInfo(
Object &
O)
const {
292 O.LoadCommands[*LCIndex].MachOLoadCommand.linkedit_data_command_data;
297 void MachOReader::readDataInCodeData(
Object &
O)
const {
298 return readLinkData(
O,
O.DataInCodeCommandIndex,
O.DataInCode);
301 void MachOReader::readLinkerOptimizationHint(
Object &
O)
const {
302 return readLinkData(
O,
O.LinkerOptimizationHintCommandIndex,
303 O.LinkerOptimizationHint);
306 void MachOReader::readFunctionStartsData(
Object &
O)
const {
307 return readLinkData(
O,
O.FunctionStartsCommandIndex,
O.FunctionStarts);
310 void MachOReader::readExportsTrie(
Object &
O)
const {
311 return readLinkData(
O,
O.ExportsTrieCommandIndex,
O.ExportsTrie);
314 void MachOReader::readChainedFixups(
Object &
O)
const {
315 return readLinkData(
O,
O.ChainedFixupsCommandIndex,
O.ChainedFixups);
318 void MachOReader::readIndirectSymbolTable(
Object &
O)
const {
324 if ((
Index & AbsOrLocalMask) != 0)
325 O.IndirectSymTable.Symbols.emplace_back(
Index, None);
327 O.IndirectSymTable.Symbols.emplace_back(
332 void MachOReader::readSwiftVersion(
Object &
O)
const {
333 struct ObjCImageInfo {
339 for (
const std::unique_ptr<Section> &Sec : LC.
Sections)
340 if (Sec->Sectname ==
"__objc_imageinfo" &&
341 (Sec->Segname ==
"__DATA" || Sec->Segname ==
"__DATA_CONST" ||
342 Sec->Segname ==
"__DATA_DIRTY") &&
343 Sec->Content.size() >=
sizeof(ObjCImageInfo)) {
344 memcpy(&ImageInfo, Sec->Content.data(),
sizeof(ObjCImageInfo));
349 O.SwiftVersion = (ImageInfo.Flags >> 8) & 0xff;
355 auto Obj = std::make_unique<Object>();
357 if (
Error E = readLoadCommands(*Obj))
359 readSymbolTable(*Obj);
360 setSymbolInRelocationInfo(*Obj);
361 readRebaseInfo(*Obj);
363 readWeakBindInfo(*Obj);
364 readLazyBindInfo(*Obj);
365 readExportInfo(*Obj);
366 readDataInCodeData(*Obj);
367 readLinkerOptimizationHint(*Obj);
368 readFunctionStartsData(*Obj);
369 readExportsTrie(*Obj);
370 readChainedFixups(*Obj);
371 readIndirectSymbolTable(*Obj);
372 readSwiftVersion(*Obj);