Add LZSS Mach-O support (needed for new xnu kernelcache).
* grub-core/Makefile.core.def (xnu): Add file lzss.c * grub-core/loader/lzss.c: New file. * grub-core/loader/xnu.c (grub_xnu_load_driver): Close binaryfile on Mach-O open failure. * grub-core/loader/macho.c (grub_macho_close): Free uncompressedXX. Don't free cmdsXX in uncompressedXX is set. (grub_macho_file): Init new fields. New argument is_64bit. All users updated. Handle compressed. Error out if no suitable architecture is found. Don't close file. (grub_macho_open): New argument is_64bit. All users updated. * grub-core/loader/macho32.c: Add defines for new fields. * grub-core/loader/macho64.c: Likewise. * grub-core/loader/machoXX.c (grub_macho_contains_macho): Make static. (grub_macho_parse): Handle compressed. Defer actual processing if compressed. (grub_macho_cmds_iterate): Decompress if compressed. New argument "filename". All users updated. (grub_macho_size): New argument "filename". All users updated. (grub_macho_get_entry_point): Likewise. (grub_macho_load): Handle compressed. * include/grub/macho.h (grub_macho_lzss_header): New struct. (GRUB_MACHO_LZSS_OFFSET): New define. (grub_decompress_lzss): New proto. * include/grub/machoload.h (grub_macho_file): New fields to handle compressed. (grub_macho_contains_macho64): Remove proto. (grub_macho_contains_macho32): Likewise. * util/grub.d/30_os-prober.in: Use kernel cache if available.
This commit is contained in:
parent
ebd17d6f51
commit
99ce1597a4
11 changed files with 339 additions and 80 deletions
|
@ -35,8 +35,12 @@ grub_macho_close (grub_macho_t macho)
|
|||
{
|
||||
grub_file_t file = macho->file;
|
||||
|
||||
grub_free (macho->cmds32);
|
||||
grub_free (macho->cmds64);
|
||||
if (!macho->uncompressed32)
|
||||
grub_free (macho->cmds32);
|
||||
grub_free (macho->uncompressed32);
|
||||
if (!macho->uncompressed64)
|
||||
grub_free (macho->cmds64);
|
||||
grub_free (macho->uncompressed64);
|
||||
|
||||
grub_free (macho);
|
||||
|
||||
|
@ -47,7 +51,7 @@ grub_macho_close (grub_macho_t macho)
|
|||
}
|
||||
|
||||
grub_macho_t
|
||||
grub_macho_file (grub_file_t file, const char *filename)
|
||||
grub_macho_file (grub_file_t file, const char *filename, int is_64bit)
|
||||
{
|
||||
grub_macho_t macho;
|
||||
union grub_macho_filestart filestart;
|
||||
|
@ -63,6 +67,10 @@ grub_macho_file (grub_file_t file, const char *filename)
|
|||
macho->end64 = -1;
|
||||
macho->cmds32 = 0;
|
||||
macho->cmds64 = 0;
|
||||
macho->uncompressed32 = 0;
|
||||
macho->uncompressed64 = 0;
|
||||
macho->compressed32 = 0;
|
||||
macho->compressed64 = 0;
|
||||
|
||||
if (grub_file_seek (macho->file, 0) == (grub_off_t) -1)
|
||||
goto fail;
|
||||
|
@ -104,14 +112,14 @@ grub_macho_file (grub_file_t file, const char *filename)
|
|||
for (i = 0; i < narchs; i++)
|
||||
{
|
||||
if (GRUB_MACHO_CPUTYPE_IS_HOST32
|
||||
(grub_be_to_cpu32 (archs[i].cputype)))
|
||||
(grub_be_to_cpu32 (archs[i].cputype)) && !is_64bit)
|
||||
{
|
||||
macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
|
||||
macho->end32 = grub_be_to_cpu32 (archs[i].offset)
|
||||
+ grub_be_to_cpu32 (archs[i].size);
|
||||
}
|
||||
if (GRUB_MACHO_CPUTYPE_IS_HOST64
|
||||
(grub_be_to_cpu32 (archs[i].cputype)))
|
||||
(grub_be_to_cpu32 (archs[i].cputype)) && is_64bit)
|
||||
{
|
||||
macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
|
||||
macho->end64 = grub_be_to_cpu32 (archs[i].offset)
|
||||
|
@ -122,14 +130,29 @@ grub_macho_file (grub_file_t file, const char *filename)
|
|||
}
|
||||
|
||||
/* Is it a thin 32-bit file? */
|
||||
if (filestart.thin32.magic == GRUB_MACHO_MAGIC32)
|
||||
if (filestart.thin32.magic == GRUB_MACHO_MAGIC32 && !is_64bit)
|
||||
{
|
||||
macho->offset32 = 0;
|
||||
macho->end32 = grub_file_size (file);
|
||||
}
|
||||
|
||||
/* Is it a thin 64-bit file? */
|
||||
if (filestart.thin64.magic == GRUB_MACHO_MAGIC64)
|
||||
if (filestart.thin64.magic == GRUB_MACHO_MAGIC64 && is_64bit)
|
||||
{
|
||||
macho->offset64 = 0;
|
||||
macho->end64 = grub_file_size (file);
|
||||
}
|
||||
|
||||
if (grub_memcmp (filestart.lzss.magic, GRUB_MACHO_LZSS_MAGIC,
|
||||
sizeof (filestart.lzss.magic)) == 0 && !is_64bit)
|
||||
{
|
||||
macho->offset32 = 0;
|
||||
macho->end32 = grub_file_size (file);
|
||||
}
|
||||
|
||||
/* Is it a thin 64-bit file? */
|
||||
if (grub_memcmp (filestart.lzss.magic, GRUB_MACHO_LZSS_MAGIC,
|
||||
sizeof (filestart.lzss.magic)) == 0 && is_64bit)
|
||||
{
|
||||
macho->offset64 = 0;
|
||||
macho->end64 = grub_file_size (file);
|
||||
|
@ -138,15 +161,30 @@ grub_macho_file (grub_file_t file, const char *filename)
|
|||
grub_macho_parse32 (macho, filename);
|
||||
grub_macho_parse64 (macho, filename);
|
||||
|
||||
if (macho->offset32 == -1 && !is_64bit)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS,
|
||||
"Mach-O doesn't contain suitable 32-bit architecture");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (macho->offset64 == -1 && is_64bit)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS,
|
||||
"Mach-O doesn't contain suitable 64-bit architecture");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return macho;
|
||||
|
||||
fail:
|
||||
macho->file = 0;
|
||||
grub_macho_close (macho);
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_macho_t
|
||||
grub_macho_open (const char *name)
|
||||
grub_macho_open (const char *name, int is_64bit)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_macho_t macho;
|
||||
|
@ -155,7 +193,7 @@ grub_macho_open (const char *name)
|
|||
if (! file)
|
||||
return 0;
|
||||
|
||||
macho = grub_macho_file (file, name);
|
||||
macho = grub_macho_file (file, name, is_64bit);
|
||||
if (! macho)
|
||||
grub_file_close (file);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue