amd64 kernel dynamic linking allows extern references to statics

Jan Mikkelsen janm at transactionware.com
Wed Jul 15 08:17:30 UTC 2015


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.

Regards,

Jan.

——Makefile:

KMOD=   refstatic
SRCS=   refstatic.c testfunc.c bus_if.h device_if.h pci_if.h

.include <bsd.kmod.mk>



—— refstatic.c:

#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/kthread.h>

#include <sys/conf.h>
#include <sys/uio.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/queue.h>

#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>

#include <machine/bus.h>
#include <machine/resource.h>

static int testvar = 1;
int func(void);

static int refstatic_probe(device_t dev)
{
    ++testvar;
    device_printf(dev, "func returns %d\n", func());
    return ENXIO;
}

static int refstatic_attach(device_t dev)
{
    (void) dev;
    return ENXIO;
}

static int refstatic_detach(device_t dev)
{
    return 0;
}


static device_method_t refstatic_methods[] = {
    DEVMETHOD(device_probe, refstatic_probe),
    DEVMETHOD(device_attach, refstatic_attach),
    DEVMETHOD(device_detach, refstatic_detach),
    { 0, 0 }
};

static driver_t refstatic_driver = {
    "refstatic",
    refstatic_methods,
    64
};

static devclass_t refstatic_devclass;

DRIVER_MODULE(refstatic, pci, refstatic_driver, refstatic_devclass, 0, 0);

——testfunc.c:

extern int testvar;

int func(void);

int func(void)
{
    return testvar;
}




More information about the freebsd-stable mailing list