diff options
author | peter <peter@FreeBSD.org> | 1998-10-16 03:55:01 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-10-16 03:55:01 +0000 |
commit | 464de37ce6099f409aa233200a94ac38216aa211 (patch) | |
tree | 59ed738c6bca93117593ea63241912064597c130 /sys/kern/link_elf.c | |
parent | ad0030e392049cd4f887968f40988dd6cf5e5ee0 (diff) | |
download | FreeBSD-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.c')
-rw-r--r-- | sys/kern/link_elf.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 5495e92..26b6213 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.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; |