diff options
author | Christopher Ferris | 2018-03-19 12:48:59 -0500 |
---|---|---|
committer | Gerrit Code Review | 2018-03-19 12:48:59 -0500 |
commit | b22451f178ff063fb99391cc9f7b089394a3018b (patch) | |
tree | f31e25b3f6138f385a82bcbe8664ce368ef37a65 /libunwindstack | |
parent | e8d1b75c0c9384d476dd929b7215d9d121775081 (diff) | |
parent | 11e96fe48a74e6ab97d4de899684d3a61a9d1129 (diff) | |
download | platform-system-core-b22451f178ff063fb99391cc9f7b089394a3018b.tar.gz platform-system-core-b22451f178ff063fb99391cc9f7b089394a3018b.tar.xz platform-system-core-b22451f178ff063fb99391cc9f7b089394a3018b.zip |
Merge "Always set the sp reg to the cfa for DWARF."
Diffstat (limited to 'libunwindstack')
36 files changed, 417 insertions, 254 deletions
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index 87172836b..08dcf7724 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp | |||
@@ -188,6 +188,7 @@ cc_test { | |||
188 | data: [ | 188 | data: [ |
189 | "tests/files/elf32.xz", | 189 | "tests/files/elf32.xz", |
190 | "tests/files/elf64.xz", | 190 | "tests/files/elf64.xz", |
191 | "tests/files/offline/art_quick_osr_stub_arm/*", | ||
191 | "tests/files/offline/bad_eh_frame_hdr_arm64/*", | 192 | "tests/files/offline/bad_eh_frame_hdr_arm64/*", |
192 | "tests/files/offline/debug_frame_first_x86/*", | 193 | "tests/files/offline/debug_frame_first_x86/*", |
193 | "tests/files/offline/eh_frame_hdr_begin_x86_64/*", | 194 | "tests/files/offline/eh_frame_hdr_begin_x86_64/*", |
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp index ddbc12ef4..5586e725d 100644 --- a/libunwindstack/DwarfSection.cpp +++ b/libunwindstack/DwarfSection.cpp | |||
@@ -190,8 +190,6 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me | |||
190 | // Always set the dex pc to zero when evaluating. | 190 | // Always set the dex pc to zero when evaluating. |
191 | cur_regs->set_dex_pc(0); | 191 | cur_regs->set_dex_pc(0); |
192 | 192 | ||
193 | AddressType prev_cfa = regs->sp(); | ||
194 | |||
195 | EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs, | 193 | EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs, |
196 | .cie = cie, | 194 | .cie = cie, |
197 | .regular_memory = regular_memory, | 195 | .regular_memory = regular_memory, |
@@ -204,14 +202,7 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me | |||
204 | last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; | 202 | last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; |
205 | return false; | 203 | return false; |
206 | } | 204 | } |
207 | // If the stack pointer register is the CFA, and the stack | 205 | eval_info.cfa = (*cur_regs)[loc->values[0]]; |
208 | // pointer register does not have any associated location | ||
209 | // information, use the current cfa value. | ||
210 | if (regs->sp_reg() == loc->values[0] && loc_regs.count(regs->sp_reg()) == 0) { | ||
211 | eval_info.cfa = prev_cfa; | ||
212 | } else { | ||
213 | eval_info.cfa = (*cur_regs)[loc->values[0]]; | ||
214 | } | ||
215 | eval_info.cfa += loc->values[1]; | 206 | eval_info.cfa += loc->values[1]; |
216 | break; | 207 | break; |
217 | case DWARF_LOCATION_VAL_EXPRESSION: { | 208 | case DWARF_LOCATION_VAL_EXPRESSION: { |
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp index a5afc7e5d..f93baeb27 100644 --- a/libunwindstack/ElfInterfaceArm.cpp +++ b/libunwindstack/ElfInterfaceArm.cpp | |||
@@ -127,13 +127,9 @@ bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Mem | |||
127 | if (arm.ExtractEntryData(entry_offset) && arm.Eval()) { | 127 | if (arm.ExtractEntryData(entry_offset) && arm.Eval()) { |
128 | // If the pc was not set, then use the LR registers for the PC. | 128 | // If the pc was not set, then use the LR registers for the PC. |
129 | if (!arm.pc_set()) { | 129 | if (!arm.pc_set()) { |
130 | regs_arm->set_pc((*regs_arm)[ARM_REG_LR]); | 130 | (*regs_arm)[ARM_REG_PC] = (*regs_arm)[ARM_REG_LR]; |
131 | (*regs_arm)[ARM_REG_PC] = regs_arm->pc(); | ||
132 | } else { | ||
133 | regs_arm->set_pc((*regs_arm)[ARM_REG_PC]); | ||
134 | } | 131 | } |
135 | regs_arm->set_sp(arm.cfa()); | 132 | (*regs_arm)[ARM_REG_SP] = arm.cfa(); |
136 | (*regs_arm)[ARM_REG_SP] = regs_arm->sp(); | ||
137 | return_value = true; | 133 | return_value = true; |
138 | 134 | ||
139 | // If the pc was set to zero, consider this the final frame. | 135 | // If the pc was set to zero, consider this the final frame. |
diff --git a/libunwindstack/RegsArm.cpp b/libunwindstack/RegsArm.cpp index 5502ce1fe..e2a9cb01f 100644 --- a/libunwindstack/RegsArm.cpp +++ b/libunwindstack/RegsArm.cpp | |||
@@ -28,13 +28,28 @@ | |||
28 | 28 | ||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsArm::RegsArm() | 31 | RegsArm::RegsArm() : RegsImpl<uint32_t>(ARM_REG_LAST, Location(LOCATION_REGISTER, ARM_REG_LR)) {} |
32 | : RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {} | ||
33 | 32 | ||
34 | ArchEnum RegsArm::Arch() { | 33 | ArchEnum RegsArm::Arch() { |
35 | return ARCH_ARM; | 34 | return ARCH_ARM; |
36 | } | 35 | } |
37 | 36 | ||
37 | uint64_t RegsArm::pc() { | ||
38 | return regs_[ARM_REG_PC]; | ||
39 | } | ||
40 | |||
41 | uint64_t RegsArm::sp() { | ||
42 | return regs_[ARM_REG_SP]; | ||
43 | } | ||
44 | |||
45 | void RegsArm::set_pc(uint64_t pc) { | ||
46 | regs_[ARM_REG_PC] = pc; | ||
47 | } | ||
48 | |||
49 | void RegsArm::set_sp(uint64_t sp) { | ||
50 | regs_[ARM_REG_SP] = sp; | ||
51 | } | ||
52 | |||
38 | uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 53 | uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
39 | uint64_t load_bias = elf->GetLoadBias(); | 54 | uint64_t load_bias = elf->GetLoadBias(); |
40 | if (rel_pc < load_bias) { | 55 | if (rel_pc < load_bias) { |
@@ -56,17 +71,13 @@ uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
56 | return 4; | 71 | return 4; |
57 | } | 72 | } |
58 | 73 | ||
59 | void RegsArm::SetFromRaw() { | ||
60 | set_pc(regs_[ARM_REG_PC]); | ||
61 | set_sp(regs_[ARM_REG_SP]); | ||
62 | } | ||
63 | |||
64 | bool RegsArm::SetPcFromReturnAddress(Memory*) { | 74 | bool RegsArm::SetPcFromReturnAddress(Memory*) { |
65 | if (pc() == regs_[ARM_REG_LR]) { | 75 | uint32_t lr = regs_[ARM_REG_LR]; |
76 | if (regs_[ARM_REG_PC] == lr) { | ||
66 | return false; | 77 | return false; |
67 | } | 78 | } |
68 | 79 | ||
69 | set_pc(regs_[ARM_REG_LR]); | 80 | regs_[ARM_REG_PC] = lr; |
70 | return true; | 81 | return true; |
71 | } | 82 | } |
72 | 83 | ||
@@ -94,7 +105,6 @@ Regs* RegsArm::Read(void* remote_data) { | |||
94 | 105 | ||
95 | RegsArm* regs = new RegsArm(); | 106 | RegsArm* regs = new RegsArm(); |
96 | memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t)); | 107 | memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t)); |
97 | regs->SetFromRaw(); | ||
98 | return regs; | 108 | return regs; |
99 | } | 109 | } |
100 | 110 | ||
@@ -103,7 +113,6 @@ Regs* RegsArm::CreateFromUcontext(void* ucontext) { | |||
103 | 113 | ||
104 | RegsArm* regs = new RegsArm(); | 114 | RegsArm* regs = new RegsArm(); |
105 | memcpy(regs->RawData(), &arm_ucontext->uc_mcontext.regs[0], ARM_REG_LAST * sizeof(uint32_t)); | 115 | memcpy(regs->RawData(), &arm_ucontext->uc_mcontext.regs[0], ARM_REG_LAST * sizeof(uint32_t)); |
106 | regs->SetFromRaw(); | ||
107 | return regs; | 116 | return regs; |
108 | } | 117 | } |
109 | 118 | ||
@@ -118,6 +127,7 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
118 | 127 | ||
119 | uint64_t offset = 0; | 128 | uint64_t offset = 0; |
120 | if (data == 0xe3a07077 || data == 0xef900077 || data == 0xdf002777) { | 129 | if (data == 0xe3a07077 || data == 0xef900077 || data == 0xdf002777) { |
130 | uint64_t sp = regs_[ARM_REG_SP]; | ||
121 | // non-RT sigreturn call. | 131 | // non-RT sigreturn call. |
122 | // __restore: | 132 | // __restore: |
123 | // | 133 | // |
@@ -131,17 +141,18 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
131 | // Form 3 (thumb): | 141 | // Form 3 (thumb): |
132 | // 0x77 0x27 movs r7, #77 | 142 | // 0x77 0x27 movs r7, #77 |
133 | // 0x00 0xdf svc 0 | 143 | // 0x00 0xdf svc 0 |
134 | if (!process_memory->ReadFully(sp(), &data, sizeof(data))) { | 144 | if (!process_memory->ReadFully(sp, &data, sizeof(data))) { |
135 | return false; | 145 | return false; |
136 | } | 146 | } |
137 | if (data == 0x5ac3c35a) { | 147 | if (data == 0x5ac3c35a) { |
138 | // SP + uc_mcontext offset + r0 offset. | 148 | // SP + uc_mcontext offset + r0 offset. |
139 | offset = sp() + 0x14 + 0xc; | 149 | offset = sp + 0x14 + 0xc; |
140 | } else { | 150 | } else { |
141 | // SP + r0 offset | 151 | // SP + r0 offset |
142 | offset = sp() + 0xc; | 152 | offset = sp + 0xc; |
143 | } | 153 | } |
144 | } else if (data == 0xe3a070ad || data == 0xef9000ad || data == 0xdf0027ad) { | 154 | } else if (data == 0xe3a070ad || data == 0xef9000ad || data == 0xdf0027ad) { |
155 | uint64_t sp = regs_[ARM_REG_SP]; | ||
145 | // RT sigreturn call. | 156 | // RT sigreturn call. |
146 | // __restore_rt: | 157 | // __restore_rt: |
147 | // | 158 | // |
@@ -155,15 +166,15 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
155 | // Form 3 (thumb): | 166 | // Form 3 (thumb): |
156 | // 0xad 0x27 movs r7, #ad | 167 | // 0xad 0x27 movs r7, #ad |
157 | // 0x00 0xdf svc 0 | 168 | // 0x00 0xdf svc 0 |
158 | if (!process_memory->ReadFully(sp(), &data, sizeof(data))) { | 169 | if (!process_memory->ReadFully(sp, &data, sizeof(data))) { |
159 | return false; | 170 | return false; |
160 | } | 171 | } |
161 | if (data == sp() + 8) { | 172 | if (data == sp + 8) { |
162 | // SP + 8 + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset | 173 | // SP + 8 + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset |
163 | offset = sp() + 8 + 0x80 + 0x14 + 0xc; | 174 | offset = sp + 8 + 0x80 + 0x14 + 0xc; |
164 | } else { | 175 | } else { |
165 | // SP + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset | 176 | // SP + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset |
166 | offset = sp() + 0x80 + 0x14 + 0xc; | 177 | offset = sp + 0x80 + 0x14 + 0xc; |
167 | } | 178 | } |
168 | } | 179 | } |
169 | if (offset == 0) { | 180 | if (offset == 0) { |
@@ -173,7 +184,6 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
173 | if (!process_memory->ReadFully(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) { | 184 | if (!process_memory->ReadFully(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) { |
174 | return false; | 185 | return false; |
175 | } | 186 | } |
176 | SetFromRaw(); | ||
177 | return true; | 187 | return true; |
178 | } | 188 | } |
179 | 189 | ||
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp index cc6f5ce87..fe24c802c 100644 --- a/libunwindstack/RegsArm64.cpp +++ b/libunwindstack/RegsArm64.cpp | |||
@@ -29,12 +29,28 @@ | |||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsArm64::RegsArm64() | 31 | RegsArm64::RegsArm64() |
32 | : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {} | 32 | : RegsImpl<uint64_t>(ARM64_REG_LAST, Location(LOCATION_REGISTER, ARM64_REG_LR)) {} |
33 | 33 | ||
34 | ArchEnum RegsArm64::Arch() { | 34 | ArchEnum RegsArm64::Arch() { |
35 | return ARCH_ARM64; | 35 | return ARCH_ARM64; |
36 | } | 36 | } |
37 | 37 | ||
38 | uint64_t RegsArm64::pc() { | ||
39 | return regs_[ARM64_REG_PC]; | ||
40 | } | ||
41 | |||
42 | uint64_t RegsArm64::sp() { | ||
43 | return regs_[ARM64_REG_SP]; | ||
44 | } | ||
45 | |||
46 | void RegsArm64::set_pc(uint64_t pc) { | ||
47 | regs_[ARM64_REG_PC] = pc; | ||
48 | } | ||
49 | |||
50 | void RegsArm64::set_sp(uint64_t sp) { | ||
51 | regs_[ARM64_REG_SP] = sp; | ||
52 | } | ||
53 | |||
38 | uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 54 | uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
39 | if (!elf->valid() || rel_pc < 4) { | 55 | if (!elf->valid() || rel_pc < 4) { |
40 | return 0; | 56 | return 0; |
@@ -42,17 +58,13 @@ uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
42 | return 4; | 58 | return 4; |
43 | } | 59 | } |
44 | 60 | ||
45 | void RegsArm64::SetFromRaw() { | ||
46 | set_pc(regs_[ARM64_REG_PC]); | ||
47 | set_sp(regs_[ARM64_REG_SP]); | ||
48 | } | ||
49 | |||
50 | bool RegsArm64::SetPcFromReturnAddress(Memory*) { | 61 | bool RegsArm64::SetPcFromReturnAddress(Memory*) { |
51 | if (pc() == regs_[ARM64_REG_LR]) { | 62 | uint64_t lr = regs_[ARM64_REG_LR]; |
63 | if (regs_[ARM64_REG_PC] == lr) { | ||
52 | return false; | 64 | return false; |
53 | } | 65 | } |
54 | 66 | ||
55 | set_pc(regs_[ARM64_REG_LR]); | 67 | regs_[ARM64_REG_PC] = lr; |
56 | return true; | 68 | return true; |
57 | } | 69 | } |
58 | 70 | ||
@@ -100,7 +112,6 @@ Regs* RegsArm64::Read(void* remote_data) { | |||
100 | uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData()); | 112 | uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData()); |
101 | reg_data[ARM64_REG_PC] = user->pc; | 113 | reg_data[ARM64_REG_PC] = user->pc; |
102 | reg_data[ARM64_REG_SP] = user->sp; | 114 | reg_data[ARM64_REG_SP] = user->sp; |
103 | regs->SetFromRaw(); | ||
104 | return regs; | 115 | return regs; |
105 | } | 116 | } |
106 | 117 | ||
@@ -109,7 +120,6 @@ Regs* RegsArm64::CreateFromUcontext(void* ucontext) { | |||
109 | 120 | ||
110 | RegsArm64* regs = new RegsArm64(); | 121 | RegsArm64* regs = new RegsArm64(); |
111 | memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t)); | 122 | memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t)); |
112 | regs->SetFromRaw(); | ||
113 | return regs; | 123 | return regs; |
114 | } | 124 | } |
115 | 125 | ||
@@ -131,12 +141,10 @@ bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_m | |||
131 | } | 141 | } |
132 | 142 | ||
133 | // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset. | 143 | // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset. |
134 | if (!process_memory->ReadFully(sp() + 0x80 + 0xb0 + 0x08, regs_.data(), | 144 | if (!process_memory->ReadFully(regs_[ARM64_REG_SP] + 0x80 + 0xb0 + 0x08, regs_.data(), |
135 | sizeof(uint64_t) * ARM64_REG_LAST)) { | 145 | sizeof(uint64_t) * ARM64_REG_LAST)) { |
136 | return false; | 146 | return false; |
137 | } | 147 | } |
138 | |||
139 | SetFromRaw(); | ||
140 | return true; | 148 | return true; |
141 | } | 149 | } |
142 | 150 | ||
diff --git a/libunwindstack/RegsMips.cpp b/libunwindstack/RegsMips.cpp index 5d20bef4a..0b10e2169 100644 --- a/libunwindstack/RegsMips.cpp +++ b/libunwindstack/RegsMips.cpp | |||
@@ -29,12 +29,28 @@ | |||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsMips::RegsMips() | 31 | RegsMips::RegsMips() |
32 | : RegsImpl<uint32_t>(MIPS_REG_LAST, MIPS_REG_SP, Location(LOCATION_REGISTER, MIPS_REG_RA)) {} | 32 | : RegsImpl<uint32_t>(MIPS_REG_LAST, Location(LOCATION_REGISTER, MIPS_REG_RA)) {} |
33 | 33 | ||
34 | ArchEnum RegsMips::Arch() { | 34 | ArchEnum RegsMips::Arch() { |
35 | return ARCH_MIPS; | 35 | return ARCH_MIPS; |
36 | } | 36 | } |
37 | 37 | ||
38 | uint64_t RegsMips::pc() { | ||
39 | return regs_[MIPS_REG_PC]; | ||
40 | } | ||
41 | |||
42 | uint64_t RegsMips::sp() { | ||
43 | return regs_[MIPS_REG_SP]; | ||
44 | } | ||
45 | |||
46 | void RegsMips::set_pc(uint64_t pc) { | ||
47 | regs_[MIPS_REG_PC] = static_cast<uint32_t>(pc); | ||
48 | } | ||
49 | |||
50 | void RegsMips::set_sp(uint64_t sp) { | ||
51 | regs_[MIPS_REG_SP] = static_cast<uint32_t>(sp); | ||
52 | } | ||
53 | |||
38 | uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 54 | uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
39 | if (!elf->valid() || rel_pc < 8) { | 55 | if (!elf->valid() || rel_pc < 8) { |
40 | return 0; | 56 | return 0; |
@@ -43,17 +59,13 @@ uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
43 | return 8; | 59 | return 8; |
44 | } | 60 | } |
45 | 61 | ||
46 | void RegsMips::SetFromRaw() { | ||
47 | set_pc(regs_[MIPS_REG_PC]); | ||
48 | set_sp(regs_[MIPS_REG_SP]); | ||
49 | } | ||
50 | |||
51 | bool RegsMips::SetPcFromReturnAddress(Memory*) { | 62 | bool RegsMips::SetPcFromReturnAddress(Memory*) { |
52 | if (pc() == regs_[MIPS_REG_RA]) { | 63 | uint32_t ra = regs_[MIPS_REG_RA]; |
64 | if (regs_[MIPS_REG_PC] == ra) { | ||
53 | return false; | 65 | return false; |
54 | } | 66 | } |
55 | 67 | ||
56 | set_pc(regs_[MIPS_REG_RA]); | 68 | regs_[MIPS_REG_PC] = ra; |
57 | return true; | 69 | return true; |
58 | } | 70 | } |
59 | 71 | ||
@@ -101,7 +113,6 @@ Regs* RegsMips::Read(void* remote_data) { | |||
101 | memcpy(regs->RawData(), &user->regs[MIPS32_EF_R0], (MIPS_REG_R31 + 1) * sizeof(uint32_t)); | 113 | memcpy(regs->RawData(), &user->regs[MIPS32_EF_R0], (MIPS_REG_R31 + 1) * sizeof(uint32_t)); |
102 | 114 | ||
103 | reg_data[MIPS_REG_PC] = user->regs[MIPS32_EF_CP0_EPC]; | 115 | reg_data[MIPS_REG_PC] = user->regs[MIPS32_EF_CP0_EPC]; |
104 | regs->SetFromRaw(); | ||
105 | return regs; | 116 | return regs; |
106 | } | 117 | } |
107 | 118 | ||
@@ -114,7 +125,6 @@ Regs* RegsMips::CreateFromUcontext(void* ucontext) { | |||
114 | (*regs)[MIPS_REG_R0 + i] = mips_ucontext->uc_mcontext.sc_regs[i]; | 125 | (*regs)[MIPS_REG_R0 + i] = mips_ucontext->uc_mcontext.sc_regs[i]; |
115 | } | 126 | } |
116 | (*regs)[MIPS_REG_PC] = mips_ucontext->uc_mcontext.sc_pc; | 127 | (*regs)[MIPS_REG_PC] = mips_ucontext->uc_mcontext.sc_pc; |
117 | regs->SetFromRaw(); | ||
118 | return regs; | 128 | return regs; |
119 | } | 129 | } |
120 | 130 | ||
@@ -149,7 +159,7 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me | |||
149 | 159 | ||
150 | // read sc_pc and sc_regs[32] from stack | 160 | // read sc_pc and sc_regs[32] from stack |
151 | uint64_t values[MIPS_REG_LAST]; | 161 | uint64_t values[MIPS_REG_LAST]; |
152 | if (!process_memory->Read(sp() + offset, values, sizeof(values))) { | 162 | if (!process_memory->Read(regs_[MIPS_REG_SP] + offset, values, sizeof(values))) { |
153 | return false; | 163 | return false; |
154 | } | 164 | } |
155 | 165 | ||
@@ -160,8 +170,6 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me | |||
160 | for (int i = 0; i < 32; i++) { | 170 | for (int i = 0; i < 32; i++) { |
161 | regs_[MIPS_REG_R0 + i] = values[1 + i]; | 171 | regs_[MIPS_REG_R0 + i] = values[1 + i]; |
162 | } | 172 | } |
163 | |||
164 | SetFromRaw(); | ||
165 | return true; | 173 | return true; |
166 | } | 174 | } |
167 | 175 | ||
diff --git a/libunwindstack/RegsMips64.cpp b/libunwindstack/RegsMips64.cpp index 4a03538e2..8848e3bab 100644 --- a/libunwindstack/RegsMips64.cpp +++ b/libunwindstack/RegsMips64.cpp | |||
@@ -29,13 +29,28 @@ | |||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsMips64::RegsMips64() | 31 | RegsMips64::RegsMips64() |
32 | : RegsImpl<uint64_t>(MIPS64_REG_LAST, MIPS64_REG_SP, | 32 | : RegsImpl<uint64_t>(MIPS64_REG_LAST, Location(LOCATION_REGISTER, MIPS64_REG_RA)) {} |
33 | Location(LOCATION_REGISTER, MIPS64_REG_RA)) {} | ||
34 | 33 | ||
35 | ArchEnum RegsMips64::Arch() { | 34 | ArchEnum RegsMips64::Arch() { |
36 | return ARCH_MIPS64; | 35 | return ARCH_MIPS64; |
37 | } | 36 | } |
38 | 37 | ||
38 | uint64_t RegsMips64::pc() { | ||
39 | return regs_[MIPS64_REG_PC]; | ||
40 | } | ||
41 | |||
42 | uint64_t RegsMips64::sp() { | ||
43 | return regs_[MIPS64_REG_SP]; | ||
44 | } | ||
45 | |||
46 | void RegsMips64::set_pc(uint64_t pc) { | ||
47 | regs_[MIPS64_REG_PC] = pc; | ||
48 | } | ||
49 | |||
50 | void RegsMips64::set_sp(uint64_t sp) { | ||
51 | regs_[MIPS64_REG_SP] = sp; | ||
52 | } | ||
53 | |||
39 | uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 54 | uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
40 | if (!elf->valid() || rel_pc < 8) { | 55 | if (!elf->valid() || rel_pc < 8) { |
41 | return 0; | 56 | return 0; |
@@ -44,17 +59,13 @@ uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
44 | return 8; | 59 | return 8; |
45 | } | 60 | } |
46 | 61 | ||
47 | void RegsMips64::SetFromRaw() { | ||
48 | set_pc(regs_[MIPS64_REG_PC]); | ||
49 | set_sp(regs_[MIPS64_REG_SP]); | ||
50 | } | ||
51 | |||
52 | bool RegsMips64::SetPcFromReturnAddress(Memory*) { | 62 | bool RegsMips64::SetPcFromReturnAddress(Memory*) { |
53 | if (pc() == regs_[MIPS64_REG_RA]) { | 63 | uint64_t ra = regs_[MIPS64_REG_RA]; |
64 | if (regs_[MIPS64_REG_PC] == ra) { | ||
54 | return false; | 65 | return false; |
55 | } | 66 | } |
56 | 67 | ||
57 | set_pc(regs_[MIPS64_REG_RA]); | 68 | regs_[MIPS64_REG_PC] = ra; |
58 | return true; | 69 | return true; |
59 | } | 70 | } |
60 | 71 | ||
@@ -102,7 +113,6 @@ Regs* RegsMips64::Read(void* remote_data) { | |||
102 | memcpy(regs->RawData(), &user->regs[MIPS64_EF_R0], (MIPS64_REG_R31 + 1) * sizeof(uint64_t)); | 113 | memcpy(regs->RawData(), &user->regs[MIPS64_EF_R0], (MIPS64_REG_R31 + 1) * sizeof(uint64_t)); |
103 | 114 | ||
104 | reg_data[MIPS64_REG_PC] = user->regs[MIPS64_EF_CP0_EPC]; | 115 | reg_data[MIPS64_REG_PC] = user->regs[MIPS64_EF_CP0_EPC]; |
105 | regs->SetFromRaw(); | ||
106 | return regs; | 116 | return regs; |
107 | } | 117 | } |
108 | 118 | ||
@@ -113,7 +123,6 @@ Regs* RegsMips64::CreateFromUcontext(void* ucontext) { | |||
113 | // Copy 64 bit sc_regs over to 64 bit regs | 123 | // Copy 64 bit sc_regs over to 64 bit regs |
114 | memcpy(regs->RawData(), &mips64_ucontext->uc_mcontext.sc_regs[0], 32 * sizeof(uint64_t)); | 124 | memcpy(regs->RawData(), &mips64_ucontext->uc_mcontext.sc_regs[0], 32 * sizeof(uint64_t)); |
115 | (*regs)[MIPS64_REG_PC] = mips64_ucontext->uc_mcontext.sc_pc; | 125 | (*regs)[MIPS64_REG_PC] = mips64_ucontext->uc_mcontext.sc_pc; |
116 | regs->SetFromRaw(); | ||
117 | return regs; | 126 | return regs; |
118 | } | 127 | } |
119 | 128 | ||
@@ -137,19 +146,17 @@ bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ | |||
137 | // vdso_rt_sigreturn => read rt_sigframe | 146 | // vdso_rt_sigreturn => read rt_sigframe |
138 | // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset | 147 | // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset |
139 | // read 64 bit sc_regs[32] from stack into 64 bit regs_ | 148 | // read 64 bit sc_regs[32] from stack into 64 bit regs_ |
140 | if (!process_memory->Read(sp() + 24 + 128 + 40, regs_.data(), | 149 | uint64_t sp = regs_[MIPS64_REG_SP]; |
150 | if (!process_memory->Read(sp + 24 + 128 + 40, regs_.data(), | ||
141 | sizeof(uint64_t) * (MIPS64_REG_LAST - 1))) { | 151 | sizeof(uint64_t) * (MIPS64_REG_LAST - 1))) { |
142 | return false; | 152 | return false; |
143 | } | 153 | } |
144 | 154 | ||
145 | // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset + sc_pc offset | 155 | // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset + sc_pc offset |
146 | // read 64 bit sc_pc from stack into 64 bit regs_[MIPS64_REG_PC] | 156 | // read 64 bit sc_pc from stack into 64 bit regs_[MIPS64_REG_PC] |
147 | if (!process_memory->Read(sp() + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC], | 157 | if (!process_memory->Read(sp + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC], sizeof(uint64_t))) { |
148 | sizeof(uint64_t))) { | ||
149 | return false; | 158 | return false; |
150 | } | 159 | } |
151 | |||
152 | SetFromRaw(); | ||
153 | return true; | 160 | return true; |
154 | } | 161 | } |
155 | 162 | ||
diff --git a/libunwindstack/RegsX86.cpp b/libunwindstack/RegsX86.cpp index 573cb2382..bb95a13f2 100644 --- a/libunwindstack/RegsX86.cpp +++ b/libunwindstack/RegsX86.cpp | |||
@@ -28,13 +28,28 @@ | |||
28 | 28 | ||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsX86::RegsX86() | 31 | RegsX86::RegsX86() : RegsImpl<uint32_t>(X86_REG_LAST, Location(LOCATION_SP_OFFSET, -4)) {} |
32 | : RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {} | ||
33 | 32 | ||
34 | ArchEnum RegsX86::Arch() { | 33 | ArchEnum RegsX86::Arch() { |
35 | return ARCH_X86; | 34 | return ARCH_X86; |
36 | } | 35 | } |
37 | 36 | ||
37 | uint64_t RegsX86::pc() { | ||
38 | return regs_[X86_REG_PC]; | ||
39 | } | ||
40 | |||
41 | uint64_t RegsX86::sp() { | ||
42 | return regs_[X86_REG_SP]; | ||
43 | } | ||
44 | |||
45 | void RegsX86::set_pc(uint64_t pc) { | ||
46 | regs_[X86_REG_PC] = static_cast<uint32_t>(pc); | ||
47 | } | ||
48 | |||
49 | void RegsX86::set_sp(uint64_t sp) { | ||
50 | regs_[X86_REG_SP] = static_cast<uint32_t>(sp); | ||
51 | } | ||
52 | |||
38 | uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 53 | uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
39 | if (!elf->valid() || rel_pc == 0) { | 54 | if (!elf->valid() || rel_pc == 0) { |
40 | return 0; | 55 | return 0; |
@@ -42,19 +57,15 @@ uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
42 | return 1; | 57 | return 1; |
43 | } | 58 | } |
44 | 59 | ||
45 | void RegsX86::SetFromRaw() { | ||
46 | set_pc(regs_[X86_REG_PC]); | ||
47 | set_sp(regs_[X86_REG_SP]); | ||
48 | } | ||
49 | |||
50 | bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) { | 60 | bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) { |
51 | // Attempt to get the return address from the top of the stack. | 61 | // Attempt to get the return address from the top of the stack. |
52 | uint32_t new_pc; | 62 | uint32_t new_pc; |
53 | if (!process_memory->ReadFully(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) { | 63 | if (!process_memory->ReadFully(regs_[X86_REG_SP], &new_pc, sizeof(new_pc)) || |
64 | new_pc == regs_[X86_REG_PC]) { | ||
54 | return false; | 65 | return false; |
55 | } | 66 | } |
56 | 67 | ||
57 | set_pc(new_pc); | 68 | regs_[X86_REG_PC] = new_pc; |
58 | return true; | 69 | return true; |
59 | } | 70 | } |
60 | 71 | ||
@@ -84,7 +95,6 @@ Regs* RegsX86::Read(void* user_data) { | |||
84 | (*regs)[X86_REG_ESP] = user->esp; | 95 | (*regs)[X86_REG_ESP] = user->esp; |
85 | (*regs)[X86_REG_EIP] = user->eip; | 96 | (*regs)[X86_REG_EIP] = user->eip; |
86 | 97 | ||
87 | regs->SetFromRaw(); | ||
88 | return regs; | 98 | return regs; |
89 | } | 99 | } |
90 | 100 | ||
@@ -99,7 +109,6 @@ void RegsX86::SetFromUcontext(x86_ucontext_t* ucontext) { | |||
99 | regs_[X86_REG_ECX] = ucontext->uc_mcontext.ecx; | 109 | regs_[X86_REG_ECX] = ucontext->uc_mcontext.ecx; |
100 | regs_[X86_REG_EAX] = ucontext->uc_mcontext.eax; | 110 | regs_[X86_REG_EAX] = ucontext->uc_mcontext.eax; |
101 | regs_[X86_REG_EIP] = ucontext->uc_mcontext.eip; | 111 | regs_[X86_REG_EIP] = ucontext->uc_mcontext.eip; |
102 | SetFromRaw(); | ||
103 | } | 112 | } |
104 | 113 | ||
105 | Regs* RegsX86::CreateFromUcontext(void* ucontext) { | 114 | Regs* RegsX86::CreateFromUcontext(void* ucontext) { |
@@ -131,7 +140,7 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
131 | // int signum | 140 | // int signum |
132 | // struct sigcontext (same format as mcontext) | 141 | // struct sigcontext (same format as mcontext) |
133 | struct x86_mcontext_t context; | 142 | struct x86_mcontext_t context; |
134 | if (!process_memory->ReadFully(sp() + 4, &context, sizeof(context))) { | 143 | if (!process_memory->ReadFully(regs_[X86_REG_SP] + 4, &context, sizeof(context))) { |
135 | return false; | 144 | return false; |
136 | } | 145 | } |
137 | regs_[X86_REG_EBP] = context.ebp; | 146 | regs_[X86_REG_EBP] = context.ebp; |
@@ -141,7 +150,6 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
141 | regs_[X86_REG_ECX] = context.ecx; | 150 | regs_[X86_REG_ECX] = context.ecx; |
142 | regs_[X86_REG_EAX] = context.eax; | 151 | regs_[X86_REG_EAX] = context.eax; |
143 | regs_[X86_REG_EIP] = context.eip; | 152 | regs_[X86_REG_EIP] = context.eip; |
144 | SetFromRaw(); | ||
145 | return true; | 153 | return true; |
146 | } else if ((data & 0x00ffffffffffffffULL) == 0x0080cd000000adb8ULL) { | 154 | } else if ((data & 0x00ffffffffffffffULL) == 0x0080cd000000adb8ULL) { |
147 | // With SA_SIGINFO set, the return sequence is: | 155 | // With SA_SIGINFO set, the return sequence is: |
@@ -157,7 +165,7 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem | |||
157 | 165 | ||
158 | // Get the location of the sigcontext data. | 166 | // Get the location of the sigcontext data. |
159 | uint32_t ptr; | 167 | uint32_t ptr; |
160 | if (!process_memory->ReadFully(sp() + 8, &ptr, sizeof(ptr))) { | 168 | if (!process_memory->ReadFully(regs_[X86_REG_SP] + 8, &ptr, sizeof(ptr))) { |
161 | return false; | 169 | return false; |
162 | } | 170 | } |
163 | // Only read the portion of the data structure we care about. | 171 | // Only read the portion of the data structure we care about. |
diff --git a/libunwindstack/RegsX86_64.cpp b/libunwindstack/RegsX86_64.cpp index 3175a90c2..e57e2bca1 100644 --- a/libunwindstack/RegsX86_64.cpp +++ b/libunwindstack/RegsX86_64.cpp | |||
@@ -28,13 +28,28 @@ | |||
28 | 28 | ||
29 | namespace unwindstack { | 29 | namespace unwindstack { |
30 | 30 | ||
31 | RegsX86_64::RegsX86_64() | 31 | RegsX86_64::RegsX86_64() : RegsImpl<uint64_t>(X86_64_REG_LAST, Location(LOCATION_SP_OFFSET, -8)) {} |
32 | : RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {} | ||
33 | 32 | ||
34 | ArchEnum RegsX86_64::Arch() { | 33 | ArchEnum RegsX86_64::Arch() { |
35 | return ARCH_X86_64; | 34 | return ARCH_X86_64; |
36 | } | 35 | } |
37 | 36 | ||
37 | uint64_t RegsX86_64::pc() { | ||
38 | return regs_[X86_64_REG_PC]; | ||
39 | } | ||
40 | |||
41 | uint64_t RegsX86_64::sp() { | ||
42 | return regs_[X86_64_REG_SP]; | ||
43 | } | ||
44 | |||
45 | void RegsX86_64::set_pc(uint64_t pc) { | ||
46 | regs_[X86_64_REG_PC] = pc; | ||
47 | } | ||
48 | |||
49 | void RegsX86_64::set_sp(uint64_t sp) { | ||
50 | regs_[X86_64_REG_SP] = sp; | ||
51 | } | ||
52 | |||
38 | uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | 53 | uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { |
39 | if (!elf->valid() || rel_pc == 0) { | 54 | if (!elf->valid() || rel_pc == 0) { |
40 | return 0; | 55 | return 0; |
@@ -42,19 +57,15 @@ uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { | |||
42 | return 1; | 57 | return 1; |
43 | } | 58 | } |
44 | 59 | ||
45 | void RegsX86_64::SetFromRaw() { | ||
46 | set_pc(regs_[X86_64_REG_PC]); | ||
47 | set_sp(regs_[X86_64_REG_SP]); | ||
48 | } | ||
49 | |||
50 | bool RegsX86_64::SetPcFromReturnAddress(Memory* process_memory) { | 60 | bool RegsX86_64::SetPcFromReturnAddress(Memory* process_memory) { |
51 | // Attempt to get the return address from the top of the stack. | 61 | // Attempt to get the return address from the top of the stack. |
52 | uint64_t new_pc; | 62 | uint64_t new_pc; |
53 | if (!process_memory->ReadFully(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) { | 63 | if (!process_memory->ReadFully(regs_[X86_64_REG_SP], &new_pc, sizeof(new_pc)) || |
64 | new_pc == regs_[X86_64_REG_PC]) { | ||
54 | return false; | 65 | return false; |
55 | } | 66 | } |
56 | 67 | ||
57 | set_pc(new_pc); | 68 | regs_[X86_64_REG_PC] = new_pc; |
58 | return true; | 69 | return true; |
59 | } | 70 | } |
60 | 71 | ||
@@ -100,7 +111,6 @@ Regs* RegsX86_64::Read(void* remote_data) { | |||
100 | (*regs)[X86_64_REG_RSP] = user->rsp; | 111 | (*regs)[X86_64_REG_RSP] = user->rsp; |
101 | (*regs)[X86_64_REG_RIP] = user->rip; | 112 | (*regs)[X86_64_REG_RIP] = user->rip; |
102 | 113 | ||
103 | regs->SetFromRaw(); | ||
104 | return regs; | 114 | return regs; |
105 | } | 115 | } |
106 | 116 | ||
@@ -118,8 +128,6 @@ void RegsX86_64::SetFromUcontext(x86_64_ucontext_t* ucontext) { | |||
118 | regs_[X86_64_REG_RCX] = ucontext->uc_mcontext.rcx; | 128 | regs_[X86_64_REG_RCX] = ucontext->uc_mcontext.rcx; |
119 | regs_[X86_64_REG_RSP] = ucontext->uc_mcontext.rsp; | 129 | regs_[X86_64_REG_RSP] = ucontext->uc_mcontext.rsp; |
120 | regs_[X86_64_REG_RIP] = ucontext->uc_mcontext.rip; | 130 | regs_[X86_64_REG_RIP] = ucontext->uc_mcontext.rip; |
121 | |||
122 | SetFromRaw(); | ||
123 | } | 131 | } |
124 | 132 | ||
125 | Regs* RegsX86_64::CreateFromUcontext(void* ucontext) { | 133 | Regs* RegsX86_64::CreateFromUcontext(void* ucontext) { |
@@ -152,7 +160,7 @@ bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ | |||
152 | // Read the mcontext data from the stack. | 160 | // Read the mcontext data from the stack. |
153 | // sp points to the ucontext data structure, read only the mcontext part. | 161 | // sp points to the ucontext data structure, read only the mcontext part. |
154 | x86_64_ucontext_t x86_64_ucontext; | 162 | x86_64_ucontext_t x86_64_ucontext; |
155 | if (!process_memory->ReadFully(sp() + 0x28, &x86_64_ucontext.uc_mcontext, | 163 | if (!process_memory->ReadFully(regs_[X86_64_REG_SP] + 0x28, &x86_64_ucontext.uc_mcontext, |
156 | sizeof(x86_64_mcontext_t))) { | 164 | sizeof(x86_64_mcontext_t))) { |
157 | return false; | 165 | return false; |
158 | } | 166 | } |
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h index b0e7ea152..4bac47313 100644 --- a/libunwindstack/include/unwindstack/Regs.h +++ b/libunwindstack/include/unwindstack/Regs.h | |||
@@ -45,8 +45,8 @@ class Regs { | |||
45 | int16_t value; | 45 | int16_t value; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | Regs(uint16_t total_regs, uint16_t sp_reg, const Location& return_loc) | 48 | Regs(uint16_t total_regs, const Location& return_loc) |
49 | : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {} | 49 | : total_regs_(total_regs), return_loc_(return_loc) {} |
50 | virtual ~Regs() = default; | 50 | virtual ~Regs() = default; |
51 | 51 | ||
52 | virtual ArchEnum Arch() = 0; | 52 | virtual ArchEnum Arch() = 0; |
@@ -57,6 +57,9 @@ class Regs { | |||
57 | virtual uint64_t pc() = 0; | 57 | virtual uint64_t pc() = 0; |
58 | virtual uint64_t sp() = 0; | 58 | virtual uint64_t sp() = 0; |
59 | 59 | ||
60 | virtual void set_pc(uint64_t pc) = 0; | ||
61 | virtual void set_sp(uint64_t sp) = 0; | ||
62 | |||
60 | uint64_t dex_pc() { return dex_pc_; } | 63 | uint64_t dex_pc() { return dex_pc_; } |
61 | void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; } | 64 | void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; } |
62 | 65 | ||
@@ -64,13 +67,10 @@ class Regs { | |||
64 | 67 | ||
65 | virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0; | 68 | virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0; |
66 | 69 | ||
67 | virtual void SetFromRaw() = 0; | ||
68 | |||
69 | virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0; | 70 | virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0; |
70 | 71 | ||
71 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0; | 72 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0; |
72 | 73 | ||
73 | uint16_t sp_reg() { return sp_reg_; } | ||
74 | uint16_t total_regs() { return total_regs_; } | 74 | uint16_t total_regs() { return total_regs_; } |
75 | 75 | ||
76 | static ArchEnum CurrentArch(); | 76 | static ArchEnum CurrentArch(); |
@@ -80,7 +80,6 @@ class Regs { | |||
80 | 80 | ||
81 | protected: | 81 | protected: |
82 | uint16_t total_regs_; | 82 | uint16_t total_regs_; |
83 | uint16_t sp_reg_; | ||
84 | Location return_loc_; | 83 | Location return_loc_; |
85 | uint64_t dex_pc_ = 0; | 84 | uint64_t dex_pc_ = 0; |
86 | }; | 85 | }; |
@@ -88,16 +87,10 @@ class Regs { | |||
88 | template <typename AddressType> | 87 | template <typename AddressType> |
89 | class RegsImpl : public Regs { | 88 | class RegsImpl : public Regs { |
90 | public: | 89 | public: |
91 | RegsImpl(uint16_t total_regs, uint16_t sp_reg, Location return_loc) | 90 | RegsImpl(uint16_t total_regs, Location return_loc) |
92 | : Regs(total_regs, sp_reg, return_loc), regs_(total_regs) {} | 91 | : Regs(total_regs, return_loc), regs_(total_regs) {} |
93 | virtual ~RegsImpl() = default; | 92 | virtual ~RegsImpl() = default; |
94 | 93 | ||
95 | uint64_t pc() override { return pc_; } | ||
96 | uint64_t sp() override { return sp_; } | ||
97 | |||
98 | void set_pc(AddressType pc) { pc_ = pc; } | ||
99 | void set_sp(AddressType sp) { sp_ = sp; } | ||
100 | |||
101 | bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); } | 94 | bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); } |
102 | 95 | ||
103 | inline AddressType& operator[](size_t reg) { return regs_[reg]; } | 96 | inline AddressType& operator[](size_t reg) { return regs_[reg]; } |
@@ -111,8 +104,6 @@ class RegsImpl : public Regs { | |||
111 | } | 104 | } |
112 | 105 | ||
113 | protected: | 106 | protected: |
114 | AddressType pc_; | ||
115 | AddressType sp_; | ||
116 | std::vector<AddressType> regs_; | 107 | std::vector<AddressType> regs_; |
117 | }; | 108 | }; |
118 | 109 | ||
diff --git a/libunwindstack/include/unwindstack/RegsArm.h b/libunwindstack/include/unwindstack/RegsArm.h index 5af90d3f5..31e6797fa 100644 --- a/libunwindstack/include/unwindstack/RegsArm.h +++ b/libunwindstack/include/unwindstack/RegsArm.h | |||
@@ -34,17 +34,21 @@ class RegsArm : public RegsImpl<uint32_t> { | |||
34 | RegsArm(); | 34 | RegsArm(); |
35 | virtual ~RegsArm() = default; | 35 | virtual ~RegsArm() = default; |
36 | 36 | ||
37 | virtual ArchEnum Arch() override final; | 37 | ArchEnum Arch() override final; |
38 | 38 | ||
39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
40 | 40 | ||
41 | void SetFromRaw() override; | ||
42 | |||
43 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 41 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
44 | 42 | ||
45 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 43 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
46 | 44 | ||
47 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 45 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
46 | |||
47 | uint64_t pc() override; | ||
48 | uint64_t sp() override; | ||
49 | |||
50 | void set_pc(uint64_t pc) override; | ||
51 | void set_sp(uint64_t sp) override; | ||
48 | 52 | ||
49 | static Regs* Read(void* data); | 53 | static Regs* Read(void* data); |
50 | 54 | ||
diff --git a/libunwindstack/include/unwindstack/RegsArm64.h b/libunwindstack/include/unwindstack/RegsArm64.h index cb05732ee..0c45ebab8 100644 --- a/libunwindstack/include/unwindstack/RegsArm64.h +++ b/libunwindstack/include/unwindstack/RegsArm64.h | |||
@@ -34,17 +34,21 @@ class RegsArm64 : public RegsImpl<uint64_t> { | |||
34 | RegsArm64(); | 34 | RegsArm64(); |
35 | virtual ~RegsArm64() = default; | 35 | virtual ~RegsArm64() = default; |
36 | 36 | ||
37 | virtual ArchEnum Arch() override final; | 37 | ArchEnum Arch() override final; |
38 | 38 | ||
39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
40 | 40 | ||
41 | void SetFromRaw() override; | ||
42 | |||
43 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 41 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
44 | 42 | ||
45 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 43 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
46 | 44 | ||
47 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 45 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
46 | |||
47 | uint64_t pc() override; | ||
48 | uint64_t sp() override; | ||
49 | |||
50 | void set_pc(uint64_t pc) override; | ||
51 | void set_sp(uint64_t sp) override; | ||
48 | 52 | ||
49 | static Regs* Read(void* data); | 53 | static Regs* Read(void* data); |
50 | 54 | ||
diff --git a/libunwindstack/include/unwindstack/RegsGetLocal.h b/libunwindstack/include/unwindstack/RegsGetLocal.h index 557eace32..81c0af374 100644 --- a/libunwindstack/include/unwindstack/RegsGetLocal.h +++ b/libunwindstack/include/unwindstack/RegsGetLocal.h | |||
@@ -51,8 +51,6 @@ inline __always_inline void RegsGetLocal(Regs* regs) { | |||
51 | : [base] "+r"(reg_data) | 51 | : [base] "+r"(reg_data) |
52 | : | 52 | : |
53 | : "memory"); | 53 | : "memory"); |
54 | |||
55 | regs->SetFromRaw(); | ||
56 | } | 54 | } |
57 | 55 | ||
58 | #elif defined(__aarch64__) | 56 | #elif defined(__aarch64__) |
@@ -83,8 +81,6 @@ inline __always_inline void RegsGetLocal(Regs* regs) { | |||
83 | : [base] "+r"(reg_data) | 81 | : [base] "+r"(reg_data) |
84 | : | 82 | : |
85 | : "x12", "x13", "memory"); | 83 | : "x12", "x13", "memory"); |
86 | |||
87 | regs->SetFromRaw(); | ||
88 | } | 84 | } |
89 | 85 | ||
90 | #elif defined(__i386__) || defined(__x86_64__) || defined(__mips__) | 86 | #elif defined(__i386__) || defined(__x86_64__) || defined(__mips__) |
@@ -93,8 +89,6 @@ extern "C" void AsmGetRegs(void* regs); | |||
93 | 89 | ||
94 | inline void RegsGetLocal(Regs* regs) { | 90 | inline void RegsGetLocal(Regs* regs) { |
95 | AsmGetRegs(regs->RawData()); | 91 | AsmGetRegs(regs->RawData()); |
96 | |||
97 | regs->SetFromRaw(); | ||
98 | } | 92 | } |
99 | 93 | ||
100 | #endif | 94 | #endif |
diff --git a/libunwindstack/include/unwindstack/RegsMips.h b/libunwindstack/include/unwindstack/RegsMips.h index 8e3c01f20..709f9e2c7 100644 --- a/libunwindstack/include/unwindstack/RegsMips.h +++ b/libunwindstack/include/unwindstack/RegsMips.h | |||
@@ -34,17 +34,21 @@ class RegsMips : public RegsImpl<uint32_t> { | |||
34 | RegsMips(); | 34 | RegsMips(); |
35 | virtual ~RegsMips() = default; | 35 | virtual ~RegsMips() = default; |
36 | 36 | ||
37 | virtual ArchEnum Arch() override final; | 37 | ArchEnum Arch() override final; |
38 | 38 | ||
39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
40 | 40 | ||
41 | void SetFromRaw() override; | ||
42 | |||
43 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 41 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
44 | 42 | ||
45 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 43 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
46 | 44 | ||
47 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 45 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
46 | |||
47 | uint64_t pc() override; | ||
48 | uint64_t sp() override; | ||
49 | |||
50 | void set_pc(uint64_t pc) override; | ||
51 | void set_sp(uint64_t sp) override; | ||
48 | 52 | ||
49 | static Regs* Read(void* data); | 53 | static Regs* Read(void* data); |
50 | 54 | ||
diff --git a/libunwindstack/include/unwindstack/RegsMips64.h b/libunwindstack/include/unwindstack/RegsMips64.h index 8c2d4437f..1de83ea9d 100644 --- a/libunwindstack/include/unwindstack/RegsMips64.h +++ b/libunwindstack/include/unwindstack/RegsMips64.h | |||
@@ -34,17 +34,21 @@ class RegsMips64 : public RegsImpl<uint64_t> { | |||
34 | RegsMips64(); | 34 | RegsMips64(); |
35 | virtual ~RegsMips64() = default; | 35 | virtual ~RegsMips64() = default; |
36 | 36 | ||
37 | virtual ArchEnum Arch() override final; | 37 | ArchEnum Arch() override final; |
38 | 38 | ||
39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 39 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
40 | 40 | ||
41 | void SetFromRaw() override; | ||
42 | |||
43 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 41 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
44 | 42 | ||
45 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 43 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
46 | 44 | ||
47 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 45 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
46 | |||
47 | uint64_t pc() override; | ||
48 | uint64_t sp() override; | ||
49 | |||
50 | void set_pc(uint64_t pc) override; | ||
51 | void set_sp(uint64_t sp) override; | ||
48 | 52 | ||
49 | static Regs* Read(void* data); | 53 | static Regs* Read(void* data); |
50 | 54 | ||
diff --git a/libunwindstack/include/unwindstack/RegsX86.h b/libunwindstack/include/unwindstack/RegsX86.h index 1bc145d97..586c9d85c 100644 --- a/libunwindstack/include/unwindstack/RegsX86.h +++ b/libunwindstack/include/unwindstack/RegsX86.h | |||
@@ -35,19 +35,23 @@ class RegsX86 : public RegsImpl<uint32_t> { | |||
35 | RegsX86(); | 35 | RegsX86(); |
36 | virtual ~RegsX86() = default; | 36 | virtual ~RegsX86() = default; |
37 | 37 | ||
38 | virtual ArchEnum Arch() override final; | 38 | ArchEnum Arch() override final; |
39 | 39 | ||
40 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 40 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
41 | 41 | ||
42 | void SetFromRaw() override; | ||
43 | |||
44 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 42 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
45 | 43 | ||
46 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 44 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
47 | 45 | ||
48 | void SetFromUcontext(x86_ucontext_t* ucontext); | 46 | void SetFromUcontext(x86_ucontext_t* ucontext); |
49 | 47 | ||
50 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 48 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
49 | |||
50 | uint64_t pc() override; | ||
51 | uint64_t sp() override; | ||
52 | |||
53 | void set_pc(uint64_t pc) override; | ||
54 | void set_sp(uint64_t sp) override; | ||
51 | 55 | ||
52 | static Regs* Read(void* data); | 56 | static Regs* Read(void* data); |
53 | 57 | ||
diff --git a/libunwindstack/include/unwindstack/RegsX86_64.h b/libunwindstack/include/unwindstack/RegsX86_64.h index 4cd45d4b9..061f479a0 100644 --- a/libunwindstack/include/unwindstack/RegsX86_64.h +++ b/libunwindstack/include/unwindstack/RegsX86_64.h | |||
@@ -35,19 +35,23 @@ class RegsX86_64 : public RegsImpl<uint64_t> { | |||
35 | RegsX86_64(); | 35 | RegsX86_64(); |
36 | virtual ~RegsX86_64() = default; | 36 | virtual ~RegsX86_64() = default; |
37 | 37 | ||
38 | virtual ArchEnum Arch() override final; | 38 | ArchEnum Arch() override final; |
39 | 39 | ||
40 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; | 40 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; |
41 | 41 | ||
42 | void SetFromRaw() override; | ||
43 | |||
44 | bool SetPcFromReturnAddress(Memory* process_memory) override; | 42 | bool SetPcFromReturnAddress(Memory* process_memory) override; |
45 | 43 | ||
46 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; | 44 | bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; |
47 | 45 | ||
48 | void SetFromUcontext(x86_64_ucontext_t* ucontext); | 46 | void SetFromUcontext(x86_64_ucontext_t* ucontext); |
49 | 47 | ||
50 | virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; | 48 | void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; |
49 | |||
50 | uint64_t pc() override; | ||
51 | uint64_t sp() override; | ||
52 | |||
53 | void set_pc(uint64_t pc) override; | ||
54 | void set_sp(uint64_t sp) override; | ||
51 | 55 | ||
52 | static Regs* Read(void* data); | 56 | static Regs* Read(void* data); |
53 | 57 | ||
diff --git a/libunwindstack/tests/DwarfOpTest.cpp b/libunwindstack/tests/DwarfOpTest.cpp index 6e15227b3..d424d5f43 100644 --- a/libunwindstack/tests/DwarfOpTest.cpp +++ b/libunwindstack/tests/DwarfOpTest.cpp | |||
@@ -1468,7 +1468,7 @@ TYPED_TEST_P(DwarfOpTest, op_breg) { | |||
1468 | } | 1468 | } |
1469 | this->op_memory_.SetMemory(0, opcode_buffer); | 1469 | this->op_memory_.SetMemory(0, opcode_buffer); |
1470 | 1470 | ||
1471 | RegsImplFake<TypeParam> regs(32, 10); | 1471 | RegsImplFake<TypeParam> regs(32); |
1472 | for (size_t i = 0; i < 32; i++) { | 1472 | for (size_t i = 0; i < 32; i++) { |
1473 | regs[i] = i + 10; | 1473 | regs[i] = i + 10; |
1474 | } | 1474 | } |
@@ -1499,7 +1499,7 @@ TYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) { | |||
1499 | }; | 1499 | }; |
1500 | this->op_memory_.SetMemory(0, opcode_buffer); | 1500 | this->op_memory_.SetMemory(0, opcode_buffer); |
1501 | 1501 | ||
1502 | RegsImplFake<TypeParam> regs(16, 10); | 1502 | RegsImplFake<TypeParam> regs(16); |
1503 | for (size_t i = 0; i < 16; i++) { | 1503 | for (size_t i = 0; i < 16; i++) { |
1504 | regs[i] = i + 10; | 1504 | regs[i] = i + 10; |
1505 | } | 1505 | } |
@@ -1526,7 +1526,7 @@ TYPED_TEST_P(DwarfOpTest, op_bregx) { | |||
1526 | 0x92, 0x80, 0x15, 0x80, 0x02}; | 1526 | 0x92, 0x80, 0x15, 0x80, 0x02}; |
1527 | this->op_memory_.SetMemory(0, opcode_buffer); | 1527 | this->op_memory_.SetMemory(0, opcode_buffer); |
1528 | 1528 | ||
1529 | RegsImplFake<TypeParam> regs(10, 10); | 1529 | RegsImplFake<TypeParam> regs(10); |
1530 | regs[5] = 0x45; | 1530 | regs[5] = 0x45; |
1531 | regs[6] = 0x190; | 1531 | regs[6] = 0x190; |
1532 | RegsInfo<TypeParam> regs_info(®s); | 1532 | RegsInfo<TypeParam> regs_info(®s); |
diff --git a/libunwindstack/tests/DwarfSectionImplTest.cpp b/libunwindstack/tests/DwarfSectionImplTest.cpp index 99f4d873f..c85764c78 100644 --- a/libunwindstack/tests/DwarfSectionImplTest.cpp +++ b/libunwindstack/tests/DwarfSectionImplTest.cpp | |||
@@ -92,7 +92,7 @@ TYPED_TEST_CASE_P(DwarfSectionImplTest); | |||
92 | 92 | ||
93 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { | 93 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { |
94 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 94 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
95 | RegsImplFake<TypeParam> regs(10, 9); | 95 | RegsImplFake<TypeParam> regs(10); |
96 | dwarf_loc_regs_t loc_regs; | 96 | dwarf_loc_regs_t loc_regs; |
97 | 97 | ||
98 | regs.set_pc(0x100); | 98 | regs.set_pc(0x100); |
@@ -108,7 +108,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { | |||
108 | 108 | ||
109 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { | 109 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { |
110 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 110 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
111 | RegsImplFake<TypeParam> regs(10, 9); | 111 | RegsImplFake<TypeParam> regs(10); |
112 | dwarf_loc_regs_t loc_regs; | 112 | dwarf_loc_regs_t loc_regs; |
113 | 113 | ||
114 | regs.set_pc(0x100); | 114 | regs.set_pc(0x100); |
@@ -124,7 +124,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { | |||
124 | 124 | ||
125 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { | 125 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { |
126 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 126 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
127 | RegsImplFake<TypeParam> regs(10, 9); | 127 | RegsImplFake<TypeParam> regs(10); |
128 | dwarf_loc_regs_t loc_regs; | 128 | dwarf_loc_regs_t loc_regs; |
129 | 129 | ||
130 | regs.set_pc(0x100); | 130 | regs.set_pc(0x100); |
@@ -142,7 +142,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { | |||
142 | 142 | ||
143 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { | 143 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { |
144 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 144 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
145 | RegsImplFake<TypeParam> regs(10, 9); | 145 | RegsImplFake<TypeParam> regs(10); |
146 | dwarf_loc_regs_t loc_regs; | 146 | dwarf_loc_regs_t loc_regs; |
147 | 147 | ||
148 | regs.set_pc(0x100); | 148 | regs.set_pc(0x100); |
@@ -160,7 +160,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { | |||
160 | 160 | ||
161 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { | 161 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { |
162 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 162 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
163 | RegsImplFake<TypeParam> regs(10, 9); | 163 | RegsImplFake<TypeParam> regs(10); |
164 | dwarf_loc_regs_t loc_regs; | 164 | dwarf_loc_regs_t loc_regs; |
165 | 165 | ||
166 | regs.set_pc(0x100); | 166 | regs.set_pc(0x100); |
@@ -176,7 +176,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { | |||
176 | 176 | ||
177 | TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { | 177 | TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { |
178 | DwarfCie cie{.return_address_register = 60}; | 178 | DwarfCie cie{.return_address_register = 60}; |
179 | RegsImplFake<TypeParam> regs(10, 9); | 179 | RegsImplFake<TypeParam> regs(10); |
180 | dwarf_loc_regs_t loc_regs; | 180 | dwarf_loc_regs_t loc_regs; |
181 | 181 | ||
182 | bool finished; | 182 | bool finished; |
@@ -186,7 +186,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { | |||
186 | 186 | ||
187 | TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { | 187 | TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { |
188 | DwarfCie cie{.return_address_register = 5}; | 188 | DwarfCie cie{.return_address_register = 5}; |
189 | RegsImplFake<TypeParam> regs(10, 9); | 189 | RegsImplFake<TypeParam> regs(10); |
190 | dwarf_loc_regs_t loc_regs; | 190 | dwarf_loc_regs_t loc_regs; |
191 | 191 | ||
192 | bool finished; | 192 | bool finished; |
@@ -196,7 +196,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { | |||
196 | 196 | ||
197 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { | 197 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { |
198 | DwarfCie cie{.return_address_register = 5}; | 198 | DwarfCie cie{.return_address_register = 5}; |
199 | RegsImplFake<TypeParam> regs(10, 9); | 199 | RegsImplFake<TypeParam> regs(10); |
200 | dwarf_loc_regs_t loc_regs; | 200 | dwarf_loc_regs_t loc_regs; |
201 | 201 | ||
202 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}}; | 202 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}}; |
@@ -225,7 +225,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { | |||
225 | 225 | ||
226 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { | 226 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { |
227 | DwarfCie cie{.return_address_register = 5}; | 227 | DwarfCie cie{.return_address_register = 5}; |
228 | RegsImplFake<TypeParam> regs(10, 9); | 228 | RegsImplFake<TypeParam> regs(10); |
229 | dwarf_loc_regs_t loc_regs; | 229 | dwarf_loc_regs_t loc_regs; |
230 | 230 | ||
231 | regs.set_pc(0x100); | 231 | regs.set_pc(0x100); |
@@ -237,12 +237,12 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { | |||
237 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 237 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); |
238 | EXPECT_FALSE(finished); | 238 | EXPECT_FALSE(finished); |
239 | EXPECT_EQ(0x20U, regs.pc()); | 239 | EXPECT_EQ(0x20U, regs.pc()); |
240 | EXPECT_EQ(0x2000U, regs.sp()); | 240 | EXPECT_EQ(0x3000U, regs.sp()); |
241 | } | 241 | } |
242 | 242 | ||
243 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { | 243 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { |
244 | DwarfCie cie{.return_address_register = 5}; | 244 | DwarfCie cie{.return_address_register = 5}; |
245 | RegsImplFake<TypeParam> regs(10, 9); | 245 | RegsImplFake<TypeParam> regs(10); |
246 | dwarf_loc_regs_t loc_regs; | 246 | dwarf_loc_regs_t loc_regs; |
247 | 247 | ||
248 | regs.set_pc(0x100); | 248 | regs.set_pc(0x100); |
@@ -260,7 +260,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { | |||
260 | 260 | ||
261 | TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { | 261 | TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { |
262 | DwarfCie cie{.return_address_register = 5}; | 262 | DwarfCie cie{.return_address_register = 5}; |
263 | RegsImplFake<TypeParam> regs(10, 9); | 263 | RegsImplFake<TypeParam> regs(10); |
264 | dwarf_loc_regs_t loc_regs; | 264 | dwarf_loc_regs_t loc_regs; |
265 | 265 | ||
266 | regs.set_pc(0x100); | 266 | regs.set_pc(0x100); |
@@ -281,7 +281,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { | |||
281 | 281 | ||
282 | TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { | 282 | TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { |
283 | DwarfCie cie{.return_address_register = 5}; | 283 | DwarfCie cie{.return_address_register = 5}; |
284 | RegsImplFake<TypeParam> regs(10, 9); | 284 | RegsImplFake<TypeParam> regs(10); |
285 | dwarf_loc_regs_t loc_regs; | 285 | dwarf_loc_regs_t loc_regs; |
286 | 286 | ||
287 | regs.set_pc(0x100); | 287 | regs.set_pc(0x100); |
@@ -312,7 +312,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { | |||
312 | 312 | ||
313 | TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { | 313 | TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { |
314 | DwarfCie cie{.return_address_register = 5}; | 314 | DwarfCie cie{.return_address_register = 5}; |
315 | RegsImplFake<TypeParam> regs(10, 9); | 315 | RegsImplFake<TypeParam> regs(10); |
316 | dwarf_loc_regs_t loc_regs; | 316 | dwarf_loc_regs_t loc_regs; |
317 | 317 | ||
318 | regs.set_pc(0x100); | 318 | regs.set_pc(0x100); |
@@ -331,7 +331,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { | |||
331 | 331 | ||
332 | TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { | 332 | TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { |
333 | DwarfCie cie{.return_address_register = 5}; | 333 | DwarfCie cie{.return_address_register = 5}; |
334 | RegsImplFake<TypeParam> regs(10, 9); | 334 | RegsImplFake<TypeParam> regs(10); |
335 | dwarf_loc_regs_t loc_regs; | 335 | dwarf_loc_regs_t loc_regs; |
336 | 336 | ||
337 | regs.set_pc(0x100); | 337 | regs.set_pc(0x100); |
@@ -346,7 +346,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { | |||
346 | 346 | ||
347 | TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { | 347 | TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { |
348 | DwarfCie cie{.return_address_register = 5}; | 348 | DwarfCie cie{.return_address_register = 5}; |
349 | RegsImplFake<TypeParam> regs(10, 9); | 349 | RegsImplFake<TypeParam> regs(10); |
350 | dwarf_loc_regs_t loc_regs; | 350 | dwarf_loc_regs_t loc_regs; |
351 | 351 | ||
352 | if (sizeof(TypeParam) == sizeof(uint64_t)) { | 352 | if (sizeof(TypeParam) == sizeof(uint64_t)) { |
@@ -380,7 +380,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { | |||
380 | 380 | ||
381 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { | 381 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { |
382 | DwarfCie cie{.return_address_register = 5}; | 382 | DwarfCie cie{.return_address_register = 5}; |
383 | RegsImplFake<TypeParam> regs(10, 9); | 383 | RegsImplFake<TypeParam> regs(10); |
384 | dwarf_loc_regs_t loc_regs; | 384 | dwarf_loc_regs_t loc_regs; |
385 | 385 | ||
386 | regs.set_pc(0x100); | 386 | regs.set_pc(0x100); |
@@ -398,7 +398,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { | |||
398 | 398 | ||
399 | TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { | 399 | TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { |
400 | DwarfCie cie{.return_address_register = 5}; | 400 | DwarfCie cie{.return_address_register = 5}; |
401 | RegsImplFake<TypeParam> regs(10, 9); | 401 | RegsImplFake<TypeParam> regs(10); |
402 | dwarf_loc_regs_t loc_regs; | 402 | dwarf_loc_regs_t loc_regs; |
403 | 403 | ||
404 | regs.set_pc(0x100); | 404 | regs.set_pc(0x100); |
@@ -415,7 +415,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { | |||
415 | 415 | ||
416 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { | 416 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { |
417 | DwarfCie cie{.return_address_register = 5}; | 417 | DwarfCie cie{.return_address_register = 5}; |
418 | RegsImplFake<TypeParam> regs(10, 9); | 418 | RegsImplFake<TypeParam> regs(10); |
419 | dwarf_loc_regs_t loc_regs; | 419 | dwarf_loc_regs_t loc_regs; |
420 | 420 | ||
421 | regs.set_pc(0x100); | 421 | regs.set_pc(0x100); |
@@ -432,7 +432,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { | |||
432 | 432 | ||
433 | TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { | 433 | TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { |
434 | DwarfCie cie{.return_address_register = 5}; | 434 | DwarfCie cie{.return_address_register = 5}; |
435 | RegsImplFake<TypeParam> regs(10, 9); | 435 | RegsImplFake<TypeParam> regs(10); |
436 | dwarf_loc_regs_t loc_regs; | 436 | dwarf_loc_regs_t loc_regs; |
437 | 437 | ||
438 | regs.set_pc(0x100); | 438 | regs.set_pc(0x100); |
@@ -451,7 +451,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { | |||
451 | 451 | ||
452 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { | 452 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { |
453 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 453 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
454 | RegsImplFake<TypeParam> regs(10, 9); | 454 | RegsImplFake<TypeParam> regs(10); |
455 | dwarf_loc_regs_t loc_regs; | 455 | dwarf_loc_regs_t loc_regs; |
456 | 456 | ||
457 | regs.set_pc(0x100); | 457 | regs.set_pc(0x100); |
@@ -471,7 +471,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { | |||
471 | 471 | ||
472 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) { | 472 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) { |
473 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 473 | DwarfCie cie{.version = 3, .return_address_register = 5}; |
474 | RegsImplFake<TypeParam> regs(10, 9); | 474 | RegsImplFake<TypeParam> regs(10); |
475 | dwarf_loc_regs_t loc_regs; | 475 | dwarf_loc_regs_t loc_regs; |
476 | 476 | ||
477 | regs.set_pc(0x100); | 477 | regs.set_pc(0x100); |
diff --git a/libunwindstack/tests/ElfFake.cpp b/libunwindstack/tests/ElfFake.cpp index ae9da5eb4..66207dbd1 100644 --- a/libunwindstack/tests/ElfFake.cpp +++ b/libunwindstack/tests/ElfFake.cpp | |||
@@ -65,8 +65,8 @@ bool ElfInterfaceFake::Step(uint64_t, uint64_t, Regs* regs, Memory*, bool* finis | |||
65 | } | 65 | } |
66 | 66 | ||
67 | RegsFake* fake_regs = reinterpret_cast<RegsFake*>(regs); | 67 | RegsFake* fake_regs = reinterpret_cast<RegsFake*>(regs); |
68 | fake_regs->FakeSetPc(entry.pc); | 68 | fake_regs->set_pc(entry.pc); |
69 | fake_regs->FakeSetSp(entry.sp); | 69 | fake_regs->set_sp(entry.sp); |
70 | *finished = entry.finished; | 70 | *finished = entry.finished; |
71 | return true; | 71 | return true; |
72 | } | 72 | } |
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp index eb850336b..f9028c4a5 100644 --- a/libunwindstack/tests/ElfTest.cpp +++ b/libunwindstack/tests/ElfTest.cpp | |||
@@ -316,7 +316,6 @@ TEST_F(ElfTest, step_in_signal_map) { | |||
316 | RegsArm regs; | 316 | RegsArm regs; |
317 | regs[13] = 0x50000; | 317 | regs[13] = 0x50000; |
318 | regs[15] = 0x8000; | 318 | regs[15] = 0x8000; |
319 | regs.SetFromRaw(); | ||
320 | 319 | ||
321 | ElfInterfaceFake* interface = new ElfInterfaceFake(memory_); | 320 | ElfInterfaceFake* interface = new ElfInterfaceFake(memory_); |
322 | elf.FakeSetInterface(interface); | 321 | elf.FakeSetInterface(interface); |
diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h index ab23194e5..ede16b32b 100644 --- a/libunwindstack/tests/RegsFake.h +++ b/libunwindstack/tests/RegsFake.h | |||
@@ -27,14 +27,16 @@ namespace unwindstack { | |||
27 | 27 | ||
28 | class RegsFake : public Regs { | 28 | class RegsFake : public Regs { |
29 | public: | 29 | public: |
30 | RegsFake(uint16_t total_regs, uint16_t sp_reg) | 30 | RegsFake(uint16_t total_regs) : Regs(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} |
31 | : Regs(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} | ||
32 | virtual ~RegsFake() = default; | 31 | virtual ~RegsFake() = default; |
33 | 32 | ||
34 | ArchEnum Arch() override { return fake_arch_; } | 33 | ArchEnum Arch() override { return fake_arch_; } |
35 | void* RawData() override { return nullptr; } | 34 | void* RawData() override { return nullptr; } |
36 | uint64_t pc() override { return fake_pc_; } | 35 | uint64_t pc() override { return fake_pc_; } |
37 | uint64_t sp() override { return fake_sp_; } | 36 | uint64_t sp() override { return fake_sp_; } |
37 | void set_pc(uint64_t pc) override { fake_pc_ = pc; } | ||
38 | void set_sp(uint64_t sp) override { fake_sp_ = sp; } | ||
39 | |||
38 | bool SetPcFromReturnAddress(Memory*) override { | 40 | bool SetPcFromReturnAddress(Memory*) override { |
39 | if (!fake_return_address_valid_) { | 41 | if (!fake_return_address_valid_) { |
40 | return false; | 42 | return false; |
@@ -51,11 +53,7 @@ class RegsFake : public Regs { | |||
51 | 53 | ||
52 | bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } | 54 | bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } |
53 | 55 | ||
54 | void SetFromRaw() override {} | ||
55 | |||
56 | void FakeSetArch(ArchEnum arch) { fake_arch_ = arch; } | 56 | void FakeSetArch(ArchEnum arch) { fake_arch_ = arch; } |
57 | void FakeSetPc(uint64_t pc) { fake_pc_ = pc; } | ||
58 | void FakeSetSp(uint64_t sp) { fake_sp_ = sp; } | ||
59 | void FakeSetDexPc(uint64_t dex_pc) { dex_pc_ = dex_pc; } | 57 | void FakeSetDexPc(uint64_t dex_pc) { dex_pc_ = dex_pc; } |
60 | void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } | 58 | void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } |
61 | void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } | 59 | void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } |
@@ -71,19 +69,23 @@ class RegsFake : public Regs { | |||
71 | template <typename TypeParam> | 69 | template <typename TypeParam> |
72 | class RegsImplFake : public RegsImpl<TypeParam> { | 70 | class RegsImplFake : public RegsImpl<TypeParam> { |
73 | public: | 71 | public: |
74 | RegsImplFake(uint16_t total_regs, uint16_t sp_reg) | 72 | RegsImplFake(uint16_t total_regs) |
75 | : RegsImpl<TypeParam>(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} | 73 | : RegsImpl<TypeParam>(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} |
76 | virtual ~RegsImplFake() = default; | 74 | virtual ~RegsImplFake() = default; |
77 | 75 | ||
78 | ArchEnum Arch() override { return ARCH_UNKNOWN; } | 76 | ArchEnum Arch() override { return ARCH_UNKNOWN; } |
77 | uint64_t pc() override { return fake_pc_; } | ||
78 | uint64_t sp() override { return fake_sp_; } | ||
79 | void set_pc(uint64_t pc) override { fake_pc_ = pc; } | ||
80 | void set_sp(uint64_t sp) override { fake_sp_ = sp; } | ||
79 | 81 | ||
80 | uint64_t GetPcAdjustment(uint64_t, Elf*) override { return 0; } | 82 | uint64_t GetPcAdjustment(uint64_t, Elf*) override { return 0; } |
81 | void SetFromRaw() override {} | ||
82 | bool SetPcFromReturnAddress(Memory*) override { return false; } | 83 | bool SetPcFromReturnAddress(Memory*) override { return false; } |
83 | bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } | 84 | bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } |
84 | 85 | ||
85 | void FakeSetPc(uint64_t pc) { this->pc_ = pc; } | 86 | private: |
86 | void FakeSetSp(uint64_t sp) { this->sp_ = sp; } | 87 | uint64_t fake_pc_ = 0; |
88 | uint64_t fake_sp_ = 0; | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | } // namespace unwindstack | 91 | } // namespace unwindstack |
diff --git a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp index ecd40518b..eac12ca64 100644 --- a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp +++ b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp | |||
@@ -56,7 +56,6 @@ void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) | |||
56 | RegsArm regs; | 56 | RegsArm regs; |
57 | regs[ARM_REG_PC] = 0x5000; | 57 | regs[ARM_REG_PC] = 0x5000; |
58 | regs[ARM_REG_SP] = addr; | 58 | regs[ARM_REG_SP] = addr; |
59 | regs.SetFromRaw(); | ||
60 | 59 | ||
61 | elf_memory_->SetData32(0x5000, pc_data); | 60 | elf_memory_->SetData32(0x5000, pc_data); |
62 | 61 | ||
@@ -87,7 +86,6 @@ void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) { | |||
87 | RegsArm regs; | 86 | RegsArm regs; |
88 | regs[ARM_REG_PC] = 0x5000; | 87 | regs[ARM_REG_PC] = 0x5000; |
89 | regs[ARM_REG_SP] = addr; | 88 | regs[ARM_REG_SP] = addr; |
90 | regs.SetFromRaw(); | ||
91 | 89 | ||
92 | elf_memory_->SetData32(0x5000, pc_data); | 90 | elf_memory_->SetData32(0x5000, pc_data); |
93 | 91 | ||
@@ -118,7 +116,6 @@ TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) { | |||
118 | RegsArm64 regs; | 116 | RegsArm64 regs; |
119 | regs[ARM64_REG_PC] = 0x8000; | 117 | regs[ARM64_REG_PC] = 0x8000; |
120 | regs[ARM64_REG_SP] = addr; | 118 | regs[ARM64_REG_SP] = addr; |
121 | regs.SetFromRaw(); | ||
122 | 119 | ||
123 | elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL); | 120 | elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL); |
124 | 121 | ||
@@ -138,7 +135,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) { | |||
138 | RegsX86 regs; | 135 | RegsX86 regs; |
139 | regs[X86_REG_EIP] = 0x4100; | 136 | regs[X86_REG_EIP] = 0x4100; |
140 | regs[X86_REG_ESP] = addr; | 137 | regs[X86_REG_ESP] = addr; |
141 | regs.SetFromRaw(); | ||
142 | 138 | ||
143 | elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL); | 139 | elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL); |
144 | for (uint64_t index = 0; index <= 25; index++) { | 140 | for (uint64_t index = 0; index <= 25; index++) { |
@@ -162,7 +158,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) { | |||
162 | RegsX86 regs; | 158 | RegsX86 regs; |
163 | regs[X86_REG_EIP] = 0x4100; | 159 | regs[X86_REG_EIP] = 0x4100; |
164 | regs[X86_REG_ESP] = addr; | 160 | regs[X86_REG_ESP] = addr; |
165 | regs.SetFromRaw(); | ||
166 | 161 | ||
167 | elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL); | 162 | elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL); |
168 | addr += 8; | 163 | addr += 8; |
@@ -191,7 +186,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) { | |||
191 | RegsX86_64 regs; | 186 | RegsX86_64 regs; |
192 | regs[X86_64_REG_RIP] = 0x7000; | 187 | regs[X86_64_REG_RIP] = 0x7000; |
193 | regs[X86_64_REG_RSP] = addr; | 188 | regs[X86_64_REG_RSP] = addr; |
194 | regs.SetFromRaw(); | ||
195 | 189 | ||
196 | elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748); | 190 | elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748); |
197 | elf_memory_->SetData16(0x7008, 0x0f05); | 191 | elf_memory_->SetData16(0x7008, 0x0f05); |
@@ -212,7 +206,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_non_rt) { | |||
212 | RegsMips regs; | 206 | RegsMips regs; |
213 | regs[MIPS_REG_PC] = 0x8000; | 207 | regs[MIPS_REG_PC] = 0x8000; |
214 | regs[MIPS_REG_SP] = addr; | 208 | regs[MIPS_REG_SP] = addr; |
215 | regs.SetFromRaw(); | ||
216 | 209 | ||
217 | elf_memory_->SetData64(0x8000, 0x0000000c24021017ULL); | 210 | elf_memory_->SetData64(0x8000, 0x0000000c24021017ULL); |
218 | 211 | ||
@@ -232,7 +225,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_rt) { | |||
232 | RegsMips regs; | 225 | RegsMips regs; |
233 | regs[MIPS_REG_PC] = 0x8000; | 226 | regs[MIPS_REG_PC] = 0x8000; |
234 | regs[MIPS_REG_SP] = addr; | 227 | regs[MIPS_REG_SP] = addr; |
235 | regs.SetFromRaw(); | ||
236 | 228 | ||
237 | elf_memory_->SetData64(0x8000, 0x0000000c24021061ULL); | 229 | elf_memory_->SetData64(0x8000, 0x0000000c24021061ULL); |
238 | 230 | ||
@@ -252,7 +244,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips64_step_if_signal_handler) { | |||
252 | RegsMips64 regs; | 244 | RegsMips64 regs; |
253 | regs[MIPS64_REG_PC] = 0x8000; | 245 | regs[MIPS64_REG_PC] = 0x8000; |
254 | regs[MIPS64_REG_SP] = addr; | 246 | regs[MIPS64_REG_SP] = addr; |
255 | regs.SetFromRaw(); | ||
256 | 247 | ||
257 | elf_memory_->SetData64(0x8000, 0x0000000c2402145bULL); | 248 | elf_memory_->SetData64(0x8000, 0x0000000c2402145bULL); |
258 | 249 | ||
diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp index 8b2f6c83f..3e80733bf 100644 --- a/libunwindstack/tests/RegsTest.cpp +++ b/libunwindstack/tests/RegsTest.cpp | |||
@@ -49,9 +49,8 @@ class RegsTest : public ::testing::Test { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | TEST_F(RegsTest, regs32) { | 51 | TEST_F(RegsTest, regs32) { |
52 | RegsImplFake<uint32_t> regs32(50, 10); | 52 | RegsImplFake<uint32_t> regs32(50); |
53 | ASSERT_EQ(50U, regs32.total_regs()); | 53 | ASSERT_EQ(50U, regs32.total_regs()); |
54 | ASSERT_EQ(10U, regs32.sp_reg()); | ||
55 | 54 | ||
56 | uint32_t* raw = reinterpret_cast<uint32_t*>(regs32.RawData()); | 55 | uint32_t* raw = reinterpret_cast<uint32_t*>(regs32.RawData()); |
57 | for (size_t i = 0; i < 50; i++) { | 56 | for (size_t i = 0; i < 50; i++) { |
@@ -72,9 +71,8 @@ TEST_F(RegsTest, regs32) { | |||
72 | } | 71 | } |
73 | 72 | ||
74 | TEST_F(RegsTest, regs64) { | 73 | TEST_F(RegsTest, regs64) { |
75 | RegsImplFake<uint64_t> regs64(30, 12); | 74 | RegsImplFake<uint64_t> regs64(30); |
76 | ASSERT_EQ(30U, regs64.total_regs()); | 75 | ASSERT_EQ(30U, regs64.total_regs()); |
77 | ASSERT_EQ(12U, regs64.sp_reg()); | ||
78 | 76 | ||
79 | uint64_t* raw = reinterpret_cast<uint64_t*>(regs64.RawData()); | 77 | uint64_t* raw = reinterpret_cast<uint64_t*>(regs64.RawData()); |
80 | for (size_t i = 0; i < 30; i++) { | 78 | for (size_t i = 0; i < 30; i++) { |
@@ -211,62 +209,56 @@ TEST_F(RegsTest, elf_invalid) { | |||
211 | EXPECT_EQ(0U, regs_mips64.GetPcAdjustment(0xa00U, invalid_elf)); | 209 | EXPECT_EQ(0U, regs_mips64.GetPcAdjustment(0xa00U, invalid_elf)); |
212 | } | 210 | } |
213 | 211 | ||
214 | TEST_F(RegsTest, arm_set_from_raw) { | 212 | TEST_F(RegsTest, arm_verify_sp_pc) { |
215 | RegsArm arm; | 213 | RegsArm arm; |
216 | uint32_t* regs = reinterpret_cast<uint32_t*>(arm.RawData()); | 214 | uint32_t* regs = reinterpret_cast<uint32_t*>(arm.RawData()); |
217 | regs[13] = 0x100; | 215 | regs[13] = 0x100; |
218 | regs[15] = 0x200; | 216 | regs[15] = 0x200; |
219 | arm.SetFromRaw(); | ||
220 | EXPECT_EQ(0x100U, arm.sp()); | 217 | EXPECT_EQ(0x100U, arm.sp()); |
221 | EXPECT_EQ(0x200U, arm.pc()); | 218 | EXPECT_EQ(0x200U, arm.pc()); |
222 | } | 219 | } |
223 | 220 | ||
224 | TEST_F(RegsTest, arm64_set_from_raw) { | 221 | TEST_F(RegsTest, arm64_verify_sp_pc) { |
225 | RegsArm64 arm64; | 222 | RegsArm64 arm64; |
226 | uint64_t* regs = reinterpret_cast<uint64_t*>(arm64.RawData()); | 223 | uint64_t* regs = reinterpret_cast<uint64_t*>(arm64.RawData()); |
227 | regs[31] = 0xb100000000ULL; | 224 | regs[31] = 0xb100000000ULL; |
228 | regs[32] = 0xc200000000ULL; | 225 | regs[32] = 0xc200000000ULL; |
229 | arm64.SetFromRaw(); | ||
230 | EXPECT_EQ(0xb100000000U, arm64.sp()); | 226 | EXPECT_EQ(0xb100000000U, arm64.sp()); |
231 | EXPECT_EQ(0xc200000000U, arm64.pc()); | 227 | EXPECT_EQ(0xc200000000U, arm64.pc()); |
232 | } | 228 | } |
233 | 229 | ||
234 | TEST_F(RegsTest, x86_set_from_raw) { | 230 | TEST_F(RegsTest, x86_verify_sp_pc) { |
235 | RegsX86 x86; | 231 | RegsX86 x86; |
236 | uint32_t* regs = reinterpret_cast<uint32_t*>(x86.RawData()); | 232 | uint32_t* regs = reinterpret_cast<uint32_t*>(x86.RawData()); |
237 | regs[4] = 0x23450000; | 233 | regs[4] = 0x23450000; |
238 | regs[8] = 0xabcd0000; | 234 | regs[8] = 0xabcd0000; |
239 | x86.SetFromRaw(); | ||
240 | EXPECT_EQ(0x23450000U, x86.sp()); | 235 | EXPECT_EQ(0x23450000U, x86.sp()); |
241 | EXPECT_EQ(0xabcd0000U, x86.pc()); | 236 | EXPECT_EQ(0xabcd0000U, x86.pc()); |
242 | } | 237 | } |
243 | 238 | ||
244 | TEST_F(RegsTest, x86_64_set_from_raw) { | 239 | TEST_F(RegsTest, x86_64_verify_sp_pc) { |
245 | RegsX86_64 x86_64; | 240 | RegsX86_64 x86_64; |
246 | uint64_t* regs = reinterpret_cast<uint64_t*>(x86_64.RawData()); | 241 | uint64_t* regs = reinterpret_cast<uint64_t*>(x86_64.RawData()); |
247 | regs[7] = 0x1200000000ULL; | 242 | regs[7] = 0x1200000000ULL; |
248 | regs[16] = 0x4900000000ULL; | 243 | regs[16] = 0x4900000000ULL; |
249 | x86_64.SetFromRaw(); | ||
250 | EXPECT_EQ(0x1200000000U, x86_64.sp()); | 244 | EXPECT_EQ(0x1200000000U, x86_64.sp()); |
251 | EXPECT_EQ(0x4900000000U, x86_64.pc()); | 245 | EXPECT_EQ(0x4900000000U, x86_64.pc()); |
252 | } | 246 | } |
253 | 247 | ||
254 | TEST_F(RegsTest, mips_set_from_raw) { | 248 | TEST_F(RegsTest, mips_verify_sp_pc) { |
255 | RegsMips mips; | 249 | RegsMips mips; |
256 | uint32_t* regs = reinterpret_cast<uint32_t*>(mips.RawData()); | 250 | uint32_t* regs = reinterpret_cast<uint32_t*>(mips.RawData()); |
257 | regs[29] = 0x100; | 251 | regs[29] = 0x100; |
258 | regs[32] = 0x200; | 252 | regs[32] = 0x200; |
259 | mips.SetFromRaw(); | ||
260 | EXPECT_EQ(0x100U, mips.sp()); | 253 | EXPECT_EQ(0x100U, mips.sp()); |
261 | EXPECT_EQ(0x200U, mips.pc()); | 254 | EXPECT_EQ(0x200U, mips.pc()); |
262 | } | 255 | } |
263 | 256 | ||
264 | TEST_F(RegsTest, mips64_set_from_raw) { | 257 | TEST_F(RegsTest, mips64_verify_sp_pc) { |
265 | RegsMips64 mips64; | 258 | RegsMips64 mips64; |
266 | uint64_t* regs = reinterpret_cast<uint64_t*>(mips64.RawData()); | 259 | uint64_t* regs = reinterpret_cast<uint64_t*>(mips64.RawData()); |
267 | regs[29] = 0xb100000000ULL; | 260 | regs[29] = 0xb100000000ULL; |
268 | regs[32] = 0xc200000000ULL; | 261 | regs[32] = 0xc200000000ULL; |
269 | mips64.SetFromRaw(); | ||
270 | EXPECT_EQ(0xb100000000U, mips64.sp()); | 262 | EXPECT_EQ(0xb100000000U, mips64.sp()); |
271 | EXPECT_EQ(0xc200000000U, mips64.pc()); | 263 | EXPECT_EQ(0xc200000000U, mips64.pc()); |
272 | } | 264 | } |
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp index 515bc8cc7..532640f38 100644 --- a/libunwindstack/tests/UnwindOfflineTest.cpp +++ b/libunwindstack/tests/UnwindOfflineTest.cpp | |||
@@ -122,7 +122,6 @@ class UnwindOfflineTest : public ::testing::Test { | |||
122 | (*regs)[entry->second] = value; | 122 | (*regs)[entry->second] = value; |
123 | } | 123 | } |
124 | fclose(fp); | 124 | fclose(fp); |
125 | regs->SetFromRaw(); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | static std::unordered_map<std::string, uint32_t> arm_regs_; | 127 | static std::unordered_map<std::string, uint32_t> arm_regs_; |
@@ -956,4 +955,119 @@ TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) { | |||
956 | EXPECT_EQ(0x7ffcc85971a0U, unwinder.frames()[4].sp); | 955 | EXPECT_EQ(0x7ffcc85971a0U, unwinder.frames()[4].sp); |
957 | } | 956 | } |
958 | 957 | ||
958 | TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) { | ||
959 | Init("art_quick_osr_stub_arm/", ARCH_ARM); | ||
960 | |||
961 | MemoryOfflineParts* memory = new MemoryOfflineParts; | ||
962 | AddMemory(dir_ + "descriptor.data", memory); | ||
963 | AddMemory(dir_ + "stack.data", memory); | ||
964 | for (size_t i = 0; i < 2; i++) { | ||
965 | AddMemory(dir_ + "entry" + std::to_string(i) + ".data", memory); | ||
966 | AddMemory(dir_ + "jit" + std::to_string(i) + ".data", memory); | ||
967 | } | ||
968 | process_memory_.reset(memory); | ||
969 | |||
970 | JitDebug jit_debug(process_memory_); | ||
971 | Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); | ||
972 | unwinder.SetJitDebug(&jit_debug, regs_->Arch()); | ||
973 | unwinder.Unwind(); | ||
974 | |||
975 | std::string frame_info(DumpFrames(unwinder)); | ||
976 | ASSERT_EQ(25U, unwinder.NumFrames()) << "Unwind:\n" << frame_info; | ||
977 | EXPECT_EQ( | ||
978 | " #00 pc 0000c788 <anonymous:d0250000> " | ||
979 | "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity.access$000)\n" | ||
980 | " #01 pc 0000cdd5 <anonymous:d0250000> " | ||
981 | "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run+60)\n" | ||
982 | " #02 pc 004135bb libart.so (art_quick_osr_stub+42)\n" | ||
983 | " #03 pc 002657a5 libart.so " | ||
984 | "(_ZN3art3jit3Jit25MaybeDoOnStackReplacementEPNS_6ThreadEPNS_9ArtMethodEjiPNS_6JValueE+876)\n" | ||
985 | " #04 pc 004021a7 libart.so (MterpMaybeDoOnStackReplacement+86)\n" | ||
986 | " #05 pc 00412474 libart.so (ExecuteMterpImpl+66164)\n" | ||
987 | " #06 pc cd8365b0 <unknown>\n" // symbol in dex file | ||
988 | " #07 pc 001d7f1b libart.so " | ||
989 | "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_" | ||
990 | "6JValueEb+374)\n" | ||
991 | " #08 pc 001dc593 libart.so " | ||
992 | "(_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadERKNS_" | ||
993 | "20CodeItemDataAccessorEPNS_11ShadowFrameEPNS_6JValueE+154)\n" | ||
994 | " #09 pc 001f4d01 libart.so " | ||
995 | "(_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_" | ||
996 | "11InstructionEtPNS_6JValueE+732)\n" | ||
997 | " #10 pc 003fe427 libart.so (MterpInvokeInterface+1354)\n" | ||
998 | " #11 pc 00405b94 libart.so (ExecuteMterpImpl+14740)\n" | ||
999 | " #12 pc 7004873e <unknown>\n" // symbol in dex file | ||
1000 | " #13 pc 001d7f1b libart.so " | ||
1001 | "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_" | ||
1002 | "6JValueEb+374)\n" | ||
1003 | " #14 pc 001dc4d5 libart.so " | ||
1004 | "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_" | ||
1005 | "20CodeItemDataAccessorEPNS_11ShadowFrameE+92)\n" | ||
1006 | " #15 pc 003f25ab libart.so (artQuickToInterpreterBridge+970)\n" | ||
1007 | " #16 pc 00417aff libart.so (art_quick_to_interpreter_bridge+30)\n" | ||
1008 | " #17 pc 00413575 libart.so (art_quick_invoke_stub_internal+68)\n" | ||
1009 | " #18 pc 00418531 libart.so (art_quick_invoke_stub+236)\n" | ||
1010 | " #19 pc 000b468d libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+136)\n" | ||
1011 | " #20 pc 00362f49 libart.so " | ||
1012 | "(_ZN3art12_GLOBAL__N_118InvokeWithArgArrayERKNS_33ScopedObjectAccessAlreadyRunnableEPNS_" | ||
1013 | "9ArtMethodEPNS0_8ArgArrayEPNS_6JValueEPKc+52)\n" | ||
1014 | " #21 pc 00363cd9 libart.so " | ||
1015 | "(_ZN3art35InvokeVirtualOrInterfaceWithJValuesERKNS_33ScopedObjectAccessAlreadyRunnableEP8_" | ||
1016 | "jobjectP10_jmethodIDP6jvalue+332)\n" | ||
1017 | " #22 pc 003851dd libart.so (_ZN3art6Thread14CreateCallbackEPv+868)\n" | ||
1018 | " #23 pc 00062925 libc.so (_ZL15__pthread_startPv+22)\n" | ||
1019 | " #24 pc 0001de39 libc.so (__start_thread+24)\n", | ||
1020 | frame_info); | ||
1021 | EXPECT_EQ(0xd025c788U, unwinder.frames()[0].pc); | ||
1022 | EXPECT_EQ(0xcd4ff140U, unwinder.frames()[0].sp); | ||
1023 | EXPECT_EQ(0xd025cdd5U, unwinder.frames()[1].pc); | ||
1024 | EXPECT_EQ(0xcd4ff140U, unwinder.frames()[1].sp); | ||
1025 | EXPECT_EQ(0xe4a755bbU, unwinder.frames()[2].pc); | ||
1026 | EXPECT_EQ(0xcd4ff160U, unwinder.frames()[2].sp); | ||
1027 | EXPECT_EQ(0xe48c77a5U, unwinder.frames()[3].pc); | ||
1028 | EXPECT_EQ(0xcd4ff190U, unwinder.frames()[3].sp); | ||
1029 | EXPECT_EQ(0xe4a641a7U, unwinder.frames()[4].pc); | ||
1030 | EXPECT_EQ(0xcd4ff298U, unwinder.frames()[4].sp); | ||
1031 | EXPECT_EQ(0xe4a74474U, unwinder.frames()[5].pc); | ||
1032 | EXPECT_EQ(0xcd4ff2b8U, unwinder.frames()[5].sp); | ||
1033 | EXPECT_EQ(0xcd8365b0U, unwinder.frames()[6].pc); | ||
1034 | EXPECT_EQ(0xcd4ff2e0U, unwinder.frames()[6].sp); | ||
1035 | EXPECT_EQ(0xe4839f1bU, unwinder.frames()[7].pc); | ||
1036 | EXPECT_EQ(0xcd4ff2e0U, unwinder.frames()[7].sp); | ||
1037 | EXPECT_EQ(0xe483e593U, unwinder.frames()[8].pc); | ||
1038 | EXPECT_EQ(0xcd4ff330U, unwinder.frames()[8].sp); | ||
1039 | EXPECT_EQ(0xe4856d01U, unwinder.frames()[9].pc); | ||
1040 | EXPECT_EQ(0xcd4ff380U, unwinder.frames()[9].sp); | ||
1041 | EXPECT_EQ(0xe4a60427U, unwinder.frames()[10].pc); | ||
1042 | EXPECT_EQ(0xcd4ff430U, unwinder.frames()[10].sp); | ||
1043 | EXPECT_EQ(0xe4a67b94U, unwinder.frames()[11].pc); | ||
1044 | EXPECT_EQ(0xcd4ff498U, unwinder.frames()[11].sp); | ||
1045 | EXPECT_EQ(0x7004873eU, unwinder.frames()[12].pc); | ||
1046 | EXPECT_EQ(0xcd4ff4c0U, unwinder.frames()[12].sp); | ||
1047 | EXPECT_EQ(0xe4839f1bU, unwinder.frames()[13].pc); | ||
1048 | EXPECT_EQ(0xcd4ff4c0U, unwinder.frames()[13].sp); | ||
1049 | EXPECT_EQ(0xe483e4d5U, unwinder.frames()[14].pc); | ||
1050 | EXPECT_EQ(0xcd4ff510U, unwinder.frames()[14].sp); | ||
1051 | EXPECT_EQ(0xe4a545abU, unwinder.frames()[15].pc); | ||
1052 | EXPECT_EQ(0xcd4ff538U, unwinder.frames()[15].sp); | ||
1053 | EXPECT_EQ(0xe4a79affU, unwinder.frames()[16].pc); | ||
1054 | EXPECT_EQ(0xcd4ff640U, unwinder.frames()[16].sp); | ||
1055 | EXPECT_EQ(0xe4a75575U, unwinder.frames()[17].pc); | ||
1056 | EXPECT_EQ(0xcd4ff6b0U, unwinder.frames()[17].sp); | ||
1057 | EXPECT_EQ(0xe4a7a531U, unwinder.frames()[18].pc); | ||
1058 | EXPECT_EQ(0xcd4ff6e8U, unwinder.frames()[18].sp); | ||
1059 | EXPECT_EQ(0xe471668dU, unwinder.frames()[19].pc); | ||
1060 | EXPECT_EQ(0xcd4ff770U, unwinder.frames()[19].sp); | ||
1061 | EXPECT_EQ(0xe49c4f49U, unwinder.frames()[20].pc); | ||
1062 | EXPECT_EQ(0xcd4ff7c8U, unwinder.frames()[20].sp); | ||
1063 | EXPECT_EQ(0xe49c5cd9U, unwinder.frames()[21].pc); | ||
1064 | EXPECT_EQ(0xcd4ff850U, unwinder.frames()[21].sp); | ||
1065 | EXPECT_EQ(0xe49e71ddU, unwinder.frames()[22].pc); | ||
1066 | EXPECT_EQ(0xcd4ff8e8U, unwinder.frames()[22].sp); | ||
1067 | EXPECT_EQ(0xe7df3925U, unwinder.frames()[23].pc); | ||
1068 | EXPECT_EQ(0xcd4ff958U, unwinder.frames()[23].sp); | ||
1069 | EXPECT_EQ(0xe7daee39U, unwinder.frames()[24].pc); | ||
1070 | EXPECT_EQ(0xcd4ff960U, unwinder.frames()[24].sp); | ||
1071 | } | ||
1072 | |||
959 | } // namespace unwindstack | 1073 | } // namespace unwindstack |
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp index 551f46c7b..2428f68fd 100644 --- a/libunwindstack/tests/UnwinderTest.cpp +++ b/libunwindstack/tests/UnwinderTest.cpp | |||
@@ -133,7 +133,7 @@ class UnwinderTest : public ::testing::Test { | |||
133 | }; | 133 | }; |
134 | 134 | ||
135 | MapsFake UnwinderTest::maps_; | 135 | MapsFake UnwinderTest::maps_; |
136 | RegsFake UnwinderTest::regs_(5, 0); | 136 | RegsFake UnwinderTest::regs_(5); |
137 | std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr); | 137 | std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr); |
138 | 138 | ||
139 | TEST_F(UnwinderTest, multiple_frames) { | 139 | TEST_F(UnwinderTest, multiple_frames) { |
@@ -141,8 +141,8 @@ TEST_F(UnwinderTest, multiple_frames) { | |||
141 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 141 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
142 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); | 142 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); |
143 | 143 | ||
144 | regs_.FakeSetPc(0x1000); | 144 | regs_.set_pc(0x1000); |
145 | regs_.FakeSetSp(0x10000); | 145 | regs_.set_sp(0x10000); |
146 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); | 146 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); |
147 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); | 147 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); |
148 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 148 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
@@ -201,8 +201,8 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) { | |||
201 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 201 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
202 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); | 202 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); |
203 | 203 | ||
204 | regs_.FakeSetPc(0x1000); | 204 | regs_.set_pc(0x1000); |
205 | regs_.FakeSetSp(0x10000); | 205 | regs_.set_sp(0x10000); |
206 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); | 206 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); |
207 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); | 207 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); |
208 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 208 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
@@ -260,8 +260,8 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) { | |||
260 | TEST_F(UnwinderTest, non_zero_load_bias) { | 260 | TEST_F(UnwinderTest, non_zero_load_bias) { |
261 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 261 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
262 | 262 | ||
263 | regs_.FakeSetPc(0xa5500); | 263 | regs_.set_pc(0xa5500); |
264 | regs_.FakeSetSp(0x10000); | 264 | regs_.set_sp(0x10000); |
265 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 265 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
266 | 266 | ||
267 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 267 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
@@ -288,8 +288,8 @@ TEST_F(UnwinderTest, non_zero_load_bias) { | |||
288 | TEST_F(UnwinderTest, non_zero_elf_offset) { | 288 | TEST_F(UnwinderTest, non_zero_elf_offset) { |
289 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 289 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
290 | 290 | ||
291 | regs_.FakeSetPc(0xa7500); | 291 | regs_.set_pc(0xa7500); |
292 | regs_.FakeSetSp(0x10000); | 292 | regs_.set_sp(0x10000); |
293 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 293 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
294 | 294 | ||
295 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 295 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
@@ -316,8 +316,8 @@ TEST_F(UnwinderTest, non_zero_elf_offset) { | |||
316 | TEST_F(UnwinderTest, non_zero_map_offset) { | 316 | TEST_F(UnwinderTest, non_zero_map_offset) { |
317 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 317 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
318 | 318 | ||
319 | regs_.FakeSetPc(0x43000); | 319 | regs_.set_pc(0x43000); |
320 | regs_.FakeSetSp(0x10000); | 320 | regs_.set_sp(0x10000); |
321 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 321 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
322 | 322 | ||
323 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 323 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
@@ -349,8 +349,8 @@ TEST_F(UnwinderTest, no_frames_after_finished) { | |||
349 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); | 349 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); |
350 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); | 350 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); |
351 | 351 | ||
352 | regs_.FakeSetPc(0x1000); | 352 | regs_.set_pc(0x1000); |
353 | regs_.FakeSetSp(0x10000); | 353 | regs_.set_sp(0x10000); |
354 | ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true)); | 354 | ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true)); |
355 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); | 355 | ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); |
356 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); | 356 | ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); |
@@ -383,8 +383,8 @@ TEST_F(UnwinderTest, max_frames) { | |||
383 | ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false)); | 383 | ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false)); |
384 | } | 384 | } |
385 | 385 | ||
386 | regs_.FakeSetPc(0x1000); | 386 | regs_.set_pc(0x1000); |
387 | regs_.FakeSetSp(0x10000); | 387 | regs_.set_sp(0x10000); |
388 | 388 | ||
389 | Unwinder unwinder(20, &maps_, ®s_, process_memory_); | 389 | Unwinder unwinder(20, &maps_, ®s_, process_memory_); |
390 | unwinder.Unwind(); | 390 | unwinder.Unwind(); |
@@ -415,8 +415,8 @@ TEST_F(UnwinderTest, verify_frames_skipped) { | |||
415 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 415 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
416 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); | 416 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); |
417 | 417 | ||
418 | regs_.FakeSetPc(0x20000); | 418 | regs_.set_pc(0x20000); |
419 | regs_.FakeSetSp(0x10000); | 419 | regs_.set_sp(0x10000); |
420 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); | 420 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); |
421 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); | 421 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); |
422 | ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false)); | 422 | ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false)); |
@@ -481,8 +481,8 @@ TEST_F(UnwinderTest, sp_not_in_map) { | |||
481 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 481 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
482 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 482 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
483 | 483 | ||
484 | regs_.FakeSetPc(0x1000); | 484 | regs_.set_pc(0x1000); |
485 | regs_.FakeSetSp(0x63000); | 485 | regs_.set_sp(0x63000); |
486 | ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false)); | 486 | ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false)); |
487 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 487 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
488 | 488 | ||
@@ -527,8 +527,8 @@ TEST_F(UnwinderTest, pc_in_device_stops_unwind) { | |||
527 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 527 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
528 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); | 528 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); |
529 | 529 | ||
530 | regs_.FakeSetPc(0x13000); | 530 | regs_.set_pc(0x13000); |
531 | regs_.FakeSetSp(0x10000); | 531 | regs_.set_sp(0x10000); |
532 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); | 532 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); |
533 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); | 533 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); |
534 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 534 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
@@ -546,8 +546,8 @@ TEST_F(UnwinderTest, sp_in_device_stops_unwind) { | |||
546 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 546 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
547 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); | 547 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); |
548 | 548 | ||
549 | regs_.FakeSetPc(0x1000); | 549 | regs_.set_pc(0x1000); |
550 | regs_.FakeSetSp(0x13000); | 550 | regs_.set_sp(0x13000); |
551 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); | 551 | ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); |
552 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); | 552 | ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); |
553 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 553 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
@@ -563,8 +563,8 @@ TEST_F(UnwinderTest, sp_in_device_stops_unwind) { | |||
563 | TEST_F(UnwinderTest, pc_without_map) { | 563 | TEST_F(UnwinderTest, pc_without_map) { |
564 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 564 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
565 | 565 | ||
566 | regs_.FakeSetPc(0x41000); | 566 | regs_.set_pc(0x41000); |
567 | regs_.FakeSetSp(0x13000); | 567 | regs_.set_sp(0x13000); |
568 | 568 | ||
569 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 569 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
570 | unwinder.Unwind(); | 570 | unwinder.Unwind(); |
@@ -593,8 +593,8 @@ TEST_F(UnwinderTest, speculative_frame) { | |||
593 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 593 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
594 | 594 | ||
595 | // Fake as if code called a nullptr function. | 595 | // Fake as if code called a nullptr function. |
596 | regs_.FakeSetPc(0); | 596 | regs_.set_pc(0); |
597 | regs_.FakeSetSp(0x10000); | 597 | regs_.set_sp(0x10000); |
598 | regs_.FakeSetReturnAddress(0x1202); | 598 | regs_.FakeSetReturnAddress(0x1202); |
599 | regs_.FakeSetReturnAddressValid(true); | 599 | regs_.FakeSetReturnAddressValid(true); |
600 | 600 | ||
@@ -657,8 +657,8 @@ TEST_F(UnwinderTest, speculative_frame_removed) { | |||
657 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 657 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
658 | 658 | ||
659 | // Fake as if code called a nullptr function. | 659 | // Fake as if code called a nullptr function. |
660 | regs_.FakeSetPc(0); | 660 | regs_.set_pc(0); |
661 | regs_.FakeSetSp(0x10000); | 661 | regs_.set_sp(0x10000); |
662 | regs_.FakeSetReturnAddress(0x1202); | 662 | regs_.FakeSetReturnAddress(0x1202); |
663 | regs_.FakeSetReturnAddressValid(true); | 663 | regs_.FakeSetReturnAddressValid(true); |
664 | 664 | ||
@@ -691,8 +691,8 @@ TEST_F(UnwinderTest, map_ignore_suffixes) { | |||
691 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); | 691 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); |
692 | 692 | ||
693 | // Fake as if code called a nullptr function. | 693 | // Fake as if code called a nullptr function. |
694 | regs_.FakeSetPc(0x1000); | 694 | regs_.set_pc(0x1000); |
695 | regs_.FakeSetSp(0x10000); | 695 | regs_.set_sp(0x10000); |
696 | ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false)); | 696 | ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false)); |
697 | ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false)); | 697 | ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false)); |
698 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 698 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
@@ -745,8 +745,8 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) { | |||
745 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); | 745 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); |
746 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); | 746 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); |
747 | 747 | ||
748 | regs_.FakeSetPc(0x1000); | 748 | regs_.set_pc(0x1000); |
749 | regs_.FakeSetSp(0x10000); | 749 | regs_.set_sp(0x10000); |
750 | ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); | 750 | ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); |
751 | ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); | 751 | ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); |
752 | ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); | 752 | ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); |
@@ -805,8 +805,8 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) { | |||
805 | 805 | ||
806 | TEST_F(UnwinderTest, dex_pc_in_map) { | 806 | TEST_F(UnwinderTest, dex_pc_in_map) { |
807 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 807 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
808 | regs_.FakeSetPc(0x1000); | 808 | regs_.set_pc(0x1000); |
809 | regs_.FakeSetSp(0x10000); | 809 | regs_.set_sp(0x10000); |
810 | regs_.FakeSetDexPc(0xa3400); | 810 | regs_.FakeSetDexPc(0xa3400); |
811 | 811 | ||
812 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 812 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
@@ -846,8 +846,8 @@ TEST_F(UnwinderTest, dex_pc_in_map) { | |||
846 | 846 | ||
847 | TEST_F(UnwinderTest, dex_pc_not_in_map) { | 847 | TEST_F(UnwinderTest, dex_pc_not_in_map) { |
848 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 848 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
849 | regs_.FakeSetPc(0x1000); | 849 | regs_.set_pc(0x1000); |
850 | regs_.FakeSetSp(0x10000); | 850 | regs_.set_sp(0x10000); |
851 | regs_.FakeSetDexPc(0x50000); | 851 | regs_.FakeSetDexPc(0x50000); |
852 | 852 | ||
853 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); | 853 | Unwinder unwinder(64, &maps_, ®s_, process_memory_); |
@@ -888,8 +888,8 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) { | |||
888 | TEST_F(UnwinderTest, dex_pc_multiple_frames) { | 888 | TEST_F(UnwinderTest, dex_pc_multiple_frames) { |
889 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); | 889 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); |
890 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); | 890 | ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |
891 | regs_.FakeSetPc(0x1000); | 891 | regs_.set_pc(0x1000); |
892 | regs_.FakeSetSp(0x10000); | 892 | regs_.set_sp(0x10000); |
893 | regs_.FakeSetDexPc(0xa3400); | 893 | regs_.FakeSetDexPc(0xa3400); |
894 | ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); | 894 | ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); |
895 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); | 895 | ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); |
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data new file mode 100644 index 000000000..300646b7b --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data new file mode 100644 index 000000000..999cb790a --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data new file mode 100644 index 000000000..6aa1c824f --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data new file mode 100644 index 000000000..19d7b65cf --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data new file mode 100644 index 000000000..edcd3e169 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so new file mode 100644 index 000000000..09ba49532 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so new file mode 100644 index 000000000..39c9025db --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so | |||
Binary files differ | |||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt new file mode 100644 index 000000000..55aaaf63f --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt | |||
@@ -0,0 +1,3 @@ | |||
1 | d0250000-d2600000 r-xp 0 00:00 0 <anonymous:d0250000> | ||
2 | e466e000-e4ae8000 r-xp 0 00:00 0 libart.so | ||
3 | e7d91000-e7e31000 r-xp 0 00:00 0 libc.so | ||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt new file mode 100644 index 000000000..0b518143a --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | r0: e814103c | ||
2 | r1: 12dcf218 | ||
3 | r2: 1a90df75 | ||
4 | r3: ffffffbf | ||
5 | r4: 0 | ||
6 | r5: 12dc0800 | ||
7 | r6: 12dcf218 | ||
8 | r7: 1a90df75 | ||
9 | r8: 0 | ||
10 | r9: dd23cc00 | ||
11 | r10: 1c | ||
12 | r11: cd4ff16c | ||
13 | ip: 0 | ||
14 | sp: cd4ff140 | ||
15 | lr: d025cdd7 | ||
16 | pc: d025c788 | ||
diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data new file mode 100644 index 000000000..f00917b77 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data | |||
Binary files differ | |||