| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /* $NetBSD: crt0-common.c,v 1.27 2022/06/21 06:52:17 skrll Exp $ */ | 1 | /* $NetBSD: crt0-common.c,v 1.30 2025/05/02 23:04:06 riastradh Exp $ */ |
| 2 | | 2 | |
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 1998 Christos Zoulas | 4 | * Copyright (c) 1998 Christos Zoulas |
| ... | @@ -36,13 +36,16 @@ | ... | @@ -36,13 +36,16 @@ |
| 36 | */ | 36 | */ |
| 37 | | 37 | |
| 38 | #include <sys/cdefs.h> | 38 | #include <sys/cdefs.h> |
| 39 | __RCSID("$NetBSD: crt0-common.c,v 1.27 2022/06/21 06:52:17 skrll Exp $"); | 39 | __RCSID("$NetBSD: crt0-common.c,v 1.30 2025/05/02 23:04:06 riastradh Exp $"); |
| 40 | | 40 | |
| 41 | #include <sys/types.h> | 41 | #include <sys/types.h> |
| 42 | #include <sys/exec.h> | 42 | #include <sys/exec.h> |
| 43 | #include <sys/exec_elf.h> | 43 | #include <sys/exec_elf.h> |
| 44 | #include <sys/syscall.h> | 44 | #include <sys/syscall.h> |
| | 45 | |
| 45 | #include <machine/profile.h> | 46 | #include <machine/profile.h> |
| | 47 | |
| | 48 | #include <limits.h> |
| 46 | #include <stdlib.h> | 49 | #include <stdlib.h> |
| 47 | #include <unistd.h> | 50 | #include <unistd.h> |
| 48 | | 51 | |
| ... | @@ -55,7 +58,6 @@ typedef void (*fptr_t)(void); | ... | @@ -55,7 +58,6 @@ typedef void (*fptr_t)(void); |
| 55 | extern void	_init(void); | 58 | extern void	_init(void); |
| 56 | extern void	_fini(void); | 59 | extern void	_fini(void); |
| 57 | #endif | 60 | #endif |
| 58 | extern void	_libc_init(void); | | |
| 59 | | 61 | |
| 60 | /* | 62 | /* |
| 61 | * Arrange for _DYNAMIC to be weak and undefined (and therefore to show up | 63 | * Arrange for _DYNAMIC to be weak and undefined (and therefore to show up |
| ... | @@ -254,11 +256,19 @@ relocate_self(struct ps_strings *ps_strings) | ... | @@ -254,11 +256,19 @@ relocate_self(struct ps_strings *ps_strings) |
| 254 | | 256 | |
| 255 | 	Elf_Dyn *dynp = (Elf_Dyn *)((uint8_t *)dynphdr->p_vaddr + relocbase); | 257 | 	Elf_Dyn *dynp = (Elf_Dyn *)((uint8_t *)dynphdr->p_vaddr + relocbase); |
| 256 | | 258 | |
| | 259 | 	const Elf_Relr *relr = 0, *relrlim; |
| 257 | 	const REL_TYPE *relocs = 0, *relocslim; | 260 | 	const REL_TYPE *relocs = 0, *relocslim; |
| 258 | 	Elf_Addr relocssz = 0; | 261 | 	Elf_Addr relrsz = 0, relocssz = 0; |
| 259 | | 262 | |
| 260 | 	for (; dynp->d_tag != DT_NULL; dynp++) { | 263 | 	for (; dynp->d_tag != DT_NULL; dynp++) { |
| 261 | 		switch (dynp->d_tag) { | 264 | 		switch (dynp->d_tag) { |
| | 265 | 		case DT_RELR: |
| | 266 | 			relr = |
| | 267 | 			 (const Elf_Relr *)(relocbase + dynp->d_un.d_ptr); |
| | 268 | 			break; |
| | 269 | 		case DT_RELRSZ: |
| | 270 | 			relrsz = dynp->d_un.d_val; |
| | 271 | 			break; |
| 262 | 		case REL_TAG: | 272 | 		case REL_TAG: |
| 263 | 			relocs = | 273 | 			relocs = |
| 264 | 			 (const REL_TYPE *)(relocbase + dynp->d_un.d_ptr); | 274 | 			 (const REL_TYPE *)(relocbase + dynp->d_un.d_ptr); |
| ... | @@ -268,7 +278,22 @@ relocate_self(struct ps_strings *ps_strings) | ... | @@ -268,7 +278,22 @@ relocate_self(struct ps_strings *ps_strings) |
| 268 | 			break; | 278 | 			break; |
| 269 | 		} | 279 | 		} |
| 270 | 	} | 280 | 	} |
| | 281 | 	relrlim = (const Elf_Relr *)((const uint8_t *)relr + relrsz); |
| 271 | 	relocslim = (const REL_TYPE *)((const uint8_t *)relocs + relocssz); | 282 | 	relocslim = (const REL_TYPE *)((const uint8_t *)relocs + relocssz); |
| | 283 | 	while (relr < relrlim) { |
| | 284 | 		Elf_Addr *where; |
| | 285 | |
| | 286 | 		where = (Elf_Addr *)(relocbase + *relr); |
| | 287 | 		*where++ += relocbase; |
| | 288 | 		while (++relr < relrlim && *relr & 1) { |
| | 289 | 			unsigned i; |
| | 290 | |
| | 291 | 			for (i = 1; i < CHAR_BIT*sizeof(*relr); i++, where++) { |
| | 292 | 				if (*relr & ((Elf_Relr)1 << i)) |
| | 293 | 					*where += relocbase; |
| | 294 | 			} |
| | 295 | 		} |
| | 296 | 	} |
| 272 | 	for (; relocs < relocslim; ++relocs) { | 297 | 	for (; relocs < relocslim; ++relocs) { |
| 273 | 		Elf_Addr *where; | 298 | 		Elf_Addr *where; |
| 274 | | 299 | |
| ... | @@ -318,9 +343,6 @@ ___start(void (*cleanup)(void),			/* from shared loader */ | ... | @@ -318,9 +343,6 @@ ___start(void (*cleanup)(void),			/* from shared loader */ |
| 318 | 		__progname = empty_string; | 343 | 		__progname = empty_string; |
| 319 | 	} | 344 | 	} |
| 320 | | 345 | |
| 321 | 	if (cleanup != NULL) | | |
| 322 | 		atexit(cleanup); | | |
| 323 | | | |
| 324 | 	_libc_init(); | 346 | 	_libc_init(); |
| 325 | | 347 | |
| 326 | 	if (&rtld_DYNAMIC == NULL) { | 348 | 	if (&rtld_DYNAMIC == NULL) { |
| ... | @@ -334,6 +356,9 @@ ___start(void (*cleanup)(void),			/* from shared loader */ | ... | @@ -334,6 +356,9 @@ ___start(void (*cleanup)(void),			/* from shared loader */ |
| 334 | | 356 | |
| 335 | 	_preinit(); | 357 | 	_preinit(); |
| 336 | | 358 | |
| | 359 | 	if (cleanup != NULL) |
| | 360 | 		atexit(cleanup); |
| | 361 | |
| 337 | #ifdef MCRT0 | 362 | #ifdef MCRT0 |
| 338 | 	atexit(_mcleanup); | 363 | 	atexit(_mcleanup); |
| 339 | 	monstartup((u_long)&__eprol, (u_long)&__etext); | 364 | 	monstartup((u_long)&__eprol, (u_long)&__etext); |