[PATCH] D67761: [ELF] Error if the linked-to section of a SHF_LINK_ORDER section is discarded

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 19 05:54:15 PDT 2019


MaskRay created this revision.
MaskRay added reviewers: grimar, manojgupta, peter.smith, ruiu, espindola.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a project: LLVM.

If st_link(A)=B, and A has the SHF_LINK_ORDER flag, we may dereference
a null pointer if B is garbage collected:

1. In Wrter.cpp:compareByFilePosition, the parent of la or lb
2. In OutputSections::finalize,  the parent of `first->getLinkOrderDep`

Simply reject such cases (PR43147). The error is similar to what ld.bfd does

  sh_link of section `.bar' points to discarded section `.foo0' of `a.o'

ld.bfd is more permissive in that it just checks whether the linked-to
section of the first input section is discarded. This is likely because
it sets sh_link of the output section according to the first input
section.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D67761

Files:
  ELF/Writer.cpp
  test/ELF/gc-sections-metadata-err.s


Index: test/ELF/gc-sections-metadata-err.s
===================================================================
--- /dev/null
+++ test/ELF/gc-sections-metadata-err.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+
+## Error if the linked-to section of an input section is discarded.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: not ld.lld --gc-sections --print-gc-sections %t.o -o %t 2>&1 | FileCheck %s
+
+# CHECK:      removing unused section {{.*}}:(.foo0)
+# CHECK-NEXT: error: {{.*}}.o:(.bar): sh_link points to discarded section {{.*}}.o:(.foo0)
+# CHECK-NEXT: error: {{.*}}.o:(.baz): sh_link points to discarded section {{.*}}.o:(.foo0)
+
+.globl _start
+_start:
+  call .foo1
+  call bar0
+  call bar1
+  call baz0
+  call baz1
+
+.section .foo0,"a"
+.section .foo1,"a"
+
+## The linked-to section of the first input section is discarded.
+.section .bar,"ao", at progbits,.foo0,unique,0
+bar0:
+.byte 0
+.section .bar,"ao", at progbits,.foo1,unique,1
+bar1:
+.byte 1
+
+## Test another case: the linked-to section of the second input section is discarded.
+.section .baz,"ao", at progbits,.foo1,unique,0
+baz0:
+.byte 0
+.section .baz,"ao", at progbits,.foo0,unique,1
+baz1:
+.byte 1
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1519,6 +1519,15 @@
         sec->type == SHT_ARM_EXIDX)
       continue;
 
+    for (InputSection *s: sections) {
+      InputSection *link = s->getLinkOrderDep();
+      if (!link->getParent())
+        error(toString(s) + ": sh_link points to discarded section " +
+              toString(link));
+    }
+    if (errorCount())
+      continue;
+
     llvm::stable_sort(sections, compareByFilePosition);
 
     for (int i = 0, n = sections.size(); i < n; ++i)
@@ -1894,6 +1903,8 @@
   // SHFLinkOrder processing must be processed after relative section placements are
   // known but before addresses are allocated.
   resolveShfLinkOrder();
+  if (errorCount())
+    return;
 
   // This is used to:
   // 1) Create "thunks":


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67761.220846.patch
Type: text/x-patch
Size: 2048 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190919/739b621b/attachment.bin>


More information about the llvm-commits mailing list