On Tue, Jun 06, 2006 at 04:44:55PM +0200, Divacky Roman wrote:
> Hi,
> 
> I am working on SoC linuxolator and I found strange thing I dont know how to
> cope with:
> 
> I made a patch which enables module build of linuxolator on amd64 but it
> refuses to kldload because of missing symbol. I tracked the problem down to
> the fact that i386 module build works in a way that it builds .kld and then
> turns this into .ko:
> 
> ld -Bshareable  -d -warn-common -o linux.ko linux.kld
> 
> this line makes transition from U symbol to A symbol.
> 
> Amd64 version uses only .ko, so this step doesnt exist there so those symbols
> remain U.
> 
> can someone explain me whats going on?
> 
> thnx roman
In private communication, Roman said that the problem symbols
are __start* and __stop*. That symbols are generated by the static linker
for the section start/end.

Since AMD64 uses relocatable objects as kld instead of shared ones,
that symbols are leaved undefined.

Patch below will simulate behaviour of the static linker for the
in-kernel elf_obj linker. The patch makes the linker_set.h
machinery fully operatable on AMD64. Please test.

Index: kern/link_elf_obj.c
===================================================================
RCS file: /usr/local/arch/ncvs/src/sys/kern/link_elf_obj.c,v
retrieving revision 1.87.2.3
diff -u -r1.87.2.3 link_elf_obj.c
--- kern/link_elf_obj.c 30 Dec 2005 22:13:58 -0000      1.87.2.3
+++ kern/link_elf_obj.c 13 Jun 2006 08:56:08 -0000
@@ -1112,6 +1112,51 @@
 }
 
 static void
+link_elf_fix_link_set(elf_file_t ef)
+{
+       static const char startn[] = "__start_";
+       static const char stopn[] = "__stop_";
+       Elf_Sym *sym;
+       const char *sym_name, *linkset_name;
+       Elf_Addr startp, stopp;
+       Elf_Size symidx;
+       int start, i;
+
+       startp = stopp = 0;
+       for (symidx = 1 /* zero entry is special */;
+               symidx < ef->ddbsymcnt; symidx++) {
+               sym = ef->ddbsymtab + symidx;
+               if (sym->st_shndx != SHN_UNDEF)
+                       continue;
+
+               sym_name = ef->ddbstrtab + sym->st_name;
+               if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) {
+                       start = 1;
+                       linkset_name = sym_name + sizeof(startn) - 1;
+               }
+               else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) {
+                       start = 0;
+                       linkset_name = sym_name + sizeof(stopn) - 1;
+               }
+               else
+                       continue;
+
+               for (i = 0; i < ef->nprogtab; i++) {
+                       if (strcmp(ef->progtab[i].name, linkset_name) == 0) {
+                               startp = (Elf_Addr)ef->progtab[i].addr;
+                               stopp = (Elf_Addr)(startp + 
ef->progtab[i].size);
+                               break;
+                       }
+               }
+               if (i == ef->nprogtab)
+                       continue;
+
+               sym->st_value = start ? startp : stopp;
+               sym->st_shndx = i;
+       }
+}
+
+static void
 link_elf_reloc_local(linker_file_t lf)
 {
        elf_file_t ef = (elf_file_t)lf;
@@ -1124,6 +1169,8 @@
        int i;
        Elf_Size symidx;
 
+       link_elf_fix_link_set(ef);
+
        /* Perform relocations without addend if there are any: */
        for (i = 0; i < ef->nrel; i++) {
                rel = ef->reltab[i].rel;

Attachment: pgp1pfq8SPRqi.pgp
Description: PGP signature

Reply via email to