public int LookupGlobalLabelValue(string name) { SyEntry entry = LookupGlobalSymbol(name); if (entry == null || entry.Kind != SymbolKind.Label) { return(-1); } return(entry.SymValue); }
public virtual void DefineCommSymbol(string name, int size, int align) { if (Pass > 1) { return; } if (LocalSymTable.ContainsKey(name)) { return; } if (size <= 0) { size = 1; } // round up alignment to a power of 2 int al = 1; while (al < align) { al <<= 1; } align = al; SyEntry newsym; if (!GlobalSymbols.TryGetValue(name, out newsym)) { newsym = new SyEntry(name, 0, size, align); GlobalSymbols[name] = newsym; } else if (newsym.Kind == SymbolKind.CommSymbol) { // combine new size and alignment with old values newsym.Size = size; newsym.Align = align; } // else ignore the .comm definition because it's // already defined as a normal label LocalSymTable[name] = newsym; }
public SyEntry LookupSymbol(string name, out bool isNewUnknown) { isNewUnknown = false; if (Char.IsDigit(name[0])) { return(LookupNumericLabel(name)); } SyEntry sy = null; if (LocalSymTable.TryGetValue(name, out sy)) { return(sy); } if (GlobalSymbols.TryGetValue(name, out sy)) { return(sy); } if (!UndefLocals.Contains(name)) { UndefLocals.Add(name); isNewUnknown = true; } return(null); }
public SyEntry DefineSymbol(string name, int lineNum, int value, SectionType section) { SyEntry sym; if (Pass > 1 && lineNum >= 0) { if (!LocalSymTable.TryGetValue(name, out sym)) { throw new AsmException("symbol {0} not found", name); } sym.SymValue = value; return(sym); } if (section != SectionType.None) { sym = new SyEntry(name, lineNum, section, 0, value); } else { sym = new SyEntry(name, lineNum, value); } LocalSymTable[name] = sym; return(sym); }
// apply relocation to the in-memory copy of the code section // addr: the run-time address of the location being relocated // offset: the offset within the object code section of the // location being relocated // section: an in-memory copy of the object code section // addend: a constant to add to the value of the relocation symbol // symbol: the relocation symbol whose value is to be added to // the location specified by addr and offset. // type: the type of relocation to be performed, as specified // in the Elf documentation (and as discovered by // inspection of Arm object code files). protected void performRelocation( uint addr, int offset, byte[] section, uint addend, ST symbol, uint type) { uint word = getInt32(section, offset); uint newWord = 0; string name = symbol.name; int val; // value of the symbol string symbolKind = "??"; SectionType st = SectionType.Unknown; if (!String.IsNullOrEmpty(name)) { bool isNewUnknown = false; SyEntry sym = af.LookupSymbol(name, out isNewUnknown); if (sym == null) { if (name == "__cs3_heap_start" || name == "_end") { // This is a temporary fixup; the proper solution would involve // reading loader script which defined __cs3_heap_start = _end. val = DataEnd; //af.DefineSymbol(name, -1, val-bssStart, SectionType.Bss); } //else if (name == "__cs3_heap_limit") // val = dataEnd + heapSize; else { if (isNewUnknown) { af.ParseError("reference to undefined external symbol {0}", name); } return; } } else { val = sym.SymValue; } } else { bool local = true; val = getSymbolValue(symbol, ref symbolKind, ref st, ref local); switch (st) { case SectionType.Text: val += TextStart; break; case SectionType.Data: val += DataStart; break; case SectionType.Bss: val += BssStart; break; default: Debug.WriteLine(String.Format( "- anon symbol, kind={0}, section type {1} ignored", symbolKind, st.ToString())); return; } } uint opnd; bool supported = true; switch (type) { case 0: return; case 2: // R_ARM_ABS32 newWord = (uint)(word + val + addend); break; case 1: // R_ARM_PC24 (used by gcc from Australia) case 27: // R_ARM_PLT32 (deprecated but used by CodeSourcery) case 28: // R_ARM_CALL (used by CodeSourcery) case 29: // R_ARM_JUMP24 (used by CodeSourcery) opnd = (uint)((word & 0x00ffffff) << 2); if ((opnd & 0x02000000) != 0) // sign extend? { opnd |= 0xFC000000; } opnd += (uint)(val + addend - addr); opnd = (uint)((opnd >> 2) & 0xFFFFFF); newWord = (uint)((word & 0xFF000000) | opnd); break; default: supported = false; break; } if (!supported || trace > 0) { Debug.WriteLine(String.Format( " Relocation: old=0x{0:X}, new=0x{1:X}, val=0x{2:X}, add=0x{3:X}, type={4}", word, newWord, val, addend, type)); } if (!supported) { throw new AsmException("unhandled relocation type: {0}", type); } putInt32(section, offset, newWord); }