Branch data 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 : 532 : 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 : 532 : assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
36 : :
37 [ + + ]: 1171 : while (len >= sizeof (Elf32_Nhdr))
38 : : {
39 : : /* Convert the header. */
40 : 651 : (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
41 : : encode);
42 [ + + ]: 651 : const Elf32_Nhdr *n = encode ? src : dest;
43 : :
44 : 651 : size_t note_len = sizeof *n;
45 : :
46 : : /* desc needs to be aligned. */
47 : 651 : note_len += n->n_namesz;
48 [ + + ]: 651 : note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len);
49 [ + + ]: 651 : 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 : 639 : note_len += n->n_descsz;
60 [ + + ]: 639 : note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len);
61 [ - + ]: 639 : 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 : 639 : size_t note_data_len = note_len - sizeof *n;
72 : 639 : src += sizeof *n;
73 : 639 : dest += sizeof *n;
74 [ + + ]: 639 : if (src != dest)
75 : 637 : memcpy (dest, src, note_data_len);
76 : :
77 : 639 : src += note_data_len;
78 : 639 : dest += note_data_len;
79 : 639 : len -= note_len;
80 : : }
81 : :
82 : : /* Copy over any leftover data unconverted. Probably part of
83 : : truncated name/desc data. */
84 [ - + - - ]: 532 : if (unlikely (len > 0) && src != dest)
85 : 0 : memcpy (dest, src, len);
86 : 532 : }
87 : :
88 : : static void
89 : 530 : elf_cvt_note4 (void *dest, const void *src, size_t len, int encode)
90 : : {
91 : 530 : elf_cvt_note (dest, src, len, encode, false);
92 : 530 : }
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 : }
|