Search topics...
Build SystemsSections & Memory Layoutfoundational

.text vs .rodata — what goes in each, and where do they live at runtime?

0 upvotes
Practice with AISoon
Study the fundamentals first — Build Systems topic page

Both live in Flash on a typical embedded target.

.text holds executable code — the machine instructions for every function in your program. The CPU's program counter (PC) points into .text to fetch and execute instructions. On Cortex-M, code in .text is read directly from Flash (with appropriate wait states for the CPU clock speed). It's marked read-execute (rx) in the MEMORY block.

.rodata holds read-only data — const-qualified globals, string literals (every "hello" your program contains), lookup tables marked const, and switch-statement jump tables. The CPU reads .rodata from Flash via the regular bus, not as instructions. It's effectively part of the loadable Flash image but has no executable permission.

Both share Flash because:

  • They're both immutable
  • They're both accessible from the CPU bus (with the right MPU configuration)
  • Putting them in RAM would waste it for no benefit

Some toolchains and linker scripts even merge .rodata into .text for simplicity (since they have the same lifecycle and permissions). The distinction matters when you want different MPU permissions (e.g., execute on .text, read-only on .rodata) or when stripping debug builds.

The practical implication: declaring const uint8_t lookup[1024] = {...}; puts it in .rodata (1024 B Flash, zero RAM). Without const, the same array goes in .data (1024 B Flash for init values + 1024 B RAM for runtime copy). Always const lookup tables.

Source: Build Systems Q&A