4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
25 #define ELF_TARGET_SPARC
30 #include <sys/types.h>
34 #include "machsym.sparc.h"
37 * Matrix of legal combinations of usage of a given register:
39 * Obj1 \ Obj2 Scratch Named
43 * (*) OK if the symbols are identical, NO if they are not. Two symbols
44 * are identical if and only if one of the following is true:
45 * A. They are both global and have the same name.
46 * B. They are both local, have the same name, and are defined in the same
47 * object. (Note that a local symbol in one object is never identical to
48 * a local symbol in another object, even if the name is the same.)
50 * Matrix of legal combinations of st_shndx for the same register symbol:
52 * Obj1 \ Obj2 UNDEF ABS
58 ld_reg_check_sparc(Sym_desc
*sdp
, Sym
*nsym
, const char *nname
, Ifl_desc
*ifl
,
61 Sym
*osym
= sdp
->sd_sym
;
62 const char *oname
= sdp
->sd_name
;
63 Conv_inv_buf_t inv_buf1
, inv_buf2
;
66 * Scratch register definitions are compatible.
68 if ((osym
->st_name
== 0) && (nsym
->st_name
== 0))
72 * A local and a global, or another local is incompatible.
74 if ((ELF_ST_BIND(osym
->st_info
) == STB_LOCAL
) ||
75 (ELF_ST_BIND(nsym
->st_info
) == STB_LOCAL
)) {
76 if (osym
->st_value
== nsym
->st_value
) {
78 ld_eprintf(ofl
, ERR_FATAL
,
79 MSG_INTL(MSG_SYM_INCOMPREG3
),
80 conv_sym_SPARC_value(osym
->st_value
, 0, &inv_buf1
),
81 sdp
->sd_file
->ifl_name
, demangle(oname
),
82 ifl
->ifl_name
, demangle(nname
));
88 if (osym
->st_value
== nsym
->st_value
) {
90 * A scratch register and a named register are incompatible.
91 * So are two different named registers.
93 if (((osym
->st_name
== 0) || (nsym
->st_name
== 0)) ||
94 (strcmp(oname
, nname
) != 0)) {
95 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_INCOMPREG1
),
96 conv_sym_SPARC_value(osym
->st_value
, 0, &inv_buf1
),
97 sdp
->sd_file
->ifl_name
, demangle(oname
),
98 ifl
->ifl_name
, demangle(nname
));
103 * A multiply initialized symbol is also illegal.
105 if ((osym
->st_shndx
== SHN_ABS
) &&
106 (nsym
->st_shndx
== SHN_ABS
)) {
107 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_MULTINIREG
),
108 conv_sym_SPARC_value(osym
->st_value
, 0, &inv_buf1
),
109 demangle(nname
), sdp
->sd_file
->ifl_name
,
114 } else if (strcmp(oname
, nname
) == 0) {
115 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_INCOMPREG2
),
116 demangle(sdp
->sd_name
), sdp
->sd_file
->ifl_name
,
117 conv_sym_SPARC_value(osym
->st_value
, 0, &inv_buf1
),
119 conv_sym_SPARC_value(nsym
->st_value
, 0, &inv_buf2
));
126 ld_mach_sym_typecheck_sparc(Sym_desc
*sdp
, Sym
*nsym
, Ifl_desc
*ifl
,
129 Conv_inv_buf_t inv_buf1
, inv_buf2
;
130 Sym
*osym
= sdp
->sd_sym
;
131 Byte otype
= ELF_ST_TYPE(osym
->st_info
);
132 Byte ntype
= ELF_ST_TYPE(nsym
->st_info
);
134 if (otype
!= ntype
) {
135 if ((otype
== STT_SPARC_REGISTER
) ||
136 (ntype
== STT_SPARC_REGISTER
)) {
137 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_DIFFTYPE
),
138 demangle(sdp
->sd_name
));
139 ld_eprintf(ofl
, ERR_NONE
, MSG_INTL(MSG_SYM_FILETYPES
),
140 sdp
->sd_file
->ifl_name
, conv_sym_info_type(
141 sdp
->sd_file
->ifl_ehdr
->e_machine
, otype
,
142 0, &inv_buf1
), ifl
->ifl_name
,
143 conv_sym_info_type(ifl
->ifl_ehdr
->e_machine
,
144 ntype
, 0, &inv_buf2
));
147 } else if (otype
== STT_SPARC_REGISTER
)
148 return (ld_reg_check_sparc(sdp
, nsym
, sdp
->sd_name
, ifl
, ofl
));
153 static const char *registers
[] = { 0,
154 MSG_ORIG(MSG_STO_REGISTERG1
), MSG_ORIG(MSG_STO_REGISTERG2
),
155 MSG_ORIG(MSG_STO_REGISTERG3
), MSG_ORIG(MSG_STO_REGISTERG4
),
156 MSG_ORIG(MSG_STO_REGISTERG5
), MSG_ORIG(MSG_STO_REGISTERG6
),
157 MSG_ORIG(MSG_STO_REGISTERG7
)
161 ld_is_regsym_sparc(Ofl_desc
*ofl
, Ifl_desc
*ifl
, Sym
*sym
, const char *strs
,
162 int symndx
, Word shndx
, const char *symsecname
, sd_flag_t
*flags
)
167 * Only do something if this is a register symbol.
169 if (ELF_ST_TYPE(sym
->st_info
) != STT_SPARC_REGISTER
)
173 * Check for bogus register number.
175 if ((sym
->st_value
< STO_SPARC_REGISTER_G1
) ||
176 (sym
->st_value
> STO_SPARC_REGISTER_G7
)) {
177 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_BADREG
),
178 ifl
->ifl_name
, symsecname
, symndx
, EC_XWORD(sym
->st_value
));
179 return ((const char *)S_ERROR
);
183 * A register symbol can only be undefined or defined (absolute).
185 if ((shndx
!= SHN_ABS
) && (shndx
!= SHN_UNDEF
)) {
186 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_BADREG
),
187 ifl
->ifl_name
, symsecname
, symndx
, EC_XWORD(sym
->st_value
));
188 return ((const char *)S_ERROR
);
192 * Determine whether this is a scratch (unnamed) definition.
194 if (sym
->st_name
== 0) {
196 * Check for bogus scratch register definitions.
198 if ((ELF_ST_BIND(sym
->st_info
) != STB_GLOBAL
) ||
199 (shndx
!= SHN_UNDEF
)) {
200 Conv_inv_buf_t inv_buf
;
202 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYM_BADSCRATCH
),
203 ifl
->ifl_name
, symsecname
, symndx
,
204 conv_sym_SPARC_value(sym
->st_value
, 0, &inv_buf
));
205 return ((const char *)S_ERROR
);
209 * Fabricate a name for this register so that this definition
210 * can be processed through the symbol resolution engine.
212 name
= registers
[sym
->st_value
];
214 name
= strs
+ sym
->st_name
;
217 * Indicate we're dealing with a register and return its name.
219 *flags
|= FLG_SY_REGSYM
;
224 ld_reg_find_sparc(Sym
*sym
, Ofl_desc
*ofl
)
226 if (ofl
->ofl_regsyms
== NULL
)
229 return (ofl
->ofl_regsyms
[sym
->st_value
]);
233 ld_reg_enter_sparc(Sym_desc
*sdp
, Ofl_desc
*ofl
)
235 if (ofl
->ofl_regsyms
== NULL
) {
237 ofl
->ofl_regsymsno
= STO_SPARC_REGISTER_G7
+ 1;
239 if ((ofl
->ofl_regsyms
= libld_calloc(sizeof (Sym_desc
*),
240 ofl
->ofl_regsymsno
)) == NULL
) {
241 ofl
->ofl_flags
|= FLG_OF_FATAL
;
246 ofl
->ofl_regsyms
[sdp
->sd_sym
->st_value
] = sdp
;