diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -276,6 +276,7 @@ bool unique; bool useAndroidRelrTags = false; bool warnBackrefs; + bool warnSectionTypeMismatch; llvm::SmallVector warnBackrefsExclude; bool warnCommon; bool warnMissingEntry; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1311,6 +1311,8 @@ OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false); config->warnBackrefs = args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false); + config->warnSectionTypeMismatch = args.hasFlag( + OPT_warn_section_type_mismatch, OPT_no_warn_section_type_mismatch, true); config->warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false); config->warnSymbolOrdering = args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -502,6 +502,10 @@ def warn_unresolved_symbols: F<"warn-unresolved-symbols">, HelpText<"Report unresolved symbols as warnings">; +defm warn_section_type_mismatch: BB<"warn-section-type-mismatch", + "Warn about merging of sections with different types (default)", + "Do not warn about merging of sections with different types">; + defm whole_archive: B<"whole-archive", "Force load of all members in a static library", "Do not force load of all members in a static library (default)">; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -114,8 +114,9 @@ void OutputSection::commitSection(InputSection *isec) { if (LLVM_UNLIKELY(type != isec->type)) { if (hasInputSections || typeIsSet) { - if (typeIsSet || !canMergeToProgbits(type) || - !canMergeToProgbits(isec->type)) { + if ((typeIsSet || !canMergeToProgbits(type) || + !canMergeToProgbits(isec->type)) && + config->warnSectionTypeMismatch) { // 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 diff --git a/lld/test/ELF/linkerscript/noload.s b/lld/test/ELF/linkerscript/noload.s --- a/lld/test/ELF/linkerscript/noload.s +++ b/lld/test/ELF/linkerscript/noload.s @@ -21,8 +21,11 @@ ## 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 +# RUN: ld.lld --script %t/lds %t.o %t/mismatch.o -o %t/out --warn-section-type-mismatch 2>&1 | FileCheck %s --check-prefix=WARN +# RUN: ld.lld --script %t/lds %t.o %t/mismatch.o -o %t/out --no-warn-section-type-mismatch 2>&1 | FileCheck %s --check-prefix=NOWARN -# WARN: warning: section type mismatch for .data_noload_a +# WARN: warning: section type mismatch for .data_noload_a +# NOWARN-NOT: warning: section type mismatch for .data_noload_a # CHECK2: Name Type Address Off Size # CHECK2: .data_noload_a NOBITS 0000000000000000 [[OFF:[0-9a-f]+]] 001001