aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-05-05 21:52:00 -0700
committerPaul Eggert2013-05-05 21:52:00 -0700
commit5ee94506f6ee4f5142bfeabc9409f95e370d38e3 (patch)
tree929f38ea53bd29b1b3141a5d09bfcafa0bb1e8f7 /src
parentdc4a2ee0efe25b03973ea5feb5de9e46560a8127 (diff)
downloademacs-5ee94506f6ee4f5142bfeabc9409f95e370d38e3.tar.gz
emacs-5ee94506f6ee4f5142bfeabc9409f95e370d38e3.zip
* unexelf.c: Fix some 32-bit integer problems, notably when debugging.
Include <limits.h>, <stdbool.h>, <intprops.h>, <verify.h>. Verify that ElfW (Half) fits in int. (fatal): Use same signature as lisp.h. (UNEXELF_DEBUG): New macro, replacing DEBUG, so that people can configure and build with -DUNEXELF_DEBUG without worrying about other modules that use DEBUG. (DEBUG_LOG) [UNEXELF_DEBUG]: New macro. All debug code that prints possibly-wide integers now uses it instead of plain fprintf. (entry_address): New function, which avoids problems with 32-bit overflow on 64-bit hosts. (OLD_SECTION_H, NEW_SECTION_H, NEW_PROGRAM_H): Use it. (round_up): Don't assume the remainder fits in int. (find_section): Use bool for boolean. Simplify debug code. (unexec): Don't assume file sizes fit in int or size_t. Omit unnecessary trailing newline in 'fatal' format. Use strerror rather than outputting decimal error number. Remove unused code when emacs is not defined; this file relies on Emacs now. Don't assume e_phnum and e_shnum are positive.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog21
-rw-r--r--src/unexelf.c175
2 files changed, 115 insertions, 81 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 648a33a6fa1..b6ae117c8b2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,26 @@
12013-05-06 Paul Eggert <eggert@cs.ucla.edu> 12013-05-06 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * unexelf.c: Fix some 32-bit integer problems, notably when debugging.
4 Include <limits.h>, <stdbool.h>, <intprops.h>, <verify.h>.
5 Verify that ElfW (Half) fits in int.
6 (fatal): Use same signature as lisp.h.
7 (UNEXELF_DEBUG): New macro, replacing DEBUG, so that people can
8 configure and build with -DUNEXELF_DEBUG without worrying about
9 other modules that use DEBUG.
10 (DEBUG_LOG) [UNEXELF_DEBUG]: New macro. All debug code that prints
11 possibly-wide integers now uses it instead of plain fprintf.
12 (entry_address): New function, which avoids problems with 32-bit
13 overflow on 64-bit hosts.
14 (OLD_SECTION_H, NEW_SECTION_H, NEW_PROGRAM_H): Use it.
15 (round_up): Don't assume the remainder fits in int.
16 (find_section): Use bool for boolean. Simplify debug code.
17 (unexec): Don't assume file sizes fit in int or size_t.
18 Omit unnecessary trailing newline in 'fatal' format.
19 Use strerror rather than outputting decimal error number.
20 Remove unused code when emacs is not defined;
21 this file relies on Emacs now.
22 Don't assume e_phnum and e_shnum are positive.
23
3 * regex.c: Fix problems when DEBUG is defined. 24 * regex.c: Fix problems when DEBUG is defined.
4 (extract_number, extract_number_and_incr): Define regardless of 25 (extract_number, extract_number_and_incr): Define regardless of
5 whether DEBUG is defined; that's simpler and makes the code less 26 whether DEBUG is defined; that's simpler and makes the code less
diff --git a/src/unexelf.c b/src/unexelf.c
index d3659404f9c..b2a9878b5e9 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -388,16 +388,19 @@ temacs:
388#include <config.h> 388#include <config.h>
389#include <unexec.h> 389#include <unexec.h>
390 390
391extern void fatal (const char *msgid, ...); 391extern _Noreturn void fatal (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
392 392
393#include <sys/types.h> 393#include <errno.h>
394#include <fcntl.h>
395#include <limits.h>
396#include <memory.h>
397#include <stdbool.h>
394#include <stdint.h> 398#include <stdint.h>
395#include <stdio.h> 399#include <stdio.h>
396#include <sys/stat.h> 400#include <sys/stat.h>
397#include <memory.h> 401#include <sys/types.h>
398#include <errno.h>
399#include <unistd.h> 402#include <unistd.h>
400#include <fcntl.h> 403
401#if !defined (__NetBSD__) && !defined (__OpenBSD__) 404#if !defined (__NetBSD__) && !defined (__OpenBSD__)
402#include <elf.h> 405#include <elf.h>
403#endif /* not __NetBSD__ and not __OpenBSD__ */ 406#endif /* not __NetBSD__ and not __OpenBSD__ */
@@ -519,6 +522,17 @@ typedef struct {
519# define ElfW(type) ElfExpandBitsW (ELFSIZE, type) 522# define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
520#endif 523#endif
521 524
525/* The code often converts ElfW (Half) values like e_shentsize to int;
526 check that this doesn't lose information. */
527#include <intprops.h>
528#include <verify.h>
529verify ((! TYPE_SIGNED (ElfW (Half)) || INT_MIN <= TYPE_MINIMUM (ElfW (Half)))
530 && TYPE_MAXIMUM (ElfW (Half)) <= INT_MAX);
531
532#ifdef UNEXELF_DEBUG
533# define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr))
534#endif
535
522/* Get the address of a particular section or program header entry, 536/* Get the address of a particular section or program header entry,
523 * accounting for the size of the entries. 537 * accounting for the size of the entries.
524 */ 538 */
@@ -546,17 +560,25 @@ typedef struct {
546 Apr 23, 1996 560 Apr 23, 1996
547 */ 561 */
548 562
563static void *
564entry_address (void *section_h, int idx, int num, int entsize)
565{
566 char *h = section_h;
567 ptrdiff_t n = idx;
568 return h + entsize * n;
569}
570
549#define OLD_SECTION_H(n) \ 571#define OLD_SECTION_H(n) \
550 (*(ElfW (Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 572 (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shnum, \
573 old_file_h->e_shentsize))
551#define NEW_SECTION_H(n) \ 574#define NEW_SECTION_H(n) \
552 (*(ElfW (Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 575 (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shnum, \
576 new_file_h->e_shentsize))
553#define NEW_PROGRAM_H(n) \ 577#define NEW_PROGRAM_H(n) \
554 (*(ElfW (Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 578 (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phnum, \
579 new_file_h->e_phentsize))
555 580
556#define PATCH_INDEX(n) \ 581#define PATCH_INDEX(n) ((n) += old_bss_index <= (n))
557 do { \
558 if ((int) (n) >= old_bss_index) \
559 (n)++; } while (0)
560typedef unsigned char byte; 582typedef unsigned char byte;
561 583
562/* Round X up to a multiple of Y. */ 584/* Round X up to a multiple of Y. */
@@ -564,7 +586,7 @@ typedef unsigned char byte;
564static ElfW (Addr) 586static ElfW (Addr)
565round_up (ElfW (Addr) x, ElfW (Addr) y) 587round_up (ElfW (Addr) x, ElfW (Addr) y)
566{ 588{
567 int rem = x % y; 589 ElfW (Addr) rem = x % y;
568 if (rem == 0) 590 if (rem == 0)
569 return x; 591 return x;
570 return x - rem + y; 592 return x - rem + y;
@@ -575,33 +597,28 @@ round_up (ElfW (Addr) x, ElfW (Addr) y)
575 about the file we are looking in. 597 about the file we are looking in.
576 598
577 If we don't find the section NAME, that is a fatal error 599 If we don't find the section NAME, that is a fatal error
578 if NOERROR is 0; we return -1 if NOERROR is nonzero. */ 600 if NOERROR is false; return -1 if NOERROR is true. */
579 601
580static int 602static int
581find_section (const char *name, const char *section_names, const char *file_name, 603find_section (const char *name, const char *section_names, const char *file_name,
582 ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, int noerror) 604 ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h,
605 bool noerror)
583{ 606{
584 int idx; 607 int idx;
585 608
586 for (idx = 1; idx < old_file_h->e_shnum; idx++) 609 for (idx = 1; idx < old_file_h->e_shnum; idx++)
587 { 610 {
588#ifdef DEBUG 611 char const *found_name = section_names + OLD_SECTION_H (idx).sh_name;
589 fprintf (stderr, "Looking for %s - found %s\n", name, 612#ifdef UNEXELF_DEBUG
590 section_names + OLD_SECTION_H (idx).sh_name); 613 fprintf (stderr, "Looking for %s - found %s\n", name, found_name);
591#endif 614#endif
592 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name, 615 if (strcmp (name, found_name) == 0)
593 name)) 616 return idx;
594 break;
595 }
596 if (idx == old_file_h->e_shnum)
597 {
598 if (noerror)
599 return -1;
600 else
601 fatal ("Can't find %s in %s.\n", name, file_name);
602 } 617 }
603 618
604 return idx; 619 if (! noerror)
620 fatal ("Can't find %s in %s", name, file_name);
621 return -1;
605} 622}
606 623
607/* **************************************************************** 624/* ****************************************************************
@@ -616,11 +633,9 @@ find_section (const char *name, const char *section_names, const char *file_name
616void 633void
617unexec (const char *new_name, const char *old_name) 634unexec (const char *new_name, const char *old_name)
618{ 635{
619 int new_file, old_file, new_file_size; 636 int new_file, old_file;
620 637 off_t new_file_size;
621#if defined (emacs) || !defined (DEBUG)
622 void *new_break; 638 void *new_break;
623#endif
624 639
625 /* Pointers to the base of the image of the two files. */ 640 /* Pointers to the base of the image of the two files. */
626 caddr_t old_base, new_base; 641 caddr_t old_base, new_base;
@@ -654,7 +669,7 @@ unexec (const char *new_name, const char *old_name)
654 int old_mdebug_index; 669 int old_mdebug_index;
655#endif 670#endif
656 struct stat stat_buf; 671 struct stat stat_buf;
657 int old_file_size; 672 off_t old_file_size;
658 673
659 /* Open the old file, allocate a buffer of the right size, and read 674 /* Open the old file, allocate a buffer of the right size, and read
660 in the file contents. */ 675 in the file contents. */
@@ -662,15 +677,15 @@ unexec (const char *new_name, const char *old_name)
662 old_file = open (old_name, O_RDONLY); 677 old_file = open (old_name, O_RDONLY);
663 678
664 if (old_file < 0) 679 if (old_file < 0)
665 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 680 fatal ("Can't open %s for reading: %s", old_name, strerror (errno));
666 681
667 if (fstat (old_file, &stat_buf) == -1) 682 if (fstat (old_file, &stat_buf) != 0)
668 fatal ("Can't fstat (%s): errno %d\n", old_name, errno); 683 fatal ("Can't fstat (%s): %s", old_name, strerror (errno));
669 684
670#if MAP_ANON == 0 685#if MAP_ANON == 0
671 mmap_fd = open ("/dev/zero", O_RDONLY); 686 mmap_fd = open ("/dev/zero", O_RDONLY);
672 if (mmap_fd < 0) 687 if (mmap_fd < 0)
673 fatal ("Can't open /dev/zero for reading: errno %d\n", errno, 0); 688 fatal ("Can't open /dev/zero for reading: %s", strerror (errno));
674#endif 689#endif
675 690
676 /* We cannot use malloc here because that may use sbrk. If it does, 691 /* We cannot use malloc here because that may use sbrk. If it does,
@@ -678,13 +693,15 @@ unexec (const char *new_name, const char *old_name)
678 extra careful to use the correct value of sbrk(0) after 693 extra careful to use the correct value of sbrk(0) after
679 allocating all buffers in the code below, which we aren't. */ 694 allocating all buffers in the code below, which we aren't. */
680 old_file_size = stat_buf.st_size; 695 old_file_size = stat_buf.st_size;
696 if (! (0 <= old_file_size && old_file_size <= SIZE_MAX))
697 fatal ("File size out of range");
681 old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE, 698 old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE,
682 MAP_ANON | MAP_PRIVATE, mmap_fd, 0); 699 MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
683 if (old_base == MAP_FAILED) 700 if (old_base == MAP_FAILED)
684 fatal ("Can't allocate buffer for %s\n", old_name, 0); 701 fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
685 702
686 if (read (old_file, old_base, stat_buf.st_size) != stat_buf.st_size) 703 if (read (old_file, old_base, old_file_size) != old_file_size)
687 fatal ("Didn't read all of %s: errno %d\n", old_name, errno); 704 fatal ("Didn't read all of %s: %s", old_name, strerror (errno));
688 705
689 /* Get pointers to headers & section names */ 706 /* Get pointers to headers & section names */
690 707
@@ -755,12 +772,8 @@ unexec (const char *new_name, const char *old_name)
755 old_data_index = find_section (".data", old_section_names, 772 old_data_index = find_section (".data", old_section_names,
756 old_name, old_file_h, old_section_h, 0); 773 old_name, old_file_h, old_section_h, 0);
757 774
758#if defined (emacs) || !defined (DEBUG)
759 new_break = sbrk (0); 775 new_break = sbrk (0);
760 new_bss_addr = (ElfW (Addr)) new_break; 776 new_bss_addr = (ElfW (Addr)) new_break;
761#else
762 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
763#endif
764 new_data2_addr = old_bss_addr; 777 new_data2_addr = old_bss_addr;
765 new_data2_size = new_bss_addr - old_bss_addr; 778 new_data2_size = new_bss_addr - old_bss_addr;
766 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset 779 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset
@@ -771,38 +784,38 @@ unexec (const char *new_name, const char *old_name)
771 section) was unaligned. */ 784 section) was unaligned. */
772 new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset); 785 new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset);
773 786
774#ifdef DEBUG 787#ifdef UNEXELF_DEBUG
775 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 788 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
776 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 789 DEBUG_LOG (old_bss_addr);
777 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 790 DEBUG_LOG (old_bss_size);
778 fprintf (stderr, "old_bss_offset %x\n", old_bss_offset); 791 DEBUG_LOG (old_bss_offset);
779 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 792 DEBUG_LOG (new_bss_addr);
780 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 793 DEBUG_LOG (new_data2_addr);
781 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 794 DEBUG_LOG (new_data2_size);
782 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 795 DEBUG_LOG (new_data2_offset);
783 fprintf (stderr, "new_data2_incr %x\n", new_data2_incr); 796 DEBUG_LOG (new_data2_incr);
784#endif 797#endif
785 798
786 if ((uintptr_t) new_bss_addr < (uintptr_t) old_bss_addr + old_bss_size) 799 if (new_bss_addr < old_bss_addr + old_bss_size)
787 fatal (".bss shrank when undumping???\n", 0, 0); 800 fatal (".bss shrank when undumping");
788 801
789 /* Set the output file to the right size. Allocate a buffer to hold 802 /* Set the output file to the right size. Allocate a buffer to hold
790 the image of the new file. Set pointers to various interesting 803 the image of the new file. Set pointers to various interesting
791 objects. stat_buf still has old_file data. */ 804 objects. */
792 805
793 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 806 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
794 if (new_file < 0) 807 if (new_file < 0)
795 fatal ("Can't creat (%s): errno %d\n", new_name, errno); 808 fatal ("Can't creat (%s): %s", new_name, strerror (errno));
796 809
797 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_incr; 810 new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_incr;
798 811
799 if (ftruncate (new_file, new_file_size)) 812 if (ftruncate (new_file, new_file_size))
800 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 813 fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno));
801 814
802 new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE, 815 new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE,
803 MAP_ANON | MAP_PRIVATE, mmap_fd, 0); 816 MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
804 if (new_base == MAP_FAILED) 817 if (new_base == MAP_FAILED)
805 fatal ("Can't allocate buffer for %s\n", old_name, 0); 818 fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
806 819
807 new_file_h = (ElfW (Ehdr) *) new_base; 820 new_file_h = (ElfW (Ehdr) *) new_base;
808 new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 821 new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
@@ -825,10 +838,10 @@ unexec (const char *new_name, const char *old_name)
825 new_file_h->e_shoff += new_data2_incr; 838 new_file_h->e_shoff += new_data2_incr;
826 new_file_h->e_shnum += 1; 839 new_file_h->e_shnum += 1;
827 840
828#ifdef DEBUG 841#ifdef UNEXELF_DEBUG
829 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff); 842 DEBUG_LOG (old_file_h->e_shoff);
830 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); 843 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
831 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); 844 DEBUG_LOG (new_file_h->e_shoff);
832 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 845 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
833#endif 846#endif
834 847
@@ -839,7 +852,7 @@ unexec (const char *new_name, const char *old_name)
839 to adjust the offset and address of any segment that is above 852 to adjust the offset and address of any segment that is above
840 data2, just in case we decide to allow this later. */ 853 data2, just in case we decide to allow this later. */
841 854
842 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 855 for (n = new_file_h->e_phnum; --n >= 0; )
843 { 856 {
844 /* Compute maximum of all requirements for alignment of section. */ 857 /* Compute maximum of all requirements for alignment of section. */
845 ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align; 858 ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
@@ -857,7 +870,7 @@ unexec (const char *new_name, const char *old_name)
857 > (old_sbss_index == -1 870 > (old_sbss_index == -1
858 ? old_bss_addr 871 ? old_bss_addr
859 : round_up (old_bss_addr, alignment))) 872 : round_up (old_bss_addr, alignment)))
860 fatal ("Program segment above .bss in %s\n", old_name, 0); 873 fatal ("Program segment above .bss in %s", old_name);
861 874
862 if (NEW_PROGRAM_H (n).p_type == PT_LOAD 875 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
863 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 876 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
@@ -867,7 +880,7 @@ unexec (const char *new_name, const char *old_name)
867 break; 880 break;
868 } 881 }
869 if (n < 0) 882 if (n < 0)
870 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0); 883 fatal ("Couldn't find segment next to .bss in %s", old_name);
871 884
872 /* Make sure that the size includes any padding before the old .bss 885 /* Make sure that the size includes any padding before the old .bss
873 section. */ 886 section. */
@@ -875,7 +888,7 @@ unexec (const char *new_name, const char *old_name)
875 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; 888 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
876 889
877#if 0 /* Maybe allow section after data2 - does this ever happen? */ 890#if 0 /* Maybe allow section after data2 - does this ever happen? */
878 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 891 for (n = new_file_h->e_phnum; --n >= 0; )
879 { 892 {
880 if (NEW_PROGRAM_H (n).p_vaddr 893 if (NEW_PROGRAM_H (n).p_vaddr
881 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr) 894 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
@@ -894,7 +907,7 @@ unexec (const char *new_name, const char *old_name)
894 907
895 /* Walk through all section headers, insert the new data2 section right 908 /* Walk through all section headers, insert the new data2 section right
896 before the new bss section. */ 909 before the new bss section. */
897 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) 910 for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
898 { 911 {
899 caddr_t src; 912 caddr_t src;
900 /* If it is (s)bss section, insert the new data2 section before it. */ 913 /* If it is (s)bss section, insert the new data2 section before it. */
@@ -1173,7 +1186,7 @@ temacs:
1173 } 1186 }
1174 1187
1175 /* Update the symbol values of _edata and _end. */ 1188 /* Update the symbol values of _edata and _end. */
1176 for (n = new_file_h->e_shnum - 1; n; n--) 1189 for (n = new_file_h->e_shnum; 0 < --n; )
1177 { 1190 {
1178 byte *symnames; 1191 byte *symnames;
1179 ElfW (Sym) *symp, *symendp; 1192 ElfW (Sym) *symp, *symendp;
@@ -1233,7 +1246,7 @@ temacs:
1233 1246
1234 /* This loop seeks out relocation sections for the data section, so 1247 /* This loop seeks out relocation sections for the data section, so
1235 that it can undo relocations performed by the runtime linker. */ 1248 that it can undo relocations performed by the runtime linker. */
1236 for (n = new_file_h->e_shnum - 1; n; n--) 1249 for (n = new_file_h->e_shnum; 0 < --n; )
1237 { 1250 {
1238 ElfW (Shdr) section = NEW_SECTION_H (n); 1251 ElfW (Shdr) section = NEW_SECTION_H (n);
1239 1252
@@ -1293,8 +1306,8 @@ temacs:
1293 /* Write out new_file, and free the buffers. */ 1306 /* Write out new_file, and free the buffers. */
1294 1307
1295 if (write (new_file, new_base, new_file_size) != new_file_size) 1308 if (write (new_file, new_base, new_file_size) != new_file_size)
1296 fatal ("Didn't write %d bytes to %s: errno %d\n", 1309 fatal ("Didn't write %lu bytes to %s: %s",
1297 new_file_size, new_name, errno); 1310 (unsigned long) new_file_size, new_name, strerror (errno));
1298 munmap (old_base, old_file_size); 1311 munmap (old_base, old_file_size);
1299 munmap (new_base, new_file_size); 1312 munmap (new_base, new_file_size);
1300 1313
@@ -1304,18 +1317,18 @@ temacs:
1304 close (mmap_fd); 1317 close (mmap_fd);
1305#endif 1318#endif
1306 1319
1307 if (close (old_file)) 1320 if (close (old_file) != 0)
1308 fatal ("Can't close (%s): errno %d\n", old_name, errno); 1321 fatal ("Can't close (%s): %s", old_name, strerror (errno));
1309 1322
1310 if (close (new_file)) 1323 if (close (new_file) != 0)
1311 fatal ("Can't close (%s): errno %d\n", new_name, errno); 1324 fatal ("Can't close (%s): %s", new_name, strerror (errno));
1312 1325
1313 if (stat (new_name, &stat_buf) == -1) 1326 if (stat (new_name, &stat_buf) != 0)
1314 fatal ("Can't stat (%s): errno %d\n", new_name, errno); 1327 fatal ("Can't stat (%s): %s", new_name, strerror (errno));
1315 1328
1316 n = umask (777); 1329 n = umask (777);
1317 umask (n); 1330 umask (n);
1318 stat_buf.st_mode |= 0111 & ~n; 1331 stat_buf.st_mode |= 0111 & ~n;
1319 if (chmod (new_name, stat_buf.st_mode) == -1) 1332 if (chmod (new_name, stat_buf.st_mode) != 0)
1320 fatal ("Can't chmod (%s): errno %d\n", new_name, errno); 1333 fatal ("Can't chmod (%s): %s", new_name, strerror (errno));
1321} 1334}