int coff_syms(FILE *in) { struct coff_header hdr; char *strtab; uint8_t *symtab; int strtab_len; int i; int ret = 0; if (read_header(in, &hdr) < 0) return -1; strtab_len = read_strtab(in, &hdr, &strtab); if (strtab_len < 0) return -1; if (read_symtab(in, &hdr, &symtab) < 0) { if (strtab) free(strtab); return -1; } for (i = 0; i < hdr.stab_count; i++) { uint8_t *entry = symtab + i * STAB_ENTRY_SIZE; uint32_t value = LE_LONG(entry, 8); int storage_class = entry[16]; char namebuf[9]; const char *name = NULL; if (LE_LONG(entry, 0)) { memcpy(namebuf, entry, 8); namebuf[8] = 0; name = namebuf; } else { uint32_t offset = LE_LONG(entry, 4); if (offset >= 4 && offset < strtab_len) name = strtab + offset; } if (name && (storage_class == C_EXT || storage_class == C_LABEL) && stab_set(name, value) < 0) { printc_err("coff: failed to insert symbol\n"); ret = -1; break; } /* Skip auxiliary entries */ i += entry[17]; } if (symtab) free(symtab); if (strtab) free(strtab); return ret; }
int pbc_param_init_set_buf(pbc_param_t par, const char *input, size_t len) { symtab_t tab; symtab_init(tab); read_symtab(tab, input, len); int res = param_set_tab(par, tab); symtab_forall_data(tab, pbc_free); symtab_clear(tab); return res; }
int search_symtab(const char *symtab,const char *query){ SYMTAB_END=0; char symbol[MAXVARSIEZE],var[MAXVARSIEZE],marker; FILE *fp=fopen(symtab,"r"); int i; while(1){ read_symtab(fp,symbol); // printf("%s\n",symbol ); if(symbol[0]=='\0'&&SYMTAB_END!=1){ continue; } if(symbol[0]=='\0'){ break; } i=0; while(symbol[i]!=' '){ var[i]=symbol[i]; i++; } var[i]='\0'; // printf("%s\n",var ); i++; marker=symbol[i]; // printf("%c\n",marker ); if(isSame(var,query)==1){ printf("\nkeyword detected ...\n"); fclose(fp); return ((int)marker-48); } if(SYMTAB_END==1){ break; } } printf("\nIts a keyword"); fclose(fp); return -1; }
Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) { struct symtab_command *symcmd = NULL; struct dysymtab_command *dysymcmd = NULL; HChar* dsymfilename = NULL; Bool have_uuid = False; UChar uuid[16]; ImageInfo ii; /* main file */ ImageInfo iid; /* auxiliary .dSYM file */ Bool ok; /* mmap the object file to look for di->soname and di->text_bias and uuid and nlist and STABS */ if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, "%s (%#lx)\n", di->filename, di->rx_map_avma ); /* This should be ensured by our caller. */ vg_assert(di->have_rx_map); vg_assert(di->have_rw_map); VG_(memset)(&ii, 0, sizeof(ii)); VG_(memset)(&iid, 0, sizeof(iid)); VG_(memset)(&uuid, 0, sizeof(uuid)); ok = map_image_aboard( di, &ii, di->filename ); if (!ok) goto fail; vg_assert(ii.macho_img != NULL && ii.macho_img_szB > 0); /* Poke around in the Mach-O header, to find some important stuff. */ // Find LC_SYMTAB and LC_DYSYMTAB, if present. // Read di->soname from LC_ID_DYLIB if present, // or from LC_ID_DYLINKER if present, // or use "NONE". // Get di->text_bias (aka slide) based on the corresponding LC_SEGMENT // Get uuid for later dsym search di->text_bias = 0; { struct MACH_HEADER *mh = (struct MACH_HEADER *)ii.macho_img; struct load_command *cmd; Int c; for (c = 0, cmd = (struct load_command *)(mh+1); c < mh->ncmds; c++, cmd = (struct load_command *)(cmd->cmdsize + (unsigned long)cmd)) { if (cmd->cmd == LC_SYMTAB) { symcmd = (struct symtab_command *)cmd; } else if (cmd->cmd == LC_DYSYMTAB) { dysymcmd = (struct dysymtab_command *)cmd; } else if (cmd->cmd == LC_ID_DYLIB && mh->filetype == MH_DYLIB) { // GrP fixme bundle? struct dylib_command *dcmd = (struct dylib_command *)cmd; UChar *dylibname = dcmd->dylib.name.offset + (UChar *)dcmd; UChar *soname = VG_(strrchr)(dylibname, '/'); if (!soname) soname = dylibname; else soname++; di->soname = ML_(dinfo_strdup)("di.readmacho.dylibname", soname); } else if (cmd->cmd==LC_ID_DYLINKER && mh->filetype==MH_DYLINKER) { struct dylinker_command *dcmd = (struct dylinker_command *)cmd; UChar *dylinkername = dcmd->name.offset + (UChar *)dcmd; UChar *soname = VG_(strrchr)(dylinkername, '/'); if (!soname) soname = dylinkername; else soname++; di->soname = ML_(dinfo_strdup)("di.readmacho.dylinkername", soname); } // A comment from Julian about why varinfo[35] fail: // // My impression is, from comparing the output of otool -l for these // executables with the logic in ML_(read_macho_debug_info), // specifically the part that begins "else if (cmd->cmd == // LC_SEGMENT_CMD) {", that it's a complete hack which just happens // to work ok for text symbols. In particular, it appears to assume // that in a "struct load_command" of type LC_SEGMENT_CMD, the first // "struct SEGMENT_COMMAND" inside it is going to contain the info we // need. However, otool -l shows, and also the Apple docs state, // that a struct load_command may contain an arbitrary number of // struct SEGMENT_COMMANDs, so I'm not sure why it's OK to merely // snarf the first. But I'm not sure about this. // // The "Try for __DATA" block below simply adds acquisition of data // svma/bias values using the same assumption. It also needs // (probably) to deal with bss sections, but I don't understand how // this all ties together really, so it requires further study. // // If you can get your head around the relationship between MachO // segments, sections and load commands, this might be relatively // easy to fix properly. // // Basically we need to come up with plausible numbers for di-> // {text,data,bss}_{avma,svma}, from which the _bias numbers are // then trivially derived. Then I think the debuginfo reader should // work pretty well. else if (cmd->cmd == LC_SEGMENT_CMD) { struct SEGMENT_COMMAND *seg = (struct SEGMENT_COMMAND *)cmd; /* Try for __TEXT */ if (!di->text_present && 0 == VG_(strcmp)(seg->segname, "__TEXT") /* DDD: is the next line a kludge? -- JRS */ && seg->fileoff == 0 && seg->filesize != 0) { di->text_present = True; di->text_svma = (Addr)seg->vmaddr; di->text_avma = di->rx_map_avma; di->text_size = seg->vmsize; di->text_bias = di->text_avma - di->text_svma; /* Make the _debug_ values be the same as the svma/bias for the primary object, since there is no secondary (debuginfo) object, but nevertheless downstream biasing of Dwarf3 relies on the _debug_ values. */ di->text_debug_svma = di->text_svma; di->text_debug_bias = di->text_bias; } /* Try for __DATA */ if (!di->data_present && 0 == VG_(strcmp)(seg->segname, "__DATA") /* && DDD:seg->fileoff == 0 */ && seg->filesize != 0) { di->data_present = True; di->data_svma = (Addr)seg->vmaddr; di->data_avma = di->rw_map_avma; di->data_size = seg->vmsize; di->data_bias = di->data_avma - di->data_svma; di->data_debug_svma = di->data_svma; di->data_debug_bias = di->data_bias; } } else if (cmd->cmd == LC_UUID) { struct uuid_command *uuid_cmd = (struct uuid_command *)cmd; VG_(memcpy)(uuid, uuid_cmd->uuid, sizeof(uuid)); have_uuid = True; } } } if (!di->soname) { di->soname = ML_(dinfo_strdup)("di.readmacho.noname", "NONE"); } /* Now we have the base object to hand. Read symbols from it. */ if (ii.macho_img && ii.macho_img_szB > 0 && symcmd && dysymcmd) { /* Read nlist symbol table */ struct NLIST *syms; UChar *strs; XArray* /* DiSym */ candSyms = NULL; Word i, nCandSyms; if (ii.macho_img_szB < symcmd->stroff + symcmd->strsize || ii.macho_img_szB < symcmd->symoff + symcmd->nsyms * sizeof(struct NLIST)) { ML_(symerr)(di, False, "Invalid Mach-O file (5 too small)."); goto fail; } if (dysymcmd->ilocalsym + dysymcmd->nlocalsym > symcmd->nsyms || dysymcmd->iextdefsym + dysymcmd->nextdefsym > symcmd->nsyms) { ML_(symerr)(di, False, "Invalid Mach-O file (bad symbol table)."); goto fail; } syms = (struct NLIST *)(ii.macho_img + symcmd->symoff); strs = (UChar *)(ii.macho_img + symcmd->stroff); if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " reading syms from primary file (%d %d)\n", dysymcmd->nextdefsym, dysymcmd->nlocalsym ); /* Read candidate symbols into 'candSyms', so we can truncate overlapping ends and generally tidy up, before presenting them to ML_(addSym). */ candSyms = VG_(newXA)( ML_(dinfo_zalloc), "di.readmacho.candsyms.1", ML_(dinfo_free), sizeof(DiSym) ); vg_assert(candSyms); // extern symbols read_symtab(candSyms, di, syms + dysymcmd->iextdefsym, dysymcmd->nextdefsym, strs, symcmd->strsize); // static and private_extern symbols read_symtab(candSyms, di, syms + dysymcmd->ilocalsym, dysymcmd->nlocalsym, strs, symcmd->strsize); /* tidy up the cand syms -- trim overlapping ends. May resize candSyms. */ tidy_up_cand_syms( candSyms, di->trace_symtab ); /* and finally present them to ML_(addSym) */ nCandSyms = VG_(sizeXA)( candSyms ); for (i = 0; i < nCandSyms; i++) { DiSym* cand = (DiSym*) VG_(indexXA)( candSyms, i ); if (di->trace_symtab) VG_(printf)("nlist final: acquire avma %010lx-%010lx %s\n", cand->addr, cand->addr + cand->size - 1, cand->name ); ML_(addSym)( di, cand ); } VG_(deleteXA)( candSyms ); } /* If there's no UUID in the primary, don't even bother to try and read any DWARF, since we won't be able to verify it matches. Our policy is not to load debug info unless we can verify that it matches the primary. Just declare success at this point. And don't complain to the user, since that would cause us to complain on objects compiled without -g. (Some versions of XCode are observed to omit a UUID entry for object linked(?) without -g. Others don't appear to omit it.) */ if (!have_uuid) goto success; /* mmap the dSYM file to look for DWARF debug info. If successful, use the .macho_img and .macho_img_szB in iid. */ dsymfilename = find_separate_debug_file( di->filename ); /* Try to load it. */ if (dsymfilename) { Bool valid; if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " dSYM= %s\n", dsymfilename); ok = map_image_aboard( di, &iid, dsymfilename ); if (!ok) goto fail; /* check it has the right uuid. */ vg_assert(have_uuid); valid = iid.macho_img && iid.macho_img_szB > 0 && check_uuid_matches( (Addr)iid.macho_img, iid.macho_img_szB, uuid ); if (valid) goto read_the_dwarf; if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " dSYM does not have " "correct UUID (out of date?)\n"); } /* There was no dsym file, or it doesn't match. We'll have to try regenerating it, unless --dsymutil=no, in which case just complain instead. */ /* If this looks like a lib that we shouldn't run dsymutil on, just give up. (possible reasons: is system lib, or in /usr etc, or the dsym dir would not be writable by the user, or we're running as root) */ vg_assert(di->filename); if (is_systemish_library_name(di->filename)) goto success; if (!VG_(clo_dsymutil)) { if (VG_(clo_verbosity) == 1) { VG_(message)(Vg_DebugMsg, "%s:\n", di->filename); } if (VG_(clo_verbosity) > 0) VG_(message)(Vg_DebugMsg, "%sdSYM directory %s; consider using " "--dsymutil=yes\n", VG_(clo_verbosity) > 1 ? " " : "", dsymfilename ? "has wrong UUID" : "is missing"); goto success; } /* Run dsymutil */ { Int r; HChar* dsymutil = "/usr/bin/dsymutil "; HChar* cmd = ML_(dinfo_zalloc)( "di.readmacho.tmp1", VG_(strlen)(dsymutil) + VG_(strlen)(di->filename) + 30 /* misc */ ); VG_(strcpy)(cmd, dsymutil); if (0) VG_(strcat)(cmd, "--verbose "); VG_(strcat)(cmd, di->filename); VG_(message)(Vg_DebugMsg, "run: %s\n", cmd); r = VG_(system)( cmd ); if (r) VG_(message)(Vg_DebugMsg, "run: %s FAILED\n", dsymutil); ML_(dinfo_free)(cmd); dsymfilename = find_separate_debug_file(di->filename); } /* Try again to load it. */ if (dsymfilename) { Bool valid; if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, " dsyms= %s\n", dsymfilename); ok = map_image_aboard( di, &iid, dsymfilename ); if (!ok) goto fail; /* check it has the right uuid. */ vg_assert(have_uuid); valid = iid.macho_img && iid.macho_img_szB > 0 && check_uuid_matches( (Addr)iid.macho_img, iid.macho_img_szB, uuid ); if (!valid) { if (VG_(clo_verbosity) > 0) { VG_(message)(Vg_DebugMsg, "WARNING: did not find expected UUID %02X%02X%02X%02X" "-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X" " in dSYM dir\n", (UInt)uuid[0], (UInt)uuid[1], (UInt)uuid[2], (UInt)uuid[3], (UInt)uuid[4], (UInt)uuid[5], (UInt)uuid[6], (UInt)uuid[7], (UInt)uuid[8], (UInt)uuid[9], (UInt)uuid[10], (UInt)uuid[11], (UInt)uuid[12], (UInt)uuid[13], (UInt)uuid[14], (UInt)uuid[15] ); VG_(message)(Vg_DebugMsg, "WARNING: for %s\n", di->filename); } unmap_image( &iid ); /* unmap_image zeroes the fields, so the following test makes sense. */ goto fail; } } /* Right. Finally we have our best try at the dwarf image, so go on to reading stuff out of it. */ read_the_dwarf: if (iid.macho_img && iid.macho_img_szB > 0) { UChar* debug_info_img = NULL; Word debug_info_sz; UChar* debug_abbv_img; Word debug_abbv_sz; UChar* debug_line_img; Word debug_line_sz; UChar* debug_str_img; Word debug_str_sz; UChar* debug_ranges_img; Word debug_ranges_sz; UChar* debug_loc_img; Word debug_loc_sz; UChar* debug_name_img; Word debug_name_sz; debug_info_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_info", &debug_info_sz); debug_abbv_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_abbrev", &debug_abbv_sz); debug_line_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_line", &debug_line_sz); debug_str_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_str", &debug_str_sz); debug_ranges_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_ranges", &debug_ranges_sz); debug_loc_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_loc", &debug_loc_sz); debug_name_img = getsectdata(iid.macho_img, iid.macho_img_szB, "__DWARF", "__debug_pubnames", &debug_name_sz); if (debug_info_img) { if (VG_(clo_verbosity) > 1) { if (0) VG_(message)(Vg_DebugMsg, "Reading dwarf3 for %s (%#lx) from %s" " (%ld %ld %ld %ld %ld %ld)\n", di->filename, di->text_avma, dsymfilename, debug_info_sz, debug_abbv_sz, debug_line_sz, debug_str_sz, debug_ranges_sz, debug_loc_sz ); VG_(message)(Vg_DebugMsg, " reading dwarf3 from dsyms file\n"); } /* The old reader: line numbers and unwind info only */ ML_(read_debuginfo_dwarf3) ( di, debug_info_img, debug_info_sz, debug_abbv_img, debug_abbv_sz, debug_line_img, debug_line_sz, debug_str_img, debug_str_sz ); /* The new reader: read the DIEs in .debug_info to acquire information on variable types and locations. But only if the tool asks for it, or the user requests it on the command line. */ if (VG_(needs).var_info /* the tool requires it */ || VG_(clo_read_var_info) /* the user asked for it */) { ML_(new_dwarf3_reader)( di, debug_info_img, debug_info_sz, debug_abbv_img, debug_abbv_sz, debug_line_img, debug_line_sz, debug_str_img, debug_str_sz, debug_ranges_img, debug_ranges_sz, debug_loc_img, debug_loc_sz ); } } } if (dsymfilename) ML_(dinfo_free)(dsymfilename); success: if (ii.img) unmap_image(&ii); if (iid.img) unmap_image(&iid); return True; /* NOTREACHED */ fail: ML_(symerr)(di, True, "Error reading Mach-O object."); if (ii.img) unmap_image(&ii); if (iid.img) unmap_image(&iid); return False; }