Annotation of /trunk/grub/patches/grub-0.97-nxstack.patch
Parent Directory | Revision Log
Revision 144 -
(hide annotations)
(download)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 18795 byte(s)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 18795 byte(s)
-import
1 | niro | 144 | Fix NX segfaulting on amd64. |
2 | |||
3 | Patch by Peter Jones. | ||
4 | |||
5 | http://lists.gnu.org/archive/html/bug-grub/2005-03/msg00011.html | ||
6 | |||
7 | --- grub-0.97/grub/asmstub.c | ||
8 | +++ grub-0.97/grub/asmstub.c | ||
9 | @@ -42,6 +42,7 @@ | ||
10 | #include <sys/time.h> | ||
11 | #include <termios.h> | ||
12 | #include <signal.h> | ||
13 | +#include <sys/mman.h> | ||
14 | |||
15 | #ifdef __linux__ | ||
16 | # include <sys/ioctl.h> /* ioctl */ | ||
17 | @@ -79,7 +80,7 @@ | ||
18 | struct apm_info apm_bios_info; | ||
19 | |||
20 | /* Emulation requirements. */ | ||
21 | -char *grub_scratch_mem = 0; | ||
22 | +void *grub_scratch_mem = 0; | ||
23 | |||
24 | struct geometry *disks = 0; | ||
25 | |||
26 | @@ -103,14 +104,62 @@ | ||
27 | static unsigned int serial_speed; | ||
28 | #endif /* SIMULATE_SLOWNESS_OF_SERIAL */ | ||
29 | |||
30 | +/* This allocates page-aligned storage of the specified size, which must be | ||
31 | + * a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE) | ||
32 | + */ | ||
33 | +#ifdef __linux__ | ||
34 | +static void * | ||
35 | +grub_mmap_alloc(size_t len) | ||
36 | +{ | ||
37 | + int mmap_flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_EXECUTABLE; | ||
38 | + | ||
39 | +#ifdef MAP_32BIT | ||
40 | + mmap_flags |= MAP_32BIT; | ||
41 | +#endif | ||
42 | + /* Mark the simulated stack executable, as GCC uses stack trampolines | ||
43 | + * to implement nested functions. */ | ||
44 | + return mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0); | ||
45 | +} | ||
46 | +#else /* !defined(__linux__) */ | ||
47 | +static void * | ||
48 | +grub_mmap_alloc(size_t len) | ||
49 | +{ | ||
50 | + int fd = 0, offset = 0, ret = 0; | ||
51 | + void *pa = MAP_FAILED; | ||
52 | + char template[] = "/tmp/grub_mmap_alloc_XXXXXX"; | ||
53 | + errno_t e; | ||
54 | + | ||
55 | + fd = mkstemp(template); | ||
56 | + if (fd < 0) | ||
57 | + return pa; | ||
58 | + | ||
59 | + unlink(template); | ||
60 | + | ||
61 | + ret = ftruncate(fd, len); | ||
62 | + if (ret < 0) | ||
63 | + return pa; | ||
64 | + | ||
65 | + /* Mark the simulated stack executable, as GCC uses stack trampolines | ||
66 | + * to implement nested functions. */ | ||
67 | + pa = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, | ||
68 | + MAP_PRIVATE|MAP_EXECUTABLE, fd, offset); | ||
69 | + | ||
70 | + e = errno; | ||
71 | + close(fd); | ||
72 | + errno = e; | ||
73 | + return pa; | ||
74 | +} | ||
75 | +#endif /* defined(__linux__) */ | ||
76 | + | ||
77 | /* The main entry point into this mess. */ | ||
78 | int | ||
79 | grub_stage2 (void) | ||
80 | { | ||
81 | /* These need to be static, because they survive our stack transitions. */ | ||
82 | static int status = 0; | ||
83 | - static char *realstack; | ||
84 | - char *scratch, *simstack; | ||
85 | + static void *realstack; | ||
86 | + void *simstack_alloc_base, *simstack; | ||
87 | + size_t simstack_size, page_size; | ||
88 | int i; | ||
89 | |||
90 | /* We need a nested function so that we get a clean stack frame, | ||
91 | @@ -140,9 +189,35 @@ | ||
92 | } | ||
93 | |||
94 | assert (grub_scratch_mem == 0); | ||
95 | - scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); | ||
96 | - assert (scratch); | ||
97 | - grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); | ||
98 | + | ||
99 | + /* Allocate enough pages for 0x100000 + EXTENDED_SIZE + 15, and | ||
100 | + * make sure the memory is aligned to a multiple of the system's | ||
101 | + * page size */ | ||
102 | + page_size = sysconf (_SC_PAGESIZE); | ||
103 | + simstack_size = ( 0x100000 + EXTENDED_MEMSIZE + 15); | ||
104 | + if (simstack_size % page_size) | ||
105 | + { | ||
106 | + /* If we're not on a page_size boundary, round up to the next one */ | ||
107 | + simstack_size &= ~(page_size-1); | ||
108 | + simstack_size += page_size; | ||
109 | + } | ||
110 | + | ||
111 | + /* Add one for a PROT_NONE boundary page at each end. */ | ||
112 | + simstack_size += 2 * page_size; | ||
113 | + | ||
114 | + simstack_alloc_base = grub_mmap_alloc(simstack_size); | ||
115 | + assert (simstack_alloc_base != MAP_FAILED); | ||
116 | + | ||
117 | + /* mark pages above and below our simstack area as innaccessable. | ||
118 | + * If the implementation we're using doesn't support that, then the | ||
119 | + * new protection modes are undefined. It's safe to just ignore | ||
120 | + * them, though. It'd be nice if we knew that we'd get a SEGV for | ||
121 | + * touching the area, but that's all. it'd be nice to have. */ | ||
122 | + mprotect (simstack_alloc_base, page_size, PROT_NONE); | ||
123 | + mprotect ((void *)((unsigned long)simstack_alloc_base + | ||
124 | + simstack_size - page_size), page_size, PROT_NONE); | ||
125 | + | ||
126 | + grub_scratch_mem = (void *)((unsigned long)simstack_alloc_base + page_size); | ||
127 | |||
128 | /* FIXME: simulate the memory holes using mprot, if available. */ | ||
129 | |||
130 | @@ -215,7 +290,7 @@ | ||
131 | device_map = 0; | ||
132 | free (disks); | ||
133 | disks = 0; | ||
134 | - free (scratch); | ||
135 | + munmap(simstack_alloc_base, simstack_size); | ||
136 | grub_scratch_mem = 0; | ||
137 | |||
138 | if (serial_device) | ||
139 | --- grub-0.97/stage2/builtins.c | ||
140 | +++ grub-0.97/stage2/builtins.c | ||
141 | @@ -131,63 +131,98 @@ | ||
142 | } | ||
143 | |||
144 | |||
145 | +/* blocklist_read_helper nee disk_read_blocklist_func was a nested | ||
146 | + * function, to which pointers were taken and exposed globally. Even | ||
147 | + * in the GNU-C nested functions extension, they have local linkage, | ||
148 | + * and aren't guaranteed to be accessable *at all* outside of their | ||
149 | + * containing scope. | ||
150 | + * | ||
151 | + * Above and beyond all of that, the variables within blocklist_func_context | ||
152 | + * are originally local variables, with local (not even static) linkage, | ||
153 | + * from within blocklist_func. These were each referenced by | ||
154 | + * disk_read_blocklist_func, which is only called from other functions | ||
155 | + * through a globally scoped pointer. | ||
156 | + * | ||
157 | + * The documentation in GCC actually uses the words "all hell will break | ||
158 | + * loose" to describe this scenario. | ||
159 | + * | ||
160 | + * Also, "start_sector" was also used uninitialized, but gcc doesn't warn | ||
161 | + * about it (possibly because of the scoping madness?) | ||
162 | + */ | ||
163 | + | ||
164 | +static struct { | ||
165 | + int start_sector; | ||
166 | + int num_sectors; | ||
167 | + int num_entries; | ||
168 | + int last_length; | ||
169 | +} blocklist_func_context = { | ||
170 | + .start_sector = 0, | ||
171 | + .num_sectors = 0, | ||
172 | + .num_entries = 0, | ||
173 | + .last_length = 0 | ||
174 | +}; | ||
175 | + | ||
176 | +/* Collect contiguous blocks into one entry as many as possible, | ||
177 | + and print the blocklist notation on the screen. */ | ||
178 | +static void | ||
179 | +blocklist_read_helper (int sector, int offset, int length) | ||
180 | +{ | ||
181 | + int *start_sector = &blocklist_func_context.start_sector; | ||
182 | + int *num_sectors = &blocklist_func_context.num_sectors; | ||
183 | + int *num_entries = &blocklist_func_context.num_entries; | ||
184 | + int *last_length = &blocklist_func_context.last_length; | ||
185 | + | ||
186 | + if (*num_sectors > 0) | ||
187 | + { | ||
188 | + if (*start_sector + *num_sectors == sector | ||
189 | + && offset == 0 && *last_length == SECTOR_SIZE) | ||
190 | + { | ||
191 | + *num_sectors++; | ||
192 | + *last_length = length; | ||
193 | + return; | ||
194 | + } | ||
195 | + else | ||
196 | + { | ||
197 | + if (*last_length == SECTOR_SIZE) | ||
198 | + grub_printf ("%s%d+%d", *num_entries ? "," : "", | ||
199 | + *start_sector - part_start, *num_sectors); | ||
200 | + else if (*num_sectors > 1) | ||
201 | + grub_printf ("%s%d+%d,%d[0-%d]", *num_entries ? "," : "", | ||
202 | + *start_sector - part_start, *num_sectors-1, | ||
203 | + *start_sector + *num_sectors-1 - part_start, | ||
204 | + *last_length); | ||
205 | + else | ||
206 | + grub_printf ("%s%d[0-%d]", *num_entries ? "," : "", | ||
207 | + *start_sector - part_start, *last_length); | ||
208 | + *num_entries++; | ||
209 | + *num_sectors = 0; | ||
210 | + } | ||
211 | + } | ||
212 | + | ||
213 | + if (offset > 0) | ||
214 | + { | ||
215 | + grub_printf("%s%d[%d-%d]", *num_entries ? "," : "", | ||
216 | + sector-part_start, offset, offset+length); | ||
217 | + *num_entries++; | ||
218 | + } | ||
219 | + else | ||
220 | + { | ||
221 | + *start_sector = sector; | ||
222 | + *num_sectors = 1; | ||
223 | + *last_length = length; | ||
224 | + } | ||
225 | +} | ||
226 | + | ||
227 | /* blocklist */ | ||
228 | static int | ||
229 | blocklist_func (char *arg, int flags) | ||
230 | { | ||
231 | char *dummy = (char *) RAW_ADDR (0x100000); | ||
232 | - int start_sector; | ||
233 | - int num_sectors = 0; | ||
234 | - int num_entries = 0; | ||
235 | - int last_length = 0; | ||
236 | - | ||
237 | - auto void disk_read_blocklist_func (int sector, int offset, int length); | ||
238 | - | ||
239 | - /* Collect contiguous blocks into one entry as many as possible, | ||
240 | - and print the blocklist notation on the screen. */ | ||
241 | - auto void disk_read_blocklist_func (int sector, int offset, int length) | ||
242 | - { | ||
243 | - if (num_sectors > 0) | ||
244 | - { | ||
245 | - if (start_sector + num_sectors == sector | ||
246 | - && offset == 0 && last_length == SECTOR_SIZE) | ||
247 | - { | ||
248 | - num_sectors++; | ||
249 | - last_length = length; | ||
250 | - return; | ||
251 | - } | ||
252 | - else | ||
253 | - { | ||
254 | - if (last_length == SECTOR_SIZE) | ||
255 | - grub_printf ("%s%d+%d", num_entries ? "," : "", | ||
256 | - start_sector - part_start, num_sectors); | ||
257 | - else if (num_sectors > 1) | ||
258 | - grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "", | ||
259 | - start_sector - part_start, num_sectors-1, | ||
260 | - start_sector + num_sectors-1 - part_start, | ||
261 | - last_length); | ||
262 | - else | ||
263 | - grub_printf ("%s%d[0-%d]", num_entries ? "," : "", | ||
264 | - start_sector - part_start, last_length); | ||
265 | - num_entries++; | ||
266 | - num_sectors = 0; | ||
267 | - } | ||
268 | - } | ||
269 | - | ||
270 | - if (offset > 0) | ||
271 | - { | ||
272 | - grub_printf("%s%d[%d-%d]", num_entries ? "," : "", | ||
273 | - sector-part_start, offset, offset+length); | ||
274 | - num_entries++; | ||
275 | - } | ||
276 | - else | ||
277 | - { | ||
278 | - start_sector = sector; | ||
279 | - num_sectors = 1; | ||
280 | - last_length = length; | ||
281 | - } | ||
282 | - } | ||
283 | |||
284 | + int *start_sector = &blocklist_func_context.start_sector; | ||
285 | + int *num_sectors = &blocklist_func_context.num_sectors; | ||
286 | + int *num_entries = &blocklist_func_context.num_entries; | ||
287 | + | ||
288 | /* Open the file. */ | ||
289 | if (! grub_open (arg)) | ||
290 | return 1; | ||
291 | @@ -204,15 +241,15 @@ | ||
292 | grub_printf (")"); | ||
293 | |||
294 | /* Read in the whole file to DUMMY. */ | ||
295 | - disk_read_hook = disk_read_blocklist_func; | ||
296 | + disk_read_hook = blocklist_read_helper; | ||
297 | if (! grub_read (dummy, -1)) | ||
298 | goto fail; | ||
299 | |||
300 | /* The last entry may not be printed yet. Don't check if it is a | ||
301 | * full sector, since it doesn't matter if we read too much. */ | ||
302 | - if (num_sectors > 0) | ||
303 | - grub_printf ("%s%d+%d", num_entries ? "," : "", | ||
304 | - start_sector - part_start, num_sectors); | ||
305 | + if (*num_sectors > 0) | ||
306 | + grub_printf ("%s%d+%d", *num_entries ? "," : "", | ||
307 | + *start_sector - part_start, *num_sectors); | ||
308 | |||
309 | grub_printf ("\n"); | ||
310 | |||
311 | @@ -1868,6 +1905,77 @@ | ||
312 | |||
313 | |||
314 | /* install */ | ||
315 | +static struct { | ||
316 | + int saved_sector; | ||
317 | + int installaddr; | ||
318 | + int installlist; | ||
319 | + char *stage2_first_buffer; | ||
320 | +} install_func_context = { | ||
321 | + .saved_sector = 0, | ||
322 | + .installaddr = 0, | ||
323 | + .installlist = 0, | ||
324 | + .stage2_first_buffer = NULL, | ||
325 | +}; | ||
326 | + | ||
327 | +/* Save the first sector of Stage2 in STAGE2_SECT. */ | ||
328 | +/* Formerly disk_read_savesect_func with local scope inside install_func */ | ||
329 | +static void | ||
330 | +install_savesect_helper(int sector, int offset, int length) | ||
331 | +{ | ||
332 | + if (debug) | ||
333 | + printf ("[%d]", sector); | ||
334 | + | ||
335 | + /* ReiserFS has files which sometimes contain data not aligned | ||
336 | + on sector boundaries. Returning an error is better than | ||
337 | + silently failing. */ | ||
338 | + if (offset != 0 || length != SECTOR_SIZE) | ||
339 | + errnum = ERR_UNALIGNED; | ||
340 | + | ||
341 | + install_func_context.saved_sector = sector; | ||
342 | +} | ||
343 | + | ||
344 | +/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and INSTALLSECT. */ | ||
345 | +/* Formerly disk_read_blocklist_func with local scope inside install_func */ | ||
346 | +static void | ||
347 | +install_blocklist_helper (int sector, int offset, int length) | ||
348 | +{ | ||
349 | + int *installaddr = &install_func_context.installaddr; | ||
350 | + int *installlist = &install_func_context.installlist; | ||
351 | + char **stage2_first_buffer = &install_func_context.stage2_first_buffer; | ||
352 | + /* Was the last sector full? */ | ||
353 | + static int last_length = SECTOR_SIZE; | ||
354 | + | ||
355 | + if (debug) | ||
356 | + printf("[%d]", sector); | ||
357 | + | ||
358 | + if (offset != 0 || last_length != SECTOR_SIZE) | ||
359 | + { | ||
360 | + /* We found a non-sector-aligned data block. */ | ||
361 | + errnum = ERR_UNALIGNED; | ||
362 | + return; | ||
363 | + } | ||
364 | + | ||
365 | + last_length = length; | ||
366 | + | ||
367 | + if (*((unsigned long *) (*installlist - 4)) | ||
368 | + + *((unsigned short *) *installlist) != sector | ||
369 | + || *installlist == (int) *stage2_first_buffer + SECTOR_SIZE + 4) | ||
370 | + { | ||
371 | + *installlist -= 8; | ||
372 | + | ||
373 | + if (*((unsigned long *) (*installlist - 8))) | ||
374 | + errnum = ERR_WONT_FIT; | ||
375 | + else | ||
376 | + { | ||
377 | + *((unsigned short *) (*installlist + 2)) = (*installaddr >> 4); | ||
378 | + *((unsigned long *) (*installlist - 4)) = sector; | ||
379 | + } | ||
380 | + } | ||
381 | + | ||
382 | + *((unsigned short *) *installlist) += 1; | ||
383 | + *installaddr += 512; | ||
384 | +} | ||
385 | + | ||
386 | static int | ||
387 | install_func (char *arg, int flags) | ||
388 | { | ||
389 | @@ -1875,8 +1983,12 @@ | ||
390 | char *stage1_buffer = (char *) RAW_ADDR (0x100000); | ||
391 | char *stage2_buffer = stage1_buffer + SECTOR_SIZE; | ||
392 | char *old_sect = stage2_buffer + SECTOR_SIZE; | ||
393 | - char *stage2_first_buffer = old_sect + SECTOR_SIZE; | ||
394 | - char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; | ||
395 | + /* stage2_first_buffer used to be defined as: | ||
396 | + * char *stage2_first_buffer = old_sect + SECTOR_SIZE; */ | ||
397 | + char **stage2_first_buffer = &install_func_context.stage2_first_buffer; | ||
398 | + /* and stage2_second_buffer was: | ||
399 | + * char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; */ | ||
400 | + char *stage2_second_buffer = old_sect + SECTOR_SIZE + SECTOR_SIZE; | ||
401 | /* XXX: Probably SECTOR_SIZE is reasonable. */ | ||
402 | char *config_filename = stage2_second_buffer + SECTOR_SIZE; | ||
403 | char *dummy = config_filename + SECTOR_SIZE; | ||
404 | @@ -1885,10 +1997,11 @@ | ||
405 | int src_drive, src_partition, src_part_start; | ||
406 | int i; | ||
407 | struct geometry dest_geom, src_geom; | ||
408 | - int saved_sector; | ||
409 | + int *saved_sector = &install_func_context.saved_sector; | ||
410 | int stage2_first_sector, stage2_second_sector; | ||
411 | char *ptr; | ||
412 | - int installaddr, installlist; | ||
413 | + int *installaddr = &install_func_context.installaddr; | ||
414 | + int *installlist = &install_func_context.installlist; | ||
415 | /* Point to the location of the name of a configuration file in Stage 2. */ | ||
416 | char *config_file_location; | ||
417 | /* If FILE is a Stage 1.5? */ | ||
418 | @@ -1897,67 +2010,13 @@ | ||
419 | int is_open = 0; | ||
420 | /* If LBA is forced? */ | ||
421 | int is_force_lba = 0; | ||
422 | - /* Was the last sector full? */ | ||
423 | - int last_length = SECTOR_SIZE; | ||
424 | - | ||
425 | + | ||
426 | + *stage2_first_buffer = old_sect + SECTOR_SIZE; | ||
427 | #ifdef GRUB_UTIL | ||
428 | /* If the Stage 2 is in a partition mounted by an OS, this will store | ||
429 | the filename under the OS. */ | ||
430 | char *stage2_os_file = 0; | ||
431 | #endif /* GRUB_UTIL */ | ||
432 | - | ||
433 | - auto void disk_read_savesect_func (int sector, int offset, int length); | ||
434 | - auto void disk_read_blocklist_func (int sector, int offset, int length); | ||
435 | - | ||
436 | - /* Save the first sector of Stage2 in STAGE2_SECT. */ | ||
437 | - auto void disk_read_savesect_func (int sector, int offset, int length) | ||
438 | - { | ||
439 | - if (debug) | ||
440 | - printf ("[%d]", sector); | ||
441 | - | ||
442 | - /* ReiserFS has files which sometimes contain data not aligned | ||
443 | - on sector boundaries. Returning an error is better than | ||
444 | - silently failing. */ | ||
445 | - if (offset != 0 || length != SECTOR_SIZE) | ||
446 | - errnum = ERR_UNALIGNED; | ||
447 | - | ||
448 | - saved_sector = sector; | ||
449 | - } | ||
450 | - | ||
451 | - /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and | ||
452 | - INSTALLSECT. */ | ||
453 | - auto void disk_read_blocklist_func (int sector, int offset, int length) | ||
454 | - { | ||
455 | - if (debug) | ||
456 | - printf("[%d]", sector); | ||
457 | - | ||
458 | - if (offset != 0 || last_length != SECTOR_SIZE) | ||
459 | - { | ||
460 | - /* We found a non-sector-aligned data block. */ | ||
461 | - errnum = ERR_UNALIGNED; | ||
462 | - return; | ||
463 | - } | ||
464 | - | ||
465 | - last_length = length; | ||
466 | - | ||
467 | - if (*((unsigned long *) (installlist - 4)) | ||
468 | - + *((unsigned short *) installlist) != sector | ||
469 | - || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4) | ||
470 | - { | ||
471 | - installlist -= 8; | ||
472 | - | ||
473 | - if (*((unsigned long *) (installlist - 8))) | ||
474 | - errnum = ERR_WONT_FIT; | ||
475 | - else | ||
476 | - { | ||
477 | - *((unsigned short *) (installlist + 2)) = (installaddr >> 4); | ||
478 | - *((unsigned long *) (installlist - 4)) = sector; | ||
479 | - } | ||
480 | - } | ||
481 | - | ||
482 | - *((unsigned short *) installlist) += 1; | ||
483 | - installaddr += 512; | ||
484 | - } | ||
485 | |||
486 | /* First, check the GNU-style long option. */ | ||
487 | while (1) | ||
488 | @@ -1987,10 +2049,10 @@ | ||
489 | addr = skip_to (0, file); | ||
490 | |||
491 | /* Get the installation address. */ | ||
492 | - if (! safe_parse_maxint (&addr, &installaddr)) | ||
493 | + if (! safe_parse_maxint (&addr, installaddr)) | ||
494 | { | ||
495 | /* ADDR is not specified. */ | ||
496 | - installaddr = 0; | ||
497 | + *installaddr = 0; | ||
498 | ptr = addr; | ||
499 | errnum = 0; | ||
500 | } | ||
501 | @@ -2084,17 +2146,17 @@ | ||
502 | = (dest_drive & BIOS_FLAG_FIXED_DISK); | ||
503 | |||
504 | /* Read the first sector of Stage 2. */ | ||
505 | - disk_read_hook = disk_read_savesect_func; | ||
506 | - if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) | ||
507 | + disk_read_hook = install_savesect_helper; | ||
508 | + if (grub_read (*stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) | ||
509 | goto fail; | ||
510 | |||
511 | - stage2_first_sector = saved_sector; | ||
512 | + stage2_first_sector = *saved_sector; | ||
513 | |||
514 | /* Read the second sector of Stage 2. */ | ||
515 | if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE) | ||
516 | goto fail; | ||
517 | |||
518 | - stage2_second_sector = saved_sector; | ||
519 | + stage2_second_sector = *saved_sector; | ||
520 | |||
521 | /* Check for the version of Stage 2. */ | ||
522 | if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS)) | ||
523 | @@ -2110,27 +2172,27 @@ | ||
524 | |||
525 | /* If INSTALLADDR is not specified explicitly in the command-line, | ||
526 | determine it by the Stage 2 id. */ | ||
527 | - if (! installaddr) | ||
528 | + if (! *installaddr) | ||
529 | { | ||
530 | if (! is_stage1_5) | ||
531 | /* Stage 2. */ | ||
532 | - installaddr = 0x8000; | ||
533 | + *installaddr = 0x8000; | ||
534 | else | ||
535 | /* Stage 1.5. */ | ||
536 | - installaddr = 0x2000; | ||
537 | + *installaddr = 0x2000; | ||
538 | } | ||
539 | |||
540 | *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR)) | ||
541 | = stage2_first_sector; | ||
542 | *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS)) | ||
543 | - = installaddr; | ||
544 | + = *installaddr; | ||
545 | *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT)) | ||
546 | - = installaddr >> 4; | ||
547 | + = *installaddr >> 4; | ||
548 | |||
549 | - i = (int) stage2_first_buffer + SECTOR_SIZE - 4; | ||
550 | + i = (int) *stage2_first_buffer + SECTOR_SIZE - 4; | ||
551 | while (*((unsigned long *) i)) | ||
552 | { | ||
553 | - if (i < (int) stage2_first_buffer | ||
554 | + if (i < (int) *stage2_first_buffer | ||
555 | || (*((int *) (i - 4)) & 0x80000000) | ||
556 | || *((unsigned short *) i) >= 0xA00 | ||
557 | || *((short *) (i + 2)) == 0) | ||
558 | @@ -2144,13 +2206,13 @@ | ||
559 | i -= 8; | ||
560 | } | ||
561 | |||
562 | - installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4; | ||
563 | - installaddr += SECTOR_SIZE; | ||
564 | + *installlist = (int) *stage2_first_buffer + SECTOR_SIZE + 4; | ||
565 | + *installaddr += SECTOR_SIZE; | ||
566 | |||
567 | /* Read the whole of Stage2 except for the first sector. */ | ||
568 | grub_seek (SECTOR_SIZE); | ||
569 | |||
570 | - disk_read_hook = disk_read_blocklist_func; | ||
571 | + disk_read_hook = install_blocklist_helper; | ||
572 | if (! grub_read (dummy, -1)) | ||
573 | goto fail; | ||
574 | |||
575 | @@ -2233,7 +2295,7 @@ | ||
576 | /* Skip the first sector. */ | ||
577 | grub_seek (SECTOR_SIZE); | ||
578 | |||
579 | - disk_read_hook = disk_read_savesect_func; | ||
580 | + disk_read_hook = install_savesect_helper; | ||
581 | if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE) | ||
582 | goto fail; | ||
583 | |||
584 | @@ -2303,7 +2365,7 @@ | ||
585 | else | ||
586 | #endif /* GRUB_UTIL */ | ||
587 | { | ||
588 | - if (! devwrite (saved_sector - part_start, 1, stage2_buffer)) | ||
589 | + if (! devwrite (*saved_sector - part_start, 1, stage2_buffer)) | ||
590 | goto fail; | ||
591 | } | ||
592 | } | ||
593 | @@ -2325,7 +2387,7 @@ | ||
594 | goto fail; | ||
595 | } | ||
596 | |||
597 | - if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) | ||
598 | + if (fwrite (*stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) | ||
599 | { | ||
600 | fclose (fp); | ||
601 | errnum = ERR_WRITE; | ||
602 | @@ -2352,7 +2414,7 @@ | ||
603 | goto fail; | ||
604 | |||
605 | if (! devwrite (stage2_first_sector - src_part_start, 1, | ||
606 | - stage2_first_buffer)) | ||
607 | + *stage2_first_buffer)) | ||
608 | goto fail; | ||
609 | |||
610 | if (! devwrite (stage2_second_sector - src_part_start, 1, | ||
611 | --- grub-0.97/stage2/shared.h | ||
612 | +++ grub-0.97/stage2/shared.h | ||
613 | @@ -36,8 +36,8 @@ | ||
614 | |||
615 | /* Maybe redirect memory requests through grub_scratch_mem. */ | ||
616 | #ifdef GRUB_UTIL | ||
617 | -extern char *grub_scratch_mem; | ||
618 | -# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) | ||
619 | +extern void *grub_scratch_mem; | ||
620 | +# define RAW_ADDR(x) ((x) + (unsigned long) grub_scratch_mem) | ||
621 | # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) | ||
622 | #else | ||
623 | # define RAW_ADDR(x) (x) |