comparison src/unexmacosx.c @ 66764:1f4cf9d552f9

(unexec_write_zero): New function. (copy_data_segment): Clear uninitialized local variables in statically linked libraries.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Wed, 09 Nov 2005 08:08:34 +0000
parents a0d1312ede66
children 3bd95f4f2941 7beb78bc1f8e
comparison
equal deleted inserted replaced
66763:f6840b4933ef 66764:1f4cf9d552f9
172 /* file offset of input file's data segment */ 172 /* file offset of input file's data segment */
173 off_t data_segment_old_fileoff; 173 off_t data_segment_old_fileoff;
174 174
175 struct segment_command *data_segment_scp; 175 struct segment_command *data_segment_scp;
176 176
177 /* Read n bytes from infd into memory starting at address dest. 177 /* Read N bytes from infd into memory starting at address DEST.
178 Return true if successful, false otherwise. */ 178 Return true if successful, false otherwise. */
179 static int 179 static int
180 unexec_read (void *dest, size_t n) 180 unexec_read (void *dest, size_t n)
181 { 181 {
182 return n == read (infd, dest, n); 182 return n == read (infd, dest, n);
183 } 183 }
184 184
185 /* Write n bytes from memory starting at address src to outfd starting 185 /* Write COUNT bytes from memory starting at address SRC to outfd
186 at offset dest. Return true if successful, false otherwise. */ 186 starting at offset DEST. Return true if successful, false
187 otherwise. */
187 static int 188 static int
188 unexec_write (off_t dest, const void *src, size_t count) 189 unexec_write (off_t dest, const void *src, size_t count)
189 { 190 {
190 if (lseek (outfd, dest, SEEK_SET) != dest) 191 if (lseek (outfd, dest, SEEK_SET) != dest)
191 return 0; 192 return 0;
192 193
193 return write (outfd, src, count) == count; 194 return write (outfd, src, count) == count;
194 } 195 }
195 196
196 /* Copy n bytes from starting offset src in infd to starting offset 197 /* Write COUNT bytes of zeros to outfd starting at offset DEST.
197 dest in outfd. Return true if successful, false otherwise. */ 198 Return true if successful, false otherwise. */
199 static int
200 unexec_write_zero (off_t dest, size_t count)
201 {
202 char buf[UNEXEC_COPY_BUFSZ];
203 ssize_t bytes;
204
205 bzero (buf, UNEXEC_COPY_BUFSZ);
206 if (lseek (outfd, dest, SEEK_SET) != dest)
207 return 0;
208
209 while (count > 0)
210 {
211 bytes = count > UNEXEC_COPY_BUFSZ ? UNEXEC_COPY_BUFSZ : count;
212 if (write (outfd, buf, bytes) != bytes)
213 return 0;
214 count -= bytes;
215 }
216
217 return 1;
218 }
219
220 /* Copy COUNT bytes from starting offset SRC in infd to starting
221 offset DEST in outfd. Return true if successful, false
222 otherwise. */
198 static int 223 static int
199 unexec_copy (off_t dest, off_t src, ssize_t count) 224 unexec_copy (off_t dest, off_t src, ssize_t count)
200 { 225 {
201 ssize_t bytes_read; 226 ssize_t bytes_read;
202 ssize_t bytes_to_read; 227 ssize_t bytes_to_read;
682 if (!unexec_write (sectp->offset, (void *) sectp->addr, sectp->size)) 707 if (!unexec_write (sectp->offset, (void *) sectp->addr, sectp->size))
683 unexec_error ("cannot write section %s", SECT_DATA); 708 unexec_error ("cannot write section %s", SECT_DATA);
684 if (!unexec_write (header_offset, sectp, sizeof (struct section))) 709 if (!unexec_write (header_offset, sectp, sizeof (struct section)))
685 unexec_error ("cannot write section %s's header", SECT_DATA); 710 unexec_error ("cannot write section %s's header", SECT_DATA);
686 } 711 }
687 else if (strncmp (sectp->sectname, SECT_BSS, 16) == 0 712 else if (strncmp (sectp->sectname, SECT_COMMON, 16) == 0)
688 || strncmp (sectp->sectname, SECT_COMMON, 16) == 0)
689 { 713 {
690 sectp->flags = S_REGULAR; 714 sectp->flags = S_REGULAR;
691 if (!unexec_write (sectp->offset, (void *) sectp->addr, sectp->size)) 715 if (!unexec_write (sectp->offset, (void *) sectp->addr, sectp->size))
692 unexec_error ("cannot write section %s", SECT_DATA); 716 unexec_error ("cannot write section %s", sectp->sectname);
693 if (!unexec_write (header_offset, sectp, sizeof (struct section))) 717 if (!unexec_write (header_offset, sectp, sizeof (struct section)))
694 unexec_error ("cannot write section %s's header", SECT_DATA); 718 unexec_error ("cannot write section %s's header", sectp->sectname);
719 }
720 else if (strncmp (sectp->sectname, SECT_BSS, 16) == 0)
721 {
722 extern char *my_endbss_static;
723 unsigned long my_size;
724
725 sectp->flags = S_REGULAR;
726
727 /* Clear uninitialized local variables in statically linked
728 libraries. In particular, function pointers stored by
729 libSystemStub.a, which is introduced in Mac OS X 10.4 for
730 binary compatibility with respect to long double, are
731 cleared so that they will be reinitialized when the
732 dumped binary is executed on other versions of OS. */
733 my_size = (unsigned long)my_endbss_static - sectp->addr;
734 if (!(sectp->addr <= (unsigned long)my_endbss_static
735 && my_size <= sectp->size))
736 unexec_error ("my_endbss_static is not in section %s",
737 sectp->sectname);
738 if (!unexec_write (sectp->offset, (void *) sectp->addr, my_size))
739 unexec_error ("cannot write section %s", sectp->sectname);
740 if (!unexec_write_zero (sectp->offset + my_size,
741 sectp->size - my_size))
742 unexec_error ("cannot write section %s", sectp->sectname);
743 if (!unexec_write (header_offset, sectp, sizeof (struct section)))
744 unexec_error ("cannot write section %s's header", sectp->sectname);
695 } 745 }
696 else if (strncmp (sectp->sectname, "__la_symbol_ptr", 16) == 0 746 else if (strncmp (sectp->sectname, "__la_symbol_ptr", 16) == 0
697 || strncmp (sectp->sectname, "__nl_symbol_ptr", 16) == 0 747 || strncmp (sectp->sectname, "__nl_symbol_ptr", 16) == 0
698 || strncmp (sectp->sectname, "__la_sym_ptr2", 16) == 0 748 || strncmp (sectp->sectname, "__la_sym_ptr2", 16) == 0
699 || strncmp (sectp->sectname, "__dyld", 16) == 0 749 || strncmp (sectp->sectname, "__dyld", 16) == 0