1/* Update data structures for changes. 2 Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Ulrich Drepper <drepper@redhat.com>, 2000. 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#ifdef HAVE_CONFIG_H 31# include <config.h> 32#endif 33 34#include <assert.h> 35#include <libelf.h> 36#include <stdbool.h> 37#include <string.h> 38 39#include "libelfP.h" 40#include "elf-knowledge.h" 41 42#ifndef LIBELFBITS 43# define LIBELFBITS 32 44#endif 45 46/* Some fields contain 32/64 sizes. We cannot use Elf32/64_Word for those, 47 since those are both 32bits. Elf32/64_Xword is always 64bits. */ 48#define Elf32_SizeWord Elf32_Word 49#define Elf64_SizeWord Elf64_Xword 50 51 52static int 53ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr, 54 size_t shnum, int *change_bop) 55{ 56 /* Always write the magic bytes. */ 57 if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) 58 { 59 memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); 60 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 61 } 62 63 /* Always set the file class. */ 64 update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS), 65 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 66 67 /* Set the data encoding if necessary. */ 68 if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE)) 69 { 70 ehdr->e_ident[EI_DATA] = 71 BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB; 72 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 73 } 74 else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM)) 75 { 76 __libelf_seterrno (ELF_E_DATA_ENCODING); 77 return 1; 78 } 79 else 80 *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN 81 && ehdr->e_ident[EI_DATA] != ELFDATA2LSB) 82 || (BYTE_ORDER == BIG_ENDIAN 83 && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)); 84 85 /* Unconditionally overwrite the ELF version. */ 86 update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT, 87 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 88 89 if (unlikely (ehdr->e_version == EV_NONE)) 90 { 91 ehdr->e_version = EV_CURRENT; 92 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 93 } 94 else if (unlikely (ehdr->e_version != EV_CURRENT)) 95 { 96 __libelf_seterrno (ELF_E_UNKNOWN_VERSION); 97 return 1; 98 } 99 100 if (unlikely (shnum >= SHN_LORESERVE)) 101 { 102 update_if_changed (ehdr->e_shnum, 0, 103 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 104 } 105 else 106 update_if_changed (ehdr->e_shnum, shnum, 107 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 108 109 if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1))) 110 { 111 ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); 112 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 113 } 114 115 /* If phnum is zero make sure e_phoff is also zero and not some random 116 value. That would cause trouble in update_file. */ 117 if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0) 118 { 119 ehdr->e_phoff = 0; 120 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 121 } 122 123 return 0; 124} 125 126 127int64_t 128internal_function 129__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) 130{ 131 ElfW2(LIBELFBITS,Ehdr) *ehdr; 132 int changed = 0; 133 int ehdr_flags = 0; 134 135 ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf); 136 137 /* Set the default values. */ 138 if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0) 139 return -1; 140 141 /* At least the ELF header is there. */ 142 ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); 143 144 /* Set the program header position. */ 145 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) 146 (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf); 147 if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) 148 { 149 size_t phnum; 150 if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) 151 return -1; 152 153 if (elf->flags & ELF_F_LAYOUT) 154 { 155 /* The user is supposed to fill out e_phoff. Use it and 156 e_phnum to determine the maximum extend. */ 157 size = MAX (size, 158 ehdr->e_phoff 159 + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum)); 160 } 161 else 162 { 163 update_if_changed (ehdr->e_phoff, 164 elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), 165 ehdr_flags); 166 167 /* We need no alignment here. */ 168 size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum); 169 } 170 } 171 172 if (shnum > 0) 173 { 174 struct Elf_Scn *scn1 = NULL; 175 Elf_ScnList *list; 176 bool first = true; 177 178 assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0); 179 180 if (shnum >= SHN_LORESERVE) 181 { 182 /* We have to fill in the number of sections in the header 183 of the zeroth section. */ 184 Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; 185 186 update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size, 187 shnum, scn0->shdr_flags); 188 } 189 190 /* Go over all sections and find out how large they are. */ 191 list = &elf->state.ELFW(elf,LIBELFBITS).scns; 192 193 /* Find the first section. */ 194 if (list->cnt > 1) 195 scn1 = &list->data[1]; 196 else if (list->next != NULL) 197 scn1 = &list->next->data[0]; 198 199 /* Load the section headers if necessary. This loads the 200 headers for all sections. */ 201 if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL) 202 (void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1); 203 204 do 205 { 206 for (size_t cnt = first == true; cnt < list->cnt; ++cnt) 207 { 208 Elf_Scn *scn = &list->data[cnt]; 209 ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); 210 int64_t offset = 0; 211 212 assert (shdr != NULL); 213 ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize; 214 ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1; 215 if (unlikely (! powerof2 (sh_align))) 216 { 217 __libelf_seterrno (ELF_E_INVALID_ALIGN); 218 return -1; 219 } 220 221 /* Set the sh_entsize value if we can reliably detect it. */ 222 switch (shdr->sh_type) 223 { 224 case SHT_SYMTAB: 225 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); 226 break; 227 case SHT_RELA: 228 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1); 229 break; 230 case SHT_GROUP: 231 /* Only relocatable files can contain section groups. */ 232 if (ehdr->e_type != ET_REL) 233 { 234 __libelf_seterrno (ELF_E_GROUP_NOT_REL); 235 return -1; 236 } 237 FALLTHROUGH; 238 case SHT_SYMTAB_SHNDX: 239 sh_entsize = elf_typesize (32, ELF_T_WORD, 1); 240 break; 241 case SHT_HASH: 242 sh_entsize = SH_ENTSIZE_HASH (ehdr); 243 break; 244 case SHT_DYNAMIC: 245 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1); 246 break; 247 case SHT_REL: 248 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1); 249 break; 250 case SHT_DYNSYM: 251 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); 252 break; 253 case SHT_SUNW_move: 254 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1); 255 break; 256 case SHT_SUNW_syminfo: 257 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); 258 break; 259 default: 260 break; 261 } 262 263 /* If the section header contained the wrong entry size 264 correct it and mark the header as modified. */ 265 update_if_changed (shdr->sh_entsize, sh_entsize, 266 scn->shdr_flags); 267 268 /* Likewise for the alignment of a compressed section. 269 For a SHF_COMPRESSED section set the correct 270 sh_addralign value, which must match the d_align of 271 the data (see __libelf_set_rawdata in elf_getdata.c). */ 272 if ((shdr->sh_flags & SHF_COMPRESSED) != 0) 273 { 274 sh_align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS), 275 ELF_T_CHDR); 276 update_if_changed (shdr->sh_addralign, sh_align, 277 scn->shdr_flags); 278 } 279 280 if (scn->data_read == 0 281 && __libelf_set_rawdata_wrlock (scn) != 0) 282 /* Something went wrong. The error value is already set. */ 283 return -1; 284 285 /* Iterate over all data blocks. */ 286 if (list->data[cnt].data_list_rear != NULL) 287 { 288 Elf_Data_List *dl = &scn->data_list; 289 290 while (dl != NULL) 291 { 292 Elf_Data *data = &dl->data.d; 293 if (dl == &scn->data_list && data->d_buf == NULL 294 && scn->rawdata.d.d_buf != NULL) 295 data = &scn->rawdata.d; 296 297 if (unlikely (data->d_version != EV_CURRENT)) 298 { 299 __libelf_seterrno (ELF_E_UNKNOWN_VERSION); 300 return -1; 301 } 302 303 if (unlikely (! powerof2 (data->d_align))) 304 { 305 __libelf_seterrno (ELF_E_INVALID_ALIGN); 306 return -1; 307 } 308 309 sh_align = MAX (sh_align, data->d_align); 310 311 if (elf->flags & ELF_F_LAYOUT) 312 { 313 /* The user specified the offset and the size. 314 All we have to do is check whether this block 315 fits in the size specified for the section. */ 316 if (unlikely ((ElfW2(LIBELFBITS,SizeWord)) 317 (data->d_off + data->d_size) 318 > shdr->sh_size)) 319 { 320 __libelf_seterrno (ELF_E_SECTION_TOO_SMALL); 321 return -1; 322 } 323 } 324 else 325 { 326 /* Determine the padding. */ 327 offset = ((offset + data->d_align - 1) 328 & ~(data->d_align - 1)); 329 330 update_if_changed (data->d_off, offset, changed); 331 332 offset += data->d_size; 333 } 334 335 /* Next data block. */ 336 dl = dl->next; 337 } 338 } 339 else 340 /* Get the size of the section from the raw data. If 341 none is available the value is zero. */ 342 offset += scn->rawdata.d.d_size; 343 344 if (elf->flags & ELF_F_LAYOUT) 345 { 346 size = MAX (size, 347 (shdr->sh_type != SHT_NOBITS 348 ? shdr->sh_offset + shdr->sh_size : 0)); 349 350 /* The alignment must be a power of two. This is a 351 requirement from the ELF specification. Additionally 352 we test for the alignment of the section being large 353 enough for the largest alignment required by a data 354 block. */ 355 if (unlikely (! powerof2 (shdr->sh_addralign)) 356 || unlikely ((shdr->sh_addralign ?: 1) < sh_align)) 357 { 358 __libelf_seterrno (ELF_E_INVALID_ALIGN); 359 return -1; 360 } 361 } 362 else 363 { 364 /* How much alignment do we need for this section. */ 365 update_if_changed (shdr->sh_addralign, sh_align, 366 scn->shdr_flags); 367 368 size = (size + sh_align - 1) & ~(sh_align - 1); 369 int offset_changed = 0; 370 update_if_changed (shdr->sh_offset, size, offset_changed); 371 changed |= offset_changed; 372 373 if (offset_changed && scn->data_list_rear == NULL) 374 { 375 /* The position of the section in the file 376 changed. Create the section data list. */ 377 if (__elf_getdata_rdlock (scn, NULL) == NULL) 378 return -1; 379 } 380 381 /* See whether the section size is correct. */ 382 int size_changed = 0; 383 update_if_changed (shdr->sh_size, 384 (ElfW2(LIBELFBITS,SizeWord)) offset, 385 size_changed); 386 changed |= size_changed; 387 388 if (shdr->sh_type != SHT_NOBITS) 389 size += offset; 390 391 scn->shdr_flags |= (offset_changed | size_changed); 392 scn->flags |= changed; 393 } 394 395 /* Check that the section size is actually a multiple of 396 the entry size. */ 397 if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1 398 && (elf->flags & ELF_F_PERMISSIVE) == 0) 399 { 400 /* For compressed sections check the uncompressed size. */ 401 ElfW2(LIBELFBITS,SizeWord) sh_size; 402 if ((shdr->sh_flags & SHF_COMPRESSED) == 0) 403 sh_size = shdr->sh_size; 404 else 405 { 406 ElfW2(LIBELFBITS,Chdr) *chdr; 407 chdr = elfw2(LIBELFBITS,getchdr) (scn); 408 if (unlikely (chdr == NULL)) 409 return -1; 410 sh_size = chdr->ch_size; 411 } 412 413 if (unlikely (sh_size % shdr->sh_entsize != 0)) 414 { 415 __libelf_seterrno (ELF_E_INVALID_SHENTSIZE); 416 return -1; 417 } 418 } 419 } 420 421 assert (list->next == NULL || list->cnt == list->max); 422 423 first = false; 424 } 425 while ((list = list->next) != NULL); 426 427 /* Store section information. */ 428 update_if_changed (ehdr->e_shentsize, 429 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags); 430 if (elf->flags & ELF_F_LAYOUT) 431 { 432 /* The user is supposed to fill out e_shoff. Use it and 433 e_shnum (or sh_size of the dummy, first section header) 434 to determine the maximum extend. */ 435 size = MAX (size, 436 (ehdr->e_shoff 437 + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum)))); 438 } 439 else 440 { 441 /* Align for section header table. 442 443 Yes, we use `sizeof' and not `__alignof__' since we do not 444 want to be surprised by architectures with less strict 445 alignment rules. */ 446#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off)) 447 size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1); 448 449 update_if_changed (ehdr->e_shoff, size, elf->flags); 450 451 /* Account for the section header size. */ 452 size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum); 453 } 454 } 455 456 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags; 457 458 return size; 459} 460