elf_newscn.c revision b08d5a8fb42f4586d756068065186b5af7e48da
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Append new section. 2b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 3b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 1998. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper This program is free software; you can redistribute it and/or modify 6b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper it under the terms of the GNU General Public License as published by 7b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the Free Software Foundation, version 2. 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper This program is distributed in the hope that it will be useful, 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper but WITHOUT ANY WARRANTY; without even the implied warranty of 11b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GNU General Public License for more details. 13b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 14b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper You should have received a copy of the GNU General Public License 15b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper along with this program; if not, write to the Free Software Foundation, 16b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libelfP.h" 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElf_Scn * 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperelf_newscn (elf) 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf; 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *result = NULL; 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool first = false; 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We rely on the prefix of the `elf', `elf32', and `elf64' element 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper being the same. */ 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (offsetof (Elf, state.elf.scns_last) 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == offsetof (Elf, state.elf32.scns_last)); 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (offsetof (Elf, state.elf.scns_last) 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == offsetof (Elf, state.elf64.scns_last)); 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (offsetof (Elf, state.elf32.scns) 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == offsetof (Elf, state.elf64.scns)); 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper rwlock_wrlock (elf->lock); 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper again: 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max) 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt]; 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++elf->state.elf.scns_last->cnt == 1 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (elf->state.elf.scns_last 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == (elf->class == ELFCLASS32 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (offsetof (Elf, state.elf32.scns) 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == offsetof (Elf, state.elf64.scns)) 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ? &elf->state.elf32.scns : &elf->state.elf64.scns))) 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is zeroth section. */ 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper first = true; 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (elf->state.elf.scns_last->cnt > 1); 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->index = result[-1].index + 1; 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We must allocate a new element. */ 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_ScnList *newp; 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (elf->state.elf.scnincr > 0); 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList) 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + ((elf->state.elf.scnincr *= 2) 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * sizeof (Elf_Scn)), 1); 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (newp == NULL) 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_NOMEM); 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = &newp->data[0]; 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* One section used. */ 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++newp->cnt; 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is the number of sections we allocated. */ 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->max = elf->state.elf.scnincr; 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Remember the index for the first section in this block. */ 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->data[0].index 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index; 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Enqueue the new list element. */ 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp; 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create a section header for this section. */ 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf->class == ELFCLASS32) 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr)); 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result->shdr.e32 == NULL) 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_NOMEM); 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr)); 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result->shdr.e64 == NULL) 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_NOMEM); 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->elf = elf; 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->list = elf->state.elf.scns_last; 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the data part. */ 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->data_read = 1; 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (first)) 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For the first section we mark the data as already available. */ 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper //result->data_list_rear = &result->data_list; 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper first = false; 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto again; 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->flags |= ELF_F_DIRTY; 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper rwlock_unlock (elf->lock); 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 144