OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [binutils/] [ar/] [ranlib.c] - Blame information for rev 68

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 hellwig
/*
2
 * ranlib.c -- archive index generator
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <unistd.h>
10
#include <time.h>
11
#include <fcntl.h>
12
 
13
#include "endian.h"
14
#include "ranlib.h"
15
#include "../include/ar.h"
16
#include "../include/a.out.h"
17
 
18
 
19
#define TEMP_NAME               "__.SYMDEF"
20
 
21
#define STRING_SIZE_INIT        1024
22
#define STRING_SIZE_GROW        2
23
 
24
#define MAX_SYM_ENTRIES         1000
25
 
26
#define MSB     ((unsigned int) 1 << (sizeof(unsigned int) * 8 - 1))
27
 
28
 
29
typedef struct {
30
  unsigned int name;    /* name of symbol (as offset into string space) */
31
  off_t position;       /* position of member which defines the symbol */
32
                        /* (as file offset to the member's ArHeader) */
33
} Entry;
34
 
35
 
36
FILE *fi;
37
FILE *fo;
38
 
39
off_t nxtOff;           /* file offset to next member */
40
off_t curOff;
41
 
42
Entry table[MAX_SYM_ENTRIES];
43
int numEntries;
44
 
45
int createIndex;
46
char firstName[MAX_NAME];
47
 
48
ArHeader arhdr;
49
ExecHeader exhdr;
50
 
51
 
52
/**************************************************************/
53
 
54
 
55
char *stringArea = NULL;
56
unsigned int sizeAllocated = 0;
57
unsigned int sizeUsed = 0;
58
 
59
 
60
unsigned int getStringPos(void) {
61
  return sizeUsed;
62
}
63
 
64
 
65
void storeCharacter(char c) {
66
  unsigned int newSize;
67
  char *newArea;
68
 
69
  if (sizeUsed + 1 > sizeAllocated) {
70
    if (sizeAllocated == 0) {
71
      newSize = STRING_SIZE_INIT;
72
    } else {
73
      newSize = STRING_SIZE_GROW * sizeAllocated;
74
    }
75
    newArea = malloc(newSize);
76
    if (newArea == NULL) {
77
      fprintf(stderr, "ar: cannot allocate string area\n");
78
      exit(1);
79
    }
80
    if (stringArea != NULL) {
81
      memcpy(newArea, stringArea, sizeUsed);
82
      free(stringArea);
83
    }
84
    stringArea = newArea;
85
    sizeAllocated = newSize;
86
  }
87
  stringArea[sizeUsed++] = c;
88
}
89
 
90
 
91
/**************************************************************/
92
 
93
 
94
int nextMember(void) {
95
  int pad;
96
 
97
  curOff = nxtOff;
98
  fseek(fi, nxtOff, SEEK_SET);
99
  if (fread(&arhdr, sizeof(arhdr), 1, fi) != 1) {
100
    return 0;
101
  }
102
  conv4FromEcoToNative((unsigned char *) &arhdr.date);
103
  conv4FromEcoToNative((unsigned char *) &arhdr.uid);
104
  conv4FromEcoToNative((unsigned char *) &arhdr.gid);
105
  conv4FromEcoToNative((unsigned char *) &arhdr.mode);
106
  conv4FromEcoToNative((unsigned char *) &arhdr.size);
107
  pad = -arhdr.size & 0x03;
108
  arhdr.size += pad;
109
  nxtOff = ftell(fi) + arhdr.size;
110
  return 1;
111
}
112
 
113
 
114
void addSymbol(unsigned int nameOffset) {
115
  off_t curPos;
116
  int c;
117
 
118
  if (numEntries >= MAX_SYM_ENTRIES) {
119
    fprintf(stderr, "ar: symbol table overflow\n");
120
    exit(1);
121
  }
122
  table[numEntries].name = getStringPos();
123
  table[numEntries].position = curOff;
124
  numEntries++;
125
  curPos = ftell(fi);
126
  fseek(fi, curOff + sizeof(arhdr) + nameOffset, SEEK_SET);
127
  do {
128
    c = fgetc(fi);
129
    storeCharacter(c);
130
  } while (c != 0) ;
131
  fseek(fi, curPos, SEEK_SET);
132
}
133
 
134
 
135
void fixSize(void) {
136
  off_t deltaOff;
137
  int pad;
138
  int i;
139
 
140
  deltaOff = sizeof(arhdr) + sizeof(int) +
141
             numEntries * sizeof(Entry) + getStringPos();
142
  pad = -deltaOff & 0x03;
143
  deltaOff += pad;
144
  nxtOff = sizeof(unsigned int);
145
  nextMember();
146
  if(strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0) {
147
    /* there is an index already present */
148
    createIndex = 0;
149
    deltaOff -= sizeof(arhdr) + arhdr.size;
150
  } else {
151
    /* no index yet present, create new one */
152
    createIndex = 1;
153
    strncpy(firstName, arhdr.name, MAX_NAME);
154
  }
155
  for (i = 0; i < numEntries; i++) {
156
    table[i].position += deltaOff;
157
  }
158
}
159
 
160
 
161
/**************************************************************/
162
 
163
 
164
void showSymdefs(char *symdefs) {
165
  FILE *in;
166
  int numSymbols;
167
  int i;
168
  Entry e;
169
  off_t curPos;
170
  off_t pos;
171
  int c;
172
 
173
  in = fopen(symdefs, "r");
174
  if (in == NULL) {
175
    printf("error: cannot open symdef file '%s'\n", symdefs);
176
    exit(1);
177
  }
178
  if (fread(&numSymbols, sizeof(int), 1, in) != 1) {
179
    printf("cannot read symdef file\n");
180
    exit(1);
181
  }
182
  conv4FromEcoToNative((unsigned char *) &numSymbols);
183
  printf("%d symbols\n", numSymbols);
184
  for (i = 0; i < numSymbols; i++) {
185
    if (fread(&e, sizeof(e), 1, in) != 1) {
186
      printf("cannot read symdef file\n");
187
      exit(1);
188
    }
189
    conv4FromEcoToNative((unsigned char *) &e.name);
190
    conv4FromEcoToNative((unsigned char *) &e.position);
191
    printf("%4d: name = 0x%08X, position = 0x%08lX, string = '",
192
           i, e.name, e.position);
193
    curPos = ftell(in);
194
    pos = sizeof(int) + numSymbols * sizeof(Entry) + e.name;
195
    fseek(in, pos, SEEK_SET);
196
    while (1) {
197
      c = fgetc(in);
198
      if (c == EOF) {
199
        printf("\nerror: unexpected end of file\n");
200
        exit(1);
201
      }
202
      if (c == 0) {
203
        break;
204
      }
205
      printf("%c", c);
206
    }
207
    printf("'\n");
208
    fseek(in, curPos, SEEK_SET);
209
  }
210
  fclose(in);
211
}
212
 
213
 
214
/**************************************************************/
215
 
216
 
217
int hasSymbols(char *archive) {
218
  unsigned int arMagic;
219
  int res;
220
 
221
  fi = fopen(archive, "r");
222
  if (fi == NULL) {
223
    return 0;
224
  }
225
  nxtOff = sizeof(unsigned int);
226
  if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
227
      read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
228
    fclose(fi);
229
    return 0;
230
  }
231
  fseek(fi, 0, SEEK_SET);
232
  if (nextMember() == 0) {
233
    fclose(fi);
234
    return 0;
235
  }
236
  fclose(fi);
237
  res = (strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0);
238
  return res;
239
}
240
 
241
 
242
int updateSymbols(char *archive, int verbose) {
243
  unsigned int arMagic;
244
  unsigned int skip;
245
  int numSymbols;
246
  unsigned int stringStart;
247
  SymbolRecord symbol;
248
  int i;
249
  char *args[3];
250
  int res;
251
 
252
  if (verbose) {
253
    printf("ar: updating symbols in %s\n", archive);
254
  }
255
  fi = fopen(archive, "r");
256
  if (fi == NULL) {
257
    fprintf(stderr, "ar: cannot re-open %s\n", archive);
258
    return 1;
259
  }
260
  nxtOff = sizeof(unsigned int);
261
  if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
262
      read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
263
    fprintf(stderr, "ar: %s not in archive format\n", archive);
264
    fclose(fi);
265
    return 1;
266
  }
267
  fseek(fi, 0, SEEK_SET);
268
  numEntries = 0;
269
  if (nextMember() == 0) {
270
    fclose(fi);
271
    return 0;
272
  }
273
  /* iterate over archive members */
274
  do {
275
    if (fread(&exhdr, sizeof(exhdr), 1, fi) != 1 ||
276
        read4FromEco((unsigned char *) &exhdr.magic) != EXEC_MAGIC) {
277
      /* archive member not in proper format - skip */
278
      continue;
279
    }
280
    conv4FromEcoToNative((unsigned char *) &exhdr.magic);
281
    conv4FromEcoToNative((unsigned char *) &exhdr.csize);
282
    conv4FromEcoToNative((unsigned char *) &exhdr.dsize);
283
    conv4FromEcoToNative((unsigned char *) &exhdr.bsize);
284
    conv4FromEcoToNative((unsigned char *) &exhdr.crsize);
285
    conv4FromEcoToNative((unsigned char *) &exhdr.drsize);
286
    conv4FromEcoToNative((unsigned char *) &exhdr.symsize);
287
    conv4FromEcoToNative((unsigned char *) &exhdr.strsize);
288
    skip = exhdr.csize + exhdr.dsize + exhdr.crsize + exhdr.drsize;
289
    fseek(fi, skip, SEEK_CUR);
290
    numSymbols = exhdr.symsize / sizeof(SymbolRecord);
291
    if (numSymbols == 0) {
292
      fprintf(stderr,
293
              "ar: symbol table of %s is empty\n",
294
              arhdr.name);
295
      continue;
296
    }
297
    stringStart = sizeof(exhdr) + skip + exhdr.symsize;
298
    /* iterate over symbols */
299
    while (--numSymbols >= 0) {
300
      if (fread(&symbol, sizeof(symbol), 1, fi) != 1) {
301
        fprintf(stderr, "ar: cannot read archive\n");
302
        break;
303
      }
304
      conv4FromEcoToNative((unsigned char *) &symbol.name);
305
      conv4FromEcoToNative((unsigned char *) &symbol.type);
306
      conv4FromEcoToNative((unsigned char *) &symbol.value);
307
      if ((symbol.type & MSB) == 0) {
308
        /* this is an exported symbol */
309
        addSymbol(stringStart + symbol.name);
310
      }
311
    }
312
  } while (nextMember() != 0) ;
313
  fixSize();
314
  fclose(fi);
315
  fo = fopen(TEMP_NAME, "w");
316
  if (fo == NULL) {
317
    fprintf(stderr, "ar: can't create temporary file\n");
318
    return 1;
319
  }
320
  conv4FromNativeToEco((unsigned char *) &numEntries);
321
  if (fwrite(&numEntries, sizeof(numEntries), 1, fo) != 1) {
322
    fprintf(stderr, "ar: can't write temporary file\n");
323
    fclose(fo);
324
    unlink(TEMP_NAME);
325
    return 1;
326
  }
327
  conv4FromEcoToNative((unsigned char *) &numEntries);
328
  for (i = 0; i < numEntries; i++) {
329
    conv4FromNativeToEco((unsigned char *) &table[i].name);
330
    conv4FromNativeToEco((unsigned char *) &table[i].position);
331
  }
332
  if (fwrite(table, sizeof(Entry), numEntries, fo) != numEntries) {
333
    fprintf(stderr, "ar: can't write temporary file\n");
334
    fclose(fo);
335
    unlink(TEMP_NAME);
336
    return 1;
337
  }
338
  for (i = 0; i < numEntries; i++) {
339
    conv4FromEcoToNative((unsigned char *) &table[i].name);
340
    conv4FromEcoToNative((unsigned char *) &table[i].position);
341
  }
342
  if (fwrite(stringArea, 1, getStringPos(), fo) != getStringPos()) {
343
    fprintf(stderr, "ar: can't write temporary file\n");
344
    fclose(fo);
345
    unlink(TEMP_NAME);
346
    return 1;
347
  }
348
  fclose(fo);
349
  if (verbose) {
350
    showSymdefs(TEMP_NAME);
351
  }
352
  if (createIndex) {
353
    /* ar -rlb firstName archive TEMP_NAME */
354
    args[0] = firstName;
355
    args[1] = archive;
356
    args[2] = TEMP_NAME;
357
    res = exec_rCmd(1, args);
358
  } else {
359
    /* ar -rl archive TEMP_NAME */
360
    args[0] = archive;
361
    args[1] = TEMP_NAME;
362
    args[2] = NULL;
363
    res = exec_rCmd(0, args);
364
  }
365
  unlink(TEMP_NAME);
366
  return res;
367
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.