xref: /titanic_41/usr/src/cmd/sgs/libelf/common/update.c (revision 864221ad7169608e293fbeaa9df563afc9f345a0)
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 (c) 1988 AT&T
24  *	  All Rights Reserved
25  *
26  *
27  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #if !defined(_ELF64)
34 #pragma weak elf_update = _elf_update
35 #endif
36 
37 #include "syn.h"
38 #include <memory.h>
39 #include <malloc.h>
40 #include <limits.h>
41 
42 #include <sgs.h>
43 #include "decl.h"
44 #include "msg.h"
45 
46 /*
47  * This module is compiled twice, the second time having
48  * -D_ELF64 defined.  The following set of macros, along
49  * with machelf.h, represent the differences between the
50  * two compilations.  Be careful *not* to add any class-
51  * dependent code (anything that has elf32 or elf64 in the
52  * name) to this code without hiding it behind a switch-
53  * able macro like these.
54  */
55 #if	defined(_ELF64)
56 
57 #define	FSZ_LONG	ELF64_FSZ_XWORD
58 #define	ELFCLASS	ELFCLASS64
59 #define	_elf_snode_init	_elf64_snode_init
60 #define	_elfxx_cookscn	_elf64_cookscn
61 #define	_elf_upd_lib	_elf64_upd_lib
62 #define	elf_fsize	elf64_fsize
63 #define	_elf_entsz	_elf64_entsz
64 #define	_elf_msize	_elf64_msize
65 #define	_elf_upd_usr	_elf64_upd_usr
66 #define	wrt		wrt64
67 #define	elf_xlatetof	elf64_xlatetof
68 #define	_elfxx_update	_elf64_update
69 #define	_elfxx_swap_wrimage	_elf64_swap_wrimage
70 
71 #else	/* ELF32 */
72 
73 #define	FSZ_LONG	ELF32_FSZ_WORD
74 #define	ELFCLASS	ELFCLASS32
75 #define	_elf_snode_init	_elf32_snode_init
76 #define	_elfxx_cookscn	_elf32_cookscn
77 #define	_elf_upd_lib	_elf32_upd_lib
78 #define	elf_fsize	elf32_fsize
79 #define	_elf_entsz	_elf32_entsz
80 #define	_elf_msize	_elf32_msize
81 #define	_elf_upd_usr	_elf32_upd_usr
82 #define	wrt		wrt32
83 #define	elf_xlatetof	elf32_xlatetof
84 #define	_elfxx_update	_elf32_update
85 #define	_elfxx_swap_wrimage	_elf32_swap_wrimage
86 
87 #endif /* ELF64 */
88 
89 
90 /*
91  * Output file update
92  *	These functions walk an Elf structure, update its information,
93  *	and optionally write the output file.  Because the application
94  *	may control of the output file layout, two upd_... routines
95  *	exist.  They're similar but too different to merge cleanly.
96  *
97  *	The library defines a "dirty" bit to force parts of the file
98  *	to be written on update.  These routines ignore the dirty bit
99  *	and do everything.  A minimal update routine might be useful
100  *	someday.
101  */
102 
103 static size_t
104 _elf_upd_lib(Elf * elf)
105 {
106 	NOTE(ASSUMING_PROTECTED(*elf))
107 	Lword		hi;
108 	Lword		hibit;
109 	Elf_Scn *	s;
110 	register Xword	sz;
111 	Ehdr *		eh = elf->ed_ehdr;
112 	unsigned	ver = eh->e_version;
113 	register char	*p = (char *)eh->e_ident;
114 	size_t		scncnt;
115 
116 	/*
117 	 * Ehdr and Phdr table go first
118 	 */
119 	p[EI_MAG0] = ELFMAG0;
120 	p[EI_MAG1] = ELFMAG1;
121 	p[EI_MAG2] = ELFMAG2;
122 	p[EI_MAG3] = ELFMAG3;
123 	p[EI_CLASS] = ELFCLASS;
124 	/* LINTED */
125 	p[EI_VERSION] = (Byte)ver;
126 	hi = elf_fsize(ELF_T_EHDR, 1, ver);
127 	/* LINTED */
128 	eh->e_ehsize = (Half)hi;
129 	if (eh->e_phnum != 0) {
130 		/* LINTED */
131 		eh->e_phentsize = (Half)elf_fsize(ELF_T_PHDR, 1, ver);
132 		/* LINTED */
133 		eh->e_phoff = (Off)hi;
134 		hi += eh->e_phentsize * eh->e_phnum;
135 	} else {
136 		eh->e_phoff = 0;
137 		eh->e_phentsize = 0;
138 	}
139 
140 	/*
141 	 * Obtain the first section header.  Typically, this section has NULL
142 	 * contents, however in the case of Extended ELF Sections this section
143 	 * is used to hold an alternative e_shnum, e_shstrndx and e_phnum.
144 	 * On initial allocation (see _elf_snode) the elements of this section
145 	 * would have been zeroed.  The e_shnum is initialized later, after the
146 	 * section header count has been determined.  The e_shstrndx and
147 	 * e_phnum may have already been initialized by the caller (for example,
148 	 * gelf_update_shdr() in mcs(1)).
149 	 */
150 	if ((s = elf->ed_hdscn) == 0) {
151 		eh->e_shnum = 0;
152 		scncnt = 0;
153 	} else {
154 		s = s->s_next;
155 		scncnt = 1;
156 	}
157 
158 	/*
159 	 * Loop through sections.  Compute section size before changing hi.
160 	 * Allow null buffers for NOBITS.
161 	 */
162 	hibit = 0;
163 	for (; s != 0; s = s->s_next) {
164 		register Dnode	*d;
165 		register Lword	fsz, j;
166 		Shdr *sh = s->s_shdr;
167 
168 		scncnt++;
169 		if (sh->sh_type == SHT_NULL) {
170 			*sh = _elf_snode_init.sb_shdr;
171 			continue;
172 		}
173 
174 		if ((s->s_myflags & SF_READY) == 0)
175 			(void) _elfxx_cookscn(s);
176 
177 		sh->sh_addralign = 1;
178 		if ((sz = (Xword)_elf_entsz(elf, sh->sh_type, ver)) != 0)
179 			/* LINTED */
180 			sh->sh_entsize = (Half)sz;
181 		sz = 0;
182 		for (d = s->s_hdnode; d != 0; d = d->db_next) {
183 			if ((fsz = elf_fsize(d->db_data.d_type,
184 			    1, ver)) == 0)
185 				return (0);
186 
187 			j = _elf_msize(d->db_data.d_type, ver);
188 			fsz *= (d->db_data.d_size / j);
189 			d->db_osz = (size_t)fsz;
190 			if ((j = d->db_data.d_align) > 1) {
191 				if (j > sh->sh_addralign)
192 					sh->sh_addralign = (Xword)j;
193 
194 				if (sz % j != 0)
195 					sz += j - sz % j;
196 			}
197 			d->db_data.d_off = (off_t)sz;
198 			d->db_xoff = sz;
199 			sz += (Xword)fsz;
200 		}
201 
202 		sh->sh_size = sz;
203 		/*
204 		 * We want to take into account the offsets for NOBITS
205 		 * sections and let the "sh_offsets" point to where
206 		 * the section would 'conceptually' fit within
207 		 * the file (as required by the ABI).
208 		 *
209 		 * But - we must also make sure that the NOBITS does
210 		 * not take up any actual space in the file.  We preserve
211 		 * the actual offset into the file in the 'hibit' variable.
212 		 * When we come to the first non-NOBITS section after a
213 		 * encountering a NOBITS section the hi counter is restored
214 		 * to its proper place in the file.
215 		 */
216 		if (sh->sh_type == SHT_NOBITS) {
217 			if (hibit == 0)
218 				hibit = hi;
219 		} else {
220 			if (hibit) {
221 				hi = hibit;
222 				hibit = 0;
223 			}
224 		}
225 		j = sh->sh_addralign;
226 		if ((fsz = hi % j) != 0)
227 			hi += j - fsz;
228 
229 		/* LINTED */
230 		sh->sh_offset = (Off)hi;
231 		hi += sz;
232 	}
233 
234 	/*
235 	 * if last section was a 'NOBITS' section then we need to
236 	 * restore the 'hi' counter to point to the end of the last
237 	 * non 'NOBITS' section.
238 	 */
239 	if (hibit) {
240 		hi = hibit;
241 		hibit = 0;
242 	}
243 
244 	/*
245 	 * Shdr table last
246 	 */
247 	if (scncnt != 0) {
248 		if (hi % FSZ_LONG != 0)
249 			hi += FSZ_LONG - hi % FSZ_LONG;
250 		/* LINTED */
251 		eh->e_shoff = (Off)hi;
252 		/*
253 		 * If we are using 'extended sections' then the
254 		 * e_shnum is stored in the sh_size field of the
255 		 * first section header.
256 		 *
257 		 * NOTE: we set e_shnum to '0' because it's specified
258 		 * this way in the gABI, and in the hopes that
259 		 * this will cause less problems to unaware
260 		 * tools then if we'd set it to SHN_XINDEX (0xffff).
261 		 */
262 		if (scncnt < SHN_LORESERVE)
263 			eh->e_shnum = scncnt;
264 		else {
265 			Shdr	*sh;
266 			sh = (Shdr *)elf->ed_hdscn->s_shdr;
267 			sh->sh_size = scncnt;
268 			eh->e_shnum = 0;
269 		}
270 		/* LINTED */
271 		eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver);
272 		hi += eh->e_shentsize * scncnt;
273 	} else {
274 		eh->e_shoff = 0;
275 		eh->e_shentsize = 0;
276 	}
277 
278 #if	!(defined(_LP64) && defined(_ELF64))
279 	if (hi > INT_MAX) {
280 		_elf_seterr(EFMT_FBIG, 0);
281 		return (0);
282 	}
283 #endif
284 
285 	return ((size_t)hi);
286 }
287 
288 
289 
290 static size_t
291 _elf_upd_usr(Elf * elf)
292 {
293 	NOTE(ASSUMING_PROTECTED(*elf))
294 	Lword		hi;
295 	Elf_Scn *	s;
296 	register Xword	sz;
297 	Ehdr *		eh = elf->ed_ehdr;
298 	unsigned	ver = eh->e_version;
299 	register char	*p = (char *)eh->e_ident;
300 
301 
302 	/*
303 	 * Ehdr and Phdr table go first
304 	 */
305 	p[EI_MAG0] = ELFMAG0;
306 	p[EI_MAG1] = ELFMAG1;
307 	p[EI_MAG2] = ELFMAG2;
308 	p[EI_MAG3] = ELFMAG3;
309 	p[EI_CLASS] = ELFCLASS;
310 	/* LINTED */
311 	p[EI_VERSION] = (Byte)ver;
312 	hi = elf_fsize(ELF_T_EHDR, 1, ver);
313 	/* LINTED */
314 	eh->e_ehsize = (Half)hi;
315 
316 	/*
317 	 * If phnum is zero, phoff "should" be zero too,
318 	 * but the application is responsible for it.
319 	 * Allow a non-zero value here and update the
320 	 * hi water mark accordingly.
321 	 */
322 
323 	if (eh->e_phnum != 0)
324 		/* LINTED */
325 		eh->e_phentsize = (Half)elf_fsize(ELF_T_PHDR, 1, ver);
326 	else
327 		eh->e_phentsize = 0;
328 	if ((sz = eh->e_phoff + eh->e_phentsize * eh->e_phnum) > hi)
329 		hi = sz;
330 
331 	/*
332 	 * Loop through sections, skipping index zero.
333 	 * Compute section size before changing hi.
334 	 * Allow null buffers for NOBITS.
335 	 */
336 
337 	if ((s = elf->ed_hdscn) == 0)
338 		eh->e_shnum = 0;
339 	else {
340 		eh->e_shnum = 1;
341 		*(Shdr*)s->s_shdr = _elf_snode_init.sb_shdr;
342 		s = s->s_next;
343 	}
344 	for (; s != 0; s = s->s_next) {
345 		register Dnode	*d;
346 		register Xword	fsz, j;
347 		Shdr *sh = s->s_shdr;
348 
349 		if ((s->s_myflags & SF_READY) == 0)
350 			(void) _elfxx_cookscn(s);
351 
352 		++eh->e_shnum;
353 		sz = 0;
354 		for (d = s->s_hdnode; d != 0; d = d->db_next) {
355 			if ((fsz = (Xword)elf_fsize(d->db_data.d_type, 1,
356 			    ver)) == 0)
357 				return (0);
358 			j = (Xword)_elf_msize(d->db_data.d_type, ver);
359 			fsz *= (Xword)(d->db_data.d_size / j);
360 			d->db_osz = (size_t)fsz;
361 
362 			if ((sh->sh_type != SHT_NOBITS) &&
363 			    ((j = (Xword)(d->db_data.d_off + d->db_osz)) > sz))
364 				sz = j;
365 		}
366 		if (sh->sh_size < sz) {
367 			_elf_seterr(EFMT_SCNSZ, 0);
368 			return (0);
369 		}
370 		if ((sh->sh_type != SHT_NOBITS) &&
371 		    (hi < sh->sh_offset + sh->sh_size))
372 			hi = sh->sh_offset + sh->sh_size;
373 	}
374 
375 	/*
376 	 * Shdr table last.  Comment above for phnum/phoff applies here.
377 	 */
378 	if (eh->e_shnum != 0)
379 		/* LINTED */
380 		eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver);
381 	else
382 		eh->e_shentsize = 0;
383 
384 	if ((sz = eh->e_shoff + eh->e_shentsize * eh->e_shnum) > hi)
385 		hi = sz;
386 
387 #if	!(defined(_LP64) && defined(_ELF64))
388 	if (hi > INT_MAX) {
389 		_elf_seterr(EFMT_FBIG, 0);
390 		return (0);
391 	}
392 #endif
393 
394 	return ((size_t)hi);
395 }
396 
397 
398 static size_t
399 wrt(Elf * elf, Xword outsz, unsigned fill, int update_cmd)
400 {
401 	NOTE(ASSUMING_PROTECTED(*elf))
402 	Elf_Data	dst, src;
403 	unsigned	flag;
404 	Xword		hi, sz;
405 	char		*image;
406 	Elf_Scn		*s;
407 	Ehdr		*eh = elf->ed_ehdr;
408 	unsigned	ver = eh->e_version;
409 	unsigned	encode;
410 	int		byte;
411 
412 	/*
413 	 * If this is an ELF_C_WRIMAGE write, then we encode into the
414 	 * byte order of the system we are running on rather than that of
415 	 * of the object. For ld.so.1, this is the same order, but
416 	 * for 'ld', it might not be in the case where we are cross
417 	 * linking an object for a different target. In this later case,
418 	 * the linker-host byte order is necessary so that the linker can
419 	 * manipulate the resulting  image. It is expected that the linker
420 	 * will call elf_swap_wrimage() if necessary to convert the image
421 	 * to the target byte order.
422 	 */
423 	encode = (update_cmd == ELF_C_WRIMAGE) ? _elf_sys_encoding() :
424 	    eh->e_ident[EI_DATA];
425 
426 	/*
427 	 * Two issues can cause trouble for the output file.
428 	 * First, begin() with ELF_C_RDWR opens a file for both
429 	 * read and write.  On the write update(), the library
430 	 * has to read everything it needs before truncating
431 	 * the file.  Second, using mmap for both read and write
432 	 * is too tricky.  Consequently, the library disables mmap
433 	 * on the read side.  Using mmap for the output saves swap
434 	 * space, because that mapping is SHARED, not PRIVATE.
435 	 *
436 	 * If the file is write-only, there can be nothing of
437 	 * interest to bother with.
438 	 *
439 	 * The following reads the entire file, which might be
440 	 * more than necessary.  Better safe than sorry.
441 	 */
442 
443 	if ((elf->ed_myflags & EDF_READ) &&
444 	    (_elf_vm(elf, (size_t)0, elf->ed_fsz) != OK_YES))
445 		return (0);
446 
447 	flag = elf->ed_myflags & EDF_WRALLOC;
448 	if ((image = _elf_outmap(elf->ed_fd, outsz, &flag)) == 0)
449 		return (0);
450 
451 	if (flag == 0)
452 		elf->ed_myflags |= EDF_IMALLOC;
453 
454 	/*
455 	 * If an error occurs below, a "dirty" bit may be cleared
456 	 * improperly.  To save a second pass through the file,
457 	 * this code sets the dirty bit on the elf descriptor
458 	 * when an error happens, assuming that will "cover" any
459 	 * accidents.
460 	 */
461 
462 	/*
463 	 * Hi is needed only when 'fill' is non-zero.
464 	 * Fill is non-zero only when the library
465 	 * calculates file/section/data buffer offsets.
466 	 * The lib guarantees they increase monotonically.
467 	 * That guarantees proper filling below.
468 	 */
469 
470 
471 	/*
472 	 * Ehdr first
473 	 */
474 
475 	src.d_buf = (Elf_Void *)eh;
476 	src.d_type = ELF_T_EHDR;
477 	src.d_size = sizeof (Ehdr);
478 	src.d_version = EV_CURRENT;
479 	dst.d_buf = (Elf_Void *)image;
480 	dst.d_size = eh->e_ehsize;
481 	dst.d_version = ver;
482 	if (elf_xlatetof(&dst, &src, encode) == 0)
483 		return (0);
484 	elf->ed_ehflags &= ~ELF_F_DIRTY;
485 	hi = eh->e_ehsize;
486 
487 	/*
488 	 * Phdr table if one exists
489 	 */
490 
491 	if (eh->e_phnum != 0) {
492 		unsigned	work;
493 		/*
494 		 * Unlike other library data, phdr table is
495 		 * in the user version.  Change src buffer
496 		 * version here, fix it after translation.
497 		 */
498 
499 		src.d_buf = (Elf_Void *)elf->ed_phdr;
500 		src.d_type = ELF_T_PHDR;
501 		src.d_size = elf->ed_phdrsz;
502 		ELFACCESSDATA(work, _elf_work)
503 		src.d_version = work;
504 		dst.d_buf = (Elf_Void *)(image + eh->e_phoff);
505 		dst.d_size = eh->e_phnum * eh->e_phentsize;
506 		hi = (Xword)(eh->e_phoff + dst.d_size);
507 		if (elf_xlatetof(&dst, &src, encode) == 0) {
508 			elf->ed_uflags |= ELF_F_DIRTY;
509 			return (0);
510 		}
511 		elf->ed_phflags &= ~ELF_F_DIRTY;
512 		src.d_version = EV_CURRENT;
513 	}
514 
515 	/*
516 	 * Loop through sections
517 	 */
518 
519 	ELFACCESSDATA(byte, _elf_byte);
520 	for (s = elf->ed_hdscn; s != 0; s = s->s_next) {
521 		register Dnode	*d, *prevd;
522 		Xword		off = 0;
523 		Shdr		*sh = s->s_shdr;
524 		char		*start = image + sh->sh_offset;
525 		char		*here;
526 
527 		/*
528 		 * Just "clean" DIRTY flag for "empty" sections.  Even if
529 		 * NOBITS needs padding, the next thing in the
530 		 * file will provide it.  (And if this NOBITS is
531 		 * the last thing in the file, no padding needed.)
532 		 */
533 		if ((sh->sh_type == SHT_NOBITS) ||
534 		    (sh->sh_type == SHT_NULL)) {
535 			d = s->s_hdnode, prevd = 0;
536 			for (; d != 0; prevd = d, d = d->db_next)
537 				d->db_uflags &= ~ELF_F_DIRTY;
538 			continue;
539 		}
540 		/*
541 		 * Clear out the memory between the end of the last
542 		 * section and the begining of this section.
543 		 */
544 		if (fill && (sh->sh_offset > hi)) {
545 			sz = sh->sh_offset - hi;
546 			(void) memset(start - sz, byte, sz);
547 		}
548 
549 
550 		for (d = s->s_hdnode, prevd = 0;
551 		    d != 0; prevd = d, d = d->db_next) {
552 			d->db_uflags &= ~ELF_F_DIRTY;
553 			here = start + d->db_data.d_off;
554 
555 			/*
556 			 * Clear out the memory between the end of the
557 			 * last update and the start of this data buffer.
558 			 */
559 			if (fill && (d->db_data.d_off > off)) {
560 				sz = (Xword)(d->db_data.d_off - off);
561 				(void) memset(here - sz, byte, sz);
562 			}
563 
564 			if ((d->db_myflags & DBF_READY) == 0) {
565 				SCNLOCK(s);
566 				if (_elf_locked_getdata(s, &prevd->db_data) !=
567 				    &d->db_data) {
568 					elf->ed_uflags |= ELF_F_DIRTY;
569 					SCNUNLOCK(s);
570 					return (0);
571 				}
572 				SCNUNLOCK(s);
573 			}
574 			dst.d_buf = (Elf_Void *)here;
575 			dst.d_size = d->db_osz;
576 
577 			/*
578 			 * Copy the translated bits out to the destination
579 			 * image.
580 			 */
581 			if (elf_xlatetof(&dst, &d->db_data, encode) == 0) {
582 				elf->ed_uflags |= ELF_F_DIRTY;
583 				return (0);
584 			}
585 
586 			off = (Xword)(d->db_data.d_off + dst.d_size);
587 		}
588 		hi = sh->sh_offset + sh->sh_size;
589 	}
590 
591 	/*
592 	 * Shdr table last
593 	 */
594 
595 	if (fill && (eh->e_shoff > hi)) {
596 		sz = eh->e_shoff - hi;
597 		(void) memset(image + hi, byte, sz);
598 	}
599 
600 	src.d_type = ELF_T_SHDR;
601 	src.d_size = sizeof (Shdr);
602 	dst.d_buf = (Elf_Void *)(image + eh->e_shoff);
603 	dst.d_size = eh->e_shentsize;
604 	for (s = elf->ed_hdscn; s != 0; s = s->s_next) {
605 		assert((uintptr_t)dst.d_buf < ((uintptr_t)image + outsz));
606 		s->s_shflags &= ~ELF_F_DIRTY;
607 		s->s_uflags &= ~ELF_F_DIRTY;
608 		src.d_buf = s->s_shdr;
609 
610 		if (elf_xlatetof(&dst, &src, encode) == 0) {
611 			elf->ed_uflags |= ELF_F_DIRTY;
612 			return (0);
613 		}
614 
615 		dst.d_buf = (char *)dst.d_buf + eh->e_shentsize;
616 	}
617 	/*
618 	 * ELF_C_WRIMAGE signifyes that we build the memory image, but
619 	 * that we do not actually write it to disk.  This is used
620 	 * by ld(1) to build up a full image of an elf file and then
621 	 * to process the file before it's actually written out to
622 	 * disk.  This saves ld(1) the overhead of having to write
623 	 * the image out to disk twice.
624 	 */
625 	if (update_cmd == ELF_C_WRIMAGE) {
626 		elf->ed_uflags &= ~ELF_F_DIRTY;
627 		elf->ed_wrimage = image;
628 		elf->ed_wrimagesz = outsz;
629 		return (outsz);
630 	}
631 
632 	if (_elf_outsync(elf->ed_fd, image, outsz,
633 	    ((elf->ed_myflags & EDF_IMALLOC) ? 0 : 1)) != 0) {
634 		elf->ed_uflags &= ~ELF_F_DIRTY;
635 		elf->ed_myflags &= ~EDF_IMALLOC;
636 		return (outsz);
637 	}
638 
639 	elf->ed_uflags |= ELF_F_DIRTY;
640 	return (0);
641 }
642 
643 
644 
645 
646 /*
647  * The following is a private interface between the linkers (ld & ld.so.1)
648  * and libelf:
649  *
650  * elf_update(elf, ELF_C_WRIMAGE)
651  *	This will cause full image representing the elf file
652  *	described by the elf pointer to be built in memory.  If the
653  *	elf pointer has a valid file descriptor associated with it
654  *	we will attempt to build the memory image from mmap()'ed
655  *	storage.  If the elf descriptor does not have a valid
656  *	file descriptor (opened with elf_begin(0, ELF_C_IMAGE, 0))
657  *	then the image will be allocated from dynamic memory (malloc()).
658  *
659  *	elf_update() will return the size of the memory image built
660  *	when sucessful.
661  *
662  *	When a subsequent call to elf_update() with ELF_C_WRITE as
663  *	the command is performed it will sync the image created
664  *	by ELF_C_WRIMAGE to disk (if fd available) and
665  *	free the memory allocated.
666  */
667 
668 off_t
669 _elfxx_update(Elf * elf, Elf_Cmd cmd)
670 {
671 	size_t		sz;
672 	unsigned	u;
673 	Ehdr		*eh = elf->ed_ehdr;
674 
675 	if (elf == 0)
676 		return (-1);
677 
678 	ELFWLOCK(elf)
679 	switch (cmd) {
680 	default:
681 		_elf_seterr(EREQ_UPDATE, 0);
682 		ELFUNLOCK(elf)
683 		return (-1);
684 
685 	case ELF_C_WRIMAGE:
686 		if ((elf->ed_myflags & EDF_WRITE) == 0) {
687 			_elf_seterr(EREQ_UPDWRT, 0);
688 			ELFUNLOCK(elf)
689 			return (-1);
690 		}
691 		break;
692 	case ELF_C_WRITE:
693 		if ((elf->ed_myflags & EDF_WRITE) == 0) {
694 			_elf_seterr(EREQ_UPDWRT, 0);
695 			ELFUNLOCK(elf)
696 			return (-1);
697 		}
698 		if (elf->ed_wrimage) {
699 			if (elf->ed_myflags & EDF_WRALLOC) {
700 				free(elf->ed_wrimage);
701 				/*
702 				 * The size is still returned even
703 				 * though nothing is actually written
704 				 * out.  This is just to be consistant
705 				 * with the rest of the interface.
706 				 */
707 				sz = elf->ed_wrimagesz;
708 				elf->ed_wrimage = 0;
709 				elf->ed_wrimagesz = 0;
710 				ELFUNLOCK(elf);
711 				return ((off_t)sz);
712 			}
713 			sz = _elf_outsync(elf->ed_fd, elf->ed_wrimage,
714 			    elf->ed_wrimagesz,
715 			    (elf->ed_myflags & EDF_IMALLOC ? 0 : 1));
716 			elf->ed_myflags &= ~EDF_IMALLOC;
717 			elf->ed_wrimage = 0;
718 			elf->ed_wrimagesz = 0;
719 			ELFUNLOCK(elf);
720 			return ((off_t)sz);
721 		}
722 		/* FALLTHROUGH */
723 	case ELF_C_NULL:
724 		break;
725 	}
726 
727 	if (eh == 0) {
728 		_elf_seterr(ESEQ_EHDR, 0);
729 		ELFUNLOCK(elf)
730 		return (-1);
731 	}
732 
733 	if ((u = eh->e_version) > EV_CURRENT) {
734 		_elf_seterr(EREQ_VER, 0);
735 		ELFUNLOCK(elf)
736 		return (-1);
737 	}
738 
739 	if (u == EV_NONE)
740 		eh->e_version = EV_CURRENT;
741 
742 	if ((u = eh->e_ident[EI_DATA]) == ELFDATANONE) {
743 		unsigned	encode;
744 
745 		ELFACCESSDATA(encode, _elf_encode)
746 		if (encode == ELFDATANONE) {
747 			_elf_seterr(EREQ_ENCODE, 0);
748 			ELFUNLOCK(elf)
749 			return (-1);
750 		}
751 		/* LINTED */
752 		eh->e_ident[EI_DATA] = (Byte)encode;
753 	}
754 
755 	u = 1;
756 	if (elf->ed_uflags & ELF_F_LAYOUT) {
757 		sz = _elf_upd_usr(elf);
758 		u = 0;
759 	} else
760 		sz = _elf_upd_lib(elf);
761 
762 	if ((sz != 0) && ((cmd == ELF_C_WRITE) || (cmd == ELF_C_WRIMAGE)))
763 		sz = wrt(elf, (Xword)sz, u, cmd);
764 
765 	if (sz == 0) {
766 		ELFUNLOCK(elf)
767 		return (-1);
768 	}
769 
770 	ELFUNLOCK(elf)
771 	return ((off_t)sz);
772 }
773 
774 
775 /*
776  * When wrt() processes an ELF_C_WRIMAGE request, the resulting image
777  * gets the byte order (encoding) of the platform running the linker
778  * rather than that of the target host. This allows the linker to modify
779  * the image, prior to flushing it to the output file. This routine
780  * is used to re-translate such an image into the byte order of the
781  * target host.
782  */
783 int
784 _elfxx_swap_wrimage(Elf * elf)
785 {
786 	NOTE(ASSUMING_PROTECTED(*elf))
787 	Elf_Data	dst, src;
788 	Elf_Scn		*s;
789 	Ehdr		*eh = elf->ed_ehdr;
790 	Half		e_phnum = eh->e_phnum;
791 	unsigned	ver = eh->e_version;
792 	unsigned	encode = eh->e_ident[EI_DATA];
793 
794 	/*
795 	 * Ehdr first
796 	 */
797 
798 	src.d_buf = dst.d_buf = (Elf_Void *)eh;
799 	src.d_type = dst.d_type = ELF_T_EHDR;
800 	src.d_size = dst.d_size = sizeof (Ehdr);
801 	src.d_version = dst.d_version = ver;
802 	if (elf_xlatetof(&dst, &src, encode) == 0)
803 		return (1);
804 
805 	/*
806 	 * Phdr table if one exists
807 	 */
808 
809 	if (e_phnum != 0) {
810 		unsigned	work;
811 		/*
812 		 * Unlike other library data, phdr table is
813 		 * in the user version.
814 		 */
815 
816 		src.d_buf = dst.d_buf = (Elf_Void *)elf->ed_phdr;
817 		src.d_type = dst.d_type = ELF_T_PHDR;
818 		src.d_size = dst.d_size = elf->ed_phdrsz;
819 		ELFACCESSDATA(work, _elf_work)
820 		src.d_version = dst.d_version = work;
821 		if (elf_xlatetof(&dst, &src, encode) == 0) {
822 			return (1);
823 		}
824 	}
825 
826 	/*
827 	 * Loop through sections
828 	 */
829 
830 	for (s = elf->ed_hdscn; s != 0; s = s->s_next) {
831 		register Dnode	*d, *prevd;
832 		Shdr		*sh = s->s_shdr;
833 
834 		if ((sh->sh_type == SHT_NOBITS) || (sh->sh_type == SHT_NULL))
835 			continue;
836 
837 		for (d = s->s_hdnode, prevd = 0;
838 		    d != 0; prevd = d, d = d->db_next) {
839 
840 			if ((d->db_myflags & DBF_READY) == 0) {
841 				SCNLOCK(s);
842 				if (_elf_locked_getdata(s, &prevd->db_data) !=
843 				    &d->db_data) {
844 					SCNUNLOCK(s);
845 					return (1);
846 				}
847 				SCNUNLOCK(s);
848 			}
849 
850 			dst = d->db_data;
851 			if (elf_xlatetof(&dst, &d->db_data, encode) == 0)
852 				return (1);
853 		}
854 	}
855 
856 	/*
857 	 * Shdr table
858 	 */
859 
860 	src.d_type = dst.d_type = ELF_T_SHDR;
861 	src.d_version = dst.d_version = ver;
862 	for (s = elf->ed_hdscn; s != 0; s = s->s_next) {
863 		src.d_buf = dst.d_buf = s->s_shdr;
864 		src.d_size = dst.d_size = sizeof (Shdr);
865 		if (elf_xlatetof(&dst, &src, encode) == 0)
866 			return (1);
867 	}
868 
869 	return (0);
870 }
871 
872 
873 
874 #ifndef _ELF64
875 /* class-independent, only needs to be compiled once */
876 
877 off_t
878 elf_update(Elf *elf, Elf_Cmd cmd)
879 {
880 	if (elf == 0)
881 		return (-1);
882 
883 	if (elf->ed_class == ELFCLASS32)
884 		return (_elf32_update(elf, cmd));
885 	else if (elf->ed_class == ELFCLASS64) {
886 		return (_elf64_update(elf, cmd));
887 	}
888 
889 	_elf_seterr(EREQ_CLASS, 0);
890 	return (-1);
891 }
892 
893 int
894 _elf_swap_wrimage(Elf *elf)
895 {
896 	if (elf == 0)
897 		return (0);
898 
899 	if (elf->ed_class == ELFCLASS32)
900 		return (_elf32_swap_wrimage(elf));
901 
902 	if (elf->ed_class == ELFCLASS64)
903 		return (_elf64_swap_wrimage(elf));
904 
905 	_elf_seterr(EREQ_CLASS, 0);
906 	return (0);
907 }
908 
909 /*
910  * 4106312, 4106398, This is an ad-hoc means for the 32-bit
911  * Elf64 version of libld.so.3 to get around the limitation
912  * of a 32-bit d_off field.  This is only intended to be
913  * used by libld to relocate symbols in large NOBITS sections.
914  */
915 Elf64_Off
916 _elf_getxoff(Elf_Data * d)
917 {
918 	return (((Dnode *)d)->db_xoff);
919 }
920 #endif /* !_ELF64 */
921