From owner-svn-src-all@FreeBSD.ORG Thu Sep 9 18:51:50 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CE7F010656C2; Thu, 9 Sep 2010 18:51:50 +0000 (UTC) (envelope-from kaiw@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A47688FC1B; Thu, 9 Sep 2010 18:51:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o89IpotQ019037; Thu, 9 Sep 2010 18:51:50 GMT (envelope-from kaiw@svn.freebsd.org) Received: (from kaiw@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o89IpoFR019035; Thu, 9 Sep 2010 18:51:50 GMT (envelope-from kaiw@svn.freebsd.org) Message-Id: <201009091851.o89IpoFR019035@svn.freebsd.org> From: Kai Wang Date: Thu, 9 Sep 2010 18:51:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212373 - head/lib/libelf X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Sep 2010 18:51:50 -0000 Author: kaiw Date: Thu Sep 9 18:51:50 2010 New Revision: 212373 URL: http://svn.freebsd.org/changeset/base/212373 Log: libelf is overly strict about the type and alignment of Elf_Data objects inside one ELF section, which prevents the creation of a ELF section with mixed data types. For example, gcc LTO use libelf to create a .gnu_lto_XXX section that contains integers and a string table, which doesn't work with our libelf implementation. The changes made in this commit include: * Allow Elf_Data type to be different than section type. * Relax Elf_Data alignment check. * Align each Elf_Data by their own alignment instead of section alignment. MFC after: 1 month Modified: head/lib/libelf/elf_update.c Modified: head/lib/libelf/elf_update.c ============================================================================== --- head/lib/libelf/elf_update.c Thu Sep 9 18:51:20 2010 (r212372) +++ head/lib/libelf/elf_update.c Thu Sep 9 18:51:50 2010 (r212373) @@ -141,7 +141,7 @@ _libelf_compute_section_extents(Elf *e, /* Compute the section alignment. */ STAILQ_FOREACH(d, &s->s_data, d_next) { - if (d->d_type != elftype) { + if (d->d_type > ELF_T_LAST) { LIBELF_SET_ERROR(DATA, 0); return (0); } @@ -149,11 +149,7 @@ _libelf_compute_section_extents(Elf *e, LIBELF_SET_ERROR(VERSION, 0); return (0); } - if ((d_align = d->d_align) % sh_align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - if (d_align == 0 || (d_align & (d_align - 1))) { + if ((d_align = d->d_align) == 0 || (d_align & (d_align - 1))) { LIBELF_SET_ERROR(DATA, 0); return (0); } @@ -168,7 +164,7 @@ _libelf_compute_section_extents(Elf *e, if ((uint64_t) d->d_off + d->d_size > scn_size) scn_size = d->d_off + d->d_size; } else { - scn_size = roundup2(scn_size, scn_alignment); + scn_size = roundup2(scn_size, d->d_align); d->d_off = scn_size; scn_size += d->d_size; } @@ -560,8 +556,6 @@ _libelf_write_scn(Elf *e, char *nf, Elf_ elftype = _libelf_xlate_shtype(sh_type); assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); - msz = _libelf_msize(elftype, ec, e->e_version); - sh_off = s->s_offset; assert(sh_off % _libelf_falign(elftype, ec) == 0); @@ -608,6 +602,8 @@ _libelf_write_scn(Elf *e, char *nf, Elf_ STAILQ_FOREACH(d, &s->s_data, d_next) { + msz = _libelf_msize(d->d_type, ec, e->e_version); + if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); @@ -615,13 +611,12 @@ _libelf_write_scn(Elf *e, char *nf, Elf_ rc = sh_off + d->d_off; assert(d->d_buf != NULL); - assert(d->d_type == (Elf_Type) elftype); assert(d->d_version == e->e_version); assert(d->d_size % msz == 0); nobjects = d->d_size / msz; - fsz = _libelf_fsize(elftype, ec, e->e_version, nobjects); + fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); dst.d_buf = nf + rc; dst.d_size = fsz;