Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.25
 
1.26
 
MAIN:plunky:20140620070733
 
symtabs.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  * 3. The name of the author may not be used to endorse or promote products
 1515  *    derived from this software without specific prior written permission
 1616  *
 1717  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1818  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1919  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 2020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2121  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2222  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2323  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2424  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2525  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2626  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2727  */
 2828 
 2929 
 3030 #include "pass1.h"
 3131 
 3232 /*
 3333  * These definitions are used in the patricia tree that stores
 3434  * the strings.
 3535  */
 3636 #define LEFT_IS_LEAF            0x80000000
 3737 #define RIGHT_IS_LEAF           0x40000000
 3838 #define IS_LEFT_LEAF(x)         (((x) & LEFT_IS_LEAF) != 0)
 3939 #define IS_RIGHT_LEAF(x)        (((x) & RIGHT_IS_LEAF) != 0)
 4040 #define BITNO(x)                ((x) & ~(LEFT_IS_LEAF|RIGHT_IS_LEAF))
 4141 #define CHECKBITS               8
 4242 
 4343 struct tree {
 4444         int bitno;
 4545         struct tree *lr[2];
 4646 };
 4747 
 4848 static struct tree *firstname;
 4949 int nametabs, namestrlen;
 5050 static struct tree *firststr;
 5151 int strtabs, strstrlen;
 5252 static char *symtab_add(char *key, struct tree **, int *, int *);
 5353 int lastloc = NOSEG;
 5454 
 5555 #define P_BIT(key, bit) (key[bit >> 3] >> (bit & 7)) & 1
 5656 #define getree() permalloc(sizeof(struct tree))
 5757 
 5858 char *
 5959 addname(char *key)     
 6060 {
 6161         return symtab_add(key, &firstname, &nametabs, &namestrlen);
 6262 }
 6363 
 6464 char *
 6565 addstring(char *key)
 6666 {
 6767         return symtab_add(key, &firststr, &strtabs, &strstrlen);
 6868 }
 6969 
 7070 /*
 7171  * Add a name to the name stack (if its non-existing),
 7272  * return its address.
 7373  * This is a simple patricia implementation.
 7474  */
<>75 -char *
  75+static char *
<_7676 symtab_add(char *key, struct tree **first, int *tabs, int *stlen)
 7777 {
 7878         struct tree *w, *new, *last;
 7979         int cix, bit, fbit, svbit, ix, bitno, len;
 8080         char *m, *k, *sm;
 8181 
 8282         /* Count full string length */
 8383         for (k = key, len = 0; *k; k++, len++)
 8484                 ;
 8585         
 8686         switch (*tabs) {
 8787         case 0:
 8888                 *first = (struct tree *)newstring(key, len);
 8989                 *stlen += (len + 1);
 9090                 (*tabs)++;
 9191                 return (char *)*first;
 9292 
 9393         case 1:
 9494                 m = (char *)*first;
 9595                 svbit = 0; /* XXX why? */
 9696                 break;
 9797 
 9898         default:
 9999                 w = *first;
 100100                 bitno = len * CHECKBITS;
 101101                 for (;;) {
 102102                         bit = BITNO(w->bitno);
 103103                         fbit = bit > bitno ? 0 : P_BIT(key, bit);
 104104                         svbit = fbit ? IS_RIGHT_LEAF(w->bitno) :
 105105                             IS_LEFT_LEAF(w->bitno);
 106106                         w = w->lr[fbit];
 107107                         if (svbit) {
 108108                                 m = (char *)w;
 109109                                 break;
 110110                         }
 111111                 }
 112112         }
 113113 
 114114         sm = m;
 115115         k = key;
 116116 
 117117         /* Check for correct string and return */
 118118         for (cix = 0; *m && *k && *m == *k; m++, k++, cix += CHECKBITS)
 119119                 ;
 120120         if (*m == 0 && *k == 0)
 121121                 return sm;
 122122 
 123123         ix = *m ^ *k;
 124124         while ((ix & 1) == 0)
 125125                 ix >>= 1, cix++;
 126126 
 127127         /* Create new node */
 128128         new = getree();
 129129         bit = P_BIT(key, cix);
 130130         new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
 131131         new->lr[bit] = (struct tree *)newstring(key, len);
 132132         *stlen += (len + 1);
 133133 
 134134         if ((*tabs)++ == 1) {
 135135                 new->lr[!bit] = *first;
 136136                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
 137137                 *first = new;
 138138                 return (char *)new->lr[bit];
 139139         }
 140140 
 141141 
 142142         w = *first;
 143143         last = NULL;
 144144         for (;;) {
 145145                 fbit = w->bitno;
 146146                 bitno = BITNO(w->bitno);
 147147                 if (bitno == cix)
 148148                         cerror("bitno == cix");
 149149                 if (bitno > cix)
 150150                         break;
 151151                 svbit = P_BIT(key, bitno);
 152152                 last = w;
 153153                 w = w->lr[svbit];
 154154                 if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF))
 155155                         break;
 156156         }
 157157 
 158158         new->lr[!bit] = w;
 159159         if (last == NULL) {
 160160                 *first = new;
 161161         } else {
 162162                 last->lr[svbit] = new;
 163163                 last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
 164164         }
 165165         if (bitno < cix)
 166166                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
 167167         return (char *)new->lr[bit];
 168168 }
 169169 
 170170 static struct tree *sympole[NSTYPES];
 171171 static struct symtab *tmpsyms[NSTYPES];
 172172 int numsyms[NSTYPES];
 173173 
 174174 /*
 175175  * Inserts a symbol into the symbol tree.
 176176  * Returns a struct symtab.
 177177  */
 178178 struct symtab *
 179179 lookup(char *key, int stype)
 180180 {
 181181         struct symtab *sym;
 182182         struct tree *w, *new, *last;
 183183         int cix, bit, fbit, svbit, bitno;
 184184         int type, uselvl;
 185185         intptr_t ix, match, code = (intptr_t)key;
 186186 
 187187         type = stype & SMASK;
 188188         uselvl = (blevel > 0 && type != SSTRING);
 189189 
 190190         /*
 191191          * The local symbols are kept in a simple linked list.
 192192          * Check this list first.
 193193          */
 194194         if (blevel > 0)
 195195                 for (sym = tmpsyms[type]; sym; sym = sym->snext)
 196196                         if (sym->sname == key)
 197197                                 return sym;
 198198 
 199199         switch (numsyms[type]) {
 200200         case 0:
 201201                 if (stype & SNOCREAT)
 202202                         return NULL;
 203203                 if (uselvl) {
 204204                         sym = getsymtab(key, stype|STEMP);
 205205                         sym->snext = tmpsyms[type];
 206206                         tmpsyms[type] = sym;
 207207                         return sym;
 208208                 }
 209209                 sympole[type] = (struct tree *)getsymtab(key, stype);
 210210                 numsyms[type]++;
 211211                 return (struct symtab *)sympole[type];
 212212 
 213213         case 1:
 214214                 w = (struct tree *)sympole[type];
 215215                 svbit = 0; /* XXX why? */
 216216                 break;
 217217 
 218218         default:
 219219                 w = sympole[type];
 220220                 for (;;) {
 221221                         bit = BITNO(w->bitno);
 222222                         fbit = (code >> bit) & 1;
 223223                         svbit = fbit ? IS_RIGHT_LEAF(w->bitno) :
 224224                             IS_LEFT_LEAF(w->bitno);
 225225                         w = w->lr[fbit];
 226226                         if (svbit)
 227227                                 break;
 228228                 }
 229229         }
 230230 
 231231         sym = (struct symtab *)w;
 232232         match = (intptr_t)sym->sname;
 233233 
 234234         ix = code ^ match;
 235235         if (ix == 0)
 236236                 return sym;
 237237         else if (stype & SNOCREAT)
 238238                 return NULL;
 239239 
 240240 #ifdef PCC_DEBUG
 241241         if (ddebug)
 242242                 printf("        adding %s as %s at level %d\n",
 243243                     key, uselvl ? "temp" : "perm", blevel);
 244244 #endif
 245245 
 246246         /*
 247247          * Insert into the linked list, if feasible.
 248248          */
 249249         if (uselvl) {
 250250                 sym = getsymtab(key, stype|STEMP);
 251251                 sym->snext = tmpsyms[type];
 252252                 tmpsyms[type] = sym;
 253253                 return sym;
 254254         }
 255255 
 256256         /*
 257257          * Need a new node. If type is SNORMAL and inside a function
 258258          * the node must be allocated as permanent anyway.
 259259          * This could be optimized by adding a remove routine, but it
 260260          * may be more trouble than it is worth.
 261261          */
 262262         if (stype == (STEMP|SNORMAL))
 263263                 stype = SNORMAL;
 264264 
 265265         for (cix = 0; (ix & 1) == 0; ix >>= 1, cix++)
 266266                 ;
 267267 
 268268         new = stype & STEMP ? tmpalloc(sizeof(struct tree)) :
 269269             permalloc(sizeof(struct tree));
 270270         bit = (code >> cix) & 1;
 271271         new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
 272272         new->lr[bit] = (struct tree *)getsymtab(key, stype);
 273273         if (numsyms[type]++ == 1) {
 274274                 new->lr[!bit] = sympole[type];
 275275                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
 276276                 sympole[type] = new;
 277277                 return (struct symtab *)new->lr[bit];
 278278         }
 279279 
 280280 
 281281         w = sympole[type];
 282282         last = NULL;
 283283         for (;;) {
 284284                 fbit = w->bitno;
 285285                 bitno = BITNO(w->bitno);
 286286                 if (bitno == cix)
 287287                         cerror("bitno == cix");
 288288                 if (bitno > cix)
 289289                         break;
 290290                 svbit = (code >> bitno) & 1;
 291291                 last = w;
 292292                 w = w->lr[svbit];
 293293                 if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF))
 294294                         break;
 295295         }
 296296 
 297297         new->lr[!bit] = w;
 298298         if (last == NULL) {
 299299                 sympole[type] = new;
 300300         } else {
 301301                 last->lr[svbit] = new;
 302302                 last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
 303303         }
 304304         if (bitno < cix)
 305305                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
 306306         return (struct symtab *)new->lr[bit];
 307307 }
 308308 
 309309 void
 310310 symclear(int level)
 311311 {
 312312         struct symtab *s;
 313313         int i;
 314314 
 315315 #ifdef PCC_DEBUG
 316316         if (ddebug)
 317317                 printf("symclear(%d)\n", level);
 318318 #endif
 319319         if (level < 1) {
 320320                 for (i = 0; i < NSTYPES; i++) {
 321321                         s = tmpsyms[i];
 322322                         tmpsyms[i] = 0;
 323323                         if (i != SLBLNAME)
 324324                                 continue;
 325325                         while (s != NULL) {
 326326                                 if (s->soffset < 0)
 327327                                         uerror("label '%s' undefined",s->sname);
 328328                                 s = s->snext;
 329329                         }
 330330                 }
 331331         } else {
 332332                 for (i = 0; i < NSTYPES; i++) {
 333333                         if (i == SLBLNAME)
 334334                                 continue; /* function scope */
 335335                         while (tmpsyms[i] != NULL &&
 336336                             tmpsyms[i]->slevel > level) {
 337337                                 tmpsyms[i] = tmpsyms[i]->snext;
 338338                         }
 339339                 }
 340340         }
 341341 }
 342342 
 343343 struct symtab *
 344344 hide(struct symtab *sym)
 345345 {
 346346         struct symtab *new;
 347347         int typ = sym->sflags & SMASK;
 348348 
 349349         new = getsymtab(sym->sname, typ|STEMP);
 350350         new->snext = tmpsyms[typ];
 351351         tmpsyms[typ] = new;
 352352 
 353353         warner(Wshadow, sym->sname, sym->slevel ? "local" : "global");
 354354 
 355355 #ifdef PCC_DEBUG
 356356         if (ddebug)
 357357                 printf("\t%s hidden at level %d (%p -> %p)\n",
 358358                     sym->sname, blevel, sym, new);
 359359 #endif
 360360         return new;
 361361 }
 362362 
 363363 /*
 364364  * Extract correct segment for the specified symbol and call
 365365  * target routines to print it out.
 366366  * If symtab entry is specified, output alignment as well.
 367367  */
 368368 void
 369369 locctr(int seg, struct symtab *sp)
 370370 {
 371371 #ifdef GCC_COMPAT
 372372         struct attr *ga;
 373373 #endif
 374374 
 375375         if (seg == NOSEG) {
 376376                 ;
 377377         } else if (sp == NULL) {
 378378                 if (lastloc != seg)
 379379                         setseg(seg, NULL);
 380380 #ifdef GCC_COMPAT
 381381         } else if ((ga = attr_find(sp->sap, GCC_ATYP_SECTION)) != NULL) {
 382382                 setseg(NMSEG, ga->sarg(0));
 383383                 seg = NOSEG;
 384384 #endif
 385385         } else {
 386386                 if (seg == DATA) {
 387387                         if (ISCON(cqual(sp->stype, sp->squal)))
 388388                                 seg = RDATA;
 389389                         else if (sp->sclass == STATIC)
 390390                                 seg = LDATA;
 391391                 }
 392392                 if (sp->sflags & STLS) {
 393393                         if (seg == DATA || seg == LDATA)
 394394                                 seg = TLSDATA;
 395395                         if (seg == UDATA) seg = TLSUDATA;
 396396                 } else if (kflag) {
 397397                         if (seg == DATA) seg = PICDATA;
 398398                         if (seg == RDATA) seg = PICRDATA;
 399399                         if (seg == LDATA) seg = PICLDATA;
 400400                 }
 401401                 if (lastloc != seg)
 402402                         setseg(seg, NULL);
 403403         }
 404404         lastloc = seg;
 405405 
 406406         /* setup alignment */
 407407 #ifndef ALFTN
 408408 #define ALFTN   ALINT
 409409 #endif
 410410         if (sp) {
 411411                 int al;
 412412 
 413413                 if (ISFTN(sp->stype)) {
 414414                         al = ALFTN;
 415415                 } else
 416416                         al = talign(sp->stype, sp->sap);
 417417                 defalign(al);
 418418                 symdirec(sp);
 419419         }
 420420 }
 421421 
 422422 #ifndef MYALIGN
 423423 void
 424424 defalign(int al)
 425425 {
 426426 #ifdef  HASP2ALIGN
 427427 #define P2ALIGN(x)      ispow2(x)
 428428 #else
 429429 #define P2ALIGN(x)      (x)
 430430 #endif
 431431         if (al != ALCHAR)
 432432                 printf("\t.align %d\n", P2ALIGN(al/ALCHAR));
 433433 }
 434434 #endif
 435435 
 436436 #ifndef MYDIREC
 437437 /*
 438438  * Directives given as attributes to symbols.
 439439  */
 440440 void
 441441 symdirec(struct symtab *sp)
 442442 {
 443443 #ifdef GCC_COMPAT
 444444         struct attr *ga;
 445445         char *name;
 446446 
 447447         if ((name = sp->soname) == NULL)
 448448                 name = exname(sp->sname);
 449449         if ((ga = attr_find(sp->sap, GCC_ATYP_WEAK)) != NULL)
 450450                 printf("\t.weak %s\n", name);
 451451         if ((ga = attr_find(sp->sap, GCC_ATYP_VISIBILITY)) &&
 452452             strcmp(ga->sarg(0), "default"))
 453453                 printf("\t.%s %s\n", ga->sarg(0), name);
 454454         if ((ga = attr_find(sp->sap, GCC_ATYP_ALIASWEAK))) {
 455455                 printf("\t.weak %s\n", ga->sarg(0));
 456456                 printf("\t.set %s,%s\n", ga->sarg(0), name);
 457457         }
 458458 #endif
 459459 }
 460460 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-31 16:48 +0100