Line data Source code
1 : /* Conversion functions for notes.
2 : Copyright (C) 2007, 2009, 2014, 2018 Red Hat, Inc.
3 : This file is part of elfutils.
4 :
5 : This file is free software; you can redistribute it and/or modify
6 : it under the terms of either
7 :
8 : * the GNU Lesser General Public License as published by the Free
9 : Software Foundation; either version 3 of the License, or (at
10 : your option) any later version
11 :
12 : or
13 :
14 : * the GNU General Public License as published by the Free
15 : Software Foundation; either version 2 of the License, or (at
16 : your option) any later version
17 :
18 : or both in parallel, as here.
19 :
20 : elfutils is distributed in the hope that it will be useful, but
21 : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : General Public License for more details.
24 :
25 : You should have received copies of the GNU General Public License and
26 : the GNU Lesser General Public License along with this program. If
27 : not, see <http://www.gnu.org/licenses/>. */
28 :
29 : static void
30 443 : elf_cvt_note (void *dest, const void *src, size_t len, int encode,
31 : bool nhdr8)
32 : {
33 : /* Note that the header is always the same size, but the padding
34 : differs for GNU Property notes. */
35 443 : assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
36 :
37 1037 : while (len >= sizeof (Elf32_Nhdr))
38 : {
39 : /* Convert the header. */
40 606 : (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
41 : encode);
42 606 : const Elf32_Nhdr *n = encode ? src : dest;
43 :
44 606 : size_t note_len = sizeof *n;
45 :
46 : /* desc needs to be aligned. */
47 606 : note_len += n->n_namesz;
48 606 : note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len);
49 606 : if (note_len > len || note_len < sizeof *n)
50 : {
51 : /* Header was translated, nothing else. */
52 12 : len -= sizeof *n;
53 12 : src += sizeof *n;
54 12 : dest += sizeof *n;
55 12 : break;
56 : }
57 :
58 : /* data as a whole needs to be aligned. */
59 594 : note_len += n->n_descsz;
60 594 : note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len);
61 594 : if (note_len > len || note_len < sizeof *n)
62 : {
63 : /* Header was translated, nothing else. */
64 0 : len -= sizeof *n;
65 0 : src += sizeof *n;
66 0 : dest += sizeof *n;
67 0 : break;
68 : }
69 :
70 : /* Copy or skip the note data. */
71 594 : size_t note_data_len = note_len - sizeof *n;
72 594 : src += sizeof *n;
73 594 : dest += sizeof *n;
74 594 : if (src != dest)
75 592 : memcpy (dest, src, note_data_len);
76 :
77 594 : src += note_data_len;
78 594 : dest += note_data_len;
79 594 : len -= note_len;
80 : }
81 :
82 : /* Copy over any leftover data unconverted. Probably part of
83 : truncated name/desc data. */
84 443 : if (unlikely (len > 0) && src != dest)
85 0 : memcpy (dest, src, len);
86 443 : }
87 :
88 : static void
89 441 : elf_cvt_note4 (void *dest, const void *src, size_t len, int encode)
90 : {
91 441 : elf_cvt_note (dest, src, len, encode, false);
92 441 : }
93 :
94 : static void
95 2 : elf_cvt_note8 (void *dest, const void *src, size_t len, int encode)
96 : {
97 2 : elf_cvt_note (dest, src, len, encode, true);
98 2 : }
|