summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-05-31 13:26:52 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-05-31 13:26:52 +0000
commit670a54c0a370c42e737347f4db1c42188048b584 (patch)
tree73c2c58f2601362cbf2475a84c130b258e96c3ff /libexec/ld.so
parent19edfb207949d42d36a91376924d9319bfc7473f (diff)
Correctly implement most linking for alpha.
Remove a lot of code copied from powerpc.
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/alpha/archdep.h50
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c266
2 files changed, 53 insertions, 263 deletions
diff --git a/libexec/ld.so/alpha/archdep.h b/libexec/ld.so/alpha/archdep.h
index 49846926455..365d4c38260 100644
--- a/libexec/ld.so/alpha/archdep.h
+++ b/libexec/ld.so/alpha/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.1 2001/05/14 22:18:20 niklas Exp $ */
+/* $OpenBSD: archdep.h,v 1.2 2001/05/31 13:26:09 art Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -52,11 +52,6 @@ int _dl_write __P((int, const char *, int));
* be used before bootstrap linking has been finished.
*/
static inline void
-_dl_dcbf(Elf64_Addr *addr)
-{
-}
-
-static inline void
_dl_wrstderr(const char *s)
{
while(*s) {
@@ -131,34 +126,23 @@ _dl_strchr(const char *p, const int c)
}
static inline void
-RELOC_RELA(Elf64_Rela *r,
- const Elf64_Sym *s, Elf64_Addr *p, int v)
+RELOC_RELA(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
{
- if(ELF64_R_TYPE((r)->r_info) == RELOC_RELATIVE) {
- if((ELF64_ST_BIND((s)->st_info) == STB_LOCAL) &&
- ((ELF64_ST_TYPE((s)->st_info) == STT_SECTION) ||
- (ELF64_ST_TYPE((s)->st_info) == STT_NOTYPE)) ) {
- *(p) = (v) + (r)->r_addend;
- } else {
- *(p) = (v) + (s)->st_value + (r)->r_addend;
- }
- } else if(ELF64_R_TYPE((r)->r_info) == RELOC_JMP_SLOT) {
- Elf64_Addr val = (v) + (s)->st_value + (r)->r_addend -
- (Elf64_Addr)(p);
- if (((val & 0xfe000000) != 0) &&
- ((val & 0xfe000000) != 0xfe000000))
- {
- /* invalid offset */
- _dl_exit(20);
- }
- val &= ~0xfc000000;
- val |= 0x48000000;
- *(p) = val;
- _dl_dcbf(p);
- } else if(ELF64_R_TYPE((r)->r_info) == RELOC_GLOB_DAT) {
- *(p) = (v) + (s)->st_value + (r)->r_addend;
- } else {
- /* error */
+ extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
+
+ if(ELF64_R_TYPE(r->r_info) == RELOC_RELATIVE) {
+ if ((caddr_t)p < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
+ (caddr_t)p >= (caddr_t)&_DYNAMIC)
+ *p += (Elf_Addr)v;
+ } else if(ELF64_R_TYPE(r->r_info) == RELOC_JMP_SLOT) {
+ Elf64_Addr val = v + s->st_value + r->r_addend -
+ (Elf64_Addr)(p);
+ *p = val;
+ __asm __volatile("imb" : : : "memory");
+ } else if(ELF64_R_TYPE(r->r_info) == RELOC_GLOB_DAT) {
+ *p = v + s->st_value + r->r_addend;
+ } else {
+ _dl_printf("unknown bootstrap relocation\n");
}
}
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c
index 3ce9c1dc4d0..dfdb2ac92a9 100644
--- a/libexec/ld.so/alpha/rtld_machine.c
+++ b/libexec/ld.so/alpha/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.1 2001/05/14 22:18:21 niklas Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.2 2001/05/31 13:26:51 art Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -62,69 +62,29 @@ _dl_bcopy(void *src, void *dest, int size)
int
_dl_md_reloc(elf_object_t *object, int rel, int relasz)
{
- int i;
- int numrela;
- int fails = 0;
+ long i;
+ long numrela;
+ long fails = 0;
Elf64_Addr loff;
Elf64_Rela *relas;
- /* for jmp table relocations */
- Elf64_Addr *pltcall;
- Elf64_Addr *plttable;
-
- Elf64_Addr * first_rela;
loff = object->load_offs;
numrela = object->Dyn.info[relasz] / sizeof(Elf64_Rela);
relas = (Elf64_Rela *)(object->Dyn.info[rel]);
-#ifdef DL_PRINTF_DEBUG
-_dl_printf("loff 0x%lx object relocation size %x, numrela %x\n", loff,
- object->Dyn.info[relasz], numrela);
-#endif
-
- if((object->status & STAT_RELOC_DONE) || !relas) {
+ if ((object->status & STAT_RELOC_DONE) || !relas) {
return(0);
}
- /* for plt relocation usage */
- if (object->Dyn.info[DT_JMPREL] != 0) {
- /* resolver stub not set up */
- Elf64_Addr val;
-
- first_rela = (Elf64_Addr *)
- (((Elf64_Rela *)(object->Dyn.info[DT_JMPREL]))->r_offset
- + loff);
- /* Need to construct table to do jumps */
- pltcall = (Elf64_Addr *)(first_rela) - 12;
-#ifdef DL_PRINTF_DEBUG
-_dl_printf("creating pltcall at %p\n", pltcall);
-_dl_printf("md_reloc( jumprel %p\n", first_rela );
-#endif
- plttable = (Elf64_Addr *)
- ((Elf64_Addr)first_rela) + (2 *
- (object->Dyn.info[DT_PLTRELSZ]/sizeof(Elf64_Rela))
- );
-
-#ifdef DL_PRINTF_DEBUG
-_dl_printf("md_reloc: plttbl size %x\n",
- (object->Dyn.info[DT_PLTRELSZ]/sizeof(Elf64_Rela))
-);
-_dl_printf("md_reloc: plttable %p\n", plttable);
-#endif
- } else {
- first_rela = NULL;
- }
- for(i = 0; i < numrela; i++, relas++) {
- Elf64_Addr *r_addr = (Elf64_Addr *)(relas->r_offset + loff);
+ for (i = 0; i < numrela; i++, relas++) {
+ Elf64_Addr *r_addr;
Elf64_Addr ooff;
const Elf64_Sym *sym, *this;
const char *symn;
-#if 0
-_dl_printf("%d offset 0x%lx info 0x%lx addend 0x%lx\n", i, relas->r_offset, relas->r_info, relas->r_addend);
-#endif
+ r_addr = (Elf64_Addr *)(relas->r_offset + loff);
- if(ELF64_R_SYM(relas->r_info) == 0xffffff) {
+ if (ELF64_R_SYM(relas->r_info) == 0xffffffff) {
continue;
}
@@ -133,180 +93,37 @@ _dl_printf("%d offset 0x%lx info 0x%lx addend 0x%lx\n", i, relas->r_offset, rela
this = sym;
symn = object->dyn.strtab + sym->st_name;
- if(ELF64_R_SYM(relas->r_info) &&
- !(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
- ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
-
- ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
- if(!this && ELF64_ST_BIND(sym->st_info) == STB_GLOBAL) {
- _dl_printf("%s:"
- " %s :can't resolve reference '%s'\n",
- _dl_progname, object->load_name,
- symn);
- fails++;
- }
-
- }
-
-#if 0
-_dl_printf("reloc %d\n", ELF64_R_TYPE(relas->r_info));
-#endif
- switch(ELF64_R_TYPE(relas->r_info)) {
-#if 1
+ switch (ELF64_R_TYPE(relas->r_info)) {
case R_TYPE(REFQUAD):
- if(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
- (ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
- ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
- *r_addr = ooff + relas->r_addend;
- } else {
- *r_addr = ooff + this->st_value +
- relas->r_addend;
- }
+ ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ if (this == NULL)
+ goto resolve_failed;
+ *r_addr += ooff + this->st_value + relas->r_addend;
break;
-#endif
case R_TYPE(RELATIVE):
#if 0
-_dl_printf("sym info %d r_addr %p relas %p\n", sym->st_info, r_addr, relas);
-#endif
- if(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
- (ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
- ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
-#if 0
-_dl_printf("addend 0x%lx\n", relas->r_addend);
-_dl_printf("*r_addr 0x%lx\n", *r_addr);
-#endif
- *r_addr = loff + relas->r_addend;
-#if 0
-_dl_printf("*r_addr 0x%lx\n", *r_addr);
-#endif
-
-#ifdef DL_PRINTF_DEBUG
-_dl_printf("rel1 r_addr %p val %lx loff %lx ooff %lx addend %lx\n", r_addr,
-loff + relas->r_addend, loff, ooff, relas->r_addend);
-#endif
-
- } else {
-#if 0
-_dl_printf("this %p\n", this);
+ if ((caddr_t)r_addr < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
+ (caddr_t)r_addr >= (caddr_t)&_DYNAMIC)
#endif
- *r_addr = loff + this->st_value +
- relas->r_addend;
- }
+ *r_addr += loff;
break;
case R_TYPE(JMP_SLOT):
- {
- Elf64_Addr val = ooff + this->st_value +
- relas->r_addend - (Elf64_Addr)r_addr;
- if (!(((val & 0xfe000000) == 0x00000000) ||
- ((val & 0xfe000000) == 0xfe000000)))
- {
- int index;
-#ifdef DL_PRINTF_DEBUG
-_dl_printf(" ooff %lx, sym val %lx, addend %lx"
- " r_addr %lx symn [%s] -> %x\n",
- ooff, this->st_value, relas->r_addend,
- r_addr, symn, val);
-#endif
- /* if offset is > RELOC_24 deal with it */
- index = (r_addr - first_rela) >> 1;
-
- if (index > (2 << 14)) {
-
- /* addis r11,r11,.PLTtable@ha*/
- val = (index*4 >> 16) +
- ((index*4 & 0x00008000) >> 15);
- r_addr[0] = 0x3d600000 | val;
- val = (Elf64_Addr)pltcall -
- (Elf64_Addr)&r_addr[2];
- r_addr[1] = 0x396b0000 | val;
- val &= ~0xfc000000;
- val |= 0x48000000;
- r_addr[2] = val;
-
- } else {
-#ifdef DL_PRINTF_DEBUG
- _dl_printf(" index %d, pltcall %x r_addr %lx\n",
- index, pltcall, r_addr);
-#endif
-
- r_addr[0] = 0x39600000 | (index * 4);
- val = (Elf64_Addr)pltcall -
- (Elf64_Addr)&r_addr[1];
- val &= ~0xfc000000;
- val |= 0x48000000;
- r_addr[1] = val;
-
- }
- _dl_dcbf(r_addr);
- _dl_dcbf(&r_addr[2]);
- val= ooff + this->st_value +
- relas->r_addend;
-#ifdef DL_PRINTF_DEBUG
- _dl_printf(" symn [%s] val 0x%x\n", symn, val);
-#endif
- plttable[index] = val;
- } else {
- /* if the offset is small enough,
- * branch directy to the dest
- */
- val &= ~0xfc000000;
- val |= 0x48000000;
- *r_addr = val;
- _dl_dcbf(r_addr);
- }
- }
-
+ ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ if (this == NULL)
+ goto resolve_failed;
+ *r_addr = ooff + this->st_value;
break;
case R_TYPE(GLOB_DAT):
- *r_addr = ooff + this->st_value + relas->r_addend;
- break;
-#if 0
-#ifdef DL_PRINTF_DEBUG
- /* should not be supported ??? */
- case RELOC_REL24:
- {
- Elf64_Addr val = ooff + this->st_value +
- relas->r_addend - (Elf64_Addr)r_addr;
- if ((val & 0xfe000000 != 0) &&
- (val & 0xfe000000 != 0xfe000000))
- {
- /* invalid offset */
- _dl_exit(20);
- }
- val &= ~0xfc000003;
- val |= (*r_addr & 0xfc000003);
- *r_addr = val;
-
- _dl_dcbf(r_addr);
- }
-#endif
- break;
- case RELOC_REL14_TAKEN:
- /* val |= 1 << (31-10) XXX? */
- case RELOC_REL14:
- case RELOC_REL14_NTAKEN:
- {
- Elf64_Addr val = ooff + this->st_value +
- relas->r_addend - (Elf64_Addr)r_addr;
- if (((val & 0xffff8000) != 0) &&
- ((val & 0xffff8000) != 0xffff8000))
- {
- /* invalid offset */
- _dl_exit(20);
- }
- val &= ~0xffff0003;
- val |= (*r_addr & 0xffff0003);
- *r_addr = val;
-#ifdef DL_PRINTF_DEBUG
- _dl_printf("rel 14 %lx val %lx\n",
- r_addr, val);
-#endif
-
- _dl_dcbf(r_addr);
- }
+ ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ if (this == NULL)
+ goto resolve_failed;
+ *r_addr = ooff + this->st_value;
break;
-#endif
case R_TYPE(COPY):
+_dl_printf("copy relocation, not tested\n");
+ ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ if (this == NULL)
+ goto resolve_failed;
#ifdef DL_PRINTF_DEBUG
_dl_printf("copy r_addr %lx, sym %x [%s] size %d val %lx\n",
r_addr, sym, symn, sym->st_size,
@@ -322,7 +139,7 @@ _dl_printf(" ooff %lx, sym val %lx, addend %lx"
*/
elf_object_t *cobj;
const Elf64_Sym *cpysrc = NULL;
- Elf64_Addr src_loff;
+ Elf64_Addr src_loff = 0;
int size;
for (cobj = _dl_objects;
cobj != NULL && cpysrc == NULL;
@@ -364,11 +181,13 @@ _dl_printf(" found other symbol at %x size %d\n",
ELF64_R_TYPE(relas->r_info), r_addr );
_dl_exit(1);
}
+ continue;
+resolve_failed:
+ _dl_printf("%s: %s :can't resolve reference '%s'\n",
+ _dl_progname, object->load_name, symn);
+ fails++;
}
- object->status |= STAT_RELOC_DONE;
-#if 0
-_dl_printf("<\n");
-#endif
+ __asm __volatile("imb" : : : "memory");
return(fails);
}
@@ -386,16 +205,3 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
{
/* relocations all done via rela relocations above */
}
-
-/* should not be defined here, but is is 32 for all powerpc 603-G4 */
-#define CACHELINESIZE 32
-void
-_dl_syncicache(char *from, size_t len)
-{
- int l = len;
- unsigned int off = 0;
-
- while (off < len) {
- off += CACHELINESIZE;
- }
-}