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

Reply via email to