private void AddCode(ElfFile file, AsmContext context) { if (context.CodeSection.VirtualSize > 0) { file.Sections.Add(new ElfSection { Name = file.Strings.SaveString(".text"), Type = ElfSectionType.ProgBits, Address = 0, Flags = ElfSectionFlags.Alloc | ElfSectionFlags.Executable, Size = (uint)context.CodeSection.BytesCount, Align = 2, Offset = (uint)file.Data.Position }); file.Segments.Add(new ElfSegment { Type = ElfSegmentType.Load, Offset = (uint)file.Data.Position, VirtualAddress = 0, PhysicalAddress = 0, FileSize = (uint)context.CodeSection.BytesCount, MemorySize = (uint)context.CodeSection.VirtualSize, Flags = ElfSegmentFlags.Executable | ElfSegmentFlags.Readable, Align = 1 }); file.Data.Write(context.CodeSection.Content.ToArray(), 0, context.CodeSection.BytesCount); } }
public void Save(AsmContext context, Stream stream) { var file = new ElfFile(); var writer = new BinaryWriter(stream); file.Sections.Add(new ElfSection()); AddCode(file, context); AddData(file, context); AddFlash(file, context); AddDebugLine(file, context); var sectionsStringsIndex = file.AddStringsSection(); const int headerSize = 0x34; const int segmentsOffset = headerSize; const int segmentEntrySize = 0x20; var dataOffset = (uint)(segmentsOffset + file.Segments.Count * segmentEntrySize); var sectionsOffset = dataOffset + file.Data.Length; var header = new ElfHeader { Identification = { Magic = new[] { (char)0x7f, 'E', 'L', 'F' }, FileClass = ElfFileClass.Elf32, DataType = ElfDataType.Lsb, Version = 1, }, Type = ElfType.Executable, Machine = 0x53, Version = 1, Entry = 0x0, ProgramHeaderOffset = segmentsOffset, SectionHeaderOffset = (uint)sectionsOffset, Flags = 0x84, ElfHeaderSize = headerSize, ProgramHeaderEntrySize = segmentEntrySize, ProgramHeaderCount = (ushort)file.Segments.Count, SectionHeaderEntrySize = 0x28, SectionHeaderCount = (ushort)file.Sections.Count, StringSectionIndex = (ushort)sectionsStringsIndex }; writer.WriteElf32(header); foreach (var segment in file.Segments) { var cloned = segment; cloned.Offset += dataOffset; writer.WriteElf32(cloned); } writer.Write(file.Data.ToArray()); foreach (var section in file.Sections) { var cloned = section; if (section.Type != ElfSectionType.Null) { cloned.Offset += dataOffset; } writer.WriteElf32(cloned); } }
private void AddDebugLine(ElfFile file, AsmContext context) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); var hdr = new DebugLineHeader { FileNames = new[] { new DebugLineFile {Name = "test.asm"}, new DebugLineFile {Name = "test2.asm"}, } }; writer.WriteDwarf2(hdr); if (mem.Length > 0) { file.Sections.Add(new ElfSection { Name = file.Strings.SaveString(".debug_line"), Type = ElfSectionType.ProgBits, Address = 0, Flags = ElfSectionFlags.None, Size = (uint)mem.Length, Align = 1, Offset = (uint)file.Data.Position }); file.Data.Write(mem.ToArray(), 0, (int)mem.Length); } }