[ELF] Change (NOLOAD) section type mismatch error to warning
authorFangrui Song <i@maskray.me>
Fri, 18 Feb 2022 19:20:36 +0000 (11:20 -0800)
committerFangrui Song <i@maskray.me>
Fri, 18 Feb 2022 19:20:36 +0000 (11:20 -0800)
Making a (NOLOAD) section SHT_PROGBITS is fishy (the user may expect all-zero
content, but the linker does not check that), but some projects (e.g. Linux
kernel https://github.com/ClangBuiltLinux/linux/issues/1597) traditionally rely
on the behavior. Issue a warning to not break them.

lld/ELF/OutputSections.cpp
lld/test/ELF/linkerscript/noload.s

index 2b5deec..252108b 100644 (file)
@@ -112,11 +112,16 @@ void OutputSection::commitSection(InputSection *isec) {
     if (hasInputSections || typeIsSet) {
       if (typeIsSet || !canMergeToProgbits(type) ||
           !canMergeToProgbits(isec->type)) {
-        errorOrWarn("section type mismatch for " + isec->name + "\n>>> " +
-                    toString(isec) + ": " +
-                    getELFSectionTypeName(config->emachine, isec->type) +
-                    "\n>>> output section " + name + ": " +
-                    getELFSectionTypeName(config->emachine, type));
+        // Changing the type of a (NOLOAD) section is fishy, but some projects
+        // (e.g. https://github.com/ClangBuiltLinux/linux/issues/1597)
+        // traditionally rely on the behavior. Issue a warning to not break
+        // them. Other types get an error.
+        auto diagnose = type == SHT_NOBITS ? warn : errorOrWarn;
+        diagnose("section type mismatch for " + isec->name + "\n>>> " +
+                 toString(isec) + ": " +
+                 getELFSectionTypeName(config->emachine, isec->type) +
+                 "\n>>> output section " + name + ": " +
+                 getELFSectionTypeName(config->emachine, type));
       }
       type = SHT_PROGBITS;
     } else {
index 92afadc..1cc0967 100644 (file)
 # CHECK:      00 .data_noload_a .data_noload_b .no_input_sec_noload {{$}}
 # CHECK:      01 .text {{$}}
 
-# RUN: not ld.lld --script %t/lds %t.o %t/mismatch.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
-
-# ERR: error: section type mismatch for .data_noload_a
+## The output SHT_PROBITS is contrary to the user expectation of SHT_NOBITS.
+## Issue a warning. See https://github.com/ClangBuiltLinux/linux/issues/1597
+# RUN: ld.lld --script %t/lds %t.o %t/mismatch.o -o %t/out 2>&1 |& FileCheck %s --check-prefix=WARN
+# RUN: llvm-readelf -S -l %t/out | FileCheck %s --check-prefix=CHECK2
+
+# WARN:   warning: section type mismatch for .data_noload_a
+# CHECK2:      Name                 Type     Address          Off               Size
+# CHECK2:      .data_noload_a       PROGBITS 0000000000000000 [[OFF:[0-9a-f]+]] 001001
 
 #--- asm
 .section .text,"ax",@progbits