When initialized data is found in a segment, print the first module where this

data comes from to ease debugging.
This commit is contained in:
Kugel Fuhr
2025-07-10 21:23:41 +02:00
parent 2e3edf9b1b
commit c2f17b6f6b
3 changed files with 29 additions and 13 deletions

View File

@@ -1709,10 +1709,20 @@ static void ProcessSegments (void)
** in any of the object file, check that there's no initialized data ** in any of the object file, check that there's no initialized data
** in the segment. ** in the segment.
*/ */
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) { if ((S->Flags & SF_BSS) != 0 && S->Seg != 0) {
PWarning (GetSourcePos (S->LI), Section* Sec = GetNonBSSSection (S->Seg);
"Segment `%s' with type `bss' contains initialized data", if (Sec) {
GetString (S->Name)); const FilePos* Pos = GetSourcePos (S->LI);
if (Sec->Obj) {
AddPNote (Pos, "Initialized data comes at least partially "
"from `%s'", GetString (Sec->Obj->Name));
} else {
AddPNote (Pos, "Initialized data is at least partially "
"linker generated");
}
PWarning (Pos, "Segment `%s' with type `bss' contains "
"initialized data", GetString (S->Name));
}
} }
/* If this segment does exist in any of the object files, insert the /* If this segment does exist in any of the object files, insert the

View File

@@ -306,9 +306,11 @@ Segment* SegFind (unsigned Name)
int IsBSSType (Segment* S) Section* GetNonBSSSection (Segment* S)
/* Check if the given segment is a BSS style segment, that is, it does not /* Used when checking a BSS style segment for initialized data. Will walk over
** contain non-zero data. ** all sections in S and check if any of them contains initialized data. If so,
** the first section containing initialized data is returned. Otherwise the
** function returns NULL.
*/ */
{ {
/* Loop over all sections */ /* Loop over all sections */
@@ -326,18 +328,20 @@ int IsBSSType (Segment* S)
unsigned long Count = F->Size; unsigned long Count = F->Size;
while (Count--) { while (Count--) {
if (*Data++ != 0) { if (*Data++ != 0) {
return 0; return Sec;
} }
} }
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) { } else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
if (GetExprVal (F->Expr) != 0) { if (GetExprVal (F->Expr) != 0) {
return 0; return Sec;
} }
} }
F = F->Next; F = F->Next;
} }
} }
return 1;
/* No uninitialized data found */
return 0;
} }

View File

@@ -131,9 +131,11 @@ Section* ReadSection (FILE* F, struct ObjData* O);
Segment* SegFind (unsigned Name); Segment* SegFind (unsigned Name);
/* Return the given segment or NULL if not found. */ /* Return the given segment or NULL if not found. */
int IsBSSType (Segment* S); Section* GetNonBSSSection (Segment* S);
/* Check if the given segment is a BSS style segment, that is, it does not /* Used when checking a BSS style segment for initialized data. Will walk over
** contain non-zero data. ** all sections in S and check if any of them contains initialized data. If so,
** the first section containing initialized data is returned. Otherwise the
** function returns NULL.
*/ */
void SegDump (void); void SegDump (void);