1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
29
30 #include "libelf.h"
31 #include "decl.h"
32 #include "msg.h"
33
34
35 Elf_Data *
elf_newdata(Elf_Scn * s)36 elf_newdata(Elf_Scn * s)
37 {
38 Dnode * d;
39 Elf_Data * rc;
40 Elf * elf;
41 unsigned work;
42
43 if (s == 0)
44 return (0);
45 elf = s->s_elf;
46 READLOCKS(elf, s)
47 if (s->s_index == SHN_UNDEF) {
48 _elf_seterr(EREQ_SCNNULL, 0);
49 READUNLOCKS(elf, s)
50 return (0);
51 }
52
53 if ((s->s_myflags & SF_READY) == 0) {
54 UPGRADELOCKS(elf, s)
55 /*
56 * re-confirm that another 'thread' hasn't come along
57 * and cooked this section while the locks were
58 * obtained.
59 */
60 if ((s->s_myflags & SF_READY) == 0)
61 (void) _elf_cookscn(s);
62 DOWNGRADELOCKS(elf, s)
63 }
64
65 /*
66 * If this is the first new node, use the one allocated
67 * in the scn itself. Update data buffer in both cases.
68 */
69 ELFACCESSDATA(work, _elf_work)
70 if (s->s_hdnode == 0) {
71 s->s_dnode.db_uflags |= ELF_F_DIRTY;
72 s->s_dnode.db_myflags |= DBF_READY;
73 s->s_hdnode = &s->s_dnode;
74 s->s_tlnode = &s->s_dnode;
75 s->s_dnode.db_scn = s;
76 s->s_dnode.db_data.d_version = work;
77 rc = &s->s_dnode.db_data;
78 READUNLOCKS(elf, s)
79 return (rc);
80 }
81 if ((d = _elf_dnode()) == 0) {
82 READUNLOCKS(elf, s)
83 return (0);
84 }
85 d->db_data.d_version = work;
86 d->db_scn = s;
87 d->db_uflags |= ELF_F_DIRTY;
88 d->db_myflags |= DBF_READY;
89 s->s_tlnode->db_next = d;
90 s->s_tlnode = d;
91 rc = &d->db_data;
92 READUNLOCKS(elf, s)
93 return (rc);
94 }
95