From 123219b5f1175b15cb26bc51de28dc6b672c0b53 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 21 May 2021 16:33:20 -0400 Subject: [PATCH] Corrected an error in the extresist code that will cause an infinite recursive loop and crash magic. Corrected a number of other issues along the way, especially one where routines in EFantenna and extresist make use of array EFDevTypes which was only created by ext2sim and ext2spice, and freed when done. Having run extresist through valgrind, there are still issues in the code. --- VERSION | 2 +- database/database.h.in | 1 + extflat/EFantenna.c | 16 +++++++-- extflat/EFdef.c | 1 + extract/ExtTech.c | 73 ++++++++++++++++++++++++------------------ resis/ResMain.c | 3 +- resis/ResReadSim.c | 12 +++++-- resis/ResRex.c | 20 +++++++++++- 8 files changed, 89 insertions(+), 39 deletions(-) diff --git a/VERSION b/VERSION index 3d283694..581ece37 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.166 +8.3.167 diff --git a/database/database.h.in b/database/database.h.in index 1ef2d9fd..0a2ea89c 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -816,6 +816,7 @@ extern void DBTechInitContact(); extern void DBTechFinalContact(); extern void DBTechFinalConnect(); extern void DBTechInitConnect(); +extern bool DBIsContact(); /* Cell symbol table */ extern void DBCellInit(); diff --git a/extflat/EFantenna.c b/extflat/EFantenna.c index 480d6f90..d6e3f500 100644 --- a/extflat/EFantenna.c +++ b/extflat/EFantenna.c @@ -228,9 +228,21 @@ runantennacheck: TxPrintf("Building flattened netlist.\n"); EFFlatBuild(inName, flatFlags); + /* Get device information from the current extraction style */ + idx = 0; + while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) + { + if (idx == MAXDEVTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + } + /* Build device lookup table */ - EFDeviceTypes = (TileType *)mallocMagic(MAXDEVTYPES * sizeof(TileType)); - for (i = 0; i < MAXDEVTYPES; i++) + EFDeviceTypes = (TileType *)mallocMagic(EFDevNumTypes * sizeof(TileType)); + for (i = 0; i < EFDevNumTypes; i++) if (EFDevTypes[i]) EFDeviceTypes[i] = extGetDevType(EFDevTypes[i]); diff --git a/extflat/EFdef.c b/extflat/EFdef.c index ecefb3d0..358c6b0d 100644 --- a/extflat/EFdef.c +++ b/extflat/EFdef.c @@ -135,6 +135,7 @@ EFDone() /* Misc cleanup */ for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]); + EFDevNumTypes = 0; /* Changed from n = 0 to n = 1; First entry "space" is predefined, */ /* not malloc'd. ---Tim 9/3/02 */ diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 7445ddb4..731cdf73 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -354,54 +354,63 @@ ExtGetDevInfo(idx, devnameptr, devtypeptr, s_rclassptr, d_rclassptr, if (t == DBNumTypes) return FALSE; if (devptr == NULL) return FALSE; - *devnameptr = locdname; - *subnameptr = devptr->exts_deviceSubstrateName; - *devtypeptr = t; + if (devnameptr) *devnameptr = locdname; + if (subnameptr) *subnameptr = devptr->exts_deviceSubstrateName; + if (devtypeptr) *devtypeptr = t; tmask = &devptr->exts_deviceSDTypes[0]; - *s_rclassptr = (short)(-1); /* NO_RESCLASS */ - - for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + if (s_rclassptr) { - rmask = &ExtCurStyle->exts_typesByResistClass[n]; - if (TTMaskIntersect(rmask, tmask)) - { - *s_rclassptr = (short)n; - break; - } - } - - tmask = &devptr->exts_deviceSDTypes[1]; - if (TTMaskIsZero(tmask)) - { - /* Set source and drain resistance classes to be the same */ - *d_rclassptr = (short)n; - } - else - { - *d_rclassptr = (short)(-1); /* NO_RESCLASS */ + *s_rclassptr = (short)(-1); /* NO_RESCLASS */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { rmask = &ExtCurStyle->exts_typesByResistClass[n]; if (TTMaskIntersect(rmask, tmask)) { - *d_rclassptr = (short)n; + *s_rclassptr = (short)n; break; } } } - tmask = &devptr->exts_deviceSubstrateTypes; - *sub_rclassptr = (short)(-1); /* NO_RESCLASS */ - - for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + if (d_rclassptr) { - rmask = &ExtCurStyle->exts_typesByResistClass[n]; - if (TTMaskIntersect(rmask, tmask)) + tmask = &devptr->exts_deviceSDTypes[1]; + if (TTMaskIsZero(tmask)) { - *sub_rclassptr = (short)(n); - break; + /* Set source and drain resistance classes to be the same */ + *d_rclassptr = (short)n; + } + else + { + *d_rclassptr = (short)(-1); /* NO_RESCLASS */ + + for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + { + rmask = &ExtCurStyle->exts_typesByResistClass[n]; + if (TTMaskIntersect(rmask, tmask)) + { + *d_rclassptr = (short)n; + break; + } + } + } + } + + if (sub_rclassptr) + { + tmask = &devptr->exts_deviceSubstrateTypes; + *sub_rclassptr = (short)(-1); /* NO_RESCLASS */ + + for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + { + rmask = &ExtCurStyle->exts_typesByResistClass[n]; + if (TTMaskIntersect(rmask, tmask)) + { + *sub_rclassptr = (short)(n); + break; + } } } diff --git a/resis/ResMain.c b/resis/ResMain.c index d5c6469e..400e3808 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -663,6 +663,7 @@ ResExtractNet(startlist, goodies, cellname) * that does not correspond exactly to the layer underneath, include * all connecting types. */ + TTMaskZero(&FirstTileMask); TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, @@ -849,10 +850,10 @@ FindStartTile(goodies, SourcePoint) TileType savtype = goodies->rg_ttype; TileType rtype; - savtype = goodies->rg_ttype; for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++) if (TTMaskHasType(rmask, rtype)) { + goodies->rg_ttype = rtype; if ((tile = FindStartTile(goodies, SourcePoint)) != NULL) { goodies->rg_ttype = savtype; diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index cb663a0b..de1afb51 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -419,7 +419,12 @@ ResSimSubckt(line) devptr = ExtCurStyle->exts_device[ttype]; rpersquare =(float)devptr->exts_linearResist; - device->resistance = MagAtof(lptr) * rpersquare/MagAtof(wptr); + /* Subcircuit types may not have a length or width value, in which */ + /* case it is zero. Don't induce a divide-by-zero error. */ + if (MagAtof(wptr) == 0) + device->resistance = 0; + else + device->resistance = MagAtof(lptr) * rpersquare/MagAtof(wptr); } else device->resistance = 0; @@ -479,7 +484,10 @@ ResSimDevice(line, rpersquare, ttype) TxError("All driven nodes will be extracted\n"); nowarning = FALSE; } - device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); + if (MagAtof(line[RDEV_WIDTH]) != 0) + device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); + else + device->resistance = 0; } device->status = FALSE; device->nextDev = ResRDevList; diff --git a/resis/ResRex.c b/resis/ResRex.c index bc67e95d..90f90cdc 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -22,6 +22,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/textio.h" #include "extract/extract.h" #include "extract/extractInt.h" +#include "extflat/extflat.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/utils.h" @@ -97,17 +98,34 @@ ExtResisForDef(celldef, resisdata) HashEntry *entry; devPtr *tptr,*oldtptr; ResSimNode *node; - int result; + int result, idx; + char *devname; ResRDevList = NULL; ResOriginalNodes = NULL; + /* Get device information from the current extraction style */ + idx = 0; + while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) + { + if (idx == MAXDEVTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + } + HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); /* read in .sim file */ result = (ResReadSim(celldef->cd_name, ResSimDevice, ResSimCapacitor, ResSimResistor, ResSimAttribute, ResSimMerge, ResSimSubckt) == 0); + /* Clean up the EFDevTypes table */ + for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]); + EFDevNumTypes = 0; + if (result) /* read in .nodes file */ result = (ResReadNode(celldef->cd_name) == 0);