Pristine Ack-5.5
[Ack-5.5.git] / util / amisc / ashow.c
1 static char     rcsid[] = "$Id: ashow.c,v 1.6 1994/06/24 10:13:45 ceriel Exp $";
2 /*
3  * show - make the contents of an ACK object file human readable.
4  */
5
6 #include <stdio.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <out.h>
10
11 #define OK      0       /* Return value of gethead if Orl Korekt. */
12 #define BMASK   0xFF    /* To extract least significant 8 bits from an int. */
13
14 /* ARGSUSED */
15 main(argc, argv)
16         int     argc;
17         char    *argv[];
18 #               define prog     argv[0]
19 {
20         register char   **arg = argv;
21         struct outhead  header;
22
23         while (*++arg) {
24                 if (! rd_open(*arg)) {
25                         error("%s: cannot read %s\n", prog, *arg);
26                         continue;
27                 }
28                 rd_ohead(&header);
29                 if (BADMAGIC(header)) {
30                         error("%s: %s not an ACK object file\n", prog, *arg);
31                 } else {
32                         printf("%s:\n", *arg);
33                         show(&header);
34                 }
35                 rd_close();
36         }
37 }
38
39 /*
40  * Read an ACK object file from `fp' and show it in a human readable way.
41  * NB. The header has already been read and is in the struct outhead `headp'
42  * points to.
43  */
44 show(headp)
45         register struct outhead *headp;
46 {
47         register int            i;
48         register struct outname *np;
49         register struct outname *name;  /* Dynamically allocated name-array. */
50         register char           *string;/* Base of string area. */
51         extern char             *myalloc();
52
53         printf("Version %d\n", headp->oh_stamp);
54         showflags((unsigned) headp->oh_flags);
55         /*
56          * Show all sections.
57          */
58         for (i = 0; i < headp->oh_nsect; i++) {
59                 printf("Section %d:\n", i);
60                 showsect();
61         }
62         /*
63          * Show relocation information.
64          */
65         for (i = 0; i < headp->oh_nrelo; i++) {
66                 printf("Relocation record %d:\n", i);
67                 showrelo();
68         }
69         /*
70          * We get all struct outname's and the strings in core first.
71          */
72         name = (struct outname *) myalloc(headp->oh_nname * SZ_NAME);
73         string = myalloc((unsigned) headp->oh_nchar);
74         rd_name(name, headp->oh_nname);
75         for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
76                 if (np->on_foff != 0) {
77                         np->on_foff -= OFF_CHAR(*headp);
78                         if (np->on_foff >= headp->oh_nchar || np->on_foff < 0) {
79                                 np->on_mptr = "????";
80                         }
81                         else np->on_mptr = string + np->on_foff;
82                 }
83         }
84         /*
85          * Transfer strings from file to core.
86          */
87         rd_string(string, headp->oh_nchar);
88         /*
89          * Now we can show all names.
90          */
91         for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
92                 printf("Name %d:\n", np - name);
93                 showname(np);
94         }
95 }
96
97 /*
98  * Show flags from header.
99  */
100 showflags(flagword)
101         unsigned        flagword;
102 {
103         if (flagword & HF_LINK) printf("unresolved references left\n");
104 }
105
106 /*
107  * Show a section.
108  */
109 showsect()
110 {
111         struct outsect  section;
112
113         rd_sect(&section, 1);
114         printf("\tstartaddress in machine\t%ld\n",      section.os_base);
115         printf("\tsection size in machine\t%ld\n",      section.os_size);
116         printf("\tstartaddress in file\t%ld\n",         section.os_foff);
117         printf("\tsection size in file\t%ld\n",         section.os_flen);
118         printf("\tsection alignment\t%ld\n",            section.os_lign);
119 }
120
121 /*
122  * Show a relocation record.
123  */
124 showrelo()
125 {
126         struct outrelo  relrec;
127
128         rd_relo(&relrec, 1);
129         switch (relrec.or_type & RELSZ) {
130         case RELO1:
131                 printf("\t1 byte\n");
132                 break;
133         case RELO2:
134                 printf("\t2 bytes\n");
135                 break;
136         case RELO4:
137                 printf("\t4 bytes\n");
138                 break;
139         default:
140                 error("\tunexpected relocation length\n");
141                 break;
142         }
143         if (relrec.or_type & RELPC) printf("\tpc relative\n");
144         if (relrec.or_type & RELBR) printf("\tbytes reversed\n");
145         if (relrec.or_type & RELWR) printf("\twords reversed\n");
146         printf("\treferencing section\t%d\n", (relrec.or_sect & BMASK) - S_MIN);
147         printf("\treferenced symbol index\t%d\n", relrec.or_nami);
148         printf("\treferencing address\t%ld\n", relrec.or_addr);
149 }
150
151 /*
152  * Show the name in the struct `namep' points to.
153  */
154 showname(namep)
155         struct outname  *namep;
156 {
157         if (namep->on_mptr)
158                 printf("\t%s\n", namep->on_mptr);
159         else
160                 printf("\tno name\n");
161         switch (namep->on_type & S_TYP) {
162         case S_UND:
163                 printf("\tundefined\n");
164                 break;
165         case S_ABS:
166                 printf("\tabsolute\n");
167                 break;
168         case S_CRS:
169                 printf("\tcross reference\n");
170         default:
171                 printf("\tin section %d\n", (namep->on_type & S_TYP) - S_MIN);
172                 break;
173         }
174         if (namep->on_type & S_EXT) printf("\texternal\n");
175         if (namep->on_type & S_STB) {
176                 printf("\tstab 0x%x\n", namep->on_type >> 8);
177                 printf("\tdesc 0x%x\n", namep->on_desc);
178         }
179         else switch (namep->on_type & S_ETC) {
180         case S_SCT:
181                 printf("\tsection name\n"); break;
182         case S_LIN:
183                 printf("\thll source line item\n"); break;
184         case S_FIL:
185                 printf("\thll source file item\n"); break;
186         case S_MOD:
187                 printf("\tass src file item\n"); break;
188         case S_COM:
189                 printf("\tcommon\n"); break;
190         case 0:
191                 break;
192         default:
193                 printf("\tstab 0x%x\n", namep->on_type >> 8);
194                 printf("\tdesc 0x%x\n", namep->on_desc);
195         }
196         printf("\tvalue %ld\n", namep->on_valu);
197 }
198
199 /*
200  * Core allocation via malloc() but fatal if no core.
201  */
202 char *
203 myalloc(u)
204         unsigned int    u;
205 {
206         register char   *rcp;
207         extern char     *malloc();
208
209         rcp = malloc(u);
210         if (rcp == (char *) 0) {
211                 error("Out of core\n");
212                 exit(1);
213         }
214         return rcp;
215 }
216
217 /* VARARGS1 */
218 error(s, a1, a2, a3, a4)
219         char    *s;
220 {
221         fflush(stdout);
222         fprintf(stderr, s, a1, a2, a3, a4);
223 }
224
225 rd_fatal()
226 {
227         error("Error in reading the object file\n");
228         exit(1);
229 }