private void BuildSymbolLookup() { var sw = System.Diagnostics.Stopwatch.StartNew(); uint totalSymbols = 0; // build information on all loaded images mImages = new ImageSymbolInfo[_dyld_image_count()]; for (uint i = 0; i < mImages.Length; i++) { GetImageSymbolInfo(i, ref mImages[i]); totalSymbols += mImages[i].SymbolTable.nsyms + (uint)SpecialSymbol.Total; } // create symbol lookup table mSymbolCount = 0; mSymbolAddressTable = new Address[totalSymbols]; mSymbolIdTable = new int[totalSymbols]; // add symbol info from all images for (uint i = 0; i < mImages.Length; i++) { // int count = mSymbolCount; AddImageSymbols(ref mImages[i]); AddImageSectionsAsSymbols(ref mImages[i]); // Console.WriteLine("Telemetry: Image[{0,3}] Symbols:{1,6} Name:{2}", i, mSymbolCount - count, mImages[i].Name); } // sort symbols by address Array.Sort(mSymbolAddressTable, mSymbolIdTable, 0, mSymbolCount); Console.WriteLine("Telemetry: Built symbol table (SymbolCount:{0} Time:{1})", mSymbolCount, sw.Elapsed); }
private unsafe void AddImageSectionsAsSymbols(ref ImageSymbolInfo image) { // get image header IntPtr ptr = _dyld_get_image_header(image.Index); var hdr = (mach_header)Marshal.PtrToStructure(ptr, typeof(mach_header)); // check header magic number if (hdr.magic != MH_MAGIC) { // unsupported header type return; } // get pointer to first load command ptr += sizeof(mach_header); // parse image load commands for (int j = 0; j < hdr.ncmds; j++) { // get load_command var lc = (load_command)Marshal.PtrToStructure(ptr, typeof(load_command)); if (lc.cmd == LC_SEGMENT) { var segment = (segment_command)Marshal.PtrToStructure(ptr, typeof(segment_command)); // get segment start and end Address segmentStart = (Address)(image.Slide + (int)segment.vmaddr); Address segmentEnd = segmentStart + segment.filesize; // mark the start and end of this image using special symbols AddSymbol(segmentStart, image.Index, image.SymbolTable.nsyms + (uint)SpecialSymbol.SegmentStart); AddSymbol(segmentEnd, image.Index, image.SymbolTable.nsyms + (uint)SpecialSymbol.SegmentEnd); } // next command ptr += (int)lc.cmdsize; } }
private unsafe void GetImageSymbolInfo(uint imageIndex, ref ImageSymbolInfo image) { // get image index image.Index = imageIndex; // get image name image.FullName = Marshal.PtrToStringAnsi(_dyld_get_image_name(imageIndex)); /// get short name image.Name = System.IO.Path.GetFileNameWithoutExtension(image.FullName); // get image 'slide' image.Slide = _dyld_get_image_vmaddr_slide(imageIndex); // get image header IntPtr ptr = _dyld_get_image_header(imageIndex); var hdr = (mach_header)Marshal.PtrToStructure(ptr, typeof(mach_header)); // check header magic number if (hdr.magic != MH_MAGIC) { // unsupported header type return; } // get pointer to first load command ptr += sizeof(mach_header); // parse image load commands for (int j = 0; j < hdr.ncmds; j++) { // get load_command var lc = (load_command)Marshal.PtrToStructure(ptr, typeof(load_command)); if (lc.cmd == LC_SEGMENT) { var segment = (segment_command)Marshal.PtrToStructure(ptr, typeof(segment_command)); // find linkedit segment if (segment.segname.Contains("LINKEDIT")) { image.LinkEdit = segment; } } else if (lc.cmd == LC_SYMTAB) { // symtab command image.SymbolTable = (symtab_command)Marshal.PtrToStructure(ptr, typeof(symtab_command)); } // next command ptr += (int)lc.cmdsize; } }
private unsafe void AddImageSymbols(ref ImageSymbolInfo image) { IntPtr baseaddr = image.Slide + (int)(image.LinkEdit.vmaddr - image.LinkEdit.fileoff); IntPtr symaddr = baseaddr + (int)image.SymbolTable.symoff; for (int symbolIndex = 0; symbolIndex < image.SymbolTable.nsyms; symbolIndex++) { nlist n = (nlist)Marshal.PtrToStructure(symaddr + symbolIndex * sizeof(nlist), typeof(nlist)); // see if this is a valid named symbol using magic flags if ((n.n_value != 0) && (n.n_type & 0xE0) == 0 && (n.n_type & 0xE) == 0xE) { // get address of symbol IntPtr address = image.Slide + (int)n.n_value; AddSymbol((Address)address, image.Index, (uint)symbolIndex); } } }
private void BuildSymbolLookup() { var sw = System.Diagnostics.Stopwatch.StartNew(); uint totalSymbols = 0; // build information on all loaded images mImages = new ImageSymbolInfo[_dyld_image_count ()]; for (uint i=0; i < mImages.Length; i++) { GetImageSymbolInfo(i, ref mImages[i]); totalSymbols += mImages[i].SymbolTable.nsyms + (uint)SpecialSymbol.Total; } // create symbol lookup table mSymbolCount = 0; mSymbolAddressTable = new Address[totalSymbols]; mSymbolIdTable = new int[totalSymbols]; // add symbol info from all images for (uint i=0; i < mImages.Length; i++) { // int count = mSymbolCount; AddImageSymbols(ref mImages[i]); AddImageSectionsAsSymbols(ref mImages[i]); // Console.WriteLine("Telemetry: Image[{0,3}] Symbols:{1,6} Name:{2}", i, mSymbolCount - count, mImages[i].Name); } // sort symbols by address Array.Sort (mSymbolAddressTable, mSymbolIdTable, 0, mSymbolCount); Console.WriteLine("Telemetry: Built symbol table (SymbolCount:{0} Time:{1})", mSymbolCount, sw.Elapsed); }
private unsafe void GetImageSymbolInfo(uint imageIndex, ref ImageSymbolInfo image) { // get image index image.Index = imageIndex; // get image name image.FullName = Marshal.PtrToStringAnsi (_dyld_get_image_name(imageIndex)); /// get short name image.Name = System.IO.Path.GetFileNameWithoutExtension(image.FullName); // get image 'slide' image.Slide = _dyld_get_image_vmaddr_slide (imageIndex); // get image header IntPtr ptr = _dyld_get_image_header (imageIndex); var hdr = (mach_header)Marshal.PtrToStructure (ptr, typeof(mach_header)); // check header magic number if (hdr.magic != MH_MAGIC) { // unsupported header type return; } // get pointer to first load command ptr += sizeof(mach_header); // parse image load commands for (int j=0; j < hdr.ncmds; j++) { // get load_command var lc = (load_command)Marshal.PtrToStructure (ptr, typeof(load_command)); if (lc.cmd == LC_SEGMENT) { var segment = (segment_command)Marshal.PtrToStructure (ptr, typeof(segment_command)); // find linkedit segment if (segment.segname.Contains ("LINKEDIT")) { image.LinkEdit = segment; } } else if (lc.cmd == LC_SYMTAB) { // symtab command image.SymbolTable = (symtab_command)Marshal.PtrToStructure (ptr, typeof(symtab_command)); } // next command ptr += (int)lc.cmdsize; } }
private unsafe void AddImageSectionsAsSymbols(ref ImageSymbolInfo image) { // get image header IntPtr ptr = _dyld_get_image_header (image.Index); var hdr = (mach_header)Marshal.PtrToStructure (ptr, typeof(mach_header)); // check header magic number if (hdr.magic != MH_MAGIC) { // unsupported header type return; } // get pointer to first load command ptr += sizeof(mach_header); // parse image load commands for (int j=0; j < hdr.ncmds; j++) { // get load_command var lc = (load_command)Marshal.PtrToStructure (ptr, typeof(load_command)); if (lc.cmd == LC_SEGMENT) { var segment = (segment_command)Marshal.PtrToStructure (ptr, typeof(segment_command)); // get segment start and end Address segmentStart = (Address)(image.Slide + (int)segment.vmaddr); Address segmentEnd = segmentStart + segment.filesize; // mark the start and end of this image using special symbols AddSymbol(segmentStart, image.Index, image.SymbolTable.nsyms + (uint)SpecialSymbol.SegmentStart); AddSymbol(segmentEnd, image.Index, image.SymbolTable.nsyms + (uint)SpecialSymbol.SegmentEnd); } // next command ptr += (int)lc.cmdsize; } }
private unsafe void AddImageSymbols(ref ImageSymbolInfo image) { IntPtr baseaddr = image.Slide + (int)(image.LinkEdit.vmaddr - image.LinkEdit.fileoff); IntPtr symaddr = baseaddr + (int)image.SymbolTable.symoff; for (int symbolIndex=0; symbolIndex < image.SymbolTable.nsyms; symbolIndex++) { nlist n = (nlist)Marshal.PtrToStructure (symaddr + symbolIndex * sizeof(nlist), typeof(nlist)); // see if this is a valid named symbol using magic flags if ((n.n_value != 0) && (n.n_type&0xE0) == 0 && (n.n_type&0xE) == 0xE) { // get address of symbol IntPtr address = image.Slide + (int)n.n_value; AddSymbol((Address)address, image.Index, (uint)symbolIndex); } } }