From 4dc376b0ee8c4896c259e3b85ff01deb975fbfd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sat, 22 Jul 2017 14:17:27 +0100 Subject: [PATCH 1/8] Save location information of symbol definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now, object files save the file name and line number where each global symbol is defined. Signed-off-by: Antonio Niño Díaz --- include/asm/fstack.h | 2 ++ include/asm/symbol.h | 4 +++- include/link/mylink.h | 2 ++ src/asm/fstack.c | 35 +++++++++++++++++++++++++++++++++-- src/asm/output.c | 3 +++ src/asm/symbol.c | 3 +++ src/link/object.c | 7 ++++++- 7 files changed, 52 insertions(+), 4 deletions(-) diff --git a/include/asm/fstack.h b/include/asm/fstack.h index c77dda4c..3d5b909a 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -41,6 +41,8 @@ extern void fstk_RunRept(ULONG count); FILE * fstk_FindFile(char *); +int fstk_GetLine(void); + extern int yywrap(void); #endif diff --git a/include/asm/symbol.h b/include/asm/symbol.h index 5c2ee729..1099730a 100644 --- a/include/asm/symbol.h +++ b/include/asm/symbol.h @@ -15,7 +15,9 @@ struct sSymbol { struct Section *pSection; ULONG ulMacroSize; char *pMacro; - SLONG(*Callback) (struct sSymbol *); + SLONG(*Callback) (struct sSymbol *); + char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */ + ULONG nFileLine; /* Line where the symbol was defined. */ }; #define SYMF_RELOC 0x001 /* symbol will be reloc'ed during * linking, it's absolute value is diff --git a/include/link/mylink.h b/include/link/mylink.h index 8fc9da1f..88e52549 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -89,6 +89,8 @@ struct sSymbol { SLONG nSectionID; /* internal to object.c */ struct sSection *pSection; SLONG nOffset; + char *pzFileName; /* Source file where the symbol was defined. */ + ULONG nFileLine; /* Line where the symbol was defined. */ }; enum ePatchType { diff --git a/src/asm/fstack.c b/src/asm/fstack.c index c15c0eb1..7b4edede 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -42,8 +42,8 @@ extern FILE *dependfile; /* * defines for nCurrentStatus */ -#define STAT_isInclude 0 -#define STAT_isMacro 1 +#define STAT_isInclude 0 /* 'Normal' state as well */ +#define STAT_isMacro 1 #define STAT_isMacroArg 2 #define STAT_isREPTBlock 3 @@ -151,6 +151,37 @@ popcontext(void) return (1); } +int +fstk_GetLine(void) +{ + struct sContext *pLastFile, **ppLastFile; + + switch (nCurrentStatus) { + case STAT_isInclude: + /* This is the normal mode, also used when including a file. */ + return nLineNo; + case STAT_isMacro: + break; /* Peek top file of the stack */ + case STAT_isMacroArg: + return nLineNo; /* ??? */ + case STAT_isREPTBlock: + break; /* Peek top file of the stack */ + } + + if ((pLastFile = pFileStack) != NULL) { + ppLastFile = &pFileStack; + while (pLastFile->pNext) { + ppLastFile = &(pLastFile->pNext); + pLastFile = *ppLastFile; + } + return pLastFile->nLine; + } + + /* This is only reached if the lexer is in REPT or MACRO mode but there + * are no saved contexts with the origin of said REPT or MACRO. */ + fatalerror("fstk_GetLine: Internal error."); +} + int yywrap(void) { diff --git a/src/asm/output.c b/src/asm/output.c index 34501f78..99044900 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -282,6 +282,9 @@ writesymbol(struct sSymbol * pSym, FILE * f) fputc(type, f); if (type != SYM_IMPORT) { + fputstring(pSym->tzFileName, f); + fputlong(pSym->nFileLine, f); + fputlong(sectid, f); fputlong(offset, f); } diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 23d59b38..2a90aafe 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -8,6 +8,7 @@ #include #include "asm/asm.h" +#include "asm/fstack.h" #include "asm/symbol.h" #include "asm/main.h" #include "asm/mymath.h" @@ -109,6 +110,8 @@ createsymbol(char *s) (*ppsym)->pMacro = NULL; (*ppsym)->pSection = NULL; (*ppsym)->Callback = NULL; + strcpy((*ppsym)->tzFileName, tzCurrentFileName); + (*ppsym)->nFileLine = fstk_GetLine(); return (*ppsym); } else { fatalerror("No memory for symbol"); diff --git a/src/link/object.c b/src/link/object.c index 9da981ac..1f6a2334 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -126,7 +126,12 @@ obj_ReadSymbol(FILE * f) } readasciiz(&pSym->pzName, f); - if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) { + pSym->Type = (enum eSymbolType)fgetc(f); + + if (pSym->Type != SYM_IMPORT) { + readasciiz(&pSym->pzFileName, f); + pSym->nFileLine = readlong(f); + pSym->nSectionID = readlong(f); pSym->nOffset = readlong(f); } From 03bb2d04c3d0211504bc2b6920a64caee3bee260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sun, 9 Jul 2017 15:08:58 +0100 Subject: [PATCH 2/8] Increment version number of object files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous change has broken compatibility of object files, so it is needed to increment the version number to make the linker reject files generated with the old code. Signed-off-by: Antonio Niño Díaz --- src/asm/output.c | 2 +- src/link/object.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/asm/output.c b/src/asm/output.c index 99044900..34c6766e 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -504,7 +504,7 @@ out_WriteObject(void) struct PatchSymbol *pSym; struct Section *pSect; - fwrite("RGB4", 1, 4, f); + fwrite("RGB5", 1, 4, f); fputlong(countsymbols(), f); fputlong(countsections(), f); diff --git a/src/link/object.c b/src/link/object.c index 1f6a2334..1e40eb83 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -336,8 +336,7 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile) tzHeader[4] = 0; if (strncmp(tzHeader, "RGB", 3) == 0) { switch (tzHeader[3]) { - case '3': - case '4': // V4 supports OAM sections, but is otherwise identical + case '5': obj_ReadRGB(pObjfile); break; default: From df25fa73af3033d58a33e892d279862434a2c6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sun, 9 Jul 2017 15:34:00 +0100 Subject: [PATCH 3/8] Update documentation of object files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Niño Díaz --- src/rgbds.5 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rgbds.5 b/src/rgbds.5 index 781a1eb0..67efb6f1 100644 --- a/src/rgbds.5 +++ b/src/rgbds.5 @@ -42,7 +42,7 @@ is a 0‐terminated string of .Bd -literal ; Header -BYTE ID[4] ; "RGB4" +BYTE ID[4] ; "RGB5" LONG NumberOfSymbols ; The number of symbols used in this file LONG NumberOfSections ; The number of sections used in this file @@ -59,6 +59,10 @@ REPT NumberOfSymbols ; Number of symbols defined in this object file. IF Type != 1 ; If symbol is defined in this object file. + STRING FileName ; File where the symbol is defined. + + LONG LineNum ; Line number in the file where the symbol is defined. + LONG SectionID ; The section number (of this object file) in which ; this symbol is defined. From 4e2a035838630e736111af8235370e12e51a6170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sun, 9 Jul 2017 15:09:03 +0100 Subject: [PATCH 4/8] Print location of definition of redefined symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When trying to define a symbol with a name that is used by another one, print the location of the first definition in the error message. Signed-off-by: Antonio Niño Díaz --- src/asm/symbol.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 2a90aafe..856826db 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -521,7 +521,8 @@ sym_AddEqu(char *tzSym, SLONG value) if ((nsym = findsymbol(tzSym, NULL)) != NULL) { if (nsym->nType & SYMF_DEFINED) { - yyerror("'%s' already defined", tzSym); + yyerror("'%s' already defined in %s(%d)", + tzSym, nsym->tzFileName, nsym->nFileLine); } } else nsym = createsymbol(tzSym); @@ -553,7 +554,8 @@ sym_AddString(char *tzSym, char *tzValue) if ((nsym = findsymbol(tzSym, NULL)) != NULL) { if (nsym->nType & SYMF_DEFINED) { - yyerror("'%s' already defined", tzSym); + yyerror("'%s' already defined in %s(%d)", + tzSym, nsym->tzFileName, nsym->nFileLine); } } else nsym = createsymbol(tzSym); @@ -656,7 +658,8 @@ sym_AddReloc(char *tzSym) if ((nsym = findsymbol(tzSym, scope)) != NULL) { if (nsym->nType & SYMF_DEFINED) { - yyerror("'%s' already defined", tzSym); + yyerror("'%s' already defined in %s(%d)", + tzSym, nsym->tzFileName, nsym->nFileLine); } } else nsym = createsymbol(tzSym); @@ -785,7 +788,8 @@ sym_AddMacro(char *tzSym) if ((nsym = findsymbol(tzSym, NULL)) != NULL) { if (nsym->nType & SYMF_DEFINED) { - yyerror("'%s' already defined", tzSym); + yyerror("'%s' already defined in %s(%d)", + tzSym, nsym->tzFileName, nsym->nFileLine); } } else nsym = createsymbol(tzSym); From 92449a4fe4f13a8e45f0589985351b80a45fa941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sat, 22 Jul 2017 15:16:38 +0100 Subject: [PATCH 5/8] Save object file name of each symbol in linker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is useful to generate error messages when there is a symbol that appears in more than one object file. Signed-off-by: Antonio Niño Díaz --- include/link/mylink.h | 1 + include/link/symbol.h | 3 ++- src/link/assign.c | 23 ++++++++++++++--------- src/link/object.c | 10 ++++++---- src/link/symbol.c | 14 +++++++++++--- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/include/link/mylink.h b/include/link/mylink.h index 88e52549..36be7ae2 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -89,6 +89,7 @@ struct sSymbol { SLONG nSectionID; /* internal to object.c */ struct sSection *pSection; SLONG nOffset; + char *pzObjFileName; /* Object file where the symbol is located. */ char *pzFileName; /* Source file where the symbol was defined. */ ULONG nFileLine; /* Line where the symbol was defined. */ }; diff --git a/include/link/symbol.h b/include/link/symbol.h index 29fdfdcf..806b12da 100644 --- a/include/link/symbol.h +++ b/include/link/symbol.h @@ -4,7 +4,8 @@ #include "types.h" void sym_Init(void); -void sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank); +void sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank, + char *tzObjFileName, char *tzFileName, ULONG nFileLine); SLONG sym_GetValue(char *tzName); SLONG sym_GetBank(char *tzName); diff --git a/src/link/assign.c b/src/link/assign.c index 61481265..35f8759f 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -566,16 +566,21 @@ CreateSymbolTable(void) ((pSect->tSymbols[i]->pSection == pSect) || (pSect->tSymbols[i]->pSection == NULL))) { if (pSect->tSymbols[i]->pSection == NULL) - sym_CreateSymbol(pSect->tSymbols[i]-> - pzName, - pSect->tSymbols[i]-> - nOffset, -1); + sym_CreateSymbol( + pSect->tSymbols[i]->pzName, + pSect->tSymbols[i]->nOffset, + -1, + pSect->tSymbols[i]->pzObjFileName, + pSect->tSymbols[i]->pzFileName, + pSect->tSymbols[i]->nFileLine); else - sym_CreateSymbol(pSect->tSymbols[i]-> - pzName, - pSect->nOrg + - pSect->tSymbols[i]-> - nOffset, pSect->nBank); + sym_CreateSymbol( + pSect->tSymbols[i]->pzName, + pSect->nOrg + pSect->tSymbols[i]->nOffset, + pSect->nBank, + pSect->tSymbols[i]->pzObjFileName, + pSect->tSymbols[i]->pzFileName, + pSect->tSymbols[i]->nFileLine); } } pSect = pSect->pNext; diff --git a/src/link/object.c b/src/link/object.c index 1e40eb83..770f6604 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -116,7 +116,7 @@ AllocSection(void) */ struct sSymbol * -obj_ReadSymbol(FILE * f) +obj_ReadSymbol(FILE * f, char *tzObjectfile) { struct sSymbol *pSym; @@ -128,6 +128,8 @@ obj_ReadSymbol(FILE * f) readasciiz(&pSym->pzName, f); pSym->Type = (enum eSymbolType)fgetc(f); + pSym->pzObjFileName = tzObjectfile; + if (pSym->Type != SYM_IMPORT) { readasciiz(&pSym->pzFileName, f); pSym->nFileLine = readlong(f); @@ -268,7 +270,7 @@ obj_ReadRGBSection(FILE * f) } void -obj_ReadRGB(FILE * pObjfile) +obj_ReadRGB(FILE * pObjfile, char *tzObjectfile) { struct sSection *pFirstSection; SLONG nNumberOfSymbols, nNumberOfSections, i; @@ -285,7 +287,7 @@ obj_ReadRGB(FILE * pObjfile) } for (i = 0; i < nNumberOfSymbols; i += 1) - tSymbols[i] = obj_ReadSymbol(pObjfile); + tSymbols[i] = obj_ReadSymbol(pObjfile, tzObjectfile); } else tSymbols = (struct sSymbol **) & dummymem; @@ -337,7 +339,7 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile) if (strncmp(tzHeader, "RGB", 3) == 0) { switch (tzHeader[3]) { case '5': - obj_ReadRGB(pObjfile); + obj_ReadRGB(pObjfile, tzObjectfile); break; default: errx(1, "'%s' uses an unsupported object file version (%s). Please reassemble it.", tzObjectfile, tzHeader); diff --git a/src/link/symbol.c b/src/link/symbol.c index b53cbb67..2053eab5 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.c @@ -12,8 +12,10 @@ struct ISymbol { char *pzName; SLONG nValue; - SLONG nBank; - //-1 = const + SLONG nBank; /* -1 = constant */ + char tzObjFileName[_MAX_PATH + 1]; /* Object file where the symbol was defined. */ + char tzFileName[_MAX_PATH + 1]; /* Source file where the symbol was defined. */ + ULONG nFileLine; /* Line where the symbol was defined. */ struct ISymbol *pNext; }; @@ -76,7 +78,8 @@ sym_GetBank(char *tzName) } void -sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank) +sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank, char *tzObjFileName, + char *tzFileName, ULONG nFileLine) { if (strcmp(tzName, "@") == 0) return; @@ -102,6 +105,11 @@ sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank) (*ppSym)->nValue = nValue; (*ppSym)->nBank = nBank; (*ppSym)->pNext = NULL; + strncpy((*ppSym)->tzObjFileName, tzObjFileName, + sizeof((*ppSym)->tzObjFileName)); + strncpy((*ppSym)->tzFileName, tzFileName, + sizeof((*ppSym)->tzFileName)); + (*ppSym)->nFileLine = nFileLine; } } } From c00f7409ee165b19ecb6ca6c3d366fd376ab06f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sat, 22 Jul 2017 15:16:43 +0100 Subject: [PATCH 6/8] Improve linker symbol redefinition error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now, the object file in which each definition is (as well as the source file and line) are printed with the error message. Signed-off-by: Antonio Niño Díaz --- src/link/symbol.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/link/symbol.c b/src/link/symbol.c index 2053eab5..10e51c49 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.c @@ -95,7 +95,10 @@ sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank, char *tzObjFileName, if (nBank == -1) return; - errx(1, "Symbol '%s' defined more than once", tzName); + errx(1, "'%s' in both %s : %s(%d) and %s : %s(%d)", + tzName, tzObjFileName, tzFileName, nFileLine, + (*ppSym)->tzObjFileName, + (*ppSym)->tzFileName, (*ppSym)->nFileLine); } } From 840ddcecd2965a2b7301944e5bf47d01a1fba353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sat, 22 Jul 2017 15:31:39 +0100 Subject: [PATCH 7/8] Update dates in manpages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Niño Díaz --- src/asm/rgbasm.5 | 2 +- src/rgbds.5 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5 index c9469890..047ae5ff 100644 --- a/src/asm/rgbasm.5 +++ b/src/asm/rgbasm.5 @@ -12,7 +12,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd April 17, 2017 +.Dd July 22, 2017 .Dt RGBASM 5 .Os RGBDS Manual .Sh NAME diff --git a/src/rgbds.5 b/src/rgbds.5 index 67efb6f1..81b87d52 100644 --- a/src/rgbds.5 +++ b/src/rgbds.5 @@ -12,7 +12,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd April 17, 2017 +.Dd July 22, 2017 .Dt RGBDS 5 .Os RGBDS Manual .Sh NAME From ec171c5f00cf6577e421e28ece288221e4bae62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Sat, 29 Jul 2017 13:11:26 +0100 Subject: [PATCH 8/8] Make object file magic string a common define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Niño Díaz --- include/common.h | 6 ++++++ src/asm/output.c | 5 ++++- src/link/object.c | 28 ++++++++++++++++------------ 3 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 include/common.h diff --git a/include/common.h b/include/common.h new file mode 100644 index 00000000..8c4bd395 --- /dev/null +++ b/include/common.h @@ -0,0 +1,6 @@ +#ifndef RGBDS_COMMON_H +#define RGBDS_COMMON_H + +#define RGBDS_OBJECT_VERSION_STRING "RGB5" + +#endif /* RGBDS_COMMON_H */ diff --git a/src/asm/output.c b/src/asm/output.c index 34c6766e..ff0a1a30 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -15,6 +15,7 @@ #include "asm/main.h" #include "asm/rpn.h" #include "asm/fstack.h" +#include "common.h" #include "extern/err.h" void out_SetCurrentSection(struct Section * pSect); @@ -504,7 +505,9 @@ out_WriteObject(void) struct PatchSymbol *pSym; struct Section *pSect; - fwrite("RGB5", 1, 4, f); + fwrite(RGBDS_OBJECT_VERSION_STRING, 1, + strlen(RGBDS_OBJECT_VERSION_STRING), f); + fputlong(countsymbols(), f); fputlong(countsections(), f); diff --git a/src/link/object.c b/src/link/object.c index 770f6604..5b2fd8cf 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -3,11 +3,13 @@ * */ +#include #include #include #include #include +#include "common.h" #include "extern/err.h" #include "link/assign.h" #include "link/mylink.h" @@ -332,20 +334,22 @@ obj_ReadRGB(FILE * pObjfile, char *tzObjectfile) void obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile) { - char tzHeader[8]; + char tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING) + 1]; - fread(tzHeader, sizeof(char), 4, pObjfile); - tzHeader[4] = 0; - if (strncmp(tzHeader, "RGB", 3) == 0) { - switch (tzHeader[3]) { - case '5': - obj_ReadRGB(pObjfile, tzObjectfile); - break; - default: - errx(1, "'%s' uses an unsupported object file version (%s). Please reassemble it.", tzObjectfile, tzHeader); - } + fread(tzHeader, sizeof(char), strlen(RGBDS_OBJECT_VERSION_STRING), + pObjfile); + + tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING)] = 0; + + if (strncmp(tzHeader, RGBDS_OBJECT_VERSION_STRING, + strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) { + obj_ReadRGB(pObjfile, tzObjectfile); } else { - errx(1, "'%s' is not a valid object", tzObjectfile); + for (int i = 0; i < strlen(RGBDS_OBJECT_VERSION_STRING); i++) + if (!isprint(tzHeader[i])) + tzHeader[i] = '?'; + errx(1, "%s: Invalid file or object file version [%s]", + tzObjectfile, tzHeader); } }