diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexelf.c | 360 |
1 files changed, 221 insertions, 139 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index 784fab1e7ff..b37e09da2f9 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -1,101 +1,19 @@ | |||
| 1 | /* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992 |
| 2 | 2 | Free Software Foundation, Inc. | |
| 3 | NO WARRANTY | ||
| 4 | |||
| 5 | BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY | ||
| 6 | NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT | ||
| 7 | WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, | ||
| 8 | RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" | ||
| 9 | WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, | ||
| 10 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
| 11 | FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY | ||
| 12 | AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE | ||
| 13 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR | ||
| 14 | CORRECTION. | ||
| 15 | |||
| 16 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. | ||
| 17 | STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY | ||
| 18 | WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE | ||
| 19 | LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR | ||
| 20 | OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||
| 21 | USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR | ||
| 22 | DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR | ||
| 23 | A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS | ||
| 24 | PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH | ||
| 25 | DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. | ||
| 26 | |||
| 27 | GENERAL PUBLIC LICENSE TO COPY | ||
| 28 | |||
| 29 | 1. You may copy and distribute verbatim copies of this source file | ||
| 30 | as you receive it, in any medium, provided that you conspicuously and | ||
| 31 | appropriately publish on each copy a valid copyright notice "Copyright | ||
| 32 | (C) 1987 Free Software Foundation, Inc."; and include following the | ||
| 33 | copyright notice a verbatim copy of the above disclaimer of warranty | ||
| 34 | and of this License. You may charge a distribution fee for the | ||
| 35 | physical act of transferring a copy. | ||
| 36 | |||
| 37 | 2. You may modify your copy or copies of this source file or | ||
| 38 | any portion of it, and copy and distribute such modifications under | ||
| 39 | the terms of Paragraph 1 above, provided that you also do the following: | ||
| 40 | |||
| 41 | a) cause the modified files to carry prominent notices stating | ||
| 42 | that you changed the files and the date of any change; and | ||
| 43 | |||
| 44 | b) cause the whole of any work that you distribute or publish, | ||
| 45 | that in whole or in part contains or is a derivative of this | ||
| 46 | program or any part thereof, to be licensed at no charge to all | ||
| 47 | third parties on terms identical to those contained in this | ||
| 48 | License Agreement (except that you may choose to grant more extensive | ||
| 49 | warranty protection to some or all third parties, at your option). | ||
| 50 | |||
| 51 | c) You may charge a distribution fee for the physical act of | ||
| 52 | transferring a copy, and you may at your option offer warranty | ||
| 53 | protection in exchange for a fee. | ||
| 54 | |||
| 55 | Mere aggregation of another unrelated program with this program (or its | ||
| 56 | derivative) on a volume of a storage or distribution medium does not bring | ||
| 57 | the other program under the scope of these terms. | ||
| 58 | |||
| 59 | 3. You may copy and distribute this program (or a portion or derivative | ||
| 60 | of it, under Paragraph 2) in object code or executable form under the terms | ||
| 61 | of Paragraphs 1 and 2 above provided that you also do one of the following: | ||
| 62 | |||
| 63 | a) accompany it with the complete corresponding machine-readable | ||
| 64 | source code, which must be distributed under the terms of | ||
| 65 | Paragraphs 1 and 2 above; or, | ||
| 66 | |||
| 67 | b) accompany it with a written offer, valid for at least three | ||
| 68 | years, to give any third party free (except for a nominal | ||
| 69 | shipping charge) a complete machine-readable copy of the | ||
| 70 | corresponding source code, to be distributed under the terms of | ||
| 71 | Paragraphs 1 and 2 above; or, | ||
| 72 | |||
| 73 | c) accompany it with the information you received as to where the | ||
| 74 | corresponding source code may be obtained. (This alternative is | ||
| 75 | allowed only for noncommercial distribution and only if you | ||
| 76 | received the program in object code or executable form alone.) | ||
| 77 | |||
| 78 | For an executable file, complete source code means all the source code for | ||
| 79 | all modules it contains; but, as a special exception, it need not include | ||
| 80 | source code for modules which are standard libraries that accompany the | ||
| 81 | operating system on which the executable file runs. | ||
| 82 | |||
| 83 | 4. You may not copy, sublicense, distribute or transfer this program | ||
| 84 | except as expressly provided under this License Agreement. Any attempt | ||
| 85 | otherwise to copy, sublicense, distribute or transfer this program is void and | ||
| 86 | your rights to use the program under this License agreement shall be | ||
| 87 | automatically terminated. However, parties who have received computer | ||
| 88 | software programs from you with this License Agreement will not have | ||
| 89 | their licenses terminated so long as such parties remain in full compliance. | ||
| 90 | |||
| 91 | 5. If you wish to incorporate parts of this program into other free | ||
| 92 | programs whose distribution conditions are different, write to the Free | ||
| 93 | Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet | ||
| 94 | worked out a simple rule that can be stated here, but we will often permit | ||
| 95 | this. We will be guided by the two goals of preserving the free status of | ||
| 96 | all derivatives of our free software and of promoting the sharing and reuse of | ||
| 97 | software. | ||
| 98 | 3 | ||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2, or (at your option) | ||
| 7 | any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 99 | 17 | ||
| 100 | In other words, you are welcome to use, share and improve this program. | 18 | In other words, you are welcome to use, share and improve this program. |
| 101 | You are forbidden to forbid anyone else to use, share and improve | 19 | You are forbidden to forbid anyone else to use, share and improve |
| @@ -397,7 +315,100 @@ Filesz Memsz Flags Align | |||
| 397 | 315 | ||
| 398 | 316 | ||
| 399 | */ | 317 | */ |
| 318 | |||
| 319 | /* Modified by wtien@urbana.mcd.mot.com of Motorola Inc. | ||
| 320 | * | ||
| 321 | * The above mechanism does not work if the unexeced ELF file is being | ||
| 322 | * re-layout by other applications (such as `strip'). All the applications | ||
| 323 | * that re-layout the internal of ELF will layout all sections in ascending | ||
| 324 | * order of their file offsets. After the re-layout, the data2 section will | ||
| 325 | * still be the LAST section in the section header vector, but its file offset | ||
| 326 | * is now being pushed far away down, and causes part of it not to be mapped | ||
| 327 | * in (ie. not covered by the load segment entry in PHDR vector), therefore | ||
| 328 | * causes the new binary to fail. | ||
| 329 | * | ||
| 330 | * The solution is to modify the unexec algorithm to insert the new data2 | ||
| 331 | * section header right before the new bss section header, so their file | ||
| 332 | * offsets will be in the ascending order. Since some of the section's (all | ||
| 333 | * sections AFTER the bss section) indexes are now changed, we also need to | ||
| 334 | * modify some fields to make them point to the right sections. This is done | ||
| 335 | * by macro PATCH_INDEX. All the fields that need to be patched are: | ||
| 336 | * | ||
| 337 | * 1. ELF header e_shstrndx field. | ||
| 338 | * 2. section header sh_link and sh_info field. | ||
| 339 | * 3. symbol table entry st_shndx field. | ||
| 340 | * | ||
| 341 | * The above example now should look like: | ||
| 342 | |||
| 343 | **** SECTION HEADER TABLE **** | ||
| 344 | [No] Type Flags Addr Offset Size Name | ||
| 345 | Link Info Adralgn Entsize | ||
| 346 | |||
| 347 | [1] 1 2 0x80480d4 0xd4 0x13 .interp | ||
| 348 | 0 0 0x1 0 | ||
| 400 | 349 | ||
| 350 | [2] 5 2 0x80480e8 0xe8 0x388 .hash | ||
| 351 | 3 0 0x4 0x4 | ||
| 352 | |||
| 353 | [3] 11 2 0x8048470 0x470 0x7f0 .dynsym | ||
| 354 | 4 1 0x4 0x10 | ||
| 355 | |||
| 356 | [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr | ||
| 357 | 0 0 0x1 0 | ||
| 358 | |||
| 359 | [5] 9 2 0x8049010 0x1010 0x338 .rel.plt | ||
| 360 | 3 7 0x4 0x8 | ||
| 361 | |||
| 362 | [6] 1 6 0x8049348 0x1348 0x3 .init | ||
| 363 | 0 0 0x4 0 | ||
| 364 | |||
| 365 | [7] 1 6 0x804934c 0x134c 0x680 .plt | ||
| 366 | 0 0 0x4 0x4 | ||
| 367 | |||
| 368 | [8] 1 6 0x80499cc 0x19cc 0x3c56f .text | ||
| 369 | 0 0 0x4 0 | ||
| 370 | |||
| 371 | [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini | ||
| 372 | 0 0 0x4 0 | ||
| 373 | |||
| 374 | [10] 1 2 0x8085f40 0x3df40 0x69c .rodata | ||
| 375 | 0 0 0x4 0 | ||
| 376 | |||
| 377 | [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 | ||
| 378 | 0 0 0x4 0 | ||
| 379 | |||
| 380 | [12] 1 3 0x8088330 0x3f330 0x20afc .data | ||
| 381 | 0 0 0x4 0 | ||
| 382 | |||
| 383 | [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 | ||
| 384 | 0 0 0x4 0 | ||
| 385 | |||
| 386 | [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got | ||
| 387 | 0 0 0x4 0x4 | ||
| 388 | |||
| 389 | [15] 6 3 0x80a9874 0x60874 0x80 .dynamic | ||
| 390 | 4 0 0x4 0x8 | ||
| 391 | |||
| 392 | [16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data | ||
| 393 | 0 0 0x4 0 | ||
| 394 | |||
| 395 | [17] 8 3 0x80c6800 0x7d800 0 .bss | ||
| 396 | 0 0 0x4 0 | ||
| 397 | |||
| 398 | [18] 2 0 0 0x7d800 0x9b90 .symtab | ||
| 399 | 19 371 0x4 0x10 | ||
| 400 | |||
| 401 | [19] 3 0 0 0x87390 0x8526 .strtab | ||
| 402 | 0 0 0x1 0 | ||
| 403 | |||
| 404 | [20] 3 0 0 0x8f8b6 0x93 .shstrtab | ||
| 405 | 0 0 0x1 0 | ||
| 406 | |||
| 407 | [21] 1 0 0 0x8f949 0x68b7 .comment | ||
| 408 | 0 0 0x1 0 | ||
| 409 | |||
| 410 | */ | ||
| 411 | |||
| 401 | #include <sys/types.h> | 412 | #include <sys/types.h> |
| 402 | #include <stdio.h> | 413 | #include <stdio.h> |
| 403 | #include <sys/stat.h> | 414 | #include <sys/stat.h> |
| @@ -428,8 +439,24 @@ extern void fatal(char *, ...); | |||
| 428 | #define NEW_PROGRAM_H(n) \ | 439 | #define NEW_PROGRAM_H(n) \ |
| 429 | (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) | 440 | (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) |
| 430 | 441 | ||
| 442 | #define PATCH_INDEX(n) \ | ||
| 443 | do { \ | ||
| 444 | if ((n) >= old_bss_index) \ | ||
| 445 | (n)++; } while (0) | ||
| 431 | typedef unsigned char byte; | 446 | typedef unsigned char byte; |
| 432 | 447 | ||
| 448 | /* Round X up to a multiple of Y. */ | ||
| 449 | |||
| 450 | int | ||
| 451 | round_up (x, y) | ||
| 452 | int x, y; | ||
| 453 | { | ||
| 454 | int rem = x % y; | ||
| 455 | if (rem == 0) | ||
| 456 | return x; | ||
| 457 | return x - rem + y; | ||
| 458 | } | ||
| 459 | |||
| 433 | /* **************************************************************** | 460 | /* **************************************************************** |
| 434 | * unexec | 461 | * unexec |
| 435 | * | 462 | * |
| @@ -465,7 +492,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 465 | Elf32_Off new_data2_offset; | 492 | Elf32_Off new_data2_offset; |
| 466 | Elf32_Addr new_data2_addr; | 493 | Elf32_Addr new_data2_addr; |
| 467 | 494 | ||
| 468 | int n, old_bss_index, old_data_index, new_data2_index; | 495 | int n, nn, old_bss_index, old_data_index, new_data2_index; |
| 469 | struct stat stat_buf; | 496 | struct stat stat_buf; |
| 470 | 497 | ||
| 471 | /* Open the old file & map it into the address space. */ | 498 | /* Open the old file & map it into the address space. */ |
| @@ -570,8 +597,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 570 | memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); | 597 | memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); |
| 571 | memcpy (new_program_h, old_program_h, | 598 | memcpy (new_program_h, old_program_h, |
| 572 | old_file_h->e_phnum * old_file_h->e_phentsize); | 599 | old_file_h->e_phnum * old_file_h->e_phentsize); |
| 573 | memcpy (new_section_h, old_section_h, | 600 | |
| 574 | old_file_h->e_shnum * old_file_h->e_shentsize); | 601 | /* Modify the e_shstrndx if necessary. */ |
| 602 | PATCH_INDEX (new_file_h->e_shstrndx); | ||
| 575 | 603 | ||
| 576 | /* Fix up file header. We'll add one section. Section header is | 604 | /* Fix up file header. We'll add one section. Section header is |
| 577 | * further away now. | 605 | * further away now. |
| @@ -597,12 +625,19 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 597 | 625 | ||
| 598 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) | 626 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) |
| 599 | { | 627 | { |
| 628 | /* Compute maximum of all requirements for alignment of section. */ | ||
| 629 | int alignment = (NEW_PROGRAM_H (n)).p_align; | ||
| 630 | if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) | ||
| 631 | alignment = OLD_SECTION_H (old_bss_index).sh_addralign; | ||
| 632 | |||
| 600 | if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr) | 633 | if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr) |
| 601 | fatal ("Program segment above .bss in %s\n", old_name, 0); | 634 | fatal ("Program segment above .bss in %s\n", old_name, 0); |
| 602 | 635 | ||
| 603 | if (NEW_PROGRAM_H(n).p_type == PT_LOAD | 636 | if (NEW_PROGRAM_H(n).p_type == PT_LOAD |
| 604 | && (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz | 637 | && (round_up ((NEW_PROGRAM_H (n)).p_vaddr |
| 605 | == old_bss_addr)) | 638 | + (NEW_PROGRAM_H (n)).p_filesz, |
| 639 | alignment) | ||
| 640 | == round_up (old_bss_addr, alignment))) | ||
| 606 | break; | 641 | break; |
| 607 | } | 642 | } |
| 608 | if (n < 0) | 643 | if (n < 0) |
| @@ -629,19 +664,6 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 629 | * is set. data2 section header gets added by copying the existing | 664 | * is set. data2 section header gets added by copying the existing |
| 630 | * .data header and modifying the offset, address and size. | 665 | * .data header and modifying the offset, address and size. |
| 631 | */ | 666 | */ |
| 632 | |||
| 633 | for (n = 1; n < new_file_h->e_shnum; n++) | ||
| 634 | { | ||
| 635 | if (NEW_SECTION_H(n).sh_offset >= new_data2_offset) | ||
| 636 | NEW_SECTION_H(n).sh_offset += new_data2_size; | ||
| 637 | |||
| 638 | if (NEW_SECTION_H(n).sh_addr | ||
| 639 | && NEW_SECTION_H(n).sh_addr >= new_data2_addr) | ||
| 640 | NEW_SECTION_H(n).sh_addr += new_data2_size - old_bss_size; | ||
| 641 | } | ||
| 642 | |||
| 643 | new_data2_index = old_file_h->e_shnum; | ||
| 644 | |||
| 645 | for (old_data_index = 1; old_data_index < old_file_h->e_shnum; | 667 | for (old_data_index = 1; old_data_index < old_file_h->e_shnum; |
| 646 | old_data_index++) | 668 | old_data_index++) |
| 647 | if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name, | 669 | if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name, |
| @@ -650,38 +672,98 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 650 | if (old_data_index == old_file_h->e_shnum) | 672 | if (old_data_index == old_file_h->e_shnum) |
| 651 | fatal ("Can't find .data in %s.\n", old_name, 0); | 673 | fatal ("Can't find .data in %s.\n", old_name, 0); |
| 652 | 674 | ||
| 653 | memcpy (&NEW_SECTION_H(new_data2_index), &OLD_SECTION_H(old_data_index), | 675 | /* Walk through all section headers, insert the new data2 section right |
| 654 | new_file_h->e_shentsize); | 676 | before the new bss section. */ |
| 655 | 677 | for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) | |
| 656 | NEW_SECTION_H(new_data2_index).sh_addr = new_data2_addr; | ||
| 657 | NEW_SECTION_H(new_data2_index).sh_offset = new_data2_offset; | ||
| 658 | NEW_SECTION_H(new_data2_index).sh_size = new_data2_size; | ||
| 659 | |||
| 660 | NEW_SECTION_H(old_bss_index).sh_size = 0; | ||
| 661 | NEW_SECTION_H(old_bss_index).sh_addr = new_data2_addr + new_data2_size; | ||
| 662 | |||
| 663 | /* Write out the sections. .data and .data1 (and data2, called | ||
| 664 | * ".data" in the strings table) get copied from the current process | ||
| 665 | * instead of the old file. | ||
| 666 | */ | ||
| 667 | |||
| 668 | for (n = new_file_h->e_shnum - 1; n; n--) | ||
| 669 | { | 678 | { |
| 670 | caddr_t src; | 679 | caddr_t src; |
| 671 | 680 | /* If it is bss section, insert the new data2 section before it. */ | |
| 672 | if (NEW_SECTION_H(n).sh_type == SHT_NULL | 681 | if (n == old_bss_index) |
| 673 | || NEW_SECTION_H(n).sh_type == SHT_NOBITS) | 682 | { |
| 683 | /* Steal the data section header for this data2 section. */ | ||
| 684 | memcpy (&NEW_SECTION_H(nn), &OLD_SECTION_H(old_data_index), | ||
| 685 | new_file_h->e_shentsize); | ||
| 686 | |||
| 687 | NEW_SECTION_H(nn).sh_addr = new_data2_addr; | ||
| 688 | NEW_SECTION_H(nn).sh_offset = new_data2_offset; | ||
| 689 | NEW_SECTION_H(nn).sh_size = new_data2_size; | ||
| 690 | /* Use the bss section's alignment. This will assure that the | ||
| 691 | new data2 section always be placed in the same spot as the old | ||
| 692 | bss section by any other application. */ | ||
| 693 | NEW_SECTION_H(nn).sh_addralign = OLD_SECTION_H(n).sh_addralign; | ||
| 694 | |||
| 695 | /* Now copy over what we have in the memory now. */ | ||
| 696 | memcpy (NEW_SECTION_H(nn).sh_offset + new_base, | ||
| 697 | (caddr_t) OLD_SECTION_H(n).sh_addr, | ||
| 698 | new_data2_size); | ||
| 699 | nn++; | ||
| 700 | } | ||
| 701 | |||
| 702 | memcpy (&NEW_SECTION_H(nn), &OLD_SECTION_H(n), | ||
| 703 | old_file_h->e_shentsize); | ||
| 704 | |||
| 705 | /* The new bss section's size is zero, and its file offset and virtual | ||
| 706 | address should be off by NEW_DATA2_SIZE. */ | ||
| 707 | if (n == old_bss_index) | ||
| 708 | { | ||
| 709 | /* NN should be `old_bss_index + 1' at this point. */ | ||
| 710 | NEW_SECTION_H(nn).sh_offset += new_data2_size; | ||
| 711 | NEW_SECTION_H(nn).sh_addr += new_data2_size; | ||
| 712 | /* Let the new bss section address alignment be the same as the | ||
| 713 | section address alignment followed the old bss section, so | ||
| 714 | this section will be placed in exactly the same place. */ | ||
| 715 | NEW_SECTION_H(nn).sh_addralign = OLD_SECTION_H(nn).sh_addralign; | ||
| 716 | NEW_SECTION_H(nn).sh_size = 0; | ||
| 717 | } | ||
| 718 | /* Any section that was original placed AFTER the bss section should now | ||
| 719 | be off by NEW_DATA2_SIZE. */ | ||
| 720 | else if (NEW_SECTION_H(nn).sh_offset >= new_data2_offset) | ||
| 721 | NEW_SECTION_H(nn).sh_offset += new_data2_size; | ||
| 722 | |||
| 723 | /* If any section hdr refers to the section after the new .data | ||
| 724 | section, make it refer to next one because we have inserted | ||
| 725 | a new section in between. */ | ||
| 726 | |||
| 727 | PATCH_INDEX(NEW_SECTION_H(nn).sh_link); | ||
| 728 | PATCH_INDEX(NEW_SECTION_H(nn).sh_info); | ||
| 729 | |||
| 730 | /* Now, start to copy the content of sections. */ | ||
| 731 | if (NEW_SECTION_H(nn).sh_type == SHT_NULL | ||
| 732 | || NEW_SECTION_H(nn).sh_type == SHT_NOBITS) | ||
| 674 | continue; | 733 | continue; |
| 675 | 734 | ||
| 735 | /* Write out the sections. .data and .data1 (and data2, called | ||
| 736 | * ".data" in the strings table) get copied from the current process | ||
| 737 | * instead of the old file. | ||
| 738 | */ | ||
| 676 | if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data") | 739 | if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data") |
| 677 | || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), | 740 | || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), |
| 678 | ".data1")) | 741 | ".data1")) |
| 679 | src = (caddr_t) NEW_SECTION_H(n).sh_addr; | 742 | src = (caddr_t) OLD_SECTION_H(n).sh_addr; |
| 680 | else | 743 | else |
| 681 | src = old_base + OLD_SECTION_H(n).sh_offset; | 744 | src = old_base + OLD_SECTION_H(n).sh_offset; |
| 682 | 745 | ||
| 683 | memcpy (NEW_SECTION_H(n).sh_offset + new_base, src, | 746 | memcpy (NEW_SECTION_H(nn).sh_offset + new_base, src, |
| 684 | NEW_SECTION_H(n).sh_size); | 747 | NEW_SECTION_H(nn).sh_size); |
| 748 | |||
| 749 | /* If it is the symbol table, its st_shndx field needs to be patched. */ | ||
| 750 | if (NEW_SECTION_H(nn).sh_type == SHT_SYMTAB | ||
| 751 | || NEW_SECTION_H(nn).sh_type == SHT_DYNSYM) | ||
| 752 | { | ||
| 753 | Elf32_Shdr *spt = &NEW_SECTION_H(nn); | ||
| 754 | unsigned int num = spt->sh_size / spt->sh_entsize; | ||
| 755 | Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H(nn).sh_offset + | ||
| 756 | new_base); | ||
| 757 | for (; num--; sym++) | ||
| 758 | { | ||
| 759 | if ((sym->st_shndx == SHN_UNDEF) | ||
| 760 | || (sym->st_shndx == SHN_ABS) | ||
| 761 | || (sym->st_shndx == SHN_COMMON)) | ||
| 762 | continue; | ||
| 763 | |||
| 764 | PATCH_INDEX(sym->st_shndx); | ||
| 765 | } | ||
| 766 | } | ||
| 685 | } | 767 | } |
| 686 | 768 | ||
| 687 | /* Close the files and make the new file executable */ | 769 | /* Close the files and make the new file executable */ |