📄 symbol.c
字号:
n /= sizeof(struct nlist); /* Look for the string table. */ m = e + N_STROFF(*o); if (b < 4) i = 0; else i = *((size_t *) m); if ((i == 0) || (b < i)) { c = "missing string table"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } if (l != NULL) f = l; /* Cycle through every symbol contained in the executable file. */ for (i = 0; i < n; i++, p++) /* We only need to bother looking at text symbols. */ if ((((p->n_type & N_TYPE) == N_TEXT) && !(p->n_type & N_STAB)) && !addsymbol(y, p, f, m + p->n_un.n_strx, a)) return 0; return 1;}#elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF/* Allocate a set of symbol nodes for a COFF or XCOFF executable file. */staticintaddsymbols(symhead *y, char *e, char *l, char *f, size_t b, size_t a){ char n[SYMNMLEN + 1]; FILHDR *o; AOUTHDR *v; SCNHDR *h; SYMENT *p; char *c, *m, *s; size_t i, t; /* Check that we have a valid COFF or XCOFF executable file. */ if (b < FILHSZ) { c = "not an object file"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } o = (FILHDR *) e; b -= FILHSZ; if (!ISCOFF(o->f_magic) || (o->f_opthdr == 0) || (b < o->f_opthdr)) { c = "not an executable file"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } /* COFF and XCOFF dynamic linkers don't record the original start * address of the text section so we must adjust the base address here * if necessary. */ if ((a != 0) && (o->f_opthdr >= sizeof(AOUTHDR))) { v = (AOUTHDR *) (e + FILHSZ); if (a > v->text_start) a -= (v->text_start & ~0xFFFF); } b -= o->f_opthdr; if ((o->f_nscns == 0) || (b < o->f_nscns * SCNHSZ)) { c = "missing section table"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } /* Look for the section index of the text section. This is * usually 1, but we should really make sure. */ h = (SCNHDR *) (e + FILHSZ + o->f_opthdr); b += FILHSZ + o->f_opthdr - o->f_symptr; for (i = t = 0; i < o->f_nscns; i++) if ((h[i].s_flags & STYP_TEXT) || (strncmp(h[i].s_name, ".text", 8) == 0)) { t = i + 1; break; } if (t == 0) t = 1; /* Look for the symbol table. */ i = o->f_nsyms * SYMESZ; if ((o->f_symptr == 0) || (o->f_nsyms == 0) || (b < i)) { c = "missing symbol table"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } p = (SYMENT *) (e + o->f_symptr); b -= i; /* Look for the string table. */ m = (char *) p + i; if (b < 4) i = 0; else i = *((size_t *) m); if ((i == 0) || (b < i)) { c = "missing string table"; if (l != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c); return 1; } if (l != NULL) f = l; /* Cycle through every symbol contained in the executable file. */ for (i = 0; i < o->f_nsyms; i += p->n_numaux + 1, p = (SYMENT *) ((char *) p + (p->n_numaux + 1) * SYMESZ)) /* We only need to bother looking at text symbols. */ if (p->n_scnum == t) { if (p->n_zeroes) { /* Symbol name is stored in structure. */ strncpy(n, p->n_name, SYMNMLEN); n[SYMNMLEN] = '\0'; s = n; } else /* Symbol name is stored in string table. */ s = m + p->n_offset; if (!addsymbol(y, p, f, s, a)) return 0; } return 1;}#elif FORMAT == FORMAT_ELF32/* Allocate a set of symbol nodes for an ELF32 object file. */staticintaddsymbols(symhead *y, Elf *e, char *a, char *f, size_t b){ Elf_Scn *s; Elf32_Shdr *h; Elf32_Sym *p; Elf_Data *d; char *m; size_t i, l, n, t; /* Look for the symbol table. */ for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s)) if ((h = elf32_getshdr(s)) && (h->sh_type == SHT_SYMTAB) && (d = elf_getdata(s, NULL))) break; if (d == NULL) /* If we couldn't find the symbol table then it is likely that the file * has been stripped. However, if the file was dynamically linked then * we may be able to obtain some symbols from its dynamic symbol table. */ for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s)) if ((h = elf32_getshdr(s)) && (h->sh_type == SHT_DYNSYM) && (d = elf_getdata(s, NULL))) break; if ((d == NULL) || (d->d_buf == NULL) || (d->d_size == 0)) { m = "missing symbol table"; if (a != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 1; } t = h->sh_link; /* Look for the string table. */ if (((s = elf_getscn(e, t)) == NULL) || ((h = elf32_getshdr(s)) == NULL) || (h->sh_type != SHT_STRTAB)) { m = "missing string table"; if (a != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 1; } if (a != NULL) f = a; p = (Elf32_Sym *) d->d_buf + 1; l = d->d_size / sizeof(Elf32_Sym); /* Cycle through every symbol contained in the object file. */ for (i = 1; i < l; i++, p++) /* We don't need to bother looking at undefined, absolute or common * symbols, and we only need to store non-data symbols. However, on * IRIX the section index for a symbol in a linked object file does * not always refer to the ELF section it was defined in so we skip * the last check. */#if SYSTEM == SYSTEM_IRIX if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) && (n != SHN_COMMON))#else /* SYSTEM */ if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) && (n != SHN_COMMON) && (s = elf_getscn(e, n)) && (h = elf32_getshdr(s)) && (h->sh_flags & SHF_EXECINSTR))#endif /* SYSTEM */ if (!addsymbol(y, p, f, elf_strptr(e, t, p->st_name), b)) return 0; return 1;}#elif FORMAT == FORMAT_ELF64/* Allocate a set of symbol nodes for an ELF64 object file. */staticintaddsymbols(symhead *y, Elf *e, char *a, char *f, size_t b){ Elf_Scn *s; Elf64_Shdr *h; Elf64_Sym *p; Elf_Data *d; char *m; size_t i, l, n, t; /* Look for the symbol table. */ for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s)) if ((h = elf64_getshdr(s)) && (h->sh_type == SHT_SYMTAB) && (d = elf_getdata(s, NULL))) break; if (d == NULL) /* If we couldn't find the symbol table then it is likely that the file * has been stripped. However, if the file was dynamically linked then * we may be able to obtain some symbols from its dynamic symbol table. */ for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s)) if ((h = elf64_getshdr(s)) && (h->sh_type == SHT_DYNSYM) && (d = elf_getdata(s, NULL))) break; if ((d == NULL) || (d->d_buf == NULL) || (d->d_size == 0)) { m = "missing symbol table"; if (a != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 1; } t = h->sh_link; /* Look for the string table. */ if (((s = elf_getscn(e, t)) == NULL) || ((h = elf64_getshdr(s)) == NULL) || (h->sh_type != SHT_STRTAB)) { m = "missing string table"; if (a != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 1; } if (a != NULL) f = a; p = (Elf64_Sym *) d->d_buf + 1; l = d->d_size / sizeof(Elf64_Sym); /* Cycle through every symbol contained in the object file. */ for (i = 1; i < l; i++, p++) /* We don't need to bother looking at undefined, absolute or common * symbols, and we only need to store non-data symbols. However, on * IRIX the section index for a symbol in a linked object file does * not always refer to the ELF section it was defined in so we skip * the last check. */#if SYSTEM == SYSTEM_IRIX if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) && (n != SHN_COMMON))#else /* SYSTEM */ if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) && (n != SHN_COMMON) && (s = elf_getscn(e, n)) && (h = elf64_getshdr(s)) && (h->sh_flags & SHF_EXECINSTR))#endif /* SYSTEM */ if (!addsymbol(y, p, f, elf_strptr(e, t, p->st_name), b)) return 0; return 1;}#elif FORMAT == FORMAT_BFD/* Allocate a set of symbol nodes for a BFD object file. */staticintaddsymbols(symhead *y, bfd *h, char *a, char *f, size_t b){ asymbol **p; char *m; long i, n; int d, r; /* Look for the symbol table. */ d = 0; if ((n = bfd_get_symtab_upper_bound(h)) < 0) { m = (char *) bfd_errmsg(bfd_get_error()); if (a != NULL) __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 0; } if (n == 0) { /* If we couldn't find the symbol table then it is likely that the file * has been stripped. However, if the file was dynamically linked then * we may be able to obtain some symbols from its dynamic symbol table. */ if ((n = bfd_get_dynamic_symtab_upper_bound(h)) < 0) { m = (char *) bfd_errmsg(bfd_get_error()); if (a != NULL) __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 0; } if (n == 0) { m = "missing symbol table"; if (a != NULL) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 1; } d = 1; } /* It's actually safe to call malloc() here since the library checks * for recursive behaviour. */ if ((p = (asymbol **) malloc(n)) == NULL) { m = "no memory for symbols"; if (a != NULL) __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); return 0; } r = 1; if (((d == 0) && ((n = bfd_canonicalize_symtab(h, p)) < 0)) || ((d == 1) && ((n = bfd_canonicalize_dynamic_symtab(h, p)) < 0))) { m = (char *) bfd_errmsg(bfd_get_error()); if (a != NULL) __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m); else __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m); r = 0; } else { /* Cycle through every symbol contained in the object file. */ if (a != NULL) f = a; for (i = 0; i < n; i++) /* We don't need to bother looking at undefined, absolute or common * symbols, and we only need to store non-data symbols. */ if (!bfd_is_und_section(p[i]->section) && !bfd_is_abs_section(p[i]->section) && !bfd_is_com_section(p[i]->section) && (p[i]->section->flags & SEC_CODE)) if (!addsymbol(y, p[i], f, (char *) p[i]->name, (size_t) p[i]->section->vma + b)) { r = 0; break; } } /* If we are making use of line number information in the object files then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -