stage1.c
author Mathieu Lacage <mathieu.lacage@alcmeon.com>
Sat, 23 Feb 2013 20:59:51 +0100
changeset 656 e4817d48962f
parent 608 0fe0080331a8
permissions -rw-r--r--
basic test for tls
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     1
#include "dprintf.h"
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
     2
#include "stage1.h"
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     3
#include "stage2.h"
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     4
#include "system.h"
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
     5
#include "vdl.h"
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 215
diff changeset
     6
#include "futex.h"
534
8baff8e0e08f vdl_utils_malloc -> vdl_alloc_malloc
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 532
diff changeset
     7
#include "vdl-alloc.h"
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
     8
#include "vdl-list.h"
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
     9
#include "vdl-utils.h"
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    10
#include "machine.h"
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    11
#include <elf.h>
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    12
#include <link.h>
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    13
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    14
241
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    15
#define READ_LONG(p)				\
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    16
  ({long v = *((long*)p);			\
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    17
    p+=sizeof(long);				\
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    18
    v;})
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    19
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    20
#define READ_POINTER(p)				\
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    21
  ({char * v = *((char**)p);			\
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    22
    p+=sizeof(char*);				\
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    23
    v;})
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    24
static struct Stage2Input
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    25
prepare_stage2 (unsigned long entry_point_struct)
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    26
{
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    27
  struct Stage2Input stage2_input;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    28
  unsigned long tmp = entry_point_struct;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    29
  ElfW(auxv_t) *auxvt, *auxvt_tmp;
241
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    30
  // although the C convention for argc is to be an int (as such, 4 bytes
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    31
  // on both i386 and x86_64), the kernel ABI has a long argc (as such,
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    32
  // 4 bytes on i386 and 8 bytes on x86_64).
97ed54758a2c be careful when reading argc from aux vector
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 239
diff changeset
    33
  stage2_input.program_argc = READ_LONG (tmp); // skip argc
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    34
  DPRINTF("argc=0x%x\n", stage2_input.program_argc);
434
1e09f4c45281 do not keep track of copy of argv/envp
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 412
diff changeset
    35
  stage2_input.program_argv = (char **)tmp;
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    36
  tmp += sizeof(char *)*(stage2_input.program_argc+1); // skip argv
434
1e09f4c45281 do not keep track of copy of argv/envp
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 412
diff changeset
    37
  stage2_input.program_envp = (char **)tmp;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    38
  while (READ_POINTER (tmp) != 0) {} // skip envp
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    39
  auxvt = (ElfW(auxv_t) *)tmp; // save aux vector start
214
a8b6aae7e195 fix un-initialized variable
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 208
diff changeset
    40
  stage2_input.sysinfo = 0;
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    41
  stage2_input.program_phdr = 0;
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    42
  stage2_input.program_phnum = 0;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    43
  auxvt_tmp = auxvt;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    44
  while (auxvt_tmp->a_type != AT_NULL)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    45
    {
125
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
    46
      if (auxvt_tmp->a_type == AT_PHDR)
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    47
	{
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    48
	  stage2_input.program_phdr = (ElfW(Phdr) *)auxvt_tmp->a_un.a_val;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    49
	}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    50
      else if (auxvt_tmp->a_type == AT_PHNUM)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    51
	{
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    52
	  stage2_input.program_phnum = auxvt_tmp->a_un.a_val;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    53
	}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    54
      else if (auxvt_tmp->a_type == AT_SYSINFO)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    55
	{
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    56
	  stage2_input.sysinfo = auxvt_tmp->a_un.a_val;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    57
	}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    58
      auxvt_tmp++;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    59
    }
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    60
  if (stage2_input.program_phdr == 0 ||
215
514bded50417 we don't really need a sysinfo output
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 214
diff changeset
    61
      stage2_input.program_phnum == 0)
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    62
    {
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    63
      system_exit (-3);
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    64
    }
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
    65
  return stage2_input;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    66
}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    67
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    68
static void global_initialize (unsigned long interpreter_load_base)
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    69
{
534
8baff8e0e08f vdl_utils_malloc -> vdl_alloc_malloc
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 532
diff changeset
    70
  // after this call to vdl_alloc_initialize is completed,
8baff8e0e08f vdl_utils_malloc -> vdl_alloc_malloc
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 532
diff changeset
    71
  // we are allowed to allocate heap memory.
8baff8e0e08f vdl_utils_malloc -> vdl_alloc_malloc
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 532
diff changeset
    72
  vdl_alloc_initialize ();
8baff8e0e08f vdl_utils_malloc -> vdl_alloc_malloc
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 532
diff changeset
    73
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    74
  struct Vdl *vdl = &g_vdl;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    75
  vdl->version = 1;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    76
  vdl->link_map = 0;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    77
  vdl->breakpoint = 0;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    78
  vdl->state = VDL_CONSISTENT;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    79
  vdl->interpreter_load_base = interpreter_load_base;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    80
  vdl->bind_now = 0; // by default, do lazy binding
476
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
    81
  vdl->finalized = 0;
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    82
  vdl->ldso = 0;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    83
  vdl->contexts = vdl_list_new ();
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    84
  vdl->search_dirs = vdl_utils_splitpath (machine_get_system_search_dirs ());
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    85
  vdl->tls_gen = 1;
606
2de97e7a3f84 limited support for static tls blocks with dlopen
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 567
diff changeset
    86
  vdl->tls_static_total_size = 0;
2de97e7a3f84 limited support for static tls blocks with dlopen
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 567
diff changeset
    87
  vdl->tls_static_current_size = 0;
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    88
  vdl->tls_static_align = 0;
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    89
  vdl->tls_n_dtv = 0;
608
0fe0080331a8 make sure tls static block is initialized
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 606
diff changeset
    90
  vdl->tls_next_index = 1;
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    91
  vdl->futex = futex_new ();
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
    92
  vdl->errors = vdl_list_new ();
412
a9b84dbf78fd handle c++ exceptions
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 369
diff changeset
    93
  vdl->n_added = 0;
a9b84dbf78fd handle c++ exceptions
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 369
diff changeset
    94
  vdl->n_removed = 0;
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    95
}
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    96
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
    97
189
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
    98
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    99
// relocate entries in DT_REL
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   100
static void
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   101
relocate_dt_rel (ElfW(Dyn) *dynamic, unsigned long load_base)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   102
{
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   103
  ElfW(Dyn) *tmp = dynamic;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   104
  ElfW(Rel) *dt_rel = 0;
208
4b26fb844aba small cleanup
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 189
diff changeset
   105
  unsigned long dt_relsz = 0;
4b26fb844aba small cleanup
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 189
diff changeset
   106
  unsigned long dt_relent = 0;
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   107
  ElfW(Rela) *dt_rela = 0;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   108
  unsigned long dt_relasz = 0;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   109
  unsigned long dt_relaent = 0;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   110
  // search DT_REL, DT_RELSZ, DT_RELENT, DT_RELA, DT_RELASZ, DT_RELAENT
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   111
  while (tmp->d_tag != DT_NULL && 
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   112
	 (dt_rel == 0 || dt_relsz == 0 || dt_relent == 0 ||
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   113
	  dt_rela == 0 || dt_relasz == 0 || dt_relaent == 0))
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   114
    {
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   115
      //DEBUG_HEX(tmp->d_tag);
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   116
      if (tmp->d_tag == DT_REL)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   117
	{
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   118
	  dt_rel = (ElfW(Rel) *)(load_base + tmp->d_un.d_ptr);
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   119
	}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   120
      else if (tmp->d_tag == DT_RELSZ)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   121
	{
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   122
	  dt_relsz = tmp->d_un.d_val;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   123
	}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   124
      else if (tmp->d_tag == DT_RELENT)
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   125
	{
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   126
	  dt_relent = tmp->d_un.d_val;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   127
	}
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   128
      else if (tmp->d_tag == DT_RELA)
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   129
	{
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   130
	  dt_rela = (ElfW(Rela) *)(load_base + tmp->d_un.d_ptr);
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   131
	}
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   132
      else if (tmp->d_tag == DT_RELASZ)
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   133
	{
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   134
	  dt_relasz = tmp->d_un.d_val;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   135
	}
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   136
      else if (tmp->d_tag == DT_RELAENT)
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   137
	{
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   138
	  dt_relaent = tmp->d_un.d_val;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   139
	}
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   140
      tmp++;
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   141
    }
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   142
  DPRINTF ("dt_rel=0x%x, dt_relsz=%d, dt_relent=%d, dt_rela=0x%x, dt_relasz=%d, dt_relaent=%d\n", 
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   143
	   dt_rel, dt_relsz, dt_relent, dt_rela, dt_relasz, dt_relaent);
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   144
567
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   145
  // relocate entries in dt_rel and dt_rela. 
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   146
  // since we are relocating the dynamic loader itself here,
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   147
  // the entries will always be of type R_XXX_RELATIVE.
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   148
  uint32_t i;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   149
  for (i = 0; i < dt_relsz; i+=dt_relent)
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   150
    {
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   151
      ElfW(Rel) *tmp = (ElfW(Rel)*)(((uint8_t*)dt_rel) + i);
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   152
      ElfW(Addr) *reloc_addr = (void *)(load_base + tmp->r_offset);
567
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   153
      if (!machine_reloc_is_relative (ELFW_R_TYPE (tmp->r_info)))
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   154
	{
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   155
	  DPRINTF ("Invalid reloc entry type: %s\n",
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   156
		   machine_reloc_type_to_str (ELFW_R_TYPE (tmp->r_info)));
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   157
	  goto error;
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   158
	}
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   159
      *reloc_addr += (ElfW(Addr))load_base;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   160
    }
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   161
  for (i = 0; i < dt_relasz; i+=dt_relaent)
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   162
    {
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   163
      ElfW(Rela) *tmp = (ElfW(Rela)*)(((uint8_t*)dt_rela) + i);
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   164
      ElfW(Addr) *reloc_addr = (void *)(load_base + tmp->r_offset);
567
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   165
      if (!machine_reloc_is_relative (ELFW_R_TYPE (tmp->r_info)))
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   166
	{
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   167
	  DPRINTF ("Invalid reloc entry type: %s\n",
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   168
		   machine_reloc_type_to_str (ELFW_R_TYPE (tmp->r_info)));
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   169
	  goto error;
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   170
	}
239
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   171
      *reloc_addr = (ElfW(Addr))load_base + tmp->r_addend;
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   172
    }
fb164865ef48 handle rela for x86_64
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
   173
208
4b26fb844aba small cleanup
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 189
diff changeset
   174
  // Note that, technically, we could also relocate DT_JMPREL entries but
4b26fb844aba small cleanup
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 189
diff changeset
   175
  // this would be fairly complex so, it's easier to just make sure that
4b26fb844aba small cleanup
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 189
diff changeset
   176
  // our generated ldso binary does not contain any.
567
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   177
error:
e6e7104e2158 check for RELATIVE entries
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 538
diff changeset
   178
  return;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   179
}
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   180
189
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   181
void stage1_finalize (void)
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   182
{
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   183
  stage2_finalize ();
476
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   184
  g_vdl.finalized = 1;
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   185
}
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   186
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   187
void stage1_freeres (void)
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   188
{
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   189
  // We are called by libc_freeres_interceptor which is our wrapper
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   190
  // around __libc_freeres.
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   191
  // If stage1_freeres is called while g_vdl.finalized is set to 1, it
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   192
  // means that stage1_finalize has already run which means that
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   193
  // we are called by valgrind. If this is so, we do perform final shutdown
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   194
  // of everything here. We are allowed to do so because 
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   195
  // this function will return to vgpreload_core and the process
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   196
  // will terminate immediately after.
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   197
  if (!g_vdl.finalized)
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   198
    {
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   199
      return;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   200
    }
476
0a304a4b0c5e do proper shutdown
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 434
diff changeset
   201
  stage2_freeres ();
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   202
  vdl_utils_str_list_delete (g_vdl.search_dirs);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   203
  vdl_list_delete (g_vdl.contexts);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   204
  futex_delete (g_vdl.futex);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   205
  {
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   206
    void **i;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   207
    for (i = vdl_list_begin (g_vdl.errors);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   208
	 i != vdl_list_end (g_vdl.errors);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   209
	 i = vdl_list_next (i))
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   210
      {
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   211
	struct VdlError *error = *i;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   212
	vdl_alloc_free (error->prev_error);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   213
	vdl_alloc_free (error->error);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   214
	vdl_alloc_delete (error);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   215
      }
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   216
    vdl_list_delete (g_vdl.errors);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   217
  }
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   218
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   219
  // After this call, we can't do any malloc/free anymore.
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   220
  vdl_alloc_destroy ();
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   221
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   222
  g_vdl.search_dirs = 0;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   223
  g_vdl.contexts = 0;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   224
  g_vdl.futex = 0;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 534
diff changeset
   225
  g_vdl.errors = 0;
189
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   226
}
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   227
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   228
// Called from stage0 entry point asm code.
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   229
void stage1 (struct Stage1InputOutput *input_output)
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   230
{
125
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   231
  // The linker defines the symbol _DYNAMIC to give you the offset from
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   232
  // the load base to the start of the PT_DYNAMIC area which has been 
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   233
  // mapped by the OS loader as part of the rw PT_LOAD segment.
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   234
  void *dynamic = _DYNAMIC;
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   235
  dynamic += input_output->load_base;
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   236
  relocate_dt_rel (dynamic, input_output->load_base);
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   237
139
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
   238
  // Now that access to global variables is possible, we initialize 
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
   239
  // our main global variable. After this function call completes,
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
   240
  // we are allowed to do memory allocations.
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
   241
  global_initialize (input_output->load_base);
8b7db8cede90 move initialization code around.
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 126
diff changeset
   242
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   243
  struct Stage2Input stage2_input = prepare_stage2 (input_output->entry_point_struct);
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   244
  stage2_input.interpreter_load_base = input_output->load_base;
125
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   245
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   246
  // Now that we have relocated this binary, we can access global variables
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   247
  // so, we switch to stage2 to complete the loader initialization.
189
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   248
  struct Stage2Output stage2_output = stage2_initialize (stage2_input);
125
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   249
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   250
  // We are all done, so we update the caller's data structure to be able
11d7bfeba99c rework bootstrapping/initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 123
diff changeset
   251
  // jump in the program's entry point.
126
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   252
  input_output->entry_point = stage2_output.entry_point;
5fec9d798df2 cleanup bootstrapping
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 125
diff changeset
   253
  input_output->dl_fini = 0;
189
7fade978508f pass test2
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 175
diff changeset
   254
  input_output->dl_fini = (unsigned long) stage1_finalize;
123
a13037ac91d0 rework initialization
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   255
}