Skip to content

Commit

Permalink
Handle thread local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 24, 2018
1 parent da7309b commit eb29bef
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
5 changes: 4 additions & 1 deletion emu/gadgets-x86/memory.S
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ si_gadgets:
.endr
.previous

# memory stuff that can't go in a header file
.gadget seg_gs
addl CPU_tls_ptr(%_cpu), %_addr
gret

.irp type, read,write
.global handle_\type\()_miss
handle_\type\()_miss:
Expand Down
17 changes: 13 additions & 4 deletions emu/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static inline int sz(int size) {
// this really wants to use all the locals of the decoder, which we can do
// really nicely in gcc using nested functions, but that won't work in clang,
// so we explicitly pass 500 arguments. sorry for the mess
static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg arg, struct modrm *modrm, uint64_t *imm, int size) {
static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg arg, struct modrm *modrm, uint64_t *imm, int size, bool seg_gs, dword_t addr_offset) {
size = sz(size);
gadgets = gadgets + size * arg_count;

Expand All @@ -67,6 +67,12 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
else
arg = arg_mem;
break;
case arg_mem_addr:
arg = arg_mem;
modrm->type = modrm_mem;
modrm->base = reg_none;
modrm->offset = addr_offset;
break;
case arg_1:
arg = arg_imm;
*imm = 1;
Expand All @@ -85,6 +91,8 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
gag(addr, modrm->base, modrm->offset);
if (modrm->type == modrm_mem_si)
ga(si, modrm->index * 4 + modrm->shift);
if (seg_gs)
g(seg_gs);
break;
}
GEN(gadgets[arg]);
Expand All @@ -93,7 +101,7 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
}
#define op(type, thing, z) do { \
extern gadget_t type##_gadgets[]; \
gen_op(state, type##_gadgets, arg_##thing, &modrm, &imm, z); \
gen_op(state, type##_gadgets, arg_##thing, &modrm, &imm, z, seg_gs, addr_offset); \
} while (0)

#define load(thing, z) op(load, thing, z)
Expand All @@ -103,7 +111,8 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
#define lo(o, src, dst, z) load(dst, z); op(o, src, z)

#define DECLARE_LOCALS \
dword_t addr_offset = 0;
dword_t addr_offset = 0; \
bool seg_gs = false

#define RETURN(thing) (void) (thing); return

Expand All @@ -115,7 +124,7 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a

#define READMODRM modrm_decode32(&state->ip, tlb, &modrm)
#define READADDR _READIMM(addr_offset, 32)
#define SEG_GS() UNDEFINED
#define SEG_GS() seg_gs = true

#define MOV(src, dst,z) load(src, z); store(dst, z)
#define MOVZX(src, dst,zs,zd) load(src, zs); store(dst, zd)
Expand Down
1 change: 1 addition & 0 deletions emu/offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ void cpu() {
OFFSET(CPU, cpu_state, sp);
OFFSET(CPU, cpu_state, eip);
OFFSET(CPU, cpu_state, gs);
OFFSET(CPU, cpu_state, tls_ptr);

OFFSET(CPU, cpu_state, eflags);
OFFSET(CPU, cpu_state, of);
Expand Down

0 comments on commit eb29bef

Please sign in to comment.