Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memory starting location in C [duplicate]

I am looking into to the memory layout of a given process. I notice that the starting memory location of each process is not 0. On this website, TEXT starts at 0x08048000. One reason can be to distinguish the address with the NULL pointer. I am just wondering if there is any another good reasons? Thanks.

like image 882
small_potato Avatar asked Oct 09 '14 07:10

small_potato


2 Answers

The null pointer doesn't actually have to be 0. It's guaranteed in the C standard that when a 0 value is given in the context of a pointer it's treated as NULL by the compiler.

But the 0 that you use in your source code is just syntactic sugar that has no relation to the actual physical address the null-pointer value is "pointing" to.

For further details see:

  • Why is NULL/0 an illegal memory location for an object?
  • Why is address zero used for the null pointer?

An application on your operating system has its unique address space, which it sees as a continuous block of memory (the memory isn't physically continuous, it's just "the impression" the operating system gives to every program).

For the most part, each process's virtual memory space is laid out in a similar and predictable manner (this is the memory layout in a Linux process, 32-bit mode):

Memory layout in a Linux process (image from Anatomy of a Program in Memory)

Look at the text segment (the default .text base on x86 is 0x08048000, chosen by the default linker script for static binding).

Why the magical 0x08048000? Likely because Linux borrowed that address from the System V i386 ABI.

... and why then did System V use 0x08048000?

The value was chosen to accommodate the stack below the .text section, growing downward. The 0x48000 bytes could be mapped by the same page table already required by the .text section (thus saving a page table in most cases), while the remaining 0x08000000 would allow more room for stack-hungry applications.

Is there anything below 0x08048000? There could be nothing (it's only 128M), but you can pretty much map anything you desire there, using the mmap() system call.

See also:

  • What's the memory before 0x08048000 used for in 32 bit machine?
  • Reorganizing the address space
  • mmap
like image 102
manlio Avatar answered Nov 04 '22 10:11

manlio


I think this sums it up:

Each process has its own set of page tables, but there is a catch. Once virtual addresses are enabled, they apply to all software running in the machine, including the kernel itself. Thus a portion of the virtual address space must be reserved to the kernel.

So while the process gets it's own address space. Without allocating a block to the kernel, it would not be able to address kernel code and data.

This is always the first block of memory it appears and so includes address 0. The user mode space starts beyond this, and so that is where both the stack and heap reside.

Distinguishing from NULL pointer

Even if the user mode space started at address 0, there would not be any data allocated to the address 0 as that will be in the stack or the heap which themselves do not start at the beginning of the user area. Therefore NULL (with the value of 0) could be used still and is not a reason for this layout.

However one benefit related to the NULL and the first block being kernel memory is any attempt to read/write to NULL throws a Segmentation Fault.

like image 22
weston Avatar answered Nov 04 '22 10:11

weston