代码之家  ›  专栏  ›  技术社区  ›  FeelTheBurns

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

  •  0
  • FeelTheBurns  · 技术社区  · 7 年前

    我遇到了与此帖子类似的问题: 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\u array-x objs/main。o

    objs/主。o: 文件格式elf32 littleriscv objs/main。o 架构:riscv:rv32,标志0x00000011:HAS\u RELOC,HAS\u SYMS start 地址0x00000000

    节:Idx名称大小VMA LMA文件关闭 Algn 8。初始化数组0000000 4 00000000 00000000 00000 154 2**2 目录、分配、加载、重新加载、数据符号表:00000000 l d。init\u数组00000000。init\u数组

    [.init\u数组]的重定位记录:偏移类型值 00000000 R\u RISCV\u 32 \u GLOBAL\u sub\u I\u foo

    这让我相信它应该被称为?我还测试了全局声明的标准C变量,这些变量会被赋值,也会显示在上。init\u数组。

    我的\u 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初始化原语(如\uu libc\u init\u array()),这是一个额外的问题,我想知道为什么会这样?

    1 回复  |  直到 7 年前
        1
  •  1
  •   FeelTheBurns    6 年前

    我终于为几个月前我所面临的这个问题找到了一个合适的解决方案。下面是我最后在初始化过程中所做的。这在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);
    }