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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [binutils/] [ar/] [ranlib.c] - Rev 104

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

/*
 * ranlib.c -- archive index generator
 */
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
 
#include "endian.h"
#include "ranlib.h"
#include "../include/ar.h"
#include "../include/a.out.h"
 
 
#define TEMP_NAME		"__.SYMDEF"
 
#define STRING_SIZE_INIT	1024
#define STRING_SIZE_GROW	2
 
#define MAX_SYM_ENTRIES		1000
 
#define MSB	((unsigned int) 1 << (sizeof(unsigned int) * 8 - 1))
 
 
typedef struct {
  unsigned int name;	/* name of symbol (as offset into string space) */
  off_t position;	/* position of member which defines the symbol */
			/* (as file offset to the member's ArHeader) */
} Entry;
 
 
FILE *fi;
FILE *fo;
 
off_t nxtOff;		/* file offset to next member */
off_t curOff;
 
Entry table[MAX_SYM_ENTRIES];
int numEntries;
 
int createIndex;
char firstName[MAX_NAME];
 
ArHeader arhdr;
ExecHeader exhdr;
 
 
/**************************************************************/
 
 
char *stringArea = NULL;
unsigned int sizeAllocated = 0;
unsigned int sizeUsed = 0;
 
 
unsigned int getStringPos(void) {
  return sizeUsed;
}
 
 
void storeCharacter(char c) {
  unsigned int newSize;
  char *newArea;
 
  if (sizeUsed + 1 > sizeAllocated) {
    if (sizeAllocated == 0) {
      newSize = STRING_SIZE_INIT;
    } else {
      newSize = STRING_SIZE_GROW * sizeAllocated;
    }
    newArea = malloc(newSize);
    if (newArea == NULL) {
      fprintf(stderr, "ar: cannot allocate string area\n");
      exit(1);
    }
    if (stringArea != NULL) {
      memcpy(newArea, stringArea, sizeUsed);
      free(stringArea);
    }
    stringArea = newArea;
    sizeAllocated = newSize;
  }
  stringArea[sizeUsed++] = c;
}
 
 
/**************************************************************/
 
 
int nextMember(void) {
  int pad;
 
  curOff = nxtOff;
  fseek(fi, nxtOff, SEEK_SET);
  if (fread(&arhdr, sizeof(arhdr), 1, fi) != 1) {
    return 0;
  }
  conv4FromEcoToNative((unsigned char *) &arhdr.date);
  conv4FromEcoToNative((unsigned char *) &arhdr.uid);
  conv4FromEcoToNative((unsigned char *) &arhdr.gid);
  conv4FromEcoToNative((unsigned char *) &arhdr.mode);
  conv4FromEcoToNative((unsigned char *) &arhdr.size);
  pad = -arhdr.size & 0x03;
  arhdr.size += pad;
  nxtOff = ftell(fi) + arhdr.size;
  return 1;
}
 
 
void addSymbol(unsigned int nameOffset) {
  off_t curPos;
  int c;
 
  if (numEntries >= MAX_SYM_ENTRIES) {
    fprintf(stderr, "ar: symbol table overflow\n");
    exit(1);
  }
  table[numEntries].name = getStringPos();
  table[numEntries].position = curOff;
  numEntries++;
  curPos = ftell(fi);
  fseek(fi, curOff + sizeof(arhdr) + nameOffset, SEEK_SET);
  do {
    c = fgetc(fi);
    storeCharacter(c);
  } while (c != 0) ;
  fseek(fi, curPos, SEEK_SET);
}
 
 
void fixSize(void) {
  off_t deltaOff;
  int pad;
  int i;
 
  deltaOff = sizeof(arhdr) + sizeof(int) +
             numEntries * sizeof(Entry) + getStringPos();
  pad = -deltaOff & 0x03;
  deltaOff += pad;
  nxtOff = sizeof(unsigned int);
  nextMember();
  if(strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0) {
    /* there is an index already present */
    createIndex = 0;
    deltaOff -= sizeof(arhdr) + arhdr.size;
  } else {
    /* no index yet present, create new one */
    createIndex = 1;
    strncpy(firstName, arhdr.name, MAX_NAME);
  }
  for (i = 0; i < numEntries; i++) {
    table[i].position += deltaOff;
  }
}
 
 
/**************************************************************/
 
 
void showSymdefs(char *symdefs) {
  FILE *in;
  int numSymbols;
  int i;
  Entry e;
  off_t curPos;
  off_t pos;
  int c;
 
  in = fopen(symdefs, "r");
  if (in == NULL) {
    printf("error: cannot open symdef file '%s'\n", symdefs);
    exit(1);
  }
  if (fread(&numSymbols, sizeof(int), 1, in) != 1) {
    printf("cannot read symdef file\n");
    exit(1);
  }
  conv4FromEcoToNative((unsigned char *) &numSymbols);
  printf("%d symbols\n", numSymbols);
  for (i = 0; i < numSymbols; i++) {
    if (fread(&e, sizeof(e), 1, in) != 1) {
      printf("cannot read symdef file\n");
      exit(1);
    }
    conv4FromEcoToNative((unsigned char *) &e.name);
    conv4FromEcoToNative((unsigned char *) &e.position);
    printf("%4d: name = 0x%08X, position = 0x%08lX, string = '",
           i, e.name, e.position);
    curPos = ftell(in);
    pos = sizeof(int) + numSymbols * sizeof(Entry) + e.name;
    fseek(in, pos, SEEK_SET);
    while (1) {
      c = fgetc(in);
      if (c == EOF) {
        printf("\nerror: unexpected end of file\n");
        exit(1);
      }
      if (c == 0) {
        break;
      }
      printf("%c", c);
    }
    printf("'\n");
    fseek(in, curPos, SEEK_SET);
  }
  fclose(in);
}
 
 
/**************************************************************/
 
 
int hasSymbols(char *archive) {
  unsigned int arMagic;
  int res;
 
  fi = fopen(archive, "r");
  if (fi == NULL) {
    return 0;
  }
  nxtOff = sizeof(unsigned int);
  if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
      read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
    fclose(fi);
    return 0;
  }
  fseek(fi, 0, SEEK_SET);
  if (nextMember() == 0) {
    fclose(fi);
    return 0;
  }
  fclose(fi);
  res = (strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0);
  return res;
}
 
 
int updateSymbols(char *archive, int verbose) {
  unsigned int arMagic;
  unsigned int skip;
  int numSymbols;
  unsigned int stringStart;
  SymbolRecord symbol;
  int i;
  char *args[3];
  int res;
 
  if (verbose) {
    printf("ar: updating symbols in %s\n", archive);
  }
  fi = fopen(archive, "r");
  if (fi == NULL) {
    fprintf(stderr, "ar: cannot re-open %s\n", archive);
    return 1;
  }
  nxtOff = sizeof(unsigned int);
  if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
      read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
    fprintf(stderr, "ar: %s not in archive format\n", archive);
    fclose(fi);
    return 1;
  }
  fseek(fi, 0, SEEK_SET);
  numEntries = 0;
  if (nextMember() == 0) {
    fclose(fi);
    return 0;
  }
  /* iterate over archive members */
  do {
    if (fread(&exhdr, sizeof(exhdr), 1, fi) != 1 ||
        read4FromEco((unsigned char *) &exhdr.magic) != EXEC_MAGIC) {
      /* archive member not in proper format - skip */
      continue;
    }
    conv4FromEcoToNative((unsigned char *) &exhdr.magic);
    conv4FromEcoToNative((unsigned char *) &exhdr.csize);
    conv4FromEcoToNative((unsigned char *) &exhdr.dsize);
    conv4FromEcoToNative((unsigned char *) &exhdr.bsize);
    conv4FromEcoToNative((unsigned char *) &exhdr.crsize);
    conv4FromEcoToNative((unsigned char *) &exhdr.drsize);
    conv4FromEcoToNative((unsigned char *) &exhdr.symsize);
    conv4FromEcoToNative((unsigned char *) &exhdr.strsize);
    skip = exhdr.csize + exhdr.dsize + exhdr.crsize + exhdr.drsize;
    fseek(fi, skip, SEEK_CUR);
    numSymbols = exhdr.symsize / sizeof(SymbolRecord);
    if (numSymbols == 0) {
      fprintf(stderr,
              "ar: symbol table of %s is empty\n",
              arhdr.name);
      continue;
    }
    stringStart = sizeof(exhdr) + skip + exhdr.symsize;
    /* iterate over symbols */
    while (--numSymbols >= 0) {
      if (fread(&symbol, sizeof(symbol), 1, fi) != 1) {
        fprintf(stderr, "ar: cannot read archive\n");
        break;
      }
      conv4FromEcoToNative((unsigned char *) &symbol.name);
      conv4FromEcoToNative((unsigned char *) &symbol.type);
      conv4FromEcoToNative((unsigned char *) &symbol.value);
      if ((symbol.type & MSB) == 0) {
        /* this is an exported symbol */
        addSymbol(stringStart + symbol.name);
      }
    }
  } while (nextMember() != 0) ;
  fixSize();
  fclose(fi);
  fo = fopen(TEMP_NAME, "w");
  if (fo == NULL) {
    fprintf(stderr, "ar: can't create temporary file\n");
    return 1;
  }
  conv4FromNativeToEco((unsigned char *) &numEntries);
  if (fwrite(&numEntries, sizeof(numEntries), 1, fo) != 1) {
    fprintf(stderr, "ar: can't write temporary file\n");
    fclose(fo);
    unlink(TEMP_NAME);
    return 1;
  }
  conv4FromEcoToNative((unsigned char *) &numEntries);
  for (i = 0; i < numEntries; i++) {
    conv4FromNativeToEco((unsigned char *) &table[i].name);
    conv4FromNativeToEco((unsigned char *) &table[i].position);
  }
  if (fwrite(table, sizeof(Entry), numEntries, fo) != numEntries) {
    fprintf(stderr, "ar: can't write temporary file\n");
    fclose(fo);
    unlink(TEMP_NAME);
    return 1;
  }
  for (i = 0; i < numEntries; i++) {
    conv4FromEcoToNative((unsigned char *) &table[i].name);
    conv4FromEcoToNative((unsigned char *) &table[i].position);
  }
  if (fwrite(stringArea, 1, getStringPos(), fo) != getStringPos()) {
    fprintf(stderr, "ar: can't write temporary file\n");
    fclose(fo);
    unlink(TEMP_NAME);
    return 1;
  }
  fclose(fo);
  if (verbose) {
    showSymdefs(TEMP_NAME);
  }
  if (createIndex) {
    /* ar -rlb firstName archive TEMP_NAME */
    args[0] = firstName;
    args[1] = archive;
    args[2] = TEMP_NAME;
    res = exec_rCmd(1, args);
  } else {
    /* ar -rl archive TEMP_NAME */
    args[0] = archive;
    args[1] = TEMP_NAME;
    args[2] = NULL;
    res = exec_rCmd(0, args);
  }
  unlink(TEMP_NAME);
  return res;
}
 

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

powered by: WebSVN 2.1.0

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