27 #if !defined(SOLARIS) && !defined(LINUX) 29 #if defined(sun) || defined(sparc) 34 #include <sys/types.h> 61 ((x).magic != 0x107 && (x).magic != 0x108 && (x).magic != 0x10b) 64 ((x).a_magic != RELOC_MAGIC && \ 65 (x).a_magic != EXEC_MAGIC && \ 66 (x).a_magic != SHARE_MAGIC && \ 67 (x).a_magic != DL_MAGIC) 70 #define FNAME_TBL_SIZE 127 74 #define TEMPNAM(d,p) dl_get_temporary_name((d), (p), __LINE__) 75 #define OPEN(fn, m) dl_open_object_file((fn), (m), __LINE__) 76 #define CLOSE(fd) dl_close_object_file((fd), __LINE__) 77 #define PIPE(fd) dl_open_pipe((fd), __LINE__) 81 #define TEMPNAM tempnam 101 #define DL_SET_ERROR_WITH_CODE(code) \ 102 er_set(ER_ERROR_SEVERITY, \ 107 #define DL_SET_ERROR_WITH_CODE_ONE_ARG(code, arg) \ 108 er_set(ER_ERROR_SEVERITY, \ 114 #define DL_SET_ERROR_SYSTEM_MSG() \ 115 er_set(ER_ERROR_SEVERITY, \ 117 dl_Errno = ER_DL_ESYS, \ 119 dl_get_system_error_message(errno)) 121 #define DL_SET_ERROR_SYSTEM_FILENAME(fn) \ 122 er_set(ER_ERROR_SEVERITY, \ 124 dl_Errno = ER_DL_EFILE, \ 127 dl_get_system_error_message(errno)) 160 pid_t (*fork_function_p) ();
166 char daemon_name[PATH_MAX];
169 #if defined (SOLARIS) || defined(HPUX) || defined(LINUX) || defined(AIX) 197 #if (defined(sun) || defined(sparc))&& !defined(SOLARIS) 198 static const char *dl_Default_libs[] = {
215 #if defined(sun) || defined(sparc) 216 static const char DEFAULT_LD_NAME[] =
"/bin/ld";
221 #elif defined(SOLARIS) 242 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 257 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 258 static size_t dl_get_image_file_size (
const char *);
259 static int dl_link_file (
DYNAMIC_LOADER *,
const char *, caddr_t,
const char **);
260 static int dl_load_objects (
DYNAMIC_LOADER *,
size_t *,
const char **,
const char **,
const size_t,
262 #elif defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 265 #error "Unknown machine type." 271 return (strerror (n));
275 #if ((defined(sun) || defined(sparc))&& !defined(SOLARIS)) 281 result = tempnam (dir, prefix);
284 fprintf (stderr,
"%s[%d]: tempnam(", __FILE__, lineno);
287 fprintf (stderr,
"\"%s\", ", dir);
291 fputs (
"NULL, ", stderr);
295 fprintf (stderr,
"\"%s\") => ", prefix);
299 fputs (
"NULL) => ", stderr);
301 fprintf (stderr,
"\"%s\" (0x%p)\n", result, result);
315 fprintf (stderr,
"%s[%d]: attempting to open %s...", __FILE__, lineno, filename);
318 fd = open (filename, mode, 0111);
323 fputs (
"failed\n", stderr);
327 fprintf (stderr,
"succeeded on fd %d\n", fd);
339 fprintf (stderr,
"%s[%d]: closing fd %d\n", __FILE__, lineno, fd);
346 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 358 #define wait WaitStatus 361 if (WIFEXITED (waitval))
363 if (WEXITSTATUS (waitval))
372 else if (WIFSIGNALED (waitval))
383 fprintf (stderr,
"dynamic loader: unknown wait status = 0x%x\n", waitval);
442 static char pathbuf[PATH_MAX];
443 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 444 #define AR_MAGIC_STR ARMAG 445 #define AR_MAGIC_STR_SIZ SARMAG 446 char ar_magic[AR_MAGIC_STRING_SIZ];
449 #define AR_MAGIC_STR AIAMAG 450 #define AR_MAGIC_STR_SIZ SAIAMAG 451 char ar_magic[AR_MAGIC_STR_SIZ];
460 fd =
OPEN (filename, O_RDONLY);
467 if (realpath ((
char *) filename, pathbuf) ==
NULL)
477 #if defined (SOLARIS) || defined (HPUX) || defined(LINUX) 482 #if defined(sun) || defined(sparc) || defined(_AIX) 484 if (lseek (fd,
sizeof (
struct filehdr), SEEK_SET) < 0)
490 if (read (fd, (
char *) &hdr,
sizeof (hdr)) ==
sizeof (hdr) && !N_BADMAG (hdr))
493 #if defined(sun) || defined(sparc) 494 this_->
size = hdr.a_text + hdr.a_data + hdr.a_bss;
499 (void) lseek (fd, 0, 0);
500 if (read (fd, ar_magic, AR_MAGIC_STR_SIZ) == AR_MAGIC_STR_SIZ)
502 if (strncmp (ar_magic, AR_MAGIC_STR, AR_MAGIC_STR_SIZ) == 0)
510 #if defined(_AIX) && defined(gcc) 549 fprintf (stderr,
"%s[%d]: dynamic loader being built\n", __FILE__, __LINE__);
567 #if defined(HAVE_VFORK) 585 #if defined (SOLARIS) || defined(HPUX) || defined(LINUX) || defined(AIX) 587 if (this_->handler.handles ==
NULL)
592 this_->handler.top = 0;
594 for (i = 0; i < this_->handler.
num; i++)
596 this_->handler.handles[
i] = 0;
606 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 626 #if defined (SOLARIS) || defined(HPUX) || defined(LINUX) || defined(AIX) 627 for (i = 0; i < this_->handler.top; i++)
630 shl_unload (this_->handler.handles[i]);
632 (void) dlclose (this_->handler.handles[i]);
636 this_->handler.top = this_->handler.
num = 0;
642 for (tp = this_->
loaded[i]; tp; tp = next_tp)
652 for (i = 0, tbl_size = this_->
loader.
num; i < tbl_size; ++i)
654 #if (defined(sun) || defined(sparc) ) && !defined(SOLARIS) 661 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 677 fprintf (stderr,
"%s[%d]: dynamic loader torn down\n", __FILE__, __LINE__);
698 for (fname = filenames, this_->
candidates.
num = 0; *fname; ++fname)
706 fprintf (stderr,
"Number of candidates = %d\n", this_->
candidates.
num);
733 fprintf (stderr,
"dl_validate_file_entry failed on %s\n", filenames[i]);
750 for (; tbl_p; tbl_p = tbl_p->
link)
753 if (strcmp (tbl_p->
filename, path) == 0)
758 fprintf (stderr,
"Duplicate: %s\n", path);
764 for (j = 0; j <
i; ++j)
772 fprintf (stderr,
"Duplicate: %s\n", path);
787 fprintf (stderr,
"Number needed to load (nneed) = %d\n", this_->
num_need_load);
797 #if (defined(sun) || defined(sparc) ) && !defined(SOLARIS) 804 dl_get_image_file_size (
const char *
filename)
808 size_t size = (size_t) - 1;
812 fd =
OPEN (filename, O_RDONLY);
819 if (read (fd, (
char *) &hdr,
sizeof (hdr)) !=
sizeof (hdr) || N_BADMAG (hdr))
825 size = hdr.a_text + hdr.a_data + hdr.a_bss;
830 fprintf (stderr,
"%s[%d]: closing fd %d\n", __FILE__, __LINE__, fd);
862 if (access (path, X_OK) == 0)
878 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 892 int i = 0, opt_cnt = 0;
895 for (option = (
const char *) strtok_r (option_string,
" \t", &save); option;
896 option = (
const char *) strtok_r ((
char *)
NULL,
" \t", &save))
898 const char **new_vec =
NULL;
900 opt_cnt +=
sizeof (
const char *);
903 new_vec = realloc (option_vec, opt_cnt);
907 new_vec = malloc (opt_cnt);
921 option_vec = new_vec;
922 option_vec[i++] = option;
930 #if !defined (SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(AIX) 941 #if defined(sun) || defined(sparc) 943 dl_link_file (
DYNAMIC_LOADER * this_,
const char *tmp_file, caddr_t load_point,
const char **libs)
957 extra_options = (
char *) getenv (
"DL_LD_OPTIONS");
960 extra_options =
strdup (extra_options);
961 if (extra_options ==
NULL)
968 for (p = libs; *
p; p++)
973 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 978 argv = malloc (
sizeof (
const char *) * (argc + 1));
987 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 993 (void) sprintf (load_point_buf,
"%p", load_point);
1007 *argvp++ = option_vec[
i];
1018 fprintf (stderr,
"%s[%d]: ", __FILE__, __LINE__);
1019 for (p = argv; *
p; ++
p)
1022 fputc (
' ', stderr);
1024 fputc (
'\n', stderr);
1033 if (pid == -1 || waitpid (pid, &waitval, 0) == -1)
1045 execv ((
char *) argv[0], (
char **) &argv[0]);
1062 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 1075 int fd =
OPEN (image_file, O_RDONLY);
1085 if (read (fd, (
char *) &hdr,
sizeof (hdr)) !=
sizeof (hdr))
1097 if (lseek (fd, N_TXTOFF (hdr), 0) == -1)
1103 size = hdr.a_text + hdr.a_data;
1104 if (read (fd, load_point, size) != size)
1125 #if ((defined(sun) || defined(sparc)) && !defined(SOLARIS)) 1130 int result = pipe (fd);
1135 fprintf (stderr,
"%s[%d]: pipe creation failed\n", __FILE__, lineno);
1139 fprintf (stderr,
"%s[%d]: pipe created on fds %d and %d\n", __FILE__, lineno, fd[0], fd[1]);
1149 void (*old_handler) () = signal (SIGPIPE, SIG_IGN);
1151 if (old_handler != SIG_DFL && old_handler != SIG_IGN)
1153 signal (SIGPIPE, old_handler);
1174 if (
PIPE (fd) == -1)
1183 fprintf (stderr,
"%s[%d]: spawning %s on fds %d and %d\n", __FILE__, __LINE__, this_->
daemon.
daemon_name, fd[0],
1192 if (daemon_pid == -1)
1208 if (dup2 (fd[0], 0) == -1)
1212 for (i = 1; i < NOFILE; ++
i)
1285 caddr_t *new_load_points;
1289 new_load_points = (caddr_t *) realloc (this_->
loader.
ptr, (this_->
loader.
num + 1) *
sizeof (caddr_t));
1293 new_load_points = (caddr_t *) malloc (
sizeof (caddr_t));
1296 if (new_load_points)
1344 #if defined (SOLARIS) || defined(HPUX) || defined(LINUX) || defined(AIX) 1353 #if (defined(sun) || defined(sparc)) && !defined(SOLARIS) 1368 dl_load_objects (
DYNAMIC_LOADER * this_,
size_t * actual,
const char **obj_files,
const char **libs,
1371 size_t estimated_size = 0;
1372 size_t actual_size = 0;
1373 caddr_t load_point =
NULL, old_load_point =
NULL;
1374 const char *tmp_file =
NULL;
1375 int first_time =
true;
1384 if (tmp_file ==
NULL)
1402 estimated_size = estimate;
1407 estimated_size += estimate;
1410 for (first_time =
true;; first_time =
false)
1413 load_point = VALLOC (estimated_size);
1414 if (load_point ==
NULL)
1420 if (load_point != old_load_point)
1422 if (dl_link_file (tmp_file, load_point, libs ==
NULL ? dl_Default_libs : libs))
1424 actual_size = dl_get_image_file_size (tmp_file);
1425 if (actual_size == -1)
1427 if (first_time && actual)
1431 *actual = actual_size - estimated_size;
1435 *actual = actual_size;
1440 if (estimated_size >= actual_size)
1445 estimated_size = actual_size;
1446 old_load_point = load_point;
1454 if (mprotect (load_point, actual_size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
1492 fprintf (stderr,
"%s[%d]: retrying unlink: errno = %d\n", __FILE__, __LINE__, errno);
1504 fprintf (stderr,
"%s[%d]: successful unlink: %s\n", __FILE__, __LINE__, tmp_file);
1508 fprintf (stderr,
"%s[%d]: hit retry max for unlink: %s\n", __FILE__, __LINE__, tmp_file);
1515 free ((
char *) tmp_file);
1527 #elif defined(SOLARIS) || defined(HPUX) || defined(LINUX) || defined(AIX) 1553 fprintf (stderr,
"Opening file: %s as handle: %d\n", obj_files[i], this_->handler.top);
1557 if (this_->handler.top == this_->handler.
num)
1559 int new_handles_num;
1565 fprintf (stderr,
"Extending handle arrary to %d handles\n", new_handles_num);
1567 new_handles = (
void **) malloc (new_handles_num *
sizeof (
void *));
1568 if (new_handles ==
NULL)
1571 "Memory allocation failed for handle extension");
1575 memcpy (new_handles, this_->handler.handles, (this_->handler.
num * sizeof (
void *)));
1577 this_->handler.handles = new_handles;
1578 this_->handler.
num = new_handles_num;
1582 this_->handler.handles[this_->handler.top] =
1583 (
void *) shl_load (obj_files[i], BIND_IMMEDIATE | BIND_NONFATAL, 0);
1585 this_->handler.handles[this_->handler.top] = dlopen (obj_files[i], RTLD_LAZY);
1587 if (this_->handler.handles[this_->handler.top] ==
NULL)
1591 sprintf (dl_msg,
"Error shl_load'ing file: %s, with error code: %d", obj_files[i], errno);
1594 fprintf (stderr,
"%s\n", dl_msg);
1598 dl_msg = dlerror ();
1601 fprintf (stderr,
"Error opening file: %s, with error \"%s\"\n", obj_files[i], dl_msg);
1612 fprintf (stderr,
"dl_open for handle: %d succeeded, value = %p\n", this_->handler.top,
1613 this_->handler.handles[this_->handler.top]);
1615 this_->handler.top++;
1651 #if defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1654 #define SYMS_NTYPE_NULL ST_NULL 1655 #define SYMS_NTYPE_ENTRY ST_ENTRY 1657 #define SYMS_NTYPE_NULL N_UNDF 1658 #define SYMS_NTYPE_ENTRY (N_TEXT | N_EXT) 1661 int i, j, num_resolutions;
1664 for (i = 0; syms[
i].n_name !=
NULL; i++)
1666 syms[
i].n_type = SYMS_NTYPE_NULL;
1670 fprintf (stderr,
"Resolving symbol: %s\n", syms[i].n_name);
1673 for (j = 0, num_resolutions = 0; j < this_->handler.top; j++)
1677 fprintf (stderr,
"resolving symbols with handle: %d, value = %p\n", j, this_->handler.handles[j]);
1680 if (shl_findsym ((shl_t *) (&this_->handler.handles[j]), syms[i].n_name, TYPE_PROCEDURE, &resolution) ==
1683 if ((resolution = dlsym (this_->handler.handles[j], syms[i].n_name)))
1687 syms[
i].n_value = (long) resolution;
1688 syms[
i].n_type = SYMS_NTYPE_ENTRY;
1692 fprintf (stderr,
"Error resolving: %s, from handle: %d: Error code %d\n", syms[i].n_name, j, errno);
1699 fprintf (stderr,
"Number of resolutions found for symbol: %s is: %d\n", syms[i].n_name, num_resolutions);
1702 if (num_resolutions > 1)
1706 syms[
i].n_type = SYMS_NTYPE_NULL;
1723 #if !defined (SOLARIS) && !defined(LINUX) && !defined(AIX) 1731 const char *image_name =
NULL;
1739 #if !defined (SOLARIS) && !defined(LINUX) && !defined(AIX) 1740 image_name = exec_path (module_name);
1741 if (image_name ==
NULL)
1751 if (dl_Loader ==
NULL)
1780 if (dl_Loader ==
NULL)
1800 #if defined(sun) || defined(sparc) || defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1810 #if defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1812 dl_load_object_module (
const char **obj_files,
const char **msgp)
1815 dl_load_object_module (
const char **obj_files,
const char **msgp,
const char **libs)
1822 *msgp =
"obsolete interface; use standard error interface instead";
1825 if (dl_Loader ==
NULL)
1836 #if defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1837 return dl_load_objects (dl_Loader, obj_files);
1839 return dl_load_objects (dl_Loader, obj_files, libs, 0,
NULL,
DL_RELATIVE);
1853 dl_resolve_object_symbol (
struct nlist *syms)
1855 if (dl_Loader ==
NULL)
1870 #if defined (ENABLE_UNUSED_FUNCTION) 1885 #if defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1887 dl_load_object_with_estimate (
const char **obj_files,
const char **msgp)
1888 #elif (defined(sun) || defined(sparc)) && !defined(SOLARIS) 1890 dl_load_object_with_estimate (
size_t * actual_size,
const char **obj_files,
const char **msgp,
const char **libs,
1898 *msgp =
"obsolete interface; use standard error interface instead";
1901 if (dl_Loader ==
NULL)
1912 #if defined(HPUX) || defined(SOLARIS) || defined(LINUX) || defined(AIX) 1913 return dl_load_objects (dl_Loader, obj_files);
1915 return dl_load_objects (dl_Loader, obj_files, libs, estimated_size, actual_size, mode);
#define ER_DL_MULTIPLY_DEFINED
char daemon_name[PATH_MAX]
static char * dl_get_temporary_name(const char *dir, const char *prefix, int lineno)
static int dl_initiate_dynamic_loader(DYNAMIC_LOADER *, const char *)
int dl_destroy_module(void)
static void dl_set_new_image_file(DYNAMIC_LOADER *, const char *)
static int dl_close_object_file(int fd, int lineno)
struct dynamic_loader::@6 loader
static const int DAEMON_NOT_AVAILABLE
static int dl_set_new_load_points(DYNAMIC_LOADER *this_, const caddr_t)
static int dl_load_object_image(caddr_t, const char *)
void(* FUNCTION_POINTER_TYPE)(void)
static void dl_destroy_candidates(DYNAMIC_LOADER *)
static void dl_set_pipe_handler(void)
#define ER_DL_DAEMON_DISAPPEARED
static DYNAMIC_LOADER * dl_Loader
struct dynamic_loader::@5 daemon
static const int MAX_UNLINK_RETRY
unsigned int hashpjw(const char *s)
static int dl_open_pipe(int *fd, int lineno)
static void dl_destroy_dynamic_loader(DYNAMIC_LOADER *)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
static const char ** dl_parse_extra_options(int *num_options, char *option_string)
pid_t(* fork_function_p)()
TBL_LINK * loaded[FNAME_TBL_SIZE]
static void dl_spawn_daemon(DYNAMIC_LOADER *)
static void dl_find_daemon(DYNAMIC_LOADER *)
static const int HANDLES_PER_EXTENT
static enum scanner_mode mode
#define ER_DL_DAEMON_MISSING
char * envvar_bindir_file(char *path, size_t size, const char *filename)
#define DL_SET_ERROR_WITH_CODE_ONE_ARG(code, arg)
static void dl_notify_daemon(DYNAMIC_LOADER *)
static void cleanup(int signo)
static const char * dl_get_system_error_message(int n)
static const int DAEMON_NOT_SPAWNED
static void dl_decipher_waitval(int waitval)
static int dl_resolve_symbol(DYNAMIC_LOADER *, struct nlist *)
static const char DAEMON_NAME[]
static int dl_open_object_file(const char *filename, int mode, int lineno)
int dl_initiate_module(const char *module_name)
static int dl_validate_candidates(DYNAMIC_LOADER *, const char **)
static int dl_validate_file_entry(FILE_ENTRY *, const char *)
static int dl_is_valid_image_file(DYNAMIC_LOADER *)
struct dynamic_loader::@4 candidates
int nlist(char *, struct nlist *)
#define free_and_init(ptr)
char * prm_get_string_value(PARAM_ID prm_id)
#define DL_SET_ERROR_SYSTEM_MSG()
#define DL_SET_ERROR_WITH_CODE(code)
char * strdup(const char *str)
static void dl_record_files(DYNAMIC_LOADER *)
#define DL_SET_ERROR_SYSTEM_FILENAME(fn)