home *** CD-ROM | disk | FTP | other *** search
- /* obj4lb.c -- fiddle with symbols in an a.out or coff format file
- ** Copyright (C) 1995 Norman D. Culver All rights reserved.
- **
- ** COMPILE: (using djcc v1.12)
- ** gcc -O2 -o obj4lb obj4lb.c
- ** coff2exe -s go32.exe obj4lb
- */
-
- #include <dos.h>
- #include <limits.h>
- #include <sys/types.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <memory.h>
- #include <string.h>
- #include <stdio.h>
- #include <binimg.h>
-
- #define coff_sym_is_fortrancommon(p) \
- ((p->e_sclass == C_EXT) && (p->e_scnum == 0) && (p->e_value != 0))
- #define coff_sym_is_undefined(p) \
- ((p->e_scnum == 0) && (p->e_sclass == C_EXT))
- #define coff_sym_is_global(p) \
- (p->e_sclass == C_EXT)
-
- /* USEFUL DEFINITIONS */
- #ifndef __GNUC__
- typedef unsigned int u_int;
- typedef unsigned char u_char;
- typedef unsigned short u_short;
- typedef unsigned long u_long;
- #endif
- typedef union {
- u_short val;
- u_char b[2];
- } SVAL;
-
- typedef union {
- u_long a0;
- void *a1;
- struct {
- SVAL offset;
- SVAL seg_addr;
- }a2;
- } ADDR;
-
- typedef struct _exports {
- struct _exports *fptr;
- char *name;
- int len;
- } EXPORTS;
-
- typedef struct _renames {
- struct _renames *fptr;
- char *oldname;
- int oldlen;
- char *newname;
- int newlen;
- } RENAMES;
-
- typedef struct _movdat {
- struct _movdat *fptr;
- unsigned long offset;
- } MOVDAT, *PMOVDAT;
-
- typedef struct relocation_info RELINFO;
-
- #define round_up(size,amt) \
- ((size&(amt-1)) ? size+(amt-(size&(amt-1))) : size)
-
- /* LOCAL VARIABLES */
- static char infile[128];
- static char outfile[128];
- static char lb4file[128];
- static struct exec header;
- static FILE *ifd, *lb4fd, *ofd;
- static EXPORTS exports;
- static RENAMES renames;
- static EXPORTS *lexports;
- static RENAMES *lrenames;
- static MOVDAT moves;
- static MOVDAT *lmoves;
- static int rename_diftot;
- static long lowoffset;
- static char *strtbl;
- static char *nstrtbl;
- static long strsize;
- static long nstrsize;
- static int nsyms;
-
- /* INPUT DATA FROM THE .o FILE */
-
- static NLIST *symtbl;
- static char *text;
- static RELINFO *text_relocs;
- static int n_text_relocs;
- static char *data;
- static RELINFO *data_relocs;
- static int n_data_relocs;
-
- /* coff stuff */
- typedef struct oxhdr {
- unsigned short info;
- unsigned short machine;
- unsigned start_addr;
- unsigned text_vaddr;
- unsigned text_size;
- unsigned text_fileaddr;
- unsigned data_vaddr;
- unsigned data_size;
- unsigned data_fileaddr;
- unsigned bss_vaddr;
- unsigned bss_size;
- unsigned image_size;
- unsigned text_reloc_fileaddr;
- unsigned text_reloc_size;
- unsigned text_reloc_cnt;
- unsigned data_reloc_fileaddr;
- unsigned data_reloc_size;
- unsigned data_reloc_cnt;
- unsigned symbols_fileaddr;
- unsigned symbols_size;
- unsigned symbols_cnt;
- unsigned strings_fileaddr;
- unsigned strings_size;
- unsigned section_headers_size;
- } OXHDR, *POXHDR;
-
- typedef struct {
- void *addr;
- long size;
- unsigned long fileptr;
- long cnt;
- } BUFS, *PBUFS;
-
- static OXHDR xhdr;
- static unsigned char scntype[128];
- static PSCNHDR t,d,b,q,s;
- static PBUFS sbf;
- static PBUFS rbf;
- static PBUFS lbf;
- static PCOFF_SYMBOL coff_symtbl;
- static short bss_section;
-
- /* start of subroutines */
-
- static void *
- xmalloc (long n)
- {
- void *p;
-
- p = calloc (1,(size_t)n);
- if (n > 0 && p == 0)
- {
- puts ("obj4lb: virtual memory exhausted");
- exit (1);
- }
- return p;
- }
- static int
- isglobal(char *str)
- {
- EXPORTS *l = &exports;
-
- while(l->fptr)
- {
- l = l->fptr;
- if(!strcmp(str, l->name))
- return 1;
- }
- return 0;
- }
- static RENAMES *
- isrenamed(char *str)
- {
- RENAMES *r = &renames;
-
- while(r->fptr)
- {
- r = r->fptr;
- if(!strcmp(str, r->oldname))
- return r;
- }
- return NULL;
- }
- static void
- aout_get_rid_of_fortrancommon(NLIST *sp, int symidx, int setglobal)
- {/* move fortrancommon symbols to the bss segment */
- u_long bssbase = N_BSSADDR(header);
- u_long bssoffset = round_up(header.a_bss, sizeof(int));
- u_long symbsize = sp->n_value;
- u_long bssaddr = bssbase + bssoffset;
- RELINFO *r;
- int i;
- void *ldata;
-
- sp->n_value = bssaddr;
- if(setglobal)
- sp->n_type = N_BSS|N_EXT;
- else
- sp->n_type = N_BSS;
- header.a_bss = bssoffset + symbsize;
-
- /* adjust all relocs which refence this variable */
- for(i = 0, r=text_relocs; i < n_text_relocs; ++i, ++r)
- {
- if(r->r_extern && r->r_symbolnum == symidx)
- {
- ldata = &text[r->r_address];
- r->r_extern = 0;
- r->r_symbolnum = N_BSS;
- if(r->r_length == 2)
- *((long *)ldata) += bssaddr;
- else
- {
- puts("4lb: non 32bit reloc encountered");
- exit(1);
- }
- }
- }
- for(i = 0, r=data_relocs; i < n_data_relocs; ++i, ++r)
- {
- if(r->r_extern && r->r_symbolnum == symidx)
- {
- ldata = &data[r->r_address];
- r->r_extern = 0;
- r->r_symbolnum = N_BSS;
- if(r->r_length == 2)
- *((long *)ldata) += bssaddr;
- else
- {
- puts("4lb: non 32bit reloc encountered");
- exit(1);
- }
- }
- }
- }
- static void
- aout_adjust_symbol(long oldoffset, long newoffset, int setglobal)
- {
- NLIST *sp;
- int i;
-
- for(i = 0, sp = symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->n_un.n_strx == oldoffset)
- {/* newoffset is set negative to avoid reuse */
- sp->n_un.n_strx = newoffset | 0x80000000;
- if(sym_is_fortrancommon(sp))
- aout_get_rid_of_fortrancommon(sp, i, setglobal);
- else if(setglobal)
- sp->n_type |= N_EXT;
- else if(!sym_is_undefined(sp))
- sp->n_type &= ~N_EXT;
- return;
- }
- }
- }
- static void
- coff_get_rid_of_fortrancommon(COFF_SYMBOL *sp, int symidx, int setglobal)
- {/* move fortrancommon symbols to the bss segment */
- PCOFF_HDR p = (PCOFF_HDR)&header;
- u_long bssbase = b->s_vaddr;
- u_long bssoffset = round_up(b->s_size, sizeof(int));
- u_long symbsize = sp->e_value;
- u_long bssaddr = bssbase + bssoffset;
- int i, j;
-
- sp->e_value = bssaddr;
- sp->e_scnum = bss_section;
- if(setglobal)
- sp->e_sclass = C_EXT;
- else
- sp->e_sclass = C_STAT;
- b->s_size = round_up(bssoffset + symbsize, sizeof(int));
-
- /* adjust all relocs which reference this variable */
- for(i = 0; i < p->f_nscns; ++i)
- {
- COFF_RELOC *r;
-
- if((r = rbf[i].addr))
- {
- int cnt = rbf[i].cnt;
- char *scndata = sbf[i].addr;
- unsigned long s_vaddr = s[i].s_vaddr;
-
- for(j = 0; j < cnt; ++j, ++r)
- {
- if(r->r_symndx == symidx)
- {
- void *ldata = &scndata[r->u.r_vaddr - s_vaddr];
- if(r->r_type == 0x0006)
- {
- *((long *)ldata) += bssaddr - symbsize;
- }
- else if(r->r_type == 0x0007)
- {
- puts("4lb: type 7 reloc encountered");
- exit(1);
- }
- else if(r->r_type == 0x0014)
- {
- puts("4lb: pcrel comdef encountered");
- exit(1);
- }
- else
- {
- puts("4lb: non 32bit reloc encountered");
- exit(1);
- }
- }
- }
- }
- }
- }
- static void
- coff_adjust_symbol(long oldoffset, long newoffset, int setglobal)
- {
- COFF_SYMBOL *sp;
- int i;
-
- for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->e.e.e_offset == oldoffset)
- {/* newoffset is set negative to avoid reuse */
- sp->e.e.e_offset = newoffset | 0x80000000;
- if(coff_sym_is_fortrancommon(sp))
- coff_get_rid_of_fortrancommon(sp, i, setglobal);
- else if(setglobal)
- sp->e_sclass = C_EXT;
- else if(!coff_sym_is_undefined(sp))
- {
- if(coff_sym_is_global(sp))
- sp->e_sclass = C_STAT;
- }
- }
- if(sp->e_numaux)
- {/* ignore aux records */
- i += sp->e_numaux;
- sp += sp->e_numaux;
- }
- }
- }
- static void
- adjust_strings(int format_fudge)
- {/* HERE'S THE BEEF -- WRITE A NEW STRING TABLE AND ADJUST SYMTAB */
- long istroff = lowoffset;
- long ostroff = lowoffset;
- char *ip, *ep, *op;
- int i;
-
- nstrsize = strsize + rename_diftot;
- nstrtbl = xmalloc(nstrsize+12);
- ip = strtbl+lowoffset;
- op = nstrtbl+lowoffset;
- ep = ip + strsize;
-
- while(ip < ep)
- {/* scan over each of the strings in the old string table */
- int global;
- int istrlen = strlen(ip);
- int olen;
- RENAMES *r;
- if(istrlen > 0)
- {
- if((r = isrenamed(ip)))
- {/* change the string on output */
- strcpy(op, r->newname);
- op += r->newlen+1;
- olen = r->newlen+1;
- global = isglobal(r->newname);
- }
- else
- {/* use the old string on output */
- strcpy(op, ip);
- op += istrlen+1;
- olen = istrlen+1;
- global = isglobal(ip);
- }
- if(coff_symtbl)
- coff_adjust_symbol(istroff, ostroff, global);
- else
- aout_adjust_symbol(istroff, ostroff, global);
- ostroff += olen;
- }
- ip += istrlen+1;
- istroff += istrlen+1;
- }
- nstrsize = ostroff + format_fudge;
- /* reset the negative values for offsets */
- if(coff_symtbl)
- {
- COFF_SYMBOL *sp;
- for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->e.e.e_offset & 0x80000000)
- sp->e.e.e_offset &= 0x7fffffff;
- if(sp->e_numaux)
- {/* ignore aux records */
- i += sp->e_numaux;
- sp += sp->e_numaux;
- }
- }
- }
- else
- {
- NLIST *sp;
- for(i = 0, sp = symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->n_un.n_strx & 0x80000000)
- sp->n_un.n_strx &= 0x7fffffff;
- }
- }
- }
- static int
- aout_read_symbols ()
- {
- int i;
- NLIST *sp;
-
- nsyms = header.a_syms / sizeof (NLIST);
- if (nsyms == 0)
- return 1;
-
- symtbl = (NLIST *)xmalloc (header.a_syms);
-
- fseek (ifd, N_SYMOFF (header), 0);
- fread ((char *)symtbl, sizeof(NLIST), nsyms, ifd);
-
- fseek (ifd, N_STROFF(header), 0);
- fread ((char *)&strsize, sizeof strsize, 1, ifd);
-
- strtbl = xmalloc (strsize);
- fseek (ifd, N_STROFF (header), 0);
- fread ((char *)strtbl, (int)strsize, 1, ifd);
-
- lowoffset = 2000000;
- for (i = 0, sp = symtbl; i < nsyms; i++, sp++)
- {
- if (sp->n_un.n_strx != 0)
- if(sp->n_un.n_strx < lowoffset)
- lowoffset = sp->n_un.n_strx;
- }
- }
- static void
- aout_read_text_and_data()
- {
- text = xmalloc(header.a_text);
- data = xmalloc(header.a_data);
-
- if(header.a_text > 0)
- {
- fseek(ifd, N_TXTOFF(header), 0);
- fread(text, (u_int)header.a_text, 1, ifd);
- }
- if(header.a_data > 0)
- {
- fseek(ifd, N_DATOFF(header), 0);
- fread(data, (u_int)header.a_data, 1, ifd);
- }
- }
- static int
- relcomp(const void *a,const void *b)
- {
- return (int)((long)((RELINFO*)a)->r_address-(long)((RELINFO*)b)->r_address);
- }
- static void
- aout_read_relocs()
- {
- int i;
- RELINFO *reloc;
-
- n_text_relocs = header.a_trsize / sizeof (RELINFO);
- n_data_relocs = header.a_drsize / sizeof (RELINFO);
-
- if(n_text_relocs > 0)
- {
- text_relocs = xmalloc(header.a_trsize);
- fseek(ifd, N_TRELOFF(header), 0);
- fread((char *)text_relocs, (u_int)header.a_trsize, 1, ifd);
- qsort (text_relocs, n_text_relocs, sizeof (RELINFO), relcomp);
- }
-
- if(n_data_relocs > 0)
- {
- data_relocs = xmalloc(header.a_drsize);
- fseek(ifd, N_DRELOFF(header), 0);
- fread((char *)data_relocs, (u_int)header.a_drsize, 1, ifd);
- qsort (data_relocs, n_data_relocs, sizeof (RELINFO),relcomp);
- }
- }
-
-
- static int
- movcmp(char *s1, char *s2)
- {
- int i = E_SYMNMLEN;
- while(i--)
- {
- if(*s1++ != *s2++)
- return 1;
- }
- return 0;
- }
- static unsigned long
- mark_moved(PCOFF_SYMBOL sp)
- {
- MOVDAT *m = &moves;
-
- /* search current entries */
- while(m->fptr)
- {
- m = m->fptr;
- if(!movcmp(sp->e.e_name, strtbl+m->offset))
- return m->offset;
- }
-
- /* enter string in moved list */
- if(!lmoves) lmoves = &moves;
- lmoves->fptr = xmalloc(sizeof(MOVDAT));
- lmoves = lmoves->fptr;
- lmoves->offset = strsize+4;
-
- memcpy(strtbl+lmoves->offset, sp->e.e_name, E_SYMNMLEN);
- strsize += E_SYMNMLEN+1;
- return lmoves->offset;
- }
- static void
- fix_silly_coff_symtbl()
- {
- COFF_SYMBOL *sp;
- int i;
- int xtracnt = 0;
-
- for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->e.e.e_zeroes)
- {/* this, 8 char or less symbol may be moved to strtbl */
- xtracnt += E_SYMNMLEN+1;
- }
- if(sp->e_numaux)
- {/* ignore aux records */
- i += sp->e_numaux;
- sp += sp->e_numaux;
- }
- }
- if(xtracnt > 0)
- {
- char *nt;
- nt = calloc(1, strsize + xtracnt + 4);
- memcpy(nt, strtbl, strsize + 4);
- free(strtbl);
- strtbl = nt;
-
- for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
- {
- if(sp->e.e.e_zeroes)
- {/* this, 8 char or less symbol must be moved to strtbl */
- sp->e.e.e_offset = mark_moved(sp);
- sp->e.e.e_zeroes = 0;
- }
- if(sp->e_numaux)
- {/* ignore aux records */
- i += sp->e_numaux;
- sp += sp->e_numaux;
- }
- }
- *((unsigned long *)strtbl) = strsize;
- }
- }
- static void
- coff_read_stuff()
- {
- PCOFF_HDR p = (PCOFF_HDR)&header;
- POXHDR hdr = &xhdr;
- int i;
- if(p->f_opthdr)
- {/* optional header is present, wrong file type */
- puts("4lb: coff optional header encountered, wrong file type");
- exit(1);
- }
- /* load section headers */
- hdr->section_headers_size = p->f_nscns * sizeof(SCNHDR);
- s = malloc(hdr->section_headers_size);
- fseek(ifd, sizeof(COFF_HDR), 0);
- fread(s, 1, hdr->section_headers_size, ifd);
-
- /* scan section headers */
- t = d = b = 0;
- for(i = 0; i < p->f_nscns; ++i)
- {/* find the text, data, and bss sections */
- q = &s[i];
- if(!strcmp(q->s_name, ".text"))
- {
- t = q;
- scntype[i+1] = N_TEXT;
- }
- else if(!strcmp(q->s_name, ".data"))
- {
- d = q;
- scntype[i+1] = N_DATA;
- }
- else if(!strcmp(q->s_name, ".bss"))
- {
- b = q;
- scntype[i+1] = N_BSS;
- bss_section = i+1;
- }
- }
- if(!t || !d || !b)
- {
- puts("4lb: missing text data or bss section");
- exit(1);
- }
- hdr->start_addr = 0;
- hdr->text_size = t->s_size;
- hdr->data_size = d->s_size;
- hdr->bss_size = b->s_size;
- hdr->text_fileaddr = t->s_scnptr;
- hdr->data_fileaddr = d->s_scnptr;
- hdr->text_vaddr = t->s_vaddr;
- hdr->data_vaddr = d->s_vaddr;
- hdr->bss_vaddr = b->s_vaddr;
- hdr->image_size = hdr->text_size + hdr->data_size + hdr->bss_size;
- hdr->text_reloc_fileaddr = t->s_relptr;
- hdr->text_reloc_size = t->s_nreloc * COFF_RELOC_SIZE;
- hdr->text_reloc_cnt = t->s_nreloc;
- hdr->data_reloc_fileaddr = d->s_relptr;
- hdr->data_reloc_size = d->s_nreloc * COFF_RELOC_SIZE;
- hdr->data_reloc_cnt = d->s_nreloc;
- if( (hdr->symbols_fileaddr = p->f_symptr)
- && (hdr->symbols_cnt = p->f_nsyms)
- )/* you just can't tell what some utilities will do */
- {
- long temp;
-
- hdr->symbols_size = p->f_nsyms * COFF_SYMBOL_SIZE;
- hdr->strings_fileaddr = hdr->symbols_fileaddr + hdr->symbols_size;
-
- fseek(ifd, hdr->strings_fileaddr, 0);
- if(fread(&temp, 1, 4, ifd) != 4)
- {
- puts("4lb: no strings in coff file");
- exit(1);
- }
- hdr->strings_size = strsize = nstrsize = temp;
- nsyms = hdr->symbols_cnt;
- }
- else
- {
- puts("4lb: no symbols in coff file");
- exit(1);
- }
- sbf = calloc(1, p->f_nscns * sizeof(BUFS));
- rbf = calloc(1, p->f_nscns * sizeof(BUFS));
- lbf = calloc(1, p->f_nscns * sizeof(BUFS));
-
- for(i = 0; i < p->f_nscns; ++i)
- {/* load each of the sections, plus relocs and linenos */
- q = &s[i];
- if(q->s_scnptr)
- {
- sbf[i].size = q->s_size;
- sbf[i].addr = malloc(sbf[i].size);
- sbf[i].fileptr = q->s_scnptr;
- fseek(ifd, sbf[i].fileptr, 0);
- fread(sbf[i].addr, 1, sbf[i].size, ifd);
- if(q->s_nreloc > 0)
- {
- rbf[i].size = q->s_nreloc*COFF_RELOC_SIZE;
- rbf[i].addr = malloc(rbf[i].size);;
- rbf[i].fileptr = q->s_relptr;
- rbf[i].cnt = q->s_nreloc;
- fseek(ifd, rbf[i].fileptr, 0);
- fread(rbf[i].addr, 1, rbf[i].size, ifd);
- }
- if(q->s_nlnno > 0)
- {
- lbf[i].size = q->s_nlnno*COFF_LINENO_SIZE;
- lbf[i].addr = malloc(lbf[i].size);
- lbf[i].fileptr = q->s_lnnoptr;
- lbf[i].cnt = q->s_nlnno;
- fseek(ifd, lbf[i].fileptr, 0);
- fread(lbf[i].addr, 1, lbf[i].size, ifd);
- }
- }
- }
- /* load the symbols and strings */
- coff_symtbl = malloc(hdr->symbols_size);
- fseek(ifd, hdr->symbols_fileaddr, 0);
- fread(coff_symtbl, 1, hdr->symbols_size, ifd);
- nstrtbl = strtbl = malloc(hdr->strings_size+4);
- fseek(ifd, hdr->strings_fileaddr, 0);
- fread(strtbl, 1, hdr->strings_size+4, ifd);
- lowoffset = 4;
- fix_silly_coff_symtbl();
- }
-
- static void
- usage()
- {
- puts("Usage: obj4lb infile");
- puts(" infile must be in a.out or coff format.");
- puts(" outfile will be the suffix .olb");
- puts(" the specification file should have the suffix .4lb");
- exit(0);
- }
- static void
- lose_backslashes(char *p)
- {
- while(*p)
- {
- if(*p == '\\')
- *p = '/';
- ++p;
- }
- }
- static int
- proc_infile(char *name)
- {
- ifd = fopen(name, "r+b");
- if(!ifd) {
- printf("4lb: Cannot open input file %s\n", infile);
- exit(1);
- }
- if(fread((char *)&header, sizeof(struct exec), 1, ifd) != 1)
- {
- printf("4lb: cannot read %s\n", name);
- exit(1);
- }
- if(N_MAGIC(header) == OMAGIC)
- {
- aout_read_symbols();
- aout_read_text_and_data();
- aout_read_relocs();
- }
- else if(N_MAGIC(header) == IMAGIC)
- {
- coff_read_stuff();
- }
- else
- {
- printf("4lb: incorrect filetype: %s magic=%x\n", name, N_MAGIC(header));
- exit(1);
- }
- return 1;
- }
- static void
- fix_suffix(char *str, char *suf)
- {
- char *cp;
- if((cp = strrchr(str, '.')) != NULL)
- strcpy(cp, suf);
- else strcat(str, suf);
- }
- static char *
- find_sym(char *cp)
- {
- while(*cp && (*cp == ':' || isspace(*cp)))
- ++cp;
-
- if(*cp) {
- char *np=cp;
-
- while(*np && *np != ':' && !isspace(*np))
- ++np;
- if(*np)
- *np = '\0';
- return cp;
- }
- return NULL;
- }
- static int
- sym_exists(const char *cp, int len)
- {
- RENAMES *r = &renames;
- char *sp = strtbl;
- char *ep = strtbl + strsize;
-
- while(r->fptr)
- {
- r = r->fptr;
- if(!strcmp(cp, r->newname))
- {
- cp = r->oldname;
- len = r->oldlen;
- break;
- }
- }
- while(sp < ep)
- {
- int splen = strlen(sp);
- if(splen == len)
- if(!strcmp(sp,cp))
- return 1;
- sp += splen+1;
- }
- return 0;
- }
- static void
- proc_4lb()
- {/* Process the specification file */
- char buf[200];
- char *cp;
-
- lexports = &exports;
- lrenames = &renames;
- while(fgets(buf, 190, lb4fd))
- {
- if((cp = strchr(buf, ':')) == NULL)
- continue;
- if(!strncmp(buf, "export", 6))
- {
- if((cp = find_sym(cp)) != NULL)
- {
- int len;
- char *strloc;
- len = strlen(cp);
- if(sym_exists(cp, len))
- {
- strloc = xmalloc(len+1);
- strcpy(strloc, cp);
- lexports->fptr = xmalloc(sizeof(EXPORTS));
- lexports = lexports->fptr;
- lexports->name = strloc;
- lexports->len = len;
- }
- }
- }
- else if(!strncmp(buf, "rename", 6))
- {
- if((cp = find_sym(cp)) != NULL)
- {
- int oldlen;
- char *oldstr;
-
- oldlen = strlen(cp);
- if(sym_exists(cp, oldlen))
- {
- oldstr = cp;
- cp += oldlen+1;
- if((cp = find_sym(cp)) != NULL)
- {
- int newlen = strlen(cp);
- char *newstr = cp;
- char *oldloc = xmalloc(oldlen+1);
- char *newloc = xmalloc(newlen+1);
- strcpy(oldloc, oldstr);
- strcpy(newloc, newstr);
- lrenames->fptr = xmalloc(sizeof(RENAMES));
- lrenames = lrenames->fptr;
- lrenames->oldname = oldloc;
- lrenames->oldlen = oldlen;
- lrenames->newname = newloc;
- lrenames->newlen = newlen;
- rename_diftot += newlen - oldlen;
- }
- }
- }
- }
- }
- }
- static void
- coff_proc_outfile(FILE *fd)
- {/* write coff format output file */
- PCOFF_HDR p = (PCOFF_HDR)&header;
- POXHDR hdr = &xhdr;
- int i;
-
- /* rename symbols and set exported symbols to global */
- adjust_strings(0);
-
- fseek(fd, 0, 0);
-
- /* header */
- fwrite(p, sizeof(COFF_HDR), 1, fd);
-
- /* section headers */
- fwrite(s, hdr->section_headers_size, 1, fd);
-
- /* sections */
- for(i = 0; i < p->f_nscns; ++i)
- {
- PSCNHDR q = &s[i];
- if(q->s_scnptr)
- {/* section has writeable data */
- q->s_scnptr = ftell(fd); /* new file offset */
- fwrite(sbf[i].addr, sbf[i].size, 1, fd);
- }
- }
- /* relocs */
- for(i = 0; i < p->f_nscns; ++i)
- {
- PSCNHDR q = &s[i];
- if(q->s_nreloc > 0 && rbf[i].size > 0)
- {/* section has relocs */
- q->s_relptr = ftell(fd);
- fwrite(rbf[i].addr, rbf[i].size, 1, fd);
- }
- else
- {
- q->s_nreloc = 0;
- q->s_relptr = 0;
- }
- }
- /* line numbers */
- for(i = 0; i < p->f_nscns; ++i)
- {
- PSCNHDR q = &s[i];
- if(q->s_nlnno > 0 && lbf[i].size > 0)
- {/* section has line numbers */
- q->s_lnnoptr = ftell(fd);
- fwrite(lbf[i].addr, lbf[i].size, 1, fd);
- }
- else
- {
- q->s_nlnno = 0;
- q->s_lnnoptr = 0;
- }
- }
- /* symbols */
- p->f_symptr = ftell(fd);
- fwrite(coff_symtbl, hdr->symbols_size, 1, fd);
-
- /* strings */
- fwrite((char *)&nstrsize, sizeof(nstrsize), 1, fd);
- if(nstrsize)
- fwrite(nstrtbl+sizeof(nstrsize),nstrsize,1,fd);
-
- /* reset section headers and symbols */
- fflush(fd);
- fseek(fd, 0, 0);
- fwrite(p, sizeof(COFF_HDR), 1, fd);
- fwrite(s, hdr->section_headers_size, 1, fd);
- fflush(fd);
- }
- static void
- aout_proc_outfile(FILE *fd)
- {/* write aout format output file */
-
- /* rename symbols and set exported symbols to global */
- adjust_strings(sizeof(nstrsize));
-
- fseek(fd, 0, 0);
-
- /* header */
- fwrite((char *)&header, sizeof(struct exec), 1, fd);
-
- /* text */
- if(header.a_text)
- fwrite(text, (u_int)header.a_text, 1, fd);
-
- /* data */
- if(header.a_data)
- fwrite(data, (u_int)header.a_data, 1, fd);
-
- /* text relocs */
- if(header.a_trsize)
- fwrite((char *)text_relocs, (u_int)header.a_trsize, 1, fd);
-
- /* data relocs */
- if(header.a_drsize);
- fwrite((char *)data_relocs, (u_int)header.a_drsize, 1, fd);
-
- /* symbol table */
- if(header.a_syms)
- fwrite((char *)symtbl, (u_int)header.a_syms, 1, fd);
-
- /* strings */
- fwrite((char *)&nstrsize, sizeof(nstrsize), 1, fd);
- if(nstrsize)
- fwrite(nstrtbl+sizeof(nstrsize),nstrsize-sizeof(nstrsize),1,fd);
- fflush(fd);
- }
- #ifdef SKELETON
- int obj4lb(int argc, char **argv)
- #else
- int main(int argc, char **argv)
- #endif
- {
- char *str;
- int i, j;
- char chr;
-
-
- if (argc != 2) usage();
- strcpy(infile,argv[1]);
- lose_backslashes(infile);
- strcpy(outfile,infile);
- strcpy(lb4file,infile);
- fix_suffix(outfile, ".olb");
- fix_suffix(lb4file, ".4lb");
-
- /* process the input file */
- if(proc_infile(infile))
- {
- fclose(ifd);
- /* process the specification file */
- lb4fd = fopen(lb4file, "r");
- if(lb4fd)
- {
- proc_4lb();
- fclose(lb4fd);
- } else {
- puts("4lb: warning export file not found");
- }
- ofd = fopen(outfile, "w+b");
- if(N_MAGIC(header) == OMAGIC)
- aout_proc_outfile(ofd);
- else
- coff_proc_outfile(ofd);
- fclose(ofd);
- }
- return 0;
- }
-