/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "xsprintf.h"
/* ld65 */
+#include "alignment.h"
#include "bin.h"
#include "binfmt.h"
#include "cfgexpr.h"
S = xmalloc (sizeof (SegDesc));
/* Initialize the fields */
- S->Name = Name;
- S->LI = GenLineInfo (&CfgErrorPos);
- S->Seg = 0;
- S->Attr = 0;
- S->Flags = 0;
- S->Align = 0;
+ S->Name = Name;
+ S->LI = GenLineInfo (&CfgErrorPos);
+ S->Seg = 0;
+ S->Attr = 0;
+ S->Flags = 0;
+ S->RunAlignment = 1;
+ S->LoadAlignment = 1;
/* Insert the struct into the list ... */
CollAppend (&SegDescList, S);
static void FreeSegDesc (SegDesc* S)
/* Free a segment descriptor */
-{
+{
FreeLineInfo (S->LI);
xfree (S);
}
};
unsigned Count;
- long Val;
/* The MEMORY section must preceed the SEGMENTS section */
if ((SectionsEncountered & SE_MEMORY) == 0) {
case CFGTOK_ALIGN:
FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
- Val = CfgCheckedConstExpr (1, 0x10000);
- S->Align = BitFind (Val);
- if ((0x01L << S->Align) != Val) {
- CfgError (&CfgErrorPos, "Alignment must be a power of 2");
- }
+ S->RunAlignment = (unsigned) CfgCheckedConstExpr (1, MAX_ALIGNMENT);
S->Flags |= SF_ALIGN;
break;
case CFGTOK_ALIGN_LOAD:
FlagAttr (&S->Attr, SA_ALIGN_LOAD, "ALIGN_LOAD");
- Val = CfgCheckedConstExpr (1, 0x10000);
- S->AlignLoad = BitFind (Val);
- if ((0x01L << S->AlignLoad) != Val) {
- CfgError (&CfgErrorPos, "Alignment must be a power of 2");
- }
+ S->LoadAlignment = (unsigned) CfgCheckedConstExpr (1, MAX_ALIGNMENT);
S->Flags |= SF_ALIGN_LOAD;
break;
AttrCheck (AttrFlags, atType, "TYPE");
/* Create the export */
Exp = CreateExprExport (Name, Value, AddrSize);
- CollAppend (&Exp->LineInfos, GenLineInfo (&CfgErrorPos));
+ CollAppend (&Exp->DefLines, GenLineInfo (&CfgErrorPos));
break;
case CfgSymImport:
/* Generate the import */
Imp = InsertImport (GenImport (Name, AddrSize));
/* Remember the file position */
- CollAppend (&Imp->LineInfos, GenLineInfo (&CfgErrorPos));
+ CollAppend (&Imp->DefLines, GenLineInfo (&CfgErrorPos));
break;
case CfgSymWeak:
if ((E = FindExport (Sym->Name)) == 0 || IsUnresolvedExport (E)) {
/* The symbol is undefined, generate an export */
E = CreateExprExport (Sym->Name, Sym->Value, Sym->AddrSize);
- CollAppend (&E->LineInfos, Sym->LI);
+ CollAppend (&E->DefLines, Sym->LI);
}
break;
/* Define the run address of the segment */
SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
- CollAppend (&E->LineInfos, S->LI);
+ CollAppend (&E->DefLines, S->LI);
/* Define the size of the segment */
SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
E = CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
- CollAppend (&E->LineInfos, S->LI);
+ CollAppend (&E->DefLines, S->LI);
S->Flags |= SF_RUN_DEF;
SB_Done (&Buf);
/* Define the load address of the segment */
SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
- CollAppend (&E->LineInfos, S->LI);
+ CollAppend (&E->DefLines, S->LI);
S->Flags |= SF_LOAD_DEF;
SB_Done (&Buf);
/* Define the start of the memory area */
SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), M, 0);
- CollAppend (&E->LineInfos, M->LI);
+ CollAppend (&E->DefLines, M->LI);
SB_Done (&Buf);
}
*/
if (S->Flags & SF_ALIGN) {
/* Align the address */
- unsigned long Val = (0x01UL << S->Align) - 1;
- Addr = (Addr + Val) & ~Val;
+ unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment);
+
+ /* If the first segment placed in the memory area needs
+ * fill bytes for the alignment, emit a warning, since
+ * this is somewhat suspicious.
+ */
+ if (M->FillLevel == 0 && NewAddr > Addr) {
+ CfgWarning (GetSourcePos (S->LI),
+ "First segment in memory area `%s' does "
+ "already need fill bytes for alignment",
+ GetString (M->Name));
+ }
+
+ /* Use the aligned address */
+ Addr = NewAddr;
+
} else if (S->Flags & (SF_OFFSET | SF_START)) {
/* Give the segment a fixed starting address */
unsigned long NewAddr = S->Addr;
*/
if (S->Flags & SF_ALIGN_LOAD) {
/* Align the address */
- unsigned long Val = (0x01UL << S->AlignLoad) - 1;
- Addr = (Addr + Val) & ~Val;
+ Addr = AlignAddr (Addr, S->LoadAlignment);
}
}
/* Define the size of the memory area */
SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
E = CreateConstExport (GetStrBufId (&Buf), M->Size);
- CollAppend (&E->LineInfos, M->LI);
+ CollAppend (&E->DefLines, M->LI);
/* Define the fill level of the memory area */
SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
- CollAppend (&E->LineInfos, M->LI);
+ CollAppend (&E->DefLines, M->LI);
SB_Done (&Buf);
}