summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-05-25 00:32:37 -0400
committerRich Felker <dalias@aerifal.cx>2015-05-25 00:46:05 -0400
commit0e0e49421f08cfd670975ecd3604f7f9015e1833 (patch)
treecc39528b1e7eac1ec86dbeb04b1b92fb766ed1a0 /src
parent09db855b35709aa627d7055c57a98e1e471920ab (diff)
downloadmusl-0e0e49421f08cfd670975ecd3604f7f9015e1833.tar.gz
simplify/shrink relocation processing in dynamic linker stage 1
the outer-loop approach made sense when we were also processing DT_JMPREL, which might be in REL or RELA form, to avoid major code duplication. commit 09db855b35709aa627d7055c57a98e1e471920ab removed processing of DT_JMPREL, and in the remaining two tables, the format (REL or RELA) is known by the name of the table. simply writing two versions of the loop results in smaller and simpler code.
Diffstat (limited to 'src')
-rw-r--r--src/ldso/dlstart.c40
1 files changed, 16 insertions, 24 deletions
diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c
index caa974a2..5f84465c 100644
--- a/src/ldso/dlstart.c
+++ b/src/ldso/dlstart.c
@@ -56,30 +56,22 @@ void _dlstart_c(size_t *sp, size_t *dynv)
for (i=0; i<local_cnt; i++) got[i] += (size_t)base;
}
- /* The use of the reloc_info structure and nested loops is a trick
- * to work around the fact that we can't necessarily make function
- * calls yet. Each struct in the array serves like the arguments
- * to a function call. */
- struct {
- void *rel;
- size_t size;
- size_t stride;
- } reloc_info[] = {
- { base+dyn[DT_REL], dyn[DT_RELSZ], 2 },
- { base+dyn[DT_RELA], dyn[DT_RELASZ], 3 },
- { 0, 0, 0 }
- };
-
- for (i=0; reloc_info[i].stride; i++) {
- size_t *rel = reloc_info[i].rel;
- size_t rel_size = reloc_info[i].size;
- size_t stride = reloc_info[i].stride;
- for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
- if (!IS_RELATIVE(rel[1])) continue;
- size_t *rel_addr = (void *)(base + rel[0]);
- size_t addend = stride==3 ? rel[2] : *rel_addr;
- *rel_addr = (size_t)base + addend;
- }
+ size_t *rel, rel_size;
+
+ rel = (void *)(base+dyn[DT_REL]);
+ rel_size = dyn[DT_RELSZ];
+ for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
+ if (!IS_RELATIVE(rel[1])) continue;
+ size_t *rel_addr = (void *)(base + rel[0]);
+ *rel_addr += (size_t)base;
+ }
+
+ rel = (void *)(base+dyn[DT_RELA]);
+ rel_size = dyn[DT_RELASZ];
+ for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
+ if (!IS_RELATIVE(rel[1])) continue;
+ size_t *rel_addr = (void *)(base + rel[0]);
+ *rel_addr = (size_t)base + rel[2];
}
const char *strings = (void *)(base + dyn[DT_STRTAB]);