Mercurial > illumos > illumos-gate
changeset 6206:6b0ed502a8e7
PSARC 2008/179 cross link-editor
6671255 link-editor should support cross linking
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/cmd/sgs/libld/common/libld.chk.msg Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,42 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +@ _START_ + +# Messages to satisfy chkmsg target. Numerous messages within common code +# (reloc.h) aren't required for each target, but chkmsg has no way of dealing +# with ifdefs, thus this file exists to satisfy common code messages. + +@ MSG_REL_UNIMPL "relocation error: file %s: symbol %s: \ + unimplemented relocation type: %d" +@ MSG_REL_UNNOBITS "relocation error: %s: file %s: symbol %s: \ + unsupported number of bits: %d" +@ MSG_REL_LOSEBITS "relocation error: %s: file %s: symbol %s: \ + value 0x%llx loses %d bits at offset 0x%llx" + +@ _END_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/cmd/sgs/libld/common/machsym.intel.c Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <debug.h> +#include "_libld.h" + + +/* + * This file contains stub routines since currently register symbols + * are not relevant to the i386 architecture. But - having these + * stub routines avoids #ifdefs in common codes - and I hate that. + */ +/* ARGSUSED */ +int +ld_reg_check(Sym_desc *sdp, Sym *nsym, const char *nname, Ifl_desc *ifl, + Ofl_desc * ofl) +{ + return (1); +} + +/* ARGSUSED */ +int +ld_mach_sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) +{ + return (0); +} + +/* ARGSUSED */ +const char * +ld_is_regsym(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, + int symndx, Word shndx, const char *symsecname, Word * flags) +{ + return (0); +} + +/* ARGSUSED */ +Sym_desc * +ld_reg_find(Sym * sym, Ofl_desc * ofl) +{ + return (0); +} + +/* ARGSUSED */ +int +ld_reg_enter(Sym_desc * sdp, Ofl_desc * ofl) +{ + return (0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/uts/intel/amd64/krtld/relmach.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _RELMACH_H +#define _RELMACH_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Architecture specific flags presented in a architecture neutral format + */ +#define SHF_NEUT_SHORT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* _RELMACH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/uts/intel/ia32/krtld/relmach.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1998-1999 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ifndef _RELMACH_H +#define _RELMACH_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Architecture specific flags presented in a architecture neutral format + */ +#define SHF_NEUT_SHORT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* _RELMACH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/uts/sparc/krtld/relmach.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1998-1999 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ifndef _RELMACH_H +#define _RELMACH_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Architecture specific flags presented in a architecture nutral format + */ +#define SHF_NEUT_SHORT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* _RELMACH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/uts/sparc/sys/machelf.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,190 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_MACHELF_H +#define _SYS_MACHELF_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/elf_SPARC.h> +#ifndef _ASM +#include <sys/types.h> +#include <sys/elf.h> +#include <sys/link.h> /* for Elf*_Dyn */ +#endif /* _ASM */ + +/* + * Make machine class dependent data types transparent to the common code + */ +#if defined(_ELF64) && !defined(_ELF32_COMPAT) + +#ifndef _ASM +typedef Elf64_Xword Xword; +typedef Elf64_Lword Lword; +typedef Elf64_Sxword Sxword; +typedef Elf64_Word Word; +typedef Elf64_Sword Sword; +typedef Elf64_Half Half; +typedef Elf64_Addr Addr; +typedef Elf64_Off Off; +typedef uchar_t Byte; +#endif /* _ASM */ + +#if defined(_KERNEL) +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE_DATA ELF64_R_TYPE_DATA +#define ELF_R_INFO ELF64_R_INFO +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE +#define ELF_M_SYM ELF64_M_SYM +#define ELF_M_SIZE ELF64_M_SIZE +#endif + +#ifndef _ASM +typedef Elf64_Ehdr Ehdr; +typedef Elf64_Shdr Shdr; +typedef Elf64_Sym Sym; +typedef Elf64_Syminfo Syminfo; +typedef Elf64_Rela Rela; +typedef Elf64_Rel Rel; +typedef Elf64_Nhdr Nhdr; +typedef Elf64_Phdr Phdr; +typedef Elf64_Dyn Dyn; +typedef Elf64_Boot Boot; +typedef Elf64_Verdef Verdef; +typedef Elf64_Verdaux Verdaux; +typedef Elf64_Verneed Verneed; +typedef Elf64_Vernaux Vernaux; +typedef Elf64_Versym Versym; +typedef Elf64_Move Move; +typedef Elf64_Cap Cap; +#endif /* _ASM */ + +#else /* _ILP32 */ + +#ifndef _ASM +typedef Elf32_Word Xword; /* Xword/Sxword are 32-bits in Elf32 */ +typedef Elf32_Lword Lword; +typedef Elf32_Sword Sxword; +typedef Elf32_Word Word; +typedef Elf32_Sword Sword; +typedef Elf32_Half Half; +typedef Elf32_Addr Addr; +typedef Elf32_Off Off; +typedef uchar_t Byte; +#endif /* _ASM */ + +#if defined(_KERNEL) +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_INFO ELF32_R_INFO +#define ELF_R_TYPE_DATA(x) (0) +#define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE +#define ELF_M_SYM ELF32_M_SYM +#define ELF_M_SIZE ELF32_M_SIZE +#endif + +#ifndef _ASM +typedef Elf32_Ehdr Ehdr; +typedef Elf32_Shdr Shdr; +typedef Elf32_Sym Sym; +typedef Elf32_Syminfo Syminfo; +typedef Elf32_Rela Rela; +typedef Elf32_Rel Rel; +typedef Elf32_Nhdr Nhdr; +typedef Elf32_Phdr Phdr; +typedef Elf32_Dyn Dyn; +typedef Elf32_Boot Boot; +typedef Elf32_Verdef Verdef; +typedef Elf32_Verdaux Verdaux; +typedef Elf32_Verneed Verneed; +typedef Elf32_Vernaux Vernaux; +typedef Elf32_Versym Versym; +typedef Elf32_Move Move; +typedef Elf32_Cap Cap; +#endif /* _ASM */ + +#endif /* _ILP32 */ + +/* + * Elf `printf' type-cast macros. These force arguments to be a fixed size + * so that Elf32 and Elf64 can share common format strings. + */ +#ifndef __lint +#define EC_ADDR(a) ((Elf64_Addr)(a)) /* "ull" */ +#define EC_OFF(a) ((Elf64_Off)(a)) /* "ull" */ +#define EC_HALF(a) ((Elf64_Half)(a)) /* "d" */ +#define EC_WORD(a) ((Elf64_Word)(a)) /* "u" */ +#define EC_SWORD(a) ((Elf64_Sword)(a)) /* "d" */ +#define EC_XWORD(a) ((Elf64_Xword)(a)) /* "ull" */ +#define EC_SXWORD(a) ((Elf64_Sxword)(a)) /* "ll" */ +#define EC_LWORD(a) ((Elf64_Lword)(a)) /* "ull" */ + +/* + * A native pointer is special. Although it can be convenient to display + * these from a common format (ull), compilers may flag the cast of a pointer + * to an integer as illegal. Casting these pointers to the native pointer + * size, suppresses any compiler errors. + */ +#define EC_NATPTR(a) ((Elf64_Xword)(uintptr_t)(a)) /* "ull" */ +#else +#define EC_ADDR(a) ((u_longlong_t)(a)) +#define EC_OFF(a) ((u_longlong_t)(a)) +#define EC_HALF(a) ((ushort_t)(a)) +#define EC_WORD(a) ((uint_t)(a)) +#define EC_SWORD(a) ((int)(a)) +#define EC_XWORD(a) ((u_longlong_t)(a)) +#define EC_SXWORD(a) ((longlong_t)(a)) +#define EC_LWORD(a) ((u_longlong_t)(a)) + +#define EC_NATPTR(a) ((u_longlong_t)(a)) +#endif + +#ifndef _ASM +/* + * Structure used to build the reloc_table[] + */ +typedef struct { + Xword re_mask; /* mask to apply to reloc */ + Word re_flags; /* relocation attributes */ + uchar_t re_fsize; /* field size (in bytes) */ + uchar_t re_bshift; /* number of bits to shift */ + uchar_t re_sigbits; /* number of significant bits */ +} Rel_entry; + +#endif /* _ASM */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_MACHELF_H */
--- a/usr/src/cmd/sgs/crle/common/lintsup.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/crle/common/lintsup.c Tue Mar 18 09:17:00 2008 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,8 +22,8 @@ /* PROTOLIB1 */ /* - * Copyright (c) 1999 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,6 +32,8 @@ * Supplimental Pseudo-code to get lint to consider * these symbols used. */ +#include <link.h> +#include <_libelf.h> #include "msg.h" void
--- a/usr/src/cmd/sgs/crle/inc.flg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/crle/inc.flg Tue Mar 18 09:17:00 2008 -0700 @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -23,7 +22,7 @@ # # ident "%Z%%M% %I% %E% SMI" # -# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # A combination of requirements and instructions for building crle and @@ -38,13 +37,11 @@ echo_file usr/src/cmd/sgs/packages/common/SUNWonld-README -echo_file usr/src/uts/intel/sys/machelf.h +echo_file usr/src/uts/common/sys/machelf.h echo_file usr/src/uts/intel/sys/Makefile -echo_file usr/src/uts/sparc/sys/machelf.h echo_file usr/src/uts/sparc/sys/Makefile echo_file usr/src/uts/common/krtld/reloc.h -echo_file usr/src/uts/intel/ia32/krtld/relmach.h -echo_file usr/src/uts/sparc/krtld/relmach.h +echo_file usr/src/uts/common/krtld/reloc_defs.h echo_file usr/src/cmd/sgs/rtld/common/_elf.h echo_file usr/src/cmd/sgs/rtld/common/_rtld.h @@ -71,12 +68,6 @@ # # (cd $SRC/cmd/sgs/tools ; NATIVECC=cc make -e) # -# The following is needed to install system headers: -# -# mkdir -p $ROOT/usr/include/sys -# (cd $SRC/uts/$MACH/sys ; make $ROOT/usr/include/sys/machelf.h), or -# (cd $SRC/uts/intel/sys ; make $ROOT/usr/include/sys/machelf.h) -# # The following is required to build libconv.a: # # (cd $SRC/cmd/sgs/libconv ; make install lint)
--- a/usr/src/cmd/sgs/dump/common/dump.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/dump/common/dump.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,7 +37,7 @@ #include <locale.h> #include <unistd.h> #include <libelf.h> -#include <link.h> +#include <sys/link.h> #include <sys/elf.h> #include <sys/machelf.h> #include <fcntl.h> @@ -1232,12 +1232,14 @@ break; /* - * Items that are bitmasks + * Integer items that are bitmasks, or which + * can be otherwise formatted in symbolic form. */ case DT_FLAGS: case DT_FEATURE_1: case DT_POSFLAG_1: case DT_FLAGS_1: + case DT_SUNW_LDMACH: str = NULL; if (v_flag) { switch (p_dyn.d_tag) { @@ -1264,6 +1266,11 @@ p_dyn.d_un.d_val, 0, &conv_buf.dyn_flag1); break; + case DT_SUNW_LDMACH: + str = conv_ehdr_mach( + p_dyn.d_un.d_val, 0, + &conv_buf.inv); + break; } } if (str) { /* Show as string */
--- a/usr/src/cmd/sgs/elfdump/common/_elfdump.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfdump/common/_elfdump.h Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include <machelf.h> +#include <_machelf.h> #include <debug.h> /*
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -28,10 +28,10 @@ /* * Dump an elf file. */ -#include <machdep.h> #include <sys/elf_386.h> #include <sys/elf_amd64.h> #include <sys/elf_SPARC.h> +#include <_libelf.h> #include <dwarf.h> #include <stdio.h> #include <unistd.h> @@ -1523,8 +1523,8 @@ (sym->st_shndx >= state->shnum)) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM5), state->file, - state->secname, demangle(symname, state->flags), - sym->st_shndx); + state->secname, EC_WORD(symndx), + demangle(symname, state->flags), sym->st_shndx); } /* @@ -1574,13 +1574,15 @@ ((tshdr->sh_flags & SHF_TLS) == 0)) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM3), state->file, - state->secname, demangle(symname, state->flags)); + state->secname, EC_WORD(symndx), + demangle(symname, state->flags)); } } else if ((type != STT_SECTION) && sym->st_size && tshdr && (tshdr->sh_flags & SHF_TLS)) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM4), state->file, - state->secname, demangle(symname, state->flags)); + state->secname, EC_WORD(symndx), + demangle(symname, state->flags)); } /* @@ -1608,7 +1610,8 @@ if (((v + sym->st_size) > tshdr->sh_size)) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM6), state->file, - state->secname, demangle(symname, state->flags), + state->secname, EC_WORD(symndx), + demangle(symname, state->flags), EC_WORD(shndx), EC_XWORD(tshdr->sh_size), EC_XWORD(sym->st_value), EC_XWORD(sym->st_size)); } @@ -1629,8 +1632,8 @@ if ((symndx < info) && (bind != STB_LOCAL)) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM7), state->file, - state->secname, demangle(symname, state->flags), - EC_XWORD(info)); + state->secname, EC_WORD(symndx), + demangle(symname, state->flags), EC_XWORD(info)); } else if ((symndx >= info) && (bind == STB_LOCAL) && ((sym->st_shndx != SHN_UNDEF) || @@ -1638,8 +1641,8 @@ (sym->st_size != 0) || (sym->st_value != 0))) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM8), state->file, - state->secname, demangle(symname, state->flags), - EC_XWORD(info)); + state->secname, EC_WORD(symndx), + demangle(symname, state->flags), EC_XWORD(info)); } } @@ -1897,6 +1900,7 @@ for (relndx = 0; relndx < relnum; relndx++, rels = (void *)((char *)rels + relsize)) { + Half mach = ehdr->e_machine; char section[BUFSIZ]; const char *symname; Word symndx, reltype; @@ -1910,11 +1914,11 @@ if (type == SHT_RELA) { rela = (Rela *)rels; symndx = ELF_R_SYM(rela->r_info); - reltype = ELF_R_TYPE(rela->r_info); + reltype = ELF_R_TYPE(rela->r_info, mach); } else { rel = (Rel *)rels; symndx = ELF_R_SYM(rel->r_info); - reltype = ELF_R_TYPE(rel->r_info); + reltype = ELF_R_TYPE(rel->r_info, mach); } symname = relsymname(cache, _cache, strsec, symndx, @@ -1926,7 +1930,6 @@ * relocations. */ if (symndx == 0) { - Half mach = ehdr->e_machine; int badrel = 0; if ((mach == EM_SPARC) || @@ -2250,6 +2253,7 @@ for (ndx = 0; ndx < numdyn; dyn++, ndx++) { union { + Conv_inv_buf_t inv; Conv_dyn_flag_buf_t flag; Conv_dyn_flag1_buf_t flag1; Conv_dyn_posflag1_buf_t posflag1; @@ -2348,6 +2352,11 @@ name = MSG_INTL(MSG_STR_DEPRECATED); break; + case DT_SUNW_LDMACH: + name = conv_ehdr_mach((Half)dyn->d_un.d_val, 0, + &c_buf.inv); + break; + /* * Cases below this point are strictly sanity checking, * and do not generate a name string. The TEST_ macros @@ -2626,7 +2635,8 @@ (cache[shndx].c_shdr)->sh_type == SHT_NOBITS))) { (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYM2), file, - _cache->c_name, demangle(symname, flags)); + _cache->c_name, EC_WORD(symndx), + demangle(symname, flags)); } (void) snprintf(index, MAXNDXSIZE, @@ -3111,6 +3121,7 @@ char *gotdata; Sym *gotsym; Xword gotsymaddr; + uint_t sys_encoding; /* * First, find the got. @@ -3247,12 +3258,14 @@ if (type == SHT_RELA) { rela = (Rela *)rels; symndx = ELF_R_SYM(rela->r_info); - reltype = ELF_R_TYPE(rela->r_info); + reltype = ELF_R_TYPE(rela->r_info, + ehdr->e_machine); offset = rela->r_offset; } else { rel = (Rel *)rels; symndx = ELF_R_SYM(rel->r_info); - reltype = ELF_R_TYPE(rel->r_info); + reltype = ELF_R_TYPE(rel->r_info, + ehdr->e_machine); offset = rel->r_offset; } @@ -3293,6 +3306,7 @@ dbg_print(0, MSG_INTL(MSG_ELF_SCN_GOT), gotcache->c_name); Elf_got_title(0); + sys_encoding = _elf_sys_encoding(); for (gotndx = 0; gotndx < gotents; gotndx++) { Got_info *gip; Sword gindex; @@ -3312,6 +3326,7 @@ gotentry = *((Xword *)(gotdata) + gotndx); Elf_got_entry(0, gindex, gaddr, gotentry, ehdr->e_machine, + ehdr->e_ident[EI_DATA], sys_encoding, gip->g_reltype, gip->g_rel, gip->g_symname); } free(gottable);
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -92,19 +92,20 @@ @ MSG_ERR_BADSHINFO "%s: %s: invalid sh_info: %d\n" @ MSG_ERR_BADSHTYPE "%s: %s: invalid sh_type: %d\n" @ MSG_ERR_BADALIGN "%s: %s: bad sh_offset alignment\n" -@ MSG_ERR_BADSYM2 "%s: %s: bad symbol entry: %s: must be SHN_COMMON or \ +@ MSG_ERR_BADSYM2 "%s: %s: index[%d]: bad symbol entry: %s: must be SHN_COMMON or \ defined in SHT_NOBITS section\n" -@ MSG_ERR_BADSYM3 "%s: %s: bad symbol entry: %s: must be defined in \ +@ MSG_ERR_BADSYM3 "%s: %s: index[%d]: bad symbol entry: %s: must be defined in \ a SHF_TLS section\n" -@ MSG_ERR_BADSYM4 "%s: %s: bad symbol entry: %s: must be defined in \ +@ MSG_ERR_BADSYM4 "%s: %s: index[%d]: bad symbol entry: %s: must be defined in \ a non-SHF_TLS section\n" -@ MSG_ERR_BADSYM5 "%s: %s: bad symbol entry: %s: invalid shndx: %d\n" -@ MSG_ERR_BADSYM6 "%s: %s: bad symbol entry: %s: section[%d] \ +@ MSG_ERR_BADSYM5 "%s: %s: index[%d]: bad symbol entry: %s: \ + invalid shndx: %d\n" +@ MSG_ERR_BADSYM6 "%s: %s: index[%d]: bad symbol entry: %s: section[%d] \ size: %#llx: symbol (address %#llx, size %#llx) \ lies outside of containing section\n" -@ MSG_ERR_BADSYM7 "%s: %s: suspicious global symbol entry: %s: lies \ +@ MSG_ERR_BADSYM7 "%s: %s: index[%d]: suspicious global symbol entry: %s: lies \ within local symbol range (index < %lld)\n" -@ MSG_ERR_BADSYM8 "%s: %s: suspicious local symbol entry: %s: lies \ +@ MSG_ERR_BADSYM8 "%s: %s: index[%d]: suspicious local symbol entry: %s: lies \ within global symbol range (index >= %lld)\n" @ MSG_ERR_RELBADSYMNDX "%s: bad symbol reference %d: from relocation \
--- a/usr/src/cmd/sgs/elfdump/common/fake_shdr.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfdump/common/fake_shdr.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -61,7 +61,6 @@ -#include <machdep.h> #include <sys/elf_amd64.h> #include <stdio.h> #include <unistd.h> @@ -156,13 +155,28 @@ Elf_Type libelf_type; } SINFO_DATA; +/* + * Many of these sections use an alignment given by M_WORD_ALIGN, a + * value that varies depending on the object target machine. Since we + * don't know that value at compile time, we settle for a value of + * 4 for ELFCLASS32 objects, and 8 for ELFCLASS64. This matches the + * platforms we current support (sparc and x86), and is good enough for + * a fake section header in any event, as the resulting object is only + * analyzed, and is not executed. + */ +#ifdef _ELF64 +#define FAKE_M_WORD_ALIGN 8 +#else +#define FAKE_M_WORD_ALIGN 4 +#endif + static SINFO_DATA sinfo_data[SINFO_T_NUM] = { /* SINFO_T_NULL */ { 0 }, /* SINFO_T_DYN */ { MSG_ORIG(MSG_PHDRNAM_DYN), SHT_DYNAMIC, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Dyn), ELF_T_DYN }, + FAKE_M_WORD_ALIGN, sizeof (Dyn), ELF_T_DYN }, /* SINFO_T_DYNSTR */ { MSG_ORIG(MSG_PHDRNAM_DYNSTR), SHT_STRTAB, SHF_ALLOC, @@ -170,39 +184,39 @@ /* SINFO_T_DYNSYM */ { MSG_ORIG(MSG_PHDRNAM_DYNSYM), SHT_DYNSYM, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, + FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, /* SINFO_T_LDYNSYM */ { MSG_ORIG(MSG_PHDRNAM_LDYNSYM), SHT_SUNW_LDYNSYM, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, + FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, /* SINFO_T_HASH */ { MSG_ORIG(MSG_PHDRNAM_HASH), SHT_HASH, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, + FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, /* SINFO_T_SYMINFO */ { MSG_ORIG(MSG_PHDRNAM_SYMINFO), SHT_SUNW_syminfo, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Syminfo), ELF_T_SYMINFO }, + FAKE_M_WORD_ALIGN, sizeof (Syminfo), ELF_T_SYMINFO }, /* SINFO_T_SYMSORT */ { MSG_ORIG(MSG_PHDRNAM_SYMSORT), SHT_SUNW_symsort, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, + FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, /* SINFO_T_TLSSORT */ { MSG_ORIG(MSG_PHDRNAM_TLSSORT), SHT_SUNW_tlssort, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, + FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, /* SINFO_T_VERNEED */ { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verneed, SHF_ALLOC, - M_WORD_ALIGN, 1, ELF_T_VNEED }, + FAKE_M_WORD_ALIGN, 1, ELF_T_VNEED }, /* SINFO_T_VERDEF */ { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verdef, SHF_ALLOC, - M_WORD_ALIGN, 1, ELF_T_VDEF }, + FAKE_M_WORD_ALIGN, 1, ELF_T_VDEF }, /* SINFO_T_VERSYM */ { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_versym, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Versym), ELF_T_HALF }, + FAKE_M_WORD_ALIGN, sizeof (Versym), ELF_T_HALF }, /* SINFO_T_INTERP */ { MSG_ORIG(MSG_PHDRNAM_INTERP), SHT_PROGBITS, SHF_ALLOC, @@ -222,11 +236,11 @@ /* SINFO_T_REL */ { MSG_ORIG(MSG_PHDRNAM_REL), SHT_REL, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Rel), ELF_T_REL }, + FAKE_M_WORD_ALIGN, sizeof (Rel), ELF_T_REL }, /* SINFO_T_RELA */ { MSG_ORIG(MSG_PHDRNAM_RELA), SHT_RELA, SHF_ALLOC, - M_WORD_ALIGN, sizeof (Rela), ELF_T_RELA }, + FAKE_M_WORD_ALIGN, sizeof (Rela), ELF_T_RELA }, /* SINFO_T_PREINITARR */ { MSG_ORIG(MSG_PHDRNAM_PREINITARR), SHT_PREINIT_ARRAY, SHF_ALLOC, @@ -242,7 +256,7 @@ /* SINFO_T_NOTE */ { MSG_ORIG(MSG_PHDRNAM_NOTE), SHT_NOTE, 0, - M_WORD_ALIGN, 1, ELF_T_NOTE } + FAKE_M_WORD_ALIGN, 1, ELF_T_NOTE } };
--- a/usr/src/cmd/sgs/elfedit/common/elfconst.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/common/elfconst.c Tue Mar 18 09:17:00 2008 -0700 @@ -436,6 +436,9 @@ { MSG_ORIG(MSG_DT_SUNW_STRPAD), DT_SUNW_STRPAD }, { MSG_ORIG(MSG_DT_SUNW_STRPAD_ALT1), DT_SUNW_STRPAD }, + { MSG_ORIG(MSG_DT_SUNW_LDMACH), DT_SUNW_LDMACH }, + { MSG_ORIG(MSG_DT_SUNW_LDMACH_ALT1), DT_SUNW_LDMACH }, + { MSG_ORIG(MSG_DT_SPARC_REGISTER), DT_SPARC_REGISTER }, { MSG_ORIG(MSG_DT_SPARC_REGISTER_ALT1), DT_SPARC_REGISTER },
--- a/usr/src/cmd/sgs/elfedit/common/elfedit.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/common/elfedit.msg Tue Mar 18 09:17:00 2008 -0700 @@ -790,6 +790,8 @@ @ MSG_DT_SUNW_TLSSORTSZ_ALT1 "sunw_tlssortsz" @ MSG_DT_SUNW_STRPAD "DT_SUNW_STRPAD" # 0x60000019 @ MSG_DT_SUNW_STRPAD_ALT1 "sunw_strpad" +@ MSG_DT_SUNW_LDMACH "DT_SUNW_ldmach" # 0x6000001b +@ MSG_DT_SUNW_LDMACH_ALT1 "sunw_ldmach" @ MSG_DT_SPARC_REGISTER "DT_SPARC_REGISTER" # 0x70000001 @ MSG_DT_SPARC_REGISTER_ALT1 "sparc_register" @ MSG_DT_DEPRECATED_SPARC_REGISTER "DT_DEPRECATED_SPARC_REGISTER" # 0x7000001
--- a/usr/src/cmd/sgs/elfedit/common/elfedit_machelf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/common/elfedit_machelf.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,7 +31,7 @@ #include <stdlib.h> #include <stdio.h> #include <unistd.h> -#include <machdep.h> +#include <_machelf.h> #include <libelf.h> #include <strings.h> #include <sgs.h>
--- a/usr/src/cmd/sgs/elfedit/common/sys.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/common/sys.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -45,8 +45,8 @@ * as a sharable object. * - It must be avaialble before the ELFCLASS of the object * is known, so it is not ELFCLASS specific. We don't build - * it twice with machdep.h, as we do for the loadable modules. - * This means that commands need to test for the type + * it twice with <sys/machelf.h>, as we do for the loadable + * modules. This means that commands need to test for the type * of their obj_state argument at runtime. * - The init function signature is different. We build an entire * module definition statically.
--- a/usr/src/cmd/sgs/elfedit/common/util_machelf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/common/util_machelf.c Tue Mar 18 09:17:00 2008 -0700 @@ -29,7 +29,7 @@ #include <stdio.h> #include <unistd.h> #include <libintl.h> -#include <machdep.h> +#include <_machelf.h> #include <libelf.h> #include <link.h> #include <strings.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/cap.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/cap.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,13 +20,12 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <ctype.h> -#include <machdep.h> #include <elfedit.h> #include <sys/elf_SPARC.h> #include <strings.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/dyn.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/dyn.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,13 +20,12 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <ctype.h> -#include <machdep.h> #include <elfedit.h> #include <sys/elf_SPARC.h> #include <strings.h> @@ -63,7 +62,8 @@ DYN_CMD_T_FLAGS = 7, /* dyn:flags */ DYN_CMD_T_FLAGS1 = 8, /* dyn:flags1 */ DYN_CMD_T_FEATURE1 = 9, /* dyn:feature1 */ - DYN_CMD_T_CHECKSUM = 10 /* dyn:checksum */ + DYN_CMD_T_CHECKSUM = 10, /* dyn:checksum */ + DYN_CMD_T_SUNW_LDMACH = 11 /* dyn:sunw_ldmach */ } DYN_CMD_T; @@ -320,6 +320,7 @@ dyn = &argstate->dyn.data[ndx]; for (; cnt--; dyn++, ndx++) { union { + Conv_inv_buf_t inv; Conv_dyn_flag_buf_t flag; Conv_dyn_flag1_buf_t flag1; Conv_dyn_posflag1_buf_t posflag1; @@ -415,6 +416,10 @@ case DT_DEPRECATED_SPARC_REGISTER: name = MSG_INTL(MSG_STR_DEPRECATED); break; + case DT_SUNW_LDMACH: + name = conv_ehdr_mach((Half)dyn->d_un.d_val, 0, + &c_buf.inv); + break; } if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { @@ -1045,6 +1050,15 @@ MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); break; + case DYN_CMD_T_SUNW_LDMACH: + if (argstate.argc > 1) + elfedit_command_usage(); + print_only = (argstate.argc == 0); + ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str( + ELFEDIT_CONST_DT, DT_SUNW_LDMACH, 1), + MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); + break; + default: /* Note expected: All commands should have been caught above */ elfedit_command_usage(); @@ -1318,6 +1332,36 @@ } } + break; + + case DYN_CMD_T_SUNW_LDMACH: + { + Conv_inv_buf_t buf1, buf2; + Half ldmach; + + ldmach = (Half) elfedit_atoconst(argstate.argv[0], + ELFEDIT_CONST_EM); + + /* Set the value */ + if (dyn[ndx].d_un.d_val == ldmach) { + elfedit_msg(ELFEDIT_MSG_DEBUG, + MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx, + dyn_name, EC_WORD(ndx), + conv_ehdr_mach(dyn[ndx].d_un.d_val, 0, + &buf1)); + } else { + elfedit_msg(ELFEDIT_MSG_DEBUG, + MSG_INTL(MSG_DEBUG_S_CHG), + dyn_ndx, dyn_name, EC_WORD(ndx), + conv_ehdr_mach(dyn[ndx].d_un.d_val, 0, + &buf1), + conv_ehdr_mach(ldmach, 0, &buf2)); + ret = ELFEDIT_CMDRET_MOD; + dyn[ndx].d_un.d_val = ldmach; + } + } + break; + } /* @@ -1454,6 +1498,22 @@ elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DTF_1); } +/*ARGSUSED*/ +static void +cpl_sunw_ldmach(elfedit_obj_state_t *obj_state, void *cpldata, int argc, + const char *argv[], int num_opt) +{ + /* + * This command doesn't accept options, so num_opt should be + * 0. This is a defensive measure, in case that should change. + */ + argc -= num_opt; + argv += num_opt; + + if (argc == 1) + elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM); +} + /* * Implementation functions for the commands @@ -1524,6 +1584,12 @@ return (cmd_body(DYN_CMD_T_CHECKSUM, obj_state, argc, argv)); } +static elfedit_cmdret_t +cmd_sunw_ldmach(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) +{ + return (cmd_body(DYN_CMD_T_SUNW_LDMACH, obj_state, argc, argv)); +} + /*ARGSUSED*/ @@ -1718,6 +1784,17 @@ static const char *name_checksum[] = { MSG_ORIG(MSG_CMD_CHECKSUM), NULL }; + /* dyn:sunw_ldmach */ + static const char *name_sunw_ldmach[] = { MSG_ORIG(MSG_CMD_SUNW_LDMACH), + NULL }; + static elfedit_cmd_optarg_t arg_sunw_ldmach[] = { + { MSG_ORIG(MSG_STR_VALUE), + /* MSG_INTL(MSG_A1_SUNW_LDMACH_VALUE) */ + ELFEDIT_I18NHDL(MSG_A1_SUNW_LDMACH_VALUE), + ELFEDIT_CMDOA_F_OPT }, + { NULL } + }; + static elfedit_cmd_t cmds[] = { @@ -1809,6 +1886,14 @@ ELFEDIT_I18NHDL(MSG_HELP_CHECKSUM), NULL, NULL }, + /* dyn:sunw_ldmach */ + { cmd_sunw_ldmach, cpl_sunw_ldmach, name_sunw_ldmach, + /* MSG_INTL(MSG_DESC_SUNW_LDMACH) */ + ELFEDIT_I18NHDL(MSG_DESC_SUNW_LDMACH), + /* MSG_INTL(MSG_HELP_SUNW_LDMACH) */ + ELFEDIT_I18NHDL(MSG_HELP_SUNW_LDMACH), + opt_ostyle, arg_sunw_ldmach }, + { NULL } };
--- a/usr/src/cmd/sgs/elfedit/modules/common/dyn.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/dyn.msg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -91,6 +91,7 @@ @ MSG_DESC_FLAGS1 "DT_FLAGS_1 bit values" @ MSG_DESC_FEATURE1 "DT_FEATURE_1 bit values" @ MSG_DESC_CHECKSUM "Recompute DT_CHECKSUM" +@ MSG_DESC_SUNW_LDMACH "Linker machine type" # Commmand option description strings @@ -189,6 +190,11 @@ the DTF_1_ symbolic constants defined in\n\ /usr/include/sys/link.h\n" +@ MSG_A1_SUNW_LDMACH_VALUE "\ + Machine type of link-editor that built the object being edited.\n\ + This can be an integer value, or any of the EM_ symbolic\n\ + constants defined in /usr/include/elf.h\n" + # Help strings @@ -386,6 +392,22 @@ DT_CHECKSUM element, and room for it exists at the end\n\ of the section, a new one is inserted.\n" +@ MSG_HELP_SUNW_LDMACH " \ + The dyn:sunw_ldmach command is used to display or alter the\n\ + DT_SUNW_LDMACH dynamic element of the ELF object. This dynamic\n\ + element records the ELF machine type of the link-editor that produced\n\ + the object. This is of special interest if the object was built\n\ + by a cross link-editor instead of being linked on a machine of the\n\ + same type as the object.\n\ + \n\ + If dyn:sunw_ldmach is called without arguments, the current\n\ + value is shown. If called with the value argument, the\n\ + DT_SUNW_LDMACH dynamic element is set to the specified machine type.\n\ + \n\ + If the current dynamic section does not have a current\n\ + DT_SUNW_LDMACH element, and room for it exists at the end\n\ + of the section, a new one is inserted.\n" + @ _END_ @@ -429,3 +451,4 @@ @ MSG_CMD_FLAGS1 "flags1" @ MSG_CMD_FEATURE1 "feature1" @ MSG_CMD_CHECKSUM "checksum" +@ MSG_CMD_SUNW_LDMACH "sunw_ldmach"
--- a/usr/src/cmd/sgs/elfedit/modules/common/ehdr.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/ehdr.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,14 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <ctype.h> -#include <machdep.h> #include <elfedit.h> #include <sys/elf_SPARC.h> #include <sys/elf_amd64.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/phdr.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/phdr.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,12 +20,11 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -#include <machdep.h> #include <elfedit.h> #include <strings.h> #include <conv.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/shdr.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/shdr.c Tue Mar 18 09:17:00 2008 -0700 @@ -27,7 +27,6 @@ #include <stdio.h> #include <unistd.h> -#include <machdep.h> #include <elfedit.h> #include <sys/elf_SPARC.h> #include <sys/elf_amd64.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/str.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/str.c Tue Mar 18 09:17:00 2008 -0700 @@ -28,7 +28,6 @@ #include <stdio.h> #include <ctype.h> #include <unistd.h> -#include <machdep.h> #include <elfedit.h> #include <strings.h> #include <debug.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/sym.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/sym.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -29,7 +29,6 @@ #include <stdio.h> #include <unistd.h> -#include <machdep.h> #include <elfedit.h> #include <strings.h> #include <debug.h>
--- a/usr/src/cmd/sgs/elfedit/modules/common/syminfo.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/elfedit/modules/common/syminfo.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,14 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <unistd.h> -#include <machdep.h> #include <elfedit.h> #include <strings.h> #include <debug.h>
--- a/usr/src/cmd/sgs/include/_libelf.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/include/_libelf.h Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,6 +44,7 @@ extern Elf64_Off _elf_getxoff(Elf_Data *); extern GElf_Xword _gelf_getdyndtflags_1(Elf *elf); +extern int _elf_swap_wrimage(Elf *elf); extern uint_t _elf_sys_encoding(void); #ifdef __cplusplus
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/include/_machelf.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Wrapper around the <sys/machelf.h> header that adds + * definitions used by SGS. + */ + +#ifndef _MACHELF_H +#define _MACHELF_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/machelf.h> +#include <string.h> /* memcpy() */ + +/* + * Make machine class dependent functions transparent to the common code + */ + +/* + * Note on ELF_R_TYPE: 64-bit sparc relocations require the use of + * ELF64_R_TYPE_ID instead of the ELF64_R_TYPE macro used for all + * other platforms. So our ELF_R_TYPE macro requires the caller to + * supply the machine type. + */ + + +#if defined(_ELF64) +#define ELF_R_TYPE(_info, _mach) \ + (((_mach) == EM_SPARCV9) ? ELF64_R_TYPE_ID(_info) : ELF64_R_TYPE(_info)) +#define ELF_R_INFO ELF64_R_INFO +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE_DATA(x) ELF64_R_TYPE_DATA(x) +#define ELF_R_TYPE_INFO(xoff, type) ELF64_R_TYPE_INFO(xoff, type) +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE +#define ELF_ST_INFO ELF64_ST_INFO +#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY +#define ELF_M_SYM ELF64_M_SYM +#define ELF_M_SIZE ELF64_M_SIZE +#define ELF_M_INFO ELF64_M_INFO +#define elf_checksum elf64_checksum +#define elf_fsize elf64_fsize +#define elf_getehdr elf64_getehdr +#define elf_getphdr elf64_getphdr +#define elf_newehdr elf64_newehdr +#define elf_newphdr elf64_newphdr +#define elf_getshdr elf64_getshdr +#define elf_xlatetof elf64_xlatetof +#define elf_xlatetom elf64_xlatetom +#else /* _ELF64 */ +#define ELF_R_TYPE(_info, _mach) ELF32_R_TYPE(_info) +#define ELF_R_INFO ELF32_R_INFO +#define ELF_R_SYM ELF32_R_SYM +/* Elf64 can hide extra offset in r_info */ +#define ELF_R_TYPE_DATA(x) (0) +#define ELF_R_TYPE_INFO(xoff, type) (type) +#define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE +#define ELF_ST_INFO ELF32_ST_INFO +#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY +#define ELF_M_SYM ELF32_M_SYM +#define ELF_M_SIZE ELF32_M_SIZE +#define ELF_M_INFO ELF32_M_INFO +#define elf_checksum elf32_checksum +#define elf_fsize elf32_fsize +#define elf_getehdr elf32_getehdr +#define elf_getphdr elf32_getphdr +#define elf_newehdr elf32_newehdr +#define elf_newphdr elf32_newphdr +#define elf_getshdr elf32_getshdr +#define elf_xlatetof elf32_xlatetof +#define elf_xlatetom elf32_xlatetom +#endif /* _ELF32 */ + + +/* + * Macros for swapping bytes. The type of the argument must + * match the type given in the macro name. + */ +#define BSWAP_HALF(_half) \ + (((_half) << 8) | ((_half) >> 8)) + +#define BSWAP_WORD(_word) \ + ((((_word) << 24) | (((_word) & 0xff00) << 8) | \ + (((_word) >> 8) & 0xff00) | ((_word) >> 24))) + +#if defined(_ELF64) +#define BSWAP_XWORD(_xword) \ + (((_xword) << 56) | \ + (((_xword) & 0x0000ff00) << 40) | \ + (((_xword) & 0x00ff0000) << 24) | \ + (((_xword) & 0xff000000) << 8) | \ + (((_xword) >> 8) & 0xff000000) | \ + (((_xword) >> 24) & 0x00ff0000) | \ + (((_xword) >> 40) & 0x0000ff00) | \ + ((_xword) >> 56)) /* Xword is unsigned - 0 bits enter from left */ +#else +#define BSWAP_XWORD(_xword) BSWAP_WORD(_xword) +#endif + +/* + * Macros for assigning Half/Word/Xword items from one location to + * another that are safe no matter what the data alignment rules of the + * running platform are. Variants exist to swap the data byteorder + * at the same time, or not. + * + * These macros are useful for code that accesses data that is aligned + * for a different system architecture, as occurs in cross linking. + * + * All of these macros assume the arguments are passed as pointers to + * bytes (signed or unsigned). + */ + +#define UL_ASSIGN_HALF(_dst, _src) (void) \ + ((_dst)[0] = (_src)[0], (_dst)[1] = (_src)[1]) +#define UL_ASSIGN_WORD(_dst, _src) (void) \ + ((_dst)[0] = (_src)[0], (_dst)[1] = (_src)[1], \ + (_dst)[2] = (_src)[2], (_dst)[3] = (_src)[3]) +#if defined(_ELF64) +#define UL_ASSIGN_XWORD(_dst, _src) (void) memcpy(_dst, (_src), sizeof (Xword)) +#else +#define UL_ASSIGN_XWORD(_xword) UL_ASSIGN_WORD(_xword) +#endif + +#define UL_ASSIGN_BSWAP_HALF(_dst, _src) (void) \ + ((_dst)[0] = (_src)[1], (_dst)[1] = (_src)[0]) +#define UL_ASSIGN_BSWAP_WORD(_dst, _src) (void) \ + ((_dst)[0] = (_src)[3], (_dst)[1] = (_src)[2], \ + (_dst)[2] = (_src)[1], (_dst)[3] = (_src)[0]) +#if defined(_ELF64) +#define UL_ASSIGN_BSWAP_XWORD(_dst, _src) (void) \ + ((_dst)[0] = (_src)[7], (_dst)[1] = (_src)[6], \ + (_dst)[2] = (_src)[5], (_dst)[3] = (_src)[4], \ + (_dst)[4] = (_src)[3], (_dst)[5] = (_src)[2], \ + (_dst)[6] = (_src)[1], (_dst)[7] = (_src)[0]) +#else +#define UL_ASSIGN_BSWAP_XWORD(_dst, _src) UL_ASSIGN_BSWAP_WORD(_dst, _src) +#endif + + +#endif /* _MACHELF_H */
--- a/usr/src/cmd/sgs/include/conv.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/include/conv.h Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,7 +41,6 @@ #include <dlfcn.h> #include <libld.h> #include <sgs.h> -#include <machdep.h> #ifdef __cplusplus extern "C" { @@ -785,7 +784,8 @@ Conv_phdr_flags_buf_t *); extern const char *conv_phdr_type(Half, Word, Conv_fmt_flags_t, Conv_inv_buf_t *); -extern const char *conv_reject_desc(Rej_desc *, Conv_reject_desc_buf_t *); +extern const char *conv_reject_desc(Rej_desc *, Conv_reject_desc_buf_t *, + Half mach); extern const char *conv_reloc_type(Half, Word, Conv_fmt_flags_t, Conv_inv_buf_t *); extern const char *conv_reloc_type_static(Half, Word, Conv_fmt_flags_t);
--- a/usr/src/cmd/sgs/include/debug.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/include/debug.h Tue Mar 18 09:17:00 2008 -0700 @@ -696,11 +696,11 @@ extern void Dbg_file_output(Ofl_desc *); extern void Dbg_file_preload(Lm_list *, const char *); extern void Dbg_file_prot(Rt_map *, int); -extern void Dbg_file_rejected(Lm_list *, Rej_desc *); +extern void Dbg_file_rejected(Lm_list *, Rej_desc *, Half mach); extern void Dbg_file_reuse(Lm_list *, const char *, const char *); extern void Dbg_file_skip(Lm_list *, const char *, const char *); -extern void Dbg_got_display(Ofl_desc *, Off, int); +extern void Dbg_got_display(Ofl_desc *, Off, int, Word, size_t); extern void Dbg_libs_audit(Lm_list *, const char *, const char *); extern void Dbg_libs_find(Lm_list *, const char *); @@ -973,8 +973,8 @@ extern void Elf_ehdr(Lm_list *, Ehdr *, Shdr *); -extern void Elf_got_entry(Lm_list *, Sword, Addr, Xword, Half, Word, void *, - const char *); +extern void Elf_got_entry(Lm_list *, Sword, Addr, Xword, Half, + uchar_t, uchar_t, Word, void *, const char *); extern void Elf_got_title(Lm_list *); extern void Elf_phdr(Lm_list *, Half, Phdr *);
--- a/usr/src/cmd/sgs/include/i386/machdep.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,340 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 1988 AT&T - * All Rights Reserved - * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Global include file for all sgs ia32 based machine dependent macros, - * constants and declarations. - */ - -#ifndef _MACHDEP_H -#define _MACHDEP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <link.h> -#include <sys/machelf.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Elf header information. - */ -#ifdef _ELF64 -#define M_MACH EM_AMD64 -#define M_CLASS ELFCLASS64 -#else -#define M_MACH EM_386 -#define M_CLASS ELFCLASS32 -#endif - -#define M_MACHPLUS M_MACH -#define M_DATA ELFDATA2LSB -#define M_FLAGSPLUS 0 - -/* - * Page boundary Macros: truncate to previous page boundary and round to - * next page boundary (refer to generic macros in ../sgs.h also). - */ -#define M_PTRUNC(X) ((X) & ~(syspagsz - 1)) -#define M_PROUND(X) (((X) + syspagsz - 1) & ~(syspagsz - 1)) - -/* - * Segment boundary macros: truncate to previous segment boundary and round - * to next page boundary. - */ -#if defined(_ELF64) -#define M_SEGSIZE ELF_AMD64_MAXPGSZ -#else -#define M_SEGSIZE ELF_386_MAXPGSZ -#endif - -#define M_STRUNC(X) ((X) & ~(M_SEGSIZE - 1)) -#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1)) - -/* - * TLS static segments must be rounded to the following requirements, - * due to libthread stack allocation. - */ -#if defined(_ELF64) -#define M_TLSSTATALIGN 0x10 -#else -#define M_TLSSTATALIGN 0x08 -#endif - - -/* - * Other machine dependent entities - */ -#if defined(_ELF64) -#define M_SEGM_ALIGN 0x00010000 -#else -#define M_SEGM_ALIGN ELF_386_MAXPGSZ -#endif - -/* - * Values for IA32 objects - */ - -/* - * Instruction encodings. - */ -#define M_INST_JMP 0xe9 -#define M_INST_PUSHL 0x68 -#define M_SPECIAL_INST 0xff -#define M_PUSHL_DISP 0x35 -#define M_PUSHL_REG_DISP 0xb3 -#define M_JMP_DISP_IND 0x25 -#define M_JMP_REG_DISP_IND 0xa3 -#define M_NOP 0x90 - -#define M_BIND_ADJ 1 /* adjustment for end of */ - /* elf_rtbndr() address */ -#ifdef _ELF64 -#define M_WORD_ALIGN 8 -#define M_SEGM_ORIGIN (Addr)0x00400000 /* default first segment offset */ -#else - -#define M_WORD_ALIGN 4 - -#define M_STACK_GAP (0x08000000) -#define M_STACK_PGS (0x00048000) -#define M_SEGM_ORIGIN (Addr)(M_STACK_GAP + M_STACK_PGS) -#endif - - -/* - * Plt and Got information; the first few .got and .plt entries are reserved - * PLT[0] jump to dynamic linker - * GOT[0] address of _DYNAMIC - */ -#define M_PLT_ENTSIZE 16 /* plt entry size in bytes */ -#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ -#define M_PLT_INSSIZE 6 /* single plt instruction size */ -#define M_PLT_RESERVSZ M_PLT_ENTSIZE /* PLT[0] reserved */ - -#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ -#define M_GOT_XLINKMAP 1 /* got index for link map */ -#define M_GOT_XRTLD 2 /* got index for rtbinder */ -#define M_GOT_XNumber 3 /* reserved no. of got entries */ - -#ifdef _ELF64 -#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ -#else /* ELF32 */ -#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ -#endif - -/* - * Make machine class dependent functions transparent to the common code - */ -#if defined(_ELF64) -#define ELF_R_TYPE ELF64_R_TYPE -#define ELF_R_INFO ELF64_R_INFO -#define ELF_R_SYM ELF64_R_SYM -#define ELF_ST_BIND ELF64_ST_BIND -#define ELF_ST_TYPE ELF64_ST_TYPE -#define ELF_ST_INFO ELF64_ST_INFO -#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY -#define ELF_M_SYM ELF64_M_SYM -#define ELF_M_SIZE ELF64_M_SIZE -#define ELF_M_INFO ELF64_M_INFO -#define elf_checksum elf64_checksum -#define elf_fsize elf64_fsize -#define elf_getehdr elf64_getehdr -#define elf_getphdr elf64_getphdr -#define elf_newehdr elf64_newehdr -#define elf_newphdr elf64_newphdr -#define elf_getshdr elf64_getshdr -#define elf_xlatetof elf64_xlatetof -#define elf_xlatetom elf64_xlatetom -#else /* _ELF64 */ -#define ELF_R_TYPE ELF32_R_TYPE -#define ELF_R_INFO ELF32_R_INFO -#define ELF_R_SYM ELF32_R_SYM -#define ELF_ST_BIND ELF32_ST_BIND -#define ELF_ST_TYPE ELF32_ST_TYPE -#define ELF_ST_INFO ELF32_ST_INFO -#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY -#define ELF_M_SYM ELF32_M_SYM -#define ELF_M_SIZE ELF32_M_SIZE -#define ELF_M_INFO ELF32_M_INFO -#define elf_checksum elf32_checksum -#define elf_fsize elf32_fsize -#define elf_getehdr elf32_getehdr -#define elf_getphdr elf32_getphdr -#define elf_newehdr elf32_newehdr -#define elf_newphdr elf32_newphdr -#define elf_getshdr elf32_getshdr -#define elf_xlatetof elf32_xlatetof -#define elf_xlatetom elf32_xlatetom -#endif /* _ELF32 */ - - -/* - * Make common relocation information transparent to the common code - */ -#if defined(_ELF64) -#define M_REL_DT_TYPE DT_RELA /* .dynamic entry */ -#define M_REL_DT_SIZE DT_RELASZ /* .dynamic entry */ -#define M_REL_DT_ENT DT_RELAENT /* .dynamic entry */ -#define M_REL_DT_COUNT DT_RELACOUNT /* .dynamic entry */ -#define M_REL_SHT_TYPE SHT_RELA /* section header type */ -#define M_REL_ELF_TYPE ELF_T_RELA /* data buffer type */ - -#else /* _ELF32 */ -#define M_REL_DT_TYPE DT_REL /* .dynamic entry */ -#define M_REL_DT_SIZE DT_RELSZ /* .dynamic entry */ -#define M_REL_DT_ENT DT_RELENT /* .dynamic entry */ -#define M_REL_DT_COUNT DT_RELCOUNT /* .dynamic entry */ -#define M_REL_SHT_TYPE SHT_REL /* section header type */ -#define M_REL_ELF_TYPE ELF_T_REL /* data buffer type */ - -#endif /* ELF32 */ - -/* - * Make common relocation types transparent to the common code - */ -#if defined(_ELF64) -#define M_R_NONE R_AMD64_NONE -#define M_R_GLOB_DAT R_AMD64_GLOB_DAT -#define M_R_COPY R_AMD64_COPY -#define M_R_RELATIVE R_AMD64_RELATIVE -#define M_R_JMP_SLOT R_AMD64_JUMP_SLOT -#define M_R_FPTR R_AMD64_NONE -#define M_R_ARRAYADDR R_AMD64_GLOB_DAT -#define M_R_NUM R_AMD64_NUM -#else -#define M_R_NONE R_386_NONE -#define M_R_GLOB_DAT R_386_GLOB_DAT -#define M_R_COPY R_386_COPY -#define M_R_RELATIVE R_386_RELATIVE -#define M_R_JMP_SLOT R_386_JMP_SLOT -#define M_R_FPTR R_386_NONE -#define M_R_ARRAYADDR R_386_GLOB_DAT -#define M_R_NUM R_386_NUM -#endif - -/* - * The following are defined as M_R_NONE so that checks - * for these relocations can be performed in common code - although - * the checks are really only relevant to SPARC. - */ -#define M_R_REGISTER M_R_NONE - -/* - * DT_REGISTER is not valid on i386 or amd64 - */ -#define M_DT_REGISTER 0xffffffff -#define M_DT_PLTRESERVE 0xfffffffe - -/* - * Make plt section information transparent to the common code. - */ -#define M_PLT_SHF_FLAGS (SHF_ALLOC | SHF_EXECINSTR) - - -/* - * Make data segment information transparent to the common code. - */ -#ifdef _ELF64 -#define M_DATASEG_PERM (PF_R | PF_W) -#else -#define M_DATASEG_PERM (PF_R | PF_W | PF_X) -#endif - -/* - * Define a set of identifies for special sections. These allow the sections - * to be ordered within the output file image. These values should be - * maintained consistently, where appropriate, in each platform specific header - * file. - * - * o null identifies that this section does not need to be added to the - * output image (ie. shared object sections or sections we're going to - * recreate (sym tables, string tables, relocations, etc.)). - * - * o any user defined section will be first in the associated segment. - * - * o interp and capabilities sections are next, as these are accessed - * immediately the first page of the image is mapped. - * - * o the syminfo, hash, dynsym, dynstr and rel's are grouped together as - * these will all be accessed first by ld.so.1 to perform relocations. - * - * o the got and dynamic are grouped together as these may also be - * accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG - * (executables only), and .got[0]. - * - * o unknown sections (stabs, comments, etc.) go at the end. - * - * Note that .tlsbss/.bss are given the largest identifiers. This insures that - * if any unknown sections become associated to the same segment as the .bss, - * the .bss sections are always the last section in the segment. - */ -#define M_ID_NULL 0x00 -#define M_ID_USER 0x01 - -#define M_ID_INTERP 0x03 /* SHF_ALLOC */ -#define M_ID_CAP 0x04 -#define M_ID_UNWINDHDR 0x05 -#define M_ID_UNWIND 0x06 -#define M_ID_SYMINFO 0x07 -#define M_ID_HASH 0x08 -#define M_ID_LDYNSYM 0x09 /* always right before DYNSYM */ -#define M_ID_DYNSYM 0x0a -#define M_ID_DYNSTR 0x0b -#define M_ID_VERSION 0x0c -#define M_ID_DYNSORT 0x0d -#define M_ID_REL 0x0e -#define M_ID_PLT 0x0f /* SHF_ALLOC + SHF_EXECISNTR */ -#define M_ID_TEXT 0x10 -#define M_ID_DATA 0x20 - -/* M_ID_USER 0x02 dual entry - listed above */ -#define M_ID_GOT 0x03 /* SHF_ALLOC + SHF_WRITE */ -#define M_ID_DYNAMIC 0x05 -#define M_ID_ARRAY 0x06 - -#define M_ID_UNKNOWN 0xfb /* just before TLS */ - -#define M_ID_TLS 0xfc /* just before bss */ -#define M_ID_TLSBSS 0xfd -#define M_ID_BSS 0xfe -#define M_ID_LBSS 0xff - -#define M_ID_SYMTAB_NDX 0x02 /* ! SHF_ALLOC */ -#define M_ID_SYMTAB 0x03 -#define M_ID_STRTAB 0x04 -#define M_ID_DYNSYM_NDX 0x05 -#define M_ID_NOTE 0x06 - - -#ifdef __cplusplus -} -#endif - -#endif /* _MACHDEP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/include/i386/machdep_x86.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,297 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1988 AT&T + * All Rights Reserved + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Global include file for all sgs ia32 based machine dependent macros, + * constants and declarations. + */ + +#ifndef _MACHDEP_X86_H +#define _MACHDEP_X86_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <link.h> +#include <sys/machelf.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Elf header information. + */ +#define M_MACH_32 EM_386 +#define M_MACH_64 EM_AMD64 + +#ifdef _ELF64 +#define M_MACH EM_AMD64 +#define M_CLASS ELFCLASS64 +#else +#define M_MACH EM_386 +#define M_CLASS ELFCLASS32 +#endif + +#define M_MACHPLUS M_MACH +#define M_DATA ELFDATA2LSB +#define M_FLAGSPLUS 0 + +/* + * Page boundary Macros: truncate to previous page boundary and round to + * next page boundary (refer to generic macros in ../sgs.h also). + */ +#define M_PTRUNC(X) ((X) & ~(syspagsz - 1)) +#define M_PROUND(X) (((X) + syspagsz - 1) & ~(syspagsz - 1)) + +/* + * Segment boundary macros: truncate to previous segment boundary and round + * to next page boundary. + */ +#if defined(_ELF64) +#define M_SEGSIZE ELF_AMD64_MAXPGSZ +#else +#define M_SEGSIZE ELF_386_MAXPGSZ +#endif + +#define M_STRUNC(X) ((X) & ~(M_SEGSIZE - 1)) +#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1)) + +/* + * TLS static segments must be rounded to the following requirements, + * due to libthread stack allocation. + */ +#if defined(_ELF64) +#define M_TLSSTATALIGN 0x10 +#else +#define M_TLSSTATALIGN 0x08 +#endif + + +/* + * Other machine dependent entities + */ +#if defined(_ELF64) +#define M_SEGM_ALIGN 0x00010000 +#else +#define M_SEGM_ALIGN ELF_386_MAXPGSZ +#endif + +/* + * Values for IA32 objects + */ + +/* + * Instruction encodings. + */ +#define M_INST_JMP 0xe9 +#define M_INST_PUSHL 0x68 +#define M_SPECIAL_INST 0xff +#define M_PUSHL_DISP 0x35 +#define M_PUSHL_REG_DISP 0xb3 +#define M_JMP_DISP_IND 0x25 +#define M_JMP_REG_DISP_IND 0xa3 +#define M_NOP 0x90 + +#define M_BIND_ADJ 1 /* adjustment for end of */ + /* elf_rtbndr() address */ +#ifdef _ELF64 +#define M_WORD_ALIGN 8 +#define M_SEGM_ORIGIN (Addr)0x00400000 /* default first segment offset */ +#else + +#define M_WORD_ALIGN 4 + +#define M_STACK_GAP (0x08000000) +#define M_STACK_PGS (0x00048000) +#define M_SEGM_ORIGIN (Addr)(M_STACK_GAP + M_STACK_PGS) +#endif + + +/* + * Plt and Got information; the first few .got and .plt entries are reserved + * PLT[0] jump to dynamic linker + * GOT[0] address of _DYNAMIC + */ +#define M_PLT_ENTSIZE 16 /* plt entry size in bytes */ +#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ +#define M_PLT_INSSIZE 6 /* single plt instruction size */ +#define M_PLT_RESERVSZ M_PLT_ENTSIZE /* PLT[0] reserved */ + +#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ +#define M_GOT_XLINKMAP 1 /* got index for link map */ +#define M_GOT_XRTLD 2 /* got index for rtbinder */ +#define M_GOT_XNumber 3 /* reserved no. of got entries */ + +#ifdef _ELF64 +#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ +#else /* ELF32 */ +#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ +#endif + +/* + * Make common relocation information transparent to the common code + */ +#if defined(_ELF64) +#define M_REL_DT_TYPE DT_RELA /* .dynamic entry */ +#define M_REL_DT_SIZE DT_RELASZ /* .dynamic entry */ +#define M_REL_DT_ENT DT_RELAENT /* .dynamic entry */ +#define M_REL_DT_COUNT DT_RELACOUNT /* .dynamic entry */ +#define M_REL_SHT_TYPE SHT_RELA /* section header type */ +#define M_REL_ELF_TYPE ELF_T_RELA /* data buffer type */ + +#else /* _ELF32 */ +#define M_REL_DT_TYPE DT_REL /* .dynamic entry */ +#define M_REL_DT_SIZE DT_RELSZ /* .dynamic entry */ +#define M_REL_DT_ENT DT_RELENT /* .dynamic entry */ +#define M_REL_DT_COUNT DT_RELCOUNT /* .dynamic entry */ +#define M_REL_SHT_TYPE SHT_REL /* section header type */ +#define M_REL_ELF_TYPE ELF_T_REL /* data buffer type */ + +#endif /* ELF32 */ + +/* + * Make common relocation types transparent to the common code + */ +#if defined(_ELF64) +#define M_R_NONE R_AMD64_NONE +#define M_R_GLOB_DAT R_AMD64_GLOB_DAT +#define M_R_COPY R_AMD64_COPY +#define M_R_RELATIVE R_AMD64_RELATIVE +#define M_R_JMP_SLOT R_AMD64_JUMP_SLOT +#define M_R_FPTR R_AMD64_NONE +#define M_R_ARRAYADDR R_AMD64_GLOB_DAT +#define M_R_NUM R_AMD64_NUM +#else +#define M_R_NONE R_386_NONE +#define M_R_GLOB_DAT R_386_GLOB_DAT +#define M_R_COPY R_386_COPY +#define M_R_RELATIVE R_386_RELATIVE +#define M_R_JMP_SLOT R_386_JMP_SLOT +#define M_R_FPTR R_386_NONE +#define M_R_ARRAYADDR R_386_GLOB_DAT +#define M_R_NUM R_386_NUM +#endif + +/* + * The following are defined as M_R_NONE so that checks + * for these relocations can be performed in common code - although + * the checks are really only relevant to SPARC. + */ +#define M_R_REGISTER M_R_NONE + +/* + * DT_REGISTER is not valid on i386 or amd64 + */ +#define M_DT_REGISTER 0xffffffff +#define M_DT_PLTRESERVE 0xfffffffe + +/* + * Make plt section information transparent to the common code. + */ +#define M_PLT_SHF_FLAGS (SHF_ALLOC | SHF_EXECINSTR) + + +/* + * Make data segment information transparent to the common code. + */ +#ifdef _ELF64 +#define M_DATASEG_PERM (PF_R | PF_W) +#else +#define M_DATASEG_PERM (PF_R | PF_W | PF_X) +#endif + +/* + * Define a set of identifies for special sections. These allow the sections + * to be ordered within the output file image. These values should be + * maintained consistently, where appropriate, in each platform specific header + * file. + * + * o null identifies that this section does not need to be added to the + * output image (ie. shared object sections or sections we're going to + * recreate (sym tables, string tables, relocations, etc.)). + * + * o any user defined section will be first in the associated segment. + * + * o interp and capabilities sections are next, as these are accessed + * immediately the first page of the image is mapped. + * + * o the syminfo, hash, dynsym, dynstr and rel's are grouped together as + * these will all be accessed first by ld.so.1 to perform relocations. + * + * o the got and dynamic are grouped together as these may also be + * accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG + * (executables only), and .got[0]. + * + * o unknown sections (stabs, comments, etc.) go at the end. + * + * Note that .tlsbss/.bss are given the largest identifiers. This insures that + * if any unknown sections become associated to the same segment as the .bss, + * the .bss sections are always the last section in the segment. + */ +#define M_ID_NULL 0x00 +#define M_ID_USER 0x01 + +#define M_ID_INTERP 0x03 /* SHF_ALLOC */ +#define M_ID_CAP 0x04 +#define M_ID_UNWINDHDR 0x05 +#define M_ID_UNWIND 0x06 +#define M_ID_SYMINFO 0x07 +#define M_ID_HASH 0x08 +#define M_ID_LDYNSYM 0x09 /* always right before DYNSYM */ +#define M_ID_DYNSYM 0x0a +#define M_ID_DYNSTR 0x0b +#define M_ID_VERSION 0x0c +#define M_ID_DYNSORT 0x0d +#define M_ID_REL 0x0e +#define M_ID_PLT 0x0f /* SHF_ALLOC + SHF_EXECISNTR */ +#define M_ID_TEXT 0x10 +#define M_ID_DATA 0x20 + +/* M_ID_USER 0x02 dual entry - listed above */ +#define M_ID_GOT 0x03 /* SHF_ALLOC + SHF_WRITE */ +#define M_ID_DYNAMIC 0x05 +#define M_ID_ARRAY 0x06 + +#define M_ID_UNKNOWN 0xfb /* just before TLS */ + +#define M_ID_TLS 0xfc /* just before bss */ +#define M_ID_TLSBSS 0xfd +#define M_ID_BSS 0xfe +#define M_ID_LBSS 0xff + +#define M_ID_SYMTAB_NDX 0x02 /* ! SHF_ALLOC */ +#define M_ID_SYMTAB 0x03 +#define M_ID_STRTAB 0x04 +#define M_ID_DYNSYM_NDX 0x05 +#define M_ID_NOTE 0x06 + + +#ifdef __cplusplus +} +#endif + +#endif /* _MACHDEP_X86_H */
--- a/usr/src/cmd/sgs/include/libld.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/include/libld.h Tue Mar 18 09:17:00 2008 -0700 @@ -35,7 +35,7 @@ #include <stdlib.h> #include <libelf.h> #include <sgs.h> -#include <machdep.h> +#include <_machelf.h> #include <string_table.h> #include <sys/avl.h> #include <alist.h> @@ -177,7 +177,7 @@ List ofl_rtldinfo; /* list of rtldinfo syms */ List ofl_osgroups; /* list of output GROUP sections */ List ofl_ostlsseg; /* pointer to sections in TLS segment */ -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) /* for amd64 target only */ List ofl_unwind; /* list of unwind output sections */ Os_desc *ofl_unwindhdr; /* Unwind hdr */ #endif @@ -400,14 +400,6 @@ !((_ofl)->ofl_dtflags_1 & DF_1_NORELOC)) /* - * Determine whether relocation processing needs to swap the - * data being relocated. - */ -#define OFL_SWAP_RELOC_DATA(_ofl, _rel) \ - ((((_ofl)->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) && \ - ((_rel)->rel_osdesc->os_shdr->sh_type == SHT_PROGBITS)) - -/* * Relocation (active & output) processing structure - transparent to common * code. * @@ -1093,6 +1085,7 @@ #define ld_create_outfile ld64_create_outfile #define ld_ent_setup ld64_ent_setup #define ld_init_strings ld64_init_strings +#define ld_init_target ld64_init_target #define ld_make_sections ld64_make_sections #define ld_main ld64_main #define ld_ofl_cleanup ld64_ofl_cleanup @@ -1107,6 +1100,7 @@ #define ld_create_outfile ld32_create_outfile #define ld_ent_setup ld32_ent_setup #define ld_init_strings ld32_init_strings +#define ld_init_target ld32_init_target #define ld_make_sections ld32_make_sections #define ld_main ld32_main #define ld_ofl_cleanup ld32_ofl_cleanup @@ -1118,12 +1112,13 @@ #endif -extern int ld32_main(int, char **); -extern int ld64_main(int, char **); +extern int ld32_main(int, char **, Half); +extern int ld64_main(int, char **, Half); extern uintptr_t ld_create_outfile(Ofl_desc *); extern uintptr_t ld_ent_setup(Ofl_desc *, Xword); extern uintptr_t ld_init_strings(Ofl_desc *); +extern int ld_init_target(Lm_list *, Half mach); extern uintptr_t ld_make_sections(Ofl_desc *); extern void ld_ofl_cleanup(Ofl_desc *); extern Ifl_desc *ld_process_open(const char *, const char *, int *,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/include/machdep.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,53 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Global include file for all sgs machine dependent macros, constants + * and declarations applicable to the current system. This header is + * to be used for code that supports the native system only. Code that + * needs to support non-native targets should avoid it, and use the + * target-specific versions found in the subdirectories below the include + * directory holding this file. + */ + +#ifndef _MACHDEP_H +#define _MACHDEP_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#if defined(__sparc) + +#include <sparc/machdep_sparc.h> + +#elif defined(__i386) || defined(__amd64) + +#include <i386/machdep_x86.h> + +#else + +#error "machdep.h does not understand current machine" + +#endif + +#endif /* _MACHDEP_H */
--- a/usr/src/cmd/sgs/include/rtld.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/include/rtld.h Tue Mar 18 09:17:00 2008 -0700 @@ -36,7 +36,7 @@ #include <sgs.h> #include <thread.h> #include <synch.h> -#include <machdep.h> +#include <link.h> #include <sys/avl.h> #include <alist.h> #include <libc_int.h>
--- a/usr/src/cmd/sgs/include/sparc/machdep.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,352 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 1988 AT&T - * All Rights Reserved - * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Global include file for all sgs SPARC machine dependent macros, constants - * and declarations. - */ - -#ifndef _MACHDEP_H -#define _MACHDEP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <link.h> -#include <sys/machelf.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Elf header information. - */ -#ifdef _ELF64 -#define M_MACH EM_SPARCV9 -#define M_CLASS ELFCLASS64 -#else -#define M_MACH EM_SPARC -#define M_CLASS ELFCLASS32 -#endif -#define M_MACHPLUS EM_SPARC32PLUS -#define M_DATA ELFDATA2MSB -#define M_FLAGSPLUS EF_SPARC_32PLUS - -/* - * Page boundary Macros: truncate to previous page boundary and round to - * next page boundary (refer to generic macros in ../sgs.h also). - */ -#define M_PTRUNC(X) ((X) & ~(syspagsz - 1)) -#define M_PROUND(X) (((X) + syspagsz - 1) & ~(syspagsz - 1)) - -/* - * Segment boundary macros: truncate to previous segment boundary and round - * to next page boundary. - */ -#ifndef M_SEGSIZE -#define M_SEGSIZE ELF_SPARC_MAXPGSZ -#endif -#define M_STRUNC(X) ((X) & ~(M_SEGSIZE - 1)) -#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1)) - - -/* - * TLS static segments must be rounded to the following requirements, - * due to libthread stack allocation. - */ -#if defined(_ELF64) -#define M_TLSSTATALIGN 0x10 -#else -#define M_TLSSTATALIGN 0x08 -#endif - - -/* - * Instruction encodings. - */ -#define M_SAVESP64 0x9de3bfc0 /* save %sp, -64, %sp */ -#define M_CALL 0x40000000 -#define M_JMPL 0x81c06000 /* jmpl %g1 + simm13, %g0 */ -#define M_SETHIG0 0x01000000 /* sethi %hi(val), %g0 */ -#define M_SETHIG1 0x03000000 /* sethi %hi(val), %g1 */ -#define M_STO7G1IM 0xde206000 /* st %o7,[%g1 + %lo(val)] */ -#define M_SUBFPSPG1 0x8227800e /* sub %fp,%sp,%g1 */ -#define M_NOP 0x01000000 /* sethi 0, %o0 (nop) */ -#define M_BA_A 0x30800000 /* ba,a */ -#define M_BA_A_PT 0x30480000 /* ba,a %icc, <dst> */ -#define M_MOVO7TOG1 0x8210000f /* mov %o7, %g1 */ -#define M_MOVO7TOG5 0x8a10000f /* mov %o7, %g5 */ -#define M_MOVI7TOG1 0x8210001f /* mov %i7, %g1 */ -#define M_BA_A_XCC 0x30680000 /* ba,a %xcc */ -#define M_JMPL_G5G0 0x81c16000 /* jmpl %g5 + 0, %g0 */ -#define M_XNOR_G5G1 0x82396000 /* xnor %g5, 0, %g1 */ - - -#define M_BIND_ADJ 4 /* adjustment for end of */ - /* elf_rtbndr() address */ - - -/* - * Plt and Got information; the first few .got and .plt entries are reserved - * PLT[0] jump to dynamic linker - * GOT[0] address of _DYNAMIC - */ -#define M_PLT_INSSIZE 4 /* single plt instruction size */ -#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ -#define M_GOT_XNumber 1 /* reserved no. of got entries */ - -/* - * ELF32 bit PLT constants - */ -#define M32_PLT_ENTSIZE 12 /* 32bit plt entry size in bytes */ - -/* - * ELF64 bit PLT constants - */ -#define M64_PLT_NEARPLTS 0x8000 /* # of NEAR PLTS we can have */ -#define M64_PLT_ENTSIZE 32 /* plt entry size in bytes */ -#define M64_PLT_FENTSIZE 24 /* size of far plt is 6 instructions */ - /* x 4bytes */ -#define M64_PLT_PSIZE 8 /* size of PLTP pointer */ -#define M64_PLT_FBLKCNTS 160 /* # of plts in far PLT blocks */ -#define M64_PLT_FBLOCKSZ (M64_PLT_FBLKCNTS *\ - M64_PLT_ENTSIZE) /* size of far PLT block */ - - -#ifdef _ELF64 -#define M_PLT_ENTSIZE M64_PLT_ENTSIZE /* plt entry size in bytes */ -#define M_PLT_XNumber 4 /* reserved no. of plt entries */ -#define M_PLT_ALIGN 256 /* alignment of .plt section */ -#define M_PLT_RESERVSZ (M_PLT_XNumber * \ - M_PLT_ENTSIZE) /* first 4 plt's reserved */ -#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ -#define M_GOT_MAXSMALL 1024 /* maximum no. of small gots */ -#else /* Elf32 */ -#define M_PLT_ENTSIZE M32_PLT_ENTSIZE /* plt entry size in bytes */ -#define M_PLT_XNumber 4 /* reserved no. of plt entries */ -#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ -#define M_PLT_RESERVSZ (M_PLT_XNumber * \ - M_PLT_ENTSIZE) /* first 4 plt's reserved */ -#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ -#define M_GOT_MAXSMALL 2048 /* maximum no. of small gots */ -#endif /* _ELF64 */ - /* transition flags for got sizing */ -#define M_GOT_LARGE (Sword)(-M_GOT_MAXSMALL - 1) -#define M_GOT_SMALL (Sword)(-M_GOT_MAXSMALL - 2) -#define M_GOT_MIXED (Sword)(-M_GOT_MAXSMALL - 3) - - -/* - * Other machine dependent entities - */ -#ifdef _ELF64 -#define M_SEGM_ALIGN ELF_SPARCV9_MAXPGSZ -/* - * Put 64-bit programs above 4 gigabytes to help insure correctness, - * so any 64-bit programs that truncate pointers will fault now instead of - * corrupting itself and dying mysteriously. - */ -#define M_SEGM_ORIGIN (Addr)0x100000000ULL /* default first segment offset */ -#define M_WORD_ALIGN 8 -#else -#define M_SEGM_ALIGN ELF_SPARC_MAXPGSZ -#define M_SEGM_ORIGIN (Addr)0x10000 /* default first segment offset */ -#define M_WORD_ALIGN 4 -#endif - -/* - * Make machine class dependent functions transparent to the common code - */ -#ifdef _ELF64 -#define ELF_R_TYPE ELF64_R_TYPE_ID -#define ELF_R_INFO ELF64_R_INFO -#define ELF_R_SYM ELF64_R_SYM -#define ELF_R_TYPE_DATA ELF64_R_TYPE_DATA -#define ELF_R_TYPE_INFO ELF64_R_TYPE_INFO -#define ELF_ST_BIND ELF64_ST_BIND -#define ELF_ST_TYPE ELF64_ST_TYPE -#define ELF_ST_INFO ELF64_ST_INFO -#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY -#define ELF_M_SYM ELF64_M_SYM -#define ELF_M_SIZE ELF64_M_SIZE -#define ELF_M_INFO ELF64_M_INFO -#define elf_checksum elf64_checksum -#define elf_fsize elf64_fsize -#define elf_getehdr elf64_getehdr -#define elf_getphdr elf64_getphdr -#define elf_newehdr elf64_newehdr -#define elf_newphdr elf64_newphdr -#define elf_getshdr elf64_getshdr -#define elf_xlatetom elf64_xlatetom -#else /* Elf32 */ -#define ELF_R_TYPE ELF32_R_TYPE -#define ELF_R_INFO ELF32_R_INFO -#define ELF_R_SYM ELF32_R_SYM -#define ELF_M_SYM ELF32_M_SYM -#define ELF_M_SIZE ELF32_M_SIZE -#define ELF_M_INFO ELF32_M_INFO -/* Elf64 can hide extra offset in r_info */ -#define ELF_R_TYPE_DATA(x) (0) -#define ELF_R_TYPE_INFO(xoff, type) (type) -#define ELF_ST_BIND ELF32_ST_BIND -#define ELF_ST_TYPE ELF32_ST_TYPE -#define ELF_ST_INFO ELF32_ST_INFO -#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY -#define elf_checksum elf32_checksum -#define elf_fsize elf32_fsize -#define elf_getehdr elf32_getehdr -#define elf_getphdr elf32_getphdr -#define elf_newehdr elf32_newehdr -#define elf_newphdr elf32_newphdr -#define elf_getshdr elf32_getshdr -#define elf_xlatetom elf32_xlatetom -#endif /* Elf32 */ - -/* - * Make common relocation information transparent to the common code - */ -#define M_REL_DT_TYPE DT_RELA /* .dynamic entry */ -#define M_REL_DT_SIZE DT_RELASZ /* .dynamic entry */ -#define M_REL_DT_ENT DT_RELAENT /* .dynamic entry */ -#define M_REL_DT_COUNT DT_RELACOUNT /* .dynamic entry */ -#define M_REL_SHT_TYPE SHT_RELA /* section header type */ -#define M_REL_ELF_TYPE ELF_T_RELA /* data buffer type */ - -/* - * Make common relocation types transparent to the common code - */ -#define M_R_NONE R_SPARC_NONE -#define M_R_GLOB_DAT R_SPARC_GLOB_DAT -#define M_R_COPY R_SPARC_COPY -#define M_R_RELATIVE R_SPARC_RELATIVE -#define M_R_JMP_SLOT R_SPARC_JMP_SLOT -#define M_R_REGISTER R_SPARC_REGISTER -#define M_R_FPTR R_SPARC_NONE -#define M_R_NUM R_SPARC_NUM - -#ifdef _ELF64 -#define M_R_ARRAYADDR R_SPARC_64 -#define M_R_DTPMOD R_SPARC_TLS_DTPMOD64 -#define M_R_DTPOFF R_SPARC_TLS_DTPOFF64 -#define M_R_TPOFF R_SPARC_TLS_TPOFF64 -#else /* _ELF32 */ -#define M_R_ARRAYADDR R_SPARC_32 -#define M_R_DTPMOD R_SPARC_TLS_DTPMOD32 -#define M_R_DTPOFF R_SPARC_TLS_DTPOFF32 -#define M_R_TPOFF R_SPARC_TLS_TPOFF32 -#endif /* _ELF64 */ - - -/* - * Make register symbols transparent to common code - */ -#define M_DT_REGISTER DT_SPARC_REGISTER - -/* - * PLTRESERVE is not relevant on sparc - */ -#define M_DT_PLTRESERVE 0xffffffff - - -/* - * Make plt section information transparent to the common code. - */ -#define M_PLT_SHF_FLAGS (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR) - -/* - * Make data segment information transparent to the common code. - */ -#define M_DATASEG_PERM (PF_R | PF_W | PF_X) - -/* - * Define a set of identifies for special sections. These allow the sections - * to be ordered within the output file image. These values should be - * maintained consistently, where appropriate, in each platform specific header - * file. - * - * o null identifies that this section does not need to be added to the - * output image (ie. shared object sections or sections we're going to - * recreate (sym tables, string tables, relocations, etc.)). - * - * o any user defined section will be first in the associated segment. - * - * o interp and capabilities sections are next, as these are accessed - * immediately the first page of the image is mapped. - * - * o the syminfo, hash, dynsym, dynstr and rel's are grouped together as - * these will all be accessed first by ld.so.1 to perform relocations. - * - * o the got, dynamic, and plt are grouped together as these may also be - * accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG - * (executables only), and .plt[0]. - * - * o unknown sections (stabs, comments etc.) go at the end. - * - * Note that .tlsbss/.bss are given the largest identifiers. This insures that - * if any unknown sections become associated to the same segment as the .bss, - * the .bss sections are always the last section in the segment. - */ -#define M_ID_NULL 0x00 -#define M_ID_USER 0x01 - -#define M_ID_INTERP 0x02 /* SHF_ALLOC */ -#define M_ID_CAP 0x03 -#define M_ID_SYMINFO 0x04 -#define M_ID_HASH 0x05 -#define M_ID_LDYNSYM 0x06 /* always right before DYNSYM */ -#define M_ID_DYNSYM 0x07 -#define M_ID_DYNSTR 0x08 -#define M_ID_VERSION 0x09 -#define M_ID_DYNSORT 0x0a -#define M_ID_REL 0x0b -#define M_ID_TEXT 0x0c /* SHF_ALLOC + SHF_EXECINSTR */ -#define M_ID_DATA 0x0d - -/* M_ID_USER 0x01 dual entry - listed above */ -#define M_ID_GOTDATA 0x02 /* SHF_ALLOC + SHF_WRITE */ -#define M_ID_GOT 0x03 -#define M_ID_PLT 0x04 -#define M_ID_DYNAMIC 0x05 -#define M_ID_ARRAY 0x06 - -#define M_ID_UNKNOWN 0xfc /* just before TLS */ - -#define M_ID_TLS 0xfd /* just before bss */ -#define M_ID_TLSBSS 0xfe -#define M_ID_BSS 0xff - -#define M_ID_SYMTAB_NDX 0x02 /* ! SHF_ALLOC */ -#define M_ID_SYMTAB 0x03 -#define M_ID_STRTAB 0x04 -#define M_ID_DYNSYM_NDX 0x05 -#define M_ID_NOTE 0x06 - -#ifdef __cplusplus -} -#endif - -#endif /* _MACHDEP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/include/sparc/machdep_sparc.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,308 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1988 AT&T + * All Rights Reserved + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Global include file for all sgs SPARC machine dependent macros, constants + * and declarations. + */ + +#ifndef _MACHDEP_SPARC_H +#define _MACHDEP_SPARC_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <link.h> +#include <sys/machelf.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Elf header information. + */ +#define M_MACH_32 EM_SPARC +#define M_MACH_64 EM_SPARCV9 + +#ifdef _ELF64 +#define M_MACH EM_SPARCV9 +#define M_CLASS ELFCLASS64 +#else +#define M_MACH EM_SPARC +#define M_CLASS ELFCLASS32 +#endif +#define M_MACHPLUS EM_SPARC32PLUS +#define M_DATA ELFDATA2MSB +#define M_FLAGSPLUS EF_SPARC_32PLUS + +/* + * Page boundary Macros: truncate to previous page boundary and round to + * next page boundary (refer to generic macros in ../sgs.h also). + */ +#define M_PTRUNC(X) ((X) & ~(syspagsz - 1)) +#define M_PROUND(X) (((X) + syspagsz - 1) & ~(syspagsz - 1)) + +/* + * Segment boundary macros: truncate to previous segment boundary and round + * to next page boundary. + */ +#ifndef M_SEGSIZE +#define M_SEGSIZE ELF_SPARC_MAXPGSZ +#endif +#define M_STRUNC(X) ((X) & ~(M_SEGSIZE - 1)) +#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1)) + + +/* + * TLS static segments must be rounded to the following requirements, + * due to libthread stack allocation. + */ +#if defined(_ELF64) +#define M_TLSSTATALIGN 0x10 +#else +#define M_TLSSTATALIGN 0x08 +#endif + + +/* + * Instruction encodings. + */ +#define M_SAVESP64 0x9de3bfc0 /* save %sp, -64, %sp */ +#define M_CALL 0x40000000 +#define M_JMPL 0x81c06000 /* jmpl %g1 + simm13, %g0 */ +#define M_SETHIG0 0x01000000 /* sethi %hi(val), %g0 */ +#define M_SETHIG1 0x03000000 /* sethi %hi(val), %g1 */ +#define M_STO7G1IM 0xde206000 /* st %o7,[%g1 + %lo(val)] */ +#define M_SUBFPSPG1 0x8227800e /* sub %fp,%sp,%g1 */ +#define M_NOP 0x01000000 /* sethi 0, %o0 (nop) */ +#define M_BA_A 0x30800000 /* ba,a */ +#define M_BA_A_PT 0x30480000 /* ba,a %icc, <dst> */ +#define M_MOVO7TOG1 0x8210000f /* mov %o7, %g1 */ +#define M_MOVO7TOG5 0x8a10000f /* mov %o7, %g5 */ +#define M_MOVI7TOG1 0x8210001f /* mov %i7, %g1 */ +#define M_BA_A_XCC 0x30680000 /* ba,a %xcc */ +#define M_JMPL_G5G0 0x81c16000 /* jmpl %g5 + 0, %g0 */ +#define M_XNOR_G5G1 0x82396000 /* xnor %g5, 0, %g1 */ + + +#define M_BIND_ADJ 4 /* adjustment for end of */ + /* elf_rtbndr() address */ + + +/* + * Plt and Got information; the first few .got and .plt entries are reserved + * PLT[0] jump to dynamic linker + * GOT[0] address of _DYNAMIC + */ +#define M_PLT_INSSIZE 4 /* single plt instruction size */ +#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ +#define M_GOT_XNumber 1 /* reserved no. of got entries */ + +/* + * ELF32 bit PLT constants + */ +#define M32_PLT_ENTSIZE 12 /* 32bit plt entry size in bytes */ + +/* + * ELF64 bit PLT constants + */ +#define M64_PLT_NEARPLTS 0x8000 /* # of NEAR PLTS we can have */ +#define M64_PLT_ENTSIZE 32 /* plt entry size in bytes */ +#define M64_PLT_FENTSIZE 24 /* size of far plt is 6 instructions */ + /* x 4bytes */ +#define M64_PLT_PSIZE 8 /* size of PLTP pointer */ +#define M64_PLT_FBLKCNTS 160 /* # of plts in far PLT blocks */ +#define M64_PLT_FBLOCKSZ (M64_PLT_FBLKCNTS *\ + M64_PLT_ENTSIZE) /* size of far PLT block */ + + +#ifdef _ELF64 +#define M_PLT_ENTSIZE M64_PLT_ENTSIZE /* plt entry size in bytes */ +#define M_PLT_XNumber 4 /* reserved no. of plt entries */ +#define M_PLT_ALIGN 256 /* alignment of .plt section */ +#define M_PLT_RESERVSZ (M_PLT_XNumber * \ + M_PLT_ENTSIZE) /* first 4 plt's reserved */ +#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ +#define M_GOT_MAXSMALL 1024 /* maximum no. of small gots */ +#else /* Elf32 */ +#define M_PLT_ENTSIZE M32_PLT_ENTSIZE /* plt entry size in bytes */ +#define M_PLT_XNumber 4 /* reserved no. of plt entries */ +#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ +#define M_PLT_RESERVSZ (M_PLT_XNumber * \ + M_PLT_ENTSIZE) /* first 4 plt's reserved */ +#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ +#define M_GOT_MAXSMALL 2048 /* maximum no. of small gots */ +#endif /* _ELF64 */ + /* transition flags for got sizing */ +#define M_GOT_LARGE (Sword)(-M_GOT_MAXSMALL - 1) +#define M_GOT_SMALL (Sword)(-M_GOT_MAXSMALL - 2) +#define M_GOT_MIXED (Sword)(-M_GOT_MAXSMALL - 3) + + +/* + * Other machine dependent entities + */ +#ifdef _ELF64 +#define M_SEGM_ALIGN ELF_SPARCV9_MAXPGSZ +/* + * Put 64-bit programs above 4 gigabytes to help insure correctness, + * so any 64-bit programs that truncate pointers will fault now instead of + * corrupting itself and dying mysteriously. + */ +#define M_SEGM_ORIGIN (Addr)0x100000000ULL /* default first segment offset */ +#define M_WORD_ALIGN 8 +#else +#define M_SEGM_ALIGN ELF_SPARC_MAXPGSZ +#define M_SEGM_ORIGIN (Addr)0x10000 /* default first segment offset */ +#define M_WORD_ALIGN 4 +#endif + +/* + * Make common relocation information transparent to the common code + */ +#define M_REL_DT_TYPE DT_RELA /* .dynamic entry */ +#define M_REL_DT_SIZE DT_RELASZ /* .dynamic entry */ +#define M_REL_DT_ENT DT_RELAENT /* .dynamic entry */ +#define M_REL_DT_COUNT DT_RELACOUNT /* .dynamic entry */ +#define M_REL_SHT_TYPE SHT_RELA /* section header type */ +#define M_REL_ELF_TYPE ELF_T_RELA /* data buffer type */ + +/* + * Make common relocation types transparent to the common code + */ +#define M_R_NONE R_SPARC_NONE +#define M_R_GLOB_DAT R_SPARC_GLOB_DAT +#define M_R_COPY R_SPARC_COPY +#define M_R_RELATIVE R_SPARC_RELATIVE +#define M_R_JMP_SLOT R_SPARC_JMP_SLOT +#define M_R_REGISTER R_SPARC_REGISTER +#define M_R_FPTR R_SPARC_NONE +#define M_R_NUM R_SPARC_NUM + +#ifdef _ELF64 +#define M_R_ARRAYADDR R_SPARC_64 +#define M_R_DTPMOD R_SPARC_TLS_DTPMOD64 +#define M_R_DTPOFF R_SPARC_TLS_DTPOFF64 +#define M_R_TPOFF R_SPARC_TLS_TPOFF64 +#else /* _ELF32 */ +#define M_R_ARRAYADDR R_SPARC_32 +#define M_R_DTPMOD R_SPARC_TLS_DTPMOD32 +#define M_R_DTPOFF R_SPARC_TLS_DTPOFF32 +#define M_R_TPOFF R_SPARC_TLS_TPOFF32 +#endif /* _ELF64 */ + + +/* + * Make register symbols transparent to common code + */ +#define M_DT_REGISTER DT_SPARC_REGISTER + +/* + * PLTRESERVE is not relevant on sparc + */ +#define M_DT_PLTRESERVE 0xffffffff + + +/* + * Make plt section information transparent to the common code. + */ +#define M_PLT_SHF_FLAGS (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR) + +/* + * Make data segment information transparent to the common code. + */ +#define M_DATASEG_PERM (PF_R | PF_W | PF_X) + +/* + * Define a set of identifies for special sections. These allow the sections + * to be ordered within the output file image. These values should be + * maintained consistently, where appropriate, in each platform specific header + * file. + * + * o null identifies that this section does not need to be added to the + * output image (ie. shared object sections or sections we're going to + * recreate (sym tables, string tables, relocations, etc.)). + * + * o any user defined section will be first in the associated segment. + * + * o interp and capabilities sections are next, as these are accessed + * immediately the first page of the image is mapped. + * + * o the syminfo, hash, dynsym, dynstr and rel's are grouped together as + * these will all be accessed first by ld.so.1 to perform relocations. + * + * o the got, dynamic, and plt are grouped together as these may also be + * accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG + * (executables only), and .plt[0]. + * + * o unknown sections (stabs, comments etc.) go at the end. + * + * Note that .tlsbss/.bss are given the largest identifiers. This insures that + * if any unknown sections become associated to the same segment as the .bss, + * the .bss sections are always the last section in the segment. + */ +#define M_ID_NULL 0x00 +#define M_ID_USER 0x01 + +#define M_ID_INTERP 0x02 /* SHF_ALLOC */ +#define M_ID_CAP 0x03 +#define M_ID_SYMINFO 0x04 +#define M_ID_HASH 0x05 +#define M_ID_LDYNSYM 0x06 /* always right before DYNSYM */ +#define M_ID_DYNSYM 0x07 +#define M_ID_DYNSTR 0x08 +#define M_ID_VERSION 0x09 +#define M_ID_DYNSORT 0x0a +#define M_ID_REL 0x0b +#define M_ID_TEXT 0x0c /* SHF_ALLOC + SHF_EXECINSTR */ +#define M_ID_DATA 0x0d + +/* M_ID_USER 0x01 dual entry - listed above */ +#define M_ID_GOTDATA 0x02 /* SHF_ALLOC + SHF_WRITE */ +#define M_ID_GOT 0x03 +#define M_ID_PLT 0x04 +#define M_ID_DYNAMIC 0x05 +#define M_ID_ARRAY 0x06 + +#define M_ID_UNKNOWN 0xfc /* just before TLS */ + +#define M_ID_TLS 0xfd /* just before bss */ +#define M_ID_TLSBSS 0xfe +#define M_ID_BSS 0xff + +#define M_ID_SYMTAB_NDX 0x02 /* ! SHF_ALLOC */ +#define M_ID_SYMTAB 0x03 +#define M_ID_STRTAB 0x04 +#define M_ID_DYNSYM_NDX 0x05 +#define M_ID_NOTE 0x06 + + +#ifdef __cplusplus +} +#endif + +#endif /* _MACHDEP_SPARC_H */
--- a/usr/src/cmd/sgs/ld/common/ld.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/ld/common/ld.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,6 +31,7 @@ #include <unistd.h> #include <stdarg.h> #include <string.h> +#include <strings.h> #include <errno.h> #include <fcntl.h> #include <libintl.h> @@ -38,6 +39,7 @@ #include <fcntl.h> #include "conv.h" #include "libld.h" +#include "machdep.h" #include "msg.h" /* @@ -68,13 +70,14 @@ if (error > ERR_NONE) { if (error == ERR_WARNING) { if (strings[ERR_WARNING] == 0) - strings[ERR_WARNING] = MSG_INTL(MSG_ERR_WARNING); + strings[ERR_WARNING] = + MSG_INTL(MSG_ERR_WARNING); } else if (error == ERR_FATAL) { if (strings[ERR_FATAL] == 0) - strings[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); + strings[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); } else if (error == ERR_ELF) { if (strings[ERR_ELF] == 0) - strings[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); + strings[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); } (void) fputs(MSG_ORIG(MSG_STR_LDDIAG), stderr); } @@ -96,26 +99,45 @@ /* - * Determine whether we need the Elf32 or Elf64 libld. + * Determine: + * - ELFCLASS of resulting object (aoutclass) + * - Whether we need the 32 or 64-bit libld (ldclass) + * - ELF machine type of resulting object (m_mach) */ static int -determine_class(int argc, char **argv, uchar_t *aoutclass, uchar_t *ldclass) +process_args(int argc, char **argv, uchar_t *aoutclass, uchar_t *ldclass, + Half *mach) { -#if defined(__sparcv9) || defined(__amd64) - uchar_t aclass = 0, lclass = ELFCLASS64; +#if defined(_LP64) + uchar_t lclass = ELFCLASS64; #else - uchar_t aclass = 0, lclass = 0; + uchar_t lclass = ELFCLASSNONE; #endif + uchar_t aclass = ELFCLASSNONE; + Half mach32 = EM_NONE, mach64 = EM_NONE; int c; getmore: /* - * Skip options. + * In general, libld.so is responsible for processing the + * command line options. The exception to this are those options + * that contain information about which linker to run and the + * class/machine of the output object. We examine the options + * here looking for the following: + * + * -64 + * Produce an ELFCLASS64 object. Use the 64-bit linker. * - * The only options we're interested in is -64 or -altzexec64. The -64 - * option is used when the only input to ld() is a mapfile or archive, - * and a 64-bit a.out is required. The -zaltexec64 option requests the - * 64-bit version of ld() is used regardless of the required a.out. + * -zaltexec64 + * Use the 64-bit linker regardless of the class + * of the output object. + * + * -z target=platform + * Produce output object for the specified platform. + * + * The -64 and -ztarget options are used when the only input to + * ld() is a mapfile or archive, and a 64-bit or non-native output + * object is required. * * If we've already processed a 32-bit object and we find -64, we have * an error condition, but let this fall through to libld to obtain the @@ -129,13 +151,40 @@ MSG_ARG_FOUR_SIZE) == 0) aclass = ELFCLASS64; break; -#if !defined(__sparcv9) && !defined(__amd64) + case 'z': +#if !defined(_LP64) + /* -z altexec64 */ if (strncmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64), - MSG_ARG_ALTEXEC64_SIZE) == 0) + MSG_ARG_ALTEXEC64_SIZE) == 0) { lclass = ELFCLASS64; + break; + } +#endif + + /* -z target=platform */ + if (strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET), + MSG_ARG_TARGET_SIZE) == 0) { + char *pstr = + optarg + MSG_ARG_TARGET_SIZE; + + if (strcasecmp(pstr, + MSG_ORIG(MSG_TARG_SPARC)) == 0) { + mach32 = EM_SPARC; + mach64 = EM_SPARCV9; + } else if (strcasecmp(pstr, + MSG_ORIG(MSG_TARG_X86)) == 0) { + mach32 = EM_386; + mach64 = EM_AMD64; + } else { + eprintf(0, ERR_FATAL, + MSG_INTL(MSG_ERR_BADTARG), + pstr); + return (1); + } + } break; -#endif + default: break; } @@ -147,7 +196,7 @@ */ for (; optind < argc; optind++) { int fd; - unsigned char ident[EI_NIDENT]; + Elf32_Ehdr ehdr32; /* * If we detect some more options return to getopt(). @@ -162,11 +211,15 @@ } /* - * If we've already determined the object class, continue. - * We're only interested in skipping all files to check for - * more options, and specifically if the -64 option is set. + * If we've already determined the object class and + * machine type, continue to the next argument. Only + * the first object contributes to this decision, and + * there's no value to opening or examing the subsequent + * ones. We do need to keep going though, because there + * may be additional options that might affect our + * class/machine decision. */ - if (aclass) + if ((aclass != ELFCLASSNONE) && (mach32 != EM_NONE)) continue; /* @@ -180,28 +233,82 @@ return (1); } - if ((read(fd, ident, EI_NIDENT) == EI_NIDENT) && - (ident[EI_MAG0] == ELFMAG0) && - (ident[EI_MAG1] == ELFMAG1) && - (ident[EI_MAG2] == ELFMAG2) && - (ident[EI_MAG3] == ELFMAG3)) { - if (((aclass = ident[EI_CLASS]) != ELFCLASS32) && - (aclass != ELFCLASS64)) - aclass = 0; + /* + * Note that we read an entire 32-bit ELF header struct + * here, even though we have yet to determine that the + * file is an ELF object or that it is ELFCLASS32. We + * do this because: + * - Any valid ELF object of any class must + * have at least this number of bytes in it, + * since an ELF header is manditory, and since + * a 32-bit header is smaller than a 64-bit one. + * - The 32 and 64-bit ELF headers are identical + * up through the e_version field, so we can + * obtain the e_machine value of a 64-bit + * object via the e_machine value we read into + * the 32-bit version. This cannot change, because + * the layout of an ELF header is fixed by the ABI. + * + * Note however that we do have to worry about the byte + * order difference between the object and the system + * running this program when we read the e_machine value, + * since it is a multi-byte value; + */ + if ((read(fd, &ehdr32, sizeof (ehdr32)) == sizeof (ehdr32)) && + (ehdr32.e_ident[EI_MAG0] == ELFMAG0) && + (ehdr32.e_ident[EI_MAG1] == ELFMAG1) && + (ehdr32.e_ident[EI_MAG2] == ELFMAG2) && + (ehdr32.e_ident[EI_MAG3] == ELFMAG3)) { + if (aclass == ELFCLASSNONE) { + aclass = ehdr32.e_ident[EI_CLASS]; + if ((aclass != ELFCLASS32) && + (aclass != ELFCLASS64)) + aclass = ELFCLASSNONE; + } + + if (mach32 == EM_NONE) { + int one = 1; + uchar_t *one_p = (uchar_t *)&one; + int ld_elfdata; + + ld_elfdata = (one_p[0] == 1) ? + ELFDATA2LSB : ELFDATA2MSB; + /* + * Both the 32 and 64-bit versions get the + * type from the object. If the user has + * asked for an inconsistant class/machine + * combination, libld will catch it. + */ + mach32 = mach64 = + (ld_elfdata == ehdr32.e_ident[EI_DATA]) ? + ehdr32.e_machine : + BSWAP_HALF(ehdr32.e_machine); + } } + (void) close(fd); } /* - * If we couldn't establish a class default to 32-bit. + * If we couldn't establish a class, default to 32-bit. */ - if (aclass == 0) + if (aclass == ELFCLASSNONE) aclass = ELFCLASS32; - if (lclass == 0) + *aoutclass = aclass; + + if (lclass == ELFCLASSNONE) lclass = ELFCLASS32; + *ldclass = lclass; - *aoutclass = aclass; - *ldclass = lclass; + /* + * Use the machine type that goes with the class we've determined. + * If we didn't find a usable machine type, use the native + * machine. + */ + *mach = (aclass == ELFCLASS64) ? mach64 : mach32; + if (*mach == EM_NONE) + *mach = (aclass == ELFCLASS64) ? M_MACH_64 : M_MACH_32; + return (0); } @@ -356,6 +463,7 @@ { char *ld_options, **oargv = argv; uchar_t aoutclass, ldclass, checkclass; + Half mach; /* * XX64 -- Strip "-Wl," from the head of each argument. This is to @@ -400,9 +508,12 @@ } /* - * Determine the object class, and link-editor class required. + * Examine the command arguments to determine: + * - object class + * - link-editor class + * - target machine */ - if (determine_class(argc, argv, &aoutclass, &ldclass)) + if (process_args(argc, argv, &aoutclass, &ldclass, &mach)) return (1); /* @@ -425,9 +536,9 @@ */ optind = opterr = 1; if (aoutclass == ELFCLASS64) - return (ld64_main(argc, argv)); + return (ld64_main(argc, argv, mach)); else - return (ld32_main(argc, argv)); + return (ld32_main(argc, argv, mach)); } /*
--- a/usr/src/cmd/sgs/ld/common/ld.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/ld/common/ld.msg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -39,6 +39,8 @@ @ MSG_SYS_ALLOC "alloc failed: %s" @ MSG_SYS_64 "unable to execute 64-bit version of ld" +@ MSG_ERR_BADTARG "unknown target platform: %s" + # Generic error diagnostic labels @ MSG_ERR_WARNING "warning: " @@ -49,7 +51,7 @@ # The following strings represent reserved words, files, pathnames and symbols. -# Reference to this strings is via the MSG_ORIG() macro, and thus no message +# Reference to these strings is via the MSG_ORIG() macro, and thus no message # translation is required. @ MSG_STR_EMPTY "" @@ -62,8 +64,13 @@ @ MSG_ARG_FOUR "4" @ MSG_ARG_ALTEXEC64 "altexec64" +@ MSG_ARG_TARGET "target=" @ MSG_LD_OPTIONS "LD_OPTIONS" @ MSG_LD_ALTEXEC "LD_ALTEXEC=" @ MSG_SUNW_OST_SGS "SUNW_OST_SGS" + +@ MSG_TARG_SPARC "sparc" +@ MSG_TARG_X86 "x86" +
--- a/usr/src/cmd/sgs/libconv/common/cap.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/cap.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -30,7 +30,7 @@ */ #include <strings.h> #include <stdio.h> -#include <sys/machelf.h> +#include <_machelf.h> #include <elfcap.h> #include "cap_msg.h" #include "_conv.h"
--- a/usr/src/cmd/sgs/libconv/common/dynamic.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/dynamic.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -359,8 +359,9 @@ }; /* - * SUNW: DT_LOOS -> DT_HIOS range. Note hole between DT_SUNW_TLSSORTSZ - * and DT_SUNW_STRPAD. We handle DT_SUNW_STRPAD as a single value below. + * SUNW: DT_LOOS -> DT_HIOS range. Note hole between DT_SUNW_TLSSORTSZ, + * DT_SUNW_STRPAD, and DT_SUNW_LDMACH. We handle the outliers + * separately below as single values. */ static const Msg tags_sunw_auxiliary[] = { MSG_DYN_SUNW_AUXILIARY, MSG_DYN_SUNW_RTLDINF, @@ -425,6 +426,8 @@ DYN_RANGE(DT_SUNW_AUXILIARY, tags_sunw_auxiliary); if (tag == DT_SUNW_STRPAD) return (MSG_ORIG(MSG_DYN_SUNW_STRPAD)); + if (tag == DT_SUNW_LDMACH) + return (MSG_ORIG(MSG_DYN_SUNW_LDMACH)); DYN_RANGE(DT_CHECKSUM, tags_checksum); DYN_RANGE(DT_CONFIG, tags_config); if (tag == DT_VERSYM)
--- a/usr/src/cmd/sgs/libconv/common/dynamic.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/dynamic.msg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -101,6 +101,7 @@ @ MSG_DYN_SUNW_TLSSORT "SUNW_TLSSORT" @ MSG_DYN_SUNW_TLSSORTSZ "SUNW_TLSSORTSZ" @ MSG_DYN_SUNW_STRPAD "SUNW_STRPAD" +@ MSG_DYN_SUNW_LDMACH "SUNW_LDMACH" @ MSG_DF_ORIGIN "ORIGIN" @ MSG_DF_SYMBOLIC "SYMBOLIC"
--- a/usr/src/cmd/sgs/libconv/common/elf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/elf.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -392,7 +392,8 @@ * terms of a string. */ const char * -conv_reject_desc(Rej_desc * rej, Conv_reject_desc_buf_t *reject_desc_buf) +conv_reject_desc(Rej_desc * rej, Conv_reject_desc_buf_t *reject_desc_buf, + Half mach) { ushort_t type = rej->rej_type; uint_t info = rej->rej_info; @@ -415,10 +416,7 @@ &reject_desc_buf->inv_buf)); else if ((type == SGS_REJ_BADFLAG) || (type == SGS_REJ_MISFLAG) || (type == SGS_REJ_HAL) || (type == SGS_REJ_US3)) - /* - * Only called from ld.so.1, thus M_MACH is hardcoded. - */ - return (conv_ehdr_flags(M_MACH, (Word)info, 0, + return (conv_ehdr_flags(mach, (Word)info, 0, &reject_desc_buf->flags_buf)); else if (type == SGS_REJ_UNKFILE) return ((const char *)0);
--- a/usr/src/cmd/sgs/libconv/common/globals.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/globals.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,14 +20,14 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <strings.h> -#include <sys/machelf.h> +#include <_machelf.h> #include "_conv.h" #include "globals_msg.h"
--- a/usr/src/cmd/sgs/libconv/common/llib-lconv Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/llib-lconv Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* LINTLIBRARY */ @@ -30,7 +30,7 @@ #include <stdlib.h> #include <libelf.h> -#include <sys/machelf.h> +#include <_machelf.h> #include <sgs.h> #include <libld.h> #include <conv.h> @@ -122,8 +122,10 @@ Conv64_phdr_flags_buf_t *); const char *conv32_phdr_type(Elf32_Half, Word, int, Conv32_inv_buf_t *); const char *conv64_phdr_type(Elf64_Half, Word, int, Conv64_inv_buf_t *); -const char *conv32_reject_desc(Rej_desc *, Conv32_reject_desc_buf_t *); -const char *conv64_reject_desc(Rej_desc *, Conv64_reject_desc_buf_t *); +const char *conv32_reject_desc(Rej_desc *, Conv32_reject_desc_buf_t *, + Elf32_Half); +const char *conv64_reject_desc(Rej_desc *, Conv64_reject_desc_buf_t *, + Elf64_Half); const char *conv32_reloc_type(Half, Word, int, Conv32_inv_buf_t *); const char *conv64_reloc_type(Half, Word, int, Conv64_inv_buf_t *); const char *conv32_reloc_type_static(Half, Word, int);
--- a/usr/src/cmd/sgs/libconv/common/symbols.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/symbols.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -29,7 +29,7 @@ * String conversion routines for symbol attributes. */ #include <stdio.h> -#include <sys/machelf.h> +#include <_machelf.h> #include <sys/elf_SPARC.h> #include <sys/elf_amd64.h> #include "_conv.h"
--- a/usr/src/cmd/sgs/libconv/common/syminfo.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libconv/common/syminfo.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -29,7 +29,7 @@ * String conversion routines for syminfo attributes. */ #include <stdio.h> -#include <sys/machelf.h> +#include <_machelf.h> #include "_conv.h" #include "syminfo_msg.h"
--- a/usr/src/cmd/sgs/libelf/common/decl.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libelf/common/decl.h Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -486,6 +486,7 @@ extern unsigned _elf_work; extern mutex_t _elf_globals_mutex; extern off_t _elf64_update(Elf * elf, Elf_Cmd cmd); +extern int _elf64_swap_wrimage(Elf *elf); /* CSTYLED */ NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \
--- a/usr/src/cmd/sgs/libelf/common/llib-lelf Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libelf/common/llib-lelf Tue Mar 18 09:17:00 2008 -0700 @@ -22,7 +22,7 @@ /* PROTOLIB1 */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -185,4 +185,5 @@ * Private Symbols */ Elf64_Off _elf_getxoff(Elf_Data *); +int _elf_swap_wrimage(Elf *); uint_t _elf_sys_encoding(void);
--- a/usr/src/cmd/sgs/libelf/common/mapfile-common Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libelf/common/mapfile-common Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -180,6 +180,7 @@ _elf_rawdata = NODYNSORT; _elf_rawfile = NODYNSORT; _elf_strptr = NODYNSORT; + _elf_swap_wrimage; _elf_update = NODYNSORT; _elf32_fsize = NODYNSORT; _elf32_xlatetof = NODYNSORT;
--- a/usr/src/cmd/sgs/libelf/common/update.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libelf/common/update.c Tue Mar 18 09:17:00 2008 -0700 @@ -24,7 +24,7 @@ * All Rights Reserved * * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,6 +66,7 @@ #define wrt wrt64 #define elf_xlatetof elf64_xlatetof #define _elfxx_update _elf64_update +#define _elfxx_swap_wrimage _elf64_swap_wrimage #else /* ELF32 */ @@ -81,6 +82,7 @@ #define wrt wrt32 #define elf_xlatetof elf32_xlatetof #define _elfxx_update _elf32_update +#define _elfxx_swap_wrimage _elf32_swap_wrimage #endif /* ELF64 */ @@ -358,7 +360,7 @@ d->db_osz = (size_t)fsz; if ((sh->sh_type != SHT_NOBITS) && - ((j = (Xword)(d->db_data.d_off + d->db_osz)) > sz)) + ((j = (Xword)(d->db_data.d_off + d->db_osz)) > sz)) sz = j; } if (sh->sh_size < sz) { @@ -404,10 +406,24 @@ Elf_Scn *s; Ehdr *eh = elf->ed_ehdr; unsigned ver = eh->e_version; - unsigned encode = eh->e_ident[EI_DATA]; + unsigned encode; int byte; /* + * If this is an ELF_C_WRIMAGE write, then we encode into the + * byte order of the system we are running on rather than that of + * of the object. For ld.so.1, this is the same order, but + * for 'ld', it might not be in the case where we are cross + * linking an object for a different target. In this later case, + * the linker-host byte order is necessary so that the linker can + * manipulate the resulting image. It is expected that the linker + * will call elf_swap_wrimage() if necessary to convert the image + * to the target byte order. + */ + encode = (update_cmd == ELF_C_WRIMAGE) ? _elf_sys_encoding() : + eh->e_ident[EI_DATA]; + + /* * Two issues can cause trouble for the output file. * First, begin() with ELF_C_RDWR opens a file for both * read and write. On the write update(), the library @@ -695,8 +711,8 @@ return ((off_t)sz); } sz = _elf_outsync(elf->ed_fd, elf->ed_wrimage, - elf->ed_wrimagesz, - (elf->ed_myflags & EDF_IMALLOC ? 0 : 1)); + elf->ed_wrimagesz, + (elf->ed_myflags & EDF_IMALLOC ? 0 : 1)); elf->ed_myflags &= ~EDF_IMALLOC; elf->ed_wrimage = 0; elf->ed_wrimagesz = 0; @@ -756,6 +772,105 @@ } +/* + * When wrt() processes an ELF_C_WRIMAGE request, the resulting image + * gets the byte order (encoding) of the platform running the linker + * rather than that of the target host. This allows the linker to modify + * the image, prior to flushing it to the output file. This routine + * is used to re-translate such an image into the byte order of the + * target host. + */ +int +_elfxx_swap_wrimage(Elf * elf) +{ + NOTE(ASSUMING_PROTECTED(*elf)) + Elf_Data dst, src; + Elf_Scn *s; + Ehdr *eh = elf->ed_ehdr; + Half e_phnum = eh->e_phnum; + unsigned ver = eh->e_version; + unsigned encode = eh->e_ident[EI_DATA]; + + /* + * Ehdr first + */ + + src.d_buf = dst.d_buf = (Elf_Void *)eh; + src.d_type = dst.d_type = ELF_T_EHDR; + src.d_size = dst.d_size = sizeof (Ehdr); + src.d_version = dst.d_version = ver; + if (elf_xlatetof(&dst, &src, encode) == 0) + return (1); + + /* + * Phdr table if one exists + */ + + if (e_phnum != 0) { + unsigned work; + /* + * Unlike other library data, phdr table is + * in the user version. + */ + + src.d_buf = dst.d_buf = (Elf_Void *)elf->ed_phdr; + src.d_type = dst.d_type = ELF_T_PHDR; + src.d_size = dst.d_size = elf->ed_phdrsz; + ELFACCESSDATA(work, _elf_work) + src.d_version = dst.d_version = work; + if (elf_xlatetof(&dst, &src, encode) == 0) { + return (1); + } + } + + /* + * Loop through sections + */ + + for (s = elf->ed_hdscn; s != 0; s = s->s_next) { + register Dnode *d, *prevd; + Shdr *sh = s->s_shdr; + + if ((sh->sh_type == SHT_NOBITS) || (sh->sh_type == SHT_NULL)) + continue; + + for (d = s->s_hdnode, prevd = 0; + d != 0; prevd = d, d = d->db_next) { + + if ((d->db_myflags & DBF_READY) == 0) { + SCNLOCK(s); + if (_elf_locked_getdata(s, &prevd->db_data) != + &d->db_data) { + SCNUNLOCK(s); + return (1); + } + SCNUNLOCK(s); + } + + dst = d->db_data; + if (elf_xlatetof(&dst, &d->db_data, encode) == 0) + return (1); + } + } + + /* + * Shdr table + */ + + src.d_type = dst.d_type = ELF_T_SHDR; + src.d_version = dst.d_version = ver; + for (s = elf->ed_hdscn; s != 0; s = s->s_next) { + src.d_buf = dst.d_buf = s->s_shdr; + src.d_size = dst.d_size = sizeof (Shdr); + if (elf_xlatetof(&dst, &src, encode) == 0) + return (1); + } + + return (0); +} + + + #ifndef _ELF64 /* class-independent, only needs to be compiled once */ @@ -775,6 +890,22 @@ return (-1); } +int +_elf_swap_wrimage(Elf *elf) +{ + if (elf == 0) + return (0); + + if (elf->ed_class == ELFCLASS32) + return (_elf32_swap_wrimage(elf)); + + if (elf->ed_class == ELFCLASS64) + return (_elf64_swap_wrimage(elf)); + + _elf_seterr(EREQ_CLASS, 0); + return (0); +} + /* * 4106312, 4106398, This is an ad-hoc means for the 32-bit * Elf64 version of libld.so.3 to get around the limitation
--- a/usr/src/cmd/sgs/libld/Makefile.com Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/Makefile.com Tue Mar 18 09:17:00 2008 -0700 @@ -31,25 +31,47 @@ COMOBJS = debug.o globals.o util.o COMOBJS32 = args32.o entry32.o exit32.o groups32.o \ - ldentry32.o ldlibs32.o ldmain32.o libs32.o \ - files32.o map32.o order32.o outfile32.o \ - place32.o relocate32.o resolve32.o sections32.o \ - sunwmove32.o support32.o syms32.o update32.o \ - version32.o + ldentry32.o ldlibs32.o ldmachdep32.o ldmain32.o \ + libs32.o files32.o map32.o order32.o \ + outfile32.o place32.o relocate32.o resolve32.o \ + sections32.o sunwmove32.o support32.o syms32.o \ + update32.o version32.o COMOBJS64 = args64.o entry64.o exit64.o groups64.o \ - ldentry64.o ldlibs64.o ldmain64.o libs64.o \ - files64.o map64.o order64.o outfile64.o \ - place64.o relocate64.o resolve64.o sections64.o \ - sunwmove64.o support64.o syms64.o update64.o \ - version64.o + ldentry64.o ldlibs64.o ldmachdep64.o ldmain64.o \ + libs64.o files64.o map64.o order64.o \ + outfile64.o place64.o relocate64.o resolve64.o \ + sections64.o sunwmove64.o support64.o syms64.o \ + update64.o version64.o TOOLOBJS = alist.o assfail.o findprime.o string_table.o \ strhash.o AVLOBJ = avl.o -G_MACHOBJS32 = doreloc32.o -G_MACHOBJS64 = doreloc64.o +# Relocation engine objects. These are kept separate from the L_XXX_MACHOBJS +# lists below in order to facilitate linting them. +G_MACHOBJS32 = doreloc_sparc_32.o doreloc_x86_32.o +G_MACHOBJS64 = doreloc_sparc_64.o doreloc_x86_64.o + +# Target specific objects (sparc/sparcv9) +L_SPARC_MACHOBJS32 = machrel.sparc32.o machsym.sparc32.o +L_SPARC_MACHOBJS64 = machrel.sparc64.o machsym.sparc64.o + +# Target specific objects (i386/amd64) +E_X86_TOOLOBJS = leb128.o +L_X86_MACHOBJS32 = machrel.intel32.o +L_X86_MACHOBJS64 = machrel.amd64.o unwind.amd64.o + + +# All target specific objects rolled together +E_TOOLOBJS = $(E_SPARC_TOOLOBJS) \ + $(E_X86_TOOLOBJS) +L_MACHOBJS32 = $(L_SPARC_MACHOBJS32) \ + $(L_X86_MACHOBJS32) +L_MACHOBJS64 = $(L_SPARC_MACHOBJS64) \ + $(L_X86_MACHOBJS64) + + BLTOBJ = msg.o ELFCAPOBJ = elfcap.o @@ -65,6 +87,14 @@ SRCDIR = ../common ELFCAP= $(SRC)/common/elfcap + +# Location of the shared relocation engines maintained under usr/src/uts. +# +KRTLD_I386 = $(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld +KRTLD_AMD64 = $(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld +KRTLD_SPARC = $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld + + # Building SUNWonld results in a call to the `package' target. Requirements # needed to run this application on older releases are established: # dlopen/dlclose requires libdl.so.1 prior to 5.10 @@ -75,7 +105,7 @@ CPPFLAGS += -DUSE_LIBLD_MALLOC -I$(SRCBASE)/lib/libc/inc \ -I$(SRCBASE)/uts/common/krtld -I$(ELFCAP) \ -I$(SRCBASE)/uts/sparc \ - $(VAR_LIBLD_CPPFLAGS) -DDO_RELOC_LIBLD + $(VAR_LIBLD_CPPFLAGS) LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(LDDBGLIBDIR) $(LDDBG_LIB) \ $(ELFLIBDIR) -lelf $(DLLIB) -lc @@ -93,10 +123,14 @@ BLTFILES = $(BLTDEFS) $(BLTDATA) $(BLTMESG) +# Due to cross linking support, every copy of libld contains every message. +# However, we keep target specific messages in their own separate files for +# organizational reasons. +# SGSMSGCOM = ../common/libld.msg SGSMSGSPARC = ../common/libld.sparc.msg SGSMSGINTEL = ../common/libld.intel.msg -SGSMSGTARG = $(SGSMSGCOM) +SGSMSGTARG = $(SGSMSGCOM) $(SGSMSGSPARC) $(SGSMSGINTEL) SGSMSGALL = $(SGSMSGCOM) $(SGSMSGSPARC) $(SGSMSGINTEL) SGSMSGFLAGS1 = $(SGSMSGFLAGS) -m $(BLTMESG) @@ -105,7 +139,10 @@ CHKSRCS = $(SRCBASE)/uts/common/krtld/reloc.h \ $(COMOBJS32:%32.o=../common/%.c) \ $(L_MACHOBJS32:%32.o=../common/%.c) \ - $(L_MACHOBJS64:%64.o=../common/%.c) + $(L_MACHOBJS64:%64.o=../common/%.c) \ + $(KRTLD_I386)/doreloc.c \ + $(KRTLD_AMD64)/doreloc.c \ + $(KRTLD_SPARC)/doreloc.c SRCS = ../common/llib-lld LIBSRCS = $(TOOLOBJS:%.o=$(SGSTOOLS)/common/%.c) \ @@ -120,6 +157,19 @@ LINTSRCS64 = $(COMOBJS64:%64.o=../common/%.c) \ $(L_MACHOBJS64:%64.o=../common/%.c) +# Add the shared relocation engine source files to the lint +# sources and add the necessary command line options to lint them +# correctly. Make can't derive the files since the source and object +# names are not directly related +$(LINTOUT32) := CPPFLAGS += -DDO_RELOC_LIBLD +$(LINTOUT64) := CPPFLAGS += -DDO_RELOC_LIBLD -D_ELF64 +$(LINTLIB32) := CPPFLAGS += -DDO_RELOC_LIBLD +$(LINTLIB64) := CPPFLAGS += -DDO_RELOC_LIBLD -D_ELF64 +LINTSRCS32 += $(KRTLD_I386)/doreloc.c \ + $(KRTLD_SPARC)/doreloc.c +LINTSRCS64 += $(KRTLD_AMD64)/doreloc.c \ + $(KRTLD_SPARC)/doreloc.c + CLEANFILES += $(LINTOUTS) $(BLTFILES) CLOBBERFILES += $(DYNLIB) $(LINTLIBS) $(LIBLINKS)
--- a/usr/src/cmd/sgs/libld/Makefile.targ Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/Makefile.targ Tue Mar 18 09:17:00 2008 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -30,19 +30,19 @@ $(POST_PROCESS_O) pics/%32.o: ../common/%.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< + $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%64.o: ../common/%.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< + $(COMPILE.c) -o $@ -D_ELF64 $< $(POST_PROCESS_O) pics/%32.o: %.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< + $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%64.o: %.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< + $(COMPILE.c) -o $@ -D_ELF64 $< $(POST_PROCESS_O) pics/%.o: $(SGSTOOLS)/common/%.c @@ -53,18 +53,40 @@ $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) -#pics/%32.o: $(SRCBASE)/uts/$(PLAT)/krtld/%.c -# $(COMPILE.c) -o $@ $(ELFTARGET32) $< -# $(POST_PROCESS_O) # -#pics/%64.o: $(SRCBASE)/uts/$(PLAT)/krtld/%.c -# $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< -# $(POST_PROCESS_O) - +# We use the shared elfcap code under usr/src/common/elfcap +# pics/elfcap.o: $(ELFCAP)/elfcap.c $(COMPILE.c) -o $@ $(ELFCAP)/elfcap.c $(POST_PROCESS_O) +# Rules for compiling the shared relocation engines (doreloc.c) maintained +# under usr/src/uts. To support cross linking, We compile and link +# all of these into every copy of libld. Each one requires a separate rule: +# - The source files are in different subtrees under usr/src/uts +# - The output file needs to include the platform name to +# keep the object files from colliding +# The DO_RELOC_LIBLD definition is needed to generate the libld version +# of the doreloc code. +# +pics/%_x86_32.o: $(KRTLD_I386)/%.c + $(COMPILE.c) -o $@ -DDO_RELOC_LIBLD $< + $(POST_PROCESS_O) + +pics/%_x86_64.o: $(KRTLD_AMD64)/%.c + $(COMPILE.c) -o $@ -D_ELF64 -DDO_RELOC_LIBLD $< + $(POST_PROCESS_O) + +pics/%_sparc_32.o: $(KRTLD_SPARC)/%.c + $(COMPILE.c) -o $@ -DDO_RELOC_LIBLD $< + $(POST_PROCESS_O) + +pics/%_sparc_64.o: \ + $(KRTLD_SPARC)/%.c + $(COMPILE.c) -o $@ -D_ELF64 -DDO_RELOC_LIBLD $< + $(POST_PROCESS_O) + + $(LIBLINKS): $(RM) $@; $(SYMLINK) $(DYNLIB) $@
--- a/usr/src/cmd/sgs/libld/amd64/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/amd64/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -20,16 +20,12 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # -E_TOOLOBJS = leb128.o -L_MACHOBJS32 = machrel.intel32.o machsym.intel32.o -L_MACHOBJS64 = machrel.amd64.o machsym.intel64.o unwind.amd64.o - include ../Makefile.com .KEEP_STATE: @@ -40,16 +36,6 @@ ROOTFS_DYNLIB64 = \ $(DYNLIB:%=$(ROOTFS_LIBDIR64)/%) -SGSMSGCHK = ../common/libld.chk.msg -SGSMSGTARG += $(SGSMSGINTEL) - -# -# For cross-compilation, it is necessary to trigger the correct include files -# (see sys/elf.h). -# -ELFTARGET64 = -DELF_TARGET_AMD64 -ELFTARGET32 = -DELF_TARGET_386 - ELFLIBDIR = $(ELFLIBDIR64) LDDBGLIBDIR = $(LDDBGLIBDIR64) CONVLIBDIR = $(CONVLIBDIR64) @@ -63,37 +49,3 @@ include ../Makefile.targ include ../../Makefile.sub.64 - -# Associate ELF32 and ELF64 objects to the appropriate headers. - -pics/%32.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld -pics/%64.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld - -# Associate the various lint targets with the appropriate headers/files. - -$(LINTOUT32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld \ - $(ELFTARGET32) -$(LINTOUT64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld \ - $(ELFTARGET64) -D_ELF64 -$(LINTLIB32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld \ - $(ELFTARGET32) -$(LINTLIB64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld \ - $(ELFTARGET64) -D_ELF64 - -LINTSRCS32 += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c) -LINTSRCS64 += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c) - -# Compensate chkmsg with the doreloc family. - -CHKSRCS += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c) -CHKSRCS += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c) - -pics/%32.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< - $(POST_PROCESS_O) - -pics/%64.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< - $(POST_PROCESS_O)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/libld/common/README.XLINK Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,373 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" + + + + +Notes On Cross Link-Editor Support in libld.so +----------------------------------------- + +The Solaris link-editor is used in two contexts: + + 1) The standard ld command + 2) Via the runtime linker (ld.so.1), when a program + calls dlopen() on a relocatable object (ET_REL). + +To support both uses, it is packaged as a sharable library (libld.so). +The ld command is therefore a simple wrapper that uses libld. + +libld.so is a cross linker. This means that it can link objects for +a system other than the system running the link-editor (e.g. A link-editor +running on an amd64 system processing sparc objects). This means that every +instance of libld.so contains code for building objects for every supported +target. This unlike GNU ld, where you build gld specifically for the +platform you're targeting. This is possible because unlike gld, we only +support Solaris, with a small number of platforms. + +At initialization, the caller of libld.so specifies the type of objects +being linked. By default, the ld command determines the machine type and +class of the object being generated from the first ELF object processed +from the command line. The -64 and -ztarget options exists to change this +default, which is useful when creating an object entirely from an archive +library or a mapfile. During initialization, the link-editor configures +itself to build an output object of the specified type. This is done via +indirection, using the global ld_targ structure to access code, data, and +constants for the specified target. + +There are two types of source files used to build libld.so: + + 1) Common code used for all targets + 2) Target specific code used only when linking for + a given target. + +All of these files reside in usr/src/cmd/sgs/libld/common. However, +it is easy to see which files belong in each category by examining +the object lists maintained in usr/src/cmd/sgs/libld/Makefile.com. +In addition, the target-specific files usually include the target +in their name (i.e. machrel.sparc.c). + +Although the target dependent and independent (common) code is well separated, +they are interdependent. For example, the common code is aware of +the target-specific section types that can occur only for some targets +(i.e. SHT_AMD64_UNWIND). This is not an architecture that allows +for arbitrary target support to be dynamically plugged into an unchanged +platform independent core. Rather, it is an organization that allows +a common core to support all the targets it knows about in a way that +is understandable and maintainable. A truly pluggable architecture +would be considerably more opaque and complex, and is neither necessary, +nor desirable, given the wide commonality between modern computer +architectures. + +It is possible to add support for new targets to libld.so. The process +of doing so is largely a matter of examining the files for existing +platforms, studying the ABI for the new target platform, and then +filling in the missing pieces for the new target. The remainder of this +file consists of sections that describe some of the issues and steps +that you will encounter in adding a new target. + +----------------------------------------------------------------------------- +The relocation code used by ld is shared by the runtime linker (ld.so.1) +and by the kernel module loader (ktrld), and is therefore found under +usr/src/uts. You must add code for a relocation engine to support the +new target. To do so, examine the common header files: + + usr/src/uts/common/krtld/reloc.h + usr/src/uts/common/krtld/reloc_defs.h + + and the existing relocation engines: + + usr/src/uts/intel/amd64/krtld/doreloc.c + usr/src/uts/intel/ia32/krtld/doreloc.c + usr/src/uts/sparc/krtld/doreloc.c + +The ABI for the target platform will be the primary information +you require. If your new system has attributes not found in an existing +target, you may have to add/modify fields in the Rel_entry struct typedef +(reloc_defs.h), or you may have to add new flags. Either sort of change +may require you to also modify the existing relocation engines, and +undoubtedly the common code in libld.so as well. + +When compiled for use by libld, the relocation engine requires an +argument named "bswap". Each relocation engine must be prepared to +swap the data bytes it is operating on. This support allows a link-editor +running on a platform with a different byte order than the target to +build objects for that target. To see how this is implemented, and how +to ifdef that support so it only exists in the libld version of +the engine, examine the code for the existing engines. + +----------------------------------------------------------------------------- +You must create a target subdirectory in usr/src/cmd/sgs/include, +and construct a machdep_XXX.h file (where XXX is the name of the +target). The machdep files for the current platforms can be helpful: + + usr/src/cmd/sgs/include/sparc/machdep_sparc.h + usr/src/cmd/sgs/include/i386/machdep_x86.h + +Note that these files support both the 32 and 64-bit versions of +a given platform, so there is only one subdirectory and machdep +file for each platform (i.e. "sparc", instead of "sparc" and "sparcv9"). + +Once you have created the target machdep_XXX.h file, you must edit: + + usr/src/cmd/sgs/include/machdep.h + +and add a #include for your new file to it, surrounded by the +appropriate #ifdef for the target platform. + +This two level structure allows us to #include machdep information +in two different ways: + + 1) Code that wants support for the current platform, + regardless of which platform that is, can include + usr/src/cmd/sgs/include/machdep.h. The runtime linker + (ld.so.1) is the primary consumer of this form. + + 2) Code that needs to support multiple targets must never + include the generic machdep.h from (1) above. Instead, + such code explicitly includes the machdep file for the target + it is interested in. For example: + + #include <sparc/machdep_sparc.h> + + libld.so uses this form to build non-native target + code. + +You will find that most of the constants defined in the target +machdep file end up as initialization for the information that +libld.so accesses via the ld_targ global variable. + +----------------------------------------------------------------------------- +Study the definition of the Target typedef in + + usr/src/cmd/sgs/libld/common/_libld.h + +This is the type of the ld_targ global variable. Filling in a complete +copy of this definition is the primary task involved in adding support +for a new target to libld.so, so it will be helpful to be familiar with +it before you dive deeper. libld follows two simple rules with regards +to ld_targ, and the Target type: + + 1) The target-independent common code can only access + target-dependent code or data via the ld_targ global + variable. + + 2) The target-dependent code can access the common + code or data freely. + +A given link-editor invocation is always for a single target. The choice +of target is made at initialization, and does not change within a +single link. Code for the other targets is present, but is not +accessed. + +----------------------------------------------------------------------------- +Files containing the target-specific code to support the new +platform must be added to libld.so. Examine the object lists +in usr/src/cmd/sgs/libld/Makefile.com to see the files for existing +platforms, and read those files to get a sense of what is required. + +Among the other files, every platform will have a file named +machrel.XXX.c. This file contains the relocation-related functions, +and it also contains an init function for the target. This init function +is responsible for initializing the ld_targ global variable so that +the common code will use the code and definitions for your +target. + +You should start by creating a machrel.XXX.c file for your new +target. Add other files as needed. Be aware that any functions or +variables you place in these target-dependent files must either +be static, or must have names that will not collide with the names +used by the rest of libld.so. The easiest way to do this is to +add a target suffix to the end of all such non-local names +(i.e. foo_sparc() instead of foo()). + +The existing code is the documentation for this phase of things: The +best way to determine what a given function should do is to read the +code for other platforms, taking into account the similarities and +differences in the ABI for your new target and those existing ones. + +----------------------------------------------------------------------------- +You may find that your new target requires support for new concepts +not found in other targets. A common example of this might be +a new target specific ELF section type (i.e. SHT_AMD64_UNWIND). Another +might be details involving PIC code and PLT generation (as found for +sparc). It may be necessary to add new fields to the ld_targ global +variable, and to modify the libld.so common code to use these new +fields. + +It is a standard convention that NULL function pointers are used to +represent functionality not required by a given target. Although the +common code can consult ld_targ.t_m.m_mach to determine the target it +is linking for, and although there is some code that does this, it +is generally undesirable and unnecessary. Instead, the common code +should test for such pointers, as with this sparc-specific example +from update.c: + + /* + * Assign a got offset if necessary. + */ + if ((ld_targ.t_mr.mr_assign_got != NULL) && + (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR) + return ((Addr)S_ERROR); + +It may be tempting to include information in the comment that explains +the target specific nature of this, and that may even be appropriate. +Consider however, that a new target may come along with the same feature +later, and if that occurs, your comments will instantly be dated. In general, +the use of ld_targ is a strong hint to the reader that they should go read +the target-specific code referenced to understand what is going on. It is +best to supply comments at the call site that describe the operation +in generic terms (i.e. "assign a got if necessary") instead of in +explicit target terms (i.e. "Assign a sparc got if necessary"). Of +course, some features are extremely target-specific (like amd64 unwind +sections), and it doesn't really help to be obscure in such cases. +This is a judgement call. + +If you do add a new field to ld_targ that uses NULL to represent +an option feature *YOU MUST DOCUMENT IT AS SUCH*. You will find +comments in _libld.h for existing optional fields. It suffices to +add a comment for your new field. In the absence of such a comment, +the common code assumes that all function pointers are safe to call +through (dereference) without first testing them. + +----------------------------------------------------------------------------- +Byte swapping is a big issue in cross linking, as the system running +the link-editor may have the opposite byte order from the target. It is +important to know when, and when not, to swap bytes. + +If the build system and target have different byte orders, the +FLG_OF1_ENCDIFF bit of the ofl_flags field of the output file +descriptor will be set. If this bit is not set, the target and +system byte orders are the same, and no byte swapping +is required. + +libld uses libelf to read and write objects. libelf automatically +swaps bytes for the sections it knows about, such as symbol tables, +relocation records, and the usual ELF plumbing. It is therefore never +necessary for your code to swap the bytes in this data. If you find that +this is not the case, you have probably uncovered a bug in libelf that +you should look into. + +The big exception to libelf transparently handling byte swapping is +progbits sections (SHT_PROGBITS). libelf does not understand program +code or data as anything other than a series of byte values, and as such, +cannot do byte swapping for them. If your code examines or modifies +such data, you are responsible for handling the byte swapping required. + +The OFL_SWAP_RELOC macros found in _libld.h can be helpful in making such +determinations. You should use these macros instead of writing your own +tests for this, as they have high documentation value. If you find they +don't handle your target, add a new one that does. + +GOT and PLT sections are SHT_PROGBITS. You will probably find +that the vast majority of byte swapping you have to handle +concern the handling of these items. + +libld contains generic functions for byte swapping: + + ld_bswap_Word(); + ld_bswap_Xword(); + +These functions are built on top of the of the BSWAP_ macros found +in usr/src/cmd/sgs/include/_machelf.h: + + BSWAP_HALF + BSWAP_WORD + BSWAP_XWORD + +When copying data from one address to another in a cross link environment, +the source and/or destination addresses may not have adequate alignment for +the data type being copied. For example, a sparc platform cannot access +8-byte data types on 4-byte boundaries, but it might need to do so when +linking X86 objects where the alignment of such data can be 4. The +UL_ASSIGN macros can be used to copy potentially unaligned data: + + UL_ASSIGN_HALF + UL_ASSIGN_WORD + UL_ASSIGN_XWORD + +The UL_ASSIGN_BSWAP macros do unaligned copies, and also perform +byte swapping when the linker host and target byte orders are +different: + + UL_ASSIGN_BSWAP_HALF + UL_ASSIGN_BSWAP_WORD + UL_ASSIGN_BSWAP_XWORD + +If you are reading/writing to relocation data, the following +routines understand relocation records and will get/set the +proper amount of data while handling any needed swapping: + + ld_reloc_targval_get() + ld_reloc_targval_set() + +Byte swapping is a fertile area for mistakes. If you're having trouble +getting a successful link in a cross link situation, you should always +do the experiment of doing the link on a platform with the same byte +order as the target. If that link succeeds, then you are looking at +a bug involving incorrect byte swapping. + +----------------------------------------------------------------------------- + As mentioned above, incorrect byte swapping is a common +error when developing libld target specific code. In addition to +trying a build machine with the same byte order as the target, elfdump +can also be a powerful tool for debugging. The first step with +elfdump is to simply dump everything and read it looking for obviously +bad information: + + % elfdump outobj 2>&1 | more + +elfdump tries to do sanity checking on the objects it +displays. Hence, the following command is a a common +idiom: + + % elfdump outobj > /dev/null + +Any problems with the file that elfdump can detect will be +written to stderr. + +----------------------------------------------------------------------------- +Once you have the target-specific code in place, you must modify the +libld initialization code so that it will know how to use it. This +logic is found in + + usr/src/cmd/sgs/libld/common/ldmain.c + +in the function ld_init_target(). + +----------------------------------------------------------------------------- +The ld front end program that uses libld must be modified so that +the "-z target=platform" command line option recognizes your +new target. This code is found in + + usr/src/cmd/sgs/ld/common + +The change consists of adding an additional strcasecmp() to the +command line processing for -ztarget. + +----------------------------------------------------------------------------- +You probably changed things getting your target integrated. +Please update this document to reflect your changes.
--- a/usr/src/cmd/sgs/libld/common/_libld.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/_libld.h Tue Mar 18 09:17:00 2008 -0700 @@ -41,27 +41,206 @@ #include <debug.h> #include <conv.h> #include <msg.h> +#include <reloc_defs.h> #ifdef __cplusplus extern "C" { #endif /* - * Types of segment index. + * In order to allow for cross linking, we need to be able to build + * libld with support for multiple targets within a single object. + * This is done using a global variable (ld_targ) of type Target to + * access target-specific code for the current target via indirection. + */ + +/* + * Machine information for target + */ +typedef struct { + Half m_mach; /* ELF machine code for target */ + Half m_machplus; /* Alt ELF machine code for target */ + /* Used for EM_SPARC32PLUS */ + Word m_flagsplus; /* ELF header flags used to identify */ + /* a machplus object */ + uchar_t m_class; /* Target ELFCLASS */ + uchar_t m_data; /* Target byte order */ + + Xword m_segm_align; /* segment alignment */ + Xword m_segm_origin; /* Default 1st segment offset */ + Word m_dataseg_perm; /* data segment permission mask */ + Word m_word_align; /* alignment to use for Word sections */ + const char *m_def_interp; /* Def. interpreter for dyn objects */ + + /* Relocation type codes */ + Word m_r_arrayaddr; + Word m_r_copy; + Word m_r_glob_dat; + Word m_r_jmp_slot; + Word m_r_num; + Word m_r_none; + Word m_r_relative; + Word m_r_register; + + /* Relocation related constants */ + Word m_rel_dt_count; /* Either DT_REL or DT_RELA */ + Word m_rel_dt_ent; /* Either DT_RELENT or DT_RELAENT */ + Word m_rel_dt_size; /* Either DT_RELSZ or DT_RELASZ */ + Word m_rel_dt_type; /* Either DT_RELCOUNT or DT_RELACOUNT */ + Word m_rel_sht_type; /* Either SHT_REL or SHT_RELA */ + + /* GOT related constants */ + Word m_got_entsize; + Word m_got_xnumber; /* reserved # of got ents */ + + /* PLT related constants */ + Word m_plt_align; + Word m_plt_entsize; + Word m_plt_reservsz; + Word m_plt_shf_flags; + + Word m_dt_register; +} Target_mach; + + +/* + * Section identifiers, used to order sections in output object */ -typedef enum { - LD_PHDR, LD_INTERP, LD_SUNWCAP, LD_TEXT, - LD_DATA, LD_BSS, -#if defined(__x86) && defined(_ELF64) - LD_LRODATA, LD_LDATA, -#endif - LD_DYN, LD_DTRACE, LD_SUNWBSS, LD_TLS, -#if defined(__x86) && defined(_ELF64) - LD_UNWIND, -#endif - LD_NOTE, LD_EXTRA, - LD_NUM -} Segment_ndx; +typedef struct { + Word id_array; + Word id_bss; + Word id_cap; + Word id_data; + Word id_dynamic; + Word id_dynsort; + Word id_dynstr; + Word id_dynsym; + Word id_dynsym_ndx; + Word id_got; + Word id_gotdata; + Word id_hash; + Word id_interp; + Word id_lbss; + Word id_ldynsym; + Word id_note; + Word id_null; + Word id_plt; + Word id_rel; + Word id_strtab; + Word id_syminfo; + Word id_symtab; + Word id_symtab_ndx; + Word id_text; + Word id_tls; + Word id_tlsbss; + Word id_unknown; + Word id_unwind; + Word id_user; + Word id_version; +} Target_machid; + +/* + * Target_nullfunc supplies machine code for generating a + * + * void (*)(void) + * + * unnamed function. Such a function can be called, and returns + * immediately without doing any work. This is used to back FUNC + * symbol definitions added with a mapfile. + * + * The machine instructions are specified as an array of bytes rather + * than a larger integer type in order to avoid byte order issues that + * can otherwise occur in cross linking. + */ +typedef struct { + const uchar_t *nf_template; /* Array of machine inst. bytes */ + size_t nf_size; /* # bytes in nf_template */ +} Target_nullfunc; + +/* + * Target_machrel holds pointers to the reloc_table and machrel functions + * for a given target machine. + * + * The following function pointers are allowed to be NULL, if the + * underlying target does not require the specified operation. All + * other functions must be supplied: + * + * mr_assign_got + * mr_reloc_register + * mr_reloc_GOTOP + * mr_allocate_got + */ +typedef struct { + const Rel_entry *mr_reloc_table; + + Word (* mr_init_rel)(Rel_desc *, void *); + void (* mr_mach_eflags)(Ehdr *, Ofl_desc *); + void (* mr_mach_make_dynamic)(Ofl_desc *, size_t *); + void (* mr_mach_update_odynamic)(Ofl_desc *, Dyn **); + Xword (* mr_calc_plt_addr)(Sym_desc *, Ofl_desc *); + uintptr_t (* mr_perform_outreloc)(Rel_desc *, Ofl_desc *); + uintptr_t (* mr_do_activerelocs)(Ofl_desc *); + uintptr_t (* mr_add_outrel)(Word, Rel_desc *, Ofl_desc *); + uintptr_t (* mr_reloc_register)(Rel_desc *, Is_desc *, + Ofl_desc *); + uintptr_t (* mr_reloc_local)(Rel_desc *, Ofl_desc *); + uintptr_t (* mr_reloc_GOTOP)(Boolean, Rel_desc *, Ofl_desc *); + uintptr_t (* mr_reloc_TLS)(Boolean, Rel_desc *, Ofl_desc *); + uintptr_t (* mr_assign_got)(Ofl_desc *, Sym_desc *); + + Gotndx * (* mr_find_gotndx)(List *, Gotref, Ofl_desc *, + Rel_desc *); + Xword (* mr_calc_got_offset)(Rel_desc *, Ofl_desc *); + uintptr_t (* mr_assign_got_ndx)(List *, Gotndx *, Gotref, + Ofl_desc *, Rel_desc *, Sym_desc *); + void (* mr_assign_plt_ndx)(Sym_desc *, Ofl_desc *); + uintptr_t (* mr_allocate_got)(Ofl_desc *); + uintptr_t (* mr_fillin_gotplt)(Ofl_desc *); +} Target_machrel; + + +/* + * Target_machsym holds pointers to the machsym functions + * for a given target machine. + * + * These fields are allowed to be NULL for targets that do not require + * special handling of register symbols. Register symbols are used by + * sparc targets. If any of these fields are non-NULL, all of them are + * required to be present (use empty stub routines if necessary). + */ +typedef struct { + int (* ms_reg_check)(Sym_desc *, Sym *, const char *, + Ifl_desc *, Ofl_desc *); + int (* ms_mach_sym_typecheck)(Sym_desc *, Sym *, + Ifl_desc *, Ofl_desc *); + const char *(* ms_is_regsym)(Ofl_desc *, Ifl_desc *, Sym *, + const char *, int, Word, const char *, Word *); + Sym_desc *(* ms_reg_find)(Sym * sym, Ofl_desc * ofl); + int (* ms_reg_enter)(Sym_desc *, Ofl_desc *); +} Target_machsym; + +/* + * amd64 unwind header support + * + * These fields are allowed to be NULL for targets that do not support + * amd64 unwind headers. If any of these fields are non-NULL, all of them are + * required to be present (use empty stub routines if necessary). + */ +typedef struct { + uintptr_t (* uw_make_unwindhdr)(Ofl_desc *); + uintptr_t (* uw_populate_unwindhdr)(Ofl_desc *); + uintptr_t (* uw_append_unwind)(Os_desc *, Ofl_desc *); +} Target_unwind; + +typedef struct { + Target_mach t_m; + Target_machid t_id; + Target_nullfunc t_nf; + Target_machrel t_mr; + Target_machsym t_ms; + Target_unwind t_uw; +} Target; + /* * Types of bss sections @@ -203,6 +382,7 @@ extern const int ldynsym_symtype[STT_NUM]; extern const int dynsymsort_symtype[STT_NUM]; + /* * Given a symbol of a type that is allowed within a .SUNW_dynsymsort or * .SUNW_dyntlssort section, examine the symbol attributes to determine @@ -293,6 +473,18 @@ /* + * The OFL_SWAP_RELOC macros are used to determine whether + * relocation processing needs to swap the data being relocated. + * It is an optimization to ld_swap_reloc_data(), as it avoids + * the function call in the case where the linker host and the + * target have the same byte order. + */ + +#define OFL_SWAP_RELOC_DATA(_ofl, _rel) \ + (((_ofl)->ofl_flags1 & FLG_OF1_ENCDIFF) && \ + ld_swap_reloc_data(_ofl, _rel)) + +/* * For backward compatibility provide a /dev/zero file descriptor. */ extern int dz_fd; @@ -321,40 +513,23 @@ #define ld_add_actrel ld64_add_actrel #define ld_add_libdir ld64_add_libdir -#define ld_add_outrel ld64_add_outrel #define ld_adj_movereloc ld64_adj_movereloc -#if defined(__sparc) -#define ld_allocate_got ld64_allocate_got -#endif #define ld_am_I_partial ld64_am_I_partial #define ld_append_isp ld64_append_isp #define ld_ar_member ld64_ar_member #define ld_ar_setup ld64_ar_setup -#define ld_assign_got ld64_assign_got -#define ld_assign_got_ndx ld64_assign_got_ndx #define ld_assign_got_TLS ld64_assign_got_TLS -#define ld_assign_plt_ndx ld64_assign_plt_ndx -#define ld_byteswap_Xword ld64_byteswap_Xword -#define ld_calc_got_offset ld64_calc_got_offset -#define ld_calc_plt_addr ld64_calc_plt_addr +#define ld_bswap_Word ld64_bswap_Word +#define ld_bswap_Xword ld64_bswap_Xword #define ld_disp_errmsg ld64_disp_errmsg -#define ld_do_activerelocs ld64_do_activerelocs #define ld_ent_check ld64_ent_check #define ld_exit ld64_exit -#define ld_fillin_gotplt ld64_fillin_gotplt -#define ld_find_gotndx ld64_find_gotndx #define ld_find_library ld64_find_library #define ld_finish_libs ld64_finish_libs #define ld_get_group ld64_get_group #define ld_lib_setup ld64_lib_setup #define ld_init ld64_init -#define ld_init_rel ld64_init_rel -#define ld_is_regsym ld64_is_regsym #define ld_lcm ld64_lcm -#define ld_mach_update_odynamic ld64_mach_update_odynamic -#define ld_mach_eflags ld64_mach_eflags -#define ld_mach_make_dynamic ld64_mach_make_dynamic -#define ld_mach_sym_typecheck ld64_mach_sym_typecheck #define ld_make_bss ld64_make_bss #define ld_make_data ld64_make_data #define ld_make_got ld64_make_got @@ -365,7 +540,6 @@ #define ld_map_out ld64_map_out #define ld_map_parse ld64_map_parse #define ld_open_outfile ld64_open_outfile -#define ld_perform_outreloc ld64_perform_outreloc #define ld_place_section ld64_place_section #define ld_process_archive ld64_process_archive #define ld_process_files ld64_process_files @@ -373,22 +547,16 @@ #define ld_process_ifl ld64_process_ifl #define ld_process_ordered ld64_process_ordered #define ld_process_sym_reloc ld64_process_sym_reloc -#define ld_reloc_local ld64_reloc_local #define ld_reloc_GOT_relative ld64_reloc_GOT_relative -#define ld_reloc_GOTOP ld64_reloc_GOTOP #define ld_reloc_plt ld64_reloc_plt -#define ld_reloc_register ld64_reloc_register #define ld_reloc_remain_entry ld64_reloc_remain_entry -#define ld_reloc_TLS ld64_reloc_TLS #define ld_reloc_targval_get ld64_reloc_targval_get #define ld_reloc_targval_set ld64_reloc_targval_set -#define ld_reg_check ld64_reg_check -#define ld_reg_enter ld64_reg_enter -#define ld_reg_find ld64_reg_find #define ld_sec_validate ld64_sec_validate #define ld_section_reld_name ld64_section_reld_name #define ld_sort_ordered ld64_sort_ordered #define ld_sort_seg_list ld64_sort_seg_list +#define ld_sunw_ldmach ld64_sunw_ldmach #define ld_sunwmove_preprocess ld64_sunwmove_preprocess #define ld_sup_atexit ld64_sup_atexit #define ld_sup_open ld64_sup_open @@ -398,6 +566,7 @@ #define ld_sup_input_section ld64_sup_input_section #define ld_sup_section ld64_sup_section #define ld_sup_start ld64_sup_start +#define ld_swap_reloc_data ld64_swap_reloc_data #define ld_sym_add_u ld64_sym_add_u #define ld_sym_adjust_vis ld64_sym_adjust_vis #define ld_sym_avl_comp ld64_sym_avl_comp @@ -408,6 +577,9 @@ #define ld_sym_process ld64_sym_process #define ld_sym_resolve ld64_sym_resolve #define ld_sym_spec ld64_sym_spec +#define ld_targ ld64_targ +#define ld_targ_init_sparc ld64_targ_init_sparc +#define ld_targ_init_x86 ld64_targ_init_x86 #define ld_vers_base ld64_vers_base #define ld_vers_check_defs ld64_vers_check_defs #define ld_vers_check_need ld64_vers_check_need @@ -423,41 +595,24 @@ #define ld_add_actrel ld32_add_actrel #define ld_add_libdir ld32_add_libdir -#define ld_add_outrel ld32_add_outrel #define ld_adj_movereloc ld32_adj_movereloc -#if defined(__sparc) -#define ld_allocate_got ld32_allocate_got -#endif #define ld_am_I_partial ld32_am_I_partial #define ld_append_isp ld32_append_isp #define ld_ar_member ld32_ar_member #define ld_ar_setup ld32_ar_setup -#define ld_assign_got ld32_assign_got -#define ld_assign_got_ndx ld32_assign_got_ndx #define ld_assign_got_TLS ld32_assign_got_TLS -#define ld_assign_plt_ndx ld32_assign_plt_ndx -#define ld_byteswap_Xword ld32_byteswap_Xword -#define ld_calc_got_offset ld32_calc_got_offset -#define ld_calc_plt_addr ld32_calc_plt_addr +#define ld_bswap_Word ld32_bswap_Word +#define ld_bswap_Xword ld32_bswap_Xword #define ld_disp_errmsg ld32_disp_errmsg -#define ld_do_activerelocs ld32_do_activerelocs #define ld_ent_check ld32_ent_check #define ld_exit ld32_exit -#define ld_fillin_gotplt ld32_fillin_gotplt -#define ld_find_gotndx ld32_find_gotndx #define ld_find_library ld32_find_library #define ld_finish_libs ld32_finish_libs #define ld_section_reld_name ld32_section_reld_name #define ld_get_group ld32_get_group #define ld_lib_setup ld32_lib_setup #define ld_init ld32_init -#define ld_init_rel ld32_init_rel -#define ld_is_regsym ld32_is_regsym #define ld_lcm ld32_lcm -#define ld_mach_update_odynamic ld32_mach_update_odynamic -#define ld_mach_eflags ld32_mach_eflags -#define ld_mach_make_dynamic ld32_mach_make_dynamic -#define ld_mach_sym_typecheck ld32_mach_sym_typecheck #define ld_make_bss ld32_make_bss #define ld_make_data ld32_make_data #define ld_make_got ld32_make_got @@ -468,7 +623,6 @@ #define ld_map_out ld32_map_out #define ld_map_parse ld32_map_parse #define ld_open_outfile ld32_open_outfile -#define ld_perform_outreloc ld32_perform_outreloc #define ld_place_section ld32_place_section #define ld_process_archive ld32_process_archive #define ld_process_files ld32_process_files @@ -476,21 +630,15 @@ #define ld_process_ifl ld32_process_ifl #define ld_process_ordered ld32_process_ordered #define ld_process_sym_reloc ld32_process_sym_reloc -#define ld_reloc_local ld32_reloc_local #define ld_reloc_GOT_relative ld32_reloc_GOT_relative -#define ld_reloc_GOTOP ld32_reloc_GOTOP #define ld_reloc_plt ld32_reloc_plt -#define ld_reloc_register ld32_reloc_register #define ld_reloc_remain_entry ld32_reloc_remain_entry -#define ld_reloc_TLS ld32_reloc_TLS #define ld_reloc_targval_get ld32_reloc_targval_get #define ld_reloc_targval_set ld32_reloc_targval_set -#define ld_reg_check ld32_reg_check -#define ld_reg_enter ld32_reg_enter -#define ld_reg_find ld32_reg_find #define ld_sec_validate ld32_sec_validate #define ld_sort_ordered ld32_sort_ordered #define ld_sort_seg_list ld32_sort_seg_list +#define ld_sunw_ldmach ld32_sunw_ldmach #define ld_sunwmove_preprocess ld32_sunwmove_preprocess #define ld_sup_atexit ld32_sup_atexit #define ld_sup_open ld32_sup_open @@ -500,6 +648,7 @@ #define ld_sup_input_section ld32_sup_input_section #define ld_sup_section ld32_sup_section #define ld_sup_start ld32_sup_start +#define ld_swap_reloc_data ld32_swap_reloc_data #define ld_sym_add_u ld32_sym_add_u #define ld_sym_adjust_vis ld32_sym_adjust_vis #define ld_sym_avl_comp ld32_sym_avl_comp @@ -510,6 +659,9 @@ #define ld_sym_process ld32_sym_process #define ld_sym_resolve ld32_sym_resolve #define ld_sym_spec ld32_sym_spec +#define ld_targ ld32_targ +#define ld_targ_init_sparc ld32_targ_init_sparc +#define ld_targ_init_x86 ld32_targ_init_x86 #define ld_vers_base ld32_vers_base #define ld_vers_check_defs ld32_vers_check_defs #define ld_vers_check_need ld32_vers_check_need @@ -527,36 +679,24 @@ extern uintptr_t ld_add_actrel(Word, Rel_desc *, Ofl_desc *); extern uintptr_t ld_add_libdir(Ofl_desc *, const char *); -extern uintptr_t ld_add_outrel(Word, Rel_desc *, Ofl_desc *); extern void ld_adj_movereloc(Ofl_desc *, Rel_desc *); extern Sym_desc * ld_am_I_partial(Rel_desc *, Xword); extern int ld_append_isp(Ofl_desc *, Os_desc *, Is_desc *, int); extern void ld_ar_member(Ar_desc *, Elf_Arsym *, Ar_aux *, Ar_mem *); extern Ar_desc *ld_ar_setup(const char *, Elf *, Ofl_desc *); -#if defined(__sparc) -extern uintptr_t ld_allocate_got(Ofl_desc *); -#endif -extern uintptr_t ld_assign_got(Ofl_desc *, Sym_desc *); -extern uintptr_t ld_assign_got_ndx(List *, Gotndx *, Gotref, Ofl_desc *, - Rel_desc *, Sym_desc *); extern uintptr_t ld_assign_got_TLS(Boolean, Rel_desc *, Ofl_desc *, Sym_desc *, Gotndx *, Gotref, Word, Word, Word, Word); -extern void ld_assign_plt_ndx(Sym_desc *, Ofl_desc *); -extern Xword ld_byteswap_Xword(Xword); -extern Xword ld_calc_got_offset(Rel_desc *, Ofl_desc *); -extern Xword ld_calc_plt_addr(Sym_desc *, Ofl_desc *); +extern Word ld_bswap_Word(Word); +extern Xword ld_bswap_Xword(Xword); extern void ld_disp_errmsg(const char *, Rel_desc *, Ofl_desc *); -extern uintptr_t ld_do_activerelocs(Ofl_desc *); extern void ld_ent_check(Ofl_desc *); extern int ld_exit(Ofl_desc *); -extern uintptr_t ld_fillin_gotplt(Ofl_desc *); -extern Gotndx * ld_find_gotndx(List *, Gotref, Ofl_desc *, Rel_desc *); extern uintptr_t ld_find_library(const char *, Ofl_desc *); extern uintptr_t ld_finish_libs(Ofl_desc *); @@ -567,17 +707,9 @@ extern uintptr_t ld_lib_setup(Ofl_desc *); extern void ld_init(Ofl_desc *); -extern Word ld_init_rel(Rel_desc *, void *); -extern const char *ld_is_regsym(Ofl_desc *, Ifl_desc *, Sym *, - const char *, int, Word, const char *, Word *); extern Xword ld_lcm(Xword, Xword); -extern void ld_mach_update_odynamic(Ofl_desc *, Dyn **); -extern void ld_mach_eflags(Ehdr *, Ofl_desc *); -extern void ld_mach_make_dynamic(Ofl_desc *, size_t *); -extern int ld_mach_sym_typecheck(Sym_desc *, Sym *, Ifl_desc *, - Ofl_desc *); extern uintptr_t ld_make_bss(Ofl_desc *, Xword, Xword, Bss_Type); extern Is_desc *ld_make_data(Ofl_desc *, size_t); extern uintptr_t ld_make_got(Ofl_desc *); @@ -590,7 +722,6 @@ extern uintptr_t ld_open_outfile(Ofl_desc *); -extern uintptr_t ld_perform_outreloc(Rel_desc *, Ofl_desc *); extern Os_desc * ld_place_section(Ofl_desc *, Is_desc *, int, Word); extern uintptr_t ld_process_archive(const char *, int, Ar_desc *, Ofl_desc *); @@ -602,26 +733,19 @@ extern uintptr_t ld_process_sym_reloc(Ofl_desc *, Rel_desc *, Rel *, Is_desc *, const char *); -extern uintptr_t ld_reloc_local(Rel_desc *, Ofl_desc *); extern uintptr_t ld_reloc_GOT_relative(Boolean, Rel_desc *, Ofl_desc *); -extern uintptr_t ld_reloc_GOTOP(Boolean, Rel_desc *, Ofl_desc *); extern uintptr_t ld_reloc_plt(Rel_desc *, Ofl_desc *); -extern uintptr_t ld_reloc_register(Rel_desc *, Is_desc *, Ofl_desc *); extern void ld_reloc_remain_entry(Rel_desc *, Os_desc *, Ofl_desc *); -extern uintptr_t ld_reloc_TLS(Boolean, Rel_desc *, Ofl_desc *); extern int ld_reloc_targval_get(Ofl_desc *, Rel_desc *, uchar_t *, Xword *); extern int ld_reloc_targval_set(Ofl_desc *, Rel_desc *, uchar_t *, Xword); -extern int ld_reg_check(Sym_desc *, Sym *, const char *, - Ifl_desc *, Ofl_desc *); -extern int ld_reg_enter(Sym_desc *, Ofl_desc *); -extern Sym_desc * ld_reg_find(Sym *, Ofl_desc *); extern void ld_sec_validate(Ofl_desc *); extern uintptr_t ld_sort_ordered(Ofl_desc *); extern uintptr_t ld_sort_seg_list(Ofl_desc *); +extern Half ld_sunw_ldmach(); extern uintptr_t ld_sunwmove_preprocess(Ofl_desc *); extern void ld_sup_atexit(Ofl_desc *, int); extern void ld_sup_open(Ofl_desc *, const char **, const char **, @@ -636,6 +760,7 @@ extern uintptr_t ld_sup_input_section(Ofl_desc*, Ifl_desc *, const char *, Shdr **, Word, Elf_Scn *, Elf *); extern void ld_sup_start(Ofl_desc *, const Half, const char *); +extern int ld_swap_reloc_data(Ofl_desc *, Rel_desc *); extern Sym_desc *ld_sym_add_u(const char *, Ofl_desc *, Msg); extern void ld_sym_adjust_vis(Sym_desc *, Ofl_desc *); extern int ld_sym_avl_comp(const void *, const void *); @@ -650,6 +775,10 @@ Ofl_desc *, int, Word, Word); extern uintptr_t ld_sym_spec(Ofl_desc *); +extern Target ld_targ; +extern const Target *ld_targ_init_sparc(void); +extern const Target *ld_targ_init_x86(void); + extern Ver_desc *ld_vers_base(Ofl_desc *); extern uintptr_t ld_vers_check_defs(Ofl_desc *); extern uintptr_t ld_vers_check_need(Ofl_desc *); @@ -667,12 +796,23 @@ extern Xword lcm(Xword, Xword); extern Listnode * list_where(List *, Word); -#if defined(__x86) && defined(_ELF64) -extern uintptr_t append_amd64_unwind(Os_desc *, Ofl_desc *); -extern uintptr_t make_amd64_unwindhdr(Ofl_desc *); -extern uintptr_t populate_amd64_unwindhdr(Ofl_desc *); + +/* + * Most platforms have both a 32 and 64-bit variant (e.g. EM_SPARC and + * EM_SPARCV9). To support this, there many files in libld that are built + * twice, once for ELFCLASS64 (_ELF64), and once for ELFCLASS32. In these + * files, we sometimes want to supply one value for the ELFCLASS32 case + * and another for ELFCLASS64. The LD_TARG_BYCLASS macro is used to do + * this. It is called with both both alternatives, and yields the one + * that applies to the current compilation environment. + */ +#ifdef _ELF64 +#define LD_TARG_BYCLASS(_ec32, _ec64) (_ec64) +#else +#define LD_TARG_BYCLASS(_ec32, _ec64) (_ec32) #endif + #ifdef __cplusplus } #endif
--- a/usr/src/cmd/sgs/libld/common/args.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/args.c Tue Mar 18 09:17:00 2008 -0700 @@ -185,6 +185,7 @@ (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRL)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRREL)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRS)); + (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTARG)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW)); @@ -539,7 +540,7 @@ * it is only at this point we're sure what the output image will be * (static or dynamic). */ - if (ld_ent_setup(ofl, M_SEGM_ALIGN) == S_ERROR) + if (ld_ent_setup(ofl, ld_targ.t_m.m_segm_align) == S_ERROR) return (S_ERROR); /* @@ -548,7 +549,7 @@ * If not, set FLG_OF1_ENCDIFF so relocation code will know * to check. */ - if (_elf_sys_encoding() != M_DATA) + if (_elf_sys_encoding() != ld_targ.t_m.m_data) ofl->ofl_flags1 |= FLG_OF1_ENCDIFF; /* @@ -740,11 +741,22 @@ { int c; + /* + * The -64 and -ztarget options are special, in that we validate + * them, but otherwise ignore them. libld.so (this code) is called + * from the ld front end program. ld has already examined the + * arguments to determine the output class and machine type of the + * output object, as reflected in the version (32/64) of ld_main() + * that was called and the value of the 'mach' argument passed. + * By time execution reaches this point, these options have already + * been seen and acted on. + */ + while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) { DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c)); switch (c) { - case '6': /* Processed by ld to */ + case '6': /* * -64 is processed by ld to determine the output class. * Here we sanity check the option incase some other @@ -1137,7 +1149,9 @@ strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) && strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) && strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) && - strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT))) { + strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) && + strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET), + MSG_ARG_TARGET_SIZE)) { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_ILLEGAL), MSG_ORIG(MSG_ARG_Z), optarg); @@ -1584,7 +1598,8 @@ MSG_INTL(reject[rej.rej_type]), rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(&rej, &rej_buf)); + conv_reject_desc(&rej, &rej_buf, + ld_targ.t_m.m_mach)); ofl->ofl_flags |= FLG_OF_FATAL; return (1); }
--- a/usr/src/cmd/sgs/libld/common/entry.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/entry.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,11 +23,13 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" +#define ELF_TARGET_AMD64 + #include <stdio.h> #include <memory.h> #include <debug.h> @@ -36,103 +38,124 @@ /* - * The loader uses a `segment descriptor' list to describe the output - * segments it can potentially create. Additional segments may be added - * using a map file. + * Types of segment index. */ +typedef enum { + LD_PHDR, + LD_INTERP, + LD_SUNWCAP, + LD_TEXT, + LD_DATA, + LD_BSS, +#if defined(_ELF64) + LD_LRODATA, /* (amd64-only) */ + LD_LDATA, /* (amd64-only) */ +#endif + LD_DYN, + LD_DTRACE, + LD_SUNWBSS, + LD_TLS, #if defined(_ELF64) -/* Phdr packing changes under Elf64 */ -static Sg_desc sg_desc[LD_NUM] = { - {{PT_PHDR, PF_R + PF_X, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_PHDR), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_INTERP, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_INTERP), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWCAP, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_SUNWCAP), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, PF_R + PF_X, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_TEXT), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, M_DATASEG_PERM, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_DATA), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, M_DATASEG_PERM, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_BSS), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS | FLG_SG_DISABLED), NULL, 0, 0}, -#if defined(__x86) && defined(_ELF64) - {{PT_LOAD, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_LRODATA), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, M_DATASEG_PERM, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_LDATA), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, + LD_UNWIND, /* (amd64-only) */ +#endif + LD_NOTE, + LD_EXTRA, + LD_NUM +} Segment_ndx; + +/* + * The loader uses a `segment descriptor' list to describe the output + * segments it can potentially create. This list is initially seeded + * using the templates contained in the sg_desc[] array below. Additional + * segments may be added using a map file. + * + * The entries in sg_desc[] must be put in the order defined by the + * Segment_ndx enum, such that a given LD_XXX value can serve as + * an index into sg_desc[] for the corresponding descriptor. + * + * The entries in sg_desc[] are initialized using the SG_DESC_INIT macro + * for two reasons: + * + * 1) The first field of the Sg_desc struct is a program header + * entry. ELF32_Phdr and ELF64_Phdr have the same fields, + * but their order is different. Use of a macro allows us + * to handle this transparently. + * 2) Most of the fields in the Sg_desc entries are set to 0. + * Use of a macro allows us to hide the clutter. + */ +#ifdef _ELF64 +#define SG_DESC_INIT(p_type, p_flags, sg_name, sg_flags) \ + { { p_type, p_flags, 0, 0, 0, 0, 0, 0}, \ + sg_name, 0, 0, NULL, NULL, sg_flags, NULL, 0, 0} +#else +#define SG_DESC_INIT(p_type, p_flags, sg_name, sg_flags) \ + { { p_type, 0, 0, 0, 0, 0, p_flags, 0}, \ + sg_name, 0, 0, NULL, NULL, sg_flags, NULL, 0, 0} #endif - {{PT_DYNAMIC, M_DATASEG_PERM, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_DYNAMIC), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWDTRACE, M_DATASEG_PERM | PF_X, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_DTRACE), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWBSS, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_SUNWBSS), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0}, - {{PT_TLS, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_TLS), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, -#if defined(__x86) - {{PT_SUNW_UNWIND, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_UNWIND), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, + +static const Sg_desc sg_desc[LD_NUM] = { + /* LD_PHDR */ + SG_DESC_INIT(PT_PHDR, PF_R + PF_X, MSG_ORIG(MSG_ENT_PHDR), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_INTERP */ + SG_DESC_INIT(PT_INTERP, PF_R, MSG_ORIG(MSG_ENT_INTERP), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_SUNWCAP */ + SG_DESC_INIT(PT_SUNWCAP, PF_R, MSG_ORIG(MSG_ENT_SUNWCAP), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_TEXT */ + SG_DESC_INIT(PT_LOAD, PF_R + PF_X, MSG_ORIG(MSG_ENT_TEXT), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_DATA */ + SG_DESC_INIT(PT_LOAD, 0, MSG_ORIG(MSG_ENT_DATA), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_BSS */ + SG_DESC_INIT(PT_LOAD, 0, MSG_ORIG(MSG_ENT_BSS), + (FLG_SG_TYPE | FLG_SG_FLAGS | FLG_SG_DISABLED)), + +#if defined(_ELF64) + /* LD_LRODATA (amd64-only) */ + SG_DESC_INIT(PT_LOAD, PF_R, MSG_ORIG(MSG_ENT_LRODATA), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_LDATA (amd64-only) */ + SG_DESC_INIT(PT_LOAD, 0, MSG_ORIG(MSG_ENT_LDATA), + (FLG_SG_TYPE | FLG_SG_FLAGS)), #endif - {{PT_NOTE, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_NOTE), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0}, - {{PT_NULL, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_STR_EMPTY), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0} + + /* LD_DYN */ + SG_DESC_INIT(PT_DYNAMIC, 0, MSG_ORIG(MSG_ENT_DYNAMIC), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_DTRACE */ + SG_DESC_INIT(PT_SUNWDTRACE, 0, + MSG_ORIG(MSG_ENT_DTRACE), (FLG_SG_TYPE | FLG_SG_FLAGS)), + + /* LD_SUNWBSS */ + SG_DESC_INIT(PT_SUNWBSS, 0, MSG_ORIG(MSG_ENT_SUNWBSS), FLG_SG_TYPE), + + /* LD_TLS */ + SG_DESC_INIT(PT_TLS, PF_R, MSG_ORIG(MSG_ENT_TLS), + (FLG_SG_TYPE | FLG_SG_FLAGS)), + +#if defined(_ELF64) + /* LD_UNWIND (amd64-only) */ + SG_DESC_INIT(PT_SUNW_UNWIND, PF_R, MSG_ORIG(MSG_ENT_UNWIND), + (FLG_SG_TYPE | FLG_SG_FLAGS)), +#endif + + /* LD_NOTE */ + SG_DESC_INIT(PT_NOTE, 0, MSG_ORIG(MSG_ENT_NOTE), FLG_SG_TYPE), + + /* LD_EXTRA */ + SG_DESC_INIT(PT_NULL, 0, MSG_ORIG(MSG_STR_EMPTY), FLG_SG_TYPE) }; -#else /* Elf32 */ -static Sg_desc sg_desc[LD_NUM] = { - {{PT_PHDR, 0, 0, 0, 0, 0, PF_R + PF_X, 0}, - MSG_ORIG(MSG_ENT_PHDR), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_INTERP, 0, 0, 0, 0, 0, PF_R, 0}, - MSG_ORIG(MSG_ENT_INTERP), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWCAP, 0, 0, 0, 0, 0, PF_R, 0}, - MSG_ORIG(MSG_ENT_SUNWCAP), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, 0, 0, 0, 0, 0, PF_R + PF_X, 0}, - MSG_ORIG(MSG_ENT_TEXT), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, 0, 0, 0, 0, 0, M_DATASEG_PERM, 0}, - MSG_ORIG(MSG_ENT_DATA), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_LOAD, 0, 0, 0, 0, 0, M_DATASEG_PERM, 0}, - MSG_ORIG(MSG_ENT_BSS), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS | FLG_SG_DISABLED), NULL, 0, 0}, - {{PT_DYNAMIC, 0, 0, 0, 0, 0, M_DATASEG_PERM, 0}, - MSG_ORIG(MSG_ENT_DYNAMIC), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWDTRACE, 0, 0, 0, 0, 0, M_DATASEG_PERM, 0}, - MSG_ORIG(MSG_ENT_DTRACE), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_SUNWBSS, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_SUNWBSS), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0}, - {{PT_TLS, PF_R, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_TLS), 0, 0, NULL, NULL, - (FLG_SG_TYPE | FLG_SG_FLAGS), NULL, 0, 0}, - {{PT_NOTE, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_ENT_NOTE), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0}, - {{PT_NULL, 0, 0, 0, 0, 0, 0, 0}, - MSG_ORIG(MSG_STR_EMPTY), 0, 0, NULL, NULL, - FLG_SG_TYPE, NULL, 0, 0} -}; -#endif /* Elfxx */ + /* @@ -142,37 +165,50 @@ * modified further using a map file. Each entrance criteria is associated * with a segment descriptor, thus a mapping of input sections to output * segments is maintained. + * + * Note the trick used for the ec_segment field, which is supposed to + * be a pointer to a segment descriptor. We initialize this with the + * index of the descriptor, and then turn it into an actual pointer + * at runtime, once memory has been allocated and the templates copied. */ static const Ent_desc ent_desc[] = { {{NULL, NULL}, MSG_ORIG(MSG_SCN_SUNWBSS), NULL, SHF_ALLOC + SHF_WRITE, SHF_ALLOC + SHF_WRITE, (Sg_desc *)LD_SUNWBSS, 0, FALSE}, + {{NULL, NULL}, NULL, SHT_NOTE, 0, 0, (Sg_desc *)LD_NOTE, 0, FALSE}, -#if defined(__x86) && defined(_ELF64) + +#if defined(_ELF64) /* (amd64-only) */ {{NULL, NULL}, MSG_ORIG(MSG_SCN_LRODATA), NULL, SHF_ALLOC + SHF_AMD64_LARGE, SHF_ALLOC + SHF_AMD64_LARGE, (Sg_desc *)LD_LRODATA, 0, FALSE}, #endif + {{NULL, NULL}, NULL, NULL, SHF_ALLOC + SHF_WRITE, SHF_ALLOC, (Sg_desc *)LD_TEXT, 0, FALSE}, + {{NULL, NULL}, NULL, SHT_NOBITS, SHF_ALLOC + SHF_WRITE, SHF_ALLOC + SHF_WRITE, (Sg_desc *)LD_BSS, 0, FALSE}, -#if defined(__x86) && defined(_ELF64) + +#if defined(_ELF64) /* (amd64-only) */ {{NULL, NULL}, NULL, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE, SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE, (Sg_desc *)LD_DATA, 0, FALSE}, + {{NULL, NULL}, NULL, NULL, SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE, SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE, (Sg_desc *)LD_LDATA, 0, FALSE}, #endif + {{NULL, NULL}, NULL, NULL, SHF_ALLOC + SHF_WRITE, SHF_ALLOC + SHF_WRITE, (Sg_desc *)LD_DATA, 0, FALSE}, + {{NULL, NULL}, NULL, 0, 0, 0, (Sg_desc *)LD_EXTRA, 0, FALSE} }; @@ -186,7 +222,7 @@ { Ent_desc *enp; Sg_desc *sgp; - size_t size; + size_t idx; /* * Initialize the elf library. @@ -204,19 +240,12 @@ SGSOFFSETOF(Sym_avlnode, sav_node)); /* - * The data segment permissions can differ depending on whether - * this object is built statically or dynamically. - */ - if (ofl->ofl_flags & FLG_OF_DYNAMIC) { - sg_desc[LD_DATA].sg_phdr.p_flags = M_DATASEG_PERM; - sg_desc[LD_SUNWBSS].sg_phdr.p_flags = M_DATASEG_PERM; - } else { - sg_desc[LD_DATA].sg_phdr.p_flags = M_DATASEG_PERM | PF_X; - } - - /* * Allocate and initialize writable copies of both the entrance and * segment descriptors. + * + * Note that on non-amd64 targets, this allocates a few more + * elements than are needed. For now, we are willing to overallocate + * a small amount to simplify the code. */ if ((sgp = libld_malloc(sizeof (sg_desc))) == 0) return (S_ERROR); @@ -226,16 +255,45 @@ (void) memcpy(enp, ent_desc, sizeof (ent_desc)); /* + * The data segment permissions can differ: + * + * - Architecural/ABI per-platform differences + * - Whether the object is built statically or dynamically + * + * Those segments so affected have their program header flags + * set here at runtime, rather than in the sg_desc templates above. + */ + sgp[LD_DATA].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; + sgp[LD_BSS].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; + sgp[LD_DYN].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; + sgp[LD_DTRACE].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; +#if defined(_ELF64) + sgp[LD_LDATA].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; + sgp[LD_DTRACE].sg_phdr.p_flags |= PF_X; +#endif + if (ofl->ofl_flags & FLG_OF_DYNAMIC) { + sgp[LD_SUNWBSS].sg_phdr.p_flags = ld_targ.t_m.m_dataseg_perm; + } else { + sgp[LD_DATA].sg_phdr.p_flags |= PF_X; + } + + /* * Traverse the new entrance descriptor list converting the segment * pointer entries to the absolute address within the new segment * descriptor list. Add each entrance descriptor to the output file * list. */ - for (size = 0; size < sizeof (ent_desc); size += sizeof (Ent_desc)) { + for (idx = 0; idx < (sizeof (ent_desc) / sizeof (ent_desc[0])); + idx++, enp++) { +#if defined(_ELF64) + /* Don't use the amd64 entry conditions for non-amd64 targets */ + if ((enp->ec_attrmask & SHF_AMD64_LARGE) && + (ld_targ.t_m.m_mach != EM_AMD64)) + continue; +#endif enp->ec_segment = &sgp[(long)enp->ec_segment]; if ((list_appendc(&ofl->ofl_ents, enp)) == 0) return (S_ERROR); - enp++; } /* @@ -243,15 +301,25 @@ * segment descriptor list. For each loadable segment initialize * a default alignment (ld(1) and ld.so.1 initialize this differently). */ - for (size = 0; size < sizeof (sg_desc); size += sizeof (Sg_desc)) { + for (idx = 0; idx < LD_NUM; idx++, sgp++) { Phdr *phdr = &(sgp->sg_phdr); +#if defined(_ELF64) + /* Ignore amd64 segment templates for non-amd64 targets */ + switch (idx) { + case LD_LRODATA: + case LD_LDATA: + case LD_UNWIND: + if ((ld_targ.t_m.m_mach != EM_AMD64)) + continue; + } +#endif + if ((list_appendc(&ofl->ofl_segs, sgp)) == 0) return (S_ERROR); if (phdr->p_type == PT_LOAD) phdr->p_align = segalign; + } - sgp++; - } return (1); }
--- a/usr/src/cmd/sgs/libld/common/files.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/files.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,6 +31,10 @@ /* * Processing of relocatable objects and shared objects. */ + +#define ELF_TARGET_AMD64 +#define ELF_TARGET_SPARC + #include <stdio.h> #include <string.h> #include <fcntl.h> @@ -53,14 +57,14 @@ * Check the validity of the elf header information for compatibility * with this machine and our own internal elf library. */ - if ((ehdr->e_machine != M_MACH) && - ((ehdr->e_machine != M_MACHPLUS) && - ((ehdr->e_flags & M_FLAGSPLUS) == 0))) { + if ((ehdr->e_machine != ld_targ.t_m.m_mach) && + ((ehdr->e_machine != ld_targ.t_m.m_machplus) && + ((ehdr->e_flags & ld_targ.t_m.m_flagsplus) == 0))) { rej->rej_type = SGS_REJ_MACH; rej->rej_info = (uint_t)ehdr->e_machine; return (0); } - if (ehdr->e_ident[EI_DATA] != M_DATA) { + if (ehdr->e_ident[EI_DATA] != ld_targ.t_m.m_data) { rej->rej_type = SGS_REJ_DATA; rej->rej_info = (uint_t)ehdr->e_ident[EI_DATA]; return (0); @@ -87,7 +91,8 @@ if (ifl_verify(ehdr, ofl, &_rej) == 0) { _rej.rej_name = name; - DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej)); + DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej, + ld_targ.t_m.m_mach)); if (rej->rej_type == 0) { *rej = _rej; rej->rej_name = strdup(_rej.rej_name); @@ -251,7 +256,7 @@ */ if (ofl->ofl_flags1 & FLG_OF1_OVSFCAP) { Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_IGNORE, CA_SUNW_SF_1, - val, M_MACH); + val, ld_targ.t_m.m_mach); return; } @@ -278,9 +283,9 @@ } Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_OLD, CA_SUNW_SF_1, - ofl->ofl_sfcap_1, M_MACH); + ofl->ofl_sfcap_1, ld_targ.t_m.m_mach); Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_NEW, CA_SUNW_SF_1, - val, M_MACH); + val, ld_targ.t_m.m_mach); /* * Determine the resolution of the present frame pointer and the @@ -305,7 +310,7 @@ } Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_RESOLVED, CA_SUNW_SF_1, - ofl->ofl_sfcap_1, M_MACH); + ofl->ofl_sfcap_1, ld_targ.t_m.m_mach); } /* @@ -323,7 +328,7 @@ */ if (ofl->ofl_flags1 & FLG_OF1_OVHWCAP) { Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_IGNORE, CA_SUNW_HW_1, - val, M_MACH); + val, ld_targ.t_m.m_mach); return; } @@ -335,13 +340,14 @@ return; Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_OLD, CA_SUNW_HW_1, - ofl->ofl_hwcap_1, M_MACH); - Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_NEW, CA_SUNW_HW_1, val, M_MACH); + ofl->ofl_hwcap_1, ld_targ.t_m.m_mach); + Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_NEW, CA_SUNW_HW_1, val, + ld_targ.t_m.m_mach); ofl->ofl_hwcap_1 |= val; Dbg_cap_sec_entry(ofl->ofl_lml, DBG_CAP_RESOLVED, CA_SUNW_HW_1, - ofl->ofl_hwcap_1, M_MACH); + ofl->ofl_hwcap_1, ld_targ.t_m.m_mach); } /* @@ -395,7 +401,8 @@ process_input(const char *name, Ifl_desc *ifl, Shdr *shdr, Elf_Scn *scn, Word ndx, int ident, Ofl_desc *ofl) { - return (process_section(name, ifl, shdr, scn, ndx, M_ID_NULL, ofl)); + return (process_section(name, ifl, shdr, scn, ndx, + ld_targ.t_id.id_null, ofl)); } /* @@ -410,7 +417,7 @@ Word ndx, int ident, Ofl_desc *ofl) { if (process_section(name, ifl, - shdr, scn, ndx, M_ID_NULL, ofl) == S_ERROR) + shdr, scn, ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); if (ifl->ifl_ehdr->e_type == ET_REL) { @@ -453,9 +460,9 @@ * be null. Otherwise make sure we don't have a .strtab section as this * should not be added to the output section list either. */ - if ((ident != M_ID_NULL) && + if ((ident != ld_targ.t_id.id_null) && (strcmp(name, MSG_ORIG(MSG_SCN_STRTAB)) == 0)) - ident = M_ID_NULL; + ident = ld_targ.t_id.id_null; error = process_section(name, ifl, shdr, scn, ndx, ident, ofl); if ((error == 0) || (error == S_ERROR)) @@ -538,14 +545,14 @@ */ if (ident) { if (shdr->sh_flags & SHF_TLS) - ident = M_ID_TLS; + ident = ld_targ.t_id.id_tls; else if ((shdr->sh_flags & ~ALL_SHF_IGNORE) == (SHF_ALLOC | SHF_EXECINSTR)) - ident = M_ID_TEXT; + ident = ld_targ.t_id.id_text; else if (shdr->sh_flags & SHF_ALLOC) { if ((strcmp(name, MSG_ORIG(MSG_SCN_PLT)) == 0) || (strcmp(name, MSG_ORIG(MSG_SCN_GOT)) == 0)) - ident = M_ID_NULL; + ident = ld_targ.t_id.id_null; else if (stab_index) { /* * This is a work-around for x86 compilers that @@ -559,11 +566,11 @@ * strip (ld -s) against a shared object whose * last section in the text segment is a .stab. */ - ident = M_ID_INTERP; + ident = ld_targ.t_id.id_interp; } else - ident = M_ID_DATA; + ident = ld_targ.t_id.id_data; } else - ident = M_ID_NOTE; + ident = ld_targ.t_id.id_note; } return (process_section(name, ifl, shdr, scn, ndx, ident, ofl)); } @@ -593,13 +600,14 @@ { if (ident) { if (shdr->sh_flags & SHF_TLS) - ident = M_ID_TLSBSS; -#if defined(__x86) && defined(_ELF64) - else if (shdr->sh_flags & SHF_AMD64_LARGE) - ident = M_ID_LBSS; + ident = ld_targ.t_id.id_tlsbss; +#if defined(_ELF64) + else if ((shdr->sh_flags & SHF_AMD64_LARGE) && + (ld_targ.t_m.m_mach == EM_AMD64)) + ident = ld_targ.t_id.id_lbss; #endif else - ident = M_ID_BSS; + ident = ld_targ.t_id.id_bss; } return (process_section(name, ifl, shdr, scn, ndx, ident, ofl)); } @@ -615,7 +623,7 @@ Is_desc *isp; if (ident) - ident = M_ID_ARRAY; + ident = ld_targ.t_id.id_array; if (process_section(name, ifl, shdr, scn, ndx, ident, ofl) == S_ERROR) return (S_ERROR); @@ -1227,7 +1235,7 @@ /* * Make sure this is a valid relocation we can handle. */ - if (shdr->sh_type != M_REL_SHT_TYPE) { + if (shdr->sh_type != ld_targ.t_m.m_rel_sht_type) { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVALSEC), ifl->ifl_name, isc->is_name, conv_sec_type(ifl->ifl_ehdr->e_machine, @@ -1320,7 +1328,7 @@ return (process_section(name, ifl, shdr, scn, ndx, 0, ofl)); } -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) static uintptr_t process_amd64_unwind(const char *name, Ifl_desc *ifl, Shdr *shdr, @@ -1506,11 +1514,11 @@ if (ifl->ifl_ehdr->e_type == ET_DYN) { column = 1; ofl->ofl_soscnt++; - ident = M_ID_NULL; + ident = ld_targ.t_id.id_null; } else { column = 0; ofl->ofl_objscnt++; - ident = M_ID_UNKNOWN; + ident = ld_targ.t_id.id_unknown; } DBG_CALL(Dbg_file_generic(ofl->ofl_lml, ifl)); @@ -1603,7 +1611,7 @@ break; case SHT_SUNW_cap: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); capisp = ifl->ifl_isdesc[ndx]; break; @@ -1615,12 +1623,12 @@ break; case SHT_SUNW_move: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); break; case SHT_SUNW_syminfo: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); sifisp = ifl->ifl_isdesc[ndx]; break; @@ -1632,45 +1640,67 @@ break; case SHT_SUNW_verdef: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); vdfisp = ifl->ifl_isdesc[ndx]; break; case SHT_SUNW_verneed: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); vndisp = ifl->ifl_isdesc[ndx]; break; case SHT_SUNW_versym: if (process_section(name, ifl, shdr, scn, - ndx, M_ID_NULL, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_null, ofl) == S_ERROR) return (S_ERROR); vsyisp = ifl->ifl_isdesc[ndx]; break; -#if defined(__sparc) case SHT_SPARC_GOTDATA: + /* + * SHT_SPARC_GOTDATA (0x70000000) is in the + * SHT_LOPROC - SHT_HIPROC range reserved + * for processor-specific semantics. It is + * only meaningful for sparc targets. + */ + if (ld_targ.t_m.m_mach != + LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9)) + goto do_default; if (process_section(name, ifl, shdr, scn, - ndx, M_ID_GOTDATA, ofl) == S_ERROR) + ndx, ld_targ.t_id.id_gotdata, ofl) == + S_ERROR) return (S_ERROR); break; -#endif -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) case SHT_AMD64_UNWIND: + /* + * SHT_AMD64_UNWIND (0x70000001) is in the + * SHT_LOPROC - SHT_HIPROC range reserved + * for processor-specific semantics. It is + * only meaningful for amd64 targets. + */ + if (ld_targ.t_m.m_mach != EM_AMD64) + goto do_default; + /* + * Target is x86, so this really is + * SHT_AMD64_UNWIND + */ if (column == 0) { /* * column == ET_REL */ if (process_amd64_unwind(name, ifl, - shdr, scn, ndx, M_ID_UNWIND, - ofl) == S_ERROR) + shdr, scn, ndx, + ld_targ.t_id.id_unwind, ofl) == + S_ERROR) return (S_ERROR); } break; #endif default: - if (ident != M_ID_NULL) - ident = M_ID_USER; + do_default: + if (ident != ld_targ.t_id.id_null) + ident = ld_targ.t_id.id_user; if (process_section(name, ifl, shdr, scn, ndx, ident, ofl) == S_ERROR) return (S_ERROR); @@ -1717,7 +1747,7 @@ ifl->ifl_shnum)) == (Os_desc *)S_ERROR) return (S_ERROR); -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) /* * If this section is 'ordered' then it was not * caught in the previous 'place_section' operation. @@ -1727,7 +1757,9 @@ */ if (osp && (osp->os_shdr->sh_type == SHT_AMD64_UNWIND) && - (append_amd64_unwind(osp, ofl) == S_ERROR)) + (ld_targ.t_uw.uw_append_unwind != NULL) && + ((*ld_targ.t_uw.uw_append_unwind)(osp, ofl) == + S_ERROR)) return (S_ERROR); #endif } @@ -1936,7 +1968,7 @@ * also occur, such as from a truncated or corrupt file. * Here we try and get the best error message possible. */ - if (M_CLASS != _class) { + if (ld_targ.t_m.m_class != _class) { _rej.rej_type = SGS_REJ_CLASS; _rej.rej_info = (uint_t)_class; } else { @@ -1944,7 +1976,8 @@ _rej.rej_str = elf_errmsg(-1); } _rej.rej_name = name; - DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej)); + DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej, + ld_targ.t_m.m_mach)); if (rej->rej_type == 0) { *rej = _rej; rej->rej_name = strdup(_rej.rej_name); @@ -2035,7 +2068,7 @@ switch (ehdr->e_type) { case ET_REL: - ld_mach_eflags(ehdr, ofl); + (*ld_targ.t_mr.mr_mach_eflags)(ehdr, ofl); error = process_elf(ifl, elf, ofl); break; case ET_DYN: @@ -2085,7 +2118,8 @@ (void) elf_errno(); _rej.rej_type = SGS_REJ_UNKFILE; _rej.rej_name = name; - DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej)); + DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej, + ld_targ.t_m.m_mach)); if (rej->rej_type == 0) { *rej = _rej; rej->rej_name = strdup(_rej.rej_name); @@ -2097,7 +2131,8 @@ (void) elf_errno(); _rej.rej_type = SGS_REJ_UNKFILE; _rej.rej_name = name; - DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej)); + DBG_CALL(Dbg_file_rejected(ofl->ofl_lml, &_rej, + ld_targ.t_m.m_mach)); if (rej->rej_type == 0) { *rej = _rej; rej->rej_name = strdup(_rej.rej_name); @@ -2293,7 +2328,8 @@ MSG_INTL(reject[_rej.rej_type]), _rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(&_rej, &rej_buf)); + conv_reject_desc(&_rej, &rej_buf, + ld_targ.t_m.m_mach)); } else sdf->sdf_file = ifl; } @@ -2404,7 +2440,8 @@ MSG_INTL(reject[rej.rej_type]), rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(&rej, &rej_buf)); + conv_reject_desc(&rej, &rej_buf, + ld_targ.t_m.m_mach)); } else { eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_NOTFOUND), file, sdf->sdf_rfile);
--- a/usr/src/cmd/sgs/libld/common/ldlibs.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/ldlibs.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -313,7 +313,7 @@ eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(reject[rej.rej_type]), rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(&rej, &rej_buf)); + conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach)); } else { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_LIB_NOTFOUND), name);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/libld/common/ldmachdep.c Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,56 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Most of the source files in libld.so are not allowed to + * include the machdep.h header, because it supplies machine + * values that are specific to the platform running the linker, + * instead of the target machine. This module is used to provide + * information about the currently running host to the rest + * of the linker code. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <_libld.h> +#include <machdep.h> + +/* + * Return an ELF machine code that reflects the currently executing + * linker. This information can be used in cross link situations to + * know which platform the linker was running on, and whether the linker + * itself was a 32 or 64-bit program. + */ +Half +ld_sunw_ldmach(void) +{ +#ifdef _LP64 + return (M_MACH_64); +#else + return (M_MACH_32); +#endif +}
--- a/usr/src/cmd/sgs/libld/common/ldmain.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/ldmain.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,12 +23,16 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* + * Processing of relocatable objects and shared objects. + */ + +/* * ld -- link/editor main program */ #include <sys/types.h> @@ -42,6 +46,14 @@ #include "_libld.h" /* + * All target specific code is referenced via this global variable, which + * is initialized in ld_main(). This allows the linker to function as + * a cross linker, by vectoring to the target-specific code for the + * current target machine. + */ +Target ld_targ; + +/* * A default library search path is used if one was not supplied on the command * line. Note: these strings can not use MSG_ORIG() since they are modified as * part of the path processing. @@ -56,13 +68,47 @@ * A default elf header provides for simplifying diagnostic processing. */ static Ehdr def_ehdr = { { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, - M_CLASS, M_DATA }, 0, M_MACH, EV_CURRENT }; + ELFCLASSNONE, ELFDATANONE }, 0, EM_NONE, + EV_CURRENT }; + +/* + * Establish the global state necessary to link the desired machine + * target, as reflected by the ld_targ global variable. + */ +int +ld_init_target(Lm_list *lml, Half mach) +{ + switch (mach) { + case EM_386: + case EM_AMD64: + ld_targ = *ld_targ_init_x86(); + break; + + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + ld_targ = *ld_targ_init_sparc(); + break; + + default: + { + Conv_inv_buf_t inv_buf; + + eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TARG_UNSUPPORTED), + conv_ehdr_mach(mach, 0, &inv_buf)); + return (1); + } + } + + return (0); +} + /* * The main program */ int -ld_main(int argc, char **argv) +ld_main(int argc, char **argv, Half mach) { char *sgs_support; /* SGS_SUPPORT environment string */ Half etype; @@ -76,7 +122,18 @@ if ((ofl = libld_calloc(1, sizeof (Ofl_desc))) == 0) return (1); + /* Initilize target state */ + if (ld_init_target(NULL, mach) != 0) + return (1); + + /* + * Set up the output ELF header, and initialize the machine + * and class details. + */ ofl->ofl_dehdr = &def_ehdr; + def_ehdr.e_ident[EI_CLASS] = ld_targ.t_m.m_class; + def_ehdr.e_ident[EI_DATA] = ld_targ.t_m.m_data; + def_ehdr.e_machine = ld_targ.t_m.m_mach; ld_init(ofl); @@ -199,7 +256,7 @@ ofl->ofl_rpath = rpath; } if (ofl->ofl_flags & FLG_OF_EXEC) - ofl->ofl_segorigin = M_SEGM_ORIGIN; + ofl->ofl_segorigin = ld_targ.t_m.m_segm_origin; /* * Argument pass two. Input all libraries and objects. @@ -309,13 +366,15 @@ if (ld_reloc_process(ofl) == S_ERROR) return (ld_exit(ofl)); -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) /* * Fill in contents for Unwind Header */ - if (populate_amd64_unwindhdr(ofl) == S_ERROR) + if ((ld_targ.t_uw.uw_populate_unwindhdr != NULL) && + ((*ld_targ.t_uw.uw_populate_unwindhdr)(ofl) == S_ERROR)) return (ld_exit(ofl)); #endif + /* * Finally create the files elf checksum. */ @@ -323,6 +382,17 @@ *ofl->ofl_checksum = (Xword)elf_checksum(ofl->ofl_elf); /* + * If this is a cross link to a target with a different byte + * order than the linker, swap the data to the target byte order. + */ + if (((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) && + (_elf_swap_wrimage(ofl->ofl_elf) != 0)) { + eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_SWAP_WRIMAGE), + ofl->ofl_name); + return (ld_exit(ofl)); + } + + /* * We're done, so make sure the updates are flushed to the output file. */ if ((ofl->ofl_size = elf_update(ofl->ofl_welf, ELF_C_WRITE)) == 0) {
--- a/usr/src/cmd/sgs/libld/common/libld.chk.msg Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -@ _START_ - -# Messages to satisfy chkmsg target. Numerous messages within common code -# (reloc.h) aren't required for each target, but chkmsg has no way of dealing -# with ifdefs, thus this file exists to satisfy common code messages. - -@ MSG_REL_UNIMPL "relocation error: file %s: symbol %s: \ - unimplemented relocation type: %d" -@ MSG_REL_UNNOBITS "relocation error: %s: file %s: symbol %s: \ - unsupported number of bits: %d" -@ MSG_REL_LOSEBITS "relocation error: %s: file %s: symbol %s: \ - value 0x%llx loses %d bits at offset 0x%llx" - -@ _END_
--- a/usr/src/cmd/sgs/libld/common/libld.intel.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/libld.intel.msg Tue Mar 18 09:17:00 2008 -0700 @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -31,8 +30,6 @@ # Message file for cmd/sgs/libld - intel specific. -@ MSG_REL_NOREG "relocation error: REGISTER relocation not supported \ - on i386 architecture" @ MSG_REL_BADTLSINS "relocation error: %s: file %s: symbol %s: section %s: \ offset 0x%llx, relocation against unknown TLS \ instruction sequence" @@ -50,3 +47,5 @@ @ MSG_SPECFIL_PLTENT "<output_file>" @ MSG_SCN_UNWINDHDR ".eh_frame_hdr" + +@ MSG_PTH_RTLD_AMD64 "/usr/lib/amd64/ld.so.1"
--- a/usr/src/cmd/sgs/libld/common/libld.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/libld.msg Tue Mar 18 09:17:00 2008 -0700 @@ -197,6 +197,8 @@ against COMDAT sections\n" @ MSG_ARG_DETAIL_ZRS "\t[-z rescan]\trescan archive list until no further \ member\n\t\t\textraction occurs\n" +@ MSG_ARG_DETAIL_ZTARG "\t[-z target=platform]\n\ + \t\t\ttarget machine for cross linking\n" @ MSG_ARG_DETAIL_ZT "\t[-z text]\tdisallow output relocations against \ text\n" @ MSG_ARG_DETAIL_ZTO "\t[-z textoff]\tallow output relocations against \ @@ -225,8 +227,6 @@ skipping null relocation record" @ MSG_REL_NOTSUP "relocation error: %s: file %s: section %s: \ relocation not currently supported" -@ MSG_REL_NOSWAP "relocation error: %s: file %s: symbol %s: \ - linker does not support byte swapping relocated data" @ MSG_REL_PICREDLOC "relocation error: %s: file %s symbol %s: \ -z redlocsym may not be used for pic code" @ MSG_REL_TLSLE "relocation error: %s: file %s: symbol %s: \ @@ -296,6 +296,8 @@ @ MSG_REL_SLOPCDATNAM "relocation warning: %s: file %s: section %s: \ symbol %s: relocation against discarded COMDAT \ section %s redirected to file %s" +@ MSG_REL_NOREG "relocation error: REGISTER relocation not supported \ + on target architecture" # # TRANSLATION_NOTE @@ -389,6 +391,11 @@ @ MSG_SYS_MMAPANON "file %s: mmap anon failed: %s" +# Messages related to platform support +@ MSG_TARG_UNSUPPORTED "unsupported ELF machine type: %s" + + + # ELF processing messages @ MSG_ELF_LIBELF "libelf: version not supported: %d" @@ -435,9 +442,9 @@ @ MSG_SYM_TENTERR "\ttentative symbol cannot override defined symbol \ of smaller size" -@ MSG_SYM_INVSHNDX "symbol `%s' has invalid section index; \ +@ MSG_SYM_INVSHNDX "symbol %s has invalid section index; \ ignored:\n\t(file %s value=%s);" -@ MSG_SYM_NONGLOB "global symbol `%s' has non-global binding:\n\ +@ MSG_SYM_NONGLOB "global symbol %s has non-global binding:\n\ \t(file %s value=%s);" @ MSG_SYM_RESERVE "reserved symbol `%s' already defined in file %s" @ MSG_SYM_NOTNULL "undefined symbol `%s' with non-zero value encountered \ @@ -578,6 +585,7 @@ @ MSG_ELF_NEWPHDR "file %s: elf_newphdr" @ MSG_ELF_STRPTR "file %s: elf_strptr" @ MSG_ELF_UPDATE "file %s: elf_update" +@ MSG_ELF_SWAP_WRIMAGE "file %s: _elf_swap_wrimage" @ MSG_REJ_MACH "file %s: wrong ELF machine type: %s" @@ -612,10 +620,10 @@ @ MSG_FMT_ARMEM "%s(%s)" @ MSG_FMT_COLPATH "%s:%s" +@ MSG_FMT_SYMNAM "`%s'" +@ MSG_FMT_NULLSYMNAM "%s[%d]" @ MSG_PTH_RTLD "/usr/lib/ld.so.1" -@ MSG_PTH_RTLD_SPARCV9 "/usr/lib/sparcv9/ld.so.1" -@ MSG_PTH_RTLD_AMD64 "/usr/lib/amd64/ld.so.1" @ MSG_PTH_DEVZERO "/dev/zero" @ MSG_SUNW_OST_SGS "SUNW_OST_SGS" @@ -1125,6 +1133,7 @@ @ MSG_ARG_NOLDYNSYM "noldynsym" @ MSG_ARG_RELAXRELOC "relaxreloc" @ MSG_ARG_GLOBAUDIT "globalaudit" +@ MSG_ARG_TARGET "target=" @ MSG_ARG_HELP "help" @ MSG_ARG_GROUP "group"
--- a/usr/src/cmd/sgs/libld/common/libld.sparc.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/libld.sparc.msg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -78,3 +78,5 @@ @ MSG_STO_REGISTERG5 "<SCRATCH REGISTER 5>" @ MSG_STO_REGISTERG6 "<SCRATCH REGISTER 6>" @ MSG_STO_REGISTERG7 "<SCRATCH REGISTER 7>" + +@ MSG_PTH_RTLD_SPARCV9 "/usr/lib/sparcv9/ld.so.1"
--- a/usr/src/cmd/sgs/libld/common/libs.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/libs.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -626,7 +626,7 @@ eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(reject[rej.rej_type]), rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(&rej, &rej_buf)); + conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach)); } /*
--- a/usr/src/cmd/sgs/libld/common/llib-lld Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/llib-lld Tue Mar 18 09:17:00 2008 -0700 @@ -22,7 +22,7 @@ /* PROTOLIB1 */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -42,8 +42,8 @@ uintptr_t ld32_init_strings(Ofl_desc *); uintptr_t ld64_init_strings(Ofl_desc *); -int ld32_main(int, char **); -int ld64_main(int, char **); +int ld32_main(int, char **, Elf32_Half); +int ld64_main(int, char **, Elf64_Half); uintptr_t ld32_make_sections(Ofl_desc *); uintptr_t ld64_make_sections(Ofl_desc *);
--- a/usr/src/cmd/sgs/libld/common/machrel.amd.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,27 +20,38 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" +/* Get the x86 version of the relocation engine */ +#define DO_RELOC_LIBLD_X86 + #include <string.h> #include <stdio.h> #include <strings.h> #include <sys/elf_amd64.h> #include <debug.h> #include <reloc.h> +#include <i386/machdep_x86.h> #include "msg.h" #include "_libld.h" +#include "unwind.amd.h" -Word + +/* Forward declarations */ +static Gotndx *ld_find_gotndx(List *, Gotref, Ofl_desc *, Rel_desc *); +static Xword ld_calc_got_offset(Rel_desc *, Ofl_desc *); + + +static Word ld_init_rel(Rel_desc *reld, void *reloc) { Rela * rel = (Rela *)reloc; /* LINTED */ - reld->rel_rtype = (Word)ELF_R_TYPE(rel->r_info); + reld->rel_rtype = (Word)ELF_R_TYPE(rel->r_info, M_MACH); reld->rel_roffset = rel->r_offset; reld->rel_raddend = rel->r_addend; reld->rel_typedata = 0; @@ -50,13 +61,13 @@ return ((Word)ELF_R_SYM(rel->r_info)); } -void +static void ld_mach_eflags(Ehdr *ehdr, Ofl_desc *ofl) { ofl->ofl_dehdr->e_flags |= ehdr->e_flags; } -void +static void ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt) { if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) { @@ -68,7 +79,7 @@ } } -void +static void ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn) { if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) { @@ -81,7 +92,7 @@ } } -Xword +static Xword ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl) { Xword value; @@ -111,7 +122,7 @@ Sword plt_off; Word got_off; Xword val1; - int bswap; + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; got_off = sdp->sd_aux->sa_PLTGOTndx * M_GOT_ENTSIZE; plt_off = M_PLT_RESERVSZ + ((sdp->sd_aux->sa_PLTndx - 1) * @@ -127,6 +138,9 @@ /* LINTED */ *(Word *)gotent = ofl->ofl_osplt->os_shdr->sh_addr + plt_off + M_PLT_INSSIZE; + if (bswap) + /* LINTED */ + *(Word *)gotent = ld_bswap_Word(*(Word *)gotent); /* * If '-z noreloc' is specified - skip the do_reloc_ld @@ -136,14 +150,6 @@ return (1); /* - * If the running linker has a different byte order than - * the target host, tell do_reloc_ld() to swap bytes. - * - * We know the PLT is PROGBITS --- we don't have to check - */ - bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; - - /* * patchup: * jmpq *name1@gotpcrel(%rip) * @@ -196,7 +202,7 @@ return (1); } -uintptr_t +static uintptr_t ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl) { Os_desc * relosp, * osp = 0; @@ -593,7 +599,7 @@ return (FIX_RELOC); } -uintptr_t +static uintptr_t ld_do_activerelocs(Ofl_desc *ofl) { Rel_desc *arsp; @@ -816,7 +822,7 @@ */ if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) *(Xword *)R2addr = - ld_byteswap_Xword(value); + ld_bswap_Xword(value); else *(Xword *)R2addr = value; continue; @@ -986,7 +992,7 @@ return (return_code); } -uintptr_t +static uintptr_t ld_add_outrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl) { Rel_desc *orsp; @@ -1126,20 +1132,9 @@ } /* - * Stub routine since register symbols are not supported on amd64. - */ -/* ARGSUSED */ -uintptr_t -ld_reloc_register(Rel_desc * rsp, Is_desc * isp, Ofl_desc * ofl) -{ - eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOREG)); - return (S_ERROR); -} - -/* * process relocation for a LOCAL symbol */ -uintptr_t +static uintptr_t ld_reloc_local(Rel_desc * rsp, Ofl_desc * ofl) { Word flags = ofl->ofl_flags; @@ -1222,19 +1217,7 @@ } -uintptr_t -/* ARGSUSED */ -ld_reloc_GOTOP(Boolean local, Rel_desc * rsp, Ofl_desc * ofl) -{ - /* - * Stub routine for common code compatibility, we shouldn't - * actually get here on amd64. - */ - assert(0); - return (S_ERROR); -} - -uintptr_t +static uintptr_t ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl) { Word rtype = rsp->rel_rtype; @@ -1317,7 +1300,7 @@ } /* ARGSUSED3 */ -Gotndx * +static Gotndx * ld_find_gotndx(List * lst, Gotref gref, Ofl_desc * ofl, Rel_desc * rdesc) { Listnode * lnp; @@ -1337,7 +1320,7 @@ return ((Gotndx *)0); } -Xword +static Xword ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl) { Os_desc *osp = ofl->ofl_osgot; @@ -1369,7 +1352,7 @@ /* ARGSUSED5 */ -uintptr_t +static uintptr_t ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl, Rel_desc * rsp, Sym_desc * sdp) { @@ -1433,7 +1416,7 @@ return (1); } -void +static void ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl) { sdp->sd_aux->sa_PLTndx = 1 + ofl->ofl_pltcnt++; @@ -1453,9 +1436,11 @@ /* * Initializes .got[0] with the _DYNAMIC symbol value. */ -uintptr_t +static uintptr_t ld_fillin_gotplt(Ofl_desc *ofl) { + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; + if (ofl->ofl_osgot) { Sym_desc *sdp; @@ -1467,6 +1452,11 @@ (M_GOT_XDYNAMIC * M_GOT_ENTSIZE)); /* LINTED */ *(Xword *)genptr = sdp->sd_sym->st_value; + if (bswap) + /* LINTED */ + *(Xword *)genptr = + /* LINTED */ + ld_bswap_Xword(*(Xword *)genptr); } } @@ -1483,7 +1473,6 @@ if ((ofl->ofl_flags & FLG_OF_DYNAMIC) && ofl->ofl_osplt) { uchar_t *pltent; Xword val1; - int bswap; pltent = (uchar_t *)ofl->ofl_osplt->os_outdata->d_buf; bcopy(plt0_template, pltent, sizeof (plt0_template)); @@ -1496,15 +1485,6 @@ return (1); /* - * If the running linker has a different byte order than - * the target host, tell do_reloc_ld() to swap bytes. - * - * We know the GOT is PROGBITS --- we don't have - * to check. - */ - bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; - - /* * filin: * PUSHQ GOT + 8(%rip) * @@ -1543,3 +1523,142 @@ return (1); } + + + +/* + * Template for generating "void (*)(void)" function + */ +static const uchar_t nullfunc_tmpl[] = { /* amd64 */ +/* 0x00 */ 0x55, /* pushq %rbp */ +/* 0x01 */ 0x48, 0x8b, 0xec, /* movq %rsp,%rbp */ +/* 0x04 */ 0x48, 0x8b, 0xe5, /* movq %rbp,%rsp */ +/* 0x07 */ 0x5d, /* popq %rbp */ +/* 0x08 */ 0xc3 /* ret */ +}; + + +/* + * Return the ld_targ definition for this target. + */ +const Target * +ld_targ_init_x86(void) +{ + static const Target _ld_targ = { + { /* Target_mach */ + M_MACH, /* m_mach */ + M_MACHPLUS, /* m_machplus */ + M_FLAGSPLUS, /* m_flagsplus */ + M_CLASS, /* m_class */ + M_DATA, /* m_data */ + + M_SEGM_ALIGN, /* m_segm_align */ + M_SEGM_ORIGIN, /* m_segm_origin */ + M_DATASEG_PERM, /* m_dataseg_perm */ + M_WORD_ALIGN, /* m_word_align */ + MSG_ORIG(MSG_PTH_RTLD_AMD64), /* m_def_interp */ + + /* Relocation type codes */ + M_R_ARRAYADDR, /* m_r_arrayaddr */ + M_R_COPY, /* m_r_copy */ + M_R_GLOB_DAT, /* m_r_glob_dat */ + M_R_JMP_SLOT, /* m_r_jmp_slot */ + M_R_NUM, /* m_r_num */ + M_R_NONE, /* m_r_none */ + M_R_RELATIVE, /* m_r_relative */ + M_R_REGISTER, /* m_r_register */ + + /* Relocation related constants */ + M_REL_DT_COUNT, /* m_rel_dt_count */ + M_REL_DT_ENT, /* m_rel_dt_ent */ + M_REL_DT_SIZE, /* m_rel_dt_size */ + M_REL_DT_TYPE, /* m_rel_dt_type */ + M_REL_SHT_TYPE, /* m_rel_sht_type */ + + /* GOT related constants */ + M_GOT_ENTSIZE, /* m_got_entsize */ + M_GOT_XNumber, /* m_got_xnumber */ + + /* PLT related constants */ + M_PLT_ALIGN, /* m_plt_align */ + M_PLT_ENTSIZE, /* m_plt_entsize */ + M_PLT_RESERVSZ, /* m_plt_reservsz */ + M_PLT_SHF_FLAGS, /* m_plt_shf_flags */ + + M_DT_REGISTER, /* m_dt_register */ + }, + { /* Target_machid */ + M_ID_ARRAY, /* id_array */ + M_ID_BSS, /* id_bss */ + M_ID_CAP, /* id_cap */ + M_ID_DATA, /* id_data */ + M_ID_DYNAMIC, /* id_dynamic */ + M_ID_DYNSORT, /* id_dynsort */ + M_ID_DYNSTR, /* id_dynstr */ + M_ID_DYNSYM, /* id_dynsym */ + M_ID_DYNSYM_NDX, /* id_dynsym_ndx */ + M_ID_GOT, /* id_got */ + M_ID_UNKNOWN, /* id_gotdata (unused) */ + M_ID_HASH, /* id_hash */ + M_ID_INTERP, /* id_interp */ + M_ID_LBSS, /* id_lbss */ + M_ID_LDYNSYM, /* id_ldynsym */ + M_ID_NOTE, /* id_note */ + M_ID_NULL, /* id_null */ + M_ID_PLT, /* id_plt */ + M_ID_REL, /* id_rel */ + M_ID_STRTAB, /* id_strtab */ + M_ID_SYMINFO, /* id_syminfo */ + M_ID_SYMTAB, /* id_symtab */ + M_ID_SYMTAB_NDX, /* id_symtab_ndx */ + M_ID_TEXT, /* id_text */ + M_ID_TLS, /* id_tls */ + M_ID_TLSBSS, /* id_tlsbss */ + M_ID_UNKNOWN, /* id_unknown */ + M_ID_UNWIND, /* id_unwind */ + M_ID_USER, /* id_user */ + M_ID_VERSION, /* id_version */ + }, + { /* Target_nullfunc */ + nullfunc_tmpl, /* nf_template */ + sizeof (nullfunc_tmpl), /* nf_size */ + }, + { /* Target_machrel */ + reloc_table, + + ld_init_rel, /* mr_init_rel */ + ld_mach_eflags, /* mr_mach_eflags */ + ld_mach_make_dynamic, /* mr_mach_make_dynamic */ + ld_mach_update_odynamic, /* mr_mach_update_odynamic */ + ld_calc_plt_addr, /* mr_calc_plt_addr */ + ld_perform_outreloc, /* mr_perform_outreloc */ + ld_do_activerelocs, /* mr_do_activerelocs */ + ld_add_outrel, /* mr_add_outrel */ + NULL, /* mr_reloc_register */ + ld_reloc_local, /* mr_reloc_local */ + NULL, /* mr_reloc_GOTOP */ + ld_reloc_TLS, /* mr_reloc_TLS */ + NULL, /* mr_assign_got */ + ld_find_gotndx, /* mr_find_gotndx */ + ld_calc_got_offset, /* mr_calc_got_offset */ + ld_assign_got_ndx, /* mr_assign_got_ndx */ + ld_assign_plt_ndx, /* mr_assign_plt_ndx */ + NULL, /* mr_allocate_got */ + ld_fillin_gotplt, /* mr_fillin_gotplt */ + }, + { /* Target_machsym */ + NULL, /* ms_reg_check */ + NULL, /* ms_mach_sym_typecheck */ + NULL, /* ms_is_regsym */ + NULL, /* ms_reg_find */ + NULL /* ms_reg_enter */ + }, + { /* Target_unwind */ + make_amd64_unwindhdr, /* uw_make_unwindhdr */ + populate_amd64_unwindhdr, /* uw_populate_unwindhdr */ + append_amd64_unwind, /* uw_append_unwind */ + } + }; + + return (&_ld_targ); +}
--- a/usr/src/cmd/sgs/libld/common/machrel.intel.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c Tue Mar 18 09:17:00 2008 -0700 @@ -29,21 +29,30 @@ */ #pragma ident "%Z%%M% %I% %E% SMI" +/* Get the x86 version of the relocation engine */ +#define DO_RELOC_LIBLD_X86 + #include <string.h> #include <stdio.h> #include <sys/elf_386.h> #include <debug.h> #include <reloc.h> +#include <i386/machdep_x86.h> #include "msg.h" #include "_libld.h" -Word +/* Forward declarations */ +static Gotndx *ld_find_gotndx(List *, Gotref, Ofl_desc *, Rel_desc *); +static Xword ld_calc_got_offset(Rel_desc *, Ofl_desc *); + + +static Word ld_init_rel(Rel_desc *reld, void *reloc) { Rel * rel = (Rel *)reloc; /* LINTED */ - reld->rel_rtype = (Word)ELF_R_TYPE(rel->r_info); + reld->rel_rtype = (Word)ELF_R_TYPE(rel->r_info, M_MACH); reld->rel_roffset = rel->r_offset; reld->rel_raddend = 0; reld->rel_typedata = 0; @@ -51,13 +60,13 @@ return ((Word)ELF_R_SYM(rel->r_info)); } -void +static void ld_mach_eflags(Ehdr *ehdr, Ofl_desc *ofl) { ofl->ofl_dehdr->e_flags |= ehdr->e_flags; } -void +static void ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt) { if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) { @@ -69,7 +78,7 @@ } } -void +static void ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn) { if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) { @@ -82,7 +91,7 @@ } } -Xword +static Xword ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl) { Xword value; @@ -113,6 +122,7 @@ uchar_t *pltent, *gotent; Sword plt_off; Word got_off; + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; got_off = sdp->sd_aux->sa_PLTGOTndx * M_GOT_ENTSIZE; plt_off = M_PLT_RESERVSZ + ((sdp->sd_aux->sa_PLTndx - 1) * @@ -126,6 +136,9 @@ /* LINTED */ *(Word *)gotent = ofl->ofl_osplt->os_shdr->sh_addr + plt_off + M_PLT_INSSIZE; + if (bswap) + /* LINTED */ + *(Word *)gotent = ld_bswap_Word(*(Word *)gotent); if (!(ofl->ofl_flags & FLG_OF_SHAROBJ)) { pltent[0] = M_SPECIAL_INST; @@ -141,12 +154,18 @@ /* LINTED */ *(Word *)pltent = (Word)got_off; } + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); pltent += 4; pltent[0] = M_INST_PUSHL; pltent++; /* LINTED */ *(Word *)pltent = (Word)rel_off; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); pltent += 4; plt_off = -(plt_off + 16); /* JMP, PUSHL, JMP take 16 bytes */ @@ -154,9 +173,12 @@ pltent++; /* LINTED */ *(Word *)pltent = (Word)plt_off; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); } -uintptr_t +static uintptr_t ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl) { Os_desc * relosp, * osp = 0; @@ -657,7 +679,7 @@ return (FIX_RELOC); } -uintptr_t +static uintptr_t ld_do_activerelocs(Ofl_desc *ofl) { Rel_desc *arsp; @@ -866,7 +888,7 @@ */ if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) *(Xword *)R2addr = - ld_byteswap_Xword(value); + ld_bswap_Xword(value); else *(Xword *)R2addr = value; continue; @@ -1035,7 +1057,7 @@ /* * Add an output relocation record. */ -uintptr_t +static uintptr_t ld_add_outrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl) { Rel_desc *orsp; @@ -1175,20 +1197,9 @@ } /* - * Stub routine since register symbols are not supported on i386. - */ -/* ARGSUSED */ -uintptr_t -ld_reloc_register(Rel_desc * rsp, Is_desc * isp, Ofl_desc * ofl) -{ - eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOREG)); - return (S_ERROR); -} - -/* * process relocation for a LOCAL symbol */ -uintptr_t +static uintptr_t ld_reloc_local(Rel_desc * rsp, Ofl_desc * ofl) { Word flags = ofl->ofl_flags; @@ -1259,19 +1270,7 @@ return (ld_add_actrel(NULL, rsp, ofl)); } -uintptr_t -/* ARGSUSED */ -ld_reloc_GOTOP(Boolean local, Rel_desc * rsp, Ofl_desc * ofl) -{ - /* - * Stub routine for common code compatibility, we shouldn't - * actually get here on x86. - */ - assert(0); - return (S_ERROR); -} - -uintptr_t +static uintptr_t ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl) { Word rtype = rsp->rel_rtype; @@ -1393,7 +1392,7 @@ } /* ARGSUSED3 */ -Gotndx * +static Gotndx * ld_find_gotndx(List * lst, Gotref gref, Ofl_desc * ofl, Rel_desc * rdesc) { Listnode * lnp; @@ -1409,7 +1408,7 @@ return ((Gotndx *)0); } -Xword +static Xword ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl) { Os_desc *osp = ofl->ofl_osgot; @@ -1441,7 +1440,7 @@ /* ARGSUSED4 */ -uintptr_t +static uintptr_t ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl, Rel_desc * rsp, Sym_desc * sdp) { @@ -1474,7 +1473,7 @@ return (1); } -void +static void ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl) { sdp->sd_aux->sa_PLTndx = 1 + ofl->ofl_pltcnt++; @@ -1485,10 +1484,11 @@ /* * Initializes .got[0] with the _DYNAMIC symbol value. */ -uintptr_t +static uintptr_t ld_fillin_gotplt(Ofl_desc *ofl) { Word flags = ofl->ofl_flags; + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; if (ofl->ofl_osgot) { Sym_desc *sdp; @@ -1501,6 +1501,11 @@ (M_GOT_XDYNAMIC * M_GOT_ENTSIZE)); /* LINTED */ *(Word *)genptr = (Word)sdp->sd_sym->st_value; + if (bswap) + /* LINTED */ + *(Word *)genptr = + /* LINTED */ + ld_bswap_Word(*(Word *)genptr); } } @@ -1526,6 +1531,11 @@ /* LINTED */ *(Word *)pltent = (Word)(ofl->ofl_osgot->os_shdr-> sh_addr + M_GOT_XLINKMAP * M_GOT_ENTSIZE); + if (bswap) + /* LINTED */ + *(Word *)pltent = + /* LINTED */ + ld_bswap_Word(*(Word *)pltent); pltent += 4; pltent[0] = M_SPECIAL_INST; pltent[1] = M_JMP_DISP_IND; @@ -1533,6 +1543,11 @@ /* LINTED */ *(Word *)pltent = (Word)(ofl->ofl_osgot->os_shdr-> sh_addr + M_GOT_XRTLD * M_GOT_ENTSIZE); + if (bswap) + /* LINTED */ + *(Word *)pltent = + /* LINTED */ + ld_bswap_Word(*(Word *)pltent); } else { pltent[0] = M_SPECIAL_INST; pltent[1] = M_PUSHL_REG_DISP; @@ -1540,6 +1555,11 @@ /* LINTED */ *(Word *)pltent = (Word)(M_GOT_XLINKMAP * M_GOT_ENTSIZE); + if (bswap) + /* LINTED */ + *(Word *)pltent = + /* LINTED */ + ld_bswap_Word(*(Word *)pltent); pltent += 4; pltent[0] = M_SPECIAL_INST; pltent[1] = M_JMP_REG_DISP_IND; @@ -1547,7 +1567,148 @@ /* LINTED */ *(Word *)pltent = (Word)(M_GOT_XRTLD * M_GOT_ENTSIZE); + if (bswap) + /* LINTED */ + *(Word *)pltent = + /* LINTED */ + ld_bswap_Word(*(Word *)pltent); } } return (1); } + + + +/* + * Template for generating "void (*)(void)" function + */ +static const uchar_t nullfunc_tmpl[] = { /* IA32 */ +/* 0x00 */ 0xc3 /* ret */ +}; + + + +/* + * Return the ld_targ definition for this target. + */ +const Target * +ld_targ_init_x86(void) +{ + static const Target _ld_targ = { + { /* Target_mach */ + M_MACH, /* m_mach */ + M_MACHPLUS, /* m_machplus */ + M_FLAGSPLUS, /* m_flagsplus */ + M_CLASS, /* m_class */ + M_DATA, /* m_data */ + + M_SEGM_ALIGN, /* m_segm_align */ + M_SEGM_ORIGIN, /* m_segm_origin */ + M_DATASEG_PERM, /* m_dataseg_perm */ + M_WORD_ALIGN, /* m_word_align */ + MSG_ORIG(MSG_PTH_RTLD), /* m_def_interp */ + + /* Relocation type codes */ + M_R_ARRAYADDR, /* m_r_arrayaddr */ + M_R_COPY, /* m_r_copy */ + M_R_GLOB_DAT, /* m_r_glob_dat */ + M_R_JMP_SLOT, /* m_r_jmp_slot */ + M_R_NUM, /* m_r_num */ + M_R_NONE, /* m_r_none */ + M_R_RELATIVE, /* m_r_relative */ + M_R_REGISTER, /* m_r_register */ + + /* Relocation related constants */ + M_REL_DT_COUNT, /* m_rel_dt_count */ + M_REL_DT_ENT, /* m_rel_dt_ent */ + M_REL_DT_SIZE, /* m_rel_dt_size */ + M_REL_DT_TYPE, /* m_rel_dt_type */ + M_REL_SHT_TYPE, /* m_rel_sht_type */ + + /* GOT related constants */ + M_GOT_ENTSIZE, /* m_got_entsize */ + M_GOT_XNumber, /* m_got_xnumber */ + + /* PLT related constants */ + M_PLT_ALIGN, /* m_plt_align */ + M_PLT_ENTSIZE, /* m_plt_entsize */ + M_PLT_RESERVSZ, /* m_plt_reservsz */ + M_PLT_SHF_FLAGS, /* m_plt_shf_flags */ + + M_DT_REGISTER, /* m_dt_register */ + }, + { /* Target_machid */ + M_ID_ARRAY, /* id_array */ + M_ID_BSS, /* id_bss */ + M_ID_CAP, /* id_cap */ + M_ID_DATA, /* id_data */ + M_ID_DYNAMIC, /* id_dynamic */ + M_ID_DYNSORT, /* id_dynsort */ + M_ID_DYNSTR, /* id_dynstr */ + M_ID_DYNSYM, /* id_dynsym */ + M_ID_DYNSYM_NDX, /* id_dynsym_ndx */ + M_ID_GOT, /* id_got */ + M_ID_UNKNOWN, /* id_gotdata (unused) */ + M_ID_HASH, /* id_hash */ + M_ID_INTERP, /* id_interp */ + M_ID_LBSS, /* id_lbss */ + M_ID_LDYNSYM, /* id_ldynsym */ + M_ID_NOTE, /* id_note */ + M_ID_NULL, /* id_null */ + M_ID_PLT, /* id_plt */ + M_ID_REL, /* id_rel */ + M_ID_STRTAB, /* id_strtab */ + M_ID_SYMINFO, /* id_syminfo */ + M_ID_SYMTAB, /* id_symtab */ + M_ID_SYMTAB_NDX, /* id_symtab_ndx */ + M_ID_TEXT, /* id_text */ + M_ID_TLS, /* id_tls */ + M_ID_TLSBSS, /* id_tlsbss */ + M_ID_UNKNOWN, /* id_unknown */ + M_ID_UNWIND, /* id_unwind */ + M_ID_USER, /* id_user */ + M_ID_VERSION, /* id_version */ + }, + { /* Target_nullfunc */ + nullfunc_tmpl, /* nf_template */ + sizeof (nullfunc_tmpl), /* nf_size */ + }, + { /* Target_machrel */ + reloc_table, + + ld_init_rel, /* mr_init_rel */ + ld_mach_eflags, /* mr_mach_eflags */ + ld_mach_make_dynamic, /* mr_mach_make_dynamic */ + ld_mach_update_odynamic, /* mr_mach_update_odynamic */ + ld_calc_plt_addr, /* mr_calc_plt_addr */ + ld_perform_outreloc, /* mr_perform_outreloc */ + ld_do_activerelocs, /* mr_do_activerelocs */ + ld_add_outrel, /* mr_add_outrel */ + NULL, /* mr_reloc_register */ + ld_reloc_local, /* mr_reloc_local */ + NULL, /* mr_reloc_GOTOP */ + ld_reloc_TLS, /* mr_reloc_TLS */ + NULL, /* mr_assign_got */ + ld_find_gotndx, /* mr_find_gotndx */ + ld_calc_got_offset, /* mr_calc_got_offset */ + ld_assign_got_ndx, /* mr_assign_got_ndx */ + ld_assign_plt_ndx, /* mr_assign_plt_ndx */ + NULL, /* mr_allocate_got */ + ld_fillin_gotplt, /* mr_fillin_gotplt */ + }, + { /* Target_machsym */ + NULL, /* ms_reg_check */ + NULL, /* ms_mach_sym_typecheck */ + NULL, /* ms_is_regsym */ + NULL, /* ms_reg_find */ + NULL /* ms_reg_enter */ + }, + { /* Target_unwind */ + NULL, /* uw_make_unwindhdr */ + NULL, /* uw_populate_unwindhdr */ + NULL, /* uw_append_unwind */ + } + }; + + return (&_ld_targ); +}
--- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,18 +23,27 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" +/* Get the sparc version of the relocation engine */ +#define DO_RELOC_LIBLD_SPARC + #include <string.h> #include <stdio.h> #include <sys/elf_SPARC.h> #include <debug.h> #include <reloc.h> +#include <sparc/machdep_sparc.h> #include "msg.h" #include "_libld.h" +#include "machsym.sparc.h" + +/* Forward declarations */ +static Xword ld_calc_got_offset(Rel_desc *, Ofl_desc *); +static Gotndx *ld_find_gotndx(List *, Gotref, Ofl_desc *, Rel_desc *); /* * Local Variable Definitions @@ -43,13 +52,13 @@ static Sword smlgotcnt = M_GOT_XNumber; /* no. of small GOT symbols */ static Sword mixgotcnt = 0; /* # syms with both large/small GOT */ -Word +static Word ld_init_rel(Rel_desc *reld, void *reloc) { Rela * rela = (Rela *)reloc; /* LINTED */ - reld->rel_rtype = (Word)ELF_R_TYPE(rela->r_info); + reld->rel_rtype = (Word)ELF_R_TYPE(rela->r_info, M_MACH); reld->rel_roffset = rela->r_offset; reld->rel_raddend = rela->r_addend; reld->rel_typedata = (Word)ELF_R_TYPE_DATA(rela->r_info); @@ -59,7 +68,7 @@ return ((Word)ELF_R_SYM(rela->r_info)); } -void +static void ld_mach_eflags(Ehdr *ehdr, Ofl_desc *ofl) { Word eflags = ofl->ofl_dehdr->e_flags; @@ -111,7 +120,7 @@ ofl->ofl_dehdr->e_flags = eflags; } -void +static void ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt) { if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) { @@ -123,7 +132,7 @@ } } -void +static void ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn) { if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) { @@ -138,7 +147,7 @@ #if defined(_ELF64) -Xword +static Xword ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl) { Xword value, pltndx, farpltndx; @@ -177,13 +186,13 @@ /* * Instructions required for Far PLT's */ -static uint32_t farplt_instrs[6] = { - 0x8a10000f, /* mov %o7, %g5 */ - 0x40000002, /* call . + 0x8 */ - 0x01000000, /* nop */ - 0xc25be000, /* ldx [%o7 + 0], %g1 */ - 0x83c3c001, /* jmpl %o7 + %g1, %g1 */ - 0x9e100005 /* mov %g5, %o7 */ +static uchar_t farplt_instrs[24] = { + 0x8a, 0x10, 0x00, 0x0f, /* mov %o7, %g5 */ + 0x40, 0x00, 0x00, 0x02, /* call . + 0x8 */ + 0x01, 0x00, 0x00, 0x00, /* nop */ + 0xc2, 0x5b, 0xe0, 0x00, /* ldx [%o7 + 0], %g1 */ + 0x83, 0xc3, 0xc0, 0x01, /* jmpl %o7 + %g1, %g1 */ + 0x9e, 0x10, 0x00, 0x05 /* mov %g5, %o7 */ }; /* @@ -217,7 +226,7 @@ * .xword .PLT0-(.PLT32927+4) * */ -void +static void plt_far_entry(Ofl_desc *ofl, Xword pltndx, Xword *roffset, Sxword *raddend) { uint_t blockndx; /* # of far PLT blocks */ @@ -336,8 +345,9 @@ static void plt_entry(Ofl_desc *ofl, Xword pltndx, Xword *roffset, Sxword *raddend) { - uchar_t *pltent; /* PLT entry being created. */ - Sxword pltoff; /* Offset of this entry from PLT top */ + uchar_t *pltent; /* PLT entry being created. */ + Sxword pltoff; /* Offset of this entry from PLT top */ + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; /* * The second part of the V9 ABI (sec. 5.2.4) @@ -360,6 +370,9 @@ */ /* LINTED */ *(Word *)pltent = M_SETHIG1 | pltoff; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[1]: ba,a %xcc, .PLT1 (.PLT1 accessed as a @@ -371,6 +384,9 @@ /* LINTED */ *(Word *)pltent = M_BA_A_XCC | (((pltoff + M_PLT_ENTSIZE) >> 2) & S_MASK(19)); + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI). @@ -378,6 +394,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[3]: sethi 0, %g0 (NOP for PLT padding). @@ -385,6 +404,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[4]: sethi 0, %g0 (NOP for PLT padding). @@ -392,6 +414,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[5]: sethi 0, %g0 (NOP for PLT padding). @@ -399,6 +424,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[6]: sethi 0, %g0 (NOP for PLT padding). @@ -406,6 +434,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[7]: sethi 0, %g0 (NOP for PLT padding). @@ -413,12 +444,15 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_NOP; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); } #else /* Elf 32 */ -Xword +static Xword ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl) { Xword value, pltndx; @@ -446,6 +480,7 @@ { Byte * pltent; /* PLT entry being created. */ Sxword pltoff; /* Offset of this entry from PLT top */ + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; pltoff = M_PLT_RESERVSZ + (pltndx - 1) * M_PLT_ENTSIZE; pltent = (Byte *)ofl->ofl_osplt->os_outdata->d_buf + pltoff; @@ -458,6 +493,9 @@ */ /* LINTED */ *(Word *)pltent = M_SETHIG1 | pltoff; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[1]: ba,a .L0 (.L0 accessed as a PC-relative index of longwords) @@ -467,6 +505,9 @@ pltoff = -pltoff; /* LINTED */ *(Word *)pltent = M_BA_A | ((pltoff >> 2) & S_MASK(22)); + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI). @@ -474,6 +515,9 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_SETHIG0; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); /* * PLT[3]: sethi 0, %g0 (NOP for PLT padding). @@ -481,23 +525,26 @@ pltent += M_PLT_INSSIZE; /* LINTED */ *(Word *)pltent = M_SETHIG0; + if (bswap) + /* LINTED */ + *(Word *)pltent = ld_bswap_Word(*(Word *)pltent); } #endif /* _ELF64 */ -uintptr_t +static uintptr_t ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl) { - Os_desc * relosp, * osp = 0; - Xword ndx, roffset, value; - Sxword raddend; - const Rel_entry * rep; - Rela rea; - char *relbits; - Sym_desc * sdp, * psym = (Sym_desc *)0; - int sectmoved = 0; - Word dtflags1 = ofl->ofl_dtflags_1; - Word flags = ofl->ofl_flags; + Os_desc * relosp, * osp = 0; + Xword ndx, roffset, value; + Sxword raddend; + const Rel_entry *rep; + Rela rea; + char *relbits; + Sym_desc * sdp, * psym = (Sym_desc *)0; + int sectmoved = 0; + Word dtflags1 = ofl->ofl_dtflags_1; + Word flags = ofl->ofl_flags; raddend = orsp->rel_raddend; sdp = orsp->rel_sym; @@ -742,9 +789,11 @@ { Sym_desc *sdp = arsp->rel_sym; Word rtype = arsp->rel_rtype; - uint_t *offset; + Word *offset, w; + int bswap = OFL_SWAP_RELOC_DATA(ofl, arsp); - offset = (uint_t *)((uintptr_t)arsp->rel_roffset + + + offset = (Word *)((uintptr_t)arsp->rel_roffset + (uintptr_t)_elf_getxoff(arsp->rel_isdesc->is_indata) + (uintptr_t)arsp->rel_osdesc->os_outdata->d_buf); @@ -768,14 +817,18 @@ case R_SPARC_TLS_GD_ADD: DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); - *offset = (TLS_GD_IE_LD | - (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RS2))); + w = bswap ? ld_bswap_Word(*offset) : *offset; + w = (TLS_GD_IE_LD | + (w & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RS2))); + *offset = bswap ? ld_bswap_Word(w) : w; return (FIX_DONE); case R_SPARC_TLS_GD_CALL: DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); *offset = TLS_GD_IE_ADD; + if (bswap) + *offset = ld_bswap_Word(*offset); return (FIX_DONE); } return (FIX_RELOC); @@ -815,8 +868,10 @@ */ DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_TLS_LE_LOX10, arsp)); - *offset = TLS_GD_LE_XOR | - (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RD)); + w = bswap ? ld_bswap_Word(*offset) : *offset; + w = TLS_GD_LE_XOR | + (w & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RD)); + *offset = bswap ? ld_bswap_Word(w) : w; arsp->rel_rtype = R_SPARC_TLS_LE_LOX10; return (FIX_RELOC); @@ -832,8 +887,9 @@ */ DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); - *offset = ((*offset) & (FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) | - TLS_IE_LE_OR; + w = bswap ? ld_bswap_Word(*offset) : *offset; + w = (w & (FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) | TLS_IE_LE_OR; + *offset = bswap ? ld_bswap_Word(w) : w; return (FIX_DONE); case R_SPARC_TLS_LDO_ADD: @@ -849,14 +905,18 @@ */ DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); - *offset = *offset & (~FM3_REG_MSK_RS1); - *offset = *offset | (REG_G7 << 14); + w = bswap ? ld_bswap_Word(*offset) : *offset; + w = w & (~FM3_REG_MSK_RS1); + w = w | (REG_G7 << 14); + *offset = bswap ? ld_bswap_Word(w) : w; return (FIX_DONE); case R_SPARC_TLS_LDM_CALL: DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); *offset = TLS_LD_LE_CLRO0; + if (bswap) + *offset = ld_bswap_Word(*offset); return (FIX_DONE); case R_SPARC_TLS_LDM_HI22: @@ -867,6 +927,8 @@ DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); *offset = M_NOP; + if (bswap) + *offset = ld_bswap_Word(*offset); return (FIX_DONE); } return (FIX_RELOC); @@ -878,9 +940,10 @@ gotop_fixups(Ofl_desc *ofl, Rel_desc *arsp) { Word rtype = arsp->rel_rtype; - uint_t *offset; + Word *offset, w; const char *ifl_name; Conv_inv_buf_t inv_buf; + int bswap; switch (rtype) { case R_SPARC_GOTDATA_OP_HIX22: @@ -906,12 +969,14 @@ */ DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, R_SPARC_NONE, arsp)); - offset = (uint_t *)(uintptr_t)(arsp->rel_roffset + + offset = (Word *)(uintptr_t)(arsp->rel_roffset + _elf_getxoff(arsp->rel_isdesc->is_indata) + (uintptr_t)arsp->rel_osdesc->os_outdata->d_buf); - - *offset = ((*offset) & (FM3_REG_MSK_RS1 | + bswap = OFL_SWAP_RELOC_DATA(ofl, arsp); + w = bswap ? ld_bswap_Word(*offset) : *offset; + w = (w & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) | GOTOP_ADDINST; + *offset = bswap ? ld_bswap_Word(w) : w; return (FIX_DONE); } /* @@ -930,7 +995,7 @@ return (FIX_ERROR); } -uintptr_t +static uintptr_t ld_do_activerelocs(Ofl_desc *ofl) { Rel_desc *arsp; @@ -1150,7 +1215,7 @@ */ if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) *(Xword *)R2addr = - ld_byteswap_Xword(value); + ld_bswap_Xword(value); else *(Xword *)R2addr = value; continue; @@ -1288,7 +1353,7 @@ return (return_code); } -uintptr_t +static uintptr_t ld_add_outrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl) { Rel_desc *orsp; @@ -1493,7 +1558,7 @@ * search the input files global symbols to determine if this relocation is * appropriate. */ -uintptr_t +static uintptr_t ld_reloc_register(Rel_desc * rsp, Is_desc * isp, Ofl_desc * ofl) { if (ofl->ofl_flags & FLG_OF_MULDEFS) { @@ -1521,7 +1586,7 @@ /* * process relocation for a LOCAL symbol */ -uintptr_t +static uintptr_t ld_reloc_local(Rel_desc * rsp, Ofl_desc * ofl) { Word flags = ofl->ofl_flags; @@ -1621,7 +1686,7 @@ * value is passed to the final relocation engine, a verification ("V") * relocation should trigger a fatal error condition. */ -uintptr_t +static uintptr_t ld_reloc_GOTOP(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) { Word rtype = rsp->rel_rtype; @@ -1646,7 +1711,7 @@ return (ld_add_actrel(FLG_REL_GOTFIX, rsp, ofl)); } -uintptr_t +static uintptr_t ld_reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) { Word rtype = rsp->rel_rtype; @@ -1795,7 +1860,7 @@ static Sword mixed_index; /* starting index for mixed GOT entries */ static Sword large_index; /* starting index for large GOT entries */ -uintptr_t +static uintptr_t ld_assign_got(Ofl_desc *ofl, Sym_desc * sdp) { Listnode * lnp; @@ -1838,7 +1903,7 @@ /* * Search the GOT index list for a GOT entry with the proper addend. */ -Gotndx * +static Gotndx * ld_find_gotndx(List * lst, Gotref gref, Ofl_desc * ofl, Rel_desc * rdesc) { Listnode * lnp; @@ -1855,7 +1920,7 @@ return ((Gotndx *)0); } -Xword +static Xword ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl) { Os_desc *osp = ofl->ofl_osgot; @@ -1886,7 +1951,7 @@ (-neggotoffset * M_GOT_ENTSIZE))); } -uintptr_t +static uintptr_t ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl, Rel_desc * rsp, Sym_desc * sdp) { @@ -1996,14 +2061,14 @@ return (1); } -void +static void ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl) { sdp->sd_aux->sa_PLTndx = 1 + ofl->ofl_pltcnt++; } -uintptr_t +static uintptr_t ld_allocate_got(Ofl_desc * ofl) { const Sword first_large_ndx = M_GOT_MAXSMALL / 2; @@ -2077,7 +2142,7 @@ /* * Initializes .got[0] with the _DYNAMIC symbol value. */ -uintptr_t +static uintptr_t ld_fillin_gotplt(Ofl_desc *ofl) { if (ofl->ofl_osgot) { @@ -2092,7 +2157,154 @@ (M_GOT_XDYNAMIC * M_GOT_ENTSIZE)); /* LINTED */ *((Xword *)genptr) = sdp->sd_sym->st_value; + if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) + /* LINTED */ + *((Xword *)genptr) = + /* LINTED */ + ld_bswap_Xword(*((Xword *)genptr)); } } return (1); } + + + +/* + * Template for generating "void (*)(void)" function + */ +static const uchar_t nullfunc_tmpl[] = { +/* 0x00 */ 0x81, 0xc3, 0xe0, 0x08, /* retl */ +/* 0x04 */ 0x01, 0x00, 0x00, 0x00 /* nop */ +}; + + + +/* + * Return the ld_targ definition for this target. + */ +const Target * +ld_targ_init_sparc(void) +{ + static const Target _ld_targ = { + { /* Target_mach */ + M_MACH, /* m_mach */ + M_MACHPLUS, /* m_machplus */ + M_FLAGSPLUS, /* m_flagsplus */ + M_CLASS, /* m_class */ + M_DATA, /* m_data */ + + M_SEGM_ALIGN, /* m_segm_align */ + M_SEGM_ORIGIN, /* m_segm_origin */ + M_DATASEG_PERM, /* m_dataseg_perm */ + M_WORD_ALIGN, /* m_word_align */ + /* m_def_interp */ +#if defined(_ELF64) + MSG_ORIG(MSG_PTH_RTLD_SPARCV9), +#else + MSG_ORIG(MSG_PTH_RTLD), +#endif + + /* Relocation type codes */ + M_R_ARRAYADDR, /* m_r_arrayaddr */ + M_R_COPY, /* m_r_copy */ + M_R_GLOB_DAT, /* m_r_glob_dat */ + M_R_JMP_SLOT, /* m_r_jmp_slot */ + M_R_NUM, /* m_r_num */ + M_R_NONE, /* m_r_none */ + M_R_RELATIVE, /* m_r_relative */ + M_R_REGISTER, /* m_r_register */ + + /* Relocation related constants */ + M_REL_DT_COUNT, /* m_rel_dt_count */ + M_REL_DT_ENT, /* m_rel_dt_ent */ + M_REL_DT_SIZE, /* m_rel_dt_size */ + M_REL_DT_TYPE, /* m_rel_dt_type */ + M_REL_SHT_TYPE, /* m_rel_sht_type */ + + /* GOT related constants */ + M_GOT_ENTSIZE, /* m_got_entsize */ + M_GOT_XNumber, /* m_got_xnumber */ + + /* PLT related constants */ + M_PLT_ALIGN, /* m_plt_align */ + M_PLT_ENTSIZE, /* m_plt_entsize */ + M_PLT_RESERVSZ, /* m_plt_reservsz */ + M_PLT_SHF_FLAGS, /* m_plt_shf_flags */ + + M_DT_REGISTER, /* m_dt_register */ + }, + { /* Target_machid */ + M_ID_ARRAY, /* id_array */ + M_ID_BSS, /* id_bss */ + M_ID_CAP, /* id_cap */ + M_ID_DATA, /* id_data */ + M_ID_DYNAMIC, /* id_dynamic */ + M_ID_DYNSORT, /* id_dynsort */ + M_ID_DYNSTR, /* id_dynstr */ + M_ID_DYNSYM, /* id_dynsym */ + M_ID_DYNSYM_NDX, /* id_dynsym_ndx */ + M_ID_GOT, /* id_got */ + M_ID_GOTDATA, /* id_gotdata */ + M_ID_HASH, /* id_hash */ + M_ID_INTERP, /* id_interp */ + M_ID_UNKNOWN, /* id_lbss (unused) */ + M_ID_LDYNSYM, /* id_ldynsym */ + M_ID_NOTE, /* id_note */ + M_ID_NULL, /* id_null */ + M_ID_PLT, /* id_plt */ + M_ID_REL, /* id_rel */ + M_ID_STRTAB, /* id_strtab */ + M_ID_SYMINFO, /* id_syminfo */ + M_ID_SYMTAB, /* id_symtab */ + M_ID_SYMTAB_NDX, /* id_symtab_ndx */ + M_ID_TEXT, /* id_text */ + M_ID_TLS, /* id_tls */ + M_ID_TLSBSS, /* id_tlsbss */ + M_ID_UNKNOWN, /* id_unknown */ + M_ID_UNKNOWN, /* id_unwind (unused) */ + M_ID_USER, /* id_user */ + M_ID_VERSION, /* id_version */ + }, + { /* Target_nullfunc */ + nullfunc_tmpl, /* nf_template */ + sizeof (nullfunc_tmpl), /* nf_size */ + }, + { /* Target_machrel */ + reloc_table, + + ld_init_rel, /* mr_init_rel */ + ld_mach_eflags, /* mr_mach_eflags */ + ld_mach_make_dynamic, /* mr_mach_make_dynamic */ + ld_mach_update_odynamic, /* mr_mach_update_odynamic */ + ld_calc_plt_addr, /* mr_calc_plt_addr */ + ld_perform_outreloc, /* mr_perform_outreloc */ + ld_do_activerelocs, /* mr_do_activerelocs */ + ld_add_outrel, /* mr_add_outrel */ + ld_reloc_register, /* mr_reloc_register */ + ld_reloc_local, /* mr_reloc_local */ + ld_reloc_GOTOP, /* mr_reloc_GOTOP */ + ld_reloc_TLS, /* mr_reloc_TLS */ + ld_assign_got, /* mr_assign_got */ + ld_find_gotndx, /* mr_find_gotndx */ + ld_calc_got_offset, /* mr_calc_got_offset */ + ld_assign_got_ndx, /* mr_assign_got_ndx */ + ld_assign_plt_ndx, /* mr_assign_plt_ndx */ + ld_allocate_got, /* mr_allocate_got */ + ld_fillin_gotplt, /* mr_fillin_gotplt */ + }, + { /* Target_machsym */ + ld_reg_check_sparc, /* ms_reg_check */ + ld_mach_sym_typecheck_sparc, /* ms_mach_sym_typecheck */ + ld_is_regsym_sparc, /* ms_is_regsym */ + ld_reg_find_sparc, /* ms_reg_find */ + ld_reg_enter_sparc /* ms_reg_enter */ + }, + { /* Target_unwind */ + NULL, /* uw_make_unwindhdr */ + NULL, /* uw_populate_unwindhdr */ + NULL, /* uw_append_unwind */ + } + }; + + return (&_ld_targ); +}
--- a/usr/src/cmd/sgs/libld/common/machsym.intel.c Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <debug.h> -#include "_libld.h" - - -/* - * This file contains stub routines since currently register symbols - * are not relevant to the i386 architecture. But - having these - * stub routines avoids #ifdefs in common codes - and I hate that. - */ -/* ARGSUSED */ -int -ld_reg_check(Sym_desc *sdp, Sym *nsym, const char *nname, Ifl_desc *ifl, - Ofl_desc * ofl) -{ - return (1); -} - -/* ARGSUSED */ -int -ld_mach_sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) -{ - return (0); -} - -/* ARGSUSED */ -const char * -ld_is_regsym(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, - int symndx, Word shndx, const char *symsecname, Word * flags) -{ - return (0); -} - -/* ARGSUSED */ -Sym_desc * -ld_reg_find(Sym * sym, Ofl_desc * ofl) -{ - return (0); -} - -/* ARGSUSED */ -int -ld_reg_enter(Sym_desc * sdp, Ofl_desc * ofl) -{ - return (0); -}
--- a/usr/src/cmd/sgs/libld/common/machsym.sparc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/machsym.sparc.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,11 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" +#define ELF_TARGET_SPARC + #include <stdio.h> #include <string.h> #include <alloca.h> @@ -32,6 +34,7 @@ #include <debug.h> #include "msg.h" #include "_libld.h" +#include "machsym.sparc.h" /* * Matrix of legal combinations of usage of a given register: @@ -55,7 +58,7 @@ * */ int -ld_reg_check(Sym_desc *sdp, Sym *nsym, const char *nname, Ifl_desc *ifl, +ld_reg_check_sparc(Sym_desc *sdp, Sym *nsym, const char *nname, Ifl_desc *ifl, Ofl_desc * ofl) { Sym *osym = sdp->sd_sym; @@ -129,7 +132,8 @@ } int -ld_mach_sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) +ld_mach_sym_typecheck_sparc(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, + Ofl_desc *ofl) { Conv_inv_buf_t inv_buf1, inv_buf2; Sym *osym = sdp->sd_sym; @@ -152,7 +156,7 @@ return (1); } } else if (otype == STT_SPARC_REGISTER) - return (ld_reg_check(sdp, nsym, sdp->sd_name, ifl, ofl)); + return (ld_reg_check_sparc(sdp, nsym, sdp->sd_name, ifl, ofl)); return (0); } @@ -165,7 +169,7 @@ }; const char * -ld_is_regsym(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, +ld_is_regsym_sparc(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, int symndx, Word shndx, const char *symsecname, Word * flags) { const char *name; @@ -229,7 +233,7 @@ } Sym_desc * -ld_reg_find(Sym * sym, Ofl_desc * ofl) +ld_reg_find_sparc(Sym * sym, Ofl_desc * ofl) { if (ofl->ofl_regsyms == 0) return (0); @@ -238,7 +242,7 @@ } int -ld_reg_enter(Sym_desc * sdp, Ofl_desc * ofl) +ld_reg_enter_sparc(Sym_desc * sdp, Ofl_desc * ofl) { if (ofl->ofl_regsyms == 0) { ofl->ofl_regsymsno = STO_SPARC_REGISTER_G7 + 1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/libld/common/machsym.sparc.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,72 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Sparc register symbols + */ + +#ifndef _MACHSYM_DOT_SPARC_DOT_H +#define _MACHSYM_DOT_SPARC_DOT_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_ELF64) + +#define ld_is_regsym_sparc ld64_is_regsym_sparc +#define ld_mach_sym_typecheck_sparc ld64_mach_sym_typecheck_sparc +#define ld_reg_check_sparc ld64_reg_check_sparc +#define ld_reg_enter_sparc ld64_reg_enter_sparc +#define ld_reg_find_sparc ld64_reg_find_sparc + +#else + +#define ld_is_regsym_sparc ld32_is_regsym_sparc +#define ld_mach_sym_typecheck_sparc ld32_mach_sym_typecheck_sparc +#define ld_reg_check_sparc ld32_reg_check_sparc +#define ld_reg_enter_sparc ld32_reg_enter_sparc +#define ld_reg_find_sparc ld32_reg_find_sparc + +#endif + +extern const char *ld_is_regsym_sparc(Ofl_desc *, Ifl_desc *, Sym *, + const char *, int, Word, const char *, Word *); +extern int ld_mach_sym_typecheck_sparc(Sym_desc *, Sym *, + Ifl_desc *, Ofl_desc *); +extern int ld_reg_check_sparc(Sym_desc *, Sym *, const char *, + Ifl_desc *, Ofl_desc *); +extern int ld_reg_enter_sparc(Sym_desc *, Ofl_desc *); +extern Sym_desc * ld_reg_find_sparc(Sym *, Ofl_desc *); + + +#ifdef __cplusplus +} +#endif + +#endif /* _MACHSYM_DOT_SPARC_DOT_H */
--- a/usr/src/cmd/sgs/libld/common/map.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/map.c Tue Mar 18 09:17:00 2008 -0700 @@ -234,14 +234,16 @@ */ if (type == CA_SUNW_HW_1) { if ((number = (Xword)elfcap_hw1_from_str( - ELFCAP_STYLE_LC, Start_tok, M_MACH)) != 0) { + ELFCAP_STYLE_LC, Start_tok, + ld_targ.t_m.m_mach)) != 0) { ofl->ofl_hwcap_1 |= number; used++; continue; } } else { if ((number = (Xword)elfcap_sf1_from_str( - ELFCAP_STYLE_LC, Start_tok, M_MACH)) != 0) { + ELFCAP_STYLE_LC, Start_tok, + ld_targ.t_m.m_mach)) != 0) { ofl->ofl_sfcap_1 |= number; used++; continue; @@ -807,7 +809,7 @@ else if ((strcmp(Start_tok, MSG_ORIG(MSG_STR_REL)) == 0) || (strcmp(Start_tok, MSG_ORIG(MSG_STR_RELA)) == 0)) - enp->ec_type = M_REL_SHT_TYPE; + enp->ec_type = ld_targ.t_m.m_rel_sht_type; else if (strcmp(Start_tok, MSG_ORIG(MSG_STR_HASH)) == 0) enp->ec_type = SHT_HASH; else if (strcmp(Start_tok, MSG_ORIG(MSG_STR_LIB)) == 0) @@ -2491,7 +2493,8 @@ ofl) == S_ERROR) return (S_ERROR); DBG_CALL(Dbg_cap_mapfile(ofl->ofl_lml, - CA_SUNW_HW_1, ofl->ofl_hwcap_1, M_MACH)); + CA_SUNW_HW_1, ofl->ofl_hwcap_1, + ld_targ.t_m.m_mach)); continue; } else if (strcmp(sgp1->sg_name, @@ -2500,7 +2503,8 @@ ofl) == S_ERROR) return (S_ERROR); DBG_CALL(Dbg_cap_mapfile(ofl->ofl_lml, - CA_SUNW_SF_1, ofl->ofl_sfcap_1, M_MACH)); + CA_SUNW_SF_1, ofl->ofl_sfcap_1, + ld_targ.t_m.m_mach)); continue; } else { @@ -2592,7 +2596,8 @@ /* * Default to segment alignment */ - sgp1->sg_phdr.p_align = M_SEGM_ALIGN; + sgp1->sg_phdr.p_align = + ld_targ.t_m.m_segm_align; sgp1->sg_flags |= FLG_SG_ALIGN; } }
--- a/usr/src/cmd/sgs/libld/common/mapfile-vers Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/mapfile-vers Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -37,7 +37,7 @@ # definitions see: # Policy for Shared Library Version Names and Interface Definitions -SUNWprivate_4.2 { +SUNWprivate_4.3 { global: dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1) @@ -50,6 +50,8 @@ ld64_ent_setup; ld32_init_strings; ld64_init_strings; + ld32_init_target; + ld64_init_target; ld32_make_sections; ld64_make_sections; ld32_ofl_cleanup;
--- a/usr/src/cmd/sgs/libld/common/outfile.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/outfile.c Tue Mar 18 09:17:00 2008 -0700 @@ -453,8 +453,9 @@ } else if (ptype == PT_TLS) { if (flags & FLG_OF_TLSPHDR) nseg++; -#if defined(__x86) && defined(_ELF64) - } else if (ptype == PT_SUNW_UNWIND) { +#if defined(_ELF64) + } else if ((ld_targ.t_m.m_mach == EM_AMD64) && + (ptype == PT_SUNW_UNWIND)) { if (ofl->ofl_unwindhdr) nseg++; #endif
--- a/usr/src/cmd/sgs/libld/common/place.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/place.c Tue Mar 18 09:17:00 2008 -0700 @@ -412,7 +412,8 @@ for (APLIST_TRAVERSE(sgp->sg_osdescs, idx1, osp)) { Shdr *_shdr = osp->os_shdr; - if ((ident == osp->os_scnsymndx) && (ident != M_ID_REL) && + if ((ident == osp->os_scnsymndx) && + (ident != ld_targ.t_id.id_rel) && (isp->is_namehash == osp->os_namehash) && (shdr->sh_type != SHT_GROUP) && (shdr->sh_type != SHT_SUNW_dof) &&
--- a/usr/src/cmd/sgs/libld/common/relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -31,15 +31,49 @@ /* * set-up for relocations */ + +#define ELF_TARGET_AMD64 +#define ELF_TARGET_SPARC + #include <string.h> #include <stdio.h> #include <alloca.h> -#include <reloc.h> #include <debug.h> #include "msg.h" #include "_libld.h" /* + * Set up the relocation table flag test macros so that they use the + * relocation table for the current target machine. + */ +#define IS_PLT(X) RELTAB_IS_PLT(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOT_RELATIVE(X) \ + RELTAB_IS_GOT_RELATIVE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOT_PC(X) RELTAB_IS_GOT_PC(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOTPCREL(X) RELTAB_IS_GOTPCREL(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOT_BASED(X) RELTAB_IS_GOT_BASED(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOT_OPINS(X) RELTAB_IS_GOT_OPINS(X, ld_targ.t_mr.mr_reloc_table) +#define IS_GOT_REQUIRED(X) \ + RELTAB_IS_GOT_REQUIRED(X, ld_targ.t_mr.mr_reloc_table) +#define IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_ADD_RELATIVE(X) \ + RELTAB_IS_ADD_RELATIVE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_REGISTER(X) RELTAB_IS_REGISTER(X, ld_targ.t_mr.mr_reloc_table) +#define IS_NOTSUP(X) RELTAB_IS_NOTSUP(X, ld_targ.t_mr.mr_reloc_table) +#define IS_SEG_RELATIVE(X) \ + RELTAB_IS_SEG_RELATIVE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_EXTOFFSET(X) RELTAB_IS_EXTOFFSET(X, ld_targ.t_mr.mr_reloc_table) +#define IS_SEC_RELATIVE(X) \ + RELTAB_IS_SEC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_TLS_INS(X) RELTAB_IS_TLS_INS(X, ld_targ.t_mr.mr_reloc_table) +#define IS_TLS_GD(X) RELTAB_IS_TLS_GD(X, ld_targ.t_mr.mr_reloc_table) +#define IS_TLS_LD(X) RELTAB_IS_TLS_LD(X, ld_targ.t_mr.mr_reloc_table) +#define IS_TLS_IE(X) RELTAB_IS_TLS_IE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_TLS_LE(X) RELTAB_IS_TLS_LE(X, ld_targ.t_mr.mr_reloc_table) +#define IS_LOCALBND(X) RELTAB_IS_LOCALBND(X, ld_targ.t_mr.mr_reloc_table) +#define IS_SIZE(X) RELTAB_IS_SIZE(X, ld_targ.t_mr.mr_reloc_table) + +/* * Structure to hold copy relocation items. */ typedef struct copy_rel { @@ -73,8 +107,9 @@ if ((ifl->ifl_flags & FLG_IF_DISPDONE) && (ofl->ofl_flags & FLG_OF_VERBOSE)) eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2), - conv_reloc_type(ifl->ifl_ehdr->e_machine, M_R_COPY, - 0, &inv_buf), ifl->ifl_name, demangle(sdp->sd_name)); + conv_reloc_type(ifl->ifl_ehdr->e_machine, + ld_targ.t_m.m_r_copy, 0, &inv_buf), + ifl->ifl_name, demangle(sdp->sd_name)); if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0) return; @@ -112,7 +147,8 @@ const char *str; Word rstndx; - if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info)) == 0) + if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info, + ld_targ.t_m.m_mach)) == 0) continue; /* @@ -131,7 +167,8 @@ eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1), conv_reloc_type(ifl->ifl_ehdr->e_machine, - (uint_t)ELF_R_TYPE(reloc->r_info), + (uint_t)ELF_R_TYPE(reloc->r_info, + ld_targ.t_m.m_mach), 0, &inv_buf), ifl->ifl_name, str, MSG_INTL(MSG_STR_UNKNOWN), EC_XWORD(reloc->r_offset), @@ -160,7 +197,8 @@ eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1), conv_reloc_type(ifl->ifl_ehdr->e_machine, - (uint_t)ELF_R_TYPE(reloc->r_info), 0, &inv_buf), + (uint_t)ELF_R_TYPE(reloc->r_info, + ld_targ.t_m.m_mach), 0, &inv_buf), ifl->ifl_name, demangle(rsdp->sd_name), str, EC_XWORD(reloc->r_offset), str); } @@ -503,32 +541,27 @@ } DBG_CALL(Dbg_reloc_ars_entry(ofl->ofl_lml, ELF_DBG_LD, - arsp->rel_isdesc->is_shdr->sh_type, M_MACH, arsp)); + arsp->rel_isdesc->is_shdr->sh_type, ld_targ.t_m.m_mach, arsp)); return (1); } /* * In the platform specific machrel.XXX.c files, we sometimes write - * a value directly into the GOT. This function can be used when + * a value directly into the got/plt. These function can be used when * the running linker has the opposite byte order of the object being * produced. */ -Xword -ld_byteswap_Xword(Xword v) +Word +ld_bswap_Word(Word v) { -#ifdef _ELF64 - return ((v << 56) | - ((v & 0x0000ff00) << 40) | - ((v & 0x00ff0000) << 24) | - ((v & 0xff000000) << 8) | - ((v >> 8) & 0xff000000) | - ((v >> 24) & 0x00ff0000) | - ((v >> 40) & 0x0000ff00) | - (v >> 56)); /* Xword is unsigned - 0 bits enter from left */ -#else - return (((v << 24) | ((v & 0xff00) << 8) | - ((v >> 8) & 0xff00) | (v >> 24))); -#endif + return (BSWAP_WORD(v)); +} + + +Xword +ld_bswap_Xword(Xword v) +{ + return (BSWAP_XWORD(v)); } @@ -546,12 +579,12 @@ * relocation we need to assign it a GOT token. Once we've got * all of the GOT's assigned we can assign the actual indexes. */ - if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_GENERIC, - ofl, rsp)) == 0) { + if ((gnp = (*ld_targ.t_mr.mr_find_gotndx)(&(sdp->sd_GOTndxs), + GOT_REF_GENERIC, ofl, rsp)) == 0) { Word rtype = rsp->rel_rtype; - if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC, - ofl, rsp, sdp) == S_ERROR) + if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), 0, + GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR) return (S_ERROR); /* @@ -584,9 +617,10 @@ if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) || (sdp->sd_sym->st_shndx != SHN_ABS)) || (sdp->sd_aux && sdp->sd_aux->sa_symspec)) { - rsp->rel_rtype = M_R_RELATIVE; - if (ld_add_outrel((FLG_REL_GOT | - FLG_REL_ADVAL), rsp, + rsp->rel_rtype = + ld_targ.t_m.m_r_relative; + if ((*ld_targ.t_mr.mr_add_outrel) + ((FLG_REL_GOT | FLG_REL_ADVAL), rsp, ofl) == S_ERROR) return (S_ERROR); rsp->rel_rtype = rtype; @@ -597,14 +631,15 @@ return (S_ERROR); } } else { - rsp->rel_rtype = M_R_GLOB_DAT; - if (ld_add_outrel(FLG_REL_GOT, rsp, ofl) == S_ERROR) + rsp->rel_rtype = ld_targ.t_m.m_r_glob_dat; + if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_GOT, + rsp, ofl) == S_ERROR) return (S_ERROR); rsp->rel_rtype = rtype; } } else { - if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC, - ofl, rsp, sdp) == S_ERROR) + if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp, + GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR) return (S_ERROR); } @@ -623,27 +658,29 @@ { Sym_desc *sdp = rsp->rel_sym; -#if defined(__x86) -#if defined(_ELF64) - /* - * AMD64 TLS code sequences do not use a unique TLS relocation to - * reference the __tls_get_addr() function call. - */ - if ((ofl->ofl_flags & FLG_OF_EXEC) && - (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) == 0)) { - return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); + switch (ld_targ.t_m.m_mach) { + case EM_AMD64: + /* + * AMD64 TLS code sequences do not use a unique TLS + * relocation to reference the __tls_get_addr() function call. + */ + if ((ofl->ofl_flags & FLG_OF_EXEC) && + (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) == + 0)) + return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); + break; + + case EM_386: + /* + * GNUC IA32 TLS code sequences do not use a unique TLS + * relocation to reference the ___tls_get_addr() function call. + */ + if ((ofl->ofl_flags & FLG_OF_EXEC) && + (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == + 0)) + return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); + break; } -#else - /* - * GNUC IA32 TLS code sequences do not use a unique TLS relocation to - * reference the ___tls_get_addr() function call. - */ - if ((ofl->ofl_flags & FLG_OF_EXEC) && - (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == 0)) { - return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); - } -#endif -#endif /* __x86 */ /* * if (not PLT yet assigned) @@ -655,7 +692,7 @@ if (sdp->sd_aux->sa_PLTndx == 0) { Word ortype = rsp->rel_rtype; - ld_assign_plt_ndx(sdp, ofl); + (*ld_targ.t_mr.mr_assign_plt_ndx)(sdp, ofl); /* * If this symbol is binding to a LAZYLOADED object then @@ -667,8 +704,9 @@ (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD))) sdp->sd_flags |= FLG_SY_LAZYLD; - rsp->rel_rtype = M_R_JMP_SLOT; - if (ld_add_outrel(FLG_REL_PLT, rsp, ofl) == S_ERROR) + rsp->rel_rtype = ld_targ.t_m.m_r_jmp_slot; + if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_PLT, rsp, ofl) == + S_ERROR) return (S_ERROR); rsp->rel_rtype = ortype; } @@ -680,8 +718,9 @@ IS_ADD_RELATIVE(rsp->rel_rtype)) { Word ortype = rsp->rel_rtype; - rsp->rel_rtype = M_R_RELATIVE; - if (ld_add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR) + rsp->rel_rtype = ld_targ.t_m.m_r_relative; + if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_ADVAL, rsp, ofl) == + S_ERROR) return (S_ERROR); rsp->rel_rtype = ortype; return (1); @@ -711,7 +750,7 @@ */ if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sym->st_shndx == SHN_ABS)) { if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0) - return (ld_add_outrel(NULL, rsp, ofl)); + return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl)); /* * If -zabsexec is set then promote the ABSOLUTE symbol to @@ -734,7 +773,7 @@ if (sdp->sd_flags & FLG_SY_MVTOCOMM) return (ld_add_actrel(NULL, rsp, ofl)); else - return (ld_add_outrel(NULL, rsp, ofl)); + return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl)); } /* @@ -751,7 +790,7 @@ ELF_ST_TYPE(sym->st_info), 0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name, demangle(rsp->rel_sname), sdp->sd_file->ifl_name); - return (ld_add_outrel(NULL, rsp, ofl)); + return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl)); } /* @@ -864,8 +903,8 @@ _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON; _sdp->sd_flags |= FLG_SY_SPECSEC; _sdp->sd_sym->st_value = - (_sdp->sd_sym->st_size < (M_WORD_ALIGN * 2)) ? - M_WORD_ALIGN : M_WORD_ALIGN * 2; + (_sdp->sd_sym->st_size < (ld_targ.t_m.m_word_align * 2)) ? + ld_targ.t_m.m_word_align : ld_targ.t_m.m_word_align * 2; /* * Whether or not the symbol references initialized @@ -893,8 +932,9 @@ if (list_appendc(&ofl->ofl_copyrels, cpy_rel) == 0) return (S_ERROR); - rsp->rel_rtype = M_R_COPY; - if (ld_add_outrel(FLG_REL_BSS, rsp, ofl) == S_ERROR) + rsp->rel_rtype = ld_targ.t_m.m_r_copy; + if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_BSS, rsp, ofl) == + S_ERROR) return (S_ERROR); rsp->rel_rtype = rtype; @@ -907,8 +947,8 @@ eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_COPY), conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine, - M_R_COPY, 0, &inv_buf), _sdp->sd_file->ifl_name, - _sdp->sd_name); + ld_targ.t_m.m_r_copy, 0, &inv_buf), + _sdp->sd_file->ifl_name, _sdp->sd_name); } DBG_CALL(Dbg_syms_reloc(ofl, sdp)); } @@ -935,7 +975,7 @@ * until runtime. */ if (ofl->ofl_flags & FLG_OF_SHAROBJ) - return (ld_add_outrel(NULL, rsp, ofl)); + return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl)); /* * Otherwise process relocation now. @@ -963,8 +1003,9 @@ * the relocation is pc-relative, and * the relocation is against a symbol in same section */ - if (local && !IS_GOT_RELATIVE(rtype) && !IS_GOT_BASED(rtype) && - !IS_GOT_PC(rtype) && IS_PC_RELATIVE(rtype) && + if (local && !IS_GOT_RELATIVE(rtype) && + !IS_GOT_BASED(rtype) && !IS_GOT_PC(rtype) && + IS_PC_RELATIVE(rtype) && ((sdp->sd_isc) && (sdp->sd_isc->is_osdesc == isp->is_osdesc))) return (ld_add_actrel(NULL, rsp, ofl)); @@ -994,31 +1035,31 @@ /* * Indicate that this relocation should be processed the same - * as a section symbol. For SPARC and AMD64 (Rela), indicate - * that the addend also needs to be applied to this relocation. + * as a section symbol. For RELA, indicate that the addend + * also needs to be applied to this relocation. */ -#if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) - oflags = FLG_REL_SCNNDX; -#else - oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL; -#endif + if ((rsp->rel_flags & FLG_REL_RELA) == FLG_REL_RELA) + oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL; + else + oflags = FLG_REL_SCNNDX; } -#if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) - /* - * Intel (Rel) relocations do not contain an addend. Any addend is - * contained within the file at the location identified by the - * relocation offset. Therefore, if we're processing a section symbol, - * or a -zredlocsym relocation (that basically transforms a local symbol - * reference into a section reference), perform an active relocation to - * propagate any addend. - */ - if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) || - (oflags == FLG_REL_SCNNDX)) - if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR) - return (S_ERROR); -#endif - return (ld_add_outrel(oflags, rsp, ofl)); + if ((rsp->rel_flags & FLG_REL_RELA) == 0) { + /* + * Intel (Rel) relocations do not contain an addend. Any + * addend is contained within the file at the location + * identified by the relocation offset. Therefore, if we're + * processing a section symbol, or a -zredlocsym relocation + * (that basically transforms a local symbol reference into + * a section reference), perform an active relocation to + * propagate any addend. + */ + if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) || + (oflags == FLG_REL_SCNNDX)) + if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR) + return (S_ERROR); + } + return ((*ld_targ.t_mr.mr_add_outrel)(oflags, rsp, ofl)); } /* @@ -1093,7 +1134,8 @@ ifl->ifl_name, demangle(rsp->rel_sname)); return (S_ERROR); - } else if ((IS_TLS_IE(rtype)) && (flags & FLG_OF_VERBOSE)) { + } else if ((IS_TLS_IE(rtype)) && + (flags & FLG_OF_VERBOSE)) { eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_TLSIE), conv_reloc_type(mach, rtype, 0, &inv_buf1), @@ -1101,7 +1143,7 @@ } } - return (ld_reloc_TLS(local, rsp, ofl)); + return ((*ld_targ.t_mr.mr_reloc_TLS)(local, rsp, ofl)); } uintptr_t @@ -1115,8 +1157,9 @@ Boolean local; Conv_inv_buf_t inv_buf; - DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, M_REL_SHT_TYPE, - (void *)reloc, isname, reld->rel_sname)); + DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, ld_targ.t_m.m_mach, + ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname, + reld->rel_sname)); /* * Indicate this symbol is being used for relocation and therefore must @@ -1192,7 +1235,8 @@ reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) { local = TRUE; } else if (!(flags & FLG_OF_RELOBJ) && - (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) { + (IS_LOCALBND(rtype) || + IS_SEG_RELATIVE(rtype))) { local = TRUE; } else if (sdp->sd_ref == REF_REL_NEED) { /* @@ -1220,8 +1264,10 @@ * relocated symbol (PSARC 1999/636, bugid 4187211). Scan the input * files symbol table to cross reference this relocation offset. */ - if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && IS_PC_RELATIVE(rtype) && - (IS_GOT_PC(rtype) == 0) && (IS_PLT(rtype) == 0)) { + if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && + IS_PC_RELATIVE(rtype) && + (IS_GOT_PC(rtype) == 0) && + (IS_PLT(rtype) == 0)) { if (disp_inspect(ofl, reld, local) == S_ERROR) return (S_ERROR); } @@ -1231,7 +1277,8 @@ * they are relevant to the current GOT. If not building a relocatable * object - give a appropriate error message. */ - if (!local && !(flags & FLG_OF_RELOBJ) && IS_GOT_BASED(rtype)) { + if (!local && !(flags & FLG_OF_RELOBJ) && + IS_GOT_BASED(rtype)) { Ifl_desc *ifl = reld->rel_isdesc->is_file; eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED), @@ -1264,8 +1311,14 @@ /* * Select the relocation to perform. */ - if (IS_REGISTER(rtype)) - return (ld_reloc_register(reld, isp, ofl)); + if (IS_REGISTER(rtype)) { + if (ld_targ.t_mr.mr_reloc_register == NULL) { + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_REL_NOREG)); + return (S_ERROR); + } + return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl)); + } if (flags & FLG_OF_RELOBJ) return (reloc_relobj(local, reld, ofl)); @@ -1273,14 +1326,19 @@ if (IS_TLS_INS(rtype)) return (reloc_TLS(local, reld, ofl)); - if (IS_GOT_OPINS(rtype)) - return (ld_reloc_GOTOP(local, reld, ofl)); + if (IS_GOT_OPINS(rtype)) { + if (ld_targ.t_mr.mr_reloc_GOTOP == NULL) { + assert(0); + return (S_ERROR); + } + return ((*ld_targ.t_mr.mr_reloc_GOTOP)(local, reld, ofl)); + } if (IS_GOT_RELATIVE(rtype)) return (ld_reloc_GOT_relative(local, reld, ofl)); if (local) - return (ld_reloc_local(reld, ofl)); + return ((*ld_targ.t_mr.mr_reloc_local)(reld, ofl)); if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0)) return (ld_reloc_plt(reld, ofl)); @@ -1288,7 +1346,7 @@ if ((sdp->sd_ref == REF_REL_NEED) || (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) || (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE)) - return (ld_add_outrel(NULL, reld, ofl)); + return ((*ld_targ.t_mr.mr_add_outrel)(NULL, reld, ofl)); if (sdp->sd_ref == REF_DYN_NEED) return (reloc_exec(reld, ofl)); @@ -1553,7 +1611,7 @@ /* * Make sure the relocation is in the valid range. */ - if (rtype >= M_R_NUM) { + if (rtype >= ld_targ.t_m.m_r_num) { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT), ifl->ifl_name, isp->is_name, rtype); return (S_ERROR); @@ -1570,10 +1628,15 @@ reld->rel_sym = 0; reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY); - DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, - isp->is_shdr->sh_type, (void *)reloc, isp->is_name, - reld->rel_sname)); - return (ld_reloc_register(reld, isp, ofl)); + DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, + ld_targ.t_m.m_mach, isp->is_shdr->sh_type, + (void *)reloc, isp->is_name, reld->rel_sname)); + if (ld_targ.t_mr.mr_reloc_register == NULL) { + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_REL_NOREG)); + return (S_ERROR); + } + return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl)); } /* @@ -1607,16 +1670,17 @@ * warning and continue (the compiler folks can get into this * state some time). Normal users should never see this error. */ - if (rtype == M_R_NONE) { - DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, - M_REL_SHT_TYPE, (void *)reloc, isp->is_name, - reld->rel_sname)); + if (rtype == ld_targ.t_m.m_r_none) { + DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, + ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type, + (void *)reloc, isp->is_name, reld->rel_sname)); eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_NULL), ifl->ifl_name, isp->is_name); return (1); } - if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && IS_NOTSUP(rtype)) { + if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && + IS_NOTSUP(rtype)) { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP), conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0, &inv_buf), ifl->ifl_name, isp->is_name); @@ -1783,7 +1847,7 @@ * relocation records processing. */ reld.rel_flags = flags; - rsndx = ld_init_rel(&reld, (void *)reloc); + rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld, (void *)reloc); if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR) ret = S_ERROR; @@ -1926,7 +1990,7 @@ * Initialize the relocation record information. */ reld.rel_flags = FLG_REL_LOAD; - rsndx = ld_init_rel(&reld, (void *)reloc); + rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld, (void *)reloc); if (((mp = get_move_entry(rsect, reloc->r_offset)) == 0) || ((reld.rel_move = libld_malloc(sizeof (Mv_desc))) == 0)) @@ -2018,7 +2082,7 @@ if (ld_sym_spec(ofl) == S_ERROR) return (S_ERROR); - ofl->ofl_gotcnt = M_GOT_XNumber; + ofl->ofl_gotcnt = ld_targ.t_m.m_got_xnumber; /* * First process all of the relocations against NON-writable @@ -2086,14 +2150,10 @@ if (ld_make_got(ofl) == S_ERROR) return (S_ERROR); -#if defined(__sparc) - if (ld_allocate_got(ofl) == S_ERROR) + /* Allocate the GOT if required by target */ + if ((ld_targ.t_mr.mr_allocate_got != NULL) && + ((*ld_targ.t_mr.mr_allocate_got)(ofl) == S_ERROR)) return (S_ERROR); -#elif defined(__x86) -/* nothing to do */ -#else -#error Unknown architecture! -#endif } return (1); @@ -2181,7 +2241,7 @@ orsp < rcp->rc_free; orsp++) { if (debug == 0) { DBG_CALL(Dbg_reloc_dooutrel(ofl->ofl_lml, - M_REL_SHT_TYPE)); + ld_targ.t_m.m_rel_sht_type)); debug = 1; } @@ -2190,13 +2250,14 @@ * order that it was originally processed. */ if (orsp->rel_flags & FLG_REL_PLT) { - if (ld_perform_outreloc(orsp, ofl) == S_ERROR) + if ((*ld_targ.t_mr.mr_perform_outreloc)(orsp, + ofl) == S_ERROR) error = S_ERROR; continue; } - if ((orsp->rel_rtype == M_R_RELATIVE) || - (orsp->rel_rtype == M_R_REGISTER)) { + if ((orsp->rel_rtype == ld_targ.t_m.m_r_relative) || + (orsp->rel_rtype == ld_targ.t_m.m_r_register)) { sorted_list[index].rl_key1 = 0; sorted_list[index].rl_key2 = /* LINTED */ @@ -2210,9 +2271,10 @@ if (orsp->rel_flags & FLG_REL_GOT) sorted_list[index].rl_key3 = - ld_calc_got_offset(orsp, ofl); + (*ld_targ.t_mr.mr_calc_got_offset)(orsp, + ofl); else { - if (orsp->rel_rtype == M_R_REGISTER) + if (orsp->rel_rtype == ld_targ.t_m.m_r_register) sorted_list[index].rl_key3 = 0; else { sorted_list[index].rl_key3 = @@ -2236,8 +2298,8 @@ * and process each relocation. */ for (index = 0; index < ofl->ofl_reloccnt; index++) { - if (ld_perform_outreloc(sorted_list[index].rl_rsp, ofl) == - S_ERROR) + if ((*ld_targ.t_mr.mr_perform_outreloc) + (sorted_list[index].rl_rsp, ofl) == S_ERROR) error = S_ERROR; } @@ -2283,7 +2345,7 @@ if (do_sorted_outrelocs(ofl) == S_ERROR) return (S_ERROR); - if (ld_do_activerelocs(ofl) == S_ERROR) + if ((*ld_targ.t_mr.mr_do_activerelocs)(ofl) == S_ERROR) return (S_ERROR); if ((ofl->ofl_flags & FLG_OF_COMREL) == 0) { @@ -2355,7 +2417,7 @@ * .dynamic section (_DYNAMIC). */ if (flags & FLG_OF_DYNAMIC) { - if (ld_fillin_gotplt(ofl) == S_ERROR) + if ((*ld_targ.t_mr.mr_fillin_gotplt)(ofl) == S_ERROR) return (S_ERROR); } @@ -2364,7 +2426,8 @@ * information if required. */ if ((osp = ofl->ofl_osgot) != NULL) - DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1)); + DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1, + ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize)); return (1); } @@ -2416,7 +2479,7 @@ /* * Only give relocation errors against loadable read-only segments. */ - if ((orsp->rel_rtype == M_R_REGISTER) || (!osp) || + if ((orsp->rel_rtype == ld_targ.t_m.m_r_register) || (!osp) || (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) || (osp->os_sgdesc->sg_phdr.p_flags & PF_W)) return; @@ -2457,8 +2520,8 @@ { Word rflags; - if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, gref, ofl, - rsp, sdp) == S_ERROR) + if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp, + gref, ofl, rsp, sdp) == S_ERROR) return (S_ERROR); rflags = FLG_REL_GOT | rflag; @@ -2466,7 +2529,7 @@ rflags |= FLG_REL_SCNNDX; rsp->rel_rtype = rtype1; - if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR) + if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) == S_ERROR) return (S_ERROR); if (local && (gref == GOT_REF_TLSIE)) { @@ -2488,7 +2551,8 @@ if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR) return (S_ERROR); } else { - if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR) + if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) == + S_ERROR) return (S_ERROR); } } @@ -2591,6 +2655,49 @@ } + +/* + * Return True (1) if the code processing the given relocation + * needs to perform byte swapping when accessing the section data. + */ +int +ld_swap_reloc_data(Ofl_desc *ofl, Rel_desc *rsp) +{ + /* + * In a cross-link situation where the linker host and target + * have opposite byte orders, it can be necessary to swap bytes + * when doing relocation processing. This is indicated by the + * presence of the FLG_OF1_ENCDIFF flag bit. However, swapping + * is only needed for the section types that libelf doesn't + * automatically xlate. + */ + if ((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) { + switch (rsp->rel_osdesc->os_shdr->sh_type) { + case SHT_PROGBITS: + return (1); + + case SHT_SPARC_GOTDATA: + if (ld_targ.t_m.m_mach == + LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9)) + return (1); + break; + + case SHT_AMD64_UNWIND: + if (ld_targ.t_m.m_mach == EM_AMD64) + return (1); + break; + } + } + + /* + * If FLG_OF1_ENCDIFF isn't set, or the section isn't + * progbits (or similar), then no swapping is needed. + */ + return (0); +} + + + /* * Obtain the current value at the given relocation target. * @@ -2609,15 +2716,7 @@ { const Rel_entry *rep; - /* We do not currently support running as a cross linker */ - if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { - REL_ERR_NOSWAP(ofl->ofl_lml, - rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, - rsp->rel_rtype); - return (0); - } - - rep = &reloc_table[rsp->rel_rtype]; + rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype]; switch (rep->re_fsize) { case 1: @@ -2625,20 +2724,41 @@ *value = (Xword) *((uchar_t *)data); break; case 2: - /* LINTED */ - *value = (Xword) *((Half *)data); + { + Half v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { + UL_ASSIGN_BSWAP_HALF(v_bytes, data); + } else { + UL_ASSIGN_HALF(v_bytes, data); + } + *value = (Xword) v; + } break; case 4: - /* LINTED */ - *value = *((Xword *)data); + { + Word v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { + UL_ASSIGN_BSWAP_WORD(v_bytes, data); + } else { + UL_ASSIGN_WORD(v_bytes, data); + } + *value = (Xword) v; + } break; default: - /* - * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ) - */ - REL_ERR_UNSUPSZ(ofl->ofl_lml, - rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, - rsp->rel_rtype, rep->re_fsize); + { + Conv_inv_buf_t inv_buf; + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_REL_UNSUPSZ), + conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype, + 0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name, + (rsp->rel_sname ? demangle(rsp->rel_sname) : + MSG_INTL(MSG_STR_UNKNOWN)), (int)rep->re_fsize); + } return (0); } return (1); @@ -2663,15 +2783,7 @@ { const Rel_entry *rep; - /* We do not currently support running as a cross linker */ - if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { - REL_ERR_NOSWAP(ofl->ofl_lml, - rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, - rsp->rel_rtype); - return (0); - } - - rep = &reloc_table[rsp->rel_rtype]; + rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype]; switch (rep->re_fsize) { case 1: @@ -2679,20 +2791,39 @@ *((uchar_t *)data) = (uchar_t)value; break; case 2: - /* LINTED */ - *((Half *)data) = (Half)value; + { + Half v = (Half)value; + uchar_t *v_bytes = (uchar_t *)&v; + + if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { + UL_ASSIGN_BSWAP_HALF(data, v_bytes); + } else { + UL_ASSIGN_HALF(data, v_bytes); + } + } break; case 4: - /* LINTED */ - *((Xword *)data) = value; + { + Word v = (Word)value; + uchar_t *v_bytes = (uchar_t *)&v; + + if (OFL_SWAP_RELOC_DATA(ofl, rsp)) { + UL_ASSIGN_BSWAP_WORD(data, v_bytes); + } else { + UL_ASSIGN_WORD(data, v_bytes); + } + } break; default: - /* - * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ) - */ - REL_ERR_UNSUPSZ(ofl->ofl_lml, - rsp->rel_isdesc->is_file->ifl_name, rsp->rel_sname, - rsp->rel_rtype, rep->re_fsize); + { + Conv_inv_buf_t inv_buf; + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_REL_UNSUPSZ), + conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype, + 0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name, + (rsp->rel_sname ? demangle(rsp->rel_sname) : + MSG_INTL(MSG_STR_UNKNOWN)), (int)rep->re_fsize); + } return (0); } return (1);
--- a/usr/src/cmd/sgs/libld/common/resolve.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/resolve.c Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* SVR4 6.2/18.2 */ @@ -31,6 +31,8 @@ /* * Symbol table resolution */ +#define ELF_TARGET_AMD64 + #include <stdio.h> #include <debug.h> #include "msg.h" @@ -274,7 +276,8 @@ /* * Perform any machine specific type checking. */ - if (ld_mach_sym_typecheck(sdp, nsym, ifl, ofl)) + if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) && + (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl)) return; /* @@ -301,7 +304,9 @@ /* * Perform any machine specific type checking. */ - (void) ld_mach_sym_typecheck(sdp, nsym, ifl, ofl); + if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL) + (void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, + ifl, ofl); } /* @@ -574,7 +579,8 @@ /* * Perform any machine specific type checking. */ - if (ld_mach_sym_typecheck(sdp, nsym, ifl, ofl)) + if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) && + (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl)) return; /* @@ -835,25 +841,28 @@ size_t size = 0; Xword value = 0; -#if defined(__x86) && defined(_ELF64) - /* - * If the original and new symbols are both COMMON, but of a different - * size model, take the small one. - */ - if ((sdp->sd_sym->st_shndx == SHN_COMMON) && - (nsym->st_shndx == SHN_X86_64_LCOMMON)) { +#if defined(_ELF64) + if (ld_targ.t_m.m_mach == EM_AMD64) { /* - * Take the original symbol. + * If the original and new symbols are both COMMON, but of + * a different size model, take the small one. */ - return; + if ((sdp->sd_sym->st_shndx == SHN_COMMON) && + (nsym->st_shndx == SHN_X86_64_LCOMMON)) { + /* + * Take the original symbol. + */ + return; - } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && - (nsym->st_shndx == SHN_COMMON)) { - /* - * Take the new symbol. - */ - sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); - return; + } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && + (nsym->st_shndx == SHN_COMMON)) { + /* + * Take the new symbol. + */ + sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, + nsymflags); + return; + } } #endif @@ -869,9 +878,10 @@ ((sdp->sd_flags & FLG_SY_SPECSEC) && (sdp->sd_sym->st_shndx == SHN_COMMON) && (nsymflags & FLG_SY_SPECSEC) && -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) (nsym->st_shndx == SHN_COMMON)) || - ((sdp->sd_flags & FLG_SY_SPECSEC) && + ((ld_targ.t_m.m_mach == EM_AMD64) && + (sdp->sd_flags & FLG_SY_SPECSEC) && (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && (nsymflags & FLG_SY_SPECSEC) && (nsym->st_shndx == SHN_X86_64_LCOMMON))) { @@ -1126,8 +1136,9 @@ (nsym->st_shndx == SHN_COMMON)) { column = SYM_TENTATIVE; nsymflags |= FLG_SY_TENTSYM; -#if defined(__x86) && defined(_ELF64) - } else if ((nsymflags & FLG_SY_SPECSEC) && +#if defined(_ELF64) + } else if ((ld_targ.t_m.m_mach == EM_AMD64) && + (nsymflags & FLG_SY_SPECSEC) && (nsym->st_shndx == SHN_X86_64_LCOMMON)) { column = SYM_TENTATIVE; nsymflags |= FLG_SY_TENTSYM;
--- a/usr/src/cmd/sgs/libld/common/sections.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/sections.c Tue Mar 18 09:17:00 2008 -0700 @@ -31,6 +31,9 @@ /* * Module sections. Initialize special sections */ + +#define ELF_TARGET_AMD64 + #include <string.h> #include <strings.h> #include <stdio.h> @@ -302,7 +305,7 @@ if (!(flags & FLG_REL_PLT)) ofl->ofl_reloccntsub++; - if (rsp->rel_rtype == M_R_RELATIVE) + if (rsp->rel_rtype == ld_targ.t_m.m_r_relative) ofl->ofl_relocrelcnt--; } } @@ -358,6 +361,9 @@ * containing those values and generates code to set the sec_info * pointer to refer to it. The pointer in sec_info remains valid * outside of the declaration scope because the info_s struct is static. + * + * We can't determine the value of M_WORD_ALIGN at compile time, so + * a different variant is used for those cases. */ #define SET_SEC_INFO(d_type, d_align, sh_flags, sh_entsize) \ { \ @@ -365,6 +371,13 @@ sh_entsize}; \ sec_info = &info_s; \ } +#define SET_SEC_INFO_WORD_ALIGN(d_type, sh_flags, sh_entsize) \ + { \ + static SEC_INFO_T info_s = { d_type, 0, sh_flags, \ + sh_entsize}; \ + info_s.align = ld_targ.t_m.m_word_align; \ + sec_info = &info_s; \ + } switch (shtype) { case SHT_PROGBITS: @@ -376,16 +389,16 @@ * that they are correct or complete for any specific * purpose. The caller must provide the correct values. */ - SET_SEC_INFO(ELF_T_BYTE, M_WORD_ALIGN, SHF_ALLOC, 0) + SET_SEC_INFO_WORD_ALIGN(ELF_T_BYTE, SHF_ALLOC, 0) break; case SHT_SYMTAB: - SET_SEC_INFO(ELF_T_SYM, M_WORD_ALIGN, 0, sizeof (Sym)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_SYM, 0, sizeof (Sym)) break; case SHT_DYNSYM: case SHT_SUNW_LDYNSYM: - SET_SEC_INFO(ELF_T_SYM, M_WORD_ALIGN, SHF_ALLOC, sizeof (Sym)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_SYM, SHF_ALLOC, sizeof (Sym)) break; case SHT_STRTAB: @@ -405,7 +418,7 @@ * Relocations with an addend (Everything except 32-bit X86). * The caller is expected to set all section header flags. */ - SET_SEC_INFO(ELF_T_RELA, M_WORD_ALIGN, 0, sizeof (Rela)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_RELA, 0, sizeof (Rela)) break; case SHT_REL: @@ -413,13 +426,13 @@ * Relocations without an addend (32-bit X86 only). * The caller is expected to set all section header flags. */ - SET_SEC_INFO(ELF_T_REL, M_WORD_ALIGN, 0, sizeof (Rel)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_REL, 0, sizeof (Rel)) break; case SHT_HASH: case SHT_SUNW_symsort: case SHT_SUNW_tlssort: - SET_SEC_INFO(ELF_T_WORD, M_WORD_ALIGN, SHF_ALLOC, sizeof (Word)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_WORD, SHF_ALLOC, sizeof (Word)) break; case SHT_DYNAMIC: @@ -428,7 +441,7 @@ * on context, so we leave that flag unset and leave it to * the caller to add it if necessary. */ - SET_SEC_INFO(ELF_T_DYN, M_WORD_ALIGN, SHF_WRITE, sizeof (Dyn)) + SET_SEC_INFO_WORD_ALIGN(ELF_T_DYN, SHF_WRITE, sizeof (Dyn)) break; case SHT_NOBITS: @@ -455,11 +468,11 @@ * linker has no need for this information. It is purely * informational, used by elfdump(1), debuggers, etc. */ - SET_SEC_INFO(ELF_T_WORD, M_WORD_ALIGN, 0, sizeof (Word)); + SET_SEC_INFO_WORD_ALIGN(ELF_T_WORD, 0, sizeof (Word)); break; case SHT_SUNW_cap: - SET_SEC_INFO(ELF_T_CAP, M_WORD_ALIGN, SHF_ALLOC, sizeof (Cap)); + SET_SEC_INFO_WORD_ALIGN(ELF_T_CAP, SHF_ALLOC, sizeof (Cap)); break; case SHT_SUNW_move: @@ -478,7 +491,7 @@ * to the header index of the associated .dynamic section, * so we also set SHF_INFO_LINK. */ - SET_SEC_INFO(ELF_T_BYTE, M_WORD_ALIGN, + SET_SEC_INFO_WORD_ALIGN(ELF_T_BYTE, SHF_ALLOC | SHF_INFO_LINK, sizeof (Syminfo)); break; @@ -489,11 +502,11 @@ * The entries in these sections are not of uniform size, * so we set the entsize to 0. */ - SET_SEC_INFO(ELF_T_BYTE, M_WORD_ALIGN, SHF_ALLOC, 0); + SET_SEC_INFO_WORD_ALIGN(ELF_T_BYTE, SHF_ALLOC, 0); break; case SHT_SUNW_versym: - SET_SEC_INFO(ELF_T_BYTE, M_WORD_ALIGN, SHF_ALLOC, + SET_SEC_INFO_WORD_ALIGN(ELF_T_BYTE, SHF_ALLOC, sizeof (Versym)); break; @@ -503,6 +516,7 @@ return (S_ERROR); } #undef SET_SEC_INFO +#undef SET_SEC_INFO_WORD_ALIGN size = entcnt * sec_info->sh_entsize; @@ -641,20 +655,20 @@ if (which == MAKE_TLS) { isec->is_name = MSG_ORIG(MSG_SCN_TBSS); - ident = M_ID_TLSBSS; + ident = ld_targ.t_id.id_tlsbss; ofl->ofl_istlsbss = isec; shdr->sh_flags |= SHF_TLS; } else if (which == MAKE_BSS) { isec->is_name = MSG_ORIG(MSG_SCN_BSS); ofl->ofl_isbss = isec; - ident = M_ID_BSS; - -#if defined(__x86) && defined(_ELF64) - } else if (which == MAKE_LBSS) { + ident = ld_targ.t_id.id_bss; + +#if defined(_ELF64) + } else if ((ld_targ.t_m.m_mach == EM_AMD64) && (which == MAKE_LBSS)) { isec->is_name = MSG_ORIG(MSG_SCN_LBSS); ofl->ofl_islbss = isec; - ident = M_ID_LBSS; + ident = ld_targ.t_id.id_lbss; shdr->sh_flags |= SHF_AMD64_LARGE; #endif } @@ -722,7 +736,8 @@ if ((data->d_buf = libld_calloc(sizeof (Addr), entcount)) == 0) return (S_ERROR); - if (ld_place_section(ofl, isec, M_ID_ARRAY, 0) == (Os_desc *)S_ERROR) + if (ld_place_section(ofl, isec, ld_targ.t_id.id_array, 0) == + (Os_desc *)S_ERROR) return (S_ERROR); osp = isec->is_osdesc; @@ -747,7 +762,7 @@ * Fabricate the relocation information (as if a relocation record had * been input - see init_rel()). */ - reld.rel_rtype = M_R_ARRAYADDR; + reld.rel_rtype = ld_targ.t_m.m_r_arrayaddr; reld.rel_roffset = 0; reld.rel_raddend = 0; reld.rel_typedata = 0; @@ -757,10 +772,11 @@ * debugging requirements. */ reloc.r_offset = 0; - reloc.r_info = ELF_R_INFO(0, M_R_ARRAYADDR); + reloc.r_info = ELF_R_INFO(0, ld_targ.t_m.m_r_arrayaddr); reloc.r_addend = 0; - DBG_CALL(Dbg_reloc_generate(ofl->ofl_lml, osp, M_REL_SHT_TYPE)); + DBG_CALL(Dbg_reloc_generate(ofl->ofl_lml, osp, + ld_targ.t_m.m_rel_sht_type)); for (LIST_TRAVERSE(list, lnp, sdp)) { reld.rel_sname = sdp->sd_name; reld.rel_sym = sdp; @@ -800,7 +816,8 @@ shdr->sh_flags = 0; shdr->sh_addralign = 1; - return ((uintptr_t)ld_place_section(ofl, isec, M_ID_NOTE, 0)); + return ((uintptr_t)ld_place_section(ofl, isec, + ld_targ.t_id.id_note, 0)); } /* @@ -831,7 +848,8 @@ if (!(flags & FLG_OF_RELOBJ)) shdr->sh_flags |= SHF_ALLOC; - osp = ofl->ofl_osdynamic = ld_place_section(ofl, isec, M_ID_DYNAMIC, 0); + osp = ofl->ofl_osdynamic = + ld_place_section(ofl, isec, ld_targ.t_id.id_dynamic, 0); /* * Reserve entries for any needed dependencies. @@ -1103,7 +1121,7 @@ /* * Account for Architecture dependent .dynamic entries, and defaults. */ - ld_mach_make_dynamic(ofl, &cnt); + (*ld_targ.t_mr.mr_mach_make_dynamic)(ofl, &cnt); /* * DT_FLAGS, DT_FLAGS_1, DT_SUNW_STRPAD, and DT_NULL. Also, @@ -1113,6 +1131,16 @@ cnt += 4 + DYNAMIC_EXTRA_ELTS; /* + * DT_SUNW_LDMACH. Used to hold the ELF machine code of the + * linker that produced the output object. This information + * allows us to determine whether a given object was linked + * natively, or by a linker running on a different type of + * system. This information can be valuable if one suspects + * that a problem might be due to alignment or byte order issues. + */ + cnt++; + + /* * Determine the size of the section from the number of entries. */ size = cnt * (size_t)shdr->sh_entsize; @@ -1129,11 +1157,11 @@ uintptr_t ld_make_got(Ofl_desc *ofl) { - Shdr *shdr; Elf_Data *data; - Is_desc *isec; - size_t size = (size_t)ofl->ofl_gotcnt * M_GOT_ENTSIZE; - size_t rsize = (size_t)ofl->ofl_relocgotsz; + Shdr *shdr; + Is_desc *isec; + size_t size = (size_t)ofl->ofl_gotcnt * ld_targ.t_m.m_got_entsize; + size_t rsize = (size_t)ofl->ofl_relocgotsz; if (new_section(ofl, SHT_PROGBITS, MSG_ORIG(MSG_SCN_GOT), 0, &isec, &shdr, &data) == S_ERROR) @@ -1143,10 +1171,10 @@ shdr->sh_flags |= SHF_WRITE; shdr->sh_size = (Xword)size; - shdr->sh_entsize = M_GOT_ENTSIZE; - - if ((ofl->ofl_osgot = ld_place_section(ofl, isec, M_ID_GOT, 0)) == - (Os_desc *)S_ERROR) + shdr->sh_entsize = ld_targ.t_m.m_got_entsize; + + ofl->ofl_osgot = ld_place_section(ofl, isec, ld_targ.t_id.id_got, 0); + if (ofl->ofl_osgot == (Os_desc *)S_ERROR) return (S_ERROR); ofl->ofl_osgot->os_szoutrels = (Xword)rsize; @@ -1186,16 +1214,8 @@ * In the case of a dynamic executable supply a default interpreter * if a specific interpreter has not been specified. */ - if (iname == 0) { - if (ofl->ofl_dehdr->e_machine == EM_SPARCV9) - iname = ofl->ofl_interp = - MSG_ORIG(MSG_PTH_RTLD_SPARCV9); - else if (ofl->ofl_dehdr->e_machine == EM_AMD64) - iname = ofl->ofl_interp = - MSG_ORIG(MSG_PTH_RTLD_AMD64); - else - iname = ofl->ofl_interp = MSG_ORIG(MSG_PTH_RTLD); - } + if (iname == NULL) + iname = ofl->ofl_interp = ld_targ.t_m.m_def_interp; size = strlen(iname) + 1; @@ -1207,7 +1227,8 @@ shdr->sh_size = (Xword)size; data->d_align = shdr->sh_addralign = 1; - ofl->ofl_osinterp = ld_place_section(ofl, isec, M_ID_INTERP, 0); + ofl->ofl_osinterp = + ld_place_section(ofl, isec, ld_targ.t_id.id_interp, 0); return ((uintptr_t)ofl->ofl_osinterp); } @@ -1260,7 +1281,7 @@ * If we're not creating a relocatable object, save the output section * to trigger the creation of an associated program header. */ - osec = ld_place_section(ofl, isec, M_ID_CAP, 0); + osec = ld_place_section(ofl, isec, ld_targ.t_id.id_cap, 0); if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) ofl->ofl_oscap = osec; @@ -1276,32 +1297,31 @@ Shdr *shdr; Elf_Data *data; Is_desc *isec; - size_t size = (size_t)M_PLT_RESERVSZ + + size_t size = ld_targ.t_m.m_plt_reservsz + (((size_t)ofl->ofl_pltcnt + (size_t)ofl->ofl_pltpad) * - M_PLT_ENTSIZE); + ld_targ.t_m.m_plt_entsize); size_t rsize = (size_t)ofl->ofl_relocpltsz; -#if defined(__sparc) /* - * Account for the NOP at the end of the plt. + * On sparc, account for the NOP at the end of the plt. */ - size += sizeof (Word); -#endif + if (ld_targ.t_m.m_mach == LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9)) + size += sizeof (Word); if (new_section(ofl, SHT_PROGBITS, MSG_ORIG(MSG_SCN_PLT), 0, &isec, &shdr, &data) == S_ERROR) return (S_ERROR); data->d_size = size; - data->d_align = M_PLT_ALIGN; - - shdr->sh_flags = M_PLT_SHF_FLAGS; + data->d_align = ld_targ.t_m.m_plt_align; + + shdr->sh_flags = ld_targ.t_m.m_plt_shf_flags; shdr->sh_size = (Xword)size; - shdr->sh_addralign = M_PLT_ALIGN; - shdr->sh_entsize = M_PLT_ENTSIZE; - - if ((ofl->ofl_osplt = ld_place_section(ofl, isec, M_ID_PLT, 0)) == - (Os_desc *)S_ERROR) + shdr->sh_addralign = ld_targ.t_m.m_plt_align; + shdr->sh_entsize = ld_targ.t_m.m_plt_entsize; + + ofl->ofl_osplt = ld_place_section(ofl, isec, ld_targ.t_id.id_plt, 0); + if (ofl->ofl_osplt == (Os_desc *)S_ERROR) return (S_ERROR); ofl->ofl_osplt->os_szoutrels = (Xword)rsize; @@ -1336,8 +1356,8 @@ * Place the section first since it will affect the local symbol * count. */ - if ((ofl->ofl_oshash = ld_place_section(ofl, isec, M_ID_HASH, 0)) == - (Os_desc *)S_ERROR) + ofl->ofl_oshash = ld_place_section(ofl, isec, ld_targ.t_id.id_hash, 0); + if (ofl->ofl_oshash == (Os_desc *)S_ERROR) return (S_ERROR); /* @@ -1394,8 +1414,9 @@ * Place the section first since it will affect the local symbol * count. */ - if ((ofl->ofl_ossymtab = ld_place_section(ofl, isec, M_ID_SYMTAB, 0)) == - (Os_desc *)S_ERROR) + ofl->ofl_ossymtab = + ld_place_section(ofl, isec, ld_targ.t_id.id_symtab, 0); + if (ofl->ofl_ossymtab == (Os_desc *)S_ERROR) return (S_ERROR); /* @@ -1413,7 +1434,7 @@ return (S_ERROR); if ((ofl->ofl_ossymshndx = ld_place_section(ofl, xisec, - M_ID_SYMTAB_NDX, 0)) == (Os_desc *)S_ERROR) + ld_targ.t_id.id_symtab_ndx, 0)) == (Os_desc *)S_ERROR) return (S_ERROR); } /* @@ -1498,10 +1519,11 @@ */ if (allow_ldynsym && ((ofl->ofl_osldynsym = ld_place_section(ofl, lisec, - M_ID_LDYNSYM, 0)) == (Os_desc *)S_ERROR)) + ld_targ.t_id.id_ldynsym, 0)) == (Os_desc *)S_ERROR)) return (S_ERROR); - if ((ofl->ofl_osdynsym = ld_place_section(ofl, isec, M_ID_DYNSYM, 0)) - == (Os_desc *)S_ERROR) + ofl->ofl_osdynsym = + ld_place_section(ofl, isec, ld_targ.t_id.id_dynsym, 0); + if (ofl->ofl_osdynsym == (Os_desc *)S_ERROR) return (S_ERROR); /* @@ -1558,7 +1580,7 @@ return (S_ERROR); if ((ofl->ofl_osdynsymsort = ld_place_section(ofl, isec, - M_ID_DYNSORT, 0)) == (Os_desc *)S_ERROR) + ld_targ.t_id.id_dynsort, 0)) == (Os_desc *)S_ERROR) return (S_ERROR); } @@ -1570,7 +1592,7 @@ return (S_ERROR); if ((ofl->ofl_osdyntlssort = ld_place_section(ofl, isec, - M_ID_DYNSORT, 0)) == (Os_desc *)S_ERROR) + ld_targ.t_id.id_dynsort, 0)) == (Os_desc *)S_ERROR) return (S_ERROR); } @@ -1600,7 +1622,7 @@ return (S_ERROR); if ((*ret_os = ld_place_section(ofl, isec, - M_ID_DYNSYM_NDX, 0)) == (Os_desc *)S_ERROR) + ld_targ.t_id.id_dynsym_ndx, 0)) == (Os_desc *)S_ERROR) return (S_ERROR); assert(*ret_os); @@ -1652,8 +1674,9 @@ * Place the section first, as it may effect the number of section * headers to account for. */ - if ((ofl->ofl_osshstrtab = ld_place_section(ofl, isec, M_ID_NOTE, 0)) == - (Os_desc *)S_ERROR) + ofl->ofl_osshstrtab = + ld_place_section(ofl, isec, ld_targ.t_id.id_note, 0); + if (ofl->ofl_osshstrtab == (Os_desc *)S_ERROR) return (S_ERROR); size = st_getstrtab_sz(ofl->ofl_shdrsttab); @@ -1695,7 +1718,8 @@ data->d_size = size; shdr->sh_size = (Xword)size; - ofl->ofl_osstrtab = ld_place_section(ofl, isec, M_ID_STRTAB, 0); + ofl->ofl_osstrtab = + ld_place_section(ofl, isec, ld_targ.t_id.id_strtab, 0); return ((uintptr_t)ofl->ofl_osstrtab); } @@ -1774,7 +1798,8 @@ shdr->sh_size = (Xword)size; - ofl->ofl_osdynstr = ld_place_section(ofl, isec, M_ID_DYNSTR, 0); + ofl->ofl_osdynstr = + ld_place_section(ofl, isec, ld_targ.t_id.id_dynstr, 0); return ((uintptr_t)ofl->ofl_osdynstr); } @@ -1799,7 +1824,7 @@ const char *rel_prefix; /* LINTED */ - if (M_REL_SHT_TYPE == SHT_REL) { + if (ld_targ.t_m.m_rel_sht_type == SHT_REL) { /* REL */ relsize = sizeof (Rel); rel_prefix = MSG_ORIG(MSG_SCN_REL); @@ -1834,8 +1859,8 @@ /* LINTED */ ofl->ofl_relocsz += (Xword)size; - if (new_section(ofl, M_REL_SHT_TYPE, sectname, 0, &isec, &shdr, &data) - == S_ERROR) + if (new_section(ofl, ld_targ.t_m.m_rel_sht_type, sectname, 0, &isec, + &shdr, &data) == S_ERROR) return (S_ERROR); data->d_size = size; @@ -1856,8 +1881,8 @@ * Associate this relocation section to the section its going to * relocate. */ - if ((rosp = ld_place_section(ofl, isec, M_ID_REL, 0)) == - (Os_desc *)S_ERROR) + rosp = ld_place_section(ofl, isec, ld_targ.t_id.id_rel, 0); + if (rosp == (Os_desc *)S_ERROR) return (S_ERROR); if (osp) { @@ -1921,7 +1946,8 @@ data->d_size = ofl->ofl_verneedsz; shdr->sh_size = (Xword)ofl->ofl_verneedsz; - ofl->ofl_osverneed = ld_place_section(ofl, isec, M_ID_VERSION, 0); + ofl->ofl_osverneed = + ld_place_section(ofl, isec, ld_targ.t_id.id_version, 0); return ((uintptr_t)ofl->ofl_osverneed); } @@ -1966,7 +1992,8 @@ data->d_size = ofl->ofl_verdefsz; shdr->sh_size = (Xword)ofl->ofl_verdefsz; - ofl->ofl_osverdef = ld_place_section(ofl, isec, M_ID_VERSION, 0); + ofl->ofl_osverdef = + ld_place_section(ofl, isec, ld_targ.t_id.id_version, 0); return ((uintptr_t)ofl->ofl_osverdef); } @@ -2061,8 +2088,8 @@ * symbol references are added. */ ofl->ofl_issunwdata1 = isec; - if ((osp = ld_place_section(ofl, isec, M_ID_DATA, 0)) == - (Os_desc *)S_ERROR) + osp = ld_place_section(ofl, isec, ld_targ.t_id.id_data, 0); + if (osp == (Os_desc *)S_ERROR) return (S_ERROR); if (!(osp->os_flags & FLG_OS_OUTREL)) { @@ -2625,7 +2652,7 @@ return (S_ERROR); if ((ofl->ofl_osversym = make_sym_sec(ofl, MSG_ORIG(MSG_SCN_SUNWVERSYM), SHT_SUNW_versym, - M_ID_VERSION)) == (Os_desc*)S_ERROR) + ld_targ.t_id.id_version)) == (Os_desc*)S_ERROR) return (S_ERROR); } @@ -2635,7 +2662,7 @@ if (ofl->ofl_flags & FLG_OF_SYMINFO) { if ((ofl->ofl_ossyminfo = make_sym_sec(ofl, MSG_ORIG(MSG_SCN_SUNWSYMINFO), SHT_SUNW_syminfo, - M_ID_SYMINFO)) == (Os_desc *)S_ERROR) + ld_targ.t_id.id_syminfo)) == (Os_desc *)S_ERROR) return (S_ERROR); } @@ -2708,8 +2735,9 @@ return (S_ERROR); if (make_dynsym(ofl) == S_ERROR) return (S_ERROR); -#if (defined(__i386) || defined(__amd64)) && defined(_ELF64) - if (make_amd64_unwindhdr(ofl) == S_ERROR) +#if defined(_ELF64) + if ((ld_targ.t_uw.uw_make_unwindhdr != NULL) && + ((*ld_targ.t_uw.uw_make_unwindhdr)(ofl) == S_ERROR)) return (S_ERROR); #endif if (make_dynsort(ofl) == S_ERROR) @@ -2811,47 +2839,13 @@ shdr->sh_size = (Xword)size; shdr->sh_flags |= SHF_WRITE; - if (ld_place_section(ofl, isec, M_ID_DATA, 0) == (Os_desc *)S_ERROR) + if (ld_place_section(ofl, isec, ld_targ.t_id.id_data, 0) == + (Os_desc *)S_ERROR) return ((Is_desc *)S_ERROR); return (isec); } -/* - * Define a set of templates for generating "void (*)(void)" function - * definitions. - */ -#if defined(__i386) || defined(__amd64) -#if defined(__lint) -static const uchar_t ret_template[] = { 0 }; -#else /* __lint */ -#if defined(_ELF64) -#define ret_template ret64_template -#else -#define ret_template ret32_template -#endif - -static const uchar_t ret32_template[] = { -/* 0x00 */ 0xc3 /* ret */ -}; - -static const uchar_t ret64_template[] = { -/* 0x00 */ 0x55, /* pushq %rbp */ -/* 0x01 */ 0x48, 0x8b, 0xec, /* movq %rsp,%rbp */ -/* 0x04 */ 0x48, 0x8b, 0xe5, /* movq %rbp,%rsp */ -/* 0x07 */ 0x5d, /* popq %rbp */ -/* 0x08 */ 0xc3 /* ret */ -}; -#endif /* __lint */ - -#elif defined(__sparc) -static const uchar_t ret_template[] = { -/* 0x00 */ 0x81, 0xc3, 0xe0, 0x08, /* retl */ -/* 0x04 */ 0x01, 0x00, 0x00, 0x00 /* nop */ -}; -#else -#error unsupported architecture! -#endif /* * Build an additional text section - used to back FUNC symbol definitions @@ -2868,8 +2862,8 @@ * Insure the size is sufficient to contain the minimum return * instruction. */ - if (size < sizeof (ret_template)) - size = sizeof (ret_template); + if (size < ld_targ.t_nf.nf_size) + size = ld_targ.t_nf.nf_size; if (new_section(ofl, SHT_PROGBITS, MSG_ORIG(MSG_SCN_TEXT), 0, &isec, &shdr, &data) == S_ERROR) @@ -2879,12 +2873,18 @@ shdr->sh_size = (Xword)size; shdr->sh_flags |= SHF_EXECINSTR; - /* Fill the buffer with the appropriate return instruction. */ + /* + * Fill the buffer with the appropriate return instruction. + * Note that there is no need to swap bytes on a non-native, + * link, as the data being copied is given in bytes. + */ if ((data->d_buf = libld_calloc(size, 1)) == 0) return ((Is_desc *)S_ERROR); - (void) memcpy(data->d_buf, ret_template, sizeof (ret_template)); - - if (ld_place_section(ofl, isec, M_ID_TEXT, 0) == (Os_desc *)S_ERROR) + (void) memcpy(data->d_buf, ld_targ.t_nf.nf_template, + ld_targ.t_nf.nf_size); + + if (ld_place_section(ofl, isec, ld_targ.t_id.id_text, 0) == + (Os_desc *)S_ERROR) return ((Is_desc *)S_ERROR); return (isec);
--- a/usr/src/cmd/sgs/libld/common/syms.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/syms.c Tue Mar 18 09:17:00 2008 -0700 @@ -32,6 +32,9 @@ /* * Symbol table management routines */ + +#define ELF_TARGET_AMD64 + #include <stdio.h> #include <string.h> #include <debug.h> @@ -78,7 +81,6 @@ int symndx, Word shndx, const char *symsecname, const char *strsecname, Word *flags) { - const char *regname; Word name = sym->st_name; if (name) { @@ -101,12 +103,16 @@ * Determine if we're dealing with a register and if so validate it. * If it's a scratch register, a fabricated name will be returned. */ - if ((regname = ld_is_regsym(ofl, ifl, sym, strs, symndx, shndx, - symsecname, flags)) == (const char *)S_ERROR) { - return (0); + if (ld_targ.t_ms.ms_is_regsym != NULL) { + const char *regname = (*ld_targ.t_ms.ms_is_regsym)(ofl, ifl, + sym, strs, symndx, shndx, symsecname, flags); + + if (regname == (const char *)S_ERROR) { + return (0); + } + if (regname) + return (regname); } - if (regname) - return (regname); /* * If this isn't a register, but we have a global symbol with a null @@ -123,6 +129,69 @@ return (strs + name); } + +/* + * For producing symbol names strings to use in error messages. + * If the symbol has a non-null name, then the string returned by + * this function is the output from demangle(), surrounded by + * single quotes. For null names, a descriptive string giving + * the symbol section and index is generated. + * + * This function uses an internal static buffer to hold the resulting + * string. The value returned is usable by the caller until the next + * call, at which point it is overwritten. + */ +static const char * +demangle_symname(const char *name, const char *symtab_name, Word symndx) +{ +#define INIT_BUFSIZE 256 + + static char *buf; + static size_t bufsize = 0; + + size_t len; + int use_name; + + + use_name = (name != NULL) && (*name != '\0'); + + if (use_name) { + name = demangle(name); + len = strlen(name) + 2; /* Include room for quotes */ + } else { + name = MSG_ORIG(MSG_STR_EMPTY); + len = strlen(symtab_name) + 2 + CONV32_INV_BUFSIZE; + } + len++; /* Null termination */ + + /* If our buffer is too small, double it until it is big enough */ + if (len > bufsize) { + size_t new_bufsize = bufsize; + char *new_buf; + + if (new_bufsize == 0) + new_bufsize = INIT_BUFSIZE; + while (len > new_bufsize) + new_bufsize *= 2; + new_buf = libld_malloc(new_bufsize); + if (new_buf == NULL) + return (name); + buf = new_buf; + bufsize = new_bufsize; + } + + if (use_name) { + (void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_SYMNAM), name); + } else { + (void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_NULLSYMNAM), + symtab_name, EC_WORD(symndx)); + } + + return (buf); + +#undef INIT_BUFSIZE +} + /* * Shared objects can be built that define specific symbols that can not be * directly bound to. These objects have a syminfo section (and an associated @@ -356,8 +425,9 @@ if (sdflags & FLG_SY_SPECSEC) { if (nsym->st_shndx == SHN_COMMON) sdp->sd_flags |= FLG_SY_TENTSYM; -#if defined(__x86) && defined(_ELF64) - else if (nsym->st_shndx == SHN_X86_64_LCOMMON) +#if defined(_ELF64) + else if ((ld_targ.t_m.m_mach == EM_AMD64) && + (nsym->st_shndx == SHN_X86_64_LCOMMON)) sdp->sd_flags |= FLG_SY_TENTSYM; #endif } @@ -464,9 +534,10 @@ if ((etype == ET_REL) && (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL) && ((nsym->st_shndx == SHN_UNDEF) || ((sdflags & FLG_SY_SPECSEC) && -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) ((nsym->st_shndx == SHN_COMMON) || - (nsym->st_shndx == SHN_X86_64_LCOMMON))))) + ((ld_targ.t_m.m_mach == EM_AMD64) && + (nsym->st_shndx == SHN_X86_64_LCOMMON)))))) #else /* BEGIN CSTYLED */ (nsym->st_shndx == SHN_COMMON)))) @@ -1022,7 +1093,7 @@ Word undef = 0, needed = 0, verdesc = 0; Xword bssalign = 0, tlsalign = 0; Xword bsssize = 0, tlssize = 0; -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) Xword lbssalign = 0, lbsssize = 0; #endif int ret; @@ -1381,13 +1452,14 @@ } } -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) /* * Calculate the size and alignment requirement for the global * .lbss. TLS or partially initialized symbols do not need to be * considered yet. */ - if (sym->st_shndx == SHN_X86_64_LCOMMON) { + if ((ld_targ.t_m.m_mach == EM_AMD64) && + (sym->st_shndx == SHN_X86_64_LCOMMON)) { lbsssize = (Xword)S_ROUND(lbsssize, sym->st_value) + sym->st_size; if (sym->st_value > lbssalign) @@ -1529,8 +1601,9 @@ if (ld_make_bss(ofl, tlssize, tlsalign, MAKE_TLS) == S_ERROR) return (S_ERROR); } -#if defined(__x86) && defined(_ELF64) - if (lbsssize && !(oflags & FLG_OF_RELOBJ)) { +#if defined(_ELF64) + if ((ld_targ.t_m.m_mach == EM_AMD64) && + lbsssize && !(oflags & FLG_OF_RELOBJ)) { if (ld_make_bss(ofl, lbsssize, lbssalign, MAKE_LBSS) == S_ERROR) return (S_ERROR); } @@ -1844,14 +1917,19 @@ Word shndx, sdflags = FLG_SY_CLEAN; const char *name; Sym_desc *rsdp; + int shndx_bad = 0; /* - * Determine the associated section index. + * Determine and validate the associated section index. */ - if (symshndx && (sym->st_shndx == SHN_XINDEX)) + if (symshndx && (sym->st_shndx == SHN_XINDEX)) { shndx = symshndx[ndx]; - else if ((shndx = sym->st_shndx) >= SHN_LORESERVE) + } else if ((shndx = sym->st_shndx) >= SHN_LORESERVE) { sdflags |= FLG_SY_SPECSEC; + } else if (shndx > ifl->ifl_ehdr->e_shnum) { + /* We need the name before we can issue error */ + shndx_bad = 1; + } /* * Check if st_name has a valid value or not. @@ -1863,6 +1941,19 @@ } /* + * Now that we have the name, if the section index + * was bad, report it. + */ + if (shndx_bad) { + eprintf(ofl->ofl_lml, ERR_WARNING, + MSG_INTL(MSG_SYM_INVSHNDX), + demangle_symname(name, isc->is_name, ndx), + ifl->ifl_name, + conv_sym_shndx(sym->st_shndx, &inv_buf)); + continue; + } + + /* * If this local symbol table originates from a shared * object, then we're only interested in recording * register symbols. As local symbol descriptors aren't @@ -1873,15 +1964,20 @@ */ rsdp = sdp = 0; if (sdflags & FLG_SY_REGSYM) { - if ((rsdp = ld_reg_find(sym, ofl)) != 0) { + /* + * The presence of FLG_SY_REGSYM means that + * the pointers in ld_targ.t_ms are non-NULL. + */ + rsdp = (*ld_targ.t_ms.ms_reg_find)(sym, ofl); + if (rsdp != 0) { /* * The fact that another register def- * inition has been found is fatal. * Call the verification routine to get * the error message and move on. */ - (void) ld_reg_check(rsdp, sym, name, - ifl, ofl); + (void) (*ld_targ.t_ms.ms_reg_check) + (rsdp, sym, name, ifl, ofl); continue; } @@ -1936,9 +2032,13 @@ /* * If this register symbol hasn't already been * recorded, enter it now. + * + * The presence of FLG_SY_REGSYM means that + * the pointers in ld_targ.t_ms are non-NULL. */ if ((rsdp == 0) && - (ld_reg_enter(sdp, ofl) == 0)) + ((*ld_targ.t_ms.ms_reg_enter)(sdp, ofl) == + 0)) return (S_ERROR); } @@ -1969,8 +2069,8 @@ if (sym->st_shndx == SHN_UNDEF) { eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_INVSHNDX), - demangle(sdp->sd_name), - ifl->ifl_name, + demangle_symname(name, isc->is_name, + ndx), ifl->ifl_name, conv_sym_shndx(sym->st_shndx, &inv_buf)); } @@ -2022,7 +2122,8 @@ (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0))) { eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_INVSHNDX), - demangle(sdp->sd_name), ifl->ifl_name, + demangle_symname(name, isc->is_name, ndx), + ifl->ifl_name, conv_sym_shndx(sym->st_shndx, &inv_buf)); sdp->sd_isc = NULL; sdp->sd_flags |= FLG_SY_INVALID; @@ -2080,16 +2181,18 @@ for (ndx = (int)local; ndx < total; sym++, ndx++) { const char *name; Word shndx, sdflags = 0; + int shndx_bad = 0; /* - * Determine the associated section index. + * Determine and validate the associated section index. */ if (symshndx && (sym->st_shndx == SHN_XINDEX)) { shndx = symshndx[ndx]; - } else { - shndx = sym->st_shndx; - if (sym->st_shndx >= SHN_LORESERVE) - sdflags |= FLG_SY_SPECSEC; + } else if ((shndx = sym->st_shndx) >= SHN_LORESERVE) { + sdflags |= FLG_SY_SPECSEC; + } else if (shndx > ifl->ifl_ehdr->e_shnum) { + /* We need the name before we can issue error */ + shndx_bad = 1; } /* @@ -2102,6 +2205,20 @@ } /* + * Now that we have the name, if the section index + * was bad, report it. + */ + if (shndx_bad) { + eprintf(ofl->ofl_lml, ERR_WARNING, + MSG_INTL(MSG_SYM_INVSHNDX), + demangle_symname(name, isc->is_name, ndx), + ifl->ifl_name, + conv_sym_shndx(sym->st_shndx, &inv_buf)); + continue; + } + + + /* * Test for the GNU hidden bit, and ignore symbols that * have it set. */ @@ -2136,7 +2253,8 @@ bind = ELF_ST_BIND(sym->st_info); if ((bind != STB_GLOBAL) && (bind != STB_WEAK)) { eprintf(ofl->ofl_lml, ERR_WARNING, - MSG_INTL(MSG_SYM_NONGLOB), demangle(name), + MSG_INTL(MSG_SYM_NONGLOB), + demangle_symname(name, isc->is_name, ndx), ifl->ifl_name, conv_sym_info_bind(bind, 0, &inv_buf)); continue; @@ -2158,7 +2276,8 @@ * unless a relocation is required against it. */ eprintf(ofl->ofl_lml, ERR_WARNING, - MSG_INTL(MSG_SYM_INVSHNDX), demangle(name), + MSG_INTL(MSG_SYM_INVSHNDX), + demangle_symname(name, isc->is_name, ndx), ifl->ifl_name, conv_sym_shndx(sym->st_shndx, &inv_buf)); continue; @@ -2229,12 +2348,17 @@ if (sdp->sd_flags & FLG_SY_REGSYM) { Sym_desc *rsdp; - if ((rsdp = ld_reg_find(sdp->sd_sym, ofl)) == 0) { - if (ld_reg_enter(sdp, ofl) == 0) + /* + * The presence of FLG_SY_REGSYM means that + * the pointers in ld_targ.t_ms are non-NULL. + */ + rsdp = (*ld_targ.t_ms.ms_reg_find)(sdp->sd_sym, ofl); + if (rsdp == 0) { + if ((*ld_targ.t_ms.ms_reg_enter)(sdp, ofl) == 0) return (S_ERROR); } else if (rsdp != sdp) { - (void) ld_reg_check(rsdp, sdp->sd_sym, - sdp->sd_name, ifl, ofl); + (void) (*ld_targ.t_ms.ms_reg_check)(rsdp, + sdp->sd_sym, sdp->sd_name, ifl, ofl); } }
--- a/usr/src/cmd/sgs/libld/common/unwind.amd.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/unwind.amd.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,20 +20,23 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" +#define ELF_TARGET_AMD64 + #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sgs.h> #include <debug.h> +#include <i386/machdep_x86.h> #include <_libld.h> -#include <sys/elf_amd64.h> #include <dwarf.h> #include <stdlib.h> +#include "unwind.amd.h" /* * A EH_FRAME_HDR consists of the following: @@ -170,7 +173,7 @@ * 6. Data Align Factor sleb128 To be multiplied with all offset * in the Call Frame Instructions * - * 7. Ret Address Reg 1 A "virtual' register representation + * 7. Ret Address Reg 1 A "virtual" register representation * of the return address. In Dwarf V2, * this is a byte, otherwise it is * uleb128. It is a byte in gcc 3.3.x @@ -392,6 +395,7 @@ */ cieversion = data[off + ndx]; ndx += 1; + /* BEGIN CSTYLED */ if (cieversion != 1) { eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_UNW_BADCIEVERS), @@ -399,8 +403,10 @@ isp->is_name, off); return (S_ERROR); } - } else + /* END CSTYLED */ + } else { fde_cnt++; + } off += length + 4; } } @@ -461,16 +467,17 @@ uintptr_t populate_amd64_unwindhdr(Ofl_desc *ofl) { - unsigned char *hdrdata; - uint_t *binarytable; - uint_t hdroff; - Listnode *lnp; - Addr hdraddr; - Os_desc *hdrosp; - Os_desc *osp; - Os_desc *first_unwind; - uint_t fde_count; - uint_t *uint_ptr; + unsigned char *hdrdata; + uint_t *binarytable; + uint_t hdroff; + Listnode *lnp; + Addr hdraddr; + Os_desc *hdrosp; + Os_desc *osp; + Os_desc *first_unwind; + uint_t fde_count; + uint_t *uint_ptr; + int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0; /* * Are we building the unwind hdr? @@ -595,6 +602,7 @@ */ for (cieaugndx = 0; cieaugstr[cieaugndx]; cieaugndx++) { + /* BEGIN CSTYLED */ switch (cieaugstr[cieaugndx]) { case 'z': /* size */ @@ -626,6 +634,7 @@ fndx++; break; } + /* END CSTYLED */ } } else { uint_t bintabndx; @@ -645,10 +654,10 @@ initloc = dwarf_ehe_extract(&fdata[foff], &fndx, cieRflag, ofl->ofl_dehdr->e_ident, shdr->sh_addr + foff + fndx); - binarytable[bintabndx] = (uint_t)(initloc - - hdraddr); - binarytable[bintabndx + 1] = (uint_t)(fdeaddr - - hdraddr); + binarytable[bintabndx] = + (uint_t)(initloc - hdraddr); + binarytable[bintabndx + 1] = + (uint_t)(fdeaddr - hdraddr); } /* @@ -660,11 +669,21 @@ } /* - * Do a quick sort on the binary table + * Do a quick sort on the binary table. If this is a cross + * link from a system with the opposite byte order, xlate + * the resulting values into LSB order. */ framehdr_addr = hdraddr; qsort((void *)binarytable, (size_t)fde_count, - (size_t)(sizeof (uint_t) * 2), bintabcompare); + (size_t)(sizeof (uint_t) * 2), bintabcompare); + if (bswap) { + uint_t *btable = binarytable; + uint_t cnt; + + for (cnt = fde_count * 2; cnt-- > 0; btable++) + *btable = ld_bswap_Word(*btable); + } + /* * Fill in: * first_frame_ptr @@ -674,12 +693,16 @@ /* LINTED */ uint_ptr = (uint_t *)(&hdrdata[hdroff]); *uint_ptr = first_unwind->os_shdr->sh_addr - - hdrosp->os_shdr->sh_addr + hdroff; + hdrosp->os_shdr->sh_addr + hdroff; + if (bswap) + *uint_ptr = ld_bswap_Word(*uint_ptr); hdroff += 4; /* LINTED */ uint_ptr = (uint_t *)&hdrdata[hdroff]; *uint_ptr = fde_count; + if (bswap) + *uint_ptr = ld_bswap_Word(*uint_ptr); return (1); } @@ -695,12 +718,12 @@ */ for (LIST_TRAVERSE(&ofl->ofl_unwind, lnp, _osp)) if (osp == _osp) - return (1); + return (1); /* * Append output section to unwind list */ if (list_appendc(&ofl->ofl_unwind, osp) == 0) - return (S_ERROR); + return (S_ERROR); return (1); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/libld/common/unwind.amd.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * amd64 unwind functionality + */ + +#ifndef _UNWIND_DOT_AMD_DOT_H +#define _UNWIND_DOT_AMD_DOT_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +extern uintptr_t append_amd64_unwind(Os_desc *, Ofl_desc *); +extern uintptr_t make_amd64_unwindhdr(Ofl_desc *); +extern uintptr_t populate_amd64_unwindhdr(Ofl_desc *); + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNWIND_DOT_AMD_DOT_H */
--- a/usr/src/cmd/sgs/libld/common/update.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/common/update.c Tue Mar 18 09:17:00 2008 -0700 @@ -33,6 +33,9 @@ * displacement calculations on the program headers and sections headers, * and generate any new output section information. */ + +#define ELF_TARGET_AMD64 + #include <stdio.h> #include <string.h> #include <unistd.h> @@ -180,7 +183,7 @@ Word bssndx, etext_ndx, edata_ndx = 0, end_ndx, start_ndx; Word end_abs = 0, etext_abs = 0, edata_abs; Word tlsbssndx = 0, sunwbssndx = 0, sunwdata1ndx; -#if defined(__x86) && defined(_ELF64) +#if defined(_ELF64) Word lbssndx = 0; Addr lbssaddr = 0; #endif @@ -643,17 +646,13 @@ sdp = ifl->ifl_oldndx[lndx]; sym = sdp->sd_sym; -#if defined(__sparc) /* * Assign a got offset if necessary. */ - if (ld_assign_got(ofl, sdp) == S_ERROR) + if ((ld_targ.t_mr.mr_assign_got != NULL) && + (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR) return ((Addr)S_ERROR); -#elif defined(__x86) -/* nothing to do */ -#else -#error Unknown architecture! -#endif + if (DBG_ENABLED) { for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp2, gnp)) { @@ -897,11 +896,12 @@ bssndx = elf_ndxscn(osp->os_scn); } -#if (defined(__i386) || defined(__amd64)) && defined(_ELF64) +#if defined(_ELF64) /* - * Assign .lbss information for use with updating LCOMMON symbols. + * For amd64 target, assign .lbss information for use + * with updating LCOMMON symbols. */ - if (ofl->ofl_islbss) { + if ((ld_targ.t_m.m_mach == EM_AMD64) && ofl->ofl_islbss) { osp = ofl->ofl_islbss->is_osdesc; lbssaddr = osp->os_shdr->sh_addr + @@ -1063,8 +1063,9 @@ */ symptr->st_value -= ofl->ofl_tlsphdr->p_vaddr; } -#if (defined(__i386) || defined(__amd64)) && defined(_ELF64) - } else if ((sdp->sd_flags & FLG_SY_SPECSEC) && +#if defined(_ELF64) + } else if ((ld_targ.t_m.m_mach == EM_AMD64) && + (sdp->sd_flags & FLG_SY_SPECSEC) && ((sdp->sd_shndx = symptr->st_shndx) == SHN_X86_64_LCOMMON) && ((local || !(flags & FLG_OF_RELOBJ)))) { @@ -1125,14 +1126,9 @@ /* * Assign a got offset if necessary. */ -#if defined(__sparc) - if (ld_assign_got(ofl, sdp) == S_ERROR) + if ((ld_targ.t_mr.mr_assign_got != NULL) && + (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR) return ((Addr)S_ERROR); -#elif defined(__x86) -/* nothing to do */ -#else -#error Unknown architecture! -#endif if (DBG_ENABLED) { for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp2, gnp)) { @@ -1691,7 +1687,8 @@ (ELF_ST_TYPE(sym->st_info) == STT_FUNC) && !(flags & FLG_OF_BFLAG)) { if (sap->sa_PLTndx) - sym->st_value = ld_calc_plt_addr(sdp, ofl); + sym->st_value = + (*ld_targ.t_mr.mr_calc_plt_addr)(sdp, ofl); } /* @@ -1833,7 +1830,8 @@ /* * Now display GOT debugging information if required. */ - DBG_CALL(Dbg_got_display(ofl, 0, 0)); + DBG_CALL(Dbg_got_display(ofl, 0, 0, + ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize)); /* * Update the section headers information. sh_info is @@ -2223,7 +2221,7 @@ } if ((ofl->ofl_flags & FLG_OF_COMREL) && ofl->ofl_relocrelcnt) { - dyn->d_tag = M_REL_DT_COUNT; + dyn->d_tag = ld_targ.t_m.m_rel_dt_count; dyn->d_un.d_val = ofl->ofl_relocrelcnt; dyn++; } @@ -2280,7 +2278,7 @@ dyn->d_un.d_ptr = shdr->sh_size; dyn++; dyn->d_tag = DT_PLTREL; - dyn->d_un.d_ptr = M_REL_DT_TYPE; + dyn->d_un.d_ptr = ld_targ.t_m.m_rel_dt_type; dyn++; dyn->d_tag = DT_JMPREL; dyn->d_un.d_ptr = shdr->sh_addr; @@ -2292,23 +2290,24 @@ dyn->d_tag = DT_PLTPAD; if (ofl->ofl_pltcnt) { dyn->d_un.d_ptr = shdr->sh_addr + - M_PLT_RESERVSZ + - ofl->ofl_pltcnt * M_PLT_ENTSIZE; + ld_targ.t_m.m_plt_reservsz + + ofl->ofl_pltcnt * ld_targ.t_m.m_plt_entsize; } else dyn->d_un.d_ptr = shdr->sh_addr; dyn++; dyn->d_tag = DT_PLTPADSZ; - dyn->d_un.d_val = ofl->ofl_pltpad * M_PLT_ENTSIZE; + dyn->d_un.d_val = ofl->ofl_pltpad * + ld_targ.t_m.m_plt_entsize; dyn++; } if (ofl->ofl_relocsz) { - dyn->d_tag = M_REL_DT_TYPE; + dyn->d_tag = ld_targ.t_m.m_rel_dt_type; dyn->d_un.d_ptr = ofl->ofl_osrelhead->os_shdr->sh_addr; dyn++; - dyn->d_tag = M_REL_DT_SIZE; + dyn->d_tag = ld_targ.t_m.m_rel_dt_size; dyn->d_un.d_ptr = ofl->ofl_relocsz; dyn++; - dyn->d_tag = M_REL_DT_ENT; + dyn->d_tag = ld_targ.t_m.m_rel_dt_ent; if (ofl->ofl_osrelhead->os_shdr->sh_type == SHT_REL) dyn->d_un.d_ptr = sizeof (Rel); else @@ -2348,7 +2347,7 @@ if ((sdp = ofl->ofl_regsyms[ndx]) == 0) continue; - dyn->d_tag = M_DT_REGISTER; + dyn->d_tag = ld_targ.t_m.m_dt_register; dyn->d_un.d_val = sdp->sd_symndx; dyn++; } @@ -2411,7 +2410,11 @@ dyn->d_un.d_val = DYNSTR_EXTRA_PAD; dyn++; - ld_mach_update_odynamic(ofl, &dyn); + dyn->d_tag = DT_SUNW_LDMACH; + dyn->d_un.d_val = ld_sunw_ldmach(); + dyn++; + + (*ld_targ.t_mr.mr_mach_update_odynamic)(ofl, &dyn); for (cnt = 1 + DYNAMIC_EXTRA_ELTS; cnt--; dyn++) { dyn->d_tag = DT_NULL; @@ -2794,15 +2797,15 @@ * Note. it may be necessary to update the `e_flags' field in the * machine dependent section. */ - ehdr->e_ident[EI_DATA] = M_DATA; + ehdr->e_ident[EI_DATA] = ld_targ.t_m.m_data; ehdr->e_machine = ofl->ofl_dehdr->e_machine; ehdr->e_flags = ofl->ofl_dehdr->e_flags; ehdr->e_version = ofl->ofl_dehdr->e_version; - if (ehdr->e_machine != M_MACH) { - if (ehdr->e_machine != M_MACHPLUS) + if (ehdr->e_machine != ld_targ.t_m.m_mach) { + if (ehdr->e_machine != ld_targ.t_m.m_machplus) return (S_ERROR); - if ((ehdr->e_flags & M_FLAGSPLUS) == 0) + if ((ehdr->e_flags & ld_targ.t_m.m_flagsplus) == 0) return (S_ERROR); } @@ -3284,7 +3287,7 @@ phdr->p_vaddr = shdr->sh_addr; phdr->p_offset = shdr->sh_offset; phdr->p_filesz = shdr->sh_size; - phdr->p_flags = M_DATASEG_PERM; + phdr->p_flags = ld_targ.t_m.m_dataseg_perm; DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp)); ofl->ofl_phdr[phdrndx++] = *phdr; @@ -3298,8 +3301,9 @@ * information for the .eh_frame output section will have been * figured out by now. */ -#if (defined(__i386) || defined(__amd64)) && defined(_ELF64) - if (phdr->p_type == PT_SUNW_UNWIND) { +#if defined(_ELF64) + if ((ld_targ.t_m.m_mach == EM_AMD64) && + (phdr->p_type == PT_SUNW_UNWIND)) { Shdr *shdr; if (ofl->ofl_unwindhdr == 0)
--- a/usr/src/cmd/sgs/libld/i386/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/i386/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -20,67 +20,19 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # -E_TOOLOBJS = leb128.o -L_MACHOBJS32 = machrel.intel32.o machsym.intel32.o -L_MACHOBJS64 = machrel.amd64.o machsym.intel64.o unwind.amd64.o - include ../Makefile.com .KEEP_STATE: -SGSMSGCHK = ../common/libld.chk.msg -SGSMSGTARG += $(SGSMSGINTEL) - -# -# For cross-compilation, it is necessary to trigger the correct include files -# (see sys/elf.h). -# -ELFTARGET64 = -DELF_TARGET_AMD64 -ELFTARGET32 = -DELF_TARGET_386 - all: $(DYNLIB) $(LIBLINKS) install \ package: all $(ROOTFS_DYNLIB) include ../Makefile.targ - -# Associate ELF32 and ELF64 objects to the appropriate headers. - -pics/%32.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld -pics/%64.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld - -# Associate the various lint targets with the appropriate headers/files. - -$(LINTOUT32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld \ - $(ELFTARGET32) -$(LINTOUT64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld \ - $(ELFTARGET64) -D_ELF64 -$(LINTLIB32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld \ - $(ELFTARGET32) -$(LINTLIB64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld \ - $(ELFTARGET64) -D_ELF64 - -LINTSRCS32 += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c) -LINTSRCS64 += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c) - -# Compensate chkmsg with the doreloc family. - -CHKSRCS += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c) -CHKSRCS += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c) - -pics/%32.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_i386)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< - $(POST_PROCESS_O) - -pics/%64.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_amd64)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< - $(POST_PROCESS_O)
--- a/usr/src/cmd/sgs/libld/sparc/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/sparc/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -20,58 +20,19 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # -L_MACHOBJS32 = machrel.sparc32.o machsym.sparc32.o -L_MACHOBJS64 = machrel.sparc64.o machsym.sparc64.o - include ../Makefile.com .KEEP_STATE: -SGSMSGTARG += $(SGSMSGSPARC) - all: $(DYNLIB) $(LIBLINKS) install \ package: all $(ROOTFS_DYNLIB) include ../Makefile.targ - -# Associate ELF32 and ELF64 objects to the appropriate headers. - -pics/%32.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld -pics/%64.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld - -# Associate the various lint targets with the appropriate headers/files. - -$(LINTOUT32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET32) -$(LINTOUT64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET64) -D_ELF64 -$(LINTLIB32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET32) -$(LINTLIB64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET64) -D_ELF64 - -LINTSRCS32 += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) -LINTSRCS64 += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) - -# Compensate chkmsg with the doreloc family. - -CHKSRCS += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) -CHKSRCS += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) - -pics/%32.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< - $(POST_PROCESS_O) - -pics/%64.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< - $(POST_PROCESS_O)
--- a/usr/src/cmd/sgs/libld/sparcv9/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/libld/sparcv9/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -20,15 +20,12 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # -L_MACHOBJS32 = machrel.sparc32.o machsym.sparc32.o -L_MACHOBJS64 = machrel.sparc64.o machsym.sparc64.o - include ../Makefile.com .KEEP_STATE: @@ -38,8 +35,6 @@ ROOTFS_DYNLIB64 = \ $(DYNLIB:%=$(ROOTFS_LIBDIR64)/%) -SGSMSGTARG += $(SGSMSGSPARC) - ELFLIBDIR = $(ELFLIBDIR64) LDDBGLIBDIR = $(LDDBGLIBDIR64) CONVLIBDIR = $(CONVLIBDIR64) @@ -53,37 +48,3 @@ include ../Makefile.targ include ../../Makefile.sub.64 - -# Associate ELF32 and ELF64 objects to the appropriate headers. - -pics/%32.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld -pics/%64.o := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld - -# Associate the various lint targets with the appropriate headers/files. - -$(LINTOUT32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET32) -$(LINTOUT64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET64) -D_ELF64 -$(LINTLIB32) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET32) -$(LINTLIB64) := CPPFLAGS += -I$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld \ - $(ELFTARGET64) -D_ELF64 - -LINTSRCS32 += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) -LINTSRCS64 += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) - -# Compensate chkmsg with the doreloc family. - -CHKSRCS += $(G_MACHOBJS32:%32.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) -CHKSRCS += $(G_MACHOBJS64:%64.o=$(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c) - -pics/%32.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET32) $< - $(POST_PROCESS_O) - -pics/%64.o: \ - $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld/%.c - $(COMPILE.c) -o $@ $(ELFTARGET64) -D_ELF64 $< - $(POST_PROCESS_O)
--- a/usr/src/cmd/sgs/liblddbg/common/files.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/files.c Tue Mar 18 09:17:00 2008 -0700 @@ -672,7 +672,7 @@ }; void -Dbg_file_rejected(Lm_list *lml, Rej_desc *rej) +Dbg_file_rejected(Lm_list *lml, Rej_desc *rej, Half mach) { Conv_reject_desc_buf_t rej_buf; @@ -682,7 +682,7 @@ Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(reject[rej->rej_type]), rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(rej, &rej_buf)); + conv_reject_desc(rej, &rej_buf, mach)); Dbg_util_nl(lml, DBG_NL_STD); }
--- a/usr/src/cmd/sgs/liblddbg/common/got.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/got.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -46,7 +46,8 @@ } void -Dbg_got_display(Ofl_desc *ofl, Off goff, int stage) +Dbg_got_display(Ofl_desc *ofl, Off goff, int stage, + Word m_got_xnumber, size_t m_got_entsize) { Lm_list *lml = ofl->ofl_lml; Gottable *gtp = ofl->ofl_gottable; @@ -56,7 +57,7 @@ if (DBG_NOTCLASS(DBG_C_GOT)) return; - if (ofl->ofl_gotcnt == M_GOT_XNumber) + if (ofl->ofl_gotcnt == m_got_xnumber) return; Dbg_util_nl(lml, DBG_NL_STD); @@ -80,7 +81,7 @@ const char *refstr, *name; Gotndx *gnp = >p->gt_gndx; Lword gotaddval; - Off off = goff + (gotndx * M_GOT_ENTSIZE); + Off off = goff + (gotndx * m_got_entsize); char index[INDEX_STR_SIZE]; (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX), @@ -125,7 +126,8 @@ void Elf_got_entry(Lm_list *lml, Sword ndx, Addr addr, Xword value, Half mach, - Word type, void *reloc, const char *name) + uchar_t ei_target_data, uchar_t ei_host_data, Word type, void *reloc, + const char *name) { Rela *rela; Rel *rel; @@ -136,15 +138,24 @@ (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX), EC_SWORD(ndx)); + /* + * Got sections are SHT_PROGBITS, and are therefore not xlated by + * libelf. If the target system has a different byte order than + * the system displaying the data, swap the bytes so they are + * presented properly. + */ + if (ei_target_data != ei_host_data) + value = BSWAP_XWORD(value); + if (reloc) { if (type == SHT_RELA) { rela = (Rela *)reloc; - str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info), - 0, &inv_buf); + str = conv_reloc_type(mach, + ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf); } else { rel = (Rel *)reloc; - str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info), - 0, &inv_buf); + str = conv_reloc_type(mach, + ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf); } if (name)
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Tue Mar 18 09:17:00 2008 -0700 @@ -22,7 +22,7 @@ /* PROTOLIB1 */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -148,15 +148,17 @@ void Dbg64_file_preload(Lm_list *, const char *); void Dbg32_file_prot(Rt_map *, int); void Dbg64_file_prot(Rt_map *, int); -void Dbg32_file_rejected(Lm_list *, Rej_desc *); -void Dbg64_file_rejected(Lm_list *, Rej_desc *); +void Dbg32_file_rejected(Lm_list *, Rej_desc *, Elf32_Half); +void Dbg64_file_rejected(Lm_list *, Rej_desc *, Elf32_Half); void Dbg32_file_reuse(Lm_list *, const char *, const char *); void Dbg64_file_reuse(Lm_list *, const char *, const char *); void Dbg32_file_skip(Lm_list *, const char *, const char *); void Dbg64_file_skip(Lm_list *, const char *, const char *); -void Dbg32_got_display(Ofl_desc *, Elf32_Off, int); -void Dbg64_got_display(Ofl_desc *, Elf64_Off, int); +void Dbg32_got_display(Ofl_desc *, Elf32_Off, int, + Elf32_Word, size_t m_got_entsize); +void Dbg64_got_display(Ofl_desc *, Elf64_Off, int, + Elf64_Word, size_t m_got_entsize); void Dbg32_libs_audit(Lm_list *, const char *, const char *); void Dbg64_libs_audit(Lm_list *, const char *, const char *); @@ -464,9 +466,9 @@ void Elf32_ehdr(Lm_list *, Elf32_Ehdr *, Elf32_Shdr *); void Elf64_got_entry(Lm_list *, Elf64_Sword, Elf64_Addr, Elf64_Xword, - Elf64_Half, Elf64_Word, void *, const char *); + Elf64_Half, uchar_t, uchar_t, Elf64_Word, void *, const char *); void Elf32_got_entry(Lm_list *, Elf32_Sword, Elf32_Addr, Elf32_Word, - Elf32_Half, Elf32_Word, void *, const char *); + Elf32_Half, uchar_t, uchar_t, Elf32_Word, void *, const char *); void Elf64_got_title(Lm_list *); void Elf32_got_title(Lm_list *);
--- a/usr/src/cmd/sgs/liblddbg/common/relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -594,14 +594,14 @@ if (type == SHT_RELA) { Rela *rela = (Rela *)reloc; - str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info), + str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf); off = rela->r_offset; add = rela->r_addend; } else { Rel *rel = (Rel *)reloc; - str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info), + str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf); off = rel->r_offset; add = 0;
--- a/usr/src/cmd/sgs/librtld/amd64/_relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/librtld/amd64/_relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -43,7 +43,7 @@ { Rela *rel = vrel; const Rel_entry *rep; - Xword rtype = ELF_R_TYPE(rel->r_info); + Xword rtype = ELF_R_TYPE(rel->r_info, M_MACH); ulong_t *_oaddr; ulong_t *_iaddr; @@ -117,7 +117,7 @@ Rt_map *lmp) { Rela *rel = vrel; - Xword type = ELF_R_TYPE(rel->r_info); + Xword type = ELF_R_TYPE(rel->r_info, M_MACH); Xword value = reloc->r_value + rel->r_addend; if (type == R_AMD64_JUMP_SLOT) {
--- a/usr/src/cmd/sgs/librtld/common/relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/librtld/common/relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -94,7 +94,7 @@ rel = (Rel *)((uintptr_t)rel + ent)) { const char *name; /* LINTED */ - uchar_t type = (uchar_t)ELF_R_TYPE(rel->r_info); + uchar_t type = (uchar_t)ELF_R_TYPE(rel->r_info, M_MACH); uchar_t bind; ulong_t offset = rel->r_offset + addr; Rt_map *_lmp; @@ -441,7 +441,7 @@ rel = (Rel *)((uintptr_t)rel + ent)) { uchar_t *iaddr, *oaddr; /* LINTED */ - uchar_t type = (uchar_t)ELF_R_TYPE(rel->r_info); + uchar_t type = (uchar_t)ELF_R_TYPE(rel->r_info, M_MACH); Addr off, bgn, end; /*
--- a/usr/src/cmd/sgs/librtld/i386/_relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/librtld/i386/_relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -45,7 +45,7 @@ /* LINTED */ ulong_t *_iaddr = (ulong_t *)iaddr; - switch (ELF_R_TYPE(rel->r_info)) { + switch (ELF_R_TYPE(rel->r_info, M_MACH)) { case R_386_NONE: break; @@ -85,7 +85,7 @@ /* LINTED */ ulong_t *_iaddr = (ulong_t *)iaddr; - if (ELF_R_TYPE(nrel->r_info) == R_386_JMP_SLOT) { + if (ELF_R_TYPE(nrel->r_info, M_MACH) == R_386_JMP_SLOT) { if (_iaddr) *_oaddr = *_iaddr + reloc->r_value; else @@ -118,7 +118,7 @@ Rt_map *lmp) { Rel *rel = vrel; - Xword type = ELF_R_TYPE(rel->r_info); + Xword type = ELF_R_TYPE(rel->r_info, M_MACH); Word value = reloc->r_value; if (type == R_386_JMP_SLOT) {
--- a/usr/src/cmd/sgs/librtld/sparc/_relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/librtld/sparc/_relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,7 +42,7 @@ { Rela *rel = vrel; const Rel_entry *rep; - Xword rtype = ELF_R_TYPE(rel->r_info); + Xword rtype = ELF_R_TYPE(rel->r_info, M_MACH); ulong_t *_oaddr; ulong_t *_iaddr; @@ -116,7 +116,7 @@ Rt_map *lmp) { Rela *rel = vrel; - Xword type = ELF_R_TYPE(rel->r_info); + Xword type = ELF_R_TYPE(rel->r_info, M_MACH); Xword value = reloc->r_value + rel->r_addend; if (type == R_SPARC_JMP_SLOT) {
--- a/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,7 +42,7 @@ { Rela *rel = vrel; const Rel_entry *rep; - Xword rtype = ELF_R_TYPE(rel->r_info); + Xword rtype = ELF_R_TYPE(rel->r_info, M_MACH); ulong_t *_oaddr; ulong_t *_iaddr; @@ -116,7 +116,7 @@ Rt_map *lmp) { Rela *rel = vrel; - Xword type = ELF_R_TYPE(rel->r_info); + Xword type = ELF_R_TYPE(rel->r_info, M_MACH); Xword value = reloc->r_value + rel->r_addend; if (type == R_SPARC_JMP_SLOT) {
--- a/usr/src/cmd/sgs/packages/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/packages/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -151,10 +151,9 @@ $(ROOT)/usr/include/sys/auxv_SPARC.h \ $(ROOT)/usr/include/sys/auxv_386.h \ $(ROOT)/usr/include/sys/link.h \ + $(ROOT)/usr/include/sys/machelf.h \ $(ROOT)/usr/include/sys/note.h \ $(ROOT)/usr/include/sys/systeminfo.h - @ cd $(SRC)/uts/$(M32)/sys; pwd; $(MAKE) \ - $(ROOT)/usr/include/sys/machelf.h @ cd ../tools/$(MACH); pwd; $(MAKE) sgsmsg piglatin @ cd ..; pwd; $(MAKE) _msg_sgsmsg @ cd ..; pwd; $(MAKE) native-add
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Tue Mar 18 09:17:00 2008 -0700 @@ -1321,3 +1321,5 @@ 6668050 First trip through PLT does not preserve args in xmm registers 6672394 ldd(1) unused dependency processing is tricked by relocations errors 6672544 elf_rtbndr must support non-ABI aligned stacks on amd64 +6671255 link-editor should support cross linking + PSARC 2008/179 cross link-editor
--- a/usr/src/cmd/sgs/packages/inc.flg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/packages/inc.flg Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -79,6 +79,7 @@ echo_file usr/src/uts/common/sys/Makefile echo_file usr/src/uts/Makefile.uts echo_file usr/src/uts/common/krtld/reloc.h +echo_file usr/src/uts/common/krtld/reloc_defs.h echo_file usr/src/uts/common/sys/Makefile.syshdrs echo_file usr/src/uts/common/sys/auxv.h echo_file usr/src/uts/common/sys/auxv_386.h @@ -90,18 +91,14 @@ echo_file usr/src/uts/common/sys/elf_notes.h echo_file usr/src/uts/common/sys/elftypes.h echo_file usr/src/uts/common/sys/link.h +echo_file usr/src/uts/common/sys/machelf.h echo_file usr/src/uts/common/sys/note.h echo_file usr/src/uts/common/sys/systeminfo.h -echo_file usr/src/uts/sparc/sys/machelf.h echo_file usr/src/uts/sparc/sys/Makefile echo_file usr/src/uts/sparc/krtld/doreloc.c -echo_file usr/src/uts/sparc/krtld/relmach.h -echo_file usr/src/uts/intel/sys/machelf.h echo_file usr/src/uts/intel/sys/Makefile echo_file usr/src/uts/intel/ia32/krtld/doreloc.c -echo_file usr/src/uts/intel/ia32/krtld/relmach.h echo_file usr/src/uts/intel/amd64/krtld/doreloc.c -echo_file usr/src/uts/intel/amd64/krtld/relmach.h echo_file usr/src/cmd/sgs/Makefile echo_file usr/src/cmd/sgs/Makefile.com echo_file usr/src/cmd/sgs/Makefile.sub
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Tue Mar 18 09:17:00 2008 -0700 @@ -408,7 +408,7 @@ if (relbgn >= relend) break; - rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); roffset = ((Rela *)relbgn)->r_offset; } while (rtype == R_AMD64_RELATIVE); @@ -579,7 +579,7 @@ while (relbgn < relend) { uint_t sb_flags = 0; - rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); /* * If this is a RELATIVE relocation in a shared object (the @@ -615,7 +615,7 @@ if (relbgn >= relend) break; - rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); } roffset = ((Rela *)relbgn)->r_offset;
--- a/usr/src/cmd/sgs/rtld/common/analyze.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/common/analyze.c Tue Mar 18 09:17:00 2008 -0700 @@ -897,7 +897,7 @@ /* LINTED */ (void) snprintf(_reject, PATH_MAX, MSG_INTL(ldd_reject[rej->rej_type]), - conv_reject_desc(rej, &rej_buf)); + conv_reject_desc(rej, &rej_buf, M_MACH)); if (rej->rej_name) path = rej->rej_name; reject = (char *)_reject; @@ -1162,7 +1162,7 @@ eprintf(lml, ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]), rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), - conv_reject_desc(rej, &rej_buf)); + conv_reject_desc(rej, &rej_buf, M_MACH)); return; } @@ -1364,7 +1364,7 @@ } rej->rej_name = nname; rej->rej_flag = (fdesc->fd_flags & FLG_FD_ALTER); - DBG_CALL(Dbg_file_rejected(lml, rej)); + DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH)); } return (0); } @@ -2232,7 +2232,7 @@ _rej.rej_name = name; _rej.rej_type = SGS_REJ_STR; _rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN); - DBG_CALL(Dbg_file_rejected(lml, &_rej)); + DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); rejection_inherit(rej, &_rej); remove_so(lml, nlmp); return (0); @@ -2266,7 +2266,7 @@ _rej.rej_name = name; _rej.rej_type = SGS_REJ_STR; _rej.rej_str = strerror(ENOENT); - DBG_CALL(Dbg_file_rejected(lml, &_rej)); + DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); rejection_inherit(rej, &_rej); return (0); }
--- a/usr/src/cmd/sgs/rtld/common/cap.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/common/cap.c Tue Mar 18 09:17:00 2008 -0700 @@ -166,7 +166,7 @@ _rej.rej_type = SGS_REJ_STR; _rej.rej_name = name; _rej.rej_str = strerror(errno); - DBG_CALL(Dbg_file_rejected(lml, &_rej)); + DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); rejection_inherit(rej, &_rej); return (0); }
--- a/usr/src/cmd/sgs/rtld/common/object.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/common/object.c Tue Mar 18 09:17:00 2008 -0700 @@ -79,8 +79,15 @@ return (0); /* - * Obtain a generic set of entrance criteria (this is the first call to - * libld.so, which will effectively lazyload it). + * Configure libld.so to process objects of the desired target + * type (this is the first call to libld.so, which will effectively + * lazyload it). + */ + if (ld_init_target(lml, M_MACH) != 0) + return (0); + + /* + * Obtain a generic set of entrance criteria */ if (ld_ent_setup(ofl, syspagsz) == S_ERROR) return (0);
--- a/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg Tue Mar 18 09:17:00 2008 -0700 @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START @@ -37,8 +37,6 @@ value 0x%llx loses %d bits at offset 0x%llx" @ MSG_REL_NOFIT "relocation error: %s: file %s: symbol %s: \ value 0x%llx does not fit" -@ MSG_REL_NOSWAP "relocation error: %s: file %s: symbol %s: \ - linker does not support byte swapping relocated data" @ MSG_REL_BADREG "relocation error: file %s: REGISTER relocation \ against bad register offset: 0x%llx"
--- a/usr/src/cmd/sgs/rtld/common/setup.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/common/setup.c Tue Mar 18 09:17:00 2008 -0700 @@ -418,7 +418,7 @@ eprintf(&lml_main, ERR_FATAL, MSG_INTL(err_reject[rej.rej_type]), argvname, - conv_reject_desc(&rej, &rej_buf)); + conv_reject_desc(&rej, &rej_buf, M_MACH)); return (0); }
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c Tue Mar 18 09:17:00 2008 -0700 @@ -385,7 +385,7 @@ if (relbgn >= relend) break; - rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info, M_MACH); roffset = ((Rel *)relbgn)->r_offset; } while (rtype == R_386_RELATIVE); @@ -555,7 +555,7 @@ while (relbgn < relend) { uint_t sb_flags = 0; - rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info, M_MACH); /* * If this is a RELATIVE relocation in a shared object (the @@ -591,7 +591,7 @@ } if (relbgn >= relend) break; - rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info, M_MACH); } roffset = ((Rel *)relbgn)->r_offset;
--- a/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -201,7 +201,7 @@ if (relbgn >= relend) break; - rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); roffset = ((Rela *)relbgn)->r_offset; } while (rtype == R_SPARC_RELATIVE);
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Tue Mar 18 09:17:00 2008 -0700 @@ -642,7 +642,7 @@ Addr vaddr; uint_t sb_flags = 0; - rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); /* * If this is a RELATIVE relocation in a shared object (the @@ -677,7 +677,7 @@ } if (relbgn >= relend) break; - rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); } roffset = ((Rela *)relbgn)->r_offset;
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Tue Mar 18 09:17:00 2008 -0700 @@ -885,7 +885,7 @@ Addr vaddr; uint_t sb_flags = 0; - rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); /* * If this is a RELATIVE relocation in a shared object @@ -921,7 +921,8 @@ } if (relbgn >= relend) break; - rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info); + rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, + M_MACH); } roffset = ((Rela *)relbgn)->r_offset;
--- a/usr/src/uts/common/krtld/kobj.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/common/krtld/kobj.c Tue Mar 18 09:17:00 2008 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2261,7 +2261,7 @@ Shdr *shp; reloc_dest_t dest = NULL; uintptr_t bits_ptr; - uintptr_t text = 0, data, sdata = 0, textptr; + uintptr_t text = 0, data, textptr; uint_t shn; int err = -1; @@ -2380,8 +2380,6 @@ if ((shp->sh_flags & SHF_WRITE) == 0) bits_ptr = text; - else if (shp->sh_flags & SHF_NEUT_SHORT) - bits_ptr = sdata; else bits_ptr = data; @@ -2410,8 +2408,6 @@ bits_ptr += shp->sh_size; if ((shp->sh_flags & SHF_WRITE) == 0) text = bits_ptr; - else if (shp->sh_flags & SHF_NEUT_SHORT) - sdata = bits_ptr; else data = bits_ptr; }
--- a/usr/src/uts/common/krtld/reloc.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/common/krtld/reloc.h Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,17 +30,15 @@ #pragma ident "%Z%%M% %I% %E% SMI" #if defined(_KERNEL) -#include <sys/machelf.h> #include <sys/bootconf.h> #include <sys/kobj.h> #include <sys/kobj_impl.h> #else -#include <machdep.h> #include <rtld.h> #include <conv.h> #endif /* _KERNEL */ -#include <relmach.h> +#include "reloc_defs.h" #ifdef __cplusplus extern "C" { @@ -48,107 +46,81 @@ /* * Global include file for relocation common code. - * - * Flags for reloc_entry->re_flags */ -#define FLG_RE_NOTREL 0x00000000 -#define FLG_RE_GOTADD 0x00000001 /* create a GOT entry */ -#define FLG_RE_GOTREL 0x00000002 /* GOT based */ -#define FLG_RE_GOTPC 0x00000004 /* GOT - P */ -#define FLG_RE_GOTOPINS 0x00000008 /* GOTOP instruction */ -#define FLG_RE_PCREL 0x00000010 -#define FLG_RE_PLTREL 0x00000020 -#define FLG_RE_VERIFY 0x00000040 /* verify value fits */ -#define FLG_RE_UNALIGN 0x00000080 /* offset is not aligned */ -#define FLG_RE_WDISP16 0x00000100 /* funky sparc DISP16 rel */ -#define FLG_RE_SIGN 0x00000200 /* value is signed */ -#define FLG_RE_ADDRELATIVE 0x00000400 /* RELATIVE relocation */ - /* required for non- */ - /* fixed objects */ -#define FLG_RE_EXTOFFSET 0x00000800 /* extra offset required */ -#define FLG_RE_REGISTER 0x00001000 /* relocation initializes */ - /* a REGISTER by OLO10 */ -#define FLG_RE_SIZE 0x00002000 /* symbol size required */ - -#define FLG_RE_NOTSUP 0x00010000 /* relocation not supported */ - -#define FLG_RE_SEGREL 0x00040000 /* segment relative */ -#define FLG_RE_SECREL 0x00080000 /* section relative */ - -#define FLG_RE_TLSGD 0x00200000 /* TLS GD relocation */ -#define FLG_RE_TLSLD 0x00400000 /* TLS LD relocation */ -#define FLG_RE_TLSIE 0x00800000 /* TLS IE relocation */ -#define FLG_RE_TLSLE 0x01000000 /* TLS LE relocation */ -#define FLG_RE_LOCLBND 0x02000000 /* relocation must bind */ - /* locally */ /* * In user land, redefine the relocation table and relocation engine to be - * class specific if necessary. This allows both engines to reside in the - * intel/amd version of libld. + * class/machine specific if necessary. This allows multiple engines to + * reside within a single instance of libld. */ #if !defined(_KERNEL) + +#if defined(DO_RELOC_LIBLD) +#undef DO_RELOC_LIBLD +#endif + +#if defined(DO_RELOC_LIBLD_X86) + +#define DO_RELOC_LIBLD #if defined(_ELF64) -#define do_reloc_ld do64_reloc_ld +#define do_reloc_ld do64_reloc_ld_x86 +#define reloc_table reloc64_table_x86 +#else +#define do_reloc_ld do32_reloc_ld_x86 +#define reloc_table reloc32_table_x86 +#endif + +#elif defined(DO_RELOC_LIBLD_SPARC) + +#define DO_RELOC_LIBLD +#if defined(_ELF64) +#define do_reloc_ld do64_reloc_ld_sparc +#define reloc_table reloc64_table_sparc +#else +#define do_reloc_ld do32_reloc_ld_sparc +#define reloc_table reloc32_table_sparc +#endif + +#else /* rtld */ + +#if defined(_ELF64) #define do_reloc_rtld do64_reloc_rtld #define reloc_table reloc64_table #else -#define do_reloc_ld do32_reloc_ld #define do_reloc_rtld do32_reloc_rtld #define reloc_table reloc32_table #endif + #endif +#endif /* !_KERNEL */ + /* * Relocation table and macros for testing relocation table flags. */ -extern const Rel_entry reloc_table[]; +extern const Rel_entry reloc_table[]; -#define IS_PLT(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_PLTREL) != 0) -#define IS_GOT_RELATIVE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_GOTADD) != 0) -#define IS_GOT_PC(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_GOTPC) != 0) -#define IS_GOTPCREL(X) ((reloc_table[(X)].re_flags & \ - (FLG_RE_GOTPC | FLG_RE_GOTADD)) == \ - (FLG_RE_GOTPC | FLG_RE_GOTADD)) -#define IS_GOT_BASED(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_GOTREL) != 0) -#define IS_GOT_OPINS(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_GOTOPINS) != 0) -#define IS_GOT_REQUIRED(X) ((reloc_table[(X)].re_flags & \ - (FLG_RE_GOTADD | FLG_RE_GOTREL | \ - FLG_RE_GOTPC | FLG_RE_GOTOPINS)) != 0) -#define IS_PC_RELATIVE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_PCREL) != 0) -#define IS_ADD_RELATIVE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_ADDRELATIVE) != 0) -#define IS_REGISTER(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_REGISTER) != 0) -#define IS_NOTSUP(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_NOTSUP) != 0) -#define IS_SEG_RELATIVE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_SEGREL) != 0) -#define IS_EXTOFFSET(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_EXTOFFSET) != 0) -#define IS_SEC_RELATIVE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_SECREL) != 0) -#define IS_TLS_INS(X) ((reloc_table[(X)].re_flags & \ - (FLG_RE_TLSGD | FLG_RE_TLSLD | \ - FLG_RE_TLSIE | FLG_RE_TLSLE)) != 0) -#define IS_TLS_GD(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_TLSGD) != 0) -#define IS_TLS_LD(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_TLSLD) != 0) -#define IS_TLS_IE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_TLSIE) != 0) -#define IS_TLS_LE(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_TLSLE) != 0) -#define IS_LOCALBND(X) ((reloc_table[(X)].re_flags & \ - FLG_RE_LOCLBND) != 0) -#define IS_SIZE(X) ((reloc_table[(X)].re_flags &\ - FLG_RE_SIZE) != 0) +#define IS_PLT(X) RELTAB_IS_PLT(X, reloc_table) +#define IS_GOT_RELATIVE(X) RELTAB_IS_GOT_RELATIVE(X, reloc_table) +#define IS_GOT_PC(X) RELTAB_IS_GOT_PC(X, reloc_table) +#define IS_GOTPCREL(X) RELTAB_IS_GOTPCREL(X, reloc_table) +#define IS_GOT_BASED(X) RELTAB_IS_GOT_BASED(X, reloc_table) +#define IS_GOT_OPINS(X) RELTAB_IS_GOT_OPINS(X, reloc_table) +#define IS_GOT_REQUIRED(X) RELTAB_IS_GOT_REQUIRED(X, reloc_table) +#define IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, reloc_table) +#define IS_ADD_RELATIVE(X) RELTAB_IS_ADD_RELATIVE(X, reloc_table) +#define IS_REGISTER(X) RELTAB_IS_REGISTER(X, reloc_table) +#define IS_NOTSUP(X) RELTAB_IS_NOTSUP(X, reloc_table) +#define IS_SEG_RELATIVE(X) RELTAB_IS_SEG_RELATIVE(X, reloc_table) +#define IS_EXTOFFSET(X) RELTAB_IS_EXTOFFSET(X, reloc_table) +#define IS_SEC_RELATIVE(X) RELTAB_IS_SEC_RELATIVE(X, reloc_table) +#define IS_TLS_INS(X) RELTAB_IS_TLS_INS(X, reloc_table) +#define IS_TLS_GD(X) RELTAB_IS_TLS_GD(X, reloc_table) +#define IS_TLS_LD(X) RELTAB_IS_TLS_LD(X, reloc_table) +#define IS_TLS_IE(X) RELTAB_IS_TLS_IE(X, reloc_table) +#define IS_TLS_LE(X) RELTAB_IS_TLS_LE(X, reloc_table) +#define IS_LOCALBND(X) RELTAB_IS_LOCALBND(X, reloc_table) +#define IS_SIZE(X) RELTAB_IS_SIZE(X, reloc_table) /* * Relocation engine. @@ -161,6 +133,11 @@ * the relocation engine that the data it is relocating * has the opposite byte order of the system running the * linker. + * - The linker is a cross-linker, meaning that it can examine + * relocation records for target hosts other than that of + * the currently running system. This means that multiple + * versions of the relocation code must be able to reside + * in a single program, without namespace clashes. * * To ensure that there is never any confusion about which version is * being linked to, we give each variant a different name, even though @@ -170,7 +147,7 @@ * The kernel version is provided if the _KERNEL macro is defined. * * do_reloc_ld() - * The ld version is provided if the DO_RELOC_LIBLD macro is defined. + * The ld version is provided if the DO_RELOC_LIBLD_ macro is defined. * * do_reloc_rtld() * The rtld version is provided if neither _KERNEL or DO_RELOC_LIBLD @@ -240,6 +217,7 @@ #error platform not defined! #endif + /* * Note: dlerror() only keeps track of a single error string, and therefore * must have errors reported through a single eprintf() call. The kernel's @@ -320,11 +298,6 @@ ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), \ EC_XWORD((uvalue)))) -#define REL_ERR_NOSWAP(lml, file, sym, rtype) \ - (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSWAP), \ - conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ - ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)))) - #endif /* _KERNEL */ #ifdef __cplusplus
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/krtld/reloc_defs.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,162 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _RELOC_DEFS_DOT_H +#define _RELOC_DEFS_DOT_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/machelf.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Definitions used by the relocation common code. + */ + + +/* + * Structure used to build the reloc_table[] + */ +typedef struct { + Xword re_mask; /* mask to apply to reloc (sparc only) */ + Word re_flags; /* relocation attributes */ + uchar_t re_fsize; /* field size (in bytes) */ + uchar_t re_bshift; /* number of bits to shift (sparc only) */ + uchar_t re_sigbits; /* number of significant bits */ +} Rel_entry; + +/* + * Flags for reloc_entry->re_flags + */ +#define FLG_RE_NOTREL 0x00000000 +#define FLG_RE_GOTADD 0x00000001 /* create a GOT entry */ +#define FLG_RE_GOTREL 0x00000002 /* GOT based */ +#define FLG_RE_GOTPC 0x00000004 /* GOT - P */ +#define FLG_RE_GOTOPINS 0x00000008 /* GOTOP instruction */ +#define FLG_RE_PCREL 0x00000010 +#define FLG_RE_PLTREL 0x00000020 +#define FLG_RE_VERIFY 0x00000040 /* verify value fits */ +#define FLG_RE_UNALIGN 0x00000080 /* offset is not aligned */ +#define FLG_RE_WDISP16 0x00000100 /* funky sparc DISP16 rel */ +#define FLG_RE_SIGN 0x00000200 /* value is signed */ +#define FLG_RE_ADDRELATIVE 0x00000400 /* RELATIVE relocation */ + /* required for non- */ + /* fixed objects */ +#define FLG_RE_EXTOFFSET 0x00000800 /* extra offset required */ +#define FLG_RE_REGISTER 0x00001000 /* relocation initializes */ + /* a REGISTER by OLO10 */ +#define FLG_RE_SIZE 0x00002000 /* symbol size required */ + +#define FLG_RE_NOTSUP 0x00010000 /* relocation not supported */ + +#define FLG_RE_SEGREL 0x00040000 /* segment relative */ +#define FLG_RE_SECREL 0x00080000 /* section relative */ + +#define FLG_RE_TLSGD 0x00200000 /* TLS GD relocation */ +#define FLG_RE_TLSLD 0x00400000 /* TLS LD relocation */ +#define FLG_RE_TLSIE 0x00800000 /* TLS IE relocation */ +#define FLG_RE_TLSLE 0x01000000 /* TLS LE relocation */ +#define FLG_RE_LOCLBND 0x02000000 /* relocation must bind */ + /* locally */ + +/* + * Relocation table and macros for testing relocation table flags. + */ + +#define RELTAB_IS_PLT(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_PLTREL) != 0) + +#define RELTAB_IS_GOT_RELATIVE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_GOTADD) != 0) + +#define RELTAB_IS_GOT_PC(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_GOTPC) != 0) + +#define RELTAB_IS_GOTPCREL(X, _reltab) \ + ((_reltab[(X)].re_flags & (FLG_RE_GOTPC | FLG_RE_GOTADD)) == \ + (FLG_RE_GOTPC | FLG_RE_GOTADD)) + +#define RELTAB_IS_GOT_BASED(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_GOTREL) != 0) + +#define RELTAB_IS_GOT_OPINS(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_GOTOPINS) != 0) + +#define RELTAB_IS_GOT_REQUIRED(X, _reltab) \ + ((_reltab[(X)].re_flags & (FLG_RE_GOTADD | FLG_RE_GOTREL | \ + FLG_RE_GOTPC | FLG_RE_GOTOPINS)) != 0) + +#define RELTAB_IS_PC_RELATIVE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_PCREL) != 0) + +#define RELTAB_IS_ADD_RELATIVE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_ADDRELATIVE) != 0) + +#define RELTAB_IS_REGISTER(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_REGISTER) != 0) + +#define RELTAB_IS_NOTSUP(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_NOTSUP) != 0) + +#define RELTAB_IS_SEG_RELATIVE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_SEGREL) != 0) + +#define RELTAB_IS_EXTOFFSET(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_EXTOFFSET) != 0) + +#define RELTAB_IS_SEC_RELATIVE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_SECREL) != 0) + +#define RELTAB_IS_TLS_INS(X, _reltab) \ + ((_reltab[(X)].re_flags & \ + (FLG_RE_TLSGD | FLG_RE_TLSLD | FLG_RE_TLSIE | FLG_RE_TLSLE)) != 0) + +#define RELTAB_IS_TLS_GD(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_TLSGD) != 0) + +#define RELTAB_IS_TLS_LD(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_TLSLD) != 0) + +#define RELTAB_IS_TLS_IE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_TLSIE) != 0) + +#define RELTAB_IS_TLS_LE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_TLSLE) != 0) + +#define RELTAB_IS_LOCALBND(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_LOCLBND) != 0) + +#define RELTAB_IS_SIZE(X, _reltab) \ + ((_reltab[(X)].re_flags & FLG_RE_SIZE) != 0) + +#ifdef __cplusplus +} +#endif + +#endif /* _RELOC_DEFS_DOT_H */
--- a/usr/src/uts/common/sys/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/common/sys/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -347,6 +347,7 @@ lwp_upimutex_impl.h \ mac.h \ mac_impl.h \ + machelf.h \ map.h \ md4.h \ md5.h \
--- a/usr/src/uts/common/sys/link.h Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/common/sys/link.h Tue Mar 18 09:17:00 2008 -0700 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -155,6 +155,8 @@ #define DT_SUNW_STRPAD 0x60000019 /* # of unused bytes at the */ /* end of dynstr */ +#define DT_SUNW_LDMACH 0x6000001b /* EM_ machine code of linker */ + /* that produced object */ /* * DT_* encoding rules do not apply between DT_HIOS and DT_LOPROC
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/sys/machelf.h Tue Mar 18 09:17:00 2008 -0700 @@ -0,0 +1,182 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_MACHELF_H +#define _SYS_MACHELF_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__amd64) +#include <sys/elf_amd64.h> +#elif defined(__i386) +#include <sys/elf_386.h> +#elif defined(__sparc) +#include <sys/elf_SPARC.h> +#endif +#ifndef _ASM +#include <sys/types.h> +#include <sys/elf.h> +#include <sys/link.h> /* for Elf*_Dyn */ +#endif /* _ASM */ + +/* + * Make machine class dependent data types transparent to the common code + */ +#if defined(_ELF64) && !defined(_ELF32_COMPAT) + +#ifndef _ASM +typedef Elf64_Xword Xword; +typedef Elf64_Lword Lword; +typedef Elf64_Sxword Sxword; +typedef Elf64_Word Word; +typedef Elf64_Sword Sword; +typedef Elf64_Half Half; +typedef Elf64_Addr Addr; +typedef Elf64_Off Off; +typedef uchar_t Byte; +#endif /* _ASM */ + +#if defined(_KERNEL) +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE_DATA ELF64_R_TYPE_DATA +#define ELF_R_INFO ELF64_R_INFO +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE +#define ELF_M_SYM ELF64_M_SYM +#define ELF_M_SIZE ELF64_M_SIZE +#endif + +#ifndef _ASM +typedef Elf64_Ehdr Ehdr; +typedef Elf64_Shdr Shdr; +typedef Elf64_Sym Sym; +typedef Elf64_Syminfo Syminfo; +typedef Elf64_Rela Rela; +typedef Elf64_Rel Rel; +typedef Elf64_Nhdr Nhdr; +typedef Elf64_Phdr Phdr; +typedef Elf64_Dyn Dyn; +typedef Elf64_Boot Boot; +typedef Elf64_Verdef Verdef; +typedef Elf64_Verdaux Verdaux; +typedef Elf64_Verneed Verneed; +typedef Elf64_Vernaux Vernaux; +typedef Elf64_Versym Versym; +typedef Elf64_Move Move; +typedef Elf64_Cap Cap; +#endif /* _ASM */ + +#else /* _ILP32 */ + +#ifndef _ASM +typedef Elf32_Word Xword; /* Xword/Sxword are 32-bits in Elf32 */ +typedef Elf32_Lword Lword; +typedef Elf32_Sword Sxword; +typedef Elf32_Word Word; +typedef Elf32_Sword Sword; +typedef Elf32_Half Half; +typedef Elf32_Addr Addr; +typedef Elf32_Off Off; +typedef uchar_t Byte; +#endif /* _ASM */ + +#if defined(_KERNEL) +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_TYPE_DATA(x) (0) +#define ELF_R_INFO ELF32_R_INFO +#define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE +#define ELF_M_SYM ELF32_M_SYM +#define ELF_M_SIZE ELF32_M_SIZE +#endif + +#ifndef _ASM +typedef Elf32_Ehdr Ehdr; +typedef Elf32_Shdr Shdr; +typedef Elf32_Sym Sym; +typedef Elf32_Syminfo Syminfo; +typedef Elf32_Rela Rela; +typedef Elf32_Rel Rel; +typedef Elf32_Nhdr Nhdr; +typedef Elf32_Phdr Phdr; +typedef Elf32_Dyn Dyn; +typedef Elf32_Boot Boot; +typedef Elf32_Verdef Verdef; +typedef Elf32_Verdaux Verdaux; +typedef Elf32_Verneed Verneed; +typedef Elf32_Vernaux Vernaux; +typedef Elf32_Versym Versym; +typedef Elf32_Move Move; +typedef Elf32_Cap Cap; +#endif /* _ASM */ + +#endif /* _ILP32 */ + +/* + * Elf `printf' type-cast macros. These force arguments to be a fixed size + * so that Elf32 and Elf64 can share common format strings. + */ +#ifndef __lint +#define EC_ADDR(a) ((Elf64_Addr)(a)) /* "ull" */ +#define EC_OFF(a) ((Elf64_Off)(a)) /* "ull" */ +#define EC_HALF(a) ((Elf64_Half)(a)) /* "d" */ +#define EC_WORD(a) ((Elf64_Word)(a)) /* "u" */ +#define EC_SWORD(a) ((Elf64_Sword)(a)) /* "d" */ +#define EC_XWORD(a) ((Elf64_Xword)(a)) /* "ull" */ +#define EC_SXWORD(a) ((Elf64_Sxword)(a)) /* "ll" */ +#define EC_LWORD(a) ((Elf64_Lword)(a)) /* "ull" */ + +/* + * A native pointer is special. Although it can be convenient to display + * these from a common format (ull), compilers may flag the cast of a pointer + * to an integer as illegal. Casting these pointers to the native pointer + * size, suppresses any compiler errors. + */ +#define EC_NATPTR(a) ((Elf64_Xword)(uintptr_t)(a)) /* "ull" */ +#else +#define EC_ADDR(a) ((u_longlong_t)(a)) +#define EC_OFF(a) ((u_longlong_t)(a)) +#define EC_HALF(a) ((ushort_t)(a)) +#define EC_WORD(a) ((uint_t)(a)) +#define EC_SWORD(a) ((int)(a)) +#define EC_XWORD(a) ((u_longlong_t)(a)) +#define EC_SXWORD(a) ((longlong_t)(a)) +#define EC_LWORD(a) ((u_longlong_t)(a)) + +#define EC_NATPTR(a) ((u_longlong_t)(a)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_MACHELF_H */
--- a/usr/src/uts/intel/amd64/krtld/doreloc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/intel/amd64/krtld/doreloc.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +30,11 @@ #include <sys/types.h> #include "reloc.h" #else +#define ELF_TARGET_AMD64 +#if defined(DO_RELOC_LIBLD) +#undef DO_RELOC_LIBLD +#define DO_RELOC_LIBLD_X86 +#endif #include <stdio.h> #include "sgs.h" #include "machdep.h" @@ -40,46 +45,64 @@ #endif /* + * We need to build this code differently when it is used for + * cross linking: + * - Data alignment requirements can differ from those + * of the running system, so we can't access data + * in units larger than a byte + * - We have to include code to do byte swapping when the + * target and linker host use different byte ordering, + * but such code is a waste when running natively. + */ +#if !defined(DO_RELOC_LIBLD) || defined(__i386) || defined(__amd64) +#define DORELOC_NATIVE +#endif + +/* * This table represents the current relocations that do_reloc() is able to * process. The relocations below that are marked SPECIAL are relocations that * take special processing and shouldn't actually ever be passed to do_reloc(). */ const Rel_entry reloc_table[R_AMD64_NUM] = { -/* R_AMD64_NONE */ {FLG_RE_NOTREL, 0}, -/* R_AMD64_64 */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_PC32 */ {FLG_RE_PCREL, 4}, -/* R_AMD64_GOT32 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_PLT32 */ {FLG_RE_PCREL | FLG_RE_PLTREL | - FLG_RE_VERIFY | FLG_RE_SIGN, 4}, -/* R_AMD64_COPY */ {FLG_RE_NOTSUP, 0}, /* SPECIAL */ -/* R_AMD64_GLOB_DAT */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_JUMP_SLOT */ {FLG_RE_NOTSUP, 0}, /* SPECIAL */ -/* R_AMD64_RELATIVE */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_GOTPCREL */ {FLG_RE_GOTPC | FLG_RE_GOTADD, 4}, -/* R_AMD64_32 */ {FLG_RE_NOTREL, 4}, -/* R_AMD64_32S */ {FLG_RE_NOTREL, 4}, -/* R_AMD64_16 */ {FLG_RE_NOTREL, 2}, -/* R_AMD64_PC16 */ {FLG_RE_PCREL, 2}, -/* R_AMD64_8 */ {FLG_RE_NOTREL, 1}, -/* R_AMD64_PC8 */ {FLG_RE_PCREL, 1}, -/* R_AMD64_DTPMOD64 */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_DTPOFF64 */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_TPOFF64 */ {FLG_RE_NOTREL, 8}, -/* R_AMD64_TLSGD */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSGD, 4}, -/* R_AMD64_TLSLD */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSLD, 4}, -/* R_AMD64_DTPOFF32 */ {FLG_RE_TLSLD, 4}, -/* R_AMD64_GOTTPOFF */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSIE, 4}, -/* R_AMD64_TPOFF32 */ {FLG_RE_TLSLE, 4}, -/* R_AMD64_PC64 */ {FLG_RE_PCREL, 8}, -/* R_AMD64_GOTOFF64 */ {FLG_RE_GOTREL, 8}, -/* R_AMD64_GOTPC32 */ {FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, 4}, -/* R_AMD64_GOT64 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_GOTPCREL64 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_GOTPC6 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_GOTPLT64 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_PLTOFF64 */ {FLG_RE_NOTSUP, 0}, -/* R_AMD64_SIZE32 */ {FLG_RE_SIZE, 4}, -/* R_AMD64_SIZE64 */ {FLG_RE_SIZE, 8} +/* R_AMD64_NONE */ {0, FLG_RE_NOTREL, 0, 0, 0}, +/* R_AMD64_64 */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_PC32 */ {0, FLG_RE_PCREL, 4, 0, 0}, +/* R_AMD64_GOT32 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_PLT32 */ {0, FLG_RE_PCREL | FLG_RE_PLTREL | + FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 0}, +/* R_AMD64_COPY */ {0, FLG_RE_NOTSUP, 0, 0, 0}, /* SPECIAL */ +/* R_AMD64_GLOB_DAT */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_JUMP_SLOT */ {0, FLG_RE_NOTSUP, 0, 0, 0}, /* SPECIAL */ +/* R_AMD64_RELATIVE */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_GOTPCREL */ {0, FLG_RE_GOTPC | FLG_RE_GOTADD, 4, 0, 0}, +/* R_AMD64_32 */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_AMD64_32S */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_AMD64_16 */ {0, FLG_RE_NOTREL, 2, 0, 0}, +/* R_AMD64_PC16 */ {0, FLG_RE_PCREL, 2, 0, 0}, +/* R_AMD64_8 */ {0, FLG_RE_NOTREL, 1, 0, 0}, +/* R_AMD64_PC8 */ {0, FLG_RE_PCREL, 1, 0, 0}, +/* R_AMD64_DTPMOD64 */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_DTPOFF64 */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_TPOFF64 */ {0, FLG_RE_NOTREL, 8, 0, 0}, +/* R_AMD64_TLSGD */ {0, FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSGD, + 4, 0, 0}, +/* R_AMD64_TLSLD */ {0, FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSLD, + 4, 0, 0}, +/* R_AMD64_DTPOFF32 */ {0, FLG_RE_TLSLD, 4}, +/* R_AMD64_GOTTPOFF */ {0, FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSIE, + 4, 0, 0}, +/* R_AMD64_TPOFF32 */ {0, FLG_RE_TLSLE, 4, 0, 0}, +/* R_AMD64_PC64 */ {0, FLG_RE_PCREL, 8, 0, 0}, +/* R_AMD64_GOTOFF64 */ {0, FLG_RE_GOTREL, 8, 0, 0}, +/* R_AMD64_GOTPC32 */ {0, FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, + 4, 0, 0}, +/* R_AMD64_GOT64 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_GOTPCREL64 */ {FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_GOTPC6 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_GOTPLT64 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_PLTOFF64 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_AMD64_SIZE32 */ {0, FLG_RE_SIZE, 4, 0, 0}, +/* R_AMD64_SIZE64 */ {0, FLG_RE_SIZE, 8, 0, 0} }; #if (R_AMD64_NUM != (R_AMD64_SIZE64 + 1)) #error "R_AMD64_NUM has grown" @@ -163,6 +186,7 @@ do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file) #elif defined(DO_RELOC_LIBLD) +/*ARGSUSED5*/ int do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, int bswap, void *lml) @@ -174,17 +198,6 @@ { const Rel_entry *rep; -#if defined(DO_RELOC_LIBLD) - /* - * We do not support building the amd64 linker as a cross linker - * at this time. - */ - if (bswap) { - REL_ERR_NOSWAP(lml, file, sym, rtype); - return (0); - } -#endif - rep = &reloc_table[rtype]; switch (rep->re_fsize) { @@ -192,10 +205,25 @@ /* LINTED */ *((uchar_t *)off) = (uchar_t)(*value); break; + case 2: +#if defined(DORELOC_NATIVE) /* LINTED */ *((Half *)off) = (Half)(*value); +#else + { + Half v = (Half)(*value); + uchar_t *v_bytes = (uchar_t *)&v; + + if (bswap) { + UL_ASSIGN_BSWAP_HALF(off, v_bytes); + } else { + UL_ASSIGN_HALF(off, v_bytes); + } + } +#endif break; + case 4: /* * The amd64 psABI requires that we perform the following @@ -242,12 +270,48 @@ return (0); } } + +#if defined(DORELOC_NATIVE) /* LINTED */ *((Word *)off) += *value; +#else + { + Word v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (bswap) { + UL_ASSIGN_BSWAP_WORD(v_bytes, off); + v += *value; + UL_ASSIGN_BSWAP_WORD(off, v_bytes); + } else { + UL_ASSIGN_WORD(v_bytes, off); + v += *value; + UL_ASSIGN_WORD(off, v_bytes); + } + } +#endif break; + case 8: +#if defined(DORELOC_NATIVE) /* LINTED */ *((Xword *)off) += *value; +#else + { + Xword v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (bswap) { + UL_ASSIGN_BSWAP_XWORD(v_bytes, off); + v += *value; + UL_ASSIGN_BSWAP_XWORD(off, v_bytes); + } else { + UL_ASSIGN_XWORD(v_bytes, off); + v += *value; + UL_ASSIGN_XWORD(off, v_bytes); + } + } +#endif break; default: /*
--- a/usr/src/uts/intel/amd64/krtld/relmach.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _RELMACH_H -#define _RELMACH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Architecture specific flags presented in a architecture neutral format - */ -#define SHF_NEUT_SHORT 0 - -#ifdef __cplusplus -} -#endif - -#endif /* _RELMACH_H */
--- a/usr/src/uts/intel/ia32/krtld/doreloc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/intel/ia32/krtld/doreloc.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +30,11 @@ #include <sys/types.h> #include "reloc.h" #else +#define ELF_TARGET_386 +#if defined(DO_RELOC_LIBLD) +#undef DO_RELOC_LIBLD +#define DO_RELOC_LIBLD_X86 +#endif #include <stdio.h> #include "sgs.h" #include "machdep.h" @@ -40,50 +45,67 @@ #endif /* + * We need to build this code differently when it is used for + * cross linking: + * - Data alignment requirements can differ from those + * of the running system, so we can't access data + * in units larger than a byte + * - We have to include code to do byte swapping when the + * target and linker host use different byte ordering, + * but such code is a waste when running natively. + */ +#if !defined(DO_RELOC_LIBLD) || defined(__i386) || defined(__amd64) +#define DORELOC_NATIVE +#endif + +/* * This table represents the current relocations that do_reloc() is able to * process. The relocations below that are marked SPECIAL are relocations that * take special processing and shouldn't actually ever be passed to do_reloc(). */ const Rel_entry reloc_table[R_386_NUM] = { -/* R_386_NONE */ {FLG_RE_NOTREL, 0}, -/* R_386_32 */ {FLG_RE_NOTREL, 4}, -/* R_386_PC32 */ {FLG_RE_PCREL, 4}, -/* R_386_GOT32 */ {FLG_RE_GOTADD, 4}, -/* R_386_PLT32 */ {FLG_RE_PLTREL | FLG_RE_PCREL, 4}, -/* R_386_COPY */ {FLG_RE_NOTREL, 0}, /* SPECIAL */ -/* R_386_GLOB_DAT */ {FLG_RE_NOTREL, 4}, -/* R_386_JMP_SLOT */ {FLG_RE_NOTREL, 4}, /* SPECIAL */ -/* R_386_RELATIVE */ {FLG_RE_NOTREL, 4}, -/* R_386_GOTOFF */ {FLG_RE_GOTREL, 4}, -/* R_386_GOTPC */ {FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, 4}, -/* R_386_32PLT */ {FLG_RE_PLTREL, 4}, -/* R_386_TLS_GD_PLT */ {FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSGD, 4}, -/* R_386_TLS_LDM_PLT */ {FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSLD, 4}, -/* R_386_TLS_TPOFF */ {FLG_RE_NOTREL, 4}, -/* R_386_TLS_IE */ {FLG_RE_GOTADD | FLG_RE_TLSIE, 4}, -/* R_386_TLS_GOTIE */ {FLG_RE_GOTADD | FLG_RE_TLSIE, 4}, -/* R_386_TLS_LE */ {FLG_RE_TLSLE, 4}, -/* R_386_TLS_GD */ {FLG_RE_GOTADD | FLG_RE_TLSGD, 4}, -/* R_386_TLS_LDM */ {FLG_RE_GOTADD | FLG_RE_TLSLD, 4}, -/* R_386_16 */ {FLG_RE_NOTREL, 2}, -/* R_386_PC16 */ {FLG_RE_PCREL, 2}, -/* R_386_8 */ {FLG_RE_NOTREL, 1}, -/* R_386_PC8 */ {FLG_RE_PCREL, 1}, -/* R_386_UNKNOWN24 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN25 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN26 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN27 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN28 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN29 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN30 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN31 */ {FLG_RE_NOTSUP, 0}, -/* R_386_TLS_LDO_32 */ {FLG_RE_TLSLD, 4}, -/* R_386_UNKNOWN33 */ {FLG_RE_NOTSUP, 0}, -/* R_386_UNKNOWN34 */ {FLG_RE_NOTSUP, 0}, -/* R_386_TLS_DTPMOD32 */ {FLG_RE_NOTREL, 4}, -/* R_386_TLS_DTPOFF32 */ {FLG_RE_NOTREL, 4}, -/* R_386_UNKONWN37 */ {FLG_RE_NOTSUP, 0}, -/* R_386_SIZE32 */ {FLG_RE_SIZE | FLG_RE_VERIFY, 4} +/* R_386_NONE */ {0, FLG_RE_NOTREL, 0, 0, 0}, +/* R_386_32 */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_PC32 */ {0, FLG_RE_PCREL, 4, 0, 0}, +/* R_386_GOT32 */ {0, FLG_RE_GOTADD, 4, 0, 0}, +/* R_386_PLT32 */ {0, FLG_RE_PLTREL | FLG_RE_PCREL, 4, 0, 0}, +/* R_386_COPY */ {0, FLG_RE_NOTREL, 0, 0, 0}, /* SPECIAL */ +/* R_386_GLOB_DAT */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_JMP_SLOT */ {0, FLG_RE_NOTREL, 4, 0, 0}, /* SPECIAL */ +/* R_386_RELATIVE */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_GOTOFF */ {0, FLG_RE_GOTREL, 4, 0, 0}, +/* R_386_GOTPC */ {0, FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, 4, + 0, 0}, +/* R_386_32PLT */ {0, FLG_RE_PLTREL, 4, 0, 0}, +/* R_386_TLS_GD_PLT */ {0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSGD, 4, + 0, 0}, +/* R_386_TLS_LDM_PLT */ {0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSLD, 4, + 0, 0}, +/* R_386_TLS_TPOFF */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_TLS_IE */ {0, FLG_RE_GOTADD | FLG_RE_TLSIE, 4, 0, 0}, +/* R_386_TLS_GOTIE */ {0, FLG_RE_GOTADD | FLG_RE_TLSIE, 4, 0, 0}, +/* R_386_TLS_LE */ {0, FLG_RE_TLSLE, 4, 0, 0}, +/* R_386_TLS_GD */ {0, FLG_RE_GOTADD | FLG_RE_TLSGD, 4, 0, 0}, +/* R_386_TLS_LDM */ {0, FLG_RE_GOTADD | FLG_RE_TLSLD, 4, 0, 0}, +/* R_386_16 */ {0, FLG_RE_NOTREL, 2, 0, 0}, +/* R_386_PC16 */ {0, FLG_RE_PCREL, 2, 0, 0}, +/* R_386_8 */ {0, FLG_RE_NOTREL, 1, 0, 0}, +/* R_386_PC8 */ {0, FLG_RE_PCREL, 1, 0, 0}, +/* R_386_UNKNOWN24 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN25 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN26 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN27 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN28 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN29 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN30 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN31 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_TLS_LDO_32 */ {0, FLG_RE_TLSLD, 4, 0, 0}, +/* R_386_UNKNOWN33 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_UNKNOWN34 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_TLS_DTPMOD32 */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_TLS_DTPOFF32 */ {0, FLG_RE_NOTREL, 4, 0, 0}, +/* R_386_UNKONWN37 */ {0, FLG_RE_NOTSUP, 0, 0, 0}, +/* R_386_SIZE32 */ {0, FLG_RE_SIZE | FLG_RE_VERIFY, 4, 0, 0} }; /* @@ -168,6 +190,7 @@ do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file) #elif defined(DO_RELOC_LIBLD) +/*ARGSUSED5*/ int do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, int bswap, void *lml) @@ -179,17 +202,6 @@ { const Rel_entry *rep; -#if defined(DO_RELOC_LIBLD) - /* - * We do not support building the X86 linker as a cross linker - * at this time. - */ - if (bswap) { - REL_ERR_NOSWAP(lml, file, sym, rtype); - return (0); - } -#endif - rep = &reloc_table[rtype]; switch (rep->re_fsize) { @@ -197,13 +209,49 @@ /* LINTED */ *((uchar_t *)off) += (uchar_t)(*value); break; + case 2: +#if defined(DORELOC_NATIVE) /* LINTED */ *((Half *)off) += (Half)(*value); +#else + { + Half v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (bswap) { + UL_ASSIGN_BSWAP_HALF(v_bytes, off); + v += *value; + UL_ASSIGN_BSWAP_HALF(off, v_bytes); + } else { + UL_ASSIGN_HALF(v_bytes, off); + v += *value; + UL_ASSIGN_HALF(off, v_bytes); + } + } +#endif break; + case 4: +#if defined(DORELOC_NATIVE) /* LINTED */ *((Xword *)off) += *value; +#else + { + Word v; + uchar_t *v_bytes = (uchar_t *)&v; + + if (bswap) { + UL_ASSIGN_BSWAP_WORD(v_bytes, off); + v += *value; + UL_ASSIGN_BSWAP_WORD(off, v_bytes); + } else { + UL_ASSIGN_WORD(v_bytes, off); + v += *value; + UL_ASSIGN_WORD(off, v_bytes); + } + } +#endif break; default: /*
--- a/usr/src/uts/intel/ia32/krtld/relmach.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _RELMACH_H -#define _RELMACH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Architecture specific flags presented in a architecture neutral format - */ -#define SHF_NEUT_SHORT 0 - -#ifdef __cplusplus -} -#endif - -#endif /* _RELMACH_H */
--- a/usr/src/uts/intel/sys/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/intel/sys/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -51,7 +51,6 @@ kd.h \ kdi_machimpl.h \ kdi_regs.h \ - machelf.h \ machlock.h \ machsig.h \ machtypes.h \
--- a/usr/src/uts/intel/sys/machelf.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_MACHELF_H -#define _SYS_MACHELF_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__amd64) -#include <sys/elf_amd64.h> -#elif defined(__i386) -#include <sys/elf_386.h> -#endif -#ifndef _ASM -#include <sys/types.h> -#include <sys/elf.h> -#include <sys/link.h> /* for Elf*_Dyn */ -#endif /* _ASM */ - -/* - * Make machine class dependent data types transparent to the common code - */ -#if defined(_ELF64) && !defined(_ELF32_COMPAT) - -#ifndef _ASM -typedef Elf64_Xword Xword; -typedef Elf64_Lword Lword; -typedef Elf64_Sxword Sxword; -typedef Elf64_Word Word; -typedef Elf64_Sword Sword; -typedef Elf64_Half Half; -typedef Elf64_Addr Addr; -typedef Elf64_Off Off; -typedef uchar_t Byte; -#endif /* _ASM */ - -#if defined(_KERNEL) -#define ELF_R_TYPE ELF64_R_TYPE -#define ELF_R_SYM ELF64_R_SYM -#define ELF_R_INFO ELF64_R_INFO -#define ELF_ST_BIND ELF64_ST_BIND -#define ELF_ST_TYPE ELF64_ST_TYPE -#define ELF_M_SYM ELF64_M_SYM -#define ELF_M_SIZE ELF64_M_SIZE -#endif - -#ifndef _ASM -typedef Elf64_Ehdr Ehdr; -typedef Elf64_Shdr Shdr; -typedef Elf64_Sym Sym; -typedef Elf64_Syminfo Syminfo; -typedef Elf64_Rela Rela; -typedef Elf64_Rel Rel; -typedef Elf64_Nhdr Nhdr; -typedef Elf64_Phdr Phdr; -typedef Elf64_Dyn Dyn; -typedef Elf64_Boot Boot; -typedef Elf64_Verdef Verdef; -typedef Elf64_Verdaux Verdaux; -typedef Elf64_Verneed Verneed; -typedef Elf64_Vernaux Vernaux; -typedef Elf64_Versym Versym; -typedef Elf64_Move Move; -typedef Elf64_Cap Cap; - -/* - * Structure used to build the reloc_table[] - */ -typedef struct { - Word re_flags; /* relocation attributes */ - uchar_t re_fsize; /* field size (in bytes) */ - uchar_t re_sigbits; /* number of significant bits */ -} Rel_entry; - -#endif /* _ASM */ - -#else /* _ILP32 */ - -#ifndef _ASM -typedef Elf32_Word Xword; /* Xword/Sxword are 32-bits in Elf32 */ -typedef Elf32_Lword Lword; -typedef Elf32_Sword Sxword; -typedef Elf32_Word Word; -typedef Elf32_Sword Sword; -typedef Elf32_Half Half; -typedef Elf32_Addr Addr; -typedef Elf32_Off Off; -typedef uchar_t Byte; -#endif /* _ASM */ - -#if defined(_KERNEL) -#define ELF_R_TYPE ELF32_R_TYPE -#define ELF_R_SYM ELF32_R_SYM -#define ELF_R_INFO ELF32_R_INFO -#define ELF_ST_BIND ELF32_ST_BIND -#define ELF_ST_TYPE ELF32_ST_TYPE -#define ELF_M_SYM ELF32_M_SYM -#define ELF_M_SIZE ELF32_M_SIZE -#endif - -#ifndef _ASM -typedef Elf32_Ehdr Ehdr; -typedef Elf32_Shdr Shdr; -typedef Elf32_Sym Sym; -typedef Elf32_Syminfo Syminfo; -typedef Elf32_Rela Rela; -typedef Elf32_Rel Rel; -typedef Elf32_Nhdr Nhdr; -typedef Elf32_Phdr Phdr; -typedef Elf32_Dyn Dyn; -typedef Elf32_Boot Boot; -typedef Elf32_Verdef Verdef; -typedef Elf32_Verdaux Verdaux; -typedef Elf32_Verneed Verneed; -typedef Elf32_Vernaux Vernaux; -typedef Elf32_Versym Versym; -typedef Elf32_Move Move; -typedef Elf32_Cap Cap; - -/* - * Structure used to build the reloc_table[] - */ -typedef struct { - uint_t re_flags; /* relocation attributes */ - uchar_t re_fsize; /* field size (in bytes) */ -} Rel_entry; - -#endif /* _ASM */ - -#endif /* _ILP32 */ - -/* - * Elf `printf' type-cast macros. These force arguments to be a fixed size - * so that Elf32 and Elf64 can share common format strings. - */ -#ifndef __lint -#define EC_ADDR(a) ((Elf64_Addr)(a)) /* "ull" */ -#define EC_OFF(a) ((Elf64_Off)(a)) /* "ull" */ -#define EC_HALF(a) ((Elf64_Half)(a)) /* "d" */ -#define EC_WORD(a) ((Elf64_Word)(a)) /* "u" */ -#define EC_SWORD(a) ((Elf64_Sword)(a)) /* "d" */ -#define EC_XWORD(a) ((Elf64_Xword)(a)) /* "ull" */ -#define EC_SXWORD(a) ((Elf64_Sxword)(a)) /* "ll" */ -#define EC_LWORD(a) ((Elf64_Lword)(a)) /* "ull" */ - -/* - * A native pointer is special. Although it can be convenient to display - * these from a common format (ull), compilers may flag the cast of a pointer - * to an integer as illegal. Casting these pointers to the native pointer - * size, suppresses any compiler errors. - */ -#define EC_NATPTR(a) ((Elf64_Xword)(uintptr_t)(a)) /* "ull" */ -#else -#define EC_ADDR(a) ((u_longlong_t)(a)) -#define EC_OFF(a) ((u_longlong_t)(a)) -#define EC_HALF(a) ((ushort_t)(a)) -#define EC_WORD(a) ((uint_t)(a)) -#define EC_SWORD(a) ((int)(a)) -#define EC_XWORD(a) ((u_longlong_t)(a)) -#define EC_SXWORD(a) ((longlong_t)(a)) -#define EC_LWORD(a) ((u_longlong_t)(a)) - -#define EC_NATPTR(a) ((u_longlong_t)(a)) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MACHELF_H */
--- a/usr/src/uts/sparc/krtld/doreloc.c Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/sparc/krtld/doreloc.c Tue Mar 18 09:17:00 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +30,11 @@ #include <sys/types.h> #include "krtld/reloc.h" #else +#define ELF_TARGET_SPARC +#if defined(DO_RELOC_LIBLD) +#undef DO_RELOC_LIBLD +#define DO_RELOC_LIBLD_SPARC +#endif #include <stdio.h> #include "sgs.h" #include "machdep.h" @@ -40,11 +45,25 @@ #endif /* + * We need to build this code differently when it is used for + * cross linking: + * - Data alignment requirements can differ from those + * of the running system, so we can't access data + * in units larger than a byte + * - We have to include code to do byte swapping when the + * target and linker host use different byte ordering, + * but such code is a waste when running natively. + */ +#if !defined(DO_RELOC_LIBLD) || defined(__sparc) +#define DORELOC_NATIVE +#endif + +/* * This table represents the current relocations that do_reloc() is able to * process. The relocations below that are marked SPECIAL are relocations that * take special processing and shouldn't actually ever be passed to do_reloc(). */ -const Rel_entry reloc_table[R_SPARC_NUM] = { +const Rel_entry reloc_table[R_SPARC_NUM] = { /* R_SPARC_NONE */ {0x0, FLG_RE_NOTREL, 0, 0, 0}, /* R_SPARC_8 */ {0x0, FLG_RE_VERIFY, 1, 0, 0}, /* R_SPARC_16 */ {0x0, FLG_RE_VERIFY, 2, 0, 0}, @@ -350,6 +369,7 @@ do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file) #elif defined(DO_RELOC_LIBLD) +/*ARGSUSED5*/ int do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, int bswap, void *lml) @@ -359,23 +379,12 @@ const char *file, void *lml) #endif { - Xword uvalue = 0; - Xword basevalue, sigbit_mask, sigfit_mask; - Xword corevalue = *value; - uchar_t bshift; - int field_size, re_flags; - const Rel_entry * rep; - -#if defined(DO_RELOC_LIBLD) - /* - * We do not support building the sparc linker as a cross linker - * at this time. - */ - if (bswap) { - REL_ERR_NOSWAP(lml, file, sym, rtype); - return (0); - } -#endif + Xword uvalue = 0; + Xword basevalue, sigbit_mask, sigfit_mask; + Xword corevalue = *value; + uchar_t bshift; + int field_size, re_flags; + const Rel_entry *rep; rep = &reloc_table[rtype]; bshift = rep->re_bshift; @@ -398,22 +407,62 @@ return (0); } - if (re_flags & FLG_RE_UNALIGN) { + /* + * We have two ways to retrieve the base value, a general one + * that will work with data of any alignment, and another that is + * fast, but which requires the data to be aligned according to + * sparc alignment rules. + * + * For non-native linking, we always use the general path. For + * native linking, the FLG_RE_UNALIGN determines it. + */ +#if defined(DORELOC_NATIVE) + if (re_flags & FLG_RE_UNALIGN) +#endif + { int i; uchar_t *dest = (uchar_t *)&basevalue; - /* - * Adjust the offset. - */ - /* LINTED */ - i = (int)(sizeof (Xword) - field_size); - if (i > 0) - dest += i; + basevalue = 0; +#if !defined(DORELOC_NATIVE) + if (bswap) { + int j = field_size - 1; + + for (i = 0; i < field_size; i++, j--) + dest[i] = off[j]; - basevalue = 0; - for (i = field_size - 1; i >= 0; i--) - dest[i] = off[i]; - } else { + } else +#endif + { + /* + * Adjust the offset + */ + /* LINTED */ + i = (int)(sizeof (Xword) - field_size); + if (i > 0) + dest += i; + for (i = field_size - 1; i >= 0; i--) + dest[i] = off[i]; + } + } + + /* + * Non-native linker: We have already fetched the value above, + * but if the relocation does not have the FLG_RE_UNALIGN + * flag set, we still need to do the same error checking we + * would do on a native linker. + * Native-linker: If this is an aligned relocation, we need to + * fetch the value and also do the error checking. + * + * The FETCH macro is used to conditionalize the fetching so that + * it only happens in the native case. + */ +#if defined(DORELOC_NATIVE) +#define FETCH(_type) basevalue = (Xword)*((_type *)off); +#else +#define FETCH(_type) +#endif + if ((re_flags & FLG_RE_UNALIGN) == 0) { if (((field_size == 2) && ((uintptr_t)off & 0x1)) || ((field_size == 4) && ((uintptr_t)off & 0x3)) || ((field_size == 8) && ((uintptr_t)off & 0x7))) { @@ -422,19 +471,20 @@ } switch (field_size) { case 1: - basevalue = (Xword)*((uchar_t *)off); + /* LINTED */ + FETCH(uchar_t); break; case 2: /* LINTED */ - basevalue = (Xword)*((Half *)off); + FETCH(Half); break; case 4: /* LINTED */ - basevalue = (Xword)*((Word *)off); + FETCH(Word); break; case 8: /* LINTED */ - basevalue = (Xword)*((Xword *)off); + FETCH(Xword); break; default: REL_ERR_UNNOBITS(lml, file, sym, rtype, @@ -442,6 +492,7 @@ return (0); } } +#undef FETCH if (sigbit_mask) { /* @@ -543,37 +594,68 @@ } *value = corevalue; - if (re_flags & FLG_RE_UNALIGN) { + /* + * Now, we store uvalue back at the location given by off. + * This is similar to the fetch case above: + * - We have general (unaligned) and fast (aligned) cases + * - Cross linkers need to use the unaligned case even + * when the relocation does not specify FLG_RE_UNALIGN. + * - A cross linker that processes a relocation that does not + * have FLG_RE_UNALIGN set has to do the same error + * checking that a native linker would do, while avoiding + * the aligned store (accomplished with the STORE macro). + */ +#if defined(DORELOC_NATIVE) + if (re_flags & FLG_RE_UNALIGN) +#endif + { int i; uchar_t *src = (uchar_t *)&uvalue; - /* - * Adjust the offset. - */ - /* LINTED */ - i = (int)(sizeof (Xword) - field_size); - if (i > 0) - src += i; +#if !defined(DORELOC_NATIVE) + if (bswap) { + int j = field_size - 1; + + for (i = 0; i < field_size; i++, j--) + off[i] = src[j]; - for (i = field_size - 1; i >= 0; i--) - off[i] = src[i]; - } else { + } else +#endif + { + /* + * Adjust the offset. + */ + /* LINTED */ + i = (int)(sizeof (Xword) - field_size); + if (i > 0) + src += i; + for (i = field_size - 1; i >= 0; i--) + off[i] = src[i]; + } + } + +#if defined(DORELOC_NATIVE) +#define STORE(_type) *((_type *)off) = (_type)uvalue +#else +#define STORE(_type) +#endif + if ((re_flags & FLG_RE_UNALIGN) == 0) { switch (rep->re_fsize) { case 1: /* LINTED */ - *((uchar_t *)off) = (uchar_t)uvalue; + STORE(uchar_t); break; case 2: /* LINTED */ - *((Half *)off) = (Half)uvalue; + STORE(Half); break; case 4: /* LINTED */ - *((Word *)off) = uvalue; + STORE(Word); break; case 8: /* LINTED */ - *((Xword *)off) = uvalue; + STORE(Xword); break; default: /* @@ -583,5 +665,7 @@ return (0); } } +#undef STORE + return (1); }
--- a/usr/src/uts/sparc/krtld/relmach.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _RELMACH_H -#define _RELMACH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Architecture specific flags presented in a architecture nutral format - */ -#define SHF_NEUT_SHORT 0 - -#ifdef __cplusplus -} -#endif - -#endif /* _RELMACH_H */
--- a/usr/src/uts/sparc/sys/Makefile Tue Mar 18 08:44:14 2008 -0700 +++ b/usr/src/uts/sparc/sys/Makefile Tue Mar 18 09:17:00 2008 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -38,7 +38,6 @@ fsr.h \ inline.h \ kdi_machimpl.h \ - machelf.h \ machlock.h \ machsig.h \ machtypes.h \
--- a/usr/src/uts/sparc/sys/machelf.h Tue Mar 18 08:44:14 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_MACHELF_H -#define _SYS_MACHELF_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/elf_SPARC.h> -#ifndef _ASM -#include <sys/types.h> -#include <sys/elf.h> -#include <sys/link.h> /* for Elf*_Dyn */ -#endif /* _ASM */ - -/* - * Make machine class dependent data types transparent to the common code - */ -#if defined(_ELF64) && !defined(_ELF32_COMPAT) - -#ifndef _ASM -typedef Elf64_Xword Xword; -typedef Elf64_Lword Lword; -typedef Elf64_Sxword Sxword; -typedef Elf64_Word Word; -typedef Elf64_Sword Sword; -typedef Elf64_Half Half; -typedef Elf64_Addr Addr; -typedef Elf64_Off Off; -typedef uchar_t Byte; -#endif /* _ASM */ - -#if defined(_KERNEL) -#define ELF_R_TYPE ELF64_R_TYPE -#define ELF_R_SYM ELF64_R_SYM -#define ELF_R_TYPE_DATA ELF64_R_TYPE_DATA -#define ELF_R_INFO ELF64_R_INFO -#define ELF_ST_BIND ELF64_ST_BIND -#define ELF_ST_TYPE ELF64_ST_TYPE -#define ELF_M_SYM ELF64_M_SYM -#define ELF_M_SIZE ELF64_M_SIZE -#endif - -#ifndef _ASM -typedef Elf64_Ehdr Ehdr; -typedef Elf64_Shdr Shdr; -typedef Elf64_Sym Sym; -typedef Elf64_Syminfo Syminfo; -typedef Elf64_Rela Rela; -typedef Elf64_Rel Rel; -typedef Elf64_Nhdr Nhdr; -typedef Elf64_Phdr Phdr; -typedef Elf64_Dyn Dyn; -typedef Elf64_Boot Boot; -typedef Elf64_Verdef Verdef; -typedef Elf64_Verdaux Verdaux; -typedef Elf64_Verneed Verneed; -typedef Elf64_Vernaux Vernaux; -typedef Elf64_Versym Versym; -typedef Elf64_Move Move; -typedef Elf64_Cap Cap; -#endif /* _ASM */ - -#else /* _ILP32 */ - -#ifndef _ASM -typedef Elf32_Word Xword; /* Xword/Sxword are 32-bits in Elf32 */ -typedef Elf32_Lword Lword; -typedef Elf32_Sword Sxword; -typedef Elf32_Word Word; -typedef Elf32_Sword Sword; -typedef Elf32_Half Half; -typedef Elf32_Addr Addr; -typedef Elf32_Off Off; -typedef uchar_t Byte; -#endif /* _ASM */ - -#if defined(_KERNEL) -#define ELF_R_TYPE ELF32_R_TYPE -#define ELF_R_SYM ELF32_R_SYM -#define ELF_R_INFO ELF32_R_INFO -#define ELF_R_TYPE_DATA(x) (0) -#define ELF_ST_BIND ELF32_ST_BIND -#define ELF_ST_TYPE ELF32_ST_TYPE -#define ELF_M_SYM ELF32_M_SYM -#define ELF_M_SIZE ELF32_M_SIZE -#endif - -#ifndef _ASM -typedef Elf32_Ehdr Ehdr; -typedef Elf32_Shdr Shdr; -typedef Elf32_Sym Sym; -typedef Elf32_Syminfo Syminfo; -typedef Elf32_Rela Rela; -typedef Elf32_Rel Rel; -typedef Elf32_Nhdr Nhdr; -typedef Elf32_Phdr Phdr; -typedef Elf32_Dyn Dyn; -typedef Elf32_Boot Boot; -typedef Elf32_Verdef Verdef; -typedef Elf32_Verdaux Verdaux; -typedef Elf32_Verneed Verneed; -typedef Elf32_Vernaux Vernaux; -typedef Elf32_Versym Versym; -typedef Elf32_Move Move; -typedef Elf32_Cap Cap; -#endif /* _ASM */ - -#endif /* _ILP32 */ - -/* - * Elf `printf' type-cast macros. These force arguments to be a fixed size - * so that Elf32 and Elf64 can share common format strings. - */ -#ifndef __lint -#define EC_ADDR(a) ((Elf64_Addr)(a)) /* "ull" */ -#define EC_OFF(a) ((Elf64_Off)(a)) /* "ull" */ -#define EC_HALF(a) ((Elf64_Half)(a)) /* "d" */ -#define EC_WORD(a) ((Elf64_Word)(a)) /* "u" */ -#define EC_SWORD(a) ((Elf64_Sword)(a)) /* "d" */ -#define EC_XWORD(a) ((Elf64_Xword)(a)) /* "ull" */ -#define EC_SXWORD(a) ((Elf64_Sxword)(a)) /* "ll" */ -#define EC_LWORD(a) ((Elf64_Lword)(a)) /* "ull" */ - -/* - * A native pointer is special. Although it can be convenient to display - * these from a common format (ull), compilers may flag the cast of a pointer - * to an integer as illegal. Casting these pointers to the native pointer - * size, suppresses any compiler errors. - */ -#define EC_NATPTR(a) ((Elf64_Xword)(uintptr_t)(a)) /* "ull" */ -#else -#define EC_ADDR(a) ((u_longlong_t)(a)) -#define EC_OFF(a) ((u_longlong_t)(a)) -#define EC_HALF(a) ((ushort_t)(a)) -#define EC_WORD(a) ((uint_t)(a)) -#define EC_SWORD(a) ((int)(a)) -#define EC_XWORD(a) ((u_longlong_t)(a)) -#define EC_SXWORD(a) ((longlong_t)(a)) -#define EC_LWORD(a) ((u_longlong_t)(a)) - -#define EC_NATPTR(a) ((u_longlong_t)(a)) -#endif - -#ifndef _ASM -/* - * Structure used to build the reloc_table[] - */ -typedef struct { - Xword re_mask; /* mask to apply to reloc */ - Word re_flags; /* relocation attributes */ - uchar_t re_fsize; /* field size (in bytes) */ - uchar_t re_bshift; /* number of bits to shift */ - uchar_t re_sigbits; /* number of significant bits */ -} Rel_entry; - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MACHELF_H */