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. Could you please try applying the attached patch to the libelf in FreeBSD 7.3 and see if it fixes gcc4.6 lto? Thanks, Kai
diff -urN libelf.orig/elf_getbase.c libelf/elf_getbase.c --- libelf.orig/elf_getbase.c 2010-05-20 18:49:43.000000000 +0200 +++ libelf/elf_getbase.c 2010-05-20 18:52:49.000000000 +0200 @@ -34,12 +34,14 @@ off_t elf_getbase(Elf *e) { - if (e == NULL || - e->e_parent == NULL) { + if (e == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (off_t) -1; } - return ((off_t) ((uintptr_t) e->e_rawfile - - (uintptr_t) e->e_parent->e_rawfile)); + if (e->e_parent) + return ((off_t) ((uintptr_t) e->e_rawfile - + (uintptr_t) e->e_parent->e_rawfile)); + else + return (off_t) 0; }