Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1126 savelij 1
/* codechunks.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Maintain address ranges & included code                                   */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
 
13
#include "codechunks.h"
14
 
15
static void SetCodePtr(tCodeChunk *pChunk, void *pCode, unsigned Granularity)
16
{
17
  switch ((pChunk->Granularity = Granularity))
18
  {
19
    case 4:
20
      pChunk->pLongCode = (LongWord*)pCode;
21
      pChunk->pWordCode = NULL;
22
      pChunk->pCode = NULL;
23
      break;
24
    case 2:
25
      pChunk->pLongCode = (LongWord*)pCode;
26
      pChunk->pWordCode = (Word*)pCode;
27
      pChunk->pCode = NULL;
28
      break;
29
    case 1:
30
      pChunk->pLongCode = (LongWord*)pCode;
31
      pChunk->pWordCode = (Word*)pCode;
32
      pChunk->pCode = (Byte*)pCode;
33
      break;
34
  }
35
}
36
 
37
static void CheckOverlap(const tCodeChunk *pChunk1, const tCodeChunk *pChunk2)
38
{
39
  LargeWord OverlapStart, OverlapEnd;
40
 
41
  OverlapStart = max(pChunk1->Start, pChunk2->Start);
42
  OverlapEnd = min(pChunk1->Start + pChunk1->Length - 1, pChunk2->Start + pChunk2->Length - 1);
43
  if (OverlapStart <= OverlapEnd)
44
    fprintf(stderr, "code chunk overlap\n");
45
}
46
 
47
static int SetCodeChunkListAllocLen(tCodeChunkList *pCodeChunkList, unsigned NewAllocLen)
48
{
49
  int Result;
50
 
51
  if (NewAllocLen < pCodeChunkList->RealLen)
52
  {
53
    unsigned z;
54
 
55
    for (z = NewAllocLen; z < pCodeChunkList->RealLen; z++)
56
      FreeCodeChunk(pCodeChunkList->Chunks + z);
57
    pCodeChunkList->RealLen = NewAllocLen;
58
  }
59
 
60
  if (!pCodeChunkList->AllocLen)
61
  {
62
    pCodeChunkList->Chunks = (tCodeChunk*)malloc(NewAllocLen * sizeof(tCodeChunk));
63
    Result = pCodeChunkList->Chunks ? 0 : ENOMEM;
64
  }
65
  else
66
  {
67
    tCodeChunk *pNewChunks = (tCodeChunk*)realloc(pCodeChunkList->Chunks, NewAllocLen * sizeof(tCodeChunk));
68
    Result = pNewChunks ? 0 : ENOMEM;
69
    if (!Result)
70
      pCodeChunkList->Chunks = pNewChunks;
71
  }
72
 
73
  if (!Result)
74
  {
75
    pCodeChunkList->AllocLen = NewAllocLen;
76
    if (!pCodeChunkList->AllocLen)
77
      pCodeChunkList->Chunks = NULL;
78
  }
79
  return Result;
80
}
81
 
82
void InitCodeChunk(tCodeChunk *pChunk)
83
{
84
  pChunk->Start = pChunk->Length = 0;
85
  pChunk->Granularity = 1;
86
  SetCodePtr(pChunk, NULL, 1);
87
}
88
 
89
int ReadCodeChunk(tCodeChunk *pChunk, const char *pFileName, LargeWord Start, LargeWord Length, unsigned Granularity)
90
{
91
  FILE *pFile = NULL;
92
  Byte *pCode = NULL;
93
  int Result;
94
 
95
  UNUSED(Granularity);
96
  FreeCodeChunk(pChunk);
97
 
98
  pFile = fopen(pFileName, OPENRDMODE);
99
  if (!pFile)
100
  {
101
    Result = EIO;
102
    goto func_exit;
103
  }
104
 
105
  if (!Length)
106
  {
107
    fseek(pFile, 0, SEEK_END);
108
    Length = ftell(pFile);
109
    fseek(pFile, 0, SEEK_SET);
110
  }
111
 
112
  pCode = (Byte*)malloc(Length);
113
  if (!pCode)
114
  {
115
    Result = ENOMEM;
116
    goto func_exit;
117
  }
118
 
119
  if (fread(pCode, 1, Length, pFile) != Length)
120
  {
121
    Result = EIO;
122
    goto func_exit;
123
  }
124
 
125
  pChunk->Start = Start;
126
  pChunk->Length = Length;
127
  SetCodePtr(pChunk, pCode, 1);
128
  pCode = NULL;
129
 
130
  Result = 0;
131
 
132
func_exit:
133
  if (pCode)
134
    free(pCode);
135
  if (pFile)
136
    fclose(pFile);
137
  return Result;
138
}
139
 
140
void FreeCodeChunk(tCodeChunk *pChunk)
141
{
142
  if (pChunk->pCode)
143
    free(pChunk->pCode);
144
  InitCodeChunk(pChunk);
145
}
146
 
147
void InitCodeChunkList(tCodeChunkList *pCodeChunkList)
148
{
149
  pCodeChunkList->RealLen =
150
  pCodeChunkList->AllocLen = 0;
151
  pCodeChunkList->Chunks = NULL;
152
}
153
 
154
int MoveCodeChunkToList(tCodeChunkList *pCodeChunkList, tCodeChunk *pNewCodeChunk, Boolean WarnOverlap)
155
{
156
  unsigned Index;
157
 
158
  /* increase size? */
159
 
160
  if (pCodeChunkList->RealLen >= pCodeChunkList->AllocLen)
161
  {
162
    int Res = SetCodeChunkListAllocLen(pCodeChunkList, pCodeChunkList->RealLen + 16);
163
 
164
    if (Res)
165
      return Res;
166
  }
167
 
168
  /* find sort in position */
169
 
170
  for (Index = 0; Index < pCodeChunkList->RealLen; Index++)
171
    if (pCodeChunkList->Chunks[Index].Start > pNewCodeChunk->Start)
172
      break;
173
 
174
  /* sort in */
175
 
176
  memmove(pCodeChunkList->Chunks + Index + 1,
177
          pCodeChunkList->Chunks + Index,
178
          sizeof(*pCodeChunkList->Chunks) * (pCodeChunkList->RealLen - Index));
179
  pCodeChunkList->Chunks[Index] = *pNewCodeChunk;
180
  pCodeChunkList->RealLen++;
181
 
182
  /* data was moved out of chunk */
183
 
184
  InitCodeChunk(pNewCodeChunk);
185
 
186
  /* check overlap? */
187
 
188
  if (WarnOverlap)
189
  {
190
    if (Index > 0)
191
      CheckOverlap(pCodeChunkList->Chunks + Index - 1,
192
                   pCodeChunkList->Chunks + Index);
193
    if (Index < pCodeChunkList->RealLen - 1U)
194
      CheckOverlap(pCodeChunkList->Chunks + Index,
195
                   pCodeChunkList->Chunks + Index + 1);
196
  }
197
 
198
  return 0;
199
}
200
 
201
extern void FreeCodeChunkList(tCodeChunkList *pCodeChunkList)
202
{
203
  SetCodeChunkListAllocLen(pCodeChunkList, 0);
204
}
205
 
206
Boolean RetrieveCodeFromChunkList(const tCodeChunkList *pCodeChunkList, LargeWord Start, Byte *pData, unsigned Count)
207
{
208
  const tCodeChunk *pChunk;
209
  LargeWord OverlapStart, OverlapEnd;
210
  Boolean Found;
211
 
212
  while (Count > 0)
213
  {
214
    Found = False;
215
    for (pChunk = pCodeChunkList->Chunks; pChunk < pCodeChunkList->Chunks + pCodeChunkList->RealLen; pChunk++)
216
    {
217
      OverlapStart = max(pChunk->Start, Start);
218
      OverlapEnd = min(pChunk->Start + pChunk->Length - 1, Start + Count - 1);
219
      if (OverlapStart <= OverlapEnd)
220
      {
221
        unsigned PartLength = OverlapEnd - OverlapStart + 1;
222
 
223
        memcpy(pData, pChunk->pCode + (OverlapStart - pChunk->Start), PartLength);
224
        pData += PartLength;
225
        Count -= PartLength;
226
        Found = True;
227
        break;
228
      }
229
    }
230
    if (!Found)
231
      return False;
232
  }
233
  return True;
234
}
235
 
236
LargeWord GetCodeChunksStored(const tCodeChunkList *pCodeChunkList)
237
{
238
  LargeWord Sum = 0;
239
  const tCodeChunk *pChunk;
240
 
241
  for (pChunk = pCodeChunkList->Chunks; pChunk < pCodeChunkList->Chunks + pCodeChunkList->RealLen; pChunk++)
242
    Sum += pChunk->Length;
243
 
244
  return Sum;
245
}