grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] fix multiboot/aout, cleanup relocators, etc


From: Robert Millan
Subject: Re: [PATCH] fix multiboot/aout, cleanup relocators, etc
Date: Thu, 7 Aug 2008 12:20:44 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Thu, Aug 07, 2008 at 01:27:53AM +0200, Robert Millan wrote:
> 
> Hi,
> 
> It seems when adding the relocators for ELF, I failed to notice both ELF and
> a.out loaders share the same grub_multiboot_real_boot function, and hence my
> code was trashing %eax.
> 
> Since this functionality is useful for the a.out loader anyway, I decided to
> implement it as well.  In the process I did some cleanup, mostly to reduce
> code duplication among both users of the relocators.
> 
> So here's the patch.  Please comment!

I think I should ellaborate a bit on this:

>    if (header->flags & MULTIBOOT_AOUT_KLUDGE)
>      {
> -      int ofs;
> +      int offset = ((char *) header - buffer -
> +                 (header->header_addr - header->load_addr));
> +      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
> +                    header->load_end_addr - header->load_addr);
>  
> -      ofs = (char *) header - buffer -
> -            (header->header_addr - header->load_addr);
> -      if ((grub_aout_load (file, ofs, header->load_addr,
> -                           ((header->load_end_addr == 0) ? 0 :
> -                            header->load_end_addr - header->load_addr),
> -                           header->bss_end_addr))
> -          !=GRUB_ERR_NONE)
> -        goto fail;
> +      if (header->bss_end_addr)
> +     grub_multiboot_payload_size = (header->bss_end_addr - 
> header->load_addr);
> +      else
> +     grub_multiboot_payload_size = load_size;
> +      grub_multiboot_payload_dest = header->load_addr;
>  
> -      entry = header->entry_addr;
> +      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + 
> grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
> +      if (! playground)
> +     goto fail;
> +
> +      grub_multiboot_payload_orig = (long) playground + 
> RELOCATOR_SIZEOF(forward);
> +
> +      if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
> +     goto fail;
> +
> +      grub_file_read (file, grub_multiboot_payload_orig, load_size);
> +      if (grub_errno)
> +     goto fail;
> +      
> +      if (header->bss_end_addr)
> +     grub_memset (grub_multiboot_payload_orig + load_size, 0,
> +                  header->bss_end_addr - header->load_addr - load_size);
> +      
> +      grub_multiboot_payload_entry_offset = header->entry_addr - 
> header->load_addr;
> +
>      }

The problem I had here is that grub_aout_load() was constrained to the api
used by our BSD loaders, and the relocator approach requires to intermangle
things, so I had to move it to multiboot.c and transform it.

Splitting it to a separate function (like we do for multiboot/ELF) wouldn't
be hard if this is seen as a good idea, but making it global wouldn't be so
sound IMHO: it relies on the relocator variables, so one would have to
implement relocators in each a.out loader, which doesn't sound like such a
bad idea, but the relocator code itself is biased towards multiboot (written
to preserve %eax and %ebx), and so it's not as generic as it looks, as other
load protocols might have conflicting constraints.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]