• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Create new, empty section data.
2    Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
3    Contributed by Ulrich Drepper <drepper@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 *
elf_newdata(Elf_Scn * scn)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