# qemu mips-softmmu built with clang seems to end up overwriting the # cc->do_interrupt(cpu) fn pointer. (see do_interrupt = 0xa5a5a5a5a5a5a5a5 # below when built without MALLOC_PRODUCTION which seems to indicate # uninitialized memory, do_interrupt is NULL with MALLOC_PRODUCTION) # adding a printf in mips_cpu_class_init() in work/qemu-1.6.0/target-mips/cpu.c # shows at least one do_interrupt fn pointer being initialized so probably # it is overwritten later or the CPUClass struct isn't copied completely # when built with clang: $ qemu-system-mips -M malta -kernel /path/to/mips.mips/MALTA/.../kernel -hda /src/FreeBSD/disk.img -nographic [...crash... see http://kernelnomicon.org/?p=401 - I've put an xz.ed kernel here: http://people.freebsd.org/~nox/tmp/kernel.MALTA.xz - the crash also happens w/o -hda] $ gdb work/qemu-1.6.0/mips-softmmu/qemu-system-mips qemu-system-mips.core [..] (gdb) bt #0 0x00000000005685ab in cpu_mips_exec (env=) at /d3t/d3t2/home/nox/ports/emulators/qemu-devel/work/qemu-1.6.0/cpu-exec.c:290 #1 0x000000000056a321 in tcg_cpu_exec (env=) at /d3t/d3t2/home/nox/ports/emulators/qemu-devel/work/qemu-1.6.0/cpus.c:1159 #2 tcg_exec_all () at /d3t/d3t2/home/nox/ports/emulators/qemu-devel/work/qemu-1.6.0/cpus.c:1192 #3 qemu_tcg_cpu_thread_fn (arg=) at /d3t/d3t2/home/nox/ports/emulators/qemu-devel/work/qemu-1.6.0/cpus.c:868 #4 0x0000000807be558d in ?? () from /lib/libthr.so.3 #5 0x0000000000000000 in ?? () (gdb) disas $rip [..] 0x00000000005685a4 <+548>: mov %r13,%rdi 0x00000000005685a7 <+551>: mov -0x40(%rbp),%rbx => 0x00000000005685ab <+555>: callq *0xb8(%rbx) 0x00000000005685b1 <+561>: movl $0xffffffff,0x10a60(%r12) 0x00000000005685bd <+573>: add $0xb8,%rbx 0x00000000005685c4 <+580>: mov %rbx,-0x40(%rbp) 0x00000000005685c8 <+584>: xor %r15d,%r15d 0x00000000005685cb <+587>: jmp 0x5685e0 0x00000000005685cd <+589>: nopl (%rax) 0x00000000005685d0 <+592>: movq $0x0,0xf8(%r13) 0x00000000005685db <+603>: nopl 0x0(%rax,%rax,1) 0x00000000005685e0 <+608>: mov 0xe8(%r13),%eax 0x00000000005685e7 <+615>: test %eax,%eax 0x00000000005685e9 <+617>: jne 0x568908 0x00000000005685ef <+623>: nop 0x00000000005685f0 <+624>: cmpq $0x0,0xd8(%r13) 0x00000000005685f8 <+632>: jne 0x568b1d 0x00000000005685fe <+638>: testb $0x1,0x8e8c1c(%rip) # 0xe51221 0x0000000000568605 <+645>: je 0x568622 0x0000000000568607 <+647>: mov 0x8e8c0a(%rip),%rsi # 0xe51218 0x000000000056860e <+654>: test %rsi,%rsi 0x0000000000568611 <+657>: je 0x568622 0x0000000000568613 <+659>: mov %r13,%rdi 0x0000000000568616 <+662>: mov $0x40f0fc,%edx 0x000000000056861b <+667>: xor %ecx,%ecx 0x000000000056861d <+669>: callq 0x52f400 0x0000000000568622 <+674>: mov 0x80(%r12),%edx 0x000000000056862a <+682>: mov %edx,%ecx 0x000000000056862c <+684>: shr $0x6,%ecx 0x000000000056862f <+687>: xor %edx,%ecx 0x0000000000568631 <+689>: mov %ecx,%eax ---Type to continue, or q to quit---q Quit (gdb) p/x $rbx $4 = 0x80c8b1d38 (gdb) fr 0 #0 0x00000000005685ab in cpu_mips_exec (env=) at /d3t/d3t2/home/nox/ports/emulators/qemu-devel/work/qemu-1.6.0/cpu-exec.c:290 290 cc->do_interrupt(cpu); (gdb) l 285 cc->do_interrupt(cpu); 286 #endif 287 ret = env->exception_index; 288 break; 289 #else 290 cc->do_interrupt(cpu); 291 env->exception_index = -1; 292 #endif 293 } 294 } (gdb) what cc type = CPUClass * (gdb) p *(CPUClass *)$rbx $5 = {parent_class = {parent_class = {type = 0x5abef0 , interfaces = 0x5b5000 , cast_cache = {0x0, 0x5ccc80 "UH\211åAWAVAUATSH\203ì\030I\211ÖI\211÷¾J\006w", 0x0, 0x52f7c0 "Hc\207\060\001"}, unparent = 0x52f7d0 }, categories = {5437408}, fw_name = 0x5a8b10 "UH\211åSPH\211ó¾J\006w", desc = 0x5a8b70 "UH\211åSPH\211ó¾J\006w", props = 0x5abb90 , no_user = 5945216, reset = 0x5ab8d0 , realize = 0x52f830 , unrealize = 0x52f820 , vmsd = 0x52f810 , init = 0x52f800 , unplug = 0x0, exit = 0x49, bus_type = 0x0}, class_by_name = 0x52f860 , reset = 0x52f6e0 , reset_dump_flags = -1515870811, do_interrupt = 0xa5a5a5a5a5a5a5a5, do_unassigned_access = 0xa5a5a5a5a5a5a5a5, memory_rw_debug = 0x80c88ab00, dump_state = 0x0, dump_statistics = 0x0, get_arch_id = 0x0, get_paging_enabled = 0x64fb0d, get_memory_mapping = 0x73c6e2, set_pc = 0x47b5a0 , synchronize_from_tb = 0x0, get_phys_page_debug = 0x0, gdb_read_register = 0x0, gdb_write_register = 0x0, write_elf64_note = 0x1, write_elf64_qemunote = 0x0, write_elf32_note = 0x52f860 , write_elf32_qemunote = 0x47b7b0 , vmsd = 0x0, gdb_num_core_regs = 0, gdb_core_xml_file = 0x0} (gdb) p &(*(CPUClass *)$rbx)->do_interrupt $6 = (void (**)(CPUState *)) 0x80c8b1df0 (gdb) p 0x80c8b1df0-$rbx $7 = 184 (gdb) p/x 184 $8 = 0xb8 (gdb)