<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54783>54783</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
lld/mac omits too many STABS entries when doing ICF
</td>
</tr>
<tr>
<th>Labels</th>
<td>
lld:MachO
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
nico
</td>
</tr>
</table>
<pre>
(I have a patch for this I'll upload in a bit. Just want to file a bug so I have a place to add some more detail.)
Consider this example:
```
% cat bar.cc
__attribute__((noinline)) inline int quux(int x) { return x; }
__attribute__((noinline)) inline int shromp(int x) { return x; }
__attribute__((noinline)) inline int freep(int x) { return x; }
int g(int i) {
return quux(i) + shromp(i) + freep(i);
}
% cat baz.cc
__attribute__((noinline)) inline int foo(int x) { return x; }
__attribute__((noinline)) inline int bar(int x) { return x; }
__attribute__((noinline)) inline int baz(int x) { return x; }
int g(int);
int main(int argc, char* argv[]) {
return foo(argc) + bar(argc) + baz(argc) + g(argc);
}
% clang -O2 bar.cc baz.cc -c -g
```
Let's link it with ld64:
```
% out/gn/bin/clang -O2 bar.o baz.o -Wl,-verbose_deduplicate
deduplicate the following 2 functions (8 bytes apiece):
__Z5freepi
__Z3bazi
deduplicate the following 4 functions (16 bytes apiece):
__Z4quuxi
__Z6shrompi
__Z3fooi
__Z3bari
deduplication saved 56 bytes of __text
% dsymutil -s a.out
----------------------------------------------------------------------
Symbol table for: 'a.out' (x86_64)
----------------------------------------------------------------------
Index n_strx n_type n_sect n_desc n_value
======== -------- ------------------ ------ ------ ----------------
[ 0] 00000034 1e (PEXT SECT ) 01 0000 0000000100003f30 '__Z6shrompi'
[ 1] 00000040 1e (PEXT SECT ) 01 0000 0000000100003f30 '__Z3fooi'
[ 2] 00000049 1e (PEXT SECT ) 01 0000 0000000100003f30 '__Z3bari'
[ 3] 00000052 1e (PEXT SECT ) 01 0080 0000000100003f30 '__Z4quuxi'
[ 4] 0000005c 1e (PEXT SECT ) 01 0000 0000000100003f40 '__Z3bazi'
[ 5] 00000065 1e (PEXT SECT ) 01 0080 0000000100003f40 '__Z5freepi'
[ 6] 00000070 64 (N_SO ) 00 0000 0000000000000000 '/Users/thakis/src/llvm-project/'
[ 7] 00000090 64 (N_SO ) 00 0000 0000000000000000 'bar.cc'
[ 8] 00000097 66 (N_OSO ) 03 0001 00000000624df143 '/Users/thakis/src/llvm-project/bar.o'
[ 9] 00000001 2e (N_BNSYM ) 01 0000 0000000100003ef0
[ 10] 000000bc 24 (N_FUN ) 01 0000 0000000100003ef0 '__Z1gi'
[ 11] 00000001 24 (N_FUN ) 00 0000 0000000000000040
[ 12] 00000001 4e (N_ENSYM ) 01 0000 0000000000000040
[ 13] 00000001 2e (N_BNSYM ) 01 0000 0000000100003f30
[ 14] 000000c3 24 (N_FUN ) 01 0000 0000000100003f30 '__Z4quuxi'
[ 15] 00000001 24 (N_FUN ) 00 0000 0000000000000010
[ 16] 00000001 4e (N_ENSYM ) 01 0000 0000000000000010
[ 17] 00000001 2e (N_BNSYM ) 01 0000 0000000100003f40
[ 18] 000000cd 24 (N_FUN ) 01 0000 0000000100003f40 '__Z5freepi'
[ 19] 00000001 24 (N_FUN ) 00 0000 0000000000000008
[ 20] 00000001 4e (N_ENSYM ) 01 0000 0000000000000008
[ 21] 00000001 64 (N_SO ) 01 0000 0000000000000000
[ 22] 00000070 64 (N_SO ) 00 0000 0000000000000000 '/Users/thakis/src/llvm-project/'
[ 23] 000000d8 64 (N_SO ) 00 0000 0000000000000000 'baz.cc'
[ 24] 000000df 66 (N_OSO ) 03 0001 00000000624df143 '/Users/thakis/src/llvm-project/baz.o'
[ 25] 00000001 2e (N_BNSYM ) 01 0000 0000000100003f50
[ 26] 00000104 24 (N_FUN ) 01 0000 0000000100003f50 '_main'
[ 27] 00000001 24 (N_FUN ) 00 0000 0000000000000050
[ 28] 00000001 4e (N_ENSYM ) 01 0000 0000000000000050
[ 29] 00000001 64 (N_SO ) 01 0000 0000000000000000
[ 30] 00000002 0f ( SECT EXT) 01 0000 0000000100003ef0 '__Z1gi'
[ 31] 00000009 0f ( SECT EXT) 01 0010 0000000100000000 '__mh_execute_header'
[ 32] 0000001d 0f ( SECT EXT) 01 0000 0000000100003f50 '_main'
[ 33] 00000023 01 ( UNDF EXT) 00 0100 0000000000000000 'dyld_stub_binder'
```
Note that ld64 emits all 8 functions to the symbol table (PEXT SECT or SECT EXT), but it doesn't emit N_FUN stabs entries for the functions that get ICF'd.
Now, lld:
```
% out/gn/bin/clang -fuse-ld=lld -O2 bar.o baz.o -Wl,--icf=all
% dsymutil -s a.out
----------------------------------------------------------------------
Symbol table for: 'a.out' (x86_64)
----------------------------------------------------------------------
Index n_strx n_type n_sect n_desc n_value
======== -------- ------------------ ------ ------ ----------------
[ 0] 00000070 64 (N_SO ) 00 0000 0000000000000000 '/Users/thakis/src/llvm-project/bar.cc'
[ 1] 00000096 66 (N_OSO ) 03 0001 00000000624df143 '/Users/thakis/src/llvm-project/bar.o'
[ 2] 000000bb 24 (N_FUN ) 01 0000 00000001000003b0 '__Z4quuxi'
[ 3] 00000001 24 (N_FUN ) 00 0000 0000000000000010
[ 4] 000000c5 24 (N_FUN ) 01 0000 00000001000003b0 '__Z6shrompi'
[ 5] 00000001 24 (N_FUN ) 00 0000 0000000000000010
[ 6] 000000d1 24 (N_FUN ) 01 0000 00000001000003c0 '__Z5freepi'
[ 7] 00000001 24 (N_FUN ) 00 0000 0000000000000008
[ 8] 000000dc 24 (N_FUN ) 01 0000 00000001000003b0 '__Z3fooi'
[ 9] 00000001 24 (N_FUN ) 00 0000 0000000000000010
[ 10] 000000e5 24 (N_FUN ) 01 0000 00000001000003b0 '__Z3bari'
[ 11] 00000001 24 (N_FUN ) 00 0000 0000000000000010
[ 12] 000000ee 24 (N_FUN ) 01 0000 00000001000003c0 '__Z3bazi'
[ 13] 00000001 24 (N_FUN ) 00 0000 0000000000000008
[ 14] 000000f7 24 (N_FUN ) 01 0000 0000000100000370 '__Z1gi'
[ 15] 00000001 24 (N_FUN ) 00 0000 0000000000000040
[ 16] 00000001 64 (N_SO ) 01 0000 0000000000000000
[ 17] 000000fe 64 (N_SO ) 00 0000 0000000000000000 '/Users/thakis/src/llvm-project/baz.cc'
[ 18] 00000124 66 (N_OSO ) 03 0001 00000000624df143 '/Users/thakis/src/llvm-project/baz.o'
[ 19] 00000149 24 (N_FUN ) 01 0000 00000001000003d0 '_main'
[ 20] 00000001 24 (N_FUN ) 00 0000 0000000000000050
[ 21] 00000001 64 (N_SO ) 01 0000 0000000000000000
[ 22] 0000000f 1e (PEXT SECT ) 01 0000 00000001000003b0 '__Z4quuxi'
[ 23] 00000019 1e (PEXT SECT ) 01 0000 00000001000003b0 '__Z6shrompi'
[ 24] 00000025 1e (PEXT SECT ) 01 0000 00000001000003c0 '__Z5freepi'
[ 25] 00000030 1e (PEXT SECT ) 01 0000 00000001000003b0 '__Z3fooi'
[ 26] 00000039 1e (PEXT SECT ) 01 0000 00000001000003b0 '__Z3bari'
[ 27] 00000042 1e (PEXT SECT ) 01 0000 00000001000003c0 '__Z3bazi'
[ 28] 00000002 0f ( SECT EXT) 01 0000 00000001000003d0 '_main'
[ 29] 00000008 0f ( SECT EXT) 01 0000 0000000100000370 '__Z1gi'
[ 30] 0000005c 0f ( SECT EXT) 01 0010 0000000100000000 '__mh_execute_header'
[ 31] 0000004b 01 ( UNDF EXT) 00 0100 0000000000000000 'dyld_stub_binder'
```
lld emits the symbol table entries, but it also emits N_FUN entries for the folded functions, and it claims that they are in the .o file that the symbol they're folded into are in.
This confuses dsymutil:
```
% dsymutil a.out
warning: (x86_64) could not find object file symbol for symbol __Z3fooi
warning: (x86_64) could not find object file symbol for symbol __Z3bari
warning: (x86_64) could not find object file symbol for symbol __Z3bazi
```
(See description of https://reviews.llvm.org/D123218 for many words on why exactly, but in summary it believes the N_FUN STABS entries and is then confused when the .o file doesn't define the symbols that the STABS info promises.)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWkuTozgS_jX2RWEHiIfxwYeuqnZEbexUT0R1x-zuxSGQsLUDyINEVbl-_aQAG4FfXeDu3sMSDvOSvkylMlP6hEJBd4sRDh7RhrwwRNCWqGiDYpEjteESPY7wLElQsU0EoYhnUCLkaor-UUiFXkmmkBIo5omuGhZrJAVqoBISMf2eUAovUoZSkTNEmSI8mY7wfGQ9jKxP1f-9yCSnrBbL3ki6TdjI-WSWGflW_atusYciolBI8mkUVc9WK6JUzsNCsdUK2gW_TPAs4RnTAvEcVTdwUuivoniDAvryTb8aze5QzlSRZ3Dv3MH9Qw9UuclFur09bpwz9n2wusS6LsnrktUbtK-wb3r5Ft8ZSu-fHMRpTZy6_kFEtwfe-_VALMTtDQX-8CNA3z9qe9Nw-nFKeFZjkHwdjfA9ijZa10_6_mXk3Y28h9PdVdmpqlV1T9XI9pP3zpN1c3-xBxOSrdHkC64jqe5ONIHf-nTklf__ZNDEmURgoz8Rh3TA1QYl1Hevh60ooOpyDeZYhtooy7YOolRBoMkfCVhp8sLyUEi2ooxCIuLgcayCMh5A3mBgpiQRrxyQMIqLLFIcsgqYIghQuFNMIrLlLCp7d68igmO1-o9XujtvPXNACX5NkNsWZPvXJLk69NqC_Cr6OtKhz4_0yY_0AcFIQr6lyNuLFjGUVuxNNfamcpcWiidoAppNtfXLV5ObHBXW8y4NRYIUCRNtnxzaDQaZVdLwTBvnLfBX4B37xH9L6Y8ZZW_aTtlKqvytvFC7LUPmAe9YpOBEmYzg9EKSovakkfNw8of2YtCxZHTq1FUMorqUbUFsI6s8HBfZTNvj98__-oqeP99_1QV00Fp2VRaO-gSHXdaJHUub0_QWPGuLsBsRrjVIROV7XXxs4M-H4Zee3MV3GnwPX8UPLuDXMdYV4BoCoj4NcI0GvB_jew2-7_VpwAF_n466EvxGwsxCvqslPK2evxxcvJRgnWjB4dASIOF-kyyXcFYb8ifXFzKHcWKZJC_pZJuL_0KgwO2RArNGgfkABeopWxc9MNBnyPcr9C8NfInu7NFtA93HLo1t1_lQ88qx5kiLeaMFiMCs0uLu6fnfvxlanHcTFlstQNuI_TBCuDba8ttTq1kXAWu_sNdHPmHbbXXPoF_oErejLm4BunX7P39H-88AOgMNCoHdBjQCOXJ6GPRaprC9oTa1Oxr7Q23aBZwNtWm3k4zYi2gfm15LXvZ8qFGtoAWIraFG7QK2Q-lcdrsE2DYqxr84X2Mj9GgwJF-_n8jX2IhDGv-UfP1-nK-xNzQUvE6vNcFqW26fUPCqUKgIX0fb2dAo6GobDI2CLuD8xlHgmHGKkRVrwLJ2OS-CCdKQ8c8xg3Z-Fd3uou9dfLVKNyv2xiK9HLBhhLL8SJQRzjbt0ZBLjuEYoYodjbIH__b0sDyA145hnw1VuksocKAiXAGzbjXiFId_EiWjJaok7oilXAFDTBIUGLxWiZL0SpPhtaa2IjctoBc2wkLpJQEqmNQtVSUyqvxcAoJELFM5B7ZaLTUyU5xWZ80UerzXCY1O2wq_avwkof1XGeJCsokGeACYc4sOEx7FUAJs8X8a_T9Jo3_KgHqGqBg5Z-7_MqJipKMw_Pg4ZTnhFcLs3HgabDLwyBuk8dlVkFtP3U3OTc8DXtA5usbqB08JOvNYk0fTHoTTMPPplaDBM_kumzHCmg3zi5NLS8M5cldhI_QYG-QUJ5eSupR5sEuYlDme9VF4dmkNYnDQddmof-M5qMmXY_ZTBo5TjMlg2TZY6RcxJoOJ2-68jzPQCwTHujXB-ZGsHObwH14Hvjpumqzb7rFS_h3DnEm98fW15h6jkkmrnR6fE64NIgbLtpxhRjqZ802i7V7_nPDhFN3i3T1Y7eUgMkfYoA_4pXRtEnIv-rGU2fwoFf4sVqtpXUVlj3hrTTsNjkoSKerSVZo6YqYioYw2BFXXJRnVdYFQ8rRmrFB0h0iutwuU1ab1xpj9y4MeUA7Uzw_APNN7ZMqKLar7Ve-EiUSm6ao8cM_rtPfAUg2K-kryjGfrik02DBIBfgHGyoQCZaFNItQDR6V4ra82Q33Z_ix9O8zmw_YtMfcf70-6CKA_M70ZSUY535af0UWMNkptpbawXkpd5uyFs1c51WPqVORrePRgYwfbQSksJdkOvYqcSgS1Xzc7vW0pUsnu4FwZkkWaknynfSVkCWcvrPLJytOev366ez74W-lT5ets3-0UYFnbnZolFcpivTulca3GEWtknsUCwWQg5eBBesfVmC4cOnfmZKy4SthCL6PgZUoiJKpwEaJqVluzUgkq9H6Hx_vluMiTRdtSa642RTiNRFpPQY5nIlzKQsfd0nNngTPeLGJK7Tj0YscJgmjuxzQOwsCPGAloiGPmjBMCJpMLvS8G42rB5zcSbb6MygF8zBfYwhhmjj6GNGb70xmO53OPBSwMYkxjOnItluqtZvv-G-eLUqmwWEt4mXCpms4dEyn5OmNsUW3EGZNCbUS-yHgkxqXyi1LzvwFzJoWa">