Back to index

glibc  2.9
Defines | Functions | Variables
dl-fptr.c File Reference
#include <libintl.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <link.h>
#include <ldsodefs.h>
#include <elf/dynamic-link.h>
#include <dl-fptr.h>
#include <atomic.h>

Go to the source code of this file.

Defines

#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN   256
#define COMPARE_AND_SWAP(ptr, old, new)   (catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0)

Functions

 ElfW (Addr)
static struct fdesc_tablenew_fdesc_table (struct local *l, size_t *size)
void _dl_unmap (struct link_map *map)

Variables

 local

Define Documentation

#define COMPARE_AND_SWAP (   ptr,
  old,
  new 
)    (catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0)

Definition at line 42 of file dl-fptr.c.

Definition at line 34 of file dl-fptr.c.


Function Documentation

void _dl_unmap ( struct link_map map)

Definition at line 267 of file dl-fptr.c.

{
  ElfW(Addr) *ftab = map->l_mach.fptr_table;
  struct fdesc *head = NULL, *tail = NULL;
  size_t i;

  __munmap ((void *) map->l_map_start,
           map->l_map_end - map->l_map_start);

  if (ftab == NULL)
    return;

  /* String together the fdesc structures that are being freed.  */
  for (i = 0; i < map->l_mach.fptr_table_len; ++i)
    {
      if (ftab[i])
       {
         *(struct fdesc **) ftab[i] = head;
         head = (struct fdesc *) ftab[i];
         if (tail == NULL)
           tail = head;
       }
    }

  /* Prepend the new list to the free_list: */
  if (tail)
    do
      tail->ip = (ElfW(Addr)) local.free_list;
    while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &local.free_list,
                            tail->ip, (ElfW(Addr)) head));

  __munmap (ftab, (map->l_mach.fptr_table_len
                 * sizeof (map->l_mach.fptr_table[0])));

  map->l_mach.fptr_table = NULL;
}
size_t ElfW ( Addr  ) [inline]

Definition at line 46 of file dl-fptr.c.

  {
    struct fdesc_table *root;
    struct fdesc *free_list;
    unsigned int npages;           /* # of pages to allocate */
    /* the next to members MUST be consecutive! */
    struct fdesc_table boot_table;
    struct fdesc boot_fdescs[1024];
  }
static struct fdesc_table* new_fdesc_table ( struct local l,
size_t size 
) [static, read]

Definition at line 72 of file dl-fptr.c.

{
  size_t old_npages = l->npages;
  size_t new_npages = old_npages + old_npages;
  struct fdesc_table *new_table;

  /* If someone has just created a new table, we return NULL to tell
     the caller to use the new table.  */
  if (! COMPARE_AND_SWAP (&l->npages, old_npages, new_npages))
    return (struct fdesc_table *) NULL;

  *size = old_npages * GLRO(dl_pagesize);
  new_table = __mmap (NULL, *size,
                    PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
  if (new_table == MAP_FAILED)
    _dl_signal_error (errno, NULL, NULL,
                    N_("cannot map pages for fdesc table"));

  new_table->len
    = (*size - sizeof (*new_table)) / sizeof (struct fdesc);
  new_table->first_unused = 1;
  return new_table;
}

Here is the call graph for this function:


Variable Documentation

Initial value:
  {
    .root = &local.boot_table,
    .npages = 2,
    .boot_table =
      {
       .len = sizeof (local.boot_fdescs) / sizeof (local.boot_fdescs[0]),
       .first_unused = 0
      }
  }

Definition at line 57 of file dl-fptr.c.