Date: Wed, 15 Jul 2015 16:27:44 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Jan Mikkelsen <janm@transactionware.com> Cc: FreeBSD Stable Mailing List <freebsd-stable@freebsd.org>, Karl Denninger <karl@denninger.net> Subject: Re: amd64 kernel dynamic linking allows extern references to statics Message-ID: <20150715132744.GD2404@kib.kiev.ua> In-Reply-To: <13C52D9D-E1E6-4F83-A881-4E867C336B31@transactionware.com> References: <13C52D9D-E1E6-4F83-A881-4E867C336B31@transactionware.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Jul 15, 2015 at 06:17:20PM +1000, Jan Mikkelsen wrote: > Hi, > > (All on 10.2-BETA1.) > > I noticed that the latest patch in the bug https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=187594 <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=187594> works on amd64 but fails to load zfs.ko on i386 with a symbol not found error. > > 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. > > 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???. > > I haven???t looked further to attempt to find the bug. However, it looks like a Bad Thing??? to me. > 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. 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) for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { strp = ef->ddbstrtab + symp->st_name; - if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { + if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0 && + ELF_ST_BIND(symp->st_info) != STB_LOCAL) { *sym = (c_linker_sym_t) symp; return 0; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150715132744.GD2404>