Contents of /trunk/grub/patches/grub-0.97-nxstack.patch
Parent Directory | Revision Log
Revision 144 -
(show 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 | 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) |