#include <stdio.h>
#include <unistd.h>
#include <errno.h>

#define DUMPLINELEN 80

int main(int argc, char **argv) {
  FILE *dumpf=NULL;
  FILE *inf=NULL;
  int offset;
  int exitval=0;
  char dumpline[DUMPLINELEN+1];
  int loc, from, to;
  int origfrom;

  if (argc!=4) {
    fprintf(stderr, "Syntax: %s relocation-dump-file address-offset "
                    "object-file\n", argv[0]);
    exit(1);
  }

  dumpf=fopen(argv[1], "r");
  if (dumpf==NULL) {
    perror("Can't open dumpfile for reading");
    exitval=1;
    goto cleanup;
  }

  offset=atoi(argv[2]);

  inf=fopen(argv[3], "r+");
  if (inf==NULL) {
    perror("Can't open object file for reading+writing");
    exitval=1;
    goto cleanup;
  }

  while (fgets(dumpline, sizeof(dumpline), dumpf)) {
    if ((strncmp(dumpline, "*loc at", 7)!=0)) {
      continue;
    }

    if (sscanf(dumpline, "*loc at %x: %x -> %x", &loc, &from, &to)!=3) {
      fprintf(stderr, "Failed to parse line: %s\n", dumpline);
      continue;
    }

    //printf("%08x/%08x/%08x\n", loc, from, to);

    if (fseek(inf, loc-offset, SEEK_SET)!=0) {
      fprintf(stderr, "Failed to fseek() input object file to "
                      "0x%08x-0x%08x=0x%08x\n",
              loc, offset, loc-offset);
      continue;
    }

    fread(&origfrom, 4, 1, inf);

    if (from!=origfrom) {
      fprintf(stderr, "Value at 0x%08x isn't currect "
                      "(is 0x%08x, should be 0x%08x)",
              loc-offset, origfrom, from);
      continue;
    }

    fseek(inf, loc-offset, SEEK_SET);

    fwrite(&to, 4, 1, inf);
  }

cleanup:

  if (dumpf!=NULL) {
    fclose(dumpf);
  }
  if (inf!=NULL) {
    fclose(inf);
  }

  exit(exitval);

}

