private void EncodeInternal(TextWriter writer, Section[] sections) { Dictionary <HeadSection, string> headRefs = CreateTableOfContents(sections); for (int i = 0; i < sections.Length; i++) { Section section = sections[i]; if (section is ParagraphSection) { ParagraphSection s = (ParagraphSection)section; writer.Write("<p>"); WriteText(writer, s.Text); writer.WriteLine("</p>"); } else if (section is HeadSection) { HeadSection s = (HeadSection)section; writer.Write("<a name=\"{0}\">", headRefs[s]); writer.Write("<h{0}>", s.Level); WriteText(writer, s.Text); writer.Write("</h{0}>", s.Level); writer.WriteLine("</a>"); } else if (section is HorizonSection) { HorizonSection s = (HorizonSection)section; writer.Write("<hr/>"); } else if (section is CodeSection) { CodeSection s = (CodeSection)section; writer.Write("<pre class=\"code\"><code>"); writer.Write(Escape(s.Text)); writer.WriteLine("</code></pre>"); } else if (section is QuoteSection) { QuoteSection s = (QuoteSection)section; writer.Write("<blockquote>"); EncodeInternal(writer, s.Texts); writer.WriteLine("</blockquote>"); } else if (section is OrderListSection) { OrderListSection s = (OrderListSection)section; writer.WriteLine("<ol>"); foreach (ListItemSection j in s.Items) { writer.Write("<li>"); WriteText(writer, j.Text); EncodeInternal(writer, j.ChildList.ToArray()); writer.WriteLine("</li>"); } writer.WriteLine("</ol>"); } else if (section is ListSection) { ListSection s = (ListSection)section; writer.WriteLine("<ul>"); foreach (ListItemSection j in s.Items) { writer.Write(String.Format("<li {0}>", GetListClass(j.Mark))); WriteText(writer, j.Text); EncodeInternal(writer, j.ChildList.ToArray()); writer.WriteLine("</li>"); } writer.WriteLine("</ul>"); } else if (section is DefinitionListSection) { DefinitionListSection s = (DefinitionListSection)section; writer.Write("<dl>"); foreach (DefinitionItemSection j in s.Items) { writer.Write("<dt>"); WriteText(writer, j.Caption); writer.WriteLine("</dt>"); writer.Write("<dd>"); WriteText(writer, j.Data); writer.WriteLine("</dd>"); } writer.WriteLine("</dl>"); } else if (section is ContentsSection) { ContentsSection s = (ContentsSection)section; List <ContentItem> contents = ContentsTableGenerator.Generate(sections, i, s.LevelLower, s.LevelUpper); WriteContents(writer, contents, headRefs); } else if (section is ContentsAllSection) { ContentsAllSection s = (ContentsAllSection)section; List <ContentItem> contents = ContentsTableGenerator.GenerateAll(sections, s.LevelLower, s.LevelUpper); WriteContents(writer, contents, headRefs); } } }
protected override void Read(System.IO.BinaryReader r) { Init(); // Read e_ident byte[] e_ident = r.ReadBytes(16); if ((e_ident[0] != 0x7f) || (e_ident[1] != (byte)'E') || (e_ident[2] != (byte)'L') || (e_ident[3] != (byte)'F')) throw new Exception("Not an ELF file"); ec = (ElfClass)e_ident[4]; ed = (ElfData)e_ident[5]; if ((ec != ElfClass.ELFCLASS32) && (ec != ElfClass.ELFCLASS64)) throw new Exception("Invalid ELF class: " + e_ident[4].ToString()); if (ed != ElfData.ELFDATA2LSB) throw new Exception("Invalid ELF data type: " + e_ident[5].ToString()); if (e_ident[6] != 1) throw new Exception("Invalid ELF version: " + e_ident[6].ToString()); // Read the rest of the file header switch (ec) { case ElfClass.ELFCLASS32: ReadElf32FileHeader(r); break; case ElfClass.ELFCLASS64: ReadElf64FileHeader(r); break; } // Identify the arch, OS and machine type os = "none"; binary_type = BinaryTypes[ec]; architecture = MachineTypes[e_machine]; // First iterate through and identify the offsets of each section List<long> sect_offsets = new List<long>(); for (int i = 0; i < e_shnum; i++) { long sh_start = e_shoff + i * e_shentsize; r.BaseStream.Seek(sh_start, System.IO.SeekOrigin.Begin); switch (ec) { case ElfClass.ELFCLASS32: r.BaseStream.Seek(16, System.IO.SeekOrigin.Current); sect_offsets.Add(r.ReadInt32()); break; case ElfClass.ELFCLASS64: r.BaseStream.Seek(24, System.IO.SeekOrigin.Current); sect_offsets.Add(r.ReadInt64()); break; } } // Now load the section data List<SectionHeader> sect_headers = new List<SectionHeader>(); for (int i = 0; i < e_shnum; i++) { // First load the section header long sh_start = e_shoff + i * e_shentsize; r.BaseStream.Seek(sh_start, System.IO.SeekOrigin.Begin); SectionHeader sh = null; switch (ec) { case ElfClass.ELFCLASS32: sh = ReadElf32SectionHeader(r); break; case ElfClass.ELFCLASS64: sh = ReadElf64SectionHeader(r); break; } sect_headers.Add(sh); // Now get the name string name = "unknown"; if (e_shstrndx != 0) { long name_offset = sect_offsets[e_shstrndx] + sh.sh_name; name = ReadString(r, name_offset); } // Now load the actual section // Decide on the type of section ISection sect = null; switch (sh.sh_type) { case SectionHeader.SHT_NULL: break; case SectionHeader.SHT_PROGBITS: case SectionHeader.SHT_REL: case SectionHeader.SHT_RELA: case SectionHeader.SHT_HASH: case SectionHeader.SHT_DYNAMIC: case SectionHeader.SHT_NOTE: case SectionHeader.SHT_STRTAB: sect = new ContentsSection(this); break; case SectionHeader.SHT_SYMTAB: case SectionHeader.SHT_DYNSYM: sect = new ElfSymbolSection(this); break; case SectionHeader.SHT_NOBITS: sect = new BssSection(this); break; } if (sect != null) { // Interpret the section type sect.IsWriteable = ((sh.sh_flags & SectionHeader.SHF_WRITE) != 0); sect.IsAlloc = ((sh.sh_flags & SectionHeader.SHF_ALLOC) != 0); sect.IsExecutable = ((sh.sh_flags & SectionHeader.SHF_EXECINSTR) != 0); sect.LoadAddress = sh.sh_addr; sect.Name = name; sect.AddrAlign = sh.sh_addralign; // Load the contents if it has any sect.Length = sh.sh_size; if (sect.HasData) { r.BaseStream.Seek(sh.sh_offset, System.IO.SeekOrigin.Begin); for (long l = 0; l < sh.sh_size; l++) sect.Data[(int)l] = r.ReadByte(); } } sections.Add(sect); } // Interpret symbols for (int i = 0; i < e_shnum; i++) { SectionHeader sh = sect_headers[i]; ISection sect = sections[i]; if ((sh.sh_type == SectionHeader.SHT_SYMTAB) && sect.HasData) { int cur_sym = 0; for (long p = 0; p < sect.Length; p += sh.sh_entsize) { ElfSymbol s = null; switch (ec) { case ElfClass.ELFCLASS32: s = ReadElf32Symbol(sect.Data, (int)p); break; case ElfClass.ELFCLASS64: s = ReadElf64Symbol(sect.Data, (int)p); break; } if (s != null) { // Load up the name of the symbol if (sh.sh_link != 0) s.Name = ReadString(sections[sh.sh_link].Data, s.st_name); // Offset s.Offset = s.st_value; // Length s.Size = s.st_size; // Type switch (s.st_bind) { case ElfSymbol.STB_GLOBAL: s.Type = SymbolType.Global; break; case ElfSymbol.STB_LOCAL: s.Type = SymbolType.Local; break; case ElfSymbol.STB_WEAK: s.Type = SymbolType.Weak; break; } switch(s.st_type) { case ElfSymbol.STT_FUNC: s.ObjectType = SymbolObjectType.Function; break; case ElfSymbol.STT_OBJECT: s.ObjectType = SymbolObjectType.Object; break; default: s.ObjectType = SymbolObjectType.Unknown; break; } // DefinedIn if (s.st_shndx == 0) { s.DefinedIn = null; s.Type = SymbolType.Undefined; } else if (s.st_shndx == -15) { // SHN_ABS s.DefinedIn = AbsSection; } else if (s.st_shndx == -14) { // SHN_COMMON s.DefinedIn = CommonSection; } else s.DefinedIn = sections[s.st_shndx]; } if(!symbols.Contains(s)) symbols.Add(s); ((ElfSymbolSection)sect).elf_syms[cur_sym++] = s; } } } // Interpret relocations for (int i = 0; i < e_shnum; i++) { SectionHeader sh = sect_headers[i]; ISection sect = sections[i]; switch (sh.sh_type) { case SectionHeader.SHT_REL: ReadRelocationSection(sh, sect, sections, false); break; case SectionHeader.SHT_RELA: ReadRelocationSection(sh, sect, sections, true); break; } } }