static void GenerateLabel (unsigned Flags, unsigned Addr) /* Generate a label in pass one if requested */ { /* Generate labels in pass #1, and only if we don't have a label already */ if (Pass == 1 && !HaveLabel (Addr) && /* Check if we must create a label */ ((Flags & flGenLabel) != 0 || ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd))) { /* As a special case, handle ranges with tables or similar. Within * such a range with a granularity > 1, do only generate dependent * labels for all addresses but the first one. Be sure to generate * a label for the start of the range, however. */ attr_t Style = GetStyleAttr (Addr); unsigned Granularity = GetGranularity (Style); if (Granularity == 1) { /* Just add the label */ AddIntLabel (Addr); } else { /* THIS CODE IS A MESS AND WILL FAIL ON SEVERAL CONDITIONS! ### */ /* Search for the start of the range or the last non dependent * label in the range. */ unsigned Offs; attr_t LabelAttr; unsigned LabelAddr = Addr; while (LabelAddr > CodeStart) { if (Style != GetStyleAttr (LabelAddr-1)) { /* End of range reached */ break; } --LabelAddr; LabelAttr = GetLabelAttr (LabelAddr); if ((LabelAttr & (atIntLabel|atExtLabel)) != 0) { /* The address has an internal or external label */ break; } } /* If the proposed label address doesn't have a label, define one */ if ((GetLabelAttr (LabelAddr) & (atIntLabel|atExtLabel)) == 0) { AddIntLabel (LabelAddr); } /* Create the label */ Offs = Addr - LabelAddr; if (Offs == 0) { AddIntLabel (Addr); } else { AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs); } } } }
void ForwardLabel (unsigned Offs) /* If necessary, output a forward label, one that is within the next few * bytes and is therefore output as "label = * + x". */ { /* Calculate the actual address */ unsigned long Addr = PC + Offs; /* Get the type of the label */ attr_t A = GetLabelAttr (Addr); /* If there is no label, or just a dependent one, bail out */ if (A == atNoLabel || (A & atDepLabel) != 0) { return; } /* An unnamed label cannot be output as a forward declaration, so this is * an error. */ if (A == atUnnamedLabel) { Error ("Cannot define unnamed label at address $%04lX", Addr); } /* Output the label */ DefForward (GetLabelName (Addr), GetComment (Addr), Offs); }
int MustDefLabel (unsigned Addr) /* Return true if we must define a label for this address, that is, if there * is a label at this address, and it is an external or internal label. */ { /* Get the label attribute */ attr_t A = GetLabelAttr (Addr); /* Check for an internal, external, or unnamed label */ return (A == atExtLabel || A == atIntLabel || A == atUnnamedLabel); }
const char* GetLabelName (unsigned Addr) /* Return the label name for an address */ { /* Get the label attribute */ attr_t A = GetLabelAttr (Addr); /* Special case unnamed labels, because these don't have a named stored in * the symbol table to save space. */ if (A == atUnnamedLabel) { return ""; } else { /* Return the label if any */ return SymTab[Addr]; } }
static void DefOutOfRangeLabel (unsigned long Addr) /* Define one label that is outside code range. */ { switch (GetLabelAttr (Addr)) { case atIntLabel: case atExtLabel: DefConst (SymTab[Addr], GetComment (Addr), Addr); break; case atUnnamedLabel: Error ("Cannot define unnamed label at address $%04lX", Addr); break; default: break; } }
static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) /* Add a label */ { /* Get an existing label attribute */ attr_t ExistingAttr = GetLabelAttr (Addr); /* Must not have two symbols for one address */ if (ExistingAttr != atNoLabel) { /* Allow redefinition if identical. Beware: Unnamed labels don't * have a name (you guessed that, didn't you?). */ if (ExistingAttr == Attr && ((Name == 0 && SymTab[Addr] == 0) || strcmp (SymTab[Addr], Name) == 0)) { return; } Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name); } /* Create a new label (xstrdup will return NULL if input NULL) */ SymTab[Addr] = xstrdup (Name); /* Remember the attribute */ MarkAddr (Addr, Attr); }
const char* GetLabel (unsigned Addr, unsigned RefFrom) /* Return the label name for an address, as it is used in a label reference. * RefFrom is the address the label is referenced from. This is needed in case * of unnamed labels, to determine the name. */ { static const char* FwdLabels[] = { ":+", ":++", ":+++", ":++++", ":+++++", ":++++++", ":+++++++", ":++++++++", ":+++++++++", ":++++++++++" }; static const char* BackLabels[] = { ":-", ":--", ":---", ":----", ":-----", ":------", ":-------", ":--------", ":---------", ":----------" }; /* Get the label attribute */ attr_t A = GetLabelAttr (Addr); /* Special case unnamed labels, because these don't have a named stored in * the symbol table to save space. */ if (A == atUnnamedLabel) { unsigned Count = 0; /* Search forward or backward depending in which direction the label * is. */ if (Addr <= RefFrom) { /* Search backwards */ unsigned I = RefFrom; while (Addr < I) { --I; A = GetLabelAttr (I); if (A == atUnnamedLabel) { ++Count; if (Count >= sizeof (BackLabels) / sizeof (BackLabels[0])) { Error ("Too many unnamed labels between label at " "$%04X and reference at $%04X", Addr, RefFrom); } } } /* Return the label name */ return BackLabels[Count-1]; } else { /* Search forwards */ unsigned I = RefFrom; while (Addr > I) { ++I; A = GetLabelAttr (I); if (A == atUnnamedLabel) { ++Count; if (Count >= sizeof (FwdLabels) / sizeof (FwdLabels[0])) { Error ("Too many unnamed labels between label at " "$%04X and reference at $%04X", Addr, RefFrom); } } } /* Return the label name */ return FwdLabels[Count-1]; } } else { /* Return the label if any */ return SymTab[Addr]; } }
int HaveLabel (unsigned Addr) /* Check if there is a label for the given address */ { /* Check for a label */ return (GetLabelAttr (Addr) != atNoLabel); }