summaryrefslogtreecommitdiffstats
path: root/libunwindstack/include/unwindstack
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2017-11-03 14:50:27 -0700
committerChristopher Ferris <cferris@google.com>2017-11-07 13:22:39 -0800
commitc9dee84d81e4672dee5dd08890c904d1ab841e56 (patch)
treeb71dfd2d4adf1041b6420cef62492494d00e864c /libunwindstack/include/unwindstack
parent1e0b9672defa3504915741c8d4cec3cc73f89568 (diff)
downloadsystem_core-c9dee84d81e4672dee5dd08890c904d1ab841e56.tar.gz
system_core-c9dee84d81e4672dee5dd08890c904d1ab841e56.tar.bz2
system_core-c9dee84d81e4672dee5dd08890c904d1ab841e56.zip
Add support for only a .eh_frame.
Static executables only have a .eh_frame section and no .eh_frame_hdr section. Add support for this by rearranging the class hierarchy and creating a DwarfEhFrameWithHdr class and a DwarfEhFrame class to handle the different cases. Add new unit tests for DwarfEhFrame and for the new functionality. Bug: 68820189 Test: Passes new unit tests, unwinds static executables. Change-Id: I63d7cb8c52a686e96579a2266e18c0d06bbb6e63
Diffstat (limited to 'libunwindstack/include/unwindstack')
-rw-r--r--libunwindstack/include/unwindstack/DwarfSection.h32
-rw-r--r--libunwindstack/include/unwindstack/ElfInterface.h5
2 files changed, 33 insertions, 4 deletions
diff --git a/libunwindstack/include/unwindstack/DwarfSection.h b/libunwindstack/include/unwindstack/DwarfSection.h
index 1e843c359..10be6b48f 100644
--- a/libunwindstack/include/unwindstack/DwarfSection.h
+++ b/libunwindstack/include/unwindstack/DwarfSection.h
@@ -90,10 +90,6 @@ class DwarfSection {
virtual bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) = 0;
- virtual bool IsCie32(uint32_t value32) = 0;
-
- virtual bool IsCie64(uint64_t value64) = 0;
-
virtual uint64_t GetCieOffsetFromFde32(uint32_t pointer) = 0;
virtual uint64_t GetCieOffsetFromFde64(uint64_t pointer) = 0;
@@ -106,6 +102,9 @@ class DwarfSection {
DwarfMemory memory_;
DwarfError last_error_;
+ uint32_t cie32_value_ = 0;
+ uint64_t cie64_value_ = 0;
+
uint64_t fde_count_ = 0;
std::unordered_map<uint64_t, DwarfFde> fde_entries_;
std::unordered_map<uint64_t, DwarfCie> cie_entries_;
@@ -115,9 +114,24 @@ class DwarfSection {
template <typename AddressType>
class DwarfSectionImpl : public DwarfSection {
public:
+ struct FdeInfo {
+ FdeInfo(uint64_t offset, uint64_t start, uint64_t length)
+ : offset(offset), start(start), end(start + length) {}
+
+ uint64_t offset;
+ AddressType start;
+ AddressType end;
+ };
+
DwarfSectionImpl(Memory* memory) : DwarfSection(memory) {}
virtual ~DwarfSectionImpl() = default;
+ bool Init(uint64_t offset, uint64_t size) override;
+
+ bool GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) override;
+
+ const DwarfFde* GetFdeFromIndex(size_t index) override;
+
bool Eval(const DwarfCie* cie, Memory* regular_memory, const dwarf_loc_regs_t& loc_regs,
Regs* regs, bool* finished) override;
@@ -134,6 +148,16 @@ class DwarfSectionImpl : public DwarfSection {
protected:
bool EvalExpression(const DwarfLocation& loc, uint8_t version, Memory* regular_memory,
AddressType* value);
+
+ bool GetCieInfo(uint8_t* segment_size, uint8_t* encoding);
+
+ bool AddFdeInfo(uint64_t entry_offset, uint8_t segment_size, uint8_t encoding);
+
+ bool CreateSortedFdeList();
+
+ std::vector<FdeInfo> fdes_;
+ uint64_t entries_offset_;
+ uint64_t entries_end_;
};
} // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/ElfInterface.h b/libunwindstack/include/unwindstack/ElfInterface.h
index 319623d01..86e51b382 100644
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -70,6 +70,8 @@ class ElfInterface {
uint64_t dynamic_offset() { return dynamic_offset_; }
uint64_t dynamic_size() { return dynamic_size_; }
+ uint64_t eh_frame_hdr_offset() { return eh_frame_hdr_offset_; }
+ uint64_t eh_frame_hdr_size() { return eh_frame_hdr_size_; }
uint64_t eh_frame_offset() { return eh_frame_offset_; }
uint64_t eh_frame_size() { return eh_frame_size_; }
uint64_t debug_frame_offset() { return debug_frame_offset_; }
@@ -112,6 +114,9 @@ class ElfInterface {
uint64_t dynamic_offset_ = 0;
uint64_t dynamic_size_ = 0;
+ uint64_t eh_frame_hdr_offset_ = 0;
+ uint64_t eh_frame_hdr_size_ = 0;
+
uint64_t eh_frame_offset_ = 0;
uint64_t eh_frame_size_ = 0;