1 /* $NetBSD: read.c,v 1.24 2009/04/14 09:06:25 lukem Exp $ */
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #if HAVE_NBTOOL_CONFIG_H
36 #include "nbtool_config.h"
39 #include <sys/cdefs.h>
40 #if defined(__RCSID) && !defined(lint)
41 __RCSID("$NetBSD: read.c,v 1.24 2009/04/14 09:06:25 lukem Exp $");
54 /* index of current (included) source file */
58 * The array pointed to by inpfns maps the file name indices of input files
59 * to the file name indices used in lint2
62 static size_t ninpfns
;
65 * The array pointed to by *fnames maps file name indizes to file names.
66 * Indices of type short are used instead of pointers to save memory.
69 static size_t *flines
;
70 static size_t nfnames
;
73 * Types are shared (to save memory for the types itself) and accessed
74 * via indices (to save memory for references to types (indices are short)).
75 * To share types, a equal type must be located fast. This is done by a
76 * hash table. Access by indices is done via an array of pointers to the
79 typedef struct thtab
{
84 static thtab_t
**thtab
; /* hash table */
85 type_t
**tlst
; /* array for indexed access */
86 static size_t tlstlen
; /* length of tlst */
88 static hte_t
**renametab
;
90 /* index of current C source file (as spezified at the command line) */
94 #define inperr(fmt, args...) \
95 inperror(__FILE__, __LINE__, fmt, ##args)
96 static void inperror(const char *, size_t, const char *, ...);
97 static void setsrc(const char *);
98 static void setfnid(int, const char *);
99 static void funccall(pos_t
*, const char *);
100 static void decldef(pos_t
*, const char *);
101 static void usedsym(pos_t
*, const char *);
102 static u_short
inptype(const char *, const char **);
103 static int gettlen(const char *, const char **);
104 static u_short
findtype(const char *, size_t, int);
105 static u_short
storetyp(type_t
*, const char *, size_t, int);
106 static int thash(const char *, size_t);
107 static char *inpqstrg(const char *, const char **);
108 static const char *inpname(const char *, const char **);
109 static int getfnidx(const char *);
112 readfile(const char *name
)
117 char *line
, *eptr
, rt
= '\0';
118 int cline
, isrc
, iline
;
122 inpfns
= xcalloc(ninpfns
= 128, sizeof (short));
124 fnames
= xcalloc(nfnames
= 256, sizeof (char *));
126 flines
= xcalloc(nfnames
, sizeof (size_t));
128 tlst
= xcalloc(tlstlen
= 256, sizeof (type_t
*));
130 thtab
= xcalloc(THSHSIZ2
, sizeof (thtab_t
));
132 _inithash(&renametab
);
134 srcfile
= getfnidx(name
);
136 if ((inp
= fopen(name
, "r")) == NULL
)
137 err(1, "cannot open %s", name
);
139 while ((line
= fgetln(inp
, &len
)) != NULL
) {
142 if (len
== 0 || line
[len
- 1] != '\n')
143 inperr("%s", &line
[len
- 1]);
144 line
[len
- 1] = '\0';
147 /* line number in csrcfile */
148 cline
= (int)strtol(cp
, &eptr
, 10);
165 } else if (rt
== 's') {
171 * Index of (included) source file. If this index is
172 * different from csrcfile, it refers to an included
175 isrc
= (int)strtol(cp
, &eptr
, 10);
177 inperr("not a number: %s", cp
);
181 /* line number in isrc */
183 inperr("bad line number");
184 iline
= (int)strtol(cp
, &eptr
, 10);
186 inperr("not a number: %s", cp
);
189 pos
.p_src
= (u_short
)csrcfile
;
190 pos
.p_line
= (u_short
)cline
;
191 pos
.p_isrc
= (u_short
)isrc
;
192 pos
.p_iline
= (u_short
)iline
;
194 /* process rest of this record */
206 inperr("bad record type %c", rt
);
211 _destroyhash(renametab
);
214 err(1, "read error on %s", name
);
221 inperror(const char *file
, size_t line
, const char *fmt
, ...)
227 (void)vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
230 errx(1, "%s,%zu: input file error: %s,%zu (%s)", file
, line
,
231 fnames
[srcfile
], flines
[srcfile
], buf
);
235 * Set the name of the C source file of the .ln file which is
239 setsrc(const char *cp
)
242 csrcfile
= getfnidx(cp
);
246 * setfnid() gets as input an index as used in an input file and the
247 * associated file name. If necessary, it creates a new lint2 file
248 * name index for this file name and creates the mapping of the index
249 * as used in the input file to the index used in lint2.
252 setfnid(int fid
, const char *cp
)
258 if ((size_t)fid
>= ninpfns
) {
259 inpfns
= xrealloc(inpfns
, (ninpfns
* 2) * sizeof (short));
260 (void)memset(inpfns
+ ninpfns
, 0, ninpfns
* sizeof (short));
264 * Should always be true because indices written in the output
265 * file by lint1 are always the previous index + 1.
267 if ((size_t)fid
>= ninpfns
)
268 errx(1, "internal error: setfnid()");
269 inpfns
[fid
] = (u_short
)getfnidx(cp
);
273 * Process a function call record (c-record).
276 funccall(pos_t
*posp
, const char *cp
)
285 fcall
= xalloc(sizeof (fcall_t
));
286 STRUCT_ASSIGN(fcall
->f_pos
, *posp
);
290 lai
= &fcall
->f_args
;
291 while ((c
= *cp
) == 'u' || c
== 'i' || c
== 'd' ||
292 c
== 'z' || c
== 'p' || c
== 'n' || c
== 's') {
297 inperr("used or discovered: %c", c
);
302 inperr("used or discovered: %c", c
);
306 inperr("used or discovered: %c", c
);
313 ai
= xalloc(sizeof (arginf_t
));
314 ai
->a_num
= (int)strtol(cp
, &eptr
, 10);
316 inperr("bad number: %s", cp
);
319 ai
->a_pcon
= ai
->a_zero
= 1;
320 } else if (c
== 'p') {
322 } else if (c
== 'n') {
326 ai
->a_fstrg
= inpqstrg(cp
, &cp
);
333 fcall
->f_rused
= rused
;
334 fcall
->f_rdisc
= rdisc
;
336 /* read name of function */
337 name
= inpname(cp
, &cp
);
339 /* first look it up in the renaming table, then in the normal table */
340 hte
= _hsearch(renametab
, name
, 0);
344 hte
= hsearch(name
, 1);
347 fcall
->f_type
= inptype(cp
, &cp
);
349 *hte
->h_lcall
= fcall
;
350 hte
->h_lcall
= &fcall
->f_nxt
;
353 inperr("trailing line data: %s", cp
);
357 * Process a declaration or definition (d-record).
360 decldef(pos_t
*posp
, const char *cp
)
363 char c
, *ep
, *pos1
, *tname
;
365 hte_t
*hte
, *renamehte
= NULL
;
366 const char *name
, *newname
;
368 (void)memset(&sym
, 0, sizeof (sym
));
369 STRUCT_ASSIGN(sym
.s_pos
, *posp
);
374 while (strchr("tdeurosvPS", (c
= *cp
)) != NULL
) {
378 if (sym
.s_def
!= NODECL
)
379 inperr("nodecl %c", c
);
383 if (sym
.s_def
!= NODECL
)
384 inperr("nodecl %c", c
);
388 if (sym
.s_def
!= NODECL
)
389 inperr("nodecl %c", c
);
394 inperr("used %c", c
);
416 sym
.s_nva
= (short)strtol(cp
, &ep
, 10);
418 inperr("bad number: %s", cp
);
425 sym
.s_nprfl
= (short)strtol(cp
, &ep
, 10);
427 inperr("bad number: %s", cp
);
434 sym
.s_nscfl
= (short)strtol(cp
, &ep
, 10);
436 inperr("bad number: %s", cp
);
442 /* read symbol name, doing renaming if necessary */
443 name
= inpname(cp
, &cp
);
447 tname
= xstrdup(name
);
448 newname
= inpname(cp
, &cp
);
450 /* enter it and see if it's already been renamed */
451 renamehte
= _hsearch(renametab
, tname
, 1);
452 if (renamehte
->h_hte
== NULL
) {
453 hte
= hsearch(newname
, 1);
454 renamehte
->h_hte
= hte
;
456 } else if (strcmp((hte
= renamehte
->h_hte
)->h_name
, newname
)) {
457 pos1
= xstrdup(mkpos(&renamehte
->h_syms
->s_pos
));
458 /* %s renamed multiple times\t%s :: %s */
459 msg(18, tname
, pos1
, mkpos(&sym
.s_pos
));
464 /* it might be a previously-done rename */
465 hte
= _hsearch(renametab
, name
, 0);
469 hte
= hsearch(name
, 1);
472 if (sym
.s_def
== DEF
|| sym
.s_def
== TDEF
)
475 sym
.s_type
= inptype(cp
, &cp
);
478 * Allocate memory for this symbol only if it was not already
479 * declared or tentatively defined at the same location with
480 * the same type. Works only for symbols with external linkage,
481 * because static symbols, tentatively defined at the same location
482 * but in different translation units are really different symbols.
484 for (symp
= hte
->h_syms
; symp
!= NULL
; symp
= symp
->s_nxt
) {
485 if (symp
->s_pos
.p_isrc
== sym
.s_pos
.p_isrc
&&
486 symp
->s_pos
.p_iline
== sym
.s_pos
.p_iline
&&
487 symp
->s_type
== sym
.s_type
&&
488 ((symp
->s_def
== DECL
&& sym
.s_def
== DECL
) ||
489 (!sflag
&& symp
->s_def
== TDEF
&& sym
.s_def
== TDEF
)) &&
490 !symp
->s_static
&& !sym
.s_static
) {
496 /* allocsym reserviert keinen Platz fuer s_nva */
497 if (sym
.s_va
|| sym
.s_prfl
|| sym
.s_scfl
) {
498 symp
= xalloc(sizeof (sym_t
));
499 STRUCT_ASSIGN(*symp
, sym
);
501 symp
= xalloc(sizeof (symp
->s_s
));
502 STRUCT_ASSIGN(symp
->s_s
, sym
.s_s
);
505 hte
->h_lsym
= &symp
->s_nxt
;
507 /* XXX hack so we can remember where a symbol was renamed */
509 renamehte
->h_syms
= symp
;
513 inperr("trailing line: %s", cp
);
517 * Read an u-record (emited by lint1 if a symbol was used).
520 usedsym(pos_t
*posp
, const char *cp
)
526 usym
= xalloc(sizeof (usym_t
));
527 STRUCT_ASSIGN(usym
->u_pos
, *posp
);
529 /* needed as delimiter between two numbers */
531 inperr("bad delim %c", cp
[-1]);
533 name
= inpname(cp
, &cp
);
534 hte
= _hsearch(renametab
, name
, 0);
538 hte
= hsearch(name
, 1);
541 *hte
->h_lusym
= usym
;
542 hte
->h_lusym
= &usym
->u_nxt
;
546 * Read a type and return the index of this type.
549 inptype(const char *cp
, const char **epp
)
554 int narg
, i
, osdef
= 0;
559 /* If we have this type already, return it's index. */
560 tlen
= gettlen(cp
, &ep
);
562 if ((tidx
= findtype(cp
, tlen
, h
)) != 0) {
567 /* No, we must create a new type. */
568 tp
= xalloc(sizeof (type_t
));
570 tidx
= storetyp(tp
, cp
, tlen
, h
);
574 while (c
== 'c' || c
== 'v') {
601 tp
->t_tspec
= s
== 's' ? SCHAR
: (s
== 'u' ? UCHAR
: CHAR
);
604 tp
->t_tspec
= s
== 'u' ? USHORT
: SHORT
;
607 tp
->t_tspec
= s
== 'u' ? UINT
: INT
;
610 tp
->t_tspec
= s
== 'u' ? ULONG
: LONG
;
613 tp
->t_tspec
= s
== 'u' ? UQUAD
: QUAD
;
616 tp
->t_tspec
= s
== 's' ? FLOAT
: (s
== 'l' ? LDOUBLE
: DOUBLE
);
633 tp
->t_tspec
= s
== 'e' ? ENUM
: (s
== 's' ? STRUCT
: UNION
);
636 tp
->t_tspec
= s
== 's' ? FCOMPLEX
637 : (s
== 'l' ? LCOMPLEX
: DCOMPLEX
);
641 switch (tp
->t_tspec
) {
643 tp
->t_dim
= (int)strtol(cp
, &eptr
, 10);
645 sidx
= inptype(cp
, &cp
); /* force seq. point! (ditto below) */
646 tp
->t_subt
= TP(sidx
);
649 sidx
= inptype(cp
, &cp
);
650 tp
->t_subt
= TP(sidx
);
654 if (isdigit((u_char
)c
)) {
657 narg
= (int)strtol(cp
, &eptr
, 10);
659 tp
->t_args
= xcalloc((size_t)(narg
+ 1),
661 for (i
= 0; i
< narg
; i
++) {
662 if (i
== narg
- 1 && *cp
== 'E') {
666 sidx
= inptype(cp
, &cp
);
667 tp
->t_args
[i
] = TP(sidx
);
671 sidx
= inptype(cp
, &cp
);
672 tp
->t_subt
= TP(sidx
);
683 tp
->t_tag
= hsearch(inpname(cp
, &cp
), 1);
687 tp
->t_tynam
= hsearch(inpname(cp
, &cp
), 1);
691 tp
->t_uniqpos
.p_line
= strtol(cp
, &eptr
, 10);
694 /* xlate to 'global' file name. */
695 tp
->t_uniqpos
.p_file
=
696 addoutfile(inpfns
[strtol(cp
, &eptr
, 10)]);
699 tp
->t_uniqpos
.p_uniq
= strtol(cp
, &eptr
, 10);
737 * Get the length of a type string.
740 gettlen(const char *cp
, const char **epp
)
753 while (c
== 'c' || c
== 'v') {
789 } else if (s
== 'u') {
791 } else if (s
== '\0') {
798 } else if (s
== '\0') {
805 } else if (s
== '\0') {
812 } else if (s
== '\0') {
819 } else if (s
== '\0') {
826 } else if (s
== 'l') {
828 } else if (s
== '\0') {
852 } else if (s
== 's') {
854 } else if (s
== 'u') {
861 } else if (s
== 'l') {
863 } else if (s
== '\0') {
868 inperr("bad type: %c %c", c
, s
);
872 inperr("undefined type: %c %c", c
, s
);
877 (void)strtol(cp
, &eptr
, 10);
879 inperr("bad number: %s", cp
);
881 (void)gettlen(cp
, &cp
);
884 (void)gettlen(cp
, &cp
);
888 if (isdigit((u_char
)c
)) {
889 narg
= (int)strtol(cp
, &eptr
, 10);
891 for (i
= 0; i
< narg
; i
++) {
892 if (i
== narg
- 1 && *cp
== 'E') {
895 (void)gettlen(cp
, &cp
);
899 (void)gettlen(cp
, &cp
);
906 (void)inpname(cp
, &cp
);
909 (void)inpname(cp
, &cp
);
912 /* unique position: line.file.uniquifier */
913 (void)strtol(cp
, &eptr
, 10);
915 inperr("bad number: %s", cp
);
918 inperr("not dot: %c", cp
[-1]);
919 (void)strtol(cp
, &eptr
, 10);
921 inperr("bad number: %s", cp
);
924 inperr("not dot: %c", cp
[-1]);
925 (void)strtol(cp
, &eptr
, 10);
927 inperr("bad number: %s", cp
);
931 inperr("bad value: %c\n", cp
[-1]);
969 * Search a type by it's type string.
972 findtype(const char *cp
, size_t len
, int h
)
976 for (thte
= thtab
[h
]; thte
!= NULL
; thte
= thte
->th_nxt
) {
977 if (strncmp(thte
->th_name
, cp
, len
) != 0)
979 if (thte
->th_name
[len
] == '\0')
980 return (thte
->th_idx
);
987 * Store a type and it's type string so we can later share this type
988 * if we read the same type string from the input file.
991 storetyp(type_t
*tp
, const char *cp
, size_t len
, int h
)
993 static u_int tidx
= 1; /* 0 is reserved */
997 if (tidx
>= USHRT_MAX
)
998 errx(1, "sorry, too many types");
1000 if (tidx
== tlstlen
- 1) {
1001 tlst
= xrealloc(tlst
, (tlstlen
* 2) * sizeof (type_t
*));
1002 (void)memset(tlst
+ tlstlen
, 0, tlstlen
* sizeof (type_t
*));
1008 /* create a hash table entry */
1009 name
= xalloc(len
+ 1);
1010 (void)memcpy(name
, cp
, len
);
1013 thte
= xalloc(sizeof (thtab_t
));
1014 thte
->th_name
= name
;
1015 thte
->th_idx
= tidx
;
1016 thte
->th_nxt
= thtab
[h
];
1019 return ((u_short
)tidx
++);
1023 * Hash function for types
1026 thash(const char *s
, size_t len
)
1031 while (len
-- != 0) {
1032 v
= (v
<< sizeof (v
)) + (u_char
)*s
++;
1033 v
^= v
>> (sizeof (v
) * CHAR_BIT
- sizeof (v
));
1035 return (v
% THSHSIZ2
);
1039 * Read a string enclosed by "". This string may contain quoted chars.
1042 inpqstrg(const char *src
, const char **epp
)
1049 dst
= strg
= xmalloc(slen
= 32);
1051 if ((c
= *src
++) != '"')
1052 inperr("not quote: %c", c
);
1053 if ((c
= *src
++) == '\0')
1054 inperr("trailing data: %c", c
);
1058 if ((c
= *src
++) == '\0')
1059 inperr("missing after \\");
1091 case '0': case '1': case '2': case '3':
1093 if ((c
= *src
++) < '0' || c
> '7')
1094 inperr("not octal: %c", c
);
1095 v
|= (c
- '0') << 3;
1096 if ((c
= *src
++) < '0' || c
> '7')
1097 inperr("not octal: %c", c
);
1102 inperr("bad \\ escape: %c", c
);
1105 /* keep space for trailing '\0' */
1106 if ((size_t)(dst
- strg
) == slen
- 1) {
1107 strg
= xrealloc(strg
, slen
* 2);
1108 dst
= strg
+ (slen
- 1);
1112 if ((c
= *src
++) == '\0')
1113 inperr("missing closing quote");
1122 * Read the name of a symbol in static memory.
1125 inpname(const char *cp
, const char **epp
)
1128 static size_t blen
= 0;
1132 len
= (int)strtol(cp
, &eptr
, 10);
1134 inperr("bad number: %s", cp
);
1137 buf
= xrealloc(buf
, blen
= len
+ 1);
1138 for (i
= 0; i
< len
; i
++) {
1140 if (!isalnum((unsigned char)c
) && c
!= '_')
1141 inperr("not alnum or _: %c", c
);
1151 * Return the index of a file name. If the name cannot be found, create
1152 * a new entry and return the index of the newly created entry.
1155 getfnidx(const char *fn
)
1160 for (i
= 1; fnames
[i
] != NULL
; i
++) {
1161 if (strcmp(fnames
[i
], fn
) == 0)
1165 if (i
== nfnames
- 1) {
1166 size_t nlen
= nfnames
* 2;
1167 fnames
= xrealloc(fnames
, nlen
* sizeof(char *));
1168 (void)memset(fnames
+ nfnames
, 0, nfnames
* sizeof(char *));
1169 flines
= xrealloc(flines
, nlen
* sizeof(size_t));
1170 (void)memset(flines
+ nfnames
, 0, nfnames
* sizeof(size_t));
1174 fnames
[i
] = xstrdup(fn
);
1180 * Separate symbols with static and external linkage.
1183 mkstatic(hte_t
*hte
)
1185 sym_t
*sym1
, **symp
, *sym
;
1186 fcall_t
**callp
, *call
;
1187 usym_t
**usymp
, *usym
;
1191 /* Look for first static definition */
1192 for (sym1
= hte
->h_syms
; sym1
!= NULL
; sym1
= sym1
->s_nxt
) {
1199 /* Do nothing if this name is used only in one translation unit. */
1201 for (sym
= hte
->h_syms
; sym
!= NULL
&& !ofnd
; sym
= sym
->s_nxt
) {
1202 if (sym
->s_pos
.p_src
!= sym1
->s_pos
.p_src
)
1205 for (call
= hte
->h_calls
; call
!= NULL
&& !ofnd
; call
= call
->f_nxt
) {
1206 if (call
->f_pos
.p_src
!= sym1
->s_pos
.p_src
)
1209 for (usym
= hte
->h_usyms
; usym
!= NULL
&& !ofnd
; usym
= usym
->u_nxt
) {
1210 if (usym
->u_pos
.p_src
!= sym1
->s_pos
.p_src
)
1215 /* errors about undef. static symbols are printed in lint1 */
1222 * Create a new hash table entry
1224 * XXX this entry should be put at the beginning of the list to
1225 * avoid to process the same symbol twice.
1227 for (nhte
= hte
; nhte
->h_link
!= NULL
; nhte
= nhte
->h_link
)
1229 nhte
->h_link
= xmalloc(sizeof (hte_t
));
1230 nhte
= nhte
->h_link
;
1231 nhte
->h_name
= hte
->h_name
;
1233 nhte
->h_def
= 1; /* error in lint1 */
1235 nhte
->h_syms
= NULL
;
1236 nhte
->h_lsym
= &nhte
->h_syms
;
1237 nhte
->h_calls
= NULL
;
1238 nhte
->h_lcall
= &nhte
->h_calls
;
1239 nhte
->h_usyms
= NULL
;
1240 nhte
->h_lusym
= &nhte
->h_usyms
;
1241 nhte
->h_link
= NULL
;
1245 * move all symbols used in this translation unit into the new
1248 for (symp
= &hte
->h_syms
; (sym
= *symp
) != NULL
; ) {
1249 if (sym
->s_pos
.p_src
== sym1
->s_pos
.p_src
) {
1251 (*symp
) = sym
->s_nxt
;
1252 if (hte
->h_lsym
== &sym
->s_nxt
)
1255 *nhte
->h_lsym
= sym
;
1256 nhte
->h_lsym
= &sym
->s_nxt
;
1261 for (callp
= &hte
->h_calls
; (call
= *callp
) != NULL
; ) {
1262 if (call
->f_pos
.p_src
== sym1
->s_pos
.p_src
) {
1263 (*callp
) = call
->f_nxt
;
1264 if (hte
->h_lcall
== &call
->f_nxt
)
1265 hte
->h_lcall
= callp
;
1267 *nhte
->h_lcall
= call
;
1268 nhte
->h_lcall
= &call
->f_nxt
;
1270 callp
= &call
->f_nxt
;
1273 for (usymp
= &hte
->h_usyms
; (usym
= *usymp
) != NULL
; ) {
1274 if (usym
->u_pos
.p_src
== sym1
->s_pos
.p_src
) {
1275 (*usymp
) = usym
->u_nxt
;
1276 if (hte
->h_lusym
== &usym
->u_nxt
)
1277 hte
->h_lusym
= usymp
;
1279 *nhte
->h_lusym
= usym
;
1280 nhte
->h_lusym
= &usym
->u_nxt
;
1282 usymp
= &usym
->u_nxt
;
1286 /* h_def must be recalculated for old hte */
1287 hte
->h_def
= nhte
->h_def
= 0;
1288 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
1289 if (sym
->s_def
== DEF
|| sym
->s_def
== TDEF
) {