diff --git a/llvm/test/tools/llvm-objcopy/MachO/add-multiple-sections.test b/llvm/test/tools/llvm-objcopy/MachO/add-multiple-sections.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/add-multiple-sections.test @@ -0,0 +1,189 @@ +## 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.out +# RUN: llvm-objcopy --add-section __TEXT,__bar=%t.bar.data %t.foo.out %t.foo.bar.out +# RUN: llvm-readobj --sections --section-data %t.foo.bar.out \ +# RUN: | FileCheck %s -check-prefix=CHECK-A + +## 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.out +# RUN: llvm-readobj --sections --section-data %t.foo_bar.out \ +# RUN: | FileCheck %s -check-prefix=CHECK-A + +## 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.out +# RUN: llvm-readobj --sections --section-data %t.foo_bar.out \ +# RUN: | FileCheck %s -check-prefix=CHECK-B + +--- !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 + +# CHECK-A: Sections [ +# CHECK-A-NEXT: Section { +# CHECK-A-NEXT: Index: 0 +# CHECK-A-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Address: 0x0 +# CHECK-A-NEXT: Size: 0x4 +# CHECK-A-NEXT: Offset: 344 +# CHECK-A-NEXT: Alignment: 0 +# CHECK-A-NEXT: RelocationOffset: 0x0 +# CHECK-A-NEXT: RelocationCount: 0 +# CHECK-A-NEXT: Type: Regular (0x0) +# CHECK-A-NEXT: Attributes [ (0x800004) +# CHECK-A-NEXT: PureInstructions (0x800000) +# CHECK-A-NEXT: SomeInstructions (0x4) +# CHECK-A-NEXT: ] +# CHECK-A-NEXT: Reserved1: 0x0 +# CHECK-A-NEXT: Reserved2: 0x0 +# CHECK-A-NEXT: Reserved3: 0x0 +# CHECK-A-NEXT: SectionData ( +# CHECK-A-NEXT: 0000: AABBCCDD |....| +# CHECK-A-NEXT: ) +# CHECK-A-NEXT: } +# CHECK-A-NEXT: Section { +# CHECK-A-NEXT: Index: 1 +# CHECK-A-NEXT: Name: __foo (5F 5F 66 6F 6F 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Address: 0x4 +# CHECK-A-NEXT: Size: 0xA +# CHECK-A-NEXT: Offset: 348 +# CHECK-A-NEXT: Alignment: 0 +# CHECK-A-NEXT: RelocationOffset: 0x0 +# CHECK-A-NEXT: RelocationCount: 0 +# CHECK-A-NEXT: Type: Regular (0x0) +# CHECK-A-NEXT: Attributes [ (0x0) +# CHECK-A-NEXT: ] +# CHECK-A-NEXT: Reserved1: 0x0 +# CHECK-A-NEXT: Reserved2: 0x0 +# CHECK-A-NEXT: Reserved3: 0x0 +# CHECK-A-NEXT: SectionData ( +# CHECK-A-NEXT: 0000: 464F4F61 62636465 6667 |FOOabcdefg| +# CHECK-A-NEXT: ) +# CHECK-A-NEXT: } +# CHECK-A-NEXT: Section { +# CHECK-A-NEXT: Index: 2 +# CHECK-A-NEXT: Name: __bar (5F 5F 62 61 72 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# CHECK-A-NEXT: Address: 0xE +# CHECK-A-NEXT: Size: 0xA +# CHECK-A-NEXT: Offset: 358 +# CHECK-A-NEXT: Alignment: 0 +# CHECK-A-NEXT: RelocationOffset: 0x0 +# CHECK-A-NEXT: RelocationCount: 0 +# CHECK-A-NEXT: Type: Regular (0x0) +# CHECK-A-NEXT: Attributes [ (0x0) +# CHECK-A-NEXT: ] +# CHECK-A-NEXT: Reserved1: 0x0 +# CHECK-A-NEXT: Reserved2: 0x0 +# CHECK-A-NEXT: Reserved3: 0x0 +# CHECK-A-NEXT: SectionData ( +# CHECK-A-NEXT: 0000: 42415261 62636465 6667 |BARabcdefg| +# CHECK-A-NEXT: ) +# CHECK-A-NEXT: } +# CHECK-A-NEXT: ] + + +# CHECK-B: Sections [ +# CHECK-B-NEXT: Section { +# CHECK-B-NEXT: Index: 0 +# CHECK-B-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Address: 0x0 +# CHECK-B-NEXT: Size: 0x4 +# CHECK-B-NEXT: Offset: 488 +# CHECK-B-NEXT: Alignment: 0 +# CHECK-B-NEXT: RelocationOffset: 0x0 +# CHECK-B-NEXT: RelocationCount: 0 +# CHECK-B-NEXT: Type: Regular (0x0) +# CHECK-B-NEXT: Attributes [ (0x800004) +# CHECK-B-NEXT: PureInstructions (0x800000) +# CHECK-B-NEXT: SomeInstructions (0x4) +# CHECK-B-NEXT: ] +# CHECK-B-NEXT: Reserved1: 0x0 +# CHECK-B-NEXT: Reserved2: 0x0 +# CHECK-B-NEXT: Reserved3: 0x0 +# CHECK-B-NEXT: SectionData ( +# CHECK-B-NEXT: 0000: AABBCCDD |....| +# CHECK-B-NEXT: ) +# CHECK-B-NEXT: } +# CHECK-B-NEXT: Section { +# CHECK-B-NEXT: Index: 1 +# CHECK-B-NEXT: Name: __foo (5F 5F 66 6F 6F 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Segment: __FOO (5F 5F 46 4F 4F 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Address: 0xB8 +# CHECK-B-NEXT: Size: 0xA +# CHECK-B-NEXT: Offset: 492 +# CHECK-B-NEXT: Alignment: 0 +# CHECK-B-NEXT: RelocationOffset: 0x0 +# CHECK-B-NEXT: RelocationCount: 0 +# CHECK-B-NEXT: Type: Regular (0x0) +# CHECK-B-NEXT: Attributes [ (0x0) +# CHECK-B-NEXT: ] +# CHECK-B-NEXT: Reserved1: 0x0 +# CHECK-B-NEXT: Reserved2: 0x0 +# CHECK-B-NEXT: Reserved3: 0x0 +# CHECK-B-NEXT: SectionData ( +# CHECK-B-NEXT: 0000: 464F4F61 62636465 6667 |FOOabcdefg| +# CHECK-B-NEXT: ) +# CHECK-B-NEXT: } +# CHECK-B-NEXT: Section { +# CHECK-B-NEXT: Index: 2 +# CHECK-B-NEXT: Name: __bar (5F 5F 62 61 72 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Segment: __BAR (5F 5F 42 41 52 00 00 00 00 00 00 00 00 00 00 00) +# CHECK-B-NEXT: Address: 0xB8 +# CHECK-B-NEXT: Size: 0xA +# CHECK-B-NEXT: Offset: 502 +# CHECK-B-NEXT: Alignment: 0 +# CHECK-B-NEXT: RelocationOffset: 0x0 +# CHECK-B-NEXT: RelocationCount: 0 +# CHECK-B-NEXT: Type: Regular (0x0) +# CHECK-B-NEXT: Attributes [ (0x0) +# CHECK-B-NEXT: ] +# CHECK-B-NEXT: Reserved1: 0x0 +# CHECK-B-NEXT: Reserved2: 0x0 +# CHECK-B-NEXT: Reserved3: 0x0 +# CHECK-B-NEXT: SectionData ( +# CHECK-B-NEXT: 0000: 42415261 62636465 6667 |BARabcdefg| +# CHECK-B-NEXT: ) +# CHECK-B-NEXT: } +# CHECK-B-NEXT: ] diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -280,6 +280,7 @@ StringRef TargetSegName = Pair.first; Section Sec(TargetSegName, Pair.second); Sec.Content = Obj.NewSectionsContents.save(Buf->getBuffer()); + Sec.Size = Sec.Content.size(); // Add the a section into an existing segment. for (LoadCommand &LC : Obj.LoadCommands) {