Skip to content

Commit

Permalink
COFF: Emit .pdata/.xdata as associative COMDAT sections/symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
filipnavara committed Oct 2, 2023
1 parent f402b72 commit 0b30437
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ protected override void EmitReferencedMethod(string symbolName)
protected override void EmitSymbolTable()
{
var definedSymbols = GetDefinedSymbols();
var sectionSymbol = new string[_sections.Count];

foreach (var (symbolName, symbolDefinition) in definedSymbols)
{
if (symbolDefinition.Value == 0 &&
sectionSymbol[symbolDefinition.SectionIndex] is null)
{
sectionSymbol[symbolDefinition.SectionIndex] = symbolName;
}
}

int sectionIndex = 0;
foreach (var (sectionHeader, _, _, comdatName) in _sections)
Expand Down Expand Up @@ -239,6 +249,17 @@ protected override void EmitSymbolTable()
StorageClass = 2 // IMAGE_SYM_CLASS_EXTERNAL
});
}
else if (sectionSymbol[sectionIndex] is not null)
{
_symbolNameToIndex.Add(sectionSymbol[sectionIndex], (uint)_symbols.Count);
_symbols.Add(new CoffSymbol
{
Name = sectionSymbol[sectionIndex],
Value = 0,
SectionIndex = (uint)(1 + sectionIndex),
StorageClass = 3 // IMAGE_SYM_CLASS_STATIC
});
}
}
sectionIndex++;
}
Expand Down Expand Up @@ -378,8 +399,6 @@ protected override void EmitUnwindInfo(
Span<byte> tempBuffer = stackalloc byte[4];
bool shareSymbol = ShouldShareSymbol((ObjectNode)nodeWithCodeInfo);

pdataSectionWriter = shareSymbol ? GetOrCreateSection(GetSharedSection(PDataSection, currentSymbolName)) : _pdataSectionWriter;

for (int i = 0; i < frameInfos.Length; i++)
{
FrameInfo frameInfo = frameInfos[i];
Expand All @@ -397,11 +416,13 @@ protected override void EmitUnwindInfo(
// and produces errors about duplicate symbols that point into the
// associative section, so we are stuck with one section per each
// unwind symbol.
xdataSectionWriter = GetOrCreateSection(GetSharedSection(ObjectNodeSection.XDataSection, unwindSymbolName));
xdataSectionWriter = GetOrCreateSection(GetSharedSection(ObjectNodeSection.XDataSection, currentSymbolName));
pdataSectionWriter = GetOrCreateSection(GetSharedSection(PDataSection, currentSymbolName));
}
else
{
xdataSectionWriter = _xdataSectionWriter;
pdataSectionWriter = _pdataSectionWriter;
}

// Need to emit the UNWIND_INFO at 4-byte alignment to ensure that the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected sealed record SymbolicRelocation(int Offset, RelocType Type, string Sy
private byte _insPaddingByte;

// Standard sections
private Dictionary<(string, string), int> _sectionNameToSectionIndex = new();
private Dictionary<string, int> _sectionNameToSectionIndex = new();
private List<ObjectWriterStream> _sectionIndexToStream = new();
private List<List<SymbolicRelocation>> _sectionIndexToRelocations = new();

Expand Down Expand Up @@ -79,14 +79,17 @@ protected SectionWriter GetOrCreateSection(ObjectNodeSection section)
int sectionIndex;
ObjectWriterStream sectionStream;

if (!_sectionNameToSectionIndex.TryGetValue((section.Name, section.ComdatName), out sectionIndex))
if (section.ComdatName is not null || !_sectionNameToSectionIndex.TryGetValue(section.Name, out sectionIndex))
{
sectionStream = new ObjectWriterStream(section.Type == SectionType.Executable ? _insPaddingByte : (byte)0);
CreateSection(section, sectionStream);
sectionIndex = _sectionNameToSectionIndex.Count;
_sectionNameToSectionIndex.Add((section.Name, section.ComdatName), sectionIndex);
sectionIndex = _sectionIndexToStream.Count;
_sectionIndexToStream.Add(sectionStream);
_sectionIndexToRelocations.Add(new());
if (section.ComdatName is null)
{
_sectionNameToSectionIndex.Add(section.Name, sectionIndex);
}
}
else
{
Expand Down

0 comments on commit 0b30437

Please sign in to comment.