[ld] Allow custom sections to be under PT_GNU_RELRO

Fangrui Song i@maskray.me
Tue Apr 7 02:51:19 GMT 2020


On 2020-04-06, Cary Coutant wrote:
>> > https://lists.llvm.org/pipermail/llvm-dev/2020-March/140395.html
>> >
>> > I understand the reason of having these conventions in linkers. On the
>> > other hand, there already exists a format with the fixed ".rel.ro"
>> > suffix for .data and .bss. Custom suffixes would also mean that the user
>> > code would depend more on implementation-specific things, i.e. prefixes.
>> > For example, one would wonder, should they annotate their data with
>> > __attribute__((section(...))) for ".data.rel.ro.my_section" or
>> > ".bss.rel.ro.my_section"?
>> >
>> > What do you think of the magic ".rel.ro" idea?
>>
>> We could sacrifice a section flag for this.  The feature may be
>> sufficiently important for that.
>
>My first reaction was: Do you *really* need to use a new custom
>section name? But after reading through the thread on the LLVM list, I
>see why -- you want the RTTI-like sections to be contiguous within the
>RELRO segment.
>
>The gold sources have this comment:
>
>  // With -z relro, we have to recognize the special sections by name.
>  // There is no other way.
>
>String matching on the section name is ugly and a performance hit
>whether it's a fixed section name (as it is now), a prefix, or a
>suffix. Yes, it should have been done with a flag from the beginning.
>
>Theoretically, we might not even have needed a new flag. If the
>compiler would mark RELRO sections as read-only, the linker could look
>for read-only, non-executable sections with dynamic relocations, and
>mark them as RELRO, or simply turn on SHF_WRITE for -z norelro. But
>that would break under older linkers, so it was much better from a
>compatibility standpoint to mark RELRO sections as writable, meaning
>there has to be some other way of recognizing that they're really
>read-only but for the relocations. It may also have made things
>difficult for the linker, requiring a scan over the relocations before
>deciding where to place the section (I haven't looked carefully to see
>if that would be a problem in gold).
>
>Starting from where we are now, I'd say we need an SHF_RELRO flag, and
>compilers should start setting that flag on .data.rel.ro and
>.data.rel.ro.local sections. Linkers should treat all .data.rel.ro and
>.data.rel.ro.local sections as if the flag were set, regardless. Maybe
>in 10-20 years, we can finally take those strcmp's out.
>
>Any sections marked SHF_RELRO should also be marked SHF_WRITE, for
>compatibility with older linkers and to make it simpler to ignore the
>flag in the -z norelro case. I'd probably also want to require that
>they NOT be SHF_EXECINSTR.

Your SHF_RELRO scheme (implies SHF_WRITE; can't be used together with
SHF_EXECINSTR) looks fine with me.

I suppose we will assign 0x1000 to SHF_RELRO. It looks like GNU ld, gold
and LLD all happily accept the unknown flag 0x1000 (.text .tdata .tbss
...). GNU ld and gold will not keep 0x1000 from the output section
flags, though.  Hope Solaris/HP-UX toolchain experts can answer the
question about their linkers.

Should SHF_TLS imply SHF_RELRO?

>That probably also means that we should graduate PT_GNU_RELRO to the
>gABI level, as PT_RELRO. Or, alternatively, DT_RELRO and DT_RELROSZ
>entries in the dynamic table. (I kind of prefer the dynamic table over
>the program header table for things like this, since it's the dynamic
>linker, not the kernel loader, that needs to know about it.)
>
>-cary

I can foresee people's objection to depriving one value 0x6474e552 from
the PT_LOOS~PT_HIOS range. (See a recent discussion
https://groups.google.com/forum/#!msg/x86-64-abi/7sr4E6THl3g/zUU2UPHOAQAJ "RFC: Usefulness of SHT_X86_64_UNWIND")


Your argument made me convinced that DT_RELRO/DT_RELROSZ is better than
PT_RELRO.  Though I also foresee people's objection that this will make
the design not readily usable. Perhaps we should bite the bullet. The
parties which are mostly interested in this feature may have a good
control of their ld.so.

So, for linker/loader implementations, when a SHF_RELRO is seen,
DT_RELRO/DT_RELROSZ should be used and PT_GNU_RELRO should disappear.

If we can reach progress on the proposal, I will be happy to implement
the feature on LLD/clang integrated assembler/llvm-readobj/llvm-objdump side.


More information about the Binutils mailing list