【问题标题】:'Section type conflict' using clang++ for Win32使用 clang++ for Win32 的“部分类型冲突”
【发布时间】:2022-01-07 00:09:31
【问题描述】:

我需要帮助将我的嵌入式 C++ 代码(在 ARM 处理器上运行)移植到本地机器 (x86)。

代码的某些部分在专用内存部分 (ROM) 上运行,以节省一些嵌入式 RAM。这是通过编译器特性attribute((section))实现的。

使用 clang/clang++ v.12 无法在我的本地 PC (Win32) 上构建相同的代码。我遇到了几个“节类型冲突”编译错误。

我有一个简短的示例代码可以重现该问题:

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")));
};

ma​​in.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;
}

编译器输出为:

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;

如果我使用 2 个不同的部分(.mySection1 用于变量,mySection2 用于方法),代码将成功构建并运行。反汇编代码如下:

.../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

我的印象是 x86 的 clang 不允许将常量变量和函数放在同一节中,但我在 clang 编译器参考中找不到任何 x86/Win32 限制...

有什么想法吗?

【问题讨论】:

  • 也许这和内存保护有关? (例如,该部分是否设置了IMAGE_SCN_MEM_EXECUTE 位)。您是否尝试过仔细查看可执行文件的 PE 标头?

标签: c++ assembly memory clang


【解决方案1】:

问题来自于使用较新版本的 arm 编译器... 从 arm 编译器 6.15 版本开始,禁止在同一内存段中混用代码和数据。 见arm compiler changelog

【讨论】:

    猜你喜欢
    • 2013-06-30
    • 1970-01-01
    • 2013-08-04
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2020-07-08
    • 2020-06-10
    相关资源
    最近更新 更多