SVN revision: 159525
Configure line: ../gcc-svn/configure --prefix=/tmp/gcc-cross/gcc-svn-bin/
--target=arm-linux-gnueabi
--with-headers=/tmp/gcc-cross/gcc-svn-bin/arm-linux-gnueabi/include
--with-libs=/tmp/gcc-cross/gcc-svn-bin/arm-linux-gnueabi/lib/
--enable-threads=posix --enable-shared --enable-languages=c
Command line: arm-linux-gnueabi-gcc -fpic -Wall -g -O0 -S -o - -c test.c
No errors/warnings from the compiler.
Input program, test.c:
int ext_var;
void ext_fn(int x);
void bad(int x) {
ext_fn(ext_var);
}
The resulting assembly of the bad function:
bad:
.LFB0:
.file 1 test.c
.loc 1 4 0
.cfi_startproc
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
.LCFI0:
.cfi_def_cfa_offset 8
add fp, sp, #4
.cfi_offset 14, -4
.cfi_offset 11, -8
.LCFI1:
.cfi_def_cfa 11, 4
sub sp, sp, #8
.loc 1 5 0 -- should not be here
ldr r3, .L2
.LPIC0:
add r3, pc, r3
.loc 1 4 0 -- should not be here
str r0, [fp, #-8]
.loc 1 5 0
ldr r2, .L2+4
ldr r3, [r3, r2]
ldr r3, [r3, #0]
mov r0, r3
bl ext_fn(PLT)
.loc 1 6 0
sub sp, fp, #4
ldmfd sp!, {fp, pc}
I have marked the .loc directives that cause the problems for me, because of
those GDB stops too early (when the function parameters are not stored yet) and
because of this GDB command `bt' shows bad parameters for the top frame. The
`next' command is confused too, of course. Furthermore, objdump -S is also
confused, shows the function header twice:
bad:
int ext_var;
void ext_fn(int x);
void bad(int x) {
0: e92d4800push{fp, lr}
4: e28db004add fp, sp, #4
8: e24dd008sub sp, sp, #8
ext_fn(ext_var);
c: e59f3020ldr r3, [pc, #32] ; 34 bad+0x34
10: e08f3003add r3, pc, r3
int ext_var;
void ext_fn(int x);
void bad(int x) {
14: e50b0008str r0, [fp, #-8]
ext_fn(ext_var);
18: e59f2018ldr r2, [pc, #24] ; 38 bad+0x38
1c: e7933002ldr r3, [r3, r2]
20: e5933000ldr r3, [r3]
24: e1a3mov r0, r3
28: ebfebl 0 ext_fn
}
2c: e24bd004sub sp, fp, #4
30: e8bd8800pop {fp, pc}
34: 001c.word 0x001c
38: .word 0x
To my understanding, the issue is caused by the on-demand generation of the
pic register loading logic for the function prologue. That part of the
prologue gets line number info of the statement that causes the generation.
My quick fix is:
Index: gcc/config/arm/arm.c
===
--- gcc/config/arm/arm.c(revision 159525)
+++ gcc/config/arm/arm.c(working copy)
@@ -4897,13 +4897,23 @@
process. */
if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
{
+ /* We want the PIC register loading instructions to have
+the same line number info as the function
+prologue. */
+ location_t saved_curr_loc = get_curr_insn_source_location ();
+ set_curr_insn_source_location (cfun-function_start_locus);
+
crtl-uses_pic_offset_table = 1;
start_sequence ();
arm_load_pic_register (0UL);
seq = get_insns ();
end_sequence ();
+
+ set_curr_insn_source_location (saved_curr_loc);
+
/* We can be called during expansion of PHI nodes, where
we can't yet emit instructions directly in the final
insn stream. Queue the insns on the entry edge, they will
This patch solves the issue for me.
This is the first time I try to do anything internally with GCC, so please
forgive my mistakes and show me the better way to fix the issue.
--
Summary: PIC compilation on ARM screws up DWARF lineinfo in
function prologue
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: gergely+gccbug at risko dot hu
GCC build triplet: i486-linux-gnu
GCC host triplet: i486-linux-gnu
GCC target triplet: arm-linux-gnueabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44189