diff options
author | jdp <jdp@FreeBSD.org> | 1999-04-05 02:36:40 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 1999-04-05 02:36:40 +0000 |
commit | da5cbf3e761684d770fd39c67eafd90586d06217 (patch) | |
tree | 9690cb0e0b0e51991e25ed653a26d4a67a409065 /libexec | |
parent | 9a0d570ac09088ff0dbac198b5c519d11e06d56d (diff) | |
download | FreeBSD-src-da5cbf3e761684d770fd39c67eafd90586d06217.zip FreeBSD-src-da5cbf3e761684d770fd39c67eafd90586d06217.tar.gz |
Resolve undefined weak references to a value of 0. This solves the
"__deregister_frame_info" problem that was seen when combining a
program linked using the old gcc with shared libraries that were
built using egcs.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 837819c..f5bad83 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.15 1999/03/24 23:47:29 nate Exp $ + * $Id: rtld.c,v 1.16 1999/04/04 06:01:09 peter Exp $ */ /* @@ -133,10 +133,13 @@ static Obj_Entry **obj_tail; /* Link field of last object in list */ static Obj_Entry *obj_main; /* The main program shared object */ static Obj_Entry obj_rtld; /* The dynamic linker shared object */ +static Elf_Sym sym_zero; /* For resolving undefined weak refs. */ + #define GDB_STATE(s) r_debug.r_state = s; r_debug_state(); extern Elf_Dyn _DYNAMIC; + /* * These are the functions the dynamic linker exports to application * programs. They are the only symbols the dynamic linker is willing @@ -272,6 +275,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) obj_tail = &obj_main->next; obj_main->refcount++; + /* Initialize a fake symbol for resolving undefined weak references. */ + sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); + sym_zero.st_shndx = SHN_ABS; + dbg("loading LD_PRELOAD libraries"); if (load_preload_objects() == -1) die(); @@ -759,6 +766,11 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, return weakdef; } + if (ELF_ST_BIND(ref->st_info) == STB_WEAK) { + *defobj_out = obj_main; + return &sym_zero; + } + _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name); return NULL; } |