Branch data Line data Source code
1 : : /* Conversion functions for versioning information. 2 : : Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Written by Ulrich Drepper <drepper@redhat.com>, 1998. 5 : : 6 : : This file is free software; you can redistribute it and/or modify 7 : : it under the terms of either 8 : : 9 : : * the GNU Lesser General Public License as published by the Free 10 : : Software Foundation; either version 3 of the License, or (at 11 : : your option) any later version 12 : : 13 : : or 14 : : 15 : : * the GNU General Public License as published by the Free 16 : : Software Foundation; either version 2 of the License, or (at 17 : : your option) any later version 18 : : 19 : : or both in parallel, as here. 20 : : 21 : : elfutils is distributed in the hope that it will be useful, but 22 : : WITHOUT ANY WARRANTY; without even the implied warranty of 23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 : : General Public License for more details. 25 : : 26 : : You should have received copies of the GNU General Public License and 27 : : the GNU Lesser General Public License along with this program. If 28 : : not, see <http://www.gnu.org/licenses/>. */ 29 : : 30 : : #include <assert.h> 31 : : #include <gelf.h> 32 : : 33 : : #include "libelfP.h" 34 : : 35 : : 36 : : static void 37 : 11 : elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode) 38 : : { 39 : : /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. 40 : : To recognize them we have to walk the data structure and convert 41 : : them one after the other. The ENCODE parameter specifies whether 42 : : we are encoding or decoding. When we are encoding we can immediately 43 : : use the data in the buffer; if not, we have to decode the data before 44 : : using it. */ 45 : 11 : size_t def_offset = 0; 46 : 11 : GElf_Verdef *ddest; 47 : 11 : GElf_Verdef *dsrc; 48 : : 49 : : /* We rely on the types being all the same size. */ 50 : 11 : assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); 51 : 11 : assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); 52 : 11 : assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); 53 : 11 : assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); 54 : : 55 [ + - ]: 11 : if (len == 0) 56 : : return; 57 : : 58 : : /* Below we rely on the next field offsets to be correct, start by 59 : : copying over all data as is in case some data isn't translated. 60 : : We don't want to leave (undefined) garbage in the dest buffer. */ 61 : 11 : memmove (dest, src, len); 62 : : 63 : 22 : do 64 : : { 65 : 22 : size_t aux_offset; 66 : 22 : GElf_Verdaux *asrc; 67 : : 68 : : /* Test for correct offset. */ 69 [ + - + - ]: 22 : if (def_offset > len || len - def_offset < sizeof (GElf_Verdef)) 70 : : return; 71 : : 72 : : /* Work the tree from the first record. */ 73 : 22 : ddest = (GElf_Verdef *) ((char *) dest + def_offset); 74 : 22 : dsrc = (GElf_Verdef *) ((char *) src + def_offset); 75 : : 76 : : /* Decode first if necessary. */ 77 [ + + ]: 22 : if (! encode) 78 : : { 79 : 14 : ddest->vd_version = bswap_16 (dsrc->vd_version); 80 : 14 : ddest->vd_flags = bswap_16 (dsrc->vd_flags); 81 : 14 : ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); 82 : 14 : ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); 83 : 14 : ddest->vd_hash = bswap_32 (dsrc->vd_hash); 84 : 14 : ddest->vd_aux = bswap_32 (dsrc->vd_aux); 85 : 14 : ddest->vd_next = bswap_32 (dsrc->vd_next); 86 : : 87 : 14 : aux_offset = def_offset + ddest->vd_aux; 88 : : } 89 : : else 90 : 8 : aux_offset = def_offset + dsrc->vd_aux; 91 : : 92 : : /* Handle all the auxiliary records belonging to this definition. */ 93 : 22 : do 94 : : { 95 : 22 : GElf_Verdaux *adest; 96 : : 97 : : /* Test for correct offset. */ 98 [ + - + - ]: 22 : if (aux_offset > len || len - aux_offset < sizeof (GElf_Verdaux)) 99 : : return; 100 : : 101 : 22 : adest = (GElf_Verdaux *) ((char *) dest + aux_offset); 102 : 22 : asrc = (GElf_Verdaux *) ((char *) src + aux_offset); 103 : : 104 [ + + ]: 22 : if (encode) 105 : 8 : aux_offset += asrc->vda_next; 106 : : 107 [ + + ]: 22 : adest->vda_name = bswap_32 (asrc->vda_name); 108 : 22 : adest->vda_next = bswap_32 (asrc->vda_next); 109 : : 110 [ + + ]: 22 : if (! encode) 111 : 14 : aux_offset += adest->vda_next; 112 : : } 113 [ - + ]: 22 : while (asrc->vda_next != 0); 114 : : 115 : : /* Encode now if necessary. */ 116 [ + + ]: 22 : if (encode) 117 : : { 118 : 8 : def_offset += dsrc->vd_next; 119 : : 120 : 8 : ddest->vd_version = bswap_16 (dsrc->vd_version); 121 : 8 : ddest->vd_flags = bswap_16 (dsrc->vd_flags); 122 : 8 : ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); 123 : 8 : ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); 124 : 8 : ddest->vd_hash = bswap_32 (dsrc->vd_hash); 125 : 8 : ddest->vd_aux = bswap_32 (dsrc->vd_aux); 126 : 8 : ddest->vd_next = bswap_32 (dsrc->vd_next); 127 : : } 128 : : else 129 : 14 : def_offset += ddest->vd_next; 130 : : } 131 [ + + ]: 22 : while (dsrc->vd_next != 0); 132 : : } 133 : : 134 : : 135 : : static void 136 : 154 : elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode) 137 : : { 138 : : /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. 139 : : To recognize them we have to walk the data structure and convert 140 : : them one after the other. The ENCODE parameter specifies whether 141 : : we are encoding or decoding. When we are encoding we can immediately 142 : : use the data in the buffer; if not, we have to decode the data before 143 : : using it. */ 144 : 154 : size_t need_offset = 0; 145 : 154 : GElf_Verneed *ndest; 146 : 154 : GElf_Verneed *nsrc; 147 : : 148 : : /* We rely on the types being all the same size. */ 149 : 154 : assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); 150 : 154 : assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); 151 : 154 : assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); 152 : 154 : assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); 153 : : 154 [ + - ]: 154 : if (len == 0) 155 : : return; 156 : : 157 : : /* Below we rely on the next field offsets to be correct, start by 158 : : copying over all data as is in case some data isn't translated. 159 : : We don't want to leave (undefined) garbage in the dest buffer. */ 160 : 154 : memmove (dest, src, len); 161 : : 162 : 160 : do 163 : : { 164 : 160 : size_t aux_offset; 165 : 160 : GElf_Vernaux *asrc; 166 : : 167 : : /* Test for correct offset. */ 168 [ + - + - ]: 160 : if (need_offset > len || len - need_offset < sizeof (GElf_Verneed)) 169 : : return; 170 : : 171 : : /* Work the tree from the first record. */ 172 : 160 : ndest = (GElf_Verneed *) ((char *) dest + need_offset); 173 : 160 : nsrc = (GElf_Verneed *) ((char *) src + need_offset); 174 : : 175 : : /* Decode first if necessary. */ 176 [ + + ]: 160 : if (! encode) 177 : : { 178 : 117 : ndest->vn_version = bswap_16 (nsrc->vn_version); 179 : 117 : ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); 180 : 117 : ndest->vn_file = bswap_32 (nsrc->vn_file); 181 : 117 : ndest->vn_aux = bswap_32 (nsrc->vn_aux); 182 : 117 : ndest->vn_next = bswap_32 (nsrc->vn_next); 183 : : 184 : 117 : aux_offset = need_offset + ndest->vn_aux; 185 : : } 186 : : else 187 : 43 : aux_offset = need_offset + nsrc->vn_aux; 188 : : 189 : : /* Handle all the auxiliary records belonging to this requirement. */ 190 : 182 : do 191 : : { 192 : 182 : GElf_Vernaux *adest; 193 : : 194 : : /* Test for correct offset. */ 195 [ + - + - ]: 182 : if (aux_offset > len || len - aux_offset < sizeof (GElf_Vernaux)) 196 : : return; 197 : : 198 : 182 : adest = (GElf_Vernaux *) ((char *) dest + aux_offset); 199 : 182 : asrc = (GElf_Vernaux *) ((char *) src + aux_offset); 200 : : 201 [ + + ]: 182 : if (encode) 202 : 48 : aux_offset += asrc->vna_next; 203 : : 204 [ + + ]: 182 : adest->vna_hash = bswap_32 (asrc->vna_hash); 205 [ + + ]: 182 : adest->vna_flags = bswap_16 (asrc->vna_flags); 206 : 182 : adest->vna_other = bswap_16 (asrc->vna_other); 207 : 182 : adest->vna_name = bswap_32 (asrc->vna_name); 208 : 182 : adest->vna_next = bswap_32 (asrc->vna_next); 209 : : 210 [ + + ]: 182 : if (! encode) 211 : 134 : aux_offset += adest->vna_next; 212 : : } 213 [ + + ]: 182 : while (asrc->vna_next != 0); 214 : : 215 : : /* Encode now if necessary. */ 216 [ + + ]: 160 : if (encode) 217 : : { 218 : 43 : need_offset += nsrc->vn_next; 219 : : 220 : 43 : ndest->vn_version = bswap_16 (nsrc->vn_version); 221 : 43 : ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); 222 : 43 : ndest->vn_file = bswap_32 (nsrc->vn_file); 223 : 43 : ndest->vn_aux = bswap_32 (nsrc->vn_aux); 224 : 43 : ndest->vn_next = bswap_32 (nsrc->vn_next); 225 : : } 226 : : else 227 : 117 : need_offset += ndest->vn_next; 228 : : } 229 [ + + ]: 160 : while (nsrc->vn_next != 0); 230 : : }