Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is read-only memory implemented in C?

Tags:

c

memory

readonly

People also ask

What is read only memory in C?

Read-Only Memory (ROM) is the primary memory unit of any computer system along with the Random Access Memory (RAM), but unlike RAM, in ROM, the binary information is stored permanently . Now, this information to be stored is provided by the designer and is then stored inside the ROM .

Why are C string literals read only?

The string literal is stored in the read-only part of memory by most of the compilers. The C and C++ standards say that string literals have static storage duration, any attempt at modifying them gives undefined behavior. s is just a pointer and like any other pointer stores address of string literal.

What is read only memory and its types?

ROM stands for Read Only Memory. The memory from which we can only read but cannot write on it. This type of memory is non-volatile. The information is stored permanently in such memories during manufacture. A ROM stores such instructions that are required to start a computer.

How does memory in C work?

In C, dynamic memory is allocated from the heap using some standard library functions. The two key dynamic memory functions are malloc() and free(). The malloc() function takes a single parameter, which is the size of the requested memory area in bytes. It returns a pointer to the allocated memory.


That's not a feature of the C language but a feature of the compiler/linker and the operating system working together.

When you compile such code the following happens:

  • The compiler will put the string into a read-only data-section.

  • The linker collects all the data in such read-only sections and puts them into a single segment. This segment resides in the executable file and is flagged with a "read only"-attribute.

  • Now comes the operating system executable loader. It loads the executable (or maps it into memory to be more exact). Once this is done, the loader walks the sections and sets access-permissions for each segment. For a read-only data segment it will most likely disable code-execute and write access. Code (for example, your functions) gets execute rights but no write access. Ordinary data like static variables gets read and write access and so on...

That's how modern operating systems do it.

As said, it's not a feature of the C language. If you compile the same problem for DOS, for example, the program will run but no write protection would be possible, because the DOS-loader does not know about read-only sections.


Executables contain two parts: a .data section, containing global variables, and a .text section, containing the actual machine code.

Strings are placed into the .data section. What C does when it sees "Hello world" is it puts the string "Hello world" into the executable itself, and replaces instance of "Hello world" in the program with the address where that string ends up being loaded.

Having said that, I'm not sure why it's read-only - theoretically a program should be able to modify its own memory..


True read-only memory is implemented by the memory subsystem of the OS. The OS can mark certain pages as read-only.

In the binary, the compiler can tell the OS which parts of the executable should be placed in read-only vs read-write memory pages.


An example of how to do this in Linux is on page 179 of Advanced Linux Programming by Mark Mitchell, Jeffrey Olham, and Alex Samuel.


When you write char s[10]="sneha"; you are allocating 10 bytes of storage space(not memory, memory comes into picture only when u r executing your program) in your object file. This is static allocation of memory( at compile time).

But when you write char *s="sneha"; you are not allocating any storage space to store "sneha". It will get stored in READ ONLY section. But the pointer s is stored in different section based on where it is declared. But it is pointing to the READ ONLY DATA "sneha". So if you try to write on it you will get segmentation fault.

For example:

char *s = "sneha";
s[1] = 'N'; 
printf("%s",s);  // you expecting output sNeha, 
                 // but you get a seg fault since it is READ ONLY DATA 

You could try something like

s[4] = '0';

and see if it says "hello w0rld" when you call

puts(s);

If it causes an immediate Segmentation Fault or a Data Execution Prevention exception then it is probably read only. (If the system lets you get away with it, that doesn't make it a good idea.)