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