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