Remove a.out runtime linker. It doesn't build and was removed from the
build over two years ago by peter. The binary a.out version of ld.so can be obtained from misc/compat22 or src/lib/compat/compat22. Discussed on: -arch Voted yes: jhb, ru, linimon, delphij
This commit is contained in:
parent
eb523c72cf
commit
290f99bb70
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=140038
@ -1,18 +0,0 @@
|
|||||||
# $FreeBSD$
|
|
||||||
PROG= ld.so
|
|
||||||
SRCS= mdprologue.S rtld.c shlib.c md.c support.c
|
|
||||||
MAN= rtld.1aout
|
|
||||||
# As there is relocation going on behind GCC's back, don't cache function addresses.
|
|
||||||
PICFLAG=-fpic -fno-function-cse
|
|
||||||
CFLAGS+=-I${.CURDIR} -I${.CURDIR}/${MACHINE_ARCH} ${PICFLAG} -DRTLD -Wall
|
|
||||||
LDFLAGS+=-nostdlib -Wl,-Bshareable,-Bsymbolic,-assert,nosymbolic
|
|
||||||
ASFLAGS+=-k
|
|
||||||
DPADD+= ${LIBC:S/c.a/c_pic.a/} ${LIBC:S/c.a/gcc_pic.a/}
|
|
||||||
LDADD+= -lc_pic -lgcc_pic
|
|
||||||
INSTALLFLAGS= -C # -C to install as atomically as possible
|
|
||||||
PRECIOUSPROG=
|
|
||||||
MLINKS= rtld.1aout ld.so.1aout
|
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/${MACHINE_ARCH}
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
@ -1,380 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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 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 */
|
|
||||||
#define FORCEDYNAMIC 32 /* Force dynamic output even if no
|
|
||||||
shared libraries included */
|
|
||||||
#define WARNRRSTEXT 64 /* Warn about rrs in text */
|
|
||||||
|
|
||||||
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__ */
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* $FreeBSD$
|
|
||||||
*
|
|
||||||
* Called by ld.so when onanating.
|
|
||||||
* This *must* be a static function, so it is not called through a jmpslot.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
md_relocate_simple(r, relocation, addr)
|
|
||||||
struct relocation_info *r;
|
|
||||||
long relocation;
|
|
||||||
char *addr;
|
|
||||||
{
|
|
||||||
if (r->r_relative)
|
|
||||||
*(long *)addr += relocation;
|
|
||||||
}
|
|
||||||
|
|
@ -1,384 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <a.out.h>
|
|
||||||
#include <stab.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "dynamic.h"
|
|
||||||
|
|
||||||
#if defined(RTLD) && defined(SUN_COMPAT)
|
|
||||||
#define REL_SIZE(r) (2) /* !!!!! Sun BUG compatible */
|
|
||||||
#else
|
|
||||||
#define REL_SIZE(r) ((r)->r_length)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get relocation addend corresponding to relocation record RP
|
|
||||||
* from address ADDR
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
md_get_addend(rp, addr)
|
|
||||||
struct relocation_info *rp;
|
|
||||||
unsigned char *addr;
|
|
||||||
{
|
|
||||||
switch (REL_SIZE(rp)) {
|
|
||||||
case 0:
|
|
||||||
return get_byte(addr);
|
|
||||||
case 1:
|
|
||||||
return get_short(addr);
|
|
||||||
case 2:
|
|
||||||
return get_long(addr);
|
|
||||||
default:
|
|
||||||
errx(1, "Unsupported relocation size: %x",
|
|
||||||
REL_SIZE(rp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put RELOCATION at ADDR according to relocation record RP.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_relocate(rp, relocation, addr, relocatable_output)
|
|
||||||
struct relocation_info *rp;
|
|
||||||
long relocation;
|
|
||||||
unsigned char *addr;
|
|
||||||
int relocatable_output;
|
|
||||||
{
|
|
||||||
switch (REL_SIZE(rp)) {
|
|
||||||
case 0:
|
|
||||||
put_byte(addr, relocation);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
put_short(addr, relocation);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
put_long(addr, relocation);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "Unsupported relocation size: %x",
|
|
||||||
REL_SIZE(rp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Machine dependent part of claim_rrs_reloc().
|
|
||||||
* Set RRS relocation type.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
md_make_reloc(rp, r, type)
|
|
||||||
struct relocation_info *rp, *r;
|
|
||||||
int type;
|
|
||||||
{
|
|
||||||
/* Relocation size */
|
|
||||||
r->r_length = rp->r_length;
|
|
||||||
|
|
||||||
if (rp->r_pcrel)
|
|
||||||
r->r_pcrel = 1;
|
|
||||||
|
|
||||||
if (type & RELTYPE_RELATIVE)
|
|
||||||
r->r_relative = 1;
|
|
||||||
|
|
||||||
if (type & RELTYPE_COPY)
|
|
||||||
r->r_copy = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
|
||||||
* to the binder slot (which is at offset 0 of the PLT).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_make_jmpslot(sp, offset, index)
|
|
||||||
jmpslot_t *sp;
|
|
||||||
long offset;
|
|
||||||
long index;
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* i386 PC-relative "fixed point" is located right after the
|
|
||||||
* instruction it pertains to.
|
|
||||||
*/
|
|
||||||
u_long fudge = - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
|
|
||||||
|
|
||||||
sp->opcode = CALL;
|
|
||||||
#if 0
|
|
||||||
sp->addr = fudge;
|
|
||||||
#else
|
|
||||||
sp->addr[0] = fudge & 0xffff;
|
|
||||||
sp->addr[1] = fudge >> 16;
|
|
||||||
#endif
|
|
||||||
sp->reloc_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
|
||||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
|
||||||
* and by `ld.so' after resolving the symbol.
|
|
||||||
* On the i386, we use the JMP instruction which is PC relative, so no
|
|
||||||
* further RRS relocations will be necessary for such a jmpslot.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_fix_jmpslot(sp, offset, addr)
|
|
||||||
jmpslot_t *sp;
|
|
||||||
long offset;
|
|
||||||
u_long addr;
|
|
||||||
{
|
|
||||||
u_long fudge = addr - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
|
|
||||||
|
|
||||||
sp->opcode = JUMP;
|
|
||||||
#if 0
|
|
||||||
sp->addr = fudge;
|
|
||||||
#else
|
|
||||||
sp->addr[0] = fudge & 0xffff;
|
|
||||||
sp->addr[1] = fudge >> 16;
|
|
||||||
#endif
|
|
||||||
sp->reloc_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bind a jmpslot to its target address. TARGET is where the jmpslot
|
|
||||||
* should jump to, and WHERE is a pointer to the jmpslot's address field.
|
|
||||||
* This is called by the dynamic linker when LD_BIND_NOW is set in the
|
|
||||||
* environment.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_bind_jmpslot(target, where)
|
|
||||||
u_long target;
|
|
||||||
caddr_t where;
|
|
||||||
{
|
|
||||||
jmpslot_t *sp =
|
|
||||||
(jmpslot_t *) (where - offsetof(jmpslot_t, addr[0]));
|
|
||||||
|
|
||||||
md_fix_jmpslot(sp, (long) sp, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the relocation record for a RRS jmpslot.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_make_jmpreloc(rp, r, type)
|
|
||||||
struct relocation_info *rp, *r;
|
|
||||||
int type;
|
|
||||||
{
|
|
||||||
jmpslot_t *sp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fix relocation address to point to the correct
|
|
||||||
* location within this jmpslot.
|
|
||||||
*/
|
|
||||||
r->r_address += sizeof(sp->opcode);
|
|
||||||
|
|
||||||
/* Relocation size */
|
|
||||||
r->r_length = 2;
|
|
||||||
|
|
||||||
/* Set relocation type */
|
|
||||||
r->r_jmptable = 1;
|
|
||||||
if (type & RELTYPE_RELATIVE)
|
|
||||||
r->r_relative = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set relocation type for a RRS GOT relocation.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_make_gotreloc(rp, r, type)
|
|
||||||
struct relocation_info *rp, *r;
|
|
||||||
int type;
|
|
||||||
{
|
|
||||||
r->r_baserel = 1;
|
|
||||||
if (type & RELTYPE_RELATIVE)
|
|
||||||
r->r_relative = 1;
|
|
||||||
|
|
||||||
/* Relocation size */
|
|
||||||
r->r_length = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set relocation type for a RRS copy operation.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_make_cpyreloc(rp, r)
|
|
||||||
struct relocation_info *rp, *r;
|
|
||||||
{
|
|
||||||
/* Relocation size */
|
|
||||||
r->r_length = 2;
|
|
||||||
|
|
||||||
r->r_copy = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
md_set_breakpoint(where, savep)
|
|
||||||
long where;
|
|
||||||
long *savep;
|
|
||||||
{
|
|
||||||
*savep = *(long *)where;
|
|
||||||
*(char *)where = TRAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef RTLD
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
int netzmagic;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize (output) exec header such that useful values are
|
|
||||||
* obtained from subsequent N_*() macro evaluations.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
md_init_header(hp, magic, flags)
|
|
||||||
struct exec *hp;
|
|
||||||
int magic, flags;
|
|
||||||
{
|
|
||||||
#ifdef NetBSD
|
|
||||||
if (oldmagic || magic == QMAGIC)
|
|
||||||
hp->a_midmag = magic;
|
|
||||||
else
|
|
||||||
N_SETMAGIC((*hp), magic, MID_I386, flags);
|
|
||||||
#endif
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
if (oldmagic)
|
|
||||||
hp->a_midmag = magic;
|
|
||||||
else if (netzmagic)
|
|
||||||
N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
|
|
||||||
else
|
|
||||||
N_SETMAGIC((*hp), magic, MID_I386, flags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
|
||||||
if (!(link_mode & SHAREABLE))
|
|
||||||
hp->a_entry = PAGSIZ;
|
|
||||||
}
|
|
||||||
#endif /* RTLD */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef NEED_SWAP
|
|
||||||
/*
|
|
||||||
* Byte swap routines for cross-linking.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
md_swapin_exec_hdr(h)
|
|
||||||
struct exec *h;
|
|
||||||
{
|
|
||||||
int skip = 0;
|
|
||||||
|
|
||||||
if (!N_BADMAG(*h))
|
|
||||||
skip = 1;
|
|
||||||
|
|
||||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
md_swapout_exec_hdr(h)
|
|
||||||
struct exec *h;
|
|
||||||
{
|
|
||||||
/* NetBSD: Always leave magic alone */
|
|
||||||
int skip = 1;
|
|
||||||
#if 0
|
|
||||||
if (N_GETMAGIC(*h) == OMAGIC)
|
|
||||||
skip = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
md_swapin_reloc(r, n)
|
|
||||||
struct relocation_info *r;
|
|
||||||
int n;
|
|
||||||
{
|
|
||||||
int bits;
|
|
||||||
|
|
||||||
for (; n; n--, r++) {
|
|
||||||
r->r_address = md_swap_long(r->r_address);
|
|
||||||
bits = ((int *)r)[1];
|
|
||||||
r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
|
|
||||||
r->r_pcrel = (bits & 1);
|
|
||||||
r->r_length = (bits >> 1) & 3;
|
|
||||||
r->r_extern = (bits >> 3) & 1;
|
|
||||||
r->r_baserel = (bits >> 4) & 1;
|
|
||||||
r->r_jmptable = (bits >> 5) & 1;
|
|
||||||
r->r_relative = (bits >> 6) & 1;
|
|
||||||
#ifdef N_SIZE
|
|
||||||
r->r_copy = (bits >> 7) & 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
md_swapout_reloc(r, n)
|
|
||||||
struct relocation_info *r;
|
|
||||||
int n;
|
|
||||||
{
|
|
||||||
int bits;
|
|
||||||
|
|
||||||
for (; n; n--, r++) {
|
|
||||||
r->r_address = md_swap_long(r->r_address);
|
|
||||||
bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
|
|
||||||
bits |= (r->r_pcrel & 1);
|
|
||||||
bits |= (r->r_length & 3) << 1;
|
|
||||||
bits |= (r->r_extern & 1) << 3;
|
|
||||||
bits |= (r->r_baserel & 1) << 4;
|
|
||||||
bits |= (r->r_jmptable & 1) << 5;
|
|
||||||
bits |= (r->r_relative & 1) << 6;
|
|
||||||
#ifdef N_SIZE
|
|
||||||
bits |= (r->r_copy & 1) << 7;
|
|
||||||
#endif
|
|
||||||
((int *)r)[1] = bits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
md_swapout_jmpslot(j, n)
|
|
||||||
jmpslot_t *j;
|
|
||||||
int n;
|
|
||||||
{
|
|
||||||
for (; n; n--, j++) {
|
|
||||||
j->opcode = md_swap_short(j->opcode);
|
|
||||||
j->addr[0] = md_swap_short(j->addr[0]);
|
|
||||||
j->addr[1] = md_swap_short(j->addr[1]);
|
|
||||||
j->reloc_index = md_swap_short(j->reloc_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NEED_SWAP */
|
|
@ -1,245 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __MD_H__
|
|
||||||
#define __MD_H__
|
|
||||||
|
|
||||||
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==sparc
|
|
||||||
#define NEED_SWAP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_ALIGNMENT (sizeof (long))
|
|
||||||
|
|
||||||
#ifdef NetBSD
|
|
||||||
#define PAGSIZ __LDPGSZ
|
|
||||||
#else
|
|
||||||
#define PAGSIZ 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(NetBSD) || defined(CROSS_LINKER)
|
|
||||||
|
|
||||||
#define N_SET_FLAG(ex,f) (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
|
|
||||||
N_SETMAGIC(ex, \
|
|
||||||
N_GETMAGIC(ex), \
|
|
||||||
MID_MACHINE, \
|
|
||||||
N_GETFLAG(ex)|(f)))
|
|
||||||
|
|
||||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
|
||||||
|
|
||||||
#define N_BADMID(ex) \
|
|
||||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeBSD does it differently
|
|
||||||
*/
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
|
|
||||||
(netzmagic == 0 ? \
|
|
||||||
N_SETMAGIC(ex, \
|
|
||||||
N_GETMAGIC(ex), \
|
|
||||||
MID_MACHINE, \
|
|
||||||
N_GETFLAG(ex)|(f)) : \
|
|
||||||
N_SETMAGIC_NET(ex, \
|
|
||||||
N_GETMAGIC_NET(ex), \
|
|
||||||
MID_MACHINE, \
|
|
||||||
N_GETFLAG_NET(ex)|(f)) ))
|
|
||||||
|
|
||||||
#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
|
|
||||||
((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
|
|
||||||
((N_GETFLAG(ex) & EX_DYNAMIC) ))
|
|
||||||
#define N_BADMID(ex) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Should be handled by a.out.h ?
|
|
||||||
*/
|
|
||||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
|
||||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
|
||||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
|
||||||
|
|
||||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (0)
|
|
||||||
#define JMPSLOT_NEEDS_RELOC (0)
|
|
||||||
|
|
||||||
#define md_got_reloc(r) (0)
|
|
||||||
|
|
||||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
|
||||||
|
|
||||||
#define RELOC_INIT_SEGMENT_RELOC(r) ((r)->r_length = 2)
|
|
||||||
|
|
||||||
/* Width of a Global Offset Table entry */
|
|
||||||
#define GOT_ENTRY_SIZE 4
|
|
||||||
typedef long got_t;
|
|
||||||
|
|
||||||
typedef struct jmpslot {
|
|
||||||
u_short opcode;
|
|
||||||
u_short addr[2];
|
|
||||||
u_short reloc_index;
|
|
||||||
#define JMPSLOT_RELOC_MASK 0xffff
|
|
||||||
} jmpslot_t;
|
|
||||||
|
|
||||||
#define NOP 0x90
|
|
||||||
#define CALL 0xe890 /* NOP + CALL opcode */
|
|
||||||
#define JUMP 0xe990 /* NOP + JMP opcode */
|
|
||||||
#define TRAP 0xcc /* INT 3 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Byte swap defs for cross linking
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NEED_SWAP)
|
|
||||||
|
|
||||||
#define md_swapin_exec_hdr(h)
|
|
||||||
#define md_swapout_exec_hdr(h)
|
|
||||||
#define md_swapin_symbols(s,n)
|
|
||||||
#define md_swapout_symbols(s,n)
|
|
||||||
#define md_swapin_zsymbols(s,n)
|
|
||||||
#define md_swapout_zsymbols(s,n)
|
|
||||||
#define md_swapin_reloc(r,n)
|
|
||||||
#define md_swapout_reloc(r,n)
|
|
||||||
#define md_swapin__dynamic(l)
|
|
||||||
#define md_swapout__dynamic(l)
|
|
||||||
#define md_swapin_section_dispatch_table(l)
|
|
||||||
#define md_swapout_section_dispatch_table(l)
|
|
||||||
#define md_swapin_so_debug(d)
|
|
||||||
#define md_swapout_so_debug(d)
|
|
||||||
#define md_swapin_rrs_hash(f,n)
|
|
||||||
#define md_swapout_rrs_hash(f,n)
|
|
||||||
#define md_swapin_sod(l,n)
|
|
||||||
#define md_swapout_sod(l,n)
|
|
||||||
#define md_swapout_jmpslot(j,n)
|
|
||||||
#define md_swapout_got(g,n)
|
|
||||||
#define md_swapin_ranlib_hdr(h,n)
|
|
||||||
#define md_swapout_ranlib_hdr(h,n)
|
|
||||||
|
|
||||||
#endif /* NEED_SWAP */
|
|
||||||
|
|
||||||
#ifdef CROSS_LINKER
|
|
||||||
|
|
||||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
|
||||||
|
|
||||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
|
||||||
( ((unsigned char *)(p))[1] ) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
|
||||||
( ((unsigned char *)(p))[1] << 16) | \
|
|
||||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
|
||||||
( ((unsigned char *)(p))[3] ) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
|
||||||
|
|
||||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
|
||||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
|
||||||
((unsigned char *)(p))[1] = \
|
|
||||||
((((unsigned long)(v)) ) & 0xff); }
|
|
||||||
|
|
||||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
|
||||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
|
||||||
((unsigned char *)(p))[1] = \
|
|
||||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
|
||||||
((unsigned char *)(p))[2] = \
|
|
||||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
|
||||||
((unsigned char *)(p))[3] = \
|
|
||||||
((((unsigned long)(v)) ) & 0xff); }
|
|
||||||
|
|
||||||
#ifdef NEED_SWAP
|
|
||||||
|
|
||||||
/* Define IO byte swapping routines */
|
|
||||||
|
|
||||||
void md_swapin_exec_hdr __P((struct exec *));
|
|
||||||
void md_swapout_exec_hdr __P((struct exec *));
|
|
||||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
|
||||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
|
||||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
|
||||||
|
|
||||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
|
||||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
|
||||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
|
||||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
|
||||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
|
||||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
|
||||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
|
||||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
|
||||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
|
||||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
|
||||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
|
||||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
|
||||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
|
||||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
|
||||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
|
||||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
|
||||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
|
||||||
|
|
||||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
|
||||||
|
|
||||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
|
||||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
|
||||||
|
|
||||||
#else /* We need not swap, but must pay attention to alignment: */
|
|
||||||
|
|
||||||
#define md_swap_short(x) (x)
|
|
||||||
#define md_swap_long(x) (x)
|
|
||||||
|
|
||||||
#endif /* NEED_SWAP */
|
|
||||||
|
|
||||||
#else /* Not a cross linker: use native */
|
|
||||||
|
|
||||||
#define md_swap_short(x) (x)
|
|
||||||
#define md_swap_long(x) (x)
|
|
||||||
|
|
||||||
#define get_byte(where) (*(char *)(where))
|
|
||||||
#define get_short(where) (*(short *)(where))
|
|
||||||
#define get_long(where) (*(long *)(where))
|
|
||||||
|
|
||||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
|
||||||
#define put_short(where,what) (*(short *)(where) = (what))
|
|
||||||
#define put_long(where,what) (*(long *)(where) = (what))
|
|
||||||
|
|
||||||
#endif /* CROSS_LINKER */
|
|
||||||
|
|
||||||
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));
|
|
||||||
void md_bind_jmpslot __P((u_long, caddr_t));
|
|
||||||
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 *));
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __MD_H__ */
|
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* i386 run-time link editor entry points.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.globl _binder, _binder_entry
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _rtl(int version, struct crt_ldso *crtp)
|
|
||||||
*/
|
|
||||||
|
|
||||||
_rtl: # crt0 calls us here
|
|
||||||
pushl %ebp # Allocate stack frame
|
|
||||||
movl %esp,%ebp
|
|
||||||
pushl %ebx
|
|
||||||
|
|
||||||
call 1f # PIC function prologue
|
|
||||||
1:
|
|
||||||
popl %ebx
|
|
||||||
addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
|
|
||||||
|
|
||||||
movl 12(%ebp),%eax # Extract data from interface structure
|
|
||||||
movl (%eax),%eax # base address of ld.so (first field)
|
|
||||||
# setup arguments for rtld()
|
|
||||||
movl (%ebx),%ecx # 1st entry in GOT is our __DYNAMIC
|
|
||||||
addl %eax,%ecx # add load address
|
|
||||||
pushl %ecx # 3rd arg
|
|
||||||
pushl 12(%ebp) # 2nd arg == &crt.
|
|
||||||
pushl 8(%ebp) # 1st arg == version
|
|
||||||
addl _rtld@GOT(%ebx),%eax # relocate address of function
|
|
||||||
call %eax # _rtld(version, crtp, DYNAMIC)
|
|
||||||
addl $12,%esp # pop arguments
|
|
||||||
|
|
||||||
popl %ebx
|
|
||||||
leave # remove stack frame
|
|
||||||
ret
|
|
||||||
|
|
||||||
# First call to a procedure generally comes through here for
|
|
||||||
# binding.
|
|
||||||
|
|
||||||
_binder_entry:
|
|
||||||
pushl %ebp # setup a stack frame
|
|
||||||
movl %esp,%ebp
|
|
||||||
pusha # save all regs
|
|
||||||
|
|
||||||
xorl %eax,%eax # clear
|
|
||||||
movl 4(%ebp),%esi # return address in PLT
|
|
||||||
movw (%esi),%ax # get hold of relocation number
|
|
||||||
subl $6,%esi # make it point to the jmpslot
|
|
||||||
|
|
||||||
pushl %eax # pushd arguments
|
|
||||||
pushl %esi #
|
|
||||||
call _binder@PLT # _binder(rpc, index)
|
|
||||||
addl $8,%esp # pop arguments
|
|
||||||
movl %eax,4(%ebp) # return value from _binder() == actual
|
|
||||||
# address of function
|
|
||||||
popa # restore regs
|
|
||||||
leave # remove our stack frame
|
|
||||||
ret
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* rtld entry pseudo code - turn into assembler and tweak it
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <a.out.h>
|
|
||||||
#include "link.h"
|
|
||||||
#include "md.h"
|
|
||||||
|
|
||||||
extern long _GOT_[];
|
|
||||||
extern void (*rtld)();
|
|
||||||
extern void (*binder())();
|
|
||||||
|
|
||||||
void
|
|
||||||
rtld_entry(version, crtp)
|
|
||||||
int version;
|
|
||||||
struct crt *crtp;
|
|
||||||
{
|
|
||||||
register struct link_dynamic *dp;
|
|
||||||
register void (*f)();
|
|
||||||
|
|
||||||
/* __DYNAMIC is first entry in GOT */
|
|
||||||
dp = (struct link_dynamic *) (_GOT_[0]+crtp->crt_ba);
|
|
||||||
|
|
||||||
f = (void (*)())((long)rtld + crtp->crt_ba);
|
|
||||||
(*f)(version, crtp, dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
binder_entry()
|
|
||||||
{
|
|
||||||
extern int PC;
|
|
||||||
struct jmpslot *sp;
|
|
||||||
void (*func)();
|
|
||||||
|
|
||||||
func = binder(PC, sp->reloc_index & 0x003fffff);
|
|
||||||
(*func)();
|
|
||||||
}
|
|
@ -1,226 +0,0 @@
|
|||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1995 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 acknowledgment:
|
|
||||||
.\" This product includes software developed by Paul Kranenburg.
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.Dd June 27, 1995
|
|
||||||
.Dt RTLD 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm ld.so ,
|
|
||||||
.Nm rtld
|
|
||||||
.Nd run-time link-editor
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm
|
|
||||||
is a self-contained, position independent program image providing run-time
|
|
||||||
support for loading and link-editing shared objects into a process'
|
|
||||||
address space.
|
|
||||||
It uses the data structures
|
|
||||||
(see
|
|
||||||
.Xr link 5 )
|
|
||||||
contained within dynamically linked programs to determine which shared
|
|
||||||
libraries are needed and loads them at a convenient virtual address
|
|
||||||
using the
|
|
||||||
.Xr mmap 2
|
|
||||||
system call.
|
|
||||||
.Pp
|
|
||||||
After all shared libraries have been successfully loaded,
|
|
||||||
.Nm
|
|
||||||
proceeds to resolve external references from both the main program and
|
|
||||||
all objects loaded.
|
|
||||||
A mechanism is provided for initialization routines
|
|
||||||
to be called, on a per-object basis, giving a shared object an opportunity
|
|
||||||
to perform any extra set-up, before execution of the program proper begins.
|
|
||||||
This is useful for C++ libraries that contain static constructors.
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
is itself a shared object that is initially loaded by the startup module
|
|
||||||
.Em crt0 .
|
|
||||||
Since
|
|
||||||
.Xr a.out 5
|
|
||||||
formats do not provide easy access to the file header from within a running
|
|
||||||
process,
|
|
||||||
.Em crt0
|
|
||||||
uses the special symbol
|
|
||||||
.Va _DYNAMIC
|
|
||||||
to determine whether a program is in fact dynamically linked or not.
|
|
||||||
Whenever
|
|
||||||
the linker
|
|
||||||
.Xr ld 1
|
|
||||||
has relocated this symbol to a location other than 0,
|
|
||||||
.Em crt0
|
|
||||||
assumes the services of
|
|
||||||
.Nm
|
|
||||||
are needed
|
|
||||||
(see
|
|
||||||
.Xr link 5
|
|
||||||
for details).
|
|
||||||
.Em crt0
|
|
||||||
passes control to
|
|
||||||
.Nm Ns 's
|
|
||||||
entry point before the program's
|
|
||||||
.Fn main
|
|
||||||
routine is called.
|
|
||||||
Thus,
|
|
||||||
.Nm
|
|
||||||
can complete the link-editing process before the dynamic program calls upon
|
|
||||||
services of any dynamic library.
|
|
||||||
.Pp
|
|
||||||
To quickly locate the required shared objects in the file system,
|
|
||||||
.Nm
|
|
||||||
may use a
|
|
||||||
.Dq hints
|
|
||||||
file, prepared by the
|
|
||||||
.Xr ldconfig 8
|
|
||||||
utility, in which the full path specification of the shared objects can be
|
|
||||||
looked up by hashing on the 3-tuple
|
|
||||||
.Aq library-name , major-version-number , minor-version-number .
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
recognizes a number of environment variables that can be used to modify
|
|
||||||
its behaviour as follows:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width "LD_IGNORE_MISSING_OBJECTS"
|
|
||||||
.It Ev LD_LIBRARY_PATH
|
|
||||||
A colon separated list of directories, overriding the default search path
|
|
||||||
for shared libraries.
|
|
||||||
This is ignored for set-user-ID and set-group-ID programs.
|
|
||||||
.It Ev LD_PRELOAD
|
|
||||||
A colon separated list of shared libraries, to be linked in before any
|
|
||||||
other shared libraries.
|
|
||||||
If the directory is not specified then
|
|
||||||
the directories specified by LD_LIBRARY_PATH will be searched first
|
|
||||||
followed by the set of built-in standard directories.
|
|
||||||
This is ignored for set-user-ID and set-group-ID programs.
|
|
||||||
.It Ev LD_BIND_NOW
|
|
||||||
When set to a nonempty string, causes
|
|
||||||
.Nm
|
|
||||||
to relocate all external function calls before starting execution of the
|
|
||||||
program.
|
|
||||||
Normally, function calls are bound lazily, at the first call
|
|
||||||
of each function.
|
|
||||||
.Ev LD_BIND_NOW
|
|
||||||
increases the start-up time of a program, but it avoids run-time
|
|
||||||
surprises caused by unexpectedly undefined functions.
|
|
||||||
.It Ev LD_WARN_NON_PURE_CODE
|
|
||||||
When set to a nonempty string, issue a warning whenever a link-editing
|
|
||||||
operation requires modification of the text segment of some loaded
|
|
||||||
object.
|
|
||||||
This is usually indicative of an incorrectly built library.
|
|
||||||
.It Ev LD_SUPPRESS_WARNINGS
|
|
||||||
When set to a nonempty string, no warning messages of any kind are
|
|
||||||
issued.
|
|
||||||
Normally, a warning is given if satisfactorily versioned
|
|
||||||
library could not be found.
|
|
||||||
.It Ev LD_IGNORE_MISSING_OBJECTS
|
|
||||||
When set to a nonempty string, makes it a nonfatal condition if
|
|
||||||
one or more required shared objects cannot be loaded.
|
|
||||||
Loading and execution proceeds using the objects that are
|
|
||||||
available.
|
|
||||||
A warning is produced for each missing object, unless the environment
|
|
||||||
variable
|
|
||||||
.Ev LD_SUPPRESS_WARNINGS
|
|
||||||
is set to a nonempty string.
|
|
||||||
.Pp
|
|
||||||
This is ignored for set-user-ID and set-group-ID programs.
|
|
||||||
.Pp
|
|
||||||
Missing shared objects can be ignored without errors if all the
|
|
||||||
following conditions hold:
|
|
||||||
.Bl -bullet
|
|
||||||
.It
|
|
||||||
They do not supply definitions for any required data symbols.
|
|
||||||
.It
|
|
||||||
No functions defined by them are called during program execution.
|
|
||||||
.It
|
|
||||||
The environment variable
|
|
||||||
.Ev LD_BIND_NOW
|
|
||||||
is unset or is set to the empty string.
|
|
||||||
.El
|
|
||||||
.It Ev LD_TRACE_LOADED_OBJECTS
|
|
||||||
When set to a nonempty string, causes
|
|
||||||
.Nm
|
|
||||||
to exit after loading the shared objects and printing a summary which includes
|
|
||||||
the absolute pathnames of all objects, to standard output.
|
|
||||||
.It Ev LD_TRACE_LOADED_OBJECTS_FMT1
|
|
||||||
.It Ev LD_TRACE_LOADED_OBJECTS_FMT2
|
|
||||||
When set, these variables are interpreted as format strings a la
|
|
||||||
.Xr printf 3
|
|
||||||
to customize the trace output and are used by
|
|
||||||
.Xr ldd 1 Ns 's
|
|
||||||
.Fl f
|
|
||||||
option and allows
|
|
||||||
.Xr ldd 1
|
|
||||||
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
|
|
||||||
(also known as
|
|
||||||
.Dq __progname ) .
|
|
||||||
.It \&%A
|
|
||||||
The value of the environment variable
|
|
||||||
.Ev LD_TRACE_LOADED_OBJECTS_PROGNAME
|
|
||||||
.It \&%o
|
|
||||||
The library name.
|
|
||||||
.It \&%m
|
|
||||||
The library's major version number.
|
|
||||||
.It \&%n
|
|
||||||
The library's minor version number.
|
|
||||||
.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.
|
|
||||||
.\" .It Ev LD_NO_INTERN_SEARCH
|
|
||||||
.\" When set,
|
|
||||||
.\" .Nm
|
|
||||||
.\" does not process any internal search paths that were recorded in the
|
|
||||||
.\" executable.
|
|
||||||
.\" .It Ev LD_NOSTD_PATH
|
|
||||||
.\" When set, do not include a set of built-in standard directory paths for
|
|
||||||
.\" searching. This might be useful when running on a system with a completely
|
|
||||||
.\" non-standard file system layout.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
.Sh FILES
|
|
||||||
/var/run/ld.so.hints
|
|
||||||
.Pp
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr ld 1 ,
|
|
||||||
.Xr link 5 ,
|
|
||||||
.Xr ldconfig 8
|
|
||||||
.Sh HISTORY
|
|
||||||
The shared library model employed first appeared in SunOS 4.0.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,340 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.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 <sys/link_aout.h>
|
|
||||||
#include "shlib.h"
|
|
||||||
#include "support.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard directories to search for files specified by -l.
|
|
||||||
*/
|
|
||||||
#ifndef STANDARD_SEARCH_DIRS
|
|
||||||
#define STANDARD_SEARCH_DIRS "/usr/lib/aout"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Actual vector of library search directories,
|
|
||||||
* including `-L'ed and LD_LIBRARY_PATH spec'd ones.
|
|
||||||
*/
|
|
||||||
char **search_dirs;
|
|
||||||
int n_search_dirs;
|
|
||||||
|
|
||||||
char *standard_search_dirs[] = {
|
|
||||||
STANDARD_SEARCH_DIRS
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
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 search_dirs[0]);
|
|
||||||
search_dirs[n_search_dirs - 1] = strdup(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
add_search_path(path)
|
|
||||||
char *path;
|
|
||||||
{
|
|
||||||
register char *cp, *dup;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Add search directories from `path' */
|
|
||||||
path = dup = strdup(path);
|
|
||||||
while ((cp = strsep(&path, ":")) != NULL)
|
|
||||||
add_search_dir(cp);
|
|
||||||
free(dup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
std_search_path()
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
/* Append standard search directories */
|
|
||||||
n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
add_search_dir(standard_search_dirs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if CP points to a valid dewey number.
|
|
||||||
* Decode and leave the result in the array DEWEY.
|
|
||||||
* Return the number of decoded entries in DEWEY.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
getdewey(dewey, cp)
|
|
||||||
int dewey[];
|
|
||||||
char *cp;
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
for (n = 0, i = 0; i < MAXDEWEY; i++) {
|
|
||||||
if (*cp == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (*cp == '.') cp++;
|
|
||||||
if (!isdigit(*cp))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dewey[n++] = strtol(cp, &cp, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compare two dewey arrays.
|
|
||||||
* Return -1 if `d1' represents a smaller value than `d2'.
|
|
||||||
* Return 1 if `d1' represents a greater value than `d2'.
|
|
||||||
* Return 0 if equal.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
cmpndewey(d1, n1, d2, n2)
|
|
||||||
int d1[], d2[];
|
|
||||||
int n1, n2;
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n1 && i < n2; i++) {
|
|
||||||
if (d1[i] < d2[i])
|
|
||||||
return -1;
|
|
||||||
if (d1[i] > d2[i])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n1 == n2)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (i == n1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (i == n2)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
errx(1, "cmpndewey: cant happen");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search directories for a shared library matching the given
|
|
||||||
* major and minor version numbers. See search_lib_dir() below for
|
|
||||||
* the detailed matching rules.
|
|
||||||
*
|
|
||||||
* As soon as a directory with an acceptable match is found, the search
|
|
||||||
* terminates. Subsequent directories are not searched for a better
|
|
||||||
* match. This is in conformance with the SunOS searching rules. Also,
|
|
||||||
* it avoids a lot of directory searches that are virtually guaranteed to
|
|
||||||
* be fruitless.
|
|
||||||
*
|
|
||||||
* The return value is a full pathname to the matching library. The
|
|
||||||
* string is dynamically allocated. If no matching library is found, the
|
|
||||||
* function returns NULL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
findshlib(name, majorp, minorp, do_dot_a)
|
|
||||||
char *name;
|
|
||||||
int *majorp, *minorp;
|
|
||||||
int do_dot_a;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n_search_dirs; i++) {
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
path = search_lib_dir(search_dirs[i], name, majorp, minorp,
|
|
||||||
do_dot_a);
|
|
||||||
if(path != NULL)
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search library directories for a file with the given name. The
|
|
||||||
* return value is a full pathname to the matching file. The string
|
|
||||||
* is dynamically allocated. If no matching file is found, the function
|
|
||||||
* returns NULL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
find_lib_file(name)
|
|
||||||
const char *name;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n_search_dirs; i++) {
|
|
||||||
char *path = concat(search_dirs[i], "/", name);
|
|
||||||
struct stat sb;
|
|
||||||
|
|
||||||
if (lstat(path, &sb) != -1) /* We found it */
|
|
||||||
return path;
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search a given directory for a library (preferably shared) satisfying
|
|
||||||
* the given criteria.
|
|
||||||
*
|
|
||||||
* The matching rules are as follows:
|
|
||||||
*
|
|
||||||
* if(*majorp == -1)
|
|
||||||
* find the library with the highest major version;
|
|
||||||
* else
|
|
||||||
* insist on a major version identical to *majorp;
|
|
||||||
*
|
|
||||||
* Always find the library with the highest minor version;
|
|
||||||
* if(*minorp != -1)
|
|
||||||
* insist on a minor version >= *minorp;
|
|
||||||
*
|
|
||||||
* It is invalid to specify a specific minor number while wildcarding
|
|
||||||
* the major number.
|
|
||||||
*
|
|
||||||
* The actual major and minor numbers found are returned via the pointer
|
|
||||||
* arguments.
|
|
||||||
*
|
|
||||||
* A suitable shared library is always preferred over a static (.a) library.
|
|
||||||
* If do_dot_a is false, then a static library will not be accepted in
|
|
||||||
* any case.
|
|
||||||
*
|
|
||||||
* The return value is a full pathname to the matching library. The
|
|
||||||
* string is dynamically allocated. If no matching library is found, the
|
|
||||||
* function returns NULL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
search_lib_dir(dir, name, majorp, minorp, do_dot_a)
|
|
||||||
char *dir;
|
|
||||||
char *name;
|
|
||||||
int *majorp;
|
|
||||||
int *minorp;
|
|
||||||
int do_dot_a;
|
|
||||||
{
|
|
||||||
int namelen;
|
|
||||||
DIR *dd;
|
|
||||||
struct dirent *dp;
|
|
||||||
int best_dewey[MAXDEWEY];
|
|
||||||
int best_ndewey;
|
|
||||||
char dot_a_name[MAXNAMLEN+1];
|
|
||||||
char dot_so_name[MAXNAMLEN+1];
|
|
||||||
|
|
||||||
if((dd = opendir(dir)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
namelen = strlen(name);
|
|
||||||
best_ndewey = 0;
|
|
||||||
dot_a_name[0] = '\0';
|
|
||||||
dot_so_name[0] = '\0';
|
|
||||||
|
|
||||||
while((dp = readdir(dd)) != NULL) {
|
|
||||||
char *extension;
|
|
||||||
|
|
||||||
if(strlen(dp->d_name) < 3 + namelen + 2 || /* lib+xxx+.a */
|
|
||||||
strncmp(dp->d_name, "lib", 3) != 0 ||
|
|
||||||
strncmp(dp->d_name + 3, name, namelen) != 0 ||
|
|
||||||
dp->d_name[3+namelen] != '.')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
extension = dp->d_name + 3 + namelen + 1; /* a or so.* */
|
|
||||||
|
|
||||||
if(strncmp(extension, "so.", 3) == 0) {
|
|
||||||
int cur_dewey[MAXDEWEY];
|
|
||||||
int cur_ndewey;
|
|
||||||
|
|
||||||
cur_ndewey = getdewey(cur_dewey, extension+3);
|
|
||||||
if(cur_ndewey < 2) /* Too few version numbers */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(*majorp != -1) { /* Need exact match on major */
|
|
||||||
if(cur_dewey[0] != *majorp)
|
|
||||||
continue;
|
|
||||||
if(*minorp != -1) { /* Need minor >= minimum */
|
|
||||||
if(cur_dewey[1] < *minorp)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cmpndewey(cur_dewey, cur_ndewey, best_dewey,
|
|
||||||
best_ndewey) <= 0) /* No better than prior match */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* We found a better match */
|
|
||||||
strcpy(dot_so_name, dp->d_name);
|
|
||||||
bcopy(cur_dewey, best_dewey,
|
|
||||||
cur_ndewey * sizeof best_dewey[0]);
|
|
||||||
best_ndewey = cur_ndewey;
|
|
||||||
} else if(do_dot_a && strcmp(extension, "a") == 0)
|
|
||||||
strcpy(dot_a_name, dp->d_name);
|
|
||||||
}
|
|
||||||
closedir(dd);
|
|
||||||
|
|
||||||
if(dot_so_name[0] != '\0') {
|
|
||||||
*majorp = best_dewey[0];
|
|
||||||
*minorp = best_dewey[1];
|
|
||||||
return concat(dir, "/", dot_so_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dot_a_name[0] != '\0')
|
|
||||||
return concat(dir, "/", dot_a_name);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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.
|
|
||||||
*-
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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((const char *));
|
|
||||||
char *search_lib_dir __P((char *, char *, int *, int *, int));
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*-
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
#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 = xmalloc(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;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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.
|
|
||||||
*-
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 *));
|
|
Loading…
Reference in New Issue
Block a user