Altera_Forum
Honored Contributor
21 years agoAnother Nios GCC Bug with -mflat
I was stepping through my code trying to figure out how a block of data was being overwritten by some of the initialization code on my project. I was rather surprised to find the data changed as soon as I stepped into any one of several simple functions - it was overwritten with the argument for the simple function, even before I had executed any statements in the body of the routine. When I looked at the assembly code generated for the function prolog, it was obvious what the problem was.
; flat prologue begin
; Expand callers frame 26 words.
mov %g1, %sp
pfx %hi(104)
subi %sp, %lo(104)
sts , %fp
; save call preserved regs
sts , %o7
sts , %l0
; Set frame pointer
mov %fp, %g1
; flat prologue end
pfx 17
st , %o0
pfx 18
st , %o1
pfx 19
st , %o2 The prolog sets up a stack frame (bounded by %fp at the top and %sp at the bottom), but then when it saves the arguments (%o0, %o1 and %o2), it uses a positive offset from %fp! This means the arguments are saved in the space allocated for saved arguements in the callers stack frame. Most of the time this works by accident, and doesn't cause an obvious problem, since the caller has made the same mistake (and thus isn't using this space). But it is noticeable when calling a routine that saves arguments on a newly set-up stack: it saves its arguments 17 32-bit words above the top of the stack (in memory that is probably allocated to something else). Fortunately, as a work around one just has to make sure there 23 32-bit words available above the initial stack pointer when setting up a stack. I haven't figured out how functions with more than six 32-bit arugments are actually working, I'm planning on avoiding them.