Home | History | Annotate | Download | only in libelf
      1 /* Create new, empty section data.
      2    Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
      3    Contributed by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      4 
      5    This program is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation, version 2.
      8 
      9    This program is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12    GNU General Public License for more details.
     13 
     14    You should have received a copy of the GNU General Public License
     15    along with this program; if not, write to the Free Software Foundation,
     16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
     17 
     18 #ifdef HAVE_CONFIG_H
     19 # include <config.h>
     20 #endif
     21 
     22 #include <stddef.h>
     23 #include <stdlib.h>
     24 
     25 #include "libelfP.h"
     26 
     27 
     28 Elf_Data *
     29 elf_newdata (Elf_Scn *scn)
     30 {
     31   Elf_Data_List *result = NULL;
     32 
     33   if (scn == NULL)
     34     return NULL;
     35 
     36   if (unlikely (scn->index == 0))
     37     {
     38       /* It is not allowed to add something to the 0th section.  */
     39       __libelf_seterrno (ELF_E_NOT_NUL_SECTION);
     40       return NULL;
     41     }
     42 
     43   if (scn->elf->class == ELFCLASS32
     44       || (offsetof (struct Elf, state.elf32.ehdr)
     45 	  == offsetof (struct Elf, state.elf64.ehdr))
     46       ? scn->elf->state.elf32.ehdr == NULL
     47       : scn->elf->state.elf64.ehdr == NULL)
     48     {
     49       __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
     50       return NULL;
     51     }
     52 
     53   rwlock_wrlock (scn->elf->lock);
     54 
     55   if (scn->data_read && scn->data_list_rear == NULL)
     56     {
     57       /* This means the section was created by the user and this is the
     58 	 first data.  */
     59       result = &scn->data_list;
     60       result->flags = ELF_F_DIRTY;
     61     }
     62   else
     63     {
     64       /* Create a new, empty data descriptor.  */
     65       result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List));
     66       if (result == NULL)
     67 	{
     68 	  __libelf_seterrno (ELF_E_NOMEM);
     69 	  goto out;
     70 	}
     71 
     72       result->flags = ELF_F_DIRTY | ELF_F_MALLOCED;
     73 
     74       if (scn->data_list_rear == NULL)
     75 	/* We create new data without reading/converting the data from the
     76 	   file.  That is fine but we have to remember this.  */
     77 	scn->data_list_rear = &scn->data_list;
     78     }
     79 
     80   /* Set the predefined values.  */
     81   result->data.d.d_version = __libelf_version;
     82 
     83   result->data.s = scn;
     84 
     85   /* Add to the end of the list.  */
     86   if (scn->data_list_rear != NULL)
     87     scn->data_list_rear->next = result;
     88 
     89   scn->data_list_rear = result;
     90 
     91  out:
     92   rwlock_unlock (scn->elf->lock);
     93 
     94   /* Please note that the following is thread safe and is also defined
     95      for RESULT == NULL since it still return NULL.  */
     96   return &result->data.d;
     97 }
     98