1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-26 08:32:00 +00:00

Added o65 symbol export capability

git-svn-id: svn://svn.cc65.org/cc65/trunk@1127 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-12-01 17:14:12 +00:00
parent ebbd68673b
commit 90ca5c1af9
5 changed files with 147 additions and 44 deletions

View File

@ -22,7 +22,9 @@ FILES {
%O: format = o65;
}
FORMATS {
o65: os = lunix, type = small, import = LUNIXKERNAL, import = LIB6502;
o65: os = lunix, type = small,
import = LUNIXKERNAL, import = LIB6502,
export = _main;
}
SYMBOLS {
__STACKSIZE__ = $800; # 2K stack

View File

@ -833,6 +833,10 @@ static void ParseO65 (void)
case CFGTOK_EXPORT:
/* We expect an identifier */
CfgAssureIdent ();
/* Check if the export symbol is also defined as an import. */
if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
CfgError ("Exported symbol `%s' cannot be an import", CfgSVal);
}
/* Check if we have this symbol defined already. The entry
* routine will check this also, but we get a more verbose
* error message when checking it here.
@ -847,15 +851,19 @@ static void ParseO65 (void)
case CFGTOK_IMPORT:
/* We expect an identifier */
CfgAssureIdent ();
/* Check if we have this symbol defined already. The entry
* routine will check this also, but we get a more verbose
* error message when checking it here.
*/
if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
CfgError ("Duplicate imported symbol: `%s'", CfgSVal);
}
/* Insert the symbol into the table */
O65SetImport (O65FmtDesc, CfgSVal);
/* Check if the imported symbol is also defined as an export. */
if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
CfgError ("Imported symbol `%s' cannot be an export", CfgSVal);
}
/* Check if we have this symbol defined already. The entry
* routine will check this also, but we get a more verbose
* error message when checking it here.
*/
if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
CfgError ("Duplicate imported symbol: `%s'", CfgSVal);
}
/* Insert the symbol into the table */
O65SetImport (O65FmtDesc, CfgSVal);
break;
case CFGTOK_TYPE:

View File

@ -400,9 +400,9 @@ Export* CreateSegExport (const char* Name, Section* Sec, unsigned long Offs)
static Export* FindExport (const char* Name)
Export* FindExport (const char* Name)
/* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export.
* return a pointer to the export.
*/
{
/* Get a pointer to the list with the symbols hash value */
@ -426,8 +426,14 @@ int IsUnresolved (const char* Name)
/* Check if this symbol is an unresolved export */
{
/* Find the export */
Export* E = FindExport (Name);
return IsUnresolvedExport (FindExport (Name));
}
int IsUnresolvedExport (const Export* E)
/* Return true if the given export is unresolved */
{
/* Check if it's unresolved */
return E != 0 && E->Expr == 0;
}

View File

@ -126,10 +126,18 @@ Export* CreateMemExport (const char* Name, Memory* Mem, unsigned long Offs);
Export* CreateSegExport (const char* Name, Section* S, unsigned long Offs);
/* Create a relative export to a segment (section) */
Export* FindExport (const char* Name);
/* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export.
*/
int IsUnresolved (const char* Name);
/* Check if this symbol is an unresolved export */
int IsConstExport (const Export* E);
int IsUnresolvedExport (const Export* E);
/* Return true if the given export is unresolved */
int IsConstExport (const Export* E);
/* Return true if the expression associated with this export is const */
long GetExportVal (const Export* E);

View File

@ -130,7 +130,7 @@ struct O65RelocTab {
/* Structure describing the format */
struct O65Desc {
O65Header Header; /* File header */
O65Header Header; /* File header */
O65Option* Options; /* List of file options */
ExtSymTab* Exports; /* Table with exported symbols */
ExtSymTab* Imports; /* Table with imported symbols */
@ -168,18 +168,31 @@ struct ExprDesc {
/*****************************************************************************/
/* Helper functions */
/* Helper functions */
/*****************************************************************************/
static ExprDesc* InitExprDesc (ExprDesc* ED, O65Desc* D)
/* Initialize an ExprDesc structure for use with O65ParseExpr */
{
ED->D = D;
ED->Val = 0;
ED->TooComplex = 0;
ED->SegRef = 0;
ED->ExtRef = 0;
return ED;
}
static void WriteSize (const O65Desc* D, unsigned long Val)
/* Write a "size" word to the file */
{
if (D->Header.Mode & MF_SIZE_32BIT) {
Write32 (D->F, Val);
} else {
Write16 (D->F, (unsigned) Val);
switch (D->Header.Mode & MF_SIZE_MASK) {
case MF_SIZE_16BIT: Write16 (D->F, (unsigned) Val); break;
case MF_SIZE_32BIT: Write32 (D->F, Val); break;
default: Internal ("Invalid size in header: %04X", D->Header.Mode);
}
}
@ -297,7 +310,7 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
}
} else {
MarkExport (E);
O65ParseExpr (E->Expr, D, Sign);
O65ParseExpr (E->Expr, D, Sign);
UnmarkExport (E);
}
break;
@ -437,7 +450,7 @@ static void FreeO65Option (O65Option* O)
/*****************************************************************************/
/* Subroutines to write o65 sections */
/* Subroutines to write o65 sections */
/*****************************************************************************/
@ -529,15 +542,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
Expr = E->Left;
}
/* Initialize the descriptor for expression parsing */
ED.D = D;
ED.Val = 0;
ED.TooComplex = 0;
ED.SegRef = 0;
ED.ExtRef = 0;
/* Recursively collect information about this expression */
O65ParseExpr (Expr, &ED, 1);
O65ParseExpr (Expr, InitExprDesc (&ED, D), 1);
/* We cannot handle both, an imported symbol and a segment ref */
if (ED.SegRef != 0 && ED.ExtRef != 0) {
@ -749,20 +755,20 @@ static void O65WriteZPSeg (O65Desc* D, Memory* M attribute ((unused)))
static void O65WriteImports (O65Desc* D)
/* Write the list of imported symbols to the O65 file */
{
const ExtSym* E;
const ExtSym* S;
/* Write the number of external symbols */
/* Write the number of imports */
WriteSize (D, ExtSymCount (D->Imports));
/* Write out the symbol names, zero terminated */
E = ExtSymList (D->Imports);
while (E) {
/* Get the name */
const char* Name = ExtSymName (E);
/* And write it to the output file */
WriteData (D->F, Name, strlen (Name) + 1);
/* Next symbol */
E = ExtSymNext (E);
S = ExtSymList (D->Imports);
while (S) {
/* Get the name */
const char* Name = ExtSymName (S);
/* And write it to the output file */
WriteData (D->F, Name, strlen (Name) + 1);
/* Next symbol */
S = ExtSymNext (S);
}
}
@ -787,10 +793,75 @@ static void O65WriteDataReloc (O65Desc* D)
static void O65WriteExports (O65Desc* D)
/* Write the list of exports */
{
/* Since ld65 creates exectutables, not object files, we do not have
* exports. This may change if we support writing shared libraries...
*/
WriteSize (D, 0);
const ExtSym* S;
/* Write the number of exports */
WriteSize (D, ExtSymCount (D->Exports));
/* Write out the symbol information */
S = ExtSymList (D->Exports);
while (S) {
ExprNode* Expr;
unsigned char SegmentID;
ExprDesc ED;
/* Get the name */
const char* Name = ExtSymName (S);
/* Get the export for this symbol. We've checked before that this
* export does really exist, so if it is unresolved, or if we don't
* find it, there is an error in the linker code.
*/
Export* E = FindExport (Name);
if (E == 0 || IsUnresolvedExport (E)) {
Internal ("Unresolved export `%s' found in O65WriteExports", Name);
}
/* Get the expression for the symbol */
Expr = E->Expr;
/* Recursively collect information about this expression */
O65ParseExpr (Expr, InitExprDesc (&ED, D), 1);
/* We cannot handle expressions with imported symbols here */
if (ED.ExtRef != 0) {
ED.TooComplex = 1;
}
/* Bail out if we cannot handle the expression */
if (ED.TooComplex) {
Error ("Expression for symbol `%s' is too complex", Name);
}
/* Determine the segment id for the expression */
if (ED.SegRef == 0) {
/* Absolute value */
SegmentID = O65SEG_ABS;
} else {
/* Segment reference. Search for the segment and map it to it's
* o65 segmentID
*/
const SegDesc* Seg = O65FindSeg (D, ED.SegRef->Seg);
if (Seg == 0) {
/* For some reason, we didn't find this segment in the list of
* segments written to the o65 file.
*/
Error ("Segment for symbol `%s' is undefined", Name);
}
SegmentID = O65SegType (Seg);
}
/* Write the name to the output file */
WriteData (D->F, Name, strlen (Name) + 1);
/* Output the segment id followed by the literal value */
Write8 (D->F, SegmentID);
WriteSize (D, ED.Val);
/* Next symbol */
S = ExtSymNext (S);
}
}
@ -992,6 +1063,14 @@ ExtSym* O65GetExport (O65Desc* D, const char* Ident)
void O65SetExport (O65Desc* D, const char* Ident)
/* Set an exported identifier */
{
/* Get the export for this symbol and check if it does exist and is
* a resolved symbol.
*/
Export* E = FindExport (Ident);
if (E == 0 || IsUnresolvedExport (E)) {
Error ("Unresolved export: `%s'", Ident);
}
/* Insert the entry into the table */
NewExtSym (D->Exports, Ident);
}