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