Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mach-O loading in kernel #364

Closed
LubosD opened this issue Dec 16, 2017 · 3 comments

Comments

Projects
None yet
2 participants
@LubosD
Copy link
Member

commented Dec 16, 2017

In relation to #304 (getting LLDB working under Darling), we need to move Mach-O loading to the kernel.

This has several benefits:

  • XNU task will be created at the same time as the Linux process (this is the main motivation - #304).
  • Faster loading, because mldr will no longer be involved.
  • Makes things a bit cleaner.

And disadvantages:

  • We'll have to redo our approach to calling ELF APIs.

Steps - Mach-O

  • Load Mach-Os in kernel. See if we can adapt Wenqi's code for this.
  • Move commpage generation into the kernel.
  • Hide /dev/mach from userspace. Open devmach fd inside the kernel Mach-O loader (and make it O_CLOEXEC).
  • Provide information to dyld_info in the XNU task (needed for debuggers).
  • Remove /dev/mach opening from libsystem_kernel. Maybe we could get the fd number via apple[] args to entry point?

Steps - ELF

  • Introduce a library for loading ELF files...:
  • Create a simple ELF loader (similar to the kernel ELF loader - no dynamic library loading).
  • Create an ELF stub that gets jumped into by the loader (dynamic loader) and returns control back into Mach-O (while passing along fnptrs to dlopen() and friends). We could pass a function pointer via argv[] and this function would longjmp() back in order to rewind the stack.
  • Modify libsystem_kernel to access our ELF wrapper for bsdthread_* syscall implementation.

More Ideas

  • Provide commpage contents as a mmap from the devmach fd. The devmach fd would then be closed before jumping to the entry point. This way we'd avoid polluting the fd table, but still learn about process termination (the memory mapping destruction would close the struct file*).
  • Register an IDT entry (e.g. 0x83) for using for LKM calls instead of ioctl() and do int 0x83 to make LKM calls.

@LubosD LubosD added the Enhancement label Dec 16, 2017

@LubosD LubosD self-assigned this Dec 16, 2017

@LubosD

This comment has been minimized.

Copy link
Member Author

commented Dec 16, 2017

Interrupt handler impl

TODO: is some register saving needed?

swapgs
call lkmcall
swapgs
iretq

Interrupt handler installation

void isr_install(void)
{
        struct desc_ptr newidtr;
        gate_desc *oldidt, *newidt;
        unsigned long idtpage;
        void* isr = NULL; // TODO: fill in func ptr here

        struct desc_ptr idtreg;

        store_idt(&idtreg);
        oldidt = (gate_desc *)idtreg.address;

        idtpage =__get_free_page(GFP_KERNEL);
        if(!idtpage)
                return;

        newidtr.address = idtpage;
        newidtr.size = idtreg.size;
        newidt = (gate_desc *)newidtr.address;

        memcpy(newidt, oldidt, idtreg.size);

        pack_gate(&newidt[0x83], GATE_INTERRUPT, (unsigned long)isr, 0x3, 0, __KERNEL_CS);

        load_idt((void *)&newidtr);
        smp_call_function((smp_call_func_t) load_idt, &newidtr, 1);
}
@LubosD

This comment has been minimized.

Copy link
Member Author

commented Jan 2, 2018

LLDB observations:

TaskPortForProcessID:

  • Called after LLDB receives SIGTRAP for the exec() that just happened. task_t should be ready when this signal is delivered. (Should already be the case, because this is supposed to be generated once the new process is ready to run.)

PosixSpawnChildForPTraceDebugging:

  • Uses ptrace(PT_ATTACHEXC) - maybe this should wait until attachable?
  • -> We should probably block the RT signals we use for ptrace() impl until the child process is ready to handle it.
@bugaevc

This comment has been minimized.

Copy link
Member

commented May 29, 2018

🎉

@bugaevc bugaevc closed this May 29, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.