aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-libc.c2
-rw-r--r--elf/dl-load.c13
-rw-r--r--elf/dl-lookup.c18
-rw-r--r--elf/dl-reloc.c8
-rw-r--r--elf/dl-runtime.c56
-rw-r--r--elf/dl-sym.c39
-rw-r--r--elf/dl-symbol.c8
-rw-r--r--elf/elf.h80
-rw-r--r--elf/rtld.c24
9 files changed, 181 insertions, 67 deletions
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index 39ccf82ed1..07aae9c8f9 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -65,7 +65,7 @@ struct do_dlsym_args
const char *name;
/* Return values of do_dlsym. */
- ElfW(Addr) loadbase;
+ lookup_t loadbase;
const ElfW(Sym) *ref;
};
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 0291bf2a74..f5d91ba6c7 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -917,11 +917,14 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
As a refinement, sometimes we have an address that we would
prefer to map such objects at; but this is only a preference,
the OS can do whatever it likes. */
- caddr_t mapat;
ElfW(Addr) mappref;
mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)
- MAP_BASE_ADDR (l));
- mapat = map_segment (mappref, maplength, c->prot, 0, c->mapoff);
+
+ /* Remember which part of the address space this object uses. */
+ l->l_map_start = map_segment (mappref, maplength, c->prot, 0,
+ c->mapoff);
+ l->l_map_end = l->l_map_start + maplength;
l->l_addr = (ElfW(Addr)) mapat - c->mapstart;
/* Change protection on the excess portion to disallow all access;
@@ -929,14 +932,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
unallocated. Then jump into the normal segment-mapping loop to
handle the portion of the segment past the end of the file
mapping. */
- __mprotect ((caddr_t) (l->l_addr + c->mapend),
+ __mprotect ((caddr_t) l->l_map_start,
loadcmds[nloadcmds - 1].allocend - c->mapend,
0);
- /* Remember which part of the address space this object uses. */
- l->l_map_start = c->mapstart + l->l_addr;
- l->l_map_end = l->l_map_start + maplength;
-
goto postmap;
}
else
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index dc4564f2c7..c38e2e81f7 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -86,7 +86,7 @@ static int
add_dependency (struct link_map *undef_map, struct link_map *map)
{
struct link_map **list;
- unsigned act;
+ unsigned int act;
unsigned int i;
int result = 0;
@@ -183,7 +183,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
/* Search loaded objects' symbol tables for a definition of the symbol
UNDEF_NAME. */
-ElfW(Addr)
+lookup_t
internal_function
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
@@ -241,7 +241,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
": symbol `", undef_name, "'\n", NULL);
*ref = current_value.s;
- return current_value.m->l_addr;
+ return LOOKUP_VALUE (current_value.m);
}
@@ -250,7 +250,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
it only considers objects which were loaded after the described
object. If there are more search lists the object described by
SKIP_MAP is only skipped. */
-ElfW(Addr)
+lookup_t
internal_function
_dl_lookup_symbol_skip (const char *undef_name,
struct link_map *undef_map, const ElfW(Sym) **ref,
@@ -328,7 +328,7 @@ _dl_lookup_symbol_skip (const char *undef_name,
": symbol `", undef_name, "' (skip)\n", NULL);
*ref = current_value.s;
- return current_value.m->l_addr;
+ return LOOKUP_VALUE (current_value.m);
}
@@ -337,7 +337,7 @@ _dl_lookup_symbol_skip (const char *undef_name,
symbol.
XXX We'll see whether we need this separate function. */
-ElfW(Addr)
+lookup_t
internal_function
_dl_lookup_versioned_symbol (const char *undef_name,
struct link_map *undef_map, const ElfW(Sym) **ref,
@@ -422,13 +422,13 @@ _dl_lookup_versioned_symbol (const char *undef_name,
"]\n", NULL);
*ref = current_value.s;
- return current_value.m->l_addr;
+ return LOOKUP_VALUE (current_value.m);
}
/* Similar to _dl_lookup_symbol_skip but takes an additional argument
with the version we are looking for. */
-ElfW(Addr)
+lookup_t
internal_function
_dl_lookup_versioned_symbol_skip (const char *undef_name,
struct link_map *undef_map,
@@ -523,7 +523,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
"] (skip)\n", NULL);
*ref = current_value.s;
- return current_value.m->l_addr;
+ return LOOKUP_VALUE (current_value.m);
}
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 4c7aabea85..d1537ec3dc 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -70,6 +70,14 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
+#define RESOLVE_MAP(ref, version, flags) \
+ (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
+ ? ((version) != NULL && (version)->hash != 0 \
+ ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
+ scope, (version), (flags)) \
+ : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope, \
+ (flags))) \
+ : l)
#define RESOLVE(ref, version, flags) \
(__builtin_expect (ELFW(ST_VISIBILITY) ((*ref)->st_other), 0) == 0 \
? ((version) != NULL && (version)->hash != 0 \
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index d76b513a27..6237afce07 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -57,6 +57,7 @@ fixup (
= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+ lookup_t result;
ElfW(Addr) value;
/* The use of `alloca' here looks ridiculous but it helps. The goal is
@@ -83,33 +84,38 @@ fixup (
if (version->hash != 0)
{
- value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l,
- &sym, l->l_scope, version,
- ELF_MACHINE_JMP_SLOT);
+ result = _dl_lookup_versioned_symbol (strtab + sym->st_name,
+ l, &sym, l->l_scope,
+ version,
+ ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
- value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
- l->l_scope, ELF_MACHINE_JMP_SLOT);
+ result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
+ l->l_scope, ELF_MACHINE_JMP_SLOT);
}
- /* Currently value contains the base load address of the object
- that defines sym. Now add in the symbol offset. */
- value = (sym ? value + sym->st_value : 0);
+ /* Currently result contains the base load address (or link map)
+ of the object that defines sym. Now add in the symbol
+ offset. */
+ value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
}
else
+ {
/* We already found the symbol. The module (and therefore its load
address) is also known. */
- value = l->l_addr + sym->st_value;
+ value = l->l_addr + sym->st_value;
+#ifdef DL_LOOKUP_RETURNS_MAP
+ result = l;
+#endif
+ }
/* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value);
/* Finally, fix up the plt itself. */
- elf_machine_fixup_plt (l, reloc, rel_addr, value);
-
- return value;
+ return elf_machine_fixup_plt (l, result, reloc, rel_addr, value);
}
#endif
@@ -124,6 +130,7 @@ profile_fixup (
{
void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
ElfW(Addr) *resultp;
+ lookup_t result;
ElfW(Addr) value;
/* The use of `alloca' here looks ridiculous but it helps. The goal is
@@ -166,27 +173,32 @@ profile_fixup (
if (version->hash != 0)
{
- value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
- l, &sym, l->l_scope,
- version,
- ELF_MACHINE_JMP_SLOT);
+ result = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+ l, &sym, l->l_scope,
+ version,
+ ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
- value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
- l->l_scope, ELF_MACHINE_JMP_SLOT);
+ result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
+ l->l_scope, ELF_MACHINE_JMP_SLOT);
}
- /* Currently value contains the base load address of the object
- that defines sym. Now add in the symbol offset. */
- value = (sym ? value + sym->st_value : 0);
+ /* Currently result contains the base load address (or link map)
+ of the object that defines sym. Now add in the symbol
+ offset. */
+ value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
}
else
+ {
/* We already found the symbol. The module (and therefore its load
address) is also known. */
value = l->l_addr + sym->st_value;
-
+#ifdef DL_LOOKUP_RETURNS_MAP
+ result = l;
+#endif
+ }
/* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value);
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 80be9544cb..84236ff993 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -1,5 +1,5 @@
/* Look up a symbol in a shared object loaded by `dlopen'.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,12 +29,12 @@ void *
internal_function
_dl_sym (void *handle, const char *name, void *who)
{
- ElfW(Addr) loadbase;
const ElfW(Sym) *ref = NULL;
+ lookup_t result;
if (handle == RTLD_DEFAULT)
/* Search the global scope. */
- loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
+ result = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
else
{
struct link_map *l, *match;
@@ -56,8 +56,8 @@ _dl_sym (void *handle, const char *name, void *who)
main program (we hope). */
match = _dl_loaded;
- loadbase = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
- 0);
+ result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
+ 0);
}
else
{
@@ -69,13 +69,13 @@ RTLD_NEXT used in code not dynamically loaded"));
while (l->l_loader)
l = l->l_loader;
- loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
- match);
+ result = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
+ match);
}
}
- if (loadbase)
- return (void *) (loadbase + ref->st_value);
+ if (result)
+ return DL_SYMBOL_ADDRESS (result, ref);
return NULL;
}
@@ -84,9 +84,9 @@ void *
internal_function
_dl_vsym (void *handle, const char *name, const char *version, void *who)
{
- ElfW(Addr) loadbase;
const ElfW(Sym) *ref = NULL;
struct r_found_version vers;
+ lookup_t result;
/* Compute hash value to the version string. */
vers.name = version;
@@ -97,8 +97,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
if (handle == RTLD_DEFAULT)
/* Search the global scope. */
- loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
- &vers, 0);
+ result = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
+ &vers, 0);
else if (handle == RTLD_NEXT)
{
struct link_map *l, *match;
@@ -118,20 +118,19 @@ RTLD_NEXT used in code not dynamically loaded"));
while (l->l_loader)
l = l->l_loader;
- loadbase = _dl_lookup_versioned_symbol_skip (name, l, &ref,
- l->l_local_scope,
- &vers, match);
+ result = _dl_lookup_versioned_symbol_skip (name, l, &ref,
+ l->l_local_scope,
+ &vers, match);
}
else
{
/* Search the scope of the given object. */
struct link_map *map = handle;
- loadbase = _dl_lookup_versioned_symbol (name, map, &ref,
- map->l_local_scope, &vers, 0);
+ result = _dl_lookup_versioned_symbol (name, map, &ref,
+ map->l_local_scope, &vers, 0);
}
- if (loadbase)
- return (void *) (loadbase + ref->st_value);
-
+ if (result)
+ return DL_SYMBOL_ADDRESS (result, ref);
return NULL;
}
diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c
index 136b10a2b5..bdd7615e48 100644
--- a/elf/dl-symbol.c
+++ b/elf/dl-symbol.c
@@ -1,5 +1,5 @@
/* Look up a symbol's run-time value in the scope of a loaded object.
- Copyright (C) 1995,96,98,99,2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96, 98, 99, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,8 +26,8 @@ ElfW(Addr)
internal_function
_dl_symbol_value (struct link_map *map, const char *name)
{
- ElfW(Addr) loadbase;
const ElfW(Sym) *ref = NULL;
- loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
- return loadbase + ref->st_value;
+ lookup_t result;
+ result = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
+ return (result ? LOOKUP_VALUE_ADDRESS (result) : 0) + ref->st_value;
}
diff --git a/elf/elf.h b/elf/elf.h
index b843011312..042dcbdb31 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1757,6 +1757,86 @@ typedef Elf32_Addr Elf32_Conflict;
/* Keep this the last entry. */
#define R_ARM_NUM 256
+/* IA-64 specific declarations. */
+
+/* Processor specific flags for the Ehdr e_flags field. */
+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
+
+/* Processor specific flags for the Phdr p_flags field. */
+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field. */
+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field. */
+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
+#define DT_IA_64_NUM 1
+
+/* IA-64 relocations. */
+#define R_IA64_NONE 0x00 /* none */
+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
+#define R_IA64_LTV32MSB 0x70 /* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB 0x71 /* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB 0x72 /* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB 0x73 /* symbol + addend, data8 LSB */
+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
+
__END_DECLS
#endif /* elf.h */
diff --git a/elf/rtld.c b/elf/rtld.c
index c3363ade31..5c3dd43abf 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -160,6 +160,8 @@ _dl_start (void *arg)
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation. */
#define RTLD_BOOTSTRAP
+#define RESOLVE_MAP(sym, version, flags) \
+ ((*(sym))->st_shndx == SHN_UNDEF ? 0 : &bootstrap_map)
#define RESOLVE(sym, version, flags) \
((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
#include "dynamic-link.h"
@@ -200,7 +202,15 @@ _dl_start (void *arg)
header table in core. Put the rest of _dl_start into a separate
function, that way the compiler cannot put accesses to the GOT
before ELF_DYNAMIC_RELOCATE. */
- return _dl_start_final (arg, &bootstrap_map, start_time);
+ {
+ ElfW(Addr) entry = _dl_start_final (arg, &bootstrap_map, start_time);
+
+#ifndef ELF_MACHINE_START_ADDRESS
+# define ELF_MACHINE_START_ADDRESS(map, start) (start)
+#endif
+
+ return ELF_MACHINE_START_ADDRESS (_dl_loaded, entry);
+ }
}
@@ -886,10 +896,16 @@ of this helper program; chances are you did not intend to run this program.\n\
for (i = 1; i < _dl_argc; ++i)
{
const ElfW(Sym) *ref = NULL;
- ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], _dl_loaded,
- &ref, _dl_loaded->l_scope,
- ELF_MACHINE_JMP_SLOT);
+ ElfW(Addr) loadbase;
+ lookup_t result;
char buf[20], *bp;
+
+ result = _dl_lookup_symbol (_dl_argv[i], _dl_loaded,
+ &ref, _dl_loaded->l_scope,
+ ELF_MACHINE_JMP_SLOT);
+
+ loadbase = LOOKUP_VALUE_ADDRESS (result);
+
buf[sizeof buf - 1] = '\0';
bp = _itoa_word (ref->st_value, &buf[sizeof buf - 1], 16, 0);
while ((size_t) (&buf[sizeof buf - 1] - bp) < sizeof loadbase * 2)