- Fix the handling of R_SPARC_OLO10, which is a bit of a special case
in the way we implement handling of relocations. As for the kernel part this fixes the loading of lots of modules, which failed to load due to unresolvable symbols when built after the GCC 4.2.0 import. This wasn't due to a change in GCC itself though but one of several changes in configuration done along the import. Specfically, HAVE_AS_REGISTER_PSEUDO_OP, which causes GCC to denote global registers used for scratch purposes and in turn GAS uses R_SPARC_OLO10 relocations for, is now defined. While at it replace some more ELF_R_TYPE which should have been ELF64_R_TYPE_ID but didn't cause problems so far. - Sync a sanity check between kernel and rtld(1) and change it to be maintenance free regarding the type used for the lookup table. - Sprinkle const on lookup tables. - Use __FBSDID. Reported and tested by: yongari MFC after: 5 days
This commit is contained in:
parent
4251babd0a
commit
77ddefb873
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=172708
@ -35,10 +35,11 @@
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -73,7 +74,7 @@
|
||||
#define _RF_U 0x04000000 /* Unaligned */
|
||||
#define _RF_SZ(s) (((s) & 0xff) << 8) /* memory target size */
|
||||
#define _RF_RS(s) ( (s) & 0xff) /* right shift */
|
||||
static int reloc_target_flags[] = {
|
||||
static const int reloc_target_flags[] = {
|
||||
0, /* NONE */
|
||||
_RF_S|_RF_A| _RF_SZ(8) | _RF_RS(0), /* RELOC_8 */
|
||||
_RF_S|_RF_A| _RF_SZ(16) | _RF_RS(0), /* RELOC_16 */
|
||||
@ -157,7 +158,7 @@ static const char *reloc_names[] = {
|
||||
#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
|
||||
#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
|
||||
|
||||
static long reloc_target_bitmask[] = {
|
||||
static const long reloc_target_bitmask[] = {
|
||||
#define _BM(x) (~(-(1ULL << (x))))
|
||||
0, /* NONE */
|
||||
_BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */
|
||||
@ -173,7 +174,7 @@ static long reloc_target_bitmask[] = {
|
||||
_BM(22), _BM(10), /* _HIPLT22, LOPLT10 */
|
||||
_BM(32), _BM(22), _BM(10), /* _PCPLT32, _PCPLT22, _PCPLT10 */
|
||||
_BM(10), _BM(11), -1, /* _10, _11, _64 */
|
||||
_BM(10), _BM(22), /* _OLO10, _HH22 */
|
||||
_BM(13), _BM(22), /* _OLO10, _HH22 */
|
||||
_BM(10), _BM(22), /* _HM10, _LM22 */
|
||||
_BM(22), _BM(10), _BM(22), /* _PC_HH22, _PC_HM10, _PC_LM22 */
|
||||
_BM(16), _BM(19), /* _WDISP16, _WDISP19 */
|
||||
@ -296,7 +297,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache)
|
||||
defobj = NULL;
|
||||
def = NULL;
|
||||
|
||||
type = ELF_R_TYPE(rela->r_info);
|
||||
type = ELF64_R_TYPE_ID(rela->r_info);
|
||||
if (type == R_SPARC_NONE)
|
||||
return (0);
|
||||
|
||||
@ -311,7 +312,8 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache)
|
||||
/*
|
||||
* Note: R_SPARC_UA16 must be numerically largest relocation type.
|
||||
*/
|
||||
if (type > R_SPARC_UA16)
|
||||
if (type >= sizeof(reloc_target_bitmask) /
|
||||
sizeof(*reloc_target_bitmask))
|
||||
return (-1);
|
||||
|
||||
value = rela->r_addend;
|
||||
@ -342,6 +344,9 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache)
|
||||
value += (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
}
|
||||
|
||||
if (type == R_SPARC_OLO10)
|
||||
value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
|
||||
|
||||
if (RELOC_PC_RELATIVE(type))
|
||||
value -= (Elf_Addr)where;
|
||||
|
||||
@ -411,7 +416,7 @@ reloc_plt(Obj_Entry *obj)
|
||||
for (rela = obj->pltrela; rela < relalim; rela++) {
|
||||
if (rela->r_addend == 0)
|
||||
continue;
|
||||
assert(ELF_R_TYPE(rela->r_info) == R_SPARC_JMP_SLOT);
|
||||
assert(ELF64_R_TYPE_ID(rela->r_info) == R_SPARC_JMP_SLOT);
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
|
||||
true, NULL);
|
||||
@ -455,7 +460,7 @@ reloc_jmpslots(Obj_Entry *obj)
|
||||
|
||||
relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
|
||||
for (rela = obj->pltrela; rela < relalim; rela++) {
|
||||
assert(ELF_R_TYPE(rela->r_info) == R_SPARC_JMP_SLOT);
|
||||
assert(ELF64_R_TYPE_ID(rela->r_info) == R_SPARC_JMP_SLOT);
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
|
||||
true, NULL);
|
||||
|
@ -36,9 +36,11 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* from: NetBSD: mdreloc.c,v 1.5 2001/04/25 12:24:51 kleink Exp
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
@ -58,7 +60,7 @@
|
||||
|
||||
#include "linker_if.h"
|
||||
|
||||
struct sysentvec elf64_freebsd_sysvec = {
|
||||
static struct sysentvec elf64_freebsd_sysvec = {
|
||||
SYS_MAXSYSCALL,
|
||||
sysent,
|
||||
0,
|
||||
@ -147,7 +149,7 @@ elf64_dump_thread(struct thread *td __unused, void *dst __unused,
|
||||
#define _RF_U 0x04000000 /* Unaligned */
|
||||
#define _RF_SZ(s) (((s) & 0xff) << 8) /* memory target size */
|
||||
#define _RF_RS(s) ( (s) & 0xff) /* right shift */
|
||||
static int reloc_target_flags[] = {
|
||||
static const int reloc_target_flags[] = {
|
||||
0, /* NONE */
|
||||
_RF_S|_RF_A| _RF_SZ(8) | _RF_RS(0), /* RELOC_8 */
|
||||
_RF_S|_RF_A| _RF_SZ(16) | _RF_RS(0), /* RELOC_16 */
|
||||
@ -231,7 +233,7 @@ static const char *reloc_names[] = {
|
||||
#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
|
||||
#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
|
||||
|
||||
static long reloc_target_bitmask[] = {
|
||||
static const long reloc_target_bitmask[] = {
|
||||
#define _BM(x) (~(-(1ULL << (x))))
|
||||
0, /* NONE */
|
||||
_BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */
|
||||
@ -247,7 +249,7 @@ static long reloc_target_bitmask[] = {
|
||||
_BM(22), _BM(10), /* _HIPLT22, LOPLT10 */
|
||||
_BM(32), _BM(22), _BM(10), /* _PCPLT32, _PCPLT22, _PCPLT10 */
|
||||
_BM(10), _BM(11), -1, /* _10, _11, _64 */
|
||||
_BM(10), _BM(22), /* _OLO10, _HH22 */
|
||||
_BM(13), _BM(22), /* _OLO10, _HH22 */
|
||||
_BM(10), _BM(22), /* _HM10, _LM22 */
|
||||
_BM(22), _BM(10), _BM(22), /* _PC_HH22, _PC_HM10, _PC_LM22 */
|
||||
_BM(16), _BM(19), /* _WDISP16, _WDISP19 */
|
||||
@ -273,7 +275,7 @@ elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
|
||||
return (-1);
|
||||
|
||||
rela = (const Elf_Rela *)data;
|
||||
if (ELF_R_TYPE(rela->r_info) != R_SPARC_RELATIVE)
|
||||
if (ELF64_R_TYPE_ID(rela->r_info) != R_SPARC_RELATIVE)
|
||||
return (-1);
|
||||
|
||||
value = rela->r_addend + (Elf_Addr)lf->address;
|
||||
@ -303,14 +305,15 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
|
||||
rela = (const Elf_Rela *)data;
|
||||
where = (Elf_Addr *)(relocbase + rela->r_offset);
|
||||
where32 = (Elf_Word *)where;
|
||||
rtype = ELF_R_TYPE(rela->r_info);
|
||||
rtype = ELF64_R_TYPE_ID(rela->r_info);
|
||||
symidx = ELF_R_SYM(rela->r_info);
|
||||
|
||||
if (rtype == R_SPARC_NONE || rtype == R_SPARC_RELATIVE)
|
||||
return (0);
|
||||
|
||||
if (rtype == R_SPARC_JMP_SLOT || rtype == R_SPARC_COPY ||
|
||||
rtype >= (sizeof(reloc_target_bitmask)/sizeof(long)))
|
||||
rtype >= sizeof(reloc_target_bitmask) /
|
||||
sizeof(*reloc_target_bitmask))
|
||||
return (-1);
|
||||
|
||||
if (RELOC_UNALIGNED(rtype))
|
||||
@ -325,6 +328,9 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
|
||||
value += addr;
|
||||
}
|
||||
|
||||
if (rtype == R_SPARC_OLO10)
|
||||
value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
|
||||
|
||||
if (RELOC_PC_RELATIVE(rtype))
|
||||
value -= (Elf_Addr)where;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user