GCC stack problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
chorakm
Posts: 14
Joined: Fri Dec 08, 2006 12:07 am

GCC stack problem

Post by chorakm »

I have an interesting problem. I'm mixing C and assembly to create my OS. I created this program that gets combined into my kernel.(to avoid having to read from HDD or FDD) I then copy the program from my kernel into another place in memory that it expects to be in and enable paging. Then I use the call instruction to jump to the code. The program has it's own linker file that looks like this:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0xA00000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
	*(.rodata*)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
In the assembly part of the code. I have a SECTION .bss at the end to declare a stack. Now the problem I notice is this. If I declare a GLOBAL array in the C code, for some odd reason, gcc thinks it's a good idea to start the array at the END of the stack! I looked at the code, and for some strange reason. it actually loads the end of the stack into ECX. If I declare the array as a local variable, it works as expected. What am I doing wrong, here? Is my linker script wrong? No matter what I do, the darn gcc compiler always puts the global array at the end of the stack. Stacks grow downward...Why is it doing this? Thanks!
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

your startup code holds a declaration for the stack reserving a certain amount of bytes for it. When you add global arrays gcc will reserve space for it as well. What happens is that ld concatenates these pieces and you get this:

text:
loader.s(.text) (startup code)
main.c(.text) (kernel code)
main.c(.rodata) (strings)

data:
main.c(.data) (kernel constants)

bss:
loader.s(.bss) (stack)
main.c(.bss) (array)

The net result is that the uninitialised array ends up directly after the stack. Nothing strange about it - its exactly where you told the linker to put it.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
chorakm
Posts: 14
Joined: Fri Dec 08, 2006 12:07 am

Post by chorakm »

I discovered adding *(COMMON) and before *(bss) to my linker script, it causes the arrays to be put at the top of the stack, instead of the bottom. This is more desirable since If I have anything right after the stack I won't override anything I suppose. Some linker scripts on this site do it this way. Is this correct?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Overflowing the stack is bad practice at the very least. You shouldn't allocate large structures on the stack anyway. For kernel land this will only cause you problems later on.
In the end, it doesn't matter where your stack (or anything else put next to it) is as it shouldn't overflow anyway.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply