diff options
author | Marcel Moolenaar <marcel@FreeBSD.org> | 2002-08-24 05:01:33 +0000 |
---|---|---|
committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2002-08-24 05:01:33 +0000 |
commit | 5cf874186137eccbb7a064cd64f6872ae854c99d (patch) | |
tree | cffd74fad644797530826418a675c0c02e376ca6 /sys | |
parent | 0731a74b0805625a3029d90f06e23c89c4f980f9 (diff) | |
download | src-5cf874186137eccbb7a064cd64f6872ae854c99d.tar.gz src-5cf874186137eccbb7a064cd64f6872ae854c99d.zip |
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.
Notes
Notes:
svn path=/head/; revision=102348
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/link_elf.c | 4 | ||||
-rw-r--r-- | sys/kern/link_elf_obj.c | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 0d48c20d1bfa..7459150e1088 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -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; diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 0d48c20d1bfa..7459150e1088 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -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; |