Fix userland ELF loader for zero sized BSS.
[qemu] / disas.c
diff --git a/disas.c b/disas.c
index f713040..04ea653 100644 (file)
--- a/disas.c
+++ b/disas.c
@@ -58,7 +58,7 @@ perror_memory (status, memaddr, info)
     /* Actually, address between memaddr and memaddr + len was
        out of bounds.  */
     (*info->fprintf_func) (info->stream,
-                          "Address 0x%llx is out of bounds.\n", memaddr);
+                          "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
 }
 
 /* This could be in a separate file, to save miniscule amounts of space
@@ -73,7 +73,7 @@ generic_print_address (addr, info)
      bfd_vma addr;
      struct disassemble_info *info;
 {
-  (*info->fprintf_func) (info->stream, "0x%llx", addr);
+    (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
 }
 
 /* Just return the given address.  */
@@ -138,6 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
    values:
     i386 - nonzero means 16 bit code
     arm  - nonzero means thumb code 
+    ppc  - nonzero means little endian
     other targets - unused
  */
 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
@@ -177,12 +178,28 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
     disasm_info.mach = bfd_mach_sparc_v9b;
 #endif    
 #elif defined(TARGET_PPC)
-    if (cpu_single_env->msr[MSR_LE])
+    if (flags)
         disasm_info.endian = BFD_ENDIAN_LITTLE;
+#ifdef TARGET_PPC64
+    disasm_info.mach = bfd_mach_ppc64;
+#else
+    disasm_info.mach = bfd_mach_ppc;
+#endif
     print_insn = print_insn_ppc;
+#elif defined(TARGET_M68K)
+    print_insn = print_insn_m68k;
 #elif defined(TARGET_MIPS)
+#ifdef TARGET_WORDS_BIGENDIAN
     print_insn = print_insn_big_mips;
 #else
+    print_insn = print_insn_little_mips;
+#endif
+#elif defined(TARGET_M68K)
+    print_insn = print_insn_m68k;
+#elif defined(TARGET_SH4)
+    disasm_info.mach = bfd_mach_sh4;
+    print_insn = print_insn_sh;
+#else
     fprintf(out, "0x" TARGET_FMT_lx
            ": Asm output not supported on this arch\n", code);
     return;
@@ -246,6 +263,8 @@ void disas(FILE *out, void *code, unsigned long size)
     print_insn = print_insn_big_mips;
 #elif defined(__MIPSEL__)
     print_insn = print_insn_little_mips;
+#elif defined(__m68k__)
+    print_insn = print_insn_m68k;
 #else
     fprintf(out, "0x%lx: Asm output not supported on this arch\n",
            (long) code);
@@ -254,11 +273,9 @@ void disas(FILE *out, void *code, unsigned long size)
     for (pc = (unsigned long)code; pc < (unsigned long)code + size; pc += count) {
        fprintf(out, "0x%08lx:  ", pc);
 #ifdef __arm__
-        /* since data are included in the code, it is better to
+        /* since data is included in the code, it is better to
            display code data too */
-        if (is_host) {
-            fprintf(out, "%08x  ", (int)bfd_getl32((const bfd_byte *)pc));
-        }
+        fprintf(out, "%08x  ", (int)bfd_getl32((const bfd_byte *)pc));
 #endif
        count = print_insn(pc, &disasm_info);
        fprintf(out, "\n");
@@ -274,6 +291,7 @@ const char *lookup_symbol(target_ulong orig_addr)
     /* Hack, because we know this is x86. */
     Elf32_Sym *sym;
     struct syminfo *s;
+    target_ulong addr;
     
     for (s = syminfos; s; s = s->next) {
        sym = s->disas_symtab;
@@ -285,8 +303,13 @@ const char *lookup_symbol(target_ulong orig_addr)
            if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
                continue;
 
-           if (orig_addr >= sym[i].st_value
-               && orig_addr < sym[i].st_value + sym[i].st_size)
+           addr = sym[i].st_value;
+#ifdef TARGET_ARM
+            /* The bottom address bit marks a Thumb symbol.  */
+            addr &= ~(target_ulong)1;
+#endif
+           if (orig_addr >= addr
+               && orig_addr < addr + sym[i].st_size)
                return s->disas_strtab + sym[i].st_name;
        }
     }
@@ -299,6 +322,7 @@ void term_vprintf(const char *fmt, va_list ap);
 void term_printf(const char *fmt, ...);
 
 static int monitor_disas_is_physical;
+static CPUState *monitor_disas_env;
 
 static int
 monitor_read_memory (memaddr, myaddr, length, info)
@@ -310,7 +334,7 @@ monitor_read_memory (memaddr, myaddr, length, info)
     if (monitor_disas_is_physical) {
         cpu_physical_memory_rw(memaddr, myaddr, length, 0);
     } else {
-        cpu_memory_rw_debug(cpu_single_env, memaddr,myaddr, length, 0);
+        cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
     }
     return 0;
 }
@@ -324,7 +348,8 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...)
     return 0;
 }
 
-void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
+void monitor_disas(CPUState *env,
+                   target_ulong pc, int nb_insn, int is_physical, int flags)
 {
     int count, i;
     struct disassemble_info disasm_info;
@@ -332,6 +357,7 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
 
     INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf);
 
+    monitor_disas_env = env;
     monitor_disas_is_physical = is_physical;
     disasm_info.read_memory_func = monitor_read_memory;
 
@@ -355,10 +381,23 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
 #elif defined(TARGET_SPARC)
     print_insn = print_insn_sparc;
 #elif defined(TARGET_PPC)
+#ifdef TARGET_PPC64
+    disasm_info.mach = bfd_mach_ppc64;
+#else
+    disasm_info.mach = bfd_mach_ppc;
+#endif
     print_insn = print_insn_ppc;
+#elif defined(TARGET_M68K)
+    print_insn = print_insn_m68k;
 #elif defined(TARGET_MIPS)
+#ifdef TARGET_WORDS_BIGENDIAN
     print_insn = print_insn_big_mips;
 #else
+    print_insn = print_insn_little_mips;
+#endif
+#elif defined(TARGET_M68K)
+    print_insn = print_insn_m68k;
+#else
     term_printf("0x" TARGET_FMT_lx
                ": Asm output not supported on this arch\n", pc);
     return;