2

Here's some information about my system:

  • Ubuntu 22.04.3 running on Intel x86_64;
  • ggc version 11.4.0;

I've noticed that the rsp register is not decremented in leaf functions as it is in non leaf functions.

For example consider this C program in a file test.c :

int fx(){
     
     int x = 30;
     int y = 34;
     int z = 45;
     return 30;  
}

int main(){    
    
    int a = 10;
    int b = 20;
    int c = fx();
     
}

After compiling it with "gcc test.c -fno-stack-protector -o test" I run the "objdump -dw -M suffix test" and I get :

0000000000001129 <fx>:
    1129:   f3 0f 1e fa             endbr64 
    112d:   55                      pushq  %rbp
    112e:   48 89 e5                movq   %rsp,%rbp
    1131:   c7 45 fc 1e 00 00 00    movl   $0x1e,-0x4(%rbp)
    1138:   c7 45 f8 22 00 00 00    movl   $0x22,-0x8(%rbp)
    113f:   c7 45 f4 2d 00 00 00    movl   $0x2d,-0xc(%rbp)
    1146:   b8 1e 00 00 00          movl   $0x1e,%eax
    114b:   5d                      popq   %rbp
    114c:   c3                      retq   

000000000000114d <main>:
    114d:   f3 0f 1e fa             endbr64 
    1151:   55                      pushq  %rbp
    1152:   48 89 e5                movq   %rsp,%rbp
    1155:   48 83 ec 10             subq   $0x10,%rsp
    1159:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
    1160:   c7 45 f8 14 00 00 00    movl   $0x14,-0x8(%rbp)
    1167:   b8 00 00 00 00          movl   $0x0,%eax
    116c:   e8 b8 ff ff ff          callq  1129 <fx>
    1171:   89 45 f4                movl   %eax,-0xc(%rbp)
    1174:   b8 00 00 00 00          movl   $0x0,%eax
    1179:   c9                      leaveq 
    117a:   c3                      retq  

As you can see, in main we have subq $0x10,%rsp but in fx this doesn't happen.

My questions:

  1. Does it have something to do with the System V ABI that gcc follows or it is just an optimization performed by the compiler?

  2. What is the reason that warrants this behavior?

  3. Is there a way to tell the compiler I do not want this behavior in leaf functions?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
alessio solari
  • 313
  • 1
  • 6
  • @Frankie_C which parameters? There are no parameters in the `fx` function. – Jabberwocky Aug 28 '23 at 09:02
  • 2
    [Where exactly is the red zone on x86-64?](https://stackoverflow.com/questions/38042188/where-exactly-is-the-red-zone-on-x86-64) – BoP Aug 28 '23 at 09:58
  • 1
    There is not need to reserve the stack frame as you do not call any other functions. – 0___________ Aug 28 '23 at 12:36
  • @0___________ Is it ok to compile a C program in an Ubuntu x86_64 system with the flag "-mno-red-zone" like "gcc file.c -fno-stack-protector -mno-red-zone -o file" ? Is this option gonna break something or cause some incompatibilities or it is just an optimization ? – alessio solari Aug 28 '23 at 12:44

1 Answers1

2

As you do not pass any parameters via registers and you do not call any other functions reserving the stack space is pointless.

void nn(int x);

int fx(void){     
     volatile int x = 30;

     nn(x);
     return 30;  
}

https://godbolt.org/z/7qE4nbdcn

Is it ok to compile a C program in an Ubuntu x86_64 system with the flag "-mno-red-zone" like "gcc file.c -fno-stack-protector -mno-red-zone -o file" ? Is this option gonna break something or cause some incompatibilities or it is just an optimization ?

It is safe. Basically, it is pointless in the userspace code. Is it an optimization? - yes sort of. Reserving the space is simply pointless unless your stack is larger than the red zone.

int fx(void){     
     volatile int x[100] = {30,};

     return 30;  
}

It will reserve the stack minus size of the red zone.

https://godbolt.org/z/8qb191x9E

I've read that the System V ABI "mandates" the red zone. Does this mean that this red zone DOES EXIST even if we use the -mno-red-zone option ? I mean, if we use this option we do not use the red zone but it still exists ?

It is not related to your code. The signal and interrupts handlers will move the stack pointer away from your one. To change it you will need to recompile the kernel and amend some of its code.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • I've read that the System V ABI "mandates" the red zone. Does this mean that this red zone DOES EXIST even if we use the -mno-red-zone option ? I mean, if we use this option we do not use the red zone but it still exists ? – alessio solari Aug 28 '23 at 14:19
  • @ 0___________://stackoverflow.com/questions/76993711/does-the-red-zone-still-exist-even-if-we-use-the-mno-red-zone-flag-in-gcc?noredirect=1#comment135729735_76993711 – alessio solari Aug 28 '23 at 14:38
  • 1
    @alessiosolari yes it is OS related. Your code has nothing to do with it. – 0___________ Aug 28 '23 at 14:45
  • 1
    @alessiosolari: Yes, the kernel's signal-delivery code and whatever else will still leave the 128 byte red-zone below RSP unmodified. It doesn't know or care that the currently executing machine code isn't going to reload that data (in this case because the compiler chose not to keep anything there.) Despite it being a `-m` option, it doesn't have to change the ABI, just not optimize in ways that take advantage of that part of the ABI. However, [kernel code usually *can't* use a red-zone](https://stackoverflow.com/q/25787408), so must be compiled with `-mno-red-zone` to match that ABI. – Peter Cordes Aug 28 '23 at 16:44