4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 * Binary compatibility ld.so. Intercepts the reference of a pre-SVR4
27 * SunOS executable to the dynamic linker, and then redirects to the
28 * "real" post-SVR4 SunOS ld.so.
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 * Import data structures (N.B.: from 5.x).
35 #include <sys/types.h>
37 #include <sys/fcntl.h>
39 #include <sys/sysconfig.h>
41 #include <sys/archsystm.h>
46 * Relocation manifest constants and macros.
48 #define ALIGN(x, a) ((int)(x) & ~((int)(a) - 1))
49 #define ROUND(x, a) (((int)(x) + ((int)(a) - 1)) & \
51 #define DYNAMIC_VERSION2 2
52 #define RELOC_SIZE (sizeof (struct relocation_info))
53 #define RELOCOFF(x) (x)->v2->ld_rel
54 #define MASK(n) ((1<<(n))-1)
55 #define IN_RANGE(v, n) ((-(1<<((n)-1))) <= (v) && (v) < (1<<((n)-1)))
57 void aout_reloc_write();
60 * 4.x SunOS Dynamic Link Editor public definitions (much derived from
61 * SunOS 4.x <link.h>.)
65 * Dynamic linking information. With the exception of
66 * ld_loaded (determined at execution time) and ld_stab_hash (a special
67 * case of relocation handled at execution time), the values in this
68 * structure reflect offsets from the containing link_dynamic structure.
70 struct link_dynamic_1
{
71 struct link_map
*ld_loaded
; /* list of loaded objects */
72 long ld_need
; /* list of needed objects */
73 long ld_rules
; /* search rules for library objects */
74 long ld_got
; /* global offset table */
75 long ld_plt
; /* procedure linkage table */
76 long ld_rel
; /* relocation table */
77 long ld_hash
; /* symbol hash table */
78 long ld_stab
; /* symbol table itself */
79 long (*ld_stab_hash
)(); /* "pointer" to symbol hash function */
80 long ld_buckets
; /* number of hash buckets */
81 long ld_symbols
; /* symbol strings */
82 long ld_symb_size
; /* size of symbol strings */
83 long ld_text
; /* size of text area */
86 struct link_dynamic_2
{
87 struct link_map
*ld_loaded
; /* list of loaded objects */
88 long ld_need
; /* list of needed objects */
89 long ld_rules
; /* search rules for library objects */
90 long ld_got
; /* global offset table */
91 long ld_plt
; /* procedure linkage table */
92 long ld_rel
; /* relocation table */
93 long ld_hash
; /* symbol hash table */
94 long ld_stab
; /* symbol table itself */
95 long (*ld_stab_hash
)(); /* "pointer" to symbol hash function */
96 long ld_buckets
; /* number of hash buckets */
97 long ld_symbols
; /* symbol strings */
98 long ld_symb_size
; /* size of symbol strings */
99 long ld_text
; /* size of text area */
100 long ld_plt_sz
; /* size of procedure linkage table */
104 * Debugger interface structure.
107 int ldd_version
; /* version # of interface */
108 int ldd_in_debugger
; /* a debugger is running us */
109 int ldd_sym_loaded
; /* we loaded some symbols */
110 char *ldd_bp_addr
; /* place for ld-generated bpt */
111 int ldd_bp_inst
; /* instruction which was there */
112 struct rtc_symb
*ldd_cp
; /* commons we built */
116 * Structure associated with each object which may be or which requires
117 * execution-time link editing. Used by the run-time linkage editor to
118 * identify needed objects and symbol definitions and references.
120 struct link_dynamic
{
122 struct ld_debug
*ldd
;
124 struct link_dynamic_1
*ld_1
;
125 struct link_dynamic_2
*ld_2
;
129 struct old_link_dynamic
{
130 int ld_version
; /* version # of this structure */
132 struct link_dynamic_1 ld_1
;
139 struct rtc_symb
*cp
; /* pointer to an array of runtime */
140 /* allocated common symbols. */
143 #define v2 ld_un.ld_2 /* short hands */
144 #define v1 ld_un.ld_1
147 * SunOS 4.x SPARC relocation types and relocation record. Note that
148 * these, among other things, make this program not portable to things
152 RELOC_8
, RELOC_16
, RELOC_32
, /* simplest relocs */
153 RELOC_DISP8
, RELOC_DISP16
, RELOC_DISP32
,
154 /* Disp's (pc-rel) */
155 RELOC_WDISP30
, RELOC_WDISP22
, /* SR word disp's */
156 RELOC_HI22
, RELOC_22
, /* SR 22-bit relocs */
157 RELOC_13
, RELOC_LO10
, /* SR 13&10-bit relocs */
158 RELOC_SFA_BASE
, RELOC_SFA_OFF13
, /* SR S.F.A. relocs */
159 RELOC_BASE10
, RELOC_BASE13
, RELOC_BASE22
,
160 /* PIC GOT references */
161 RELOC_PC10
, RELOC_PC22
, /* PIC reference to GOT */
162 RELOC_JMP_TBL
, /* PIC call */
163 RELOC_SEGOFF16
, /* .so offset-in-segment */
164 RELOC_GLOB_DAT
, RELOC_JMP_SLOT
, RELOC_RELATIVE
,
165 /* ld.so relocation types */
168 struct relocation_info
{
169 unsigned long int r_address
; /* relocation addr */
170 unsigned int r_index
:24; /* segment index or symbol index */
171 unsigned int r_extern
: 1; /* if F, r_index==SEG#; if T, SYM idx */
172 int : 2; /* <unused> */
173 enum reloc_type r_type
: 5; /* type of relocation to perform */
174 long int r_addend
; /* addend for relocation value */
178 * Size of relocations.
180 #define GETRELSZ(x) \
181 (x->ld_version < 2 ? \
182 ((struct old_link_dynamic *)x)->v1.ld_hash - \
183 ((struct old_link_dynamic *)x)->v1.ld_rel : \
184 (x)->v2->ld_hash - (x)->v2->ld_rel)
187 * Interface between crt0 & ld.so.
190 int crt_baseaddr
; /* Address ld.so is at */
191 int crt_dzfd
; /* /dev/zero file descriptor */
192 int crt_rlfd
; /* ld.so file descriptor */
193 struct link_dynamic
*crt_udp
; /* "main_" dynamic */
194 char **crt_ep
; /* environment strings */
195 caddr_t crt_breakp
; /* place to put initial breakpoint */
199 * Structure we provide to ELF ld.so upon entry.
201 Elf32_Boot eb
[EB_MAX
];
206 char *program_name
; /* used in messages */
209 * 4.0 ld.so main entry point.
211 rtld(version
, ip
, dp
, argp
)
212 int version
; /* interface version */
213 struct crt_i1
*ip
; /* interface passed from program */
214 register struct link_dynamic
*dp
; /* ld.so dynamic pointer */
215 caddr_t argp
; /* pointer to begining of args */
217 char *ldso
; /* name of what we really want to be */
218 int i
, p
; /* working */
219 int r
; /* working (# of *our* relocations */
220 int page_size
= 0; /* size of a page */
221 struct relocation_info
*rp
; /* working pointer to our relocs */
222 int fd
; /* fd assigned to ld.so */
223 Elf32_Ehdr
*ehdr
; /* ELF header of ld.so */
224 Elf32_Phdr
*phdr
; /* first Phdr in file */
225 Elf32_Phdr
*pptr
; /* working Phdr */
226 Elf32_Phdr
*lph
; /* last loadable Phdr */
227 Elf32_Phdr
*fph
= 0; /* first loadable Phdr */
228 caddr_t maddr
; /* pointer to mapping claim */
229 Elf32_Off mlen
; /* total mapping claim */
230 caddr_t faddr
; /* first program mapping of ld.so */
231 Elf32_Off foff
; /* file offset for segment mapping */
232 Elf32_Off flen
; /* file length for segment mapping */
233 caddr_t addr
; /* working mapping address */
234 caddr_t zaddr
; /* /dev/zero working mapping addr */
235 Elf32_Boot
*ebp
; /* communication with ld.so */
236 struct stat sb
; /* stat buffer for sizing */
237 auxv_t
*ap
; /* working aux pointer */
238 void (* wrt
)(); /* address of write/iflush routine */
241 * ld.so must itself be relocated, take care of this now.
242 * We can not refer to global data before this step is
243 * complete. Perform the relocation by stepping over all
244 * entries in the relocation table and turn them into
245 * absolute addresses. Note that, in order to avoid invoking
246 * as yet unrelocated items, we perform the relocation count
247 * by counting rather than risk invoking subroutine calls
248 * to intrinsic .div or .mul routines. Note also that we
249 * assume that there are no symbolic relocations to be
252 dp
->v2
= (struct link_dynamic_2
*)
253 ((caddr_t
)dp
->v2
+ ip
->crt_baseaddr
);
260 rp
= (struct relocation_info
*)(RELOCOFF(dp
) +
261 (dp
->ld_version
< DYNAMIC_VERSION2
?
262 (int)dp
: ip
->crt_baseaddr
));
265 * Determine the location of the routine that will write the relocation.
266 * This hasn't yet been relocated so determine the real address using
269 wrt
= (void (*)())((caddr_t
)aout_reloc_write
+ ip
->crt_baseaddr
);
272 * Relocate ourselves - we only need RELOC_RELATIVE and RELOC_32.
273 * Note, if panic() was called its probable that it will barf as the
274 * corresponding plt wouldn't have been relocated yet.
276 for (i
= 0; i
< r
; i
++) {
277 long *where
= (long *)((caddr_t
)rp
->r_address
+ ip
->crt_baseaddr
);
278 long what
= ip
->crt_baseaddr
;
281 switch (rp
->r_type
) {
283 what
+= *where
<< (32-22);
284 value
= (*where
& ~MASK(22)) | ((what
>> (32-22)) & MASK(22));
287 what
+= (*where
& MASK(10));
288 value
= (*where
& ~MASK(10)) | (what
& MASK(10));
298 panic("unknown relocation type %d\n", rp
->r_type
);
305 * We're relocated, we can now initialize things referencing
308 ldso
= "/usr/lib/ld.so.1";
311 * Close off the file descriptor used to get us here -- let it
312 * be available for the next (probable) use below.
314 (void) close(ip
->crt_rlfd
);
317 * Discover things about our environment: auxiliary vector (if
318 * any), arguments, program name, and the like.
321 program_name
= (char *)(argp
+ sizeof (int));
323 panic("bad startup interface version of %d",
325 ebp
->eb_tag
= EB_DYNAMIC
,
326 (ebp
++)->eb_un
.eb_ptr
= (Elf32_Addr
)ip
->crt_udp
;
327 ebp
->eb_tag
= EB_ARGV
, (ebp
++)->eb_un
.eb_ptr
= (Elf32_Addr
)program_name
;
328 ebp
->eb_tag
= EB_ENVP
, (ebp
++)->eb_un
.eb_ptr
= (Elf32_Addr
)ip
->crt_ep
;
329 ebp
->eb_tag
= EB_DEVZERO
,
330 (ebp
++)->eb_un
.eb_val
= (Elf32_Word
)ip
->crt_dzfd
;
331 for (addr
= (caddr_t
)ip
->crt_ep
; *addr
; addr
+= sizeof (char *))
333 addr
+= sizeof (char *);
336 * The kernel sends us an abbreviated aux vector with some
337 * potentially handy stuff that saves us on syscalls.
341 * The f77 compiler shipped as part of SC1.0 on 4.x creates binaries
342 * that use the _fix_libc_ feature of acc. This makes the resulting
343 * executable object dependent on the undocumented behaviour of
344 * libc's .rem and .div routines e.g. that .div returns the
345 * remainder in %o3 (and similarly .rem returns the division in %o3).
347 * The only simple solution is to disable hardware divide for
348 * all 4.x applications so that the old software routines that have
349 * this "support" in them are used instead. And we do that by
350 * clearing the divide-in-hardware flag from the aux vector before
351 * libc's .init routine gets to see it. Awful isn't it.
353 ebp
->eb_tag
= EB_AUXV
, (ebp
++)->eb_un
.eb_ptr
= (Elf32_Addr
)addr
;
354 for (ap
= (auxv_t
*)addr
; ap
->a_type
!= AT_NULL
; ap
++)
355 if (ap
->a_type
== AT_PAGESZ
) {
356 page_size
= ap
->a_un
.a_val
;
357 ebp
->eb_tag
= EB_PAGESIZE
, (ebp
++)->eb_un
.eb_val
=
358 (Elf32_Word
)page_size
;
359 } else if (ap
->a_type
== AT_SUN_HWCAP
)
360 ap
->a_un
.a_val
&= ~AV_SPARC_HWDIV_32x32
;
363 * If we didn't get a page size from looking in the auxiliary
364 * vector, we need to get one now.
366 if (page_size
== 0) {
367 page_size
= sysconfig(_CONFIG_PAGESIZE
);
368 ebp
->eb_tag
= EB_PAGESIZE
, (ebp
++)->eb_un
.eb_val
=
369 (Elf32_Word
)page_size
;
373 * Map in the ELF-based ld.so. Note that we're mapping it as
374 * an ELF database, not as a program -- we just want to walk it's
375 * data structures. Further mappings will actually establish the
376 * program in the address space.
378 if ((fd
= open(ldso
, O_RDONLY
)) == -1)
379 panic("unable to open %s", ldso
);
380 if (fstat(fd
, &sb
) == -1)
381 panic("unable to find size of %s", ldso
);
382 ehdr
= (Elf32_Ehdr
*)mmap(0, sb
.st_size
, PROT_READ
| PROT_EXEC
,
384 if (ehdr
== (Elf32_Ehdr
*)-1)
385 panic("unable to map %s", ldso
);
388 * Validate the file we're looking at, ensure it has the correct
389 * ELF structures, such as: ELF magic numbers, coded for SPARC,
392 if (ehdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
393 ehdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
394 ehdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
395 ehdr
->e_ident
[EI_MAG3
] != ELFMAG3
)
396 panic("%s is not an ELF file", ldso
);
397 if (ehdr
->e_ident
[EI_CLASS
] != ELFCLASS32
||
398 ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
)
399 panic("%s has wrong class or data encoding", ldso
);
400 if (ehdr
->e_type
!= ET_DYN
)
401 panic("%s is not a shared object", ldso
);
402 if ((ehdr
->e_machine
!= EM_SPARC
) &&
403 (ehdr
->e_machine
!= EM_SPARC32PLUS
))
404 panic("%s is not a valid SPARC object: e_machine: %x",
405 ldso
, ehdr
->e_machine
);
406 if (ehdr
->e_version
> EV_CURRENT
)
407 panic("%s has bad ELF version of %d", ldso
, ehdr
->e_version
);
410 * Point at program headers and start figuring out what to load.
412 phdr
= (Elf32_Phdr
*)((caddr_t
)ehdr
+ ehdr
->e_phoff
);
413 for (p
= 0, pptr
= phdr
; p
< (int)ehdr
->e_phnum
; p
++,
414 pptr
= (Elf32_Phdr
*)((caddr_t
)pptr
+ ehdr
->e_phentsize
))
415 if (pptr
->p_type
== PT_LOAD
) {
418 } else if (pptr
->p_vaddr
<= lph
->p_vaddr
)
420 "%s invalid program header - segments out of order", ldso
);
425 * We'd better have at least one loadable segment.
428 panic("%s has no loadable segments", ldso
);
431 * Map enough address space to hold the program (as opposed to the
432 * file) represented by ld.so. The amount to be assigned is the
433 * range between the end of the last loadable segment and the
434 * beginning of the first PLUS the alignment of the first segment.
435 * mmap() can assign us any page-aligned address, but the relocations
436 * assume the alignments included in the program header. As an
437 * optimization, however, let's assume that mmap() will actually
438 * give us an aligned address -- since if it does, we can save
439 * an munmap() later on. If it doesn't -- then go try it again.
441 mlen
= ROUND((lph
->p_vaddr
+ lph
->p_memsz
) -
442 ALIGN(fph
->p_vaddr
, page_size
), page_size
);
443 maddr
= (caddr_t
)mmap(0, mlen
, PROT_READ
| PROT_EXEC
,
445 if (maddr
== (caddr_t
)-1)
446 panic("unable to reserve space for %s", ldso
);
447 faddr
= (caddr_t
)ROUND(maddr
, fph
->p_align
);
450 * Check to see whether alignment skew was really needed.
452 if (faddr
!= maddr
) {
453 (void) munmap(maddr
, mlen
);
454 mlen
= ROUND((lph
->p_vaddr
+ lph
->p_memsz
) -
455 ALIGN(fph
->p_vaddr
, fph
->p_align
) + fph
->p_align
,
457 maddr
= (caddr_t
)mmap(0, mlen
, PROT_READ
| PROT_EXEC
,
459 if (maddr
== (caddr_t
)-1)
460 panic("unable to reserve space for %s", ldso
);
461 faddr
= (caddr_t
)ROUND(maddr
, fph
->p_align
);
463 ebp
->eb_tag
= EB_LDSO_BASE
, (ebp
++)->eb_un
.eb_ptr
= (Elf32_Addr
)faddr
;
466 * We have the address space reserved, so map each loadable segment.
468 for (pptr
= phdr
; (pptr
- phdr
) < (int)ehdr
->e_phnum
; pptr
++) {
471 * Skip non-loadable segments or segments that don't occupy
474 if ((pptr
->p_type
!= PT_LOAD
) || (pptr
->p_memsz
== 0))
478 * Determine the file offset to which the mapping will
479 * directed (must be aligned) and how much to map (might
480 * be more than the file in the case of .bss.)
482 foff
= ALIGN(pptr
->p_offset
, page_size
);
483 flen
= pptr
->p_memsz
+ (pptr
->p_offset
- foff
);
486 * Set address of this segment relative to our base.
488 addr
= (caddr_t
)ALIGN(faddr
+ pptr
->p_vaddr
, page_size
);
491 * Unmap anything form the last mapping address to this
495 (void) munmap(maddr
, addr
- maddr
);
496 mlen
-= addr
- maddr
;
500 * Determine the mapping protection from the section
504 if (pptr
->p_flags
& PF_R
)
506 if (pptr
->p_flags
& PF_W
)
508 if (pptr
->p_flags
& PF_X
)
510 if ((caddr_t
)mmap((caddr_t
)addr
, flen
, i
,
511 MAP_FIXED
| MAP_PRIVATE
, fd
, foff
) == (caddr_t
)-1)
512 panic("unable to map a segment from %s", ldso
);
515 * If the memory occupancy of the segment overflows the
516 * definition in the file, we need to "zero out" the
517 * end of the mapping we've established, and if necessary,
518 * map some more space from /dev/zero.
520 if (pptr
->p_memsz
> pptr
->p_filesz
) {
521 foff
= (int)faddr
+ pptr
->p_vaddr
+ pptr
->p_filesz
;
522 zaddr
= (caddr_t
)ROUND(foff
, page_size
);
523 _zero(foff
, zaddr
- foff
);
524 r
= (faddr
+ pptr
->p_vaddr
+ pptr
->p_memsz
) - zaddr
;
526 if ((caddr_t
)mmap((caddr_t
)zaddr
, r
, i
,
527 MAP_FIXED
| MAP_PRIVATE
, ip
->crt_dzfd
,
530 "unable to map .bss /dev/zero for %s",
535 * Update the mapping claim pointer.
537 maddr
= addr
+ ROUND(flen
, page_size
);
538 mlen
-= maddr
- addr
;
542 * Unmap any final reservation.
545 (void) munmap(maddr
, mlen
);
548 * Clean up file descriptor space we've consumed. Pass along
549 * the /dev/zero file descriptor we got -- every cycle counts.
554 * The call itself. Note that we start 1 instruction word in.
555 * The ELF ld.so contains an "entry vector" of branch instructions,
556 * which, for our interest are:
557 * +0: ba, a <normal startup>
558 * +4: ba, a <compatibility startup>
559 * By starting at the compatibility startup, the ELF ld.so knows
560 * that a pointer to "eb" is available to it and further knows
561 * how to calculate the offset to the program's arguments and
564 ebp
->eb_tag
= EB_NULL
, ebp
->eb_un
.eb_val
= 0;
565 (*((void (*)())(ehdr
->e_entry
+ faddr
+ sizeof (long))))(eb
);