[llvm-objcopy][MachO] Fix --add-section
This diff fixes --add-section functionality and simplifies the tests organization. Test plan: make check-all Differential revision: https://reviews.llvm.org/D87497
This commit is contained in:
parent
98756d865b
commit
e60a760b7d
|
@ -0,0 +1,114 @@
|
|||
## Show that llvm-objcopy adds a new section into a 32-bit object file if
|
||||
## --add-section is given.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: echo -n abcdefg > %t.data
|
||||
|
||||
## Case 1: Add a new section into an existing segment.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__bar=%t.data %t %t.out1
|
||||
# RUN: llvm-readobj --sections --section-data %t.out1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE1
|
||||
|
||||
## Case 2: Add a new section into a nonexistent segment.
|
||||
# RUN: llvm-objcopy --add-section __FOO,__bar=%t.data %t %t.out2
|
||||
# RUN: llvm-readobj --sections --section-data %t.out2 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE2
|
||||
|
||||
## Case 3: Add a new section into an existing segment using /dev/null as an input.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__bar=/dev/null %t %t.out3
|
||||
# RUN: llvm-readobj --sections --section-data %t.out3 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE3
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 1
|
||||
sizeofcmds: 124
|
||||
flags: 0x00002000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT
|
||||
cmdsize: 124
|
||||
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
|
||||
|
||||
# COMMON: Index: 0
|
||||
# COMMON-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Address: 0x0
|
||||
# COMMON-NEXT: Size: 0x4
|
||||
# COMMON-NEXT: Offset:
|
||||
# COMMON-NEXT: Alignment: 0
|
||||
# COMMON-NEXT: RelocationOffset: 0x0
|
||||
# COMMON-NEXT: RelocationCount: 0
|
||||
# COMMON-NEXT: Type: Regular (0x0)
|
||||
# COMMON-NEXT: Attributes [ (0x800004)
|
||||
# COMMON-NEXT: PureInstructions (0x800000)
|
||||
# COMMON-NEXT: SomeInstructions (0x4)
|
||||
# COMMON-NEXT: ]
|
||||
# COMMON-NEXT: Reserved1: 0x0
|
||||
# COMMON-NEXT: Reserved2: 0x0
|
||||
# COMMON-NEXT: SectionData (
|
||||
# COMMON-NEXT: 0000: AABBCCDD |....|
|
||||
# COMMON-NEXT: )
|
||||
|
||||
# COMMON: Index: 1
|
||||
# COMMON-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: 0x4
|
||||
# CASE1-NEXT: Size: 0x7
|
||||
# CASE1-NEXT: Offset: 224
|
||||
|
||||
# CASE2-NEXT: Segment: __FOO (5F 5F 46 4F 4F 00 00 00 00 00 00 00 00 00 00 00)
|
||||
# CASE2-NEXT: Address: 0x98
|
||||
# CASE2-NEXT: Size: 0x7
|
||||
# CASE2-NEXT: Offset: 280
|
||||
|
||||
# CASE3-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# CASE3-NEXT: Address: 0x4
|
||||
# CASE3-NEXT: Size: 0x0
|
||||
# CASE3-NEXT: Offset: 224
|
||||
|
||||
# COMMON-NEXT: Alignment: 0
|
||||
# COMMON-NEXT: RelocationOffset: 0x0
|
||||
# COMMON-NEXT: RelocationCount: 0
|
||||
# COMMON-NEXT: Type: Regular (0x0)
|
||||
# COMMON-NEXT: Attributes [ (0x0)
|
||||
# COMMON-NEXT: ]
|
||||
# COMMON-NEXT: Reserved1: 0x0
|
||||
# COMMON-NEXT: Reserved2: 0x0
|
||||
|
||||
# CASE1-NEXT: SectionData (
|
||||
# CASE1-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# CASE1-NEXT: )
|
||||
|
||||
# CASE2-NEXT: SectionData (
|
||||
# CASE2-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# CASE2-NEXT: )
|
||||
|
||||
# CASE3-NEXT: SectionData (
|
||||
# CASE3-NEXT: )
|
|
@ -0,0 +1,119 @@
|
|||
## Show that llvm-objcopy adds a new section into a 64-bit object if
|
||||
## --add-section is given.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: echo -n abcdefg > %t.data
|
||||
|
||||
## Case 1: Add a new section into an existing segment.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__bar=%t.data %t %t.out1
|
||||
# RUN: llvm-readobj --sections --section-data %t.out1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE1
|
||||
|
||||
## Case 2: Add a new section into a nonexistent segment.
|
||||
# RUN: llvm-objcopy --add-section __FOO,__bar=%t.data %t %t.out2
|
||||
# RUN: llvm-readobj --sections --section-data %t.out2 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE2
|
||||
# RUN: llvm-readobj --sections --section-data %t.out2 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,CASE2
|
||||
|
||||
## Case 3: Add a new section into an existing segment using /dev/null as an input.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__bar=/dev/null %t %t.out3
|
||||
# RUN: llvm-readobj --sections --section-data %t.out3 \
|
||||
# RUN: | FileCheck %s --check-prefixes=COMMON,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
|
||||
|
||||
# COMMON: Index: 0
|
||||
# COMMON-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Address: 0x0
|
||||
# COMMON-NEXT: Size: 0x4
|
||||
# COMMON-NEXT: Offset:
|
||||
# COMMON-NEXT: Alignment: 0
|
||||
# COMMON-NEXT: RelocationOffset: 0x0
|
||||
# COMMON-NEXT: RelocationCount: 0
|
||||
# COMMON-NEXT: Type: Regular (0x0)
|
||||
# COMMON-NEXT: Attributes [ (0x800004)
|
||||
# COMMON-NEXT: PureInstructions (0x800000)
|
||||
# COMMON-NEXT: SomeInstructions (0x4)
|
||||
# COMMON-NEXT: ]
|
||||
# COMMON-NEXT: Reserved1: 0x0
|
||||
# COMMON-NEXT: Reserved2: 0x0
|
||||
# COMMON-NEXT: Reserved3: 0x0
|
||||
# COMMON-NEXT: SectionData (
|
||||
# COMMON-NEXT: 0000: AABBCCDD |....|
|
||||
# COMMON-NEXT: )
|
||||
|
||||
# COMMON: Index: 1
|
||||
# COMMON-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: 0x4
|
||||
# CASE1-NEXT: Size: 0x7
|
||||
# CASE1-NEXT: Offset: 268
|
||||
|
||||
# CASE2: Segment: __FOO (5F 5F 46 4F 4F 00 00 00 00 00 00 00 00 00 00 00)
|
||||
# CASE2-NEXT: Address: 0xB8
|
||||
# CASE2-NEXT: Size: 0x7
|
||||
# CASE2-NEXT: Offset: 340
|
||||
|
||||
# CASE3-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# CASE3-NEXT: Address: 0x4
|
||||
# CASE3-NEXT: Size: 0x0
|
||||
# CASE3-NEXT: Offset: 268
|
||||
|
||||
# COMMON-NEXT: Alignment: 0
|
||||
# COMMON-NEXT: RelocationOffset: 0x0
|
||||
# COMMON-NEXT: RelocationCount: 0
|
||||
# COMMON-NEXT: Type: Regular (0x0)
|
||||
# COMMON-NEXT: Attributes [ (0x0)
|
||||
# COMMON-NEXT: ]
|
||||
# COMMON-NEXT: Reserved1: 0x0
|
||||
# COMMON-NEXT: Reserved2: 0x0
|
||||
# COMMON-NEXT: Reserved3: 0x0
|
||||
|
||||
# CASE1-NEXT: SectionData (
|
||||
# CASE1-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# CASE1-NEXT: )
|
||||
|
||||
# CASE2-NEXT: SectionData (
|
||||
# CASE2-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# CASE2-NEXT: )
|
||||
|
||||
# CASE3-NEXT: SectionData (
|
||||
# CASE3-NEXT: )
|
|
@ -0,0 +1,14 @@
|
|||
## Test --add-section error messages.
|
||||
|
||||
# RUN: yaml2obj %p/Inputs/x86_64.yaml -o %t
|
||||
# RUN: echo -n abcdefg > %t.data
|
||||
|
||||
## Error case 1: Nonexistent input file is specified by --add-section.
|
||||
# RUN: not llvm-objcopy --add-section __TEXT,__text=%t.missing %t %t.nonexistent-file 2>&1 \
|
||||
# RUN: | FileCheck %s -DINPUT=%t -DSECTION_DATA_FILE=%t.missing --check-prefix=NONEXSITENT-FILE
|
||||
# NONEXSITENT-FILE: error: '[[INPUT]]': '[[SECTION_DATA_FILE]]': {{[Nn]}}o such file or directory
|
||||
|
||||
## Error case 2: Too long segment name.
|
||||
# RUN: not llvm-objcopy --add-section __TOOOOOOOOO_LONG,__text=%t.data %t %t.too-long-seg-name 2>&1 \
|
||||
# RUN: | FileCheck %s -DINPUT=%t --check-prefix=TOO-LONG-SEG-NAME
|
||||
# TOO-LONG-SEG-NAME: error: '[[INPUT]]': too long segment name: '__TOOOOOOOOO_LONG'
|
|
@ -1,175 +0,0 @@
|
|||
## Show that llvm-objcopy adds a new section into the object if
|
||||
## --add-section is given.
|
||||
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t.64bit
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t.32bit
|
||||
# RUN: echo -n abcdefg > %t.data
|
||||
|
||||
## Error case 1: Nonexistent input file is specified by --add-section.
|
||||
# RUN: not llvm-objcopy --add-section __TEXT,__text=%t.missing %t.64bit %t.nonexistent-file 2>&1 \
|
||||
# RUN: | FileCheck %s -DINPUT=%t.64bit -DSECTION_DATA_FILE=%t.missing --check-prefix=NONEXSITENT-FILE
|
||||
# NONEXSITENT-FILE: error: '[[INPUT]]': '[[SECTION_DATA_FILE]]': {{[Nn]}}o such file or directory
|
||||
|
||||
## Error case 2: Too long segment name.
|
||||
# RUN: not llvm-objcopy --add-section __TOOOOOOOOO_LONG,__text=%t.data %t.64bit %t.too-long-seg-name 2>&1 \
|
||||
# RUN: | FileCheck %s -DINPUT=%t.64bit --check-prefix=TOO-LONG-SEG-NAME
|
||||
# TOO-LONG-SEG-NAME: error: '[[INPUT]]': too long segment name: '__TOOOOOOOOO_LONG'
|
||||
|
||||
## Case 1: Add a new section into an existing segment.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__text=%t.data %t.64bit %t.out1.64bit
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__text=%t.data %t.32bit %t.out1.32bit
|
||||
# RUN: llvm-readobj --sections --section-data %t.out1.64bit \
|
||||
# RUN: | FileCheck %s --check-prefixes=64BIT,COMMON,CASE1
|
||||
# RUN: llvm-readobj --sections --section-data %t.out1.32bit \
|
||||
# RUN: | FileCheck %s --check-prefixes=32BIT,COMMON,CASE1
|
||||
|
||||
## Case 2: Add a new section into a nonexistent segment.
|
||||
# RUN: llvm-objcopy --add-section __FOO,__bar=%t.data %t.64bit %t.out2.64bit
|
||||
# RUN: llvm-objcopy --add-section __FOO,__bar=%t.data %t.32bit %t.out2.32bit
|
||||
# RUN: llvm-readobj --sections --section-data --macho-segment %t.out2.64bit \
|
||||
# RUN: | FileCheck %s --check-prefixes=64BIT,COMMON,CASE2,CASE2-64BIT
|
||||
# RUN: llvm-readobj --sections --section-data --macho-segment %t.out2.32bit \
|
||||
# RUN: | FileCheck %s --check-prefixes=32BIT,COMMON,CASE2,CASE2-32BIT
|
||||
|
||||
## Case 3: Add a new section with /dev/null.
|
||||
# RUN: llvm-objcopy --add-section __TEXT,__text=/dev/null %t.64bit %t.devnull
|
||||
# RUN: llvm-readobj --sections --section-data %t.devnull \
|
||||
# RUN: | FileCheck %s --check-prefixes=64BIT,COMMON,DEVNULL
|
||||
|
||||
## 64-bit binary
|
||||
--- !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: ''
|
||||
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
|
||||
|
||||
## 32-bit binary
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 1
|
||||
sizeofcmds: 124
|
||||
flags: 0x00002000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT
|
||||
cmdsize: 124
|
||||
segname: ''
|
||||
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
|
||||
|
||||
# COMMON: Index: 0
|
||||
# COMMON-NEXT: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON: Index: 1
|
||||
# CASE1-NEXT: __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)
|
||||
# CASE2-NEXT: Name: __bar (5F 5F 62 61 72 00 00 00 00 00 00 00 00 00 00 00)
|
||||
# CASE2-NEXT: Segment: __FOO (5F 5F 46 4F 4F 00 00 00 00 00 00 00 00 00 00 00)
|
||||
# DEVNULL-NEXT: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
|
||||
# DEVNULL-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
|
||||
# COMMON-NEXT: Address: 0x0
|
||||
# CASE1-NEXT: Size: 0x7
|
||||
# CASE2-NEXT: Size: 0x7
|
||||
# DEVNULL-NEXT: Size: 0x0
|
||||
# 64BIT-NEXT: Offset: 340
|
||||
# 32BIT-NEXT: Offset: 280
|
||||
# COMMON-NEXT: Alignment: 0
|
||||
# COMMON-NEXT: RelocationOffset: 0x0
|
||||
# COMMON-NEXT: RelocationCount: 0
|
||||
# COMMON-NEXT: Type: Regular (0x0)
|
||||
# COMMON-NEXT: Attributes [ (0x0)
|
||||
# COMMON-NEXT: ]
|
||||
# COMMON-NEXT: Reserved1: 0x0
|
||||
# COMMON-NEXT: Reserved2: 0x0
|
||||
# 64BIT-NEXT: Reserved3: 0x0
|
||||
# COMMON-NEXT: SectionData (
|
||||
# CASE1-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# CASE2-NEXT: 0000: 61626364 656667 |abcdefg|
|
||||
# COMMON-NEXT: )
|
||||
|
||||
# CASE2: Segment {
|
||||
# CASE2-64BIT-NEXT: Cmd: LC_SEGMENT_64
|
||||
# CASE2-32BIT-NEXT: Cmd: LC_SEGMENT{{$}}
|
||||
# CASE2-NEXT: Name:
|
||||
# CASE2-64BIT-NEXT: Size: 152
|
||||
# CASE2-32BIT-NEXT: Size: 124
|
||||
# CASE2-NEXT: vmaddr: 0x0
|
||||
# CASE2-NEXT: vmsize: 0x4
|
||||
# CASE2-64BIT-NEXT: fileoff: 336
|
||||
# CASE2-32BIT-NEXT: fileoff: 276
|
||||
# CASE2-NEXT: filesize: 4
|
||||
# CASE2-NEXT: maxprot: rwx
|
||||
# CASE2-NEXT: initprot: rwx
|
||||
# CASE2-NEXT: nsects: 1
|
||||
# CASE2-NEXT: flags: 0x0
|
||||
# CASE2-NEXT: }
|
||||
# CASE2-NEXT: Segment {
|
||||
# CASE2-64BIT-NEXT: Cmd: LC_SEGMENT_64
|
||||
# CASE2-32BIT-NEXT: Cmd: LC_SEGMENT{{$}}
|
||||
# CASE2-NEXT: Name: __FOO
|
||||
# CASE2-64BIT-NEXT: Size: 152
|
||||
# CASE2-32BIT-NEXT: Size: 124
|
||||
# CASE2-NEXT: vmaddr: 0x0
|
||||
# CASE2-NEXT: vmsize: 0x7
|
||||
# CASE2-64BIT-NEXT: fileoff: 340
|
||||
# CASE2-32BIT-NEXT: fileoff: 280
|
||||
# CASE2-NEXT: filesize: 7
|
||||
# CASE2-NEXT: maxprot: ---
|
||||
# CASE2-NEXT: initprot: ---
|
||||
# CASE2-NEXT: nsects: 1
|
||||
# CASE2-NEXT: flags: 0x0
|
||||
# CASE2-NEXT: }
|
|
@ -259,7 +259,11 @@ static Error addSection(StringRef SecName, StringRef Filename, Object &Obj) {
|
|||
for (LoadCommand &LC : Obj.LoadCommands) {
|
||||
Optional<StringRef> SegName = LC.getSegmentName();
|
||||
if (SegName && SegName == TargetSegName) {
|
||||
uint64_t Addr = *LC.getSegmentVMAddr();
|
||||
for (const std::unique_ptr<Section> &S : LC.Sections)
|
||||
Addr = std::max(Addr, S->Addr + S->Size);
|
||||
LC.Sections.push_back(std::make_unique<Section>(Sec));
|
||||
LC.Sections.back()->Addr = Addr;
|
||||
return Error::success();
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +272,7 @@ static Error addSection(StringRef SecName, StringRef Filename, Object &Obj) {
|
|||
// Insert a new section into it.
|
||||
LoadCommand &NewSegment = Obj.addSegment(TargetSegName);
|
||||
NewSegment.Sections.push_back(std::make_unique<Section>(Sec));
|
||||
NewSegment.Sections.back()->Addr = *NewSegment.getSegmentVMAddr();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
|
@ -111,24 +111,53 @@ Error Object::removeSections(
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
uint64_t Object::nextAvailableSegmentAddress() const {
|
||||
uint64_t HeaderSize =
|
||||
is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
|
||||
uint64_t Addr = HeaderSize + Header.SizeOfCmds;
|
||||
for (const LoadCommand &LC : LoadCommands) {
|
||||
const MachO::macho_load_command &MLC = LC.MachOLoadCommand;
|
||||
switch (MLC.load_command_data.cmd) {
|
||||
case MachO::LC_SEGMENT:
|
||||
Addr = std::max(Addr,
|
||||
static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +
|
||||
MLC.segment_command_data.vmsize);
|
||||
break;
|
||||
case MachO::LC_SEGMENT_64:
|
||||
Addr = std::max(Addr, MLC.segment_command_64_data.vmaddr +
|
||||
MLC.segment_command_64_data.vmsize);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return Addr;
|
||||
}
|
||||
|
||||
template <typename SegmentType>
|
||||
static void constructSegment(SegmentType &Seg,
|
||||
llvm::MachO::LoadCommandType CmdType,
|
||||
StringRef SegName) {
|
||||
StringRef SegName, uint64_t SegVMAddr) {
|
||||
assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name");
|
||||
memset(&Seg, 0, sizeof(SegmentType));
|
||||
Seg.cmd = CmdType;
|
||||
strncpy(Seg.segname, SegName.data(), SegName.size());
|
||||
Seg.maxprot |=
|
||||
(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
|
||||
Seg.initprot |=
|
||||
(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
|
||||
Seg.vmaddr = SegVMAddr;
|
||||
}
|
||||
|
||||
LoadCommand &Object::addSegment(StringRef SegName) {
|
||||
LoadCommand LC;
|
||||
const uint64_t SegVMAddr = nextAvailableSegmentAddress();
|
||||
if (is64Bit())
|
||||
constructSegment(LC.MachOLoadCommand.segment_command_64_data,
|
||||
MachO::LC_SEGMENT_64, SegName);
|
||||
MachO::LC_SEGMENT_64, SegName, SegVMAddr);
|
||||
else
|
||||
constructSegment(LC.MachOLoadCommand.segment_command_data,
|
||||
MachO::LC_SEGMENT, SegName);
|
||||
MachO::LC_SEGMENT, SegName, SegVMAddr);
|
||||
|
||||
LoadCommands.push_back(std::move(LC));
|
||||
return LoadCommands.back();
|
||||
|
@ -152,6 +181,18 @@ Optional<StringRef> LoadCommand::getSegmentName() const {
|
|||
}
|
||||
}
|
||||
|
||||
Optional<uint64_t> LoadCommand::getSegmentVMAddr() const {
|
||||
const MachO::macho_load_command &MLC = MachOLoadCommand;
|
||||
switch (MLC.load_command_data.cmd) {
|
||||
case MachO::LC_SEGMENT:
|
||||
return MLC.segment_command_data.vmaddr;
|
||||
case MachO::LC_SEGMENT_64:
|
||||
return MLC.segment_command_64_data.vmaddr;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace macho
|
||||
} // end namespace objcopy
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -94,6 +94,9 @@ struct LoadCommand {
|
|||
|
||||
// Returns the segment name if the load command is a segment command.
|
||||
Optional<StringRef> getSegmentName() const;
|
||||
|
||||
// Returns the segment vm address if the load command is a segment command.
|
||||
Optional<uint64_t> getSegmentVMAddr() const;
|
||||
};
|
||||
|
||||
// A symbol information. Fields which starts with "n_" are same as them in the
|
||||
|
@ -340,6 +343,8 @@ struct Object {
|
|||
return Header.Magic == MachO::MH_MAGIC_64 ||
|
||||
Header.Magic == MachO::MH_CIGAM_64;
|
||||
}
|
||||
|
||||
uint64_t nextAvailableSegmentAddress() const;
|
||||
};
|
||||
|
||||
} // end namespace macho
|
||||
|
|
Loading…
Reference in New Issue