summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libexec/rtld-elf/amd64/reloc.c30
-rw-r--r--libexec/rtld-elf/i386/reloc.c30
2 files changed, 42 insertions, 18 deletions
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index 3954452..c306a84 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -115,10 +115,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
const Elf_Rel *rellim;
const Elf_Rel *rel;
SymCache *cache;
-
- cache = (SymCache *)alloca(obj->nchains * sizeof(SymCache));
+ int bytes = obj->nchains * sizeof(SymCache);
+ int r = -1;
+
+ /*
+ * The dynamic loader may be called from a thread, we have
+ * limited amounts of stack available so we cannot use alloca().
+ */
+ cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+ if (cache == MAP_FAILED)
+ cache = NULL;
if (cache != NULL)
- memset(cache, 0, obj->nchains * sizeof(SymCache));
+ memset(cache, 0, bytes);
rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
@@ -137,7 +145,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where += (Elf_Addr) (defobj->relocbase + def->st_value);
}
@@ -156,7 +164,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where +=
(Elf_Addr) (defobj->relocbase + def->st_value) -
@@ -174,7 +182,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
if (!obj->mainprog) {
_rtld_error("%s: Unexpected R_386_COPY relocation"
" in shared library", obj->path);
- return -1;
+ goto done;
}
break;
@@ -186,7 +194,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where = (Elf_Addr) (defobj->relocbase + def->st_value);
}
@@ -200,10 +208,14 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
_rtld_error("%s: Unsupported relocation type %d"
" in non-PLT relocations\n", obj->path,
ELF_R_TYPE(rel->r_info));
- return -1;
+ goto done;
}
}
- return 0;
+ if (cache)
+ munmap(cache, bytes);
+ r = 0;
+done:
+ return(r);
}
/* Process the PLT relocations. */
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index 3954452..c306a84 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -115,10 +115,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
const Elf_Rel *rellim;
const Elf_Rel *rel;
SymCache *cache;
-
- cache = (SymCache *)alloca(obj->nchains * sizeof(SymCache));
+ int bytes = obj->nchains * sizeof(SymCache);
+ int r = -1;
+
+ /*
+ * The dynamic loader may be called from a thread, we have
+ * limited amounts of stack available so we cannot use alloca().
+ */
+ cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+ if (cache == MAP_FAILED)
+ cache = NULL;
if (cache != NULL)
- memset(cache, 0, obj->nchains * sizeof(SymCache));
+ memset(cache, 0, bytes);
rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
@@ -137,7 +145,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where += (Elf_Addr) (defobj->relocbase + def->st_value);
}
@@ -156,7 +164,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where +=
(Elf_Addr) (defobj->relocbase + def->st_value) -
@@ -174,7 +182,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
if (!obj->mainprog) {
_rtld_error("%s: Unexpected R_386_COPY relocation"
" in shared library", obj->path);
- return -1;
+ goto done;
}
break;
@@ -186,7 +194,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
- return -1;
+ goto done;
*where = (Elf_Addr) (defobj->relocbase + def->st_value);
}
@@ -200,10 +208,14 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
_rtld_error("%s: Unsupported relocation type %d"
" in non-PLT relocations\n", obj->path,
ELF_R_TYPE(rel->r_info));
- return -1;
+ goto done;
}
}
- return 0;
+ if (cache)
+ munmap(cache, bytes);
+ r = 0;
+done:
+ return(r);
}
/* Process the PLT relocations. */
OpenPOWER on IntegriCloud