From d0a184df5d7327c266185011a14aa45cbff01c12 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Tue, 1 Oct 1996 01:22:51 +0000 Subject: [PATCH] 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) --- gnu/usr.bin/ld/Makefile | 4 +- gnu/usr.bin/ld/PORTING | 4 +- gnu/usr.bin/ld/dynamic.h | 377 ++++++++++++++++++++++++++++++++++++ gnu/usr.bin/ld/etc.c | 66 ------- gnu/usr.bin/ld/ld.1 | 119 ++++++++---- gnu/usr.bin/ld/ld.1aout | 119 ++++++++---- gnu/usr.bin/ld/ld.c | 94 ++++++--- gnu/usr.bin/ld/ld.h | 337 +------------------------------- gnu/usr.bin/ld/lib.c | 82 ++++---- gnu/usr.bin/ld/rrs.c | 50 +++-- gnu/usr.bin/ld/shlib.c | 42 ++-- gnu/usr.bin/ld/shlib.h | 43 ++++ gnu/usr.bin/ld/support.c | 86 ++++++++ gnu/usr.bin/ld/support.h | 35 ++++ gnu/usr.bin/ld/symbol.c | 35 +++- gnu/usr.bin/ld/warnings.c | 34 +++- gnu/usr.bin/ld/xbits.c | 3 +- libexec/rtld-aout/dynamic.h | 377 ++++++++++++++++++++++++++++++++++++ libexec/rtld-aout/shlib.c | 42 ++-- libexec/rtld-aout/shlib.h | 43 ++++ libexec/rtld-aout/support.c | 86 ++++++++ libexec/rtld-aout/support.h | 35 ++++ 22 files changed, 1523 insertions(+), 590 deletions(-) create mode 100644 gnu/usr.bin/ld/dynamic.h delete mode 100644 gnu/usr.bin/ld/etc.c create mode 100644 gnu/usr.bin/ld/shlib.h create mode 100644 gnu/usr.bin/ld/support.c create mode 100644 gnu/usr.bin/ld/support.h create mode 100644 libexec/rtld-aout/dynamic.h create mode 100644 libexec/rtld-aout/shlib.h create mode 100644 libexec/rtld-aout/support.c create mode 100644 libexec/rtld-aout/support.h diff --git a/gnu/usr.bin/ld/Makefile b/gnu/usr.bin/ld/Makefile index 132c6751bf28..7d9c7c0e9218 100644 --- a/gnu/usr.bin/ld/Makefile +++ b/gnu/usr.bin/ld/Makefile @@ -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 diff --git a/gnu/usr.bin/ld/PORTING b/gnu/usr.bin/ld/PORTING index fc6f918a9146..017f6d77095e 100644 --- a/gnu/usr.bin/ld/PORTING +++ b/gnu/usr.bin/ld/PORTING @@ -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 diff --git a/gnu/usr.bin/ld/dynamic.h b/gnu/usr.bin/ld/dynamic.h new file mode 100644 index 000000000000..1231a6262592 --- /dev/null +++ b/gnu/usr.bin/ld/dynamic.h @@ -0,0 +1,377 @@ +/* + * Copyright (c) 1993 Paul Kranenburg + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef __DYNAMIC_H__ +#define __DYNAMIC_H__ + +#define SUN_COMPAT + +#include "md.h" +#include "link.h" + +#ifndef RELOC_JMPTAB_P + +#define RELOC_JMPTAB_P(r) ((r)->r_jmptable) +#define RELOC_BASEREL_P(r) ((r)->r_baserel) +#define RELOC_RELATIVE_P(r) ((r)->r_relative) +#define RELOC_COPY_P(r) ((r)->r_copy) +#define RELOC_LAZY_P(r) ((r)->r_jmptable) + +#define CHECK_GOT_RELOC(r) ((r)->r_pcrel) +#define RELOC_PIC_TYPE(r) ((r)->r_baserel? \ + PIC_TYPE_LARGE:PIC_TYPE_NONE) +#endif + +#ifndef RELOC_INIT_SEGMENT_RELOC +#define RELOC_INIT_SEGMENT_RELOC(r) +#endif + +#ifndef MAX_GOTOFF +#define MAX_GOTOFF(x) (LONG_MAX) +#endif + +#ifndef MIN_GOTOFF +#define MIN_GOTOFF(x) (LONG_MIN) +#endif + +/* + * Internal representation of relocation types + */ +#define RELTYPE_EXTERN 1 +#define RELTYPE_JMPSLOT 2 +#define RELTYPE_BASEREL 4 +#define RELTYPE_RELATIVE 8 +#define RELTYPE_COPY 16 + +#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK) + +typedef struct localsymbol { + struct nzlist nzlist; /* n[z]list from file */ + struct glosym *symbol; /* Corresponding global symbol, + if any */ + struct localsymbol *next; /* List of definitions */ + struct file_entry *entry; /* Backpointer to file */ + long gotslot_offset; /* Position in GOT, if any */ + int symbolnum; /* Position in output nlist */ + int flags; +#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */ +#define LS_WRITE 2 /* Symbol goes in output symtable */ +#define LS_RENAME 4 /* xlat name to `.' */ +#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 .c */ +void md_init_header __P((struct exec *, int, int)); +long md_get_addend __P((struct relocation_info *, unsigned char *)); +void md_relocate __P((struct relocation_info *, long, unsigned char *, int)); +void md_make_jmpslot __P((jmpslot_t *, long, long)); +void md_fix_jmpslot __P((jmpslot_t *, long, u_long)); +int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *)); +void md_set_breakpoint __P((long, long *)); + +#ifdef NEED_SWAP +/* In xbits.c: */ +void swap_longs __P((long *, int)); +void swap_symbols __P((struct nlist *, int)); +void swap_zsymbols __P((struct nzlist *, int)); +void swap_ranlib_hdr __P((struct ranlib *, int)); +void swap__dynamic __P((struct link_dynamic *)); +void swap_section_dispatch_table __P((struct section_dispatch_table *)); +void swap_so_debug __P((struct so_debug *)); +void swapin_sod __P((struct sod *, int)); +void swapout_sod __P((struct sod *, int)); +void swapout_fshash __P((struct fshash *, int)); +#endif + +#endif /* __DYNAMIC_H__ */ diff --git a/gnu/usr.bin/ld/etc.c b/gnu/usr.bin/ld/etc.c deleted file mode 100644 index 59e0a18c6de4..000000000000 --- a/gnu/usr.bin/ld/etc.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * $Id: etc.c,v 1.7 1994/02/13 20:41:05 jkh Exp $ - */ - -#include -#include -#include - -/* - * 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; -} - diff --git a/gnu/usr.bin/ld/ld.1 b/gnu/usr.bin/ld/ld.1 index d0adbb84a92c..6aebcd776337 100644 --- a/gnu/usr.bin/ld/ld.1 +++ b/gnu/usr.bin/ld/ld.1 @@ -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.so.m.n (where +output. If the +.Fl B Ns Ar dynamic +option is in effect, a shared library of the +form lib.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.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.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 diff --git a/gnu/usr.bin/ld/ld.1aout b/gnu/usr.bin/ld/ld.1aout index d0adbb84a92c..6aebcd776337 100644 --- a/gnu/usr.bin/ld/ld.1aout +++ b/gnu/usr.bin/ld/ld.1aout @@ -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.so.m.n (where +output. If the +.Fl B Ns Ar dynamic +option is in effect, a shared library of the +form lib.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.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.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 diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c index 3a9dfebe7090..580931e41d34 100644 --- a/gnu/usr.bin/ld/ld.c +++ b/gnu/usr.bin/ld/ld.c @@ -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 #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91"; #include #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]; } } diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h index f16b3f8ade87..f020d6e4dc22 100644 --- a/gnu/usr.bin/ld/ld.h +++ b/gnu/usr.bin/ld/ld.h @@ -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 `.' */ -#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 .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" diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c index 550dedf32192..7741ea206f6c 100644 --- a/gnu/usr.bin/ld/lib.c +++ b/gnu/usr.bin/ld/lib.c @@ -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 @@ -21,6 +52,7 @@ #include #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. diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c index d218b9c67c3a..f69c09223567 100644 --- a/gnu/usr.bin/ld/rrs.c +++ b/gnu/usr.bin/ld/rrs.c @@ -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 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #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 */ diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c index 9460d35b19bc..44e30f0b75ea 100644 --- a/gnu/usr.bin/ld/shlib.c +++ b/gnu/usr.bin/ld/shlib.c @@ -27,28 +27,26 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: shlib.c,v 1.14 1996/01/13 00:14:53 jdp Exp $ + * $Id: shlib.c,v 1.15 1996/04/20 18:27:56 jdp Exp $ */ #include -#include -#include #include #include #include #include -#include -#include -#include +#include #include #include -#include +#include +#include +#include +#include +#include -#include "ld.h" - -#ifdef SUNOS4 -char *strsep(); -#endif +#include +#include "shlib.h" +#include "support.h" /* * Standard directories to search for files specified by -l. @@ -59,7 +57,7 @@ char *strsep(); /* * Actual vector of library search directories, - * including `-L'ed and LD_LIBARAY_PATH spec'd ones. + * including `-L'ed and LD_LIBRARY_PATH spec'd ones. */ char **search_dirs; int n_search_dirs; @@ -73,9 +71,14 @@ void add_search_dir(name) char *name; { + int n; + + for (n = 0; n < n_search_dirs; n++) + if (strcmp(search_dirs[n], name) == 0) + return; n_search_dirs++; search_dirs = (char **) - xrealloc(search_dirs, n_search_dirs * sizeof(char *)); + xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]); search_dirs[n_search_dirs - 1] = strdup(name); } @@ -83,17 +86,16 @@ void add_search_path(path) char *path; { - register char *cp; + register char *cp, *dup; if (path == NULL) return; - /* Add search directories from `paths' */ - while ((cp = strsep(&path, ":")) != NULL) { + /* Add search directories from `path' */ + path = dup = strdup(path); + while ((cp = strsep(&path, ":")) != NULL) add_search_dir(cp); - if (path) - *(path-1) = ':'; - } + free(dup); } void diff --git a/gnu/usr.bin/ld/shlib.h b/gnu/usr.bin/ld/shlib.h new file mode 100644 index 000000000000..796d37e7636c --- /dev/null +++ b/gnu/usr.bin/ld/shlib.h @@ -0,0 +1,43 @@ +/*- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ + +/* + * prototypes for shlib.c. Big deal. + */ + +extern char **search_dirs; +extern int n_search_dirs; + +void add_search_dir __P((char *)); +void add_search_path __P((char *)); +void std_search_path __P((void)); +int getdewey __P((int[], char *)); +int cmpndewey __P((int[], int, int[], int)); +char *findshlib __P((char *, int *, int *, int)); +char *find_lib_file __P((char *)); +char *search_lib_dir __P((char *, char *, int *, int *, int)); diff --git a/gnu/usr.bin/ld/support.c b/gnu/usr.bin/ld/support.c new file mode 100644 index 000000000000..6fdf5057e87a --- /dev/null +++ b/gnu/usr.bin/ld/support.c @@ -0,0 +1,86 @@ +/* + * Generic "support" routines to replace those obtained from libiberty for ld. + * + * I've collected these from random bits of (published) code I've written + * over the years, not that they are a big deal. peter@freebsd.org + *- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ +#include +#include +#include +#include + +#include "support.h" + +char * +concat(s1, s2, s3) + const char *s1, *s2, *s3; +{ + int len = 1; + char *s; + if (s1) + len += strlen(s1); + if (s2) + len += strlen(s2); + if (s3) + len += strlen(s3); + s = malloc(len); + s[0] = '\0'; + if (s1) + strcat(s, s1); + if (s2) + strcat(s, s2); + if (s3) + strcat(s, s3); + return s; +} + +void * +xmalloc(n) + size_t n; +{ + char *p = malloc(n); + + if (p == NULL) + errx(1, "Could not allocate memory"); + + return p; +} + +void * +xrealloc(p, n) + void *p; + size_t n; +{ + p = realloc(p, n); + + if (p == NULL) + errx(1, "Could not allocate memory"); + + return p; +} diff --git a/gnu/usr.bin/ld/support.h b/gnu/usr.bin/ld/support.h new file mode 100644 index 000000000000..5be1e31c19d9 --- /dev/null +++ b/gnu/usr.bin/ld/support.h @@ -0,0 +1,35 @@ +/*- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ + +/* + * prototypes for support.c. Big deal. + */ + +void *xmalloc __P((size_t)); +void *xrealloc __P((void *, size_t)); +char *concat __P((const char *, const char *, const char *)); diff --git a/gnu/usr.bin/ld/symbol.c b/gnu/usr.bin/ld/symbol.c index c07637ed5ebe..10738705569c 100644 --- a/gnu/usr.bin/ld/symbol.c +++ b/gnu/usr.bin/ld/symbol.c @@ -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 #include "ld.h" +#include "dynamic.h" symbol *symtab[SYMTABSIZE]; /* The symbol table. */ int num_hash_tab_syms; /* Number of symbols in symbol hash table. */ diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c index b4f0b3e6f9a3..660bcc5cc89d 100644 --- a/gnu/usr.bin/ld/warnings.c +++ b/gnu/usr.bin/ld/warnings.c @@ -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 @@ -24,6 +55,7 @@ #endif #include "ld.h" +#include "dynamic.h" static int reported_undefineds; diff --git a/gnu/usr.bin/ld/xbits.c b/gnu/usr.bin/ld/xbits.c index 6374bebe23c5..edcb16af843c 100644 --- a/gnu/usr.bin/ld/xbits.c +++ b/gnu/usr.bin/ld/xbits.c @@ -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 #include "ld.h" +#include "dynamic.h" void swap_longs(lp, n) diff --git a/libexec/rtld-aout/dynamic.h b/libexec/rtld-aout/dynamic.h new file mode 100644 index 000000000000..1231a6262592 --- /dev/null +++ b/libexec/rtld-aout/dynamic.h @@ -0,0 +1,377 @@ +/* + * Copyright (c) 1993 Paul Kranenburg + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef __DYNAMIC_H__ +#define __DYNAMIC_H__ + +#define SUN_COMPAT + +#include "md.h" +#include "link.h" + +#ifndef RELOC_JMPTAB_P + +#define RELOC_JMPTAB_P(r) ((r)->r_jmptable) +#define RELOC_BASEREL_P(r) ((r)->r_baserel) +#define RELOC_RELATIVE_P(r) ((r)->r_relative) +#define RELOC_COPY_P(r) ((r)->r_copy) +#define RELOC_LAZY_P(r) ((r)->r_jmptable) + +#define CHECK_GOT_RELOC(r) ((r)->r_pcrel) +#define RELOC_PIC_TYPE(r) ((r)->r_baserel? \ + PIC_TYPE_LARGE:PIC_TYPE_NONE) +#endif + +#ifndef RELOC_INIT_SEGMENT_RELOC +#define RELOC_INIT_SEGMENT_RELOC(r) +#endif + +#ifndef MAX_GOTOFF +#define MAX_GOTOFF(x) (LONG_MAX) +#endif + +#ifndef MIN_GOTOFF +#define MIN_GOTOFF(x) (LONG_MIN) +#endif + +/* + * Internal representation of relocation types + */ +#define RELTYPE_EXTERN 1 +#define RELTYPE_JMPSLOT 2 +#define RELTYPE_BASEREL 4 +#define RELTYPE_RELATIVE 8 +#define RELTYPE_COPY 16 + +#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK) + +typedef struct localsymbol { + struct nzlist nzlist; /* n[z]list from file */ + struct glosym *symbol; /* Corresponding global symbol, + if any */ + struct localsymbol *next; /* List of definitions */ + struct file_entry *entry; /* Backpointer to file */ + long gotslot_offset; /* Position in GOT, if any */ + int symbolnum; /* Position in output nlist */ + int flags; +#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */ +#define LS_WRITE 2 /* Symbol goes in output symtable */ +#define LS_RENAME 4 /* xlat name to `.' */ +#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 .c */ +void md_init_header __P((struct exec *, int, int)); +long md_get_addend __P((struct relocation_info *, unsigned char *)); +void md_relocate __P((struct relocation_info *, long, unsigned char *, int)); +void md_make_jmpslot __P((jmpslot_t *, long, long)); +void md_fix_jmpslot __P((jmpslot_t *, long, u_long)); +int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int)); +void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *)); +void md_set_breakpoint __P((long, long *)); + +#ifdef NEED_SWAP +/* In xbits.c: */ +void swap_longs __P((long *, int)); +void swap_symbols __P((struct nlist *, int)); +void swap_zsymbols __P((struct nzlist *, int)); +void swap_ranlib_hdr __P((struct ranlib *, int)); +void swap__dynamic __P((struct link_dynamic *)); +void swap_section_dispatch_table __P((struct section_dispatch_table *)); +void swap_so_debug __P((struct so_debug *)); +void swapin_sod __P((struct sod *, int)); +void swapout_sod __P((struct sod *, int)); +void swapout_fshash __P((struct fshash *, int)); +#endif + +#endif /* __DYNAMIC_H__ */ diff --git a/libexec/rtld-aout/shlib.c b/libexec/rtld-aout/shlib.c index 9460d35b19bc..44e30f0b75ea 100644 --- a/libexec/rtld-aout/shlib.c +++ b/libexec/rtld-aout/shlib.c @@ -27,28 +27,26 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: shlib.c,v 1.14 1996/01/13 00:14:53 jdp Exp $ + * $Id: shlib.c,v 1.15 1996/04/20 18:27:56 jdp Exp $ */ #include -#include -#include #include #include #include #include -#include -#include -#include +#include #include #include -#include +#include +#include +#include +#include +#include -#include "ld.h" - -#ifdef SUNOS4 -char *strsep(); -#endif +#include +#include "shlib.h" +#include "support.h" /* * Standard directories to search for files specified by -l. @@ -59,7 +57,7 @@ char *strsep(); /* * Actual vector of library search directories, - * including `-L'ed and LD_LIBARAY_PATH spec'd ones. + * including `-L'ed and LD_LIBRARY_PATH spec'd ones. */ char **search_dirs; int n_search_dirs; @@ -73,9 +71,14 @@ void add_search_dir(name) char *name; { + int n; + + for (n = 0; n < n_search_dirs; n++) + if (strcmp(search_dirs[n], name) == 0) + return; n_search_dirs++; search_dirs = (char **) - xrealloc(search_dirs, n_search_dirs * sizeof(char *)); + xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]); search_dirs[n_search_dirs - 1] = strdup(name); } @@ -83,17 +86,16 @@ void add_search_path(path) char *path; { - register char *cp; + register char *cp, *dup; if (path == NULL) return; - /* Add search directories from `paths' */ - while ((cp = strsep(&path, ":")) != NULL) { + /* Add search directories from `path' */ + path = dup = strdup(path); + while ((cp = strsep(&path, ":")) != NULL) add_search_dir(cp); - if (path) - *(path-1) = ':'; - } + free(dup); } void diff --git a/libexec/rtld-aout/shlib.h b/libexec/rtld-aout/shlib.h new file mode 100644 index 000000000000..796d37e7636c --- /dev/null +++ b/libexec/rtld-aout/shlib.h @@ -0,0 +1,43 @@ +/*- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ + +/* + * prototypes for shlib.c. Big deal. + */ + +extern char **search_dirs; +extern int n_search_dirs; + +void add_search_dir __P((char *)); +void add_search_path __P((char *)); +void std_search_path __P((void)); +int getdewey __P((int[], char *)); +int cmpndewey __P((int[], int, int[], int)); +char *findshlib __P((char *, int *, int *, int)); +char *find_lib_file __P((char *)); +char *search_lib_dir __P((char *, char *, int *, int *, int)); diff --git a/libexec/rtld-aout/support.c b/libexec/rtld-aout/support.c new file mode 100644 index 000000000000..6fdf5057e87a --- /dev/null +++ b/libexec/rtld-aout/support.c @@ -0,0 +1,86 @@ +/* + * Generic "support" routines to replace those obtained from libiberty for ld. + * + * I've collected these from random bits of (published) code I've written + * over the years, not that they are a big deal. peter@freebsd.org + *- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ +#include +#include +#include +#include + +#include "support.h" + +char * +concat(s1, s2, s3) + const char *s1, *s2, *s3; +{ + int len = 1; + char *s; + if (s1) + len += strlen(s1); + if (s2) + len += strlen(s2); + if (s3) + len += strlen(s3); + s = malloc(len); + s[0] = '\0'; + if (s1) + strcat(s, s1); + if (s2) + strcat(s, s2); + if (s3) + strcat(s, s3); + return s; +} + +void * +xmalloc(n) + size_t n; +{ + char *p = malloc(n); + + if (p == NULL) + errx(1, "Could not allocate memory"); + + return p; +} + +void * +xrealloc(p, n) + void *p; + size_t n; +{ + p = realloc(p, n); + + if (p == NULL) + errx(1, "Could not allocate memory"); + + return p; +} diff --git a/libexec/rtld-aout/support.h b/libexec/rtld-aout/support.h new file mode 100644 index 000000000000..5be1e31c19d9 --- /dev/null +++ b/libexec/rtld-aout/support.h @@ -0,0 +1,35 @@ +/*- + * Copyright (C) 1996 + * Peter Wemm. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *- + * $Id$ + */ + +/* + * prototypes for support.c. Big deal. + */ + +void *xmalloc __P((size_t)); +void *xrealloc __P((void *, size_t)); +char *concat __P((const char *, const char *, const char *));