[PATCH] D111137: [ELF] Fix assigning segments to orphan sections

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 10 11:48:39 PDT 2021


MaskRay added a comment.

> Fix assigning segments to orphan sections

I'd not use "Fix". It makes a case more user-friendly but does not necessarily mean we have a bug.
I may use something like: Propagate `phdrs` to orphan section with a smaller rank.

I have a mixed feeling on this patch. It does make it a bit more user-friendly for the added case by not making the non-PF_W segment PF_W, but:

- the logic is inconsistent when the `PHDRS` command is not used.
- it makes the `maybePropagatePhdrs` phdrs propagation logic duplicate in a different place

In addition, the original rationale is not sufficient justifying.
>From https://maskray.me/blog/2021-07-04-sections-and-overwrite-sections, when linking a regular program, if one really wants to use a linker script, the linker script should at least specify the first output section of each segment, specifically including the first output section of PT_GNU_RELRO. A minimal example:

  text
  SECTIONS
  {
    PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  
    . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
    .init_array    :
    {
      PROVIDE_HIDDEN (__init_array_start = .);
      KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
      KEEP (*(.init_array))
      PROVIDE_HIDDEN (__init_array_end = .);
    }
    .fini_array    :
    {
      PROVIDE_HIDDEN (__fini_array_start = .);
      KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
      KEEP (*(.fini_array))
      PROVIDE_HIDDEN (__fini_array_end = .);
    }
    . = DATA_SEGMENT_RELRO_END (0, .);
    .data           : { *(.data .data.*) }
    . = .;
    .bss            : { *(.bss .bss.*) *(COMMON) }
    . = DATA_SEGMENT_END (.);
  }

I haven't formed my opinion completely, and want to hear from Peter, but do have some concern on this direction.



================
Comment at: lld/ELF/Writer.cpp:1263
+  // the orphan section may be placed in the previous segment, which may
+  // corrupt its flags.
+  auto foundSec = dyn_cast<OutputSection>(*i);
----------------
"corrupt" is inaccurate. A non-PF_W segment may now become PF_W, but it is not corrupted.


================
Comment at: lld/ELF/Writer.cpp:1265
+  auto foundSec = dyn_cast<OutputSection>(*i);
+  if (script->hasPhdrsCommands() && foundSec && foundSec->hasInputSections &&
+      sec->sortRank < foundSec->sortRank)
----------------
`&& foundSec->hasInputSections` can be deleted


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111137/new/

https://reviews.llvm.org/D111137



More information about the llvm-commits mailing list