Exemple #1
0
        /// <summary>
        /// A function to extract the debug_info and store it for future reference
        /// </summary>
        /// <param name="nmPath"></param>
        /// <param name="elfPath"></param>
        public void Run(string readElfPath, string elfPath)
        {
            string result = "";

            if (elfPath == "" || readElfPath == "")
            {
                return;
            }
            ProcessAdapter.Execute(ref result, readElfPath, "--debug-dump=info " + Quote(elfPath));
            string[] lines = result.Split(new[] { '\r', '\n' });
            DwarfInfo        = lines.ToList();
            CompilationUnits = new List <string[]>();
            // Select the index of all lines that contain the compilation unit tag
            var ci = DwarfInfo.Select((s, i) => new { s, i }).Where(x => x.s.Contains(COMPILE_UNIT)).Select(x => x.i).ToList();

            ci.Add(DwarfInfo.Count - 1); // last index
            for (int i = 0; i < ci.Count - 1; i++)
            {
                CompilationUnits.Add(DwarfInfo.GetRange(ci[i], ci[i + 1] - ci[i]).ToArray());
            }

            // test
            //FindSymbolCUnit("gRecipeFwd", Convert.ToUInt32("1074", 16));
            //FindSubRoutineCUnit("vSPIM_Task", Convert.ToUInt32("4ecc", 16));
            //FindSubRoutineCUnit("gRecipeFwd", Convert.ToUInt32("1075", 16));
        }
        /// <summary>
        /// Input the search path for .o files. We extract all the resolved symbols inside each .o file and store them for future reference
        /// </summary>
        /// <param name="nmPath"></param>
        /// <param name="objSearchPaths"></param>
        public void GatherStaticSyms(string nmPath, string[] objSearchPaths)
        {
            string result = "";

            UnresolvedSymols = new List <Symbol>();

            // 1. Extract all the object files from the various directories
            // Note select() doesnt execute the where() filter, but selectmany works!
            var objs = objSearchPaths.SelectMany(x => Directory.GetFiles(x).Where(y =>
            {
                if ((Path.GetExtension(y).ToLower() == ".o" || Path.GetExtension(y).ToLower() == ".obj"))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }));

            // 2. Run NM on them and get their symbols
            foreach (var obj in objs)
            {
                ProcessAdapter.Execute(ref result, nmPath, "--print-size --size-sort " + Quote(obj.ToString()));
                string[] symTable = result.Split(new[] { '\r', '\n' });
                string   secName  = "unknown";

                foreach (string line in symTable)
                {
                    string[] entries = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
                    if (entries.Length < 3)
                    {
                        continue;
                    }

                    // We are only interested in local symbols -> lower case stuff except for C
                    // https://sourceware.org/binutils/docs/binutils/nm.html
                    if (entries[2] == "t")
                    {
                        secName = SEC_NAME_TEXT;
                    }
                    else if (Regex.IsMatch(entries[2], @"[dg]"))
                    {
                        secName = SEC_NAME_DATA;
                    }
                    else if (Regex.IsMatch(entries[2], @"[bCs]"))
                    {
                        secName = SEC_NAME_BSS;
                    }
                    else
                    {
                        continue;
                    }

                    Symbol sym = new Symbol(entries[3], obj.ToString(), Convert.ToUInt32(entries[0], 16), Convert.ToUInt32(entries[1], 16), secName); sym.GlobalScope = Symbol.TYPE_STATIC;
                    UnresolvedSymols.Add(sym);
                }
            }
        }
        public void Run(string nmPath, string elfPath)
        {
            string result = "";

            Symbols = new List <Symbol>();
            if (elfPath == "")
            {
                return;
            }
            ProcessAdapter.Execute(ref result, nmPath, "--demangle --print-size --size-sort " + Quote(elfPath)); //--line-numbers

            // Parse the resultant table
            // 00800744 00000004 b LoaderIPMode  --> b means static BSS symbol, B beans global BSS symbol, same for d/D data
            // 00006364 00000018 T vTaskSuspendAll	/cygdrive/d/Freelance/Study/FTDI/VFWLoaderDemo/lib/FreeRTOS/Source/tasks.c:1632
            string[] symTable = result.Split(new[] { '\r', '\n' });

            foreach (string line in symTable)
            {
                // Split using spaces - note that the module path may itself contain spaces
                string[] entries = line.Split(new char[0], 4, StringSplitOptions.RemoveEmptyEntries);
                if (entries.Length < 4)
                {
                    continue;
                }
                string path    = "";
                int    type    = Symbol.TYPE_STATIC;
                string secName = "unknown";
                // Extract the module path, we also take into account paths with spaces in between

                if (entries[3] == "_setlocale_r")
                {
                    Debug.Write("_setlocale_r");
                }

                entries[3] = entries[3].TrimEnd(' '); // trim spaces from the end of function name

                if (UseDWARF)
                {
                    // Extract module path from DARF info
                    if (entries[2].ToLower() == "t")
                    {
                        // Subroutines
                        path = DwarfParser.Instance.FindSubRoutineCUnit(entries[3], Convert.ToUInt32(entries[0], 16));
                    }
                    else if (entries[2].ToLower() == "w") // Weak symbols could be either vars or subroutines
                    {
                        Debug.WriteLine("Found a weak symbol " + entries[3]);
                        path = DwarfParser.Instance.FindSubRoutineCUnit(entries[3], Convert.ToUInt32(entries[0], 16));
                        if (path != String.Empty)
                        {
                            Debug.WriteLine("Is a subroutine " + path);
                        }
                        else
                        {
                            path = DwarfParser.Instance.FindSymbolCUnit(entries[3], Convert.ToUInt32(entries[0], 16) & (~RAM_ADDRESS_MASK));
                            if (path != String.Empty)
                            {
                                Debug.WriteLine("Is a variable " + path);
                                // FIXME: for now just assume all weak variable syms are in BSS
                                entries[2] = "b";
                            }
                        }
                    }
                    else
                    {
                        // variables
                        path = DwarfParser.Instance.FindSymbolCUnit(entries[3], Convert.ToUInt32(entries[0], 16) & (~RAM_ADDRESS_MASK));
                    }
                }
                else
                {
                    if (entries.Length > 4)
                    {
                        int end = line.IndexOf(':');
                        int j   = 0;
                        for (int i = 0; i < line.Length; i++)
                        {
                            // Find the index of 4th space
                            if (line[i] == ' ' || line[i] == '\t')
                            {
                                j++;
                                if (j == 4)
                                {
                                    j = i + 1; break;
                                }
                            }
                        }
                        path = line.Substring(j, end - j);
                    }
                }

                if (Regex.IsMatch(entries[2], @"[TDBGSR]"))
                {
                    type = Symbol.TYPE_GLOBAL;
                }
                // Get the section
                if (entries[2].ToLower() == "t")
                {
                    secName = SEC_NAME_TEXT;
                }
                if (entries[2].ToLower() == "d" || entries[2].ToLower() == "g" || entries[2].ToLower() == "r")
                {
                    secName = SEC_NAME_DATA;
                }
                if (entries[2].ToLower() == "b" || entries[2].ToLower() == "s" || entries[2].ToLower() == "c")
                {
                    secName = SEC_NAME_BSS;
                }

                Symbol sym = new Symbol(entries[3], path, Convert.ToUInt32(entries[0], 16), Convert.ToUInt32(entries[1], 16), secName); sym.GlobalScope = type;
                Symbols.Add(sym);
            }
        }