[llvm] [llvm-objcopy] Fix file offsets when PT_INTERP/PT_LOAD offsets are equal (PR #80562)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 11:15:50 PST 2024


================
@@ -1234,6 +1234,13 @@ static bool compareSegmentsByOffset(const Segment *A, const Segment *B) {
     return true;
   if (A->OriginalOffset > B->OriginalOffset)
     return false;
+  // If one is PT_LOAD and the other isn't (e.g. PT_INTERP, PT_GNU_RELRO,
+  // PT_TLS), order the PT_LOAD first to ensure ParentSegment relationship will
+  // be correct.
+  bool AIsLOAD = A->Type == PT_LOAD;
+  bool BIsLOAD = B->Type == PT_LOAD;
+  if (AIsLOAD != BIsLOAD)
----------------
MaskRay wrote:

A program is broken if it has two `PT_LOAD` at the same offset. Most dynamic loaders will translate `PT_LOAD` to mmap commands. The map from a later `PT_LOAD` will overwrite the map from a previous one. I feel that testing this would be nice, but the value is quite low, since it is very difficult to create two `PT_LOAD` at the same offset even with a linker script... And the coverage is less relevant to this patch.

Just comparing `p_align` doesn't work when PT_TLS/PT_GNU_RELRO has an alignment of maxpagesize, as my description says:

> The same issue occurs for PT_TLS/PT_GNU_RELRO if we PT_TLS's alignment is smaller and we place the PT_LOAD after PT_TLS/PT_GNU_RELRO segments (not linker default, but possible with a PHDRS linker script command).

https://github.com/llvm/llvm-project/pull/80562


More information about the llvm-commits mailing list