Function address nearly the same as other variables addresses

Viewed 76

Why are function addresses nearly the same as the address of static global variables or dynamically allocated variables? Here is the code for demonstration:

#include <stdio.h>
#include <stdlib.h>
int global_var;
int global_var1;
int global_var2;

static int st_var = 3;

void func()
{
  return;
}

int main(void)
{ 
  int x;
  int* x_m = malloc(sizeof(int));
  printf("Malloc: %p\n", x_m);

  printf("Local: %p\n", &x);

  printf("Function: %p\n", &func);

  printf("Global: %p\n", &global_var);
  printf("Global: %p\n", &global_var1);
  printf("Global: %p\n", &global_var2);

  printf("Static: %p\n", &st_var);


  free(x_m);
  return 0;
}
Output: 
Malloc: 0x55bede9ce2a0
Local: 0x7ffdbc67b25c
Function: 0x55bede7151a9
Global: 0x55bede718024
Global: 0x55bede718030
Global: 0x55bede718020
Static: 0x55bede718010

Can somebody explain this? Because I thought that just global and static variables are stored into the .bss segment.

1 Answers

This is because, usually, the .text section (containing function code) and the .bss section of an ELF executable are mapped "relatively near" each other.

You can check this with readelf:

$ gcc prog.c
$ readelf -S a.out
There are 29 section headers, starting at offset 0x1ac0:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
...
  [14] .text             PROGBITS         00000000000007e0  000007e0
       0000000000000302  0000000000000000  AX       0     0     16
...
  [24] .bss              NOBITS           0000000000201010  00001010
       0000000000000010  0000000000000000  WA       0     0     8
...

You can see from above from the "Address" field of .text and .bss that they will be loaded 0x201010-0x7e0 = 0x200830 bytes apart in virtual memory when the program runs.

In any case, this does not mean that your code is in the .bss section or that your variables are in the .text section. They are in two different yet "relatively near" sections.

The distance between the two is arbitrary, there is no real minimum or maximum requirement dictated by the ELF specification. You could write your own linker script to place them farther away if you really want.

Related