Go back to previous page
Go back to home page


Last update: 02-Jan-2016
Author: R. Koucha

How to make executable shared libraries









s


Introduction
Example of shared library
Making an executable shared library
References
About the author

Introduction

You may know that it is possible to run the C shared library. For example, on my Linux system, if I run it, it displays its version:

$ /lib/libc.so.6
GNU C Library (Ubuntu EGLIBC 2.11.1-0ubuntu7.8) stable release version 2.11.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.3.
Compiled on a Linux >>2.6.24-27-server<< system on 2011-01-21.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

This paper focuses on the recipe to make executable shared libraries.

Example of shared library

Here is the source file of a shared library:

service.c
#include <stdio.h>

void lib_service(void)
{

  printf("This is a service of the shared library\n");

} // lib_service


Here is a main program which uses the preceding shared library:

main.c
#include <stdio.h>

extern void lib_service(void);

int main(int ac, char *av[])
{

  lib_service();

  return 0;
} // main


To build this program along with its shared library, we do:

$ gcc -shared service.c -o libservice.so -Wl,-soname,libservice.so
$ gcc main.c -o main -lservice -L.

To run the program we do:

$ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:`pwd`
$ ./main
This is a service of the shared library

If we run the library we get a segmentation fault:

$ chmod +x ./libservice.so
$ ./libservice.so
Erreur de segmentation

Making an executable shared library

We must first specify an entry point for the library:


service.c
#include <stdio.h>

void lib_service(void)
{

  printf("This is a service of the shared library\n");

} // lib_service


void lib_entry(void)
{
  printf("Entry point of the service library\n");
}



This entry point is set into the object thanks to the "-e" option of the linker:

$ gcc -shared service.c -o libservice.so -Wl,-soname,libservice.so -Wl,-e,lib_entry

But the execution still fails:

$ ./libservice.so
Illegal instruction

We must make the entry point be a "no return" function thanks to the "_exit()" service:

service.c
#include <stdio.h>
#include <unistd.h>

void lib_service(void)
{

  printf("This is a service of the shared library\n");

} // lib_service


void lib_entry(void)
{
  printf("Entry point of the service library\n");

  _exit(0);
}



But the execution still fails:

$ gcc -shared service.c -o libservice.so -Wl,-soname,libservice.so -Wl,-e,lib_entry
$ ./libservice.so
Illegal instruction

We specify the interpreter file to be the dynamic linker. On our Linux system, it is "/lib/ld-linux.so.2":


service.c
#include <stdio.h>
#include <unistd.h>


const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";

void lib_service(void)
{

  printf("This is a service of the shared library\n");

} // lib_service


void lib_entry(void)
{
  printf("Entry point of the service library\n");

  _exit(0);
}



Now it works !

$ gcc -shared service.c -o libservice.so -Wl,-soname,libservice.so -Wl,-e,lib_entry
$ ./libservice.so
Entry point of the service library

Although, it is executable, the file is still usable as a library since the "main" executable can still dynamically link with it:

$ ./main
This is a service of the shared library


NB: If you are using the G++ compiler, make sure that the entry point is defined as a C language symbol with the extern "C" directive. For example:

service.c
#include <stdio.h>
#include <unistd.h>


const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";

void lib_service(void)
{

  printf("This is a service of the shared library\n");

} // lib_service


extern "C" {

void lib_entry(void)
{
  printf("Entry point of the service library\n");

  _exit(0);
}

}


References

About the author

The author is an engineer in computer sciences located in France. He can be contacted here or you can have a look at his WEB home page.




Go back to previous page
Go back to home page