/*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)); }
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()); }
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); }
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]; } } }
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 }); } } }