[LLVMdev] Grouping related functions in a code section

Matt Renzelmann mjr at cs.wisc.edu
Thu May 14 11:47:05 PDT 2009


Andrew, Eli, thank you both for your help.  You both proposed essentially
the same idea at the same time and it works fine.  I appreciate your
assistance thus far.  I'd set this aside for a few days to work on another
thing, but am back now and have another question.

User mode Linux contains a "__syscall_stub" code section.  The linker script
defines it to be page-aligned, and it contains several function
definitions--not just pointers to functions, but the code itself.  User mode
Linux then memory maps this page into the address spaces of new processes.
User mode Linux first calls "clone" to fork a new process, and then uses
"mmap64" to map this page in.

One purpose of this page of code is that it contains a SIGSEGV handler.  The
newly forked process promptly installs this signal handler, and uses a
function stored in this code.

Here's an outline of the whole process:

// In the newly-cloned process, map in the magic page
// __syscall_stub_start defined in linker script
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
// Get executable permission:
addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
               PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);

The previous code maps the page of code into memory:  the page address is
stored in the linker-script-defined __syscall_stub_start symbol.  Then we
have:

unsigned long v = STUB_CODE +
    (unsigned long) stub_segv_handler - // a function stored in this page
    (unsigned long) &__syscall_stub_start; // from linker script

set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_ONSTACK | SA_NODEFER;
sa.sa_handler = (void *) v; // Use this function.

The stub_segv_handler function is defined with:

void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig) {...}

I don't actually quite understand the reason all these gyrations are
necessary and why it can't just use the signal handler function
directly--since it should have been cloned too--but I presume there is a
reason or it wouldn't be done this way.

Is there a clean way to deal with this problem in LLVM?  Again, using LD
itself is straightforward because a linker script allows you to group these
functions together into a single page--is some equivalent possible in LLVM?

Thanks and regards,
Matt




More information about the llvm-dev mailing list