protected override AssemblerState CreateAssemblerState(binary_library.IBinaryFile file) { AssemblerState ret = base.CreateAssemblerState(file); ret.cur_bitness = binary_library.Bitness.Bits32; return(ret); }
public void WriteToOutput(binary_library.IBinaryFile of, metadata.MetadataStream ms, target.Target t, binary_library.ISection rd = null) { if (str_tab.Count == 0) { return; } if (rd == null) { rd = of.GetRDataSection(); } rd.Align(t.GetCTSize(ir.Opcode.ct_object)); var stab_lab = of.CreateSymbol(); stab_lab.Name = Label; stab_lab.ObjectType = binary_library.SymbolObjectType.Object; stab_lab.Offset = (ulong)rd.Data.Count; stab_lab.Type = binary_library.SymbolType.Weak; rd.AddSymbol(stab_lab); int stab_base = rd.Data.Count; foreach (byte b in str_tab) { rd.Data.Add(b); } foreach (var kvp in sig_metadata_addrs) { var reloc = of.CreateRelocation(); reloc.DefinedIn = rd; reloc.Type = t.GetDataToDataReloc(); reloc.Addend = 0; if (sig_metadata_addends.ContainsKey(kvp.Key)) { reloc.Addend = sig_metadata_addends[kvp.Key]; } var md_lab = of.CreateSymbol(); md_lab.Name = kvp.Value; md_lab.ObjectType = binary_library.SymbolObjectType.Object; reloc.References = md_lab; reloc.Offset = (ulong)(kvp.Key + stab_base); of.AddRelocation(reloc); } stab_lab.Size = rd.Data.Count - (int)stab_lab.Offset; }
public binary_library.ISymbol GetStringTableSymbol(binary_library.IBinaryFile of) { binary_library.ISymbol sym; if (st_cache.TryGetValue(of, out sym)) { return(sym); } else { sym = of.CreateSymbol(); st_cache[of] = sym; return(sym); } }
public DwarfSections(binary_library.IBinaryFile _bf) { bf = _bf; abbrev = CreateDwarfSection("abbrev"); //aranges = CreateDwarfSection("aranges"); frame = CreateDwarfSection("frame"); info = CreateDwarfSection("info"); line = CreateDwarfSection("line"); //loc = CreateDwarfSection("loc"); //macinfo = CreateDwarfSection("macinfo"); pubnames = CreateDwarfSection("pubnames"); pubtypes = CreateDwarfSection("pubtypes"); //ranges = CreateDwarfSection("ranges"); str = CreateDwarfSection("str"); //types = CreateDwarfSection("types"); }
static void Main(string[] args) { // Load a test file string test_file = "..\\..\\..\\libsupcs\\x86_64_cpu.asm"; FileStream fs = new FileStream(test_file, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs); string file = sr.ReadToEnd(); // Tokenize and parse List <Tokenizer.TokenDefinition> tokens = Tokenizer.Tokenize(file, Tokenizer.CAsmTokenGrammar, Tokenizer.NasmPreprocessorOptions); AsmParser.ParseOutput parsed = AsmParser.Parse(tokens); // Create an output file binary_library.IBinaryFile output_file = binary_library.BinaryFile.CreateBinaryFile("elf"); // Assemble to the output file Assembler ass = new x86_Assembler(); ass.Assemble(parsed, output_file); }
public void WriteToOutput(binary_library.IBinaryFile of, metadata.MetadataStream ms, target.Target t) { var rd = of.GetRDataSection(); rd.Align(t.GetCTSize(ir.Opcode.ct_object)); var stab_lab = GetStringTableSymbol(of); stab_lab.Name = Label; stab_lab.ObjectType = binary_library.SymbolObjectType.Object; stab_lab.Offset = (ulong)rd.Data.Count; stab_lab.Type = binary_library.SymbolType.Global; rd.AddSymbol(stab_lab); int stab_base = rd.Data.Count; foreach (byte b in str_tab) { rd.Data.Add(b); } var str_lab = of.CreateSymbol(); str_lab.Name = StringObject.m.MangleType(StringObject); str_lab.ObjectType = binary_library.SymbolObjectType.Object; foreach (var str_addr in str_addrs.Values) { var reloc = of.CreateRelocation(); reloc.DefinedIn = rd; reloc.Type = t.GetDataToDataReloc(); reloc.Addend = 0; reloc.References = str_lab; reloc.Offset = (ulong)(str_addr + stab_base); of.AddRelocation(reloc); } stab_lab.Size = rd.Data.Count - (int)stab_lab.Offset; }
public static bool AssembleBoxedMethod(metadata.MethodSpec ms, binary_library.IBinaryFile bf, target.Target t, TysilaState s, StringBuilder debug_passes = null, binary_library.ISection ts = null) { if (ts == null) { ts = bf.GetTextSection(); } s.bf = bf; s.text_section = ts; // Symbol List <binary_library.ISymbol> meth_syms = new List <binary_library.ISymbol>(); var mangled_name = ms.MangleMethod(); var meth_sym = bf.CreateSymbol(); meth_sym.Name = mangled_name; meth_sym.ObjectType = binary_library.SymbolObjectType.Function; meth_sym.Offset = (ulong)ts.Data.Count; meth_sym.Type = binary_library.SymbolType.Weak; ts.AddSymbol(meth_sym); meth_syms.Add(meth_sym); Code c = ms.ret_type_needs_boxing ? t.AssembleBoxRetTypeMethod(ms, s) : t.AssembleBoxedMethod(ms, s); c.t = t; t.AssemblePass(c); foreach (var sym in meth_syms) { sym.Size = ts.Data.Count - (int)sym.Offset; } DumpDebug(debug_passes, meth_syms, c); return(true); }
// Build the hash table List <int>[] BuildHashTable(binary_library.IBinaryFile f) { int sc = f.GetSymbolCount(); int bc = CalculateBucketCount(sc); List <int>[] ht = new List <int> [bc]; for (int i = 1; i < sc; i++) { binary_library.ISymbol sym = f.GetSymbol(i); uint hash = HashFunction(sym.Name); int bucket_no = (int)(hash % (uint)bc); if (ht[bucket_no] == null) { ht[bucket_no] = new List <int>(); } ht[bucket_no].Add(i); } return(ht); }
public void Assemble(AsmParser.ParseOutput input, binary_library.IBinaryFile output) { AssemblerState state = CreateAssemblerState(output); if (input.Type != AsmParser.ParseOutput.OutputType.Block) { throw new Exception("Expected Block"); } foreach (AsmParser.ParseOutput line in input.Children) { if (line.Type != AsmParser.ParseOutput.OutputType.Line) { throw new Exception("Expected Line"); } foreach (AsmParser.ParseOutput line_entry in line.Children) { switch (line_entry.Type) { case AsmParser.ParseOutput.OutputType.DirectiveCommand: AssembleDirective(line_entry, state); break; case AsmParser.ParseOutput.OutputType.OpCommand: AssembleOperation(line_entry, state); break; case AsmParser.ParseOutput.OutputType.Label: AssembleLabel(line_entry, state); break; default: throw new NotSupportedException(); } } } }
public abstract bool AssembleJitStub(metadata.MethodSpec ms, libtysila5.target.Target t, binary_library.IBinaryFile bf, libtysila5.TysilaState s);
public AssemblerState(binary_library.IBinaryFile binary_file) { file = binary_file; SelectSection(".text"); }
protected virtual AssemblerState CreateAssemblerState(binary_library.IBinaryFile file) { return(new AssemblerState(file)); }
static int Main(string[] args) { /* Parse args */ var argc = args.Length; char c; var go = new XGetoptCS.XGetopt(); var arg_str = "t:L:o:"; while ((c = go.Getopt(argc, args, arg_str)) != '\0') { switch (c) { case 't': arch = go.Optarg; break; case 'L': new_search_dirs.Add(go.Optarg); break; case 'o': output_name = go.Optarg; break; case '?': dump_opts(); return(-1); } } tysila4.Program.search_dirs.InsertRange(0, new_search_dirs); var curopt = go.Optind; while (curopt < argc) { input_files.Add(args[curopt++]); } if (input_files.Count == 0) { System.Console.WriteLine("No input files specified"); dump_opts(); return(-1); } /* Load up each input file in turn */ var ifiles = new List <binary_library.IBinaryFile>(); foreach (var ifname in input_files) { var ifinfo = new System.IO.FileInfo(ifname); if (!ifinfo.Exists) { throw new System.IO.FileNotFoundException("Cannot find: " + ifname); } /* Determine file type from extension */ binary_library.IBinaryFile ifobj = null; if (ifinfo.Extension == ".o" || ifinfo.Extension == ".obj") { ifobj = new binary_library.elf.ElfFile(); } if (ifobj == null) { ifobj = binary_library.BinaryFile.CreateBinaryFile(ifinfo.Extension); } if (ifobj == null) { throw new Exception("Unsupported file type: " + ifinfo.FullName); } /* Load up the particular file */ ifobj.Filename = ifinfo.FullName; ifobj.Read(); ifiles.Add(ifobj); } /* Get a list of all defined symbols */ var def_syms = new Dictionary <string, binary_library.ISymbol>(); foreach (var file in ifiles) { var sym_count = file.GetSymbolCount(); for (int i = 0; i < sym_count; i++) { var sym = file.GetSymbol(i); if (sym.DefinedIn != null && sym.Type != binary_library.SymbolType.Undefined) { def_syms[sym.Name] = sym; } } } /* Get a list of those relocations which are missing */ var missing = new Dictionary <string, binary_library.ISymbol>(); foreach (var file in ifiles) { var reloc_count = file.GetRelocationCount(); for (int i = 0; i < reloc_count; i++) { var reloc = file.GetRelocation(i); if (reloc.References != null && !def_syms.ContainsKey(reloc.References.Name)) { if (reloc.References.Name == "_Zu1O_7#2Ector_Rv_P1u1t") { System.Diagnostics.Debugger.Break(); } missing[reloc.References.Name] = reloc.References; } } } /* Generate an output object */ var o = new binary_library.elf.ElfFile(ifiles[0].Bitness); o.Init(); o.Architecture = arch; o.Filename = output_name; /* Generate dummy module */ var ofi = new System.IO.FileInfo(output_name); var ms = new metadata.MetadataStream(ofi.Name.Substring(0, ofi.Name.Length - ofi.Extension.Length)); ms.al = new libtysila5.libtysila.AssemblyLoader(new tysila4.FileSystemFileLoader()); ms.LoadBuiltinTypes(); /* Load up assembler target */ var t = libtysila5.target.Target.targets[arch]; var fsi = new System.IO.FileInfo(output_name); var s = new libtysila5.TysilaState(); s.st = new libtysila5.StringTable(fsi.Name.Substring(0, fsi.Name.Length - fsi.Extension.Length), ms.al, t); /* Generate signature of missing_function(string) to call */ var special_c = new libtysila5.Code { ms = new metadata.MethodSpec { m = ms } }; var special = special_c.special_meths; var missing_msig = special.CreateMethodSignature(null, new metadata.TypeSpec[] { ms.SystemString }); /* Generate stub functions for missing methods */ var m = missing.Keys; var missing_types = new List <string>(); var other_missing = new List <string>(); foreach (var str in m) { try { if (ms.IsMangledMethod(str)) { GenerateMissingMethod(str, ms, t, missing_msig, o, s); } else { ms.IsMangledMethod(str); missing_types.Add(str); } } catch (ArgumentException) { other_missing.Add(str); } } /* Write out */ s.st.WriteToOutput(o, ms, t); o.Write(); /* Dump missing types */ if (missing_types.Count > 0) { Console.WriteLine("Warning: the following missing types were also found:"); foreach (var mt in missing_types) { Console.WriteLine(" " + mt); } } return(0); }
public static bool AssembleMethod(metadata.MethodSpec ms, binary_library.IBinaryFile bf, target.Target t, TysilaState s, StringBuilder debug_passes = null, MetadataStream base_m = null, Code code_override = null, binary_library.ISection ts = null, binary_library.ISection data_sect = null, dwarf.DwarfCU dcu = null) { if (ms.ret_type_needs_boxing) { throw new Exception("AssembleMethod called for box rettype stub - use AssembleBoxedMethod instead"); } if (ms.is_boxed) { throw new Exception("AssembleMethod called for boxed method - use AssembleBoxedMethod instead"); } if (ts == null) { ts = bf.GetTextSection(); } s.bf = bf; s.text_section = ts; binary_library.SymbolType sym_st = binary_library.SymbolType.Global; var csite = ms.msig; var mdef = ms.mdrow; var m = ms.m; /* Don't compile if not for this architecture */ if (!t.IsMethodValid(ms)) { return(false); } // Get method RVA, don't compile if no body var rva = m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, mdef, 0); // New signature table s.sigt = new SignatureTable(ms.MangleMethod()); /* Is this an array method? */ if (rva == 0 && ms.type != null && ms.type.stype == TypeSpec.SpecialType.Array && code_override == null) { if (ms.name_override == "Get") { code_override = ir.ConvertToIR.CreateArrayGet(ms, t, s); } else if (ms.name_override == ".ctor") { // there are two constructors, choose the correct one var pcount = ms.m.GetMethodDefSigParamCount(ms.msig); if (pcount == ms.type.arr_rank) { code_override = ir.ConvertToIR.CreateArrayCtor1(ms, t, s); } else if (pcount == 2 * ms.type.arr_rank) { code_override = ir.ConvertToIR.CreateArrayCtor2(ms, t, s); } else { throw new NotSupportedException("Invalid number of parameters to " + ms.MangleMethod() + " for array of rank " + ms.type.arr_rank.ToString()); } } else if (ms.name_override == "Set") { code_override = ir.ConvertToIR.CreateArraySet(ms, t, s); } else if (ms.name_override == "Address") { code_override = ir.ConvertToIR.CreateArrayAddress(ms, t, s); } else { throw new NotImplementedException(ms.name_override); } sym_st = binary_library.SymbolType.Weak; } /* Is this a vector method? */ if (rva == 0 && ms.type != null && ms.type.stype == TypeSpec.SpecialType.SzArray && code_override == null) { if (ms.Name == "IndexOf") { code_override = ir.ConvertToIR.CreateVectorIndexOf(ms, t, s); } else if (ms.Name == "Insert") { code_override = ir.ConvertToIR.CreateVectorInsert(ms, t, s); } else if (ms.Name == "RemoveAt") { code_override = ir.ConvertToIR.CreateVectorRemoveAt(ms, t, s); } else if (ms.Name == "get_Item") { code_override = ir.ConvertToIR.CreateVectorget_Item(ms, t, s); } else if (ms.Name == "set_Item") { code_override = ir.ConvertToIR.CreateVectorset_Item(ms, t, s); } else if (ms.Name == "get_Count") { code_override = ir.ConvertToIR.CreateVectorget_Count(ms, t, s); } else if (ms.Name == "CopyTo") { code_override = ir.ConvertToIR.CreateVectorCopyTo(ms, t, s); } /*else if (ms.Name == "GetEnumerator") * code_override = ir.ConvertToIR.CreateVectorGetEnumerator(ms, t);*/ else if (ms.Name == "Add" || ms.Name == "Clear" || ms.Name == "Contains" || ms.Name == "Remove" || ms.Name == "get_IsReadOnly" || ms.Name == "get_IsSynchronized" || ms.Name == "get_SyncRoot" || ms.Name == "get_IsFixedSize" || ms.Name == "Clone" || ms.Name == "CompareTo" || ms.Name == "GetHashCode" || ms.Name == "Equals") { code_override = ir.ConvertToIR.CreateVectorUnimplemented(ms, t, s); } else { return(false); } sym_st = binary_library.SymbolType.Weak; } if (rva == 0 && code_override == null) { return(false); } // Get mangled name for defining a symbol List <binary_library.ISymbol> meth_syms = new List <binary_library.ISymbol>(); var mangled_name = m.MangleMethod(ms); var meth_sym = bf.CreateSymbol(); meth_sym.Name = mangled_name; meth_sym.ObjectType = binary_library.SymbolObjectType.Function; meth_sym.Offset = (ulong)ts.Data.Count; meth_sym.Type = binary_library.SymbolType.Global; ts.AddSymbol(meth_sym); meth_syms.Add(meth_sym); foreach (var alias in ms.MethodAliases) { var alias_sym = bf.CreateSymbol(); alias_sym.Name = alias; alias_sym.ObjectType = binary_library.SymbolObjectType.Function; alias_sym.Offset = (ulong)ts.Data.Count; alias_sym.Type = binary_library.SymbolType.Global; ts.AddSymbol(alias_sym); meth_syms.Add(alias_sym); } if (ms.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs20WeakLinkageAttribute_7#2Ector_Rv_P1u1t")) { sym_st = binary_library.SymbolType.Weak; } if (base_m != null && ms.m != base_m) { sym_st = binary_library.SymbolType.Weak; } foreach (var sym in meth_syms) { sym.Type = sym_st; } // Get signature if not specified if (csite == 0) { csite = (int)m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, mdef, 4); } Code cil; if (code_override == null) { var meth = m.GetRVA(rva); var flags = meth.ReadByte(0); int max_stack = 0; long code_size = 0; long lvar_sig_tok = 0; int boffset = 0; List <metadata.ExceptionHeader> ehdrs = null; bool has_exceptions = false; if ((flags & 0x3) == 0x2) { // Tiny header code_size = flags >> 2; max_stack = 8; boffset = 1; } else if ((flags & 0x3) == 0x3) { // Fat header uint fat_flags = meth.ReadUShort(0) & 0xfffU; int fat_hdr_len = (meth.ReadUShort(0) >> 12) * 4; max_stack = meth.ReadUShort(2); code_size = meth.ReadUInt(4); lvar_sig_tok = meth.ReadUInt(8); boffset = fat_hdr_len; if ((flags & 0x8) == 0x8) { has_exceptions = true; ehdrs = new List <metadata.ExceptionHeader>(); int ehdr_offset = boffset + (int)code_size; ehdr_offset = util.util.align(ehdr_offset, 4); while (true) { int kind = meth.ReadByte(ehdr_offset); if ((kind & 0x1) != 0x1) { throw new Exception("Invalid exception header"); } bool is_fat = false; if ((kind & 0x40) == 0x40) { is_fat = true; } int data_size = meth.ReadInt(ehdr_offset); data_size >>= 8; if (is_fat) { data_size &= 0xffffff; } else { data_size &= 0xff; } int clause_count; if (is_fat) { clause_count = (data_size - 4) / 24; } else { clause_count = (data_size - 4) / 12; } ehdr_offset += 4; for (int i = 0; i < clause_count; i++) { var ehdr = ParseExceptionHeader(meth, ref ehdr_offset, is_fat, ms); ehdr.EhdrIdx = i; ehdrs.Add(ehdr); } if ((kind & 0x80) != 0x80) { break; } } } } else { throw new Exception("Invalid method header flags"); } /* Parse CIL code */ cil = libtysila5.cil.CilParser.ParseCIL(meth, ms, boffset, (int)code_size, lvar_sig_tok, has_exceptions, ehdrs); cil.s = s; /* Allocate local vars and args */ t.AllocateLocalVarsArgs(cil); /* Convert to IR */ cil.t = t; ir.ConvertToIR.DoConversion(cil); } else { cil = code_override; } /* Allocate registers */ ir.AllocRegs.DoAllocation(cil); /* Choose instructions */ target.ChooseInstructions.DoChoosing(cil); t.AssemblePass(cil); //((target.x86.x86_Assembler)cil.t).AssemblePass(cil); foreach (var sym in meth_syms) { sym.Size = ts.Data.Count - (int)sym.Offset; } foreach (var extra_sym in cil.extra_labels) { var esym = bf.CreateSymbol(); esym.Name = extra_sym.Name; esym.ObjectType = binary_library.SymbolObjectType.Function; esym.Offset = (ulong)extra_sym.Offset; esym.Type = sym_st; ts.AddSymbol(esym); } /* Dump debug */ DumpDebug(debug_passes, meth_syms, cil); /* Signature table */ if (data_sect == null) { data_sect = bf.GetDataSection(); } s.sigt.WriteToOutput(bf, ms.m, t, data_sect); /* DWARF output */ if (dcu != null) { var ddie = dcu.GetMethodDie(ms); ddie.sym = meth_syms[0]; ddie.cil = cil; var ddts = dcu.GetTypeDie(ms.type) as dwarf.DwarfParentDIE; ddts.Children.Add(ddie); if (ms.ReturnType != null) { dcu.GetTypeDie(ms.ReturnType); if (ms.ReturnType.stype == TypeSpec.SpecialType.None && !ms.ReturnType.IsValueType) { dcu.GetTypeDie(ms.ReturnType.Pointer); } } foreach (var la in cil.la_types) { dcu.GetTypeDie(la); if (la.stype == TypeSpec.SpecialType.None && !la.IsValueType) { dcu.GetTypeDie(la.Pointer); } } foreach (var lv in cil.lv_types) { dcu.GetTypeDie(lv); if (lv.stype == TypeSpec.SpecialType.None && !lv.IsValueType) { dcu.GetTypeDie(lv.Pointer); } } if (!ms.IsStatic) { dcu.GetTypeDie(ms.type.Pointer); } // do we have source lines? if (ms.m.pdb != null && ms.mdrow > 0) { var sps = ms.m.pdb.DebugGetSeqPtForMDRow(ms.mdrow); if (sps != null && cil.cil != null && cil.cil.Count > 0) { /* Start building a Line Number Program * * We follow the example in DWARF4 D.5 (p251), with a few changes * * header - defined per CU * - add this/these source files to it if necessary * * DW_LNE_set_address - psize 0s, reloc to mangled name * DW_LNS_advance_pc - mc_offset of first cil instruction * DW_LNS_set_prologue_end * DW_LNS_set_file - source file * SPECIAL(0,0) - add first opcode * SPECIAL(x,y) - add rest of opcodes * DW_LNE_end_sequence * */ string cur_file = null; int cur_line = 1; int cur_mc = 0; int cur_col = 0; var lnp = dcu.lnp; // DW_LNE_set_address lnp.AddRange(new byte[] { 0x00, (byte)(t.psize + 1), 0x02 }); dcu.lnp_relocs.Add(lnp.Count, meth_syms[0]); for (int i = 0; i < t.psize; i++) { lnp.Add(0); } // DW_LNS_advance_pc lnp.Add(0x02); dwarf.DwarfDIE.w(lnp, (uint)cil.cil[0].mc_offset); cur_mc = cil.cil[0].mc_offset; // DW_LNS_set_prologue_end lnp.Add(0x0a); foreach (var cn in cil.cil) { var mc_advance = cn.mc_offset - cur_mc; // get current line number MetadataStream.SeqPt csp = null; foreach (var sp in sps) { if (sp.IlOffset == cn.il_offset & !sp.IsHidden) { csp = sp; break; } } if (csp != null) { var line_advance = csp.StartLine - cur_line; if (ddie.StartLine == 0) { ddie.StartLine = csp.StartLine; } if (ddie.StartColumn == 0) { ddie.StartColumn = csp.StartCol; } if (csp.DocName != cur_file) { // DW_LNS_set_file lnp.Add(0x04); uint file_no; if (!dcu.lnp_files.TryGetValue(csp.DocName, out file_no)) { file_no = (uint)(dcu.lnp_files.Count + 1); dcu.lnp_files[csp.DocName] = file_no; dcu.lnp_fnames.Add(csp.DocName); } if (ddie.SourceFileId == 0) { ddie.SourceFileId = (int)file_no; } dwarf.DwarfDIE.w(lnp, file_no); cur_file = csp.DocName; } if (csp.StartCol != cur_col) { // DW_LNS_set_column lnp.Add(0x05); dwarf.DwarfDIE.w(lnp, (uint)csp.StartCol); cur_col = csp.StartCol; } /* SPECIAL if possible * Use example on DWARF4 p132: * opcode_base = 13, line_base = -3, line_range = 12 * * Gives a line advance range of [-3,8] and op_advance [0,19] */ if ((line_advance >= dcu.line_base && line_advance < (dcu.line_base + dcu.line_range)) && (mc_advance >= 0 && mc_advance < dcu.mc_advance_max)) { var spec_opcode = (line_advance - dcu.line_base) + (dcu.line_range * mc_advance) + dcu.opcode_base; lnp.Add((byte)spec_opcode); } else { // DW_LNS_advance_pc lnp.Add(0x02); dwarf.DwarfDIE.w(lnp, (uint)mc_advance); // DW_LNS_advance_line lnp.Add(0x03); dwarf.DwarfDIE.w(lnp, line_advance); // SPECIAL(0,0) var spec_opcode = (0 - dcu.line_base) + dcu.opcode_base; lnp.Add((byte)spec_opcode); } cur_line += line_advance; cur_mc += mc_advance; } } // Advance to end var to_advance = (int)meth_syms[0].Size - cur_mc; lnp.Add(0x02); dwarf.DwarfDIE.w(lnp, to_advance); // DW_LNE_end_sequence lnp.Add(0x00); lnp.Add(0x01); lnp.Add(0x01); } } } return(true); }
static void Main(string[] args) { if (ParseArgs(args) == false) { DispUsage(); return; } InitMaps(); // Initialize the default linker scripts DefaultScripts.InitScripts(); // Load the input files if (ifiles.Count == 0) { Console.WriteLine("No input files!"); return; } List <binary_library.IBinaryFile> inputs = new List <binary_library.IBinaryFile>(); foreach (string ifile in ifiles) { binary_library.elf.ElfFile ef = new binary_library.elf.ElfFile(); ef.Filename = ifile; ef.Read(); inputs.Add(ef); } // Determine the architecture string cur_arch = null; if (options["arch"].Set) { cur_arch = options["arch"].String; } foreach (binary_library.IBinaryFile ifile in inputs) { if (cur_arch == null) { cur_arch = ifile.NameTriple; } } string[] ntriple = cur_arch.Split('-'); if (ntriple.Length != 3) { Console.WriteLine("Error: invalid architecture: " + cur_arch); throw new Exception(); } // Check input files are of the appropriate architecture foreach (var ifile in inputs) { if (ntriple[0] != ifile.Architecture) { Console.WriteLine("Error: " + ifile.Filename + " is not built for architecture " + ntriple[0]); throw new Exception(); } } // Determine output file type string oformat = null; binary_library.Bitness bn = binary_library.Bitness.BitsUnknown; if (options["oformat"].Set) { oformat = options["oformat"].String.ToLower(); if (bitness_map.ContainsKey(oformat)) { bn = bitness_map[oformat]; } if (oformat == "elf32" || oformat == "elf64") { oformat = "elf"; } } else if (oformat_map.ContainsKey(ntriple[1])) { oformat = oformat_map[ntriple[1]]; } else { oformat = "elf"; } if (bn == binary_library.Bitness.BitsUnknown && bitness_map.ContainsKey(ntriple[0])) { bn = bitness_map[ntriple[0]]; } // Create an output file binary_library.IBinaryFile of = null; if (oformat == "elf") { of = new binary_library.elf.ElfFile(bn); } else if (oformat == "binary") { of = new binary_library.binary.FlatBinaryFile(); } else if (oformat == "hex") { of = new binary_library.binary.HexFile(); } else { throw new Exception("Unsupported output format: " + oformat); } if (output_file == null) { output_file = "a.out"; } of.Init(); of.Architecture = ntriple[0]; if (ntriple[1] == "elf" && bn == binary_library.Bitness.Bits64) { of.BinaryType = "elf64"; } else { of.BinaryType = ntriple[1]; } of.OS = ntriple[2]; // Get the linker script LinkerScript script = DefaultScripts.GetScript(ntriple); // Fill out comment section comment += "triple: " + of.Architecture + "-" + of.BinaryType + "-" + of.OS + nl; comment += "arch: " + of.Architecture + nl; comment += "binarytype: " + of.Architecture + nl; comment += "os: " + of.OS + nl; comment += "script: " + script.Name + nl; comment += "comp-date: " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + nl; comment += "endtl" + nl + "\0"; // Run the script script.RunScript(of, inputs); // ELF specific options if (of is binary_library.elf.ElfFile) { var ef = of as binary_library.elf.ElfFile; ef.CreateHashSection = gen_hash; } of.Filename = output_file; of.Write(); }
// Write out the hash table public void Write(BinaryWriter s, binary_library.IBinaryFile f, int ver, int endian, int bitness) { long offset_to_hash_table = 0; long offset_to_file_name = 0; if (ver > 0) { // Write header long header_offset = s.BaseStream.Position; s.Write((byte)'T'); s.Write((byte)'Y'); s.Write((byte)'H'); s.Write((byte)'A'); s.Write((byte)'S'); s.Write((byte)'H'); s.Write((byte)' '); s.Write((byte)' '); s.Write((ushort)ver); s.Write((byte)endian); s.Write((byte)bitness); offset_to_hash_table = s.BaseStream.Position; s.Write((int)0); offset_to_file_name = s.BaseStream.Position; s.Write((int)0); } // Build hash table long hash_table_start = s.BaseStream.Position; List <int>[] ht = BuildHashTable(f); WriteIntPtr(s, ht.Length, bitness); WriteIntPtr(s, f.GetSymbolCount(), bitness); // Build arrays to contain the bucket and chains long[] buckets = new long[ht.Length]; long[] chains = new long[f.GetSymbolCount()]; // Iterate through each chain for (int i = 0; i < ht.Length; i++) { List <int> bucket = ht[i]; if (bucket == null) { continue; } for (int j = 0; j < bucket.Count; j++) { int chain = bucket[j]; // First entry is pointed to by bucket if (j == 0) { buckets[i] = chain; } int next_chain = 0; if (j < (bucket.Count - 1)) { next_chain = bucket[j + 1]; } chains[chain] = next_chain; } } // Write out foreach (long b in buckets) { WriteIntPtr(s, b, bitness); } foreach (long c in chains) { WriteIntPtr(s, c, bitness); } if (ver > 0) { // Point the hash table pointer to the hash table long cur_pos = s.BaseStream.Position; s.BaseStream.Seek(offset_to_hash_table, SeekOrigin.Begin); s.Write((int)hash_table_start); // Write out the input file name s.BaseStream.Seek(offset_to_file_name, SeekOrigin.Begin); s.Write((int)cur_pos); s.BaseStream.Seek(cur_pos, SeekOrigin.Begin); System.IO.FileInfo fi = new FileInfo(f.Filename); foreach (char c in fi.Name) { s.Write((byte)c); } s.Write((byte)0); } }
public static void OutputEHdr(MethodSpecWithEhdr ms, Target t, binary_library.IBinaryFile of, TysilaState s, MetadataStream base_m = null, binary_library.ISection os = null) { // Don't compile if not for this architecture if (!t.IsMethodValid(ms.ms)) { return; } if (os == null) { os = of.GetRDataSection(); } os.Align(t.GetPointerSize()); var d = os.Data; /* Symbol */ var sym = of.CreateSymbol(); sym.Name = ms.ms.MangleMethod() + "EH"; sym.ObjectType = binary_library.SymbolObjectType.Object; sym.Offset = (ulong)d.Count; sym.Type = binary_library.SymbolType.Global; os.AddSymbol(sym); if (base_m != null && ms.ms.m != base_m) { sym.Type = binary_library.SymbolType.Weak; } foreach (var ehdr in ms.c.ehdrs) { var v = t.IntPtrArray(BitConverter.GetBytes((int)ehdr.EType)); foreach (var b in v) { d.Add(b); } /* Handler */ var hand_sym = of.CreateSymbol(); hand_sym.Name = ms.ms.MangleMethod() + "EH" + ehdr.EhdrIdx.ToString(); var hand_reloc = of.CreateRelocation(); hand_reloc.Addend = 0; hand_reloc.DefinedIn = os; hand_reloc.Offset = (ulong)d.Count; hand_reloc.References = hand_sym; hand_reloc.Type = t.GetDataToCodeReloc(); of.AddRelocation(hand_reloc); for (int i = 0; i < t.GetPointerSize(); i++) { d.Add(0); } /* Catch object */ if (ehdr.ClassToken != null) { var catch_sym = of.CreateSymbol(); catch_sym.Name = ehdr.ClassToken.MangleType(); var catch_reloc = of.CreateRelocation(); catch_reloc.Addend = 0; catch_reloc.DefinedIn = os; catch_reloc.Offset = (ulong)d.Count; catch_reloc.References = catch_sym; catch_reloc.Type = t.GetDataToDataReloc(); of.AddRelocation(catch_reloc); s.r.VTableRequestor.Request(ehdr.ClassToken); } else if (ehdr.EType == ExceptionHeader.ExceptionHeaderType.Filter) { var filt_sym = of.CreateSymbol(); filt_sym.Name = ms.ms.MangleMethod() + "EHF" + ehdr.EhdrIdx.ToString(); var filt_reloc = of.CreateRelocation(); filt_reloc.Addend = 0; filt_reloc.DefinedIn = os; filt_reloc.Offset = (ulong)d.Count; filt_reloc.References = filt_sym; filt_reloc.Type = t.GetDataToCodeReloc(); of.AddRelocation(filt_reloc); } for (int i = 0; i < t.GetPointerSize(); i++) { d.Add(0); } } sym.Size = (long)((ulong)d.Count - sym.Offset); }