Program Sections

When a program is compiled, it is divided into several sections that categorize the types of data and instruction it contains. These sections help the linker organize and manage program's memory layout efficiently.

Here are the primary sections you will encounter:

  1. .text
  2. .data
  3. .bss
  4. .rodata
  5. .comment
  6. .eh_frame
  7. .init, .fini, .ctors, .dtors
  8. Heap and Stack (though not sections in the binary, they are crucial in memory layout)

1 Visualization of Program Sections

Consider a typical memory layout for a simple program:

Memory Address
|--------------|----------------------|
| Section      | Description          |
|--------------|----------------------|
| 0x00000000   | .text (code)         |
|              | - Executable code    |
|--------------|----------------------|
| 0x00100000   | .rodata (read-only)  |
|              | - Constants          |
|--------------|----------------------|
| 0x00200000   | .data (initialized)  |
|              | - Global/static vars |
|--------------|----------------------|
| 0x00300000   | .bss (zero-init)     |
|              | - Uninitialized vars |
|--------------|----------------------|
| 0x00400000   | Heap                 |
|              | - Dynamic allocation |
|--------------|----------------------|
| 0x00500000   | Stack                |
|              | - Function call data |
|--------------|----------------------|

2 Detailed Explanation of Each Section

1 .text Section:

Contains the executable code of the program.

Characteristics:

  • Read-only
  • Executable

Memory Example:

0x08048000: start:   MOV EAX, 1
0x08048005:          ADD EAX, 2
0x08048008:          INT 0x80  ; syscall

2 .rodata Section:

Stores read-only data such as string literals and constants.

Characteristics:

  • Read-only

Memory Example:

0x08049000:          "Hello, World!\0"

3 .data Section:

Contains initialized global and static variables.

Characteristics:

  • Read-write

Memory Example:

0x0804A000: int_var: 0x12345678
0x0804A004: char_var: 'A'

4 .bss Section:

Contains uninitialized global and static variables, which are zeroed out at runtime.

Characteristics:

  • Read-write

Memory Example:

0x0804B000: uninit_var: 0x00000000
0x0804B004: another_var: 0x00000000

5 .comment Section:

Typically includes comments or metadata (not used at runtime).

Characteristics:

  • Often discarded

Memory Example:

(This section is often not loaded into memory and may contain version info or compiler metadata.)

6 .eh_frame Section:

Used for exception handling (part of the stack unwinding process).

Characteristics:

  • Read-only

Memory Example:

(Contains frame unwind information for exception handling.)

7 init, .fini, .ctors, .dtors Sections:

Contain initialization and finalization code and constructors/destructors for C++.

Characteristics:

  • .init and .fini are used for initialization and cleanup routines.
  • .ctors and .dtors are used for constructors and destructors.

Memory Example:

.init
0x08048000: _init_start:
0x08048004:          <init code>

.fini
0x08048010: _fini_start:
0x08048014:          <cleanup code>

.ctors
0x08048020: constructor_list:
0x08048024:          <address of constructor>

.dtors
0x08048030: destructor_list:
0x08048034:          <address of destructor>

8 Heap and Stack

  • Heap: Used for dynamic memory allocation (malloc, free).
    • Grows upwards in memory.
  • Stack: Used for function call management (local variables, return addresses).
    • Grows downwards in memory.

3 Creating Custom Sections

3.1 In C:

3.1.1 Creating Custom

To place variables or function in the custom section, you can use GCC-specific attributes in your C code.

#include <stdio.h>

// Placing a variable in the custom section
int my_custom_variable __attribute__((section(".mycustomsection"))) = 42;

// Placing a function in the custom section
void my_custom_function(void) __attribute__((section(".mycustomsection")));

void my_custom_function(void) {
    printf("Hello from custom section!\n");
}

int main() {
    printf("Custom variable value: %d\n", my_custom_variable);
    my_custom_function();
    return 0;
}

Code Attributes

  • __attribute__((section(".mycustomsection"))): This GCC-specific attribute places the variable or function in the .mycustomsection.
  • The custom variable and function will be located in the memory region specified for .mycustomsection.

3.1.1 Linker Script Example:

Here's a sample linker script that defines custom sections:

OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
OUTPUT("custom_sections.bin")

MEMORY
{
    ROM (rx) : ORIGIN = 0x08048000, LENGTH = 0x00001000
    RAM (rwx) : ORIGIN = 0x08049000, LENGTH = 0x01000000
}

SECTIONS
{
    .text : {
        *(.text)
        . = ALIGN(4096);
    } > ROM

    .data : {
        *(.data)
        . = ALIGN(4096);
    } > RAM

    .bss : {
        *(.bss)
        . = ALIGN(4096);
    } > RAM

    .mycustomsection : {
        *(.mycustomsection)
        . = ALIGN(4096);
    } > RAM

    /DISCARD/ : {
        *(.comment)
        *(.eh_frame)
    }
}

Linker Script (.mycustomsection)

  • .mycustomsection: This custom section is defined to store any data or code labeled with the .mycustomsection attribute.
  • * indicates that all input sections with the specified name should be included in this output section.
  • > RAM places the custom section in RAM. You can change this to another memory region if needed.
  • . = ALIGN(4096); ensures that the section is aligned on a 4096-byte boundary, which can be important for performance or hardware requirements.

3.1.2 Visualizing Custom Sections

Here's how the memory layout might look with a custom section added:

Memory Address
|--------------|----------------------|
| Section      | Description          |
|--------------|----------------------|
| 0x08048000   | .text (code)         |
|              | - Executable code    |
|--------------|----------------------|
| 0x08049000   | .rodata (read-only)  |
|              | - Constants          |
|--------------|----------------------|
| 0x0804A000   | .data (initialized)  |
|              | - Global/static vars |
|--------------|----------------------|
| 0x0804B000   | .bss (zero-init)     |
|              | - Uninitialized vars |
|--------------|----------------------|
| 0x0804C000   | .mycustomsection     |
|              | - Custom data/funcs  |
|--------------|----------------------|
| 0x0804D000   | Heap                 |
|              | - Dynamic allocation |
|--------------|----------------------|
| 0xFFFFE000   | Stack                |
|              | - Function call data |
|--------------|----------------------|

In this example:

  • .mycustomsection starts at address 0x0804C000 and includes my_custom_variable and my_custom_function.

3.2 In Assembly

3.2.1 Assembly Code with Custom Sections

Let's start with an example in assembly where we define a custom section named .mycustomsection.

.section .text
.globl _start
_start:
    call my_custom_function
    mov $1, %eax    # syscall: exit
    xor %ebx, %ebx  # exit code 0
    int $0x80

.section .mycustomsection
.globl my_custom_function
my_custom_function:
    # Function body
    push %ebp
    mov %esp, %ebp
    mov $message, %eax
    call print_string
    pop %ebp
    ret

message:
    .asciz "Hello from custom section!\n"

.section .data
print_string:
    # Print string pointed to by %eax
    push %ebp
    mov %esp, %ebp
    mov %eax, %ecx      # Pointer to string
    mov $4, %eax        # syscall: write
    mov $1, %ebx        # file descriptor: stdout
    mov $24, %edx       # message length
    int $0x80
    pop %ebp
    ret



  1. .section .text
    1. The .text section contains the _start label, which is the entry point of the program.
    2. _start calls my_custom_function and then exits.
  2. .section .mycustomsection
    1. This section is defined as .mycustomsection.
    2. It contains the my_custom_function and a message string.
  3. .section .data
    1. The .data section contains the print_string function, which is used to print a string to the console.

3.2.2 Linker Script with Custom Sections

Next, we need a linker script that defines where our custom section should be placed in memory.

OUTPUT_FORMAT(elf32-i386)
ENTRY(_start)
OUTPUT("custom_sections.bin")

MEMORY
{
    ROM (rx) : ORIGIN = 0x08048000, LENGTH = 0x00001000
    RAM (rwx) : ORIGIN = 0x08049000, LENGTH = 0x01000000
}

SECTIONS
{
    .text : {
        *(.text)
        . = ALIGN(4096);
    } > ROM

    .data : {
        *(.data)
        . = ALIGN(4096);
    } > RAM

    .bss : {
        *(.bss)
        . = ALIGN(4096);
    } > RAM

    .mycustomsection : {
        *(.mycustomsection)
        . = ALIGN(4096);
    } > RAM

    /DISCARD/ : {
        *(.comment)
        *(.eh_frame)
    }
}

PROVIDE(_stack_start = 0xFFFFE000);
PROVIDE(_heap_start = 0x0804C000);
  1. OUTPUT_FORMAT(elf32-i386)
    1. Specifies the output file format, in this case, 32-bit ELF for x86.
  2. ENTRY(_start)
    1. Defines the entry point of the program as _start.
  3. MEMORY Block
    1. ROM: Read-only memory region, starting at 0x08048000 with a length of 0x00001000 bytes.
    2. RAM: Read-write memory region, starting at 0x08049000 with a length of 0x01000000 bytes.
  4. SECTIONS Block
    1. .text: Contains the .text section and aligns it to the next 4096-byte boundary.
    2. .data: Contains the .data section and aligns it to the next 4096-byte boundary.
    3. .bss: Contains the .bss section and aligns it to the next 4096-byte boundary.
    4. .mycustomsection: Contains the .mycustomsection and aligns it to the next 4096-byte boundary.
    5. /DISCARD/: Discards the .comment and .eh_frame sections.
  5. PROVIDE Statements
    1. _stack_start: Defines the start of the stack at 0xFFFFE000.
    2. _heap_start: Defines the start of the heap at 0x0804C000.

3.2.3 Building and Linking

To assemble and link this program, you would typically use the following commands:

as -o program.o program.s
ld -T linker_script.ld -o program program.o

3.2.4 Visualizing the Memory Layout

Here's how the memory layout might look with the custom section:

Memory Address
|--------------|----------------------|
| Section      | Description          |
|--------------|----------------------|
| 0x08048000   | .text (code)         |
|              | - Executable code    |
|--------------|----------------------|
| 0x08049000   | .rodata (read-only)  |
|              | - Constants          |
|--------------|----------------------|
| 0x0804A000   | .data (initialized)  |
|              | - Global/static vars |
|--------------|----------------------|
| 0x0804B000   | .bss (zero-init)     |
|              | - Uninitialized vars |
|--------------|----------------------|
| 0x0804C000   | .mycustomsection     |
|              | - Custom data/funcs  |
|--------------|----------------------|
| 0x0804D000   | Heap                 |
|              | - Dynamic allocation |
|--------------|----------------------|
| 0xFFFFE000   | Stack                |
|              | - Function call data |
|--------------|----------------------|