diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -31,6 +31,7 @@ ENUM_CODEGENOPT(CompressDebugSections, llvm::DebugCompressionType, 2, llvm::DebugCompressionType::None) CODEGENOPT(RelaxELFRelocations, 1, 0) ///< -Wa,--mrelax-relocations +CODEGENOPT(KeepSectionSymbols, 1, 0) ///< -Wa,-generate-unused-section-symbols=yes CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. CODEGENOPT(Dwarf64 , 1, 0) ///< -gdwarf64. CODEGENOPT(Dwarf32 , 1, 1) ///< -gdwarf32. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6184,6 +6184,10 @@ def defsym : Separate<["-"], "defsym">, HelpText<"Define a value for a symbol">; +def keep_section_symbols : Separate<["-"], "keep-section-symbols">, + HelpText<"(integrated-as) Retain section symbols">, + MarshallingInfoFlag>; + } // let Flags = [CC1AsOption] //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2688,6 +2688,10 @@ CmdArgs.push_back(Value.data()); } else if (Value == "--version") { D.PrintVersion(C, llvm::outs()); + } else if (Value.consume_front("-generate-unused-section-symbols=") && + (Value == "yes" || Value == "no")) { + if (Value == "yes") + CmdArgs.push_back("-keep-section-symbols"); } else { D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; diff --git a/clang/test/Driver/as-options.s b/clang/test/Driver/as-options.s --- a/clang/test/Driver/as-options.s +++ b/clang/test/Driver/as-options.s @@ -116,3 +116,12 @@ // RUN: %clang -mrelax-all -fno-integrated-as -x c++ %s -S -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=WARN --allow-empty %s // WARN: unused + +// RUN: %clang -Wa,-generate-unused-section-symbols=yes %s -c -o /dev/null -v 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-KEEP +// RUN: %clang -Wa,-generate-unused-section-symbols=no %s -c -o /dev/null -v 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-DROP +// RUN: %clang %s -c -o /dev/null -v 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-DROP +// CHECK-KEEP: -keep-section-symbols +// CHECK-DROP-NOT: -keep-section-symbols diff --git a/clang/test/Misc/cc1as-keep-section-symbols.s b/clang/test/Misc/cc1as-keep-section-symbols.s new file mode 100644 --- /dev/null +++ b/clang/test/Misc/cc1as-keep-section-symbols.s @@ -0,0 +1,12 @@ +// REQUIRES: x86-registered-target + +// RUN: %clang -cc1as -triple x86_64-pc-linux-gnu -filetype obj -keep-section-symbols %s -o %t +// RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-KEEP + +// RUN: %clang -cc1as -triple x86_64-pc-linux-gnu -filetype obj %s -o %t +// RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-DROP + +// CHECK-KEEP: SECTION LOCAL DEFAULT {{[0-9]+}} .text +// CHECK-DROP-NOT: SECTION LOCAL DEFAULT {{[0-9]+}} .text +.text + nop diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -136,6 +136,7 @@ unsigned NoWarn : 1; unsigned IncrementalLinkerCompatible : 1; unsigned EmbedBitcode : 1; + unsigned KeepSectionSymbols : 1; /// The name of the relocation model to use. std::string RelocationModel; @@ -300,6 +301,7 @@ Opts.IncrementalLinkerCompatible = Args.hasArg(OPT_mincremental_linker_compatible); Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym); + Opts.KeepSectionSymbols = Args.hasArg(OPT_keep_section_symbols); // EmbedBitcode Option. If -fembed-bitcode is enabled, set the flag. // EmbedBitcode behaves the same for all embed options for assembly files. @@ -370,6 +372,7 @@ MAI->setCompressDebugSections(Opts.CompressDebugSections); MAI->setRelaxELFRelocations(Opts.RelaxELFRelocations); + MAI->setKeepSectionSymbols(Opts.KeepSectionSymbols); bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj; if (Opts.OutputPath.empty()) diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -518,6 +518,9 @@ // X86_64 ELF. bool RelaxELFRelocations = true; + // If true, emit ELF STT_SECTION symbols. + bool KeepSectionSymbols = false; + // If true, then the lexer and expression parser will support %neg(), // %hi(), and similar unary operators. bool HasMipsExpressions = false; @@ -853,6 +856,8 @@ bool canRelaxRelocations() const { return RelaxELFRelocations; } void setRelaxELFRelocations(bool V) { RelaxELFRelocations = V; } + bool getKeepSectionSymbols() const { return KeepSectionSymbols; } + void setKeepSectionSymbols(bool V) { KeepSectionSymbols = V; } bool hasMipsExpressions() const { return HasMipsExpressions; } bool needsFunctionDescriptors() const { return NeedsFunctionDescriptors; } bool shouldUseMotorolaIntegers() const { return UseMotorolaIntegers; } diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -610,7 +610,10 @@ return false; if (Symbol.getType() == ELF::STT_SECTION) - return false; + return Layout.getAssembler() + .getContext() + .getAsmInfo() + ->getKeepSectionSymbols(); return true; } diff --git a/llvm/test/MC/X86/keep-section-symbols.s b/llvm/test/MC/X86/keep-section-symbols.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/X86/keep-section-symbols.s @@ -0,0 +1,10 @@ +# RUN: llvm-mc -keep-section-symbols %s -triple x86_64-linux-gnu -filetype=obj -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-KEEP + +# RUN: llvm-mc %s -triple x86_64-linux-gnu -filetype=obj -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-DROP + +# CHECK-KEEP: SECTION LOCAL DEFAULT {{[0-9]+}} .text +# CHECK-DROP-NOT: SECTION LOCAL DEFAULT {{[0-9]+}} .text +.text + nop diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -212,6 +212,10 @@ static cl::opt NoExecStack("no-exec-stack", cl::desc("File doesn't need an exec stack"), cl::cat(MCCategory)); +static cl::opt + KeepSectionSymbols("keep-section-symbols", + cl::desc("Do not discard section symbols"), + cl::cat(MCCategory)); enum ActionType { AC_AsLex, @@ -401,6 +405,7 @@ assert(MAI && "Unable to create target asm info!"); MAI->setRelaxELFRelocations(RelaxELFRel); + MAI->setKeepSectionSymbols(KeepSectionSymbols); if (CompressDebugSections != DebugCompressionType::None) { if (!zlib::isAvailable()) {