Hello, The binaries produced by LLVM and other compilers divide code up into various sections, e.g. the .text section. What is the recommended approach to assigning a symbol the address of a section using LLVM? Using GCC/LD, you can do this with a linker script, e.g. in a linker script you can do: _text = .; _stext = .; These symbols are then available in the corresponding C code using an "extern" definition. But, LLVM doesn't support linker scripts--so what's the trick? Thanks and regards, Matt
On Mon, May 11, 2009 at 10:02 AM, Matt Renzelmann <mjr at cs.wisc.edu> wrote:> These symbols are then available in the corresponding C code using an > "extern" definition. But, LLVM doesn't support linker scripts--so what's > the trick?There is no "trick"; llvm-gcc and gcc should work in exactly the same way in this regard. -Eli
On May 11, 2009, at 10:02 AM, Matt Renzelmann wrote:> Hello, > > The binaries produced by LLVM and other compilers divide code up into > various sections, e.g. the .text section. > > What is the recommended approach to assigning a symbol the address > of a > section using LLVM? Using GCC/LD, you can do this with a linker > script, > e.g. in a linker script you can do: > > _text = .; > _stext = .; > > These symbols are then available in the corresponding C code using an > "extern" definition. But, LLVM doesn't support linker scripts--so > what's > the trick?Hi Matt, I don't know of a straight-forward way to do this. However, you can probably use module-level inline asm to do the trick. -Chris
Matt Renzelmann
2009-May-14 18:47 UTC
[LLVMdev] Grouping related functions in a code section
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