In math code we often have to make sure the compiler does not fold operations at compile time. In glibc we use variable declared as
static const volatile double foo = 42.0;
The problem is that gcc moves such variables into .data. But we could achieve that easily by leaving out the 'const'. What is needed is a method to achieve volatile behavior while having the variable in .rodata (and .rodata.cst8 etc).
I therefore would like to ask for a change in the compiler which preserves the 'const' in the presence of 'volatile' and place the variable in read-only memory.
Subject: Re: New: change semantics of const volatile variables
"drepper at redhat dot com" <firstname.lastname@example.org> writes:
| In math code we often have to make sure the compiler does not fold operations
| at compile time. In glibc we use variable declared as
| static const volatile double foo = 42.0;
| The problem is that gcc moves such variables into .data. But we could achieve
| that easily by leaving out the 'const'. What is needed is a method to achieve
| volatile behavior while having the variable in .rodata (and .rodata.cst8 etc).
| I therefore would like to ask for a change in the compiler which preserves the
| 'const' in the presence of 'volatile' and place the variable in read-only
that is tricky because of the general interpretation:
[#10] EXAMPLE 1 An object declared
extern const volatile int real_time_clock;
may be modifiable by hardware, but cannot be assigned to,
incremented, or decremented.
If it may be modified by hardware or other external means, it can't go
into .rodata section.
Using gcc's section attributes won't fully work either.
Using __attribute((section(".rodata"))) is OK in the compiler, although the assembler (correctly) complaints. But what is really needed is
__attribute((section(".rodata.cst8"))). This will cause gcc to fail with an ICE.
Subject: Re: change semantics of const volatile variables
"drepper at redhat dot com" <email@example.com> writes:
| __attribute((section(".rodata.cst8"))). This will cause gcc to fail with an
That is compiler bug. That is useful piece of data. I believe the PR
should be retitled and reclassified based on that.
*** Bug 51085 has been marked as a duplicate of this bug. ***
So I am being bitten by this in the BPF backend .
Long story short: LLVM places initialized `volatile const' variables in .rodata, whereas GCC puts them in .data.
The kernel's libbpf scans the objects and generates a "skeleton" header that, among other things, reflects the sections in the compiled BPF object. This divergence in behavior between LLVM and GCC makes the skeleton to define different data structures, i.e. obj->rodata->foo vs. obj->data->foo. See  for details.
I don't actually understand Gabriel's comment, "If it may be modified by hardware or other external means, it can't go into .rodata section.". Why not? The permissions of the .rodata section eventually determines the permissions used to map the corresponding pages in the particular process running the program, but I don't see how can prevent the same physical memory to be updated by hardware, or even other processes mapping the same physical page using write perms.
Or what am I missing? Can we change the behavior of GCC to put such variables in .rodata?
If, as a workaround, I try to use a `section' attribute, like in:
__attribute__((section(".rodata"))) volatile const int lala = 0;
I don't get an ICE, but a section with write permissions:
And the assembler then complains:
foo-gcc.s:4: Warning: setting incorrect section attributes for .rodata
After a little discussion in IRC I filed this LLVM bug:
Regarding the ICE described by Ulrich, I cannot reproduce it using:
bpf-unknown-none-gcc (GCC) 13.0.0 20220708 (experimental)
Maybe it is time to close this bug?
So I got feedback from the clang/llvm folks on this.
As you can see in  they asked the WG14 reflectors about the footnote 135 in the C18 spec and their conclusion is that there is no normative objection to place `const volatile' variables in read-only sections, much like non-volatile consts.
This matches my earlier impression (before I got pointed to that footnote) and since there is at least one target being impacted by this GCC/LLVM discrepancy (bpf-unknown-none) I intend to prepare a patch to change the place where GCC places the `const volatiles'.
The master branch has been updated by Jose E. Marchesi <firstname.lastname@example.org>:
Author: Jose E. Marchesi <email@example.com>
Date: Thu Aug 4 21:16:10 2022 +0200
place `const volatile' objects in read-only sections
It is common for C BPF programs to use variables that are implicitly
set by the BPF loader and run-time. It is also necessary for these
variables to be stored in read-only storage so the BPF verifier
recognizes them as such. This leads to declarations using both
`const' and `volatile' qualifiers, like this:
const volatile unsigned char is_allow_list = 0;
Where `volatile' is used to avoid the compiler to optimize out the
variable, or turn it into a constant, and `const' to make sure it is
placed in .rodata.
Now, it happens that:
- GCC places `const volatile' objects in the .data section, under the
assumption that `volatile' somehow voids the `const'.
- LLVM places `const volatile' objects in .rodata, under the
assumption that `volatile' is orthogonal to `const'.
So there is a divergence, that has practical consequences: it makes
BPF programs compiled with GCC to not work properly.
When looking into this, I found this bugzilla:
"change semantics of const volatile variables"
which was filed back in 2005, long ago. This report was already
asking to put `const volatile' objects in .rodata, questioning the
While discussing this in the #gcc IRC channel I was pointed out to the
following excerpt from the C18 spec:
6.7.3 Type qualifiers / 5 The properties associated with qualified
types are meaningful only for expressions that are
lval-values [note 135]
135) The implementation may place a const object that is not
volatile in a read-only region of storage. Moreover, the
implementation need not allocate storage for such an object if
its $ address is never used.
This footnote may be interpreted as if const objects that are volatile
shouldn't be put in read-only storage. Even if I personally was not
very convinced of that interpretation (see my earlier comment in BZ
25521) I filed the following issue in the LLVM tracker in order to
discuss the matter:
As you can see, Aaron Ballman, one of the LLVM hackers, asked the WG14
reflectors about this. He reported that the reflectors don't think
footnote 135 has any normative value.
So, not having a normative mandate on either direction, there are two
a) To change GCC to place `const volatile' objects in .rodata instead
b) To change LLVM to place `const volatile' objects in .data instead
- One target (bpf-unknown-none) breaks with the current GCC behavior.
- No target/platform relies on the GCC behavior, that we know.
- Changing the LLVM behavior at this point would be very severely
traumatic for the BPF people and their users.
I think the right thing to do at this point is a).
Therefore this patch.
Regtested in x86_64-linux-gnu and bpf-unknown-none.
No regressions observed.
* varasm.cc (categorize_decl_for_section): Place `const volatile'
objects in read-only sections.
* lib/target-supports.exp (check_effective_target_elf): Define.
* gcc.dg/pr25521.c: New test.