Section* NewSection (Segment* Seg, unsigned long Alignment, unsigned char AddrSize) /* Create a new section for the given segment */ { /* Allocate memory */ Section* S = xmalloc (sizeof (Section)); /* Initialize the data */ S->Next = 0; S->Seg = Seg; S->Obj = 0; S->FragRoot = 0; S->FragLast = 0; S->Size = 0; S->Alignment= Alignment; S->AddrSize = AddrSize; /* Calculate the alignment bytes needed for the section */ S->Fill = AlignCount (Seg->Size, S->Alignment); /* Adjust the segment size and set the section offset */ Seg->Size += S->Fill; S->Offs = Seg->Size; /* Current size is offset */ /* Insert the section into the segment */ CollAppend (&Seg->Sections, S); /* Return the struct */ return S; }
void SegAlign (unsigned long Alignment, int FillVal) /* Align the PC segment to Alignment. If FillVal is -1, emit fill fragments * (the actual fill value will be determined by the linker), otherwise use * the given value. */ { unsigned char Data [4]; unsigned long CombinedAlignment; unsigned long Count; /* The segment must have the combined alignment of all separate alignments * in the source. Calculate this alignment and check it for sanity. */ CombinedAlignment = LeastCommonMultiple (ActiveSeg->Align, Alignment); if (CombinedAlignment > MAX_ALIGNMENT) { Error ("Combined alignment for active segment is %lu which exceeds %lu", CombinedAlignment, MAX_ALIGNMENT); /* Avoid creating large fills for an object file that is thrown away * later. */ Count = 1; } else { ActiveSeg->Align = CombinedAlignment; /* Output a warning for larger alignments if not suppressed */ if (CombinedAlignment > LARGE_ALIGNMENT && !LargeAlignment) { Warning (0, "Combined alignment is suspiciously large (%lu)", CombinedAlignment); } /* Calculate the number of fill bytes */ Count = AlignCount (ActiveSeg->PC, Alignment); } /* Emit the data or a fill fragment */ if (FillVal != -1) { /* User defined fill value */ memset (Data, FillVal, sizeof (Data)); while (Count) { if (Count > sizeof (Data)) { EmitData (Data, sizeof (Data)); Count -= sizeof (Data); } else { EmitData (Data, Count); Count = 0; } } } else { /* Linker defined fill value */ EmitFill (Count); } }