(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