diff options
| author | John Polstra <jdp@FreeBSD.org> | 2000-01-29 01:27:04 +0000 |
|---|---|---|
| committer | John Polstra <jdp@FreeBSD.org> | 2000-01-29 01:27:04 +0000 |
| commit | 7dbe16fbeef1df733f74de7203647a4eba928609 (patch) | |
| tree | e68cb1ab7205d71d070d2a9fc194f8a433a8b083 /libexec/rtld-elf/alpha | |
| parent | 2a0bb85541802e36517ff6b94b5020ef14b496a4 (diff) | |
Notes
Diffstat (limited to 'libexec/rtld-elf/alpha')
| -rw-r--r-- | libexec/rtld-elf/alpha/reloc.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/libexec/rtld-elf/alpha/reloc.c b/libexec/rtld-elf/alpha/reloc.c index 114f3ae438ed..8763be46952b 100644 --- a/libexec/rtld-elf/alpha/reloc.c +++ b/libexec/rtld-elf/alpha/reloc.c @@ -159,7 +159,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) /* Process the PLT relocations. */ int -reloc_plt(Obj_Entry *obj, bool bind_now) +reloc_plt(Obj_Entry *obj) { /* All PLT relocations are the same kind: either Elf_Rel or Elf_Rela. */ if (obj->pltrelsize != 0) { @@ -175,17 +175,6 @@ reloc_plt(Obj_Entry *obj, bool bind_now) /* Relocate the GOT slot pointing into the PLT. */ where = (Elf_Addr *)(obj->relocbase + rel->r_offset); *where += (Elf_Addr)obj->relocbase; - - if (bind_now) { /* Fully resolve the procedure address. */ - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true); - if (def == NULL) - return -1; - reloc_jmpslot(where, - (Elf_Addr)(defobj->relocbase + def->st_value)); - } } } else { const Elf_Rela *relalim; @@ -200,19 +189,56 @@ reloc_plt(Obj_Entry *obj, bool bind_now) /* Relocate the GOT slot pointing into the PLT. */ where = (Elf_Addr *)(obj->relocbase + rela->r_offset); *where += (Elf_Addr)obj->relocbase; + } + } + return 0; +} - if (bind_now) { /* Fully resolve the procedure address. */ - const Elf_Sym *def; - const Obj_Entry *defobj; +/* Relocate the jump slots in an object. */ +int +reloc_jmpslots(Obj_Entry *obj) +{ + if (obj->jmpslots_done) + return 0; + /* All PLT relocations are the same kind: either Elf_Rel or Elf_Rela. */ + if (obj->pltrelsize != 0) { + const Elf_Rel *rellim; + const Elf_Rel *rel; - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true); - if (def == NULL) - return -1; - reloc_jmpslot(where, - (Elf_Addr)(defobj->relocbase + def->st_value)); - } + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); + for (rel = obj->pltrel; rel < rellim; rel++) { + Elf_Addr *where; + const Elf_Sym *def; + const Obj_Entry *defobj; + + assert(ELF_R_TYPE(rel->r_info) == R_ALPHA_JMP_SLOT); + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true); + if (def == NULL) + return -1; + reloc_jmpslot(where, + (Elf_Addr)(defobj->relocbase + def->st_value)); + } + } else { + const Elf_Rela *relalim; + const Elf_Rela *rela; + + relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize); + for (rela = obj->pltrela; rela < relalim; rela++) { + Elf_Addr *where; + const Elf_Sym *def; + const Obj_Entry *defobj; + + assert(ELF_R_TYPE(rela->r_info) == R_ALPHA_JMP_SLOT); + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true); + if (def == NULL) + return -1; + reloc_jmpslot(where, + (Elf_Addr)(defobj->relocbase + def->st_value)); } } + obj->jmpslots_done = true; return 0; } |
