19MachOLayoutBuilder::getStringTableBuilderKind(
const Object &O,
bool Is64Bit) {
26uint32_t MachOLayoutBuilder::computeSizeOfCmds()
const {
30 auto cmd = MLC.load_command_data.cmd;
32 case MachO::LC_SEGMENT:
36 case MachO::LC_SEGMENT_64:
43#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
45 Size += sizeof(MachO::LCStruct) + LC.Payload.size(); \
47#include "llvm/BinaryFormat/MachO.def"
48#undef HANDLE_LOAD_COMMAND
55void MachOLayoutBuilder::constructStringTable() {
56 for (std::unique_ptr<SymbolEntry> &
Sym :
O.SymTable.Symbols)
57 StrTableBuilder.
add(
Sym->Name);
61void MachOLayoutBuilder::updateSymbolIndexes() {
63 for (
auto &Symbol :
O.SymTable.Symbols)
69 assert(MLC.load_command_data.cmd == MachO::LC_DYSYMTAB);
73 [](
const std::unique_ptr<SymbolEntry> &
A,
74 const std::unique_ptr<SymbolEntry> &
B) {
75 bool AL = A->isLocalSymbol(),
76 BL = B->isLocalSymbol();
79 return !AL && !A->isUndefinedSymbol() &&
80 B->isUndefinedSymbol();
82 "Symbols are not sorted by their types.");
85 auto Iter =
O.SymTable.Symbols.begin();
86 auto End =
O.SymTable.Symbols.end();
87 for (; Iter !=
End; ++Iter) {
88 if ((*Iter)->isExternalSymbol())
95 for (; Iter !=
End; ++Iter) {
96 if ((*Iter)->isUndefinedSymbol())
102 MLC.dysymtab_command_data.ilocalsym = 0;
103 MLC.dysymtab_command_data.nlocalsym = NumLocalSymbols;
104 MLC.dysymtab_command_data.iextdefsym = NumLocalSymbols;
105 MLC.dysymtab_command_data.nextdefsym = NumExtDefSymbols;
106 MLC.dysymtab_command_data.iundefsym = NumLocalSymbols + NumExtDefSymbols;
107 MLC.dysymtab_command_data.nundefsym =
108 O.SymTable.Symbols.size() - (NumLocalSymbols + NumExtDefSymbols);
113uint64_t MachOLayoutBuilder::layoutSegments() {
116 const bool IsObjectFile =
119 if (
O.EncryptionInfoCommandIndex) {
129 switch (MLC.load_command_data.cmd) {
130 case MachO::LC_SEGMENT:
131 SegmentVmAddr = MLC.segment_command_data.vmaddr;
132 SegmentVmSize = MLC.segment_command_data.vmsize;
133 Segname =
StringRef(MLC.segment_command_data.segname,
134 strnlen(MLC.segment_command_data.segname,
135 sizeof(MLC.segment_command_data.segname)));
137 case MachO::LC_SEGMENT_64:
138 SegmentVmAddr = MLC.segment_command_64_data.vmaddr;
139 SegmentVmSize = MLC.segment_command_64_data.vmsize;
140 Segname =
StringRef(MLC.segment_command_64_data.segname,
141 strnlen(MLC.segment_command_64_data.segname,
142 sizeof(MLC.segment_command_64_data.segname)));
148 if (Segname ==
"__LINKEDIT") {
151 LinkEditLoadCommand = &MLC;
159 for (std::unique_ptr<Section> &Sec : LC.
Sections) {
161 "Section's address cannot be smaller than Segment's one");
162 uint32_t SectOffset = Sec->Addr - SegmentVmAddr;
164 if (!Sec->hasValidOffset()) {
169 Sec->Offset = SegOffset + SegFileSize + PaddingSize;
170 Sec->Size = Sec->Content.size();
171 SegFileSize += PaddingSize + Sec->Size;
174 if (!Sec->hasValidOffset()) {
177 Sec->Offset = SegOffset + SectOffset;
178 Sec->Size = Sec->Content.size();
179 SegFileSize = std::max(SegFileSize, SectOffset + Sec->Size);
182 VMSize = std::max(VMSize, SectOffset + Sec->Size);
189 SegFileSize =
alignTo(SegFileSize, PageSize);
192 Segname ==
"__PAGEZERO" ? SegmentVmSize :
alignTo(VMSize, PageSize);
195 switch (MLC.load_command_data.cmd) {
196 case MachO::LC_SEGMENT:
197 MLC.segment_command_data.cmdsize =
200 MLC.segment_command_data.nsects = LC.
Sections.size();
201 MLC.segment_command_data.fileoff = SegOffset;
202 MLC.segment_command_data.vmsize = VMSize;
203 MLC.segment_command_data.filesize = SegFileSize;
205 case MachO::LC_SEGMENT_64:
206 MLC.segment_command_64_data.cmdsize =
209 MLC.segment_command_64_data.nsects = LC.
Sections.size();
210 MLC.segment_command_64_data.fileoff = SegOffset;
211 MLC.segment_command_64_data.vmsize = VMSize;
212 MLC.segment_command_64_data.filesize = SegFileSize;
222 for (std::unique_ptr<Section> &Sec : LC.
Sections) {
223 Sec->RelOff = Sec->Relocations.empty() ? 0 :
Offset;
224 Sec->NReloc = Sec->Relocations.size();
240 Offset >= HeaderSize +
O.Header.SizeOfCmds) &&
241 "Incorrect tail offset");
246 size_t DyldInfoExportsTrieSize = 0;
247 size_t DyldExportsTrieSize = 0;
248 for (
const auto &LC :
O.LoadCommands) {
250 case MachO::LC_DYLD_INFO:
251 case MachO::LC_DYLD_INFO_ONLY:
252 DyldInfoExportsTrieSize =
O.Exports.Trie.size();
254 case MachO::LC_DYLD_EXPORTS_TRIE:
255 DyldExportsTrieSize =
O.Exports.Trie.size();
261 assert((DyldInfoExportsTrieSize == 0 || DyldExportsTrieSize == 0) &&
262 "Export trie in both LCs");
275 return PreviousOffset;
278 uint64_t StartOfRebaseInfo = updateOffset(
O.Rebases.Opcodes.size());
279 uint64_t StartOfBindingInfo = updateOffset(
O.Binds.Opcodes.size());
280 uint64_t StartOfWeakBindingInfo = updateOffset(
O.WeakBinds.Opcodes.size());
281 uint64_t StartOfLazyBindingInfo = updateOffset(
O.LazyBinds.Opcodes.size());
282 uint64_t StartOfExportTrie = updateOffset(DyldInfoExportsTrieSize);
283 uint64_t StartOfChainedFixups = updateOffset(
O.ChainedFixups.Data.size());
284 uint64_t StartOfDyldExportsTrie = updateOffset(DyldExportsTrieSize);
285 uint64_t StartOfFunctionStarts = updateOffset(
O.FunctionStarts.Data.size());
286 uint64_t StartOfDataInCode = updateOffset(
O.DataInCode.Data.size());
287 uint64_t StartOfLinkerOptimizationHint =
288 updateOffset(
O.LinkerOptimizationHint.Data.size());
289 uint64_t StartOfSymbols = updateOffset(NListSize *
O.SymTable.Symbols.size());
291 updateOffset(
sizeof(
uint32_t) *
O.IndirectSymTable.Symbols.size());
292 uint64_t StartOfSymbolStrings = updateOffset(StrTableBuilder.
getSize());
293 uint64_t StartOfDylibCodeSignDRs = updateOffset(
O.DylibCodeSignDRs.Data.size());
297 if (
O.CodeSignatureCommandIndex) {
298 StartOfCodeSignature =
alignTo(StartOfCodeSignature, 16);
304 CodeSignature.
Align);
306 (StartOfCodeSignature + CodeSignature.
BlockSize - 1) /
310 CodeSignature.
Align);
317 CodeSignatureSize =
Size;
320 StartOfCodeSignature + CodeSignatureSize - StartOfLinkEdit;
324 if (LinkEditLoadCommand) {
326 switch (LinkEditLoadCommand->load_command_data.cmd) {
327 case MachO::LC_SEGMENT:
329 MLC->segment_command_data.fileoff = StartOfLinkEdit;
330 MLC->segment_command_data.vmsize =
alignTo(LinkEditSize, PageSize);
331 MLC->segment_command_data.filesize = LinkEditSize;
333 case MachO::LC_SEGMENT_64:
335 MLC->segment_command_64_data.fileoff = StartOfLinkEdit;
336 MLC->segment_command_64_data.vmsize =
alignTo(LinkEditSize, PageSize);
337 MLC->segment_command_64_data.filesize = LinkEditSize;
344 auto cmd = MLC.load_command_data.cmd;
346 case MachO::LC_CODE_SIGNATURE:
347 MLC.linkedit_data_command_data.dataoff = StartOfCodeSignature;
348 MLC.linkedit_data_command_data.datasize = CodeSignatureSize;
350 case MachO::LC_DYLIB_CODE_SIGN_DRS:
351 MLC.linkedit_data_command_data.dataoff = StartOfDylibCodeSignDRs;
352 MLC.linkedit_data_command_data.datasize =
O.DylibCodeSignDRs.Data.size();
354 case MachO::LC_SYMTAB:
355 MLC.symtab_command_data.symoff = StartOfSymbols;
356 MLC.symtab_command_data.nsyms =
O.SymTable.Symbols.size();
357 MLC.symtab_command_data.stroff = StartOfSymbolStrings;
358 MLC.symtab_command_data.strsize = StrTableBuilder.
getSize();
360 case MachO::LC_DYSYMTAB: {
361 if (MLC.dysymtab_command_data.ntoc != 0 ||
362 MLC.dysymtab_command_data.nmodtab != 0 ||
363 MLC.dysymtab_command_data.nextrefsyms != 0 ||
364 MLC.dysymtab_command_data.nlocrel != 0 ||
365 MLC.dysymtab_command_data.nextrel != 0)
367 "shared library is not yet supported");
368 MLC.dysymtab_command_data.indirectsymoff =
369 O.IndirectSymTable.Symbols.size() ? StartOfIndirectSymbols : 0;
370 MLC.dysymtab_command_data.nindirectsyms =
371 O.IndirectSymTable.Symbols.size();
375 case MachO::LC_DATA_IN_CODE:
376 MLC.linkedit_data_command_data.dataoff = StartOfDataInCode;
377 MLC.linkedit_data_command_data.datasize =
O.DataInCode.Data.size();
379 case MachO::LC_LINKER_OPTIMIZATION_HINT:
380 MLC.linkedit_data_command_data.dataoff = StartOfLinkerOptimizationHint;
381 MLC.linkedit_data_command_data.datasize =
382 O.LinkerOptimizationHint.Data.size();
384 case MachO::LC_FUNCTION_STARTS:
385 MLC.linkedit_data_command_data.dataoff = StartOfFunctionStarts;
386 MLC.linkedit_data_command_data.datasize =
O.FunctionStarts.Data.size();
388 case MachO::LC_DYLD_CHAINED_FIXUPS:
389 MLC.linkedit_data_command_data.dataoff = StartOfChainedFixups;
390 MLC.linkedit_data_command_data.datasize =
O.ChainedFixups.Data.size();
392 case MachO::LC_DYLD_EXPORTS_TRIE:
393 MLC.linkedit_data_command_data.dataoff = StartOfDyldExportsTrie;
394 MLC.linkedit_data_command_data.datasize = DyldExportsTrieSize;
396 case MachO::LC_DYLD_INFO:
397 case MachO::LC_DYLD_INFO_ONLY:
398 MLC.dyld_info_command_data.rebase_off =
399 O.Rebases.Opcodes.empty() ? 0 : StartOfRebaseInfo;
400 MLC.dyld_info_command_data.rebase_size =
O.Rebases.Opcodes.size();
401 MLC.dyld_info_command_data.bind_off =
402 O.Binds.Opcodes.empty() ? 0 : StartOfBindingInfo;
403 MLC.dyld_info_command_data.bind_size =
O.Binds.Opcodes.size();
404 MLC.dyld_info_command_data.weak_bind_off =
405 O.WeakBinds.Opcodes.empty() ? 0 : StartOfWeakBindingInfo;
406 MLC.dyld_info_command_data.weak_bind_size =
O.WeakBinds.Opcodes.size();
407 MLC.dyld_info_command_data.lazy_bind_off =
408 O.LazyBinds.Opcodes.empty() ? 0 : StartOfLazyBindingInfo;
409 MLC.dyld_info_command_data.lazy_bind_size =
O.LazyBinds.Opcodes.size();
410 MLC.dyld_info_command_data.export_off =
411 O.Exports.Trie.empty() ? 0 : StartOfExportTrie;
412 MLC.dyld_info_command_data.export_size = DyldInfoExportsTrieSize;
425 case MachO::LC_ENCRYPTION_INFO:
426 case MachO::LC_ENCRYPTION_INFO_64:
427 case MachO::LC_LOAD_DYLINKER:
429 case MachO::LC_RPATH:
430 case MachO::LC_SEGMENT:
431 case MachO::LC_SEGMENT_64:
432 case MachO::LC_VERSION_MIN_MACOSX:
433 case MachO::LC_VERSION_MIN_IPHONEOS:
434 case MachO::LC_VERSION_MIN_TVOS:
435 case MachO::LC_VERSION_MIN_WATCHOS:
436 case MachO::LC_BUILD_VERSION:
437 case MachO::LC_ID_DYLIB:
438 case MachO::LC_LOAD_DYLIB:
439 case MachO::LC_LOAD_WEAK_DYLIB:
441 case MachO::LC_SOURCE_VERSION:
442 case MachO::LC_THREAD:
443 case MachO::LC_UNIXTHREAD:
444 case MachO::LC_SUB_FRAMEWORK:
445 case MachO::LC_SUB_UMBRELLA:
446 case MachO::LC_SUB_CLIENT:
447 case MachO::LC_SUB_LIBRARY:
448 case MachO::LC_LINKER_OPTION:
454 "unsupported load command (cmd=0x%x)", cmd);
462 O.Header.NCmds = O.LoadCommands.size();
463 O.Header.SizeOfCmds = computeSizeOfCmds();
464 constructStringTable();
465 updateSymbolIndexes();
468 return layoutTail(
Offset);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
size_t add(CachedHashStringRef S)
Add a string to the builder.
void finalize()
Analyze the strings and build the final table.
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.
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static constexpr size_t HashSize
static constexpr uint32_t FixedHeadersSize
static constexpr size_t BlockSize
static constexpr uint32_t Align
MachO::macho_load_command MachOLoadCommand
std::vector< std::unique_ptr< Section > > Sections