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/powerpc | |
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/powerpc')
-rw-r--r-- | sys/powerpc/powerpc/elf_machdep.c | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index 1e7c86d..847ab2a 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: elf_machdep.c,v 1.1 1998/09/11 08:47:02 dfr Exp $ */ #include <sys/param.h> @@ -38,73 +38,81 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) { Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); + Elf_Addr *where; + Elf_Addr addr, tmp_value; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; - switch (ELF_R_TYPE(rela->r_info)) { + switch (type) { + case ELF_RELOC_REL: + rel = (Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("elf_reloc: unknown relocation mode %d\n", type); + } - case R_ALPHA_REFQUAD: { - Elf_Addr addr; - Elf_Addr tmp_value; + switch (rtype) { + case R_ALPHA_REFQUAD: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; + addr += addend; + if (*where != addr) + *where = addr; + break; - tmp_value = addr + *where + rela->r_addend; - if (*where != tmp_value) - *where = tmp_value; - } - break; - - case R_ALPHA_GLOB_DAT: { - Elf_Addr addr; - + case R_ALPHA_GLOB_DAT: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_JMP_SLOT: { + case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - Elf_Addr addr; - addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_RELATIVE: { - *where += relocbase; - } - break; + case R_ALPHA_RELATIVE: + addr = relocbase + addend; + if (*where != addr) + *where = addr; + break; - case R_ALPHA_COPY: { + case R_ALPHA_COPY: /* * There shouldn't be copy relocations in kernel * objects. */ printf("kldload: unexpected R_COPY relocation\n"); return -1; - } - break; default: printf("kldload: unexpected relocation type %d\n", - ELF_R_TYPE(rela->r_info)); + rtype); return -1; } return(0); |