Get the start and end address of text section in an executable

c gcc ld
phoxis picture phoxis · Sep 10, 2011 · Viewed 21.3k times · Source

I need to get the start and end address of an executable's text section. How can I get it?

I can get the starting address from the _init symbol or the _start symbol, but what about the ending address? Shall I consider the ending address of the text section to be the last address before starting of the .rodata section?

Or shall I edit the default ld script and add my own symbols to indicate the start and end of the text section, and pass it to GCC when compiling? In this case, where shall I place the new symbols, shall I consider the init and fini section?

What is a good way to get the start and end address of the text section?

Answer

Matthew Slattery picture Matthew Slattery · Sep 10, 2011

The GNU binutils default linker scripts for ELF-based platforms normally define quite a number of different symbols which can be used to find the start and end of various sections.

The end of the text section is usually referenced by a choice of three different symbols: etext, _etext or __etext; the start can be found as __executable_start. (Note that these symbols are usually exported using the PROVIDE() mechanism, which means that they will be overridden if something else in your executable defines them rather than merely referencing them. In particular that means that _etext or __etext are likely to be safer choices than etext.)

Example:

$ cat etext.c
#include <stdio.h>

extern char __executable_start;
extern char __etext;

int main(void)
{
  printf("0x%lx\n", (unsigned long)&__executable_start);
  printf("0x%lx\n", (unsigned long)&__etext);
  return 0;
}
$ gcc -Wall -o etext etext.c
$ ./etext
0x8048000
0x80484a0
$

I don't believe that any of these symbols are specified by any standard, so this shouldn't be assumed to be portable (I have no idea whether even GNU binutils provides them for all ELF-based platforms, or whether the set of symbols provided has changed over different binutils versions), although I guess if a) you are doing something that needs this information, and b) you're considering hacked linker scripts as an option, then portability isn't too much of a concern!

To see the exact set of symbols you get when building a particular thing on a particular platform, give the --verbose flag to ld (or -Wl,--verbose to gcc) to print the linker script it chooses to use (there are really several different default linker scripts, which vary according to linker options and the type of object you're building).