From owner-freebsd-stable@freebsd.org Wed Jul 15 23:18:24 2015 Return-Path: Delivered-To: freebsd-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E1B6B9A213F for ; Wed, 15 Jul 2015 23:18:23 +0000 (UTC) (envelope-from janm@transactionware.com) Received: from mail3.transactionware.com (mail.transactionware.com [203.14.245.7]) by mx1.freebsd.org (Postfix) with SMTP id 514F11946 for ; Wed, 15 Jul 2015 23:18:22 +0000 (UTC) (envelope-from janm@transactionware.com) Received: (qmail 32599 invoked by uid 907); 15 Jul 2015 23:18:18 -0000 Received: from eth222.nsw.adsl.internode.on.net (HELO [192.168.1.32]) (150.101.196.221) (smtp-auth username janm, mechanism plain) by mail3.transactionware.com (qpsmtpd/0.84) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Thu, 16 Jul 2015 09:18:18 +1000 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2102\)) Subject: Re: amd64 kernel dynamic linking allows extern references to statics From: Jan Mikkelsen In-Reply-To: <20150715132744.GD2404@kib.kiev.ua> Date: Thu, 16 Jul 2015 09:18:15 +1000 Cc: FreeBSD Stable Mailing List , Karl Denninger Content-Transfer-Encoding: quoted-printable Message-Id: References: <13C52D9D-E1E6-4F83-A881-4E867C336B31@transactionware.com> <20150715132744.GD2404@kib.kiev.ua> To: Konstantin Belousov X-Mailer: Apple Mail (2.2102) X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jul 2015 23:18:24 -0000 > On 15 Jul 2015, at 11:27 pm, Konstantin Belousov = wrote: >=20 > On Wed, Jul 15, 2015 at 06:17:20PM +1000, Jan Mikkelsen wrote: >> Hi, >>=20 >> (All on 10.2-BETA1.) >>=20 >> I noticed that the latest patch in the bug = https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D187594 = works on = amd64 but fails to load zfs.ko on i386 with a symbol not found error. >>=20 >> Looking at the patch, there is one file that has ???extern int = zio_use_uma??? to reference a variable that is declared elsewhere as = ???static int zio_use_uma???. To me this obviously should not work. = However it does work on amd64 but fails on i386. >>=20 >> Below is a small test case that reproduces the problem. The generated = kernel module loads on amd64 but fails on i386. On amd64 one compilation = unit is accessing a static in from another compilation unit by declaring = the variable ???extern???.=20 >>=20 >> I haven???t looked further to attempt to find the bug. However, it = looks like a Bad Thing??? to me. >>=20 >=20 > I am not sure that this is fixable. Issue is that amd64 modules are > relinked object files, and they might have unresolved relocations = against > local symbols. Change like the following probably fix your test case, > but also quite possible would break legitimate local references. >=20 > diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c > index 021381d..6fa5276 100644 > --- a/sys/kern/link_elf_obj.c > +++ b/sys/kern/link_elf_obj.c > @@ -1096,7 +1096,8 @@ link_elf_lookup_symbol(linker_file_t lf, const = char *name, c_linker_sym_t *sym) >=20 > for (i =3D 0, symp =3D ef->ddbsymtab; i < ef->ddbsymcnt; i++, = symp++) { > strp =3D ef->ddbstrtab + symp->st_name; > - if (symp->st_shndx !=3D SHN_UNDEF && strcmp(name, strp) = =3D=3D 0) { > + if (symp->st_shndx !=3D SHN_UNDEF && strcmp(name, strp) = =3D=3D 0 && > + ELF_ST_BIND(symp->st_info) !=3D STB_LOCAL) { > *sym =3D (c_linker_sym_t) symp; > return 0; > } I don=E2=80=99t know why there could be an unresolved relocation against = a local symbol. My (admittedly trivial) tests with nm and static = functions/variables have not led to a =E2=80=9CU=E2=80=9D record. Under = what circumstances would this happen? Separately to this is that this behaviour also defeats multiple = definition checking at link time. Modifying my test slightly to have one = compilation unit with =E2=80=9Cstatic int testvar=E2=80=9D, one = compilation unit with =E2=80=9Cint testvar=E2=80=9D and one with = =E2=80=9Cextern int testvar=E2=80=9D gives nm output like this from the = .ko file: 00000000000000d0 d testvar 00000000000000c0 d testvar It is unclear which instance of testvar the =E2=80=9Cextern=E2=80=9D = declaration used for resolution. Simple testing seems to show it was the = one with the non-static storage class. However, a piece of code = depending on the previous resolution to local names could break by the = addition a file with a name clash. Also, not no =E2=80=9CU=E2=80=9D = record =E2=80=94 the =E2=80=9Cextern int testvar=E2=80=9D declaration = has been resolved at this point. Making both definitions static gives this: U testvar 00000000000000c0 d testvar 00000000000000d0 d testvar Which testvar will I get at load time? Who knows? Adding a file with a = static variable with a name clash in another compilation unit can change = the behaviour of a module. The big question for me is: under which legitimate case is this feature = necessary? The downsides seem significant. Regards, Jan.