This is an archive of the discontinued LLVM Phabricator instance.

MC: make section classification a bit more thorough
ClosedPublic

Authored by compnerd on Aug 5 2022, 10:00 AM.

Details

Summary

This does *NOT* change the emitted section flags in any way. This only
impacts the internal classification of sections.

Extend the section classification in LLVM for ELF targets. This has one
important change: we now classify sections as text by default rather
than readonly. This matches the behaviour for GAS better.

Ensure that any section that has a writable attribute set is not treated
as readonly. We also special case any section named .debug_ which is
reserved for DWARF as metadata. In the case none of the attributes are
set (or because no attributes were provided), consult the section name
for classification. We match the well known names and classify the
section accordingly. Any remaining section is now classified as text.

This change allows us to classify sections in the MC layer more
precisely which is needed for subsequent changes for handling target
specific behaviour.

Diff Detail

Event Timeline

compnerd created this revision.Aug 5 2022, 10:00 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 5 2022, 10:00 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
compnerd requested review of this revision.Aug 5 2022, 10:00 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 5 2022, 10:00 AM
compnerd updated this revision to Diff 450318.Aug 5 2022, 10:18 AM
echristo accepted this revision.Aug 17 2022, 4:45 PM
echristo added a reviewer: MaskRay.

This works for me... adding Ray in case there's something I've missed or forgotten. I really thought this was handled before somewhere.

This revision is now accepted and ready to land.Aug 17 2022, 4:45 PM
This revision was landed with ongoing or failed builds.Aug 19 2022, 9:47 AM
This revision was automatically updated to reflect the committed changes.

This patch breaks building the Linux kernel for RISC-V. A simplified reproducer:

enum { true };
__attribute__((__section__(".init.data"))) char *message;
_Bool __attribute__((__section__(".init.data"))) initramfs_async = true;
$ clang --version | head -1
ClangBuiltLinux clang version 16.0.0 (https://github.com/llvm/llvm-project 73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6)

$ clang --target=riscv64-linux-gnu -c -o /dev/null initramfs.i
fatal error: error in backend: unable to write nop sequence of 7 bytes
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: clang --target=riscv64-linux-gnu -c -o /dev/null initramfs.i
1.      <eof> parser at end of file
2.      Code generation
 #0 0x000055b56adaacf3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3697cf3)
 #1 0x000055b56ada8d6e llvm::sys::RunSignalHandlers() (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3695d6e)
 #2 0x000055b56ad257af (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0
 #3 0x000055b56ad2573f llvm::CrashRecoveryContext::HandleExit(int) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x361273f)
 #4 0x000055b56ada5817 llvm::sys::Process::Exit(int, bool) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3692817)
 #5 0x000055b569a46662 (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x2333662)
 #6 0x000055b56ad2a619 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3617619)
 #7 0x000055b56aa1a5a4 llvm::MCAssembler::writeSectionData(llvm::raw_ostream&, llvm::MCSection const*, llvm::MCAsmLayout const&) const (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x33075a4)
 #8 0x000055b56aa04c58 (anonymous namespace)::ELFWriter::writeObject(llvm::MCAssembler&, llvm::MCAsmLayout const&) ELFObjectWriter.cpp:0:0
 #9 0x000055b56aa03755 (anonymous namespace)::ELFSingleObjectWriter::writeObject(llvm::MCAssembler&, llvm::MCAsmLayout const&) ELFObjectWriter.cpp:0:0
#10 0x000055b56aa1b4e6 llvm::MCAssembler::Finish() (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x33084e6)
#11 0x000055b56aa3adb8 llvm::MCELFStreamer::finishImpl() (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3327db8)
#12 0x000055b56bb93339 llvm::AsmPrinter::doFinalization(llvm::Module&) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x4480339)
#13 0x000055b56a690909 llvm::FPPassManager::doFinalization(llvm::Module&) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x2f7d909)
#14 0x000055b56a689f1c llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x2f76f1c)
#15 0x000055b56b5f0fbd clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3eddfbd)
#16 0x000055b56b9ecd1e clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) CodeGenAction.cpp:0:0
#17 0x000055b56c2f1a3a clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x4bdea3a)
#18 0x000055b56b92fc60 clang::FrontendAction::Execute() (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x421cc60)
#19 0x000055b56b8a1b9f clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x418eb9f)
#20 0x000055b56b9e6182 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x42d3182)
#21 0x000055b569a46138 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x2333138)
#22 0x000055b569a43e7f ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#23 0x000055b56b71e522 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_1>(long) Job.cpp:0:0
#24 0x000055b56ad2562c llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x361262c)
#25 0x000055b56b71e07f clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x400b07f)
#26 0x000055b56b6dd64f clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3fca64f)
#27 0x000055b56b6dd8fe clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3fca8fe)
#28 0x000055b56b6fa6a0 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x3fe76a0)
#29 0x000055b569a4354b clang_main(int, char**) (/home/nathan/tmp/tmp.BkODB37lsK/install/llvm/73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6/bin/clang-16+0x233054b)
#30 0x00007f078dabc2d0 (/usr/lib/libc.so.6+0x232d0)
#31 0x00007f078dabc38a __libc_start_main (/usr/lib/libc.so.6+0x2338a)
#32 0x000055b569a40aa5 _start /build/glibc/src/glibc/csu/../sysdeps/x86_64/start.S:117:0
clang-16: error: clang frontend command failed with exit code 70 (use -v to see invocation)
ClangBuiltLinux clang version 16.0.0 (https://github.com/llvm/llvm-project 73a9dfcee24df959b59a46d75dcbdc0bcfb50fe6)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: ...
clang-16: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

There is no issue at the direct parent.

$ clang --version | head -1
ClangBuiltLinux clang version 16.0.0 (https://github.com/llvm/llvm-project e41dd0205242af4f8e2a370d0346f24f0b0eb788)

$ clang --target=riscv64-linux-gnu -c -o /dev/null initramfs.i

This patch breaks building the Linux kernel for RISC-V. A simplified reproducer:

@compnerd is working on a fix for that, D132482. This should probably have been reverted earlier until the fix was ready but I guess it's nearly there now? Do revert if you think that's not the case.

@compnerd is working on a fix for that, D132482. This should probably have been reverted earlier until the fix was ready but I guess it's nearly there now? Do revert if you think that's not the case.

Right, I suspect D132482 will be merged within the next couple of days based on the feedback that has been given so far, so I think it is just better to forward fix rather than revert then fix. Our CI is already red from this change hitting apt.llvm.org packages so we can just wait for D132482 to be applied.

MatzeB added a subscriber: MatzeB.EditedAug 24 2022, 5:37 PM

Hey, I started hitting assertions when creating assembly and subsequently assembling things. In my case I am building the llvm-test-suite with -save-temps=obj but I can reproduce with something smaller/simpler:

struct C {
  C(int x) { a = x; }
  int a;
};
inline C& getNullInstance() {
  static C instance(42);
  return instance;
}
void* used = (void*)getNullInstance;
$ CLANG=~/local/llvm-builds/e41dd0205242/bin/clang
$ $CLANG -S repro.cpp && $CLANG -c repro.s
# no error

$ CLANG=~/local/llvm-builds/73a9dfcee24d/bin/clang
$ $CLANG -S repro.cpp && $CLANG -c repro.s
clang: /tmp/tmpssp98atc/llvm-project/llvm/lib/MC/MCAssembler.cpp:767: void llvm::MCAssembler::writeSectionData(llvm::raw_ostream &, const llvm::MCSection *, const llvm::MCAsmLayout &) const: Assertion `(cast<MCAlignFragment>(F).getValueSize() == 0 || cast<MCAlignFragment>(F).getValue() == 0) && "Invalid align in virtual section!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang -c repro.s
 #0 0x0000000001d15c23 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x1d15c23)
 #1 0x0000000001d13a5e llvm::sys::RunSignalHandlers() (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x1d13a5e)
 #2 0x0000000001d1502d llvm::sys::CleanupOnSignal(unsigned long) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x1d1502d)
 #3 0x0000000001c8a2de (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0
 #4 0x0000000001c8a530 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #5 0x00007f919418dce0 __restore_rt (/lib64/libpthread.so.0+0x12ce0)
 #6 0x00007f9192eb0a9f raise (/lib64/libc.so.6+0x4ea9f)
 #7 0x00007f9192e83e05 abort (/lib64/libc.so.6+0x21e05)
 #8 0x00007f9192e83cd9 _nl_load_domain.cold.0 (/lib64/libc.so.6+0x21cd9)
 #9 0x00007f9192ea93f6 (/lib64/libc.so.6+0x473f6)
#10 0x000000000195b462 llvm::MCAssembler::writeSectionData(llvm::raw_ostream&, llvm::MCSection const*, llvm::MCAsmLayout const&) const (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x195b462)
#11 0x00000000019e0c0a (anonymous namespace)::ELFWriter::writeObject(llvm::MCAssembler&, llvm::MCAsmLayout const&) ELFObjectWriter.cpp:0:0
#12 0x00000000019df1f5 (anonymous namespace)::ELFSingleObjectWriter::writeObject(llvm::MCAssembler&, llvm::MCAsmLayout const&) ELFObjectWriter.cpp:0:0
#13 0x000000000195c4a6 llvm::MCAssembler::Finish() (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x195c4a6)
#14 0x000000000197ba46 llvm::MCELFStreamer::finishImpl() (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x197ba46)
#15 0x00000000019e86d1 (anonymous namespace)::AsmParser::Run(bool, bool) AsmParser.cpp:0:0
#16 0x00000000009e2244 cc1as_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x9e2244)
#17 0x00000000009dc4c6 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#18 0x0000000002586082 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_1>(long) Job.cpp:0:0
#19 0x0000000001c8a159 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x1c8a159)
#20 0x0000000002585ad0 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x2585ad0)
#21 0x00000000025457e8 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x25457e8)
#22 0x0000000002545aee clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x2545aee)
#23 0x00000000025656d0 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x25656d0)
#24 0x00000000009db8d1 clang_main(int, char**) (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x9db8d1)
#25 0x00007f9192e9ccf3 __libc_start_main (/lib64/libc.so.6+0x3acf3)
#26 0x00000000009d8cfe _start (/home/matthiasb/local/llvm-builds/73a9dfcee24d/bin/clang+0x9d8cfe)

Looking at the assembly files with this diff we start emitting .p2align 2, 0x90 instead of just .p2align 2 for some weak-symbol things. This subsequently triggers the compiler assertion.

Once I generated the "bad" assembly it hits an assert even in clang/llvm versions before this change...

Let's go ahead and revert in the meantime, can totally reapply later.

MaskRay added inline comments.Aug 24 2022, 10:26 PM
llvm/lib/MC/MCContext.cpp
578

.data1 is similar to .data . It does not have the SHF_STRINGS flag.

MaskRay added inline comments.Aug 24 2022, 10:27 PM
llvm/lib/MC/MCContext.cpp
571

Better to fix the distinction for .tdata (SHT_PROGBITS) and .tbss (SHT_NOBITS)

compnerd marked 2 inline comments as done.Aug 30 2022, 2:45 PM

Slightly better reduction:

struct C { int i_; };
inline C& __attribute__((__used__)) getRef() {
  static C instance{0};
  return instance;
}

It seems that we have some special case handling for other names in the ELF TLOF. We need to handle those cases as well most likely.