@@ -34,12 +34,36 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ
3434
3535 protected override ObjectNodeSection GetDehydratedSection ( NodeFactory factory )
3636 {
37- if ( HasCCtorContext
38- || _preinitializationManager . IsPreinitialized ( _type ) )
37+ if ( HasCCtorContext )
3938 {
40- // We have data to be emitted so this needs to be in an initialized data section
39+ // Needs to be writable initialized section because we need info on how to run cctor and whether it ran.
4140 return ObjectNodeSection . DataSection ;
4241 }
42+ else if ( _preinitializationManager . IsPreinitialized ( _type ) )
43+ {
44+ // Unix linkers don't like relocs to readonly data section
45+ if ( ! factory . Target . IsWindows )
46+ return ObjectNodeSection . DataSection ;
47+
48+ ReadOnlyFieldPolicy readOnlyPolicy = _preinitializationManager . ReadOnlyFieldPolicy ;
49+
50+ bool allFieldsReadOnly = true ;
51+ foreach ( FieldDesc field in _type . GetFields ( ) )
52+ {
53+ if ( ! IsNonGcStaticField ( field ) )
54+ continue ;
55+
56+ allFieldsReadOnly = readOnlyPolicy . IsReadOnly ( field ) ;
57+ if ( ! allFieldsReadOnly )
58+ break ;
59+ }
60+
61+ // If all fields are read only, we can place this into a read only section
62+ if ( allFieldsReadOnly )
63+ return ObjectNodeSection . ReadOnlyDataSection ;
64+ else
65+ return ObjectNodeSection . DataSection ;
66+ }
4367 else
4468 {
4569 // This is all zeros; place this to the BSS section
@@ -149,6 +173,9 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
149173 return dependencyList ;
150174 }
151175
176+ private static bool IsNonGcStaticField ( FieldDesc field )
177+ => field . IsStatic && ! field . HasRva && ! field . IsLiteral && ! field . IsThreadStatic && ! field . HasGCStaticBase ;
178+
152179 protected override ObjectData GetDehydratableData ( NodeFactory factory , bool relocsOnly )
153180 {
154181 ObjectDataBuilder builder = new ObjectDataBuilder ( factory , relocsOnly ) ;
@@ -193,7 +220,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
193220 int initialOffset = builder . CountBytes ;
194221 foreach ( FieldDesc field in _type . GetFields ( ) )
195222 {
196- if ( ! field . IsStatic || field . HasRva || field . IsLiteral || field . IsThreadStatic || field . HasGCStaticBase )
223+ if ( ! IsNonGcStaticField ( field ) )
197224 continue ;
198225
199226 int padding = field . Offset . AsInt - builder . CountBytes + initialOffset ;
0 commit comments