From 28aa6e3bb4fd633d0bc2d153669cdf9c4acbded7 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 17 May 2017 08:47:28 +0000 Subject: [PATCH] [RuntimeDyld] Fix debug section relocation (pr20457) Summary: Debug info sections, (or non-SHF_ALLOC sections in general) should be linked as if their load address was zero to emulate the behavior of the static linker. This bug was discovered because it was breaking lldb expression evaluation on linux. Reviewers: lhames Subscribers: aprantl, eugene, clayborg, lldb-commits, llvm-commits Differential Revision: https://reviews.llvm.org/D32899 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303239 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../RuntimeDyld/RuntimeDyld.cpp | 10 +++++++--- .../RuntimeDyld/X86/ELF_x86-64_debug_frame.s | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 test/ExecutionEngine/RuntimeDyld/X86/ELF_x86-64_debug_frame.s diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index e9a4b71c903..ab86e5d6a0f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -705,7 +705,7 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj, unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; unsigned PaddingSize = 0; unsigned StubBufSize = 0; - bool IsRequired = isRequiredForExecution(Section) || ProcessAllSections; + bool IsRequired = isRequiredForExecution(Section); bool IsVirtual = Section.isVirtual(); bool IsZeroInit = isZeroInit(Section); bool IsReadOnly = isReadOnlyData(Section); @@ -745,8 +745,8 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj, Alignment = std::max(Alignment, getStubAlignment()); // Some sections, such as debug info, don't need to be loaded for execution. - // Leave those where they are. - if (IsRequired) { + // Process those only if explicitly requested. + if (IsRequired || ProcessAllSections) { Allocate = DataSize + PaddingSize + StubBufSize; if (!Allocate) Allocate = 1; @@ -790,6 +790,10 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj, Sections.push_back( SectionEntry(Name, Addr, DataSize, Allocate, (uintptr_t)pData)); + // Debug info sections are linked as if their load address was zero + if (!IsRequired) + Sections.back().setLoadAddress(0); + if (Checker) Checker->registerSection(Obj.getFileName(), SectionID); diff --git a/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86-64_debug_frame.s b/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86-64_debug_frame.s new file mode 100644 index 00000000000..8f907a6c499 --- /dev/null +++ b/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86-64_debug_frame.s @@ -0,0 +1,20 @@ +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj -o %T/ELF_x86-64_debug_frame.o %s +# RUN: llvm-rtdyld -triple=x86_64-pc-linux -verify -check=%s %T/ELF_x86-64_debug_frame.o + + .text + .file "debug_frame_test.c" + .align 16, 0x90 + .type foo,@function +foo: + .cfi_startproc + retq +.Ltmp0: + .size foo, .Ltmp0-foo + .cfi_endproc + .cfi_sections .debug_frame + +# Check that .debug_frame is mapped to 0. +# rtdyld-check: section_addr(ELF_x86-64_debug_frame.o, .debug_frame) = 0 + +# Check that The relocated FDE's CIE offset also points to zero. +# rtdyld-check: *{4}(section_addr(ELF_x86-64_debug_frame.o, .debug_frame) + 0x1C) = 0 -- 2.40.0