int enum_symbols (FILE * fp, long size, int (*func) (const char *sym, void *param), void *param) { long end; struct dbuf_s buf; struct dbuf_s symname; assert (func != NULL); dbuf_init (&buf, 512); dbuf_init (&symname, 32); end = (size >= 0) ? ftell (fp) + size : -1; /* * Read in the object file. Look for lines that * begin with "S" and end with "D". These are * symbol table definitions. If we find one, see * if it is our symbol. Make sure we only read in * our object file and don't go into the next one. */ while (end < 0 || ftell (fp) < end) { const char *p; dbuf_set_length (&buf, 0); if (dbuf_getline (&buf, fp) == 0) break; p = dbuf_c_str (&buf); if ('T' == p[0]) break; /* * Skip everything that's not a symbol record. */ if ('S' == p[0] && ' ' == p[1]) { dbuf_set_length (&symname, 0); for (p += 2; *p && ' ' != *p; ++p) dbuf_append_char (&symname, *p); /* If it's an actual symbol, record it */ if (' ' == p[0] && 'D' == p[1]) if (func != NULL) if ((*func) (dbuf_c_str (&symname), NULL)) return 1; } } dbuf_destroy (&buf); dbuf_destroy (&symname); return 0; }
/*-----------------------------------------------------------------*/ FILE * createDumpFile (int id) { struct _dumpFiles *dumpFilesPtr = dumpFiles; static int dumpIndex = 0; static char dumpIndexStr[32]; while (dumpFilesPtr->id) { if (dumpFilesPtr->id == id) break; dumpFilesPtr++; } if (!dumpFilesPtr->id) { fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n"); exit (1); } sprintf (dumpIndexStr, ".%d", dumpIndex); dumpIndex++; if (!dumpFilesPtr->filePtr) { // not used before, create it struct dbuf_s dumpFileName; dbuf_init (&dumpFileName, PATH_MAX); dbuf_append_str (&dumpFileName, dstFileName); #ifdef _DEBUG dbuf_append_str (&dumpFileName, dumpIndexStr); #endif dbuf_append_str (&dumpFileName, dumpFilesPtr->ext); if (!(dumpFilesPtr->filePtr = fopen (dbuf_c_str (&dumpFileName), "w"))) { werror (E_FILE_OPEN_ERR, dbuf_c_str (&dumpFileName)); dbuf_destroy (&dumpFileName); exit (1); } dbuf_destroy (&dumpFileName); } #if 0 fprintf (dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex); #endif return dumpFilesPtr->filePtr; }
static void _gbz80_rgblink (void) { FILE *lnkfile; struct dbuf_s lnkFileName; char *buffer; dbuf_init (&lnkFileName, PATH_MAX); /* first we need to create the <filename>.lnk file */ dbuf_append_str (&lnkFileName, dstFileName); dbuf_append_str (&lnkFileName, ".lk"); if (!(lnkfile = fopen (dbuf_c_str (&lnkFileName), "w"))) { werror (E_FILE_OPEN_ERR, dbuf_c_str (&lnkFileName)); dbuf_destroy (&lnkFileName); exit (1); } dbuf_destroy (&lnkFileName); fprintf (lnkfile, "[Objects]\n"); fprintf (lnkfile, "%s.rel\n", dstFileName); fputStrSet (lnkfile, relFilesSet); fprintf (lnkfile, "\n[Libraries]\n"); /* additional libraries if any */ fputStrSet (lnkfile, libFilesSet); fprintf (lnkfile, "\n[Output]\n" "%s.gb", dstFileName); fclose (lnkfile); buffer = buildCmdLine (port->linker.cmd, dstFileName, NULL, NULL, NULL); /* call the linker */ if (sdcc_system (buffer)) { Safe_free (buffer); perror ("Cannot exec linker"); exit (1); } Safe_free (buffer); }
VOID DefineSDCC_Line (void) { struct dbuf_s dbuf; struct sym *pSym; /* * Symbol is A$FILE$nnn */ dbuf_init (&dbuf, NCPS); dbuf_printf (&dbuf, "A$%s$%u", BaseFileName (cfile, 1), srcline[cfile]); pSym = lookup (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); pSym->s_type = S_USER; pSym->s_area = dot.s_area; pSym->s_addr = laddr; pSym->s_flag |= S_GBL; }
VOID DefineNoICE_Line (void) { struct dbuf_s dbuf; struct sym *pSym; /* * Symbol is FILE.nnn */ dbuf_init (&dbuf, NCPS); dbuf_printf (&dbuf, "%s.%u", BaseFileName (asmc, 0), srcline); pSym = lookup (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); pSym->s_type = S_USER; pSym->s_area = dot.s_area; pSym->s_addr = laddr; pSym->s_flag |= S_GBL; }
/*-----------------------------------------------------------------*/ void picglue () { FILE *asmFile; struct dbuf_s ovrBuf; struct dbuf_s vBuf; dbuf_init(&ovrBuf, 4096); dbuf_init(&vBuf, 4096); pCodeInitRegisters(); /* check for main() */ mainf = newSymbol ("main", 0); mainf->block = 0; mainf = findSymWithLevel (SymbolTab, mainf); if (!mainf || !IFFUNC_HASBODY(mainf->type)) { /* main missing -- import stack from main module */ //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n"); pic14_options.isLibrarySource = 1; } /* At this point we've got all the code in the form of pCode structures */ /* Now it needs to be rearranged into the order it should be placed in the */ /* code space */ movepBlock2Head('P'); // Last movepBlock2Head(code->dbName); movepBlock2Head('X'); movepBlock2Head(statsg->dbName); // First /* print the global struct definitions */ if (options.debug) cdbStructBlock (0); /* do the overlay segments */ pic14emitOverlay(&ovrBuf); /* PENDING: this isnt the best place but it will do */ if (port->general.glue_up_main) { /* create the interrupt vector table */ pic14createInterruptVect (&vBuf); } AnalyzepCode('*'); ReuseReg(); // ReuseReg where call tree permits InlinepCode(); AnalyzepCode('*'); if (options.debug) pcode_test(); /* now put it all together into the assembler file */ /* create the assembler file name */ if ((noAssemble || options.c1mode) && fullDstFileName) { sprintf (buffer, "%s", fullDstFileName); } else { sprintf (buffer, "%s", dstFileName); strcat (buffer, ".asm"); } if (!(asmFile = fopen (buffer, "w"))) { werror (E_FILE_OPEN_ERR, buffer); exit (1); } /* prepare statistics */ resetpCodeStatistics (); /* initial comments */ pic14initialComments (asmFile); /* print module name */ fprintf (asmFile, "%s\t.file\t\"%s\"\n", options.debug ? "" : ";", fullSrcFileName); /* Let the port generate any global directives, etc. */ if (port->genAssemblerPreamble) { port->genAssemblerPreamble(asmFile); } /* Put all variables into a cblock */ AnalyzeBanking(); /* emit initialized data */ showAllMemmaps(asmFile); /* print the locally defined variables in this module */ writeUsedRegs(asmFile); /* create the overlay segments */ fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; overlayable items in internal ram \n"); fprintf (asmFile, "%s", iComments2); dbuf_write_and_destroy (&ovrBuf, asmFile); /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) dbuf_write_and_destroy (&vBuf, asmFile); else dbuf_destroy(&vBuf); /* create interupt ventor handler */ pic14_emitInterruptHandler (asmFile); /* copy over code */ fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; code\n"); fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name); /* unknown */ copypCode(asmFile, 'X'); /* _main function */ copypCode(asmFile, 'M'); /* other functions */ copypCode(asmFile, code->dbName); /* unknown */ copypCode(asmFile, 'P'); dumppCodeStatistics (asmFile); fprintf (asmFile,"\tend\n"); fclose (asmFile); pic14_debugLogClose(); }
int enum_symbols (FILE * fp, long size, int (*func) (const char *sym, void *param), void *param) { long end; struct dbuf_s buf; struct dbuf_s symname; assert (func != NULL); dbuf_init (&buf, 512); dbuf_init (&symname, 32); end = (size >= 0) ? ftell (fp) + size : -1; /* * Read in the object file. Look for lines that * begin with "S" and end with "D". These are * symbol table definitions. If we find one, see * if it is our symbol. Make sure we only read in * our object file and don't go into the next one. */ while (end < 0 || ftell (fp) < end) { const char *p; dbuf_set_length (&buf, 0); if (dbuf_getline (&buf, fp) == 0) break; p = dbuf_c_str (&buf); /* Skip whitespace */ while (isspace (*p)) p++; /* Skip local symbols or directives */ if ('.' == p[0]) continue; /* * Skip everything that's not a symbol. */ if (isalpha (*p) || '_' == *p) { bool found = false; dbuf_set_length (&symname, 0); while (isalnum (*p) || '_' == *p) dbuf_append_char (&symname, *p++); if (':' == *p) /* a label */ { if (':' == *++p) /* a global label */ found = true; } else /* no label */ { size_t i; /* Skip whitespace */ while (isspace (*p)) p++; for (found = false, i = 0; !found && i < sizeof(directives) / sizeof(symbol_t); i++) { if (0 == strncmp(p, directives[i].text, strlen(directives[i].text))) { switch (directives[i].subtype) { case stEQU: case stBYTE: case stWORD_BE: case stWORD_LE: case stLONG_BE: case stLONG_LE: case stBUFFER: case stTEXT: case stDS: case stDSIN: case stDSOUT: case stDSIO: case stDSROM: case stDSRAM: /* It's a symbol */ found = true; break; default: break; } } } } /* If it's an actual symbol, record it */ if (found) if (func != NULL) if ((*func) (dbuf_c_str (&symname), NULL)) return 1; } } dbuf_destroy (&buf); dbuf_destroy (&symname); return 0; }
void dbuf_delete(struct dbuf_s *dbuf) { dbuf_destroy(dbuf); free(dbuf); }
static void _pic14_do_link (void) { /* * link command format: * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs} * */ #define LFRM "{linker} {incdirs} {sysincdirs} {lflags} -w -r -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}" hTab *linkValues = NULL; char *lcmd; set *tSet = NULL; int ret; char * procName; shash_add (&linkValues, "linker", "gplink"); /* LIBRARY SEARCH DIRS */ mergeSets (&tSet, libPathsSet); mergeSets (&tSet, libDirsSet); shash_add (&linkValues, "incdirs", joinStrSet (processStrSet (tSet, "-I", NULL, shell_escape))); joinStrSet (processStrSet (libDirsSet, "-I", NULL, shell_escape)); shash_add (&linkValues, "sysincdirs", joinStrSet (processStrSet (libDirsSet, "-I", NULL, shell_escape))); shash_add (&linkValues, "lflags", joinStrSet (linkOptionsSet)); { char *s = shell_escape (fullDstFileName ? fullDstFileName : dstFileName); shash_add (&linkValues, "outfile", s); Safe_free (s); } if (fullSrcFileName) { struct dbuf_s dbuf; char *s; dbuf_init (&dbuf, 128); dbuf_append_str (&dbuf, fullDstFileName ? fullDstFileName : dstFileName); dbuf_append (&dbuf, ".o", 2); s = shell_escape (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); shash_add (&linkValues, "user_ofile", s); Safe_free (s); } shash_add (&linkValues, "ofiles", joinStrSet (processStrSet (relFilesSet, NULL, NULL, shell_escape))); /* LIBRARIES */ procName = processor_base_name (); if (!procName) procName = "16f877"; addSet (&libFilesSet, Safe_strdup (pic14_getPIC()->isEnhancedCore ? "libsdcce.lib" : "libsdcc.lib")); { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_append (&dbuf, "pic", sizeof ("pic") - 1); dbuf_append_str (&dbuf, procName); dbuf_append (&dbuf, ".lib", sizeof (".lib") - 1); addSet (&libFilesSet, dbuf_detach_c_str (&dbuf)); } shash_add (&linkValues, "libs", joinStrSet (processStrSet (libFilesSet, NULL, NULL, shell_escape))); lcmd = msprintf(linkValues, LFRM); ret = sdcc_system (lcmd); Safe_free (lcmd); if (ret) exit (1); }
static void _setValues(void) { const char *s; if (options.nostdlib == FALSE) { const char *s; char path[PATH_MAX]; struct dbuf_s dbuf; dbuf_init(&dbuf, PATH_MAX); for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet)) { buildCmdLine2(path, sizeof path, "-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s); dbuf_append_str(&dbuf, path); } buildCmdLine2(path, sizeof path, "-l\"{port}.lib\"", s); dbuf_append_str(&dbuf, path); setMainValue ("z80libspec", dbuf_c_str(&dbuf)); dbuf_destroy(&dbuf); for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet)) { struct stat stat_buf; buildCmdLine2(path, sizeof path, "%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s); if (stat(path, &stat_buf) == 0) break; } if (s == NULL) setMainValue ("z80crt0", "\"crt0{objext}\""); else { char *buf; size_t len = strlen(path) + 3; buf = Safe_alloc(len); SNPRINTF(buf, len, "\"%s\"", path); setMainValue("z80crt0", buf); Safe_free(buf); } } else { setMainValue ("z80libspec", ""); setMainValue ("z80crt0", ""); } setMainValue ("z80extralibfiles", (s = joinStrSet(libFilesSet))); Safe_free((void *)s); setMainValue ("z80extralibpaths", (s = joinStrSet(libPathsSet))); Safe_free((void *)s); if (IS_GB) { setMainValue ("z80outputtypeflag", "-Z"); setMainValue ("z80outext", ".gb"); } else { setMainValue ("z80outputtypeflag", "-i"); setMainValue ("z80outext", ".ihx"); } setMainValue ("stdobjdstfilename" , "{dstfilename}{objext}"); setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}"); setMainValue ("z80extraobj", (s = joinStrSet(relFilesSet))); Safe_free((void *)s); sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc); setMainValue ("z80bases", buffer); }
/*-----------------------------------------------------------------*/ static symbol * createStackSpil (symbol * sym) { symbol *sloc = NULL; struct dbuf_s dbuf; D (D_ALLOC, ("createStackSpil: for sym %p %s\n", sym, sym->name)); /* first go try and find a free one that is already existing on the stack */ if (applyToSet (_G.stackSpil, isFreeSTM8, &sloc, sym)) { /* found a free one : just update & return */ sym->usl.spillLoc = sloc; sym->stackSpil = 1; sloc->isFree = 0; addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: found existing\n")); return sym; } /* could not then have to create one , this is the hard part we need to allocate this on the stack : this is really a hack!! but cannot think of anything better at this time */ dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "sloc%d", _G.slocNum++); sloc = newiTemp (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); SPEC_SCLS (sloc->etype) = S_AUTO; SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE (sloc->etype) = 0; allocLocal (sloc); sloc->isref = 1; /* to prevent compiler warning */ wassertl (currFunc, "Local variable used outside of function."); /* if it is on the stack then update the stack */ if (IN_STACK (sloc->etype)) { if (currFunc) currFunc->stack += getSize (sloc->type); _G.stackExtend += getSize (sloc->type); } else { _G.dataExtend += getSize (sloc->type); } /* add it to the stackSpil set */ addSetHead (&_G.stackSpil, sloc); sym->usl.spillLoc = sloc; sym->stackSpil = 1; /* add it to the set of itempStack set of the spill location */ addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: created new\n")); return sym; }
/*-----------------------------------------------------------------*/ eBBlock * iCode2eBBlock (iCode * ic) { iCode *loop; eBBlock *ebb = neweBBlock (); /* allocate an entry */ /* put the first one unconditionally */ ebb->sch = ic; ic->seq = 0; /* if this is a label then */ if (ic->op == LABEL) ebb->entryLabel = ic->label; else { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "_eBBlock%d", eBBNum++); ebb->entryLabel = newSymbol (dbuf_c_str (&dbuf), 1); dbuf_destroy (&dbuf); ebb->entryLabel->key = labelKey++; } if (ic && (ic->op == GOTO || ic->op == JUMPTABLE || ic->op == IFX)) { ebb->ech = ebb->sch; return ebb; } /* if this is a function call */ if (ic->op == CALL || ic->op == PCALL) { sym_link *type = operandType (IC_LEFT (ic)); ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL (currFunc->type) = 1; if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) { ebb->ech = ebb->sch; return ebb; } } if ((ic->next && ic->next->op == LABEL) || !ic->next) { ebb->ech = ebb->sch; return ebb; } /* loop thru till we find one with a label */ for (loop = ic->next; loop; loop = loop->next) { loop->seq = 0; /* if this is the last one */ if (!loop->next) break; /* if this is a function call */ if (loop->op == CALL || loop->op == PCALL) { sym_link *type = operandType (IC_LEFT (loop)); ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL (currFunc->type) = 1; if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) break; } /* if the next one is a label */ /* if this is a goto or ifx */ if (loop->next->op == LABEL || loop->op == GOTO || loop->op == JUMPTABLE || loop->op == IFX) break; } /* mark the end of the chain */ ebb->ech = loop; return ebb; }
static void _setValues (void) { const char *s; struct dbuf_s dbuf; if (options.nostdlib == FALSE) { const char *s; char *path; struct dbuf_s dbuf; dbuf_init (&dbuf, PATH_MAX); for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet)) { path = buildCmdLine2 ("-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s); dbuf_append_str (&dbuf, path); Safe_free (path); } path = buildCmdLine2 ("-l\"{port}.lib\"", s); dbuf_append_str (&dbuf, path); Safe_free (path); setMainValue ("z80libspec", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet)) { struct stat stat_buf; path = buildCmdLine2 ("%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s); if (stat (path, &stat_buf) == 0) { Safe_free (path); break; } else Safe_free (path); } if (s == NULL) setMainValue ("z80crt0", "\"crt0{objext}\""); else { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "\"%s\"", path); setMainValue ("z80crt0", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); } } else { setMainValue ("z80libspec", ""); setMainValue ("z80crt0", ""); } setMainValue ("z80extralibfiles", (s = joinStrSet (libFilesSet))); Safe_free ((void *) s); setMainValue ("z80extralibpaths", (s = joinStrSet (libPathsSet))); Safe_free ((void *) s); if (IS_GB) { setMainValue ("z80outputtypeflag", "-Z"); setMainValue ("z80outext", ".gb"); } else { setMainValue ("z80outputtypeflag", "-i"); setMainValue ("z80outext", ".ihx"); } setMainValue ("stdobjdstfilename", "{dstfilename}{objext}"); setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}"); setMainValue ("z80extraobj", (s = joinStrSet (relFilesSet))); Safe_free ((void *) s); dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc); setMainValue ("z80bases", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); /* For the old register allocator (with the new one we decide to omit the frame pointer for each function individually) */ if (!IS_GB && options.omitFramePtr) port->stack.call_overhead = 2; }