about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2017-03-13 00:30:26 -0400
committerRich Felker <dalias@aerifal.cx>2017-03-13 00:32:45 -0400
commit4823b13a75b40c4408c1101b363ab00fd118fb27 (patch)
tree65204d069fb5d41a74720f2ed7d72e461cf3b89c
parent4ff234f6cba96403b5de6d29d48a59fd73252040 (diff)
downloadmusl-4823b13a75b40c4408c1101b363ab00fd118fb27.tar.gz
musl-4823b13a75b40c4408c1101b363ab00fd118fb27.tar.xz
musl-4823b13a75b40c4408c1101b363ab00fd118fb27.zip
reorder addend handling before symbol lookup in relocation code
these two tasks are independent now, but in order to support lazy
relocations, the failure path for symbol lookup may want the addend to
be available.
-rw-r--r--ldso/dynlink.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 0e394e0d..0bd9d50c 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -323,8 +323,24 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
 		if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
 		type = R_TYPE(rel[1]);
 		if (type == REL_NONE) continue;
-		sym_index = R_SYM(rel[1]);
 		reloc_addr = laddr(dso, rel[0]);
+
+		if (stride > 2) {
+			addend = rel[2];
+		} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
+			addend = 0;
+		} else if (reuse_addends) {
+			/* Save original addend in stage 2 where the dso
+			 * chain consists of just ldso; otherwise read back
+			 * saved addend since the inline one was clobbered. */
+			if (head==&ldso)
+				saved_addends[save_slot] = *reloc_addr;
+			addend = saved_addends[save_slot++];
+		} else {
+			addend = *reloc_addr;
+		}
+
+		sym_index = R_SYM(rel[1]);
 		if (sym_index) {
 			sym = syms + sym_index;
 			name = strings + sym->st_name;
@@ -345,21 +361,6 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
 			def.dso = dso;
 		}
 
-		if (stride > 2) {
-			addend = rel[2];
-		} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
-			addend = 0;
-		} else if (reuse_addends) {
-			/* Save original addend in stage 2 where the dso
-			 * chain consists of just ldso; otherwise read back
-			 * saved addend since the inline one was clobbered. */
-			if (head==&ldso)
-				saved_addends[save_slot] = *reloc_addr;
-			addend = saved_addends[save_slot++];
-		} else {
-			addend = *reloc_addr;
-		}
-
 		sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
 		tls_val = def.sym ? def.sym->st_value : 0;