Exemple #1
0
        public void EnsureAllEntriesHaveSize()
        {
            int count = Count;

#if DEBUG
            // Debug support
            int x = 0;
            if (x != 0)
            {
                string line = string.Empty;
                for (int i = 0; i < count; i++)
                {
                    GenericSymbol entry = iEntries[i];
                    line = i.ToString("d8") + "   [" + entry.Address.ToString("x8") + "-" + entry.EndAddress.ToString("x8") + "] " + entry.Symbol.ToString();
                    System.Diagnostics.Debug.WriteLine(line);
                }
            }
#endif

            // Now go through the entries and update their sizes (if they don't have one)
            for (int i = 1; i < count; i++)
            {
                GenericSymbol entry         = iEntries[i];
                GenericSymbol previousEntry = iEntries[i - 1];
                //
                if (previousEntry.Size == 0)
                {
                    long calculatedPreviousEntrySize = (entry.Address - previousEntry.Address) - 1;
                    if (calculatedPreviousEntrySize > 0)
                    {
                        previousEntry.Size = calculatedPreviousEntrySize;
                    }
                }
            }
        }
Exemple #2
0
        public GenericSymbol EntryByAddress(long aAddress)
        {
            GenericSymbolCollection collection = null;
            GenericSymbol           ret        = EntryByAddress(aAddress, out collection);

            return(ret);
        }
Exemple #3
0
        public override void Add(GenericSymbolEngine aEngine, GenericSymbol aSymbol)
        {
            // We don't take data symbols, just code
            MapSymbol symbol = (MapSymbol)aSymbol;

            MapSymbol.TType type = symbol.Type;

            if (type == MapSymbol.TType.EThumbCode || type == MapSymbol.TType.EARMCode)
            {
                // Don't take code entries with no size
                if (aSymbol.Size > 0)
                {
                    // Make sure we remove the null symbol if this is the first 'valid' symbol for
                    // the collection.
                    if (Count == 1 && this[0].IsUnknownSymbol)
                    {
                        RemoveAt(0);
                    }

                    iEntries.Add(aSymbol);
                }
                else
                {
#if TRACE
                    System.Diagnostics.Debug.WriteLine("Discarding zero size entry: " + aSymbol.ToString());
#endif
                }
            }
        }
        private bool Parser_CollectionCompleted(SymbolsForBinary aCollection)
        {
            // Check whether the collection contains any item. If it doesn't, ditch it.
            // Remove empty collections or sort completed ones.
            bool takeCollection = false;
            int  count          = aCollection.Count;

            if (count > 0)
            {
                // Check whether the collection contains at least 2 symbols, and if not
                // does the one and only symbol just have a length of zero?
                if (count == 1)
                {
                    GenericSymbol symbol = aCollection.FirstSymbol;
                    takeCollection = (symbol.Size > 0) || symbol.IsUnknownSymbol;
                }
                else
                {
                    takeCollection = true;
                }
            }

            // If its okay to take the collection, let's sort it and activate if necessary.
            if (takeCollection)
            {
#if INSPECT_SYMBOL_DATA
                using (StreamWriter writer = new StreamWriter(@"C:\Temp\OldSymbols\" + Path.GetFileName(aCollection.HostBinaryFileName) + ".symbol"))
                {
                    aCollection.WriteToStream(writer);
                }
#endif
                // All the symbol collections - whether they are loaded or idle.
                iAllSymbols.Add(aCollection);

                // Then put the collection in the correct container depending on
                // activation type.
                if (iActivationType == TActivationType.EImmediate)
                {
                    aCollection.Sort();
                    iActivatedSymbols.Add(aCollection);
                    //
                    iRange.UpdateMin(aCollection.AddressRangeStart);
                    iRange.UpdateMax(aCollection.AddressRangeEnd);
                }
                else if (iActivationType == TActivationType.EOnDemand)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(SortCollection), aCollection);
                    iIdleSymbols.Add(aCollection);
                }
            }
            else
            {
                //System.Diagnostics.Debug.WriteLine( "Discarded Symbol Collection: " + aCollection.TargetBinary );
                //System.Diagnostics.Debug.WriteLine( " " );
            }

            iCurrentBinary = null;
            return(SymbolFileParser.KCollectionCompletedAndContinueParsing);
        }
        private GenericSymbol SymbolForAddress(uint aAddress, SymbolManager aSymbolManager)
        {
            System.Diagnostics.Debug.Assert(aSymbolManager != null);

            // Try and find a matching collection / symbol entry
            GenericSymbolCollection collection;
            GenericSymbol           symbol = aSymbolManager.EntryByAddress(aAddress, out collection);

            return(symbol);
        }
        public GenericExplicitInterfaceImplementationProperty(Property property, GenericSymbol gen, string adapter, Dictionary <string, string> mappings, CodeGenerationOptions opt)
        {
            Name = property.AdjustedName;

            PropertyType = new TypeReferenceWriter(opt.GetTypeReferenceName(property));
            ExplicitInterfaceImplementation = opt.GetOutputName(gen.Gen.FullName);

            Comments.Add($"// This method is explicitly implemented as a member of an instantiated {gen.FullName}");

            if (property.Getter != null)
            {
                HasGet = true;

                if (gen.Gen.IsGeneratable)
                {
                    GetterComments.Add($"// Metadata.xml XPath method reference: path=\"{gen.Gen.MetadataXPathReference}/method[@name='{property.Getter.JavaName}'{property.Getter.Parameters.GetMethodXPathPredicate ()}]\"");
                }
                if (property.Getter.GenericArguments != null && property.Getter.GenericArguments.Any())
                {
                    GetterAttributes.Add(new CustomAttr(property.Getter.GenericArguments.ToGeneratedAttributeString()));
                }

                SourceWriterExtensions.AddSupportedOSPlatform(GetterAttributes, property.Getter, opt);

                GetterAttributes.Add(new RegisterAttr(property.Getter.JavaName, property.Getter.JniSignature, property.Getter.ConnectorName + ":" + property.Getter.GetAdapterName(opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString()));

                GetBody.Add($"return {property.Name};");
            }

            if (property.Setter != null)
            {
                HasSet = true;

                if (gen.Gen.IsGeneratable)
                {
                    SetterComments.Add($"// Metadata.xml XPath method reference: path=\"{gen.Gen.MetadataXPathReference}/method[@name='{property.Setter.JavaName}'{property.Setter.Parameters.GetMethodXPathPredicate ()}]\"");
                }
                if (property.Setter.GenericArguments != null && property.Setter.GenericArguments.Any())
                {
                    SetterAttributes.Add(new CustomAttr(property.Setter.GenericArguments.ToGeneratedAttributeString()));
                }

                SourceWriterExtensions.AddSupportedOSPlatform(SetterAttributes, property.Setter, opt);

                SetterAttributes.Add(new RegisterAttr(property.Setter.JavaName, property.Setter.JniSignature, property.Setter.ConnectorName + ":" + property.Setter.GetAdapterName(opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString()));

                // Temporarily rename the parameter to "value"
                var pname = property.Setter.Parameters [0].Name;
                property.Setter.Parameters [0].Name = "value";
                SetBody.Add($"{property.Name} = {property.Setter.Parameters.GetGenericCall (opt, mappings)};");
                property.Setter.Parameters [0].Name = pname;
            }
        }
        private bool LastSymbolSharesSameAddressRange(GenericSymbol aSymbol)
        {
            bool ret = false;
            //
            GenericSymbol last = InternalLastSymbol;

            if (last != null && last.FallsWithinDomain(aSymbol.Address))
            {
                ret = true;
            }
            //
            return(ret);
        }
        private bool TakeEntry(GenericSymbol aSymbol, bool aAllowNonRomSymbols)
        {
            bool take = IsEntryReallyData(aSymbol);

            if (!take)
            {
                // We'll take the entry if all we have at the moment is
                // the default entry or then no entries at all.
                if (OnlyContainsDefaultSymbol || iEntries.Count == 0)
                {
                    take = true;
                }
                else
                {
                    GenericSymbol last = LastSymbol;
                    System.Diagnostics.Debug.Assert(last != null);
                    GenericSymbol.TAddressType addressType = aSymbol.AddressType;
                    //
                    switch (addressType)
                    {
                    // We always take these...
                    case GenericSymbol.TAddressType.EAddressTypeROMSymbol:
                        take = true;
                        break;

                    // We sometimes take these...
                    case GenericSymbol.TAddressType.EAddressTypeRAMSymbol:
                        take = aAllowNonRomSymbols;
                        break;

                    case GenericSymbol.TAddressType.EAddressTypeLabel:
                        take = true;
                        break;

                    case GenericSymbol.TAddressType.EAddressTypeSubObject:
                        take = (aSymbol.Size > 0) || (last.EndAddress < aSymbol.Address);
                        break;

                    // We never take these
                    default:
                    case GenericSymbol.TAddressType.EAddressTypeReadOnlySymbol:
                    case GenericSymbol.TAddressType.EAddressTypeUnknown:
                    case GenericSymbol.TAddressType.EAddressTypeKernelGlobalVariable:
                        break;
                    }
                }
            }
            //
            return(take);
        }
Exemple #9
0
        public GenericExplicitInterfaceImplementationMethod(Method method, GenericSymbol gen, CodeGenerationOptions opt)
        {
            this.method = method;
            this.opt    = opt;
            this.gen    = gen;

            Name = method.Name;

            ReturnType = new TypeReferenceWriter(opt.GetTypeReferenceName(method.RetVal));
            ExplicitInterfaceImplementation = opt.GetOutputName(gen.Gen.FullName);

            Comments.Add($"// This method is explicitly implemented as a member of an instantiated {gen.FullName}");

            SourceWriterExtensions.AddMethodCustomAttributes(Attributes, method);
            this.AddMethodParameters(method.Parameters, opt);
        }
        private void DoAddEntry(GenericSymbol aSymbol)
        {
            // Make sure we remove the null symbol if this is the first 'valid' symbol for
            // the collection.
            if (OnlyContainsDefaultSymbol)
            {
                RemoveAt(0);
            }

            // If the symbol has no size, then try to work it out next time around
            if (aSymbol.Size == 0)
            {
                iFlags |= TFlags.EFlagsCalculateLengthOfPreviousSymbol;
            }

            // Save it
            iEntries.Add(aSymbol);
        }
        private bool IsEntryReallyData(GenericSymbol aSymbol)
        {
            bool isData = false;

            // Check to see if its from a data=<something> IBY entry...
            string baseName   = Path.GetFileName(HostBinaryFileName).ToLower();
            string symbolName = aSymbol.Symbol.ToLower();

            if (symbolName == baseName && aSymbol.Size == 0)
            {
                // Its from a data entry
                isData = true;

                // Data entries only consist of a single symbol (the data itself)
                iFlags |= TFlags.EFlagsDisallowFurtherSymbolsForCollection;
            }

            return(isData);
        }
        public override GenericSymbol SymbolForAddress(long aAddress)
        {
#if DEBUG
            int x = 0;
            if (x > 0)
            {
                base.Dump(aAddress);
            }
#endif
            GenericSymbol ret = null;
            //
            AddressFindingComparer comparer = new AddressFindingComparer();
            SymbolSymbol           temp     = SymbolSymbol.NewUnknown((uint)aAddress, 0, string.Empty);
            int pos = iEntries.BinarySearch(temp, comparer);
            if (pos >= 0 && pos < iEntries.Count)
            {
                ret = iEntries[pos];
                System.Diagnostics.Debug.Assert(ret.AddressRange.Contains(aAddress));
            }
            //
            return(ret);
        }
Exemple #13
0
        public override GenericSymbol SymbolForAddress(long aAddress)
        {
#if DEBUG
            int x = 0;
            if (x > 0)
            {
                base.Dump(aAddress);
            }
#endif
            GenericSymbol ret = null;
            //
            foreach (GenericSymbol symbol in this)
            {
                if (symbol.FallsWithinDomain(aAddress))
                {
                    ret = symbol;
                    break;
                }
            }
            //
            return(ret);
        }
Exemple #14
0
        private static GenericSymbol TryParseGeneric(string name, string assembly)
        {
            if (!name.EndsWith("]"))
            {
                return(null);
            }
            var iLeft = name.IndexOf('[');

            if (iLeft <= 0)
            {
                throw new ILTypeLoadException(name);
            }

            var element = ParseDirect(name.Substring(0, iLeft), assembly);
            var type    = new GenericSymbol(element);
            var balance = 0;
            var start   = iLeft + 1;

            for (int i = start; i < name.Length - 1; i++)
            {
                var ch = name[i];
                if (ch == '[')
                {
                    balance++;
                }
                else if (ch == ']')
                {
                    balance--;
                }
                else if (ch == ',' && balance == 0)
                {
                    type.GenericParameters.Add(ParseFull(name.Substring(start, i - start)));
                    start = i + 1;
                }
            }

            type.GenericParameters.Add(ParseFull(name.Substring(start, name.Length - start - 1)));
            return(type);
        }
Exemple #15
0
        public GenericSymbol EntryByAddress(long aAddress, out GenericSymbolCollection aCollection)
        {
            aCollection = null;
            GenericSymbolCollection rofsCollection = null;

            // First check with the map file engine to see if there is a loaded
            // code segment entry that matches the specified address.
            GenericSymbol ret = iEngineROFS.EntryByAddress(aAddress, ref rofsCollection);

            //
            if (ret == null)
            {
                GenericSymbolCollection romCollection = null;
                ret = iEngineROM.EntryByAddress(aAddress, ref romCollection);

                // Decide which collection to return in the case that
                // a) we found a matching symbol, or
                // b) when we didn't.
                if (ret == null && rofsCollection != null)
                {
                    // ROFS wins by default if we found something inside the ROFS engine...
                    aCollection = rofsCollection;
                }
                else
                {
                    // Otherwise we'll use the ROM collection (irrespective of whether something
                    // was found or not)
                    aCollection = romCollection;
                }
            }
            else
            {
                // ROFS wins
                aCollection = rofsCollection;
            }

            return(ret);
        }
        private void UpdateCollectionBaseAddressBasedUponFirstSymbol(GenericSymbol aSymbol)
        {
            // If we are not processing the first Symbol in the collection, then we
            // can rely on the base address being set. Otherwise, we are
            // defining the base address itself.
            if (!((iFlags & TFlags.EFlagsHaveSeenFirstSymbol) == TFlags.EFlagsHaveSeenFirstSymbol))
            {
                // Set collection base address to symbol starting address
                BaseAddress = aSymbol.Address;

                // Since this is the first symbol in the collection, and we're going to use
                // its address as the offset (base) address for the entire collection,
                // if we just set the collection base address to the symbol's address and
                // the continue, this entry will be double offset (the new offset for the collection
                // + the offset of the symbol itself). We must therefore set the symbol's offset
                // address to zero.
                SymbolSymbol realSymbol = (SymbolSymbol)aSymbol;
                realSymbol.ResetOffsetAddress(0);

                // Make sure we set a flag so that we don't attempt to do this again.
                iFlags |= TFlags.EFlagsHaveSeenFirstSymbol;
            }
        }
        internal void Add(GenericSymbolEngine aEngine, GenericSymbol aSymbol, bool aAllowNonRomSymbols)
        {
            System.Diagnostics.Debug.Assert(aSymbol is SymbolSymbol);

            // Check for Image$$ER_RO$$Base or Image$$ER_RO$$Limit.
            // This symbol is emitted for user-side code and can be used to work around some maksym problems.
            string symbolName = aSymbol.Symbol;

            if (symbolName.StartsWith(KSymbolNameImageBaseOrLimitPrefix))
            {
                bool isBase = symbolName.Contains("Base");

                // If we've just seen the base entry, but we already have some stored symbols, then
                // probably this is a maksym problem that we must try to work around.
                if (isBase)
                {
                    int count = iEntries.Count;
                    if (count > 0 && !iEntries[0].IsUnknownSymbol)
                    {
                        // Discard all the entries we've seen so far because most likely
                        // they are invalid.
                        System.Diagnostics.Debug.WriteLine(string.Format("Discarding {0} invalid symbols for library: {1}", count, base.HostBinaryFileName));
                        iEntries.Clear();

                        // At this point, we need to reset the base address because any symbols that have gone
                        // before are invalid.
                        iFlags &= ~TFlags.EFlagsHaveSeenFirstSymbol;
                    }
                }
                else
                {
                    // Reached the limit - stop storing symbols at this point as everything else is likely data.
                    iFlags |= TFlags.EFlagsDisallowFurtherSymbolsForCollection;
                }
            }

            // Don't save the entry if we're in disabled state.
            bool newAdditionsDisabled = (iFlags & TFlags.EFlagsDisallowFurtherSymbolsForCollection) == TFlags.EFlagsDisallowFurtherSymbolsForCollection;

            if (!newAdditionsDisabled)
            {
                // Whether or not we keep the entry
                bool addEntry = false;

                // Set base address
                UpdateCollectionBaseAddressBasedUponFirstSymbol(aSymbol);

                GenericSymbol lastSymbol = InternalLastSymbol;
                if (lastSymbol != null)
                {
                    if (lastSymbol.Address > aSymbol.Address)
                    {
                        // Work-around for maksym problem where it fails to parse some MAP files correctly.
                    }
                    else
                    {
                        // If we have a last symbol, and it's address is prior to that of the new symbol, we can
                        // try to update the last symbol's size (if it needs it updating - the method will check that).
                        UpdateLengthOfPreviousSymbol(aSymbol);

                        // Check to see if we already have a symbol within this address range
                        bool overlappingSymbol = LastSymbolSharesSameAddressRange(aSymbol);
                        if (overlappingSymbol)
                        {
                            // They overlap - which one do we keep?
                            addEntry = FilterOutCommonAddressEntry(lastSymbol, aSymbol);
                        }
                        else
                        {
                            addEntry = TakeEntry(aSymbol, aAllowNonRomSymbols);
                        }
                    }
                }
                else
                {
                    addEntry = TakeEntry(aSymbol, aAllowNonRomSymbols);
                }

                // If we need to keep the symbol, then save it now...
                if (addEntry)
                {
                    DoAddEntry(aSymbol);
                }
            }
        }
        private bool FilterOutCommonAddressEntry(GenericSymbol aLast, GenericSymbol aNew)
        {
            bool acceptNew = false;

            //
            if (aLast.IsUnknownSymbol)
            {
                // Always discard the unknown symbol in preference of anything better
                iEntries.Remove(aLast);
                acceptNew = true;
            }
            else if (aNew.Size > 0)
            {
                if (aLast.Size == 0)
                {
                    // New is 'better' because it contains proper sizing information
                    iEntries.Remove(aLast);
                    acceptNew = true;
                }
                else if (aLast.Size < aNew.Size)
                {
                    // New is 'better' because it is bigger
                    iEntries.Remove(aLast);
                    acceptNew = true;
                }
                else if (aLast.Size == aNew.Size)
                {
                    // Both the same size. Take symbols over everything else.
                    if (aNew.IsSymbol && !aLast.IsSymbol)
                    {
                        // Keep the symbol (new)
                        iEntries.Remove(aLast);
                        acceptNew = true;
                    }
                    else if (!aNew.IsSymbol && aLast.IsSymbol)
                    {
                        // Keep the symbol (last)
                        acceptNew = false;
                    }
                    else
                    {
                        // Take higher priority...
                        if (aNew.AddressType > aLast.AddressType)
                        {
                            iEntries.Remove(aLast);
                            acceptNew = true;
                        }
                        else
                        {
                            acceptNew = false;
                        }
                    }
                }
            }
            else if (aLast.Size > 0)
            {
                // Last is 'better' because the new entry doesn't have any size
                acceptNew = false;
            }
            else if (aLast.Size == 0 && aNew.Size == 0)
            {
                // Both entries have no size and the same address. We cannot
                // accept both, therefore we make an arbitrary decision about
                // which to keep.
                if (aLast.IsSubObject && !aNew.IsSubObject)
                {
                    // Discard the sub object (last)
                    iEntries.Remove(aLast);
                    acceptNew = true;
                }
                else if (aNew.IsSubObject && !aLast.IsSubObject)
                {
                    // Discard the sub object (new)
                    acceptNew = false;
                }
                else if (aNew.IsSymbol && !aLast.IsSymbol)
                {
                    // Keep the symbol (new)
                    iEntries.Remove(aLast);
                    acceptNew = true;
                }
                else if (!aNew.IsSymbol && aLast.IsSymbol)
                {
                    // Keep the symbol (last)
                    acceptNew = false;
                }
                else
                {
                    // Couldn't make a good decision. Junk the new entry
                    acceptNew = false;
                }
            }
            //
            return(acceptNew);
        }
        private void UpdateLengthOfPreviousSymbol(GenericSymbol aNewSymbol)
        {
            bool clearFlag = false;

            //
            if ((iFlags & TFlags.EFlagsCalculateLengthOfPreviousSymbol) == TFlags.EFlagsCalculateLengthOfPreviousSymbol)
            {
                // Must have some existing symbol.
                System.Diagnostics.Debug.Assert(Count > 0);

                // Last symbol must have bad size?
                GenericSymbol previousSymbol = InternalLastSymbol;
                System.Diagnostics.Debug.Assert(previousSymbol.Size == 0);

                // The new symbol must be exactly the same address as the last symbol
                // (in which case, the new symbol must have a valid size or else we're
                // unable to do anything sensible with it)
                //
                // OR
                //
                // The new symbol must be after the last symbol. It cannot be before.
                System.Diagnostics.Debug.Assert(aNewSymbol.Address >= previousSymbol.Address);
                if (aNewSymbol.Address == previousSymbol.Address)
                {
                    if (aNewSymbol.Size > 0)
                    {
                        // Okay, the new symbol has a valid size, the old one didn't.
                        clearFlag           = true;
                        previousSymbol.Size = aNewSymbol.Size;
                    }
                    else
                    {
                        // Hmm, neither the last or new symbol have a valid size.
                        // Nothing we can do in this case...
                    }
                }
                else
                {
                    // Need to work out the length of the previous symbol by comparing the
                    // address of this symbol against it.
                    //
                    // Only do this if the region type hasn't changed.
                    MemoryModel.TMemoryModelRegion previousType = MemoryModel.RegionByAddress(previousSymbol.Address, aNewSymbol.MemoryModelType);
                    MemoryModel.TMemoryModelRegion regionType   = MemoryModel.RegionByAddress(aNewSymbol.Address, aNewSymbol.MemoryModelType);
                    if (regionType == previousType)
                    {
                        // If this new symbol and the old symbol have the same address, then
                        // also check the size of the previous symbol. If it was zero, then discard it
                        // and keep this new entry. Otherwise, discard this new one instead.
                        long delta = aNewSymbol.Address - previousSymbol.Address;
                        if (delta > 1)
                        {
                            // It's okay, this symbol had a later address than the last one
                            // This is normal.
                            previousSymbol.Size = delta;
                        }
                        else
                        {
                            // This is not good. Two symbols both have the same address.
                            iEntries.Remove(previousSymbol);
                        }
                    }

                    clearFlag = true;
                }
            }

            if (clearFlag)
            {
                iFlags &= ~TFlags.EFlagsCalculateLengthOfPreviousSymbol;
            }
        }
 public override void Remove(GenericSymbol aSymbol)
 {
     iEntries.Remove(aSymbol);
 }
 public override void Add(GenericSymbolEngine aEngine, GenericSymbol aSymbol)
 {
     Add(aEngine, aSymbol, true);
 }