// NOTE: might be nice to identify the symbol's origin, e.g. which platform // symbol file it was defined in. This could then be stored in a // DisplayList line, for benefit of the Info panel. /// <summary> /// Internal base-object constructor, called by other constructors. /// </summary> private DefSymbol(string label, int value, Source source, Type type) : base(label, value, source, type) { Debug.Assert(source == Source.Platform || source == Source.Project); Debug.Assert(type == Type.ExternalAddr || type == Type.Constant); Xrefs = new XrefSet(); }
/// <summary> /// Constructs a DefSymbol from an existing DefSymbol, with a different label. Use /// this to change the label while keeping everything else the same. /// </summary> /// <remarks> /// This can't be a simple Rename() function that uses a copy constructor because /// the label is in the base class. /// /// The Xrefs reference points to the actual XrefSet in the original. This is not /// ideal, but it's the easiest way to keep xrefs working across Lv de-duplication /// (you actually *want* xrefs added to copies to be held by the original). /// </remarks> /// <param name="defSym">Source DefSymbol.</param> /// <param name="label">Label to use.</param> public DefSymbol(DefSymbol defSym, string label) : this(label, defSym.Value, defSym.SymbolSource, defSym.SymbolType, defSym.LabelAnno, defSym.DataDescriptor.FormatSubType, defSym.DataDescriptor.Length, defSym.HasWidth, defSym.Comment, defSym.Direction, defSym.MultiMask, defSym.Tag) { Debug.Assert(SymbolSource == Source.Variable); Xrefs = defSym.Xrefs; }
/// <summary> /// Generates an auto-label with a prefix string based on the XrefSet. /// </summary> /// <param name="addr">Address that label will be applied to.</param> /// <param name="symbols">Symbol table, for uniqueness check.</param> /// <param name="xset">Cross-references for this location.</param> /// <returns>Newly-created, unique symbol.</returns> public static Symbol GenerateAnnotatedLabel(int addr, SymbolTable symbols, XrefSet xset, Style style) { Debug.Assert(xset != null); Debug.Assert(style != Style.Simple); RefTypes rtypes = RefTypes.None; foreach (XrefSet.Xref xr in xset) { switch (xr.Type) { case XrefSet.XrefType.SubCallOp: rtypes |= RefTypes.SubCall; break; case XrefSet.XrefType.BranchOp: rtypes |= RefTypes.Branch; break; case XrefSet.XrefType.RefFromData: rtypes |= RefTypes.DataRef; break; case XrefSet.XrefType.MemAccessOp: switch (xr.AccType) { case Asm65.OpDef.MemoryEffect.Read: rtypes |= RefTypes.Read; break; case Asm65.OpDef.MemoryEffect.Write: rtypes |= RefTypes.Write; break; case Asm65.OpDef.MemoryEffect.ReadModifyWrite: rtypes |= RefTypes.Read; rtypes |= RefTypes.Write; break; case Asm65.OpDef.MemoryEffect.None: case Asm65.OpDef.MemoryEffect.Unknown: break; default: Debug.Assert(false); break; } break; default: Debug.Assert(false); break; } } if (rtypes == RefTypes.None) { // unexpected Debug.Assert(false); return(GenerateUniqueForAddress(addr, symbols, "X_")); } StringBuilder sb = new StringBuilder(8); for (int i = 0; i < TAGS.Length; i++) { if (((int)rtypes & (1 << i)) != 0) { sb.Append(TAGS[i]); if (style == Style.Annotated) { break; } } } sb.Append('_'); return(GenerateUniqueForAddress(addr, symbols, sb.ToString())); }