resetting manifest requested domain to floor
[platform/upstream/libelf0.git] / lib / x.remscn.c
1 /*
2 x.remscn.c - implementation of the elfx_remscn(3) function.
3 Copyright (C) 1995 - 2001, 2003 Michael Riepe
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include <private.h>
21
22 #ifndef lint
23 static const char rcsid[] = "@(#) $Id: x.remscn.c,v 1.15 2008/05/23 08:15:35 michael Exp $";
24 #endif /* lint */
25
26 size_t
27 elfx_remscn(Elf *elf, Elf_Scn *scn) {
28     Elf_Scn *pscn;
29     Scn_Data *sd;
30     Scn_Data *tmp;
31     size_t index;
32
33     if (!elf || !scn) {
34         return SHN_UNDEF;
35     }
36     elf_assert(elf->e_magic == ELF_MAGIC);
37     if (elf->e_kind != ELF_K_ELF) {
38         seterr(ERROR_NOTELF);
39         return SHN_UNDEF;
40     }
41     elf_assert(scn->s_magic == SCN_MAGIC);
42     elf_assert(elf->e_ehdr);
43     if (scn->s_elf != elf) {
44         seterr(ERROR_ELFSCNMISMATCH);
45         return SHN_UNDEF;
46     }
47     elf_assert(elf->e_scn_1);
48     if (scn == elf->e_scn_1) {
49         seterr(ERROR_NULLSCN);
50         return SHN_UNDEF;
51     }
52
53     /*
54      * Find previous section.
55      */
56     for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
57         if (pscn->s_link == scn) {
58             break;
59         }
60     }
61     if (pscn->s_link != scn) {
62         seterr(ERROR_ELFSCNMISMATCH);
63         return SHN_UNDEF;
64     }
65
66     /*
67      * Unlink section.
68      */
69     if (elf->e_scn_n == scn) {
70         elf->e_scn_n = pscn;
71     }
72     pscn->s_link = scn->s_link;
73     index = scn->s_index;
74
75     /*
76      * Free section descriptor and data.
77      */
78     for (sd = scn->s_data_1; sd; sd = tmp) {
79         elf_assert(sd->sd_magic == DATA_MAGIC);
80         elf_assert(sd->sd_scn == scn);
81         tmp = sd->sd_link;
82         if (sd->sd_free_data && sd->sd_memdata) {
83             free(sd->sd_memdata);
84         }
85         if (sd->sd_freeme) {
86             free(sd);
87         }
88     }
89     if ((sd = scn->s_rawdata)) {
90         elf_assert(sd->sd_magic == DATA_MAGIC);
91         elf_assert(sd->sd_scn == scn);
92         if (sd->sd_free_data && sd->sd_memdata) {
93             free(sd->sd_memdata);
94         }
95         if (sd->sd_freeme) {
96             free(sd);
97         }
98     }
99     if (scn->s_freeme) {
100         elf_assert(scn->s_index > 0);
101         free(scn);
102     }
103
104     /*
105      * Adjust section indices.
106      */
107     for (scn = pscn->s_link; scn; scn = scn->s_link) {
108         elf_assert(scn->s_index > index);
109         scn->s_index--;
110     }
111
112     /*
113      * Adjust section count in ELF header
114      */
115     if (_elf_update_shnum(elf, elf->e_scn_n->s_index + 1)) {
116         return SHN_UNDEF;
117     }
118     return index;
119 }