Exemplo n.º 1
0
        /*static uint GetMemorySize(Elf32File file, string memory) {
         *  var flashSections = file.GetSectionsByMemoryType(memory);
         *  var dataItems = flashSections.SelectMany(v => v.Items);
         *  return (uint)dataItems.Aggregate<DwarfCompilationUnitItem, ulong>(0, (current, item) => current + item.Size);
         * }*/

        static uint GetSectionSize(ElfFile file, string section)
        {
            var dataSection = file.GetSection(section);
            var dataItems   = dataSection.Items;

            return((uint)dataItems.Aggregate <DwarfCompilationUnitItem, ulong>(0, (current, item) => current + item.Size));
        }
Exemplo n.º 2
0
        public static DwarfCompilationUnit[] ReadCompilationUnits(ElfFile file)
        {
            var cuSection = file.GetSection(DwarfSections.DebugInfo);
            var stm       = file.DataStream;
            //move stream to section start
            var sectionEnd = cuSection.Header.offset + cuSection.Header.size;
            var result     = new List <DwarfCompilationUnit>();

            ulong readPosition = cuSection.Header.offset;

            //read compilation units
            while (readPosition < sectionEnd)
            {
                stm.Seek((long)readPosition, SeekOrigin.Begin);

                var  unit        = new DwarfCompilationUnit();
                bool is64BitUnit = false;

                //read unit length
                unit.Length = stm.ReadStructure <UInt32>();

                //unit len can be 64 bit, check that
                if (unit.Length == 0xffffffffU)
                {
                    unit.Length = stm.ReadStructure <UInt64>();
                    is64BitUnit = true;
                }

                readPosition = (ulong)stm.Position + unit.Length;
                unit.DataEnd = (long)readPosition;

                //read version
                unit.Version = stm.ReadStructure <UInt16>();
                //read abbrev offset
                unit.AbbrevOffset = is64BitUnit ? stm.ReadStructure <UInt64>() : stm.ReadStructure <UInt32>();
                //read address size
                unit.AddressSize = (byte)stm.ReadByte();

                //save offset to unit data
                unit.DataOffset = (ulong)stm.Position;
                unit.Is64Bit    = is64BitUnit;

                result.Add(unit);
            }
            return(result.ToArray());
        }
Exemplo n.º 3
0
        public void ReadValues(ElfFile file)
        {
            var stm = file.DataStream;

            stm.Position = (long)DataOffset;

            int hierarchyDepth = 0;

            //read all abbreviations
            while (stm.Position < DataEnd)
            {
                ulong abbreviationCode = stm.ReadLeb128Unsigned();
                if (abbreviationCode == 0)
                {
                    if (hierarchyDepth > 0)
                    {
                        hierarchyDepth--;
                    }
                }
                else
                {
                    var symbol = new DwarfSymbolDescpription();
                    var entry  = Abbrev.GetEntryByAbbreviationCode(abbreviationCode);
                    symbol.Abbreviation = entry;
                    Symbols.Add(symbol);

                    //read each entry value
                    foreach (var attribute in entry.attributes)
                    {
                        //if (entry.tag != DwarfConstants.DwarfTag.DW_TAG_compile_unit) {
                        if (attribute.form == DwarfConstants.DwarfForm.DW_FORM_indirect)
                        {
                            stm.ReadLeb128Unsigned();
                            continue;
                        }

                        switch (attribute.form)
                        {
                        case DwarfConstants.DwarfForm.DW_FORM_strp:
                            var ptr        = ReadPointer(stm);
                            var tmpPos     = stm.Position;
                            var strSection = file.GetSection(DwarfSections.DebugStr);
                            if (strSection != null)
                            {
                                stm.Position = strSection.Header.offset + (uint)ptr;
                                var str = stm.ReadAnsiString();
                                symbol.Values.Add(new DwarfStringValue(attribute.attribute, str));
                            }
                            stm.Position = tmpPos;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_block1:
                            symbol.Values.Add(new DwarfAttribBufferValue(attribute.attribute, stm, (byte)stm.ReadByte()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_block2:
                            symbol.Values.Add(new DwarfAttribBufferValue(attribute.attribute, stm, stm.ReadStructure <UInt16>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_block4:
                            symbol.Values.Add(new DwarfAttribBufferValue(attribute.attribute, stm, (int)stm.ReadStructure <UInt32>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_exprloc:
                        case DwarfConstants.DwarfForm.DW_FORM_block:
                            symbol.Values.Add(new DwarfAttribBufferValue(attribute.attribute, stm, (int)stm.ReadLeb128Unsigned()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_data1:
                            symbol.Values.Add(new DwarfScalarValue <byte>(attribute.attribute, (byte)stm.ReadByte()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_data2:
                            symbol.Values.Add(new DwarfScalarValue <UInt16>(attribute.attribute, stm.ReadStructure <UInt16>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_data4:
                            symbol.Values.Add(new DwarfScalarValue <UInt32>(attribute.attribute, stm.ReadStructure <UInt32>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_data8:
                            symbol.Values.Add(new DwarfScalarValue <UInt64>(attribute.attribute, stm.ReadStructure <UInt64>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_addr:
                            if (AddressSize == 2)
                            {
                                symbol.Values.Add(new DwarfScalarValue <UInt16>(attribute.attribute, stm.ReadStructure <UInt16>()));
                            }
                            else if (AddressSize == 4)
                            {
                                symbol.Values.Add(new DwarfScalarValue <UInt32>(attribute.attribute, stm.ReadStructure <UInt32>()));
                            }
                            else if (AddressSize == 8)
                            {
                                symbol.Values.Add(new DwarfScalarValue <UInt64>(attribute.attribute, stm.ReadStructure <UInt64>()));
                            }
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_string:
                            symbol.Values.Add(new DwarfStringValue(attribute.attribute, stm.ReadAnsiString()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_flag:
                            symbol.Values.Add(new DwarfAttribBoolValue(attribute.attribute, stm.ReadByte() != 0));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_sdata:
                            symbol.Values.Add(new DwarfScalarValue <Int64>(attribute.attribute, stm.ReadLeb128Signed()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_udata:
                            symbol.Values.Add(new DwarfScalarValue <UInt64>(attribute.attribute, stm.ReadLeb128Unsigned()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref_addr:
                            stm.Position += PtrSize;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref1:
                            stm.Position += 1;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref2:
                            stm.Position += 2;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref4:
                            stm.Position += 4;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref8:
                            stm.Position += 8;
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_sec_offset:
                            if (PtrSize == 4)
                            {
                                symbol.Values.Add(new DwarfScalarValue <UInt32>(attribute.attribute,
                                                                                stm.ReadStructure <UInt32>()));
                            }
                            else
                            {
                                symbol.Values.Add(new DwarfScalarValue <UInt64>(attribute.attribute, stm.ReadStructure <UInt64>()));
                            }
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_ref_sig8:
                            symbol.Values.Add(new DwarfScalarValue <UInt64>(attribute.attribute, stm.ReadStructure <UInt64>()));
                            break;

                        case DwarfConstants.DwarfForm.DW_FORM_flag_present:
                            symbol.Values.Add(new DwarfAttribBoolValue(attribute.attribute, true));
                            break;

                        default:
                            throw new Exception("WTF");
                            break;
                        }
                    }
                    if (entry.hasChild != 0)
                    {
                        ++hierarchyDepth;
                    }
                }
            }
            ParseItems(file);
            ParseLines(file);
        }
Exemplo n.º 4
0
        public void ParseLines(ElfFile file)
        {
            var stm         = file.DataStream;
            var lineSection = file.GetSection(DwarfSections.DebugLine);

            stm.Position = lineSection.Header.offset + (long)LineNumberOffset;

            ulong tmp     = stm.ReadStructure <UInt32>();
            bool  is64Bit = false;

            if (tmp == UInt32.MaxValue)
            {
                tmp     = stm.ReadStructure <UInt64>();
                is64Bit = true;
            }

            ushort cuVersion = stm.ReadStructure <ushort>();

            //read abbrev table offset
            var abbrevOffset = is64Bit ? stm.ReadStructure <UInt64>() : stm.ReadStructure <UInt32>();

            if (cuVersion >= 4)
            {
                stm.Seek(1, SeekOrigin.Current);
            }

            stm.Seek(4, SeekOrigin.Current);
            int num4 = stm.ReadByte();

            for (int i = 1; i <= num4 - 1; ++i)
            {
                ulong num3 = stm.ReadLeb128Unsigned();
            }

            List <string> list1 = new List <string>();

            while (true)
            {
                string str = stm.ReadAnsiString();
                if (!string.IsNullOrEmpty(str))
                {
                    list1.Add(str);
                }
                else
                {
                    break;
                }
            }

            List <string> list2 = new List <string>();

            while (true)
            {
                string str1 = stm.ReadAnsiString();
                if (!string.IsNullOrEmpty(str1))
                {
                    uint   num3 = (uint)stm.ReadLeb128Unsigned();
                    int    num5 = (int)stm.ReadLeb128Unsigned();
                    int    num6 = (int)stm.ReadLeb128Unsigned();
                    string str2 = str1;
                    if ((int)num3 == 0)
                    {
                        str2 = CompilationDirectory + "/" + str1;
                    }
                    else if (num3 > 0U && num3 < (uint)list1.Count)
                    {
                        str2 = list1[(int)num3 - 1] + "/" + str1;
                    }
                    list2.Add(str2);
                }
                else
                {
                    break;
                }
            }

            Lines = list2.ToArray();

            foreach (var item in Items)
            {
                if (item.File >= 0)
                {
                    item.FileStr = Lines[item.File - 1];
                }
            }
        }
Exemplo n.º 5
0
        public DwarfData(ElfFile file)
        {
            _file = file;
            //extract compilation units
            compilationUnits = DwarfCompilationUnit.ReadCompilationUnits(file);

            //extract abbreviations
            var abbrevSection = file.GetSection(DwarfSections.Abbrev);
            int id            = 0;

            foreach (var cu in compilationUnits)
            {
                cu.Abbrev = DwarfAbbreviation.Read(file, (long)cu.AbbrevOffset + abbrevSection.Header.offset);
                cu.ReadValues(file);
                id++;
            }

            //build file items tables
            var nameTable = new Dictionary <string, DwarfCompilationUnitItem>();
            var pcTable   = new Dictionary <ulong, DwarfCompilationUnitItem>();

            foreach (var unit in compilationUnits)
            {
                foreach (var dwarfAbbreviationEntry in unit.Abbrev.entries)
                {
                    foreach (var attr in dwarfAbbreviationEntry.attributes)
                    {
                        if (attr.attribute == DwarfConstants.DwarfAttribute.DW_AT_MIPS_linkage_name)
                        {
                            Console.WriteLine("LN");
                        }
                    }
                }

                foreach (var item in unit.Items)
                {
                    if (item.Pc != 0)
                    {
                        pcTable[item.Pc] = item;
                    }
                    if (!string.IsNullOrEmpty(item.Name))
                    {
                        nameTable[item.Name] = item;
                    }
                }
            }


            var symbols  = file.Sections.SelectMany(v => v.Symbols).ToArray();
            var tmpItems = new List <DwarfCompilationUnitItem>();

            foreach (var symbol in symbols)
            {
                DwarfCompilationUnitItem item = null;
                //find item corresponding to symbol
                if (!string.IsNullOrEmpty(symbol.Name) && nameTable.TryGetValue(symbol.Name, out item) ||
                    symbol.Header.ValueAddr != 0 && pcTable.TryGetValue(symbol.Header.ValueAddr, out item))
                {
                    if ((int)item.Size == 0)
                    {
                        item.Size = symbol.Header.Size;
                    }

                    if ((long)item.Pc == 0L)
                    {
                        item.Pc = symbol.Header.ValueAddr;
                    }

                    //dictionary3[mem.pc] = true;
                    if (string.IsNullOrEmpty(item.Name))
                    {
                        item.Name = symbol.Name;
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(symbol.Name))
                    {
                        item = new DwarfCompilationUnitItem(symbol);
                    }
                }

                if (item != null && item.Size != 0 && !string.IsNullOrEmpty(item.Name) && item.HasLine())
                {
                    tmpItems.Add(item);
                }
            }

            //sort members by pc
            tmpItems.Sort(((mem, member) => mem.Pc.CompareTo(member.Pc)));
            foreach (var unitItem in tmpItems)
            {
                if (unitItem.Size != 0)
                {
                    DwarfCompilationUnitItem item = null;
                    if (globalItems.Count > 0)
                    {
                        item = globalItems[globalItems.Count - 1];
                    }

                    if (item != null && (item.Pc == unitItem.Pc))
                    {
                        if (!item.HasLine() && unitItem.HasLine())
                        {
                            globalItems[globalItems.Count - 1] = unitItem;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else if (item != null && item.Pc <= unitItem.Pc && item.Pc + item.Size > unitItem.Pc)
                    {
                        item.Size = (uint)(unitItem.Pc - item.Pc);
                    }


                    globalItems.Add(unitItem);
                }
            }

            //fill sections with items
            foreach (var item in globalItems)
            {
                if (item.Size != 0)
                {
                    var index = file.GetSectionId(item.Pc);
                    if (index >= 0)
                    {
                        var section = file.Sections[index];
                        section.Items.Add(item);
                    }
                }
            }

            foreach (var section in file.Sections)
            {
                ulong itemsSize = section.Items.Aggregate <DwarfCompilationUnitItem, ulong>(0, (current, item) => current + item.Size);
                var   diff      = section.Header.size - itemsSize;
                if (diff != 0)
                {
                    section.Items.Add(new DwarfCompilationUnitItem()
                    {
                        Name = "other", Size = diff
                    });
                }
            }
        }