Date: Fri, 17 May 2024 09:28:13 +0800 From: Zhenlei Huang <zlei@FreeBSD.org> To: Konstantin Belousov <kostikbel@gmail.com> Cc: FreeBSD Current <current@freebsd.org> Subject: Re: gcc behavior of init priority of .ctors and .dtors section Message-ID: <B085A9CB-786E-48F7-BE43-94FE8097C949@FreeBSD.org> In-Reply-To: <ZkZP3SWpe61etZOc@kib.kiev.ua> References: <3ECF8C28-D2D9-4212-B025-3EC64E46BADC@FreeBSD.org> <ZkZP3SWpe61etZOc@kib.kiev.ua>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --] > On May 17, 2024, at 2:26 AM, Konstantin Belousov <kostikbel@gmail.com> wrote: > > On Thu, May 16, 2024 at 08:06:46PM +0800, Zhenlei Huang wrote: >> Hi, >> >> I'm recently working on https://reviews.freebsd.org/D45194 and got noticed >> that gcc behaves weirdly. >> >> A simple source file to demonstrate that. >> >> ``` >> # cat ctors.c >> >> #include <stdio.h> >> >> __attribute__((constructor(101))) void init_101() { puts("init 1"); } >> __attribute__((constructor(65535))) void init_65535() { puts("init 3"); } >> __attribute__((constructor)) void init() { puts("init 4"); } >> __attribute__((constructor(65535))) void init_65535_2() { puts("init 5"); } >> __attribute__((constructor(65534))) void init_65534() { puts("init 2"); } >> >> int main() { puts("main"); } >> >> __attribute__((destructor(65534))) void fini_65534() { puts("fini 2"); } >> __attribute__((destructor(65535))) void fini_65535() { puts("fini 3"); } >> __attribute__((destructor)) void fini() { puts("fini 4"); } >> __attribute__((destructor(65535))) void fini_65535_2() { puts("fini 5"); } >> __attribute__((destructor(101))) void fini_101() { puts("fini 1"); } >> >> # clang ctors.c && ./a.out >> init 1 >> init 2 >> init 3 >> init 4 >> init 5 >> main >> fini 5 >> fini 4 >> fini 3 >> fini 2 >> fini 1 >> ``` >> >> clang with the option -fno-use-init-array and run will produce the same result, which >> is what I expected. > Why do you add that switch? gcc13 in ports is not configured with option --enable-initfini-array then it only produces .ctors / .dtors sections but not .init_array / .fini_array sections. So I add that switch for clang to produce `.ctors` sections instead as a baseline ( .ctors produced by clang indeed works as expected, the same with .init_array ). > >> >> gcc13 from ports >> ``` >> # gcc ctors.c && ./a.out >> init 1 >> init 2 >> init 5 >> init 4 >> init 3 >> main >> fini 3 >> fini 4 >> fini 5 >> fini 2 >> fini 1 >> ``` >> >> The above order is not expected. I think clang's one is correct. >> >> Further hacking with readelf shows that clang produces the right order of >> section .rela.ctors but gcc does not. >> >> ``` >> # clang -fno-use-init-array -c ctors.c && readelf -r ctors.o | grep 'Relocation section with addend (.rela.ctors)' -A5 > clang.txt >> # gcc -c ctors.c && readelf -r ctors.o | grep 'Relocation section with addend (.rela.ctors)' -A5 > gcc.txt >> # diff clang.txt gcc.txt >> 3,5c3,5 >> < 000000000000 000800000001 R_X86_64_64 0000000000000060 init_65535_2 + 0 >> < 000000000008 000700000001 R_X86_64_64 0000000000000040 init + 0 >> < 000000000010 000600000001 R_X86_64_64 0000000000000020 init_65535 + 0 >> --- >>> 000000000000 000600000001 R_X86_64_64 0000000000000011 init_65535 + 0 >>> 000000000008 000700000001 R_X86_64_64 0000000000000022 init + 0 >>> 000000000010 000800000001 R_X86_64_64 0000000000000033 init_65535_2 + 0 >> ``` >> >> The above show clearly gcc produces the wrong order of section `.rela.ctors`. >> >> Is that expected behavior ? >> >> I have not tried Linux version of gcc. > Note that init array vs. init function behavior is encoded by a note added > by crt1.o. I suspect that the problem is that gcc port is built without > --enable-initfini-array configure option. [-- Attachment #2 --] <html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On May 17, 2024, at 2:26 AM, Konstantin Belousov <<a href="mailto:kostikbel@gmail.com" class="">kostikbel@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta charset="UTF-8" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">On Thu, May 16, 2024 at 08:06:46PM +0800, Zhenlei Huang wrote:</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">Hi,<br class=""><br class="">I'm recently working on <a href="https://reviews.freebsd.org/D45194" class="">https://reviews.freebsd.org/D45194</a> and got noticed<br class="">that gcc behaves weirdly.<br class=""><br class="">A simple source file to demonstrate that.<br class=""><br class="">```<br class=""># cat ctors.c<br class=""><br class="">#include <stdio.h><br class=""><br class="">__attribute__((constructor(101))) void init_101() { puts("init 1"); }<br class="">__attribute__((constructor(65535))) void init_65535() { puts("init 3"); }<br class="">__attribute__((constructor)) void init() { puts("init 4"); }<br class="">__attribute__((constructor(65535))) void init_65535_2() { puts("init 5"); }<br class="">__attribute__((constructor(65534))) void init_65534() { puts("init 2"); }<br class=""><br class="">int main() { puts("main"); }<br class=""><br class="">__attribute__((destructor(65534))) void fini_65534() { puts("fini 2"); }<br class="">__attribute__((destructor(65535))) void fini_65535() { puts("fini 3"); }<br class="">__attribute__((destructor)) void fini() { puts("fini 4"); }<br class="">__attribute__((destructor(65535))) void fini_65535_2() { puts("fini 5"); }<br class="">__attribute__((destructor(101))) void fini_101() { puts("fini 1"); }<br class=""><br class=""># clang ctors.c && ./a.out<br class="">init 1<br class="">init 2<br class="">init 3<br class="">init 4<br class="">init 5<br class="">main<br class="">fini 5<br class="">fini 4<br class="">fini 3<br class="">fini 2<br class="">fini 1<br class="">```<br class=""><br class="">clang with the option -fno-use-init-array and run will produce the same result, which<br class="">is what I expected.<br class=""></blockquote><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Why do you add that switch?</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div></blockquote><div><br class=""></div><div>gcc13 in ports is not configured with option --enable-initfini-array then it only produces .ctors / .dtors sections but</div><div>not .init_array / .fini_array sections. So I add that switch for clang to produce `.ctors` sections instead as</div><div>a baseline ( .ctors produced by clang indeed works as expected, the same with .init_array ).<br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class="">gcc13 from ports<br class="">```<br class=""># gcc ctors.c && ./a.out<br class="">init 1<br class="">init 2<br class="">init 5<br class="">init 4<br class="">init 3<br class="">main<br class="">fini 3<br class="">fini 4<br class="">fini 5<br class="">fini 2<br class="">fini 1<br class="">```<br class=""><br class="">The above order is not expected. I think clang's one is correct.<br class=""><br class="">Further hacking with readelf shows that clang produces the right order of<br class="">section .rela.ctors but gcc does not.<br class=""><br class="">```<br class=""># clang -fno-use-init-array -c ctors.c && readelf -r ctors.o | grep 'Relocation section with addend (.rela.ctors)' -A5 > clang.txt<br class=""># gcc -c ctors.c && readelf -r ctors.o | grep 'Relocation section with addend (.rela.ctors)' -A5 > gcc.txt<br class=""># diff clang.txt gcc.txt<br class="">3,5c3,5<br class="">< 000000000000 000800000001 R_X86_64_64 0000000000000060 init_65535_2 + 0<br class="">< 000000000008 000700000001 R_X86_64_64 0000000000000040 init + 0<br class="">< 000000000010 000600000001 R_X86_64_64 0000000000000020 init_65535 + 0<br class="">---<br class=""><blockquote type="cite" class="">000000000000 000600000001 R_X86_64_64 0000000000000011 init_65535 + 0<br class="">000000000008 000700000001 R_X86_64_64 0000000000000022 init + 0<br class="">000000000010 000800000001 R_X86_64_64 0000000000000033 init_65535_2 + 0<br class=""></blockquote>```<br class=""><br class="">The above show clearly gcc produces the wrong order of section `.rela.ctors`.<br class=""><br class="">Is that expected behavior ?<br class=""><br class="">I have not tried Linux version of gcc.<br class=""></blockquote><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Note that init array vs. init function behavior is encoded by a note added</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">by crt1.o. I suspect that the problem is that gcc port is built without</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">--enable-initfini-array configure option.</span></div></blockquote></div><br class=""><div class=""> <div><br class=""></div> </div> <br class=""></body></html>help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B085A9CB-786E-48F7-BE43-94FE8097C949>
