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