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
cleanup(Elf * ielf,Elf * oelf,Elf * melf,Cache * icache,Cache * mcache,int fd,const char * opath)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
rt_dldump(Rt_map * lmp,const char * opath,int flags,Addr addr)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