mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-05 18:05:16 +00:00
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…
x
Reference in New Issue
Block a user