예제 #1
0
        public int LookupGlobalLabelValue(string name)
        {
            SyEntry entry = LookupGlobalSymbol(name);

            if (entry == null || entry.Kind != SymbolKind.Label)
            {
                return(-1);
            }
            return(entry.SymValue);
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        // 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);
        }