'Section type conflict' using clang++ for Win32

Viewed 50

I need help to port my embedded C++ code (running on an ARM processor) into a local machine (x86).

Some parts of the code run on a dedicated memory section (ROM), to spare some embedded RAM. This was achieved with the compiler feature attribute((section)).

The same code doesn't build on my local PC (Win32) using clang/clang++ v.12. I run into several 'section type conflict' compilation errors.

I have a short sample code that reproduces the issue:

Constant.hpp

#pragma once

class Constant {
public:
    Constant(int val) { value = val; }
    int get() { return value; }
private:
    int value = 0;
};

Global.hpp

#pragma once
#include "Constant.hpp"

static Constant myConstant = Constant{3};
extern Constant * const pConstant __attribute__((__section__(".mySection1"))) = &myConstant;

Sum.hpp

#pragma once

struct Sum {
  Sum() = default;
  int calculate(int a, int b) __attribute__((__section__(".mySection1")));
};

main.cpp

#include <iostream>
#include "Global.hpp"
#include "Sum.hpp"

extern Constant * const pConstant;

int main(int argc, char **argv) {
    Sum * sum = new Sum();
    int result = sum->calculate(1, pConstant->get());
    std::cout << result << std::endl;
    return 0;
}

The compiler output is:

error: 'calculate' causes a section type conflict with 'pConstant'
  int calculate(int a, int b) __attribute__((__section__(".mySection1")));
      ^
.../Global.hpp:6:25: note: declared here
extern Constant * const pConstant __attribute__((__section__(".mySection1"))) = &myConstant;

If I use 2 different sections (.mySection1 for the variable and mySection2 for the method), the code builds and runs successfully. Disassembled code is below:

.../Sum.cpp.obj:     file format pe-i386

SYMBOL TABLE:
[  0](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x2a nreloc 3 nlnno 0 checksum 0x7187c290 assoc 1 comdat 0
[  2](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 2 comdat 0
[  4](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x4 nreloc 0 nlnno 0 checksum 0x0 assoc 3 comdat 0
[  6](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x1f nreloc 0 nlnno 0 checksum 0x6ff4fbec assoc 4 comdat 2
[  8](sec  4)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 ??0Constant@@QAE@H@Z
[  9](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .mySection2
AUX scnlen 0x2b nreloc 2 nlnno 0 checksum 0x56c90986 assoc 5 comdat 0
[ 11](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x11 nreloc 0 nlnno 0 checksum 0x80cdff44 assoc 6 comdat 2
[ 13](sec  6)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 ?get@Constant@@QAEHXZ
[ 14](sec  7)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .mySection1
AUX scnlen 0x4 nreloc 1 nlnno 0 checksum 0x0 assoc 7 comdat 0
[ 16](sec  8)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .CRT$XCU
AUX scnlen 0x4 nreloc 1 nlnno 0 checksum 0x0 assoc 8 comdat 0
[ 18](sec  9)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .drectve
AUX scnlen 0x18 nreloc 0 nlnno 0 checksum 0x63557b96 assoc 9 comdat 0
[ 20](sec 10)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug$S
AUX scnlen 0x56c nreloc 23 nlnno 0 checksum 0xa675e8b1 assoc 10 comdat 0
[ 22](sec 13)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug$S
AUX scnlen 0x150 nreloc 9 nlnno 0 checksum 0xecc1ccc6 assoc 4 comdat 5
[ 24](sec 14)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug$S
AUX scnlen 0x11c nreloc 7 nlnno 0 checksum 0xefad5adf assoc 6 comdat 5
[ 26](sec 11)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug$T
AUX scnlen 0x3b0 nreloc 0 nlnno 0 checksum 0x954cd43c assoc 11 comdat 0
[ 28](sec 12)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .llvm_addrsig
AUX scnlen 0x4 nreloc 0 nlnno 0 checksum 0x9c7eb272 assoc 12 comdat 0
[ 30](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000001 @feat.00
[ 31](sec  1)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000000 ??__EmyConstant@@YAXXZ
[ 32](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 _myConstant
[ 33](sec  5)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 ?calculate@Sum@@QAEHH@Z
[ 34](sec  1)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000020 __GLOBAL__sub_I_Sum.cpp
[ 35](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ?pConstant@@3QAVConstant@@A
[ 36](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 Sum.cpp
File

I have the impression that clang for x86 doesn't allow to place constant variables and functions in the same section, but I couldn't find any x86/Win32 restriction on the clang compiler reference...

Any ideas?

1 Answers

The issue came from using a newer version of the arm compiler... Since arm compiler version 6.15, it is forbidden to mix code and data in the same memory section. See arm compiler changelog

Related