public static void OutputStaticFields(metadata.TypeSpec ts, target.Target t, binary_library.IBinaryFile of, MetadataStream base_m = null, binary_library.ISection os = null, binary_library.ISection tlsos = null) { // Don't compile if not for this architecture if (!t.IsTypeValid(ts)) { return; } int align = 1; if (ts.SimpleType == 0) { align = GetTypeAlignment(ts, t, true); } if (os == null) { os = of.GetDataSection(); } os.Align(t.GetPointerSize()); os.Align(align); ulong offset = (ulong)os.Data.Count; ulong tl_offset = 0; if (tlsos != null) { tl_offset = (ulong)tlsos.Data.Count; } int cur_offset = 0; int cur_tloffset = 0; /* is_initialized */ for (int i = 0; i < t.psize; i++) { os.Data.Add(0); } cur_offset += t.psize; /* Iterate through methods looking for requested * one */ var first_fdef = ts.m.GetIntEntry(MetadataStream.tid_TypeDef, ts.tdrow, 4); var last_fdef = ts.m.GetLastFieldDef(ts.tdrow); for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++) { // Ensure field is static or not as required var flags = ts.m.GetIntEntry(MetadataStream.tid_Field, (int)fdef_row, 0); if ((flags & 0x10) == 0x10) { // Increment by type size var fsig = (int)ts.m.GetIntEntry(MetadataStream.tid_Field, (int)fdef_row, 2); var ft = ts.m.GetFieldType(ref fsig, ts.gtparams, null); var ft_size = t.GetSize(ft); ft_size = util.util.align(ft_size, align); bool is_tls = ts.m.thread_local_fields[(int)fdef_row]; ISection cur_os = os; if (is_tls) { if (tlsos == null) { throw new NotSupportedException("No thread-local section provided"); } cur_os = tlsos; } /* See if there is any data defined as an rva */ var rva = ts.m.fieldrvas[(int)fdef_row]; if (rva != 0) { var rrva = (int)ts.m.ResolveRVA(rva); for (int i = 0; i < ft_size; i++) { cur_os.Data.Add(ts.m.file.ReadByte(rrva++)); } } else { for (int i = 0; i < ft_size; i++) { cur_os.Data.Add(0); } } /* Output any additional defined symbols */ foreach (var alias in ts.m.GetFieldAliases((int)fdef_row)) { var asym = of.CreateSymbol(); asym.Name = alias; asym.Offset = offset + (ulong)cur_offset; asym.Type = binary_library.SymbolType.Global; asym.ObjectType = binary_library.SymbolObjectType.Object; cur_os.AddSymbol(asym); asym.Size = ft_size; if (base_m != null && ts.m != base_m) { asym.Type = binary_library.SymbolType.Weak; } } if (is_tls) { cur_tloffset += ft_size; } else { cur_offset += ft_size; } } } if (cur_offset > 0) { /* Add symbol */ var sym = of.CreateSymbol(); sym.Name = ts.m.MangleType(ts) + "S"; sym.Offset = offset; sym.Type = binary_library.SymbolType.Global; sym.ObjectType = binary_library.SymbolObjectType.Object; os.AddSymbol(sym); sym.Size = os.Data.Count - (int)offset; if (base_m != null && ts.m != base_m) { sym.Type = binary_library.SymbolType.Weak; } } if (cur_tloffset > 0) { /* Add thread local symbol */ var sym = of.CreateSymbol(); sym.Name = ts.m.MangleType(ts) + "ST"; sym.Offset = tl_offset; sym.Type = binary_library.SymbolType.Global; sym.ObjectType = binary_library.SymbolObjectType.Object; tlsos.AddSymbol(sym); sym.Size = tlsos.Data.Count - (int)tl_offset; if (base_m != null && ts.m != base_m) { sym.Type = binary_library.SymbolType.Weak; } } }
public override void DoCommand(binary_library.IBinaryFile output, IList <binary_library.IBinaryFile> inputs, LinkerScriptState state) { // Generate a list of sections to include IList <binary_library.ISection> sections = null; switch (selection) { case InputFileSelection.All: sections = new List <binary_library.ISection>(); foreach (binary_library.IBinaryFile ifile in inputs) { binary_library.ISection sect = ifile.FindSection(input_section); if (sect != null) { sections.Add(sect); } } break; case InputFileSelection.AllNotSpecified: sections = new List <binary_library.ISection>(); foreach (binary_library.IBinaryFile ifile in inputs) { binary_library.ISection sect = ifile.FindSection(input_section); if ((sect != null) && (!state.included_sections.Contains(sect))) { sections.Add(sect); } } break; case InputFileSelection.Specific: sections = new List <binary_library.ISection>(); foreach (binary_library.IBinaryFile ifile in inputs) { System.IO.FileInfo fi = new System.IO.FileInfo(ifile.Filename); if (fi.Exists && (fi.Name == input_file)) { binary_library.ISection sect = ifile.FindSection(input_section); if ((sect != null) && (!state.included_sections.Contains(sect))) { sections.Add(sect); } } } break; } // Write the sections data to the section cache and its symbols to the output file binary_library.ISection osect = state.cur_section; foreach (binary_library.ISection sect in sections) { // Write the data if (osect.HasData) { if (sect.HasData) { foreach (byte b in sect.Data) { state.data[osect].Add(b); } } else { for (int i = 0; i < sect.Length; i++) { state.data[osect].Add(0); } } } else { osect.Length += sect.Length; } // Write the symbols int sym_count = sect.GetSymbolCount(); for (int i = 0; i < sym_count; i++) { ISymbol sym = sect.GetSymbol(i); ISymbol new_sym = output.CreateSymbol(); new_sym.Name = sym.Name; new_sym.Offset = state.cur_sect_offset + sym.Offset; new_sym.Size = sym.Size; new_sym.Type = sym.Type; new_sym.ObjectType = sym.ObjectType; osect.AddSymbol(new_sym); } // Save where this section is loaded to state.input_section_locations[sect] = new LinkerScriptState.InputSectionLocation { OutputSection = osect, OutputSectionOffset = state.cur_sect_offset }; state.cur_sect_offset += (ulong)sect.Length; } // Add the sections to the list of included sections state.included_sections.AddRange(sections); }