xref: /illumos-gate/usr/src/cmd/sgs/librtld/common/dldump.c (revision 88f8b78a88cbdc6d8c1af5c3e54bc49d25095c98)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 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 
166 	if (lmp == lml_main.lm_head) {
167 		char	proc[16];
168 		int	pfd;
169 
170 		/*
171 		 * Get a /proc descriptor.
172 		 */
173 		(void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC),
174 		    (int)getpid());
175 		if ((pfd = open(proc, O_RDONLY)) == -1) {
176 			err = errno;
177 			eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
178 			    strerror(err));
179 			return (1);
180 		}
181 
182 		/*
183 		 * If we've been asked to process the dynamic executable we
184 		 * might not know its full path (this is prior to realpath()
185 		 * processing becoming default), and thus use /proc to obtain a
186 		 * file descriptor of the input file.
187 		 */
188 		if ((fd = ioctl(pfd, PIOCOPENM, (void *)0)) == -1) {
189 			err = errno;
190 			eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC), ipath,
191 			    strerror(err));
192 			(void) close(pfd);
193 			return (1);
194 		}
195 
196 		/*
197 		 * Obtain the process's status structure from which we can
198 		 * determine the size of the process's heap.  Note, if the
199 		 * application is using mapmalloc then the heap size is going
200 		 * to be zero, and if we're dumping a data section that makes
201 		 * reference to the malloc'ed area we're not going to get a
202 		 * useful image.
203 		 */
204 		if (!(flags & RTLD_NOHEAP)) {
205 			if (ioctl(pfd, PIOCSTATUS, (void *)&_status) == -1) {
206 				err = errno;
207 				eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC),
208 				    ipath, strerror(err));
209 				(void) close(fd);
210 				(void) close(pfd);
211 				return (1);
212 			}
213 			if ((flags & RTLD_MEMORY) && _status.pr_brksize)
214 				status = &_status;
215 		}
216 		(void) close(pfd);
217 	} else {
218 		/*
219 		 * Open the specified file.
220 		 */
221 		if ((fd = open(ipath, O_RDONLY, 0)) == -1) {
222 			err = errno;
223 			eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), ipath,
224 			    strerror(err));
225 			return (1);
226 		}
227 	}
228 
229 	/*
230 	 * Initialize with the ELF library and make sure this is a suitable
231 	 * ELF file we're dealing with.
232 	 */
233 	(void) elf_version(EV_CURRENT);
234 	if ((ielf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
235 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), ipath);
236 		cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
237 		return (1);
238 	}
239 	(void) close(fd);
240 
241 	if ((elf_kind(ielf) != ELF_K_ELF) ||
242 	    ((iehdr = elf_getehdr(ielf)) == NULL) ||
243 	    ((iehdr->e_type != ET_EXEC) && (iehdr->e_type != ET_DYN))) {
244 		eprintf(ERR_FATAL, MSG_INTL(MSG_IMG_ELF), ipath);
245 		cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
246 		return (1);
247 	}
248 
249 	/*
250 	 * Make sure we can create the new output file.
251 	 */
252 	if ((fd = open(opath, (O_RDWR | O_CREAT | O_TRUNC), 0777)) == -1) {
253 		err = errno;
254 		eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), opath,
255 		    strerror(err));
256 		cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
257 		return (1);
258 	}
259 	if ((oelf = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
260 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
261 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
262 		return (1);
263 	}
264 
265 	/*
266 	 * Obtain the input program headers.  Remember the last data segments
267 	 * program header entry as this will be updated later to reflect any new
268 	 * heap section size.
269 	 */
270 	if ((iphdr = elf_getphdr(ielf)) == NULL) {
271 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETPHDR), ipath);
272 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
273 		return (1);
274 	}
275 
276 	for (num = 0, ophdr = iphdr; num != iehdr->e_phnum; num++, ophdr++) {
277 		/*
278 		 * Save the program header that contains the NOBITS section, or
279 		 * the last loadable program header if no NOBITS exists.  A
280 		 * NOBITS section translates to a memory size requirement that
281 		 * is greater than the file data it is mapped from.  Note that
282 		 * we inspect all headers just incase there only exist text
283 		 * segments.
284 		 */
285 		if (ophdr->p_type == PT_LOAD) {
286 			if (ophdr->p_filesz != ophdr->p_memsz)
287 				data_phdr = ophdr;
288 			else if (data_phdr) {
289 				if (data_phdr->p_vaddr < ophdr->p_vaddr)
290 					data_phdr = ophdr;
291 			} else
292 				data_phdr = ophdr;
293 		}
294 	}
295 
296 	/*
297 	 * If there is no data segment, and a heap section is required,
298 	 * warn the user and disable the heap addition (Note that you can't
299 	 * simply append the heap to the last segment, as it might be a text
300 	 * segment, and would therefore have the wrong permissions).
301 	 */
302 	if (status && !data_phdr) {
303 		eprintf(ERR_WARNING, MSG_INTL(MSG_IMG_DATASEG), ipath);
304 		status = 0;
305 	}
306 
307 	/*
308 	 * Obtain the input files section header string table.
309 	 */
310 	if ((scn = elf_getscn(ielf, iehdr->e_shstrndx)) == NULL) {
311 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETSCN), ipath);
312 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
313 		return (1);
314 	}
315 	if ((data = elf_getdata(scn, NULL)) == NULL) {
316 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
317 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
318 		return (1);
319 	}
320 	shstr = (char *)data->d_buf;
321 
322 	/*
323 	 * Construct a cache to maintain the input files section information.
324 	 * Obtain an extra cache element if a heap addition is required.  Also
325 	 * add an additional entry (marked FLG_C_END) to make the processing of
326 	 * this cache easier.
327 	 */
328 	num = iehdr->e_shnum;
329 	if (status)
330 		num++;
331 	if ((icache = malloc((num + 1) * sizeof (Cache))) == 0) {
332 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
333 		return (1);
334 	}
335 	icache[num].c_flags = FLG_C_END;
336 
337 	_icache = icache;
338 	_icache++;
339 
340 	/*
341 	 * Traverse each section from the input file collecting the appropriate
342 	 * ELF information.  Indicate how the section will be processed to
343 	 * generate the output image.
344 	 */
345 	for (scn = 0; scn = elf_nextscn(ielf, scn); _icache++) {
346 
347 		if ((_icache->c_shdr = shdr = elf_getshdr(scn)) == NULL) {
348 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), ipath);
349 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
350 			return (1);
351 		}
352 
353 		if ((_icache->c_data = elf_getdata(scn, NULL)) == NULL) {
354 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
355 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
356 			return (1);
357 		}
358 		_icache->c_name = shstr + (size_t)(shdr->sh_name);
359 		_icache->c_scn = scn;
360 		_icache->c_flags = 0;
361 		_icache->c_info = 0;
362 
363 		/*
364 		 * If the section has no address it is not part of the mapped
365 		 * image, and is unlikely to require any further processing.
366 		 * The section header string table will be rewritten (this isn't
367 		 * always necessary, it's only really required when relocation
368 		 * sections are renamed or sections are stripped, but we do
369 		 * things the same way regardless).
370 		 */
371 		if (shdr->sh_addr == 0) {
372 			if ((shdr->sh_type == SHT_STRTAB) &&
373 			    ((strcmp(_icache->c_name,
374 			    MSG_ORIG(MSG_SCN_SHSTR))) == 0))
375 				_icache->c_flags = FLG_C_SHSTR;
376 			else if (flags & RTLD_STRIP) {
377 				_icache->c_flags = FLG_C_EXCLUDE;
378 				continue;
379 			}
380 		}
381 
382 		/*
383 		 * Skip relocation sections for the time being, they'll be
384 		 * analyzed after all sections have been processed.
385 		 */
386 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr)
387 			continue;
388 
389 		/*
390 		 * Sections at this point will simply be passed through to the
391 		 * output file.  Keep track of the section header string table
392 		 * size.
393 		 */
394 		shstr_size += strlen(_icache->c_name) + 1;
395 
396 		/*
397 		 * If a heap section is to be added to the output image,
398 		 * indicate that it will be added following the last data
399 		 * section.
400 		 */
401 		if (shdr->sh_addr && ((shdr->sh_addr + shdr->sh_size) ==
402 		    (data_phdr->p_vaddr + data_phdr->p_memsz))) {
403 			data_cache = _icache;
404 
405 			if (status) {
406 				_icache++;
407 				_icache->c_name =
408 					(char *)MSG_ORIG(MSG_SCN_HEAP);
409 				_icache->c_flags = FLG_C_HEAP;
410 
411 				_icache->c_scn = 0;
412 				_icache->c_shdr = 0;
413 				_icache->c_data = 0;
414 				_icache->c_info = 0;
415 
416 				shstr_size += strlen(_icache->c_name) + 1;
417 			}
418 		}
419 	}
420 
421 	/*
422 	 * Now that we've processed all input sections count the relocation
423 	 * entries (relocation sections need to reference their symbol tables).
424 	 */
425 	_icache = icache;
426 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
427 
428 		if ((shdr = _icache->c_shdr) == 0)
429 			continue;
430 
431 		/*
432 		 * If any form of relocations are to be applied to the output
433 		 * image determine what relocation counts exist.  These will be
434 		 * used to reorganize (localize) the relocation records.
435 		 */
436 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
437 			rel_entsize = shdr->sh_entsize;
438 
439 			if (count_reloc(icache, _icache, lmp, flags, addr,
440 			    &rel_null_no, &rel_data_no, &rel_func_no)) {
441 				cleanup(ielf, oelf, melf, icache, mcache,
442 				    fd, opath);
443 				return (1);
444 			}
445 		}
446 	}
447 
448 	/*
449 	 * If any form of relocations are to be applied to the output image
450 	 * then we will reorganize (localize) the relocation records.  If this
451 	 * reorganization occurs, the relocation sections will no longer have a
452 	 * one-to-one relationship with the section they relocate, hence we
453 	 * rename them to a more generic name.
454 	 */
455 	_icache = icache;
456 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
457 
458 		if ((shdr = _icache->c_shdr) == 0)
459 			continue;
460 
461 		if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
462 			if (rel_null_no) {
463 				_icache->c_flags = FLG_C_RELOC;
464 				_icache->c_name =
465 				    (char *)MSG_ORIG(MSG_SCN_RELOC);
466 			}
467 			shstr_size += strlen(_icache->c_name) + 1;
468 		}
469 	}
470 
471 
472 	/*
473 	 * If there is no data section, and a heap is required, warn the user
474 	 * and disable the heap addition.
475 	 */
476 	if (!data_cache) {
477 		eprintf(ERR_WARNING, MSG_INTL(MSG_IMG_DATASEC), ipath);
478 		status = 0;
479 		endx = 0;
480 	}
481 
482 	/*
483 	 * Determine the value of _edata (which will also be _end) and its
484 	 * section index for updating the data segments phdr and symbol table
485 	 * information later.  If a new heap section is being added, update
486 	 * the values appropriately.
487 	 */
488 	edata = data_phdr->p_vaddr + data_phdr->p_memsz;
489 	if (status)
490 		edata += status->pr_brksize;
491 
492 	if (endx) {
493 		/* LINTED */
494 		endx = (Half)elf_ndxscn(data_cache->c_scn);
495 		if (status)
496 			endx++;
497 	}
498 
499 	/*
500 	 * We're now ready to construct the new elf image.
501 	 *
502 	 * Obtain a new elf header and initialize it with any basic information
503 	 * that isn't calculated as part of elf_update().
504 	 */
505 	if ((oehdr = elf_newehdr(oelf)) == NULL) {
506 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_NEWEHDR), opath);
507 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
508 		return (1);
509 	}
510 	oehdr->e_machine = iehdr->e_machine;
511 	oehdr->e_flags = iehdr->e_flags;
512 	oehdr->e_type = ET_EXEC;
513 	oehdr->e_entry = iehdr->e_entry;
514 	if (addr)
515 		oehdr->e_entry += addr;
516 
517 	/*
518 	 * Obtain a new set of program headers.  Initialize these with the same
519 	 * information as the input program headers.  Update the virtual address
520 	 * and the data segments size to reflect any new heap section.
521 	 */
522 	if ((ophdr = elf_newphdr(oelf, iehdr->e_phnum)) == NULL) {
523 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_NEWPHDR), opath);
524 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
525 		return (1);
526 	}
527 	for (num = 0; num != iehdr->e_phnum; num++, iphdr++, ophdr++) {
528 		*ophdr = *iphdr;
529 		if ((ophdr->p_type != PT_INTERP) && (ophdr->p_type != PT_NOTE))
530 			ophdr->p_vaddr += addr;
531 		if (data_phdr == iphdr) {
532 			if (status)
533 				ophdr->p_memsz = edata - ophdr->p_vaddr;
534 			ophdr->p_filesz = ophdr->p_memsz;
535 		}
536 	}
537 
538 	/*
539 	 * Establish a buffer for the new section header string table.  This
540 	 * will be filled in as each new section is created.
541 	 */
542 	if ((shstr = malloc(shstr_size)) == 0) {
543 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
544 		return (1);
545 	}
546 	_shstr = shstr;
547 	*_shstr++ = '\0';
548 
549 	/*
550 	 * Use the input files cache information to generate new sections.
551 	 */
552 	_icache = icache;
553 	for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
554 		/*
555 		 * Skip any excluded sections.
556 		 */
557 		if (_icache->c_flags == FLG_C_EXCLUDE)
558 			continue;
559 
560 		/*
561 		 * Create a matching section header in the output file.
562 		 */
563 		if ((scn = elf_newscn(oelf)) == NULL) {
564 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_NEWSCN), opath);
565 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
566 			return (1);
567 		}
568 		if ((shdr = elf_getshdr(scn)) == NULL) {
569 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_NEWSHDR), opath);
570 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
571 			return (1);
572 		}
573 
574 		/*
575 		 * If this is the heap section initialize the appropriate
576 		 * entries, otherwise simply use the original section header
577 		 * information.
578 		 */
579 		if (_icache->c_flags == FLG_C_HEAP) {
580 			shdr->sh_type = SHT_PROGBITS;
581 			shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
582 		} else
583 			*shdr = *_icache->c_shdr;
584 
585 		/*
586 		 * Create a matching data buffer for this section.
587 		 */
588 		if ((data = elf_newdata(scn)) == NULL) {
589 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_NEWDATA), opath);
590 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
591 			return (1);
592 		}
593 
594 		/*
595 		 * Determine what data will be used for this section.
596 		 */
597 		if (_icache->c_flags == FLG_C_SHSTR) {
598 			/*
599 			 * Reassign the shstrtab to the new data buffer we're
600 			 * creating.  Insure that the new elf header references
601 			 * this section header table.
602 			 */
603 			*data = *_icache->c_data;
604 
605 			data->d_buf = (void *)shstr;
606 			data->d_size = shstr_size;
607 
608 			_icache->c_info = shstr;
609 
610 			/* LINTED */
611 			oehdr->e_shstrndx = (Half)elf_ndxscn(scn);
612 
613 		} else if (_icache->c_flags == FLG_C_HEAP) {
614 			/*
615 			 * Assign the heap to the appropriate memory offset.
616 			 */
617 			data->d_buf = status->pr_brkbase;
618 			data->d_type = ELF_T_BYTE;
619 			data->d_size = (size_t)status->pr_brksize;
620 			data->d_off = 0;
621 			data->d_align = 1;
622 			data->d_version = EV_CURRENT;
623 
624 			shdr->sh_addr = data_cache->c_shdr->sh_addr +
625 			    data_cache->c_shdr->sh_size;
626 
627 		} else if (_icache->c_flags == FLG_C_RELOC) {
628 			/*
629 			 * If some relocations are to be saved in the new image
630 			 * then the relocation sections will be reorganized to
631 			 * localize their contents.  These relocation sections
632 			 * will no longer have a one-to-one relationship with
633 			 * the section they relocate, hence we rename them and
634 			 * remove their sh_info info.
635 			 */
636 			*data = *_icache->c_data;
637 
638 			shdr->sh_info = 0;
639 
640 		} else {
641 			/*
642 			 * By default simply pass the section through.  If
643 			 * we've been asked to use the memory image of the
644 			 * input file reestablish the data buffer address.
645 			 */
646 			*data = *_icache->c_data;
647 
648 			if ((shdr->sh_addr) && (flags & RTLD_MEMORY))
649 				data->d_buf = (void *)(shdr->sh_addr + addr);
650 
651 			/*
652 			 * Update any NOBITS section to indicate that it now
653 			 * contains data.  If this image is being created
654 			 * directly from the input file, zero out the .bss
655 			 * section (this saves ld.so.1 having to zero out memory
656 			 * or do any /dev/zero mappings).
657 			 */
658 			if (shdr->sh_type == SHT_NOBITS) {
659 				shdr->sh_type = SHT_PROGBITS;
660 				if (!(flags & RTLD_MEMORY)) {
661 					if ((data->d_buf = calloc(1,
662 					    data->d_size)) == 0) {
663 						cleanup(ielf, oelf, melf,
664 						    icache, mcache, fd, opath);
665 						return (1);
666 					}
667 				}
668 			}
669 		}
670 
671 		/*
672 		 * Update the section header string table.
673 		 */
674 		/* LINTED */
675 		shdr->sh_name = (Word)(_shstr - shstr);
676 		(void) strcpy(_shstr, _icache->c_name);
677 		_shstr = _shstr + strlen(_icache->c_name) + 1;
678 
679 		/*
680 		 * For each section that has a virtual address update its
681 		 * address to the fixed location of the new image.
682 		 */
683 		if (shdr->sh_addr)
684 			shdr->sh_addr += addr;
685 
686 		/*
687 		 * If we've inserted a new section any later sections may need
688 		 * their sh_link fields updated (.stabs comes to mind).
689 		 */
690 		if (status && endx && (shdr->sh_link >= endx))
691 			shdr->sh_link++;
692 	}
693 
694 	/*
695 	 * Generate the new image, and obtain a new elf descriptor that will
696 	 * allow us to write and update the new image.
697 	 */
698 	if (elf_update(oelf, ELF_C_WRIMAGE) == -1) {
699 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
700 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
701 		return (1);
702 	}
703 	if ((melf = elf_begin(0, ELF_C_IMAGE, oelf)) == NULL) {
704 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
705 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
706 		return (1);
707 	}
708 	if ((mehdr = elf_getehdr(melf)) == NULL) {
709 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETEHDR), opath);
710 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
711 		return (1);
712 	}
713 
714 	/*
715 	 * Construct a cache to maintain the memory files section information.
716 	 */
717 	if ((mcache = malloc(mehdr->e_shnum * sizeof (Cache))) == 0) {
718 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
719 		return (1);
720 	}
721 	_mcache = mcache;
722 	_mcache++;
723 
724 	for (scn = 0; scn = elf_nextscn(melf, scn); _mcache++) {
725 
726 		if ((_mcache->c_shdr = elf_getshdr(scn)) == NULL) {
727 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), opath);
728 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
729 			return (1);
730 		}
731 
732 		if ((_mcache->c_data = elf_getdata(scn, NULL)) == NULL) {
733 			eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), opath);
734 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
735 			return (1);
736 		}
737 	}
738 
739 	/*
740 	 * Now that we have a complete description of the new image update any
741 	 * sections that are required.
742 	 *
743 	 *  o	reset any symbol table entries.
744 	 *
745 	 *  o	reset any relocation entries.
746 	 *
747 	 *  o	reset dynamic entries.
748 	 */
749 	_mcache = &mcache[0];
750 	for (_icache = &icache[1]; _icache->c_flags != FLG_C_END; _icache++) {
751 
752 		if (_icache->c_flags == FLG_C_EXCLUDE)
753 			continue;
754 
755 		_mcache++;
756 		shdr = _mcache->c_shdr;
757 
758 		/*
759 		 * Update the symbol table entries.  _end and _edata will be
760 		 * changed to reflect any heap addition.  All global symbols
761 		 * will be updated to their new fixed address.
762 		 */
763 		if ((shdr->sh_type == SHT_SYMTAB) ||
764 		    (shdr->sh_type == SHT_DYNSYM)) {
765 			update_sym(mcache, _mcache, edata, endx, addr);
766 			continue;
767 		}
768 
769 		/*
770 		 * Update any relocations.  All relocation requirements will
771 		 * have been established in count_reloc().
772 		 */
773 		if (shdr->sh_type == M_REL_SHT_TYPE) {
774 			if (rel_base == (Rel *)0) {
775 				rel_base = (Rel *)_mcache->c_data->d_buf;
776 				rel_null = rel_base;
777 				rel_data = (Rel *)((Xword)rel_null +
778 				    (rel_null_no * rel_entsize));
779 				rel_func = (Rel *)((Xword)rel_data +
780 				    (rel_data_no * rel_entsize));
781 			}
782 
783 			update_reloc(mcache, icache, _icache, opath, lmp,
784 			    &rel_null, &rel_data, &rel_func);
785 			continue;
786 		}
787 
788 		/*
789 		 * Perform any dynamic entry updates after all relocation
790 		 * processing has been carried out (as its possible the .dynamic
791 		 * section could occur before the .rel sections, delay this
792 		 * processing until last).
793 		 */
794 		if (shdr->sh_type == SHT_DYNAMIC)
795 			dyn_cache = _mcache;
796 	}
797 
798 	if (dyn_cache) {
799 		Xword	off = (Xword)rel_base - (Xword)mehdr;
800 
801 		/*
802 		 * If we're dumping a fixed object (typically the dynamic
803 		 * executable) compensate for its real base address.
804 		 */
805 		if (!addr)
806 			off += ADDR(lmp);
807 
808 		if (update_dynamic(mcache, dyn_cache, lmp, flags, addr, off,
809 		    opath, rel_null_no, rel_data_no, rel_func_no, rel_entsize,
810 		    elf_checksum(melf))) {
811 			cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
812 			return (1);
813 		}
814 	}
815 
816 	/*
817 	 * Having completed all section updates write the memory file out.
818 	 */
819 	if (elf_update(oelf, ELF_C_WRITE) == -1) {
820 		eprintf(ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
821 		cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
822 		return (1);
823 	}
824 
825 	cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
826 	return (0);
827 }
828