Support for .weak (in addition to the N_INDR stab) for gcc/g++. Also deal

with the -R option and store the path in the dynamic header when specified.
The $LD_RUN_PATH environment variable is not checked yet.

While here, split up the code a bit more to enable more selective replacing
of GPL'ed components that are linked with ld.so with others.

Obtained from: NetBSD (mostly, the breakup is my fault)
This commit is contained in:
Peter Wemm 1996-10-01 01:22:51 +00:00
parent 9ee4f69e6f
commit d0a184df5d
22 changed files with 1523 additions and 590 deletions

View File

@ -1,8 +1,8 @@
# $Id: Makefile,v 1.16 1994/12/23 22:30:29 nate Exp $
# $Id: Makefile,v 1.17 1995/09/22 14:14:32 phk Exp $
#
PROG= ld
SRCS= ld.c symbol.c lib.c shlib.c warnings.c etc.c rrs.c xbits.c md.c
SRCS= ld.c symbol.c lib.c shlib.c warnings.c support.c rrs.c xbits.c md.c
CFLAGS += -I$(.CURDIR) -I$(.CURDIR)/$(MACHINE)
LDFLAGS+= -Xlinker -Bstatic

View File

@ -1,4 +1,4 @@
$Id$
$Id: PORTING,v 1.1 1994/12/23 22:56:08 nate Exp $
This document describes some of the machine dependent parts in ld(1) and rtld(?)
Most of the machine dependencies are a result of different ways in which
@ -90,6 +90,8 @@ RELOC_JMPTAB_P(r) - relocation is for a PLT entry
RELOC_BASEREL_P(r) - relocation is for a GOT entry
RELOC_RELATIVE_P(r) - relocation is load address relative
RELOC_COPY_P(r) - relocation involves an initialization
RELOC_INIT_SEGMENT_RELOC(r) - initialize a relocation record pertaining to
a segment; traditional archs can use bzero().
RELOC_LAZY_P(r) - (run-time) resolution can be lazy.
CHECK_GOT_RELOC(r) - consistency check on relocations involving
the "_GLOBAL_OFFSET_TABLE" symbol

377
gnu/usr.bin/ld/dynamic.h Normal file
View File

@ -0,0 +1,377 @@
/*
* Copyright (c) 1993 Paul Kranenburg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef __DYNAMIC_H__
#define __DYNAMIC_H__
#define SUN_COMPAT
#include "md.h"
#include "link.h"
#ifndef RELOC_JMPTAB_P
#define RELOC_JMPTAB_P(r) ((r)->r_jmptable)
#define RELOC_BASEREL_P(r) ((r)->r_baserel)
#define RELOC_RELATIVE_P(r) ((r)->r_relative)
#define RELOC_COPY_P(r) ((r)->r_copy)
#define RELOC_LAZY_P(r) ((r)->r_jmptable)
#define CHECK_GOT_RELOC(r) ((r)->r_pcrel)
#define RELOC_PIC_TYPE(r) ((r)->r_baserel? \
PIC_TYPE_LARGE:PIC_TYPE_NONE)
#endif
#ifndef RELOC_INIT_SEGMENT_RELOC
#define RELOC_INIT_SEGMENT_RELOC(r)
#endif
#ifndef MAX_GOTOFF
#define MAX_GOTOFF(x) (LONG_MAX)
#endif
#ifndef MIN_GOTOFF
#define MIN_GOTOFF(x) (LONG_MIN)
#endif
/*
* Internal representation of relocation types
*/
#define RELTYPE_EXTERN 1
#define RELTYPE_JMPSLOT 2
#define RELTYPE_BASEREL 4
#define RELTYPE_RELATIVE 8
#define RELTYPE_COPY 16
#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
typedef struct localsymbol {
struct nzlist nzlist; /* n[z]list from file */
struct glosym *symbol; /* Corresponding global symbol,
if any */
struct localsymbol *next; /* List of definitions */
struct file_entry *entry; /* Backpointer to file */
long gotslot_offset; /* Position in GOT, if any */
int symbolnum; /* Position in output nlist */
int flags;
#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */
#define LS_WRITE 2 /* Symbol goes in output symtable */
#define LS_RENAME 4 /* xlat name to `<file>.<name>' */
#define LS_HASGOTSLOT 8 /* This symbol has a GOT entry */
#define LS_WARNING 16 /* Second part of a N_WARNING duo */
} localsymbol_t;
/*
* Global symbol data is recorded in these structures, one for each global
* symbol. They are found via hashing in 'symtab', which points to a vector
* of buckets. Each bucket is a chain of these structures through the link
* field.
*
* Rewritten version to support extra info for dynamic linking.
*/
struct glosym {
struct glosym *link; /* Next symbol hash bucket. */
char *name; /* Name of this symbol. */
long value; /* Value of this symbol */
localsymbol_t *refs; /* Chain of local symbols from object
files pertaining to this global
symbol */
localsymbol_t *sorefs;/* Same for local symbols from shared
object files. */
char *warning; /* message, from N_WARNING nlists */
int common_size; /* Common size */
int symbolnum; /* Symbol index in output symbol table */
int rrs_symbolnum; /* Symbol index in RRS symbol table */
localsymbol_t *def_lsp; /* The local symbol that gave this
global symbol its definition */
char defined; /* Definition of this symbol */
char so_defined; /* Definition of this symbol in a shared
object. These go into the RRS symbol table */
u_char undef_refs; /* Count of number of "undefined"
messages printed for this symbol */
u_char mult_defs; /* Same for "multiply defined" symbols */
struct glosym *alias; /* For symbols of type N_INDR, this
points at the real symbol. */
int setv_count; /* Number of elements in N_SETV symbols */
int size; /* Size of this symbol (either from N_SIZE
symbols or a from shared object's RRS */
int aux; /* Auxiliary type information conveyed in
the `n_other' field of nlists */
/* The offset into one of the RRS tables, -1 if not used */
long jmpslot_offset;
long gotslot_offset;
long flags;
#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
#define GS_REFERENCED 0x2 /* Symbol is referred to by something
interesting */
#define GS_TRACE 0x4 /* Symbol will be traced */
#define GS_HASJMPSLOT 0x8 /* */
#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
#define GS_CPYRELOCCLAIMED 0x40 /* */
#define GS_WEAK 0x80 /* Symbol is weakly defined */
};
#ifndef __symbol_defined__
#define __symbol_defined__
typedef struct glosym symbol;
#endif
/* The symbol hash table: a vector of SYMTABSIZE pointers to struct glosym. */
extern symbol *symtab[];
#define FOR_EACH_SYMBOL(i,sp) { \
int i; \
for (i = 0; i < SYMTABSIZE; i++) { \
register symbol *sp; \
for (sp = symtab[i]; sp; sp = sp->link)
#define END_EACH_SYMBOL }}
extern symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
extern symbol *dynamic_symbol; /* the symbol __DYNAMIC */
/*
* Each input file, and each library member ("subfile") being loaded, has a
* `file_entry' structure for it.
*
* For files specified by command args, these are contained in the vector which
* `file_table' points to.
*
* For library members, they are dynamically allocated, and chained through the
* `chain' field. The chain is found in the `subfiles' field of the
* `file_entry'. The `file_entry' objects for the members have `superfile'
* fields pointing to the one for the library.
*
* Rewritten version to support extra info for dynamic linking.
*/
struct file_entry {
char *filename; /* Name of this file. */
/*
* Name to use for the symbol giving address of text start Usually
* the same as filename, but for a file spec'd with -l this is the -l
* switch itself rather than the filename.
*/
char *local_sym_name;
struct exec header; /* The file's a.out header. */
localsymbol_t *symbols; /* Symbol table of the file. */
int nsymbols; /* Number of symbols in above array. */
int string_size; /* Size in bytes of string table. */
char *strings; /* Pointer to the string table when
in core, NULL otherwise */
int strings_offset; /* Offset of string table,
(normally N_STROFF() + 4) */
/*
* Next two used only if `relocatable_output' or if needed for
* output of undefined reference line numbers.
*/
struct relocation_info *textrel; /* Text relocations */
int ntextrel; /* # of text relocations */
struct relocation_info *datarel; /* Data relocations */
int ndatarel; /* # of data relocations */
/*
* Relation of this file's segments to the output file.
*/
int text_start_address; /* Start of this file's text segment
in the output file core image. */
int data_start_address; /* Start of this file's data segment
in the output file core image. */
int bss_start_address; /* Start of this file's bss segment
in the output file core image. */
struct file_entry *subfiles; /* For a library, points to chain of
entries for the library members. */
struct file_entry *superfile; /* For library member, points to the
library's own entry. */
struct file_entry *chain; /* For library member, points to next
entry for next member. */
int starting_offset; /* For a library member, offset of the
member within the archive. Zero for
files that are not library members.*/
int total_size; /* Size of contents of this file,
if library member. */
#ifdef SUN_COMPAT
struct file_entry *silly_archive;/* For shared libraries which have
a .sa companion */
#endif
int lib_major, lib_minor; /* Version numbers of a shared object */
int flags;
#define E_IS_LIBRARY 1 /* File is a an archive */
#define E_HEADER_VALID 2 /* File's header has been read */
#define E_SEARCH_DIRS 4 /* Search directories for file */
#define E_SEARCH_DYNAMIC 8 /* Search for shared libs allowed */
#define E_JUST_SYMS 0x10 /* File is used for incremental load */
#define E_DYNAMIC 0x20 /* File is a shared object */
#define E_SCRAPPED 0x40 /* Ignore this file */
#define E_SYMBOLS_USED 0x80 /* Symbols from this entry were used */
#define E_SECONDCLASS 0x100 /* Shared object is a subsidiary */
};
/*
* Runtime Relocation Section (RRS).
* This describes the data structures that go into the output text and data
* segments to support the run-time linker. The RRS can be empty (plain old
* static linking), or can just exist of GOT and PLT entries (in case of
* statically linked PIC code).
*/
extern int rrs_section_type; /* What's in the RRS section */
#define RRS_NONE 0
#define RRS_PARTIAL 1
#define RRS_FULL 2
extern int rrs_text_size; /* Size of RRS text additions */
extern int rrs_text_start; /* Location of above */
extern int rrs_data_size; /* Size of RRS data additions */
extern int rrs_data_start; /* Location of above */
extern char *rrs_search_paths; /* `-L' RT paths */
/* Version number to put in __DYNAMIC (set by -V) */
extern int soversion;
#ifndef DEFAULT_SOVERSION
#define DEFAULT_SOVERSION LD_VERSION_BSD
#endif
extern int pc_relocation; /* Current PC reloc value */
extern int number_of_shobjs; /* # of shared objects linked in */
/* Current link mode */
extern int link_mode;
#define DYNAMIC 1 /* Consider shared libraries */
#define SYMBOLIC 2 /* Force symbolic resolution */
#define FORCEARCHIVE 4 /* Force inclusion of all members
of archives */
#define SHAREABLE 8 /* Build a shared object */
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
extern FILE *outstream; /* Output file. */
extern struct exec outheader; /* Output file header. */
extern int magic; /* Output file magic. */
extern int oldmagic;
extern int relocatable_output;
extern int pic_type;
#define PIC_TYPE_NONE 0
#define PIC_TYPE_SMALL 1
#define PIC_TYPE_LARGE 2
void read_header __P((int, struct file_entry *));
void read_entry_symbols __P((int, struct file_entry *));
void read_entry_strings __P((int, struct file_entry *));
void read_entry_relocation __P((int, struct file_entry *));
void enter_file_symbols __P((struct file_entry *));
void read_file_symbols __P((struct file_entry *));
int set_element_prefixed_p __P((char *));
int text_offset __P((struct file_entry *));
int file_open __P((struct file_entry *));
void each_file __P((void (*)(), void *));
void each_full_file __P((void (*)(), void *));
unsigned long check_each_file __P((unsigned long (*)(), void *));
void mywrite __P((void *, int, int, FILE *));
void padfile __P((int, FILE *));
/* In warnings.c: */
void perror_name __P((char *));
void perror_file __P((struct file_entry *));
void print_symbols __P((FILE *));
char *get_file_name __P((struct file_entry *));
void print_file_name __P((struct file_entry *, FILE *));
void prline_file_name __P((struct file_entry *, FILE *));
int do_warnings __P((FILE *));
/* In etc.c: */
#include "support.h"
/* In symbol.c: */
void symtab_init __P((int));
symbol *getsym __P((char *)), *getsym_soft __P((char *));
/* In lib.c: */
void search_library __P((int, struct file_entry *));
void read_shared_object __P((int, struct file_entry *));
int findlib __P((struct file_entry *));
/* In shlib.c: */
#include "shlib.h"
/* In rrs.c: */
void init_rrs __P((void));
int rrs_add_shobj __P((struct file_entry *));
void alloc_rrs_reloc __P((struct file_entry *, symbol *));
void alloc_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
void alloc_rrs_jmpslot __P((struct file_entry *, symbol *));
void alloc_rrs_gotslot __P((struct file_entry *, struct relocation_info *, localsymbol_t *));
void alloc_rrs_cpy_reloc __P((struct file_entry *, symbol *));
int claim_rrs_reloc __P((struct file_entry *, struct relocation_info *, symbol *, long *));
long claim_rrs_jmpslot __P((struct file_entry *, struct relocation_info *, symbol *, long));
long claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
long claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
void claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
void claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
void consider_rrs_section_lengths __P((void));
void relocate_rrs_addresses __P((void));
void write_rrs __P((void));
/* In <md>.c */
void md_init_header __P((struct exec *, int, int));
long md_get_addend __P((struct relocation_info *, unsigned char *));
void md_relocate __P((struct relocation_info *, long, unsigned char *, int));
void md_make_jmpslot __P((jmpslot_t *, long, long));
void md_fix_jmpslot __P((jmpslot_t *, long, u_long));
int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
void md_set_breakpoint __P((long, long *));
#ifdef NEED_SWAP
/* In xbits.c: */
void swap_longs __P((long *, int));
void swap_symbols __P((struct nlist *, int));
void swap_zsymbols __P((struct nzlist *, int));
void swap_ranlib_hdr __P((struct ranlib *, int));
void swap__dynamic __P((struct link_dynamic *));
void swap_section_dispatch_table __P((struct section_dispatch_table *));
void swap_so_debug __P((struct so_debug *));
void swapin_sod __P((struct sod *, int));
void swapout_sod __P((struct sod *, int));
void swapout_fshash __P((struct fshash *, int));
#endif
#endif /* __DYNAMIC_H__ */

View File

@ -1,66 +0,0 @@
/*
* $Id: etc.c,v 1.7 1994/02/13 20:41:05 jkh Exp $
*/
#include <err.h>
#include <stdlib.h>
#include <string.h>
/*
* Like malloc but get fatal error if memory is exhausted.
*/
void *
xmalloc(size)
size_t size;
{
register void *result = (void *)malloc(size);
if (!result)
errx(1, "virtual memory exhausted");
return result;
}
/*
* Like realloc but get fatal error if memory is exhausted.
*/
void *
xrealloc(ptr, size)
void *ptr;
size_t size;
{
register void *result;
if (ptr == NULL)
result = (void *)malloc(size);
else
result = (void *)realloc(ptr, size);
if (!result)
errx(1, "virtual memory exhausted");
return result;
}
/*
* Return a newly-allocated string whose contents concatenate
* the strings S1, S2, S3.
*/
char *
concat(s1, s2, s3)
const char *s1, *s2, *s3;
{
register int len1 = strlen(s1),
len2 = strlen(s2),
len3 = strlen(s3);
register char *result = (char *)xmalloc(len1 + len2 + len3 + 1);
strcpy(result, s1);
strcpy(result + len1, s2);
strcpy(result + len1 + len2, s3);
result[len1 + len2 + len3] = 0;
return result;
}

View File

@ -27,7 +27,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $Id: ld.1,v 1.10 1996/05/28 16:17:46 phk Exp $
.\" $Id: ld.1,v 1.11 1996/08/29 18:05:54 wosch Exp $
.\"
.Dd October 14, 1993
.Dt LD 1
@ -41,16 +41,17 @@
.Bk -words
.Op Fl A Ar symbol-file
.Op Fl assert Ar keyword
.Op Fl B Ar linkmode
.Op Fl B Ns Ar linkmode
.Op Fl D Ar datasize
.Op Fl d Ar c
.Op Fl d Ar p
.Op Fl e Ar entry
.Op Fl l Ar library-specifier
.Op Fl L Ar library-search-path
.Op Fl l Ns Ar library-specifier
.Op Fl L Ns Ar library-search-path
.Op Fl nostdlib
.Op Fl O Ar filename
.Op Fl o Ar filename
.Op Fl R Ns Ar record-library-search-path
.Op Fl T Ar address
.Op Fl u Ar symbol
.Op Fl V Ar shlib-version
@ -71,41 +72,49 @@ The options are as follows:
.It Fl A Ar symbol-file
The the symbol-file is taken as a base for link-editing the object files
on the command line.
.It Fl a\&ssert Ar keyword
.It Fl assert Ar keyword
This option has currently no effect. It is here for compatibility with
SunOS ld. All conditions which would cause a Sun assertion to fail will
currently always cause error or warning messages from
.Nm ld\&.
.It Fl B Ar dynamic
.Nm ld .
.It Fl B Ns Ar dynamic
Specifies that linking against dynamic libraries can take place. If a library
specifier of the form -lx appears on the command line,
.Nm ld
searches for a library of the from libx.so.n.m (see the
.Ar l
option) according to the search rules in effect. If such a file can not be
searches for a library of the from libx.so.n.m
.Po see the \&
.Fl l
option
.Pc
according to the search rules in effect. If such a file can not be
found a traditional archive is looked for.
This options can appear anywhere on the command line and is complementary
to -Bstatic.
.It Fl B Ar static
The counterpart of -Bdynamic. This option turns off dynamic linking for
all library specifiers until a -Bdynamic is once again given. Any explicitly
to
.Fl B Ns Ar static.
.It Fl B Ns Ar static
The counterpart of
.Fl B Ns Ar dynamic .
This option turns off dynamic linking for
all library specifiers until a
.Fl B Ns Ar dynamic
is once again given. Any explicitly
mentioned shared object encountered on the command line while this option is
in effect is flagged as an error.
.It Fl B Ar shareable
.It Fl B Ns Ar shareable
Instructs the linker to build a shared object from the object files rather
than a normal executable image.
.It Fl B Ar symbolic
.It Fl B Ns Ar symbolic
This option causes all symbolic references in the output to be resolved in
this link-edit session. The only remaining run-time relocation requirements are
.Em base-relative
relocations, ie. translation with respect to the load address. Failure to
resolve any symbolic reference causes an error to be reported.
.It Fl B Ar forcearchive
.It Fl B Ns Ar forcearchive
Force all members of archives to be loaded, whether or not such members
contribute a definition to any plain object files. Useful for making a
shared library from an archive of PIC objects without having to unpack
the archive.
.It Fl B Ar silly
.It Fl B Ns Ar silly
Search for
.Em \.sa
silly archive companions of shared objects. Useful for compatibility with
@ -122,30 +131,42 @@ calls will be re-directed through the Procedure Linkage Table (see
.Xr link 5)
.It Fl e Ar entry-symbol
Specifies the entry symbol for an executable.
.It Fl L Ar path
.It Fl L Ns Ar path
Add
.Ar path
to the list of directories to search for libraries specified with the
.Ar -l
option.
.It Fl l Ar lib-spec
.It Fl l Ns Ar lib-spec
This option specifies a library to be considered for inclusion in the
output. If the -Bdynamic option is in effect, a shared library of the
form lib<spec>.so.m.n (where
output. If the
.Fl B Ns Ar dynamic
option is in effect, a shared library of the
form lib<spec>.so.m.n
.Po where \&
.Em m
is the major, and
.Em n
is the minor version number, respectively) is searched for first. The
is the minor version number, respectively
.Pc is searched for first. The
library with the highest version found in the search path is selected.
If no shared library is found or the -Bstatic options is in effect,
an archive of the form lib<spec>.a is looked for in the library seach path.
If no shared library is found or the
.Fl B Ns Ar static
options is in effect, an archive of the form lib<spec>.a is looked for in
the library seach path.
.It Fl M
Produce output about the mapping of segments of the input files and the
values assigned to (global) symbols in the output file.
values assigned to
.Pq global
symbols in the output file.
.It Fl N
Produce a OMAGIC output file.
Produce a
.Dv OMAGIC
output file.
.It Fl n
Produce a NMAGIC output file.
Produce a
.Dv NMAGIC
output file.
.It Fl nostdlib
Do not search the built-in path
.Po
@ -153,7 +174,7 @@ usually
.Dq /usr/lib
.Pc
for
.Ar -l
.Fl l
specified libraries.
.It Fl O Ar filename
Specifies the name of the output file.
@ -165,10 +186,15 @@ and when output is complete renamed to
Specifies the name of the output file. Defaults to
.Dq a.out.
.It Fl Q
Produce a QMAGIC (FreeBSD/BSDi-i386) output file. This is the default.
Produce a
.Dv QMAGIC
(FreeBSD/BSDi-i386) output file. This is the default.
.It Fl r
Produce relocatable object file, suitable for another pass through
.Nm ld.
.It Fl R
Record the given path within the executable for run-time libary search.
This only applies to dynamically linked executables.
.It Fl S
Strip all debugger symbols from the output.
.It Fl s
@ -184,8 +210,9 @@ Force
to be marked as undefined. Useful to force loading of an archive member
in the absence of any other references to that member.
.It Fl V Ar version
Put the given version number into the output shared library (if one is
created). Useful to make shared libaries compatible with other operating
Put the given version number into the output shared library
.Pq if one is created .
Useful to make shared libaries compatible with other operating
systems. Eg. SunOS 4.x libraries use version number 3. Defaults to 8.
.It Fl X
Discard local symbols in the input files that start with the letter
@ -196,17 +223,37 @@ Discard all local symbols in the input files.
Trace the manipulations inflicted on
.Ar symbol
.It Fl Z
Make a 386BSD ZMAGIC output file.
Make a 386BSD
.Dv ZMAGIC
output file.
.It Fl z
Make a NetBSD ZMAGIC output file.
Make a NetBSD
.Dv ZMAGIC
output file.
.Sh ENVIRONMENT
.Nm
utilizes the following environment variables:
.Bl -tag -width "LD_LIBRARY_PATH"
.It Ev LD_LIBRARY_PATH
This colon-separated list of directories is inserted into the search
path for libraries following any directories specified via
.Fl L
options and preceding the built-in path.
.\" .It Ev LD_NOSTD_PATH
.\" When set, do not search the built-in path for libraries.
.\" This is an alternative to the
.\" .Fl nostdlib
.\" command-line flag.
.El
.Sh FILES
.Sh SEE ALSO
.Xr ldconfig 8 ,
.Xr link 5
.Xr link 5 ,
.Xr rtld 1
.Sh CAVEATS
An entry point must now explicitly be given if the output is intended to be
a normal executable program. This was not the case for the previous version of
.Nm ld\&.
.Nm ld .
.Sh BUGS
Shared objects are not properly checked for undefined symbols.
.Pp

View File

@ -27,7 +27,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $Id: ld.1,v 1.10 1996/05/28 16:17:46 phk Exp $
.\" $Id: ld.1,v 1.11 1996/08/29 18:05:54 wosch Exp $
.\"
.Dd October 14, 1993
.Dt LD 1
@ -41,16 +41,17 @@
.Bk -words
.Op Fl A Ar symbol-file
.Op Fl assert Ar keyword
.Op Fl B Ar linkmode
.Op Fl B Ns Ar linkmode
.Op Fl D Ar datasize
.Op Fl d Ar c
.Op Fl d Ar p
.Op Fl e Ar entry
.Op Fl l Ar library-specifier
.Op Fl L Ar library-search-path
.Op Fl l Ns Ar library-specifier
.Op Fl L Ns Ar library-search-path
.Op Fl nostdlib
.Op Fl O Ar filename
.Op Fl o Ar filename
.Op Fl R Ns Ar record-library-search-path
.Op Fl T Ar address
.Op Fl u Ar symbol
.Op Fl V Ar shlib-version
@ -71,41 +72,49 @@ The options are as follows:
.It Fl A Ar symbol-file
The the symbol-file is taken as a base for link-editing the object files
on the command line.
.It Fl a\&ssert Ar keyword
.It Fl assert Ar keyword
This option has currently no effect. It is here for compatibility with
SunOS ld. All conditions which would cause a Sun assertion to fail will
currently always cause error or warning messages from
.Nm ld\&.
.It Fl B Ar dynamic
.Nm ld .
.It Fl B Ns Ar dynamic
Specifies that linking against dynamic libraries can take place. If a library
specifier of the form -lx appears on the command line,
.Nm ld
searches for a library of the from libx.so.n.m (see the
.Ar l
option) according to the search rules in effect. If such a file can not be
searches for a library of the from libx.so.n.m
.Po see the \&
.Fl l
option
.Pc
according to the search rules in effect. If such a file can not be
found a traditional archive is looked for.
This options can appear anywhere on the command line and is complementary
to -Bstatic.
.It Fl B Ar static
The counterpart of -Bdynamic. This option turns off dynamic linking for
all library specifiers until a -Bdynamic is once again given. Any explicitly
to
.Fl B Ns Ar static.
.It Fl B Ns Ar static
The counterpart of
.Fl B Ns Ar dynamic .
This option turns off dynamic linking for
all library specifiers until a
.Fl B Ns Ar dynamic
is once again given. Any explicitly
mentioned shared object encountered on the command line while this option is
in effect is flagged as an error.
.It Fl B Ar shareable
.It Fl B Ns Ar shareable
Instructs the linker to build a shared object from the object files rather
than a normal executable image.
.It Fl B Ar symbolic
.It Fl B Ns Ar symbolic
This option causes all symbolic references in the output to be resolved in
this link-edit session. The only remaining run-time relocation requirements are
.Em base-relative
relocations, ie. translation with respect to the load address. Failure to
resolve any symbolic reference causes an error to be reported.
.It Fl B Ar forcearchive
.It Fl B Ns Ar forcearchive
Force all members of archives to be loaded, whether or not such members
contribute a definition to any plain object files. Useful for making a
shared library from an archive of PIC objects without having to unpack
the archive.
.It Fl B Ar silly
.It Fl B Ns Ar silly
Search for
.Em \.sa
silly archive companions of shared objects. Useful for compatibility with
@ -122,30 +131,42 @@ calls will be re-directed through the Procedure Linkage Table (see
.Xr link 5)
.It Fl e Ar entry-symbol
Specifies the entry symbol for an executable.
.It Fl L Ar path
.It Fl L Ns Ar path
Add
.Ar path
to the list of directories to search for libraries specified with the
.Ar -l
option.
.It Fl l Ar lib-spec
.It Fl l Ns Ar lib-spec
This option specifies a library to be considered for inclusion in the
output. If the -Bdynamic option is in effect, a shared library of the
form lib<spec>.so.m.n (where
output. If the
.Fl B Ns Ar dynamic
option is in effect, a shared library of the
form lib<spec>.so.m.n
.Po where \&
.Em m
is the major, and
.Em n
is the minor version number, respectively) is searched for first. The
is the minor version number, respectively
.Pc is searched for first. The
library with the highest version found in the search path is selected.
If no shared library is found or the -Bstatic options is in effect,
an archive of the form lib<spec>.a is looked for in the library seach path.
If no shared library is found or the
.Fl B Ns Ar static
options is in effect, an archive of the form lib<spec>.a is looked for in
the library seach path.
.It Fl M
Produce output about the mapping of segments of the input files and the
values assigned to (global) symbols in the output file.
values assigned to
.Pq global
symbols in the output file.
.It Fl N
Produce a OMAGIC output file.
Produce a
.Dv OMAGIC
output file.
.It Fl n
Produce a NMAGIC output file.
Produce a
.Dv NMAGIC
output file.
.It Fl nostdlib
Do not search the built-in path
.Po
@ -153,7 +174,7 @@ usually
.Dq /usr/lib
.Pc
for
.Ar -l
.Fl l
specified libraries.
.It Fl O Ar filename
Specifies the name of the output file.
@ -165,10 +186,15 @@ and when output is complete renamed to
Specifies the name of the output file. Defaults to
.Dq a.out.
.It Fl Q
Produce a QMAGIC (FreeBSD/BSDi-i386) output file. This is the default.
Produce a
.Dv QMAGIC
(FreeBSD/BSDi-i386) output file. This is the default.
.It Fl r
Produce relocatable object file, suitable for another pass through
.Nm ld.
.It Fl R
Record the given path within the executable for run-time libary search.
This only applies to dynamically linked executables.
.It Fl S
Strip all debugger symbols from the output.
.It Fl s
@ -184,8 +210,9 @@ Force
to be marked as undefined. Useful to force loading of an archive member
in the absence of any other references to that member.
.It Fl V Ar version
Put the given version number into the output shared library (if one is
created). Useful to make shared libaries compatible with other operating
Put the given version number into the output shared library
.Pq if one is created .
Useful to make shared libaries compatible with other operating
systems. Eg. SunOS 4.x libraries use version number 3. Defaults to 8.
.It Fl X
Discard local symbols in the input files that start with the letter
@ -196,17 +223,37 @@ Discard all local symbols in the input files.
Trace the manipulations inflicted on
.Ar symbol
.It Fl Z
Make a 386BSD ZMAGIC output file.
Make a 386BSD
.Dv ZMAGIC
output file.
.It Fl z
Make a NetBSD ZMAGIC output file.
Make a NetBSD
.Dv ZMAGIC
output file.
.Sh ENVIRONMENT
.Nm
utilizes the following environment variables:
.Bl -tag -width "LD_LIBRARY_PATH"
.It Ev LD_LIBRARY_PATH
This colon-separated list of directories is inserted into the search
path for libraries following any directories specified via
.Fl L
options and preceding the built-in path.
.\" .It Ev LD_NOSTD_PATH
.\" When set, do not search the built-in path for libraries.
.\" This is an alternative to the
.\" .Fl nostdlib
.\" command-line flag.
.El
.Sh FILES
.Sh SEE ALSO
.Xr ldconfig 8 ,
.Xr link 5
.Xr link 5 ,
.Xr rtld 1
.Sh CAVEATS
An entry point must now explicitly be given if the output is intended to be
a normal executable program. This was not the case for the previous version of
.Nm ld\&.
.Nm ld .
.Sh BUGS
Shared objects are not properly checked for undefined symbols.
.Pp

View File

@ -32,7 +32,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
Set, indirect, and warning symbol features added by Randy Smith. */
/*
* $Id: ld.c,v 1.34 1996/06/08 04:52:57 wpaul Exp $
* $Id: ld.c,v 1.35 1996/07/12 19:08:20 jkh Exp $
*/
/* Define how to initialize system-dependent header fields. */
@ -43,6 +43,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -55,6 +56,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
#include <string.h>
#include "ld.h"
#include "dynamic.h"
/* Vector of entries for input files specified by arguments.
These are all the input files except for members of specified libraries. */
@ -120,6 +122,7 @@ int set_sect_start; /* start of set element vectors */
int set_sect_size; /* size of above */
int link_mode; /* Current link mode */
int pic_type; /* PIC type */
/*
* When loading the text and data, we can avoid doing a close
@ -427,6 +430,7 @@ classify_arg(arg)
case 'l':
case 'O':
case 'o':
case 'R':
case 'u':
case 'V':
case 'y':
@ -726,6 +730,12 @@ decode_option(swt, arg)
text_start = 0;
return;
case 'R':
rrs_search_paths = (rrs_search_paths == NULL)
? strdup(arg)
: concat(rrs_search_paths, ":", arg);
return;
case 'S':
strip_symbols = STRIP_DEBUGGER;
return;
@ -1891,7 +1901,14 @@ digest_pass1()
}
}
if (sp->defined) {
/*
* If this symbol has acquired final definition, we're done.
* Commons must be allowed to bind to shared object data
* definitions.
*/
if (sp->defined &&
(sp->common_size == 0 ||
relocatable_output || building_shared_object)) {
if ((sp->defined & N_TYPE) == N_SETV)
/* Allocate zero entry in set vector */
setv_fill_count++;
@ -1924,7 +1941,7 @@ digest_pass1()
continue;
}
spsave=sp;
spsave=sp; /*XXX*/
again:
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
register struct nlist *p = &lsp->nzlist.nlist;
@ -1933,6 +1950,26 @@ digest_pass1()
if ((type & N_EXT) && type != (N_UNDF | N_EXT) &&
(type & N_TYPE) != N_FN) {
/* non-common definition */
if (sp->common_size) {
/*
* This common has an so defn; switch
* to it iff defn is: data, first-class
* and not weak.
*/
if (N_AUX(p) != AUX_OBJECT ||
N_ISWEAK(p) ||
(lsp->entry->flags & E_SECONDCLASS))
continue;
/*
* Change common to so ref. First,
* downgrade common to undefined.
*/
sp->common_size = 0;
sp->defined = 0;
common_defined_global_count--;
undefined_global_sym_count++;
}
sp->def_lsp = lsp;
sp->so_defined = type;
sp->aux = N_AUX(p);
@ -1952,9 +1989,9 @@ printf("pass1: SO definition for %s, type %x in %s at %#x\n",
sp->def_lsp->nzlist.nz_value);
#endif
sp->def_lsp->entry->flags |= E_SYMBOLS_USED;
if (sp->flags & GS_REFERENCED)
if (sp->flags & GS_REFERENCED) {
undefined_global_sym_count--;
else
} else
sp->flags |= GS_REFERENCED;
if (undefined_global_sym_count < 0)
errx(1, "internal error: digest_pass1,2: "
@ -1965,8 +2002,19 @@ printf("pass1: SO definition for %s, type %x in %s at %#x\n",
sp = sp->alias;
goto again;
}
} else if (sp->defined) {
if (sp->common_size == 0)
errx(1, "internal error: digest_pass1,3: "
"%s: not a common: %x",
sp->name, sp->defined);
/*
* Common not bound to shared object data; treat
* it now like other defined symbols were above.
*/
if (!sp->alias)
defined_global_sym_count++;
}
sp=spsave;
sp=spsave; /*XXX*/
} END_EACH_SYMBOL;
if (setv_fill_count != set_sect_size/sizeof(long))
@ -2053,6 +2101,11 @@ consider_relocation(entry, dataseg)
lsp = &entry->symbols[reloc->r_symbolnum];
alloc_rrs_gotslot(entry, reloc, lsp);
if (pic_type != PIC_TYPE_NONE &&
RELOC_PIC_TYPE(reloc) != pic_type)
errx(1, "%s: illegal reloc type mix",
get_file_name(entry));
pic_type = RELOC_PIC_TYPE(reloc);
} else if (RELOC_EXTERN_P(reloc)) {
@ -2222,7 +2275,7 @@ consider_file_section_lengths(entry)
entry->data_start_address = data_size;
data_size += entry->header.a_data;
entry->bss_start_address = bss_size;
bss_size += entry->header.a_bss;
bss_size += MALIGN(entry->header.a_bss);
text_reloc_size += entry->header.a_trsize;
data_reloc_size += entry->header.a_drsize;
@ -2583,7 +2636,7 @@ write_header()
}
md_swapout_exec_hdr(&outheader);
mywrite(&outheader, sizeof (struct exec), 1, outstream);
mywrite(&outheader, 1, sizeof (struct exec), outstream);
md_swapin_exec_hdr(&outheader);
/*
@ -2651,7 +2704,7 @@ copy_text(entry)
entry->textrel, entry->ntextrel, entry, 0);
/* Write the relocated text to the output file. */
mywrite(bytes, 1, entry->header.a_text, outstream);
mywrite(bytes, entry->header.a_text, 1, outstream);
}
/*
@ -2722,7 +2775,7 @@ copy_data(entry)
perform_relocation(bytes, entry->header.a_data,
entry->datarel, entry->ndatarel, entry, 1);
mywrite(bytes, 1, entry->header.a_data, outstream);
mywrite(bytes, entry->header.a_data, 1, outstream);
}
/*
@ -2733,7 +2786,6 @@ copy_data(entry)
* relocation info, in core. NRELOC says how many there are.
*/
/* HACK: md.c may need access to this */
int pc_relocation;
void
@ -2753,9 +2805,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
int data_relocation = entry->data_start_address - entry->header.a_text;
int bss_relocation = entry->bss_start_address -
entry->header.a_text - entry->header.a_data;
pc_relocation = dataseg?
entry->data_start_address - entry->header.a_text:
entry->text_start_address;
pc_relocation = dataseg
? entry->data_start_address - entry->header.a_text
: entry->text_start_address;
for (; r < end; r++) {
int addr = RELOC_ADDRESS(r);
@ -3119,18 +3171,6 @@ coptxtrel(entry)
RELOC_SYMBOL(r) = (sp->defined & N_TYPE);
} else
RELOC_SYMBOL(r) = sp->symbolnum;
#ifdef RELOC_ADD_EXTRA
/*
* If we aren't going to be adding in the
* value in memory on the next pass of the
* loader, then we need to add it in from the
* relocation entry, unless the symbol remains
* external in our output. Otherwise the work we
* did in this pass is lost.
*/
if (!RELOC_MEMORY_ADD_P(r) && !RELOC_EXTERN_P(r))
RELOC_ADD_EXTRA(r) += sp->value;
#endif
} else
/*
* Global symbols come first.
@ -3269,7 +3309,7 @@ write_string_table()
err(1, "write_string_table: %s: fseek", output_filename);
for (i = 0; i < strtab_index; i++) {
mywrite(strtab_vector[i], 1, strtab_lens[i], outstream);
mywrite(strtab_vector[i], strtab_lens[i], 1, outstream);
strtab_len += strtab_lens[i];
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: ld.h,v 1.15 1996/01/13 00:14:52 jdp Exp $
* $Id: ld.h,v 1.16 1996/04/20 18:27:55 jdp Exp $
*/
/*-
* This code is derived from software copyrighted by the Free Software
@ -143,35 +143,8 @@ extern int netzmagic;
#define RELOC_TARGET_BITPOS(r) 0
#define RELOC_TARGET_BITSIZE(r) 32
#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_INIT_SEGMENT_RELOC(r)
#endif
#ifndef MAX_GOTOFF
#define MAX_GOTOFF (LONG_MAX)
#endif
#ifndef MIN_GOTOFF
#define MIN_GOTOFF (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
#ifdef nounderscore
#define LPREFIX '.'
#else
@ -332,97 +305,10 @@ extern int netzmagic;
#endif
#endif /* not __GNU_STAB__ */
#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;
/* Symbol table */
/*
* 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.
*/
typedef 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 */
} symbol;
/* Number of buckets in symbol hash table */
#define SYMTABSIZE 1009
/* 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 }}
/* # of global symbols referenced and not defined. */
extern int undefined_global_sym_count;
@ -455,88 +341,16 @@ struct string_list_element {
struct string_list_element *next;
};
struct glosym;
#ifndef __symbol_defined__
#define __symbol_defined__
typedef struct glosym symbol;
#endif
extern symbol *entry_symbol; /* the entry symbol, if any */
extern symbol *edata_symbol; /* the symbol _edata */
extern symbol *etext_symbol; /* the symbol _etext */
extern symbol *end_symbol; /* the symbol _end */
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.
*/
struct file_entry {
char *filename; /* Name of this file. */
/*
* Name to use for the symbol giving address of text start Usually
* the same as filename, but for a file spec'd with -l this is the -l
* switch itself rather than the filename.
*/
char *local_sym_name;
struct exec header; /* The file's a.out header. */
localsymbol_t *symbols; /* Symbol table of the file. */
int nsymbols; /* Number of symbols in above array. */
int string_size; /* Size in bytes of string table. */
char *strings; /* Pointer to the string table when
in core, NULL otherwise */
int strings_offset; /* Offset of string table,
(normally N_STROFF() + 4) */
/*
* Next two used only if `relocatable_output' or if needed for
* output of undefined reference line numbers.
*/
struct relocation_info *textrel; /* Text relocations */
int ntextrel; /* # of text relocations */
struct relocation_info *datarel; /* Data relocations */
int ndatarel; /* # of data relocations */
/*
* Relation of this file's segments to the output file.
*/
int text_start_address; /* Start of this file's text segment
in the output file core image. */
int data_start_address; /* Start of this file's data segment
in the output file core image. */
int bss_start_address; /* Start of this file's bss segment
in the output file core image. */
struct file_entry *subfiles; /* For a library, points to chain of
entries for the library members. */
struct file_entry *superfile; /* For library member, points to the
library's own entry. */
struct file_entry *chain; /* For library member, points to next
entry for next member. */
int starting_offset; /* For a library member, offset of the
member within the archive. Zero for
files that are not library members.*/
int total_size; /* Size of contents of this file,
if library member. */
#ifdef SUN_COMPAT
struct file_entry *silly_archive;/* For shared libraries which have
a .sa companion */
#endif
int lib_major, lib_minor; /* Version numbers of a shared object */
int flags;
#define E_IS_LIBRARY 1 /* File is a an archive */
#define E_HEADER_VALID 2 /* File's header has been read */
#define E_SEARCH_DIRS 4 /* Search directories for file */
#define E_SEARCH_DYNAMIC 8 /* Search for shared libs allowed */
#define E_JUST_SYMS 0x10 /* File is used for incremental load */
#define E_DYNAMIC 0x20 /* File is a shared object */
#define E_SCRAPPED 0x40 /* Ignore this file */
#define E_SYMBOLS_USED 0x80 /* Symbols from this entry were used */
#define E_SECONDCLASS 0x100 /* Shared object is a subsidiary */
};
/*
* Section start addresses.
@ -554,45 +368,7 @@ extern int bss_start; /* start of bss */
extern int text_reloc_size; /* total size of text relocation. */
extern int data_reloc_size; /* total size of data relocation. */
/*
* 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 */
/* Version number to put in __DYNAMIC (set by -V) */
extern int soversion;
#ifndef DEFAULT_SOVERSION
#define DEFAULT_SOVERSION LD_VERSION_BSD
#endif
extern int pc_relocation; /* Current PC reloc value */
extern int number_of_shobjs; /* # of shared objects linked in */
/* Current link mode */
extern int link_mode;
#define DYNAMIC 1 /* Consider shared libraries */
#define SYMBOLIC 2 /* Force symbolic resolution */
#define FORCEARCHIVE 4 /* Force inclusion of all members
of archives */
#define SHAREABLE 8 /* Build a shared object */
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
extern FILE *outstream; /* Output file. */
extern struct exec outheader; /* Output file header. */
extern int magic; /* Output file magic. */
extern int oldmagic;
extern int relocatable_output;
/* Size of a page. */
@ -603,101 +379,4 @@ extern int n_search_dirs; /* Length of above. */
extern int write_map; /* write a load map (`-M') */
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: */
void *xmalloc __P((size_t));
void *xrealloc __P((void *, size_t));
char *concat __P((const char *, const char *, const char *));
/* 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: */
char *findshlib __P((char *, int *, int *, int));
char *find_lib_file __P((char *));
char *search_lib_dir __P((char *, char *, int *, int *, int));
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));
/* 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
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));
/* 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
#include "dynamic.h"

View File

@ -1,5 +1,36 @@
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
*
* Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
*
* Modified 1993 by Paul Kranenburg, Erasmus University
*/
/* Derived from ld.c: "@(#)ld.c 6.10 (Berkeley) 5/22/91"; */
/* Linker `ld' for GNU
Copyright (C) 1988 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Richard Stallman with some help from Eric Albert.
Set, indirect, and warning symbol features added by Randy Smith. */
/*
* $Id: lib.c,v 1.16 1995/09/28 19:43:22 bde Exp $ - library routines
* $Id: lib.c,v 1.17 1996/07/12 19:08:23 jkh Exp $ - library routines
*/
#include <sys/param.h>
@ -21,6 +52,7 @@
#include <ctype.h>
#include "ld.h"
#include "dynamic.h"
static void linear_library __P((int, struct file_entry *));
static void symdef_library __P((int, struct file_entry *, int));
@ -515,26 +547,12 @@ subfile_wanted_p(entry)
fprintf(stdout, " needed due to %s\n", sp->name);
}
return 1;
} else {
} else if (!sp->defined && sp->sorefs) {
/*
* Check for undefined symbols or commons
* in shared objects.
*/
struct localsymbol *lsp;
int wascommon = sp->defined && sp->common_size;
int iscommon = type == (N_UNDF|N_EXT) && p->n_value;
if (wascommon) {
/*
* sp was defined as common by shared object.
*/
if (iscommon && p->n_value < sp->common_size)
sp->common_size = p->n_value;
continue;
}
if (sp->sorefs == NULL)
continue;
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
int type = lsp->nzlist.nlist.n_type;
@ -543,28 +561,22 @@ subfile_wanted_p(entry)
type != (N_UNDF | N_EXT))
break; /* We don't need it */
}
if (lsp != NULL) {
/* There's a real definition */
if (iscommon)
/*
* But this member wants it to be
* a common; ignore it.
*/
continue;
if (N_ISWEAK(&lsp->nzlist.nlist))
/* Weak symbols don't pull archive members */
continue;
}
if (lsp != NULL)
/*
* We have a worthy definition in a shared
* object that was specified ahead of the
* archive we're examining now. So, punt.
*/
continue;
/*
* At this point, either the new symbol is a common
* and the shared object reference is undefined --
* in which case we note the common -- or the shared
* object reference has a definition -- in which case
* the library member takes precedence.
* At this point, we have an undefined shared
* object reference. Again, if the archive member
* defines a common we just note the its size.
* Otherwise, the member gets included.
*/
if (iscommon) {
if (type == (N_UNDF|N_EXT) && p->n_value) {
/*
* New symbol is common, just takes its
* size, but don't load.

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: rrs.c,v 1.15 1996/05/27 18:06:02 jdp Exp $
* $Id: rrs.c,v 1.16 1996/07/12 19:08:27 jkh Exp $
*/
#include <sys/param.h>
@ -36,6 +36,7 @@
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -48,6 +49,7 @@
#include <string.h>
#include "ld.h"
#include "dynamic.h"
static struct _dynamic rrs_dyn; /* defined in link.h */
static struct so_debug rrs_so_debug; /* defined in link.h */
@ -59,6 +61,8 @@ static struct nzlist *rrs_symbols; /* RRS symbol table */
static char *rrs_strtab; /* RRS strings */
static struct rrs_hash *rrs_hashtab; /* RT hash table */
static struct shobj *rrs_shobjs;
char *rrs_search_paths; /* `-L' RT search */
static int rrs_search_paths_size;
static int reserved_rrs_relocs;
static int claimed_rrs_relocs;
@ -73,7 +77,10 @@ static int rrs_symbol_size;
static int current_jmpslot_offset;
static int current_got_offset;
static int max_got_offset;
static int min_got_offset;
static int got_origin;
static int current_reloc_offset;
static int current_hash_index;
int number_of_shobjs;
@ -428,7 +435,7 @@ claim_rrs_gotslot(entry, rp, lsp, addend)
/* GOT offset 0 is reserved */
current_got_offset += sizeof(got_t);
if (current_got_offset > MAX_GOTOFF)
if (current_got_offset > max_got_offset)
errx(1, "%s: GOT overflow on symbol `%s' at %#x",
get_file_name(entry), sp->name, RELOC_ADDRESS(rp));
@ -535,7 +542,7 @@ claim_rrs_internal_gotslot(entry, rp, lsp, addend)
/* GOT offset 0 is reserved */
current_got_offset += sizeof(got_t);
if (current_got_offset > MAX_GOTOFF)
if (current_got_offset > max_got_offset)
errx(1, "%s: GOT overflow for relocation at %#x",
get_file_name(entry), RELOC_ADDRESS(rp));
@ -816,6 +823,11 @@ consider_rrs_section_lengths()
rrs_text_size = reserved_rrs_relocs * sizeof(struct relocation_info);
rrs_text_size += number_of_rrs_hash_entries * sizeof(struct rrs_hash);
rrs_text_size += number_of_rrs_symbols * rrs_symbol_size;
rrs_search_paths_size = rrs_search_paths
? strlen(rrs_search_paths) + 1
: 0;
rrs_search_paths_size = MALIGN(rrs_search_paths_size);
rrs_text_size += rrs_search_paths_size;
/* Align strings size */
rrs_strtab_size = MALIGN(rrs_strtab_size);
@ -839,6 +851,7 @@ consider_rrs_section_lengths()
void
relocate_rrs_addresses()
{
int gotsize;
dynamic_symbol->value = 0;
@ -849,16 +862,16 @@ relocate_rrs_addresses()
*/
current_jmpslot_offset = sizeof(jmpslot_t);
current_got_offset = 0;
max_got_offset = MAX_GOTOFF(pic_type);
min_got_offset = MIN_GOTOFF(pic_type);
gotsize = number_of_gotslots * sizeof(got_t);
if (1 /* Not "-fPIC" seen */) {
int gotsize = number_of_gotslots * sizeof(got_t);
if (gotsize + min_got_offset - (int)sizeof(got_t) > max_got_offset)
warnx("Global Offset Table overflow (use `-fPIC')");
if (gotsize + MIN_GOTOFF - (int)sizeof(got_t) > MAX_GOTOFF)
warnx("Global Offset Table overflow");
if (gotsize > MAX_GOTOFF)
/* Position at "two-complements" origin */
current_got_offset += MIN_GOTOFF;
}
if (gotsize > max_got_offset)
/* Position at "two-complements" origin */
current_got_offset += min_got_offset;
got_origin = -current_got_offset;
@ -905,14 +918,18 @@ relocate_rrs_addresses()
number_of_rrs_hash_entries * sizeof(struct rrs_hash);
rrs_sdt.sdt_strings = rrs_sdt.sdt_nzlist +
number_of_rrs_symbols * rrs_symbol_size;
rrs_sdt.sdt_paths = rrs_search_paths
? rrs_sdt.sdt_strings + rrs_strtab_size
: 0;
rrs_sdt.sdt_sods = rrs_shobjs
? rrs_sdt.sdt_strings + rrs_strtab_size +
rrs_search_paths_size
: 0;
rrs_sdt.sdt_filler2 = 0;
rrs_sdt.sdt_str_sz = rrs_strtab_size;
rrs_sdt.sdt_text_sz = text_size;
rrs_sdt.sdt_plt_sz = number_of_jmpslots * sizeof(jmpslot_t);
rrs_sdt.sdt_sods = rrs_shobjs ? rrs_sdt.sdt_strings+rrs_strtab_size : 0;
rrs_sdt.sdt_filler1 = 0;
rrs_sdt.sdt_filler2 = 0;
/*
* Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC.
* The value `&__DYNAMIC' is in the GOT table at offset 0.
@ -1163,6 +1180,9 @@ write_rrs_text()
/* Write the strings */
mywrite(rrs_strtab, rrs_strtab_size, 1, outstream);
/* Write RT search path */
mywrite(rrs_search_paths, rrs_search_paths_size, 1, outstream);
/*
* Write the names of the shared objects needed at run-time
*/

View File

@ -27,28 +27,26 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: shlib.c,v 1.14 1996/01/13 00:14:53 jdp Exp $
* $Id: shlib.c,v 1.15 1996/04/20 18:27:56 jdp Exp $
*/
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <err.h>
#include <fcntl.h>
#include <string.h>
#include <a.out.h>
#include <ctype.h>
#include <dirent.h>
#include <a.out.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ld.h"
#ifdef SUNOS4
char *strsep();
#endif
#include <link.h>
#include "shlib.h"
#include "support.h"
/*
* Standard directories to search for files specified by -l.
@ -59,7 +57,7 @@ char *strsep();
/*
* Actual vector of library search directories,
* including `-L'ed and LD_LIBARAY_PATH spec'd ones.
* including `-L'ed and LD_LIBRARY_PATH spec'd ones.
*/
char **search_dirs;
int n_search_dirs;
@ -73,9 +71,14 @@ void
add_search_dir(name)
char *name;
{
int n;
for (n = 0; n < n_search_dirs; n++)
if (strcmp(search_dirs[n], name) == 0)
return;
n_search_dirs++;
search_dirs = (char **)
xrealloc(search_dirs, n_search_dirs * sizeof(char *));
xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]);
search_dirs[n_search_dirs - 1] = strdup(name);
}
@ -83,17 +86,16 @@ void
add_search_path(path)
char *path;
{
register char *cp;
register char *cp, *dup;
if (path == NULL)
return;
/* Add search directories from `paths' */
while ((cp = strsep(&path, ":")) != NULL) {
/* Add search directories from `path' */
path = dup = strdup(path);
while ((cp = strsep(&path, ":")) != NULL)
add_search_dir(cp);
if (path)
*(path-1) = ':';
}
free(dup);
}
void

43
gnu/usr.bin/ld/shlib.h Normal file
View File

@ -0,0 +1,43 @@
/*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
/*
* prototypes for shlib.c. Big deal.
*/
extern char **search_dirs;
extern int n_search_dirs;
void add_search_dir __P((char *));
void add_search_path __P((char *));
void std_search_path __P((void));
int getdewey __P((int[], char *));
int cmpndewey __P((int[], int, int[], int));
char *findshlib __P((char *, int *, int *, int));
char *find_lib_file __P((char *));
char *search_lib_dir __P((char *, char *, int *, int *, int));

86
gnu/usr.bin/ld/support.c Normal file
View File

@ -0,0 +1,86 @@
/*
* Generic "support" routines to replace those obtained from libiberty for ld.
*
* I've collected these from random bits of (published) code I've written
* over the years, not that they are a big deal. peter@freebsd.org
*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include "support.h"
char *
concat(s1, s2, s3)
const char *s1, *s2, *s3;
{
int len = 1;
char *s;
if (s1)
len += strlen(s1);
if (s2)
len += strlen(s2);
if (s3)
len += strlen(s3);
s = malloc(len);
s[0] = '\0';
if (s1)
strcat(s, s1);
if (s2)
strcat(s, s2);
if (s3)
strcat(s, s3);
return s;
}
void *
xmalloc(n)
size_t n;
{
char *p = malloc(n);
if (p == NULL)
errx(1, "Could not allocate memory");
return p;
}
void *
xrealloc(p, n)
void *p;
size_t n;
{
p = realloc(p, n);
if (p == NULL)
errx(1, "Could not allocate memory");
return p;
}

35
gnu/usr.bin/ld/support.h Normal file
View File

@ -0,0 +1,35 @@
/*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
/*
* prototypes for support.c. Big deal.
*/
void *xmalloc __P((size_t));
void *xrealloc __P((void *, size_t));
char *concat __P((const char *, const char *, const char *));

View File

@ -1,5 +1,37 @@
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
*
* Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
*
* Modified 1993 by Paul Kranenburg, Erasmus University
*/
/* Derived from ld.c: "@(#)ld.c 6.10 (Berkeley) 5/22/91"; */
/* Linker `ld' for GNU
Copyright (C) 1988 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Richard Stallman with some help from Eric Albert.
Set, indirect, and warning symbol features added by Randy Smith. */
/*
* $Id: symbol.c,v 1.5 1994/06/15 22:39:56 rich Exp $ - symbol table routines
* symbol table routines
* $Id: symbol.c,v 1.6 1994/12/23 22:30:54 nate Exp $
*/
/* Create the symbol table entries for `etext', `edata' and `end'. */
@ -14,6 +46,7 @@
#include <string.h>
#include "ld.h"
#include "dynamic.h"
symbol *symtab[SYMTABSIZE]; /* The symbol table. */
int num_hash_tab_syms; /* Number of symbols in symbol hash table. */

View File

@ -1,5 +1,36 @@
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
*
* Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
*
* Modified 1993 by Paul Kranenburg, Erasmus University
*/
/* Derived from ld.c: "@(#)ld.c 6.10 (Berkeley) 5/22/91"; */
/* Linker `ld' for GNU
Copyright (C) 1988 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Richard Stallman with some help from Eric Albert.
Set, indirect, and warning symbol features added by Randy Smith. */
/*
* $Id: warnings.c,v 1.10 1995/03/04 17:46:10 nate Exp $
* $Id: warnings.c,v 1.11 1996/07/12 19:08:29 jkh Exp $
*/
#include <sys/param.h>
@ -24,6 +55,7 @@
#endif
#include "ld.h"
#include "dynamic.h"
static int reported_undefineds;

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: xbits.c,v 1.2 1993/11/09 04:19:08 paul Exp $
* $Id: xbits.c,v 1.3 1994/02/13 20:41:50 jkh Exp $
*/
/*
@ -48,6 +48,7 @@
#include <string.h>
#include "ld.h"
#include "dynamic.h"
void
swap_longs(lp, n)

377
libexec/rtld-aout/dynamic.h Normal file
View File

@ -0,0 +1,377 @@
/*
* Copyright (c) 1993 Paul Kranenburg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef __DYNAMIC_H__
#define __DYNAMIC_H__
#define SUN_COMPAT
#include "md.h"
#include "link.h"
#ifndef RELOC_JMPTAB_P
#define RELOC_JMPTAB_P(r) ((r)->r_jmptable)
#define RELOC_BASEREL_P(r) ((r)->r_baserel)
#define RELOC_RELATIVE_P(r) ((r)->r_relative)
#define RELOC_COPY_P(r) ((r)->r_copy)
#define RELOC_LAZY_P(r) ((r)->r_jmptable)
#define CHECK_GOT_RELOC(r) ((r)->r_pcrel)
#define RELOC_PIC_TYPE(r) ((r)->r_baserel? \
PIC_TYPE_LARGE:PIC_TYPE_NONE)
#endif
#ifndef RELOC_INIT_SEGMENT_RELOC
#define RELOC_INIT_SEGMENT_RELOC(r)
#endif
#ifndef MAX_GOTOFF
#define MAX_GOTOFF(x) (LONG_MAX)
#endif
#ifndef MIN_GOTOFF
#define MIN_GOTOFF(x) (LONG_MIN)
#endif
/*
* Internal representation of relocation types
*/
#define RELTYPE_EXTERN 1
#define RELTYPE_JMPSLOT 2
#define RELTYPE_BASEREL 4
#define RELTYPE_RELATIVE 8
#define RELTYPE_COPY 16
#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
typedef struct localsymbol {
struct nzlist nzlist; /* n[z]list from file */
struct glosym *symbol; /* Corresponding global symbol,
if any */
struct localsymbol *next; /* List of definitions */
struct file_entry *entry; /* Backpointer to file */
long gotslot_offset; /* Position in GOT, if any */
int symbolnum; /* Position in output nlist */
int flags;
#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */
#define LS_WRITE 2 /* Symbol goes in output symtable */
#define LS_RENAME 4 /* xlat name to `<file>.<name>' */
#define LS_HASGOTSLOT 8 /* This symbol has a GOT entry */
#define LS_WARNING 16 /* Second part of a N_WARNING duo */
} localsymbol_t;
/*
* Global symbol data is recorded in these structures, one for each global
* symbol. They are found via hashing in 'symtab', which points to a vector
* of buckets. Each bucket is a chain of these structures through the link
* field.
*
* Rewritten version to support extra info for dynamic linking.
*/
struct glosym {
struct glosym *link; /* Next symbol hash bucket. */
char *name; /* Name of this symbol. */
long value; /* Value of this symbol */
localsymbol_t *refs; /* Chain of local symbols from object
files pertaining to this global
symbol */
localsymbol_t *sorefs;/* Same for local symbols from shared
object files. */
char *warning; /* message, from N_WARNING nlists */
int common_size; /* Common size */
int symbolnum; /* Symbol index in output symbol table */
int rrs_symbolnum; /* Symbol index in RRS symbol table */
localsymbol_t *def_lsp; /* The local symbol that gave this
global symbol its definition */
char defined; /* Definition of this symbol */
char so_defined; /* Definition of this symbol in a shared
object. These go into the RRS symbol table */
u_char undef_refs; /* Count of number of "undefined"
messages printed for this symbol */
u_char mult_defs; /* Same for "multiply defined" symbols */
struct glosym *alias; /* For symbols of type N_INDR, this
points at the real symbol. */
int setv_count; /* Number of elements in N_SETV symbols */
int size; /* Size of this symbol (either from N_SIZE
symbols or a from shared object's RRS */
int aux; /* Auxiliary type information conveyed in
the `n_other' field of nlists */
/* The offset into one of the RRS tables, -1 if not used */
long jmpslot_offset;
long gotslot_offset;
long flags;
#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
#define GS_REFERENCED 0x2 /* Symbol is referred to by something
interesting */
#define GS_TRACE 0x4 /* Symbol will be traced */
#define GS_HASJMPSLOT 0x8 /* */
#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
#define GS_CPYRELOCCLAIMED 0x40 /* */
#define GS_WEAK 0x80 /* Symbol is weakly defined */
};
#ifndef __symbol_defined__
#define __symbol_defined__
typedef struct glosym symbol;
#endif
/* The symbol hash table: a vector of SYMTABSIZE pointers to struct glosym. */
extern symbol *symtab[];
#define FOR_EACH_SYMBOL(i,sp) { \
int i; \
for (i = 0; i < SYMTABSIZE; i++) { \
register symbol *sp; \
for (sp = symtab[i]; sp; sp = sp->link)
#define END_EACH_SYMBOL }}
extern symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
extern symbol *dynamic_symbol; /* the symbol __DYNAMIC */
/*
* Each input file, and each library member ("subfile") being loaded, has a
* `file_entry' structure for it.
*
* For files specified by command args, these are contained in the vector which
* `file_table' points to.
*
* For library members, they are dynamically allocated, and chained through the
* `chain' field. The chain is found in the `subfiles' field of the
* `file_entry'. The `file_entry' objects for the members have `superfile'
* fields pointing to the one for the library.
*
* Rewritten version to support extra info for dynamic linking.
*/
struct file_entry {
char *filename; /* Name of this file. */
/*
* Name to use for the symbol giving address of text start Usually
* the same as filename, but for a file spec'd with -l this is the -l
* switch itself rather than the filename.
*/
char *local_sym_name;
struct exec header; /* The file's a.out header. */
localsymbol_t *symbols; /* Symbol table of the file. */
int nsymbols; /* Number of symbols in above array. */
int string_size; /* Size in bytes of string table. */
char *strings; /* Pointer to the string table when
in core, NULL otherwise */
int strings_offset; /* Offset of string table,
(normally N_STROFF() + 4) */
/*
* Next two used only if `relocatable_output' or if needed for
* output of undefined reference line numbers.
*/
struct relocation_info *textrel; /* Text relocations */
int ntextrel; /* # of text relocations */
struct relocation_info *datarel; /* Data relocations */
int ndatarel; /* # of data relocations */
/*
* Relation of this file's segments to the output file.
*/
int text_start_address; /* Start of this file's text segment
in the output file core image. */
int data_start_address; /* Start of this file's data segment
in the output file core image. */
int bss_start_address; /* Start of this file's bss segment
in the output file core image. */
struct file_entry *subfiles; /* For a library, points to chain of
entries for the library members. */
struct file_entry *superfile; /* For library member, points to the
library's own entry. */
struct file_entry *chain; /* For library member, points to next
entry for next member. */
int starting_offset; /* For a library member, offset of the
member within the archive. Zero for
files that are not library members.*/
int total_size; /* Size of contents of this file,
if library member. */
#ifdef SUN_COMPAT
struct file_entry *silly_archive;/* For shared libraries which have
a .sa companion */
#endif
int lib_major, lib_minor; /* Version numbers of a shared object */
int flags;
#define E_IS_LIBRARY 1 /* File is a an archive */
#define E_HEADER_VALID 2 /* File's header has been read */
#define E_SEARCH_DIRS 4 /* Search directories for file */
#define E_SEARCH_DYNAMIC 8 /* Search for shared libs allowed */
#define E_JUST_SYMS 0x10 /* File is used for incremental load */
#define E_DYNAMIC 0x20 /* File is a shared object */
#define E_SCRAPPED 0x40 /* Ignore this file */
#define E_SYMBOLS_USED 0x80 /* Symbols from this entry were used */
#define E_SECONDCLASS 0x100 /* Shared object is a subsidiary */
};
/*
* Runtime Relocation Section (RRS).
* This describes the data structures that go into the output text and data
* segments to support the run-time linker. The RRS can be empty (plain old
* static linking), or can just exist of GOT and PLT entries (in case of
* statically linked PIC code).
*/
extern int rrs_section_type; /* What's in the RRS section */
#define RRS_NONE 0
#define RRS_PARTIAL 1
#define RRS_FULL 2
extern int rrs_text_size; /* Size of RRS text additions */
extern int rrs_text_start; /* Location of above */
extern int rrs_data_size; /* Size of RRS data additions */
extern int rrs_data_start; /* Location of above */
extern char *rrs_search_paths; /* `-L' RT paths */
/* Version number to put in __DYNAMIC (set by -V) */
extern int soversion;
#ifndef DEFAULT_SOVERSION
#define DEFAULT_SOVERSION LD_VERSION_BSD
#endif
extern int pc_relocation; /* Current PC reloc value */
extern int number_of_shobjs; /* # of shared objects linked in */
/* Current link mode */
extern int link_mode;
#define DYNAMIC 1 /* Consider shared libraries */
#define SYMBOLIC 2 /* Force symbolic resolution */
#define FORCEARCHIVE 4 /* Force inclusion of all members
of archives */
#define SHAREABLE 8 /* Build a shared object */
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
extern FILE *outstream; /* Output file. */
extern struct exec outheader; /* Output file header. */
extern int magic; /* Output file magic. */
extern int oldmagic;
extern int relocatable_output;
extern int pic_type;
#define PIC_TYPE_NONE 0
#define PIC_TYPE_SMALL 1
#define PIC_TYPE_LARGE 2
void read_header __P((int, struct file_entry *));
void read_entry_symbols __P((int, struct file_entry *));
void read_entry_strings __P((int, struct file_entry *));
void read_entry_relocation __P((int, struct file_entry *));
void enter_file_symbols __P((struct file_entry *));
void read_file_symbols __P((struct file_entry *));
int set_element_prefixed_p __P((char *));
int text_offset __P((struct file_entry *));
int file_open __P((struct file_entry *));
void each_file __P((void (*)(), void *));
void each_full_file __P((void (*)(), void *));
unsigned long check_each_file __P((unsigned long (*)(), void *));
void mywrite __P((void *, int, int, FILE *));
void padfile __P((int, FILE *));
/* In warnings.c: */
void perror_name __P((char *));
void perror_file __P((struct file_entry *));
void print_symbols __P((FILE *));
char *get_file_name __P((struct file_entry *));
void print_file_name __P((struct file_entry *, FILE *));
void prline_file_name __P((struct file_entry *, FILE *));
int do_warnings __P((FILE *));
/* In etc.c: */
#include "support.h"
/* In symbol.c: */
void symtab_init __P((int));
symbol *getsym __P((char *)), *getsym_soft __P((char *));
/* In lib.c: */
void search_library __P((int, struct file_entry *));
void read_shared_object __P((int, struct file_entry *));
int findlib __P((struct file_entry *));
/* In shlib.c: */
#include "shlib.h"
/* In rrs.c: */
void init_rrs __P((void));
int rrs_add_shobj __P((struct file_entry *));
void alloc_rrs_reloc __P((struct file_entry *, symbol *));
void alloc_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
void alloc_rrs_jmpslot __P((struct file_entry *, symbol *));
void alloc_rrs_gotslot __P((struct file_entry *, struct relocation_info *, localsymbol_t *));
void alloc_rrs_cpy_reloc __P((struct file_entry *, symbol *));
int claim_rrs_reloc __P((struct file_entry *, struct relocation_info *, symbol *, long *));
long claim_rrs_jmpslot __P((struct file_entry *, struct relocation_info *, symbol *, long));
long claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
long claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
void claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
void claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
void consider_rrs_section_lengths __P((void));
void relocate_rrs_addresses __P((void));
void write_rrs __P((void));
/* In <md>.c */
void md_init_header __P((struct exec *, int, int));
long md_get_addend __P((struct relocation_info *, unsigned char *));
void md_relocate __P((struct relocation_info *, long, unsigned char *, int));
void md_make_jmpslot __P((jmpslot_t *, long, long));
void md_fix_jmpslot __P((jmpslot_t *, long, u_long));
int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
void md_set_breakpoint __P((long, long *));
#ifdef NEED_SWAP
/* In xbits.c: */
void swap_longs __P((long *, int));
void swap_symbols __P((struct nlist *, int));
void swap_zsymbols __P((struct nzlist *, int));
void swap_ranlib_hdr __P((struct ranlib *, int));
void swap__dynamic __P((struct link_dynamic *));
void swap_section_dispatch_table __P((struct section_dispatch_table *));
void swap_so_debug __P((struct so_debug *));
void swapin_sod __P((struct sod *, int));
void swapout_sod __P((struct sod *, int));
void swapout_fshash __P((struct fshash *, int));
#endif
#endif /* __DYNAMIC_H__ */

View File

@ -27,28 +27,26 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: shlib.c,v 1.14 1996/01/13 00:14:53 jdp Exp $
* $Id: shlib.c,v 1.15 1996/04/20 18:27:56 jdp Exp $
*/
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <err.h>
#include <fcntl.h>
#include <string.h>
#include <a.out.h>
#include <ctype.h>
#include <dirent.h>
#include <a.out.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ld.h"
#ifdef SUNOS4
char *strsep();
#endif
#include <link.h>
#include "shlib.h"
#include "support.h"
/*
* Standard directories to search for files specified by -l.
@ -59,7 +57,7 @@ char *strsep();
/*
* Actual vector of library search directories,
* including `-L'ed and LD_LIBARAY_PATH spec'd ones.
* including `-L'ed and LD_LIBRARY_PATH spec'd ones.
*/
char **search_dirs;
int n_search_dirs;
@ -73,9 +71,14 @@ void
add_search_dir(name)
char *name;
{
int n;
for (n = 0; n < n_search_dirs; n++)
if (strcmp(search_dirs[n], name) == 0)
return;
n_search_dirs++;
search_dirs = (char **)
xrealloc(search_dirs, n_search_dirs * sizeof(char *));
xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]);
search_dirs[n_search_dirs - 1] = strdup(name);
}
@ -83,17 +86,16 @@ void
add_search_path(path)
char *path;
{
register char *cp;
register char *cp, *dup;
if (path == NULL)
return;
/* Add search directories from `paths' */
while ((cp = strsep(&path, ":")) != NULL) {
/* Add search directories from `path' */
path = dup = strdup(path);
while ((cp = strsep(&path, ":")) != NULL)
add_search_dir(cp);
if (path)
*(path-1) = ':';
}
free(dup);
}
void

43
libexec/rtld-aout/shlib.h Normal file
View File

@ -0,0 +1,43 @@
/*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
/*
* prototypes for shlib.c. Big deal.
*/
extern char **search_dirs;
extern int n_search_dirs;
void add_search_dir __P((char *));
void add_search_path __P((char *));
void std_search_path __P((void));
int getdewey __P((int[], char *));
int cmpndewey __P((int[], int, int[], int));
char *findshlib __P((char *, int *, int *, int));
char *find_lib_file __P((char *));
char *search_lib_dir __P((char *, char *, int *, int *, int));

View File

@ -0,0 +1,86 @@
/*
* Generic "support" routines to replace those obtained from libiberty for ld.
*
* I've collected these from random bits of (published) code I've written
* over the years, not that they are a big deal. peter@freebsd.org
*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include "support.h"
char *
concat(s1, s2, s3)
const char *s1, *s2, *s3;
{
int len = 1;
char *s;
if (s1)
len += strlen(s1);
if (s2)
len += strlen(s2);
if (s3)
len += strlen(s3);
s = malloc(len);
s[0] = '\0';
if (s1)
strcat(s, s1);
if (s2)
strcat(s, s2);
if (s3)
strcat(s, s3);
return s;
}
void *
xmalloc(n)
size_t n;
{
char *p = malloc(n);
if (p == NULL)
errx(1, "Could not allocate memory");
return p;
}
void *
xrealloc(p, n)
void *p;
size_t n;
{
p = realloc(p, n);
if (p == NULL)
errx(1, "Could not allocate memory");
return p;
}

View File

@ -0,0 +1,35 @@
/*-
* Copyright (C) 1996
* Peter Wemm. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*-
* $Id$
*/
/*
* prototypes for support.c. Big deal.
*/
void *xmalloc __P((size_t));
void *xrealloc __P((void *, size_t));
char *concat __P((const char *, const char *, const char *));