This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: LTO and libelf (and FreeBSD)
On Thu, May 20, 2010 at 7:19 PM, Kai Wang <kaiw@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))