about summary refs log tree commit diff stats
path: root/src/elfs
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-11-13 00:04:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-11-13 00:04:26 +0100
commit3cb7632dc84c954c76b84bb3477de2b6ba3d599c (patch)
treee250dc582585fa5abda034c9f654ff8863263af6 /src/elfs
parentcde8e54b513cce726008fecf2bb6b67d81da9a21 (diff)
downloadbox64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.tar.gz
box64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.zip
Also use size when selecting symbol for R_X86_64_COPY and R_X86_64_GLOB_DAT relocations
Diffstat (limited to 'src/elfs')
-rwxr-xr-xsrc/elfs/elfloader.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 227ef075..d7f4a530 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -382,7 +382,7 @@ int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
     return 0;
 }
 
-int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, int version, const char* vername)
+int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername)
 {
     if(!h)
         return 0;
@@ -394,7 +394,7 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t**
         int t = ELF64_R_TYPE(rela[i].r_info);
         Elf64_Sym *sym = &h->DynSym[ELF64_R_SYM(rela[i].r_info)];
         const char* symname = SymName(h, sym);
-        if(t==R_X86_64_COPY && symname && !strcmp(symname, name)) {
+        if(t==R_X86_64_COPY && symname && !strcmp(symname, name) && sym->st_size==size) {
             int version2 = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[ELF64_R_SYM(rela[i].r_info)]:-1;
             if(version2!=-1) version2 &= 0x7fff;
             if(version && !version2) version2=-1;   // match a versionned symbol against a global "local" symbol
@@ -421,6 +421,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
         uint64_t *p = (uint64_t*)(rel[i].r_offset + head->delta);
         uintptr_t offs = 0;
         uintptr_t end = 0;
+        size_t size = sym->st_size;
         //uintptr_t tmp = 0;
         int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rel[i].r_info)]:-1;
         if(version!=-1) version &=0x7fff;
@@ -462,7 +463,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     *p += offs;
                 break;
             case R_X86_64_GLOB_DAT:
-                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) {
+                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) {
                     // set global offs / size for the symbol
                     offs = sym->st_value;
                     end = offs + sym->st_size;
@@ -494,11 +495,11 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     uintptr_t old_offs = offs;
                     uintptr_t old_end = end;
                     offs = 0;
-                    GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
+                    GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first
                     if(offs==0) {
-                        GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername);   // get original copy if any
+                        GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername);   // get original copy if any
                         if(!offs && local_maplib)
-                            GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername);
+                            GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername);
                     }
                     if(!offs) {
                         offs = old_offs;
@@ -593,6 +594,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
         uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta);
         uintptr_t offs = 0;
         uintptr_t end = 0;
+        size_t size = sym->st_size;
         elfheader_t* h_tls = NULL;//head;
         int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rela[i].r_info)]:-1;
         if(version!=-1) version &=0x7fff;
@@ -643,11 +645,11 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 globoffs = offs;
                 globend = end;
                 offs = end = 0;
-                GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
+                GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first
                 if(!offs && local_maplib)
-                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername);
+                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername);
                 if(!offs)
-                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername);
+                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername);
                 if(!offs) {offs = globoffs; end = globend;}
                 if(offs) {
                     // add r_addend to p?
@@ -659,7 +661,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 }
                 break;
             case R_X86_64_GLOB_DAT:
-                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) {
+                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) {
                     // set global offs / size for the symbol
                     offs = sym->st_value + head->delta;
                     end = offs + sym->st_size;