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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 1988 AT&T
42 static const char armag
[] = ARMAG
;
46 * Initialize archive member
49 _elf_member(int fd
, Elf
* ref
, unsigned flags
)
55 if (ref
->ed_nextoff
>= ref
->ed_fsz
)
57 if (ref
->ed_fd
== -1) /* disabled */
59 if (flags
& EDF_WRITE
) {
60 _elf_seterr(EREQ_ARRDWR
, 0);
63 if (ref
->ed_fd
!= fd
) {
64 _elf_seterr(EREQ_ARMEMFD
, 0);
67 if ((_elf_vm(ref
, ref
->ed_nextoff
, sizeof (struct ar_hdr
)) !=
68 OK_YES
) || ((mh
= _elf_armem(ref
,
69 ref
->ed_ident
+ ref
->ed_nextoff
, ref
->ed_fsz
)) == 0))
72 base
= ref
->ed_nextoff
+ sizeof (struct ar_hdr
);
73 if (ref
->ed_fsz
- base
< mh
->m_hdr
.ar_size
) {
74 _elf_seterr(EFMT_ARMEMSZ
, 0);
77 if ((elf
= (Elf
*)calloc(1, sizeof (Elf
))) == 0) {
78 _elf_seterr(EMEM_ELF
, errno
);
84 elf
->ed_myflags
|= flags
;
86 elf
->ed_fsz
= mh
->m_hdr
.ar_size
;
87 elf
->ed_baseoff
= ref
->ed_baseoff
+ base
;
88 elf
->ed_memoff
= base
- mh
->m_slide
;
89 elf
->ed_siboff
= base
+ elf
->ed_fsz
+ (elf
->ed_fsz
& 1);
90 ref
->ed_nextoff
= elf
->ed_siboff
;
91 elf
->ed_image
= ref
->ed_image
;
92 elf
->ed_imagesz
= ref
->ed_imagesz
;
93 elf
->ed_vm
= ref
->ed_vm
;
94 elf
->ed_vmsz
= ref
->ed_vmsz
;
95 elf
->ed_ident
= ref
->ed_ident
+ base
- mh
->m_slide
;
98 * If this member is the archive string table,
99 * we've already altered the bytes.
102 if (ref
->ed_arstroff
== ref
->ed_nextoff
)
103 elf
->ed_status
= ES_COOKED
;
109 _elf_regular(int fd
, unsigned flags
) /* initialize regular file */
113 if ((elf
= (Elf
*)calloc(1, sizeof (Elf
))) == 0) {
114 _elf_seterr(EMEM_ELF
, errno
);
119 elf
->ed_myflags
|= flags
;
120 if (_elf_inmap(elf
) != OK_YES
) {
129 _elf_config(Elf
* elf
)
134 ELFRWLOCKINIT(&elf
->ed_rwlock
);
137 * Determine if this is a ELF file.
139 base
= elf
->ed_ident
;
140 if ((elf
->ed_fsz
>= EI_NIDENT
) &&
141 (_elf_vm(elf
, (size_t)0, (size_t)EI_NIDENT
) == OK_YES
) &&
142 (base
[EI_MAG0
] == ELFMAG0
) &&
143 (base
[EI_MAG1
] == ELFMAG1
) &&
144 (base
[EI_MAG2
] == ELFMAG2
) &&
145 (base
[EI_MAG3
] == ELFMAG3
)) {
146 elf
->ed_kind
= ELF_K_ELF
;
147 elf
->ed_class
= base
[EI_CLASS
];
148 elf
->ed_encode
= base
[EI_DATA
];
149 if ((elf
->ed_version
= base
[EI_VERSION
]) == 0)
151 elf
->ed_identsz
= EI_NIDENT
;
154 * Allow writing only if originally specified read only.
155 * This is only necessary if the file must be translating
156 * from one encoding to another.
158 ELFACCESSDATA(encode
, _elf_encode
)
159 if ((elf
->ed_vm
== 0) && ((elf
->ed_myflags
& EDF_WRITE
) == 0) &&
160 (elf
->ed_encode
!= encode
)) {
161 if (mprotect((char *)elf
->ed_image
, elf
->ed_imagesz
,
162 PROT_READ
|PROT_WRITE
) == -1) {
163 _elf_seterr(EIO_VM
, errno
);
171 * Determine if this is an Archive
173 if ((elf
->ed_fsz
>= SARMAG
) &&
174 (_elf_vm(elf
, (size_t)0, (size_t)SARMAG
) == OK_YES
) &&
175 (memcmp(base
, armag
, SARMAG
) == 0)) {
177 elf
->ed_kind
= ELF_K_AR
;
178 elf
->ed_identsz
= SARMAG
;
183 * Return a few ident bytes, but not so many that
184 * getident() must read a large file. 512 is arbitrary.
187 elf
->ed_kind
= ELF_K_NONE
;
188 if ((elf
->ed_identsz
= elf
->ed_fsz
) > 512)
189 elf
->ed_identsz
= 512;
195 elf_memory(char *image
, size_t sz
)
201 * version() no called yet?
203 ELFACCESSDATA(work
, _elf_work
)
204 if (work
== EV_NONE
) {
205 _elf_seterr(ESEQ_VER
, 0);
209 if ((elf
= (Elf
*)calloc(1, sizeof (Elf
))) == 0) {
210 _elf_seterr(EMEM_ELF
, errno
);
214 elf
->ed_myflags
|= EDF_READ
| EDF_MEMORY
;
215 elf
->ed_image
= elf
->ed_ident
= image
;
216 elf
->ed_imagesz
= elf
->ed_fsz
= elf
->ed_identsz
= sz
;
217 elf
->ed_kind
= ELF_K_ELF
;
218 elf
->ed_class
= image
[EI_CLASS
];
219 elf
->ed_encode
= image
[EI_DATA
];
220 if ((elf
->ed_version
= image
[EI_VERSION
]) == 0)
222 elf
->ed_identsz
= EI_NIDENT
;
224 elf
= _elf_config(elf
);
229 * The following is a private interface between the linkers (ld & ld.so.1)
232 * elf_begin(0, ELF_C_IMAGE, ref)
233 * Return a new elf_descriptor which uses the memory image from
234 * ref as the base image of the elf file. Before this elf_begin()
235 * is called an elf_update(ref, ELF_C_WRIMAGE) must have been
236 * done to the ref elf descriptor.
237 * The ELF_C_IMAGE is unique in that modificatino of the Elf structure
238 * is illegal (no elf_new*()) but you can modify the actual
239 * data image of the file in question.
241 * When you are done processing this file you can then perform a
244 * NOTE: if an elf_update(ref, ELF_C_WRITE) is done on the ref Elf
245 * descriptor then the memory image that the ELF_C_IMAGE
246 * is using has been discarded. The proper calling convention
247 * for this is as follows:
249 * elf1 = elf_begin(fd, ELF_C_WRITE, 0);
251 * elf_update(elf1, ELF_C_WRIMAGE); build memory image
252 * elf2 = elf_begin(0, ELF_C_IMAGE, elf1);
255 * elf_updage(elf1, ELF_C_WRITE); flush memory image to disk
259 * elf_begin(0, ELF_C_IMAGE, 0);
260 * returns a pointer to an elf descriptor as if it were opened
261 * with ELF_C_WRITE except that it has no file descriptor and it
262 * will not create a file. It's to be used with the command:
264 * elf_update(elf, ELF_C_WRIMAGE)
266 * which will build a memory image instead of a file image.
267 * The memory image is allocated via dynamic memory (malloc) and
268 * can be free with a subsequent call to
270 * elf_update(elf, ELF_C_WRITE)
272 * NOTE: that if elf_end(elf) is called it will not free the
273 * memory image if it is still allocated. It is then
274 * the callers responsiblity to free it via a call
277 * Here is a potential calling sequence for this interface:
279 * elf1 = elf_begin(0, ELF_C_IMAGE, 0);
281 * elf_update(elf1, ELF_C_WRIMAGE); build memory image
282 * elf2 = elf_begin(0, ELF_C_IMAGE, elf1);
284 * image_ptr = elf32_getehdr(elf2); get pointer to image
294 elf_begin(int fd
, Elf_Cmd cmd
, Elf
*ref
)
300 ELFACCESSDATA(work
, _elf_work
)
301 if (work
== EV_NONE
) /* version() not called yet */
303 _elf_seterr(ESEQ_VER
, 0);
308 _elf_seterr(EREQ_BEGIN
, 0);
319 if ((image
= ref
->ed_wrimage
) == 0) {
320 _elf_seterr(EREQ_NOWRIMAGE
, 0);
324 imagesz
= ref
->ed_wrimagesz
;
326 return (elf_memory(image
, imagesz
));
330 if ((elf
= (Elf
*)calloc(1, sizeof (Elf
))) == 0) {
331 _elf_seterr(EMEM_ELF
, errno
);
334 ELFRWLOCKINIT(&elf
->ed_rwlock
);
337 elf
->ed_myflags
|= EDF_WRITE
;
338 if (cmd
== ELF_C_IMAGE
)
339 elf
->ed_myflags
|= EDF_WRALLOC
;
342 flags
= EDF_WRITE
| EDF_READ
;
351 * A null ref asks for a new file
352 * Non-null ref bumps the activation count
353 * or gets next archive member
357 if ((elf
= _elf_regular(fd
, flags
)) == 0)
361 if ((ref
->ed_myflags
& flags
) != flags
) {
362 _elf_seterr(EREQ_RDWR
, 0);
369 if (ref
->ed_kind
!= ELF_K_AR
) {
374 if ((elf
= _elf_member(fd
, ref
, flags
)) == 0) {
382 elf
= _elf_config(elf
);