comparison dynload/dynload_unix.c @ 317:3df50603afa9

- dynload fix to get proc name when elf relocation is in use
author Tassilo Philipp
date Tue, 12 Nov 2019 21:16:58 +0100
parents 3840e0188520
children 85c80b0c021c
comparison
equal deleted inserted replaced
316:dc8bbffc39e6 317:3df50603afa9
180 /* get loaded object's handle if not requesting info about process itself */ 180 /* get loaded object's handle if not requesting info about process itself */
181 if(d->pLib != NULL) { 181 if(d->pLib != NULL) {
182 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's 182 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's
183 * do what we do on macOS above, re-dlopen the already loaded lib (just 183 * do what we do on macOS above, re-dlopen the already loaded lib (just
184 * increases ref count) and compare handles */ 184 * increases ref count) and compare handles */
185 /* @@@ might be b/c it's the reloc addr... see below */
185 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); 186 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST);
186 if(lib) 187 if(lib)
187 dlclose(lib); 188 dlclose(lib);
188 } 189 }
189 190
190 /* compare handles and get name if found; if d->pLib == NULL this will 191 /* compare handles and get name if found; if d->pLib == NULL this will
191 enter info on first iterated object, which is the process itself */ 192 enter info on first iterated object, which is the process itself */
192 if(lib == (void*)d->pLib) { 193 if(lib == (void*)d->pLib) {
193 l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize); 194 l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize);
194 195
195 /* on some platforms (e.g. Linux) dlpi_name is empty for the main process' 196 /* if dlpi_name is empty, lookup name via dladdr(proc_load_addr, ...) */
196 object, but dlpi_addr is given, in that case lookup name via dladdr */ 197 if(l == 0 && d->pLib == NULL) {
197 if(l == 0 && d->pLib == NULL && (void*)info->dlpi_addr != NULL) { 198 /* dlpi_addr is the reloc base (0 if PIE), find real virtual load addr */
198 Dl_info i; 199 void* vladdr = (void*)info->dlpi_addr;
199 if(dladdr((void*)info->dlpi_addr, &i) != 0) 200 int i = 0;
200 l = dl_strlen_strcpy(d->sOut, i.dli_fname, d->bufSize); 201 for(; i < info->dlpi_phnum; ++i) {
202 if(info->dlpi_phdr[i].p_type == PT_LOAD) {
203 vladdr = (void*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
204 break;
205 }
206 }
207 Dl_info di;
208 if(dladdr(vladdr, &di) != 0)
209 l = dl_strlen_strcpy(d->sOut, di.dli_fname, d->bufSize);
201 } 210 }
202 } 211 }
203 212
204 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */ 213 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */
205 } 214 }