summaryrefslogtreecommitdiffstats
path: root/sys/kern/link_elf_obj.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-10-16 03:55:01 +0000
committerpeter <peter@FreeBSD.org>1998-10-16 03:55:01 +0000
commit464de37ce6099f409aa233200a94ac38216aa211 (patch)
tree59ed738c6bca93117593ea63241912064597c130 /sys/kern/link_elf_obj.c
parentad0030e392049cd4f887968f40988dd6cf5e5ee0 (diff)
downloadFreeBSD-src-464de37ce6099f409aa233200a94ac38216aa211.zip
FreeBSD-src-464de37ce6099f409aa233200a94ac38216aa211.tar.gz
*gulp*. Jordan specifically OK'ed this..
This is the bulk of the support for doing kld modules. Two linker_sets were replaced by SYSINIT()'s. VFS's and exec handlers are self registered. kld is now a superset of lkm. I have converted most of them, they will follow as a seperate commit as samples. This all still works as a static a.out kernel using LKM's.
Diffstat (limited to 'sys/kern/link_elf_obj.c')
-rw-r--r--sys/kern/link_elf_obj.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 5495e92..26b6213 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: link_elf.c,v 1.5 1998/10/13 09:27:00 peter Exp $
+ * $Id: link_elf.c,v 1.6 1998/10/15 17:16:24 peter Exp $
*/
#include <sys/param.h>
@@ -771,12 +771,12 @@ out:
}
static const char *
-symbol_name(elf_file_t ef, const Elf_Rela *rela)
+symbol_name(elf_file_t ef, Elf_Word r_info)
{
const Elf_Sym *ref;
- if (ELF_R_SYM(rela->r_info)) {
- ref = ef->symtab + ELF_R_SYM(rela->r_info);
+ if (ELF_R_SYM(r_info)) {
+ ref = ef->symtab + ELF_R_SYM(r_info);
return ef->strtab + ref->st_name;
} else
return NULL;
@@ -790,43 +790,54 @@ relocate_file(linker_file_t lf)
const Elf_Rel *rel;
const Elf_Rela *relalim;
const Elf_Rela *rela;
+ const char *symname;
/* Perform relocations without addend if there are any: */
- rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize);
- for (rel = ef->rel; ef->rel != NULL && rel < rellim; rel++) {
- Elf_Rela locrela;
-
- locrela.r_info = rel->r_info;
- locrela.r_offset = rel->r_offset;
- locrela.r_addend = 0;
- if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela)))
- return ENOENT;
+ rel = ef->rel;
+ if (rel) {
+ rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize);
+ while (rel < rellim) {
+ symname = symbol_name(ef, rel->r_info);
+ if (elf_reloc(lf, rel, ELF_RELOC_REL, symname))
+ return ENOENT;
+ rel++;
+ }
}
/* Perform relocations with addend if there are any: */
- relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize);
- for (rela = ef->rela; ef->rela != NULL && rela < relalim; rela++) {
- if (elf_reloc(lf, rela, symbol_name(ef, rela)))
- return ENOENT;
+ rela = ef->rela;
+ if (rela) {
+ relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize);
+ while (rela < relalim) {
+ symname = symbol_name(ef, rela->r_info);
+ if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname))
+ return ENOENT;
+ rela++;
+ }
}
/* Perform PLT relocations without addend if there are any: */
- rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize);
- for (rel = ef->pltrel; ef->pltrel != NULL && rel < rellim; rel++) {
- Elf_Rela locrela;
-
- locrela.r_info = rel->r_info;
- locrela.r_offset = rel->r_offset;
- locrela.r_addend = 0;
- if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela)))
- return ENOENT;
+ rel = ef->pltrel;
+ if (rel) {
+ rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize);
+ while (rel < rellim) {
+ symname = symbol_name(ef, rel->r_info);
+ if (elf_reloc(lf, rel, ELF_RELOC_REL, symname))
+ return ENOENT;
+ rel++;
+ }
}
/* Perform relocations with addend if there are any: */
- relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize);
- for (rela = ef->pltrela; ef->pltrela != NULL && rela < relalim; rela++) {
- if (elf_reloc(lf, rela, symbol_name(ef, rela)))
- return ENOENT;
+ rela = ef->pltrela;
+ if (rela) {
+ relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize);
+ while (rela < relalim) {
+ symname = symbol_name(ef, rela->r_info);
+ if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname))
+ return ENOENT;
+ rela++;
+ }
}
return 0;
OpenPOWER on IntegriCloud