My goal is to run a compiled C
code in my RISCV
simlator. I have compiled a C code with RISCV32I (32bit) compiler and it output my code in ELF format (then i have selected .text
section and used it in my RISC-V
simulator). Perfect. Then, i tried to run that compiled code in my simulator, but i found that in in <__libc_init_array>
function there is "some" code that will always jump to the adress 0 of my program, which i dont want, obviously.
Disassembly of my output file:
000102ec <__libc_init_array>:
102ec: ff010113 addi sp,sp,-16
102f0: 00812423 sw s0,8(sp)
102f4: 01212023 sw s2,0(sp)
102f8: 00001417 auipc s0,0x1
102fc: 3c840413 addi s0,s0,968 # 116c0 <__init_array_start>
10300: 00001917 auipc s2,0x1
10304: 3c090913 addi s2,s2,960 # 116c0 <__init_array_start>
10308: 40890933 sub s2,s2,s0
1030c: 00112623 sw ra,12(sp)
10310: 00912223 sw s1,4(sp)
10314: 40295913 srai s2,s2,0x2
10318: 00090e63 beqz s2,10334 <__libc_init_array+0x48>
1031c: 00000493 li s1,0
10320: 00042783 lw a5,0(s0)
10324: 00148493 addi s1,s1,1
10328: 00440413 addi s0,s0,4
1032c: 000780e7 jalr a5
10330: fe9918e3 bne s2,s1,10320 <__libc_init_array+0x34>
10334: 00001417 auipc s0,0x1
10338: 38c40413 addi s0,s0,908 # 116c0 <__init_array_start>
1033c: 00001917 auipc s2,0x1
10340: 38c90913 addi s2,s2,908 # 116c8 <__init_array_end>
10344: 40890933 sub s2,s2,s0
10348: 40295913 srai s2,s2,0x2
1034c: dbdff0ef jal ra,10108 <_fini>
10350: 00090e63 beqz s2,1036c <__libc_init_array+0x80>
10354: 00000493 li s1,0
10358: 00042783 lw a5,0(s0)
1035c: 00148493 addi s1,s1,1
10360: 00440413 addi s0,s0,4
10364: 000780e7 jalr a5
10368: fe9918e3 bne s2,s1,10358 <__libc_init_array+0x6c>
1036c: 00c12083 lw ra,12(sp)
10370: 00812403 lw s0,8(sp)
10374: 00412483 lw s1,4(sp)
10378: 00012903 lw s2,0(sp)
1037c: 01010113 addi sp,sp,16
10380: 00008067 ret
On the line 10350
we can find an comparison that if true, will jump over a few lines. But for some reason it is not true, so we must continue. And here it becomes interesting. The next instruction loads a 0
into register s1
, fine, but the next one tries to load some value into reg a5
from address 0(s0)
. But the output of the read will be 0
, because in the memory there is nothing. I could not find any reference to this specific address form start of this code (from _start
). In fact, there is no attempt to write or read to that address at all apart from this function.
10350: 00090e63 beqz s2,1036c <__libc_init_array+0x80>
10354: 00000493 li s1,0
10358: 00042783 lw a5,0(s0)
1035c: 00148493 addi s1,s1,1
10360: 00440413 addi s0,s0,4
10364: 000780e7 jalr a5
Am i missing something? This is the last step before the program jumps to the main section so i do not want to go back to address 0
.
Thanks for any help
EDIT
There is a dump of .init_array
and .data
, but I don't see how they can effect the value on the problematic address (there is even compressed instruction and some unknown FLD, both of these are unsupported by my simulator).
Disassembly of section .init_array:
000116c0 <__init_array_start>:
116c0: 00ac addi a1,sp,72
116c2: 0001 nop
000116c4 <__frame_dummy_init_array_entry>:
116c4: 01a8 addi a0,sp,200
116c6: 0001 nop
Disassembly of section .fini_array:
000116c8 <__do_global_dtors_aux_fini_array_entry>:
116c8: 0160 addi s0,sp,140
116ca: 0001 nop
Disassembly of section .data:
000116d0 <__DATA_BEGIN__>:
116d0: 0000 unimp
116d2: 0000 unimp
116d4: 19bc addi a5,sp,248
116d6: 0001 nop
116d8: 1a24 addi s1,sp,312
116da: 0001 nop
116dc: 1a8c addi a1,sp,368
116de: 0001 nop
...
11778: 0001 nop
1177a: 0000 unimp
1177c: 0000 unimp
1177e: 0000 unimp
11780: 330e fld ft6,224(sp)
11782: abcd j 11d74 <__BSS_END__+0x230>
11784: 1234 addi a3,sp,296
11786: e66d bnez a2,11870 <__DATA_BEGIN__+0x1a0>
11788: deec sw a1,124(a3)
1178a: 0005 c.nop 1
1178c: 0000000b 0xb
...
10338
sets ups0
to point to__init_array_start
.s2
is set up to be the size of that array. If the size is not zero, there should most certainly be something in the array which is notNULL
or else you have some problem. Note it's data so you won't see any code writing to it. – Jester__init_array_start
array holds addresses of global constructors. For some reason linker resolves one of these addresses toNULL
but it's not possible to say why without full reprocase. – yugr.data
segment from ELF file. – yugr