20void MachOReader::readHeader(
Object &O)
const {
30template <
typename SectionType>
32 StringRef SegName(Sec.segname, strnlen(Sec.segname,
sizeof(Sec.segname)));
33 StringRef SectName(Sec.sectname, strnlen(Sec.sectname,
sizeof(Sec.sectname)));
59template <
typename SectionType,
typename SegmentType>
63 std::vector<std::unique_ptr<Section>> Sections;
64 for (
auto Curr =
reinterpret_cast<const SectionType *
>(LoadCmd.
Ptr +
66 End =
reinterpret_cast<const SectionType *
>(LoadCmd.
Ptr +
70 memcpy((
void *)&Sec,
reinterpret_cast<const char *
>(Curr),
89 return Data.takeError();
112 "Incorrect number of relocations");
114 return std::move(Sections);
117Error MachOReader::readLoadCommands(
Object &O)
const {
120 static constexpr char TextSegmentName[] =
"__TEXT";
123 switch (LoadCmd.C.cmd) {
124 case MachO::LC_CODE_SIGNATURE:
125 O.CodeSignatureCommandIndex =
O.LoadCommands.size();
127 case MachO::LC_SEGMENT:
131 if (
StringRef(
reinterpret_cast<const char *
>(
134 O.TextSegmentCommandIndex =
O.LoadCommands.size();
136 if (
Expected<std::vector<std::unique_ptr<Section>>> Sections =
137 extractSections<MachO::section, MachO::segment_command>(
138 LoadCmd, MachOObj, NextSectionIndex))
141 return Sections.takeError();
143 case MachO::LC_SEGMENT_64:
147 if (
StringRef(
reinterpret_cast<const char *
>(
150 O.TextSegmentCommandIndex =
O.LoadCommands.size();
152 if (
Expected<std::vector<std::unique_ptr<Section>>> Sections =
153 extractSections<MachO::section_64, MachO::segment_command_64>(
154 LoadCmd, MachOObj, NextSectionIndex))
157 return Sections.takeError();
159 case MachO::LC_SYMTAB:
160 O.SymTabCommandIndex =
O.LoadCommands.size();
162 case MachO::LC_DYSYMTAB:
163 O.DySymTabCommandIndex =
O.LoadCommands.size();
165 case MachO::LC_DYLD_INFO:
166 case MachO::LC_DYLD_INFO_ONLY:
167 O.DyLdInfoCommandIndex =
O.LoadCommands.size();
169 case MachO::LC_DATA_IN_CODE:
170 O.DataInCodeCommandIndex =
O.LoadCommands.size();
172 case MachO::LC_LINKER_OPTIMIZATION_HINT:
173 O.LinkerOptimizationHintCommandIndex =
O.LoadCommands.size();
175 case MachO::LC_FUNCTION_STARTS:
176 O.FunctionStartsCommandIndex =
O.LoadCommands.size();
178 case MachO::LC_DYLIB_CODE_SIGN_DRS:
179 O.DylibCodeSignDRsIndex =
O.LoadCommands.size();
181 case MachO::LC_DYLD_EXPORTS_TRIE:
182 O.ExportsTrieCommandIndex =
O.LoadCommands.size();
184 case MachO::LC_DYLD_CHAINED_FIXUPS:
185 O.ChainedFixupsCommandIndex =
O.LoadCommands.size();
187 case MachO::LC_ENCRYPTION_INFO:
188 case MachO::LC_ENCRYPTION_INFO_64:
189 O.EncryptionInfoCommandIndex =
O.LoadCommands.size();
192#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
193 case MachO::LCName: \
194 memcpy((void *)&(LC.MachOLoadCommand.LCStruct##_data), LoadCmd.Ptr, \
195 sizeof(MachO::LCStruct)); \
196 if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost) \
197 MachO::swapStruct(LC.MachOLoadCommand.LCStruct##_data); \
198 if (LoadCmd.C.cmdsize > sizeof(MachO::LCStruct)) \
199 LC.Payload = ArrayRef<uint8_t>( \
200 reinterpret_cast<uint8_t *>(const_cast<char *>(LoadCmd.Ptr)) + \
201 sizeof(MachO::LCStruct), \
202 LoadCmd.C.cmdsize - sizeof(MachO::LCStruct)); \
205 switch (LoadCmd.C.cmd) {
213 reinterpret_cast<uint8_t *
>(
const_cast<char *
>(LoadCmd.Ptr)) +
217#include "llvm/BinaryFormat/MachO.def"
219 O.LoadCommands.push_back(std::move(LC));
224template <
typename nlist_t>
227 "n_strx exceeds the size of the string table");
237void MachOReader::readSymbolTable(
Object &O)
const {
239 for (
auto Symbol : MachOObj.
symbols()) {
243 Symbol.getRawDataRefImpl()))
245 Symbol.getRawDataRefImpl())));
247 O.SymTable.Symbols.push_back(std::make_unique<SymbolEntry>(SE));
251void MachOReader::setSymbolInRelocationInfo(
Object &O)
const {
252 std::vector<const Section *> Sections;
253 for (
auto &LC :
O.LoadCommands)
254 for (std::unique_ptr<Section> &Sec : LC.
Sections)
255 Sections.push_back(Sec.get());
258 for (std::unique_ptr<Section> &Sec : LC.
Sections)
259 for (
auto &Reloc : Sec->Relocations)
260 if (!Reloc.Scattered && !Reloc.IsAddend) {
264 Reloc.Symbol =
O.SymTable.getSymbolByIndex(SymbolNum);
268 assert(SymbolNum >= 1 && SymbolNum <= Sections.size() &&
269 "Invalid section index.");
270 Reloc.Sec = Sections[SymbolNum - 1];
275void MachOReader::readRebaseInfo(
Object &O)
const {
279void MachOReader::readBindInfo(
Object &O)
const {
283void MachOReader::readWeakBindInfo(
Object &O)
const {
287void MachOReader::readLazyBindInfo(
Object &O)
const {
291void MachOReader::readExportInfo(
Object &O)
const {
296 O.Exports.Trie = Trie;
299void MachOReader::readLinkData(
Object &O, std::optional<size_t> LCIndex,
304 O.LoadCommands[*LCIndex].MachOLoadCommand.linkedit_data_command_data;
309void MachOReader::readDataInCodeData(
Object &O)
const {
310 return readLinkData(O,
O.DataInCodeCommandIndex,
O.DataInCode);
313void MachOReader::readLinkerOptimizationHint(
Object &O)
const {
314 return readLinkData(O,
O.LinkerOptimizationHintCommandIndex,
315 O.LinkerOptimizationHint);
318void MachOReader::readFunctionStartsData(
Object &O)
const {
319 return readLinkData(O,
O.FunctionStartsCommandIndex,
O.FunctionStarts);
322void MachOReader::readDylibCodeSignDRs(
Object &O)
const {
323 return readLinkData(O,
O.DylibCodeSignDRsIndex,
O.DylibCodeSignDRs);
326void MachOReader::readExportsTrie(
Object &O)
const {
327 return readLinkData(O,
O.ExportsTrieCommandIndex,
O.ExportsTrie);
330void MachOReader::readChainedFixups(
Object &O)
const {
331 return readLinkData(O,
O.ChainedFixupsCommandIndex,
O.ChainedFixups);
334void MachOReader::readIndirectSymbolTable(
Object &O)
const {
340 if ((Index & AbsOrLocalMask) != 0)
341 O.IndirectSymTable.Symbols.emplace_back(Index, std::nullopt);
343 O.IndirectSymTable.Symbols.emplace_back(
344 Index,
O.SymTable.getSymbolByIndex(Index));
348void MachOReader::readSwiftVersion(
Object &O)
const {
349 struct ObjCImageInfo {
355 for (
const std::unique_ptr<Section> &Sec : LC.
Sections)
356 if (Sec->Sectname ==
"__objc_imageinfo" &&
357 (Sec->Segname ==
"__DATA" || Sec->Segname ==
"__DATA_CONST" ||
358 Sec->Segname ==
"__DATA_DIRTY") &&
359 Sec->Content.size() >=
sizeof(ObjCImageInfo)) {
360 memcpy(&ImageInfo, Sec->Content.data(),
sizeof(ObjCImageInfo));
365 O.SwiftVersion = (ImageInfo.Flags >> 8) & 0xff;
371 auto Obj = std::make_unique<Object>();
373 if (
Error E = readLoadCommands(*Obj))
375 readSymbolTable(*Obj);
376 setSymbolInRelocationInfo(*Obj);
377 readRebaseInfo(*Obj);
379 readWeakBindInfo(*Obj);
380 readLazyBindInfo(*Obj);
381 readExportInfo(*Obj);
382 readDataInCodeData(*Obj);
383 readLinkerOptimizationHint(*Obj);
384 readFunctionStartsData(*Obj);
385 readDylibCodeSignDRs(*Obj);
386 readExportsTrie(*Obj);
387 readChainedFixups(*Obj);
388 readIndirectSymbolTable(*Obj);
389 readSwiftVersion(*Obj);
390 return std::move(Obj);
#define offsetof(TYPE, MEMBER)
static Section constructSectionCommon(const SectionType &Sec, uint32_t Index)
static Expected< std::vector< std::unique_ptr< Section > > > extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd, const object::MachOObjectFile &MachOObj, uint32_t &NextSectionIndex)
Section constructSection(const MachO::section &Sec, uint32_t Index)
SymbolEntry constructSymbolEntry(StringRef StrTable, const nlist_t &nlist)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
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).
The instances of the Type class are immutable: once they are created, they are never changed.
Expected< std::unique_ptr< Object > > create() const override
StringRef getData() const
bool isLittleEndian() const
Expected< SectionRef > getSection(unsigned SectionIndex) const
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
MachO::dysymtab_command getDysymtabLoadCommand() const
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
ArrayRef< uint8_t > getSectionContents(uint32_t Offset, uint64_t Size) const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getDyldExportsTrie() const
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
const MachO::mach_header & getHeader() const
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
iterator_range< load_command_iterator > load_commands() const
bool is64Bit() const override
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
StringRef getStringTableData() const
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
symbol_iterator_range symbols() const
void swapStruct(fat_header &mh)
static const bool IsLittleEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
MachO::macho_load_command MachOLoadCommand
std::vector< std::unique_ptr< Section > > Sections
std::vector< uint8_t > Payload
std::optional< uint32_t > OriginalOffset
std::vector< RelocationInfo > Relocations