(please read to the end)

On 08/23/13 15:04, Sergey Isakov wrote:
> No Martin,
> I deleted folders BaseTools and Conf and started ab ovo.
> The same error during compilation
> ---------
> GenFw: ERROR 3000: Invalid
> -----------
>
> On 23.08.2013, at 16:37, Olivier Martin wrote:
>
>> I have just tried to build OvmfPkg (command: ./OvmfPkg/build.sh) on
>> my machine (X64 host machine, GCC44) with the latest SVN revision and
>> it works fine for me.
>> I am using the latest BaseTools (clean rebuild) and its
>> configurations files.

I have reproduced this error with gcc-4.4 by:
- intentionally keeping my Conf/ directory across the BuildTools update
  (this causes the build error),
- regenerating the Conf/ directory after the update
  (with OvmfPkg/build.sh -- it works),
- since I keep my Conf/ directory in my git tree too, I can easily diff
  the changes, hunk for hunk.

The relevant hunk IMO is

    diff --git a/Conf/build_rule.txt b/Conf/build_rule.txt
    index 107e783..4a21aba 100644
    --- a/Conf/build_rule.txt
    +++ b/Conf/build_rule.txt
    @@ -301,8 +301,8 @@
             -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)

         <Command.GCC>
    -        $(OBJCOPY) --only-keep-debug ${src} 
$(DEBUG_DIR)(+)$(MODULE_NAME).debug
    -        $(OBJCOPY) --strip-unneeded ${src}
    +        $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug
    +        $(OBJCOPY) --strip-unneeded -R .eh_frame ${src}

             #
             #The below 2 lines are only needed for UNIXGCC tool chain, which 
genereates PE image directly

When I allow this hunk (coming from the BaseTools update) to take
effect, everything works fine. If I revert just this one hunk, I'm
seeing the exact same error:

    GenFw: ERROR 3000: Invalid
      /.../Build/OvmfX64/DEBUG_GCC44/X64/OvmfPkg/Sec/SecMain/DEBUG/SecMain.dll 
bad symbol definition.

(The above hunk affects the [Dynamic-Library-File] section, which is
consistent with the error being emitted for a DLL.)


I've reviewed the BaseTools sync itself (edk2 SVN r14591) to some
extent. One interesting hunk is:

    diff --git a/BaseTools/Scripts/gcc4.4-ld-script 
b/BaseTools/Scripts/gcc4.4-ld-script
    index d71dd9c..68b2767 100644
    --- a/BaseTools/Scripts/gcc4.4-ld-script
    +++ b/BaseTools/Scripts/gcc4.4-ld-script
    @@ -18,6 +18,10 @@ SECTIONS
         )
         . = ALIGN(0x20);
       }
    +  .eh_frame ALIGN(0x20) :
    +  {
    +    KEEP (*(.eh_frame))
    +  }
       .got ALIGN(0x20) :
       {
         *(.got .got.*)

(See eg.
<http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html>
for the meaning of .eh_frame.)

This linker script is used in "BaseTools/Conf/tools_def.template"
(citation wrapped for readability):

    DEFINE GCC44_IA32_X64_DLINK_COMMON   = -nostdlib -n -q \
      --gc-sections --script=$(EDK_TOOLS_PATH)/Scripts/gcc4.4-ld-script

The macro seems to be reused by all of GCC45, GCC46, GCC47.


So, my idea is,

(a) The BaseTools sync now instructs all gcc versions, from 4.4 to 4.7
inclusive, to keep the .eh_frame section.

(b) When turning a DLL file into an EFI file under GCC,

(b1) the debug symbols aren't copied separately into a .debug file with
     objcopy any longer -- the entire file is preserved,

(b2) When stripping the file, we have to strip .eh_frame manually
     (with the -R option), basically "undoing" step (a) above,
     because apparently --strip-unneeded doesn't include it

The GenFw call directly follows the modified objcopy invocation (the one
with the '-R .eh_frame' option).

Now, because my reversion of the <Command.GCC> hunk reproduces the error
on gcc-4.4, I think we can safely say that (with gcc-4.4) it is the
.eh_frame section that trips up GenFw.

The GenFw error message is printed in
"BaseTools/Source/C/GenFw/Elf64Convert.c", function WriteSections64():

      //
      // Process all relocation entries for this section.
      //
      for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) 
RelShdr->sh_entsize) {

        //
        // Set pointer to relocation entry
        //
        Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + 
RelIdx);

        //
        // Set pointer to symbol table entry associated with the relocation 
entry.
        //
        Elf_Sym  *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * 
SymtabShdr->sh_entsize);

        Elf_Shdr *SymShdr;
        UINT8    *Targ;

        //
        // Check section header index found in symbol table and get the section
        // header location.
        //
        if (Sym->st_shndx == SHN_UNDEF
            || Sym->st_shndx == SHN_ABS
            || Sym->st_shndx > mEhdr->e_shnum) {
          Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", 
mInImageName);
        }

So, we're traversing relocation entries. For each relocation entry, we
look up the referenced symbol (the symbol to be relocated). If this
symbol has unexpected properties, we bail.

Now check out the contents of "SecMain.dll" *unless* we strip the
.eh_frame section (with 'readelf --all'):

    Section Headers:
      [ 5] .eh_frame         PROGBITS        000000000000a100 009f40 000b50 00  
 A  0   0  8
      [ 6] .rela.eh_frame    RELA            0000000000000000 010318 0018c0 18  
    9   5  8
    ...
    Relocation section '.rela.eh_frame' at offset 0x10318 contains 264 entries:
    ...

This seems to confirm the theory: the above loop likely finds the
".rela.eh_frame" section, with 264 entries. I guess those relocation
entries point into the .eh_frame section. Stuff in .eh_frame is
something that GenFw doesn't like, so it bails out.

'objcopy --strip-unneeded' doesn't remove either of ".eh_frame" or
".rela.eh_frame". The option '-R .eh_frame' removes both.


All this seems to imply that the gcc-4.7 toolchain puts *yet another*
extra section (with its corresponding relocation section) into the DLL
file -- something *else* that the objcopy command should remove by hand
(with -R). This does not happen, and GenFw chokes on symbols in that
mysterious section.

Sergey, can you please post the output of:

  readelf --all --wide FILE-THAT-TRIPS-UP-GenFw.dll

Thanks,
Laszlo


------------------------------------------------------------------------------
Introducing Performance Central, a new site from SourceForge and 
AppDynamics. Performance Central is your source for news, insights, 
analysis and resources for efficient Application Performance Management. 
Visit us today!
http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to