~ubuntu-branches/ubuntu/precise/eglibc/precise

« back to all changes in this revision

Viewing changes to debian/patches/any/cvs-reloc-sort.diff

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-10-04 17:48:26 UTC
  • mfrom: (216.1.23 oneiric)
  • Revision ID: package-import@ubuntu.com-20111004174826-2cyb9ewn3ucymlsx
Tags: 2.13-20ubuntu5
libc6-dev: Don't break the current {gnat,gcj}-4.4-base versons. LP: #853688.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
2012-01-27  Ulrich Drepper  <drepper@gmail.com>
2
 
 
3
 
        [BZ #13618]
4
 
        * elf/dl-open.c (dl_open_worker): Sort objects by dependency before
5
 
        relocation.
6
 
 
7
 
diff --git a/elf/dl-open.c b/elf/dl-open.c
8
 
index a0b5c50..a56bdc1 100644
9
 
--- a/elf/dl-open.c
10
 
+++ b/elf/dl-open.c
11
 
@@ -302,45 +302,109 @@ dl_open_worker (void *a)
12
 
   if (GLRO(dl_lazy))
13
 
     reloc_mode |= mode & RTLD_LAZY;
14
 
 
15
 
-  /* Relocate the objects loaded.  We do this in reverse order so that copy
16
 
-     relocs of earlier objects overwrite the data written by later objects.  */
17
 
-
18
 
+  /* Sort the objects by dependency for the relocation process.  This
19
 
+     allows IFUNC relocations to work and it also means copy
20
 
+     relocation of dependencies are if necessary overwritten.  */
21
 
+  size_t nmaps = 0;
22
 
   struct link_map *l = new;
23
 
-  while (l->l_next)
24
 
-    l = l->l_next;
25
 
-  while (1)
26
 
+  do
27
 
+    {
28
 
+      if (! l->l_real->l_relocated)
29
 
+       ++nmaps;
30
 
+      l = l->l_next;
31
 
+    }
32
 
+  while (l != NULL);
33
 
+  struct link_map *maps[nmaps];
34
 
+  nmaps = 0;
35
 
+  l = new;
36
 
+  do
37
 
     {
38
 
       if (! l->l_real->l_relocated)
39
 
+       maps[nmaps++] = l;
40
 
+      l = l->l_next;
41
 
+    }
42
 
+  while (l != NULL);
43
 
+  if (nmaps > 1)
44
 
+    {
45
 
+      char seen[nmaps];
46
 
+      memset (seen, '\0', nmaps);
47
 
+      size_t i = 0;
48
 
+      while (1)
49
 
        {
50
 
-#ifdef SHARED
51
 
-         if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
52
 
+         ++seen[i];
53
 
+         struct link_map *thisp = maps[i];
54
 
+
55
 
+         /* Find the last object in the list for which the current one is
56
 
+            a dependency and move the current object behind the object
57
 
+            with the dependency.  */
58
 
+         size_t k = nmaps - 1;
59
 
+         while (k > i)
60
 
            {
61
 
-             /* If this here is the shared object which we want to profile
62
 
-                make sure the profile is started.  We can find out whether
63
 
-                this is necessary or not by observing the `_dl_profile_map'
64
 
-                variable.  If was NULL but is not NULL afterwars we must
65
 
-                start the profiling.  */
66
 
-             struct link_map *old_profile_map = GL(dl_profile_map);
67
 
+             struct link_map **runp = maps[k]->l_initfini;
68
 
+             if (runp != NULL)
69
 
+               /* Look through the dependencies of the object.  */
70
 
+               while (*runp != NULL)
71
 
+                 if (__builtin_expect (*runp++ == thisp, 0))
72
 
+                   {
73
 
+                     /* Move the current object to the back past the last
74
 
+                        object with it as the dependency.  */
75
 
+                     memmove (&maps[i], &maps[i + 1],
76
 
+                              (k - i) * sizeof (maps[0]));
77
 
+                     maps[k] = thisp;
78
 
+
79
 
+                     if (seen[i + 1] > 1)
80
 
+                       {
81
 
+                         ++i;
82
 
+                         goto next_clear;
83
 
+                       }
84
 
+
85
 
+                     char this_seen = seen[i];
86
 
+                     memmove (&seen[i], &seen[i + 1],
87
 
+                              (k - i) * sizeof (seen[0]));
88
 
+                     seen[k] = this_seen;
89
 
+
90
 
+                     goto next;
91
 
+                   }
92
 
+
93
 
+             --k;
94
 
+           }
95
 
 
96
 
-             _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
97
 
+         if (++i == nmaps)
98
 
+           break;
99
 
+       next_clear:
100
 
+         memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0]));
101
 
+       next:;
102
 
+       }
103
 
+    }
104
 
 
105
 
-             if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
106
 
-               {
107
 
-                 /* We must prepare the profiling.  */
108
 
-                 _dl_start_profile ();
109
 
+  for (size_t i = nmaps; i-- > 0; )
110
 
+    {
111
 
+      l = maps[i];
112
 
 
113
 
-                 /* Prevent unloading the object.  */
114
 
-                 GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
115
 
-               }
116
 
+#ifdef SHARED
117
 
+      if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
118
 
+       {
119
 
+         /* If this here is the shared object which we want to profile
120
 
+            make sure the profile is started.  We can find out whether
121
 
+            this is necessary or not by observing the `_dl_profile_map'
122
 
+            variable.  If it was NULL but is not NULL afterwars we must
123
 
+            start the profiling.  */
124
 
+         struct link_map *old_profile_map = GL(dl_profile_map);
125
 
+
126
 
+         _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
127
 
+
128
 
+         if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
129
 
+           {
130
 
+             /* We must prepare the profiling.  */
131
 
+             _dl_start_profile ();
132
 
+
133
 
+             /* Prevent unloading the object.  */
134
 
+             GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
135
 
            }
136
 
-         else
137
 
-#endif
138
 
-           _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
139
 
        }
140
 
-
141
 
-      if (l == new)
142
 
-       break;
143
 
-      l = l->l_prev;
144
 
+      else
145
 
+#endif
146
 
+       _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
147
 
     }
148
 
 
149
 
   /* If the file is not loaded now as a dependency, add the search