1 /* plist.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Anzeige des Inhalts einer Code-Datei */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13
14 #include "version.h"
15 #include "endian.h"
16 #include "bpemu.h"
17 #include "stringlists.h"
18 #include "cmdarg.h"
19 #include "nls.h"
20 #include "nlmessages.h"
21 #include "plist.rsc"
22 #include "ioerrs.h"
23 #include "strutil.h"
24 #include "toolutils.h"
25 #include "headids.h"
26
main(int argc,char ** argv)27 int main(int argc, char **argv)
28 {
29 FILE *ProgFile;
30 String ProgName;
31 Byte Header, Segment, Gran, CPU;
32 LongWord StartAdr, Sums[PCMax + 1];
33 Word Len, ID, z;
34 int Ch;
35 Boolean HeadFnd;
36 char *ph1, *ph2;
37 String Ver;
38 PFamilyDescr FoundId;
39
40 nls_init();
41 if (!NLS_Initialize(&argc, argv))
42 exit(4);
43
44 endian_init();
45 bpemu_init();
46 strutil_init();
47 nlmessages_init("plist.msg", *argv, MsgId1, MsgId2); ioerrs_init(*argv);
48 cmdarg_init(*argv);
49 toolutils_init(*argv);
50
51 as_snprintf(Ver, sizeof(Ver), "PLIST/C V%s", Version);
52 WrCopyRight(Ver);
53
54 if (argc <= 1)
55 {
56 int l;
57
58 errno = 0;
59 printf("%s", getmessage(Num_MessFileRequest));
60 if (!fgets(ProgName, STRINGSIZE, stdin))
61 return 0;
62 l = strlen(ProgName);
63 if ((l > 0) && (ProgName[l - 1] == '\n'))
64 ProgName[--l] = '\0';
65 ChkIO(OutName);
66 }
67 else if (argc == 2)
68 strmaxcpy(ProgName, argv[1], STRINGSIZE);
69 else
70 {
71 errno = 0;
72 printf("%s%s%s\n", getmessage(Num_InfoMessHead1), GetEXEName(argv[0]), getmessage(Num_InfoMessHead2));
73 ChkIO(OutName);
74 for (ph1 = getmessage(Num_InfoMessHelp), ph2 = strchr(ph1, '\n'); ph2; ph1 = ph2 + 1, ph2 = strchr(ph1, '\n'))
75 {
76 *ph2 = '\0';
77 printf("%s\n", ph1);
78 *ph2 = '\n';
79 }
80 exit(1);
81 }
82
83 AddSuffix(ProgName, STRINGSIZE, getmessage(Num_Suffix));
84
85 ProgFile = fopen(ProgName, OPENRDMODE);
86 if (!ProgFile)
87 ChkIO(ProgName);
88
89 if (!Read2(ProgFile, &ID))
90 ChkIO(ProgName);
91 if (ID != FileMagic)
92 FormatError(ProgName, getmessage(Num_FormatInvHeaderMsg));
93
94 errno = 0; printf("\n"); ChkIO(OutName);
95 errno = 0; printf("%s\n", getmessage(Num_MessHeaderLine1)); ChkIO(OutName);
96 errno = 0; printf("%s\n", getmessage(Num_MessHeaderLine2)); ChkIO(OutName);
97
98 for (z = 0; z <= PCMax; Sums[z++] = 0);
99
100 do
101 {
102 ReadRecordHeader(&Header, &CPU, &Segment, &Gran, ProgName, ProgFile);
103
104 HeadFnd = False;
105
106 if (Header == FileHeaderEnd)
107 {
108 errno = 0; fputs(getmessage(Num_MessGenerator), stdout); ChkIO(OutName);
109 do
110 {
111 errno = 0; Ch = fgetc(ProgFile); ChkIO(ProgName);
112 if (Ch != EOF)
113 {
114 errno = 0; putchar(Ch); ChkIO(OutName);
115 }
116 }
117 while (Ch != EOF);
118 errno = 0; printf("\n"); ChkIO(OutName);
119 HeadFnd = True;
120 }
121
122 else if (Header == FileHeaderStartAdr)
123 {
124 if (!Read4(ProgFile, &StartAdr))
125 ChkIO(ProgName);
126 errno = 0;
127 printf("%s%08lX\n", getmessage(Num_MessEntryPoint), LoDWord(StartAdr));
128 ChkIO(OutName);
129 }
130
131 else if (Header == FileHeaderRelocInfo)
132 {
133 PRelocInfo RelocInfo;
134 PRelocEntry PEntry;
135 PExportEntry PExp;
136 int z;
137
138 RelocInfo = ReadRelocInfo(ProgFile);
139 for (z = 0, PEntry = RelocInfo->RelocEntries; z < RelocInfo->RelocCount; z++, PEntry++)
140 printf("%s %08lX %3d:%d(%c) %c%s\n",
141 getmessage(Num_MessRelocInfo),
142 LoDWord(PEntry->Addr), RelocBitCnt(PEntry->Type) >> 3,
143 RelocBitCnt(PEntry->Type) & 7,
144 (PEntry->Type & RelocFlagBig) ? 'B' : 'L',
145 (PEntry->Type & RelocFlagSUB) ? '-' : '+', PEntry->Name);
146
147 for (z = 0, PExp = RelocInfo->ExportEntries; z < RelocInfo->ExportCount; z++, PExp++)
148 printf("%s %08lX %c %s\n",
149 getmessage(Num_MessExportInfo),
150 LoDWord(PExp->Value),
151 (PExp->Flags & RelFlag_Relative) ? 'R' : ' ',
152 PExp->Name);
153
154 DestroyRelocInfo(RelocInfo);
155 }
156
157 else if ((Header == FileHeaderDataRec) || (Header == FileHeaderRDataRec)
158 || (Header == FileHeaderRelocRec) || (Header == FileHeaderRRelocRec))
159 {
160 errno = 0;
161 if (Magic != 0)
162 FoundId = NULL;
163 else
164 FoundId = FindFamilyById(CPU);
165 if (!FoundId)
166 printf("\?\?\?=%02x ", Header);
167 else
168 printf("%-13s ", FoundId->Name);
169 ChkIO(OutName);
170
171 errno = 0; printf("%-7s ", SegNames[Segment]); ChkIO(OutName);
172
173 if (!Read4(ProgFile, &StartAdr))
174 ChkIO(ProgName);
175 errno = 0; printf("%08lX ", LoDWord(StartAdr)); ChkIO(OutName);
176
177 if (!Read2(ProgFile, &Len))
178 ChkIO(ProgName);
179 errno = 0; printf("%04X ", LoWord(Len)); ChkIO(OutName);
180
181 if (Len != 0)
182 StartAdr += (Len / Gran) - 1;
183 else
184 StartAdr--;
185 errno = 0; printf("%08lX\n", LoDWord(StartAdr)); ChkIO(OutName);
186
187 Sums[Segment] += Len;
188
189 if (ftell(ProgFile) + Len >= FileSize(ProgFile))
190 FormatError(ProgName, getmessage(Num_FormatInvRecordLenMsg));
191 else if (fseek(ProgFile, Len, SEEK_CUR) != 0)
192 ChkIO(ProgName);
193 }
194 else
195 SkipRecord(Header, ProgName, ProgFile);
196 }
197 while (Header != 0);
198
199 errno = 0; printf("\n"); ChkIO(OutName);
200 errno = 0; printf("%s", getmessage(Num_MessSum1)); ChkIO(OutName);
201 for (z = 0; z <= PCMax; z++)
202 if ((z == SegCode) || (Sums[z] != 0))
203 {
204 errno = 0;
205 printf(LongIntFormat, Sums[z]);
206 printf("%s%s\n%s", getmessage((Sums[z] == 1) ? Num_MessSumSing : Num_MessSumPlur),
207 SegNames[z], Blanks(strlen(getmessage(Num_MessSum1))));
208 }
209 errno = 0; printf("\n"); ChkIO(OutName);
210 errno = 0; printf("\n"); ChkIO(OutName);
211
212 errno = 0; fclose(ProgFile); ChkIO(ProgName);
213 (void)HeadFnd;
214 return 0;
215 }
216