public void AddSections(MapFileBuilder mapFileBuilder) { foreach (Section section in _sections) { mapFileBuilder.AddSection(section); } }
/// <summary> /// Fill in map builder section table. /// </summary> /// <param name="mapFileBuilder">Map file builder to set up</param> public void AddSections(MapFileBuilder mapFileBuilder) { _sectionBuilder.AddSections(mapFileBuilder); }
/// <summary> /// Add an ObjectData block to a given section. /// </summary> /// <param name="data">Block to add</param> /// <param name="sectionIndex">Section index</param> /// <param name="name">Node name to emit in the map file</param> /// <param name="mapFileBuilder">Optional map file to emit</param> public void AddObjectData(ObjectNode.ObjectData objectData, int sectionIndex, string name, MapFileBuilder mapFileBuilder) { Section section = _sections[sectionIndex]; // Calculate alignment padding - apparently ObjectDataBuilder can produce an alignment of 0 int alignedOffset = section.Content.Count; if (objectData.Alignment > 1) { alignedOffset = (section.Content.Count + objectData.Alignment - 1) & -objectData.Alignment; int padding = alignedOffset - section.Content.Count; if (padding > 0) { if ((section.Characteristics & SectionCharacteristics.ContainsCode) != 0) { uint cp = _codePadding; while (padding >= sizeof(uint)) { section.Content.WriteUInt32(cp); padding -= sizeof(uint); } if (padding >= 2) { section.Content.WriteUInt16(unchecked ((ushort)cp)); cp >>= 16; } if ((padding & 1) != 0) { section.Content.WriteByte(unchecked ((byte)cp)); } } else { section.Content.WriteBytes(0, padding); } } } if (mapFileBuilder != null) { MapFileNode node = new MapFileNode(sectionIndex, alignedOffset, objectData.Data.Length, name); mapFileBuilder.AddNode(node); if (objectData.Relocs != null) { foreach (Relocation reloc in objectData.Relocs) { RelocType fileReloc = Relocation.GetFileRelocationType(reloc.RelocType); if (fileReloc != RelocType.IMAGE_REL_BASED_ABSOLUTE) { mapFileBuilder.AddRelocation(node, fileReloc); } } } } section.Content.WriteBytes(objectData.Data); if (objectData.DefinedSymbols != null) { foreach (ISymbolDefinitionNode symbol in objectData.DefinedSymbols) { if (mapFileBuilder != null) { Utf8StringBuilder sb = new Utf8StringBuilder(); symbol.AppendMangledName(GetNameMangler(), sb); int sectionRelativeOffset = alignedOffset + symbol.Offset; mapFileBuilder.AddSymbol(new MapFileSymbol(sectionIndex, sectionRelativeOffset, sb.ToString())); } _symbolMap.Add(symbol, new SymbolTarget( sectionIndex: sectionIndex, offset: alignedOffset + symbol.Offset, size: objectData.Data.Length)); } } if (objectData.Relocs != null && objectData.Relocs.Length != 0) { section.PlacedObjectDataToRelocate.Add(new PlacedObjectData(alignedOffset, objectData)); } }
/// <summary> /// Emit a single object data item into the output R2R PE file using the section builder. /// </summary> /// <param name="objectData">Object data to emit</param> /// <param name="section">Target section</param> /// <param name="name">Textual name of the object data for diagnostic purposese</param> /// <param name="mapFileBuilder">Optional map file builder to output the data item to</param> public void AddObjectData(ObjectNode.ObjectData objectData, ObjectNodeSection section, string name, MapFileBuilder mapFileBuilder) { if (_written) { throw new InternalCompilerErrorException("Inconsistent upstream behavior - AddObjectData mustn't be called after Write"); } int targetSectionIndex; switch (section.Type) { case SectionType.ReadOnly: // We put ReadOnly data into the text section to limit the number of sections. case SectionType.Executable: targetSectionIndex = _textSectionIndex; break; case SectionType.Writeable: targetSectionIndex = _dataSectionIndex; break; default: throw new NotImplementedException(); } _sectionBuilder.AddObjectData(objectData, targetSectionIndex, name, mapFileBuilder); }