Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of dynamic initialization for global variables and static member variables in C++

I have some questions about the implementation of variable initialization in C++ in regards to the linking and executable module loading process. My main concern is with dynamic initialization of global variables and static member variables, wherein the initialization process involves the execution of code. I'm looking for the answer to address my questions for both Windows and Linux.

I already understand that in the case of static initialization:

-the initial value is placed into its own section during compilation

-the sections are mapped into memory by the OS module loader

-the variable is assigned the location of the initial value's memory address with the application of a DIR32 type relocation

Here are my questions.

  1. What information does the compiler place into a generated object file relating to dynamic initialization of global variables for the linker to use? Please go into as much detail as possible about related sections and generated symbols. What differences are there for static member variables compared to non-static global variables?

  2. What information does the linker place into the final linked module during the linking process so that the OS module loader is able to correctly initialize all variables (including dynamically initialized global/static member variables that make calls to functions as part of initialization)?

  3. How is the function that needs to be executed during dynamic variable initialization mapped to the particular variable that needs to be initialized with that code?

  4. When an executable or dynamically linked module is loaded, how is dynamic initialization of variables performed?

  5. Does the implementation of C++11 constant expressions (marked by the constexpr specifier) involve any special considerations compared to the implementation of regular static member variables and functions?

I have a specific example case I'm hoping the answer could refer to within the framework of the above questions, since I felt that having a concrete example of taking an object file, identifying the relevant sections/symbols and how this particular code would be linked and loaded so that successful initialization of the static variable could be carried out would make the answer easier to understand. This example is for Windows using MSVC as the compiler; please mention specific differences for gcc/linux wherever they exist.

Here is a simple example of C++ code involving a regular variable and a static member variable which from my understanding needs to be dynamically initialized by the OS loader before main because it makes a call to a function as part of its initialization:

class Test
{
public:

    static int testFunction()
    {
        return 10;
    }

    static int memberVar;
};

int Test::memberVar = Test::testFunction();

int foo()
{
    return 5;
}

int var = foo();


int main(int argc, char* argv[])
{
    var;

    Test::memberVar;

    return 0;
}

And here is a dump of the sections and symbols for the object file produced by MSVC using the above code compiled in debug mode (the dump was created with llvm-readobj, a utility which comes with llvm/clang):

File: Source.obj
Format: COFF-i386
Arch: i386
AddressSize: 32bit
Sections [
  Section {
    Number: 1
    Name: .drectve (2E 64 72 65 63 74 76 65)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 65
    PointerToRawData: 0x2BC
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0x100A00)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_LNK_INFO (0x200)
      IMAGE_SCN_LNK_REMOVE (0x800)
    ]
  }
  Section {
    Number: 2
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 3380
    PointerToRawData: 0x2FD
    PointerToRelocations: 0x1031
    PointerToLineNumbers: 0x0
    RelocationCount: 8
    LineNumberCount: 0
    Characteristics [ (0x42100040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 3
    Name: .debug$T (2E 64 65 62 75 67 24 54)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 136
    PointerToRawData: 0x1081
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0x42100040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 4
    Name: .text$di (2E 74 65 78 74 24 64 69)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 60
    PointerToRawData: 0x1109
    PointerToRelocations: 0x1145
    PointerToLineNumbers: 0x0
    RelocationCount: 3
    LineNumberCount: 0
    Characteristics [ (0x60501020)
      IMAGE_SCN_ALIGN_16BYTES (0x500000)
      IMAGE_SCN_CNT_CODE (0x20)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_EXECUTE (0x20000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 5
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 216
    PointerToRawData: 0x1163
    PointerToRelocations: 0x123B
    PointerToLineNumbers: 0x0
    RelocationCount: 5
    LineNumberCount: 0
    Characteristics [ (0x42101040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 6
    Name: .text$di (2E 74 65 78 74 24 64 69)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 60
    PointerToRawData: 0x126D
    PointerToRelocations: 0x12A9
    PointerToLineNumbers: 0x0
    RelocationCount: 3
    LineNumberCount: 0
    Characteristics [ (0x60501020)
      IMAGE_SCN_ALIGN_16BYTES (0x500000)
      IMAGE_SCN_CNT_CODE (0x20)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_EXECUTE (0x20000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 7
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 204
    PointerToRawData: 0x12C7
    PointerToRelocations: 0x1393
    PointerToLineNumbers: 0x0
    RelocationCount: 5
    LineNumberCount: 0
    Characteristics [ (0x42101040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 8
    Name: .text$mn (2E 74 65 78 74 24 6D 6E)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 42
    PointerToRawData: 0x13C5
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0x60501020)
      IMAGE_SCN_ALIGN_16BYTES (0x500000)
      IMAGE_SCN_CNT_CODE (0x20)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_EXECUTE (0x20000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 9
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 192
    PointerToRawData: 0x13EF
    PointerToRelocations: 0x14AF
    PointerToLineNumbers: 0x0
    RelocationCount: 5
    LineNumberCount: 0
    Characteristics [ (0x42101040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 10
    Name: .text$mn (2E 74 65 78 74 24 6D 6E)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 42
    PointerToRawData: 0x14E1
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0x60501020)
      IMAGE_SCN_ALIGN_16BYTES (0x500000)
      IMAGE_SCN_CNT_CODE (0x20)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_EXECUTE (0x20000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 11
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 204
    PointerToRawData: 0x150B
    PointerToRelocations: 0x15D7
    PointerToLineNumbers: 0x0
    RelocationCount: 5
    LineNumberCount: 0
    Characteristics [ (0x42101040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 12
    Name: .text$mn (2E 74 65 78 74 24 6D 6E)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 39
    PointerToRawData: 0x1609
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0x60501020)
      IMAGE_SCN_ALIGN_16BYTES (0x500000)
      IMAGE_SCN_CNT_CODE (0x20)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_EXECUTE (0x20000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 13
    Name: .debug$S (2E 64 65 62 75 67 24 53)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 224
    PointerToRawData: 0x1630
    PointerToRelocations: 0x1710
    PointerToLineNumbers: 0x0
    RelocationCount: 5
    LineNumberCount: 0
    Characteristics [ (0x42101040)
      IMAGE_SCN_ALIGN_1BYTES (0x100000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 14
    Name: .bss (2E 62 73 73 00 00 00 00)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 8
    PointerToRawData: 0x0
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0xC0300080)
      IMAGE_SCN_ALIGN_4BYTES (0x300000)
      IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80)
      IMAGE_SCN_MEM_READ (0x40000000)
      IMAGE_SCN_MEM_WRITE (0x80000000)
    ]
  }
  Section {
    Number: 15
    Name: .rtc$IMZ (2E 72 74 63 24 49 4D 5A)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 4
    PointerToRawData: 0x1742
    PointerToRelocations: 0x1746
    PointerToLineNumbers: 0x0
    RelocationCount: 1
    LineNumberCount: 0
    Characteristics [ (0x40301040)
      IMAGE_SCN_ALIGN_4BYTES (0x300000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 16
    Name: .rtc$TMZ (2E 72 74 63 24 54 4D 5A)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 4
    PointerToRawData: 0x1750
    PointerToRelocations: 0x1754
    PointerToLineNumbers: 0x0
    RelocationCount: 1
    LineNumberCount: 0
    Characteristics [ (0x40301040)
      IMAGE_SCN_ALIGN_4BYTES (0x300000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_LNK_COMDAT (0x1000)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
  Section {
    Number: 17
    Name: .CRT$XCU (2E 43 52 54 24 58 43 55)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 8
    PointerToRawData: 0x175E
    PointerToRelocations: 0x1766
    PointerToLineNumbers: 0x0
    RelocationCount: 2
    LineNumberCount: 0
    Characteristics [ (0x40300040)
      IMAGE_SCN_ALIGN_4BYTES (0x300000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_MEM_READ (0x40000000)
    ]
  }
]
Symbols [
  Symbol {
    Name: @comp.id
    Value: 14776701
    Section: IMAGE_SYM_ABSOLUTE (-1)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: @feat.00
    Value: 2147484049
    Section: IMAGE_SYM_ABSOLUTE (-1)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: .drectve
    Value: 0
    Section: .drectve (1)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 65
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
    AuxSectionDef {
      Length: 0
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (2)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 3380
      RelocationCount: 8
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
    AuxSectionDef {
      Length: 112874624
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$T
    Value: 0
    Section: .debug$T (3)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 136
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
    AuxSectionDef {
      Length: 0
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .text$di
    Value: 0
    Section: .text$di (4)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 60
      RelocationCount: 3
      LineNumberCount: 0
      Checksum: 0x46C8586B
      Number: 0
      Selection: Any (0x2)
    }
    AuxSectionDef {
      Length: 2651074843
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (5)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 216
      RelocationCount: 5
      LineNumberCount: 0
      Checksum: 0x0
      Number: 4
      Selection: Associative (0x5)
      AssocSection: .text$di (4)
    }
    AuxSectionDef {
      Length: 726561912
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .text$di
    Value: 0
    Section: .text$di (6)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 60
      RelocationCount: 3
      LineNumberCount: 0
      Checksum: 0x46C8586B
      Number: 0
      Selection: Any (0x2)
    }
    AuxSectionDef {
      Length: 1313174712
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (7)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 204
      RelocationCount: 5
      LineNumberCount: 0
      Checksum: 0x0
      Number: 6
      Selection: Associative (0x5)
      AssocSection: .text$di (6)
    }
    AuxSectionDef {
      Length: 3135640214
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .text$mn
    Value: 0
    Section: .text$mn (8)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 42
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0xB9575122
      Number: 0
      Selection: NoDuplicates (0x1)
    }
    AuxSectionDef {
      Length: 936864182
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (9)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 192
      RelocationCount: 5
      LineNumberCount: 0
      Checksum: 0x0
      Number: 8
      Selection: Associative (0x5)
      AssocSection: .text$mn (8)
    }
    AuxSectionDef {
      Length: 3843792410
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .text$mn
    Value: 0
    Section: .text$mn (10)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 42
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x2AAFA5E4
      Number: 0
      Selection: Any (0x2)
    }
    AuxSectionDef {
      Length: 919462443
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (11)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 204
      RelocationCount: 5
      LineNumberCount: 0
      Checksum: 0x0
      Number: 10
      Selection: Associative (0x5)
      AssocSection: .text$mn (10)
    }
    AuxSectionDef {
      Length: 1658743834
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .text$mn
    Value: 0
    Section: .text$mn (12)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 39
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x9F9044F9
      Number: 0
      Selection: NoDuplicates (0x1)
    }
    AuxSectionDef {
      Length: 607079010
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: .debug$S
    Value: 0
    Section: .debug$S (13)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 224
      RelocationCount: 5
      LineNumberCount: 0
      Checksum: 0x0
      Number: 12
      Selection: Associative (0x5)
      AssocSection: .text$mn (12)
    }
    AuxSectionDef {
      Length: 3159278302
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: ?testFunction@Test@@SAHXZ
    Value: 0
    Section: .text$mn (10)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: ??__E?memberVar@Test@@2HA@@YAXXZ
    Value: 0
    Section: .text$di (4)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: ?foo@@YAHXZ
    Value: 0
    Section: .text$mn (8)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: ??__Evar@@YAXXZ
    Value: 0
    Section: .text$di (6)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: _main
    Value: 0
    Section: .text$mn (12)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: __RTC_CheckEsp
    Value: 0
    Section: IMAGE_SYM_UNDEFINED (0)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: __RTC_InitBase
    Value: 0
    Section: IMAGE_SYM_UNDEFINED (0)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: __RTC_Shutdown
    Value: 0
    Section: IMAGE_SYM_UNDEFINED (0)
    BaseType: Null (0x0)
    ComplexType: Function (0x2)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: .bss
    Value: 0
    Section: .bss (14)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 8
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
    AuxSectionDef {
      Length: 0
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: ?memberVar@Test@@2HA
    Value: 4
    Section: .bss (14)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: ?var@@3HA
    Value: 0
    Section: .bss (14)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: .rtc$IMZ
    Value: 0
    Section: .rtc$IMZ (15)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 4
      RelocationCount: 1
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: Any (0x2)
    }
    AuxSectionDef {
      Length: 1569749662
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: __RTC_InitBase.rtc$IMZ
    Value: 0
    Section: .rtc$IMZ (15)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: .rtc$TMZ
    Value: 0
    Section: .rtc$TMZ (16)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 4
      RelocationCount: 1
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: Any (0x2)
    }
    AuxSectionDef {
      Length: 1278087628
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: __RTC_Shutdown.rtc$TMZ
    Value: 0
    Section: .rtc$TMZ (16)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: .CRT$XCU
    Value: 0
    Section: .CRT$XCU (17)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 2
    AuxSectionDef {
      Length: 8
      RelocationCount: 2
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
    AuxSectionDef {
      Length: 3724741121
      RelocationCount: 0
      LineNumberCount: 0
      Checksum: 0x0
      Number: 0
      Selection: 0x0
    }
  }
  Symbol {
    Name: ?memberVar$initializer$@Test@@2P6AXXZA
    Value: 0
    Section: .CRT$XCU (17)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: _var$initializer$
    Value: 4
    Section: .CRT$XCU (17)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Static (0x3)
    AuxSymbolCount: 0
  }
]

Thank you very much for considering my question; a thorough answer would be greatly appreciated.

like image 637
Sanee Berlow Avatar asked Jun 30 '15 11:06

Sanee Berlow


People also ask

What is dynamic initialization of variables in C?

Dynamic initialization of object refers to initializing the objects at run time i.e. the initial value of an object is to be provided during run time. Dynamic initialization can be achieved using constructors and passing parameters values to the constructors.

What is static and dynamic initialization in C?

Static Initialization: Here, the variable is assigned a value in advance. This variable then acts as a constant. Dynamic Initialization: Here, the variable is assigned a value at the run time. The value of this variable can be altered every time the program is being run.

What is static initialisation and dynamic initialisation?

The difference between static initialization and dynamic initialization: A static initialization in java is a particular block that is made to run before the main () method in java whereas dynamic initialization refers to the initiation of the project during the rum time.

What is static and global variable in C?

Static variables can be declared both inside and outside the main function while the global variables are always declared outside the main function.


1 Answers

This is less a linker problem than a compiler/run-time problem. The complete answer varies from system to system of course, but for gcc/clang on Linux goes something like this. Any specific symbols or sections that I'll mention are for the ARM, other processors may be different.

I copied you little example program into the ELLCC demo, which is a clang based distribution , and compiled it for ARM. I had to turn off optimization to see anything interesting, because your initialized variables aren't used.

What you'll see by looking at the assembly language is that the compiler will generate code to do any initialization that needs to be done in the source file. As you pointed out, things initialized to link-time constant values can be initialized by putting the appropriate symbol and it's initial value in a section (usually called .data for writable stuff and .const for read only stuff.) Values that can't be calculated at compile or link time are initialized by a a compiler generated function that is executed before main() is entered. If you compile your example and look at the assembly, near the end there are a few lines that look like this:

.section    .init_array,"aw",%init_array
.align  2
.long   _GLOBAL__sub_I__6873_0.cc(target1)

The magic here is that the section .init_array is a section with special meaning to the compiler and run-time system. the compiler has placed the address of an internally generated function in the .init_array section. The function does any initialization that this source files needs. If you had static C++ constructors in the source they'd also be called from here. There is a similar section for x86 processors called .ctors which has similar semantics.

Now comes the run-time part. When the program starts up, the run-time system gets control first. It does things like initialize the library, maybe load dynamic libraries, etc. and the takes each function pointer in the .init_array and executes it. This gets your variables initialized.

Notice that the linker didn't really have to do anything except gather all the function pointers in .init_array in one place so the run-time system could fund them.

As you might be guessing by now, there is also another section called .fini_array (or .dtors in the x86 world) that us used when the program tries to exit do handle global destructors.

like image 197
Richard Pennington Avatar answered Oct 17 '22 07:10

Richard Pennington