On Thu, May 20, 2010 at 7:19 PM, Kai Wang <k...@freebsd.org> wrote: > On Sun, May 02, 2010 at 11:38:39PM +0200, Gerald Pfeifer wrote: >> As http://gcc.gnu.org/ml/gcc-testresults/2010-05/msg00120.html shows, >> *-unknown-freebsd* exhibits tons of failures around LTO. >> >> I dug a bit deeper, and even the most trivial test program >> int main() { } >> fails with >> lto1: internal compiler error: compressed stream: data error >> Please submit a full bug report, >> with preprocessed source if appropriate. >> See <http://gcc.gnu.org/bugs.html> for instructions. >> lto-wrapper: /files/pfeifer/gcc/bin/gcc returned 1 exit status >> collect2: lto-wrapper returned 1 exit status >> when compiled with gcc -flto x.c. > > Hi Gerald, > > First sorry about the late reply. > > The problem is indeed caused by a small incomptibility of FreeBSD > libelf with other libelf implementations. > > The elf_getbase() API in FreeBSD libelf can only be called using > an archive member ELF descriptor. It will return -1 (indicates an error) > when called with a "regular" ELF object. > > The lto_obj_build_section_table() function in lto-elf.c calls > elf_getbase() to get the offset base for a "regular" ELF object. On > FreeBSD it gets -1. (Side notes: lto-elf.c should really check return > values of libelf APIs) And later it uses -1 as base_offset for all the > ELF sections thus results in an off-by-one error when passing the > section data to zlib to inflate.
Interesting. We are sure that elf_getbase does not fail at that point. > Could you please try applying the attached patch to the libelf in > FreeBSD 7.3 and see if it fixes gcc4.6 lto? Or the following workaround for gcc. Richard. Index: lto/lto-elf.c =================================================================== --- lto/lto-elf.c (revision 159624) +++ lto/lto-elf.c (working copy) @@ -189,6 +189,13 @@ lto_obj_build_section_table (lto_file *l section_hash_table = htab_create (37, hash_name, eq_name, free); base_offset = elf_getbase (elf_file->elf); + /* We are reasonably sure that elf_getbase does not fail at this + point. So assume that we run into the incompatibility with + the FreeBSD libelf implementation that has a non-working + elf_getbase for non-archive members in which case the offset + should be zero. */ + if (base_offset == (size_t)-1) + base_offset = 0; for (section = elf_getscn (elf_file->elf, 0); section; section = elf_nextscn (elf_file->elf, section))