Mercurial > projects > winelf > hg > index.cgi
changeset 4:54ff11eb9191
Now works properly on x86_64 :)
author | Gregor Richards <Richards@codu.org> |
---|---|
date | Sun, 13 Dec 2009 18:04:50 -0500 |
parents | 56f873c979c3 |
children | 6b8e05507b18 |
files | elfload/src/elfload.c |
diffstat | 1 files changed, 72 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/elfload/src/elfload.c Sat Jul 25 22:36:11 2009 -0400 +++ b/elfload/src/elfload.c Sun Dec 13 18:04:50 2009 -0500 @@ -213,8 +213,8 @@ } /* do processor-specific relocation */ -#if defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || \ - defined(__x86_64__) || defined(_M_X64) +#if (defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_X86_)) && \ + !(defined(__x86_64__) || defined(_M_X64)) #define REL_P ((ssize_t) (currel->r_offset + f->offset)) #define REL_S ((ssize_t) (findELFSymbol( \ f->strtab + f->symtab[ELFNATIVE_R_SYM(currel->r_info)].st_name, \ @@ -261,6 +261,9 @@ case R_386_RELATIVE: WORD32_REL(f->loc + REL_A); break; + + default: + fprintf(stderr, "Unsupported relocation %d\n", ELFNATIVE_R_TYPE(currel->r_info)); } } } @@ -277,6 +280,73 @@ } +#elif defined(__x86_64__) || defined(_M_X64) +#define REL_P ((ssize_t) (currel->r_offset + f->offset)) +#define REL_S ((ssize_t) (findELFSymbol( \ + f->strtab + f->symtab[ELFNATIVE_R_SYM(currel->r_info)].st_name, \ + NULL, fileNo, -1, NULL))) +#define REL_A (*((ssize_t *) REL_P)) +#define WORD32_REL(to) REL_A = (int32_t) (to) +#define WORD64_REL(to) REL_A = (ssize_t) (to) + + /* we ought to have rel and symtab defined */ + if (f->rela && f->symtab) { + ElfNative_Rela *currel = f->rela; + for (; (void *) currel < (void *) f->rela + f->relasz; currel++) { + switch (ELFNATIVE_R_TYPE(currel->r_info)) { + case R_X86_64_64: + WORD64_REL(REL_S + REL_A); + break; + + case R_X86_64_PC32: + WORD32_REL(REL_S + REL_A - REL_P); + break; + + case R_X86_64_COPY: + { + /* this is a bit more convoluted, as we need to find it in both places and copy */ + ElfNative_Sym *localsym, *sosym; + localsym = &(f->symtab[ELFNATIVE_R_SYM(currel->r_info)]); + void *soptr = findELFSymbol( + f->strtab + localsym->st_name, + NULL, -1, fileNo, &sosym); + + /* OK, we should have both, so copy it over */ + if (localsym && sosym) { + memcpy((void *) (localsym->st_value + f->offset), + soptr, sosym->st_size); + } else { + /* depend on localsym's size */ + memcpy((void *) (localsym->st_value + f->offset), + soptr, localsym->st_size); + + } + + break; + } + + case R_X86_64_RELATIVE: + WORD64_REL(f->loc + REL_A); + break; + + default: + fprintf(stderr, "Unsupported relocation %d\n", ELFNATIVE_R_TYPE(currel->r_info)); + } + } + } + + if (f->jmprel && f->symtab) { + ElfNative_Rel *currel = (ElfNative_Rel *) f->jmprel; + for (; (void *) currel < f->jmprel + f->jmprelsz; currel++) { + switch (ELFNATIVE_R_TYPE(currel->r_info)) { + case R_X86_64_JUMP_SLOT: + WORD64_REL(REL_S); + break; + } + } + } + + #else #error Unsupported architecture. #endif