Changeset View
Changeset View
Standalone View
Standalone View
sys/i386/i386/elf_machdep.c
Show First 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | if (dst != NULL) { | ||||
xsave_mask; | xsave_mask; | ||||
} else | } else | ||||
len += elf32_populate_note(NT_X86_XSTATE, NULL, NULL, | len += elf32_populate_note(NT_X86_XSTATE, NULL, NULL, | ||||
cpu_max_ext_state_size, NULL); | cpu_max_ext_state_size, NULL); | ||||
} | } | ||||
*off = len; | *off = len; | ||||
} | } | ||||
#define ERI_LOCAL 0x0001 | |||||
#define ERI_ONLYIFUNC 0x0002 | |||||
/* Process one elf relocation with addend. */ | /* Process one elf relocation with addend. */ | ||||
static int | static int | ||||
elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, | elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, | ||||
int type, int local, elf_lookup_fn lookup) | int type, elf_lookup_fn lookup, int flags) | ||||
{ | { | ||||
Elf_Addr *where; | Elf_Addr *where; | ||||
Elf_Addr addr; | Elf_Addr addr; | ||||
Elf_Addr addend; | Elf_Addr addend; | ||||
Elf_Word rtype, symidx; | Elf_Word rtype, symidx; | ||||
const Elf_Rel *rel; | const Elf_Rel *rel; | ||||
const Elf_Rela *rela; | const Elf_Rela *rela; | ||||
int error; | int error; | ||||
Show All 12 Lines | case ELF_RELOC_RELA: | ||||
addend = rela->r_addend; | addend = rela->r_addend; | ||||
rtype = ELF_R_TYPE(rela->r_info); | rtype = ELF_R_TYPE(rela->r_info); | ||||
symidx = ELF_R_SYM(rela->r_info); | symidx = ELF_R_SYM(rela->r_info); | ||||
break; | break; | ||||
default: | default: | ||||
panic("unknown reloc type %d\n", type); | panic("unknown reloc type %d\n", type); | ||||
} | } | ||||
if (local) { | if (((flags & ERI_ONLYIFUNC) == 0) ^ (rtype != R_386_IRELATIVE)) | ||||
return (0); | |||||
if ((flags & ERI_LOCAL) != 0) { | |||||
if (rtype == R_386_RELATIVE) { /* A + B */ | if (rtype == R_386_RELATIVE) { /* A + B */ | ||||
addr = elf_relocaddr(lf, relocbase + addend); | addr = elf_relocaddr(lf, relocbase + addend); | ||||
if (*where != addr) | if (*where != addr) | ||||
*where = addr; | *where = addr; | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 35 Lines | case R_386_GLOB_DAT: /* S */ | ||||
return -1; | return -1; | ||||
if (*where != addr) | if (*where != addr) | ||||
*where = addr; | *where = addr; | ||||
break; | break; | ||||
case R_386_RELATIVE: | case R_386_RELATIVE: | ||||
break; | break; | ||||
case R_386_IRELATIVE: | |||||
addr = relocbase + addend; | |||||
addr = ((Elf_Addr (*)(void))addr)(); | |||||
if (*where != addr) | |||||
*where = addr; | |||||
break; | |||||
default: | default: | ||||
printf("kldload: unexpected relocation type %d\n", | printf("kldload: unexpected relocation type %d\n", | ||||
rtype); | rtype); | ||||
return -1; | return -1; | ||||
} | } | ||||
return(0); | return(0); | ||||
} | } | ||||
int | int | ||||
elf_reloc_ifunc(linker_file_t lf, Elf_Addr relocbase, const void *data, | |||||
int type, elf_lookup_fn lookup) | |||||
{ | |||||
return (elf_reloc_internal(lf, relocbase, data, type, lookup, | |||||
ERI_ONLYIFUNC)); | |||||
} | |||||
int | |||||
elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, | elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, | ||||
elf_lookup_fn lookup) | elf_lookup_fn lookup) | ||||
{ | { | ||||
return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); | return (elf_reloc_internal(lf, relocbase, data, type, lookup, 0)); | ||||
} | } | ||||
int | int | ||||
elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, | elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, | ||||
int type, elf_lookup_fn lookup) | int type, elf_lookup_fn lookup) | ||||
{ | { | ||||
return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); | return (elf_reloc_internal(lf, relocbase, data, type, lookup, | ||||
ERI_LOCAL)); | |||||
} | } | ||||
int | int | ||||
elf_cpu_load_file(linker_file_t lf __unused) | elf_cpu_load_file(linker_file_t lf __unused) | ||||
{ | { | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
elf_cpu_unload_file(linker_file_t lf __unused) | elf_cpu_unload_file(linker_file_t lf __unused) | ||||
{ | { | ||||
return (0); | return (0); | ||||
} | } |