What are the first 16 bytes in the .rodata section?

For example, I have the following code:

#include <cstdio>

void myprintf(const char* ptr) {
        printf("%p\n", ptr);

int main() {
        myprintf("hello world");
        static char hi[] = "hi";

I compiled:

$ g++ -Wall test_elf.cpp -o test_elf -O3 -std=c++17

And then

$ readelf -W -p .rodata test_elf 

String dump of section '.rodata':
  [    10]  %p^J
  [    14]  hello world
  [    23]  ab
  [    26]  cde

As you can see, there are 16 bytes before the first constant string literal. I use elf.h to parse, and I also see there are 16 bytes before the first constant string literal. 14 bytes of them are just zero. 1 non zero byte is 1. Another is 2.


1 Answer 1


Trying to provide a more general answer that would hopefully complement this answer linked in the comments.

To those who are unsure, the .rodata section in an executable contains all read-only variables and constants with a global scope (i.e. will be defined for the entire duration of the program's execution) although the lines are becoming a little blurry and there are exceptions to the rules which are not actually enforced, the .rodata section usually hold all global and static variables that are read only. This is obviously the reason the strings you defined are there.

Although your code does not directly define any constructs except those few string literals, the .rodata section will hold all data deemed globally scoped and read-only by the compiler and linker, regardless of whether it was defined in your code or an additional variable/object your program uses explicitly or implicitly.

Now to your question; I mentioned additional objects can be explicitly and implicitly defined in your code, without you actually writing them. One explicit example is all the code #includeed in your program (cstdio in this case). Code implicitly included in your program is, for example, the code GCC adds that wraps and calls your defined main function and handles different operating system interfaces (setting up functions related stdin, stderr, stdout) as well as set up and teardown of program objects (that code is where globally scoped objects are initialized by calling their constructor in C++).

Although this is explained in depth in the linked answer, the actual values (1 and 2) appear to be for a constant defined by GCC's init.c:

const int _IO_stdin_used = 0x20001;

That file is part of GCC's initialization code mentioned above, and is used to control the version of a input/output library GCC implements input/output in programs with.

it's worth noting that an hex-dump will help increase confidence in whether that is indeed the reason for the additional bytes you're seeing, as well as following the compilation and linking process, of course

A difference worth mentioning between your example and the one in the SO question if the 14 zero bytes, which are of course padding to a boundary of 16 bytes, which is something compilers often do to optimize for execution time. Replacing the -O3 with -Os (optimize for size) will probably drop the 14 null bytes, although that is not guaranteed and may depend on the version of GCC you're using.

  • 1
    No it doesn't.
    – user202729
    Aug 23, 2018 at 0:36
  • Yes, I made clear that was just an assumption I made. Thanks for following it through with a test.
    – NirIzr
    Aug 23, 2018 at 0:43
  • Thanks for expanding the answer in another post. Just a side question -- is it possible to figure out programmatically (e.g. parsing with elf.h) whether a given virtual memory address/offset is a string literal instead of other constants? Thanks!
    – HCSF
    Aug 23, 2018 at 1:53
  • 1
    That question might not be as simple as it sounds and additionally more about programing than reverse engineering, I suggest you open a new question over at stackoverflow.com
    – NirIzr
    Aug 23, 2018 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.