summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
diff options
context:
space:
mode:
authorMitch Phillips <mitchphillips@outlook.com>2017-10-31 23:20:05 +0000
committerMitch Phillips <mitchphillips@outlook.com>2017-10-31 23:20:05 +0000
commit7db6f7a344653a7425ab1d6263f3c9a8356556a4 (patch)
treec24cfd12feff449f82f64196375904a0eb4a1c4c /llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
parent7438b2631720c9e7cbd23d9ce789cafd02400cd5 (diff)
downloadbcm5719-llvm-7db6f7a344653a7425ab1d6263f3c9a8356556a4.tar.gz
bcm5719-llvm-7db6f7a344653a7425ab1d6263f3c9a8356556a4.zip
Parse DWARF information to reduce false positives.
Summary: Help differentiate code and data by parsing DWARF information. This will reduce false positive rates where data is placed in executable sections and is mistakenly parsed as code, resulting in an inflation in the number of indirect CF instructions (and hence an inflation of the number of unprotected). Also prints the DWARF line data around the region of each indirect CF instruction. Reviewers: pcc Subscribers: probinson, llvm-commits, vlad.tsyrklevich, mgorny, aprantl, kcc Differential Revision: https://reviews.llvm.org/D38654 llvm-svn: 317050
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 928571bfd0a..278e861dfd3 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -11,6 +11,7 @@
#include "GraphBuilder.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -42,6 +43,19 @@ using Instr = llvm::cfi_verify::FileAnalysis::Instr;
namespace llvm {
namespace cfi_verify {
+static cl::opt<bool> IgnoreDWARF(
+ "ignore-dwarf",
+ cl::desc(
+ "Ignore all DWARF data. This relaxes the requirements for all "
+ "statically linked libraries to have been compiled with '-g', but "
+ "will result in false positives for 'CFI unprotected' instructions."),
+ cl::init(false));
+
+cl::opt<unsigned long long> DWARFSearchRange(
+ "dwarf-search-range",
+ cl::desc("Address search range used to determine if instruction is valid."),
+ cl::init(0x10));
+
Expected<FileAnalysis> FileAnalysis::Create(StringRef Filename) {
// Open the filename provided.
Expected<object::OwningBinary<object::Binary>> BinaryOrErr =
@@ -294,6 +308,28 @@ Error FileAnalysis::initialiseDisassemblyMembers() {
}
Error FileAnalysis::parseCodeSections() {
+ if (!IgnoreDWARF) {
+ DWARF.reset(DWARFContext::create(*Object).release());
+ if (!DWARF)
+ return make_error<StringError>("Could not create DWARF information.",
+ inconvertibleErrorCode());
+
+ bool LineInfoValid = false;
+
+ for (auto &Unit : DWARF->compile_units()) {
+ const auto &LineTable = DWARF->getLineTableForUnit(Unit.get());
+ if (LineTable && !LineTable->Rows.empty()) {
+ LineInfoValid = true;
+ break;
+ }
+ }
+
+ if (!LineInfoValid)
+ return make_error<StringError>(
+ "DWARF line information missing. Did you compile with '-g'?",
+ inconvertibleErrorCode());
+ }
+
for (const object::SectionRef &Section : Object->sections()) {
// Ensure only executable sections get analysed.
if (!(object::ELFSectionRef(Section).getFlags() & ELF::SHF_EXECINSTR))
@@ -311,6 +347,19 @@ Error FileAnalysis::parseCodeSections() {
return Error::success();
}
+DILineInfoTable FileAnalysis::getLineInfoForAddressRange(uint64_t Address) {
+ if (!hasLineTableInfo())
+ return DILineInfoTable();
+
+ return DWARF->getLineInfoForAddressRange(Address, DWARFSearchRange);
+}
+
+bool FileAnalysis::hasValidLineInfoForAddressRange(uint64_t Address) {
+ return !getLineInfoForAddressRange(Address).empty();
+}
+
+bool FileAnalysis::hasLineTableInfo() const { return DWARF != nullptr; }
+
void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
uint64_t SectionAddress) {
MCInst Instruction;
@@ -330,6 +379,11 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
InstrMeta.VMAddress = VMAddress;
InstrMeta.InstructionSize = InstructionSize;
InstrMeta.Valid = ValidInstruction;
+
+ // Check if this instruction exists in the range of the DWARF metadata.
+ if (hasLineTableInfo() && !hasValidLineInfoForAddressRange(VMAddress))
+ continue;
+
addInstruction(InstrMeta);
if (!ValidInstruction)
OpenPOWER on IntegriCloud