Date: Thu, 1 Apr 2004 19:58:15 -0800 (PST) From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 50162 for review Message-ID: <200404020358.i323wFBo045752@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=50162 Change 50162 by peter@peter_hammer on 2004/04/01 19:57:17 checkpoint. close, but still no cigar. The STT_* types are only relevant for STB_LOCAL binding, it seems. STB_GLOBAL would always be a fallthrough. Or something. Hmmm. Affected files ... .. //depot/projects/hammer/sys/kern/link_elf_obj.c#21 edit Differences ... ==== //depot/projects/hammer/sys/kern/link_elf_obj.c#21 (text+ko) ==== @@ -64,6 +64,8 @@ Elf_Off filesz; int align; int flags; + int sec; /* Original section */ + char *name; } Elf_progent; typedef struct { @@ -71,6 +73,8 @@ Elf_Off memsz; int align; int flags; + int sec; /* Original section */ + char *name; } Elf_nobitent; typedef struct { @@ -90,6 +94,7 @@ struct linker_file lf; /* Common fields */ caddr_t address; /* Relocation address */ vm_object_t object; /* VM object to hold file pages */ + Elf_Shdr *e_shdr; Elf_progent *progtab; int nprogtab; @@ -108,6 +113,9 @@ caddr_t ddbstrtab; /* String table */ long ddbstrcnt; /* number of bytes in string table */ + caddr_t shstrtab; /* Section name string table */ + long shstrcnt; /* number of bytes in string table */ + #if 0 caddr_t symbase; /* malloc'ed symbol base */ caddr_t strbase; /* malloc'ed string base */ @@ -195,6 +203,7 @@ struct nameidata nd; struct thread *td = curthread; /* XXX */ Elf_Ehdr *hdr; + Elf_Shdr *shdr; int nbytes, i; caddr_t mapbase; size_t mapsize; @@ -202,9 +211,9 @@ int resid, flags; elf_file_t ef; linker_file_t lf; - Elf_Shdr *shdr; int symtabindex; int symstrindex; + int shstrindex; int nsym; int pb, nb, rl, ra; int alignmask; @@ -281,6 +290,19 @@ printf("elf_load_obj: initial checks look ok!\n"); +printf("section table read in ok\n"); + lf = linker_make_file(filename, &link_elf_class); + if (!lf) { + error = ENOMEM; + goto out; + } + ef = (elf_file_t) lf; + ef->nprogtab = 0; + ef->nnobittab = 0; + ef->e_shdr = 0; + ef->nrel = 0; + ef->nrela = 0; + /* Allocate and read in the section header */ nbytes = hdr->e_shnum * hdr->e_shentsize; if (nbytes == 0 || hdr->e_shoff == 0 || @@ -294,6 +316,7 @@ error = ENOMEM; goto out; } + ef->e_shdr = shdr; error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td); if (error) @@ -303,21 +326,9 @@ goto out; } -printf("section table read in ok\n"); - lf = linker_make_file(filename, &link_elf_class); - if (!lf) { - error = ENOMEM; - goto out; - } - ef = (elf_file_t) lf; - printf("scan header1\n"); /* Scan the section header for information and table sizing. */ - ef->nprogtab = 0; - ef->nnobittab = 0; nsym = 0; - ef->nrel = 0; - ef->nrela = 0; symtabindex = -1; symstrindex = -1; for (i = 0; i < hdr->e_shnum; i++) { @@ -395,6 +406,18 @@ goto out; } + /* Do we have a string table for the section names? */ + shstrindex = -1; + if (hdr->e_shstrndx != 0 && shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { + shstrindex = hdr->e_shstrndx; + ef->shstrcnt = shdr[shstrindex].sh_size; + ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER, M_WAITOK); + if (ef->shstrtab == NULL) { + error = ENOMEM; + goto out; + } + } + /* Size code/data(progbits) and bss(nobits). allocate space for relocs */ pb = 0; nb = 0; @@ -420,7 +443,12 @@ ef->progtab[pb].fileoff = shdr[i].sh_offset; ef->progtab[pb].filesz = shdr[i].sh_size; ef->progtab[pb].align = shdr[i].sh_addralign; -printf("progbits at %ld\n", mapsize); + ef->progtab[pb].sec = i; + if (ef->shstrtab && shdr[i].sh_name != 0) + ef->progtab[pb].name = ef->shstrtab + shdr[i].sh_name; + else + ef->progtab[pb].name = "<<PROGBITS>>"; +printf("progbits at %ld, sec %d, name %s\n", mapsize, ef->progtab[pb].sec, ef->progtab[pb].name); mapsize += shdr[i].sh_size; pb++; break; @@ -428,7 +456,12 @@ ef->nobittab[nb].addr = (void *)(uintptr_t)mapsize; ef->nobittab[nb].memsz = shdr[i].sh_size; ef->nobittab[nb].align = shdr[i].sh_addralign; -printf("nobits at %ld\n", mapsize); + ef->nobittab[nb].sec = i; + if (ef->shstrtab && shdr[i].sh_name != 0) + ef->nobittab[nb].name = ef->shstrtab + shdr[i].sh_name; + else + ef->nobittab[nb].name = "<<NOBITS>>"; +printf("nobits at %ld, sec %d name %s\n", mapsize, ef->nobittab[nb].sec, ef->nobittab[nb].name); mapsize += shdr[i].sh_size; nb++; break; @@ -505,6 +538,15 @@ &resid, td); if (error) goto out; + if (ef->shstrtab) { +printf("reading shstrtab\n"); + error = vn_rdwr(UIO_READ, nd.ni_vp, + ef->shstrtab, shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset, + UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, + &resid, td); + if (error) + goto out; + } printf("reading progbits\n"); /* Read in the text/data/set/etc sections */ @@ -586,8 +628,6 @@ printf("link_elf_obj: finishing up! error = %d\n", error); if (error && lf) linker_file_unload(lf); - if (shdr) - free(shdr, M_LINKER); if (hdr) free(hdr, M_LINKER); VOP_UNLOCK(nd.ni_vp, 0, td); @@ -611,6 +651,8 @@ } if (ef->address) free(ef->address, M_LINKER); + if (ef->e_shdr) + free(ef->e_shdr, M_LINKER); if (ef->ddbsymtab) free(ef->ddbsymtab, M_LINKER); if (ef->ddbstrtab) @@ -881,7 +923,8 @@ elf_file_t ef = (elf_file_t)lf; const Elf_Sym *sym; const char *symbol; - Elf_addr ret; + Elf_Addr ret; + int i; printf("elf_obj_lookup: symidx %ld (< %ld?)\n", symidx, ef->ddbsymcnt); @@ -914,12 +957,32 @@ printf("calling linker_file_lookup_symbol, deps %d\n", deps); ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); -printf("linker_file_lookup_symbol returns %p\n", ret); +printf("linker_file_lookup_symbol returns 0x%lx\n", ret); return ret; case STT_SECTION: /* Relative to section number */ - XXX + for (i = 0; i < ef->nprogtab; i++) { + if (sym->st_shndx == ef->progtab[i].sec) { +printf("FOUND PROGBITS SECTION RELOC, name %s\n", ef->progtab[i].name); + ret = (Elf_Addr)ef->progtab[i].addr; +printf("returning base 0x%lx\n", ret); + return ret; + } + } + for (i = 0; i < ef->nnobittab; i++) { + if (sym->st_shndx == ef->nobittab[i].sec) { +printf("FOUND NOBITS SECTION RELOC, name %s\n", ef->nobittab[i].name); + ret = (Elf_Addr)ef->nobittab[i].addr; +printf("returning base 0x%lx\n", ret); + return ret; + } + } +printf("STT_SECTION index %d not found!\n", sym->st_shndx); + return (0); + default: +printf("Unknown symbol type! %d\n", ELF64_ST_TYPE(sym->st_info)); + return (0); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404020358.i323wFBo045752>