/* * Emit the section preamble, absolute location (if any) and * symbol name(s) for intialized data. */ static int emitIvalLabel(struct dbuf_s *oBuf, symbol *sym) { char *segname; static int in_code = 0; static int sectionNr = 0; if (sym) { // code or data space? if (IS_CODE(getSpec(sym->type))) { segname = "code"; in_code = 1; } else { segname = "idata"; in_code = 0; } dbuf_printf(oBuf, "\nID_%s_%d\t%s", moduleName, sectionNr++, segname); if (SPEC_ABSA(getSpec(sym->type))) { // specify address for absolute symbols dbuf_printf(oBuf, "\t0x%04X", SPEC_ADDR(getSpec(sym->type))); } // if dbuf_printf(oBuf, "\n%s\n", sym->rname); addSet(&emitted, sym->rname); } return (in_code); }
/* * Iterate over all memmaps and emit their contents (attributes, symbols). */ static void showAllMemmaps(FILE *of) { struct dbuf_s locBuf; memmap *maps[] = { xstack, istack, code, data, pdata, xdata, xidata, xinit, idata, bit, statsg, c_abs, x_abs, i_abs, d_abs, sfr, sfrbit, reg, generic, overlay, eeprom, home }; memmap * map; int i; DEBUGprintf ("---begin memmaps---\n"); if (!extBuf) extBuf = dbuf_new(1024); if (!gloBuf) gloBuf = dbuf_new(1024); if (!gloDefBuf) gloDefBuf = dbuf_new(1024); if (!ivalBuf) ivalBuf = dbuf_new(1024); dbuf_init(&locBuf, 1024); dbuf_printf (extBuf, "%s; external declarations\n%s", iComments2, iComments2); dbuf_printf (gloBuf, "%s; global declarations\n%s", iComments2, iComments2); dbuf_printf (gloDefBuf, "%s; global definitions\n%s", iComments2, iComments2); dbuf_printf (ivalBuf, "%s; initialized data\n%s", iComments2, iComments2); dbuf_printf (&locBuf, "%s; compiler-defined variables\n%s", iComments2, iComments2); for (i = 0; i < sizeof(maps) / sizeof (memmap *); i++) { map = maps[i]; //DEBUGprintf ("memmap %i: %p\n", i, map); if (map) { #if 0 fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n", map->pageno, map->sname, map->dbName, map->ptrType, map->slbl, map->sloc, map->fmap, map->paged, map->direct, map->bitsp, map->codesp, map->regsp, map->syms); #endif emitSymbolSet(map->syms, 0); } // if (map) } // for i DEBUGprintf ("---end of memmaps---\n"); emitSymbolSet(publics, 1); emitSymbolSet(externs, 2); emitPseudoStack(gloBuf, extBuf); pic14_constructAbsMap(gloDefBuf, gloBuf); pic14printLocals (&locBuf); pic14_emitConfigWord(of); // must be done after all the rest dbuf_write_and_destroy(extBuf, of); dbuf_write_and_destroy(gloBuf, of); dbuf_write_and_destroy(gloDefBuf, of); dbuf_write_and_destroy(&locBuf, of); dbuf_write_and_destroy(ivalBuf, of); extBuf = gloBuf = gloDefBuf = ivalBuf = NULL; }
/*-----------------------------------------------------------------*/ static void printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf) { symbol *sym; if (!map) return; if (!map->syms) return; for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { if (sym->level == 0) continue; if (sym->localof != func) continue; dbuf_printf (oBuf, ";%-25s Allocated ", sym->name); /* if assigned to registers */ if (!sym->allocreq && sym->reqv) { int i; sym = OP_SYMBOL (sym->reqv); if (!sym->isspilt || sym->remat) { dbuf_append_str (oBuf, "to registers "); for (i = 0; i < 4 && sym->regs[i]; i++) dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i])); dbuf_append_char (oBuf, '\n'); continue; } else { sym = sym->usl.spillLoc; } } /* if on stack */ if (sym->onStack) { dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack); continue; } /* otherwise give rname */ dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } }
/* Generate interrupt vector table. */ static int _pblaze_genIVT(struct dbuf_s *oBuf, symbol ** interrupts, int maxInterrupts) { if (pblaze_interrupt) { if (pblaze_options.dialect) { dbuf_printf(oBuf, "\tADDRESS\t3ff\n"); } else { dbuf_printf(oBuf, "\tORG\t$3ff\n"); } dbuf_printf(oBuf, "\tJUMP\t%s\n", pblaze_interrupt->name); } return TRUE; }
/* * format a mime message - this is the recursive on, not intended * for external use. */ int mime_format_part (MIME *m, DBUF *b) { MIME *n; char boundary[100]; int bl; mime_size (m); dbuf_printf (b, "%s", m->headers); dbuf_write (b, m->body, m->len); if ((bl = mime_getBoundary (m, boundary, 100)) < 1) return (dbuf_size (b)); boundary[bl++] = '\n'; for (n = m->next; n != NULL; n = n->next) { debug ("adding next part at %d\n", dbuf_size (b)); dbuf_write (b, boundary, bl); mime_format_part (n, b); } debug ("adding final boundary at %d\n", dbuf_size (b)); dbuf_write (b, boundary, bl - 1); dbuf_write (b, "--\n", 4); debug ("final size is %d\n", dbuf_size (b)); debug ("actual size is %d (%d/%d)\n", strlen (dbuf_getbuf(b)), strlen (m->headers), strlen (dbuf_getbuf(b)) - strlen (m->headers)); return (dbuf_size (b)); }
static void do_html_begin(deark *c, lctx *d) { dbuf *f; if(d->html_outf) return; d->html_outf = dbuf_create_output_file(c, "html", NULL, 0); f = d->html_outf; if(c->write_bom && !c->ascii_html) dbuf_write_uchar_as_utf8(f, 0xfeff); dbuf_puts(f, "<!DOCTYPE html>\n"); dbuf_puts(f, "<html>\n"); dbuf_puts(f, "<head>\n"); dbuf_printf(f, "<meta charset=\"%s\">\n", c->ascii_html?"US-ASCII":"UTF-8"); dbuf_puts(f, "<title></title>\n"); dbuf_puts(f, "<style type=\"text/css\">\n"); dbuf_puts(f, " body { color: #000; background-color: #fff }\n"); dbuf_puts(f, " p { margin-top: 0; margin-bottom: 0 }\n"); dbuf_puts(f, " .c { color: #ccc }\n"); // Visible control characters // Replacement object dbuf_puts(f, " .r { padding: 0.5ex; color: #800; background-color: #eee;\n"); dbuf_puts(f, " font-style: italic; border: 0.34ex dotted #800 }\n"); dbuf_puts(f, " .tc { text-align: center }\n"); dbuf_puts(f, " .tr { text-align: right }\n"); dbuf_puts(f, " .tj { text-align: justify }\n"); dbuf_puts(f, "</style>\n"); dbuf_puts(f, "</head>\n"); dbuf_puts(f, "<body>\n"); }
/* * format up an HTTP response and return it */ DBUF *server_respond (int code, char *fmt, ...) { int l, len, avail; va_list ap; char *ch; DBUF *b; char buf[4096]; /* * note our response body is limited to 4096 bytes - only small * response is needed or allowed. */ len = sprintf (buf, "<html><body>"); avail = 4096 - (len * 2 + 4); va_start (ap, fmt); l = vsnprintf (buf + len, avail, fmt, ap); va_end (ap); if ((l > 0) && (l < avail)) len += l; len += sprintf (buf + len, "</body></html>"); /* * if we are no longer running, notify the client that we are * closing this connection. */ b = dbuf_alloc (); dbuf_printf (b, "Status: %d\r\n" "Content-Length: %d\r\n" "Connection: %s\r\n\r\n%s", code, len, phineas_running () ? "Keep-alive" : "Close", buf); debug ("response:\n%s\n", dbuf_getbuf (b)); return (b); }
static void pic14printLocals (struct dbuf_s *oBuf) { set *allregs[6] = { dynAllocRegs/*, dynStackRegs, dynProcessorRegs*/, dynDirectRegs, dynDirectBitRegs/*, dynInternalRegs */ }; regs *reg; int i, is_first = 1; static unsigned sectionNr = 0; /* emit all registers from all possible sets */ for (i = 0; i < 6; i++) { if (allregs[i] == NULL) continue; for (reg = setFirstItem(allregs[i]); reg; reg = setNextItem(allregs[i])) { if (reg->isEmitted) continue; if (reg->wasUsed && !reg->isExtern) { if (!pic14_stringInSet(reg->name, &emitted, 1)) { if (reg->isFixed) { // Should not happen, really... assert ( !"Compiler-assigned variables should not be pinned... This is a bug." ); dbuf_printf(oBuf, "UDL_%s_%u\tudata\t0x%04X\n%s\tres\t%d\n", moduleName, sectionNr++, reg->address, reg->name, reg->size); } else { if (getenv("SDCC_PIC14_SPLIT_LOCALS")) { // assign each local register into its own section dbuf_printf(oBuf, "UDL_%s_%u\tudata\n%s\tres\t%d\n", moduleName, sectionNr++, reg->name, reg->size); } else { // group all local registers into a single section // This should greatly improve BANKSEL generation... if (is_first) { dbuf_printf(oBuf, "UDL_%s_%u\tudata\n", moduleName, sectionNr++); is_first = 0; } dbuf_printf(oBuf, "%s\tres\t%d\n", reg->name, reg->size); } } } } reg->isEmitted = 1; } // for } // for }
/* Generate interrupt vector table. */ static int _hc08_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts) { int i; dbuf_printf (oBuf, "\t.area\tCODEIVT (ABS)\n"); dbuf_printf (oBuf, "\t.org\t0x%04x\n", (0xfffe - (maxInterrupts * 2))); for (i=maxInterrupts; i>0; i--) { if (interrupts[i]) dbuf_printf (oBuf, "\t.dw\t%s\n", interrupts[i]->rname); else dbuf_printf (oBuf, "\t.dw\t0xffff\n"); } dbuf_printf (oBuf, "\t.dw\t%s", "__sdcc_gs_init_startup\n"); return TRUE; }
static int emitIfNew(struct dbuf_s *oBuf, set **emitted, const char *fmt, const char *name) { int wasPresent = pic14_stringInSet(name, emitted, 1); if (!wasPresent) { dbuf_printf (oBuf, fmt, name); } // if return (!wasPresent); }
/* Generate interrupt vector table. */ static int _mcs51_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts) { int i; dbuf_printf (oBuf, "\t%cjmp\t__sdcc_gsinit_startup\n", options.acall_ajmp?'a':'l'); if((options.acall_ajmp)&&(maxInterrupts)) dbuf_printf (oBuf, "\t.ds\t1\n"); /* now for the other interrupts */ for (i = 0; i < maxInterrupts; i++) { if (interrupts[i]) { dbuf_printf (oBuf, "\t%cjmp\t%s\n", options.acall_ajmp?'a':'l', interrupts[i]->rname); if ( i != maxInterrupts - 1 ) dbuf_printf (oBuf, "\t.ds\t%d\n", options.acall_ajmp?6:5); } else { dbuf_printf (oBuf, "\treti\n"); if ( i != maxInterrupts - 1 ) dbuf_printf (oBuf, "\t.ds\t7\n"); } } return TRUE; }
/* * Allocate and return an authorization required response */ DBUF *basicauth_response (char *realm) { DBUF *b = dbuf_alloc (); char *html = "<html><body>Access restricted - " "Authorization required!</body></html>"; dbuf_printf (b, "Status: 401\r\n" "WWW-Authenticate: Basic realm=\"%s\"\r\n" "Content-Length: %d\r\n\r\n%s", realm, strlen (html), html); return (b); }
/* Mangling format: _fun_policy_params where: policy is the function policy params is the parameter format policy format: rsp where: r is 'r' for reentrant, 's' for static functions s is 'c' for callee saves, 'r' for caller saves f is 'f' for profiling on, 'x' for profiling off examples: rr - reentrant, caller saves params format: A combination of register short names and s to signify stack variables. examples: bds - first two args appear in BC and DE, the rest on the stack s - all arguments are on the stack. */ static const char * _mangleSupportFunctionName (const char *original) { struct dbuf_s dbuf; if (strstr (original, "longlong")) return (original); dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "%s_rr%s_%s", original, options.profile ? "f" : "x", options.noRegParams ? "s" : "bds" /* MB: but the library only has hds variants ??? */ ); return dbuf_detach_c_str (&dbuf); }
/*-----------------------------------------------------------------*/ void printLine (lineNode * head, struct dbuf_s *oBuf) { iCode *last_ic = NULL; bool debug_iCode_tracking = (getenv ("DEBUG_ICODE_TRACKING") != NULL); while (head) { if (head->ic != last_ic) { last_ic = head->ic; if (debug_iCode_tracking) { if (head->ic) dbuf_printf (oBuf, "; block = %d, seq = %d\n", head->ic->block, head->ic->seq); else dbuf_append_str (oBuf, "; iCode lost\n"); } } /* don't indent comments & labels */ if (head->line && (head->isComment || head->isLabel)) { dbuf_printf (oBuf, "%s\n", head->line); } else { if (head->isInline && *head->line == '#') { /* comment out preprocessor directives in inline asm */ dbuf_append_char (oBuf, ';'); } dbuf_printf (oBuf, "\t%s\n", head->line); } head = head->next; } }
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 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; }
static void _pic14_finaliseOptions (void) { struct dbuf_s dbuf; pCodeInitRegisters(); port->mem.default_local_map = data; port->mem.default_globl_map = data; dbuf_init (&dbuf, 512); dbuf_printf (&dbuf, "-D__SDCC_PROCESSOR=\"%s\"", port->processor); addSet (&preArgvSet, Safe_strdup (dbuf_detach_c_str (&dbuf))); { char *upperProc, *p1, *p2; int len; dbuf_set_length (&dbuf, 0); len = strlen (port->processor); upperProc = Safe_malloc (len); for (p1 = port->processor, p2 = upperProc; *p1; ++p1, ++p2) { *p2 = toupper (*p1); } dbuf_append (&dbuf, "-D__SDCC_PIC", sizeof ("-D__SDCC_PIC") - 1); dbuf_append (&dbuf, upperProc, len); addSet (&preArgvSet, dbuf_detach_c_str (&dbuf)); } if (!pic14_options.no_warn_non_free && !options.use_non_free) { fprintf(stderr, "WARNING: Command line option --use-non-free not present.\n" " When compiling for PIC14/PIC16, please provide --use-non-free\n" " to get access to device headers and libraries.\n" " If you do not use these, you may provide --no-warn-non-free\n" " to suppress this warning (not recommended).\n"); } // if }
/*-----------------------------------------------------------------*/ void printAllocInfo (symbol * func, struct dbuf_s * oBuf) { #define BREAKLINE ";------------------------------------------------------------\n" int cnt = 0; set *ovrset; set *tempOverlaySyms; if (!func) return; /* must be called after register allocation is complete */ dbuf_append_str (oBuf, BREAKLINE); dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name); dbuf_append_str (oBuf, BREAKLINE); cnt += printAllocInfoSeg (xstack, func, oBuf); cnt += printAllocInfoSeg (istack, func, oBuf); cnt += printAllocInfoSeg (code, func, oBuf); cnt += printAllocInfoSeg (data, func, oBuf); cnt += printAllocInfoSeg (xdata, func, oBuf); cnt += printAllocInfoSeg (idata, func, oBuf); cnt += printAllocInfoSeg (sfr, func, oBuf); cnt += printAllocInfoSeg (sfrbit, func, oBuf); tempOverlaySyms = overlay->syms; /* search the set of overlay sets for local variables/parameters */ for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets)) { overlay->syms = ovrset; cnt += printAllocInfoSeg (overlay, func, oBuf); } overlay->syms = tempOverlaySyms; if (cnt) dbuf_append_str (oBuf, BREAKLINE); }
/*-----------------------------------------------------------------*/ static void pic14createInterruptVect (struct dbuf_s * vBuf) { mainf = newSymbol ("main", 0); mainf->block = 0; /* only if the main function exists */ if (!(mainf = findSymWithLevel (SymbolTab, mainf))) { struct options *op = &options; if (!(op->cc_only || noAssemble)) // werror (E_NO_MAIN); fprintf(stderr,"WARNING: function 'main' undefined\n"); return; } /* if the main is only a prototype ie. no body then do nothing */ if (!IFFUNC_HASBODY(mainf->type)) { /* if ! compile only then main function should be present */ if (!(options.cc_only || noAssemble)) // werror (E_NO_MAIN); fprintf(stderr,"WARNING: function 'main' undefined\n"); return; } dbuf_printf (vBuf, "%s", iComments2); dbuf_printf (vBuf, "; reset vector \n"); dbuf_printf (vBuf, "%s", iComments2); // Lkr file should place section STARTUP at address 0x0, but does not ... dbuf_printf (vBuf, "STARTUP\t%s 0x0000\n", CODE_NAME); dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */ dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n"); dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n"); popGetExternal("__sdcc_gsinit_startup", 0); }
/*-----------------------------------------------------------------*/ static int printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf) { symbol *sym; int flg = FALSE; if (!map || !map->syms) return 0; for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { if (sym->level == 0) continue; if (sym->localof != func) continue; dbuf_printf (oBuf, ";%-25s Allocated ", sym->name); flg = TRUE; /* if assigned to registers */ if (!sym->allocreq && sym->reqv) { int i; sym = OP_SYMBOL (sym->reqv); if (!sym->isspilt || sym->remat) { dbuf_append_str (oBuf, "to registers "); for (i = 0; i < 4 && sym->regs[i]; i++) dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i])); dbuf_append_char (oBuf, '\n'); continue; } else { sym = sym->usl.spillLoc; } } /* if on stack */ if (sym->onStack) { int stack_offset = 0; if (options.omitFramePtr) { if (SPEC_OCLS (sym->etype)->paged) stack_offset = func->xstack; else stack_offset = func->stack; } dbuf_printf (oBuf, "to stack - %s %+d\n", SYM_BP (sym), sym->stack - stack_offset); continue; } /* otherwise give rname */ dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } return flg; }
/*-----------------------------------------------------------------*/ 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; }
/* * Parse the type and its initializer and emit it (recursively). */ static void emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *list) { symbol *sym; int size, i; long lit; unsigned char *str; size = getSize(my_type); if (IS_PTR(my_type)) { DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL); emitIvals(oBuf, topsym, list, 0, size); return; } if (IS_ARRAY(my_type) && topsym && topsym->isstrlit) { str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char; emitIvalLabel(oBuf, topsym); do { dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.'); } while (*(str++)); return; } if (IS_ARRAY(my_type) && list && list->type == INIT_NODE) { fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name); assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." ); return; } if (IS_ARRAY(my_type)) { DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size); assert (!list || list->type == INIT_DEEP); if (list) list = list->init.deep; for (i = 0; i < DCL_ELEM(my_type); i++) { emitInitVal(oBuf, topsym, my_type->next, list); topsym = NULL; if (list) list = list->next; } // for i return; } if (IS_FLOAT(my_type)) { // float, 32 bit DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0); emitIvals(oBuf, topsym, list, 0, size); return; } if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) { // integral type, 8, 16, or 32 bit DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0); emitIvals(oBuf, topsym, list, 0, size); return; } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) { // struct DEBUGprintf ("(struct, %d byte) handled below\n", size); assert (!list || (list->type == INIT_DEEP)); // iterate over struct members and initList if (list) list = list->init.deep; sym = SPEC_STRUCT(my_type)->fields; while (sym) { long bitfield = 0; int len = 0; if (IS_BITFIELD(sym->type)) { while (sym && IS_BITFIELD(sym->type)) { int bitoff = SPEC_BSTR(getSpec(sym->type)) + 8 * sym->offset; assert (!list || ((list->type == INIT_NODE) && IS_AST_LIT_VALUE(list->init.node))); lit = (long) (list ? list2int(list) : 0); DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n", lit, SPEC_BLEN(getSpec(sym->type)), bitoff, bitfield); bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << bitoff; len += SPEC_BLEN(getSpec(sym->type)); sym = sym->next; if (list) list = list->next; } // while assert (len < sizeof (long) * 8); // did we overflow our initializer?!? len = (len + 7) & ~0x07; // round up to full bytes emitIvals(oBuf, topsym, NULL, bitfield, len / 8); topsym = NULL; } // if if (sym) { emitInitVal(oBuf, topsym, sym->type, list); topsym = NULL; sym = sym->next; if (list) list = list->next; } // if } // while if (list) { assert ( !"Excess initializers." ); } // if return; } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) { // union DEBUGprintf ("(union, %d byte) handled below\n", size); assert (list && list->type == INIT_DEEP); // iterate over union members and initList, try to map number and type of fields and initializers my_type = matchIvalToUnion(list, my_type, size); if (my_type) { emitInitVal(oBuf, topsym, my_type, list->init.deep); topsym = NULL; size -= getSize(my_type); if (size > 0) { // pad with (leading) zeros emitIvals(oBuf, NULL, NULL, 0, size); } return; } // if assert ( !"No UNION member matches the initializer structure."); } else if (IS_BITFIELD(my_type)) { assert ( !"bitfields should only occur in structs..." ); } else { printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type)); assert( !"Unhandled initialized type."); } }
/* * Actually emit the initial values in .asm format. */ static void emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size) { int i; ast *node; operand *op; value *val = NULL; int inCodeSpace = 0; char *str = NULL; int in_code; assert (size <= sizeof(long)); assert (!list || (list->type == INIT_NODE)); node = list ? list->init.node : NULL; in_code = emitIvalLabel(oBuf, sym); if (!in_code) dbuf_printf (oBuf, "\tdb\t"); if (!node) { // initialize as zero for (i = 0; i < size; i++) { if (in_code) { dbuf_printf (oBuf, "\tretlw 0x%02x\n", lit & 0xff); } else { dbuf_printf (oBuf, "%s0x%02x", (i == 0) ? "" : ", ", lit & 0xff); } lit >>= 8; } // for if (!in_code) dbuf_printf (oBuf, "\n"); return; } // if op = NULL; if (constExprTree(node) && (val = constExprValue(node, 0))) { op = operandFromValue(val); DEBUGprintf ("%s: constExpr ", __FUNCTION__); } else if (IS_AST_VALUE(node)) { op = operandFromAst(node, 0); } else if (IS_AST_OP(node)) { str = parseIvalAst(node, &inCodeSpace); DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str); op = NULL; } else { assert ( !"Unhandled construct in intializer." ); } if (op) { aopOp(op, NULL, 1); assert(AOP(op)); //printOperand(op, of); } for (i = 0; i < size; i++) { char *text; /* * FIXME: This is hacky and needs some more thought. */ if (op && IS_SYMOP(op) && IS_FUNC(OP_SYM_TYPE(op))) { /* This branch is introduced to fix #1427663. */ PCOI(AOP(op)->aopu.pcop)->offset+=i; text = get_op(AOP(op)->aopu.pcop, NULL, 0); PCOI(AOP(op)->aopu.pcop)->offset-=i; } else { text = op ? aopGet(AOP(op), i, 0, 0) : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0); } // if if (in_code) { dbuf_printf (oBuf, "\tretlw %s\n", text); } else { dbuf_printf (oBuf, "%s%s", (i == 0) ? "" : ", ", text); } } // for if (!in_code) dbuf_printf (oBuf, "\n"); }
dbuf *dbuf_create_output_file(deark *c, const char *ext, de_finfo *fi, unsigned int createflags) { char nbuf[500]; char msgbuf[200]; dbuf *f; const char *basefn; int file_index; u8 is_directory = 0; char *name_from_finfo = NULL; i64 name_from_finfo_len = 0; if(ext && fi && fi->original_filename_flag) { de_dbg(c, "[internal warning: Incorrect use of create_output_file]"); } f = de_malloc(c, sizeof(dbuf)); f->c = c; f->max_len_hard = c->max_output_file_size; f->is_managed = 1; if(fi && fi->is_directory) { is_directory = 1; } if(is_directory && !c->keep_dir_entries) { de_dbg(c, "skipping 'directory' file"); f->btype = DBUF_TYPE_NULL; goto done; } if(c->extract_policy==DE_EXTRACTPOLICY_MAINONLY) { if(createflags&DE_CREATEFLAG_IS_AUX) { de_dbg(c, "skipping 'auxiliary' file"); f->btype = DBUF_TYPE_NULL; goto done; } } else if(c->extract_policy==DE_EXTRACTPOLICY_AUXONLY) { if(!(createflags&DE_CREATEFLAG_IS_AUX)) { de_dbg(c, "skipping 'main' file"); f->btype = DBUF_TYPE_NULL; goto done; } } file_index = c->file_count; c->file_count++; basefn = c->base_output_filename ? c->base_output_filename : "output"; if(fi && ucstring_isnonempty(fi->file_name_internal)) { name_from_finfo_len = 1 + ucstring_count_utf8_bytes(fi->file_name_internal); name_from_finfo = de_malloc(c, name_from_finfo_len); ucstring_to_sz(fi->file_name_internal, name_from_finfo, (size_t)name_from_finfo_len, 0, DE_ENCODING_UTF8); } if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && !c->base_output_filename && fi && fi->is_directory && (fi->is_root_dir || (fi->detect_root_dot_dir && fi->orig_name_was_dot))) { de_strlcpy(nbuf, ".", sizeof(nbuf)); } else if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && !c->base_output_filename && fi && fi->original_filename_flag && name_from_finfo) { // TODO: This is a "temporary" hack to allow us to, when both reading from // and writing to an archive format, use some semblance of the correct // filename (instead of "output.xxx.yyy"). // There are some things that we don't handle optimally, such as // subdirectories. // A major redesign of the file naming logic would be good. de_strlcpy(nbuf, name_from_finfo, sizeof(nbuf)); } else { char fn_suffix[256]; if(ext && name_from_finfo) { de_snprintf(fn_suffix, sizeof(fn_suffix), "%s.%s", name_from_finfo, ext); } else if(ext) { de_strlcpy(fn_suffix, ext, sizeof(fn_suffix)); } else if(is_directory && name_from_finfo) { de_snprintf(fn_suffix, sizeof(fn_suffix), "%s.dir", name_from_finfo); } else if(name_from_finfo) { de_strlcpy(fn_suffix, name_from_finfo, sizeof(fn_suffix)); } else if(is_directory) { de_strlcpy(fn_suffix, "dir", sizeof(fn_suffix)); } else { de_strlcpy(fn_suffix, "bin", sizeof(fn_suffix)); } de_snprintf(nbuf, sizeof(nbuf), "%s.%03d.%s", basefn, file_index, fn_suffix); } f->name = de_strdup(c, nbuf); if(fi) { // The finfo object passed to us at file creation is not required to // remain valid, so make a copy of anything in it that we might need // later. f->fi_copy = de_finfo_create(c); finfo_shallow_copy(c, fi, f->fi_copy); // Here's where we respect the -intz option, by using it to convert to // UTC in some cases. if(f->fi_copy->mod_time.is_valid && f->fi_copy->mod_time.tzcode==DE_TZCODE_LOCAL && c->input_tz_offs_seconds!=0) { de_timestamp_cvt_to_utc(&f->fi_copy->mod_time, -c->input_tz_offs_seconds); } if(f->fi_copy->image_mod_time.is_valid && f->fi_copy->image_mod_time.tzcode==DE_TZCODE_LOCAL && c->input_tz_offs_seconds!=0) { de_timestamp_cvt_to_utc(&f->fi_copy->image_mod_time, -c->input_tz_offs_seconds); } } if(file_index < c->first_output_file) { f->btype = DBUF_TYPE_NULL; goto done; } if(c->max_output_files>=0 && file_index >= c->first_output_file + c->max_output_files) { f->btype = DBUF_TYPE_NULL; goto done; } c->num_files_extracted++; if(c->extrlist_dbuf) { dbuf_printf(c->extrlist_dbuf, "%s\n", f->name); dbuf_flush(c->extrlist_dbuf); } if(c->list_mode) { f->btype = DBUF_TYPE_NULL; if(c->list_mode_include_file_id) { de_msg(c, "%d:%s", file_index, f->name); } else { de_msg(c, "%s", f->name); } goto done; } if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE && c->archive_fmt==DE_ARCHIVEFMT_TAR) { de_info(c, "Adding %s to TAR file", f->name); f->btype = DBUF_TYPE_ODBUF; // A dummy max_len_hard value. The parent will do the checking. f->max_len_hard = DE_DUMMY_MAX_FILE_SIZE; f->writing_to_tar_archive = 1; de_tar_start_member_file(c, f); } else if(c->output_style==DE_OUTPUTSTYLE_ARCHIVE) { // ZIP i64 initial_alloc; de_info(c, "Adding %s to ZIP file", f->name); f->btype = DBUF_TYPE_MEMBUF; f->max_len_hard = DE_MAX_MEMBUF_SIZE; if(is_directory) { // A directory entry is not expected to have any data associated // with it (besides the files it contains). initial_alloc = 16; } else { initial_alloc = 65536; } f->membuf_buf = de_malloc(c, initial_alloc); f->membuf_alloc = initial_alloc; f->write_memfile_to_zip_archive = 1; } else if(c->output_style==DE_OUTPUTSTYLE_STDOUT) { de_info(c, "Writing %s to [stdout]", f->name); f->btype = DBUF_TYPE_STDOUT; // TODO: Should we increase f->max_len_hard? f->fp = stdout; } else { de_info(c, "Writing %s", f->name); f->btype = DBUF_TYPE_OFILE; f->fp = de_fopen_for_write(c, f->name, msgbuf, sizeof(msgbuf), c->overwrite_mode, 0); if(!f->fp) { de_err(c, "Failed to write %s: %s", f->name, msgbuf); f->btype = DBUF_TYPE_NULL; } } done: de_free(c, name_from_finfo); return f; }
static void emitPseudoStack(struct dbuf_s *oBuf, struct dbuf_s *oBufExt) { int shared, low, high, size, i; PIC_device *pic; /* also emit STK symbols * XXX: This is ugly and fails as soon as devices start to get * differently sized sharebanks, since STK12 will be * required by larger devices but only up to STK03 might * be defined using smaller devices. */ shared = pic14_getSharedStack(&low, &high, &size); if (!pic14_options.isLibrarySource) { pic = pic14_getPIC(); dbuf_printf (oBuf, "\n"); dbuf_printf (oBuf, "\tglobal PSAVE\n"); dbuf_printf (oBuf, "\tglobal SSAVE\n"); dbuf_printf (oBuf, "\tglobal WSAVE\n"); for (i = size - 4; i >= 0; i--) { dbuf_printf (oBuf, "\tglobal STK%02d\n", i); } // for i dbuf_printf (oBuf, "\n"); // 16f84 has no SHAREBANK (in linkerscript) but memory aliased in two // banks, sigh... if (1 || !shared) { // for single banked devices: use normal, "banked" RAM dbuf_printf (oBuf, "sharebank udata_ovr 0x%04X\n", low); } else { // for devices with at least two banks, require a sharebank section dbuf_printf (oBuf, "sharebank udata_shr\n"); } dbuf_printf (oBuf, "PSAVE\tres 1\n"); dbuf_printf (oBuf, "SSAVE\tres 1\n"); dbuf_printf (oBuf, "WSAVE\tres 1\n"); // WSAVE *must* be in sharebank (IRQ handlers) /* fill rest of sharebank with stack STKxx .. STK00 */ for (i = size - 4; i >= 0; i--) { dbuf_printf (oBuf, "STK%02d\tres 1\n", i); } // for i } else { /* declare STKxx as extern for all files * except the one containing main() */ dbuf_printf (oBufExt, "\n"); dbuf_printf (oBufExt, "\textern PSAVE\n"); dbuf_printf (oBufExt, "\textern SSAVE\n"); dbuf_printf (oBufExt, "\textern WSAVE\n"); for (i = size - 4; i >= 0; i--) { char buffer[128]; SNPRINTF(&buffer[0], 127, "STK%02d", i); dbuf_printf (oBufExt, "\textern %s\n", &buffer[0]); pic14_stringInSet(&buffer[0], &emitted, 1); } // for i } dbuf_printf (oBuf, "\n"); }
/*-----------------------------------------------------------------*/ static void pic14emitOverlay (struct dbuf_s * aBuf) { set *ovrset; /* if (!elementsInSet (ovrSetSets))*/ /* the hack below, fixes translates for devices which * only have udata_shr memory */ dbuf_printf (aBuf, "%s\t%s\n", (elementsInSet(ovrSetSets)?"":";"), port->mem.overlay_name); /* for each of the sets in the overlay segment do */ for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets)) { symbol *sym; if (elementsInSet (ovrset)) { /* this dummy area is used to fool the assembler otherwise the assembler will append each of these declarations into one chunk and will not overlay sad but true */ /* I don't think this applies to us. We are using gpasm. CRF */ dbuf_printf (aBuf, ";\t.area _DUMMY\n"); /* output the area informtion */ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */ } for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset)) { /* if extern then do nothing */ if (IS_EXTERN (sym->etype)) continue; /* if allocation required check is needed then check if the symbol really requires allocation only for local variables */ if (!IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level) continue; /* if global variable & not static or extern and addPublics allowed then add it to the public set */ if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype)) addSetHead (&publics, sym); /* if extern then do nothing or is a function then do nothing */ if (IS_FUNC (sym->type)) continue; /* print extra debug info if required */ if (options.debug || sym->level == 0) { if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */ else dbuf_printf (aBuf, "G_"); /* scope is global */ } else /* symbol is local */ dbuf_printf (aBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-")); dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block); } /* if is has an absolute address then generate an equate for this no need to allocate space */ if (SPEC_ABSA (sym->etype)) { if (options.debug || sym->level == 0) dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype)); dbuf_printf (aBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); } else { if (options.debug || sym->level == 0) dbuf_printf (aBuf, "==.\n"); /* allocate space */ dbuf_printf (aBuf, "%s:\n", sym->rname); dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff); } } } }
static int do_pragma(int id, const char *name, const char *cp) { struct pragma_token_s token; int err = 0; int processed = 1; init_pragma_token(&token); switch (id) { case P_BANK: { struct dbuf_s buffer; dbuf_init(&buffer, 128); cp = get_pragma_token(cp, &token); switch (token.type) { case TOKEN_EOL: err = 1; break; case TOKEN_INT: switch (_G.asmType) { case ASM_TYPE_ASXXXX: dbuf_printf (&buffer, "CODE_%d", token.val.int_val); break; case ASM_TYPE_RGBDS: dbuf_printf (&buffer, "CODE,BANK[%d]", token.val.int_val); break; case ASM_TYPE_ISAS: /* PENDING: what to use for ISAS? */ dbuf_printf (&buffer, "CODE,BANK(%d)", token.val.int_val); break; default: wassert (0); } break; default: { const char *str = get_pragma_string (&token); dbuf_append_str (&buffer, (0 == strcmp("BASE", str)) ? "HOME" : str); } break; } cp = get_pragma_token (cp, &token); if (TOKEN_EOL != token.type) { err = 1; break; } dbuf_c_str (&buffer); /* ugly, see comment in src/port.h (borutr) */ gbz80_port.mem.code_name = dbuf_detach (&buffer); code->sname = gbz80_port.mem.code_name; options.code_seg = (char *)gbz80_port.mem.code_name; } break; case P_PORTMODE: { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */ const char *str; cp = get_pragma_token (cp, &token); if (TOKEN_EOL == token.type) { err = 1; break; } str = get_pragma_string (&token); cp = get_pragma_token (cp, &token); if (TOKEN_EOL != token.type) { err = 1; break; } if (!strcmp(str, "z80")) { z80_opts.port_mode = 80; } else if(!strcmp(str, "z180")) { z80_opts.port_mode = 180; } else if(!strcmp(str, "save")) { z80_opts.port_back = z80_opts.port_mode; } else if(!strcmp(str, "restore" )) { z80_opts.port_mode = z80_opts.port_back; } else err = 1; } break; case P_CODESEG: case P_CONSTSEG: { char *segname; cp = get_pragma_token (cp, &token); if (token.type == TOKEN_EOL) { err = 1; break; } segname = Safe_strdup (get_pragma_string(&token)); cp = get_pragma_token (cp, &token); if (token.type != TOKEN_EOL) { Safe_free (segname); err = 1; break; } if (id == P_CODESEG) { if (options.code_seg) Safe_free(options.code_seg); options.code_seg = segname; } else { if (options.const_seg) Safe_free(options.const_seg); options.const_seg = segname; } } break; default: processed = 0; break; } get_pragma_token(cp, &token); if (1 == err) werror(W_BAD_PRAGMA_ARGUMENTS, name); free_pragma_token(&token); return processed; }
static void pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf) { memmap *maps[] = { data, sfr, NULL }; int i; hTab *ht = NULL; symbol *sym; set *aliases; int addr, min=-1, max=-1; int size; for (i=0; maps[i] != NULL; i++) { for (sym = (symbol *)setFirstItem (maps[i]->syms); sym; sym = setNextItem (maps[i]->syms)) { if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype)) { addr = SPEC_ADDR(sym->etype); /* handle CONFIG words here */ if (IS_CONFIG_ADDRESS( addr )) { //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr ); //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) ); if (sym->ival) { pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) ); } else { fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name ); } continue; } if (max == -1 || addr > max) max = addr; if (min == -1 || addr < min) min = addr; //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr); aliases = hTabItemWithKey (ht, addr); if (aliases) { /* May not use addSetHead, as we cannot update the * list's head in the hastable `ht'. */ addSet (&aliases, sym); #if 0 fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n", __FUNCTION__, elementsInSet(aliases), sym->name, addr); #endif } else { addSet (&aliases, sym); hTabAddItem (&ht, addr, aliases); } // if } // if } // for sym } // for i /* now emit definitions for all absolute symbols */ dbuf_printf (oBuf, "%s", iComments2); dbuf_printf (oBuf, "; absolute symbol definitions\n"); dbuf_printf (oBuf, "%s", iComments2); for (addr=min; addr <= max; addr++) { size = 1; aliases = hTabItemWithKey (ht, addr); if (aliases && elementsInSet(aliases)) { /* Make sure there is no initialized value at this location! */ for (sym = setFirstItem(aliases); sym; sym = setNextItem(aliases)) { if (sym->ival) break; } // for if (sym) continue; dbuf_printf (oBuf, "UD_abs_%s_%x\tudata_ovr\t0x%04x\n", moduleName, addr, addr); for (sym = setFirstItem (aliases); sym; sym = setNextItem (aliases)) { if (getSize(sym->type) > size) { size = getSize(sym->type); } /* initialized values are handled somewhere else */ if (sym->ival) continue; /* emit STATUS as well as _STATUS, required for SFRs only */ //dbuf_printf (oBuf, "%s\tres\t0\n", sym->name); dbuf_printf (oBuf, "%s\n", sym->rname); if (IS_GLOBAL(sym) && !IS_STATIC(sym->etype)) { //emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->name); emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->rname); } // if } // for dbuf_printf (oBuf, "\tres\t%d\n", size); } // if } // for i }
static bool _parseOptions (int *pargc, char **argv, int *i) { if (argv[*i][0] == '-') { if (IS_GB) { if (!strncmp (argv[*i], OPTION_BO, sizeof (OPTION_BO) - 1)) { /* ROM bank */ int bank = getIntArg (OPTION_BO, argv, i, *pargc); struct dbuf_s buffer; dbuf_init (&buffer, 16); dbuf_printf (&buffer, "CODE_%u", bank); dbuf_c_str (&buffer); /* ugly, see comment in src/port.h (borutr) */ gbz80_port.mem.code_name = dbuf_detach (&buffer); options.code_seg = (char *)gbz80_port.mem.code_name; return TRUE; } else if (!strncmp (argv[*i], OPTION_BA, sizeof (OPTION_BA) - 1)) { /* RAM bank */ int bank = getIntArg (OPTION_BA, argv, i, *pargc); struct dbuf_s buffer; dbuf_init (&buffer, 16); dbuf_printf (&buffer, "DATA_%u", bank); dbuf_c_str (&buffer); /* ugly, see comment in src/port.h (borutr) */ gbz80_port.mem.data_name = dbuf_detach (&buffer); return TRUE; } } else if (!strncmp (argv[*i], OPTION_ASM, sizeof (OPTION_ASM) - 1)) { char *asmblr = getStringArg (OPTION_ASM, argv, i, *pargc); if (!strcmp (asmblr, "rgbds")) { asm_addTree (&_rgbds_gb); gbz80_port.assembler.cmd = _gbz80_rgbasmCmd; gbz80_port.linker.cmd = _gbz80_rgblinkCmd; gbz80_port.linker.do_link = _gbz80_rgblink; _G.asmType = ASM_TYPE_RGBDS; return TRUE; } else if (!strcmp (asmblr, "asxxxx")) { _G.asmType = ASM_TYPE_ASXXXX; return TRUE; } else if (!strcmp (asmblr, "isas")) { asm_addTree (&_isas_gb); /* Munge the function prefix */ gbz80_port.fun_prefix = ""; _G.asmType = ASM_TYPE_ISAS; return TRUE; } else if (!strcmp (asmblr, "z80asm")) { port->assembler.externGlobal = TRUE; asm_addTree (&_z80asm_z80); _G.asmType = ASM_TYPE_ISAS; return TRUE; } } else if (!strncmp (argv[*i], OPTION_PORTMODE, sizeof (OPTION_PORTMODE) - 1)) { char *portmode = getStringArg (OPTION_ASM, argv, i, *pargc); if (!strcmp (portmode, "z80")) { z80_opts.port_mode = 80; return TRUE; } else if (!strcmp (portmode, "z180")) { z80_opts.port_mode = 180; return TRUE; } } } return FALSE; }
/* * Emit a set of symbols. * type - 0: have symbol tell whether it is local, extern or global * 1: assume all symbols in set to be global * 2: assume all symbols in set to be extern */ static void emitSymbolSet(set *s, int type) { symbol *sym; initList *list; unsigned sectionNr = 0; for (sym = setFirstItem(s); sym; sym = setNextItem(s)) { #if 0 fprintf (stdout, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n", sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used); #endif if (sym->etype && SPEC_ABSA(sym->etype) && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)) && sym->ival) { // handle config words pic14_assignConfigWordValue(SPEC_ADDR(sym->etype), (int)list2int(sym->ival)); pic14_stringInSet(sym->rname, &emitted, 1); continue; } if (sym->isstrlit) { // special case: string literals emitInitVal(ivalBuf, sym, sym->type, NULL); continue; } if (type != 0 || sym->cdef || (!IS_STATIC(sym->etype) && IS_GLOBAL(sym))) { // bail out for ___fsadd and friends if (sym->cdef && !sym->used) continue; /* export or import non-static globals */ if (!pic14_stringInSet(sym->rname, &emitted, 0)) { if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef) { /* do not add to emitted set, it might occur again! */ //if (!sym->used) continue; // declare symbol emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname); } else { // declare symbol emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname); if (!sym->ival && !IS_FUNC(sym->type)) { // also define symbol if (IS_ABSOLUTE(sym->etype)) { // absolute location? //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype)); // deferred to pic14_constructAbsMap } else { dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++); dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type)); } } // if } // if pic14_stringInSet(sym->rname, &emitted, 1); } // if } // if list = sym->ival; //if (list) showInitList(list, 0); if (list) { resolveIvalSym( list, sym->type ); emitInitVal(ivalBuf, sym, sym->type, sym->ival); dbuf_printf (ivalBuf, "\n"); } } // for sym }