From: SourceForge.net <no...@so...> - 2008-06-20 04:15:20
|
Bugs item #1998466, was opened at 2008-06-19 23:13 Message generated for change (Comment added) made by jimmbelll You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1998466&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: ds390 target Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Jim Bell (jimmbelll) Assigned to: Nobody/Anonymous (nobody) Summary: Code size > 64K and linker produces garbage (DS80C400) Initial Comment: SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.8.0 #5117 (Mar 23 2008) (MINGW32) Once the code size crosses 64K, the linker produces garbage. These two python programs help reproduce it. The first one produces source code: a main program and two large source-code files, and compiles them. The second one analyzes the resulting .ihx (or .hex) file, looking for gaps or overlaps. Hope this helps. # # GenBig.py # Written by: Jim Bell (http://jc-bell.com) # # This reproduces the SDCC Dallas DS80C400 64K boundary bug. # It produces three files: Big.c, OtherBig.c and Bug64k1.c # Big.c and OtherBig.c produce a large number of functions. # Bug64k1 has the main function that verifies that the highest # of each Big and OtherBig functions work. # # It requires the files from Dallas App Note 3346 # http://www.maxim-ic.com/appnotes.cfm/an_pk/3346 # Put them in the same directory as this script. # # This script does the build and link per app note 3346 # # Fix the SDCC_PATH variable below for your environment. # import sys; import os; # 247 works, 248 doesn't. w/rominit commented out: 250 works NUM_FUNCS=252 MAGIC_NUM=249 # 250 if you comment out init_romexport in startup400.a51 SDCC_PATH="C:\\Software\\Open\\app\\SDCC\\bin" CFLAGS="-mds400 --model-flat24 --stack-10bit" LFLAGS="-Wl-r --xram-loc 0x10000 --xram-size 0x3fff --code-loc 0x400000" SDCC = os.path.join(SDCC_PATH, "sdcc"); PACKIHX = os.path.join(SDCC_PATH, "packihx"); ASX = os.path.join(SDCC_PATH, "asx8051"); bigPfx = [ "Big", "OtherBig" ] mainPfx = "Bug64k1" def WriteFunc(f, x, pfx): f.write(""" unsigned long int %(var)s; void %(func)s(void) { if (%(var)s > 1) { %(var)s += %(val)d; } else { %(var)s -= 1; } } """ % { 'func' : "F%s%d" % (pfx,x), 'var' : "v%s%d" % (pfx,x), 'val' : x }); def WriteBigFile(pfxName, nFuncs): f = file(pfxName + ".c", "w"); print ("%s.c: %s%d" % (pfxName,pfxName,nFuncs)) for x in range(nFuncs): WriteFunc(f, x+1, pfxName); f.close(); def WriteMain(baseFn, n): f = file(baseFn + ".c", "w"); f.write(""" #include <stdio.h> extern unsigned long vBig%(total)d; extern void FBig%(total)d(void); extern unsigned long vOtherBig%(total)d; extern void FOtherBig%(total)d(void); void main(void) { unsigned long int myVal, myOtherVal; unsigned long int myRef, myOtherRef; printf(\"Welcome. Functions:%(total)d.\\n\"); vBig%(total)d= 88; myRef = 88 + %(total)d; vOtherBig%(total)d = 9988; myOtherRef = 9988 + %(total)d; FBig%(total)d(); myVal = vBig%(total)d; FOtherBig%(total)d(); myOtherVal = vOtherBig%(total)d; printf(\"The functions returned. Did they work? %%lu==%%lu? %%lu==%%lu?.\\n\", myVal, myRef, myOtherVal, myOtherRef); while (1) { } } """ % { 'total' : n}); f.close(); def RunCmd(c): r = os.system(c) if (r != 0): print "\t%s\nFailed: error code %d" % (c,r) raise SystemExit def DoCompile(baseFn): print "Compiling " + baseFn + ".c" RunCmd("%s %s --no-xinit-opt --codeseg %s -c %s.c" % (SDCC, CFLAGS, baseFn, baseFn)); def DoLink(mainPfx, pfxList): print "Assembling startup400.a51" RunCmd(ASX + " -losffgp startup400.a51"); print "Linking"; relList = mainPfx + ".rel startup400.rel"; for b in pfxList: relList = relList + " " + b + ".rel"; RunCmd("%s %s %s %s -l rominit.lib" % (SDCC, CFLAGS, LFLAGS, relList)); RunCmd("%s %s.ihx > %s.hex" % (PACKIHX, mainPfx, mainPfx)); # # Main code. # n = NUM_FUNCS; #int(sys.argv[1]) # print "Here we are, and sys.argv[1] is ", n for b in bigPfx: WriteBigFile(b, n); WriteMain(mainPfx, n); for b in bigPfx: DoCompile(b); DoCompile(mainPfx); DoLink(mainPfx, bigPfx); willWork = "" if (n > MAGIC_NUM): willWork = " NOT" print "\nDone. This should%s work. Load %s.hex" % (willWork, mainPfx) ################### End of GenBig.py #################### # # ProcIhx.py -- Analyze the .ihx and .hex linker output files. # import sys; import os; def Assert(cond): if (not cond): raise Exception, "Assertion failed" # global reptCount; reptCount = 0; class Ctxt: def __init__(self, fn="", ln=0): self.fileName = fn; self.lineNum = ln; pass def str(self): return "%s, line %d" % (self.fileName, self.lineNum) def Report(self, x): print self.str() + ":", x global reptCount; reptCount = reptCount + 1; #if (reptCount > 10): # raise SystemExit class MemBlk: def __init__(self, addr, hd, ct): self.addr32 = addr; self.hexData = hd; self.fileName = ct.fileName; self.lineNum = ct.lineNum; pass; def NumBytes(self): return len(self.hexData) / 2; def Empty(self): return len(self.hexData) == 0; def HiBound(self): return self.addr32 + self.NumBytes(); def LoBound(self): return self.addr32; def str(self): return "%2d b @ %X" % (len(self.hexData)/2, self.addr32); def Report(self, x): print self.str() + ": " + x; def ReadFile(fn, myMem): addrHi16 = 0; myMem.clear(); lnCnt = 0; atEof = False; fCtxt = Ctxt(fn); for ln in file(fn, "r"): lnCnt += 1; fCtxt.lineNum = lnCnt; if len(ln) <= 0: fCtxt.Report("Blank line"); continue Assert(ln[0] == ':'); # :0E003600E0D0E0D0E0D0E0900103E07458F09C nData = int(ln[1:3], 16) * 2; # *2 -> hex bytes # print ln[1:3], " ", ln[3:7], " ", ln[7:9], " ", ln[9:9+nData], " ", ln[9+nData:9+nData+2], ">>>", ln[11+nData:] addr16 = int(ln[3:7], 16); recType = ln[7:9] data = ln[9:9+nData] if (len(ln) - nData != 12): fCtxt.Report("Extraneous data: " + ln[11+nData:]); if (recType == '00'): # data # store it if (atEof): fCtxt.Report("Data found after EOF"); addr32 = addrHi16 | addr16; if (addr32 in myMem): fCtxt.Report("Memory already defined, line " + myMem[addr32].str()); else: myMem[addr32] = MemBlk(addr32, data, fCtxt); elif (recType == '01'): # EOF atEof = True; elif (recType == '02'): # Extended Segment Address fCtxt.Report("We don't consider extended segment address records"); elif (recType == '04'): if (len(data) != 4): fCtxt.Report("Expecting 4 hex-digits of extended linear address, but found '%s'" % data); addrHi16 = int(data, 16) << 16; fCtxt.Report("Extended linear address %X" % addrHi16); else: fCtxt.Report("Unknown record type '%s'" % recType); # presume the checksum is ok # post-loop def CheckMem(myMem): prevMB = MemBlk(0x400000, "", Ctxt("")); nOvlaps = nGaps = nRecs = 0; for addr,mb in sorted(myMem.iteritems()): nRecs += 1; if (addr == prevMB.addr32) and not prevMB.Empty(): mb.Report("Memory start-overlap w/block " + prevMB.str()); elif (mb.LoBound() < prevMB.HiBound()): mb.Report("Memory overlap (%d bytes) %s" % (prevMB.HiBound() - mb.LoBound(), prevMB.str())); nOvlaps += 1; elif (mb.LoBound() > prevMB.HiBound()): prevMB.Report(" -- Memory gap (%6d bytes) -- %s" % (mb.LoBound() - prevMB.HiBound(), mb.str())); nGaps += 1; prevMB = mb; print "%d recs: %d gaps; %d overlaps" % (nRecs, nGaps, nOvlaps) mem1 = dict() ReadFile("Bug64k1.ihx", mem1); CheckMem(mem1); ##################### End of ProcIhx.py #### ---------------------------------------------------------------------- >Comment By: Jim Bell (jimmbelll) Date: 2008-06-19 23:15 Message: Logged In: YES user_id=1804579 Originator: YES File Added: GenBig.py ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1998466&group_id=599 |