Corrected an error that (in a rare circumstance) can cause netgen

to go into an infinite loop and fill memory until it crashes, due
to a complete pin mismatch between devices causing one device to
have its pins removed and replaced with proxy pins.
This commit is contained in:
Tim Edwards 2021-02-24 16:12:19 -05:00
parent 402e1f0f25
commit c7848c9c02
3 changed files with 61 additions and 14 deletions

View File

@ -1 +1 @@
1.5.167 1.5.168

View File

@ -1161,9 +1161,10 @@ int UniquePins(char *name, int filenum)
struct nlist *cleanuppins(struct hashlist *p, void *clientdata) struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
{ {
struct nlist *ptr; struct nlist *ptr;
struct objlist *ob, *obt, *lob, *nob, *firstpin; struct objlist *ob, *obt, *lob, *nob, *firstpin, *pob;
struct nlist *tc = (struct nlist *)clientdata; struct nlist *tc = (struct nlist *)clientdata;
int pinnum; int pinnum;
char *saveinst = NULL;
ptr = (struct nlist *)(p->ptr); ptr = (struct nlist *)(p->ptr);
if (tc->file != ptr->file) return NULL; if (tc->file != ptr->file) return NULL;
@ -1211,14 +1212,45 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
} }
FREE(ob->name); FREE(ob->name);
if (ob->instance.name != NULL) FREE(ob->instance.name); if (ob->instance.name != NULL) {
/* Keep a copy of the instance name (see below) */
if (saveinst != NULL) FREE(saveinst);
saveinst = ob->instance.name;
}
if (ob->model.class != NULL) FREE(ob->model.class); if (ob->model.class != NULL) FREE(ob->model.class);
FREE(ob); FREE(ob);
} }
else { else {
if ((ob->type == PROPERTY) && (pinnum == 1))
{
/* If this happens, then all the pins got removed,
* and there is probably something very much wrong
* with the setup. However, to keep netgen from
* blowing up, add back a "proxy(no pins)" record
* in front; otherwise we'd have an orphaned
* property record.
*/
pob = GetObject();
pob->name = (char *)MALLOC(15);
sprintf(pob->name, "proxy(no pins)");
pob->model.class = strsave(ob->model.class);
if (saveinst != NULL)
pob->instance.name = strsave(saveinst);
else
/* This should never happen */
pob->instance.name = strsave("error");
pob->type = pinnum++;
pob->node = -1;
pob->next = ob;
lob->next = pob;
lob = ob;
}
else
{
lob = ob; lob = ob;
ob->type = pinnum++; // Renumber pins in order ob->type = pinnum++; // Renumber pins in order
} }
}
ob = nob; ob = nob;
obt = obt->next; obt = obt->next;
} }
@ -1228,6 +1260,8 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
HashPtrInstall(firstpin->instance.name, firstpin, &(ptr->instdict)); HashPtrInstall(firstpin->instance.name, firstpin, &(ptr->instdict));
} }
} }
if (saveinst != NULL) FREE(saveinst);
return NULL; /* Keep the search going */ return NULL; /* Keep the search going */
} }

View File

@ -6715,18 +6715,31 @@ struct nlist *addproxies(struct hashlist *p, void *clientdata)
firstpin = ob; firstpin = ob;
while (tob && (tob->type == PORT || tob->type == UNKNOWN)) { while (tob && (tob->type == PORT || tob->type == UNKNOWN)) {
if (tob->type == UNKNOWN) { if (tob->type == UNKNOWN) {
/* ??? Do not do anything with (no pins) entries */ /* Do not do anything with (no pins) entries (in the reference cell) */
if (strcmp(tob->name, "proxy(no pins)")) { if (strcmp(tob->name, "proxy(no pins)")) {
/* But if the target cell instance has proxy(no pins), then reuse
* the record and modify it.
*/
if (!strcmp(ob->name, "proxy(no pins)")) {
obn = ob;
FREE(ob->name);
obn->name = (char *)MALLOC(strlen(ob->instance.name)
+ strlen(tob->name) + 2);
sprintf(obn->name, "%s/%s", ob->instance.name, tob->name);
ob = obn->next;
}
else {
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist)); obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
obn->name = (char *)MALLOC(strlen(firstpin->instance.name) obn->name = (char *)MALLOC(strlen(firstpin->instance.name)
+ strlen(tob->name) + 2); + strlen(tob->name) + 2);
sprintf(obn->name, "%s/%s", firstpin->instance.name, tob->name); sprintf(obn->name, "%s/%s", firstpin->instance.name, tob->name);
obn->instance.name = strsave(firstpin->instance.name); obn->instance.name = strsave(firstpin->instance.name);
obn->model.class = strsave(tc->name); obn->model.class = strsave(tc->name);
obn->type = i++;
obn->node = numnodes++;
obn->next = ob; // Splice into object list obn->next = ob; // Splice into object list
lob->next = obn; lob->next = obn;
}
obn->type = i++;
obn->node = numnodes++;
lob = obn; lob = obn;
// Hash the new pin record for "LookupObject()" // Hash the new pin record for "LookupObject()"