Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250822225404.908578-1-hulata@sysart.tech>
Date: Sat, 23 Aug 2025 00:54:04 +0200
From: tombo <hulata@...art.tech>
To: musl@...ts.openwall.com
Cc: tombo <hulata@...art.tech>
Subject: [PATCH v3] vdso: add support for GNU hash tables

Hi Rich, thanks for the review. Hopefully this version addresses all the points.

---
 src/internal/vdso.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/internal/vdso.c b/src/internal/vdso.c
index d46d3228..2b6e1ae2 100644
--- a/src/internal/vdso.c
+++ b/src/internal/vdso.c
@@ -40,6 +40,24 @@ static int checkver(Verdef *def, int vsym, const char *vername, char *strings)
 #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
 #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
 
+static size_t count_syms_gnu(uint32_t *gh)
+{
+	size_t nsym, i;
+	uint32_t *buckets = gh + 4 + (gh[2]*sizeof(size_t)/4);
+	uint32_t *hashval;
+	for (i = nsym = 0; i < gh[0]; i++) {
+		if (buckets[i] > nsym)
+			nsym = buckets[i];
+	}
+	if (nsym) {
+		hashval = buckets + gh[0] + (nsym - gh[1]);
+		do nsym++;
+		while (!(*hashval++ & 1));
+	}
+	return nsym;
+}
+
+
 void *__vdsosym(const char *vername, const char *name)
 {
 	size_t i;
@@ -60,6 +78,7 @@ void *__vdsosym(const char *vername, const char *name)
 	char *strings = 0;
 	Sym *syms = 0;
 	Elf_Symndx *hashtab = 0;
+	uint32_t *ghashtab = 0;
 	uint16_t *versym = 0;
 	Verdef *verdef = 0;
 	
@@ -69,15 +88,20 @@ void *__vdsosym(const char *vername, const char *name)
 		case DT_STRTAB: strings = p; break;
 		case DT_SYMTAB: syms = p; break;
 		case DT_HASH: hashtab = p; break;
+		case DT_GNU_HASH: ghashtab = p; break;
 		case DT_VERSYM: versym = p; break;
 		case DT_VERDEF: verdef = p; break;
 		}
 	}	
 
-	if (!strings || !syms || !hashtab) return 0;
+	if (!strings || !syms) return 0;
 	if (!verdef) versym = 0;
+	size_t nsym = 0;
+
+	if (hashtab) nsym = hashtab[1];
+	else if (ghashtab) nsym = count_syms_gnu(ghashtab);
 
-	for (i=0; i<hashtab[1]; i++) {
+	for (i=0; i<nsym; i++) {
 		if (!(1<<(syms[i].st_info&0xf) & OK_TYPES)) continue;
 		if (!(1<<(syms[i].st_info>>4) & OK_BINDS)) continue;
 		if (!syms[i].st_shndx) continue;
-- 
2.46.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.