aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2005-11-09 08:08:34 +0000
committerYAMAMOTO Mitsuharu2005-11-09 08:08:34 +0000
commit433456d7a71e8d11bf7e1d41ba23e8c0bcd82dbd (patch)
tree7615376db0423a69c0ffcacb72be5ede152988e4 /src
parent10ae126cfca41014f920dbc02031f00974752b7a (diff)
downloademacs-433456d7a71e8d11bf7e1d41ba23e8c0bcd82dbd.tar.gz
emacs-433456d7a71e8d11bf7e1d41ba23e8c0bcd82dbd.zip
(unexec_write_zero): New function.
(copy_data_segment): Clear uninitialized local variables in statically linked libraries.
Diffstat (limited to 'src')
-rw-r--r--src/unexmacosx.c68
1 files changed, 59 insertions, 9 deletions
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index 9db9622f6f5..43e1f5e805c 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -174,7 +174,7 @@ off_t data_segment_old_fileoff;
174 174
175struct segment_command *data_segment_scp; 175struct 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. */
179static int 179static int
180unexec_read (void *dest, size_t n) 180unexec_read (void *dest, size_t n)
@@ -182,8 +182,9 @@ unexec_read (void *dest, size_t n)
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. */
187static int 188static int
188unexec_write (off_t dest, const void *src, size_t count) 189unexec_write (off_t dest, const void *src, size_t count)
189{ 190{
@@ -193,8 +194,32 @@ unexec_write (off_t dest, const void *src, size_t count)
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. */
199static int
200unexec_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. */
198static int 223static int
199unexec_copy (off_t dest, off_t src, ssize_t count) 224unexec_copy (off_t dest, off_t src, ssize_t count)
200{ 225{
@@ -684,14 +709,39 @@ copy_data_segment (struct load_command *lc)
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