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