xref: /titanic_50/usr/src/cmd/sgs/librtld/common/dldump.c (revision ae115bc77f6fcde83175c75b4206dc2e50747966)
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 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * dldump(3c) creates a new file image from the specified input file.
27  */
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include	<sys/param.h>
31 #include	<sys/procfs.h>
32 #include	<fcntl.h>
33 #include	<stdio.h>
34 #include	<libelf.h>
35 #include	<link.h>
36 #include	<dlfcn.h>
37 #include	<stdlib.h>
38 #include	<string.h>
39 #include	<unistd.h>
40 #include	<errno.h>
41 #include	"libld.h"
42 #include	"msg.h"
43 #include	"_librtld.h"
44 
45 /*
46  * Generic clean up routine
47  */
48 static void
49 cleanup(Elf *ielf, Elf *oelf, Elf *melf, Cache *icache, Cache *mcache,
50     int fd, const char *opath)
51 {
52 	if (icache) {
53 		Cache *	_icache = icache;
54 
55 		for (++_icache; _icache->c_flags != FLG_C_END; _icache++) {
56 			if (_icache->c_info)
57 				(void) free(_icache->c_info);
58 		}
59 		(void) free((void *)icache);
60 	}
61 	if (mcache)
62 		(void) free((void *)mcache);
63 
64 	if (ielf)
65 		(void) elf_end(ielf);
66 	if (oelf)
67 		(void) elf_end(oelf);
68 	if (melf)
69 		(void) elf_end(melf);
70 	if (fd)
71 		(void) close(fd);
72 	if (opath)
73 		(void) unlink(opath);
74 }
75 
76 /*
77  * The dldump(3x) interface directs control to the runtime linker.  The runtime
78  * linker brings in librtld.so.1 to provide the underlying support for this
79  * call (this is because librtld.so.1 requires libelf.so.1, and the whole wad
80  * is rather expensive to drag around with ld.so.1).
81  *
82  * rt_dldump(Rt_map * lmp, const char * opath, int flags, Addr addr)
83  *
84  * lmp provides the link-map of the ipath (the input file).
85  *
86  * opath specifies the output file.
87  *
88  * flags provides a variety of options that control how the new image will be
89  * relocated (if required).
90  *
91  * addr indicates the base address at which the associated input image is mapped
92  * within the process.
93  *
94  * The modes of operation and the various flags provide a number of combinations
95  * of images that can be created, some are useful, some maybe not.  The
96  * following provide a couple of basic models for dldump(3x) use:
97  *
98  *  new executable -	dldump(0, outfile, RTLD_MEMORY)
99  *
100  *			A dynamic executable may undergo some initialization
101  *			and the results of this saved in a new file for later
102  *			execution.  The executable will presumable update
103  *			parts of its data segment and heap (note that the heap
104  *			should be acquired using malloc() so that it follows
105  *			the end of the data segment for this technique to be
106  *			useful).  These updated memory elements are saved to the
107  *			new file, including a new .SUNW_heap section if
108  *			required.
109  *
110  *			For greatest flexibility, no relocated information
111  *			should be saved (by default any relocated information is
112  *			returned to the value it had in its original file).
113  *			This allows the new image to bind to new dynamic objects
114  *			when executed on the same or newer upgrades of the OS.
115  *
116  *			Fixing relocations by applying RTLD_REL_ALL will bind
117  *			the image to the dependencies presently mapped as part
118  *			of the process.  Thus the new executable will only work
119  *			correctly when these same dependencies map to exactly
120  *			to the same locations. (note that RTLD_REL_RELATIVE will
121  *			have no effect as dynamic executables commonly don't
122  *			contain any relative relocations).
123  *
124  *  new shared object -	dldump(infile, outfile, RTLD_REL_RELATIVE)
125  *
126  *			A shared object can be fixed to a known address so as
127  *			to reduce its relocation overhead on startup.  Because
128  *			the new file is fixed to a new base address (which is
129  *			the address at which the object was found mapped to the
130  *			process) it is now a dynamic executable.
131  *
132  *			Data changes that have occurred due to the object
133  *			gaining control (at the least this would be .init
134  *			processing) will not be carried over to the new image.
135  *
136  *			By only performing relative relocations all global
137  *			relocations are available for unique binding to each
138  *			process - thus interposition etc. is still available.
139  *
140  *			Using RTLD_REL_ALL will fix all relocations in the new
141  *			file, which will certainly provide for faster startup
142  *			of the new image, but at the loss of interposition
143  *			flexibility.
144  */
145 int
146 rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr)
147 {
148 	Elf *		ielf = 0, *oelf = 0, *melf = 0;
149 	Ehdr		*iehdr, *oehdr, *mehdr;
150 	Phdr		*iphdr, *ophdr, *data_phdr = 0;
151 	Cache		*icache = 0, *_icache, *mcache = 0, *_mcache;
152 	Cache		*data_cache = 0, *dyn_cache = 0;
153 	Xword		rel_null_no = 0, rel_data_no = 0, rel_func_no = 0;
154 	Xword		rel_entsize;
155 	Rel		*rel_base = 0, *rel_null, *rel_data, *rel_func;
156 	Elf_Scn		*scn;
157 	Shdr		*shdr;
158 	Elf_Data	*data;
159 	Half		endx = 1;
160 	int		fd = 0, err, num;
161 	size_t		shstr_size = 1;
162 	Addr		edata;
163 	char		*shstr, *_shstr, *ipath = NAME(lmp);
164 	prstatus_t	*status = 0, _status;
165 	Lm_list		*lml = LIST(lmp);
166 	Alist		*nodirect = 0;
167 
168 	if (lmp == lml_main.lm_head) {
169 		char	proc[16];
170 		int	pfd;
171 
172 		/*
173 		 * Get a /proc descriptor.
174 		 */
175 		(void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC),
176 		    (int)getpid());
177 		if ((pfd = open(proc, O_RDONLY)) == -1) {
178 			err = errno;
179 			eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
180 			    strerror(err));
181 			return (1);
182 		}
183 
184 		/*
185 		 * If we've been asked to process the dynamic executable we
186 		 * might not know its full path (this is prior to realpath()
187 		 * processing becoming default), and thus use /proc to obtain a
188 		 * file descriptor of the input file.
189 		 */
190 		if ((fd = ioctl(pfd, PIOCOPENM, (void *)0)) == -1) {
191 			err = errno;
192 			eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), ipath,
193 			    strerror(err));
194 			(void) close(pfd);
195 			return (1);
196 		}
197 
198 		/*
199 		 * Obtain the process's status structure from which we can
200 		 * determine the size of the process's heap.  Note, if the
201 		 * application is using mapmalloc then the heap size is going
202 		 * to be zero, and if we're dumping a data section that makes
203 		 * reference to the malloc'ed area we're not going to get a
204 		 * useful image.
205 		 */
206 		if (!(flags & RTLD_NOHEAP)) {
207 			if (ioctl(pfd, PIOCSTATUS, (void *)&_status) == -1) {
208 				err = errno;
209 				eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC),
210 				    ipath, strerror(err));
211 				(void) close(fd);
212 				(void) close(pfd);
213 				return (1);
214 			}
215 			if ((flags & RTLD_MEMORY) && _status.pr_brksize)
216 				status = &_status;
217 		}
218 		(void) close(pfd);
219 	} else {
220 		/*
221 		 * Open the specified file.
222 		 */
223 		if ((fd = open(ipath, O_RDONLY, 0)) == -1) {
224 			err = errno;
225 			eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), ipath,
226 			    strerror(err));
227 			return (1);
228 		}
229 	}
230 
231 	/*
232 	 * Initialize with the ELF library and make sure this is a suitable
233 	 * ELF file we're dealing with.
234 	 */
235 	(void) elf_version(EV_CURRENT);
236 	if ((ielf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
237 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), ipath);
238 		cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
239 		return (1);
240 	}
241 	(void) close(fd);
242 
243 	if ((elf_kind(ielf) != ELF_K_ELF) ||
244 	    ((iehdr = elf_getehdr(ielf)) == NULL) ||
245 	    ((iehdr->e_type != ET_EXEC) && (iehdr->e_type != ET_DYN))) {
246 		eprintf(lml, ERR_FATAL, MSG_INTL(MSG_IMG_ELF), ipath);
247 		cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
248 		return (1);
249 	}
250 
251 	/*
252 	 * Make sure we can create the new output file.
253 	 */
254 	if ((fd = open(opath, (O_RDWR | O_CREAT | O_TRUNC), 0777)) == -1) {
255 		err = errno;
256 		eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), opath,
257 		    strerror(err));
258 		cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
259 		return (1);
260 	}
261 	if ((oelf = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
262 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
263 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
264 		return (1);
265 	}
266 
267 	/*
268 	 * Obtain the input program headers.  Remember the last data segments
269 	 * program header entry as this will be updated later to reflect any new
270 	 * heap section size.
271 	 */
272 	if ((iphdr = elf_getphdr(ielf)) == NULL) {
273 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETPHDR), ipath);
274 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
275 		return (1);
276 	}
277 
278 	for (num = 0, ophdr = iphdr; num != iehdr->e_phnum; num++, ophdr++) {
279 		/*
280 		 * Save the program header that contains the NOBITS section, or
281 		 * the last loadable program header if no NOBITS exists.  A
282 		 * NOBITS section translates to a memory size requirement that
283 		 * is greater than the file data it is mapped from.  Note that
284 		 * we inspect all headers just incase there only exist text
285 		 * segments.
286 		 */
287 		if (ophdr->p_type == PT_LOAD) {
288 			if (ophdr->p_filesz != ophdr->p_memsz)
289 				data_phdr = ophdr;
290 			else if (data_phdr) {
291 				if (data_phdr->p_vaddr < ophdr->p_vaddr)
292 					data_phdr = ophdr;
293 			} else
294 				data_phdr = ophdr;
295 		}
296 	}
297 
298 	/*
299 	 * If there is no data segment, and a heap section is required,
300 	 * warn the user and disable the heap addition (Note that you can't
301 	 * simply append the heap to the last segment, as it might be a text
302 	 * segment, and would therefore have the wrong permissions).
303 	 */
304 	if (status && !data_phdr) {
305 		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_IMG_DATASEG), ipath);
306 		status = 0;
307 	}
308 
309 	/*
310 	 * Obtain the input files section header string table.
311 	 */
312 	if ((scn = elf_getscn(ielf, iehdr->e_shstrndx)) == NULL) {
313 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSCN), ipath);
314 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
315 		return (1);
316 	}
317 	if ((data = elf_getdata(scn, NULL)) == NULL) {
318 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
319 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
320 		return (1);
321 	}
322 	shstr = (char *)data->d_buf;
323 
324 	/*
325 	 * Construct a cache to maintain the input files section information.
326 	 * Obtain an extra cache element if a heap addition is required.  Also
327 	 * add an additional entry (marked FLG_C_END) to make the processing of
328 	 * this cache easier.
329 	 */
330 	num = iehdr->e_shnum;
331 	if (status)
332 		num++;
333 	if ((icache = malloc((num + 1) * sizeof (Cache))) == 0) {
334 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
335 		return (1);
336 	}
337 	icache[num].c_flags = FLG_C_END;
338 
339 	_icache = icache;
340 	_icache++;
341 
342 	/*
343 	 * Traverse each section from the input file collecting the appropriate
344 	 * ELF information.  Indicate how the section will be processed to
345 	 * generate the output image.
346 	 */
347 	for (scn = 0; scn = elf_nextscn(ielf, scn); _icache++) {
348 
349 		if ((_icache->c_shdr = shdr = elf_getshdr(scn)) == NULL) {
350 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), ipath);
351 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
352 			return (1);
353 		}
354 
355 		if ((_icache->c_data = elf_getdata(scn, NULL)) == NULL) {
356 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
357 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
358 			return (1);
359 		}
360 		_icache->c_name = shstr + (size_t)(shdr->sh_name);
361 		_icache->c_scn = scn;
362 		_icache->c_flags = 0;
363 		_icache->c_info = 0;
364 
365 		/*
366 		 * Process any .SUNW_syminfo section.  Symbols that are tagged
367 		 * as NO_DIRECT are collected, as they should not be bound to.
368 		 */
369 		if ((flags & ~RTLD_REL_RELATIVE) &&
370 		    (shdr->sh_type == SHT_SUNW_syminfo)) {
371 			if (syminfo(_icache, &nodirect)) {
372 				cleanup(ielf, oelf, melf, icache, mcache,
373 				    fd, opath);
374 				return (1);
375 			}
376 		}
377 
378 		/*
379 		 * If the section has no address it is not part of the mapped
380 		 * image, and is unlikely to require any further processing.
381 		 * The section header string table will be rewritten (this isn't
382 		 * always necessary, it's only really required when relocation
383 		 * sections are renamed or sections are stripped, but we do
384 		 * things the same way regardless).
385 		 */
386 		if (shdr->sh_addr == 0) {
387 			if ((shdr->sh_type == SHT_STRTAB) &&
388 			    ((strcmp(_icache->c_name,
389 			    MSG_ORIG(MSG_SCN_SHSTR))) == 0))
390 				_icache->c_flags = FLG_C_SHSTR;
391 			else if (flags & RTLD_STRIP) {
392 				_icache->c_flags = FLG_C_EXCLUDE;
393 				continue;
394 			}
395 		}
396 
397 		/*
398 		 * Skip relocation sections for the time being, they'll be
399 		 * analyzed after all sections have been processed.
400 		 */
401 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr)
402 			continue;
403 
404 		/*
405 		 * Sections at this point will simply be passed through to the
406 		 * output file.  Keep track of the section header string table
407 		 * size.
408 		 */
409 		shstr_size += strlen(_icache->c_name) + 1;
410 
411 		/*
412 		 * If a heap section is to be added to the output image,
413 		 * indicate that it will be added following the last data
414 		 * section.
415 		 */
416 		if (shdr->sh_addr && ((shdr->sh_addr + shdr->sh_size) ==
417 		    (data_phdr->p_vaddr + data_phdr->p_memsz))) {
418 			data_cache = _icache;
419 
420 			if (status) {
421 				_icache++;
422 				_icache->c_name =
423 					(char *)MSG_ORIG(MSG_SCN_HEAP);
424 				_icache->c_flags = FLG_C_HEAP;
425 
426 				_icache->c_scn = 0;
427 				_icache->c_shdr = 0;
428 				_icache->c_data = 0;
429 				_icache->c_info = 0;
430 
431 				shstr_size += strlen(_icache->c_name) + 1;
432 			}
433 		}
434 	}
435 
436 	/*
437 	 * Now that we've processed all input sections count the relocation
438 	 * entries (relocation sections need to reference their symbol tables).
439 	 */
440 	_icache = icache;
441 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
442 
443 		if ((shdr = _icache->c_shdr) == 0)
444 			continue;
445 
446 		/*
447 		 * If any form of relocations are to be applied to the output
448 		 * image determine what relocation counts exist.  These will be
449 		 * used to reorganize (localize) the relocation records.
450 		 */
451 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
452 			rel_entsize = shdr->sh_entsize;
453 
454 			if (count_reloc(icache, _icache, lmp, flags, addr,
455 			    &rel_null_no, &rel_data_no, &rel_func_no,
456 			    nodirect)) {
457 				cleanup(ielf, oelf, melf, icache, mcache,
458 				    fd, opath);
459 				return (1);
460 			}
461 		}
462 	}
463 
464 	/*
465 	 * If any form of relocations are to be applied to the output image
466 	 * then we will reorganize (localize) the relocation records.  If this
467 	 * reorganization occurs, the relocation sections will no longer have a
468 	 * one-to-one relationship with the section they relocate, hence we
469 	 * rename them to a more generic name.
470 	 */
471 	_icache = icache;
472 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
473 
474 		if ((shdr = _icache->c_shdr) == 0)
475 			continue;
476 
477 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
478 			if (rel_null_no) {
479 				_icache->c_flags = FLG_C_RELOC;
480 				_icache->c_name =
481 				    (char *)MSG_ORIG(MSG_SCN_RELOC);
482 			}
483 			shstr_size += strlen(_icache->c_name) + 1;
484 		}
485 	}
486 
487 
488 	/*
489 	 * If there is no data section, and a heap is required, warn the user
490 	 * and disable the heap addition.
491 	 */
492 	if (!data_cache) {
493 		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_IMG_DATASEC), ipath);
494 		status = 0;
495 		endx = 0;
496 	}
497 
498 	/*
499 	 * Determine the value of _edata (which will also be _end) and its
500 	 * section index for updating the data segments phdr and symbol table
501 	 * information later.  If a new heap section is being added, update
502 	 * the values appropriately.
503 	 */
504 	edata = data_phdr->p_vaddr + data_phdr->p_memsz;
505 	if (status)
506 		edata += status->pr_brksize;
507 
508 	if (endx) {
509 		/* LINTED */
510 		endx = (Half)elf_ndxscn(data_cache->c_scn);
511 		if (status)
512 			endx++;
513 	}
514 
515 	/*
516 	 * We're now ready to construct the new elf image.
517 	 *
518 	 * Obtain a new elf header and initialize it with any basic information
519 	 * that isn't calculated as part of elf_update().
520 	 */
521 	if ((oehdr = elf_newehdr(oelf)) == NULL) {
522 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWEHDR), opath);
523 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
524 		return (1);
525 	}
526 	oehdr->e_machine = iehdr->e_machine;
527 	oehdr->e_flags = iehdr->e_flags;
528 	oehdr->e_type = ET_EXEC;
529 	oehdr->e_entry = iehdr->e_entry;
530 	if (addr)
531 		oehdr->e_entry += addr;
532 
533 	/*
534 	 * Obtain a new set of program headers.  Initialize these with the same
535 	 * information as the input program headers.  Update the virtual address
536 	 * and the data segments size to reflect any new heap section.
537 	 */
538 	if ((ophdr = elf_newphdr(oelf, iehdr->e_phnum)) == NULL) {
539 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWPHDR), opath);
540 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
541 		return (1);
542 	}
543 	for (num = 0; num != iehdr->e_phnum; num++, iphdr++, ophdr++) {
544 		*ophdr = *iphdr;
545 		if ((ophdr->p_type != PT_INTERP) && (ophdr->p_type != PT_NOTE))
546 			ophdr->p_vaddr += addr;
547 		if (data_phdr == iphdr) {
548 			if (status)
549 				ophdr->p_memsz = edata - ophdr->p_vaddr;
550 			ophdr->p_filesz = ophdr->p_memsz;
551 		}
552 	}
553 
554 	/*
555 	 * Establish a buffer for the new section header string table.  This
556 	 * will be filled in as each new section is created.
557 	 */
558 	if ((shstr = malloc(shstr_size)) == 0) {
559 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
560 		return (1);
561 	}
562 	_shstr = shstr;
563 	*_shstr++ = '\0';
564 
565 	/*
566 	 * Use the input files cache information to generate new sections.
567 	 */
568 	_icache = icache;
569 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
570 		/*
571 		 * Skip any excluded sections.
572 		 */
573 		if (_icache->c_flags == FLG_C_EXCLUDE)
574 			continue;
575 
576 		/*
577 		 * Create a matching section header in the output file.
578 		 */
579 		if ((scn = elf_newscn(oelf)) == NULL) {
580 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWSCN), opath);
581 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
582 			return (1);
583 		}
584 		if ((shdr = elf_getshdr(scn)) == NULL) {
585 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWSHDR), opath);
586 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
587 			return (1);
588 		}
589 
590 		/*
591 		 * If this is the heap section initialize the appropriate
592 		 * entries, otherwise simply use the original section header
593 		 * information.
594 		 */
595 		if (_icache->c_flags == FLG_C_HEAP) {
596 			shdr->sh_type = SHT_PROGBITS;
597 			shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
598 		} else
599 			*shdr = *_icache->c_shdr;
600 
601 		/*
602 		 * Create a matching data buffer for this section.
603 		 */
604 		if ((data = elf_newdata(scn)) == NULL) {
605 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWDATA), opath);
606 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
607 			return (1);
608 		}
609 
610 		/*
611 		 * Determine what data will be used for this section.
612 		 */
613 		if (_icache->c_flags == FLG_C_SHSTR) {
614 			/*
615 			 * Reassign the shstrtab to the new data buffer we're
616 			 * creating.  Insure that the new elf header references
617 			 * this section header table.
618 			 */
619 			*data = *_icache->c_data;
620 
621 			data->d_buf = (void *)shstr;
622 			data->d_size = shstr_size;
623 
624 			_icache->c_info = shstr;
625 
626 			/* LINTED */
627 			oehdr->e_shstrndx = (Half)elf_ndxscn(scn);
628 
629 		} else if (_icache->c_flags == FLG_C_HEAP) {
630 			/*
631 			 * Assign the heap to the appropriate memory offset.
632 			 */
633 			data->d_buf = status->pr_brkbase;
634 			data->d_type = ELF_T_BYTE;
635 			data->d_size = (size_t)status->pr_brksize;
636 			data->d_off = 0;
637 			data->d_align = 1;
638 			data->d_version = EV_CURRENT;
639 
640 			shdr->sh_addr = data_cache->c_shdr->sh_addr +
641 			    data_cache->c_shdr->sh_size;
642 
643 		} else if (_icache->c_flags == FLG_C_RELOC) {
644 			/*
645 			 * If some relocations are to be saved in the new image
646 			 * then the relocation sections will be reorganized to
647 			 * localize their contents.  These relocation sections
648 			 * will no longer have a one-to-one relationship with
649 			 * the section they relocate, hence we rename them and
650 			 * remove their sh_info info.
651 			 */
652 			*data = *_icache->c_data;
653 
654 			shdr->sh_info = 0;
655 
656 		} else {
657 			/*
658 			 * By default simply pass the section through.  If
659 			 * we've been asked to use the memory image of the
660 			 * input file reestablish the data buffer address.
661 			 */
662 			*data = *_icache->c_data;
663 
664 			if ((shdr->sh_addr) && (flags & RTLD_MEMORY))
665 				data->d_buf = (void *)(shdr->sh_addr + addr);
666 
667 			/*
668 			 * Update any NOBITS section to indicate that it now
669 			 * contains data.  If this image is being created
670 			 * directly from the input file, zero out the .bss
671 			 * section (this saves ld.so.1 having to zero out memory
672 			 * or do any /dev/zero mappings).
673 			 */
674 			if (shdr->sh_type == SHT_NOBITS) {
675 				shdr->sh_type = SHT_PROGBITS;
676 				if (!(flags & RTLD_MEMORY)) {
677 					if ((data->d_buf = calloc(1,
678 					    data->d_size)) == 0) {
679 						cleanup(ielf, oelf, melf,
680 						    icache, mcache, fd, opath);
681 						return (1);
682 					}
683 				}
684 			}
685 		}
686 
687 		/*
688 		 * Update the section header string table.
689 		 */
690 		/* LINTED */
691 		shdr->sh_name = (Word)(_shstr - shstr);
692 		(void) strcpy(_shstr, _icache->c_name);
693 		_shstr = _shstr + strlen(_icache->c_name) + 1;
694 
695 		/*
696 		 * For each section that has a virtual address update its
697 		 * address to the fixed location of the new image.
698 		 */
699 		if (shdr->sh_addr)
700 			shdr->sh_addr += addr;
701 
702 		/*
703 		 * If we've inserted a new section any later sections may need
704 		 * their sh_link fields updated (.stabs comes to mind).
705 		 */
706 		if (status && endx && (shdr->sh_link >= endx))
707 			shdr->sh_link++;
708 	}
709 
710 	/*
711 	 * Generate the new image, and obtain a new elf descriptor that will
712 	 * allow us to write and update the new image.
713 	 */
714 	if (elf_update(oelf, ELF_C_WRIMAGE) == -1) {
715 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
716 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
717 		return (1);
718 	}
719 	if ((melf = elf_begin(0, ELF_C_IMAGE, oelf)) == NULL) {
720 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
721 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
722 		return (1);
723 	}
724 	if ((mehdr = elf_getehdr(melf)) == NULL) {
725 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETEHDR), opath);
726 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
727 		return (1);
728 	}
729 
730 	/*
731 	 * Construct a cache to maintain the memory files section information.
732 	 */
733 	if ((mcache = malloc(mehdr->e_shnum * sizeof (Cache))) == 0) {
734 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
735 		return (1);
736 	}
737 	_mcache = mcache;
738 	_mcache++;
739 
740 	for (scn = 0; scn = elf_nextscn(melf, scn); _mcache++) {
741 
742 		if ((_mcache->c_shdr = elf_getshdr(scn)) == NULL) {
743 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), opath);
744 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
745 			return (1);
746 		}
747 
748 		if ((_mcache->c_data = elf_getdata(scn, NULL)) == NULL) {
749 			eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), opath);
750 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
751 			return (1);
752 		}
753 	}
754 
755 	/*
756 	 * Now that we have a complete description of the new image update any
757 	 * sections that are required.
758 	 *
759 	 *  o	reset any symbol table entries.
760 	 *
761 	 *  o	reset any relocation entries.
762 	 *
763 	 *  o	reset dynamic entries.
764 	 */
765 	_mcache = &mcache[0];
766 	for (_icache = &icache[1]; _icache->c_flags != FLG_C_END; _icache++) {
767 
768 		if (_icache->c_flags == FLG_C_EXCLUDE)
769 			continue;
770 
771 		_mcache++;
772 		shdr = _mcache->c_shdr;
773 
774 		/*
775 		 * Update the symbol table entries.  _end and _edata will be
776 		 * changed to reflect any heap addition.  All global symbols
777 		 * will be updated to their new fixed address.
778 		 */
779 		if ((shdr->sh_type == SHT_SYMTAB) ||
780 		    (shdr->sh_type == SHT_DYNSYM) ||
781 		    (shdr->sh_type == SHT_SUNW_LDYNSYM)) {
782 			update_sym(mcache, _mcache, edata, endx, addr);
783 			continue;
784 		}
785 
786 		/*
787 		 * Update any relocations.  All relocation requirements will
788 		 * have been established in count_reloc().
789 		 */
790 		if (shdr->sh_type == M_REL_SHT_TYPE) {
791 			if (rel_base == (Rel *)0) {
792 				rel_base = (Rel *)_mcache->c_data->d_buf;
793 				rel_null = rel_base;
794 				rel_data = (Rel *)((Xword)rel_null +
795 				    (rel_null_no * rel_entsize));
796 				rel_func = (Rel *)((Xword)rel_data +
797 				    (rel_data_no * rel_entsize));
798 			}
799 
800 			update_reloc(mcache, icache, _icache, opath, lmp,
801 			    &rel_null, &rel_data, &rel_func);
802 			continue;
803 		}
804 
805 		/*
806 		 * Perform any dynamic entry updates after all relocation
807 		 * processing has been carried out (as its possible the .dynamic
808 		 * section could occur before the .rel sections, delay this
809 		 * processing until last).
810 		 */
811 		if (shdr->sh_type == SHT_DYNAMIC)
812 			dyn_cache = _mcache;
813 	}
814 
815 	if (dyn_cache) {
816 		Xword	off = (Xword)rel_base - (Xword)mehdr;
817 
818 		/*
819 		 * If we're dumping a fixed object (typically the dynamic
820 		 * executable) compensate for its real base address.
821 		 */
822 		if (!addr)
823 			off += ADDR(lmp);
824 
825 		if (update_dynamic(mcache, dyn_cache, lmp, flags, addr, off,
826 		    opath, rel_null_no, rel_data_no, rel_func_no, rel_entsize,
827 		    elf_checksum(melf))) {
828 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
829 			return (1);
830 		}
831 	}
832 
833 	/*
834 	 * Having completed all section updates write the memory file out.
835 	 */
836 	if (elf_update(oelf, ELF_C_WRITE) == -1) {
837 		eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
838 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
839 		return (1);
840 	}
841 
842 	cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
843 	return (0);
844 }
845