Work around a GCC optimization bug on ia64: In link_elf_symbol_values(),
a pointer to a symbol is given and we have to find the containing symbol table. We do this by bounds checking. For some strange reason (ie I haven't found the root cause) the first test succeeded for said symbol, implying that the symbol came from the .dynsym table. In reality however the symbol actually resided in the .symtab table. Needless to say that all that was returned was junk. The upper bounds check was: (symptr - baseptr) < symtab_size This has been rewritten to: symptr < (baseptr + symtab_size) As a side-effect, slightly more optimal (and still correct :-) code can be generated on ia64.
This commit is contained in:
parent
a37394066b
commit
c558abdba7
@ -1051,7 +1051,7 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* sy
|
||||
elf_file_t ef = (elf_file_t) lf;
|
||||
const Elf_Sym* es = (const Elf_Sym*) sym;
|
||||
|
||||
if (es >= ef->symtab && ((es - ef->symtab) < ef->nchains)) {
|
||||
if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
|
||||
symval->name = ef->strtab + es->st_name;
|
||||
symval->value = (caddr_t) ef->address + es->st_value;
|
||||
symval->size = es->st_size;
|
||||
@ -1059,7 +1059,7 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* sy
|
||||
}
|
||||
if (ef->symtab == ef->ddbsymtab)
|
||||
return ENOENT;
|
||||
if (es >= ef->ddbsymtab && ((es - ef->ddbsymtab) < ef->ddbsymcnt)) {
|
||||
if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
|
||||
symval->name = ef->ddbstrtab + es->st_name;
|
||||
symval->value = (caddr_t) ef->address + es->st_value;
|
||||
symval->size = es->st_size;
|
||||
|
@ -1051,7 +1051,7 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* sy
|
||||
elf_file_t ef = (elf_file_t) lf;
|
||||
const Elf_Sym* es = (const Elf_Sym*) sym;
|
||||
|
||||
if (es >= ef->symtab && ((es - ef->symtab) < ef->nchains)) {
|
||||
if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
|
||||
symval->name = ef->strtab + es->st_name;
|
||||
symval->value = (caddr_t) ef->address + es->st_value;
|
||||
symval->size = es->st_size;
|
||||
@ -1059,7 +1059,7 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* sy
|
||||
}
|
||||
if (ef->symtab == ef->ddbsymtab)
|
||||
return ENOENT;
|
||||
if (es >= ef->ddbsymtab && ((es - ef->ddbsymtab) < ef->ddbsymcnt)) {
|
||||
if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
|
||||
symval->name = ef->ddbstrtab + es->st_name;
|
||||
symval->value = (caddr_t) ef->address + es->st_value;
|
||||
symval->size = es->st_size;
|
||||
|
Loading…
Reference in New Issue
Block a user