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