PERFORCE change 50162 for review
Peter Wemm
peter at FreeBSD.org
Thu Apr 1 19:58:17 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=50162
Change 50162 by peter at 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);
}
}
More information about the p4-projects
mailing list