From 4b999f1962a12177a033eaa0986990e1422be3ad Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Sat, 31 Mar 2012 02:28:03 +0200 Subject: [PATCH] build shared versions of libraries building defaults to off until clang is updated. current clang does not handle -shared, necessary to change the ld invocation to build shared libraries properly. a new clang should be installed and MKPIC defaults to no unless the newer clang is detected. changes: . mainly small imports of a Makefile or two and small fixes (turning things back on that were turned off in Makefiles) . e.g.: dynamic librefuse now depends on dynamic libpuffs, so libpuffs has to be built dynamically too and a make dependency barrier is needed in lib/Makefile . all library objects now have a PIC (for .so) and non-PIC version, so everything is built twice. . generate PIC versions of the compat (un-RENAMEd) jump files, include function type annotation in generated assembly . build progs with -static by default for now . also build ld.elf_so . also import NetBSD ldd --- .gitignore | 2 + drivers/tty/keymaps/Makefile.inc | 2 +- etc/mtree/minix.tree | 2 + lib/Makefile | 16 +- lib/generateasm.mk | 20 ++ lib/libc/Makefile | 6 +- lib/libc/Makefile.inc | 4 - lib/libc/compat-minix/Makefile.inc | 6 +- lib/libc/dlfcn/dlfcn_elf.c | 7 - lib/libc/minix-config.inc | 1 - lib/libcompat_minix/Makefile | 1 + lib/libcompat_minix/shlib_version | 2 + lib/libminlib/Makefile | 2 + lib/libminlib/shlib_version | 2 + lib/libpuffs/shlib_version | 3 + lib/libterminfo/Makefile | 6 +- lib/libterminfo/minix-config.inc | 4 - lib/libutil/compat-minix/Makefile.inc | 5 +- lib/libz/shlib_version | 2 + libexec/Makefile | 2 +- libexec/ld.elf_so/Makefile | 12 +- libexec/ld.elf_so/expand.c | 6 + libexec/ld.elf_so/load.c | 8 + libexec/ld.elf_so/map_object.c | 12 +- libexec/ld.elf_so/paths.c | 11 +- libexec/ld.elf_so/reloc.c | 7 + libexec/ld.elf_so/rtld.c | 4 + libexec/ld.elf_so/rtld.h | 2 +- libexec/ld.elf_so/xmalloc.c | 8 + share/mk/Makefile | 2 +- share/mk/bsd.gcc.mk | 22 ++ share/mk/bsd.lib.mk | 18 +- share/mk/bsd.own.mk | 16 ++ share/mk/bsd.prog.mk | 6 + share/mk/bsd.shlib.mk | 40 ++++ tools/nbsd_ports | 1 + usr.bin/Makefile | 3 +- usr.bin/ldd/Makefile | 44 ++++ usr.bin/ldd/Makefile.common | 13 ++ usr.bin/ldd/Makefile.elf | 10 + usr.bin/ldd/Makefile.inc | 26 +++ usr.bin/ldd/dummy.c | 3 + usr.bin/ldd/elf32/Makefile | 23 ++ usr.bin/ldd/elf32_compat/Makefile | 24 ++ usr.bin/ldd/elf64/Makefile | 47 ++++ usr.bin/ldd/ldd.1 | 124 +++++++++++ usr.bin/ldd/ldd.c | 305 ++++++++++++++++++++++++++ usr.bin/ldd/ldd.h | 50 +++++ usr.bin/ldd/ldd_elfxx.c | 162 ++++++++++++++ 49 files changed, 1051 insertions(+), 53 deletions(-) create mode 100644 lib/generateasm.mk create mode 100644 lib/libcompat_minix/shlib_version create mode 100644 lib/libminlib/shlib_version create mode 100644 lib/libpuffs/shlib_version create mode 100644 lib/libz/shlib_version create mode 100644 share/mk/bsd.gcc.mk create mode 100644 share/mk/bsd.shlib.mk create mode 100644 usr.bin/ldd/Makefile create mode 100644 usr.bin/ldd/Makefile.common create mode 100644 usr.bin/ldd/Makefile.elf create mode 100644 usr.bin/ldd/Makefile.inc create mode 100644 usr.bin/ldd/dummy.c create mode 100644 usr.bin/ldd/elf32/Makefile create mode 100644 usr.bin/ldd/elf32_compat/Makefile create mode 100644 usr.bin/ldd/elf64/Makefile create mode 100644 usr.bin/ldd/ldd.1 create mode 100644 usr.bin/ldd/ldd.c create mode 100644 usr.bin/ldd/ldd.h create mode 100644 usr.bin/ldd/ldd_elfxx.c diff --git a/.gitignore b/.gitignore index 0fd13dbef..67ed1cfba 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,9 @@ cscope.* *.[1-9].gz *.o *.[psS]o +lib*.so* *.a +*.so.* *.d .depend nbsdsrc/* diff --git a/drivers/tty/keymaps/Makefile.inc b/drivers/tty/keymaps/Makefile.inc index 8c8b1236a..0c7a093e4 100644 --- a/drivers/tty/keymaps/Makefile.inc +++ b/drivers/tty/keymaps/Makefile.inc @@ -4,7 +4,7 @@ FILESDIR= /usr/lib/keymaps .src.map: ${_MKTARGET_CREATE} - $(CC) -DKEYSRC=\"$<\" -o $<_genmap ${.CURDIR}/genmap.c + $(CC) $(LDFLAGS) -DKEYSRC=\"$<\" -o $<_genmap ${.CURDIR}/genmap.c ./$<_genmap > $@ @rm -f $<_genmap diff --git a/etc/mtree/minix.tree b/etc/mtree/minix.tree index c1b9a707a..09215b6e5 100644 --- a/etc/mtree/minix.tree +++ b/etc/mtree/minix.tree @@ -1,5 +1,7 @@ 755 root operator / 755 root operator /bin +755 root operator /lib +755 root operator /libexec 755 root operator /sbin 755 root operator /dev /dev/mouse -> /dev/kbdaux diff --git a/lib/Makefile b/lib/Makefile index 30a7b869f..83837ccd2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,13 +1,23 @@ .include -SUBDIR= csu libcompat_minix libc libblockdriver libchardriver \ +SUBDIR= csu +SUBDIR+= .WAIT +SUBDIR+= libc +SUBDIR+= .WAIT +SUBDIR+= libcompat_minix libc libblockdriver libchardriver \ libnetdriver libedit libm libsys libtimers libutil \ libl libz libfetch libvtreefs libaudiodriver libmthread \ libexec libdevman libusb libminlib libasyn \ libddekit libminixfs libbdev libelf libminc libcrypt libterminfo \ - libcurses libvassert libutil libpuffs librefuse libbz2 libarchive \ - libprop libnetsock libsffs libhgfs libvboxfs + libvassert libutil libbz2 libarchive libprop \ + libnetsock libpuffs libsffs libhgfs libvboxfs SUBDIR+= ../external/public-domain/xz/lib +# libraries that follow depend on earlier ones + +SUBDIR+= .WAIT +SUBDIR+= librefuse +SUBDIR+= libcurses + .include diff --git a/lib/generateasm.mk b/lib/generateasm.mk new file mode 100644 index 000000000..0fddf0bda --- /dev/null +++ b/lib/generateasm.mk @@ -0,0 +1,20 @@ +${ASM}: + ${_MKTARGET_CREATE} + printf '/* MINIX3 */ \n\ +/* \n\ +* Compatibility jump table for renamed symbols. \n\ +* \n\ +* DO NOT EDIT: this file is automatically generated. \n\ +*/ \n\ +#include \n\ +.global ${.PREFIX:S/^compat__//:C/([0-9]{2})$//}; \n\ +.global ${.PREFIX:S/^compat//}; \n\ +.type ${.PREFIX:S/^compat__//:C/([0-9]{2})$//},@function \n\ +${.PREFIX:S/^compat__//:C/([0-9]{2})$//}: \n\ +#ifdef PIC \n\ +jmpl *PIC_PLT(${.PREFIX:S/^compat//}) \n\ +#else \n\ +jmp ${.PREFIX:S/^compat//} \n\ +#endif \n\ +\n ' >${.TARGET} + diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 32e67e752..f65088283 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -159,9 +159,9 @@ FILESDIR= /var/db # workaround for I18N stuffs: build singlebyte setlocale() for libc.a, # multibyte for libc.so. the quirk should be removed when we support # dlopen() from within statically linked binaries. -.if (${CITRUS} == "yes") -CSHLIBFLAGS+= -D_I18N_DYNAMIC -.endif +#.if (${CITRUS} == "yes") +#CSHLIBFLAGS+= -D_I18N_DYNAMIC +#.endif .include diff --git a/lib/libc/Makefile.inc b/lib/libc/Makefile.inc index 0b2facf8e..a6e22ad1c 100644 --- a/lib/libc/Makefile.inc +++ b/lib/libc/Makefile.inc @@ -19,11 +19,7 @@ USE_FORT?= yes -.if defined(__MINIX) -USE_SHLIBDIR= no -.else USE_SHLIBDIR= yes -.endif CITRUS?= yes diff --git a/lib/libc/compat-minix/Makefile.inc b/lib/libc/compat-minix/Makefile.inc index eaa63c7c8..31a50051e 100644 --- a/lib/libc/compat-minix/Makefile.inc +++ b/lib/libc/compat-minix/Makefile.inc @@ -11,7 +11,7 @@ ASM= compat__opendir230.S compat__alphasort30.S compat__ctime50.S \ compat__getutmp50.S compat__getutmpx50.S compat__getutxent50.S \ compat__getutxid50.S compat__getutxline50.S compat__glob30.S \ compat__globfree30.S compat__gmtime50.S compat__gmtime_r50.S \ - compat__localtime50.S compat__localtime_r50.S compat__localtime_rz50.S \ + compat__localtime_r50.S compat__localtime_rz50.S \ compat__longjmp14.S compat__mknod50.S compat__mktime50.S \ compat__mktime_z50.S compat__nanosleep50.S compat__offtime50.S \ compat__offtime_r50.S compat__opendir30.S compat__posix2time50.S \ @@ -33,7 +33,5 @@ ASM= compat__opendir230.S compat__alphasort30.S compat__ctime50.S \ compat__vfork14.S SRCS+= ${ASM} -${ASM}: - ${_MKTARGET_CREATE} - printf '/* MINIX3 */\n\n/*\n * Compatibility jump table for renamed symbols.\n *\n * DO NOT EDIT: this file is automatically generated.\n */\n.global ${.PREFIX:S/^compat__//:C/([0-9]{2})$//};\n.global ${.PREFIX:S/^compat//};\n${.PREFIX:S/^compat__//:C/([0-9]{2})$//}: jmp ${.PREFIX:S/^compat//}\n' >${.TARGET} +.include "../generateasm.mk" diff --git a/lib/libc/dlfcn/dlfcn_elf.c b/lib/libc/dlfcn/dlfcn_elf.c index 9feae96b7..1f9bb8daf 100644 --- a/lib/libc/dlfcn/dlfcn_elf.c +++ b/lib/libc/dlfcn/dlfcn_elf.c @@ -48,12 +48,7 @@ __RCSID("$NetBSD: dlfcn_elf.c,v 1.7 2010/10/16 10:27:07 skrll Exp $"); #define dl_iterate_phdr ___dl_iterate_phdr #define ELFSIZE ARCH_ELFSIZE -#ifdef __minix -#include -#include -#else #include "rtld.h" -#endif #ifdef __weak_alias __weak_alias(dlopen,___dlopen) @@ -133,7 +128,6 @@ dlinfo(void *handle, int req, void *v) return -1; } -#ifndef __minix /*ARGSUSED*/ int dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), @@ -142,4 +136,3 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), return 0; } -#endif diff --git a/lib/libc/minix-config.inc b/lib/libc/minix-config.inc index 68df0ea59..78671f2b7 100644 --- a/lib/libc/minix-config.inc +++ b/lib/libc/minix-config.inc @@ -1,6 +1,5 @@ NETBSDSRCDIR= ${MINIXSRCDIR} NETBSDINCLUDES= /usr/include/ -MACHINE_ARCH?= i386 CITRUS=yes USE_INET6=no diff --git a/lib/libcompat_minix/Makefile b/lib/libcompat_minix/Makefile index 0009bb655..1f545ead2 100644 --- a/lib/libcompat_minix/Makefile +++ b/lib/libcompat_minix/Makefile @@ -3,6 +3,7 @@ LIB= compat_minix CPPFLAGS+= -D_MINIX_COMPAT MACHINE_ARCH= ${ARCH} +USE_SHLIBDIR= yes .PATH: ${.CURDIR} diff --git a/lib/libcompat_minix/shlib_version b/lib/libcompat_minix/shlib_version new file mode 100644 index 000000000..1edea46de --- /dev/null +++ b/lib/libcompat_minix/shlib_version @@ -0,0 +1,2 @@ +major=1 +minor=0 diff --git a/lib/libminlib/Makefile b/lib/libminlib/Makefile index e4b7fdeef..b3f3f470f 100644 --- a/lib/libminlib/Makefile +++ b/lib/libminlib/Makefile @@ -3,6 +3,8 @@ INCSDIR= /usr/include LIB= minlib +USE_SHLIBDIR= yes + CPPFLAGS.fslib.c+= -I${MINIXSRCDIR}/servers CPPFLAGS.fsversion.c+= -I${MINIXSRCDIR}/servers SRCS+= fslib.c fsversion.c diff --git a/lib/libminlib/shlib_version b/lib/libminlib/shlib_version new file mode 100644 index 000000000..1edea46de --- /dev/null +++ b/lib/libminlib/shlib_version @@ -0,0 +1,2 @@ +major=1 +minor=0 diff --git a/lib/libpuffs/shlib_version b/lib/libpuffs/shlib_version new file mode 100644 index 000000000..0647f916d --- /dev/null +++ b/lib/libpuffs/shlib_version @@ -0,0 +1,3 @@ +major=1 +minor=1 + diff --git a/lib/libterminfo/Makefile b/lib/libterminfo/Makefile index 466afe4dd..a6537ade8 100644 --- a/lib/libterminfo/Makefile +++ b/lib/libterminfo/Makefile @@ -2,10 +2,8 @@ .if defined(__MINIX) .include "minix-config.inc" -USE_SHLIBDIR= no -.else -USE_SHLIBDIR= yes .endif +USE_SHLIBDIR= yes LIB= terminfo WARNS= 4 @@ -59,9 +57,7 @@ man: terminfo.5 gen: hash compiled_terms man .include -.if !defined(__MINIX) .include -.endif .if ${MKLINKLIB} != "no" SYMLINKS+= libterminfo.a ${LIBDIR}/libtermcap.a diff --git a/lib/libterminfo/minix-config.inc b/lib/libterminfo/minix-config.inc index 0c6a32143..04f98301a 100644 --- a/lib/libterminfo/minix-config.inc +++ b/lib/libterminfo/minix-config.inc @@ -1,10 +1,6 @@ NETBSDSRCDIR= ${MINIXSRCDIR} NETBSDINCLUDES= /usr/include/ -MACHINE_ARCH?= i386 CPPFLAGS+= -D_NETBSD_SOURCE MKLINKLIB= yes -MKPROFILE= no -MKPIC= no - diff --git a/lib/libutil/compat-minix/Makefile.inc b/lib/libutil/compat-minix/Makefile.inc index 278e0ad7d..b40d98baa 100644 --- a/lib/libutil/compat-minix/Makefile.inc +++ b/lib/libutil/compat-minix/Makefile.inc @@ -4,7 +4,4 @@ ASM= compat__login_getpwclass50.S compat__login50.S compat__loginx50.S \ compat__pw_getpwconf50.S compat__setusercontext50.S SRCS+= ${ASM} -${ASM}: - ${_MKTARGET_CREATE} - printf '/* MINIX3 */\n\n/*\n * Compatibility jump table for renamed symbols.\n *\n * DO NOT EDIT: this file is automatically generated.\n */\n.global ${.PREFIX:S/^compat__//:C/([0-9]{2})$//};\n.global ${.PREFIX:S/^compat//};\n${.PREFIX:S/^compat__//:C/([0-9]{2})$//}: jmp ${.PREFIX:S/^compat//}\n' >${.TARGET} - +.include "../generateasm.mk" diff --git a/lib/libz/shlib_version b/lib/libz/shlib_version new file mode 100644 index 000000000..1edea46de --- /dev/null +++ b/lib/libz/shlib_version @@ -0,0 +1,2 @@ +major=1 +minor=0 diff --git a/libexec/Makefile b/libexec/Makefile index 58fc6a4fd..245a91706 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -3,6 +3,6 @@ .include # NetBSD imports -SUBDIR= makewhatis +SUBDIR= makewhatis ld.elf_so .include diff --git a/libexec/ld.elf_so/Makefile b/libexec/ld.elf_so/Makefile index 179d9a9a6..6cdfa0c58 100644 --- a/libexec/ld.elf_so/Makefile +++ b/libexec/ld.elf_so/Makefile @@ -5,6 +5,12 @@ WARNS?=4 +# This executable needs to be linked dynamically +MINIXDYNAMIC=yes + +# And the minix gcc currently references /libexec/ld-elf.so.1 +SYMLINKS+= ${SHLINKINSTALLDIR}/${PROG} /libexec/ld-elf.so.1 + # This needs to be before bsd.init.mk .if defined(BSD_MK_COMPAT_FILE) .include <${BSD_MK_COMPAT_FILE}> @@ -75,7 +81,7 @@ SRCS+= stack_protector.c .PATH.c: ${NETBSDSRCDIR}/lib/libc/stdlib SRCS+= exit.c -errlist_concat.h: ${NETBSDSRCDIR}/lib/libc/gen/errlist.awk ${NETBSDSRCDIR}/sys/sys/errno.h +errlist_concat.h: ${NETBSDSRCDIR}/lib/libc/gen/errlist.awk ${NETBSDSRCDIR}/include/sys/errno.h ${TOOL_AWK} -v concat=1 -f ${.ALLSRC} > ${.TARGET}.tmp && \ mv -f ${.TARGET}.tmp ${.TARGET} @@ -93,8 +99,8 @@ CPPFLAGS+= -DCOMBRELOC #CPPFLAGS+= -DDEBUG #CPPFLAGS+= -DRTLD_DEBUG #CPPFLAGS+= -DRTLD_DEBUG_RELOC -#DBG= -g -DBG= -O3 -fomit-frame-pointer +DBG= -g +#DBG= -O3 -fomit-frame-pointer .if ${SHLIBDIR} != ${LIBDIR} CPPFLAGS+= -DRTLD_DEFAULT_LIBRARY_PATH=\"${SHLIBDIR}:${LIBDIR}\" diff --git a/libexec/ld.elf_so/expand.c b/libexec/ld.elf_so/expand.c index 3be194d37..9cd0b5564 100644 --- a/libexec/ld.elf_so/expand.c +++ b/libexec/ld.elf_so/expand.c @@ -62,15 +62,20 @@ static const struct { ADD(PLATFORM) /* uname -p */ }; +#ifndef __minix static int mib[3][2] = { { CTL_KERN, KERN_OSTYPE }, { CTL_KERN, KERN_OSRELEASE }, { CTL_HW, HW_MACHINE_ARCH }, }; +#endif static size_t expand(char *buf, const char *execname, int what, size_t bl) { +#ifdef __minix + return 0; +#else const char *p, *ep; char *bp = buf; size_t len; @@ -106,6 +111,7 @@ expand(char *buf, const char *execname, int what, size_t bl) *bp++ = *p++, bl--; return bp - buf; +#endif } diff --git a/libexec/ld.elf_so/load.c b/libexec/ld.elf_so/load.c index cefda1edb..493c29553 100644 --- a/libexec/ld.elf_so/load.c +++ b/libexec/ld.elf_so/load.c @@ -57,6 +57,10 @@ __RCSID("$NetBSD: load.c,v 1.42 2010/12/24 12:41:43 skrll Exp $"); #include #include +#ifdef __minix +#define munmap minix_munmap +#endif + #include "debug.h" #include "rtld.h" @@ -211,6 +215,9 @@ _rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, dbg(("load by name %s %p", name, x)); for (; x; x = x->next) { +#ifdef __minix + continue; +#else if (strcmp(x->name, name) != 0) continue; @@ -274,6 +281,7 @@ _rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, } +#endif } if (got) diff --git a/libexec/ld.elf_so/map_object.c b/libexec/ld.elf_so/map_object.c index 9771b80dc..7f6d0bb87 100644 --- a/libexec/ld.elf_so/map_object.c +++ b/libexec/ld.elf_so/map_object.c @@ -119,6 +119,7 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb) int nsegs; caddr_t mapbase = MAP_FAILED; size_t mapsize = 0; + size_t bsssize = 0; int mapflags; Elf_Off base_offset; #ifdef MAP_ALIGNED @@ -367,22 +368,29 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb) goto bad; } + bsssize= base_vlimit - data_vlimit; + if(bsssize > 0) { /* Overlay the bss segment onto the proper region. */ - if (mmap(mapbase + data_vlimit - base_vaddr, base_vlimit - data_vlimit, + if (mmap(mapbase + data_vlimit - base_vaddr, bsssize, data_flags, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) == MAP_FAILED) { - _rtld_error("mmap of bss failed: %s", xstrerror(errno)); + _rtld_error("mmap of bss (at 0x%lx, 0x%lx bytes) failed: %s", + mapbase + data_vlimit - base_vaddr, bsssize, xstrerror(errno)); goto bad; } + } /* Unmap the gap between the text and data. */ gap_addr = mapbase + round_up(text_vlimit - base_vaddr); gap_size = data_addr - gap_addr; + +#ifndef __minix if (gap_size != 0 && mprotect(gap_addr, gap_size, PROT_NONE) == -1) { _rtld_error("mprotect of text -> data gap failed: %s", xstrerror(errno)); goto bad; } +#endif #ifdef RTLD_LOADER /* Clear any BSS in the last page of the data segment. */ diff --git a/libexec/ld.elf_so/paths.c b/libexec/ld.elf_so/paths.c index 6ccffbc53..70865da2e 100644 --- a/libexec/ld.elf_so/paths.c +++ b/libexec/ld.elf_so/paths.c @@ -49,7 +49,9 @@ __RCSID("$NetBSD: paths.c,v 1.40 2009/05/19 20:44:52 christos Exp $"); #include #include #include +#ifndef __minix #include +#endif #include #include @@ -336,13 +338,17 @@ void _rtld_process_hints(const char *execname, Search_Path **path_p, Library_Xform **lib_p, const char *fname) { + +#ifdef __minix + /* Minix doesn't support MAP_SHARED. */ + return; +#else int fd; char *buf, small[128]; const char *b, *ep, *ptr; struct stat st; ssize_t sz; Search_Path **head_p = path_p; - if ((fd = open(fname, O_RDONLY)) == -1) { /* Don't complain */ return; @@ -406,8 +412,10 @@ _rtld_process_hints(const char *execname, Search_Path **path_p, if (buf != small) (void)munmap(buf, sz); +#endif } +#ifndef __minix /* Basic name -> sysctl MIB translation */ int _rtld_sysctl(const char *name, void *oldp, size_t *oldlen) @@ -476,3 +484,4 @@ bad: xfree(result); return (-1); } +#endif diff --git a/libexec/ld.elf_so/reloc.c b/libexec/ld.elf_so/reloc.c index c0666b211..14c180948 100644 --- a/libexec/ld.elf_so/reloc.c +++ b/libexec/ld.elf_so/reloc.c @@ -166,6 +166,7 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now) (long)(obj->pltrellim - obj->pltrel), (long)(obj->pltrelalim - obj->pltrela))); +#ifndef __minix if (obj->textrel) { /* * There are relocations to the write-protected text @@ -178,9 +179,13 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now) return -1; } } +#endif + dbg(("doing non-PLT relocations")); if (_rtld_relocate_nonplt_objects(obj) < 0) ok = 0; + +#ifndef __minix if (obj->textrel) { /* Re-protected the text segment. */ if (mprotect(obj->mapbase, obj->textsize, PROT_READ | PROT_EXEC) == -1) { @@ -189,6 +194,8 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now) return -1; } } +#endif + dbg(("doing lazy PLT binding")); if (_rtld_relocate_plt_lazy(obj) < 0) ok = 0; diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index 24528c387..b1a5462fb 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -38,6 +38,10 @@ * John Polstra . */ +#ifdef __minix +#define munmap minix_munmap +#endif + #include #ifndef lint __RCSID("$NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll Exp $"); diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h index 11f0a8257..ecf005df0 100644 --- a/libexec/ld.elf_so/rtld.h +++ b/libexec/ld.elf_so/rtld.h @@ -47,7 +47,7 @@ #if defined(_RTLD_SOURCE) #ifndef RTLD_DEFAULT_LIBRARY_PATH -#define RTLD_DEFAULT_LIBRARY_PATH "/usr/lib" +#define RTLD_DEFAULT_LIBRARY_PATH "/lib:/usr/lib:/libexec" #endif #define _PATH_LD_HINTS "/etc/ld.so.conf" diff --git a/libexec/ld.elf_so/xmalloc.c b/libexec/ld.elf_so/xmalloc.c index e80c03a77..626378dab 100644 --- a/libexec/ld.elf_so/xmalloc.c +++ b/libexec/ld.elf_so/xmalloc.c @@ -60,6 +60,10 @@ * SUCH DAMAGE. */ +#ifdef __minix +#define munmap minix_munmap +#endif + #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ #endif /* LIBC_SCCS and not lint */ @@ -409,6 +413,10 @@ mstats(char *s) } #endif +/* Minix mmap can do this. */ +#ifdef __minix +#define mmap minix_mmap +#endif static int morepages(int n) diff --git a/share/mk/Makefile b/share/mk/Makefile index a44b707f4..5c4dd27ea 100644 --- a/share/mk/Makefile +++ b/share/mk/Makefile @@ -8,7 +8,7 @@ FILES= bsd.dep.mk bsd.files.mk \ bsd.init.mk bsd.kinc.mk bsd.klinks.mk bsd.lib.mk \ bsd.links.mk bsd.man.mk bsd.obj.mk bsd.own.mk \ bsd.prog.mk bsd.subdir.mk bsd.sys.mk bsd.doc.mk \ - sys.mk + bsd.shlib.mk sys.mk # MINIX-specific files FILES+= minix.bootprog.mk minix.service.mk \ diff --git a/share/mk/bsd.gcc.mk b/share/mk/bsd.gcc.mk new file mode 100644 index 000000000..b1281ded5 --- /dev/null +++ b/share/mk/bsd.gcc.mk @@ -0,0 +1,22 @@ +# $NetBSD: bsd.gcc.mk,v 1.3 2008/10/25 19:11:28 mrg Exp $ + +.if !defined(_BSD_GCC_MK_) +_BSD_GCC_MK_=1 + +.if defined(EXTERNAL_TOOLCHAIN) +_GCC_CRTBEGIN!= ${CC} --print-file-name=crtbegin.o +_GCC_CRTBEGINS!= ${CC} --print-file-name=crtbeginS.o +_GCC_CRTEND!= ${CC} --print-file-name=crtend.o +_GCC_CRTENDS!= ${CC} --print-file-name=crtendS.o +_GCC_CRTDIR!= dirname ${_GCC_CRTBEGIN} +_GCC_LIBGCCDIR!= dirname `${CC} --print-libgcc-file-name` +.else +_GCC_CRTBEGIN?= ${DESTDIR}/usr/lib/crtbegin.o +_GCC_CRTBEGINS?= ${DESTDIR}/usr/lib/crtbeginS.o +_GCC_CRTEND?= ${DESTDIR}/usr/lib/crtend.o +_GCC_CRTENDS?= ${DESTDIR}/usr/lib/crtendS.o +_GCC_CRTDIR?= ${DESTDIR}/usr/lib +_GCC_LIBGCCDIR?= ${DESTDIR}/usr/lib +.endif + +.endif # ! defined(_BSD_GCC_MK_) diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index 01efb8a15..db7acbfac 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -2,7 +2,7 @@ # @(#)bsd.lib.mk 8.3 (Berkeley) 4/22/94 .include -#.include +.include #.include # Pull in here so we can override its .c.o rule .include @@ -11,11 +11,15 @@ LIBISMODULE?= no LIBISPRIVATE?= no LIBISCXX?= no -# Some tough Minix defaults -MKPROFILE:= no -MKSTATICLIB:= yes -MKPIC:= no -MKLINT:= no +# Build shared libraries if not set to no by now +MKPIC?= yes + +# If we're making a library but aren't making shared +# libraries and it's because there's a non-shared-aware clang +# installed, warn the user that that's the reason. +.if $(MKPIC) == "no" && defined(NONPICCLANG) +.warning Old clang, not building shared. +.endif _LIB_PREFIX= lib @@ -518,7 +522,7 @@ DPLIBC ?= ${DESTDIR}${LIBC_SO} .else LDLIBC ?= -nodefaultlibs .if ${LIB} == "c" -LDADD+= -lgcc_pic +#LDADD+= -lgcc_pic .endif .endif .endif diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 2add88fad..cac9f2290 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -66,6 +66,8 @@ USE_COMPILERCRTSTUFF?= no .endif USE_COMPILERCRTSTUFF?= yes +USE_FORT?= no + # default to GDB6 HAVE_GDB?= 6 @@ -732,6 +734,20 @@ MKBINUTILS?= ${MKBFD} MKZFS?= yes .endif +# Some tough Minix defaults +MKPROFILE?= no +MKSTATICLIB:= yes +MKLINT:= no + +# Is a clang installed that understands what to do with -shared, +# needed to build shared libraries? If not then default to no +# to build them. (It could still be done with gcc though so MKPIC +# might be set to yes by the user.) +.if !exists(/usr/pkg/bin/clang.dynok) +NONPICCLANG= yes # Hint to other Makefiles +MKPIC?= no +.endif + # # MK* options which default to "yes". # diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index 82c14f83f..0fe175f7c 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -369,4 +369,10 @@ ${TARGETS}: # ensure existence ${.CURDIR}/.gitignore: Makefile echo $(CLEANFILES) $(PROGS) | tr ' ' '\n' >${.TARGET} +.if defined(MINIXDYNAMIC) +LDFLAGS += -dynamic +.else +LDFLAGS += -static +.endif + .endif # HOSTPROG diff --git a/share/mk/bsd.shlib.mk b/share/mk/bsd.shlib.mk new file mode 100644 index 000000000..763b6395a --- /dev/null +++ b/share/mk/bsd.shlib.mk @@ -0,0 +1,40 @@ +# $NetBSD: bsd.shlib.mk,v 1.6 2007/08/29 21:34:17 hira Exp $ + +.if !defined(_BSD_SHLIB_MK_) +_BSD_SHLIB_MK_=1 + +.if ${MKDYNAMICROOT} == "no" +SHLIBINSTALLDIR?= /usr/lib +.else +SHLIBINSTALLDIR?= /lib +.endif + +.if ${MKDYNAMICROOT} == "no" || \ + (${BINDIR:Ux} != "/bin" && ${BINDIR:Ux} != "/sbin" && \ + ${BINDIR:Ux} != "/libexec" && ${USE_SHLIBDIR:Uno} == "no") +SHLIBDIR?= /usr/lib +.else +SHLIBDIR?= /lib +.endif + +.if ${USE_SHLIBDIR:Uno} != "no" +_LIBSODIR?= ${SHLIBINSTALLDIR} +.else +_LIBSODIR?= ${LIBDIR} +.endif + +.if ${MKDYNAMICROOT} == "no" +SHLINKINSTALLDIR?= /usr/libexec +.else +SHLINKINSTALLDIR?= /libexec +.endif + +.if ${MKDYNAMICROOT} == "no" || \ + (${BINDIR:Ux} != "/bin" && ${BINDIR:Ux} != "/sbin" && \ + ${BINDIR:Ux} != "/libexec") +SHLINKDIR?= /usr/libexec +.else +SHLINKDIR?= /libexec +.endif + +.endif # !defined(_BSD_SHLIB_MK_) diff --git a/tools/nbsd_ports b/tools/nbsd_ports index dfbd4412b..ba1063a8d 100644 --- a/tools/nbsd_ports +++ b/tools/nbsd_ports @@ -2,6 +2,7 @@ # Timestamp in UTC,minixpath,netbsdpath # minixpath: path in Minix source tree (starting from /usr/src/) # netbsdpath: path in BSD source tree (starting from src/) +2011/01/17 18:11:10,usr.bin/ldd 2011/01/17 18:11:10,external/bsd/file 2011/01/17 18:11:10,lib/csu 2011/01/17 18:11:10,libexec/ld.elf_so diff --git a/usr.bin/Makefile b/usr.bin/Makefile index fac8c6136..d608224d5 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -4,7 +4,8 @@ # NetBSD imports SUBDIR= login indent m4 stat tic sed mkdep uniq seq du man \ - apropos chpass newgrp passwd bzip2 bzip2recover gzip su genassym + apropos chpass newgrp passwd bzip2 bzip2recover gzip su genassym \ + ldd/elf32 .WAIT ldd # Non-NetBSD imports SUBDIR+= ministat diff --git a/usr.bin/ldd/Makefile b/usr.bin/ldd/Makefile new file mode 100644 index 000000000..351d3787d --- /dev/null +++ b/usr.bin/ldd/Makefile @@ -0,0 +1,44 @@ +# $NetBSD: Makefile,v 1.15 2009/12/15 04:06:43 mrg Exp $ + +WARNS?= 3 # XXX: -Wsign-compare issues ld.elf_so source + +.include # for MKDYNAMICROOT definition + +PROG= ldd +SRCS= ldd.c +MAN= ldd.1 + + +SUBDIR+= elf32 elf64 elf32_compat + +.if (${MACHINE_ARCH} != "alpha") +LIB_ELF32DIR!= cd ${.CURDIR}/elf32 && ${PRINTOBJDIR} +EXTRA_LIBS+= ${LIB_ELF32DIR}/libldd_elf32.a +.endif + +.if (${MACHINE_ARCH} == "mips64el") || (${MACHINE_ARCH} == "mips64eb") +LIB_ELF32COMPATDIR!= cd ${.CURDIR}/elf32_compat && ${PRINTOBJDIR} +EXTRA_LIBS+= ${LIB_ELF32COMPATDIR}/libldd_elf32_compat.a +.endif + +.if (${MACHINE_ARCH} == "alpha") || (${MACHINE_ARCH} == "sparc64") || \ + (${MACHINE_ARCH} == "x86_64") || (${MACHINE_ARCH} == "powerpc64") || \ + (${MACHINE_ARCH} == "mips64el") || (${MACHINE_ARCH} == "mips64eb") +LIB_ELF64DIR!= cd ${.CURDIR}/elf64 && ${PRINTOBJDIR} +EXTRA_LIBS+= ${LIB_ELF64DIR}/libldd_elf64.a +CPPFLAGS.ldd.c= -DELFSIZE=64 +.else +CPPFLAGS.ldd.c= -DELFSIZE=32 +.endif + +LDADD+= ${EXTRA_LIBS} +DPADD+= ${EXTRA_LIBS} + +.include "Makefile.common" + +.if (${MKDYNAMICROOT} == "no") +LDSTATIC?= -static +.endif + +.include +.include diff --git a/usr.bin/ldd/Makefile.common b/usr.bin/ldd/Makefile.common new file mode 100644 index 000000000..901bcb1dd --- /dev/null +++ b/usr.bin/ldd/Makefile.common @@ -0,0 +1,13 @@ +# $NetBSD: Makefile.common,v 1.1 2009/01/06 03:59:56 mrg Exp $ + +LDELFSO=${NETBSDSRCDIR}/libexec/ld.elf_so +CPPFLAGS+= -I${LDELFSO} -DLIBDIR=\"${LIBDIR}\" +CPPFLAGS+= -D_RTLD_SOURCE +#CPPFLAGS+= -DDEBUG +.PATH: ${LDELFSO} + +.if (${MACHINE_ARCH} == "sparc") || (${MACHINE_ARCH} == "sparc64") || \ + (${MACHINE_ARCH} == "arm") || (${MACHINE_ARCH} == "m68k") || \ + (${MACHINE_ARCH} == "powerpc") +CPPFLAGS+= -DVARPSZ +.endif diff --git a/usr.bin/ldd/Makefile.elf b/usr.bin/ldd/Makefile.elf new file mode 100644 index 000000000..b3ac1532f --- /dev/null +++ b/usr.bin/ldd/Makefile.elf @@ -0,0 +1,10 @@ +# $NetBSD: Makefile.elf,v 1.3 2009/01/07 07:52:28 mrg Exp $ + +# Makefile fragment to build a (32 or 64 bit) libldd_elfxx.a. +# Expects CPPFLAGS to have ELFSIZE set, and LIB to be set. + +SRCS= ldd_elfxx.c +SRCS+= xmalloc.c debug.c expand.c map_object.c load.c search.c \ + headers.c paths.c + +.include "Makefile.common" diff --git a/usr.bin/ldd/Makefile.inc b/usr.bin/ldd/Makefile.inc new file mode 100644 index 000000000..c97e2a3eb --- /dev/null +++ b/usr.bin/ldd/Makefile.inc @@ -0,0 +1,26 @@ +# $NetBSD: Makefile.inc,v 1.4 2009/12/15 04:06:43 mrg Exp $ + +WARNS?= 3 # XXX: -Wsign-compare issues ld.elf_so source + +.if ${MACHINE_ARCH} == "sparc64" +MLIBDIR= sparc +.endif + +.if ${MACHINE_ARCH} == "x86_64" +MLIBDIR= i386 +.endif + +.if ${MACHINE_ARCH} == "powerpc64" +MLIBDIR= powerpc +.endif + +# For now make "elf32" look for native (n32) +.if (${MACHINE_ARCH} == "mips64eb") || (${MACHINE_ARCH} == "mips64el") +MLIBDIR= 64 +COMPAT_MLIBDIR= o32 +CPPFLAGS+= -DLDD_ELF64 +.endif + +.if exists(${.CURDIR}/../../Makefile.inc) +.include "${.CURDIR}/../../Makefile.inc" +.endif diff --git a/usr.bin/ldd/dummy.c b/usr.bin/ldd/dummy.c new file mode 100644 index 000000000..51f4a6e2e --- /dev/null +++ b/usr.bin/ldd/dummy.c @@ -0,0 +1,3 @@ +/* $NetBSD: dummy.c,v 1.1 2009/01/07 00:39:24 mrg Exp $ */ + +/* This file left intentially blank. */ diff --git a/usr.bin/ldd/elf32/Makefile b/usr.bin/ldd/elf32/Makefile new file mode 100644 index 000000000..81fe415ea --- /dev/null +++ b/usr.bin/ldd/elf32/Makefile @@ -0,0 +1,23 @@ +# $NetBSD: Makefile,v 1.7 2009/12/13 08:50:56 mrg Exp $ + +.include +.include + +CPPFLAGS+= -DELFSIZE=32 +LIB= ldd_elf32 + +# XXX Force one member +SRCS= dummy.c + +LIBISPRIVATE= yes +.PATH: ${.CURDIR}/.. + +.ifdef MLIBDIR +CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" +.endif + +.if ${MACHINE_ARCH} != "alpha" +.include "../Makefile.elf" +.endif + +.include diff --git a/usr.bin/ldd/elf32_compat/Makefile b/usr.bin/ldd/elf32_compat/Makefile new file mode 100644 index 000000000..50cd55016 --- /dev/null +++ b/usr.bin/ldd/elf32_compat/Makefile @@ -0,0 +1,24 @@ +# $NetBSD: Makefile,v 1.1 2009/12/13 08:50:56 mrg Exp $ + +.include +.include + +CPPFLAGS+= -DELFSIZE=32 -DELF32_COMPAT +LIB= ldd_elf32_compat + +# XXX Force one member +SRCS= dummy.c + +LIBISPRIVATE= yes +.PATH: ${.CURDIR}/.. + +.ifdef COMPAT_MLIBDIR +MLIBDIR= ${COMPAT_MLIBDIR} +CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" +.endif + +.ifdef MLIBDIR +.include "../Makefile.elf" +.endif + +.include diff --git a/usr.bin/ldd/elf64/Makefile b/usr.bin/ldd/elf64/Makefile new file mode 100644 index 000000000..441b3693b --- /dev/null +++ b/usr.bin/ldd/elf64/Makefile @@ -0,0 +1,47 @@ +# $NetBSD: Makefile,v 1.5 2009/12/13 08:50:57 mrg Exp $ + +.include + +CPPFLAGS+= -DELFSIZE=64 +LIB= ldd_elf64 + +# XXX Force one member +SRCS= dummy.c + +LIBISPRIVATE= yes +.PATH: ${.CURDIR}/.. + +.if (${MACHINE_ARCH} == "alpha") || (${MACHINE_ARCH} == "sparc64") || \ + (${MACHINE_ARCH} == "x86_64") || (${MACHINE_ARCH} == "powerpc64") || \ + (${MACHINE_ARCH} == "mips64el") || (${MACHINE_ARCH} == "mips64eb") + +# XXX we need to make sure that we don't accidentally get the elf32 +# XXX versions of these. + +RTLD_FUNCS = \ + _rtld_expand_path \ + _rtld_digest_dynamic \ + _rtld_digest_phdr \ + _rtld_load_needed_objects \ + _rtld_load_object \ + _rtld_map_object \ + _rtld_obj_free \ + _rtld_obj_new \ + _rtld_add_paths \ + _rtld_process_hints \ + _rtld_sysctl \ + _rtld_load_library + +.for _d in ${RTLD_FUNCS} +CPPFLAGS+= -D${_d}=_elf64_${_d} +.endfor + +.if (${MACHINE_ARCH} == "mips64el") || (${MACHINE_ARCH} == "mips64eb") +CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" +.endif + +.include "../Makefile.elf" + +.endif + +.include diff --git a/usr.bin/ldd/ldd.1 b/usr.bin/ldd/ldd.1 new file mode 100644 index 000000000..0e2e3201f --- /dev/null +++ b/usr.bin/ldd/ldd.1 @@ -0,0 +1,124 @@ +.\" $NetBSD: ldd.1,v 1.18 2009/09/07 20:06:21 wiz Exp $ +.\" +.\" Copyright (c) 1998 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Paul Kranenburg. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd September 7, 2009 +.Dt LDD 1 +.Os +.Sh NAME +.Nm ldd +.Nd list dynamic object dependencies +.Sh SYNOPSIS +.Nm +.Op Fl o +.Op Fl f Ar format +.Ar program ... +.Sh DESCRIPTION +.Nm +displays all shared objects that are needed to run the given program. +Contrary to +.Xr nm 1 , +the list includes +.Dq indirect +dependencies that are the result of needed shared objects which themselves +depend on yet other shared objects. +Zero, one or two +.Fl f +options may be given. +The argument is a format string passed to +.Xr rtld 1 +and allows customization of +.Nm ldd Ns 's +output. +The first format argument is used for library objects and defaults to +.Qq "\et-l%o.%m =\*[Gt] %p\en" . +The second format argument is used for non-library objects and defaults to +.Qq "\et%o =\*[Gt] %p\en" . +.Pp +These arguments are interpreted as format strings a la +.Xr printf 3 +to customize the trace output and allow +.Nm +to be operated as a filter more conveniently. +The following conversions can be used: +.Bl -tag -width xxxx +.It \&%a +The main program's name +.Po also known as +.Dq __progname +.Pc . +.It \&%A +The value of the environment variable +.Ev LD_TRACE_LOADED_OBJECTS_PROGNAME +in a.out and the program name from the argument vector from elf. +.It \&%o +The library name. +.It \&%m +The library's major version number. +.It \&%n +The library's minor version number (a.out only, ignored in elf). +.It \&%p +The full pathname as determined by +.Nm rtld Ns 's +library search rules. +.It \&%x +The library's load address +.El +.Pp +Additionally, +.Sy \en +and +.Sy \et +are recognized and have their usual meaning. +.Pp +The +.Fl o +option is an alias for +.Fl f +.Ar \&%a:-l\&%o.\&%m =\*[Gt] \&%p\en , +which makes +.Nm +behave analogously to +.Ic nm Fl o . +.Sh SEE ALSO +.Xr ld 1 , +.Xr ld.elf_so 1 , +.Xr nm 1 , +.Xr rtld 1 +.Sh HISTORY +A +.Nm +utility first appeared in SunOS 4.0, it appeared in its current form +in +.Nx 0.9a . +.Sh BUGS +The +a.out +.Nm +actually runs the program it has been requested to analyze which in specially +constructed environments can have security implications. diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c new file mode 100644 index 000000000..f21a500b1 --- /dev/null +++ b/usr.bin/ldd/ldd.c @@ -0,0 +1,305 @@ +/* $NetBSD: ldd.c,v 1.15 2010/10/16 10:27:08 skrll Exp $ */ + +/*- + * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Paul Kranenburg. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright 1996 John D. Polstra. + * Copyright 1996 Matt Thomas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by John Polstra. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#ifndef lint +__RCSID("$NetBSD: ldd.c,v 1.15 2010/10/16 10:27:08 skrll Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" +#include "ldd.h" + +/* + * Data declarations. + */ +static char *error_message; /* Message for dlopen(), or NULL */ +bool _rtld_trust; /* False for setuid and setgid programs */ +Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ +Obj_Entry **_rtld_objtail = &_rtld_objlist; + /* Link field of last object in list */ +u_int _rtld_objcount; /* Number of shared objects */ +u_int _rtld_objloads; /* Number of objects loaded */ + +Obj_Entry *_rtld_objmain; /* The main program shared object */ +size_t _rtld_pagesz; + +Search_Path *_rtld_default_paths; +Search_Path *_rtld_paths; +Library_Xform *_rtld_xforms; + +static void usage(void) __dead; +char *main_local; +char *main_progname; + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-f ] [-f ] " + " ...\n", getprogname()); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *fmt1 = NULL, *fmt2 = NULL; + int c; + +#ifdef DEBUG + debug = 1; +#endif + while ((c = getopt(argc, argv, "f:o")) != -1) { + switch (c) { + case 'f': + if (fmt1) { + if (fmt2) + errx(1, "Too many formats"); + fmt2 = optarg; + } else + fmt1 = optarg; + break; + case 'o': + if (fmt1 || fmt2) + errx(1, "Cannot use -o and -f together"); + fmt1 = "%a:-l%o.%m => %p\n"; + break; + default: + usage(); + /*NOTREACHED*/ + } + } + argc -= optind; + argv += optind; + + if (argc <= 0) { + usage(); + /*NOTREACHED*/ + } + + for (; argc != 0; argc--, argv++) { + int fd; + + fd = open(*argv, O_RDONLY); + if (fd == -1) { + warn("%s", *argv); + continue; + } + if (elf_ldd(fd, *argv, fmt1, fmt2) == -1 + /* Alpha never had 32 bit support. */ +#if defined(_LP64) && !defined(__alpha__) + && elf32_ldd(fd, *argv, fmt1, fmt2) == -1 +#ifdef __mips__ + && elf32_ldd_compat(fd, *argv, fmt1, fmt2) == -1 +#endif +#endif + ) + warnx("%s", error_message); + close(fd); + } + + return 0; +} + +/* + * Error reporting function. Use it like printf. If formats the message + * into a buffer, and sets things up so that the next call to dlerror() + * will return the message. + */ +void +_rtld_error(const char *fmt, ...) +{ + static char buf[512]; + va_list ap; + va_start(ap, fmt); + xvsnprintf(buf, sizeof buf, fmt, ap); + error_message = buf; + va_end(ap); +} + +char * +dlerror() +{ + char *msg = error_message; + error_message = NULL; + return msg; +} + +void +fmtprint(const char *libname, Obj_Entry *obj, const char *fmt1, + const char *fmt2) +{ + const char *libpath = obj ? obj->path : "not found"; + char libnamebuf[200]; + char *libmajor = NULL; + const char *fmt; + char *cp; + int c; + + if (strncmp(libname, "lib", 3) == 0 && + (cp = strstr(libname, ".so")) != NULL) { + int i = cp - (libname + 3); + + if (i >= sizeof(libnamebuf)) + i = sizeof(libnamebuf) - 1; + (void)memcpy(libnamebuf, libname + 3, i); + libnamebuf[i] = '\0'; + if (cp[3] && isdigit((unsigned char)cp[4])) + libmajor = &cp[4]; + libname = libnamebuf; + } + + if (fmt1 == NULL) + fmt1 = libmajor != NULL ? + "\t-l%o.%m => %p\n" : + "\t-l%o => %p\n"; + if (fmt2 == NULL) + fmt2 = "\t%o => %p\n"; + + fmt = libname == libnamebuf ? fmt1 : fmt2; + while ((c = *fmt++) != '\0') { + switch (c) { + default: + putchar(c); + continue; + case '\\': + switch (c = *fmt) { + case '\0': + continue; + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + } + break; + case '%': + switch (c = *fmt) { + case '\0': + continue; + case '%': + default: + putchar(c); + break; + case 'A': + printf("%s", main_local); + break; + case 'a': + printf("%s", main_progname); + break; + case 'o': + printf("%s", libname); + break; + case 'm': + printf("%s", libmajor); + break; + case 'n': + /* XXX: not supported for elf */ + break; + case 'p': + printf("%s", libpath); + break; + case 'x': + printf("%p", obj ? obj->mapbase : 0); + break; + } + break; + } + ++fmt; + } +} + +void +print_needed(Obj_Entry *obj, const char *fmt1, const char *fmt2) +{ + const Needed_Entry *needed; + + for (needed = obj->needed; needed != NULL; needed = needed->next) { + const char *libname = obj->strtab + needed->name; + + if (needed->obj != NULL) { + if (!needed->obj->printed) { + fmtprint(libname, needed->obj, fmt1, fmt2); + needed->obj->printed = 1; + print_needed(needed->obj, fmt1, fmt2); + } + } else { + fmtprint(libname, needed->obj, fmt1, fmt2); + } + } +} diff --git a/usr.bin/ldd/ldd.h b/usr.bin/ldd/ldd.h new file mode 100644 index 000000000..fba99161b --- /dev/null +++ b/usr.bin/ldd/ldd.h @@ -0,0 +1,50 @@ +/* $NetBSD: ldd.h,v 1.6 2009/12/15 04:06:43 mrg Exp $ */ + +/* + * Copyright (c) 2008 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +int elf32_ldd(int, char *, const char *, const char *); + +#ifdef _LP64 +#define LDD_ELF64 +#endif + +#ifdef LDD_ELF64 +int elf64_ldd(int, char *, const char *, const char *); +#define elf_ldd elf64_ldd +#elif defined(ELF32_COMPAT) +#define elf_ldd elf32_compat_ldd +#else +#define elf_ldd elf32_ldd +#endif + +void fmtprint(const char *, Obj_Entry *, const char *, const char *); +void print_needed(Obj_Entry *, const char *, const char *); + +extern char *main_local; +extern char *main_progname; diff --git a/usr.bin/ldd/ldd_elfxx.c b/usr.bin/ldd/ldd_elfxx.c new file mode 100644 index 000000000..86464016e --- /dev/null +++ b/usr.bin/ldd/ldd_elfxx.c @@ -0,0 +1,162 @@ +/* $NetBSD: ldd_elfxx.c,v 1.4 2009/09/07 04:49:03 dholland Exp $ */ + +/*- + * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Paul Kranenburg. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright 1996 John D. Polstra. + * Copyright 1996 Matt Thomas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by John Polstra. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#ifndef lint +__RCSID("$NetBSD: ldd_elfxx.c,v 1.4 2009/09/07 04:49:03 dholland Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" +#include "ldd.h" + +#define munmap minix_munmap + +/* + * elfxx_ldd() - bit-size independant ELF ldd implementation. + * returns 0 on success and -1 on failure. + */ +int +ELFNAME(ldd)(int fd, char *path, const char *fmt1, const char *fmt2) +{ + struct stat st; + + if (lseek(fd, 0, SEEK_SET) < 0 || + fstat(fd, &st) < 0) { + _rtld_error("%s: %s", path, strerror(errno)); + return -1; + } + + _rtld_pagesz = sysconf(_SC_PAGESIZE); + +#ifdef RTLD_ARCH_SUBDIR + _rtld_add_paths(path, &_rtld_default_paths, + RTLD_DEFAULT_LIBRARY_PATH "/" RTLD_ARCH_SUBDIR); +#endif + _rtld_add_paths(path, &_rtld_default_paths, RTLD_DEFAULT_LIBRARY_PATH); + + _rtld_paths = NULL; + _rtld_trust = (st.st_mode & (S_ISUID | S_ISGID)) == 0; + if (_rtld_trust) + _rtld_add_paths(path, &_rtld_paths, getenv("LD_LIBRARY_PATH")); + + _rtld_process_hints(path, &_rtld_paths, &_rtld_xforms, _PATH_LD_HINTS); + _rtld_objmain = _rtld_map_object(xstrdup(path), fd, &st); + if (_rtld_objmain == NULL) + return -1; + + _rtld_objmain->path = xstrdup(path); + _rtld_digest_dynamic(path, _rtld_objmain); + + /* Link the main program into the list of objects. */ + *_rtld_objtail = _rtld_objmain; + _rtld_objtail = &_rtld_objmain->next; + ++_rtld_objmain->refcount; + + (void) _rtld_load_needed_objects(_rtld_objmain, 0); + + if (fmt1 == NULL) + printf("%s:\n", _rtld_objmain->path); + main_local = path; + main_progname = _rtld_objmain->path; + print_needed(_rtld_objmain, fmt1, fmt2); + + while (_rtld_objlist != NULL) { + Obj_Entry *obj = _rtld_objlist; + _rtld_objlist = obj->next; + while (obj->rpaths != NULL) { + const Search_Path *rpath = obj->rpaths; + obj->rpaths = rpath->sp_next; + xfree(__UNCONST(rpath->sp_path)); + xfree(__UNCONST(rpath)); + } + while (obj->needed != NULL) { + const Needed_Entry *needed = obj->needed; + obj->needed = needed->next; + xfree(__UNCONST(needed)); + } + (void) munmap(obj->mapbase, obj->mapsize); + xfree(obj->path); + xfree(obj); + } + + _rtld_objmain = NULL; + _rtld_objtail = &_rtld_objlist; + /* Need to free _rtld_paths? */ + + return 0; +}