const volatile behaviour change in GCC 7
Hello, for RTEMS we use linker sets to initialize the system. The following code worked up to GCC 6, but no longer in GCC 7: typedef void ( *rtems_sysinit_handler )( void ); typedef struct { rtems_sysinit_handler handler; } rtems_sysinit_item; rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); void rtems_initialize_executive(void) { const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; while ( cur != end ) { ( *cur->handler )(); ++cur; } } The corresponding GNU ld linker script section is: .rtemsroset : ALIGN_WITH_INPUT { KEEP (*(SORT(.rtemsroset.*))) } > REGION_RODATA AT > REGION_RODATA_LOAD In GCC 7, the compiler deduces that "cur != end" is always true and generates an infinite loop. Up to GCC 6 the "volatile const" seemed to prevent this optimization. I know that this linker set stuff is quite non-standard, but is there a way to get this to work again on GCC 7? The nice thing with the "type volatile const X[0]..." construct is that you can generate arbitrary linker sets via it without a need to edit the linker command file and with no storage overhead. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
Re: const volatile behaviour change in GCC 7
On Thu, Sep 22, 2016 at 3:23 PM, Sebastian Huber wrote: > Hello, > > for RTEMS we use linker sets to initialize the system. The following code > worked up to GCC 6, but no longer in GCC 7: > > typedef void ( *rtems_sysinit_handler )( void ); > > typedef struct { > rtems_sysinit_handler handler; > } rtems_sysinit_item; > > rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) > __attribute__((__used__)); > > rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) > __attribute__((__used__)); > > void rtems_initialize_executive(void) > { > const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; > const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; > > while ( cur != end ) { > ( *cur->handler )(); > ++cur; > } > } > > The corresponding GNU ld linker script section is: > > .rtemsroset : ALIGN_WITH_INPUT { > KEEP (*(SORT(.rtemsroset.*))) > } > REGION_RODATA AT > REGION_RODATA_LOAD > > In GCC 7, the compiler deduces that "cur != end" is always true and > generates an infinite loop. > > Up to GCC 6 the "volatile const" seemed to prevent this optimization. I know > that this linker set stuff is quite non-standard, but is there a way to get > this to work again on GCC 7? Yes do the following (which will work with every GCC version): #define MAKEGCCNOTKNOWTHEADDRESS(ptr) asm("":"+r"(ptr)) const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; MAKEGCCNOTKNOWTHEADDRESS(cur); MAKEGCCNOTKNOWTHEADDRESS(end); You can think of better names if you want but this is the best way really. Thanks, Andrew Pinski > > The nice thing with the "type volatile const X[0]..." construct is that you > can generate arbitrary linker sets via it without a need to edit the linker > command file and with no storage overhead. > > -- > Sebastian Huber, embedded brains GmbH > > Address : Dornierstr. 4, D-82178 Puchheim, Germany > Phone : +49 89 189 47 41-16 > Fax : +49 89 189 47 41-09 > E-Mail : sebastian.hu...@embedded-brains.de > PGP : Public key available on request. > > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. >
gcc 3.4.6 asm charset error
GCC 3.4.6 natively handles different character sets for source and target. It actually works fine, writing source code in ASCII targeting an EBCDIC destination. However, __asm() doesn't seem to be working. As seen below, it is generating EBCDIC data in the ASCII assembler output. Those funny characters are in fact the EBCDIC code for "ABC" and "DEF". Anyone know how to fix this? Thanks. Paul. C:\scratch\bb99>type test.c extern int i; void foo(void) { i = 5; __asm("ABC"); __asm("DEF"); } C:\scratch\bb99>gccmvs-3_4_6-1_0 -S test.c C:\scratch\bb99>type test.s COPY PDPTOP CSECT * Program text area DS0F * X-func foo prologue FOO PDPPRLG CINDEX=0,FRAME=88,BASER=12,ENTRY=YES B FEN0 LTORG FEN0 EQU * DROP 12 BALR 12,0 USING *,12 PG0 EQU * LR11,1 L 10,=A(PGT0) * Function foo code L 2,=V(I) MVC 0(4,2),=F'5' ┴┬├ ─┼╞ * Function foo epilogue PDPEPIL * Function foo literal pool DS0F LTORG * Function foo page table DS0F PGT0 EQU * DCA(PG0) END C:\scratch\bb99>
Re: const volatile behaviour change in GCC 7
On Sep 22 2016, Sebastian Huber wrote: > for RTEMS we use linker sets to initialize the system. The following code > worked up to GCC 6, but no longer in GCC 7: > > typedef void ( *rtems_sysinit_handler )( void ); > > typedef struct { > rtems_sysinit_handler handler; > } rtems_sysinit_item; > > rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) > __attribute__((__used__)); > > rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) > __attribute__((__used__)); > > void rtems_initialize_executive(void) > { > const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; > const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; > > while ( cur != end ) { > ( *cur->handler )(); > ++cur; > } > } > > The corresponding GNU ld linker script section is: > > .rtemsroset : ALIGN_WITH_INPUT { > KEEP (*(SORT(.rtemsroset.*))) > } > REGION_RODATA AT > REGION_RODATA_LOAD > > In GCC 7, the compiler deduces that "cur != end" is always true and > generates an infinite loop. > > Up to GCC 6 the "volatile const" seemed to prevent this optimization. These qualifiers do not say anything about the variable cur and end themselves, only about the values they point to. As such I don't see how they can have any influence on the value of "cur != end". Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: const volatile behaviour change in GCC 7
On Thu, Sep 22, 2016 at 9:58 AM, Andreas Schwab wrote: > On Sep 22 2016, Sebastian Huber wrote: > >> for RTEMS we use linker sets to initialize the system. The following code >> worked up to GCC 6, but no longer in GCC 7: >> >> typedef void ( *rtems_sysinit_handler )( void ); >> >> typedef struct { >> rtems_sysinit_handler handler; >> } rtems_sysinit_item; >> >> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] >> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) >> __attribute__((__used__)); >> >> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] >> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) >> __attribute__((__used__)); >> >> void rtems_initialize_executive(void) >> { >> const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; >> const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; >> >> while ( cur != end ) { >> ( *cur->handler )(); >> ++cur; >> } >> } >> >> The corresponding GNU ld linker script section is: >> >> .rtemsroset : ALIGN_WITH_INPUT { >> KEEP (*(SORT(.rtemsroset.*))) >> } > REGION_RODATA AT > REGION_RODATA_LOAD >> >> In GCC 7, the compiler deduces that "cur != end" is always true and >> generates an infinite loop. >> >> Up to GCC 6 the "volatile const" seemed to prevent this optimization. > > These qualifiers do not say anything about the variable cur and end > themselves, only about the values they point to. As such I don't see > how they can have any influence on the value of "cur != end". Yeah, GCC 7 now optimizes pointer comparisons more aggressively. OTOH I can't reproduce with a simpler const int a[0]; const int b[0]; int foo () { return a != b; } unless I add 'static' to the vars at which point earlier GCC optimize this as well. Eventually you'll hit undefined behavior during loop analysis as you are accessing a zero-sized array. But I don't remember this changing in GCC 7 either. Richard. > Andreas. > > -- > Andreas Schwab, SUSE Labs, sch...@suse.de > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 > "And now for something completely different."
Re: const volatile behaviour change in GCC 7
On 22/09/16 09:23, Sebastian Huber wrote: > Hello, > > for RTEMS we use linker sets to initialize the system. The following > code worked up to GCC 6, but no longer in GCC 7: > > typedef void ( *rtems_sysinit_handler )( void ); > > typedef struct { > rtems_sysinit_handler handler; > } rtems_sysinit_item; > > rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) > __attribute__((__used__)); > > rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) > __attribute__((__used__)); > > void rtems_initialize_executive(void) > { > const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; > const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; > > while ( cur != end ) { > ( *cur->handler )(); > ++cur; > } > } > Your trouble is that your two pointers, cur and end, are pointing at different variables. Comparing two pointers that are independent (i.e., not pointing to parts of the same aggregate object) is undefined - the compiler can assume that these two external objects could be anywhere in memory, so there is no way (in pure C) for you to know or care how they are related. Therefore it can assume that you will never reach "cur == end". Ideally, you want to tell the compiler that you are dealing with an array, rather than two independent pointers. But I am not sure how to express this without at least a little extra overhead (such as having the linker generate an "array size" constant that you read along with the start of the array). Andrew's MAKEGCCNOTKNOWTHEADDRESS macro will work, however. > The corresponding GNU ld linker script section is: > > .rtemsroset : ALIGN_WITH_INPUT { > KEEP (*(SORT(.rtemsroset.*))) > } > REGION_RODATA AT > REGION_RODATA_LOAD > > In GCC 7, the compiler deduces that "cur != end" is always true and > generates an infinite loop. > > Up to GCC 6 the "volatile const" seemed to prevent this optimization. I > know that this linker set stuff is quite non-standard, but is there a > way to get this to work again on GCC 7? > > The nice thing with the "type volatile const X[0]..." construct is that > you can generate arbitrary linker sets via it without a need to edit the > linker command file and with no storage overhead. >
Re: const volatile behaviour change in GCC 7
Sebastian Huber writes: > Hello, > > for RTEMS we use linker sets to initialize the system. The following > code worked up to GCC 6, but no longer in GCC 7: > > typedef void ( *rtems_sysinit_handler )( void ); > > typedef struct { > rtems_sysinit_handler handler; > } rtems_sysinit_item; > > rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) > __attribute__((__used__)); > > rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] > __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) > __attribute__((__used__)); > > void rtems_initialize_executive(void) > { > const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; > const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; You likely have 'volatile' in a wrong place. Try (untested): rtems_sysinit_item const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); void rtems_initialize_executive(void) { rtems_sysinit_item const *volatile cur = _Linker_set__Sysinit_begin; rtems_sysinit_item const *volatile end = _Linker_set__Sysinit_end; while(cur != end) { cur->handler(); ++cur; } } Alternatively, try (untested, and I removed attributes to make my point clearer): /* Linker-defined symbols */ rtems_sysinit_item const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); /* Get volatile pointers to the above */ static rtems_sysinit_item const *volatile begin_ = _Linker_set__Sysinit_begin; static rtems_sysinit_item const *volatile end_ = _Linker_set__Sysinit_end; void rtems_initialize_executive(void) { rtems_sysinit_item const *cur = begin_; rtems_sysinit_item const *end = end_; while(cur != end) { cur->handler(); ++cur; } } HTH -- Sergey
Re: const volatile behaviour change in GCC 7
On 22/09/16 14:11, Sergey Organov wrote: Sebastian Huber writes: Hello, for RTEMS we use linker sets to initialize the system. The following code worked up to GCC 6, but no longer in GCC 7: typedef void ( *rtems_sysinit_handler )( void ); typedef struct { rtems_sysinit_handler handler; } rtems_sysinit_item; rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); void rtems_initialize_executive(void) { const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin; const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end; You likely have 'volatile' in a wrong place. Try (untested): rtems_sysinit_item const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); void rtems_initialize_executive(void) { rtems_sysinit_item const *volatile cur = _Linker_set__Sysinit_begin; rtems_sysinit_item const *volatile end = _Linker_set__Sysinit_end; while(cur != end) { cur->handler(); ++cur; } } No, I don't want to load/store the pointers from/to memory all the time in this loop. Alternatively, try (untested, and I removed attributes to make my point clearer): /* Linker-defined symbols */ rtems_sysinit_item const _Linker_set__Sysinit_begin[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) __attribute__((__used__)); rtems_sysinit_item const _Linker_set__Sysinit_end[0] __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) __attribute__((__used__)); /* Get volatile pointers to the above */ static rtems_sysinit_item const *volatile begin_ = _Linker_set__Sysinit_begin; static rtems_sysinit_item const *volatile end_ = _Linker_set__Sysinit_end; void rtems_initialize_executive(void) { rtems_sysinit_item const *cur = begin_; rtems_sysinit_item const *end = end_; while(cur != end) { cur->handler(); ++cur; } } I don't want any storage for these begin/end markers. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
Re: const volatile behaviour change in GCC 7
> On Sep 22, 2016, at 6:17 AM, David Brown wrote: > > ... > Your trouble is that your two pointers, cur and end, are pointing at > different variables. Comparing two pointers that are independent (i.e., > not pointing to parts of the same aggregate object) is undefined - the > compiler can assume that these two external objects could be anywhere in > memory, so there is no way (in pure C) for you to know or care how they > are related. Therefore it can assume that you will never reach "cur == > end". Would making them intptr_t instead of pointers fix that? paul
Re: const volatile behaviour change in GCC 7
On 22/09/16 16:57, paul.kon...@dell.com wrote: > >> On Sep 22, 2016, at 6:17 AM, David Brown wrote: >> >> ... >> Your trouble is that your two pointers, cur and end, are pointing at >> different variables. Comparing two pointers that are independent (i.e., >> not pointing to parts of the same aggregate object) is undefined - the >> compiler can assume that these two external objects could be anywhere in >> memory, so there is no way (in pure C) for you to know or care how they >> are related. Therefore it can assume that you will never reach "cur == >> end". > > Would making them intptr_t instead of pointers fix that? > With care, yes. But I think it still relies on gcc not being quite as smart as it could be. This seems to generate working code, but the compier could in theory still apply the same analysis: void rtems_initialize_executive(void) { uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; while ( cur != end ) { const volatile rtems_sysinit_item *p = (const volatile rtems_sysinit_item *) cur; ( *p->handler )(); cur += sizeof(p); } }
Re: const volatile behaviour change in GCC 7
> On Sep 22, 2016, at 11:16 AM, David Brown wrote: > > On 22/09/16 16:57, paul.kon...@dell.com wrote: >> >>> On Sep 22, 2016, at 6:17 AM, David Brown wrote: >>> >>> ... >>> Your trouble is that your two pointers, cur and end, are pointing at >>> different variables. Comparing two pointers that are independent (i.e., >>> not pointing to parts of the same aggregate object) is undefined - the >>> compiler can assume that these two external objects could be anywhere in >>> memory, so there is no way (in pure C) for you to know or care how they >>> are related. Therefore it can assume that you will never reach "cur == >>> end". >> >> Would making them intptr_t instead of pointers fix that? >> > > With care, yes. But I think it still relies on gcc not being quite as > smart as it could be. This seems to generate working code, but the > compier could in theory still apply the same analysis: > > void rtems_initialize_executive(void) > { > uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; > uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; I would not expect the compiler to apply pointer rules for code like this. (u)intptr_t is an integer type; it happens to be one whose width is chosen to match the width of pointers on the platform in question, but that doesn't change the fact the type is integer. For example, it is perfectly valid for an intptr_t variable to contain values that could not possibly be pointers on a given platform. paul
Re: const volatile behaviour change in GCC 7
On September 22, 2016 5:20:56 PM GMT+02:00, paul.kon...@dell.com wrote: > >> On Sep 22, 2016, at 11:16 AM, David Brown >wrote: >> >> On 22/09/16 16:57, paul.kon...@dell.com wrote: >>> On Sep 22, 2016, at 6:17 AM, David Brown >wrote: ... Your trouble is that your two pointers, cur and end, are pointing >at different variables. Comparing two pointers that are independent >(i.e., not pointing to parts of the same aggregate object) is undefined - >the compiler can assume that these two external objects could be >anywhere in memory, so there is no way (in pure C) for you to know or care how >they are related. Therefore it can assume that you will never reach >"cur == end". >>> >>> Would making them intptr_t instead of pointers fix that? >>> >> >> With care, yes. But I think it still relies on gcc not being quite >as >> smart as it could be. This seems to generate working code, but the >> compier could in theory still apply the same analysis: >> >> void rtems_initialize_executive(void) >> { >> uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; >> uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; > >I would not expect the compiler to apply pointer rules for code like >this. (u)intptr_t is an integer type; it happens to be one whose width >is chosen to match the width of pointers on the platform in question, >but that doesn't change the fact the type is integer. For example, it >is perfectly valid for an intptr_t variable to contain values that >could not possibly be pointers on a given platform. I can't see how it could either. BTW your testcase contains another fragility, the order of two global vars. Richard. > paul
Re: const volatile behaviour change in GCC 7
On 22/09/16 16:20, paul.kon...@dell.com wrote: > >> On Sep 22, 2016, at 11:16 AM, David Brown wrote: >> >> On 22/09/16 16:57, paul.kon...@dell.com wrote: >>> On Sep 22, 2016, at 6:17 AM, David Brown wrote: ... Your trouble is that your two pointers, cur and end, are pointing at different variables. Comparing two pointers that are independent (i.e., not pointing to parts of the same aggregate object) is undefined - the compiler can assume that these two external objects could be anywhere in memory, so there is no way (in pure C) for you to know or care how they are related. Therefore it can assume that you will never reach "cur == end". >>> >>> Would making them intptr_t instead of pointers fix that? >>> >> >> With care, yes. But I think it still relies on gcc not being quite as >> smart as it could be. This seems to generate working code, but the >> compier could in theory still apply the same analysis: >> >> void rtems_initialize_executive(void) >> { >> uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; >> uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; > > I would not expect the compiler to apply pointer rules for code like this. > (u)intptr_t is an integer type; it happens to be one whose width is chosen to > match the width of pointers on the platform in question, but that doesn't > change the fact the type is integer. For example, it is perfectly valid for > an intptr_t variable to contain values that could not possibly be pointers on > a given platform. > > paul > It sounds to me as these are the sort of optimizations that should be disabled when compiling with -ffreestanding. R.
Re: const volatile behaviour change in GCC 7
> On Sep 22, 2016, at 11:31 AM, Richard Earnshaw (lists) > wrote: > >>> ... >>> void rtems_initialize_executive(void) >>> { >>> uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; >>> uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; >> >> I would not expect the compiler to apply pointer rules for code like this. >> (u)intptr_t is an integer type; it happens to be one whose width is chosen >> to match the width of pointers on the platform in question, but that doesn't >> change the fact the type is integer. For example, it is perfectly valid for >> an intptr_t variable to contain values that could not possibly be pointers >> on a given platform. >> >> paul >> > > It sounds to me as these are the sort of optimizations that should be > disabled when compiling with -ffreestanding. Possibly so. I dislike workarounds of that form; it seems safer to change the C code to rely on properties called out by the standard. After all, if an optimization is permitted, it might at some future time be done, and counting on there to be a way to turn off that optimization via a switch, or relying on that switch not changing across releases, isn't as safe. paul
Re: const volatile behaviour change in GCC 7
Sebastian Huber writes: > On 22/09/16 14:11, Sergey Organov wrote: >> Sebastian Huber writes: >>> Hello, [...] >> Alternatively, try (untested, and I removed attributes to make my point >> clearer): >> >> /* Linker-defined symbols */ >> >> rtems_sysinit_item const _Linker_set__Sysinit_begin[0] >> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin"))) >> __attribute__((__used__)); >> >> rtems_sysinit_item const _Linker_set__Sysinit_end[0] >> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end"))) >> __attribute__((__used__)); >> >> /* Get volatile pointers to the above */ >> static rtems_sysinit_item const *volatile begin_ = >> _Linker_set__Sysinit_begin; >> static rtems_sysinit_item const *volatile end_ = _Linker_set__Sysinit_end; >> >> void rtems_initialize_executive(void) >> { >>rtems_sysinit_item const *cur = begin_; >>rtems_sysinit_item const *end = end_; >> >>while(cur != end) { >> cur->handler(); >> ++cur; >>} >> } >> >> > > I don't want any storage for these begin/end markers. Why? 8 more bytes in context of RTEMS? It likely doesn't matter. At all. -- Sergey
Re: const volatile behaviour change in GCC 7
On 22/09/16 17:30, Richard Biener wrote: On September 22, 2016 5:20:56 PM GMT+02:00, paul.kon...@dell.com wrote: On Sep 22, 2016, at 11:16 AM, David Brown wrote: On 22/09/16 16:57, paul.kon...@dell.com wrote: On Sep 22, 2016, at 6:17 AM, David Brown wrote: ... Your trouble is that your two pointers, cur and end, are pointing at different variables. Comparing two pointers that are independent (i.e., not pointing to parts of the same aggregate object) is undefined - the compiler can assume that these two external objects could beanywhere in memory, so there is no way (in pure C) for you to know or care how they are related. Therefore it can assume that you will never reach "cur == end". Would making them intptr_t instead of pointers fix that? With care, yes. But I think it still relies on gcc not being quite as smart as it could be. This seems to generate working code, but the compier could in theory still apply the same analysis: void rtems_initialize_executive(void) { uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; I would not expect the compiler to apply pointer rules for code like this. (u)intptr_t is an integer type; it happens to be one whose width is chosen to match the width of pointers on the platform in question, but that doesn't change the fact the type is integer. For example, it is perfectly valid for an intptr_t variable to contain values that could not possibly be pointers on a given platform. The compiler /can/ perform such analysis and see the undefined behaviour of the code, and use that to optimise away the check for the loop. It is legal to convert (by cast or initialisation) an intptr_t or uintptr_t variable to a pointer - but it is /not/ legal to dereference it unless the intptr_t or uintptr_t was set from a legal pointer. Thus when the compiler is considering the validity of access through the casted uintptr_t variable, it can look back to where the contents of that variable came and consider those pointers. Since the compiler can assume that incrementing one pointer repeatedly never matches the other pointer (as they point to unrelated objects), the same applies even if the values have been cast back and forth through intptr_t variables. In general, I find that if you can't figure out a simple way to express your desires for this sort of thing using fully defined standard C behaviour, then complex methods with castings and the like will not be entirely correct either. They might work at the moment - gcc is a smart compiler, but it has its limits - but they might not work in the future (as the compiler gets better all the time). Compiler-specific workarounds like the assembly macro proposed are often the safest methods. Alternatively, you accept a slight performance hit by using an extra "volatile" step to limit the optimisation. Or you change the requirements, by finding a different way to handle it - such as by letting the linker figure out the size of the table and including it as a readable constant. I can't see how it could either. BTW your testcase contains another fragility, the order of two global vars. That is, in fact, the crux of the problem - the two linker symbols are unrelated, so by the rules of C pointers they are incomparable as are all pointers derived from them.
Re: gcc 3.4.6 asm charset error
On Thu, Sep 22, 2016 at 05:35:22PM +1000, Paul Edwards wrote: > GCC 3.4.6 natively handles different character > sets for source and target. It actually works > fine, writing source code in ASCII targeting > an EBCDIC destination. > > However, __asm() doesn't seem to be working. > As seen below, it is generating EBCDIC data > in the ASCII assembler output. Those funny > characters are in fact the EBCDIC code for > "ABC" and "DEF". > > Anyone know how to fix this? Does it work better with a GCC version that is less than ten years old? Segher
gcc-6-20160922 is now available
Snapshot gcc-6-20160922 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/6-20160922/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 6 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-6-branch revision 240383 You'll find: gcc-6-20160922.tar.bz2 Complete GCC MD5=c0cb1ea933dc6de83a2a026f6478c89e SHA1=b112e29bb8ad178c14d39ead01f61b14e81fde51 Diffs from 6-20160915 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-6 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
Re: gcc 3.4.6 asm charset error
GCC 3.4.6 is the last version of GCC that supports the i370 target that I use. Last time I tried adding the i370 target from GCC 3.4.6 to GCC 4.x I got errors that I don't know how to fix. Actually GCC 3.4.6 also has errors which I don't know how to fix, so I normally use GCC 3.2.3. I hope one day someone with the required technical skills will volunteer to fix the remaining problems with GCC on MVS, and i370 will be a target once again in the latest GCC, but no-one has volunteered to clean it up for more than a decade. BFN. Paul. -Original Message- From: Segher Boessenkool Sent: Friday, September 23, 2016 6:21 AM To: Paul Edwards Cc: gcc@gcc.gnu.org Subject: Re: gcc 3.4.6 asm charset error On Thu, Sep 22, 2016 at 05:35:22PM +1000, Paul Edwards wrote: GCC 3.4.6 natively handles different character sets for source and target. It actually works fine, writing source code in ASCII targeting an EBCDIC destination. However, __asm() doesn't seem to be working. As seen below, it is generating EBCDIC data in the ASCII assembler output. Those funny characters are in fact the EBCDIC code for "ABC" and "DEF". Anyone know how to fix this? Does it work better with a GCC version that is less than ten years old? Segher