Fact-checked by Grok 2 weeks ago

Data segment

In and operating systems, the data segment is a dedicated portion of a process's that stores initialized global and static variables, ensuring their values persist throughout the program's execution. This segment is typically read-write but not , distinguishing it from the code-containing text segment, and it contrasts with the segment, which holds uninitialized or zero-initialized variables. In file formats like ELF, the data segment corresponds to loadable program headers (e.g., PT_LOAD with writable flags) and sections such as .data (of type SHT_PROGBITS with SHF_ALLOC and SHF_WRITE attributes), where the file size reflects initialized data while the memory size may extend to include adjacent uninitialized areas. The data segment plays a crucial role in by allowing compilers and linkers to allocate fixed space for variables known at , facilitating efficient loading and relocation by the operating system loader. For instance, and C++ programs, global variables like int global_var = 42; reside here, with their initial values embedded directly in the file, unlike dynamically allocated memory or runtime stack variables. Its fixed size is determined during , promoting program stability but limiting flexibility compared to the expandable ; modern systems often place it in a protected region to prevent unauthorized access. Historically, the concept evolved from early segmented memory architectures in the , such as those in the PDP-11 and , to support modular code organization and address larger spaces beyond flat models.

Program Memory Layout

Text Segment

The text segment, also known as the , is the read-only portion of a program's that stores the and constant data, ensuring immutability during execution. This segment encapsulates the compiled instructions of the program, such as functions and routines, along with any immutable literals or lookup tables required for operation. By designating this area as non-writable, the segment safeguards the integrity of the program's logic against accidental or malicious alterations. The primary role of the text segment is to hold the program's instructions, which are loaded directly from the .text section of the file into memory at process initialization. In formats like , the operating system's loader parses the program header table to identify loadable segments, mapping the .text section—containing the —into the corresponding region. This mapping establishes the foundation for code execution, with the processor fetching instructions from this segment to carry out the program's behavior. The segment's contents remain fixed throughout the process lifetime, promoting efficiency through potential sharing among multiple instances of the same . Protection mechanisms for the text segment are enforced by the operating system through hardware, typically granting read (PF_R) and execute (PF_X) permissions while explicitly denying write (PF_W) access via ELF program header flags. This read-execute policy prevents self-modification of code, mitigating risks such as exploits that could inject malicious instructions. The enforcement occurs at the hardware level using the (MMU), which traps invalid write attempts and raises exceptions like segmentation faults. For example, in ELF binaries on Unix-like systems, the .text section is mapped to the text segment during process loading by the kernel's binfmt_elf module, which iterates over PT_LOAD program headers to establish the memory layout with appropriate protections. The text segment typically precedes the data segment in the virtual memory address space, providing a structured progression from code to initialized variables.

Data Segment

The data segment is a dedicated region in a program's virtual memory layout that stores initialized global and static variables requiring explicit values determined at compile time. These variables retain their predefined values across the entire program execution, providing persistent storage independent of function calls or runtime allocation. In executable file formats like ELF, prevalent in Unix-like systems, the data segment corresponds to the .data section, which holds initialized data essential to forming the program's initial memory image upon loading. Similarly, in the Portable Executable (PE) format used by Windows, initialized global and static variables reside in sections such as .data, flagged with IMAGE_SCN_CNT_INITIALIZED_DATA to indicate their role. During program startup, the operating system's loader copies the contents of the executable's .data section directly into the corresponding memory addresses in the process's . This ensures that the initialized values are immediately available without additional setup, as specified by the program's headers (e.g., PT_LOAD in , which maps file offsets to virtual addresses). For example, in C programming, a like int globals[10] = {1, 2, 3}; places the and its partial initialization (with remaining elements zero-filled by the ) into the segment, preserving these values for access by any in the program. The loading mechanism contrasts with dynamic allocation, as the data segment's contents are statically bound at link time. The data segment is typically granted read-write permissions by the loader, enabling both retrieval and modification of its contents during execution—permissions encoded as SHF_WRITE in ELF sections or IMAGE_SCN_MEM_WRITE in PE. This distinguishes it from read-only areas like the text segment, allowing programs to update global state as needed. However, this storage of explicit initialization values directly contributes to the executable file's size, as the binary must embed the data bytes (e.g., the non-zero elements of an array), unlike uninitialized counterparts that avoid such overhead. It often adjoins the BSS segment for uninitialized globals, forming a contiguous block of static data in memory.

BSS Segment

The BSS segment, an abbreviation for Block Started by Symbol, serves as the dedicated area in an executable file for storing uninitialized global and static variables, which the system automatically initializes to zero by default. This segment originated from early assembly language conventions but remains a standard feature in modern executable formats like ELF, where it is implemented as the .bss section of type SHT_NOBITS. Unlike the data segment, which accommodates variables with explicit non-zero initial values requiring storage in the file, the BSS segment optimizes for zero-initialized data to minimize executable size. During the program loading process, the operating system loader does not copy any content from the into the segment; instead, it allocates the necessary memory space based on the size specified in the executable's section header and explicitly zero-fills the entire block at . This approach ensures that all variables in the segment start with a value of zero without embedding potentially large blocks of redundant zero bytes in the itself. In the format, the .bss section contributes to the program's memory image under attributes SHF_ALLOC and SHF_WRITE, allowing allocation and modification, while its SHT_NOBITS type confirms that it occupies zero bytes on disk—only the size information is recorded to guide the loader. In languages like C, global or static variables declared without an initializer, such as int uninit_var;, are placed in the BSS segment by the compiler and linker, ensuring they receive an implicit zero initialization upon program startup. The GNU Compiler Collection (GCC) handles this placement through macros like ASM_OUTPUT_ALIGNED_BSS for aligned uninitialized data, directing such variables to the BSS section during code generation. In assembly code, programmers similarly reserve space for uninitialized symbols within this segment, relying on the loader for zeroing. This space-saving mechanism is particularly beneficial for large arrays or buffers that would otherwise bloat the executable file with unnecessary zeros. In the typical virtual memory layout of a process, the BSS segment immediately follows the data segment, forming a contiguous read-write region for static data before the heap begins. This positioning allows efficient memory mapping by the loader, with the BSS extension seamlessly integrated into the program's address space without gaps.

Heap

The heap serves as the dynamic memory region in a program's address space, enabling runtime allocation of memory blocks whose size and timing cannot be predetermined at compile time. In languages like C, this is achieved through functions such as malloc(), which requests a specified number of bytes from the heap and returns a pointer to the allocated block, while in C++, the new operator performs similar dynamic allocation for objects or arrays. This contrasts with static allocations in the data segment, which are fixed prior to execution. The heap's management involves expanding its boundaries as allocations occur, typically growing upward from higher addresses starting just after the BSS segment, using underlying system calls like brk() or sbrk() on Unix-like systems to adjust the program's data segment end. Heap allocators, such as dlmalloc—a widely used general-purpose implementation developed by Doug Lea—handle the subdivision of this region into chunks, tracking allocated and free blocks to fulfill requests efficiently while minimizing overhead. These allocators maintain metadata for each chunk, including size and status, to enable coalescing of adjacent free blocks and prevent overlaps. Allocations on the heap persist until explicitly deallocated, such as via free() in C or delete in C++, allowing memory to outlive the function that requested it and supporting long-lived data structures across the program's execution. This runtime control over lifetime facilitates flexible usage but requires programmers to manage deallocation to avoid leaks. A representative example is constructing a linked list at runtime, where each node—containing data and a pointer to the next—is allocated individually on the heap using malloc(sizeof(Node)), enabling the list to grow dynamically based on input size without predefined limits. A key challenge in heap usage is fragmentation, which degrades allocation over time. Internal fragmentation occurs within allocated blocks when the requested size does not fully utilize the chunk due to requirements or allocator , leaving unusable slack space. External fragmentation arises between blocks, where frequent allocations and deallocations scatter free memory into small, non-contiguous fragments that cannot satisfy larger requests despite sufficient total free space. These issues can lead to allocation failures or performance degradation, prompting the use of strategies like compaction in advanced allocators, though they remain inherent to manual .

Stack

The stack serves as a dynamic of in a program's , functioning as a Last-In-First-Out (LIFO) to manage calls, variables, parameters, and addresses during . Each time a is invoked, a stack frame—or activation record—is pushed onto the , encapsulating the function's data and execution context; upon the function's , this frame is popped, automatically reclaiming the . This mechanism ensures efficient, temporary storage tied to the function's scope, distinct from the static allocations in the data segment that persist throughout the program's lifetime. The typically begins at a high and grows downward toward lower addresses as new are added, a convention that facilitates collision avoidance with the upward-growing in many architectures. frames include space for local , which are allocated automatically without explicit intervention; for instance, declaring int local_var; within a reserves space on the current frame for that , which becomes invalid once the exits. This automatic allocation and deallocation occur seamlessly as part of the function call and process, managed by the and . The finite size of the imposes practical limits on operations like , where each recursive call adds a new ; many systems, such as , default to an 8 MB size per , potentially supporting thousands of recursive calls depending on frame complexity but risking exhaustion with deeper nesting. Exceeding this limit triggers a , often resulting in a as the program attempts to access unauthorized beyond the allocated stack bounds, leading to abrupt termination.

Characteristics of the Data Segment

Initialization and Storage

The data segment is formed during the linking stage of , where the linker merges the .data sections from multiple relocatable s—produced by compilers or —into a single contiguous block within the executable file. This process resolves inter-file references and organizes the initialized global and static variables into the segment, which is marked with attributes for allocation and writability in the program's memory image. In code, the .data directive switches the assembler's output to this section, allowing explicit placement of initialized bytes, words, or other elements; for instance, a directive like .data followed by .byte 0x42 allocates and initializes a single byte in the .data section of the resulting . Initialized variables in the data segment are stored contiguously according to their types and sizes, with bytes inserted between elements or at the end to enforce requirements for efficient access and . For example, on architectures, integers typically require 4-byte , leading to after smaller types like characters to position subsequent variables at multiples of 4 bytes. Structures and unions may include additional to ensure their overall size is a multiple of the strictest of their members, preventing misalignment issues. During linking, relocation entries in the object files are processed to fix addresses within the data segment relative to its load address, adjusting symbolic references such as pointers or offsets to their absolute positions in the final binary. This step accounts for the segment's placement in virtual memory, using types like R_X86_64_RELATIVE for base address additions. Variations in endianness and alignment rules across architectures pose portability challenges for the data segment; for instance, multi-byte values like integers are stored with the least significant byte first in little-endian systems (common on x86) or most significant byte first in big-endian systems (e.g., some PowerPC variants), while padding amounts differ based on natural alignment boundaries. The ELF format mitigates this through the EI_DATA header field, which specifies the required byte order, and section alignment attributes like sh_addralign to enforce portable layout constraints. In contrast to the BSS segment, which reserves space for uninitialized data without storing values in the binary, the data segment explicitly embeds initialization images.

Access Patterns and Lifetime

The data segment is accessed through direct addressing using global symbols, which are resolved by the linker during the linking phase to absolute or relative offsets within the program's layout. This resolution process involves the linker combining object files, mapping symbols to specific addresses in the .data , and generating the final where references to these globals can be directly dereferenced at without further . In contrast to the , which manages temporary lifetimes for local variables, the data segment provides persistent access to initialized globals throughout the program's execution. The lifetime of the data segment spans the entire duration of the program, from loading into memory by the operating system until process termination, ensuring that and static initialized variables remain allocated and accessible without deallocation during . In unmanaged languages like and C++, this fixed lifetime means the segment is not subject to collection, relying instead on the programmer or compiler to handle any necessary cleanup, though typically none is required as the OS reclaims the memory upon exit. In multithreaded programs, the data segment is generally shared across all threads within the same , allowing concurrent access to global variables but necessitating synchronization mechanisms such as mutexes to prevent . Each thread does not receive a private copy of the data segment; instead, it shares the same , which promotes efficiency but introduces challenges like the need for operations or locks when multiple threads modify shared globals. The read-write nature of the data segment permits modifications to its contents during execution, enabling dynamic updates to variables, but this can lead to race conditions in multithreaded environments where unsynchronized access results in unpredictable behavior or data inconsistencies. For instance, if two threads simultaneously increment a shared counter without proper locking, the final value may be incorrect due to interleaved operations. Debugging tools like GDB facilitate inspection of the data segment by allowing examination of global variable values through commands such as print or info variables, which display the contents of symbols resolved to addresses in the .data section. This capability is essential for verifying the state of initialized globals during program pauses, with GDB resolving symbol names to memory locations for direct value retrieval and analysis.

Size Determination

The size of the data segment in an is primarily determined during the and linking phases, where the allocates space for all initialized global and static variables, including scalars, arrays, and structs, within sections such as .data. The linker then combines these sections from multiple s, calculating the total size by summing the individual contributions to form the cohesive data segment. This process ensures that the segment encompasses only the initialized data required by the program, with the emitting the necessary initialization values alongside the allocated space. In executable file formats like and , the data segment size is explicitly recorded in header structures to guide the operating system's loader. For files, the relevant PT_LOAD program header entry specifies the size through the p_filesz field, which captures the on-disk size of initialized (e.g., from .data sections), and the p_memsz field, which includes additional space for any adjacent uninitialized if needed, with the difference zero-filled at load time. Similarly, in the format, the optional header's SizeOfInitializedData field denotes the summed size of all sections flagged with IMAGE_SCN_CNT_INITIALIZED_DATA, such as .data and .rdata, while individual section headers provide raw and virtual sizes aligned to file and section requirements. These header values, computed by the linker, fix the initial segment size post-linking, influencing the program's overall memory layout by defining the boundary between code and data regions. Compilers offer flags to optimize data segment sizing by enabling finer-grained section placement, which the linker can then selectively include or exclude. For instance, GCC's -fdata-sections option directs the compiler to place each initialized data item into its own dedicated section within the object file, allowing the linker (with options like --gc-sections) to eliminate unused portions and thereby reduce the final data segment size in the executable. Although the initial size is static after linking, some Unix-like systems permit runtime extension of the data segment beyond this fixed allocation using system calls like brk or sbrk, subject to process limits, while the core initialized portion remains fixed in size. Operating systems impose maximum on the data segment to prevent resource exhaustion, particularly in 32-bit environments constrained by . In , the RLIMIT_DATA resource , controllable via ulimit -d, which is often unlimited by but can be configured to cap the total data segment size (including growth), though it can be set higher up to the architecture's 2–3 GB virtual depending on settings like PAE. On 32-bit Windows, processes are generally restricted to 2 GB of user-mode by , extendable to 3 GB via the /3GB switch for systems requiring larger data allocations, beyond which the data segment cannot expand without 64-bit migration.

Variations Across Language Paradigms

Compiled Languages

In compiled languages such as C, C++, and Fortran, the data segment serves as a dedicated portion of the executable file and runtime memory to store initialized global and static variables, ensuring their values are preserved across function calls and program execution. These variables, declared with explicit initializers like int global_var = 10; in C or equivalent module-level declarations in Fortran, are allocated at compile time and linked into the .data section of the object file, distinguishing them from uninitialized variables placed in the BSS segment. This allocation provides a fixed, predictable layout in the resulting binary, where the compiler and linker determine offsets relative to the segment's base address, facilitating efficient access during program startup. The contents of the data segment exhibit a structured behavior observable through and tools; for instance, the GNU utility can extract and display the full binary contents of the .data section using options like -s -j .data, revealing dumps of values and alignments as they appear in the . This predictability aids in , optimization, and verification, as the segment's layout remains consistent across compilations unless influenced by linker flags or optimizations. Portability across platforms introduces variations in segment naming and organization: in systems using the format, the .data section holds writable initialized data, while the Windows format employs .data for modifiable initialized variables and .rdata for read-only constants like string literals, both marked with specific flags in the section headers (e.g., IMAGE_SCN_CNT_INITIALIZED_DATA for .data). When generating () for shared libraries, as commonly required in C and C++ for dynamic linking, the data segment undergoes additional relocations to support loading at arbitrary addresses; references to global variables are resolved via indirections through the (GOT) in the data segment, avoiding fixed absolute addresses and enabling code sharing across processes without per-instance copying. This mechanism, activated by compiler flags like -fPIC in , introduces a small overhead for initial relocation but enhances and efficiency in multi-process environments. A recommended in these languages is to minimize the use of large global or static variables, as excessive data in the segment can inflate its size, leading to poorer locality and increased pressure; instead, favor local or heap-allocated storage for .

Interpreted Languages

In interpreted languages, the traditional concept of a fixed data segment is largely absent, as these languages prioritize dynamic memory management over static allocation at load time. Instead, global variables and constants are stored in runtime environments, such as dictionaries or objects, which allow for flexibility in variable creation, modification, and scoping during execution. For instance, in Python, global variables defined at the module level are stored as attributes in the module's __dict__ dictionary, a dynamic mapping that serves as the module's namespace and is referenced by functions via their __globals__ attribute. Similarly, in JavaScript, global variables are properties attached to the global object (accessible as globalThis or window in browsers), which is itself an object allocated on the heap rather than a pre-allocated static segment. This approach contrasts with compiled native layouts, where initialized data is loaded into a fixed .data section at program startup. Hybrid cases, such as languages compiled to for interpretation, introduce structures that partially simulate a . In , for example, the constant pool within .class files acts as a repository for initialized constants, including string literals, numeric values, and symbolic references like class names and field descriptors, which are resolved and loaded into the JVM's runtime during class initialization. These constants are indexed and accessed via instructions, providing a form of static-like without direct mapping to an OS-level .data segment. The model in such interpreted systems relies heavily on heaps for allocation, where globals and constants are dynamically placed rather than loaded from a fixed .data section, enabling portability across platforms but introducing overhead from runtime resolution. A representative example of global state management in pure interpreters is Python's sys.modules, a dictionary maintained by the interpreter that maps module names to their corresponding objects, effectively serving as a central registry for loaded modules and their associated global namespaces without any static segment involvement. This structure allows modules to share and access global state dynamically, as each module's globals reside in its own dictionary within this registry. The evolution of interpreters has introduced just-in-time (JIT) compilation to bridge performance gaps, yet the absence of traditional data segments persists. In modern JIT engines like V8 for , is compiled to native on-the-fly, potentially generating temporary code sections with embedded constants, but global data remains allocated as dynamic objects on the , maintaining the interpreted paradigm's flexibility over fixed layouts.

Managed Environments

In managed environments such as the (JVM) and the .NET (CLR), the concept of a traditional operating system-level data segment is virtualized and integrated into the runtime's memory model, where static fields are stored in dedicated areas like the method area or associated structures rather than a fixed OS segment. This abstraction allows the runtime to handle initialization, access, and garbage collection uniformly across application domains, decoupling developers from low-level concerns inherent in native compiled languages. Class loaders in these environments initialize static fields at class load time through dedicated mechanisms, providing a virtualized equivalent to the data segment's role in storing initialized global data. In the JVM, for instance, static variables are stored as fields of the instance object in the , with residing in the Metaspace (the post-JDK 8 implementation of the method area using native ). Initialization occurs via the implicitly generated <clinit> , which executes when the is first loaded or referenced, ensuring static fields are set before any member access. Similarly, in the CLR, static fields are embedded in the MethodTable (stored in the loader , part of the domain-neutral ) for , while and types are allocated on the managed and referenced via handles in the AppDomain table, with initialization triggered during type loading by the . This approach offers key advantages, including automatic through collection, which mitigates issues like fragmentation or manual size allocation that plague traditional data segments, and enables without fixed reservations at process startup. In modern contexts, extends these ideas with a linear model—a single, growable contiguous byte array—that incorporates data segments for initializing static byte sequences at specific offsets during module instantiation, blending data segment persistence with heap-like dynamism in sandboxed environments.

Historical Development

Origins in Early Systems

Early efforts to manage limited main in large-scale computers during the 1960s, such as in the family announced in 1964, involved structuring programs using load modules divided into segments to support overlays. In the System/360 Operating System (OS/360), a root segment containing essential code and control information remained resident in , while other segments were loaded serially as needed to fit within constraints of typically 8K to 256K words of core storage. This separation of code and data areas allowed efficient reuse of space, as non-resident segments could overlay previously used areas without requiring the entire program to fit simultaneously, addressing the era's high cost and scarcity of . In the , assembly languages for further refined data handling through directives that positioned constants and controlled segment layout. Directives such as EQU, which equated symbols to constant values for initialized data, and ORG, which set the origin or starting address for code and data placement, originated in early assemblers and were adapted in minicomputer environments like the PDP-11 to optimize memory allocation amid 16-bit address limits and small core sizes often under 64K words. These tools enabled programmers to define static data areas explicitly, separating initialized constants from executable code to facilitate modular loading and reduce fragmentation in resource-constrained systems. The microprocessor (1978) introduced segmented memory with dedicated data segment registers (, ES), supporting separate code and data addressing to manage larger memory spaces in early PC systems. The development of Unix on the PDP-11 in the formalized the data segment structure, distinguishing initialized data (.data) from uninitialized storage (.bss) within the a.out format. On the PDP-11, running under 56K bytes of , the .data directive allocated space for explicitly initialized variables, while .bss reserved blocks for zero-initialized globals without embedding zeros in the file, reflecting hardware limitations where every byte of storage and disk space was precious. This separation motivated efficient use by minimizing size—often critical for tape or disk-limited distributions—while ensuring runtime zeroing of .bss via the loader, preventing waste on redundant zero bytes that comprised much of uninitialized data. A key milestone came with Unix Version 7 in , which standardized these segment concepts in its assembler and linker for the PDP-11, embedding .data and .bss into the portable a.out format used across systems. This standardization solidified the tripartite division of text (code), data (initialized), and bss (uninitialized) segments, influencing subsequent Unix variants by providing a blueprint for balancing initialization overhead with storage efficiency in low-memory environments.

Evolution in Modern OS

In the 1980s, the 80386 , released in 1985, introduced , which utilized segment descriptors to provide finer-grained for data segments compared to prior real-mode addressing. These descriptors, stored in descriptor tables, defined segment base addresses, limits, and access rights—such as read/write permissions without execution—allowing operating systems to enforce boundaries and privileges that prevented unauthorized access or overflows into other memory regions. This advancement enabled more robust multitasking and data isolation in systems like early precursors and Unix variants. The 1990s saw the standardization of the (ELF) in operating systems including and , where PT_LOAD program headers delineated loadable segments for , explicitly setting writable flags (via p_flags) to mark modifiable areas distinct from read-only code. Adopted widely by the mid-1990s, ELF replaced older formats like a.out, facilitating consistent loading of initialized and uninitialized (e.g., .data and .bss sections) into writable memory regions while supporting dynamic linking. This uniformity improved portability and efficiency in handling segment initialization across systems. During the 2000s, (ASLR) emerged as a key security enhancement, with the patch for introducing it in 2001 by randomizing base addresses of data segments, , and libraries to thwart predictable exploits. Complementing this, the W^X policy—pioneered in and adopted in 3.3 in May 2003—leveraged hardware NX bits to ensure data segments remained non-executable, blocking attacks that inject into writable areas. By 2025, these evolutions extend to containerized environments like , where isolate processes while 64-bit kernels support terabyte-scale data segments within a 128 TB user , enabling large-scale applications without compromising isolation.

References

  1. [1]
    CS 537 Lecture Notes, Part 8 Segmentation - cs.wisc.edu
    Another segment (the data segment) holds the memory used for global variables. Its protection is read/write (but usually not executable), and is normally ...
  2. [2]
    Storage Class
    The memory of a C++ program running on Unix consists of the following sections: Text segment; Static data region. Initialized data segment; Uninitialized data ...
  3. [3]
    elf(5) - Linux manual page - man7.org
    An executable file using the ELF file format consists of an ELF header, followed by a program header table or a section header table, or both. The ELF header ...
  4. [4]
    Memory Usage - UAF CS
    Above the text segment is the data segment (starting at 0x10010000), which is divided into two parts. The static data portion contains objects whose size and ...
  5. [5]
    [PDF] Memory management in C: The heap and the stack
    Oct 7, 2010 · • Data segment: Data segment is sub divided into two parts. – Initialized data segment: All the global, static and constant data are stored ...
  6. [6]
    Memory Layout
    Data Segment: This holds the data that the program operates on. Part of the data is static. This is data that is allocated by the assembler and whose size ...
  7. [7]
    Predefined Segments - Linker and Libraries Guide
    The text segment is the first segment in the process, and is therefore assigned the ELF header, and the program header array by the link-editor. This can be ...
  8. [8]
    How programs get run: ELF binaries - LWN.net
    Feb 4, 2015 · The code loops through all of the PT_LOAD segments in the program file and maps them into the process's address space, setting up the new ...<|control11|><|separator|>
  9. [9]
    Segment Permissions - Oracle Help Center
    For example, typical text segments have read and execute, but not write permissions. Data segments normally have read, write, and execute permissions.Missing: enforcement | Show results with:enforcement
  10. [10]
    [PDF] Tool Interface Standard (TIS) Executable and Linking Format (ELF ...
    This section holds version control information. .data and .data1. These sections hold initialized data that contribute to the program's memory image.
  11. [11]
    PE Format - Win32 apps - Microsoft Learn
    Jul 14, 2025 · This document specifies the structure of executable (image) files and object files under the Microsoft Windows family of operating systems.
  12. [12]
    Memory Layout of C Programs - GeeksforGeeks
    Oct 18, 2025 · The data segment stores global and static variables of the program. · Variables in this segment retain their values throughout program execution.
  13. [13]
    ELF Special Sections - Linux Foundation
    .bss. This section holds uninitialized data that contribute to the program's memory image. ·.comment. This section holds version control information. ·.data.
  14. [14]
    Block Started by Symbol - Computer Dictionary Online
    (BSS) The uninitialised data segment produced by Unix linkers. Objects in the bss segment have only a name and a size but no value.
  15. [15]
    [PDF] Executables Feb. 21, 2020
    Feb 21, 2020 · Memory image has bss segment! ... Merges multiple relocatable (.o) object files into a single executable object file that can loaded and executed ...
  16. [16]
    Uninitialized Data (GNU Compiler Collection (GCC) Internals)
    ### Summary: GCC Handling of Uninitialized Global and Static Variables and BSS Section
  17. [17]
    [PDF] Dynamic Memory Management: Dlmalloc
    Malloc manages the heap and provides standard memory management. ▫ In dlmalloc, memory chunks are either allocated to a process or are free. Page 59 ...
  18. [18]
    [PDF] CS3214 Lecture Memory Allocation - Computer Science (CS)
    – For any block, internal fragmentation is the difference between the block size and the payload size. – Caused by overhead of maintaining heap data structures, ...
  19. [19]
    [PDF] Memory Allocation & Heap
    Memory Allocation & Heap. Page 2. Memory allocation within a process ... ○ internal fragmentation. ○ external fragmentation. ▫ malloc fragmentation.
  20. [20]
    CS360 Lecture notes -- Fragmentation - UTK-EECS
    There are two types of fragmentation -- external and internal. External is fragmentation due to unused memory on nodes of the free list. In the example above, ...
  21. [21]
    The Stack, The Heap, and Dynamic Memory Allocation - CS 3410
    The compiler takes care of managing data on the stack: it allocates space in stack frames for all your local variables automatically. Your code, on the ...
  22. [22]
    5.5. Local Memory - OpenDSA
    Local variables are also known as automatic variables since their allocation and deallocation is done automatically as part of the function call mechanism.
  23. [23]
    CS 225 | Stack and Heap Memory - Course Websites
    The layout consists of a lot of segments, including: stack : stores local variables. heap : dynamic memory for programmer to allocate. data : stores global ...
  24. [24]
    pthreads(7) - Linux manual page - man7.org
    ... default stack size for new threads. To be effective, this limit must be set before the program is executed, perhaps using the ulimit -s shell built-in ...
  25. [25]
    Testing and Debugging - UT Computer Science
    Segfault: A Segfault (segmentation fault) is signaled by the CPU when the program attempts to access memory that does not exist. A common cause of segfaults is ...
  26. [26]
    Top (LD)
    **Summary of LD Process for Combining .data Sections:**
  27. [27]
    Assembler Directives - x86 Assembly Language Reference Manual
    tdata directive changes the current section to .tdata. The .tdata section contains the initialization image for initialized TLS data objects. .text. The ...
  28. [28]
    [PDF] System V Application Binary Interface - AMD64 Architecture ...
    Jul 2, 2012 · Structure and union objects can require padding to meet size and alignment ... The end of the data segment requires special handling for ...
  29. [29]
    None
    Summary of each segment:
  30. [30]
    [PDF] Introduction to Computer Systems
    Feb 26, 2025 · What Do Linkers Do? □ Step 1: Symbol resolution. ▫ Programs ... .data section. Page 28. Carnegie Mellon. Linker Symbols. □ Global symbols. ▫ ...
  31. [31]
    CSC 209: Process memory layout and OS considerations
    Variables with global lifetime are allocated in the data segment. Scope is an error-checking issue for the C compiler; global versus stack is a lifetime issue.
  32. [32]
    Threads - CS 3410 - Cornell: Computer Science
    When there are multiple threads, everything remains the same (the heap, text, and data segments are all unchanged) except that there are multiple stacks ...Missing: per | Show results with:per
  33. [33]
    6.2. Processes vs. Threads — Computer Systems Fundamentals
    However, all of the other segments of memory, including the code, global data, heap, and kernel, are shared.
  34. [34]
    What resources are shared between threads? - Stack Overflow
    Nov 19, 2009 · Threads share code, data, and heap segments, but each thread has its own stack, which is divided from the process's stack area.How do two or more threads share memory on the heap that they ...Multithreading vs Shared Memory - Stack OverflowMore results from stackoverflow.com
  35. [35]
    6.3. Race Conditions and Critical Sections - Computer Science - JMU
    Every access to a global variable in a multithreaded program creates a critical section. ... multiple threads concurrently without introducing any race conditions ...
  36. [36]
    Race Condition Vulnerability - GeeksforGeeks
    Oct 30, 2025 · Race condition occurs when multiple threads or processes read and write the same variable i.e. they have access to some shared data and they ...
  37. [37]
    Data (Debugging with GDB) - Sourceware
    The usual way to examine data in your program is with the print command (abbreviated p ), or its synonym inspect. It evaluates and prints the value of an ...
  38. [38]
    Code Gen Options (Using the GNU Compiler Collection (GCC))
    ... GCC option. ... Set the default ELF image symbol visibility to the specified option—all symbols are marked with this unless overridden within the code.
  39. [39]
    LD - Sourceware
    This file documents the GNU linker ld (GNU Binutils) version 2.42. This document is distributed under the terms of the GNU Free Documentation License version ...
  40. [40]
    getrlimit(2) - Linux manual page - man7.org
    Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited. RLIMIT_CORE This is the maximum ...
  41. [41]
    Memory Limits for Windows and Windows Server Releases
    Jun 11, 2025 · Windows Home Server is available only in a 32-bit edition. The physical memory limit is 4 GB. Physical Memory Limits: Windows Server 2003 R2.
  42. [42]
    Sections (GNU Compiler Collection (GCC) Internals)
    In the most common case, there are three sections: the text section, which holds instructions and read-only data; the data section, which holds initialized ...
  43. [43]
    None
    Nothing is retrieved...<|separator|>
  44. [44]
    objdump(1) - Linux manual page - man7.org
    objdump displays information about one or more object files. The options control what particular information to display.Missing: reveal | Show results with:reveal
  45. [45]
    Position-Independent Code (Linker and Libraries Guide)
    When you use position-independent code, relocatable references are generated as an indirection that will use data in the shared object's data segment. The text ...<|separator|>
  46. [46]
    Improving cache performance in dynamic applications through data ...
    Strategies for cache and local memory management by global program transformations. ... A split data cache organization based on run-time data locality estimation.
  47. [47]
    3. Data model — Python 3.14.0 documentation
    A reference to the dictionary that holds the function's global variables – the global namespace of the module in which the function was defined. function.__ ...
  48. [48]
    globalThis - JavaScript - MDN Web Docs
    Jul 8, 2025 · The globalThis property provides a standard way of accessing the global this value (and hence the global object itself) across environments.
  49. [49]
    Chapter 4. The class File Format
    Summary of each segment:
  50. [50]
    sys — System-specific parameters and functions — Python 3.14.0 ...
    This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.Sys.monitoring · Python Runtime Services · Fileinput · Audit events table
  51. [51]
    Visualizing memory management in V8 Engine (JavaScript, NodeJS ...
    Jan 27, 2020 · Code-space: This is where the Just In Time(JIT) compiler stores compiled code Blocks. This is the only space with executable memory (although ...
  52. [52]
    Chapter 2. The Structure of the Java Virtual Machine
    ### Summary: Storage of Static Variables in JVM (Post-JDK 8, Metaspace vs Heap) and Class Loading with `<clinit>`
  53. [53]
    .NET Framework Internals: How the CLR Creates Runtime Objects
    In this article, we'll explore CLR internals, including object instance layout, method table layout, method dispatching, interface-based dispatching, and ...
  54. [54]
    JVM Storage for Static Members | Baeldung
    Jan 8, 2024 · Since Java 8, Metaspace only stores the class metadata, and heap memory keeps the static members. Furthermore, the heap memory also provides ...
  55. [55]
  56. [56]
    Overview — WebAssembly 3.0 (2025-11-02)
    ### Summary of Linear Memory Model and Data Segments in WebAssembly
  57. [57]
    [PDF] IBM System/360 Operating System: .Concepts and Facilities
    Storage Occupied by Segment A ( the Root Segment). Storage When Segments A and B are Resident. Storage After Segment C Overlays Segment B. Figure 9. Storage ...Missing: layout | Show results with:layout
  58. [58]
    [PDF] IBM System/360 Operating System Assembler Language
    This publication contains specifications for the IBM System/360 Operating System. Assembler Language (Levels E and F). The assembler language is a symbolic.
  59. [59]
    [PDF] v7vol2b.pdf - Amazon S3
    Segments. Assembled code and data fall into three segments: the text segment, the data segment, and the bss segment. The text segment is the one in which the ...
  60. [60]
    Operating Modes of 80386 Microprocessors - GeeksforGeeks
    May 14, 2023 · A 32-bit address space is available in protected mode, a sophisticated operating mode that gives users access to up to 4GB of memory.
  61. [61]
    Protected Mode Basics - Robert R. Collins
    In protected mode, memory segmentation is defined by a set of tables (called descriptor tables) and the segment registers contain pointers into these tables.
  62. [62]
    Program Header (Linker and Libraries Guide)
    A program header is an array of structures describing segments needed for program execution, including p_type, p_offset, and p_vaddr.Missing: 1990s | Show results with:1990s
  63. [63]
    [PDF] On the Effectiveness of Address-Space Randomization - Ben Pfaff
    This mechanism is available for both Linux (via PaX ASLR) and OpenBSD. We study the e ectiveness of address-space randomization and nd that its utility on 32- ...
  64. [64]
    [PDF] IMIX: In-Process Memory Isolation EXtension - USENIX
    Aug 17, 2018 · Prominent examples include: W⊕X [44, 48] which prevents data from being executed, ... Using type analysis in compiler to mitigate integer-overflow ...
  65. [65]
    22.3. Memory Management — The Linux Kernel documentation
    Negative addresses such as “-23 TB” are absolute addresses in bytes, counted down from the top of the 64-bit address space. It's easier to understand the layout ...Missing: limit | Show results with:limit