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