【问题标题】:RISCV Global object constructors are not being called未调用 RISCV 全局对象构造函数
【发布时间】:2018-08-11 03:44:06
【问题描述】:

我遇到了与这篇文章类似的问题: Global constructor call not in .init_array section

我将重复使用他的示例,但我认为这是 RISCV 环境特有的问题,这就是我创建新帖子的原因。

class foobar
{
    int i;

public:
    foobar()
    {
        i = 100;
    }

    void inc()
    {
        i++;
    }
};

foobar foo;

int main()
{
    foo.inc();
    for (;;);
}

问题是 foo 的构造函数永远不会被调用。我在第一个增量上放了一个断点,i 的值为 0,而不是预期的 100。

这里是输出:riscv64-unknown-elf-objdump.exe -j .init_array -x objs/main.o

objs/main.o:文件格式elf32-littleriscv objs/main.o 架构:riscv:rv32,标志 0x00000011:HAS_RELOC,HAS_SYMS 启动 地址0x00000000

节:Idx 名称大小 VMA LMA 文件关闭 算法 8 .init_array 00000004 00000000 00000000 00000154 2**2 CONTENTS、ALLOC、LOAD、RELOC、数据符号表:00000000 l d .init_array 00000000 .init_array

[.init_array] 的搬迁记录:偏移类型值 00000000 R_RISCV_32 _GLOBAL__sub_I_foo

这让我相信它应该被调用?我还测试了全局声明的标准 C 变量,它们确实被分配并显示在 .init_array 上。

我的 _init() 看起来像这样:

void _init(void)
{
    copy_section(&__sdata_load, &__sdata_start, &__sdata_end);
    copy_section(&__data_load, &__data_start, &__data_end);
    zero_section(&__sbss_start, &__sbss_end);
    zero_section(&__bss_start, &__bss_end);

    exit(main());
}

看起来其他基于 RISCV 的项目也没有利用 libc 初始化原语(如 __libc_init_array()),作为一个额外的问题,我想知道为什么会这样?

【问题讨论】:

    标签: c++ constructor linker global-variables riscv


    【解决方案1】:

    我终于为我在几个月前遇到的这个问题找到了一个合适的解决方案。这是我最终放入初始化过程的内容。这在 main() 之前调用。这在很大程度上受到我在原始问题中链接的帖子中提出的解决方案的影响。

    extern void (**__preinit_array_start)();
    extern void (**__preinit_array_end)();
    extern void (**__init_array_start)();
    extern void (**__init_array_end)();
    extern void (**__fini_array_start)();
    extern void (**__fini_array_end)();
    
    static void execute_array(void (** _start)(), void (** _end)())
    {
        size_t count;
        size_t i;
    
        count = _end - _start;
        for (i = 0; i < count; i++)
        {
            (*_start[i])();
        }
    }
    
    void _init(void)
    {
        execute_array(__preinit_array_start, __preinit_array_end);
        execute_array(__init_array_start, __init_array_end);
    
        main();
    }
    
    void _fini()
    {
        execute_array(__fini_array_start, __fini_array_end);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2018-10-26
      • 2021-06-17
      相关资源
      最近更新 更多