Apply kernigh@'s fix to broken symbol tables in aelflod (via mailing list patch):

---snip---
The ELF spec at http://www.sco.com/developers/gabi/ says, "In each
symbol table, all symbols with STB_LOCAL binding precede the weak and
global symbols," and that sh_info is the index of the first non-local
symbol.

I was mixing local and global symbols and setting sh_info to zero. I
also forgot to set the type of the .shstrtab section.
---snip---
This commit is contained in:
David Given 2017-01-18 00:06:14 +01:00
parent 81c677d218
commit 01a61e0708

View file

@ -43,6 +43,7 @@ char* stringarea;
uint32_t ack_off_char;
int nstab = 0; /* S_STB symbol count */
int nsym = 0; /* other symbol count */
int nlocal = 0; /* local symbols */
char* outputfile = NULL; /* Name of output file, or NULL */
char* program; /* Name of current program: argv[0] */
@ -347,11 +348,22 @@ void emit_stab(void)
void emit_symtab(void)
{
struct outname* n;
int i;
int i, pass;
bool global;
/* ELF .symtab must have local symbols before other symbols.
* We emit locals in pass 0, globals in pass 1. */
for (pass = 0; pass < 2; pass++) {
for (i = 0; i < outhead.oh_nname; i++) {
n = &outname[i];
if (!(n->on_type & S_STB)) {
/* Don't emit .stab symbol in .symtab. */
if (n->on_type & S_STB)
continue;
global = (n->on_type & S_EXT);
if ((pass == 0 && !global) ||
(pass == 1 && global)) {
emit32(cvname(n)); /* name index */
emit32(n->on_valu); /* value */
emit32(0); /* size = unknown */
@ -361,6 +373,7 @@ void emit_symtab(void)
}
}
}
}
void emit_strtab(void)
{
@ -386,8 +399,8 @@ void emit_shstrtab(void)
void emit_sh(int i)
{
uint32_t name, type, flags, addr, offset, size, addralign,
link, entsize;
uint32_t name, type, flags, addr, offset, size, link, info,
addralign, entsize;
/* If no debugger symbols, skip .stab and .stabstr */
if (nstab == 0 && (i == N_STAB || i == N_STABSTR))
@ -412,6 +425,7 @@ void emit_sh(int i)
break;
case N_STABSTR:
case N_STRTAB:
case N_SHSTRTAB:
type = 3; /* SHT_STRTAB */
break;
default:
@ -495,6 +509,15 @@ void emit_sh(int i)
break;
}
switch (i) {
case N_SYMTAB:
info = nlocal;
break;
default:
info = 0;
break;
}
emit32(name);
emit32(type);
emit32(flags);
@ -502,7 +525,7 @@ void emit_sh(int i)
emit32(offset);
emit32(size);
emit32(link);
emit32(0); /* info */
emit32(info);
emit32(addralign);
emit32(entsize);
}
@ -585,10 +608,13 @@ int rnames(FILE* f)
outname[i].on_type = uget2(c); c += 2;
outname[i].on_desc = uget2(c); c += 2;
outname[i].on_valu = get4(c);
if (outname[i].on_type & S_STB)
if (outname[i].on_type & S_STB) {
nstab++;
else
} else {
nsym++;
if (!(outname[i].on_type & S_EXT))
nlocal++;
}
}
stringarea = malloc(outhead.oh_nchar);