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>
next in thread | previous in thread | raw e-mail | index | archive | help
--Apple-Mail=_84795C71-C966-413C-8C56-4970D5530BD1 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On May 17, 2024, at 2:26 AM, Konstantin Belousov <kostikbel@gmail.com> = wrote: >=20 > On Thu, May 16, 2024 at 08:06:46PM +0800, Zhenlei Huang wrote: >> Hi, >>=20 >> I'm recently working on https://reviews.freebsd.org/D45194 and got = noticed >> that gcc behaves weirdly. >>=20 >> A simple source file to demonstrate that. >>=20 >> ``` >> # cat ctors.c >>=20 >> #include <stdio.h> >>=20 >> __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"); } >>=20 >> int main() { puts("main"); } >>=20 >> __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"); } >>=20 >> # 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 >> ``` >>=20 >> 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 ). >=20 >>=20 >> 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 >> ``` >>=20 >> The above order is not expected. I think clang's one is correct. >>=20 >> Further hacking with readelf shows that clang produces the right = order of >> section .rela.ctors but gcc does not. >>=20 >> ``` >> # 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 >> ``` >>=20 >> The above show clearly gcc produces the wrong order of section = `.rela.ctors`. >>=20 >> Is that expected behavior ? >>=20 >> 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. --Apple-Mail=_84795C71-C966-413C-8C56-4970D5530BD1 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii <html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; = charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; line-break: after-white-space;" class=3D""><br = class=3D""><div><br class=3D""><blockquote type=3D"cite" class=3D""><div = class=3D"">On May 17, 2024, at 2:26 AM, Konstantin Belousov <<a = href=3D"mailto:kostikbel@gmail.com" class=3D"">kostikbel@gmail.com</a>>= wrote:</div><br class=3D"Apple-interchange-newline"><div class=3D""><meta= charset=3D"UTF-8" class=3D""><span style=3D"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=3D"">On Thu, May 16, 2024 at 08:06:46PM +0800, Zhenlei Huang = wrote:</span><br style=3D"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=3D""><blockquote type=3D"cite" style=3D"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=3D"">Hi,<br = class=3D""><br class=3D"">I'm recently working on <a = href=3D"https://reviews.freebsd.org/D45194" = class=3D"">https://reviews.freebsd.org/D45194</a> and got noticed<br = class=3D"">that gcc behaves weirdly.<br class=3D""><br class=3D"">A = simple source file to demonstrate that.<br class=3D""><br = class=3D"">```<br class=3D""># cat ctors.c<br class=3D""><br = class=3D"">#include <stdio.h><br class=3D""><br = class=3D"">__attribute__((constructor(101))) void init_101() { = puts("init 1"); }<br class=3D"">__attribute__((constructor(65535))) void = init_65535() { puts("init 3"); }<br = class=3D"">__attribute__((constructor)) void init() { puts("init 4"); = }<br class=3D"">__attribute__((constructor(65535))) void init_65535_2() = { puts("init 5"); }<br class=3D"">__attribute__((constructor(65534))) = void init_65534() { puts("init 2"); }<br class=3D""><br class=3D"">int = main() { puts("main"); }<br class=3D""><br = class=3D"">__attribute__((destructor(65534))) void fini_65534() { = puts("fini 2"); }<br class=3D"">__attribute__((destructor(65535))) void = fini_65535() { puts("fini 3"); }<br class=3D"">__attribute__((destructor))= void fini() { puts("fini 4"); }<br = class=3D"">__attribute__((destructor(65535))) void fini_65535_2() { = puts("fini 5"); }<br class=3D"">__attribute__((destructor(101))) void = fini_101() { puts("fini 1"); }<br class=3D""><br class=3D""># clang = ctors.c && ./a.out<br class=3D"">init 1<br class=3D"">init 2<br = class=3D"">init 3<br class=3D"">init 4<br class=3D"">init 5<br = class=3D"">main<br class=3D"">fini 5<br class=3D"">fini 4<br = class=3D"">fini 3<br class=3D"">fini 2<br class=3D"">fini 1<br = class=3D"">```<br class=3D""><br class=3D"">clang with the option = -fno-use-init-array and run will produce the same result, which<br = class=3D"">is what I expected.<br class=3D""></blockquote><span = style=3D"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=3D"">Why do you = add that switch?</span><br style=3D"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=3D""></div></blockquote><div><br = class=3D""></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=3D""></div><br class=3D""><blockquote = type=3D"cite" class=3D""><div class=3D""><br style=3D"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=3D""><blockquote type=3D"cite" = style=3D"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=3D""><br class=3D"">gcc13 from ports<br = class=3D"">```<br class=3D""># gcc ctors.c && ./a.out<br = class=3D"">init 1<br class=3D"">init 2<br class=3D"">init 5<br = class=3D"">init 4<br class=3D"">init 3<br class=3D"">main<br = class=3D"">fini 3<br class=3D"">fini 4<br class=3D"">fini 5<br = class=3D"">fini 2<br class=3D"">fini 1<br class=3D"">```<br class=3D""><br= class=3D"">The above order is not expected. I think clang's one is = correct.<br class=3D""><br class=3D"">Further hacking with readelf shows = that clang produces the right order of<br class=3D"">section .rela.ctors = but gcc does not.<br class=3D""><br class=3D"">```<br class=3D""># clang = -fno-use-init-array -c ctors.c && readelf -r ctors.o | grep = 'Relocation section with addend (.rela.ctors)' -A5 > clang.txt<br = class=3D""># gcc -c ctors.c && readelf -r ctors.o | grep = 'Relocation section with addend (.rela.ctors)' -A5 > gcc.txt<br = class=3D""># diff clang.txt gcc.txt<br class=3D"">3,5c3,5<br = class=3D"">< 000000000000 000800000001 R_X86_64_64 = 0000000000000060 = init_65535_2 + 0<br class=3D"">< 000000000008 000700000001 = R_X86_64_64 = 0000000000000040 init + = 0<br class=3D"">< 000000000010 000600000001 R_X86_64_64 = 0000000000000020 = init_65535 + 0<br class=3D"">---<br class=3D""><blockquote type=3D"cite" = class=3D"">000000000000 000600000001 R_X86_64_64 = 0000000000000011 = init_65535 + 0<br class=3D"">000000000008 000700000001 R_X86_64_64 = 0000000000000022 init + = 0<br class=3D"">000000000010 000800000001 R_X86_64_64 = 0000000000000033 = init_65535_2 + 0<br class=3D""></blockquote>```<br class=3D""><br = class=3D"">The above show clearly gcc produces the wrong order of = section `.rela.ctors`.<br class=3D""><br class=3D"">Is that expected = behavior ?<br class=3D""><br class=3D"">I have not tried Linux version = of gcc.<br class=3D""></blockquote><span style=3D"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=3D"">Note that init array vs. init function behavior is encoded by = a note added</span><br style=3D"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=3D""><span style=3D"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=3D"">by crt1.o. = I suspect that the problem is that gcc port is built = without</span><br style=3D"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=3D""><span style=3D"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=3D"">--enable-initfini-array configure = option.</span></div></blockquote></div><br class=3D""><div class=3D""> <div><br class=3D""></div> </div> <br class=3D""></body></html>= --Apple-Mail=_84795C71-C966-413C-8C56-4970D5530BD1--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B085A9CB-786E-48F7-BE43-94FE8097C949>