public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Andrew Fish <afish@apple.com>
To: valerij zaporogeci <vlrzprgts@gmail.com>
Cc: edk2-devel <edk2-devel@lists.01.org>
Subject: Re: TE relocations
Date: Wed, 05 Oct 2016 09:51:06 -0700	[thread overview]
Message-ID: <68CAE063-1A6B-493B-B728-B2991F018DC6@apple.com> (raw)
In-Reply-To: <CANPuzFwKjhBks_ASxhWQ8CTi8faUQ=k0vpAzf-VbFfYY0hpoWw@mail.gmail.com>


> On Oct 5, 2016, at 8:08 AM, valerij zaporogeci <vlrzprgts@gmail.com> wrote:
> 
> Hi everyone. I have a problem with understanding the description of TE
> files and its relocations.

TE is basically PE/COFF with a smaller header. Unlike ELF (Mach-O, etc.) PE/COFF includes the headers in the executable image. The TE header is basically the bits required by EFI and the adjustments (so you can calculate the location the PE/COFF header would have started, since the sections are relative to that in the PE/COFF debug info) needed by the debugger to turn it into a PE/COFF. 

The only reason TE exists is to save size in the ROM for XIP code. The build tools zero out the unused parts of the PE/COFF header so they tend to compress well and TE is not needed. 

> The specifications says this:
> "17.2 XIP Images
> For execute-in-place (XIP) images that do not require relocations,
> loading a TE image simply
> requires that the loader adjust the image’s entry point from the value
> specified in the
> EFI_TE_IMAGE_HEADER. For example, if the image (and thus the TE
> header) resides at memory
> location LoadedImageAddress, then the actual entry for the driver is
> computed as follows:
> EntryPoint = LoadedImageAddress + sizeof (EFI_TE_IMAGE_HEADER)
> +
> ((EFI_TE_IMAGE_HEADER *)LoadedImageAddress)–>
> AddressOfEntryPoint – ((EFI_TE_IMAGE_HEADER *)
> LoadedImageAddress)–>StrippedSize;"
> 
> But it looks not as simple as "simply" adjusting the only
> AddressOfEntryPoint. What "do not require relocations means" here?

PE/COFF images are linked at a specific address and can execute directly if they are run from that address. If a PE/COFF image is loaded/executed from a different address the relocations must be applied to adjust all the absolute references in the image to the new addresses. 

The edk2 links PE/COFF images at zero (or for things like ELF they add a pad for the PE/COFF header ~0x220). When an FV is constructed and XIP (SEC, PEIM, and PEI CORE) images are placed in the FV these PE/COFF images get relocated to the address in the FV (ROM address). 

If the code is XIP then there is no need for relocations as that code can run from any address. 

I think this section is making the point that even if the image does not contain any relocations (all code is PC relative for example) you still have to adjust the EntryPoint to point to ROM address of the entry point. 

> Suppose an Image has ImageBase set to X in its header, and it IS at
> the address X in XIP memory. Will it need relocations?

No. 

> For PE it
> won't, but it seems it is not the case for TE. Since not only
> AddressOfEntryPoint is affected, also CodeBase, sections RVAs and all
> base relocations too. They all are lying not at their RVA in XIP
> memory, because TE has a smaller header and screws up even
> FileAlignment of sections. Doesn't it?

No. The TE header lets you compute the location of the PE/COFF header as this is required to make debuggers happy. So part of the TE construction is making sure the virtual start of the PE/COFF header is aligned correctly. You also need to make sure that the file alignment and section alignment are the same. For most toolchains 0x20 is uses as the file and section alignment to save space.

Note: 0x20 was picked as that was the smallest value we could get to work with Visual Studio "back in the day."

> The adjustment in the quote uses StrippedSize and it is described as
> what was removed from PE:
> 
> "The StrippedSize should be set to the number of bytes removed from
> the start of the original
> image, which will typically include the MS-DOS, COFF, and optional
> headers, as well as the section headers."
> 
> But does it take into account section alignment by FileAlignment?

Yes as I pointed out section alignment and FileAlignment has to be the same for XIP to work. 

> (SectionAlignment==FileAlignment in this case). Because for example if
> FileAlignment = 200h, then in PE, section for code would be sitting at
> n*200h from the beginning of the file and from ImageBase in XIP
> memory.
> Here is how specification describes PE->TE tranformation process:
> "• Create an EFI_TE_IMAGE_HEADER in memory
> • Parse the PE/COFF headers in an existing image and extract the
> necessary fields to fill in  the EFI_TE_IMAGE_HEADER
> • Fill in the signature and stripped size fields in the EFI_TE_IMAGE_HEADER
> • Write out the EFI_TE_IMAGE_HEADER to a new binary file
> • Write out the contents of the original image, less the stripped
> headers, to the output file"
> 
> This process would place any section at different file offset
> (dispecting alignment) than in PE, and as a result for XIP - different
> RVA from ImageBase. For XIP this would mean that such a file requires
> relocation, even though its actual ImageBase is exactly what is
> written in the file. For non-XIP it would mean that the loader would
> need section headers to know what displacement to put the section to
> in memory to not break addresses. But they are stripped! Otherwise, if
> it just blindly copies what is after TE header, RVAs would be broken,
> all addresses would be broken, as for XIP.
> In fact this means any TE file loaded at its preferred ImageBase will
> need relocations. And for non-XIP. section header cannot be stripped.
> Then what TE files would not need relocations?

Any TE that executes from the ROM directly does not need relocations. That is how it works today. As long as SectionAlignment == FileAlignment then everything works from an XIP point of view. 

I guess we could have some bugs in the entire stack (PE/COFF -> TE -> FV) of not honoring the original PE/COFF alignment? But as my Niece would say Meh. The point of TE is to save space in the ROM vs. PE/COFF so if the section alignment is 0x200 there is no point in using TE, you should just use PE/COFF. 

The rules in the FDF file allow you to control if XIP code is TE or PE/COFF. It looks like different platforms pick different rules. 
https://github.com/tianocore/edk2/blob/master/QuarkPlatformPkg/QuarkMin.fdf#L517 <https://github.com/tianocore/edk2/blob/master/QuarkPlatformPkg/QuarkMin.fdf#L517>
https://github.com/tianocore/edk2/blob/master/OvmfPkg/OvmfPkgX64.fdf#L420 <https://github.com/tianocore/edk2/blob/master/OvmfPkg/OvmfPkgX64.fdf#L420>

It is also possible to control on a per module basis if an XIP image in TE or PE/COFF using RuleOverride in the FDF. 

Thanks,

Andrew Fish

PS. I was looking at the TE Image Header and I was reminded that Vincent Zimmer used his initials for the TE signature. I'm sure Vincent will claim this was an ode to Mark Zbikowski, since MZ is the signature in the DOS header :). 
 https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/PeImage.h#L719 <https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/PeImage.h#L719>
  UINT16                    Signature;            ///< The signature for TE format = "VZ".


> Did I understand right?
> Thank you for answers.
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel



  reply	other threads:[~2016-10-05 16:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-05 15:08 TE relocations valerij zaporogeci
2016-10-05 16:51 ` Andrew Fish [this message]
2016-10-05 19:24   ` valerij zaporogeci
2016-10-05 20:58     ` Andrew Fish
2016-10-05 21:45       ` valerij zaporogeci
2016-10-05 22:11         ` Andrew Fish
2016-10-05 23:25           ` valerij zaporogeci
2016-10-06  0:07             ` Andrew Fish
2016-10-06 13:01               ` valerij zaporogeci
2016-10-08  8:54               ` Gao, Liming

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=68CAE063-1A6B-493B-B728-B2991F018DC6@apple.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox