Assign symbol the address of a section


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,

There is no "trick"; llvm-gcc and gcc should work in exactly the same
way in this regard.


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.


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

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);
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,