Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* TODO:
- * notify gdb of unload
- * for non-prelinked libraries, find a way to decrement libbase
- */
- static void call_destructors(soinfo *si);
- unsigned unload_library(soinfo *si)
- {
- unsigned *d;
- if (si->refcount == 1) {
- TRACE("%5d unloading '%s'\n", pid, si->name);
- call_destructors(si);
- /*
- * Make sure that we undo the PT_GNU_RELRO protections we added
- * in link_image. This is needed to undo the DT_NEEDED hack below.
- */
- if ((si->gnu_relro_start != 0) && (si->gnu_relro_len != 0)) {
- Elf_Addr start = (si->gnu_relro_start & ~PAGE_MASK);
- unsigned len = (si->gnu_relro_start - start) + si->gnu_relro_len;
- if (mprotect((void *) start, len, PROT_READ | PROT_WRITE) < 0)
- DL_ERR("%5d %s: could not undo GNU_RELRO protections. "
- "Expect a crash soon. errno=%d (%s)",
- pid, si->name, errno, strerror(errno));
- }
- for(d = si->dynamic; *d; d += 2) {
- if(d[0] == DT_NEEDED){
- soinfo *lsi = (soinfo *)d[1];
- // The next line will segfault if the we don't undo the
- // PT_GNU_RELRO protections (see comments above and in
- // link_image().
- d[1] = 0;
- if (validate_soinfo(lsi)) {
- TRACE("%5d %s needs to unload %s\n", pid,
- si->name, lsi->name);
- unload_library(lsi);
- }
- else
- DL_ERR("%5d %s: could not unload dependent library",
- pid, si->name);
- }
- }
- munmap((char *)si->base, si->size);
- notify_gdb_of_unload(si);
- free_info(si);
- si->refcount = 0;
- }
- else {
- si->refcount--;
- INFO("%5d not unloading '%s', decrementing refcount to %d\n",
- pid, si->name, si->refcount);
- }
- return si->refcount;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement