소스 검색

fix symbol acceptance/rejection rules for TLS

symbol value of 0 is not "undefined" for TLS; it's the address of the
first symbol in the TLS segment. however, non-definition TLS
references also have values of 0, so check the section.

hopefully the new logic is more clear, too.
Rich Felker 12 년 전
부모
커밋
bd17431a2c
1개의 변경된 파일14개의 추가작업 그리고 8개의 파일을 삭제
  1. 14 8
      src/ldso/dynlink.c

+ 14 - 8
src/ldso/dynlink.c

@@ -209,14 +209,20 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
 			if (!h) h = sysv_hash(s);
 			sym = sysv_lookup(s, h, dso);
 		}
-		if (sym && (!need_def || sym->st_shndx) && sym->st_value
-		 && (1<<(sym->st_info&0xf) & OK_TYPES)
-		 && (1<<(sym->st_info>>4) & OK_BINDS)) {
-			if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
-			def.sym = sym;
-			def.dso = dso;
-			if (sym->st_info>>4 == STB_GLOBAL) break;
-		}
+		if (!sym) continue;
+		if (!sym->st_shndx)
+			if (need_def || (sym->st_info&0xf) == STT_TLS)
+				continue;
+		if (!sym->st_value)
+			if ((sym->st_info&0xf) != STT_TLS)
+				continue;
+		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
+		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
+
+		if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
+		def.sym = sym;
+		def.dso = dso;
+		if (sym->st_info>>4 == STB_GLOBAL) break;
 	}
 	return def;
 }