[RFA] ARM : prologue scan

Jerome Guitton
2003-07-21T14:27:48Z

[-- Attachment #1: Type: text/plain, Size: 1791 bytes --]

Here is a patch to improve the interpretation of the prologue for the
ARM targets. Consider this C code :

void r() {
void s () {
}

void q () {
s();
}

q();
}

with GCC 3.2.3 configured for xscale-elf, this assembler is generated:

[...]

q.1:
@ Nested: function declared inside another function.
@ args = 0, pretend = 0, frame = 4
@ frame_needed = 1, uses_anonymous_args = 0
str ip, [sp, #-4]!
add ip, sp, #4
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #8
ldr ip, [fp, #4]
@ ip needed for prologue
sub sp, sp, #4
str ip, [fp, #-16]
mov r3, ip
mov ip, r3
bl s.0
ldmea fp, {fp, sp, pc}
.Lfe2:

[...]

The prologue is compliant with the ARM Thumb procedure call standard, but
GDB is not able to interprete the instruction "add ip, sp, #4",
and builds a bogus backtrace:

(gdb) l r.c:2
1 void r() {
2 void s () {
3 }
4
5 void q () {
6 s();
7 }
8
9 q();
10 }
(gdb) b 2
Breakpoint 1 at 0x0: file r.c, line 2.
(gdb) r r
Starting program: /cardiff.a/guitton/fsf/gdb/tmp/r.o r

Breakpoint 1, s.0 () at r.c:2
2 void s () {
(gdb) bt
#0 s.0 () at r.c:2
#1 q.1 () at r.c:6
#2 0xa2eebb940 in system__exception_table__exception_htable__iterator_indexXn
(gdb)

This patch adds the interpretation of the missing "add" (resp. "sub")
instruction. I have run the testsuite with the simulator, and I
found no regression; but there was a lot of test that failed, so I have
some suspicion on my setup. Can someone give me the average success/failure
on this target, or (even better :-) test it on his own setup?
Is the arm simulator (HEAD) reliable?

--
Jerome

[-- Attachment #2: arm_bt.dif --]
[-- Type: text/plain, Size: 2395 bytes --]

2003-07-21 J. Guitton <guitton@gnat.com>

* arm-tdep.c (arm_skip_prologue): Add the handling of "sub ip, sp #n"
and "add ip, sp #n", as these instructions can be found in a ATPCS
compliant prologue.
(arm_scan_prologue): Ditto.

Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.143
diff -3 -u -p -r1.143 arm-tdep.c
--- arm-tdep.c 13 Jun 2003 14:15:51 -0000 1.143
+++ arm-tdep.c 21 Jul 2003 14:02:01 -0000
@@ -449,6 +449,12 @@ arm_skip_prologue (CORE_ADDR pc)
if (inst == 0xe1a0c00d) /* mov ip, sp */
continue;

+ if ((inst & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
+ continue;
+
+ if ((inst & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
+ continue;
+
/* Some prologues begin with "str lr, [sp, #-4]!". */
if (inst == 0xe52de004) /* str lr, [sp, #-4]! */
continue;
@@ -708,7 +714,7 @@ thumb_scan_prologue (struct frame_info *
static void
arm_scan_prologue (struct frame_info *fi)
{
- int regno, sp_offset, fp_offset;
+ int regno, sp_offset, fp_offset, ip_offset;
LONGEST return_value;
CORE_ADDR prologue_start, prologue_end, current_pc;

@@ -809,6 +815,23 @@ arm_scan_prologue (struct frame_info *fi

if (insn == 0xe1a0c00d) /* mov ip, sp */
{
+ ip_offset = 0;
+ continue;
+ }
+ else if ((insn & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
+ {
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32 - rot));
+ ip_offset = imm;
+ continue;
+ }
+ else if ((insn & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
+ {
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32 - rot));
+ ip_offset = -imm;
continue;
}
else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */
@@ -858,7 +881,7 @@ arm_scan_prologue (struct frame_info *fi
unsigned imm = insn & 0xff; /* immediate value */
unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
imm = (imm >> rot) | (imm << (32 - rot));
- sp_offset -= imm;
+ sp_offset -= imm + ip_offset;
}
else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
{