1 | /* Copyright (C) 2004 Free Software Foundation, Inc.
|
---|
2 | This file is part of the GNU C Library.
|
---|
3 | Contributed by David Mosberger <davidm@hpl.hp.com>, 2004.
|
---|
4 |
|
---|
5 | The GNU C Library is free software; you can redistribute it and/or
|
---|
6 | modify it under the terms of the GNU Lesser General Public
|
---|
7 | License as published by the Free Software Foundation; either
|
---|
8 | version 2.1 of the License, or (at your option) any later version.
|
---|
9 |
|
---|
10 | The GNU C Library is distributed in the hope that it will be useful,
|
---|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
13 | Lesser General Public License for more details.
|
---|
14 |
|
---|
15 | You should have received a copy of the GNU Lesser General Public
|
---|
16 | License along with the GNU C Library; if not, write to the Free
|
---|
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
---|
18 | 02111-1307 USA. */
|
---|
19 |
|
---|
20 | #include <link.h>
|
---|
21 | #include <stddef.h>
|
---|
22 | #include <stdio.h>
|
---|
23 | #include <stdlib.h>
|
---|
24 |
|
---|
25 | #define SET 0
|
---|
26 | #define ADD 1
|
---|
27 | #define REMOVE 2
|
---|
28 |
|
---|
29 | #define leq(l,r) (((r) - (l)) <= ~0ULL / 2)
|
---|
30 |
|
---|
31 | static int
|
---|
32 | callback (struct dl_phdr_info *info, size_t size, void *ptr)
|
---|
33 | {
|
---|
34 | static int last_adds = 0, last_subs = 0;
|
---|
35 | intptr_t cmd = (intptr_t) ptr;
|
---|
36 |
|
---|
37 | printf (" size = %Zu\n", size);
|
---|
38 | if (size < (offsetof (struct dl_phdr_info, dlpi_subs)
|
---|
39 | + sizeof (info->dlpi_subs)))
|
---|
40 | {
|
---|
41 | fprintf (stderr, "dl_iterate_phdr failed to pass dlpi_adds/dlpi_subs\n");
|
---|
42 | exit (5);
|
---|
43 | }
|
---|
44 |
|
---|
45 | printf (" dlpi_adds = %Lu dlpi_subs = %Lu\n",
|
---|
46 | info->dlpi_adds, info->dlpi_subs);
|
---|
47 |
|
---|
48 | switch (cmd)
|
---|
49 | {
|
---|
50 | case SET:
|
---|
51 | break;
|
---|
52 |
|
---|
53 | case ADD:
|
---|
54 | if (leq (info->dlpi_adds, last_adds))
|
---|
55 | {
|
---|
56 | fprintf (stderr, "dlpi_adds failed to get incremented!\n");
|
---|
57 | exit (3);
|
---|
58 | }
|
---|
59 | break;
|
---|
60 |
|
---|
61 | case REMOVE:
|
---|
62 | if (leq (info->dlpi_subs, last_subs))
|
---|
63 | {
|
---|
64 | fprintf (stderr, "dlpi_subs failed to get incremented!\n");
|
---|
65 | exit (4);
|
---|
66 | }
|
---|
67 | break;
|
---|
68 | }
|
---|
69 | last_adds = info->dlpi_adds;
|
---|
70 | last_subs = info->dlpi_subs;
|
---|
71 | return -1;
|
---|
72 | }
|
---|
73 |
|
---|
74 | static void *
|
---|
75 | load (const char *path)
|
---|
76 | {
|
---|
77 | void *handle;
|
---|
78 |
|
---|
79 | printf ("loading `%s'\n", path);
|
---|
80 | handle = dlopen (path, RTLD_LAZY);
|
---|
81 | if (!handle)
|
---|
82 | exit (1);
|
---|
83 | dl_iterate_phdr (callback, (void *)(intptr_t) ADD);
|
---|
84 | return handle;
|
---|
85 | }
|
---|
86 |
|
---|
87 | static void
|
---|
88 | unload (const char *path, void *handle)
|
---|
89 | {
|
---|
90 | printf ("unloading `%s'\n", path);
|
---|
91 | if (dlclose (handle) < 0)
|
---|
92 | exit (2);
|
---|
93 | dl_iterate_phdr (callback, (void *)(intptr_t) REMOVE);
|
---|
94 | }
|
---|
95 |
|
---|
96 | int
|
---|
97 | main (int argc, char **argv)
|
---|
98 | {
|
---|
99 | void *handle1, *handle2;
|
---|
100 |
|
---|
101 | dl_iterate_phdr (callback, (void *)(intptr_t) SET);
|
---|
102 | handle1 = load ("firstobj.so");
|
---|
103 | handle2 = load ("globalmod1.so");
|
---|
104 | unload ("firstobj.so", handle1);
|
---|
105 | unload ("globalmod1.so", handle2);
|
---|
106 | return 0;
|
---|
107 | }
|
---|