Commit 9edc5d79666777c226554df5daf8bd5ffca8099d

Authored by Mika Westerberg
Committed by Riku Voipio
1 parent edf8e2af

linux-user: added x86 and x86_64 support for ELF coredump

Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Showing 1 changed file with 83 additions and 0 deletions
linux-user/elfload.c
... ... @@ -134,6 +134,52 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
134 134 regs->rip = infop->entry;
135 135 }
136 136  
  137 +typedef target_ulong elf_greg_t;
  138 +typedef uint32_t target_uid_t;
  139 +typedef uint32_t target_gid_t;
  140 +typedef int32_t target_pid_t;
  141 +
  142 +#define ELF_NREG 27
  143 +typedef elf_greg_t elf_gregset_t[ELF_NREG];
  144 +
  145 +/*
  146 + * Note that ELF_NREG should be 29 as there should be place for
  147 + * TRAPNO and ERR "registers" as well but linux doesn't dump
  148 + * those.
  149 + *
  150 + * See linux kernel: arch/x86/include/asm/elf.h
  151 + */
  152 +static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
  153 +{
  154 + (*regs)[0] = env->regs[15];
  155 + (*regs)[1] = env->regs[14];
  156 + (*regs)[2] = env->regs[13];
  157 + (*regs)[3] = env->regs[12];
  158 + (*regs)[4] = env->regs[R_EBP];
  159 + (*regs)[5] = env->regs[R_EBX];
  160 + (*regs)[6] = env->regs[11];
  161 + (*regs)[7] = env->regs[10];
  162 + (*regs)[8] = env->regs[9];
  163 + (*regs)[9] = env->regs[8];
  164 + (*regs)[10] = env->regs[R_EAX];
  165 + (*regs)[11] = env->regs[R_ECX];
  166 + (*regs)[12] = env->regs[R_EDX];
  167 + (*regs)[13] = env->regs[R_ESI];
  168 + (*regs)[14] = env->regs[R_EDI];
  169 + (*regs)[15] = env->regs[R_EAX]; /* XXX */
  170 + (*regs)[16] = env->eip;
  171 + (*regs)[17] = env->segs[R_CS].selector & 0xffff;
  172 + (*regs)[18] = env->eflags;
  173 + (*regs)[19] = env->regs[R_ESP];
  174 + (*regs)[20] = env->segs[R_SS].selector & 0xffff;
  175 + (*regs)[21] = env->segs[R_FS].selector & 0xffff;
  176 + (*regs)[22] = env->segs[R_GS].selector & 0xffff;
  177 + (*regs)[23] = env->segs[R_DS].selector & 0xffff;
  178 + (*regs)[24] = env->segs[R_ES].selector & 0xffff;
  179 + (*regs)[25] = env->segs[R_FS].selector & 0xffff;
  180 + (*regs)[26] = env->segs[R_GS].selector & 0xffff;
  181 +}
  182 +
137 183 #else
138 184  
139 185 #define ELF_START_MMAP 0x80000000
... ... @@ -164,8 +210,45 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
164 210 A value of 0 tells we have no such handler. */
165 211 regs->edx = 0;
166 212 }
  213 +
  214 +typedef target_ulong elf_greg_t;
  215 +typedef uint16_t target_uid_t;
  216 +typedef uint16_t target_gid_t;
  217 +typedef int32_t target_pid_t;
  218 +
  219 +#define ELF_NREG 17
  220 +typedef elf_greg_t elf_gregset_t[ELF_NREG];
  221 +
  222 +/*
  223 + * Note that ELF_NREG should be 19 as there should be place for
  224 + * TRAPNO and ERR "registers" as well but linux doesn't dump
  225 + * those.
  226 + *
  227 + * See linux kernel: arch/x86/include/asm/elf.h
  228 + */
  229 +static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
  230 +{
  231 + (*regs)[0] = env->regs[R_EBX];
  232 + (*regs)[1] = env->regs[R_ECX];
  233 + (*regs)[2] = env->regs[R_EDX];
  234 + (*regs)[3] = env->regs[R_ESI];
  235 + (*regs)[4] = env->regs[R_EDI];
  236 + (*regs)[5] = env->regs[R_EBP];
  237 + (*regs)[6] = env->regs[R_EAX];
  238 + (*regs)[7] = env->segs[R_DS].selector & 0xffff;
  239 + (*regs)[8] = env->segs[R_ES].selector & 0xffff;
  240 + (*regs)[9] = env->segs[R_FS].selector & 0xffff;
  241 + (*regs)[10] = env->segs[R_GS].selector & 0xffff;
  242 + (*regs)[11] = env->regs[R_EAX]; /* XXX */
  243 + (*regs)[12] = env->eip;
  244 + (*regs)[13] = env->segs[R_CS].selector & 0xffff;
  245 + (*regs)[14] = env->eflags;
  246 + (*regs)[15] = env->regs[R_ESP];
  247 + (*regs)[16] = env->segs[R_SS].selector & 0xffff;
  248 +}
167 249 #endif
168 250  
  251 +#define USE_ELF_CORE_DUMP
169 252 #define ELF_EXEC_PAGESIZE 4096
170 253  
171 254 #endif
... ...