public void SimpleCodeSectionAndSymbolSection() { var elf = new ElfObjectFile(); var codeStream = new MemoryStream(); codeStream.Write(Encoding.UTF8.GetBytes("This is a text")); codeStream.Position = 0; var codeSection = new ElfCustomSection(codeStream).ConfigureAs(ElfSectionSpecialType.Text); elf.AddSection(codeSection); var stringSection = new ElfStringTable(); elf.AddSection(stringSection); var symbolSection = new ElfSymbolTable() { Link = stringSection, Entries = { new ElfSymbol() { Name = "local_symbol", Bind = ElfSymbolBind.Local, Section = codeSection, Size = 16, Type = ElfSymbolType.Function, Visibility = ElfSymbolVisibility.Protected, Value = 0x7896 }, new ElfSymbol() { Name = "GlobalSymbol", Bind = ElfSymbolBind.Global, Section = codeSection, Size = 4, Type = ElfSymbolType.Function, Value = 0x12345 } } }; elf.AddSection(symbolSection); elf.AddSection(new ElfSectionHeaderStringTable()); AssertReadElf(elf, "test2.elf"); }
public void SimpleCodeSection() { var elf = new ElfObjectFile(); var codeStream = new MemoryStream(); codeStream.Write(Encoding.UTF8.GetBytes("This is a text")); codeStream.Position = 0; var codeSection = new ElfCustomSection(codeStream).ConfigureAs(ElfSectionSpecialType.Text); elf.AddSection(codeSection); elf.AddSection(new ElfSectionHeaderStringTable()); AssertReadElf(elf, "test.elf"); }
public void SimpleProgramHeaderAndCodeSectionAndSymbolSectionAndRelocation() { var arch = ElfArch.X86_64; var elf = new ElfObjectFile(); var codeStream = new MemoryStream(); codeStream.Write(new byte[4096]); var codeSection = elf.AddSection( new ElfCustomSection(codeStream) { VirtualAddress = 0x1000, Alignment = 4096 }.ConfigureAs(ElfSectionSpecialType.Text) ); var dataStream = new MemoryStream(); dataStream.Write(new byte[1024]); var dataSection = elf.AddSection( new ElfCustomSection(dataStream) { VirtualAddress = 0x2000, Alignment = 4096 }.ConfigureAs(ElfSectionSpecialType.ReadOnlyData) ); var stringSection = elf.AddSection(new ElfStringTable()); var symbolSection = elf.AddSection( new ElfSymbolTable() { Link = stringSection, Entries = { new ElfSymbol() { Name = "local_symbol", Bind = ElfSymbolBind.Local, Section = codeSection, Size = 16, Type = ElfSymbolType.Function, Visibility = ElfSymbolVisibility.Protected, Value = 0x7896 }, new ElfSymbol() { Name = "GlobalSymbol", Bind = ElfSymbolBind.Global, Section = codeSection, Size = 4, Type = ElfSymbolType.Function, Value = 0x12345 } } } ); elf.AddSegment( new ElfSegment() { Type = ElfSegmentTypeCore.Load, Range = codeSection, VirtualAddress = 0x1000, PhysicalAddress = 0x1000, Flags = ElfSegmentFlagsCore.Readable | ElfSegmentFlagsCore.Executable, Size = 4096, SizeInMemory = 4096, Alignment = 4096, } ); elf.AddSegment( new ElfSegment() { Type = ElfSegmentTypeCore.Load, Range = dataSection, VirtualAddress = 0x2000, PhysicalAddress = 0x2000, Flags = ElfSegmentFlagsCore.Readable | ElfSegmentFlagsCore.Writable, Size = 1024, SizeInMemory = 1024, Alignment = 4096, } ); var relocTable = elf.AddSection( new ElfRelocationTable { Name = ".rela.text", Link = symbolSection, Info = codeSection, Entries = { new ElfRelocation() { SymbolIndex = 1, Type = ElfRelocationType.R_X86_64_32, Offset = 0 }, new ElfRelocation() { SymbolIndex = 2, Type = ElfRelocationType.R_X86_64_8, Offset = 0 } } } ); elf.AddSection(new ElfSectionHeaderStringTable()); AssertReadElf(elf, "test4.elf"); }
public void CreateDwarf() { // Create ELF object var elf = new ElfObjectFile(ElfArch.X86_64); var codeSection = new ElfBinarySection(new MemoryStream(new byte[0x64])).ConfigureAs(ElfSectionSpecialType.Text); elf.AddSection(codeSection); var stringSection = new ElfStringTable(); elf.AddSection(stringSection); elf.AddSection(new ElfSymbolTable() { Link = stringSection }); elf.AddSection(new ElfSectionHeaderStringTable()); var elfDiagnostics = new DiagnosticBag(); elf.UpdateLayout(elfDiagnostics); Assert.False(elfDiagnostics.HasErrors); // Create DWARF Object var dwarfFile = new DwarfFile(); // Create .debug_line information var fileName = new DwarfFileName() { Name = "check1.cpp", Directory = Environment.CurrentDirectory, }; var fileName2 = new DwarfFileName() { Name = "check2.cpp", Directory = Environment.CurrentDirectory, }; // First line table for (int i = 0; i < 2; i++) { var lineTable = new DwarfLineProgramTable(); dwarfFile.LineSection.AddLineProgramTable(lineTable); lineTable.AddressSize = DwarfAddressSize.Bit64; lineTable.FileNames.Add(fileName); lineTable.FileNames.Add(fileName2); lineTable.AddLineSequence(new DwarfLineSequence() { new DwarfLine() { File = fileName, Address = 0, Column = 1, Line = 1, }, new DwarfLine() { File = fileName, Address = 1, Column = 1, Line = 2, } } ); // NOTE: doesn't seem to be generated by regular GCC // (it seems that only one line sequence is usually used) lineTable.AddLineSequence(new DwarfLineSequence() { new DwarfLine() { File = fileName2, Address = 0, Column = 1, Line = 1, }, } ); } // Create .debug_info var rootDIE = new DwarfDIECompileUnit() { Name = fileName.Name, LowPC = 0, // 0 relative to base virtual address HighPC = (int)codeSection.Size, // default is offset/length after LowPC CompDir = fileName.Directory, StmtList = dwarfFile.LineSection.LineTables[0], }; var subProgram = new DwarfDIESubprogram() { Name = "MyFunction", }; rootDIE.AddChild(subProgram); var cu = new DwarfCompilationUnit() { AddressSize = DwarfAddressSize.Bit64, Root = rootDIE }; dwarfFile.InfoSection.AddUnit(cu); // AddressRange table dwarfFile.AddressRangeTable.AddressSize = DwarfAddressSize.Bit64; dwarfFile.AddressRangeTable.Unit = cu; dwarfFile.AddressRangeTable.Ranges.Add(new DwarfAddressRange(0, 0, codeSection.Size)); // Transfer DWARF To ELF var dwarfElfContext = new DwarfElfContext(elf); dwarfFile.WriteToElf(dwarfElfContext); var outputFileName = "create_dwarf.o"; using (var output = new FileStream(outputFileName, FileMode.Create)) { elf.Write(output); } elf.Print(Console.Out); Console.WriteLine(); dwarfFile.AbbreviationTable.Print(Console.Out); Console.WriteLine(); dwarfFile.AddressRangeTable.Print(Console.Out); Console.WriteLine(); dwarfFile.InfoSection.Print(Console.Out); Console.WriteLine("ReadBack --debug-dump=rawline"); var readelf = LinuxUtil.ReadElf(outputFileName, "--debug-dump=rawline").TrimEnd(); Console.WriteLine(readelf); }