]>
Commit | Line | Data |
---|---|---|
bb330e25 AF |
1 | # |
2 | # Based on this commit: | |
3 | # | |
4 | # commit 62058ce612ed3459501b4c4332e268edfe977f59 | |
5 | # Author: Carlos O'Donell <carlos@redhat.com> | |
6 | # Date: Mon Sep 29 13:14:21 2014 -0400 | |
7 | # | |
8 | # Correctly size profiling reloc table (bug 17411) | |
9 | # | |
10 | # During auditing or profiling modes the dynamic loader | |
11 | # builds a cache of the relocated PLT entries in order | |
12 | # to reuse them when called again through the same PLT | |
13 | # entry. This way the PLT entry is never completed and | |
14 | # the call into the resolver always results in profiling | |
15 | # or auditing code running. | |
16 | # | |
17 | # The problem is that the PLT relocation cache size | |
18 | # is not computed correctly. The size of the cache | |
19 | # should be "Size of a relocation result structure" | |
20 | # x "Number of PLT-related relocations". Instead the | |
21 | # code erroneously computes "Size of a relocation | |
22 | # result" x "Number of bytes worth of PLT-related | |
23 | # relocations". I can only assume this was a mistake | |
24 | # in the understanding of the value of DT_PLTRELSZ | |
25 | # which is the number of bytes of PLT-related relocs. | |
26 | # We do have a DT_RELACOUNT entry, which is a count | |
27 | # for dynamic relative relocs, but we have no | |
28 | # DT_PLTRELCOUNT and thus we need to compute it. | |
29 | # | |
30 | # This patch corrects the computation of the size of the | |
31 | # relocation table used by the glibc profiling code. | |
32 | # | |
33 | # For more details see: | |
34 | # https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html | |
35 | # | |
36 | # [BZ #17411] | |
37 | # * elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for | |
38 | # l_reloc_result. | |
39 | # | |
40 | diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c | |
41 | index d2c6dac..97a7119 100644 | |
42 | --- a/elf/dl-reloc.c | |
43 | +++ b/elf/dl-reloc.c | |
44 | @@ -279,8 +279,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], | |
45 | l->l_name); | |
46 | } | |
47 | ||
48 | - l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), | |
49 | - l->l_info[DT_PLTRELSZ]->d_un.d_val); | |
50 | + size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA | |
51 | + ? sizeof (ElfW(Rela)) | |
52 | + : sizeof (ElfW(Rel)); | |
53 | + size_t relcount = l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeofrel; | |
54 | + l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), relcount); | |
55 | + | |
56 | if (l->l_reloc_result == NULL) | |
57 | { | |
58 | errstring = N_("\ |