[DWARF parser] Fix nasty memory corruption in .dwo files handling.

Forge a test case where llvm-symbolizer has to use external .dwo
file to produce the inlining information.

llvm-svn: 217270
This commit is contained in:
Alexey Samsonov 2014-09-05 19:29:45 +00:00
parent e4d4801c3a
commit d3e121331b
6 changed files with 41 additions and 13 deletions

View File

@ -235,11 +235,14 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
return DieArray.size();
}
DWARFUnit::DWOHolder::DWOHolder(std::unique_ptr<object::ObjectFile> DWOFile)
: DWOFile(std::move(DWOFile)),
DWOContext(
cast<DWARFContext>(DIContext::getDWARFContext(*this->DWOFile))),
DWOU(nullptr) {
DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath)
: DWOFile(), DWOContext(), DWOU(nullptr) {
auto Obj = object::ObjectFile::createObjectFile(DWOPath);
if (!Obj)
return;
DWOFile = std::move(Obj.get());
DWOContext.reset(
cast<DWARFContext>(DIContext::getDWARFContext(*DWOFile.getBinary())));
if (DWOContext->getNumDWOCompileUnits() > 0)
DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
}
@ -261,12 +264,7 @@ bool DWARFUnit::parseDWO() {
sys::path::append(AbsolutePath, CompilationDir);
}
sys::path::append(AbsolutePath, DWOFileName);
ErrorOr<object::OwningBinary<object::ObjectFile>> DWOFile =
object::ObjectFile::createObjectFile(AbsolutePath);
if (!DWOFile)
return false;
// Reset DWOHolder.
DWO = llvm::make_unique<DWOHolder>(std::move(DWOFile->getBinary()));
DWO = llvm::make_unique<DWOHolder>(AbsolutePath);
DWARFUnit *DWOCU = DWO->getUnit();
// Verify that compile unit in .dwo file is valid.
if (!DWOCU || DWOCU->getDWOId() != getDWOId()) {

View File

@ -51,11 +51,11 @@ class DWARFUnit {
std::vector<DWARFDebugInfoEntryMinimal> DieArray;
class DWOHolder {
std::unique_ptr<object::ObjectFile> DWOFile;
object::OwningBinary<object::ObjectFile> DWOFile;
std::unique_ptr<DWARFContext> DWOContext;
DWARFUnit *DWOU;
public:
DWOHolder(std::unique_ptr<object::ObjectFile> DWOFile);
DWOHolder(StringRef DWOPath);
DWARFUnit *getUnit() const { return DWOU; }
};
std::unique_ptr<DWOHolder> DWO;

Binary file not shown.

View File

@ -0,0 +1,17 @@
int foo(int a) {
return a + 1;
}
int main(int argc, char *argv[]) {
return foo(argc);
}
// Build instructions:
// 1) clang++ -### -O2 -gsplit-dwarf.cc split-dwarf-test.cc -o split-dwarf-test
// 2) Replace the value "-fdebug-compilation-dir" flag to "Output"
// (this is the temp directory used by lit).
// 3) Manually run clang-cc1, objcopy and ld invocations.
// 4) Copy the binary and .dwo file to the Inputs directory. Make sure the
// .dwo file will be available for symbolizer (use test RUN-lines to copy
// the .dwo file to a directory
// <execution_directory>/<directory_provided_in_fdebug_compilation_dir>.

Binary file not shown.

View File

@ -19,10 +19,15 @@ RUN: echo "%p/Inputs/macho-universal:x86_64 0x100000f05" >> %t.input
RUN: echo "%p/Inputs/llvm-symbolizer-dwo-test 0x400514" >> %t.input
RUN: echo "%p/Inputs/fission-ranges.elf-x86_64 0x720" >> %t.input
RUN: echo "%p/Inputs/arange-overlap.elf-x86_64 0x714" >> %t.input
RUN: cp %p/Inputs/split-dwarf-test.dwo %T
RUN: echo "%p/Inputs/split-dwarf-test 0x4004d0" >> %t.input
RUN: echo "%p/Inputs/split-dwarf-test 0x4004c0" >> %t.input
RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
RUN: --default-arch=i386 < %t.input | FileCheck %s
REQUIRES: shell
CHECK: main
CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
@ -98,6 +103,14 @@ CHECK-NEXT: {{.*}}fission-ranges.cc:6
CHECK: _ZN1S3bazEv
CHECK-NEXT: {{.*}}arange-overlap.cc:6
CHECK: _Z3fooi
CHECK-NEXT: {{.*}}split-dwarf-test.cc
CHECK-NEXT: main
CHECK-NEXT: {{.*}}split-dwarf-test.cc
CHECK: _Z3fooi
CHECK-NEXT: {{.*}}split-dwarf-test.cc
RUN: echo "unexisting-file 0x1234" > %t.input2
RUN: llvm-symbolizer < %t.input2