summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-aout
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-10-01 01:22:51 +0000
committerpeter <peter@FreeBSD.org>1996-10-01 01:22:51 +0000
commit84a69ec571fc69439f49a2a47d5963f49cf6488e (patch)
tree971c56261cf0f40cf9505ac3c935e0bbc707a2df /libexec/rtld-aout
parent23b2a82332a3d2e5a644b9b9476f24286d0889a3 (diff)
downloadFreeBSD-src-84a69ec571fc69439f49a2a47d5963f49cf6488e.zip
FreeBSD-src-84a69ec571fc69439f49a2a47d5963f49cf6488e.tar.gz
Support for .weak (in addition to the N_INDR stab) for gcc/g++. Also deal
with the -R option and store the path in the dynamic header when specified. The $LD_RUN_PATH environment variable is not checked yet. While here, split up the code a bit more to enable more selective replacing of GPL'ed components that are linked with ld.so with others. Obtained from: NetBSD (mostly, the breakup is my fault)
Diffstat (limited to 'libexec/rtld-aout')
-rw-r--r--libexec/rtld-aout/dynamic.h377
-rw-r--r--libexec/rtld-aout/shlib.c40
-rw-r--r--libexec/rtld-aout/shlib.h43
-rw-r--r--libexec/rtld-aout/support.c86
-rw-r--r--libexec/rtld-aout/support.h35
5 files changed, 562 insertions, 19 deletions
diff --git a/libexec/rtld-aout/dynamic.h b/libexec/rtld-aout/dynamic.h
new file mode 100644
index 0000000..1231a62
--- /dev/null
+++ b/libexec/rtld-aout/dynamic.h
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __DYNAMIC_H__
+#define __DYNAMIC_H__
+
+#define SUN_COMPAT
+
+#include "md.h"
+#include "link.h"
+
+#ifndef RELOC_JMPTAB_P
+
+#define RELOC_JMPTAB_P(r) ((r)->r_jmptable)
+#define RELOC_BASEREL_P(r) ((r)->r_baserel)
+#define RELOC_RELATIVE_P(r) ((r)->r_relative)
+#define RELOC_COPY_P(r) ((r)->r_copy)
+#define RELOC_LAZY_P(r) ((r)->r_jmptable)
+
+#define CHECK_GOT_RELOC(r) ((r)->r_pcrel)
+#define RELOC_PIC_TYPE(r) ((r)->r_baserel? \
+ PIC_TYPE_LARGE:PIC_TYPE_NONE)
+#endif
+
+#ifndef RELOC_INIT_SEGMENT_RELOC
+#define RELOC_INIT_SEGMENT_RELOC(r)
+#endif
+
+#ifndef MAX_GOTOFF
+#define MAX_GOTOFF(x) (LONG_MAX)
+#endif
+
+#ifndef MIN_GOTOFF
+#define MIN_GOTOFF(x) (LONG_MIN)
+#endif
+
+/*
+ * Internal representation of relocation types
+ */
+#define RELTYPE_EXTERN 1
+#define RELTYPE_JMPSLOT 2
+#define RELTYPE_BASEREL 4
+#define RELTYPE_RELATIVE 8
+#define RELTYPE_COPY 16
+
+#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
+
+typedef struct localsymbol {
+ struct nzlist nzlist; /* n[z]list from file */
+ struct glosym *symbol; /* Corresponding global symbol,
+ if any */
+ struct localsymbol *next; /* List of definitions */
+ struct file_entry *entry; /* Backpointer to file */
+ long gotslot_offset; /* Position in GOT, if any */
+ int symbolnum; /* Position in output nlist */
+ int flags;
+#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */
+#define LS_WRITE 2 /* Symbol goes in output symtable */
+#define LS_RENAME 4 /* xlat name to `<file>.<name>' */
+#define LS_HASGOTSLOT 8 /* This symbol has a GOT entry */
+#define LS_WARNING 16 /* Second part of a N_WARNING duo */
+} localsymbol_t;
+
+/*
+ * Global symbol data is recorded in these structures, one for each global
+ * symbol. They are found via hashing in 'symtab', which points to a vector
+ * of buckets. Each bucket is a chain of these structures through the link
+ * field.
+ *
+ * Rewritten version to support extra info for dynamic linking.
+ */
+
+struct glosym {
+ struct glosym *link; /* Next symbol hash bucket. */
+ char *name; /* Name of this symbol. */
+ long value; /* Value of this symbol */
+ localsymbol_t *refs; /* Chain of local symbols from object
+ files pertaining to this global
+ symbol */
+ localsymbol_t *sorefs;/* Same for local symbols from shared
+ object files. */
+
+ char *warning; /* message, from N_WARNING nlists */
+ int common_size; /* Common size */
+ int symbolnum; /* Symbol index in output symbol table */
+ int rrs_symbolnum; /* Symbol index in RRS symbol table */
+
+ localsymbol_t *def_lsp; /* The local symbol that gave this
+ global symbol its definition */
+
+ char defined; /* Definition of this symbol */
+ char so_defined; /* Definition of this symbol in a shared
+ object. These go into the RRS symbol table */
+ u_char undef_refs; /* Count of number of "undefined"
+ messages printed for this symbol */
+ u_char mult_defs; /* Same for "multiply defined" symbols */
+ struct glosym *alias; /* For symbols of type N_INDR, this
+ points at the real symbol. */
+ int setv_count; /* Number of elements in N_SETV symbols */
+ int size; /* Size of this symbol (either from N_SIZE
+ symbols or a from shared object's RRS */
+ int aux; /* Auxiliary type information conveyed in
+ the `n_other' field of nlists */
+
+ /* The offset into one of the RRS tables, -1 if not used */
+ long jmpslot_offset;
+ long gotslot_offset;
+
+ long flags;
+
+#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
+#define GS_REFERENCED 0x2 /* Symbol is referred to by something
+ interesting */
+#define GS_TRACE 0x4 /* Symbol will be traced */
+#define GS_HASJMPSLOT 0x8 /* */
+#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
+#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
+#define GS_CPYRELOCCLAIMED 0x40 /* */
+#define GS_WEAK 0x80 /* Symbol is weakly defined */
+
+};
+#ifndef __symbol_defined__
+#define __symbol_defined__
+typedef struct glosym symbol;
+#endif
+
+/* The symbol hash table: a vector of SYMTABSIZE pointers to struct glosym. */
+extern symbol *symtab[];
+#define FOR_EACH_SYMBOL(i,sp) { \
+ int i; \
+ for (i = 0; i < SYMTABSIZE; i++) { \
+ register symbol *sp; \
+ for (sp = symtab[i]; sp; sp = sp->link)
+
+#define END_EACH_SYMBOL }}
+
+extern symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
+extern symbol *dynamic_symbol; /* the symbol __DYNAMIC */
+
+/*
+ * Each input file, and each library member ("subfile") being loaded, has a
+ * `file_entry' structure for it.
+ *
+ * For files specified by command args, these are contained in the vector which
+ * `file_table' points to.
+ *
+ * For library members, they are dynamically allocated, and chained through the
+ * `chain' field. The chain is found in the `subfiles' field of the
+ * `file_entry'. The `file_entry' objects for the members have `superfile'
+ * fields pointing to the one for the library.
+ *
+ * Rewritten version to support extra info for dynamic linking.
+ */
+
+struct file_entry {
+ char *filename; /* Name of this file. */
+ /*
+ * Name to use for the symbol giving address of text start Usually
+ * the same as filename, but for a file spec'd with -l this is the -l
+ * switch itself rather than the filename.
+ */
+ char *local_sym_name;
+ struct exec header; /* The file's a.out header. */
+ localsymbol_t *symbols; /* Symbol table of the file. */
+ int nsymbols; /* Number of symbols in above array. */
+ int string_size; /* Size in bytes of string table. */
+ char *strings; /* Pointer to the string table when
+ in core, NULL otherwise */
+ int strings_offset; /* Offset of string table,
+ (normally N_STROFF() + 4) */
+ /*
+ * Next two used only if `relocatable_output' or if needed for
+ * output of undefined reference line numbers.
+ */
+ struct relocation_info *textrel; /* Text relocations */
+ int ntextrel; /* # of text relocations */
+ struct relocation_info *datarel; /* Data relocations */
+ int ndatarel; /* # of data relocations */
+
+ /*
+ * Relation of this file's segments to the output file.
+ */
+ int text_start_address; /* Start of this file's text segment
+ in the output file core image. */
+ int data_start_address; /* Start of this file's data segment
+ in the output file core image. */
+ int bss_start_address; /* Start of this file's bss segment
+ in the output file core image. */
+ struct file_entry *subfiles; /* For a library, points to chain of
+ entries for the library members. */
+ struct file_entry *superfile; /* For library member, points to the
+ library's own entry. */
+ struct file_entry *chain; /* For library member, points to next
+ entry for next member. */
+ int starting_offset; /* For a library member, offset of the
+ member within the archive. Zero for
+ files that are not library members.*/
+ int total_size; /* Size of contents of this file,
+ if library member. */
+#ifdef SUN_COMPAT
+ struct file_entry *silly_archive;/* For shared libraries which have
+ a .sa companion */
+#endif
+ int lib_major, lib_minor; /* Version numbers of a shared object */
+
+ int flags;
+#define E_IS_LIBRARY 1 /* File is a an archive */
+#define E_HEADER_VALID 2 /* File's header has been read */
+#define E_SEARCH_DIRS 4 /* Search directories for file */
+#define E_SEARCH_DYNAMIC 8 /* Search for shared libs allowed */
+#define E_JUST_SYMS 0x10 /* File is used for incremental load */
+#define E_DYNAMIC 0x20 /* File is a shared object */
+#define E_SCRAPPED 0x40 /* Ignore this file */
+#define E_SYMBOLS_USED 0x80 /* Symbols from this entry were used */
+#define E_SECONDCLASS 0x100 /* Shared object is a subsidiary */
+};
+
+/*
+ * Runtime Relocation Section (RRS).
+ * This describes the data structures that go into the output text and data
+ * segments to support the run-time linker. The RRS can be empty (plain old
+ * static linking), or can just exist of GOT and PLT entries (in case of
+ * statically linked PIC code).
+ */
+extern int rrs_section_type; /* What's in the RRS section */
+#define RRS_NONE 0
+#define RRS_PARTIAL 1
+#define RRS_FULL 2
+extern int rrs_text_size; /* Size of RRS text additions */
+extern int rrs_text_start; /* Location of above */
+extern int rrs_data_size; /* Size of RRS data additions */
+extern int rrs_data_start; /* Location of above */
+extern char *rrs_search_paths; /* `-L' RT paths */
+
+/* Version number to put in __DYNAMIC (set by -V) */
+extern int soversion;
+#ifndef DEFAULT_SOVERSION
+#define DEFAULT_SOVERSION LD_VERSION_BSD
+#endif
+
+extern int pc_relocation; /* Current PC reloc value */
+
+extern int number_of_shobjs; /* # of shared objects linked in */
+
+/* Current link mode */
+extern int link_mode;
+#define DYNAMIC 1 /* Consider shared libraries */
+#define SYMBOLIC 2 /* Force symbolic resolution */
+#define FORCEARCHIVE 4 /* Force inclusion of all members
+ of archives */
+#define SHAREABLE 8 /* Build a shared object */
+#define SILLYARCHIVE 16 /* Process .sa companions, if any */
+
+extern FILE *outstream; /* Output file. */
+extern struct exec outheader; /* Output file header. */
+extern int magic; /* Output file magic. */
+extern int oldmagic;
+extern int relocatable_output;
+extern int pic_type;
+#define PIC_TYPE_NONE 0
+#define PIC_TYPE_SMALL 1
+#define PIC_TYPE_LARGE 2
+
+void read_header __P((int, struct file_entry *));
+void read_entry_symbols __P((int, struct file_entry *));
+void read_entry_strings __P((int, struct file_entry *));
+void read_entry_relocation __P((int, struct file_entry *));
+void enter_file_symbols __P((struct file_entry *));
+void read_file_symbols __P((struct file_entry *));
+int set_element_prefixed_p __P((char *));
+int text_offset __P((struct file_entry *));
+int file_open __P((struct file_entry *));
+void each_file __P((void (*)(), void *));
+void each_full_file __P((void (*)(), void *));
+unsigned long check_each_file __P((unsigned long (*)(), void *));
+void mywrite __P((void *, int, int, FILE *));
+void padfile __P((int, FILE *));
+
+/* In warnings.c: */
+void perror_name __P((char *));
+void perror_file __P((struct file_entry *));
+void print_symbols __P((FILE *));
+char *get_file_name __P((struct file_entry *));
+void print_file_name __P((struct file_entry *, FILE *));
+void prline_file_name __P((struct file_entry *, FILE *));
+int do_warnings __P((FILE *));
+
+/* In etc.c: */
+#include "support.h"
+
+/* In symbol.c: */
+void symtab_init __P((int));
+symbol *getsym __P((char *)), *getsym_soft __P((char *));
+
+/* In lib.c: */
+void search_library __P((int, struct file_entry *));
+void read_shared_object __P((int, struct file_entry *));
+int findlib __P((struct file_entry *));
+
+/* In shlib.c: */
+#include "shlib.h"
+
+/* In rrs.c: */
+void init_rrs __P((void));
+int rrs_add_shobj __P((struct file_entry *));
+void alloc_rrs_reloc __P((struct file_entry *, symbol *));
+void alloc_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
+void alloc_rrs_jmpslot __P((struct file_entry *, symbol *));
+void alloc_rrs_gotslot __P((struct file_entry *, struct relocation_info *, localsymbol_t *));
+void alloc_rrs_cpy_reloc __P((struct file_entry *, symbol *));
+
+int claim_rrs_reloc __P((struct file_entry *, struct relocation_info *, symbol *, long *));
+long claim_rrs_jmpslot __P((struct file_entry *, struct relocation_info *, symbol *, long));
+long claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
+long claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
+void claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
+void claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
+void consider_rrs_section_lengths __P((void));
+void relocate_rrs_addresses __P((void));
+void write_rrs __P((void));
+
+/* In <md>.c */
+void md_init_header __P((struct exec *, int, int));
+long md_get_addend __P((struct relocation_info *, unsigned char *));
+void md_relocate __P((struct relocation_info *, long, unsigned char *, int));
+void md_make_jmpslot __P((jmpslot_t *, long, long));
+void md_fix_jmpslot __P((jmpslot_t *, long, u_long));
+int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int));
+void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
+void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
+void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
+void md_set_breakpoint __P((long, long *));
+
+#ifdef NEED_SWAP
+/* In xbits.c: */
+void swap_longs __P((long *, int));
+void swap_symbols __P((struct nlist *, int));
+void swap_zsymbols __P((struct nzlist *, int));
+void swap_ranlib_hdr __P((struct ranlib *, int));
+void swap__dynamic __P((struct link_dynamic *));
+void swap_section_dispatch_table __P((struct section_dispatch_table *));
+void swap_so_debug __P((struct so_debug *));
+void swapin_sod __P((struct sod *, int));
+void swapout_sod __P((struct sod *, int));
+void swapout_fshash __P((struct fshash *, int));
+#endif
+
+#endif /* __DYNAMIC_H__ */
diff --git a/libexec/rtld-aout/shlib.c b/libexec/rtld-aout/shlib.c
index 9460d35..44e30f0 100644
--- a/libexec/rtld-aout/shlib.c
+++ b/libexec/rtld-aout/shlib.c
@@ -27,28 +27,26 @@
* (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: shlib.c,v 1.14 1996/01/13 00:14:53 jdp Exp $
+ * $Id: shlib.c,v 1.15 1996/04/20 18:27:56 jdp Exp $
*/
#include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
+#include <a.out.h>
+#include <ctype.h>
+#include <dirent.h>
#include <err.h>
#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <a.out.h>
-#include "ld.h"
-
-#ifdef SUNOS4
-char *strsep();
-#endif
+#include <link.h>
+#include "shlib.h"
+#include "support.h"
/*
* Standard directories to search for files specified by -l.
@@ -59,7 +57,7 @@ char *strsep();
/*
* Actual vector of library search directories,
- * including `-L'ed and LD_LIBARAY_PATH spec'd ones.
+ * including `-L'ed and LD_LIBRARY_PATH spec'd ones.
*/
char **search_dirs;
int n_search_dirs;
@@ -73,9 +71,14 @@ void
add_search_dir(name)
char *name;
{
+ int n;
+
+ for (n = 0; n < n_search_dirs; n++)
+ if (strcmp(search_dirs[n], name) == 0)
+ return;
n_search_dirs++;
search_dirs = (char **)
- xrealloc(search_dirs, n_search_dirs * sizeof(char *));
+ xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]);
search_dirs[n_search_dirs - 1] = strdup(name);
}
@@ -83,17 +86,16 @@ void
add_search_path(path)
char *path;
{
- register char *cp;
+ register char *cp, *dup;
if (path == NULL)
return;
- /* Add search directories from `paths' */
- while ((cp = strsep(&path, ":")) != NULL) {
+ /* Add search directories from `path' */
+ path = dup = strdup(path);
+ while ((cp = strsep(&path, ":")) != NULL)
add_search_dir(cp);
- if (path)
- *(path-1) = ':';
- }
+ free(dup);
}
void
diff --git a/libexec/rtld-aout/shlib.h b/libexec/rtld-aout/shlib.h
new file mode 100644
index 0000000..796d37e
--- /dev/null
+++ b/libexec/rtld-aout/shlib.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (C) 1996
+ * Peter Wemm. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *-
+ * $Id$
+ */
+
+/*
+ * prototypes for shlib.c. Big deal.
+ */
+
+extern char **search_dirs;
+extern int n_search_dirs;
+
+void add_search_dir __P((char *));
+void add_search_path __P((char *));
+void std_search_path __P((void));
+int getdewey __P((int[], char *));
+int cmpndewey __P((int[], int, int[], int));
+char *findshlib __P((char *, int *, int *, int));
+char *find_lib_file __P((char *));
+char *search_lib_dir __P((char *, char *, int *, int *, int));
diff --git a/libexec/rtld-aout/support.c b/libexec/rtld-aout/support.c
new file mode 100644
index 0000000..6fdf505
--- /dev/null
+++ b/libexec/rtld-aout/support.c
@@ -0,0 +1,86 @@
+/*
+ * Generic "support" routines to replace those obtained from libiberty for ld.
+ *
+ * I've collected these from random bits of (published) code I've written
+ * over the years, not that they are a big deal. peter@freebsd.org
+ *-
+ * Copyright (C) 1996
+ * Peter Wemm. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *-
+ * $Id$
+ */
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+
+#include "support.h"
+
+char *
+concat(s1, s2, s3)
+ const char *s1, *s2, *s3;
+{
+ int len = 1;
+ char *s;
+ if (s1)
+ len += strlen(s1);
+ if (s2)
+ len += strlen(s2);
+ if (s3)
+ len += strlen(s3);
+ s = malloc(len);
+ s[0] = '\0';
+ if (s1)
+ strcat(s, s1);
+ if (s2)
+ strcat(s, s2);
+ if (s3)
+ strcat(s, s3);
+ return s;
+}
+
+void *
+xmalloc(n)
+ size_t n;
+{
+ char *p = malloc(n);
+
+ if (p == NULL)
+ errx(1, "Could not allocate memory");
+
+ return p;
+}
+
+void *
+xrealloc(p, n)
+ void *p;
+ size_t n;
+{
+ p = realloc(p, n);
+
+ if (p == NULL)
+ errx(1, "Could not allocate memory");
+
+ return p;
+}
diff --git a/libexec/rtld-aout/support.h b/libexec/rtld-aout/support.h
new file mode 100644
index 0000000..5be1e31
--- /dev/null
+++ b/libexec/rtld-aout/support.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (C) 1996
+ * Peter Wemm. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *-
+ * $Id$
+ */
+
+/*
+ * prototypes for support.c. Big deal.
+ */
+
+void *xmalloc __P((size_t));
+void *xrealloc __P((void *, size_t));
+char *concat __P((const char *, const char *, const char *));
OpenPOWER on IntegriCloud