static void
load_lib_and_get_table (int device, int lib_num, mapping_table *&table,
			int &table_size)
{
  struct TargetImage {
    int64_t size;
    /* 10 characters is enough for max int value.  */
    char name[sizeof ("lib0000000000.so")];
    char data[];
  } __attribute__ ((packed));

  void ***host_table_descr = (void ***) lib_descrs[lib_num].first;
  void **host_func_start = host_table_descr[0];
  void **host_func_end   = host_table_descr[1];
  void **host_var_start  = host_table_descr[2];
  void **host_var_end    = host_table_descr[3];

  void **target_image_descr = (void **) lib_descrs[lib_num].second;
  void *image_start = target_image_descr[0];
  void *image_end   = target_image_descr[1];

  TRACE ("() host_table_descr { %p, %p, %p, %p }", host_func_start,
	 host_func_end, host_var_start, host_var_end);
  TRACE ("() target_image_descr { %p, %p }", image_start, image_end);

  int64_t image_size = (uintptr_t) image_end - (uintptr_t) image_start;
  TargetImage *image
    = (TargetImage *) malloc (sizeof (int64_t) + sizeof ("lib0000000000.so")
			      + image_size);
  if (!image)
    {
      fprintf (stderr, "%s: Can't allocate memory\n", __FILE__);
      exit (1);
    }

  image->size = image_size;
  sprintf (image->name, "lib%010d.so", lib_num);
  memcpy (image->data, image_start, image->size);

  TRACE ("() __offload_register_image %s { %p, %d }",
	 image->name, image_start, image->size);
  __offload_register_image (image);

  int tgt_num_funcs = 0;
  int tgt_num_vars = 0;
  void **tgt_table = NULL;
  get_target_table (device, tgt_num_funcs, tgt_num_vars, tgt_table);
  free (image);

  /* The func table contains only addresses, the var table contains addresses
     and corresponding sizes.  */
  int host_num_funcs = host_func_end - host_func_start;
  int host_num_vars  = (host_var_end - host_var_start) / 2;
  TRACE ("() host_num_funcs = %d, tgt_num_funcs = %d",
	 host_num_funcs, tgt_num_funcs);
  TRACE ("() host_num_vars = %d, tgt_num_vars = %d",
	 host_num_vars, tgt_num_vars);
  if (host_num_funcs != tgt_num_funcs)
    {
      fprintf (stderr, "%s: Can't map target functions\n", __FILE__);
      exit (1);
    }
  if (host_num_vars != tgt_num_vars)
    {
      fprintf (stderr, "%s: Can't map target variables\n", __FILE__);
      exit (1);
    }

  table = (mapping_table *) realloc (table, (table_size + host_num_funcs
					     + host_num_vars)
					    * sizeof (mapping_table));
  if (table == NULL)
    {
      fprintf (stderr, "%s: Can't allocate memory\n", __FILE__);
      exit (1);
    }

  for (int i = 0; i < host_num_funcs; i++)
    {
      mapping_table t;
      t.host_start = (uintptr_t) host_func_start[i];
      t.host_end = t.host_start + 1;
      t.tgt_start = (uintptr_t) tgt_table[i];
      t.tgt_end = t.tgt_start + 1;

      TRACE ("() lib %d, func %d:\t0x%llx -- 0x%llx",
	     lib_num, i, t.host_start, t.tgt_start);

      table[table_size++] = t;
    }

  for (int i = 0; i < host_num_vars * 2; i += 2)
    {
      mapping_table t;
      t.host_start = (uintptr_t) host_var_start[i];
      t.host_end = t.host_start + (uintptr_t) host_var_start[i+1];
      t.tgt_start = (uintptr_t) tgt_table[tgt_num_funcs+i];
      t.tgt_end = t.tgt_start + (uintptr_t) tgt_table[tgt_num_funcs+i+1];

      TRACE ("() lib %d, var %d:\t0x%llx (%d) -- 0x%llx (%d)", lib_num, i/2,
	     t.host_start, t.host_end - t.host_start,
	     t.tgt_start, t.tgt_end - t.tgt_start);

      table[table_size++] = t;
    }

  delete [] tgt_table;
}
inline const ColumnBase& LinkView::get_column_base(size_t index) const
{
    return get_target_table().get_column_base(index);
}