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