Skip to content

Instantly share code, notes, and snippets.

@stv0g
Last active December 31, 2015 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stv0g/68746961da78d2b0e52f to your computer and use it in GitHub Desktop.
Save stv0g/68746961da78d2b0e52f to your computer and use it in GitHub Desktop.
x86-64 compatible call to user code
/** @brief Jump back to user code
*
* This function runs the user code after stopping it just as if
* it was a return from a procedure.
*
* @return 0 in any case
*/
static inline int jump_to_user_code(size_t ep, size_t stack)
{
#ifdef CONFIG_X86_64
size_t *argc = (size_t*) stack;
size_t *argv = (size_t*) stack + 1;
size_t *env = (size_t*) stack + 2;
stack += 3 * sizeof(size_t);
#elif defined (CONFIG_X86_32)
asm volatile ("mov %0, %%ds; mov %0, %%fs; mov %0, %%gs; mov %0, %%es" :: "r"(0x23)); // update segment registers
#endif
asm volatile ("push $0x23; push %0; push $0x1B; push %1" :: "r"(stack), "r"(ep)); // fake stack, see Intel Reference Manual, Vol 1, 6.3.6
#ifdef CONFIG_X86_64
asm volatile ("lretq" :: "S" (*argc), "D" (*argv), "d" (*env) : "cc"); // far return to user level code and save arguments to registers
#elif defined (CONFIG_X86_32)
asm volatile ("lret" ::: "cc"); // far return to user level code
#endif
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment