--- /dev/null
+## This test verifies that llvm-objcopy can add multiple sections to a Mach-O binary.
+
+# RUN: yaml2obj %s -o %t
+# RUN: echo -n FOOabcdefg > %t.foo.data
+# RUN: echo -n BARabcdefg > %t.bar.data
+
+## Case 1: Add a new section twice into an existing segment.
+# RUN: llvm-objcopy --add-section __TEXT,__foo=%t.foo.data %t %t.foo.1
+# RUN: llvm-objcopy --add-section __TEXT,__bar=%t.bar.data %t.foo.1 %t.foo.bar.1
+# RUN: llvm-readobj --sections --section-data %t.foo.bar.1 \
+# RUN: | FileCheck %s -check-prefix=CASE1
+
+## Case 2: Add two new sections into an existing segment.
+# RUN: llvm-objcopy --add-section __TEXT,__foo=%t.foo.data --add-section __TEXT,__bar=%t.bar.data %t %t.foo.bar.2
+# RUN: llvm-readobj --sections --section-data %t.foo.bar.2 \
+# RUN: | FileCheck %s -check-prefix=CASE1
+
+## Case 3: Add two new sections into two different segments.
+# RUN: llvm-objcopy --add-section __FOO,__foo=%t.foo.data --add-section __BAR,__bar=%t.bar.data %t %t.foo.bar.3
+# RUN: llvm-readobj --sections --section-data %t.foo.bar.3 \
+# RUN: | FileCheck %s -check-prefix=CASE3
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000001
+ ncmds: 1
+ sizeofcmds: 152
+ flags: 0x00002000
+ reserved: 0x00000000
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4
+ fileoff: 184
+ filesize: 4
+ maxprot: 7
+ initprot: 7
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0000000000000000
+ content: 'AABBCCDD'
+ size: 4
+ offset: 184
+ align: 0
+ reloff: 0x00000000
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x00000000
+ reserved2: 0x00000000
+ reserved3: 0x00000000
+
+# CASE1: Sections [
+# CASE1-NEXT: Section {
+# CASE1-NEXT: Index: 0
+# CASE1-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Address: 0x0
+# CASE1-NEXT: Size: 0x4
+# CASE1-NEXT: Offset: 344
+# CASE1-NEXT: Alignment: 0
+# CASE1-NEXT: RelocationOffset: 0x0
+# CASE1-NEXT: RelocationCount: 0
+# CASE1-NEXT: Type: Regular (0x0)
+# CASE1-NEXT: Attributes [ (0x800004)
+# CASE1-NEXT: PureInstructions (0x800000)
+# CASE1-NEXT: SomeInstructions (0x4)
+# CASE1-NEXT: ]
+# CASE1-NEXT: Reserved1: 0x0
+# CASE1-NEXT: Reserved2: 0x0
+# CASE1-NEXT: Reserved3: 0x0
+# CASE1-NEXT: SectionData (
+# CASE1-NEXT: 0000: AABBCCDD |....|
+# CASE1-NEXT: )
+# CASE1-NEXT: }
+# CASE1-NEXT: Section {
+# CASE1-NEXT: Index: 1
+# CASE1-NEXT: Name: __foo (5F 5F 66 6F 6F 00 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Address: 0x4
+# CASE1-NEXT: Size: 0xA
+# CASE1-NEXT: Offset: 348
+# CASE1-NEXT: Alignment: 0
+# CASE1-NEXT: RelocationOffset: 0x0
+# CASE1-NEXT: RelocationCount: 0
+# CASE1-NEXT: Type: Regular (0x0)
+# CASE1-NEXT: Attributes [ (0x0)
+# CASE1-NEXT: ]
+# CASE1-NEXT: Reserved1: 0x0
+# CASE1-NEXT: Reserved2: 0x0
+# CASE1-NEXT: Reserved3: 0x0
+# CASE1-NEXT: SectionData (
+# CASE1-NEXT: 0000: 464F4F61 62636465 6667 |FOOabcdefg|
+# CASE1-NEXT: )
+# CASE1-NEXT: }
+# CASE1-NEXT: Section {
+# CASE1-NEXT: Index: 2
+# CASE1-NEXT: Name: __bar (5F 5F 62 61 72 00 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+# CASE1-NEXT: Address: 0xE
+# CASE1-NEXT: Size: 0xA
+# CASE1-NEXT: Offset: 358
+# CASE1-NEXT: Alignment: 0
+# CASE1-NEXT: RelocationOffset: 0x0
+# CASE1-NEXT: RelocationCount: 0
+# CASE1-NEXT: Type: Regular (0x0)
+# CASE1-NEXT: Attributes [ (0x0)
+# CASE1-NEXT: ]
+# CASE1-NEXT: Reserved1: 0x0
+# CASE1-NEXT: Reserved2: 0x0
+# CASE1-NEXT: Reserved3: 0x0
+# CASE1-NEXT: SectionData (
+# CASE1-NEXT: 0000: 42415261 62636465 6667 |BARabcdefg|
+# CASE1-NEXT: )
+# CASE1-NEXT: }
+# CASE1-NEXT: ]
+
+# CASE3: Sections [
+# CASE3-NEXT: Section {
+# CASE3-NEXT: Index: 0
+# CASE3-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Address: 0x0
+# CASE3-NEXT: Size: 0x4
+# CASE3-NEXT: Offset: 488
+# CASE3-NEXT: Alignment: 0
+# CASE3-NEXT: RelocationOffset: 0x0
+# CASE3-NEXT: RelocationCount: 0
+# CASE3-NEXT: Type: Regular (0x0)
+# CASE3-NEXT: Attributes [ (0x800004)
+# CASE3-NEXT: PureInstructions (0x800000)
+# CASE3-NEXT: SomeInstructions (0x4)
+# CASE3-NEXT: ]
+# CASE3-NEXT: Reserved1: 0x0
+# CASE3-NEXT: Reserved2: 0x0
+# CASE3-NEXT: Reserved3: 0x0
+# CASE3-NEXT: SectionData (
+# CASE3-NEXT: 0000: AABBCCDD |....|
+# CASE3-NEXT: )
+# CASE3-NEXT: }
+# CASE3-NEXT: Section {
+# CASE3-NEXT: Index: 1
+# CASE3-NEXT: Name: __foo (5F 5F 66 6F 6F 00 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Segment: __FOO (5F 5F 46 4F 4F 00 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Address: 0xB8
+# CASE3-NEXT: Size: 0xA
+# CASE3-NEXT: Offset: 492
+# CASE3-NEXT: Alignment: 0
+# CASE3-NEXT: RelocationOffset: 0x0
+# CASE3-NEXT: RelocationCount: 0
+# CASE3-NEXT: Type: Regular (0x0)
+# CASE3-NEXT: Attributes [ (0x0)
+# CASE3-NEXT: ]
+# CASE3-NEXT: Reserved1: 0x0
+# CASE3-NEXT: Reserved2: 0x0
+# CASE3-NEXT: Reserved3: 0x0
+# CASE3-NEXT: SectionData (
+# CASE3-NEXT: 0000: 464F4F61 62636465 6667 |FOOabcdefg|
+# CASE3-NEXT: )
+# CASE3-NEXT: }
+# CASE3-NEXT: Section {
+# CASE3-NEXT: Index: 2
+# CASE3-NEXT: Name: __bar (5F 5F 62 61 72 00 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Segment: __BAR (5F 5F 42 41 52 00 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT: Address: 0x40B8
+# CASE3-NEXT: Size: 0xA
+# CASE3-NEXT: Offset: 502
+# CASE3-NEXT: Alignment: 0
+# CASE3-NEXT: RelocationOffset: 0x0
+# CASE3-NEXT: RelocationCount: 0
+# CASE3-NEXT: Type: Regular (0x0)
+# CASE3-NEXT: Attributes [ (0x0)
+# CASE3-NEXT: ]
+# CASE3-NEXT: Reserved1: 0x0
+# CASE3-NEXT: Reserved2: 0x0
+# CASE3-NEXT: Reserved3: 0x0
+# CASE3-NEXT: SectionData (
+# CASE3-NEXT: 0000: 42415261 62636465 6667 |BARabcdefg|
+# CASE3-NEXT: )
+# CASE3-NEXT: }
+# CASE3-NEXT: ]
+
}
template <typename SegmentType>
-static void constructSegment(SegmentType &Seg,
- llvm::MachO::LoadCommandType CmdType,
- StringRef SegName, uint64_t SegVMAddr) {
+static void
+constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType,
+ StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize) {
assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name");
memset(&Seg, 0, sizeof(SegmentType));
Seg.cmd = CmdType;
Seg.initprot |=
(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
Seg.vmaddr = SegVMAddr;
+ Seg.vmsize = SegVMSize;
}
-LoadCommand &Object::addSegment(StringRef SegName) {
+LoadCommand &Object::addSegment(StringRef SegName, uint64_t SegVMSize) {
LoadCommand LC;
const uint64_t SegVMAddr = nextAvailableSegmentAddress();
if (is64Bit())
constructSegment(LC.MachOLoadCommand.segment_command_64_data,
- MachO::LC_SEGMENT_64, SegName, SegVMAddr);
+ MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);
else
constructSegment(LC.MachOLoadCommand.segment_command_data,
- MachO::LC_SEGMENT, SegName, SegVMAddr);
+ MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);
LoadCommands.push_back(std::move(LC));
return LoadCommands.back();