summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-03-22 02:43:11 +0000
committerFangrui Song <maskray@google.com>2019-03-22 02:43:11 +0000
commit4597dce48319437a80db95153f65e289832f979b (patch)
treecc2a7741e814700dfa955f0bec7ba271c2c8cdd2 /llvm/lib/DebugInfo
parent1955c8f17267dc263aa7dfb2404341de05fdacaf (diff)
downloadbcm5719-llvm-4597dce48319437a80db95153f65e289832f979b.tar.gz
bcm5719-llvm-4597dce48319437a80db95153f65e289832f979b.zip
[DWARF] Refactor RelocVisitor and fix computation of SHT_RELA-typed relocation entries
Summary: getRelocatedValue may compute incorrect value for SHT_RELA-typed relocation entries. // DWARFDataExtractor.cpp uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, ... // This formula is correct for REL, but may be incorrect for RELA if the value // stored in the location (getUnsigned(Off, Size)) is not zero. return getUnsigned(Off, Size) + Rel->Value; In this patch, we * refactor these visit* functions to include a new parameter `uint64_t A`. Since these visit* functions are no longer used as visitors, rename them to resolve*. + REL: A is used as the addend. A is the value stored in the location where the relocation applies: getUnsigned(Off, Size) + RELA: The addend encoded in RelocationRef is used, e.g. getELFAddend(R) * and add another set of supports* functions to check if a given relocation type is handled. DWARFObjInMemory uses them to fail early. Reviewers: echristo, dblaikie Reviewed By: echristo Subscribers: mgorny, aprantl, aheejin, fedor.sergeev, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57939 llvm-svn: 356729
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp20
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp11
2 files changed, 19 insertions, 12 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index dc0539f4634..789874f5cbd 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -36,7 +36,7 @@
#include "llvm/Object/Decompressor.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/RelocVisitor.h"
+#include "llvm/Object/RelocationResolver.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
@@ -1500,6 +1500,9 @@ public:
// Symbol to [address, section index] cache mapping.
std::map<SymbolRef, SymInfo> AddrCache;
+ bool (*Supports)(uint64_t);
+ RelocationResolver Resolver;
+ std::tie(Supports, Resolver) = getRelocationResolver(Obj);
for (const RelocationRef &Reloc : Section.relocations()) {
// FIXME: it's not clear how to correctly handle scattered
// relocations.
@@ -1514,9 +1517,15 @@ public:
continue;
}
- object::RelocVisitor V(Obj);
- uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
- if (V.error()) {
+ // Check if Resolver can handle this relocation type early so as not to
+ // handle invalid cases in DWARFDataExtractor.
+ //
+ // TODO Don't store Resolver in every RelocAddrEntry.
+ if (Supports && Supports(Reloc.getType())) {
+ Map->try_emplace(Reloc.getOffset(),
+ RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc,
+ Resolver, SymInfoOrErr->Address});
+ } else {
SmallString<32> Type;
Reloc.getTypeName(Type);
ErrorPolicy EP = HandleError(
@@ -1524,10 +1533,7 @@ public:
errorCodeToError(object_error::parse_failed)));
if (EP == ErrorPolicy::Halt)
return;
- continue;
}
- RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
- Map->insert({Reloc.getOffset(), Rel});
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index bd8c23765e4..6f2f992f53e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -18,12 +18,13 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
*SecNdx = object::SectionedAddress::UndefSection;
if (!Section)
return getUnsigned(Off, Size);
- Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
- if (!Rel)
- return getUnsigned(Off, Size);
+ Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
+ uint64_t A = getUnsigned(Off, Size);
+ if (!E)
+ return A;
if (SecNdx)
- *SecNdx = Rel->SectionIndex;
- return getUnsigned(Off, Size) + Rel->Value;
+ *SecNdx = E->SectionIndex;
+ return E->Resolver(E->Reloc, E->SymbolValue, A);
}
Optional<uint64_t>
OpenPOWER on IntegriCloud