|
|
1.1 root 1: /* @(#)lists.c 1.6 11/11/83 */
2:
3: #include <stdio.h>
4: #include <ar.h>
5: #include "dis.h"
6: #include "filehdr.h"
7: #include "ldfcn.h"
8: #include "sgs.h"
9: #include "scnhdr.h"
10: #include "linenum.h"
11: #include "syms.h"
12: #include "structs.h"
13: #if OLIST
14: #include "olist_defs.h"
15: #else
16: #define TOOL "dis"
17: #endif
18:
19: /*
20: * build_sections()
21: *
22: * create the list of sections to be disassembled
23: */
24:
25: SCNLIST *
26: build_sections()
27: {
28: extern char *calloc();
29:
30: extern LDFILE *f_ptr;
31: extern FILHDR filhdr;
32: extern int nsecs;
33: extern char *namedsec[];
34: extern int namedtype[];
35: extern char *fname;
36: extern int trace;
37:
38: SCNLIST *sclist;
39: SCNLIST *sclisttail;
40: SCNLIST *sectp;
41: SCNHDR scnhdr;
42: int sect;
43: int i;
44:
45: /* read all the section headers in the file. If the section
46: * is one of the named sections, add it to the list. If
47: * there were no named sections, and the section is a text
48: * section, add it to the list
49: */
50:
51: sclisttail = sclist = NULL;
52: if (nsecs >= 0)
53: {
54: for ( i = 0; i <= nsecs; i++ )
55: {
56: FSEEK( f_ptr, FILHSZ + filhdr.f_opthdr, BEGINNING );
57: for ( sect = 1; sect <= filhdr.f_nscns; sect++ )
58: {
59: FREAD( &scnhdr, SCNHSZ, 1, f_ptr );
60: if (strncmp( namedsec[i], scnhdr.s_name, 8 ) == 0)
61: break;
62: }
63: if (sect > filhdr.f_nscns)
64: {
65: fprintf( stderr, "%s%s: %s: %s: cannot find section header\n",
66: SGS, TOOL, fname, namedsec[i] );
67: continue;
68: }
69: if (trace > 0)
70: printf( "\nsection name is {%s}\n", scnhdr.s_name );
71: if ((scnhdr.s_scnptr == 0)
72: || (scnhdr.s_flags & STYP_DSECT)
73: || (scnhdr.s_flags & STYP_NOLOAD))
74: {
75: fprintf(stderr,"%s%s: %s: %.8s: not a loaded section\n",
76: SGS, TOOL, fname, scnhdr.s_name );
77: continue;
78: }
79:
80: if ((sectp = (SCNLIST *) calloc( 1, sizeof(SCNLIST))) == NULL)
81: fatal( "memory allocation failure" );
82: sectp->shdr = scnhdr;
83: sectp->scnum = sect;
84: sectp->stype = namedtype[i];
85: if (sclisttail)
86: sclisttail->snext = sectp;
87: sclisttail = sectp;
88: if (sclist == NULL)
89: sclist = sectp;
90: }
91: }
92: else
93: for ( sect = 1; sect <= filhdr.f_nscns; sect++ )
94: {
95: if (ldshread (f_ptr, sect, &scnhdr ) == FAILURE)
96: fatal( "can't read section header %d\n" );
97: if (trace > 0)
98: printf( "\nsection name is {%s}\n", scnhdr.s_name );
99:
100: if ((strcmp( ".text", scnhdr.s_name, NCPS) != 0)
101: && (scnhdr.s_lnnoptr == 0)
102: && !(scnhdr.s_flags & STYP_TEXT))
103: continue;
104:
105: #if OLIST
106: if ((strcmp( scnhdr.s_name, ".plb" ) == 0)
107: || (strcmp( scnhdr.s_name, ".ecd" ) == 0))
108: continue;
109: #endif
110:
111: if ((scnhdr.s_scnptr == 0)
112: || (scnhdr.s_flags & STYP_DSECT)
113: || (scnhdr.s_flags & STYP_NOLOAD))
114: {
115: fprintf(stderr,"%s%s: %s: %.8s: not a loaded section\n",
116: SGS, TOOL, fname, scnhdr.s_name );
117: continue;
118: }
119:
120: if ((sectp = (SCNLIST *) calloc( 1, sizeof(SCNLIST))) == NULL)
121: fatal( "memory allocation failure" );
122: sectp->shdr = scnhdr;
123: sectp->scnum = sect;
124: sectp->stype = TEXT;
125: if (sclisttail)
126: sclisttail->snext = sectp;
127: sclisttail = sectp;
128: if (sclist == NULL)
129: sclist = sectp;
130: }
131:
132: return( sclist );
133: }
134:
135:
136:
137: /*
138: * section_free()
139: *
140: * free the space used by the list of section headers
141: */
142:
143: section_free( sclist )
144: SCNLIST *sclist;
145: {
146: SCNLIST *sectp;
147: SCNLIST *stemp;
148: FUNCLIST *funcp;
149: FUNCLIST *ftemp;
150:
151: if (sclist == NULL)
152: return;
153:
154: sectp = sclist;
155: while ( sectp )
156: {
157: stemp = sectp;
158: funcp = sectp->funcs;
159: sectp = sectp->snext;
160: free( stemp );
161:
162: while ( funcp )
163: {
164: ftemp = funcp;
165: funcp = funcp->nextfunc;
166: free( ftemp->funcnm );
167: free( ftemp );
168: }
169: }
170: }
171:
172: /*
173: * build_funcs()
174: *
175: * for each section in the list for section headers,
176: * make a list of the functions in that section
177: */
178:
179: #if !AR16WR || OLIST
180: build_funcs( sclist )
181: SCNLIST *sclist;
182: {
183: extern char *calloc();
184: extern char *ldgetname();
185:
186: extern LDFILE *symb;
187: extern FILHDR filhdr;
188:
189: SCNLIST *sectp;
190: SYMENT symbol;
191: AUXENT axent;
192: FUNCLIST *func;
193: char *func_name;
194: long i;
195:
196: for ( i = 0; i < filhdr.f_nsyms; i++)
197: {
198: if (ldtbread( symb, i, &symbol ) == FAILURE )
199: fatal( "cannot read symbol table" );
200:
201: for (sectp = sclist; sectp; sectp = sectp->snext)
202: if (sectp->scnum == symbol.n_scnum)
203: break;
204:
205: if (ISFCN( symbol.n_type ) || ((symbol.n_sclass==C_EXT ||
206: symbol.n_sclass == C_STAT) &&
207: (strncmp(sectp->shdr.s_name,".text",8) == 0) &&
208: (strncmp(symbol.n_name,".text",8) != 0)))
209: {
210: if ((func = (FUNCLIST *) calloc( 1, sizeof(FUNCLIST))) == NULL)
211: fatal( "memory allocation failure");
212: if ((func_name = ldgetname( symb, &symbol )) == NULL)
213: fatal( "can't read function name");
214: if ((func->funcnm = calloc(1, strlen( func_name ) + 1)) == NULL)
215: fatal( "memory allocation failure" );
216: strcpy( func->funcnm, func_name );
217: func->faddr = symbol.n_value;
218: func->fcnindex = i;
219: #if OLIST
220: i++;
221: if (ldtbread( symb, i, &axent ) == FAILURE )
222: fatal( "cannot read symbol table" );
223: func->fend = func->faddr + axent.x_sym.x_misc.x_fsize;
224: #else
225: i += symbol.n_numaux;
226: #endif
227: add_func( func, sclist, symbol.n_scnum );
228: }
229:
230: else
231: i += symbol.n_numaux;
232: }
233:
234: #if OLIST
235: for ( sectp = sclist; sectp; sectp = sectp->snext )
236: for ( func = sectp->funcs; func; func = func->nextfunc )
237: if (func->nextfunc)
238: {
239: if (func->fend < func->nextfunc->faddr)
240: func->fend = func->nextfunc->faddr;
241: }
242: else if (func->fend < (sectp->shdr.s_paddr + sectp->shdr.s_size))
243: func->fend = sectp->shdr.s_paddr + sectp->shdr.s_size;
244: #endif
245: }
246:
247: /*
248: * add_func()
249: *
250: * add func to the list of functions associated with the section
251: * given by sect
252: */
253:
254: add_func( func, sclist, sect )
255: FUNCLIST *func;
256: SCNLIST *sclist;
257: short sect;
258: {
259: extern char *fname;
260:
261: static short last_sect = 0;
262: static FUNCLIST *last_func = NULL;
263: static char *last_file = NULL;
264:
265: SCNLIST *sectp;
266: FUNCLIST *funcp;
267: FUNCLIST *backp;
268: static int elist=1;
269:
270: /*
271: * if this function follows the last function added to the list,
272: * the addition can be done quickly
273: */
274: if (elist && (last_sect == sect) && last_func && (last_func->faddr < func->faddr)
275: && last_file && !strcmp( fname, last_file ))
276: {
277: funcp = last_func->nextfunc;
278: func->nextfunc = funcp;
279: funcp = func;
280: last_func = func;
281: elist = 1;
282: }
283: else
284: {
285: /* find the corresponding section pointer */
286: for ( sectp = sclist; sectp; sectp = sectp->snext )
287: {
288: if (sectp->scnum == sect)
289: break;
290: }
291:
292: if (sectp)
293: {
294: /* keep the list of functions ordered by address */
295: if ((sectp->funcs == NULL)
296: || (sectp->funcs->faddr > func->faddr))
297: {
298: func->nextfunc = sectp->funcs;
299: sectp->funcs = func;
300: if (sectp->funcs == NULL) elist=1;
301: else elist=0;
302: }
303: else
304: {
305: backp = sectp->funcs;
306: funcp = sectp->funcs->nextfunc;
307: for ( ; funcp; funcp = funcp->nextfunc)
308: {
309: if (func->faddr < funcp->faddr)
310: {
311: func->nextfunc = funcp;
312: backp->nextfunc = func;
313: break;
314: }
315: backp = funcp;
316: }
317: if (funcp == NULL)
318: backp->nextfunc = func;
319: elist = 0;
320: }
321:
322: last_func = func;
323: last_sect = sect;
324: last_file = fname;
325: }
326:
327: else
328: free( func );
329: }
330: }
331: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.