On 8/8/26 22:35, grischka wrote:
On 8/8/26 19:31, Herman ten Brugge via Tinycc-devel wrote:
After commit "tccelf: unify SHT_NOTE sections" openbsd and freebsd
do not work anymore.
I debugged the problem and found that if I disable the GNU_RELRO
section the problem disappears.
Hi, thanks for checking.
Seems there is two things, a mistake and an intentional change.
1) The mistake is that according to an earlier change from you
/* NetBSD only supports 2 PT_LOAD sections. ...
and according to the previous #ifdef'ing doesn't support GNU_RELRO
either.
To keep this, the "k = 0;" there needs to be unconditional. Like
if ((f & SHF_WRITE) == 0)
f |= SHF_EXECINSTR;
k = 0; /* no RELRO */
The result is:
TCC: Section to Segment mapping:
Segment Sections...
00
01 .interp
02 rx .interp .note.gnu.property .note.ABI-tag .dynsym .dynstr
.hash .gnu.hash .gnu.version .gnu.version_r .rela.got .rela.plt
.eh_frame .rodata.cst4 .eh_frame_hdr .data.ro .init .fini .plt .text
03 rw .dynamic .got .data .bss
04 .dynamic
05 .note.gnu.property .note.ABI-tag
06 .eh_frame_hdr
2) the intentional change was about the observation that at least
on the linux x86_64 here, the GNU_RELRO segment not necessarily
has its own LOAD segment, but like NOTE, TLS, or DYNAMIC too
would specify just a sub-range of some LOAD segment.
GCC, x86_64-linux: Section to Segment mapping:
Segment Sections...
00
01 .interp
02 ro .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag
.gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 rx .init .plt .plt.got .plt.sec .text .fini
04 ro .rodata .eh_frame_hdr .eh_frame
05 rw .init_array .fini_array .dynamic .got .data .bss
06 .dynamic
07 .note.gnu.property
08 .note.gnu.build-id .note.ABI-tag
09 .note.gnu.property
10 .eh_frame_hdr
11 (gnu_stack)
12 .init_array .fini_array .dynamic .got
Here RELRO(12) is sub-range of LOAD(05) which also includes .data .bss
Now question is what to do for OpenBSD. THe simple change is to
make it behave like Free/NetBSD, i.e. only 2 LOAD, no RELRO.
If we do want RELRO for OpenBSD but with a separate LOAD, then this
could work:
if (k < 0x700) {
int f1;
f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR);
#if TARGETOS_NetBSD || TARGETOS_FreeBSD
/* NetBSD only supports 2 PT_LOAD sections.
See:
https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
if ((f & SHF_WRITE) == 0)
f |= SHF_EXECINSTR;
k = 0; /* no RELRO */
#endif
f1 = f;
if ((k & 0xfff0) == 0x240) /* RELRO sections */
d->relro = 1, f |= SHFX_RELRO;
#if TARGETOS_OpenBSD
f1 = f; /* have separate LOAD segment for RELRO */
#endif
if ((s->sh_flags & SHF_TLS) && s->sh_size)
d->tls = 1, f |= SHF_TLS;
/* start new header when flags changed, but avoid zero
memsz */
if (f1 != f0 && s->sh_size)
f0 = f1, ++n, f |= SHFX_NEWPH;
}
The result of this (for TARGETOS_OpenBSD) is:
TCC: Section to Segment mapping:
Segment Sections...
00
01 .interp
02 ro .interp .note.gnu.property .note.ABI-tag .dynsym .dynstr
.hash .gnu.hash .gnu.version .gnu.version_r .rela.got .rela.plt
.eh_frame .rodata.cst4 .eh_frame_hdr .data.ro
03 rx .init .fini .plt .text
04 ro .dynamic .got
05 rw .data .bss
06 .dynamic
07 .note.gnu.property .note.ABI-tag
08 .eh_frame_hdr
09 .dynamic .got
with RELRO(09) associated to its own LOAD(04)
I tested above change on OpenBSD, NetBSD and FreeBSD.
They all work now correctly.
(There is still a problem on OpenBSD with TLS. I will do that in a
separate mail.)
Thanks for the quick fix.
Herman
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel