comparison src/unexelf.c @ 4505:348f6a32d9b5

(unexec): Add casts for some comparisons. (PATCH_INDEX): Likewise.
author Richard M. Stallman <rms@gnu.org>
date Tue, 10 Aug 1993 01:32:23 +0000
parents 9b80d7737d2b
children cff556bf85e8
comparison
equal deleted inserted replaced
4504:65ef94a9e2c4 4505:348f6a32d9b5
419 #include <fcntl.h> 419 #include <fcntl.h>
420 #include <elf.h> 420 #include <elf.h>
421 #include <sys/mman.h> 421 #include <sys/mman.h>
422 422
423 #ifndef emacs 423 #ifndef emacs
424 #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) 424 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
425 #else 425 #else
426 extern void fatal(char *, ...); 426 extern void fatal (char *, ...);
427 #endif 427 #endif
428 428
429 /* Get the address of a particular section or program header entry, 429 /* Get the address of a particular section or program header entry,
430 * accounting for the size of the entries. 430 * accounting for the size of the entries.
431 */ 431 */
439 #define NEW_PROGRAM_H(n) \ 439 #define NEW_PROGRAM_H(n) \
440 (*(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)))
441 441
442 #define PATCH_INDEX(n) \ 442 #define PATCH_INDEX(n) \
443 do { \ 443 do { \
444 if ((n) >= old_bss_index) \ 444 if ((int) (n) >= old_bss_index) \
445 (n)++; } while (0) 445 (n)++; } while (0)
446 typedef unsigned char byte; 446 typedef unsigned char byte;
447 447
448 /* Round X up to a multiple of Y. */ 448 /* Round X up to a multiple of Y. */
449 449
501 501
502 if (old_file < 0) 502 if (old_file < 0)
503 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 503 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
504 504
505 if (fstat (old_file, &stat_buf) == -1) 505 if (fstat (old_file, &stat_buf) == -1)
506 fatal ("Can't fstat(%s): errno %d\n", old_name, errno); 506 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
507 507
508 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0); 508 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
509 509
510 if (old_base == (caddr_t) -1) 510 if (old_base == (caddr_t) -1)
511 fatal ("Can't mmap(%s): errno %d\n", old_name, errno); 511 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
512 512
513 #ifdef DEBUG 513 #ifdef DEBUG
514 fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size, 514 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size,
515 old_base); 515 old_base);
516 #endif 516 #endif
517 517
518 /* Get pointers to headers & section names */ 518 /* Get pointers to headers & section names */
519 519
520 old_file_h = (Elf32_Ehdr *) old_base; 520 old_file_h = (Elf32_Ehdr *) old_base;
521 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); 521 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
522 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); 522 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
523 old_section_names = (char *) old_base 523 old_section_names = (char *) old_base
524 + OLD_SECTION_H(old_file_h->e_shstrndx).sh_offset; 524 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
525 525
526 /* Find the old .bss section. Figure out parameters of the new 526 /* Find the old .bss section. Figure out parameters of the new
527 * data2 and bss sections. 527 * data2 and bss sections.
528 */ 528 */
529 529
530 for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++) 530 for (old_bss_index = 1; old_bss_index < (int) old_file_h->e_shnum;
531 old_bss_index++)
531 { 532 {
532 #ifdef DEBUG 533 #ifdef DEBUG
533 fprintf (stderr, "Looking for .bss - found %s\n", 534 fprintf (stderr, "Looking for .bss - found %s\n",
534 old_section_names + OLD_SECTION_H(old_bss_index).sh_name); 535 old_section_names + OLD_SECTION_H (old_bss_index).sh_name);
535 #endif 536 #endif
536 if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name, 537 if (!strcmp (old_section_names + OLD_SECTION_H (old_bss_index).sh_name,
537 ".bss")) 538 ".bss"))
538 break; 539 break;
539 } 540 }
540 if (old_bss_index == old_file_h->e_shnum) 541 if (old_bss_index == old_file_h->e_shnum)
541 fatal ("Can't find .bss in %s.\n", old_name, 0); 542 fatal ("Can't find .bss in %s.\n", old_name, 0);
542 543
543 old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr; 544 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
544 old_bss_size = OLD_SECTION_H(old_bss_index).sh_size; 545 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
545 #if defined(emacs) || !defined(DEBUG) 546 #if defined(emacs) || !defined(DEBUG)
546 bss_end = (unsigned int) sbrk (0); 547 bss_end = (unsigned int) sbrk (0);
547 new_bss_addr = (Elf32_Addr) bss_end; 548 new_bss_addr = (Elf32_Addr) bss_end;
548 #else 549 #else
549 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 550 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
550 #endif 551 #endif
551 new_data2_addr = old_bss_addr; 552 new_data2_addr = old_bss_addr;
552 new_data2_size = new_bss_addr - old_bss_addr; 553 new_data2_size = new_bss_addr - old_bss_addr;
553 new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset; 554 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
554 555
555 #ifdef DEBUG 556 #ifdef DEBUG
556 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 557 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
557 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 558 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
558 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 559 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
563 #endif 564 #endif
564 565
565 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 566 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
566 fatal (".bss shrank when undumping???\n", 0, 0); 567 fatal (".bss shrank when undumping???\n", 0, 0);
567 568
568 /* Set the output file to the right size and mmap(2) it. Set 569 /* Set the output file to the right size and mmap it. Set
569 * pointers to various interesting objects. stat_buf still has 570 * pointers to various interesting objects. stat_buf still has
570 * old_file data. 571 * old_file data.
571 */ 572 */
572 573
573 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 574 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
574 if (new_file < 0) 575 if (new_file < 0)
575 fatal ("Can't creat(%s): errno %d\n", new_name, errno); 576 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
576 577
577 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size; 578 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
578 579
579 if (ftruncate (new_file, new_file_size)) 580 if (ftruncate (new_file, new_file_size))
580 fatal ("Can't ftruncate(%s): errno %d\n", new_name, errno); 581 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
581 582
582 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, 583 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
583 new_file, 0); 584 new_file, 0);
584 585
585 if (new_base == (caddr_t) -1) 586 if (new_base == (caddr_t) -1)
586 fatal ("Can't mmap(%s): errno %d\n", new_name, errno); 587 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
587 588
588 new_file_h = (Elf32_Ehdr *) new_base; 589 new_file_h = (Elf32_Ehdr *) new_base;
589 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); 590 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
590 new_section_h = (Elf32_Shdr *) 591 new_section_h = (Elf32_Shdr *)
591 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); 592 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
628 /* Compute maximum of all requirements for alignment of section. */ 629 /* Compute maximum of all requirements for alignment of section. */
629 int alignment = (NEW_PROGRAM_H (n)).p_align; 630 int alignment = (NEW_PROGRAM_H (n)).p_align;
630 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 631 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
631 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 632 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
632 633
633 if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr) 634 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
634 fatal ("Program segment above .bss in %s\n", old_name, 0); 635 fatal ("Program segment above .bss in %s\n", old_name, 0);
635 636
636 if (NEW_PROGRAM_H(n).p_type == PT_LOAD 637 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
637 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 638 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
638 + (NEW_PROGRAM_H (n)).p_filesz, 639 + (NEW_PROGRAM_H (n)).p_filesz,
639 alignment) 640 alignment)
640 == round_up (old_bss_addr, alignment))) 641 == round_up (old_bss_addr, alignment)))
641 break; 642 break;
642 } 643 }
643 if (n < 0) 644 if (n < 0)
644 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0); 645 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
645 646
646 NEW_PROGRAM_H(n).p_filesz += new_data2_size; 647 NEW_PROGRAM_H (n).p_filesz += new_data2_size;
647 NEW_PROGRAM_H(n).p_memsz = NEW_PROGRAM_H(n).p_filesz; 648 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
648 649
649 #if 0 /* Maybe allow section after data2 - does this ever happen? */ 650 #if 0 /* Maybe allow section after data2 - does this ever happen? */
650 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 651 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
651 { 652 {
652 if (NEW_PROGRAM_H(n).p_vaddr 653 if (NEW_PROGRAM_H (n).p_vaddr
653 && NEW_PROGRAM_H(n).p_vaddr >= new_data2_addr) 654 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
654 NEW_PROGRAM_H(n).p_vaddr += new_data2_size - old_bss_size; 655 NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
655 656
656 if (NEW_PROGRAM_H(n).p_offset >= new_data2_offset) 657 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
657 NEW_PROGRAM_H(n).p_offset += new_data2_size; 658 NEW_PROGRAM_H (n).p_offset += new_data2_size;
658 } 659 }
659 #endif 660 #endif
660 661
661 /* Fix up section headers based on new .data2 section. Any section 662 /* Fix up section headers based on new .data2 section. Any section
662 * whose offset or virtual address is after the new .data2 section 663 * whose offset or virtual address is after the new .data2 section
663 * gets its value adjusted. .bss size becomes zero and new address 664 * gets its value adjusted. .bss size becomes zero and new address
664 * is set. data2 section header gets added by copying the existing 665 * is set. data2 section header gets added by copying the existing
665 * .data header and modifying the offset, address and size. 666 * .data header and modifying the offset, address and size.
666 */ 667 */
667 for (old_data_index = 1; old_data_index < old_file_h->e_shnum; 668 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
668 old_data_index++) 669 old_data_index++)
669 if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name, 670 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
670 ".data")) 671 ".data"))
671 break; 672 break;
672 if (old_data_index == old_file_h->e_shnum) 673 if (old_data_index == old_file_h->e_shnum)
673 fatal ("Can't find .data in %s.\n", old_name, 0); 674 fatal ("Can't find .data in %s.\n", old_name, 0);
674 675
675 /* Walk through all section headers, insert the new data2 section right 676 /* Walk through all section headers, insert the new data2 section right
676 before the new bss section. */ 677 before the new bss section. */
677 for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) 678 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
678 { 679 {
679 caddr_t src; 680 caddr_t src;
680 /* If it is bss section, insert the new data2 section before it. */ 681 /* If it is bss section, insert the new data2 section before it. */
681 if (n == old_bss_index) 682 if (n == old_bss_index)
682 { 683 {
683 /* Steal the data section header for this data2 section. */ 684 /* Steal the data section header for this data2 section. */
684 memcpy (&NEW_SECTION_H(nn), &OLD_SECTION_H(old_data_index), 685 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
685 new_file_h->e_shentsize); 686 new_file_h->e_shentsize);
686 687
687 NEW_SECTION_H(nn).sh_addr = new_data2_addr; 688 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_offset = new_data2_offset;
689 NEW_SECTION_H(nn).sh_size = new_data2_size; 690 NEW_SECTION_H (nn).sh_size = new_data2_size;
690 /* Use the bss section's alignment. This will assure that the 691 /* 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 new data2 section always be placed in the same spot as the old
692 bss section by any other application. */ 693 bss section by any other application. */
693 NEW_SECTION_H(nn).sh_addralign = OLD_SECTION_H(n).sh_addralign; 694 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
694 695
695 /* Now copy over what we have in the memory now. */ 696 /* Now copy over what we have in the memory now. */
696 memcpy (NEW_SECTION_H(nn).sh_offset + new_base, 697 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
697 (caddr_t) OLD_SECTION_H(n).sh_addr, 698 (caddr_t) OLD_SECTION_H (n).sh_addr,
698 new_data2_size); 699 new_data2_size);
699 nn++; 700 nn++;
700 } 701 }
701 702
702 memcpy (&NEW_SECTION_H(nn), &OLD_SECTION_H(n), 703 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
703 old_file_h->e_shentsize); 704 old_file_h->e_shentsize);
704 705
705 /* The new bss section's size is zero, and its file offset and virtual 706 /* The new bss section's size is zero, and its file offset and virtual
706 address should be off by NEW_DATA2_SIZE. */ 707 address should be off by NEW_DATA2_SIZE. */
707 if (n == old_bss_index) 708 if (n == old_bss_index)
708 { 709 {
709 /* NN should be `old_bss_index + 1' at this point. */ 710 /* 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_offset += new_data2_size;
711 NEW_SECTION_H(nn).sh_addr += new_data2_size; 712 NEW_SECTION_H (nn).sh_addr += new_data2_size;
712 /* Let the new bss section address alignment be the same as the 713 /* Let the new bss section address alignment be the same as the
713 section address alignment followed the old bss section, so 714 section address alignment followed the old bss section, so
714 this section will be placed in exactly the same place. */ 715 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_addralign = OLD_SECTION_H (nn).sh_addralign;
716 NEW_SECTION_H(nn).sh_size = 0; 717 NEW_SECTION_H (nn).sh_size = 0;
717 } 718 }
718 /* Any section that was original placed AFTER the bss section should now 719 /* Any section that was original placed AFTER the bss section should now
719 be off by NEW_DATA2_SIZE. */ 720 be off by NEW_DATA2_SIZE. */
720 else if (NEW_SECTION_H(nn).sh_offset >= new_data2_offset) 721 else if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
721 NEW_SECTION_H(nn).sh_offset += new_data2_size; 722 NEW_SECTION_H (nn).sh_offset += new_data2_size;
722 723
723 /* If any section hdr refers to the section after the new .data 724 /* 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 section, make it refer to next one because we have inserted
725 a new section in between. */ 726 a new section in between. */
726 727
727 PATCH_INDEX(NEW_SECTION_H(nn).sh_link); 728 PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
728 PATCH_INDEX(NEW_SECTION_H(nn).sh_info); 729 PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
729 730
730 /* Now, start to copy the content of sections. */ 731 /* Now, start to copy the content of sections. */
731 if (NEW_SECTION_H(nn).sh_type == SHT_NULL 732 if (NEW_SECTION_H (nn).sh_type == SHT_NULL
732 || NEW_SECTION_H(nn).sh_type == SHT_NOBITS) 733 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
733 continue; 734 continue;
734 735
735 /* Write out the sections. .data and .data1 (and data2, called 736 /* Write out the sections. .data and .data1 (and data2, called
736 * ".data" in the strings table) get copied from the current process 737 * ".data" in the strings table) get copied from the current process
737 * instead of the old file. 738 * instead of the old file.
738 */ 739 */
739 if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data") 740 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
740 || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), 741 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
741 ".data1")) 742 ".data1"))
742 src = (caddr_t) OLD_SECTION_H(n).sh_addr; 743 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
743 else 744 else
744 src = old_base + OLD_SECTION_H(n).sh_offset; 745 src = old_base + OLD_SECTION_H (n).sh_offset;
745 746
746 memcpy (NEW_SECTION_H(nn).sh_offset + new_base, src, 747 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
747 NEW_SECTION_H(nn).sh_size); 748 NEW_SECTION_H (nn).sh_size);
748 749
749 /* If it is the symbol table, its st_shndx field needs to be patched. */ 750 /* 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 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
751 || NEW_SECTION_H(nn).sh_type == SHT_DYNSYM) 752 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
752 { 753 {
753 Elf32_Shdr *spt = &NEW_SECTION_H(nn); 754 Elf32_Shdr *spt = &NEW_SECTION_H (nn);
754 unsigned int num = spt->sh_size / spt->sh_entsize; 755 unsigned int num = spt->sh_size / spt->sh_entsize;
755 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H(nn).sh_offset + 756 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset +
756 new_base); 757 new_base);
757 for (; num--; sym++) 758 for (; num--; sym++)
758 { 759 {
759 if ((sym->st_shndx == SHN_UNDEF) 760 if ((sym->st_shndx == SHN_UNDEF)
760 || (sym->st_shndx == SHN_ABS) 761 || (sym->st_shndx == SHN_ABS)
761 || (sym->st_shndx == SHN_COMMON)) 762 || (sym->st_shndx == SHN_COMMON))
762 continue; 763 continue;
763 764
764 PATCH_INDEX(sym->st_shndx); 765 PATCH_INDEX (sym->st_shndx);
765 } 766 }
766 } 767 }
767 } 768 }
768 769
769 /* Close the files and make the new file executable */ 770 /* Close the files and make the new file executable */
770 771
771 if (close (old_file)) 772 if (close (old_file))
772 fatal ("Can't close(%s): errno %d\n", old_name, errno); 773 fatal ("Can't close (%s): errno %d\n", old_name, errno);
773 774
774 if (close (new_file)) 775 if (close (new_file))
775 fatal ("Can't close(%s): errno %d\n", new_name, errno); 776 fatal ("Can't close (%s): errno %d\n", new_name, errno);
776 777
777 if (stat (new_name, &stat_buf) == -1) 778 if (stat (new_name, &stat_buf) == -1)
778 fatal ("Can't stat(%s): errno %d\n", new_name, errno); 779 fatal ("Can't stat (%s): errno %d\n", new_name, errno);
779 780
780 n = umask (777); 781 n = umask (777);
781 umask (n); 782 umask (n);
782 stat_buf.st_mode |= 0111 & ~n; 783 stat_buf.st_mode |= 0111 & ~n;
783 if (chmod (new_name, stat_buf.st_mode) == -1) 784 if (chmod (new_name, stat_buf.st_mode) == -1)
784 fatal ("Can't chmod(%s): errno %d\n", new_name, errno); 785 fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
785 } 786 }