version 1.17, 2002/08/21 15:51:08 |
version 1.18, 2002/08/21 15:53:12 |
|
|
off_t *sz; |
off_t *sz; |
{ |
{ |
int cnt, len; |
int cnt, len; |
char *nstr, *nstrbase, *p, *strbase; |
char *nstr, *nstrbase=0, *used=0, *p, *strbase; |
NLIST *sym, *nsym; |
NLIST *sym, *nsym; |
u_long allocsize; |
u_long allocsize; |
int mid; |
int mid; |
NLIST *symbase; |
NLIST *symbase; |
|
unsigned int *mapping=0; |
|
int error=1; |
|
unsigned int nsyms; |
|
struct relocation_info *reloc_base; |
|
unsigned int i, j; |
|
|
/* Quit if no symbols. */ |
/* Quit if no symbols. */ |
if (ep->a_syms == 0) |
if (ep->a_syms == 0) |
|
|
allocsize = fix_long_order(*(u_long *)strbase, mid); |
allocsize = fix_long_order(*(u_long *)strbase, mid); |
if ((nstrbase = malloc((u_int) allocsize)) == NULL) { |
if ((nstrbase = malloc((u_int) allocsize)) == NULL) { |
warnx("%s", strerror(ENOMEM)); |
warnx("%s", strerror(ENOMEM)); |
return 1; |
goto end; |
} |
} |
nstr = nstrbase + sizeof(u_long); |
nstr = nstrbase + sizeof(u_long); |
|
|
|
/* okay, so we also need to keep symbol numbers for relocations. */ |
|
nsyms = ep->a_syms/ sizeof(NLIST); |
|
used = calloc(nsyms, 1); |
|
if (!used) { |
|
warnx("%s", strerror(ENOMEM)); |
|
goto end; |
|
} |
|
mapping = malloc(nsyms * sizeof(unsigned int)); |
|
if (!mapping) { |
|
warnx("%s", strerror(ENOMEM)); |
|
goto end; |
|
} |
|
|
|
if ((ep->a_trsize || ep->a_drsize) && byte_sex(mid) != BYTE_ORDER) { |
|
warnx("%s: cross-stripping not supported", fn); |
|
goto end; |
|
} |
|
|
|
/* first check the relocations for used symbols, and mark them */ |
|
/* text */ |
|
reloc_base = (struct relocation_info *) ((char *)ep + N_TRELOFF(*ep)); |
|
if (N_TRELOFF(*ep) + ep->a_trsize > sp->st_size) { |
|
warnx("%s: bad text relocation", fn); |
|
goto end; |
|
} |
|
for (i = 0; i < ep->a_trsize / sizeof(struct relocation_info); i++) { |
|
if (!reloc_base[i].r_extern) |
|
continue; |
|
if (reloc_base[i].r_symbolnum > nsyms) { |
|
warnx("%s: bad symbol number in text relocation", fn); |
|
goto end; |
|
} |
|
used[reloc_base[i].r_symbolnum] = 1; |
|
} |
|
/* data */ |
|
reloc_base = (struct relocation_info *) ((char *)ep + N_DRELOFF(*ep)); |
|
if (N_DRELOFF(*ep) + ep->a_drsize > sp->st_size) { |
|
warnx("%s: bad data relocation", fn); |
|
goto end; |
|
} |
|
for (i = 0; i < ep->a_drsize / sizeof(struct relocation_info); i++) { |
|
if (!reloc_base[i].r_extern) |
|
continue; |
|
if (reloc_base[i].r_symbolnum > nsyms) { |
|
warnx("%s: bad symbol number in data relocation", fn); |
|
goto end; |
|
} |
|
used[reloc_base[i].r_symbolnum] = 1; |
|
} |
|
|
/* |
/* |
* Read through the symbol table. For each non-debugging symbol, |
* Read through the symbol table. For each non-debugging symbol, |
* copy it and save its string in the new string table. Keep |
* copy it and save its string in the new string table. Keep |
* track of the number of symbols. |
* track of the number of symbols. |
*/ |
*/ |
for (cnt = ep->a_syms / sizeof(NLIST); cnt--; ++sym) { |
for (cnt = nsyms, i = 0, j = 0; cnt--; ++sym, ++i) { |
fix_nlist_order(sym, mid); |
fix_nlist_order(sym, mid); |
if (!(sym->n_type & N_STAB) && sym->strx) { |
if (!(sym->n_type & N_STAB) && sym->strx) { |
*nsym = *sym; |
*nsym = *sym; |
nsym->strx = nstr - nstrbase; |
nsym->strx = nstr - nstrbase; |
p = strbase + sym->strx; |
p = strbase + sym->strx; |
if (xflag && |
if (xflag && !used[i] && |
(!(sym->n_type & N_EXT) || |
(!(sym->n_type & N_EXT) || |
(sym->n_type & ~N_EXT) == N_FN || |
(sym->n_type & ~N_EXT) == N_FN || |
strcmp(p, "gcc_compiled.") == 0 || |
strcmp(p, "gcc_compiled.") == 0 || |
|
|
continue; |
continue; |
} |
} |
len = strlen(p) + 1; |
len = strlen(p) + 1; |
|
mapping[i] = j++; |
if (N_STROFF(*ep) + sym->strx + len > sp->st_size) { |
if (N_STROFF(*ep) + sym->strx + len > sp->st_size) { |
warnx("%s: bad symbol table", fn); |
warnx("%s: bad symbol table", fn); |
return 1; |
goto end; |
} |
} |
bcopy(p, nstr, len); |
bcopy(p, nstr, len); |
nstr += len; |
nstr += len; |
|
|
} |
} |
} |
} |
|
|
|
/* renumber symbol relocations */ |
|
/* text */ |
|
reloc_base = (struct relocation_info *) ((char *)ep + N_TRELOFF(*ep)); |
|
for (i = 0; i < ep->a_trsize / sizeof(struct relocation_info); i++) { |
|
if (!reloc_base[i].r_extern) |
|
continue; |
|
reloc_base[i].r_symbolnum = mapping[reloc_base[i].r_symbolnum]; |
|
} |
|
/* data */ |
|
reloc_base = (struct relocation_info *) ((char *)ep + N_DRELOFF(*ep)); |
|
for (i = 0; i < ep->a_drsize / sizeof(struct relocation_info); i++) { |
|
if (!reloc_base[i].r_extern) |
|
continue; |
|
reloc_base[i].r_symbolnum = mapping[reloc_base[i].r_symbolnum]; |
|
} |
|
|
/* Fill in new symbol table size. */ |
/* Fill in new symbol table size. */ |
ep->a_syms = (nsym - symbase) * sizeof(NLIST); |
ep->a_syms = (nsym - symbase) * sizeof(NLIST); |
|
|
|
|
* at the address past the last symbol entry. |
* at the address past the last symbol entry. |
*/ |
*/ |
bcopy(nstrbase, (void *)nsym, len); |
bcopy(nstrbase, (void *)nsym, len); |
|
error = 0; |
|
end: |
free(nstrbase); |
free(nstrbase); |
|
free(used); |
|
free(mapping); |
|
|
/* Truncate to the current length. */ |
/* Truncate to the current length. */ |
*sz = (char *)nsym + len - (char *)ep; |
*sz = (char *)nsym + len - (char *)ep; |
|
|
return 0; |
return error; |
} |
} |
|
|
void |
void |