Revert "arm: Allow the first function to use linked register as return pc"

This reverts commit f2b3ab5e0a.

Reason for revert: Causes symbolization errors on ARM ChromeOS
devices crbug.com/1182948.

Original change's description:
> arm: Allow the first function to use linked register as return pc
>
> For a crash at the function entry with corrupted PC, the caller's PC
> could be lying in the link register. Using the PC from link register
> would be more effective than blindly scanning the stack immediately.
>
> Change-Id: I51673b7298e70faeeab2bfa97075e3c4793f94bc
> Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2678992
> Reviewed-by: Mike Frysinger <vapier@chromium.org>
> Reviewed-by: Joshua Peraza <jperaza@chromium.org>

Bug: 1182948
Change-Id: I2818b35ab1fb99012919cccc0fb80368e456ca15
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2765164
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Brian Sheedy 2021-03-16 17:39:32 +00:00 committed by Joshua Peraza
parent 8b22babdf8
commit dff7d5afd5
3 changed files with 1 additions and 33 deletions

View file

@ -232,7 +232,7 @@ TEST_F(MicrodumpProcessorTest, TestProcessMultiple) {
ASSERT_EQ("arm", state.system_info()->cpu); ASSERT_EQ("arm", state.system_info()->cpu);
ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys", ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys",
state.system_info()->os_version); state.system_info()->os_version);
ASSERT_EQ(6U, state.threads()->at(0)->frames()->size()); ASSERT_EQ(5U, state.threads()->at(0)->frames()->size());
} }
TEST_F(MicrodumpProcessorTest, TestProcessMips) { TEST_F(MicrodumpProcessorTest, TestProcessMips) {

View file

@ -238,27 +238,6 @@ StackFrameARM* StackwalkerARM::GetCallerByFramePointer(
return frame; return frame;
} }
StackFrameARM* StackwalkerARM::GetCallerByLinkRegister(
const vector<StackFrame*>& frames) {
StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
uint32_t last_lr = last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR];
if (!(last_frame->context_validity & StackFrameARM::CONTEXT_VALID_LR) ||
!InstructionAddressSeemsValid(last_lr)) {
return NULL;
}
StackFrameARM* frame = new StackFrameARM();
frame->trust = StackFrame::FRAME_TRUST_SCAN;
frame->context = last_frame->context;
frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = last_lr;
frame->context_validity =
context_frame_validity_ & (~StackFrameARM::CONTEXT_VALID_LR);
return frame;
}
StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack,
bool stack_scan_allowed) { bool stack_scan_allowed) {
if (!memory_ || !stack) { if (!memory_ || !stack) {
@ -285,12 +264,6 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack,
if (fp_register_ >= 0 && !frame.get()) if (fp_register_ >= 0 && !frame.get())
frame.reset(GetCallerByFramePointer(frames)); frame.reset(GetCallerByFramePointer(frames));
// For the first frame, return address may still be in the LR register at
// entry. Prefer to use LR register than scanning stack if LR register value
// points to a function range.
if (frames.size() == 1 && !frame.get())
frame.reset(GetCallerByLinkRegister(frames));
// If everuthing failed, fall back to stack scanning. // If everuthing failed, fall back to stack scanning.
if (stack_scan_allowed && !frame.get()) if (stack_scan_allowed && !frame.get())
frame.reset(GetCallerByStackScan(frames)); frame.reset(GetCallerByStackScan(frames));

View file

@ -82,11 +82,6 @@ class StackwalkerARM : public Stackwalker {
// Return NULL on failure. // Return NULL on failure.
StackFrameARM* GetCallerByFramePointer(const vector<StackFrame*>& frames); StackFrameARM* GetCallerByFramePointer(const vector<StackFrame*>& frames);
// Use the link register if it seems to be a valid function adderss.
// The caller takes ownership of the returned frame. Return NULL on failure.
// This is useful when PC register is corrupted.
StackFrameARM* GetCallerByLinkRegister(const vector<StackFrame*>& frames);
// Scan the stack for plausible return addresses. The caller takes ownership // Scan the stack for plausible return addresses. The caller takes ownership
// of the returned frame. Return NULL on failure. // of the returned frame. Return NULL on failure.
StackFrameARM* GetCallerByStackScan(const vector<StackFrame*>& frames); StackFrameARM* GetCallerByStackScan(const vector<StackFrame*>& frames);