RISCV全局对象构造函数未被调用

时间:2018-03-02 21:03:48

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

我在这篇文章中遇到了类似的问题: 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文件关闭   Algn 8 .init_array 00000004 00000000 00000000 00000154 2 ** 2                     内容,ALLOC,LOAD,RELOC,DATA SYMBOL表:00000000 l d .init_array 00000000 .init_array

     

[.init_array]的重新定位记录:OFFSET类型值   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()),作为一个额外的问题,我想知道为什么会这样?

1 个答案:

答案 0 :(得分:0)

我终于为几个月前面对的这个问题提出了适当的解决方案。这就是我最终投入初始化过程的内容。这在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);
}