diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2002-08-23 22:57:04 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2002-08-23 22:57:04 +0000 |
commit | bfce6caf8080fa2d4f5024cab4059d709567fae4 (patch) | |
tree | 76cf0b5a29cb9439e94d9326ba53457e1dcb7f01 /libexec/ld.so/resolve.c | |
parent | 9958388d0a4d2166f3f7b1acfaae96e99f8843b7 (diff) |
Change arguments to _dl_find_symbol() myself, warnnotfound, and inplt into
a single flags field with bits representing each. Use defines to create
the appropriate masks.
Add a new argument sym_size to warn about symbols which have
the incorrect size. This replaces 'ifdef notyet' code which
was in several of the md files with a single version.
sym_size == 0 means do not check, and symbols of type FUNC are
not checked.
Diffstat (limited to 'libexec/ld.so/resolve.c')
-rw-r--r-- | libexec/ld.so/resolve.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index 312401ffbd8..f26cf307181 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.12 2002/08/11 16:51:04 drahn Exp $ */ +/* $OpenBSD: resolve.c,v 1.13 2002/08/23 22:57:03 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -175,9 +175,10 @@ _dl_lookup_object(const char *name) Elf_Addr _dl_find_symbol(const char *name, elf_object_t *startlook, - const Elf_Sym **ref, int myself, int warnnotfound, int inplt) + const Elf_Sym **ref, int flags, int req_size) { const Elf_Sym *weak_sym = 0; + const char *weak_symn = ""; /* remove warning */ Elf_Addr weak_offs = 0; unsigned long h = 0; const char *p = name; @@ -191,10 +192,13 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, h &= ~g; } - for (object = startlook; object; object = (myself ? 0 : object->next)) { + for (object = startlook; + object; + object = ((flags & SYM_SEARCH_SELF) ? 0 : object->next)) { const Elf_Sym *symt = object->dyn.symtab; const char *strt = object->dyn.strtab; long si; + const char *symn; for (si = object->buckets[h % object->nbuckets]; si != STN_UNDEF; si = object->chains[si]) { @@ -208,29 +212,47 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, ELF_ST_TYPE(sym->st_info) != STT_FUNC) continue; + symn = strt + sym->st_name; if (sym != *ref && - _dl_strcmp(strt + sym->st_name, name)) + _dl_strcmp(symn, name)) continue; + /* allow this symbol if we are referring to a function + * which has a value, even if section is UNDEF. + * this allows &func to refer to PLT as per the + * ELF spec. st_value is checked above. + * if flags has SYM_PLT set, we must have actual + * symbol, so this symbol is skipped. + */ if (sym->st_shndx == SHN_UNDEF) { - if ((inplt || sym->st_value == 0 || - ELF_ST_TYPE(sym->st_info) != STT_FUNC)) { + if ((flags & SYM_PLT) || sym->st_value == 0 || + ELF_ST_TYPE(sym->st_info) != STT_FUNC) { continue; } } if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) { *ref = sym; + if (req_size != sym->st_size && + req_size != 0 && + (ELF_ST_TYPE(sym->st_info) != STT_FUNC)) { + _dl_printf("%s: %s : WARNING: " + "symbol(%s) size mismatch ", + _dl_progname, object->load_name, + symn); + _dl_printf("relink your program\n"); + } return(object->load_offs); } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) { if (!weak_sym) { weak_sym = sym; + weak_symn = symn; weak_offs = object->load_offs; } } } } - if (warnnotfound) { + if (flags & SYM_WARNNOTFOUND) { if (!weak_sym && *ref && ELF_ST_BIND((*ref)->st_info) != STB_WEAK) { _dl_printf("%s: undefined symbol '%s'\n", @@ -238,5 +260,13 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, } } *ref = weak_sym; + if (weak_sym && req_size != weak_sym->st_size && + req_size != 0 && (ELF_ST_TYPE(weak_sym->st_info) != STT_FUNC)) { + _dl_printf("%s: %s : WARNING: " + "symbol(%s) size mismatch ", + _dl_progname, object->load_name, + weak_symn); + _dl_printf("relink your program\n"); + } return(weak_offs); } |