version 1.5, 1997/11/07 03:42:47 |
version 1.6, 1999/05/10 16:14:07 |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
#include <archive.h> |
#include <archive.h> |
|
#include "byte.c" |
|
|
|
|
extern CHDR chdr; /* converted header */ |
extern CHDR chdr; /* converted header */ |
extern char *archive; /* archive name */ |
extern char *archive; /* archive name */ |
extern char *tname; /* temporary file "name" */ |
extern char *tname; /* temporary file "name" */ |
|
|
static long symcnt; /* symbol count */ |
static long symcnt; /* symbol count */ |
static long tsymlen; /* total string length */ |
static long tsymlen; /* total string length */ |
|
|
static void rexec(), symobj(); |
static int rexec(); |
|
static void symobj(); |
extern void *emalloc(); |
extern void *emalloc(); |
|
|
build() |
build() |
{ |
{ |
CF cf; |
CF cf; |
int afd, tfd; |
int afd, tfd; |
|
int check_mid; |
|
int current_mid; |
off_t size; |
off_t size; |
|
|
|
check_mid = 0; |
afd = open_archive(O_RDWR); |
afd = open_archive(O_RDWR); |
fp = fdopen(afd, "r+"); |
fp = fdopen(afd, "r+"); |
tfd = tmp(); |
tfd = tmp(); |
|
|
symcnt = tsymlen = 0; |
symcnt = tsymlen = 0; |
pnext = &rhead; |
pnext = &rhead; |
while(get_arobj(afd)) { |
while(get_arobj(afd)) { |
|
int new_mid; |
|
|
if (!strcmp(chdr.name, RANLIBMAG)) { |
if (!strcmp(chdr.name, RANLIBMAG)) { |
skip_arobj(afd); |
skip_arobj(afd); |
continue; |
continue; |
} |
} |
rexec(afd, tfd); |
new_mid = rexec(afd, tfd); |
|
if (check_mid && new_mid != current_mid) |
|
errx(1, "Mixed object format archive: %d / %d", |
|
new_mid, current_mid); |
|
current_mid = new_mid; |
|
check_mid = 1; |
put_arobj(&cf, (struct stat *)NULL); |
put_arobj(&cf, (struct stat *)NULL); |
} |
} |
*pnext = NULL; |
*pnext = NULL; |
|
|
/* Create the symbol table. */ |
/* Create the symbol table. Endianess the same as last mid seen */ |
symobj(); |
symobj(current_mid); |
|
|
/* Copy the saved objects into the archive. */ |
/* Copy the saved objects into the archive. */ |
size = lseek(tfd, (off_t)0, SEEK_CUR); |
size = lseek(tfd, (off_t)0, SEEK_CUR); |
|
|
/* |
/* |
* rexec |
* rexec |
* Read the exec structure; ignore any files that don't look |
* Read the exec structure; ignore any files that don't look |
* exactly right. |
* exactly right. Return MID. |
*/ |
*/ |
static void |
static int |
rexec(rfd, wfd) |
rexec(rfd, wfd) |
register int rfd; |
register int rfd; |
int wfd; |
int wfd; |
|
|
goto badread; |
goto badread; |
|
|
/* Check magic number and symbol count. */ |
/* Check magic number and symbol count. */ |
if (N_BADMAG(ebuf) || ebuf.a_syms == 0) |
if (BAD_OBJECT(ebuf) || ebuf.a_syms == 0) |
goto bad1; |
goto bad1; |
|
fix_header_order(&ebuf); |
|
|
/* Seek to string table. */ |
/* Seek to string table. */ |
if (lseek(rfd, N_STROFF(ebuf) + r_off, SEEK_SET) == (off_t)-1) |
if (lseek(rfd, N_STROFF(ebuf) + r_off, SEEK_SET) == (off_t)-1) |
|
|
if (nr != sizeof(strsize)) |
if (nr != sizeof(strsize)) |
goto badread; |
goto badread; |
|
|
|
strsize = fix_long_order(strsize, N_GETMID(ebuf)); |
/* Read in the string table. */ |
/* Read in the string table. */ |
strsize -= sizeof(strsize); |
strsize -= sizeof(strsize); |
strtab = (char *)emalloc(strsize); |
strtab = (char *)emalloc(strsize); |
|
|
badfmt(); |
badfmt(); |
error(archive); |
error(archive); |
} |
} |
|
fix_nlist_order(&nl, N_GETMID(ebuf)); |
|
|
/* Ignore if no name or local. */ |
/* Ignore if no name or local. */ |
if (!nl.n_un.n_strx || !(nl.n_type & N_EXT)) |
if (!nl.n_un.n_strx || !(nl.n_type & N_EXT)) |
|
|
|
|
bad2: free(strtab); |
bad2: free(strtab); |
bad1: (void)lseek(rfd, (off_t)r_off, SEEK_SET); |
bad1: (void)lseek(rfd, (off_t)r_off, SEEK_SET); |
|
return N_GETMID(ebuf); |
} |
} |
|
|
/* |
/* |
* symobj -- |
* symobj -- |
* Write the symbol table into the archive, computing offsets as |
* Write the symbol table into the archive, computing offsets as |
* writing. |
* writing. Use the right format depending on mid. |
*/ |
*/ |
static void |
static void |
symobj() |
symobj(mid) |
|
int mid; |
{ |
{ |
register RLIB *rp, *rnext; |
register RLIB *rp, *rnext; |
struct ranlib rn; |
struct ranlib rn; |
|
|
error(tname); |
error(tname); |
|
|
/* First long is the size of the ranlib structure section. */ |
/* First long is the size of the ranlib structure section. */ |
size = symcnt * sizeof(struct ranlib); |
size = fix_long_order(symcnt * sizeof(struct ranlib), mid); |
if (!fwrite((char *)&size, sizeof(size), 1, fp)) |
if (!fwrite((char *)&size, sizeof(size), 1, fp)) |
error(tname); |
error(tname); |
|
|
|
|
rn.ran_un.ran_strx = stroff; |
rn.ran_un.ran_strx = stroff; |
stroff += rp->symlen; |
stroff += rp->symlen; |
rn.ran_off = size + rp->pos; |
rn.ran_off = size + rp->pos; |
|
fix_ranlib_order(&rn, mid); |
if (!fwrite((char *)&rn, sizeof(struct ranlib), 1, fp)) |
if (!fwrite((char *)&rn, sizeof(struct ranlib), 1, fp)) |
error(archive); |
error(archive); |
} |
} |
|
|
/* Second long is the size of the string table. */ |
/* Second long is the size of the string table. */ |
if (!fwrite((char *)&tsymlen, sizeof(tsymlen), 1, fp)) |
|
|
size = fix_long_order(tsymlen, mid); |
|
if (!fwrite((char *)&size, sizeof(size), 1, fp)) |
error(tname); |
error(tname); |
|
|
/* Write out the string table. */ |
/* Write out the string table. */ |