* Copyright (c) 1980 The Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)symorder.c 5.8 (Berkeley) %G%";
* symorder - reorder symbol table
struct nlist order
[SPACE
];
struct nlist
*newtab
, *symtab
;
int nsym
, strtabsize
, symfound
, small
;
char *kfile
, *newstrings
, *strings
, asym
[BUFSIZ
];
register struct nlist
*p
, *symp
;
register char *start
, *t
;
while ((ch
= getopt(argc
, argv
, "t")) != EOF
)
if ((f
= fopen(argv
[0], "r")) == NULL
)
for (p
= order
; fgets(asym
, sizeof(asym
), f
) != NULL
;) {
for (t
= asym
; isspace(*t
); ++t
);
p
->n_un
.n_name
= strdup(start
);
if ((f
= fopen(kfile
, "r")) == NULL
)
if ((o
= open(kfile
, O_WRONLY
)) < 0)
if ((fread(&exec
, sizeof(exec
), 1, f
)) != 1)
badfmt("no exec header");
badfmt("bad magic number");
(void)fstat(fileno(f
), &stb
);
if (stb
.st_size
< N_STROFF(exec
) + sizeof(off_t
))
badfmt("no string table");
/* seek to and read the symbol table */
(void)fseek(f
, sa
, SEEK_SET
);
if (!(symtab
= (struct nlist
*)malloc(n
)))
if (fread((void *)symtab
, 1, n
, f
) != n
)
badfmt("corrupted symbol table");
/* read string table size and string table */
if (fread((void *)&strtabsize
, sizeof(int), 1, f
) != 1 ||
badfmt("corrupted string table");
strings
= malloc(strtabsize
);
* Subtract four from strtabsize since strtabsize includes itself,
* and we've already read it.
if (fread(strings
, 1, strtabsize
- sizeof(int), f
) !=
strtabsize
- sizeof(int))
badfmt("corrupted string table");
newtab
= (struct nlist
*)malloc(n
);
if (newtab
== (struct nlist
*)NULL
)
i
= n
/ sizeof(struct nlist
);
reorder(symtab
, newtab
, i
);
newstrings
= malloc(strtabsize
);
for (symp
= symtab
; --i
>= 0; symp
++) {
if (symp
->n_un
.n_strx
== 0)
if (small
&& inlist(symp
) < 0) continue;
symp
->n_un
.n_strx
-= sizeof(int);
(void)strcpy(t
, &strings
[symp
->n_un
.n_strx
]);
symp
->n_un
.n_strx
= (t
- newstrings
) + sizeof(int);
/* update shrunk sizes */
strtabsize
= t
- newstrings
+ sizeof(int);
n
= symfound
* sizeof(struct nlist
);
(void)lseek(o
, 0, SEEK_SET
);
if (write(o
, (void *)&exec
, sizeof(exec
)) != sizeof(exec
))
(void)lseek(o
, sa
, SEEK_SET
);
if (write(o
, (void *)symtab
, n
) != n
)
if (write(o
, (void *)&strtabsize
, sizeof(int)) != sizeof(int))
if (write(o
, newstrings
, strtabsize
- sizeof(int)) !=
strtabsize
- sizeof(int))
if (small
) ftruncate(o
, lseek(o
, 0, SEEK_CUR
));
if ((i
= nsym
- symfound
) > 0) {
(void)printf("symorder: %d symbol%s not found:\n",
for (i
= 0; i
< nsym
; i
++)
if (order
[i
].n_value
== 0)
printf("%s\n", order
[i
].n_un
.n_name
);
reorder(st1
, st2
, entries
)
register struct nlist
*st1
, *st2
;
register struct nlist
*p
;
for (p
= st1
, n
= entries
; --n
>= 0; ++p
)
for (p
= st2
+ symfound
, n
= entries
; --n
>= 0; ++st1
) {
register struct nlist
*p
;
register struct nlist
*op
;
if (p
->n_un
.n_strx
>= strtabsize
)
badfmt("corrupted symbol table");
nam
= &strings
[p
->n_un
.n_strx
- sizeof(int)];
for (op
= &order
[nsym
]; --op
>= order
; ) {
if (strcmp(op
->n_un
.n_name
, nam
) != 0)
"symorder: %s: %s: %s\n", kfile
, why
, strerror(EFTYPE
));
(void)fprintf(stderr
, "symorder: ");
(void)fprintf(stderr
, "%s: ", n
);
(void)fprintf(stderr
, "%s\n", strerror(sverr
));
(void)fprintf(stderr
, "usage: symorder [-t] symlist file\n");