[lld] [LLD][ELF] Do not emit __start/__stop for empty sections (PR #96213)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 16:58:28 PDT 2024


MaskRay wrote:

Summarizing the issue.
```
finalizeSections
  addStartStopSymbols     // __start_empty is defined
  // __start_empty is added to .symtab
  sortSections
    adjustOutputSections  // `empty` is discarded
  // __start_empty is Defined with an invalid section index
```

`if (script->isDiscarded(&osec))` to `addStartStopSymbols` is fine,
but `if (sym->isLocal() && sym->isUndefined())` to .symtab makes me nervous because .symtab performance matters.

Default and protected visibility encapsulation symbols would still be left undefined (
e.g. `.protected __start_empty,__stop_empty`), differing from the hidden visibility.

I think we should do the following:

```
--- i/lld/ELF/Writer.cpp
+++ w/lld/ELF/Writer.cpp
@@ -2078,6 +2078,8 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection &osec) {
     return;
-  addOptionalRegular(saver().save("__start_" + s), &osec, 0,
-                     config->zStartStopVisibility);
-  addOptionalRegular(saver().save("__stop_" + s), &osec, -1,
+  bool defined = addOptionalRegular(saver().save("__start_" + s), &osec, 0,
                      config->zStartStopVisibility);
+  defined |= addOptionalRegular(saver().save("__stop_" + s), &osec, -1,
+                                config->zStartStopVisibility) != nullptr;
+  if (defined)
+    osec.usedInExpression = true;
 }
```

Behaviors of different visibilities are unified, even if the behavior differs from GNU ld.


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


More information about the llvm-commits mailing list