* Is init_priority file scope or global scope?
@ 2010-12-12 0:47 H.J. Lu
2010-12-12 7:45 ` Dave Korn
2010-12-13 19:30 ` Ian Lance Taylor
0 siblings, 2 replies; 5+ messages in thread
From: H.J. Lu @ 2010-12-12 0:47 UTC (permalink / raw)
To: GCC Development
Hi,
Using .init_array section on Linux/x86 raised a question on
init_priority. GCC manual says
`init_priority (PRIORITY)'
In Standard C++, objects defined at namespace scope are guaranteed
to be initialized in an order in strict accordance with that of
their definitions _in a given translation unit_. No guarantee is
made for initializations across translation units. However, GNU
C++ allows users to control the order of initialization of objects
defined at namespace scope with the `init_priority' attribute by
specifying a relative PRIORITY, a constant integral expression
currently bounded between 101 and 65535 inclusive. Lower numbers
indicate a higher priority.
In the following example, `A' would normally be created before
`B', but the `init_priority' attribute has reversed that order:
Some_Class A __attribute__ ((init_priority (2000)));
Some_Class B __attribute__ ((init_priority (543)));
Note that the particular values of PRIORITY do not matter; only
their relative ordering.
Is init_priority file scope or global scope? I consider init_priority is
file scope. Is that a correct assumption?
--
H.J.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Is init_priority file scope or global scope?
[not found] ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
@ 2010-12-12 7:40 ` Dave Korn
2010-12-13 19:41 ` Ian Lance Taylor
0 siblings, 1 reply; 5+ messages in thread
From: Dave Korn @ 2010-12-12 7:40 UTC (permalink / raw)
To: H.J. Lu, gcc
On 12/12/2010 06:54, H.J. Lu wrote:
[ off-list, but it's not personal, so let's Cc the list back in, someone might
find this explanation of the mechanism useful in the archives. ]
> Can you check the assembly output? Since
>
> ----
> Note that the particular values of PRIORITY do not matter; only
> their relative ordering.
> ---
>
> on Linux, the numeric string in section name isn't the same as
> PRIORITY in source file. That means on Linux, the order
> of .ctors sections in 2 files isn't the relative ordering of PRIORITY
> of those 2 files.
Well, at least on PE-COFF, the numeric string is (65536-priority). It is
zero padded to five digits, so that the linker's alphabetical sort effectively
becomes a numeric sort, and the reason for the inverting the numeric order of
priorities is because .ctors gets read backwards at startup.
I did actually check the assembly somewhere between writing "IIRC" and
finishing my email as it happens. For a testcase based on your example:
class Some_Class {
int x;
public:
Some_Class();
~Some_Class();
};
Some_Class A __attribute__ ((init_priority (2000)));
Some_Class B __attribute__ ((init_priority (543)));
... what we get is a static_initialization_and_destruction function that takes
the init priority level as an argument and constructs or destroys (per a
second argument) everything at that level only:
.file "clas.c"
.globl _A
.bss
.align 4
_A:
.space 4
.globl _B
.align 4
_B:
.space 4
.text
.def __Z41__static_initialization_and_destruction_0ii; .scl 3; .type 32; .endef
__Z41__static_initialization_and_destruction_0ii:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
cmpl $1, 8(%ebp)
jne L2
cmpl $2000, 12(%ebp)
^^^^^^^^^^^^^^^^^^^^^^^
jne L3
^^^^^^^^^^
movl $_A, (%esp)
call __ZN10Some_ClassC1Ev
L3:
cmpl $543, 12(%ebp)
^^^^^^^^^^^^^^^^^^^^^^
jne L2
^^^^^^^^^^
movl $_B, (%esp)
call __ZN10Some_ClassC1Ev
L2:
cmpl $0, 8(%ebp)
jne L1
cmpl $543, 12(%ebp)
^^^^^^^^^^^^^^^^^^^^^^
jne L5
^^^^^^^^^^
movl $_B, (%esp)
call __ZN10Some_ClassD1Ev
L5:
cmpl $2000, 12(%ebp)
^^^^^^^^^^^^^^^^^^^^^^^
jne L1
^^^^^^^^^^
movl $_A, (%esp)
call __ZN10Some_ClassD1Ev
L1:
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
Then we have __GLOBAL__[I/D] functions for each priority level, which load
the appropriate priority and construct/destruct argument and call that:
.def __GLOBAL__I.00543_A; .scl 3; .type 32; .endef
__GLOBAL__I.00543_A:
LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl $543, 4(%esp)
^^^^^^^^^^^^^^^^^^^^^
movl $1, (%esp)
^^^^^^^^^^^^^^^^^^
call __Z41__static_initialization_and_destruction_0ii
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE1:
.def __GLOBAL__D.00543_A; .scl 3; .type 32; .endef
__GLOBAL__D.00543_A:
LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl $543, 4(%esp)
^^^^^^^^^^^^^^^^^^^^^
movl $0, (%esp)
^^^^^^^^^^^^^^^^^^
call __Z41__static_initialization_and_destruction_0ii
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE2:
.def __GLOBAL__I.02000_A; .scl 3; .type 32; .endef
__GLOBAL__I.02000_A:
LFB3:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl $2000, 4(%esp)
^^^^^^^^^^^^^^^^^^^^^^
movl $1, (%esp)
^^^^^^^^^^^^^^^^^^
call __Z41__static_initialization_and_destruction_0ii
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE3:
.def __GLOBAL__D.02000_A; .scl 3; .type 32; .endef
__GLOBAL__D.02000_A:
LFB4:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl $2000, 4(%esp)
^^^^^^^^^^^^^^^^^^^^^^
movl $0, (%esp)
^^^^^^^^^^^^^^^^^^
call __Z41__static_initialization_and_destruction_0ii
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE4:
... and it is these routines that are inserted in reverse-priority order into
the .ctors and .dtors tables (don't forget that the .ctors table is run
backward, the .dtors is run forward):
.section .ctors.64992,"w"
.align 4
.long __GLOBAL__I.00543_A
.text
.section .dtors.64992,"w"
.align 4
.long __GLOBAL__D.00543_A
.text
.section .ctors.63535,"w"
.align 4
.long __GLOBAL__I.02000_A
.text
.section .dtors.63535,"w"
.align 4
.long __GLOBAL__D.02000_A
So that ought to be entirely global ordering at final-link time. I don't
know if ELF does it differently.
cheers,
DaveK
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Is init_priority file scope or global scope?
2010-12-12 0:47 Is init_priority file scope or global scope? H.J. Lu
@ 2010-12-12 7:45 ` Dave Korn
[not found] ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
2010-12-13 19:30 ` Ian Lance Taylor
1 sibling, 1 reply; 5+ messages in thread
From: Dave Korn @ 2010-12-12 7:45 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Development
On 12/12/2010 00:47, H.J. Lu wrote:
> Hi,
>
> Using .init_array section on Linux/x86 raised a question on
> init_priority. GCC manual says
>
> `init_priority (PRIORITY)'
> In Standard C++, objects defined at namespace scope are guaranteed
> to be initialized in an order in strict accordance with that of
> their definitions _in a given translation unit_. No guarantee is
> made for initializations across translation units. However, GNU
> C++ allows users to control the order of initialization of objects
> defined at namespace scope with the `init_priority' attribute by
> specifying a relative PRIORITY, a constant integral expression
> currently bounded between 101 and 65535 inclusive. Lower numbers
> indicate a higher priority.
>
> In the following example, `A' would normally be created before
> `B', but the `init_priority' attribute has reversed that order:
>
> Some_Class A __attribute__ ((init_priority (2000)));
> Some_Class B __attribute__ ((init_priority (543)));
>
> Note that the particular values of PRIORITY do not matter; only
> their relative ordering.
>
> Is init_priority file scope or global scope? I consider init_priority is
> file scope. Is that a correct assumption?
>
At least on PE-COFF, it's implemented by appending a numeric string to the
.ctor/.dtor section name for the object's __GLOBAL__[CD] entries and letting
them all get sorted by the linker into numeric order in the final output
.ctors/.dtors table, so it ought to be global.
cheers,
DaveK
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Is init_priority file scope or global scope?
2010-12-12 0:47 Is init_priority file scope or global scope? H.J. Lu
2010-12-12 7:45 ` Dave Korn
@ 2010-12-13 19:30 ` Ian Lance Taylor
1 sibling, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2010-12-13 19:30 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Development
"H.J. Lu" <hjl.tools@gmail.com> writes:
> Using .init_array section on Linux/x86 raised a question on
> init_priority. GCC manual says
>
> `init_priority (PRIORITY)'
> In Standard C++, objects defined at namespace scope are guaranteed
> to be initialized in an order in strict accordance with that of
> their definitions _in a given translation unit_. No guarantee is
> made for initializations across translation units. However, GNU
> C++ allows users to control the order of initialization of objects
> defined at namespace scope with the `init_priority' attribute by
> specifying a relative PRIORITY, a constant integral expression
> currently bounded between 101 and 65535 inclusive. Lower numbers
> indicate a higher priority.
>
> In the following example, `A' would normally be created before
> `B', but the `init_priority' attribute has reversed that order:
>
> Some_Class A __attribute__ ((init_priority (2000)));
> Some_Class B __attribute__ ((init_priority (543)));
>
> Note that the particular values of PRIORITY do not matter; only
> their relative ordering.
>
> Is init_priority file scope or global scope? I consider init_priority is
> file scope. Is that a correct assumption?
No. That would be useless. init_priority has global scope. That is
what it was designed for.
The documentation could be more clear, but it is clearly saying "C++
specifies the order in a translation unit, init_priority specifies the
order across translation units."
Ian
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Is init_priority file scope or global scope?
2010-12-12 7:40 ` Dave Korn
@ 2010-12-13 19:41 ` Ian Lance Taylor
0 siblings, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2010-12-13 19:41 UTC (permalink / raw)
To: Dave Korn; +Cc: H.J. Lu, gcc
Dave Korn <dave.korn.cygwin@gmail.com> writes:
> Well, at least on PE-COFF, the numeric string is (65536-priority). It is
> zero padded to five digits, so that the linker's alphabetical sort effectively
> becomes a numeric sort, and the reason for the inverting the numeric order of
> priorities is because .ctors gets read backwards at startup.
Same on ELF (except that on ARM EABI it uses .init_array and does not
subtract from 65535; see arm_elf_asm_cdtor).
Ian
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-12-13 19:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-12 0:47 Is init_priority file scope or global scope? H.J. Lu
2010-12-12 7:45 ` Dave Korn
[not found] ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
2010-12-12 7:40 ` Dave Korn
2010-12-13 19:41 ` Ian Lance Taylor
2010-12-13 19:30 ` Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).