Здравствуйте, я пишу небольшую программу для работы на процессоре ARMv8. Все работало хорошо, пока я не добавил больше функций. Теперь при вызове новой функции процессор переходит в синхронное исключение, но я не могу сказать, почему и что пошло не так. ESR_EL3
выглядит следующим образом: EC=0, IL=1, ISS=0
. ELR_EL3
указывает на функцию, для которой процессор генерирует исключение. Где мне искать, что пошло не так? Программа написана в C. С уважением
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: AArch64
Version: 0x1
Entry point address: 0x80800
Start of program headers: 64 (bytes into file)
Start of section headers: 24536 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 4
Size of section headers: 64 (bytes)
Number of section headers: 8
Section header string table index: 7
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000080120 00000120
000000000000398c 0000000000000000 AX 0 0 1024
[ 2] .rodata PROGBITS 0000000000084000 00004000
0000000000000753 0000000000000000 A 0 0 8
[ 3] .data PROGBITS 0000000000085000 00005000
0000000000000001 0000000000000000 WA 0 0 1
[ 4] .bss NOBITS 0000000000086000 00006000
0000000000000040 0000000000000000 WA 0 0 8
[ 5] .symtab SYMTAB 0000000000000000 00005008
0000000000000ac8 0000000000000018 6 48 8
[ 6] .strtab STRTAB 0000000000000000 00005ad0
00000000000004ce 0000000000000000 0 0 1
[ 7] .shstrtab STRTAB 0000000000000000 00005f9e
0000000000000034 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000080000 0x0000000000080000
0x0000000000003aac 0x0000000000003aac R E 0x10000
LOAD 0x0000000000004000 0x0000000000084000 0x0000000000084000
0x0000000000000753 0x0000000000000753 R 0x10000
LOAD 0x0000000000005000 0x0000000000085000 0x0000000000085000
0x0000000000000001 0x0000000000000001 RW 0x10000
LOAD 0x0000000000006000 0x0000000000086000 0x0000000000086000
0x0000000000000000 0x0000000000000040 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .text
01 .rodata
02 .data
03 .bss
There is no dynamic section in this file.
There are no relocations in this file.
The decoding of unwind sections for machine type AArch64 is not currently supported.
Symbol table '.symtab' contains 115 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000080120 0 SECTION LOCAL DEFAULT 1
2: 0000000000084000 0 SECTION LOCAL DEFAULT 2
3: 0000000000085000 0 SECTION LOCAL DEFAULT 3
4: 0000000000086000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 FILE LOCAL DEFAULT ABS bcm2835.c
6: 0000000000080120 0 NOTYPE LOCAL DEFAULT 1 $x
7: 0000000000000000 0 FILE LOCAL DEFAULT ABS dtb.c
8: 0000000000080128 0 NOTYPE LOCAL DEFAULT 1 $x
9: 0000000000080128 68 FUNC LOCAL DEFAULT 1 endian_conv_u32
10: 0000000000084000 0 NOTYPE LOCAL DEFAULT 2 $d
11: 0000000000000000 0 FILE LOCAL DEFAULT ABS elf.c
12: 00000000000841c8 0 NOTYPE LOCAL DEFAULT 2 $d
13: 0000000000080500 0 NOTYPE LOCAL DEFAULT 1 $x
14: 0000000000000000 0 FILE LOCAL DEFAULT ABS entry.s
15: 0000000000080800 0 NOTYPE LOCAL DEFAULT 1 $x
16: 0000000000081388 0 NOTYPE LOCAL DEFAULT 1 $d
17: 0000000000000000 0 FILE LOCAL DEFAULT ABS heap.c
18: 0000000000086000 0 NOTYPE LOCAL DEFAULT 4 $d
19: 00000000000813a0 0 NOTYPE LOCAL DEFAULT 1 $x
20: 00000000000841e8 0 NOTYPE LOCAL DEFAULT 2 $d
21: 0000000000000000 0 FILE LOCAL DEFAULT ABS log.c
22: 0000000000086010 0 NOTYPE LOCAL DEFAULT 4 $d
23: 0000000000081818 0 NOTYPE LOCAL DEFAULT 1 $x
24: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
25: 0000000000084210 0 NOTYPE LOCAL DEFAULT 2 $d
26: 0000000000081934 0 NOTYPE LOCAL DEFAULT 1 $x
27: 0000000000000000 0 FILE LOCAL DEFAULT ABS pmm.c
28: 0000000000081b98 0 NOTYPE LOCAL DEFAULT 1 $x
29: 0000000000081c48 88 FUNC LOCAL DEFAULT 1 pmm_check
30: 0000000000081ca0 500 FUNC LOCAL DEFAULT 1 pmm_merge
31: 0000000000081e94 512 FUNC LOCAL DEFAULT 1 pmm_split_by_addr
32: 0000000000082094 436 FUNC LOCAL DEFAULT 1 pmm_split_by_size
33: 0000000000084450 0 NOTYPE LOCAL DEFAULT 2 $d
34: 0000000000000000 0 FILE LOCAL DEFAULT ABS spinlock.s
35: 00000000000829bc 0 NOTYPE LOCAL DEFAULT 1 $x
36: 0000000000000000 0 FILE LOCAL DEFAULT ABS stack.c
37: 0000000000086018 0 NOTYPE LOCAL DEFAULT 4 $d
38: 00000000000829e0 0 NOTYPE LOCAL DEFAULT 1 $x
39: 0000000000000000 0 FILE LOCAL DEFAULT ABS string.c
40: 0000000000082a40 0 NOTYPE LOCAL DEFAULT 1 $x
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS tree.c
42: 00000000000832a8 0 NOTYPE LOCAL DEFAULT 1 $x
43: 00000000000832a8 40 FUNC LOCAL DEFAULT 1 tree_height_max
44: 00000000000832d0 44 FUNC LOCAL DEFAULT 1 tree_height
45: 00000000000832fc 84 FUNC LOCAL DEFAULT 1 tree_rotate_left
46: 0000000000083350 84 FUNC LOCAL DEFAULT 1 tree_rotate_right
47: 0000000000083550 116 FUNC LOCAL DEFAULT 1 tree_remove_left
48: 0000000000080800 0 FUNC GLOBAL DEFAULT 1 entry
49: 0000000000081818 284 FUNC GLOBAL DEFAULT 1 log
50: 000000000008298c 48 FUNC GLOBAL DEFAULT 1 pmm_debug
51: 0000000000082b84 296 FUNC GLOBAL DEFAULT 1 string_format2x
52: 0000000000081ac0 24 FUNC GLOBAL DEFAULT 1 main_curr_el_spx_serror
53: 0000000000080120 8 FUNC GLOBAL DEFAULT 1 bcm2835_init
54: 0000000000086010 1 OBJECT GLOBAL DEFAULT 4 log_spinlock
55: 000000000008038c 372 FUNC GLOBAL DEFAULT 1 dtb_parse
56: 00000000000827c0 24 FUNC GLOBAL DEFAULT 1 pmm_del
57: 00000000000833a4 428 FUNC GLOBAL DEFAULT 1 tree_insert
58: 0000000000081b50 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch32_irq
59: 0000000000081a00 24 FUNC GLOBAL DEFAULT 1 main_curr_el_sp0_serror
60: 0000000000081ad8 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch64_syn
61: 00000000000801dc 432 FUNC GLOBAL DEFAULT 1 dtb_struct
62: 0000000000082248 664 FUNC GLOBAL DEFAULT 1 pmm_alloc
63: 0000000000086028 1 OBJECT GLOBAL DEFAULT 4 main_ok
64: 0000000000086008 8 OBJECT GLOBAL DEFAULT 4 heap_head
65: 00000000000813b4 24 FUNC GLOBAL DEFAULT 1 heap_extend
66: 0000000000082ad4 64 FUNC GLOBAL DEFAULT 1 string_length
67: 0000000000086030 1 OBJECT GLOBAL DEFAULT 4 pmm_spinlock
68: 0000000000082cac 388 FUNC GLOBAL DEFAULT 1 string_format2d
69: 00000000000829bc 0 FUNC GLOBAL DEFAULT 1 spinlock_acquire
70: 0000000000081790 136 FUNC GLOBAL DEFAULT 1 heap_debug
71: 00000000000813cc 688 FUNC GLOBAL DEFAULT 1 heap_alloc
72: 0000000000085000 1 OBJECT GLOBAL DEFAULT 3 entry_data
73: 00000000000837d4 88 FUNC GLOBAL DEFAULT 1 tree_max
74: 0000000000082e30 968 FUNC GLOBAL DEFAULT 1 string_format2
75: 00000000000831f8 176 FUNC GLOBAL DEFAULT 1 string_format
76: 00000000000824e0 336 FUNC GLOBAL DEFAULT 1 pmm_free
77: 00000000000819e8 24 FUNC GLOBAL DEFAULT 1 main_curr_el_sp0_fiq
78: 0000000000086000 1 OBJECT GLOBAL DEFAULT 4 heap_spinlock
79: 00000000000829e0 48 FUNC GLOBAL DEFAULT 1 stack_alloc
80: 0000000000086038 8 OBJECT GLOBAL DEFAULT 4 pmm_tree
81: 0000000000081b08 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch64_fiq
82: 0000000000082630 400 FUNC GLOBAL DEFAULT 1 pmm_add
83: 0000000000082b14 112 FUNC GLOBAL DEFAULT 1 string_format2s
84: 0000000000082a40 148 FUNC GLOBAL DEFAULT 1 compare_string
85: 00000000000827d8 436 FUNC GLOBAL DEFAULT 1 pmm_debug_walk
86: 0000000000081af0 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch64_irq
87: 00000000000819d0 24 FUNC GLOBAL DEFAULT 1 main_curr_el_sp0_irq
88: 0000000000081934 132 FUNC GLOBAL DEFAULT 1 main
89: 00000000000838d8 172 FUNC GLOBAL DEFAULT 1 tree_next
90: 00000000000819b8 24 FUNC GLOBAL DEFAULT 1 main_curr_el_sp0_sync
91: 00000000000813a0 20 FUNC GLOBAL DEFAULT 1 heap_add
92: 0000000000081b80 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch32_ser
93: 000000000008167c 276 FUNC GLOBAL DEFAULT 1 heap_free
94: 0000000000081a18 120 FUNC GLOBAL DEFAULT 1 main_curr_el_spx_sync
95: 0000000000081b38 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch32_syn
96: 000000000008382c 172 FUNC GLOBAL DEFAULT 1 tree_prev
97: 0000000000081b98 176 FUNC GLOBAL DEFAULT 1 pmm_compare
98: 0000000000080c00 4 OBJECT GLOBAL DEFAULT 1 entry_vbar_el3
99: 00000000000829d4 0 FUNC GLOBAL DEFAULT 1 spinlock_release
100: 0000000000083a20 140 FUNC GLOBAL DEFAULT 1 tree_walk
101: 000000000008016c 112 FUNC GLOBAL DEFAULT 1 dtb_string
102: 0000000000080500 356 FUNC GLOBAL DEFAULT 1 elf_kernel_init
103: 00000000000841e4 1 OBJECT GLOBAL DEFAULT 2 entry_rodata
104: 0000000000086020 8 OBJECT GLOBAL DEFAULT 4 stack_tree
105: 0000000000086018 1 OBJECT GLOBAL DEFAULT 4 stack_spinlock
106: 0000000000086000 1 OBJECT GLOBAL DEFAULT 4 entry_bss
107: 000000000008377c 88 FUNC GLOBAL DEFAULT 1 tree_min
108: 0000000000081aa8 24 FUNC GLOBAL DEFAULT 1 main_curr_el_spx_fiq
109: 0000000000081a90 24 FUNC GLOBAL DEFAULT 1 main_curr_el_spx_irq
110: 0000000000081b20 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch64_ser
111: 0000000000082a10 48 FUNC GLOBAL DEFAULT 1 stack_free
112: 0000000000083984 156 FUNC GLOBAL DEFAULT 1 tree_find
113: 0000000000081b68 24 FUNC GLOBAL DEFAULT 1 main_lower_el_aarch32_fiq
114: 00000000000835c4 440 FUNC GLOBAL DEFAULT 1 tree_remove
No version information found in this file.
Вот функция, создающая проблему:
int32_t elf_kernel_init(uint64_t addr){
int32_t rc = 0, i;
struct elf_hdr* hdr = (struct elf_hdr*) addr;
struct elf_phdr* phdr;
struct elf_shdr* shdr;
if(hdr->mag0 != ELF_HDR_MAG0) rc = -EINVALID;
if(hdr->mag1 != ELF_HDR_MAG1) rc = -EINVALID;
if(hdr->mag2 != ELF_HDR_MAG2) rc = -EINVALID;
if(hdr->mag3 != ELF_HDR_MAG3) rc = -EINVALID;
if(hdr->bits != ELF_HDR_BITS_64) rc = -EINVALID;
if(hdr->data != ELF_HDR_DATA_2LSB) rc = -EINVALID;
if(hdr->fversion != ELF_HDR_FVERSION_CURRENT) rc = -EINVALID;
if(hdr->osabi != ELF_HDR_OSABI_SYSV) rc = -EINVALID;
if(hdr->aversion != 0) rc = -EINVALID;
if(hdr->type != ELF_HDR_TYPE_EXEC) rc = -EINVALID;
if(hdr->machine != ELF_HDR_MACHINE_RISCV) rc = -EINVALID;
if(hdr->eversion != ELF_HDR_EVERSION_CURRENT) rc = -EINVALID;
if(rc < 0){
log("elf: header check failed!\r\n");
return rc;
}
return 0;
}
А вот мой скрипт компоновщика:
ENTRY(entry)
PHDRS{
text PT_LOAD FILEHDR PHDRS;
rodata PT_LOAD;
data PT_LOAD;
bss PT_LOAD;
}
SECTIONS{
. = 0x80000;
.text ALIGN(4K) + SIZEOF_HEADERS : { *(.text) } :text
.rodata ALIGN(4K) : { *(.rodata) } :rodata
.data ALIGN(4K) : { *(.data) } :data
.bss ALIGN(4K) : { *(.bss) } :bss
/DISCARD/ : { *(.comment) *(.note.GNU-stack) *(.note.gnu.property) *(.eh_frame) }
}