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