/// <summary> /// Tries to get the innermost symbol containing the specified scalar. If no symbol contains the scalar the trial fails. /// </summary> /// <returns><c>true</c>, if the interval was found, <c>false</c> when such interval does not exist.</returns> /// <param name="scalar">Scalar.</param> /// <param name="interval">Found interval.</param> public bool TryGet(SymbolAddress scalar, out Symbol interval) { interval = default(Symbol); var marker = new MarkerSymbol(scalar); var index = Array.BinarySearch <Symbol>(symbols, marker, comparer); if (index < 0) { index = ~index; // we are behind last element or before 1st if (index == 0) { return(false); } // move back one element because search will always point to the 1st larger element than the marker index--; } /*** * We might be between two towers, that lie on the common ground (we will be between the top of the left tower and * before the base of the next one). `index` points to the left top symbol, we check if any enclosing symbol also contains the * scalar. If not, there is no such symbol (the common ground) and scalar just lies between two towers. If it exists scalar * is between two symbol lying on the same base. ****/ index = FindEnclosingInterval(index, scalar); if (index != NoEnclosingInterval) { interval = symbols[index]; return(true); } return(false); }
private void LoadELF <T>(ELF <T> elf, bool useVirtualAddress) where T : struct { if (!elf.TryGetSection(".symtab", out var symtabSection)) { return; } var thumb = elf.Machine == ELFSharp.ELF.Machine.ARM; var symtab = (SymbolTable <T>)symtabSection; var elfSymbols = symtab.Entries.Where(x => !armSpecificSymbolNames.Contains(x.Name)).Where(x => !excludedSymbolTypes.Contains(x.Type)) .Where(x => x.PointedSectionIndex != (uint)SpecialSectionIndex.Undefined).Select(x => new Symbol(x, thumb)); InsertSymbols(elfSymbols); EntryPoint = elf.GetEntryPoint(); FirstNotNullSectionAddress = elf.Sections .Where(x => x.Type != SectionType.Null && x.Flags.HasFlag(SectionFlags.Allocatable)) .Select(x => x.GetSectionPhysicalAddress()) .Cast <ulong?>() .Min(); var segments = elf.Segments.Where(x => x.Type == ELFSharp.ELF.Segments.SegmentType.Load).OfType <ELFSharp.ELF.Segments.Segment <T> >(); foreach (var segment in segments) { var loadAddress = useVirtualAddress ? segment.GetSegmentAddress() : segment.GetSegmentPhysicalAddress(); maxLoadAddress = SymbolAddress.Max(maxLoadAddress, loadAddress + segment.GetSegmentSize()); } }
/// <summary> /// Inserts one symbol into the lookup structure. /// </summary> /// <param name="symbol">Symbol.</param> public void InsertSymbol(Symbol symbol) { var symbolToAdd = GetUnique(symbol); symbols.Add(symbolToAdd); symbolsByName.Add(symbol.Name, symbol); maxLoadAddress = SymbolAddress.Max(maxLoadAddress, symbol.End); }
/// <summary> /// Tries to get the innermost symbol which contains the specified address. /// </summary> /// <returns><c>true</c>, if a symbol was found, <c>false</c> when no symbol contains specified address.</returns> /// <param name="offset">Offset.</param> /// <param name="symbol">Symbol.</param> public bool TryGetSymbolByAddress(SymbolAddress offset, out Symbol symbol) { if (offset > maxLoadAddress) { symbol = default(Symbol); return(false); } return(symbols.TryGet(offset, out symbol)); }
/// <summary> /// Gets the innermost symbol which contains the specified address. /// </summary> /// <returns>The symbol by address.</returns> /// <param name="offset">Offset.</param> public Symbol GetSymbolByAddress(SymbolAddress offset) { Symbol symbol; if (!TryGetSymbolByAddress(offset, out symbol)) { throw new KeyNotFoundException("No symbol for given address [" + offset + "] found."); } return(symbol); }
/// <summary> /// Checks if the given <paramref name="scalar"/> is enclosed by the one under <paramref name="index"/> or one of it's "parents". /// </summary> /// <returns>The enclosing interval index or NoEnclosingInterval.</returns> /// <param name="index">Index of the input interval.</param> /// <param name = "scalar"></param> private int FindEnclosingInterval(int index, SymbolAddress scalar) { var original = index; while (index != NoEnclosingInterval && !symbols[index].Contains(scalar)) { index = indexOfEnclosingInterval[index]; } // A special case when we hit after a 0-length symbol thas does not have any parent. // We do not need to check it in the loop, as such a symbol would never enclose other symbols. // This gives an approximate result. if (index == NoEnclosingInterval) { if (symbols[original].Start <= scalar && symbols[original].End == symbols[original].Start && (symbols.Length == original + 1 || symbols[original + 1].Start > scalar)) { index = original; } } return(index); }
/// <summary> /// Inserts a batch of symbols. /// </summary> /// <param name="symbols">Symbols.</param> public void InsertSymbols(IEnumerable <Symbol> symbols) { var symbolsToAdd = new List <Symbol>(); // deduplicate symbols foreach (var symbol in symbols) { symbolsToAdd.Add(GetUnique(symbol)); } // Add symbols to name map foreach (var symbolToAdd in symbolsToAdd) { AddSymbolToNameLookup(symbolToAdd); maxLoadAddress = SymbolAddress.Max(maxLoadAddress, symbolToAdd.End); } // Add symbols to interval set this.symbols.Add(symbolsToAdd); }
/// <summary> /// Inserts a new symbol with defined parameters into the lookup structure. /// </summary> /// <param name="name">Name.</param> /// <param name="start">Start.</param> /// <param name="size">Size.</param> /// <param name="type">SymbolType.</param> /// <param name="binding">Symbol binding</param> /// <param name="isThumb">If set to <c>true</c>, symbol is marked as a thumb symbol.</param> public void InsertSymbol(string name, SymbolAddress start, SymbolAddress size, SymbolType type = SymbolType.NotSpecified, SymbolBinding binding = SymbolBinding.Global, bool isThumb = false) { var symbol = new Symbol(start, start + size, name, type, binding, isThumb); InsertSymbol(symbol); }
public MarkerSymbol(SymbolAddress value) : base(value, MarkerComparer <SymbolAddress> .GetMarkerValue()) { }