Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Apr 2004 17:45:28 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 50153 for review
Message-ID:  <200404020145.i321jSKT016545@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=50153

Change 50153 by peter@peter_hammer on 2004/04/01 17:44:47

	call the correct elf_reloc callback function by passing it through.
	this api change affects both elf linkers..

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/elf_machdep.c#15 edit
.. //depot/projects/hammer/sys/kern/link_elf.c#15 edit
.. //depot/projects/hammer/sys/kern/link_elf_obj.c#16 edit
.. //depot/projects/hammer/sys/sys/linker.h#10 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/elf_machdep.c#15 (text+ko) ====

@@ -104,7 +104,7 @@
 
 /* Process one elf relocation with addend. */
 static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, const void *data, int type, int local, elf_lookup_fn lu)
 {
 	Elf_Addr relocbase = (Elf_Addr) lf->address;
 	Elf_Addr *where;
@@ -156,8 +156,9 @@
 			break;
 
 		case R_X86_64_64:		/* S + A */
-			addr = elf_lookup(lf, symidx, 1);
-printf("R_X86_64_64: addr 0x%lx, addend 0x%lx\n", addr, addend);
+printf("R_X86_64_64\n");
+			addr = lu(lf, symidx, 1);
+printf("addr 0x%lx, addend 0x%lx\n", addr, addend);
 			if (addr == 0)
 				return -1;
 			addr += addend;
@@ -167,8 +168,9 @@
 			break;
 
 		case R_X86_64_PC32:	/* S + A - P */
-			addr = elf_lookup(lf, symidx, 1);
-printf("R_X86_64_PC32: addr 0x%lx, addend 0x%lx\n", addr, addend);
+printf("R_X86_64_PC32\n");
+			addr = lu(lf, symidx, 1);
+printf("addr 0x%lx, addend 0x%lx\n", addr, addend);
 			if (addr == 0)
 				return -1;
 			addr += addend - (Elf_Addr)where;
@@ -189,8 +191,9 @@
 			break;
 
 		case R_X86_64_GLOB_DAT:	/* S */
-			addr = elf_lookup(lf, symidx, 1);
-printf("R_X86_64_GLOB_DAT: addr 0x%lx\n", addr);
+printf("R_X86_64_GLOB_DAT\n");
+			addr = lu(lf, symidx, 1);
+printf("addr 0x%lx\n", addr);
 			if (addr == 0)
 				return -1;
 			if (*where != addr)
@@ -210,17 +213,17 @@
 }
 
 int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, const void *data, int type, elf_lookup_fn lu)
 {
 
-	return (elf_reloc_internal(lf, data, type, 0));
+	return (elf_reloc_internal(lf, data, type, 0, lu));
 }
 
 int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, const void *data, int type, elf_lookup_fn lu)
 {
 
-	return (elf_reloc_internal(lf, data, type, 1));
+	return (elf_reloc_internal(lf, data, type, 1, lu));
 }
 
 int

==== //depot/projects/hammer/sys/kern/link_elf.c#15 (text+ko) ====

@@ -118,6 +118,7 @@
 				int (*)(const char *, void *),
 				void *);
 static void	link_elf_reloc_local(linker_file_t);
+static Elf_Addr	elf_lookup(linker_file_t lf, Elf_Word symidx, int deps);
 
 static kobj_method_t link_elf_methods[] = {
     KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
@@ -928,7 +929,7 @@
     if (rel) {
 	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
 	while (rel < rellim) {
-	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, elf_lookup)) {
 		symname = symbol_name(ef, rel->r_info);
 		printf("link_elf: symbol %s undefined\n", symname);
 		return ENOENT;
@@ -942,7 +943,7 @@
     if (rela) {
 	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
 	while (rela < relalim) {
-	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, elf_lookup)) {
 		symname = symbol_name(ef, rela->r_info);
 		printf("link_elf: symbol %s undefined\n", symname);
 		return ENOENT;
@@ -956,7 +957,7 @@
     if (rel) {
 	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
 	while (rel < rellim) {
-	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, elf_lookup)) {
 		symname = symbol_name(ef, rel->r_info);
 		printf("link_elf: symbol %s undefined\n", symname);
 		return ENOENT;
@@ -970,7 +971,7 @@
     if (rela) {
 	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
 	while (rela < relalim) {
-	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, elf_lookup)) {
 		symname = symbol_name(ef, rela->r_info);
 		printf("link_elf: symbol %s undefined\n", symname);
 		return ENOENT;
@@ -1244,7 +1245,7 @@
  * This is not only more efficient, it's also more correct. It's not always
  * the case that the symbol can be found through the hash table.
  */
-Elf_Addr
+static Elf_Addr
 elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
 {
 	elf_file_t ef = (elf_file_t)lf;
@@ -1297,7 +1298,7 @@
     if ((rel = ef->rel) != NULL) {
 	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
 	while (rel < rellim) {
-	    elf_reloc_local(lf, rel, ELF_RELOC_REL);
+	    elf_reloc_local(lf, rel, ELF_RELOC_REL, elf_lookup);
 	    rel++;
 	}
     }
@@ -1306,7 +1307,7 @@
     if ((rela = ef->rela) != NULL) {
 	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
 	while (rela < relalim) {
-	    elf_reloc_local(lf, rela, ELF_RELOC_RELA);
+	    elf_reloc_local(lf, rela, ELF_RELOC_RELA, elf_lookup);
 	    rela++;
 	}
     }

==== //depot/projects/hammer/sys/kern/link_elf_obj.c#16 (text+ko) ====

@@ -128,6 +128,8 @@
 		    int (*)(const char *, void *), void *);
 static void	link_elf_reloc_local(linker_file_t);
 
+static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Word symidx, int deps);
+
 static kobj_method_t link_elf_methods[] = {
 	KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
 	KOBJMETHOD(linker_symbol_values,	link_elf_symbol_values),
@@ -622,7 +624,7 @@
 printf("rellim is %p\n", rellim);
 			while (rel < rellim) {
 printf("rel doing: %p\n", rel);
-				if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+				if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, elf_obj_lookup)) {
 					symname = symbol_name(ef, rel->r_info);
 					printf("link_elf: symbol %s undefined\n", symname);
 					return ENOENT;
@@ -641,7 +643,7 @@
 printf("relalim is %p\n", relalim);
 			while (rela < relalim) {
 printf("rela doing: %p\n", rela);
-				if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+				if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, elf_obj_lookup)) {
 					symname = symbol_name(ef, rela->r_info);
 					printf("link_elf: symbol %s undefined\n", symname);
 					return ENOENT;
@@ -841,7 +843,6 @@
 }
 #endif
 
-#if 0
 /*
  * Symbol lookup function that can be used when the symbol index is known (ie
  * in relocations). It uses the symbol index instead of doing a fully fledged
@@ -849,18 +850,22 @@
  * This is not only more efficient, it's also more correct. It's not always
  * the case that the symbol can be found through the hash table.
  */
-Elf_Addr
-elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
+static Elf_Addr
+elf_obj_lookup(linker_file_t lf, Elf_Word symidx, int deps)
 {
 	elf_file_t ef = (elf_file_t)lf;
 	const Elf_Sym *sym;
 	const char *symbol;
+	int error;
+
+printf("elf_obj_lookup: symidx %ld (< %ld?)\n", symidx, ef->ddbsymcnt);
 
 	/* Don't even try to lookup the symbol if the index is bogus. */
-	if (symidx >= ef->nchains)
+	if (symidx >= ef->ddbsymcnt)
 		return (0);
 
-	sym = ef->symtab + symidx;
+	sym = ef->ddbsymtab + symidx;
+printf("sym: %p (base %p)\n", sym, ef->ddbsymtab);
 
 	/*
 	 * Don't do a full lookup when the symbol is local. It may even
@@ -880,15 +885,19 @@
 	 * always be added.
 	 */
 
-	symbol = ef->strtab + sym->st_name;
+	symbol = ef->ddbstrtab + sym->st_name;
+printf("strtab %p, st_name %d\n", ef->ddbstrtab, sym->st_name);
+printf("symbol = %p (%s)\n", symbol, symbol);
 
 	/* Force a lookup failure if the symbol name is bogus. */
 	if (*symbol == 0)
 		return (0);
 
-	return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+printf("calling linker_file_lookup_symbol, deps %d\n", deps);
+	error = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+printf("linker_file_lookup_symbol returns %d\n", error);
+	return error;
 }
-#endif
 
 static void
 link_elf_reloc_local(linker_file_t lf)
@@ -909,7 +918,7 @@
 printf("rellim is %p\n", rellim);
 			while (rel < rellim) {
 printf("rel doing: %p\n", rel);
-				elf_reloc_local(lf, rel, ELF_RELOC_REL);
+				elf_reloc_local(lf, rel, ELF_RELOC_REL, elf_obj_lookup);
 				rel++;
 			}
 		}
@@ -924,7 +933,7 @@
 printf("relalim is %p\n", relalim);
 			while (rela < relalim) {
 printf("rela doing: %p\n", rela);
-				elf_reloc_local(lf, rela, ELF_RELOC_RELA);
+				elf_reloc_local(lf, rela, ELF_RELOC_RELA, elf_obj_lookup);
 				rela++;
 			}
 		}

==== //depot/projects/hammer/sys/sys/linker.h#10 (text+ko) ====

@@ -241,10 +241,11 @@
 
 #endif
 
+typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Word, int);
+
 /* Support functions */
-int	elf_reloc(linker_file_t _lf, const void *_rel, int _type);
-int	elf_reloc_local(linker_file_t _lf, const void *_rel, int _type);
-Elf_Addr elf_lookup(linker_file_t, Elf_Word, int);
+int	elf_reloc(linker_file_t _lf, const void *_rel, int _type, elf_lookup_fn _lu);
+int	elf_reloc_local(linker_file_t _lf, const void *_rel, int _type, elf_lookup_fn _lu);
 const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Word _symidx);
 const char *elf_get_symname(linker_file_t _lf, Elf_Word _symidx);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404020145.i321jSKT016545>