revng / revng

revng: the core repository of the rev.ng project
https://rev.ng/
GNU General Public License v2.0
1.28k stars 99 forks source link

Crash when DWARF reports function at address `NULL` #326

Closed PwnVerse closed 11 months ago

PwnVerse commented 11 months ago

Attaching the ARM ELF used for testing here


/home/ritvik/Desktop/Files/orchestra/root/bin/revng \
  pipeline \
  --analyze=Import/ImportBinary/input/:Binary \
  --analyze=Import/AddPrimitiveTypes/ \
  --analyze=Lift/DetectABI/module.ll/:Root \
  --produce=Recompile/output/:Translated \
  -i \
  hid_composite_freertos.elf:begin/input \
  -o \
  hid_composite_freertos.elf.translated:Recompile/output \
  --compile-opt-level=0

root/libexec/revng/revng-pipeline \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngFunctionIsolation.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngRecompile.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModelImporterBinary.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModelImporter.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngYieldPipes.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModel.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngTypeShrinking.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngABI.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngBasicAnalyses.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngABIAnalyses.so \
  -load \
  /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngEarlyFunctionAnalysis.so \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/translate.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/hex-dump.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/enforce-abi.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/analyses-lists.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-cfg.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/isolate-translate.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-assembly.yml \
  -P \
  /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-call-graph.yml \
  --analyze=Import/ImportBinary/input/:Binary \
  --analyze=Import/AddPrimitiveTypes/ \
  --analyze=Lift/DetectABI/module.ll/:Root \
  --produce=Recompile/output/:Translated \
  -i \
  hid_composite_freertos.elf:begin/input \
  -o \
  hid_composite_freertos.elf.translated:Recompile/output \
  --compile-opt-level=0

Check failed at /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/JumpTargetManager.cpp:875

PC.isValid()
PLEASE submit a bug report to https://github.com/revng/revng and include the crash backtrace
Stack dump:
0.      Program arguments: root/libexec/revng/revng-pipeline -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngFunctionIsolation.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngRecompile.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModelImporterBinary.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModelImporter.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngYieldPipes.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngModel.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngTypeShrinking.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngABI.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngBasicAnalyses.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngABIAnalyses.so -load /home/ritvik/Desktop/Files/orchestra/root/lib64/revng/analyses/librevngEarlyFunctionAnalysis.so -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/translate.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/hex-dump.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/enforce-abi.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/analyses-lists.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-cfg.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/isolate-translate.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-assembly.yml -P /home/ritvik/Desktop/Files/orchestra/root/share/revng/pipelines/yield-call-graph.yml --analyze=Import/ImportBinary/input/:Binary --analyze=Import/AddPrimitiveTypes/ --analyze=Lift/DetectABI/module.ll/:Root --produce=Recompile/output/:Translated -i hid_composite_freertos.elf:begin/input -o hid_composite_freertos.elf.translated:Recompile/output --compile-opt-level=0
1.      Running pass 'Lift Pass' on module 'revng.module'.
 #0 0x00007f1f42f9589e llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /builds/gitlab/revng/orchestra/orchestra/sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:570:13
 #1 0x00007f1f42f93c04 llvm::sys::RunSignalHandlers() /builds/gitlab/revng/orchestra/orchestra/sources/llvm-project/llvm/lib/Support/Signals.cpp:105:18
 #2 0x00007f1f42f95e0d SignalHandler(int) /builds/gitlab/revng/orchestra/orchestra/sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:415:1
 #3 0x00007f1f42a42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007f1f42a96a7c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007f1f42a96a7c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007f1f42a96a7c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007f1f42a42476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007f1f42a287f3 abort ./stdlib/abort.c:81:7
 #9 0x00007f1f47139479 /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Support/Assert.cpp:17:3
#10 0x00007f1f471394c0 revng_do_abort /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Support/Assert.cpp:46:0
#11 0x00007f1f41b4fe89 JumpTargetManager::isPC(MetaAddress) const /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/JumpTargetManager.h:310:5
#12 0x00007f1f41b4fe89 JumpTargetManager::registerJT(MetaAddress, JTReason::Values) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/JumpTargetManager.cpp:877:11
#13 0x00007f1f41b51b04 bool std::__1::operator==[abi:v160001]<model::Function const*>(std::__1::__wrap_iter<model::Function const*> const&, std::__1::__wrap_iter<model::Function const*> const&) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/clang-release/bin/../include/c++/v1/__iterator/wrap_iter.h:159:23
#14 0x00007f1f41b51b04 bool std::__1::operator!=[abi:v160001]<model::Function const*>(std::__1::__wrap_iter<model::Function const*> const&, std::__1::__wrap_iter<model::Function const*> const&) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/clang-release/bin/../include/c++/v1/__iterator/wrap_iter.h:191:18
#15 0x00007f1f41b51b04 JumpTargetManager::harvestGlobalData() /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/JumpTargetManager.cpp:466:40
#16 0x00007f1f41aeb8ce CodeGenerator::translate(std::__1::optional<unsigned long>) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/CodeGenerator.cpp:824:22
#17 0x00007f1f41b3861d LiftPass::runOnModule(llvm::Module&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/Lift.cpp:146:1
#18 0x00007f1f43a34532 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /builds/gitlab/revng/orchestra/orchestra/sources/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:0:27
#19 0x00007f1f43a34532 llvm::legacy::PassManagerImpl::run(llvm::Module&) /builds/gitlab/revng/orchestra/orchestra/sources/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:543:44
#20 0x00007f1f41b394cd revng::pipes::Lift::run(pipeline::Context&, revng::pipes::FileContainer<&revng::kinds::Binary, &revng::pipes::BinaryFileName.<char const at offset 0>, &revng::pipes::BinaryFileMIMEType.<char const at offset 0>, &revng::pipes::BinaryFileSuffix.<char const at offset 0>> const&, pipeline::LLVMContainer&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Lift/LiftPipe.cpp:47:1
#21 0x00007f1f41b4a3da llvm::Error::setChecked(bool) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:300:13
#22 0x00007f1f41b4a3da llvm::Error::operator=(llvm::Error&&) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:215:5
#23 0x00007f1f41b4a3da llvm::Error::Error(llvm::Error&&) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:192:11
#24 0x00007f1f41b4a3da pipeline::InvokableWrapperImpl<revng::pipes::Lift>::run(pipeline::Context&, pipeline::ContainerSet&, llvm::StringMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, llvm::MallocAllocator> const&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/include/revng/Pipeline/Invokable.h:403:12
#25 0x00007f1f41b4a3da pipeline::detail::PipeWrapperImpl<revng::pipes::Lift>::run(pipeline::Context&, pipeline::ContainerSet&, llvm::StringMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, llvm::MallocAllocator> const&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/include/revng/Pipeline/Pipe.h:179:22
#26 0x00007f1f47984ddf llvm::Error::getPtr() const /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:272:42
#27 0x00007f1f47984ddf llvm::Error::operator bool() /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:235:16
#28 0x00007f1f47984ddf llvm::cantFail(llvm::Error, char const*) /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:746:7
#29 0x00007f1f47984ddf pipeline::Step::run(pipeline::Context&, pipeline::ContainerSet&&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Pipeline/Step.cpp:96:5
#30 0x00007f1f4797a893 pipeline::Runner::run(llvm::StringRef, pipeline::ContainerToTargetsMap const&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Pipeline/Runner.cpp:359:5
#31 0x00007f1f47979709 llvm::Error::getPtr() const /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:272:42
#32 0x00007f1f47979709 llvm::Error::operator bool() /builds/gitlab/revng/orchestra/orchestra/root/lib64/llvm/llvm/include/llvm/Support/Error.h:235:16
#33 0x00007f1f47979709 pipeline::Runner::runAnalysis(llvm::StringRef, llvm::StringRef, pipeline::ContainerToTargetsMap const&, llvm::StringMap<pipeline::ContainerToTargetsMap, llvm::MallocAllocator>&, llvm::StringMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, llvm::MallocAllocator> const&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/lib/Pipeline/Runner.cpp:258:12
#34 0x000056455356b555 runAnalysis(pipeline::Runner&, llvm::StringRef) /builds/gitlab/revng/orchestra/orchestra/sources/revng/tools/pipeline/Main.cpp:138:25
#35 0x000056455356b555 runPipeline(pipeline::Runner&) /builds/gitlab/revng/orchestra/orchestra/sources/revng/tools/pipeline/Main.cpp:147:7
#36 0x000056455356b555 main /builds/gitlab/revng/orchestra/orchestra/sources/revng/tools/pipeline/Main.cpp:204:3
#37 0x00007f1f42a29d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#38 0x00007f1f42a29e40 call_init ./csu/../csu/libc-start.c:128:20
#39 0x00007f1f42a29e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#40 0x000056455356a529 _start (root/libexec/revng/revng-pipeline+0x15529)```
aleclearmind commented 11 months ago

Thanks for reporting this. We'll look into it.

Unfortunately the person familiar with that part of the code (me :)) is going to be off until Sep 28th. I'll give it a try when I come back.

aleclearmind commented 11 months ago

Debug info were providing an invalid address for some reason (0). Quickfix incoming but we'll need to investigate 1) why in DWARF we have 0, 2) ensure we never put in the model functions (or anything else with an address) whose entry point is out of any segment.

Example offending debug info:

0x000020a5:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("dcd_edpt_close")
                DW_AT_decl_file ("/home/ritvik/Desktop/Files/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c")
                DW_AT_decl_line (419)
                DW_AT_decl_column       (0x06)
                DW_AT_prototyped        (true)
                DW_AT_low_pc    (0x00000000)
                DW_AT_high_pc   (0x00000138)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)
                DW_AT_GNU_all_call_sites        (true)
                DW_AT_sibling   (0x0000215b)
aleclearmind commented 11 months ago

Fixed in 79c5f59. The binary you attached can now be lifted correctly.

What remains to be done is to ensure all model::Functions lie within a model::Segment and prevent the DWARF importer from creating functions out of any segment (right now we just ban functions at NULL address).

Thanks for reporting this and feel free to open a new issue if encounter other problems.