diff --git a/test/tools/llvm-lipo/Inputs/CPU10-slice.yaml b/test/tools/llvm-lipo/Inputs/CPU10-slice.yaml new file mode 100644 index 00000000000..f2d8ea5c141 --- /dev/null +++ b/test/tools/llvm-lipo/Inputs/CPU10-slice.yaml @@ -0,0 +1,359 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x0000000A + cpusubtype: 0x80000003 + filetype: 0x00000001 + ncmds: 15 + sizeofcmds: 1216 + flags: 0x00200085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 472 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 7 + initprot: 5 + nsects: 5 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F00 + size: 133 + offset: 0x00000F00 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __stubs + segname: __TEXT + addr: 0x0000000100000F86 + size: 6 + offset: 0x00000F86 + align: 1 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x00000000 + reserved2: 0x00000006 + reserved3: 0x00000000 + - sectname: __stub_helper + segname: __TEXT + addr: 0x0000000100000F8C + size: 26 + offset: 0x00000F8C + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __cstring + segname: __TEXT + addr: 0x0000000100000FA6 + size: 10 + offset: 0x00000FA6 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000002 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000FB0 + size: 72 + offset: 0x00000FB0 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DATA + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 2 + flags: 0 + Sections: + - sectname: __nl_symbol_ptr + segname: __DATA + addr: 0x0000000100001000 + size: 16 + offset: 0x00001000 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000006 + reserved1: 0x00000001 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __la_symbol_ptr + segname: __DATA + addr: 0x0000000100001010 + size: 8 + offset: 0x00001010 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000007 + reserved1: 0x00000003 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 280 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 8192 + rebase_size: 8 + bind_off: 8200 + bind_size: 24 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 8224 + lazy_bind_size: 16 + export_off: 8240 + export_size: 64 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8312 + nsyms: 5 + stroff: 8408 + strsize: 64 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 3 + iundefsym: 3 + nundefsym: 2 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 8392 + nindirectsyms: 4 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + PayloadString: /usr/lib/dyld + ZeroPadBytes: 7 + - cmd: LC_UUID + cmdsize: 24 + uuid: D01A2A5D-F96C-326A-80C7-FAD7D4023E07 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 658944 + sdk: 658944 + ntools: 1 + Tools: + - tool: 3 + version: 29491968 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 3904 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 82115073 + compatibility_version: 65536 + PayloadString: /usr/lib/libSystem.B.dylib + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8304 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8312 + datasize: 0 +LinkEditData: + RebaseOpcodes: + - Opcode: REBASE_OPCODE_SET_TYPE_IMM + Imm: 1 + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ExtraData: + - 0x0000000000000010 + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 1 + - Opcode: REBASE_OPCODE_DONE + Imm: 0 + BindOpcodes: + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: dyld_stub_binder + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ULEBExtraData: + - 0x0000000000000000 + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + LazyBindOpcodes: + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ULEBExtraData: + - 0x0000000000000010 + Symbol: '' + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: _printf + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 5 + Name: _ + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 2 + NodeOffset: 31 + Name: _mh_execute_header + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 0 + NodeOffset: 35 + Name: ma + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 48 + Name: ximum + Flags: 0x0000000000000000 + Address: 0x0000000000000F00 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 53 + Name: in + Flags: 0x0000000000000000 + Address: 0x0000000000000F40 + Other: 0x0000000000000000 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971200 + - n_strx: 28 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971136 + - n_strx: 37 + n_type: 0x01 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 45 + n_type: 0x01 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - __mh_execute_header + - _main + - _maximum + - _printf + - dyld_stub_binder + - '' + - '' +... diff --git a/test/tools/llvm-lipo/Inputs/CPU14-slice.yaml b/test/tools/llvm-lipo/Inputs/CPU14-slice.yaml new file mode 100644 index 00000000000..8f3d0f87eaa --- /dev/null +++ b/test/tools/llvm-lipo/Inputs/CPU14-slice.yaml @@ -0,0 +1,88 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACE + cputype: 0x0000000e + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 4 + sizeofcmds: 312 + flags: 0x00002000 +LoadCommands: + - cmd: LC_SEGMENT + cmdsize: 192 + segname: '' + vmaddr: 0 + vmsize: 72 + fileoff: 340 + filesize: 72 + maxprot: 7 + initprot: 7 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000000 + size: 18 + offset: 0x00000154 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __eh_frame + segname: __TEXT + addr: 0x0000000000000014 + size: 52 + offset: 0x00000168 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x6800000B + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_VERSION_MIN_MACOSX + cmdsize: 16 + version: 656384 + sdk: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 412 + nsyms: 1 + stroff: 424 + strsize: 8 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + NameList: + - n_strx: 1 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 0 + StringTable: + - '' + - _main + - '' +... diff --git a/test/tools/llvm-lipo/create-compute-alignment.test b/test/tools/llvm-lipo/create-compute-alignment.test new file mode 100644 index 00000000000..b986012ea7c --- /dev/null +++ b/test/tools/llvm-lipo/create-compute-alignment.test @@ -0,0 +1,20 @@ +# RUN: yaml2obj %p/Inputs/i386-slice.yaml > %t-i386.o +# RUN: yaml2obj %p/Inputs/CPU14-slice.yaml > %t-CPU14.o +# RUN: yaml2obj %p/Inputs/CPU10-slice.yaml > %t-CPU10.o + +# RUN: llvm-lipo %t-i386.o %t-CPU14.o %t-CPU10.o -create -output %t-universal.o + +# RUN: llvm-objdump %t-universal.o -m --universal-headers | FileCheck %s +# CHECK: fat_magic FAT_MAGIC +# CHECK: nfat_arch 3 +# CHECK: architecture +# CHECK: cputype (10) +# CHECK: offset 72 +# CHECK: align 2^3 (8) +# CHECK: architecture +# CHECK: cputype (14) +# CHECK: offset 8544 +# CHECK: align 2^4 (16) +# CHECK: architecture i386 +# CHECK: offset 12288 +# CHECK: align 2^12 (4096) diff --git a/test/tools/llvm-lipo/create-without-alignment.test b/test/tools/llvm-lipo/create-default-alignment.test similarity index 100% rename from test/tools/llvm-lipo/create-without-alignment.test rename to test/tools/llvm-lipo/create-default-alignment.test diff --git a/tools/llvm-lipo/llvm-lipo.cpp b/tools/llvm-lipo/llvm-lipo.cpp index ea64d69f6ce..87167679a41 100644 --- a/tools/llvm-lipo/llvm-lipo.cpp +++ b/tools/llvm-lipo/llvm-lipo.cpp @@ -374,10 +374,42 @@ static void checkArchDuplicates(const ArrayRef &Slices) { } } -static uint32_t calculateAlignment(const MachOObjectFile *ObjectFile) { - // TODO: Implement getAlign() and remove hard coding - // Will be implemented in a follow-up. +// For compatibility with cctools lipo, alignment is calculated as the minimum +// aligment of all segments. Each segments's alignment is the maximum alignment +// from its sections +static uint32_t calculateSegmentAlignment(const MachOObjectFile &O) { + uint32_t P2CurrentAlignment; + uint32_t P2MinAlignment = MachOUniversalBinary::MaxSectionAlignment; + const bool Is64Bit = O.is64Bit(); + for (const auto &LC : O.load_commands()) { + if (LC.C.cmd != (Is64Bit ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT)) + continue; + if (O.getHeader().filetype == MachO::MH_OBJECT) { + unsigned NumberOfSections = + (Is64Bit ? O.getSegment64LoadCommand(LC).nsects + : O.getSegmentLoadCommand(LC).nsects); + P2CurrentAlignment = NumberOfSections ? 2 : P2MinAlignment; + for (unsigned SI = 0; SI < NumberOfSections; ++SI) { + P2CurrentAlignment = std::max(P2CurrentAlignment, + (Is64Bit ? O.getSection64(LC, SI).align + : O.getSection(LC, SI).align)); + } + } else { + P2CurrentAlignment = + countTrailingZeros(Is64Bit ? O.getSegment64LoadCommand(LC).vmaddr + : O.getSegmentLoadCommand(LC).vmaddr); + } + P2MinAlignment = std::min(P2MinAlignment, P2CurrentAlignment); + } + // return a value >= 4 byte aligned, and less than MachO MaxSectionAlignment + return std::max( + static_cast(2), + std::min(P2MinAlignment, static_cast( + MachOUniversalBinary::MaxSectionAlignment))); +} + +static uint32_t calculateAlignment(const MachOObjectFile *ObjectFile) { switch (ObjectFile->getHeader().cputype) { case MachO::CPU_TYPE_I386: case MachO::CPU_TYPE_X86_64: @@ -389,7 +421,7 @@ static uint32_t calculateAlignment(const MachOObjectFile *ObjectFile) { case MachO::CPU_TYPE_ARM64_32: return 14; // log2 value of page size(16k) for Darwin ARM default: - return 12; + return calculateSegmentAlignment(*ObjectFile); } }