diff options
author | ab196087 <none@none> | 2007-10-05 09:04:23 -0700 |
---|---|---|
committer | ab196087 <none@none> | 2007-10-05 09:04:23 -0700 |
commit | f3324781c875e2f9865c291e43f86ee710b0c145 (patch) | |
tree | e40126b8346b53e3502d08b7e962e34e44e77fb4 | |
parent | 8259acd8641e32a891a4ad20a6479c529bb052c3 (diff) | |
download | illumos-joyent-f3324781c875e2f9865c291e43f86ee710b0c145.tar.gz |
6610591 do_reloc() should not require unused arguments
35 files changed, 391 insertions, 212 deletions
diff --git a/usr/src/cmd/sgs/include/_libelf.h b/usr/src/cmd/sgs/include/_libelf.h index 78098ed8c7..2fda0edcbf 100644 --- a/usr/src/cmd/sgs/include/_libelf.h +++ b/usr/src/cmd/sgs/include/_libelf.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,6 +44,7 @@ extern "C" { extern Elf64_Off _elf_getxoff(Elf_Data *); extern GElf_Xword _gelf_getdyndtflags_1(Elf *elf); +extern uint_t _elf_sys_encoding(void); #ifdef __cplusplus } diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h index fd5204a1bf..d7a6590fa5 100644 --- a/usr/src/cmd/sgs/include/libld.h +++ b/usr/src/cmd/sgs/include/libld.h @@ -360,7 +360,8 @@ struct ofl_desc { /* section */ #define FLG_OF1_MEMORY 0x00200000 /* produce a memory model */ #define FLG_OF1_RLXREL 0x00400000 /* -z relaxreloc flag set */ - +#define FLG_OF1_ENCDIFF 0x00800000 /* Host running linker has different */ + /* byte order than output object */ #define FLG_OF1_VADDR 0x01000000 /* vaddr was explicitly set */ #define FLG_OF1_EXTRACT 0x02000000 /* archive member has been extracted */ #define FLG_OF1_RESCAN 0x04000000 /* any archives should be rescanned */ @@ -376,7 +377,7 @@ struct ofl_desc { * Test to see if the output file would allow the presence of * a .dynsym section. */ -#define OFL_ALLOW_DYNSYM(ofl) ((ofl->ofl_flags & \ +#define OFL_ALLOW_DYNSYM(_ofl) (((_ofl)->ofl_flags & \ (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC) /* @@ -386,10 +387,26 @@ struct ofl_desc { * even if the answer is True (1), we will only generate one if there * are local symbols that require it. */ -#define OFL_ALLOW_LDYNSYM(ofl) ((ofl->ofl_flags & \ +#define OFL_ALLOW_LDYNSYM(_ofl) (((_ofl)->ofl_flags & \ (FLG_OF_DYNAMIC | FLG_OF_RELOBJ | FLG_OF_NOLDYNSYM)) == FLG_OF_DYNAMIC) /* + * Test to see if relocation processing should be done. This is normally + * true, but can be disabled via the '-z noreloc' option. Note that + * relocatable objects are still relocated even if '-z noreloc' is present. + */ +#define OFL_DO_RELOC(_ofl) (((_ofl)->ofl_flags & FLG_OF_RELOBJ) || \ + !((_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. */ diff --git a/usr/src/cmd/sgs/libelf/common/llib-lelf b/usr/src/cmd/sgs/libelf/common/llib-lelf index abea0b7b0a..1e33d62c3d 100644 --- a/usr/src/cmd/sgs/libelf/common/llib-lelf +++ b/usr/src/cmd/sgs/libelf/common/llib-lelf @@ -22,7 +22,7 @@ /* PROTOLIB1 */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -185,3 +185,4 @@ int nlist(const char *, struct nlist *); * Private Symbols */ Elf64_Off _elf_getxoff(Elf_Data *); +uint_t _elf_sys_encoding(void); diff --git a/usr/src/cmd/sgs/libelf/common/mapfile-common b/usr/src/cmd/sgs/libelf/common/mapfile-common index b7166ee056..b1c1499c43 100644 --- a/usr/src/cmd/sgs/libelf/common/mapfile-common +++ b/usr/src/cmd/sgs/libelf/common/mapfile-common @@ -167,6 +167,7 @@ SUNWprivate_1.1 { _elf_getscn = NODYNSORT; _elf32_getshdr = NODYNSORT; _elf_hash = NODYNSORT; + _elf_sys_encoding; _elf_kind = NODYNSORT; _elf_ndxscn = NODYNSORT; _elf_newdata = NODYNSORT; diff --git a/usr/src/cmd/sgs/libelf/common/xlate.m4 b/usr/src/cmd/sgs/libelf/common/xlate.m4 index 605d236baf..f7cd3beddd 100644 --- a/usr/src/cmd/sgs/libelf/common/xlate.m4 +++ b/usr/src/cmd/sgs/libelf/common/xlate.m4 @@ -798,6 +798,31 @@ _elf32_entsz(Elf *elf, Elf32_Word shtype, unsigned ver) /* + * Determine the data encoding used by the current system. + */ +uint_t +_elf_sys_encoding(void) +{ + union { + Elf32_Word w; + unsigned char c[W_sizeof]; + } u; + + u.w = 0x10203; + /*CONSTANTCONDITION*/ + if (~(Elf32_Word)0 == -(Elf32_Sword)1 && tomw(u.c, W_L) == 0x10203) + return (ELFDATA2LSB); + + /*CONSTANTCONDITION*/ + if (~(Elf32_Word)0 == -(Elf32_Sword)1 && tomw(u.c, W_M) == 0x10203) + return (ELFDATA2MSB); + + /* Not expected to occur */ + return (ELFDATANONE); +} + + +/* * XX64 This routine is also used to 'version' interactions with Elf64 * applications, but there's no way to figure out if the caller is * asking Elf32 or Elf64 questions, even though it has Elf32 @@ -807,13 +832,6 @@ unsigned elf_version(unsigned ver) { register unsigned j; - union - { - Elf32_Word w; - unsigned char c[W_sizeof]; - } u; - - if (ver == EV_NONE) return EV_CURRENT; @@ -832,15 +850,7 @@ elf_version(unsigned ver) } _elf_work = ver; - u.w = 0x10203; - /*CONSTANTCONDITION*/ - if (~(Elf32_Word)0 == -(Elf32_Sword)1 - && tomw(u.c, W_L) == 0x10203) - _elf_encode = ELFDATA2LSB; - /*CONSTANTCONDITION*/ - else if (~(Elf32_Word)0 == -(Elf32_Sword)1 - && tomw(u.c, W_M) == 0x10203) - _elf_encode = ELFDATA2MSB; + _elf_encode = _elf_sys_encoding(); (void) mutex_unlock(&_elf_globals_mutex); diff --git a/usr/src/cmd/sgs/libld/Makefile.com b/usr/src/cmd/sgs/libld/Makefile.com index 2bb0f77183..e9914c6d9a 100644 --- a/usr/src/cmd/sgs/libld/Makefile.com +++ b/usr/src/cmd/sgs/libld/Makefile.com @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -74,7 +74,7 @@ package := DLLIB = $(VAR_PKG_DL_LIB) CPPFLAGS += -DUSE_LIBLD_MALLOC -I$(SRCBASE)/lib/libc/inc \ -I$(SRCBASE)/uts/common/krtld -I$(ELFCAP) \ - $(VAR_LIBLD_CPPFLAGS) + $(VAR_LIBLD_CPPFLAGS) -DDO_RELOC_LIBLD LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(LDDBGLIBDIR) $(LDDBG_LIB) \ $(ELFLIBDIR) -lelf $(DLLIB) -lc diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h index 6bb33e9fcf..47f8c98f04 100644 --- a/usr/src/cmd/sgs/libld/common/_libld.h +++ b/usr/src/cmd/sgs/libld/common/_libld.h @@ -330,6 +330,7 @@ extern Sdf_desc *sdf_find(const char *, List *); #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_disp_errmsg ld64_disp_errmsg @@ -427,6 +428,7 @@ extern Sdf_desc *sdf_find(const char *, List *); #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_disp_errmsg ld32_disp_errmsg @@ -531,6 +533,7 @@ extern uintptr_t ld_assign_got_TLS(Boolean, Rel_desc *, Ofl_desc *, 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 *); diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c index 850ceb4687..cc86d42312 100644 --- a/usr/src/cmd/sgs/libld/common/args.c +++ b/usr/src/cmd/sgs/libld/common/args.c @@ -530,6 +530,15 @@ check_flags(Ofl_desc * ofl, int argc) return (S_ERROR); /* + * Does the host currently running the linker have the same + * byte order as the target for which the object is being produced? + * If not, set FLG_OF1_ENCDIFF so relocation code will know + * to check. + */ + if (_elf_sys_encoding() != M_DATA) + ofl->ofl_flags1 |= FLG_OF1_ENCDIFF; + + /* * Initialize string tables. Symbol definitions within mapfiles can * result in the creation of input sections. */ diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index 49bf850b7b..57cc49bcd6 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -225,6 +225,8 @@ 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: \ diff --git a/usr/src/cmd/sgs/libld/common/machrel.amd.c b/usr/src/cmd/sgs/libld/common/machrel.amd.c index f2dbff3758..145367896b 100644 --- a/usr/src/cmd/sgs/libld/common/machrel.amd.c +++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c @@ -111,8 +111,7 @@ plt_entry(Ofl_desc * ofl, Sym_desc * sdp) Sword plt_off; Word got_off; Xword val1; - Word flags = ofl->ofl_flags; - Word dtflags1 = ofl->ofl_dtflags_1; + int bswap; got_off = sdp->sd_aux->sa_PLTGOTndx * M_GOT_ENTSIZE; plt_off = M_PLT_RESERVSZ + ((sdp->sd_aux->sa_PLTndx - 1) * @@ -130,6 +129,21 @@ plt_entry(Ofl_desc * ofl, Sym_desc * sdp) M_PLT_INSSIZE; /* + * If '-z noreloc' is specified - skip the do_reloc_ld + * stage. + */ + if (!OFL_DO_RELOC(ofl)) + 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) * @@ -138,20 +152,12 @@ plt_entry(Ofl_desc * ofl, Sym_desc * sdp) val1 = (ofl->ofl_osgot->os_shdr->sh_addr + got_off) - (ofl->ofl_osplt->os_shdr->sh_addr + plt_off) - 0x06; - /* - * If '-z noreloc' is specified - skip the do_reloc - * stage. - */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc(R_AMD64_GOTPCREL, &pltent[0x02], - &val1, MSG_ORIG(MSG_SYM_PLTENT), - MSG_ORIG(MSG_SPECFIL_PLTENT), ofl->ofl_lml) == 0) { - eprintf(ofl->ofl_lml, ERR_FATAL, - MSG_INTL(MSG_PLT_PLTNFAIL), sdp->sd_aux->sa_PLTndx, - demangle(sdp->sd_name)); - return (S_ERROR); - } + if (do_reloc_ld(R_AMD64_GOTPCREL, &pltent[0x02], + &val1, MSG_ORIG(MSG_SYM_PLTENT), + MSG_ORIG(MSG_SPECFIL_PLTENT), bswap, ofl->ofl_lml) == 0) { + eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL), + sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name)); + return (S_ERROR); } /* @@ -159,47 +165,34 @@ plt_entry(Ofl_desc * ofl, Sym_desc * sdp) * pushq $pltndx */ val1 = (Xword)(sdp->sd_aux->sa_PLTndx - 1); - /* - * If '-z noreloc' is specified - skip the do_reloc - * stage. - */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc(R_AMD64_32, &pltent[0x07], - &val1, MSG_ORIG(MSG_SYM_PLTENT), - MSG_ORIG(MSG_SPECFIL_PLTENT), ofl->ofl_lml) == 0) { - eprintf(ofl->ofl_lml, ERR_FATAL, - MSG_INTL(MSG_PLT_PLTNFAIL), sdp->sd_aux->sa_PLTndx, - demangle(sdp->sd_name)); - return (S_ERROR); - } + + if (do_reloc_ld(R_AMD64_32, &pltent[0x07], + &val1, MSG_ORIG(MSG_SYM_PLTENT), + MSG_ORIG(MSG_SPECFIL_PLTENT), bswap, ofl->ofl_lml) == 0) { + eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL), + sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name)); + return (S_ERROR); } /* * patchup: * jmpq .plt0(%rip) - * NOTE: 0x10 represents next instruction. The rather complex series - * of casts is necessary to sign extend an offset into a 64-bit value - * while satisfying various compiler error checks. Handle with care. + * NOTE: 0x10 represents next instruction. The rather complex + * series of casts is necessary to sign extend an offset into + * a 64-bit value while satisfying various compiler error + * checks. Handle with care. */ val1 = (Xword)((intptr_t)((uintptr_t)plt0 - (uintptr_t)(&pltent[0x10]))); - /* - * If '-z noreloc' is specified - skip the do_reloc - * stage. - */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc(R_AMD64_PC32, &pltent[0x0c], - &val1, MSG_ORIG(MSG_SYM_PLTENT), - MSG_ORIG(MSG_SPECFIL_PLTENT), ofl->ofl_lml) == 0) { - eprintf(ofl->ofl_lml, ERR_FATAL, - MSG_INTL(MSG_PLT_PLTNFAIL), sdp->sd_aux->sa_PLTndx, - demangle(sdp->sd_name)); - return (S_ERROR); - } + if (do_reloc_ld(R_AMD64_PC32, &pltent[0x0c], + &val1, MSG_ORIG(MSG_SYM_PLTENT), + MSG_ORIG(MSG_SPECFIL_PLTENT), bswap, ofl->ofl_lml) == 0) { + eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL), + sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name)); + return (S_ERROR); } + return (1); } @@ -608,7 +601,6 @@ ld_do_activerelocs(Ofl_desc *ofl) Listnode *lnp; uintptr_t return_code = 1; Word flags = ofl->ofl_flags; - Word dtflags1 = ofl->ofl_dtflags_1; if (ofl->ofl_actrels.head) DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml)); @@ -822,7 +814,11 @@ ld_do_activerelocs(Ofl_desc *ofl) /* * And do it. */ - *(Xword *)R2addr = value; + if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) + *(Xword *)R2addr = + ld_byteswap_Xword(value); + else + *(Xword *)R2addr = value; continue; } else if (IS_GOT_BASED(arsp->rel_rtype) && @@ -969,13 +965,19 @@ ld_do_activerelocs(Ofl_desc *ofl) value -= *addr; /* - * If '-z noreloc' is specified - skip the do_reloc + * If '-z noreloc' is specified - skip the do_reloc_ld * stage. */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc((uchar_t)arsp->rel_rtype, + if (OFL_DO_RELOC(ofl)) { + /* + * If this is a PROGBITS section and the + * running linker has a different byte order + * than the target host, tell do_reloc_ld() + * to swap bytes. + */ + if (do_reloc_ld((uchar_t)arsp->rel_rtype, addr, &value, arsp->rel_sname, ifl_name, + OFL_SWAP_RELOC_DATA(ofl, arsp), ofl->ofl_lml) == 0) return_code = S_ERROR; } @@ -1454,9 +1456,6 @@ static uchar_t plt0_template[M_PLT_ENTSIZE] = { uintptr_t ld_fillin_gotplt(Ofl_desc *ofl) { - Word flags = ofl->ofl_flags; - Word dtflags1 = ofl->ofl_dtflags_1; - if (ofl->ofl_osgot) { Sym_desc *sdp; @@ -1481,14 +1480,31 @@ ld_fillin_gotplt(Ofl_desc *ofl) * 0x0e NOP * 0x0f NOP */ - if ((flags & FLG_OF_DYNAMIC) && ofl->ofl_osplt) { + 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)); /* + * If '-z noreloc' is specified - skip the do_reloc_ld + * stage. + */ + if (!OFL_DO_RELOC(ofl)) + 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) * @@ -1500,19 +1516,12 @@ ld_fillin_gotplt(Ofl_desc *ofl) (M_GOT_XLINKMAP * M_GOT_ENTSIZE) - ofl->ofl_osplt->os_shdr->sh_addr - 0x06; - /* - * If '-z noreloc' is specified - skip the do_reloc - * stage. - */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc(R_AMD64_GOTPCREL, &pltent[0x02], - &val1, MSG_ORIG(MSG_SYM_PLTENT), - MSG_ORIG(MSG_SPECFIL_PLTENT), ofl->ofl_lml) == 0) { - eprintf(ofl->ofl_lml, ERR_FATAL, - MSG_INTL(MSG_PLT_PLT0FAIL)); - return (S_ERROR); - } + if (do_reloc_ld(R_AMD64_GOTPCREL, &pltent[0x02], + &val1, MSG_ORIG(MSG_SYM_PLTENT), + MSG_ORIG(MSG_SPECFIL_PLTENT), bswap, ofl->ofl_lml) == 0) { + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_PLT_PLT0FAIL)); + return (S_ERROR); } /* @@ -1522,20 +1531,15 @@ ld_fillin_gotplt(Ofl_desc *ofl) val1 = (ofl->ofl_osgot->os_shdr->sh_addr) + (M_GOT_XRTLD * M_GOT_ENTSIZE) - ofl->ofl_osplt->os_shdr->sh_addr - 0x0c; - /* - * If '-z noreloc' is specified - skip the do_reloc - * stage. - */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc(R_AMD64_GOTPCREL, &pltent[0x08], - &val1, MSG_ORIG(MSG_SYM_PLTENT), - MSG_ORIG(MSG_SPECFIL_PLTENT), ofl->ofl_lml) == 0) { - eprintf(ofl->ofl_lml, ERR_FATAL, - MSG_INTL(MSG_PLT_PLT0FAIL)); - return (S_ERROR); - } + + if (do_reloc_ld(R_AMD64_GOTPCREL, &pltent[0x08], + &val1, MSG_ORIG(MSG_SYM_PLTENT), + MSG_ORIG(MSG_SPECFIL_PLTENT), bswap, ofl->ofl_lml) == 0) { + eprintf(ofl->ofl_lml, ERR_FATAL, + MSG_INTL(MSG_PLT_PLT0FAIL)); + return (S_ERROR); } } + return (1); } diff --git a/usr/src/cmd/sgs/libld/common/machrel.intel.c b/usr/src/cmd/sgs/libld/common/machrel.intel.c index 6f2272b992..33a828be25 100644 --- a/usr/src/cmd/sgs/libld/common/machrel.intel.c +++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c @@ -647,7 +647,6 @@ ld_do_activerelocs(Ofl_desc *ofl) Listnode *lnp; uintptr_t return_code = 1; Word flags = ofl->ofl_flags; - Word dtflags1 = ofl->ofl_dtflags_1; if (ofl->ofl_actrels.head) DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml)); @@ -847,7 +846,11 @@ ld_do_activerelocs(Ofl_desc *ofl) /* * And do it. */ - *(Xword *)R2addr = value; + if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) + *(Xword *)R2addr = + ld_byteswap_Xword(value); + else + *(Xword *)R2addr = value; continue; } else if (IS_GOT_BASED(arsp->rel_rtype) && @@ -984,13 +987,13 @@ ld_do_activerelocs(Ofl_desc *ofl) value -= *addr; /* - * If '-z noreloc' is specified - skip the do_reloc + * If '-z noreloc' is specified - skip the do_reloc_ld * stage. */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc((uchar_t)arsp->rel_rtype, addr, + if (OFL_DO_RELOC(ofl)) { + if (do_reloc_ld((uchar_t)arsp->rel_rtype, addr, &value, arsp->rel_sname, ifl_name, + OFL_SWAP_RELOC_DATA(ofl, arsp), ofl->ofl_lml) == 0) return_code = S_ERROR; } diff --git a/usr/src/cmd/sgs/libld/common/machrel.sparc.c b/usr/src/cmd/sgs/libld/common/machrel.sparc.c index c9ada3391e..8abe4f5ca2 100644 --- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c +++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c @@ -938,7 +938,6 @@ ld_do_activerelocs(Ofl_desc *ofl) Listnode *lnp; uintptr_t return_code = 1; Word flags = ofl->ofl_flags; - Word dtflags1 = ofl->ofl_dtflags_1; if (ofl->ofl_actrels.head) DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml)); @@ -1149,7 +1148,11 @@ ld_do_activerelocs(Ofl_desc *ofl) /* * And do it. */ - *(Xword *)R2addr = value; + if (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) + *(Xword *)R2addr = + ld_byteswap_Xword(value); + else + *(Xword *)R2addr = value; continue; } else if (IS_GOT_BASED(arsp->rel_rtype) && @@ -1273,10 +1276,10 @@ ld_do_activerelocs(Ofl_desc *ofl) * If '-z noreloc' is specified - skip the do_reloc * stage. */ - if ((flags & FLG_OF_RELOBJ) || - !(dtflags1 & DF_1_NORELOC)) { - if (do_reloc((uchar_t)arsp->rel_rtype, addr, + if (OFL_DO_RELOC(ofl)) { + if (do_reloc_ld((uchar_t)arsp->rel_rtype, addr, &value, arsp->rel_sname, ifl_name, + OFL_SWAP_RELOC_DATA(ofl, arsp), ofl->ofl_lml) == 0) return_code = S_ERROR; } diff --git a/usr/src/cmd/sgs/libld/common/relocate.c b/usr/src/cmd/sgs/libld/common/relocate.c index 74fcd5839f..2a98c8c1ed 100644 --- a/usr/src/cmd/sgs/libld/common/relocate.c +++ b/usr/src/cmd/sgs/libld/common/relocate.c @@ -503,6 +503,31 @@ ld_add_actrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl) 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 + * the running linker has the opposite byte order of the object being + * produced. + */ +Xword +ld_byteswap_Xword(Xword 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 +} + + uintptr_t ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) { diff --git a/usr/src/cmd/sgs/librtld/amd64/_relocate.c b/usr/src/cmd/sgs/librtld/amd64/_relocate.c index 26dbc9ba2d..1feb03939a 100644 --- a/usr/src/cmd/sgs/librtld/amd64/_relocate.c +++ b/usr/src/cmd/sgs/librtld/amd64/_relocate.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -137,7 +137,7 @@ apply_reloc(void *vrel, Reloc *reloc, const char *name, uchar_t *oaddr, (void) memcpy((void *)oaddr, (void *)value, (size_t)reloc->r_size); } else { - (void) do_reloc(type, oaddr, &value, reloc->r_name, name, + (void) do_reloc_rtld(type, oaddr, &value, reloc->r_name, name, LIST(lmp)); } } diff --git a/usr/src/cmd/sgs/librtld/common/mapfile-32-vers b/usr/src/cmd/sgs/librtld/common/mapfile-32-vers index 8fc21079ce..b7466f02a9 100644 --- a/usr/src/cmd/sgs/librtld/common/mapfile-32-vers +++ b/usr/src/cmd/sgs/librtld/common/mapfile-32-vers @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,6 +28,6 @@ { global: - do32_reloc = FUNCTION parent; - reloc32_table = DATA parent; + do32_reloc_rtld = FUNCTION parent; + reloc32_table = DATA parent; }; diff --git a/usr/src/cmd/sgs/librtld/common/mapfile-64-vers b/usr/src/cmd/sgs/librtld/common/mapfile-64-vers index 88a09d216c..894f3bd3d7 100644 --- a/usr/src/cmd/sgs/librtld/common/mapfile-64-vers +++ b/usr/src/cmd/sgs/librtld/common/mapfile-64-vers @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,6 +28,6 @@ { global: - do64_reloc = FUNCTION parent; - reloc64_table = DATA parent; + do64_reloc_rtld = FUNCTION parent; + reloc64_table = DATA parent; }; diff --git a/usr/src/cmd/sgs/librtld/i386/_relocate.c b/usr/src/cmd/sgs/librtld/i386/_relocate.c index ebf603b088..74ca80ba7c 100644 --- a/usr/src/cmd/sgs/librtld/i386/_relocate.c +++ b/usr/src/cmd/sgs/librtld/i386/_relocate.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -137,7 +137,7 @@ apply_reloc(void *vrel, Reloc *reloc, const char *name, uchar_t *oaddr, (void) memcpy((void *)oaddr, (void *)value, (size_t)reloc->r_size); } else { - (void) do_reloc(type, oaddr, &value, reloc->r_name, name, + (void) do_reloc_rtld(type, oaddr, &value, reloc->r_name, name, LIST(lmp)); } } diff --git a/usr/src/cmd/sgs/librtld/sparc/_relocate.c b/usr/src/cmd/sgs/librtld/sparc/_relocate.c index c93a6f17d1..fd8c8de356 100644 --- a/usr/src/cmd/sgs/librtld/sparc/_relocate.c +++ b/usr/src/cmd/sgs/librtld/sparc/_relocate.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -138,7 +138,7 @@ apply_reloc(void *vrel, Reloc *reloc, const char *name, uchar_t *oaddr, } else { if (IS_EXTOFFSET(type)) value += ELF_R_TYPE_DATA(rel->r_info); - (void) do_reloc(type, oaddr, &value, reloc->r_name, name, + (void) do_reloc_rtld(type, oaddr, &value, reloc->r_name, name, LIST(lmp)); } } diff --git a/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c b/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c index c93a6f17d1..fd8c8de356 100644 --- a/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c +++ b/usr/src/cmd/sgs/librtld/sparcv9/_relocate.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -138,7 +138,7 @@ apply_reloc(void *vrel, Reloc *reloc, const char *name, uchar_t *oaddr, } else { if (IS_EXTOFFSET(type)) value += ELF_R_TYPE_DATA(rel->r_info); - (void) do_reloc(type, oaddr, &value, reloc->r_name, name, + (void) do_reloc_rtld(type, oaddr, &value, reloc->r_name, name, LIST(lmp)); } } diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 23f519a21b..01d6851d4f 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1265,3 +1265,4 @@ Bugid Risk Synopsis 6473571 strip and mcs get confused and corrupt files when passed non-ELF arguments 6253589 mcs has problems handling multiple SHT_NOTE sections +6610591 do_reloc() should not require unused arguments diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c index 6b4dae596d..5f028d72f7 100644 --- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c +++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c @@ -162,7 +162,7 @@ elf_plt_trace_write(ulong_t roffset, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, */ symvalue = (Xword)((uintptr_t)dyndata - (uintptr_t)(&dyn_plt[TRCREL1OFF]) - 4); - if (do_reloc(R_AMD64_PC32, &dyn_plt[TRCREL1OFF], + if (do_reloc_rtld(R_AMD64_PC32, &dyn_plt[TRCREL1OFF], &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -175,7 +175,7 @@ elf_plt_trace_write(ulong_t roffset, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, * R_AMD64_64 0x15 0 elf_plt_trace */ symvalue = (Xword)elf_plt_trace; - if (do_reloc(R_AMD64_64, &dyn_plt[TRCREL2OFF], + if (do_reloc_rtld(R_AMD64_64, &dyn_plt[TRCREL2OFF], &symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -1023,7 +1023,7 @@ elf_reloc(Rt_map *lmp, uint_t plt) /* * Write the relocation out. */ - if (do_reloc(rtype, (uchar_t *)roffset, + if (do_reloc_rtld(rtype, (uchar_t *)roffset, (Xword *)&value, name, NAME(lmp), LIST(lmp)) == 0) ret = 0; diff --git a/usr/src/cmd/sgs/rtld/common/mapfile-32-vers b/usr/src/cmd/sgs/rtld/common/mapfile-32-vers index 3e5589f19a..bfb3b00315 100644 --- a/usr/src/cmd/sgs/rtld/common/mapfile-32-vers +++ b/usr/src/cmd/sgs/rtld/common/mapfile-32-vers @@ -28,6 +28,6 @@ SUNWprivate_1.2 { protected: - do32_reloc; # Required to support librtld.so + do32_reloc_rtld; # Required to support librtld.so reloc32_table; }; diff --git a/usr/src/cmd/sgs/rtld/common/mapfile-64-vers b/usr/src/cmd/sgs/rtld/common/mapfile-64-vers index 158caeac61..8b0592363f 100644 --- a/usr/src/cmd/sgs/rtld/common/mapfile-64-vers +++ b/usr/src/cmd/sgs/rtld/common/mapfile-64-vers @@ -28,6 +28,6 @@ SUNWprivate_1.2 { protected: - do64_reloc; # Required to support librtld.so + do64_reloc_rtld; # Required to support librtld.so reloc64_table; }; diff --git a/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg b/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg index 124f28ffe8..828789fe7d 100644 --- a/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg +++ b/usr/src/cmd/sgs/rtld/common/rtld.sparc.msg @@ -1,13 +1,12 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # 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. @@ -38,6 +37,8 @@ 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" diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c index e6a9744362..57b69c81da 100644 --- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c +++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c @@ -139,7 +139,7 @@ elf_plt_trace_write(uint_t roffset, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, * pushl dyn_data */ symvalue = (Word)dyndata; - if (do_reloc(R_386_32, &dyn_plt[4], &symvalue, + if (do_reloc_rtld(R_386_32, &dyn_plt[4], &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -154,7 +154,7 @@ elf_plt_trace_write(uint_t roffset, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, * jmp elf_plt_trace */ symvalue = (ulong_t)(elf_plt_trace) - (ulong_t)(dyn_plt + 9); - if (do_reloc(R_386_PC32, &dyn_plt[9], &symvalue, + if (do_reloc_rtld(R_386_PC32, &dyn_plt[9], &symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -977,8 +977,8 @@ elf_reloc(Rt_map *lmp, uint_t plt) /* * Write the relocation out. */ - if (do_reloc(rtype, (uchar_t *)roffset, (Word *)&value, - name, NAME(lmp), LIST(lmp)) == 0) + if (do_reloc_rtld(rtype, (uchar_t *)roffset, + (Word *)&value, name, NAME(lmp), LIST(lmp)) == 0) ret = 0; DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), ELF_DBG_RTLD, diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c index 3335271e77..40ecf7214a 100644 --- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c +++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c @@ -283,7 +283,7 @@ elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp, * sethi %hi(dyndata), %g1 */ symvalue = (Xword)dyndata; - if (do_reloc(R_SPARC_HI22, (uchar_t *)(dyn_plt + 0x20), + if (do_reloc_rtld(R_SPARC_HI22, (uchar_t *)(dyn_plt + 0x20), &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -295,7 +295,7 @@ elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp, * or %g1, %lo(dyndata), %g1 */ symvalue = (Xword)dyndata; - if (do_reloc(R_SPARC_LO10, (uchar_t *)(dyn_plt + 0x24), + if (do_reloc_rtld(R_SPARC_LO10, (uchar_t *)(dyn_plt + 0x24), &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -308,7 +308,7 @@ elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp, */ symvalue = (Xword)((uintptr_t)&elf_plt_trace - (dyn_plt + 0x28)); - if (do_reloc(R_SPARC_WDISP30, (uchar_t *)(dyn_plt + 0x28), + if (do_reloc_rtld(R_SPARC_WDISP30, (uchar_t *)(dyn_plt + 0x28), &symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE), MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { *fail = 1; @@ -1130,7 +1130,7 @@ elf_reloc(Rt_map *lmp, uint_t plt) } else *(uint_t *)roffset += value; } else { - if (do_reloc(rtype, (uchar_t *)roffset, + if (do_reloc_rtld(rtype, (uchar_t *)roffset, (Xword *)&value, name, NAME(lmp), LIST(lmp)) == 0) ret = 0; @@ -1138,7 +1138,8 @@ elf_reloc(Rt_map *lmp, uint_t plt) /* * The value now contains the 'bit-shifted' value that - * was or'ed into memory (this was set by do_reloc()). + * was or'ed into memory (this was set by + * do_reloc_rtld()). */ DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), ELF_DBG_RTLD, (Xword)roffset, (Xword)value)); diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c index fe0fd8239f..691bff0ebe 100644 --- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c +++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c @@ -328,7 +328,7 @@ int dyn_plt_ent_size = sizeof (dyn_plt_template) + /* * Relocate the instructions given by the VAL64_TO_G1 macro above. - * The arguments parallel those of do_reloc(). + * The arguments parallel those of do_reloc_rtld(). * * entry: * off - Address of 1st instruction in sequence. @@ -349,7 +349,7 @@ reloc_val64_to_g1(Byte *off, Addr *value, const char *sym, Lm_list *lml) * sethi %hh(value), %g5 */ tmp_value = (Xword)value; - if (do_reloc(R_SPARC_HH22, off, &tmp_value, sym, + if (do_reloc_rtld(R_SPARC_HH22, off, &tmp_value, sym, MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { return (0); } @@ -359,7 +359,7 @@ reloc_val64_to_g1(Byte *off, Addr *value, const char *sym, Lm_list *lml) * or %g5, %hm(value), %g5 */ tmp_value = (Xword)value; - if (do_reloc(R_SPARC_HM10, off + 4, &tmp_value, sym, + if (do_reloc_rtld(R_SPARC_HM10, off + 4, &tmp_value, sym, MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { return (0); } @@ -369,7 +369,7 @@ reloc_val64_to_g1(Byte *off, Addr *value, const char *sym, Lm_list *lml) * sethi %lm(value), %g1 */ tmp_value = (Xword)value; - if (do_reloc(R_SPARC_LM22, off + 12, &tmp_value, sym, + if (do_reloc_rtld(R_SPARC_LM22, off + 12, &tmp_value, sym, MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { return (0); } @@ -379,7 +379,7 @@ reloc_val64_to_g1(Byte *off, Addr *value, const char *sym, Lm_list *lml) * or %g1, %lo(value), %g1 */ tmp_value = (Xword)value; - if (do_reloc(R_SPARC_LO10, off + 16, &tmp_value, sym, + if (do_reloc_rtld(R_SPARC_LO10, off + 16, &tmp_value, sym, MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { return (0); } @@ -1394,7 +1394,7 @@ elf_reloc(Rt_map *lmp, uint_t plt) } else *(ulong_t *)roffset += value; } else { - if (do_reloc(rtype, (uchar_t *)roffset, + if (do_reloc_rtld(rtype, (uchar_t *)roffset, (Xword *)&value, name, NAME(lmp), LIST(lmp)) == 0) ret = 0; @@ -1402,7 +1402,8 @@ elf_reloc(Rt_map *lmp, uint_t plt) /* * The value now contains the 'bit-shifted' value that - * was or'ed into memory (this was set by do_reloc()). + * was or'ed into memory (this was set by + * do_reloc_rtld()). */ DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), ELF_DBG_RTLD, (Xword)roffset, (Xword)value)); diff --git a/usr/src/head/libelf.h b/usr/src/head/libelf.h index f1b7856923..394b8ce3e9 100644 --- a/usr/src/head/libelf.h +++ b/usr/src/head/libelf.h @@ -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,7 +22,7 @@ /* All Rights Reserved */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -195,6 +194,7 @@ int elf_getphnum _((Elf *, size_t *)); int elf_getshnum _((Elf *, size_t *)); int elf_getshstrndx _((Elf *, size_t *)); unsigned long elf_hash _((const char *)); +uint_t elf_sys_encoding _((void)); long elf32_checksum _((Elf *)); Elf_Kind elf_kind _((Elf *)); Elf *elf_memory _((char *, size_t)); diff --git a/usr/src/uts/common/krtld/reloc.h b/usr/src/uts/common/krtld/reloc.h index 98c0a745e2..61ebbab6a4 100644 --- a/usr/src/uts/common/krtld/reloc.h +++ b/usr/src/uts/common/krtld/reloc.h @@ -89,10 +89,12 @@ extern "C" { */ #if !defined(_KERNEL) #if defined(_ELF64) -#define do_reloc do64_reloc +#define do_reloc_ld do64_reloc_ld +#define do_reloc_rtld do64_reloc_rtld #define reloc_table reloc64_table #else -#define do_reloc do32_reloc +#define do_reloc_ld do32_reloc_ld +#define do_reloc_rtld do32_reloc_rtld #define reloc_table reloc32_table #endif #endif @@ -150,9 +152,43 @@ extern const Rel_entry reloc_table[]; /* * Relocation engine. + * + * The do_reloc() code is used in three different places: The kernel, + * the linker, and the runtime linker. All three use the same first + * 5 arguments. In addition: + * - The linker and rtld want a link map pointer argument + * - The linker wants to pass a byte swap argument that tells + * the relocation engine that the data it is relocating + * has the opposite byte order of the system running the + * linker. + * + * To ensure that there is never any confusion about which version is + * being linked to, we give each variant a different name, even though + * each one is generated from the same source code. + * + * do_reloc_krtld() + * 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. + * + * do_reloc_rtld() + * The rtld version is provided if neither _KERNEL or DO_RELOC_LIBLD + * are defined. + * + * Implementations of do_reloc() should use these same macros to + * conditionalize any code not used by all three versions. */ -extern int do_reloc(uchar_t, uchar_t *, Xword *, const char *, +#if defined(_KERNEL) +extern int do_reloc_krtld(uchar_t, uchar_t *, Xword *, const char *, + const char *); +#elif defined(DO_RELOC_LIBLD) +extern int do_reloc_ld(uchar_t, uchar_t *, Xword *, const char *, + const char *, int, void *); +#else +extern int do_reloc_rtld(uchar_t, uchar_t *, Xword *, const char *, const char *, void *); +#endif #if defined(_KERNEL) /* @@ -209,7 +245,7 @@ extern const char *conv_reloc_SPARC_type(Word); * must have errors reported through a single eprintf() call. The kernel's * _kobj_printf is somewhat more limited, and must receive messages with only * one argument to the format string. The following macros account for these - * differences, as krtld and rtld share do_reloc(). + * differences, as krtld and rtld share the same do_reloc() source. */ #define REL_ERR_UNIMPL(lml, file, sym, rtype) \ _kobj_printf(ops, MSG_REL_PREFIL, (file)); \ @@ -284,6 +320,11 @@ extern const char *demangle(const char *); ((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 diff --git a/usr/src/uts/intel/amd64/krtld/doreloc.c b/usr/src/uts/intel/amd64/krtld/doreloc.c index 788ba7e2a3..b2706d77cc 100644 --- a/usr/src/uts/intel/amd64/krtld/doreloc.c +++ b/usr/src/uts/intel/amd64/krtld/doreloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -157,13 +157,34 @@ const Rel_entry reloc_table[R_AMD64_NUM] = { #define HIBITS 0xffffffff80000000ULL -/* ARGSUSED5 */ +#if defined(_KERNEL) +#define lml 0 /* Needed by arglist of REL_ERR_* macros */ int -do_reloc(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, +do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file) +#elif defined(DO_RELOC_LIBLD) +int +do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file, int bswap, void *lml) +#else +int +do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, void *lml) +#endif { 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) { diff --git a/usr/src/uts/intel/amd64/krtld/kobj_reloc.c b/usr/src/uts/intel/amd64/krtld/kobj_reloc.c index 5cf7541f13..56c8087baa 100644 --- a/usr/src/uts/intel/amd64/krtld/kobj_reloc.c +++ b/usr/src/uts/intel/amd64/krtld/kobj_reloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -141,7 +141,7 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, #ifdef KOBJ_DEBUG if (kobj_debug & D_RELOCATIONS) { _kobj_printf(ops, "krtld:\ttype\t\t\toffset\t addend" - " symbol\n"); + " symbol\n"); _kobj_printf(ops, "krtld:\t\t\t\t\t value\n"); } #endif @@ -179,9 +179,9 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, if (kobj_debug & D_RELOCATIONS) { Sym * symp; symp = (Sym *) - (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); + (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); _kobj_printf(ops, "krtld:\t%s", - conv_reloc_amd64_type(rtype)); + conv_reloc_amd64_type(rtype)); _kobj_printf(ops, "\t0x%8llx", off); _kobj_printf(ops, " 0x%8llx", addend); _kobj_printf(ops, " %s\n", @@ -205,7 +205,7 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, * value is base address of this object */ symref = (Sym *) - (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); + (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); if (ELF_ST_BIND(symref->st_info) == STB_LOCAL) { /* *** this is different for .o and .so */ @@ -224,11 +224,8 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, if (symref->st_shndx == SHN_UNDEF && tnf_reloc_resolve(mp->strings + - symref->st_name, &symref->st_value, - &addend, - off, - &probelist, - &taglist) != 0) { + symref->st_name, &symref->st_value, + &addend, off, &probelist, &taglist) != 0) { if (ELF_ST_BIND(symref->st_info) != STB_WEAK) { _kobj_printf(ops, @@ -265,9 +262,9 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, } #endif - if (do_reloc(rtype, (unsigned char *)off, &value, + if (do_reloc_krtld(rtype, (unsigned char *)off, &value, (const char *)mp->strings + symref->st_name, - mp->filename, 0) == 0) + mp->filename) == 0) err = 1; } /* end of while loop */ @@ -290,7 +287,7 @@ do_relocations(struct module *mp) /* do the relocations */ for (shn = 1; shn < mp->hdr.e_shnum; shn++) { rshp = (Shdr *) - (mp->shdrs + shn * mp->hdr.e_shentsize); + (mp->shdrs + shn * mp->hdr.e_shentsize); if (rshp->sh_type == SHT_REL) { _kobj_printf(ops, "%s can't process type SHT_REL\n", mp->filename); diff --git a/usr/src/uts/intel/ia32/krtld/doreloc.c b/usr/src/uts/intel/ia32/krtld/doreloc.c index 8903af22f4..08195e8851 100644 --- a/usr/src/uts/intel/ia32/krtld/doreloc.c +++ b/usr/src/uts/intel/ia32/krtld/doreloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -162,13 +162,34 @@ const Rel_entry reloc_table[R_386_NUM] = { * been performed before calling this function except for the addition of * the addresses in the instructions. */ -/* ARGSUSED5 */ +#if defined(_KERNEL) +#define lml 0 /* Needed by arglist of REL_ERR_* macros */ int -do_reloc(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, +do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file) +#elif defined(DO_RELOC_LIBLD) +int +do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file, int bswap, void *lml) +#else +int +do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, void *lml) +#endif { 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) { diff --git a/usr/src/uts/intel/ia32/krtld/kobj_reloc.c b/usr/src/uts/intel/ia32/krtld/kobj_reloc.c index 53955cf08d..befd15853a 100644 --- a/usr/src/uts/intel/ia32/krtld/kobj_reloc.c +++ b/usr/src/uts/intel/ia32/krtld/kobj_reloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -175,9 +175,9 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, if (kobj_debug & D_RELOCATIONS) { Sym * symp; symp = (Sym *) - (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); + (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); _kobj_printf(ops, "krtld:\t%s", - conv_reloc_386_type(rtype)); + conv_reloc_386_type(rtype)); _kobj_printf(ops, "\t0x%8x", off); _kobj_printf(ops, " %s\n", (const char *)mp->strings + symp->st_name); @@ -200,7 +200,7 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, * value is base address of this object */ symref = (Sym *) - (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); + (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); if (ELF32_ST_BIND(symref->st_info) == STB_LOCAL) { /* *** this is different for .o and .so */ @@ -219,10 +219,8 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, if (symref->st_shndx == SHN_UNDEF && tnf_reloc_resolve(mp->strings + - symref->st_name, &symref->st_value, - off, - &probelist, - &taglist) != 0) { + symref->st_name, &symref->st_value, + off, &probelist, &taglist) != 0) { if (ELF32_ST_BIND(symref->st_info) != STB_WEAK) { _kobj_printf(ops, @@ -258,9 +256,9 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc, } #endif - if (do_reloc(rtype, (unsigned char *)off, (Word *)&value, + if (do_reloc_krtld(rtype, (unsigned char *)off, (Word *)&value, (const char *)mp->strings + symref->st_name, - mp->filename, 0) == 0) + mp->filename) == 0) err = 1; } /* end of while loop */ @@ -283,7 +281,7 @@ do_relocations(struct module *mp) /* do the relocations */ for (shn = 1; shn < mp->hdr.e_shnum; shn++) { rshp = (Shdr *) - (mp->shdrs + shn * mp->hdr.e_shentsize); + (mp->shdrs + shn * mp->hdr.e_shentsize); if (rshp->sh_type == SHT_RELA) { _kobj_printf(ops, "%s can't process type SHT_RELA\n", mp->filename); diff --git a/usr/src/uts/sparc/krtld/doreloc.c b/usr/src/uts/sparc/krtld/doreloc.c index 94f2b6c6d3..ff9864ae84 100644 --- a/usr/src/uts/sparc/krtld/doreloc.c +++ b/usr/src/uts/sparc/krtld/doreloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -344,10 +344,20 @@ const Rel_entry reloc_table[R_SPARC_NUM] = { * Upon successful completion of do_reloc() *value will be set to the * 'bit-shifted' value that will be or'ed into memory. */ -/* ARGSUSED5 */ +#if defined(_KERNEL) +#define lml 0 /* Needed by arglist of REL_ERR_* macros */ int -do_reloc(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, +do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file) +#elif defined(DO_RELOC_LIBLD) +int +do_reloc_ld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, + const char *file, int bswap, void *lml) +#else +int +do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, const char *file, void *lml) +#endif { Xword uvalue = 0; Xword basevalue, sigbit_mask, sigfit_mask; @@ -356,6 +366,17 @@ do_reloc(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, 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 + rep = &reloc_table[rtype]; bshift = rep->re_bshift; field_size = rep->re_fsize; diff --git a/usr/src/uts/sparc/krtld/kobj_reloc.c b/usr/src/uts/sparc/krtld/kobj_reloc.c index fd3846a383..eda18f35a1 100644 --- a/usr/src/uts/sparc/krtld/kobj_reloc.c +++ b/usr/src/uts/sparc/krtld/kobj_reloc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -173,7 +173,7 @@ do_relocate( #ifdef KOBJ_DEBUG if (kobj_debug & D_RELOCATIONS) { _kobj_printf(ops, "krtld:\ttype\t\t\toffset\t addend" - " symbol\n"); + " symbol\n"); _kobj_printf(ops, "krtld:\t\t\t\t\t value\n"); } #endif @@ -191,9 +191,9 @@ do_relocate( for (i = 0; i < mp->hdr.e_shnum; i++, shp++) { if (shp->sh_addr == baseaddr) { if ((shp->sh_flags & SHF_ALLOC) && - !(shp->sh_flags & SHF_WRITE)) + !(shp->sh_flags & SHF_WRITE)) destination = (Addr)mp->destination + - (baseaddr - (Addr)mp->text); + (baseaddr - (Addr)mp->text); break; } } @@ -256,7 +256,7 @@ do_relocate( * value is base address of this object */ symref = (Sym *) - (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); + (mp->symtbl+(stndx * mp->symhdr->sh_entsize)); if (ELF_ST_BIND(symref->st_info) == STB_LOCAL) { /* *** this is different for .o and .so */ value = symref->st_value; @@ -276,11 +276,8 @@ do_relocate( if (symref->st_shndx == SHN_UNDEF && tnf_reloc_resolve(mp->strings + - symref->st_name, &symref->st_value, - &addend, - off, - &probelist, - &taglist) != 0) { + symref->st_name, &symref->st_value, + &addend, off, &probelist, &taglist) != 0) { if (ELF_ST_BIND(symref->st_info) != STB_WEAK) { _kobj_printf(ops, @@ -304,7 +301,7 @@ do_relocate( value += addend; if (IS_EXTOFFSET(rtype)) { value += - (Word) ELF_R_TYPE_DATA(((Rela *)reladdr)->r_info); + (Word) ELF_R_TYPE_DATA(((Rela *)reladdr)->r_info); } /* @@ -324,9 +321,9 @@ do_relocate( _kobj_printf(ops, " 0x%8llx\n", value); } #endif - if (do_reloc(rtype, (unsigned char *)off, (Xword *)&value, + if (do_reloc_krtld(rtype, (unsigned char *)off, (Xword *)&value, (const char *)mp->strings + symref->st_name, - mp->filename, 0) == 0) + mp->filename) == 0) err = 1; } /* end of while loop */ @@ -349,7 +346,7 @@ do_relocations(struct module *mp) /* do the relocations */ for (shn = 1; shn < mp->hdr.e_shnum; shn++) { rshp = (Shdr *) - (mp->shdrs + shn * mp->hdr.e_shentsize); + (mp->shdrs + shn * mp->hdr.e_shentsize); if (rshp->sh_type == SHT_REL) { _kobj_printf(ops, "%s can't process type SHT_REL\n", mp->filename); @@ -381,7 +378,7 @@ do_relocations(struct module *mp) #ifdef KOBJ_DEBUG if (kobj_debug & D_RELOCATIONS) { _kobj_printf(ops, "krtld: relocating: file=%s ", - mp->filename); + mp->filename); _kobj_printf(ops, " section=%d\n", shn); } #endif |