title: GCC Linker places variable in undesired section along with <object> causes a section type conflict with
body: <p>in my embedded program I have several "configuration objects" which alow user to configure its device. All of these objects are <code>const</code> (with pointer to memory which can be configured) and are put into specified section (to have objects from different compilation units in one place). The structure and example of such object is as follows:</p>
  
  <pre><code>class CObjectParams
  {
  public:
     OMB::ObjectId  ObjectID;
     TMODULE_ID     ModuleID;
     void*          pData;
     unsigned short u16Length;
  
     TAccessControl AccessControl;
  
     CConverter*    pConverter;
  
  
     int ReadObject(void* pDataDestination) const;
     int WriteObject(void* pDataSource) const;
  };
  </code></pre>
  
  <p>Example:</p>
  
  <pre><code>const volatile TSoftwareDescriptor* const BootloaderSoftwareDescriptor = (const volatile TSoftwareDescriptor* const) (FLASH_BASE + DESCRIPTOR_OFFSET);
  
  const CObjectParams __attribute__((used, section("_objects_section"))) BootloaderSoftwareVersionObjectParams =
  {
     OMB::ObjectId::BOOTLOADER_SOFTWARE_VERSION,
     TMODULE_ID::MODULE_ID_FIRMWARE,
     (void*) &amp;BootloaderSoftwareDescriptor-&gt;u32FirmwareVersion,
     sizeof(BootloaderSoftwareDescriptor-&gt;u32FirmwareVersion),
     {
        (ACCESS_READ),
        LOCATION_DIRECT,
        FIXED_LENGTH,
     },
     nullptr,
  };
  </code></pre>
  
  <p>The problem, I think, is that linker cannot resolve <code>&amp;BootloaderSoftwareDescriptor-&gt;u32FirmwareVersion</code> address at link time and therefore tries to put it into <code>.data</code> section to initialize during startup. After lifting <code>section("_objects_section")</code> restriction and analyzing <code>.map</code> file my concerns are confirmed.
  So why linker cannot resolve mentioned address at link time since <code>BootloaderSoftwareDescriptor</code> is constant pointer and known at compile time?</p>
  
  <p>Here is example code which shows this error:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  #define FIXED_LENGTH     0
  #define LOCATION_DIRECT  0
  #define ACCESS_READ      0b000010
  
  
  enum ObjectId : unsigned short
  {
      NO_OBJECT = 0x000,
  
      A,
      B,
      C,
      D
  };
  
  enum TMODULE_ID : unsigned short
  {
     MODULE_ID_CONFIG                       = 0x00, 
     MODULE_ID_DIAGNOSTICS                  = 0x01,
     MODULE_ID_FIRMWARE                     = 0x04,
  };
  
  struct TAccessControl
  {
     unsigned char b6Access     : 6;
     unsigned char b4Location   : 2;
     unsigned char b1LengthType : 1;
  
     unsigned char b7Unused     : 7;
  };
  
  class CConverter
  {
  public:
     virtual void ConvertTo(void* pDestination, void* pSource, int size) {};
     virtual void ConvertFrom(void* pDestination, void* pSource, int size) {};
  };
  
  class CObjectParams
  {
  public:
     ObjectId  ObjectID;
     TMODULE_ID     ModuleID;
     void*          pData;
     unsigned short u16Length;
  
     TAccessControl AccessControl;
  
     CConverter*    pConverter;
  
  
     int ReadObject(void* pDataDestination) const;
     int WriteObject(void* pDataSource) const;
  };
  
  struct TSoftwareDescriptor
  {
     unsigned int u32FirmwareCrc;
     unsigned int u32FirmwareSize;
     unsigned int u32HardwareVersion;
     unsigned int u32FirmwareVersion;
     const char S8BuildDate[12];  // Mmm-dd-yyyy\0
     const char S8BuildTime[9];   // HH:mm:ss\0
     unsigned int U32RFU[10] =
     {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     };
  };
  
  #define FLASH_BASE            (0x08000000UL)
  #define DESCRIPTOR_OFFSET     50
  
  const volatile TSoftwareDescriptor* const BootloaderSoftwareDescriptor = (const volatile TSoftwareDescriptor* const) (FLASH_BASE + DESCRIPTOR_OFFSET);
  
  
  const CObjectParams __attribute__((used, section("_objects_section"))) NullObjectParams =
  {
     ObjectId::A,
     TMODULE_ID::MODULE_ID_FIRMWARE,
     nullptr,
     sizeof(int),
     {
        (ACCESS_READ),
        LOCATION_DIRECT,
        FIXED_LENGTH,
     },
     nullptr,
  };
  
  const CObjectParams __attribute__((used, section("_objects_section"))) BootloaderSoftwareVersionObjectParams =
  {
     ObjectId::B,
     TMODULE_ID::MODULE_ID_FIRMWARE,
     (void*) &amp;BootloaderSoftwareDescriptor-&gt;u32FirmwareVersion,
     sizeof(BootloaderSoftwareDescriptor),
     {
        (ACCESS_READ),
        LOCATION_DIRECT,
        FIXED_LENGTH,
     },
     nullptr,
  };
  
  
  
  
  int main()
  {
      printf("%d\n%d\n", NullObjectParams.pData, BootloaderSoftwareVersionObjectParams.pData);
      return 0;
  }
  </code></pre>