|
Message-ID: <20121013013106.GH254@brightrain.aerifal.cx> Date: Fri, 12 Oct 2012 21:31:06 -0400 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Re: PATCH: dl_iterate_phdr() On Fri, Oct 12, 2012 at 08:24:24PM -0500, Alex Caudill wrote: > No, seriously, this time it's right! ;) No, still at least one bug and a few style issues. > On 10/12/12, Alex Caudill <alex.caudill@...il.com> wrote: > @@ -30,12 +31,14 @@ static char errbuf[128]; > typedef Elf32_Ehdr Ehdr; > typedef Elf32_Phdr Phdr; > typedef Elf32_Sym Sym; > +typedef Elf32_Addr Addr; This is not needed. > + Phdr *phdr; > + uint16_t phnum; There's no reason to use uint16_t; it just causes gratuitous slowness and bloat on archs where accessign 16-bit units is painful. Just use a clean type like int. > @@ -324,6 +330,8 @@ static void *map_library(int fd, struct dso *dso) > eh->e_phoff = sizeof *eh; > } > ph = (void *)((char *)buf + eh->e_phoff); > + dso->phdr = ph; > + dso->phnum = (uint16_t)eh->e_phnum; This cast is also useless. > @@ -815,18 +823,19 @@ void *__dynlink(int argc, char **argv) > lib->name = lib->shortname = "libc.so"; > lib->global = 1; > ehdr = (void *)lib->base; > - find_map_range((void *)(aux[AT_BASE]+ehdr->e_phoff), > - ehdr->e_phnum, ehdr->e_phentsize, lib); > - lib->dynv = (void *)(lib->base + find_dyn( > - (void *)(aux[AT_BASE]+ehdr->e_phoff), > - ehdr->e_phnum, ehdr->e_phentsize)); > + lib->phnum = (uint16_t)ehdr->e_phnum; And so is this one. > @@ -1051,6 +1061,7 @@ void *dlopen(const char *file, int mode) > orig_tail = tail; > end: > __release_ptc(); > + if (errflag == 0) gencnt++; Use if (p), not if (errflag == 0). Not sure if it's a bug, but at least it's an inconsistency with the below check. > pthread_rwlock_unlock(&lock); > if (p) do_init_fini(orig_tail); > pthread_setcancelstate(cs, 0); > @@ -1166,6 +1177,33 @@ void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) > pthread_rwlock_unlock(&lock); > return res; > } > + > +int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data) > +{ > + struct dso *current; > + struct dl_phdr_info info; > + int ret = 0; > + for(current = head; current;) { > + info.dlpi_addr = (Addr)current->base; > + info.dlpi_name = current->name; > + info.dlpi_phdr = current->phdr; > + info.dlpi_phnum = current->phnum; > + info.dlpi_adds = gencnt; > + info.dlpi_subs = 0; > + info.dlpi_tls_modid = current->tls_id; > + info.dlpi_tls_data = current->tls_image; > + > + ret = (callback)(&info, sizeof (info), data); > + > + if (ret != 0) break; > + > + pthread_rwlock_rdlock(&lock); > + if (current == tail) break; > + current = current->next; > + pthread_rwlock_unlock(&lock); This code will return with the lock still held, which is rather problematic. The idea of locking/unlocking on each iteration was not to use this break logic, but instead rely on the for loop condition to exit the loop. Just remove the if (current == tail) break; line and it should be safe. Rich
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.