<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/67773>67773</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
llvm-objcopy --add-section MachO: invalid vmaddr for a new section
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
peroksid90
</td>
</tr>
</table>
<pre>
For MachO binaries llvm-objcopy doesn't calculate properly vmaddr for a new segment. It is overlaped with LINKEDIT
This is due to incorrect logic inside ```nextAvailableSegmentAddress```
https://github.com/llvm/llvm-project/blob/535665ebf04bfd9ea757ebd051d05158e8ef6fa5/llvm/lib/ObjCopy/MachO/MachOObject.cpp#L145
Which is just iterate over all existed segments and find a next vmaddr.
But at the moment of call to ```nextAvailableSegmentAddress``` the size of LINKEDIT is old. And at the end of llvm-objcopy, on layout recalculation, due to new segment - the size of LINKEDIT is changed.
Here are steps to reproduce
```
llvm-objcopy --version
llvm-objcopy, compatible with GNU objcopy
Homebrew LLVM version 17.0.1
Optimized build.
```
```
cat main.c
int main() {
return 1;
}
```
```
clang main.c -o main
dd if=/dev/zero of=output_file bs=1 count=5000000
llvm-objcopy --add-section=NEW,new=output_file main main_new
```
```
otool -l main_new
........
........
Load command 2
cmd LC_SEGMENT_64
cmdsize 72
segname __LINKEDIT
vmaddr 0x0000000100004000
vmsize 0x000000000000c000
fileoff 5029888
filesize 39632
maxprot 0x00000001
initprot 0x00000001
nsects 0
flags 0x0
........
........
Load command 16
cmd LC_SEGMENT_64
cmdsize 152
segname NEW
vmaddr 0x0000000100008000
vmsize 0x00000000004c8000
fileoff 16384
filesize 5013504
maxprot 0x00000007
initprot 0x00000007
nsects 1
flags 0x0
Section
sectname new
segname NEW
addr 0x0000000100008000
size 0x00000000004c4b40
offset 16384
align 2^0 (1)
reloff 0
nreloc 0
flags 0x00000000
reserved1 0
reserved2 0
........
so, the end address of LINKEDIT
```
>>> hex(0x0000000100004000 + 0x000000000000c000)
'0x100010000'
```
and the first address of NEW
```
0x100008000
```
So you can see NEW is overlaped with LINKEDIT
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVk1z2zgP_jX0BWOPRH1ZBx-SOO7bedPkkO72mKFIyGaWIjUk5Tj99TuULEdxnW3DcagJAAJ4HoAfzDm51Ygrkl2TbD1jnd8Zu2rRmn-cFGU0q4x4XW2MhW-M7x6gkppZiQ6U2jdzUz1z076CMOg0oYUHzhTvFPMIrTUtWvUK-4YJYaE2FhhofAGH2wa1X8BXD9KB2aNVrEUBL9Lv4O7r_f9v11-_k2hNoqth_r6TLpiKDsEbkJoba5F7UGYrOUjtpEAgeTT8NB781Z5JxSqFj0O0KyEsOneyGRzvvG8dSa4I3RC62Uq_66oFNw2hmwDw-Jm31jwj94RuKmUqQjdZkuV5hlUdpVUtSmRFVmAloiwOf9kSl1jnNcsmfmRY91A935j2ldBNT-f4faiC-wVvW0KTuzjNpuB_7CTfBfTPnfMgPdpAb2ANmFKAB-k8ipFVB0wLqKUWPdsHf-R_MTi77jwwD36H0JhgD6YORVOB108R2Ptw8icGD2PR-noqsYCrEH-Ig1oEk2nDEHoDRoNir6bzYHHsGml0UB3LPOkVmH8Yju-Y3qJYTCkb5v-hRWAWwXlsXfBosbVGdBzfGb9viXeNPZ_v0bqQ1mTBORJumpZ5WSkcOvjL_V8wqodETIOVxRe4u_v7Gxw9QlwsokU8WAA8tF428icKqDqpRjgAZ9kBfKDgzEPDpF7waapSD1JCl4SWQIrrUVta9J3VEJNklBXri4RcFHLF9PYYEOZmCNJrhABZk2RN6EbgntDNT7QGTBCZzredf6qlQqgcSdYxcNNpT5J1FvXjYgmYEHOHvO-OZH1_-4PQG40vZw5DBv30FHR_DMR4YxTM1fnSfl4cx6X_7gwTofRN2G90rEoYvBFwd_P0ePvl2-3996c8HZW8EX0HFydzh1vNGoSnp_fHHsB4bEaHgZkoDlN64qi36L2dLPrBJxaBF1PXkEW0XC6XR3GQ9guTMk9OmTTs0FrjJ_GOGqmlv6wB0KEsDt5SglqxrQumb6JPUhnnx6W_pTHOfuExNMd_Erj8DYEpX14gMM6TZXpOXxbFSRalHxJYfEhgcU5g_CGBj8e-P-Hkvgd6alS4BP53wMOiX5GnVToxMXXt0L-DHgZTcquBkuw2AkKXMaHlm9aiCnRNvOgg4lPJG8JouufBokO7RxHDuYSOkvddM8zOhCN4vGfYcElN74jLR0FyO_xghwdCl7_uMiD0-tLWGuESWkSHeFxBaHExTmjokFstrfPT7E61Olsw-JxU6-IZ9mjg1XTAmQaHfeH_8CE1nWdilYgyKdkMV3FeZmVBkzyd7VZLJviyxjxGzIo8iZIqp1Ve0ToTEa9pPZMrGtEkKmkZFTSP0kWV0iJJeJJQkaYoOEkjbJhUi3CSL4zdzqRzHa7yoiiSmWIVKtc_OSkNl3yvJJSGF6hd9ad_1W0dSSMlnXdvXrz0ClcfXw_DI5UkYdPtmZLi0uOzt5x1Vq0-_frrE3WEbnog_wYAAP__AkY5cw">