Mercurial > emacs
annotate src/unexcw.c @ 96975:60149c696033
2008-07-24 Carsten Dominik <dominik@science.uva.nl>
* org-exp.el (org-export-region-as-html, org-export-as-html): Make
sure that calls from `org-export-region-as-html' do not do the
special check for a subtree.
* org-agenda.el (org-batch-store-agenda-views): Fix parsing bug.
* org.el (org-open-file): Use
`org-open-directory-means-index-dot-org'.
(org-open-directory-means-index-dot-org): New option.
* org.el (org-make-link-string): Remove link attributes from
description.
(org-open-at-point): Remove link attributes bevore using the path.
* org-exp.el (org-export-as-html): Handle link attributes.
* org.el (org-extract-attributes, org-attributes-to-string): New functions.
* org-table.el (org-table-to-lisp): New function.
* org.el (org-narrow-to-subtree): Do not include the final newline
into the narrowed region.
* org-agenda.el (org-agenda-custom-commands-local-options): Fixed
bug with user-define skipping condition.
* org-agenda.el (org-agenda-get-restriction-and-command): Fixed typo.
* org-exp.el (org-export-html-style-default): Automatic overflow
handling for pre fields.
(org-export-as-ascii, org-export-as-html): Change default format
for time stamp.
* org-table.el (org-table-export): Offer completion for translator
functions, and do not require a heading above the table.
* org.el (org-renumber-ordered-list, org-beginning-of-item-list):
Cater for the case of a list starting in the first line of the
buffer.
* org-publish.el (org-publish-find-title): Bug fix.
(org-publish-org-index): Implement new :index-style option.
* org-publish.el (org-publish-timestamp-filename): Use
SHA1-encoded file names in the timestamp directory.
* org-publish.el (org-publish-needed-p): Be verbose about files
published and files skipped.
* org-exp.el (org-export-preprocess-string): Swap link
normalization and inernal link targeting.
* org-publish.el (org-publish-needed-p): Create timestamp
directory when it does not exist.
* org-clock.el (org-clock-out-when-done): Doc fix.
* org.el (org-agenda-skip-unavailable-files): Doc fix.
* org-exp.el (org-export-remove-comment-blocks-and-subtrees):
Ignore case when searching for the COMMENT cookie at export time.
* org-exp.el (org-get-file-contents)
(org-get-and-remove-property): New functions.
(org-export-handle-include-files): Handle the new prefix options.
(org-export-as-html): Fix the verse environment.
* org.el (org-time=, org-time<, org-time<=, org-time>)
(org-time>=, org-time<>, org-2ft): New functions.
(org-op-to-function): Also provide for the time testing fucntions.
* org-exp.el (org-export-html-style-default): New constant.
* org-exp.el (org-export-html-style-extra): New variable.
(org-export-splice-style): New function.
* org-exp.el (org-export-plist-vars, org-export-as-html):
Implement `org-export-creator-info'.
(org-export-creator-info): New option.
* org.el (org-clock-drawer-start-re, org-clock-drawer-end-re)
(org-property-drawer-re, org-clock-drawer-re): New constants.
* org-exp.el (org-icalendar-use-deadline)
(org-icalendar-use-scheduled): New options.
(org-icalendar-include-todo): Default changed to t.
(org-print-icalendar-entries): Implement better utilization of
scheduling and deadline time stamps.
(org-export-target-internal-links, org-export-as-html): Allow file
lines without the "file:" prefix if the file path is an absolute
path or starts with ".".
* org-clock.el (org-clocktable-shift): Also undertand yesterday,
lastweek etc.
(org-clock-special-range): Also undertand yesterday, lastweek etc.
* org.el (org-agenda-skip-archived-trees): Docstring now
discourages using this.
(org-scan-tags): Check for org-agenda-archives-mode.
(org-map-entries): Make sure org-agenda-archives-mode is nil.
(org-agenda-files): Functionality of second arg changed.
* org-agenda.el (org-agenda-archives-mode): New variable
(org-write-agenda, org-prepare-agenda, org-agenda-list)
(org-search-view, org-todo-list, org-tags-view)
(org-agenda-list-stuck-projects): Call `org-agenda-files' with
`ifmode' argument.
(org-agenda-quit): Reset the archives mode.
(org-agenda-archives-mode): New command.
(org-agenda-set-mode-name): Include archives info.
* org.el (org-paste-subtree): Make sure the yanked headline is
visible if it was yanked at a visible point.
(org-move-item-up): Fix the bug with moving white space at the end
of the item.
(org-show-empty-lines-in-parent): New function.
author | Carsten Dominik <dominik@science.uva.nl> |
---|---|
date | Thu, 24 Jul 2008 13:59:56 +0000 |
parents | 8971ddf55736 |
children | e038c1a8307c |
rev | line source |
---|---|
54844 | 1 /* unexec() support for Cygwin; |
2 complete rewrite of xemacs Cygwin unexec() code | |
3 | |
79759 | 4 Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
54844 | 5 |
6 This file is part of GNU Emacs. | |
7 | |
94963
8971ddf55736
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79759
diff
changeset
|
8 GNU Emacs is free software: you can redistribute it and/or modify |
54844 | 9 it under the terms of the GNU General Public License as published by |
94963
8971ddf55736
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79759
diff
changeset
|
10 the Free Software Foundation, either version 3 of the License, or |
8971ddf55736
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79759
diff
changeset
|
11 (at your option) any later version. |
54844 | 12 |
13 GNU Emacs is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
94963
8971ddf55736
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79759
diff
changeset
|
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
54844 | 20 |
21 #include <config.h> | |
22 #include <lisp.h> | |
23 #include <stdio.h> | |
24 #include <fcntl.h> | |
25 #include <a.out.h> | |
26 #include <unistd.h> | |
27 #include <assert.h> | |
28 | |
29 #define DOTEXE ".exe" | |
30 | |
31 extern int bss_sbrk_did_unexec; | |
32 | |
33 /* emacs symbols that indicate where bss and data end for emacs internals */ | |
34 extern char my_endbss[]; | |
35 extern char my_edata[]; | |
36 | |
37 /* | |
38 ** header for Windows executable files | |
39 */ | |
40 typedef struct | |
41 { | |
42 FILHDR file_header; | |
43 PEAOUTHDR file_optional_header; | |
44 SCNHDR section_header[32]; | |
45 } exe_header_t; | |
46 | |
47 int debug_unexcw = 0; | |
48 | |
49 /* | |
50 ** Read the header from the executable into memory so we can more easily access it. | |
51 */ | |
52 static exe_header_t * | |
53 read_exe_header (int fd, exe_header_t * exe_header_buffer) | |
54 { | |
55 int i; | |
56 int ret; | |
57 | |
58 assert (fd >= 0); | |
59 assert (exe_header_buffer != 0); | |
60 | |
61 ret = lseek (fd, 0L, SEEK_SET); | |
62 assert (ret != -1); | |
63 | |
64 ret = | |
65 read (fd, &exe_header_buffer->file_header, | |
66 sizeof (exe_header_buffer->file_header)); | |
67 assert (ret == sizeof (exe_header_buffer->file_header)); | |
68 | |
69 assert (exe_header_buffer->file_header.e_magic == 0x5a4d); | |
70 assert (exe_header_buffer->file_header.nt_signature == 0x4550); | |
71 assert (exe_header_buffer->file_header.f_magic == 0x014c); | |
72 assert (exe_header_buffer->file_header.f_nscns > 0); | |
73 assert (exe_header_buffer->file_header.f_nscns <= | |
74 sizeof (exe_header_buffer->section_header) / | |
75 sizeof (exe_header_buffer->section_header[0])); | |
76 assert (exe_header_buffer->file_header.f_opthdr > 0); | |
77 | |
78 ret = | |
79 read (fd, &exe_header_buffer->file_optional_header, | |
80 sizeof (exe_header_buffer->file_optional_header)); | |
81 assert (ret == sizeof (exe_header_buffer->file_optional_header)); | |
82 | |
83 assert (exe_header_buffer->file_optional_header.magic == 0x010b); | |
84 | |
85 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i) | |
86 { | |
87 ret = | |
88 read (fd, &exe_header_buffer->section_header[i], | |
89 sizeof (exe_header_buffer->section_header[i])); | |
90 assert (ret == sizeof (exe_header_buffer->section_header[i])); | |
91 } | |
92 | |
93 return (exe_header_buffer); | |
94 } | |
95 | |
96 /* | |
97 ** Fix the dumped emacs executable: | |
98 ** | |
99 ** - copy .data section data of interest from running executable into | |
100 ** output .exe file | |
101 ** | |
102 ** - convert .bss section into an initialized data section (like | |
103 ** .data) and copy .bss section data of interest from running | |
104 ** executable into output .exe file | |
105 */ | |
106 static void | |
107 fixup_executable (int fd) | |
108 { | |
109 exe_header_t exe_header_buffer; | |
110 exe_header_t *exe_header; | |
111 int i; | |
112 int ret; | |
113 int found_data = 0; | |
114 int found_bss = 0; | |
115 | |
116 exe_header = read_exe_header (fd, &exe_header_buffer); | |
117 assert (exe_header != 0); | |
118 | |
119 assert (exe_header->file_header.f_nscns > 0); | |
120 for (i = 0; i < exe_header->file_header.f_nscns; ++i) | |
121 { | |
122 unsigned long start_address = | |
123 exe_header->section_header[i].s_vaddr + | |
124 exe_header->file_optional_header.ImageBase; | |
125 unsigned long end_address = | |
126 exe_header->section_header[i].s_vaddr + | |
127 exe_header->file_optional_header.ImageBase + | |
128 exe_header->section_header[i].s_paddr; | |
129 if (debug_unexcw) | |
130 printf ("%8s start 0x%08x end 0x%08x\n", | |
131 exe_header->section_header[i].s_name, | |
132 start_address, end_address); | |
133 if (my_edata >= (char *) start_address | |
134 && my_edata < (char *) end_address) | |
135 { | |
136 /* data section */ | |
137 ret = | |
138 lseek (fd, (long) (exe_header->section_header[i].s_scnptr), | |
139 SEEK_SET); | |
140 assert (ret != -1); | |
141 ret = | |
142 write (fd, (char *) start_address, | |
143 my_edata - (char *) start_address); | |
144 assert (ret == my_edata - (char *) start_address); | |
145 ++found_data; | |
146 if (debug_unexcw) | |
147 printf (" .data, mem start 0x%08x mem length %d\n", | |
148 start_address, my_edata - (char *) start_address); | |
149 if (debug_unexcw) | |
150 printf (" .data, file start %d file length %d\n", | |
151 (int) exe_header->section_header[i].s_scnptr, | |
152 (int) exe_header->section_header[i].s_paddr); | |
153 } | |
154 else if (my_endbss >= (char *) start_address | |
155 && my_endbss < (char *) end_address) | |
156 { | |
157 /* bss section */ | |
158 ++found_bss; | |
159 if (exe_header->section_header[i].s_flags & 0x00000080) | |
160 { | |
161 /* convert uninitialized data section to initialized data section */ | |
162 struct stat statbuf; | |
163 ret = fstat (fd, &statbuf); | |
164 assert (ret != -1); | |
165 | |
166 exe_header->section_header[i].s_flags &= ~0x00000080; | |
167 exe_header->section_header[i].s_flags |= 0x00000040; | |
168 | |
169 exe_header->section_header[i].s_scnptr = | |
170 (statbuf.st_size + | |
171 exe_header->file_optional_header.FileAlignment) / | |
172 exe_header->file_optional_header.FileAlignment * | |
173 exe_header->file_optional_header.FileAlignment; | |
174 | |
175 exe_header->section_header[i].s_size = | |
176 (exe_header->section_header[i].s_paddr + | |
177 exe_header->file_optional_header.FileAlignment) / | |
178 exe_header->file_optional_header.FileAlignment * | |
179 exe_header->file_optional_header.FileAlignment; | |
180 | |
181 ret = | |
182 lseek (fd, | |
183 (long) (exe_header->section_header[i].s_scnptr + | |
184 exe_header->section_header[i].s_size - 1), | |
185 SEEK_SET); | |
186 assert (ret != -1); | |
187 ret = write (fd, "", 1); | |
188 assert (ret == 1); | |
189 | |
190 ret = | |
191 lseek (fd, | |
192 (long) ((char *) &exe_header->section_header[i] - | |
193 (char *) exe_header), SEEK_SET); | |
194 assert (ret != -1); | |
195 ret = | |
196 write (fd, &exe_header->section_header[i], | |
197 sizeof (exe_header->section_header[i])); | |
198 assert (ret == sizeof (exe_header->section_header[i])); | |
199 if (debug_unexcw) | |
200 printf (" seek to %ld, write %d\n", | |
201 (long) ((char *) &exe_header->section_header[i] - | |
202 (char *) exe_header), | |
203 sizeof (exe_header->section_header[i])); | |
204 } | |
205 /* write initialized data section */ | |
206 ret = | |
207 lseek (fd, (long) (exe_header->section_header[i].s_scnptr), | |
208 SEEK_SET); | |
209 assert (ret != -1); | |
210 ret = | |
211 write (fd, (char *) start_address, | |
212 my_endbss - (char *) start_address); | |
213 assert (ret == (my_endbss - (char *) start_address)); | |
214 if (debug_unexcw) | |
215 printf (" .bss, mem start 0x%08x mem length %d\n", | |
216 start_address, my_endbss - (char *) start_address); | |
217 if (debug_unexcw) | |
218 printf (" .bss, file start %d file length %d\n", | |
219 (int) exe_header->section_header[i].s_scnptr, | |
220 (int) exe_header->section_header[i].s_paddr); | |
221 } | |
222 } | |
223 assert (found_bss == 1); | |
224 assert (found_data == 1); | |
225 } | |
226 | |
227 /* | |
228 ** Windows likes .exe suffixes on executables. | |
229 */ | |
230 static char * | |
231 add_exe_suffix_if_necessary (const char *name, char *modified) | |
232 { | |
233 int i = strlen (name); | |
234 if (i <= (sizeof (DOTEXE) - 1)) | |
235 { | |
236 sprintf (modified, "%s%s", name, DOTEXE); | |
237 } | |
238 else if (!strcasecmp (name + i - (sizeof (DOTEXE) - 1), DOTEXE)) | |
239 { | |
240 strcpy (modified, name); | |
241 } | |
242 else | |
243 { | |
244 sprintf (modified, "%s%s", name, DOTEXE); | |
245 } | |
246 return (modified); | |
247 } | |
248 | |
249 int | |
250 unexec (char *outfile, char *infile, unsigned start_data, unsigned d1, | |
251 unsigned d2) | |
252 { | |
253 char infile_buffer[FILENAME_MAX]; | |
254 char outfile_buffer[FILENAME_MAX]; | |
255 int fd_in; | |
256 int fd_out; | |
257 int ret; | |
258 int ret2; | |
259 | |
260 if (bss_sbrk_did_unexec) | |
261 { | |
262 /* can only dump once */ | |
73688
f5b44958a759
(unexec): Fix typo in output message.
Juanma Barranquero <lekktu@gmail.com>
parents:
68651
diff
changeset
|
263 printf ("You can only dump Emacs once on this platform.\n"); |
54844 | 264 return (1); |
265 } | |
266 | |
267 report_sheap_usage (1); | |
268 | |
269 infile = add_exe_suffix_if_necessary (infile, infile_buffer); | |
270 outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer); | |
271 | |
272 fd_in = open (infile, O_RDONLY | O_BINARY); | |
273 assert (fd_in >= 0); | |
274 fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755); | |
275 assert (fd_out >= 0); | |
276 for (;;) | |
277 { | |
278 char buffer[4096]; | |
279 ret = read (fd_in, buffer, sizeof (buffer)); | |
280 if (ret == 0) | |
281 { | |
282 /* eof */ | |
283 break; | |
284 } | |
285 assert (ret > 0); | |
286 /* data */ | |
287 ret2 = write (fd_out, buffer, ret); | |
288 assert (ret2 == ret); | |
289 } | |
290 ret = close (fd_in); | |
291 assert (ret == 0); | |
292 | |
293 bss_sbrk_did_unexec = 1; | |
294 fixup_executable (fd_out); | |
295 bss_sbrk_did_unexec = 0; | |
296 | |
297 ret = close (fd_out); | |
298 assert (ret == 0); | |
299 | |
300 return (0); | |
301 } | |
54858
44a3fff23885
Changes from arch/CVS synchronization
Miles Bader <miles@gnu.org>
parents:
54844
diff
changeset
|
302 |
44a3fff23885
Changes from arch/CVS synchronization
Miles Bader <miles@gnu.org>
parents:
54844
diff
changeset
|
303 /* arch-tag: fc44f6c3-ca0a-45e0-a5a2-58b6101b1e65 |
44a3fff23885
Changes from arch/CVS synchronization
Miles Bader <miles@gnu.org>
parents:
54844
diff
changeset
|
304 (do not change this comment) */ |