Branch data Line data Source code
1 : : /* Append new section. 2 : : Copyright (C) 1998,1999,2000,2001,2002,2005,2009,2014,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 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include <assert.h> 35 : : #include <stdbool.h> 36 : : #include <stddef.h> 37 : : #include <stdlib.h> 38 : : #include <string.h> 39 : : 40 : : #include "libelfP.h" 41 : : 42 : : 43 : : Elf_Scn * 44 : 1652275 : elf_newscn (Elf *elf) 45 : : { 46 : 1652275 : Elf_Scn *result = NULL; 47 : 1652275 : bool first = false; 48 : : 49 [ + - ]: 1652275 : if (elf == NULL) 50 : : return NULL; 51 : : 52 : : /* We rely on the prefix of the `elf', `elf32', and `elf64' element 53 : : being the same. */ 54 : : assert (offsetof (Elf, state.elf.scns_last) 55 : : == offsetof (Elf, state.elf32.scns_last)); 56 : : assert (offsetof (Elf, state.elf.scns_last) 57 : : == offsetof (Elf, state.elf64.scns_last)); 58 : : assert (offsetof (Elf, state.elf32.scns) 59 : : == offsetof (Elf, state.elf64.scns)); 60 : : 61 : 1652832 : rwlock_wrlock (elf->lock); 62 : : 63 : 1652832 : again: 64 [ + + ]: 1652832 : if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max) 65 : : { 66 : 1651853 : result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt]; 67 : : 68 [ + + ]: 1651853 : if (++elf->state.elf.scns_last->cnt == 1 69 : 557 : && (elf->state.elf.scns_last 70 : : == (elf->class == ELFCLASS32 71 : : || (offsetof (Elf, state.elf32.scns) 72 : : == offsetof (Elf, state.elf64.scns)) 73 [ - + ]: 557 : ? &elf->state.elf32.scns : &elf->state.elf64.scns))) 74 : : /* This is zeroth section. */ 75 : : first = true; 76 : : else 77 : : { 78 [ - + ]: 1651296 : assert (elf->state.elf.scns_last->cnt > 1); 79 : 1651296 : result->index = result[-1].index + 1; 80 : : } 81 : : } 82 : : else 83 : : { 84 : : /* We must allocate a new element. */ 85 : 979 : Elf_ScnList *newp = NULL; 86 : : 87 [ - + ]: 979 : assert (elf->state.elf.scnincr > 0); 88 : : 89 : 979 : if ( 90 : : #if SIZE_MAX <= 4294967295U 91 : : likely (elf->state.elf.scnincr 92 : : < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList)) 93 : : #else 94 : : 1 95 : : #endif 96 : : ) 97 : 979 : newp = calloc (sizeof (Elf_ScnList) 98 : 979 : + ((elf->state.elf.scnincr *= 2) 99 : 979 : * sizeof (Elf_Scn)), 1); 100 [ - + ]: 979 : if (newp == NULL) 101 : : { 102 : 0 : __libelf_seterrno (ELF_E_NOMEM); 103 : 0 : goto out; 104 : : } 105 : : 106 : 979 : result = &newp->data[0]; 107 : : 108 : : /* One section used. */ 109 : 979 : ++newp->cnt; 110 : : 111 : : /* This is the number of sections we allocated. */ 112 : 979 : newp->max = elf->state.elf.scnincr; 113 : : 114 : : /* Remember the index for the first section in this block. */ 115 : 979 : newp->data[0].index 116 : 979 : = 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index; 117 : : 118 : : /* Enqueue the new list element. */ 119 : 979 : elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp; 120 : : } 121 : : 122 : : /* Create a section header for this section. */ 123 [ + + ]: 1652832 : if (elf->class == ELFCLASS32) 124 : : { 125 : 1054741 : result->shdr.e32 = calloc (1, sizeof (Elf32_Shdr)); 126 [ - + ]: 1054741 : if (result->shdr.e32 == NULL) 127 : : { 128 : 0 : __libelf_seterrno (ELF_E_NOMEM); 129 : 0 : goto out; 130 : : } 131 : : } 132 : : else 133 : : { 134 : 598091 : result->shdr.e64 = calloc (1, sizeof (Elf64_Shdr)); 135 [ - + ]: 598091 : if (result->shdr.e64 == NULL) 136 : : { 137 : 0 : __libelf_seterrno (ELF_E_NOMEM); 138 : 0 : goto out; 139 : : } 140 : : } 141 : : 142 : 1652832 : result->elf = elf; 143 : 1652832 : result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; 144 : 1652832 : result->list = elf->state.elf.scns_last; 145 : : 146 : : /* Initialize the data part. */ 147 : 1652832 : result->data_read = 1; 148 [ + + ]: 1652832 : if (unlikely (first)) 149 : : { 150 : : /* For the first section we mark the data as already available. */ 151 : : //result->data_list_rear = &result->data_list; 152 : 557 : first = false; 153 : 557 : goto again; 154 : : } 155 : : 156 : 1652275 : result->flags |= ELF_F_DIRTY; 157 : : 158 : : out: 159 : : rwlock_unlock (elf->lock); 160 : : 161 : : return result; 162 : : }