summaryrefslogtreecommitdiff
path: root/elf/multiload.c
blob: e85cc96589064c31d3df926914fac06d58e29e63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <dlfcn.h>
#include <errno.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main (void)
{
  void *a;
  void *b;
  void *c;
  void *d;
  char *wd;
  char *base;
  char *buf;

  mtrace ();

  /* Change to the binary directory.  */
  if (chdir (OBJDIR) != 0)
    {
      printf ("cannot change to `%s': %m", OBJDIR);
      exit (EXIT_FAILURE);
    }

  wd = getcwd (NULL, 0);
  base = basename (wd);
  buf = alloca (strlen (wd) + strlen (base) + 5 + sizeof "testobj1.so");

  printf ("loading `%s'\n", "./testobj1.so");
  a = dlopen ("./testobj1.so", RTLD_NOW);
  if (a == NULL)
    {
      printf ("cannot load `./testobj1.so': %s\n", dlerror ());
      exit (EXIT_FAILURE);
    }

  stpcpy (stpcpy (stpcpy (buf, "../"), base), "/testobj1.so");
  printf ("loading `%s'\n", buf);
  b = dlopen (buf, RTLD_NOW);
  if (b == NULL)
    {
      printf ("cannot load `%s': %s\n", buf, dlerror ());
      exit (EXIT_FAILURE);
    }

  stpcpy (stpcpy (buf, wd), "/testobj1.so");
  printf ("loading `%s'\n", buf);
  c = dlopen (buf, RTLD_NOW);
  if (c == NULL)
    {
      printf ("cannot load `%s': %s\n", buf, dlerror ());
      exit (EXIT_FAILURE);
    }

  stpcpy (stpcpy (stpcpy (stpcpy (buf, wd), "/../"), base), "/testobj1.so");
  printf ("loading `%s'\n", buf);
  d = dlopen (buf, RTLD_NOW);
  if (d == NULL)
    {
      printf ("cannot load `%s': %s\n", buf, dlerror ());
      exit (EXIT_FAILURE);
    }

  if (a != b || b != c || c != d)
    {
      puts ("shared object loaded more than once");
      exit (EXIT_FAILURE);
    }

  if (dlclose (a) != 0)
    {
      puts ("closing `a' failed");
      exit (EXIT_FAILURE);
    }
  if (dlclose (b) != 0)
    {
      puts ("closing `a' failed");
      exit (EXIT_FAILURE);
    }
  if (dlclose (c) != 0)
    {
      puts ("closing `a' failed");
      exit (EXIT_FAILURE);
    }
  if (dlclose (d) != 0)
    {
      puts ("closing `a' failed");
      exit (EXIT_FAILURE);
    }

  free (wd);

  return 0;
}

extern int foo (int a);
int
foo (int a)
{
  return a;
}