📄 symbol.c
字号:
#endif /* FORMAT */ if (r == 1) { l = y->dtree.size - l; __mp_diag("read %lu symbol%s from ", l, (l == 1) ? "" : "s"); } else __mp_diag("problem reading symbols from "); if (__mp_diagflags & FLG_HTML) __mp_diagtag("<TT>"); __mp_diag("%s", s); if (__mp_diagflags & FLG_HTML) __mp_diagtag("</TT>"); if (v != NULL) if (__mp_diagflags & FLG_HTML) { __mp_diag(" ["); __mp_diagtag("<TT>"); __mp_diag("%s", v); __mp_diagtag("</TT>"); __mp_diag("]"); } else __mp_diag(" [%s]", v); __mp_diag("\n"); if (__mp_diagflags & FLG_HTML) __mp_diagtag("<BR>\n"); return r;}/* Add any external or additional symbols to the symbol table. */MP_GLOBALint__mp_addextsymbols(symhead *y, meminfo *e){#if DYNLINK == DYNLINK_AIX static char b[4096]; struct ld_info *l; char *s;#elif DYNLINK == DYNLINK_BSD#if SYSTEM == SYSTEM_SUNOS struct link_dynamic *d; struct link_map *l;#else /* SYSTEM */ struct _dynamic *d; struct so_map *l;#endif /* SYSTEM */#elif DYNLINK == DYNLINK_HPUX struct shl_descriptor d; size_t i; unsigned int o;#elif DYNLINK == DYNLINK_IRIX struct obj_list *l; struct obj *o; objectinfo *i; char *s; size_t b;#elif DYNLINK == DYNLINK_OSF ldr_region_info_t r; ldr_module_info_t i; ldr_module_t m; ldr_process_t p; size_t c, l, n; size_t b;#elif DYNLINK == DYNLINK_SVR4#if ENVIRON == ENVIRON_64 Elf64_Dyn *d;#else /* ENVIRON */ Elf32_Dyn *d;#endif /* ENVIRON */ dynamiclink *l;#elif DYNLINK == DYNLINK_WINDOWS modinfo m;#endif /* DYNLINK */ /* This function liaises with the dynamic linker when a program is * dynamically linked in order to read symbols from any required shared * objects. */#if DYNLINK == DYNLINK_AIX if (loadquery(L_GETINFO, b, sizeof(b)) != -1) { /* We skip past the first item on the list since it represents the * executable file, but we may wish to record the name of the file * if we haven't already determined it. */ l = (struct ld_info *) b; s = l->ldinfo_filename; if ((e->prog == NULL) && (*s != '\0')) e->prog = __mp_addstring(&y->strings, s); while (l = l->ldinfo_next ? (struct ld_info *) ((char *) l + l->ldinfo_next) : NULL) if (*l->ldinfo_filename != '\0') { /* If the filename represents an archive file then the member * name within the archive will follow immediately after it. */ s = l->ldinfo_filename + strlen(l->ldinfo_filename) + 1; if (*s == '\0') s = NULL; if (!__mp_addsymbols(y, l->ldinfo_filename, s, (unsigned long) l->ldinfo_textorg)) return 0; } }#elif DYNLINK == DYNLINK_BSD /* Check to see if the dynamic linker has set up the _DYNAMIC symbol * and also check that it is a valid structure. */ if ((d = &_DYNAMIC) &&#if SYSTEM == SYSTEM_SUNOS (d->ld_version > 1) && (d->ld_version <= 3) && (d->ld_un.ld_1 != NULL))#else /* SYSTEM */ (d->d_version == LD_VERSION_BSD) && (d->d_un.d_sdt != NULL))#endif /* SYSTEM */ {#if SYSTEM == SYSTEM_SUNOS l = d->ld_un.ld_1->ld_loaded;#else /* SYSTEM */ l = d->d_un.d_sdt->sdt_loaded;#endif /* SYSTEM */ while (l != NULL) {#if SYSTEM == SYSTEM_SUNOS if ((l->lm_name != NULL) && (*l->lm_name != '\0') && !__mp_addsymbols(y, l->lm_name, NULL, l->lm_addr))#else /* SYSTEM */ if ((l->som_path != NULL) && (*l->som_path != '\0') && !__mp_addsymbols(y, l->som_path, NULL, l->som_addr))#endif /* SYSTEM */ return 0;#if SYSTEM == SYSTEM_SUNOS l = l->lm_next;#else /* SYSTEM */ l = l->som_next;#endif /* SYSTEM */ } }#elif DYNLINK == DYNLINK_HPUX /* An index of -1 indicates the dynamic linker and an index of 0 indicates * the main executable program. We are interested in all other object files * that the program depends on, but we may wish to record the name of the * executable file if we haven't already determined it. */ if ((e->prog == NULL) && (shl_get_r(0, &d) != -1) && (d.filename[0] != '\0')) e->prog = __mp_addstring(&y->strings, d.filename); for (i = 1; shl_get_r(i, &d) != -1; i++) { /* Determine the offset of the first text symbol in the library. This * is normally 0x1000 but may be something else on later systems. The * handle structure is not documented anywhere, but the fourth word * appears to contain the information we need, based on trial and error. */ if (d.handle != NULL) o = ((unsigned int *) d.handle)[3]; else o = 0; if ((d.filename[0] != '\0') && !__mp_addsymbols(y, d.filename, NULL, d.tstart - o)) return 0; }#elif DYNLINK == DYNLINK_IRIX if (l = __rld_obj_head) /* Determine if the shared object list we are looking at contains O32 * ABI object files or N32 ABI object files. */ if (l->data == 0xFFFFFFFF) { /* We skip past the first item on the list since it represents the * executable file, but we may wish to record the name of the file * if we haven't already determined it. */ i = (objectinfo *) l; s = (char *) i->name; if ((e->prog == NULL) && (s != NULL) && (*s != '\0')) e->prog = __mp_addstring(&y->strings, s); while (i = (objectinfo *) i->next) { s = (char *) i->name; b = (long) i->ehdr - (long) i->ohdr; if ((s != NULL) && (*s != '\0') && !__mp_addsymbols(y, s, NULL, b)) return 0; } } else { /* We skip past the first item on the list since it represents the * executable file, but we may wish to record the name of the file * if we haven't already determined it. */ o = (struct obj *) l->data; s = o->o_path; if ((e->prog == NULL) && (s != NULL) && (*s != '\0')) e->prog = __mp_addstring(&y->strings, s); while (l = l->next) { o = (struct obj *) l->data; s = o->o_path; b = (long) o->o_text_start - (long) o->o_base_address; if ((s != NULL) && (*s != '\0') && !__mp_addsymbols(y, s, NULL, b)) return 0; } }#elif DYNLINK == DYNLINK_OSF c = 0; p = ldr_my_process(); m = LDR_NULL_MODULE; while ((ldr_next_module(p, &m) == 0) && (m != LDR_NULL_MODULE)) if (ldr_inq_module(p, m, &i, sizeof(i), &l) == 0) { /* We skip past the first item on the list since it represents the * executable file, but we may wish to record the name of the file * if we haven't already determined it. */ if (c++ == 0) { if ((e->prog == NULL) && (i.lmi_name[0] != '\0')) e->prog = __mp_addstring(&y->strings, i.lmi_name); continue; } for (n = 0; n < (size_t) i.lmi_nregion; n++) if ((ldr_inq_region(p, m, (ldr_region_t) n, &r, sizeof(r), &l) == 0) && (strcmp(r.lri_name, ".text") == 0)) { b = (long) r.lri_mapaddr - (long) r.lri_vaddr; if ((i.lmi_name[0] != '\0') && !__mp_addsymbols(y, i.lmi_name, NULL, b)) return 0; break; } }#elif DYNLINK == DYNLINK_SVR4#if ENVIRON == ENVIRON_64 if ((&_DYNAMIC != NULL) && (d = (Elf64_Dyn *) _DYNAMIC))#else /* ENVIRON */ if ((&_DYNAMIC != NULL) && (d = (Elf32_Dyn *) _DYNAMIC))#endif /* ENVIRON */ { /* Search for the DT_DEBUG tag in the _DYNAMIC symbol. */ for (l = NULL; d->d_tag != DT_NULL; d++) if (d->d_tag == DT_DEBUG) { if (!d->d_un.d_ptr) l = NULL; else l = (dynamiclink *) *((unsigned long *) d->d_un.d_ptr + 1); break; } /* We skip past the first item on the list since it represents the * executable file, but we may wish to record the name of the file * if we haven't already determined it. */ if (l != NULL) { if ((e->prog == NULL) && (l->name != NULL) && (*l->name != '\0')) e->prog = __mp_addstring(&y->strings, l->name); l = l->next; } while (l != NULL) { if ((l->name != NULL) && (*l->name != '\0') && !__mp_addsymbols(y, l->name, NULL, l->base)) return 0; l = l->next; } }#elif DYNLINK == DYNLINK_WINDOWS /* We always want to initialise the imagehlp library here since we will * be using it to obtain the symbols from any loaded DLLs here and * possibly also from the executable file if we are not using any other * object file access library. In any case we can set the demangling * option in the imagehlp library and also instruct it to load line number * information if the USEDEBUG option is given. */ if (y->lineinfo) SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); else SymSetOptions(SYMOPT_UNDNAME); SymInitialize(GetCurrentProcess(), NULL, 1); /* The imagehlp library allows us to locate the symbols contained in * all of the loaded DLLs without having to actually read the files * themselves. */ m.syms = y; m.index = 0; m.libs = 1; if (!SymEnumerateModules(GetCurrentProcess(), addsyms, &m)) return 0;#endif /* DYNLINK */ return 1;}/* Attempt to tidy up the symbol table by correcting any potential errors or * conflicts from the symbols that have been read. */MP_GLOBALvoid__mp_fixsymbols(symhead *y){ symnode *n, *p; void *l, *m;#if TARGET == TARGET_AMIGA unsigned long o;#endif /* TARGET */#if TARGET == TARGET_AMIGA o = 0;#endif /* TARGET */ l = NULL; for (n = (symnode *) __mp_minimum(y->dtree.root); n != NULL; n = p) { /* If a symbol has a zero size and it is closely followed by another * symbol then the likelihood is that the symbol really has a non-zero * size so we fix that here. This commonly occurs with system startup * files. */ p = (symnode *) __mp_successor(&n->data.node); if ((n->data.size == 0) && (n->data.addr >= l)) if ((p == NULL) || (n->data.file != p->data.file)) n->data.size = 256; else n->data.size = (char *) p->data.addr - (char *) n->data.addr; if ((m = (char *) n->data.addr + n->data.size) > l) l = m;#if TARGET == TARGET_AMIGA /* On AmigaOS, sections are scatter-loaded into memory and will occupy * different addresses each time a program is loaded. One easy way to * determine the run-time address of each function is to find the * offset for one function and add it to all functions, but this means * that this function must be compiled with symbolic information and * assumes that all text symbols are in the one hunk. */ if ((o == 0) && (strcmp(n->data.name, "___mp_fixsymbols") == 0)) o = (char *) __mp_fixsymbols - (char *) n->data.addr;#endif /* TARGET */ }#if TARGET == TARGET_AMIGA if (o != 0) {#if FORMAT == FORMAT_BFD if (y->hhead != NULL) ((objectfile *) y->hhead)->base = o;#endif /* FORMAT */ for (n = (symnode *) __mp_minimum(y->dtree.root); n != NULL; n = (symnode *) __mp_successor(&n->index.node)) { n->data.node.key += o; n->data.addr = (char *) n->data.addr + o; } }#endif /* TARGET */}/* Protect the memory blocks used by the symbol table with the supplied access * permission. */MP_GLOBALint__mp_protectsymbols(symhead *y, memaccess a){ symnode *n; /* The library already knows what its protection status is so we don't * need to do anything if the request has already been done. */ if (y->prot == a) { y->protrecur++; return 1; } else if (y->protrecur > 0) { y->protrecur--; return 1; } y->prot = a; for (n = (symnode *) __mp_minimum(y->itree.root); n != NULL; n = (symnode *) __mp_successor(&n->index.node)) if (!__mp_memprotect(&y->heap->memory, n->index.block, n->index.size, a)) return 0; return 1;}/* Attempt to find the symbol located at a particular address. */MP_GLOBALsymnode *__mp_findsymbol(symhead *y, void *p){ symnode *m, *n, *r; /* This function does not deal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -