1*c6ba0247Srahnds /* $OpenBSD: archdep.h,v 1.2 2000/10/01 00:54:35 rahnds Exp $ */ 289c547eeSrahnds 389c547eeSrahnds /* 489c547eeSrahnds * Copyright (c) 1998 Per Fogelstrom, Opsycon AB 589c547eeSrahnds * 689c547eeSrahnds * Redistribution and use in source and binary forms, with or without 789c547eeSrahnds * modification, are permitted provided that the following conditions 889c547eeSrahnds * are met: 989c547eeSrahnds * 1. Redistributions of source code must retain the above copyright 1089c547eeSrahnds * notice, this list of conditions and the following disclaimer. 1189c547eeSrahnds * 2. Redistributions in binary form must reproduce the above copyright 1289c547eeSrahnds * notice, this list of conditions and the following disclaimer in the 1389c547eeSrahnds * documentation and/or other materials provided with the distribution. 1489c547eeSrahnds * 3. All advertising materials mentioning features or use of this software 1589c547eeSrahnds * must display the following acknowledgement: 1689c547eeSrahnds * This product includes software developed under OpenBSD by 1789c547eeSrahnds * Per Fogelstrom, Opsycon AB, Sweden. 1889c547eeSrahnds * 4. The name of the author may not be used to endorse or promote products 1989c547eeSrahnds * derived from this software without specific prior written permission. 2089c547eeSrahnds * 2189c547eeSrahnds * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 2289c547eeSrahnds * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2389c547eeSrahnds * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2489c547eeSrahnds * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 2589c547eeSrahnds * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2689c547eeSrahnds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2789c547eeSrahnds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2889c547eeSrahnds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2989c547eeSrahnds * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3089c547eeSrahnds * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3189c547eeSrahnds * SUCH DAMAGE. 3289c547eeSrahnds * 3389c547eeSrahnds */ 3489c547eeSrahnds 3589c547eeSrahnds #ifndef _POWERPC_ARCHDEP_H_ 3689c547eeSrahnds #define _POWERPC_ARCHDEP_H_ 3789c547eeSrahnds 3889c547eeSrahnds #define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */ 3989c547eeSrahnds 4089c547eeSrahnds #define MACHID EM_PPC /* ELF e_machine ID value checked */ 4189c547eeSrahnds 4289c547eeSrahnds #define RELTYPE Elf32_Rela 4389c547eeSrahnds #define RELSIZE sizeof(Elf32_Rela) 4489c547eeSrahnds 4589c547eeSrahnds #include <elf_abi.h> 4689c547eeSrahnds #include <machine/reloc.h> 4789c547eeSrahnds 4889c547eeSrahnds /* HACK */ 4989c547eeSrahnds #define DT_PROCNUM 0 5089c547eeSrahnds #ifndef DT_BIND_NOW 5189c547eeSrahnds #define DT_BIND_NOW 0 5289c547eeSrahnds #endif 5389c547eeSrahnds 5489c547eeSrahnds /* 5589c547eeSrahnds * Simple reloc of REL32's. Used by bootstrapping. 5689c547eeSrahnds */ 5789c547eeSrahnds #define SIMPLE_RELOC(r, s, p, v) \ 5889c547eeSrahnds if(ELF32_R_TYPE((r)->r_info) == RELOC_32) { \ 5989c547eeSrahnds if((ELF32_ST_BIND((s)->st_info) == STB_LOCAL) && \ 6089c547eeSrahnds (ELF32_ST_TYPE((s)->st_info) == STT_SECTION || \ 6189c547eeSrahnds ELF32_ST_TYPE((s)->st_info) == STT_NOTYPE) ) { \ 6289c547eeSrahnds *(p) += (v); \ 6389c547eeSrahnds } \ 6489c547eeSrahnds else { \ 6589c547eeSrahnds *(p) = (v) + (s)->st_value; \ 6689c547eeSrahnds } \ 6789c547eeSrahnds } 6889c547eeSrahnds 6989c547eeSrahnds /* 7089c547eeSrahnds * The following functions are declared inline so they can 7189c547eeSrahnds * be used before bootstrap linking has been finished. 7289c547eeSrahnds */ 7389c547eeSrahnds static inline void 7489c547eeSrahnds _dl_dcbf(Elf32_Addr *addr) 7589c547eeSrahnds { 76*c6ba0247Srahnds __asm__ volatile ("dcbst 0, %0\n\t" 77*c6ba0247Srahnds "sync\n\t" 78*c6ba0247Srahnds "icbi 0, %0\n\t" 79*c6ba0247Srahnds "sync\n\t" 80*c6ba0247Srahnds "isync" 8189c547eeSrahnds : : "r" (addr) : "0"); 8289c547eeSrahnds } 8389c547eeSrahnds 8489c547eeSrahnds static inline int _dl_write (int fd, const char* buf, int len); 8589c547eeSrahnds static inline void 8689c547eeSrahnds _dl_wrstderr(const char *s) 8789c547eeSrahnds { 8889c547eeSrahnds while(*s) { 8989c547eeSrahnds _dl_write(2, s, 1); 9089c547eeSrahnds s++; 9189c547eeSrahnds } 9289c547eeSrahnds } 9389c547eeSrahnds 9489c547eeSrahnds static inline void * 9589c547eeSrahnds _dl_memset(void *p, const char v, size_t c) 9689c547eeSrahnds { 9789c547eeSrahnds char *ip = p; 9889c547eeSrahnds 9989c547eeSrahnds while(c--) 10089c547eeSrahnds *ip++ = v; 10189c547eeSrahnds return(p); 10289c547eeSrahnds } 10389c547eeSrahnds 10489c547eeSrahnds static inline int 10589c547eeSrahnds _dl_strlen(const char *p) 10689c547eeSrahnds { 10789c547eeSrahnds const char *s = p; 10889c547eeSrahnds 10989c547eeSrahnds while(*s != '\0') 11089c547eeSrahnds s++; 11189c547eeSrahnds return(s - p); 11289c547eeSrahnds } 11389c547eeSrahnds 11489c547eeSrahnds static inline char * 11589c547eeSrahnds _dl_strcpy(char *d, const char *s) 11689c547eeSrahnds { 11789c547eeSrahnds char *rd = d; 11889c547eeSrahnds 11989c547eeSrahnds while((*d++ = *s++) != '\0'); 12089c547eeSrahnds 12189c547eeSrahnds return(rd); 12289c547eeSrahnds } 12389c547eeSrahnds 12489c547eeSrahnds static inline int 12589c547eeSrahnds _dl_strncmp(const char *d, const char *s, int c) 12689c547eeSrahnds { 12789c547eeSrahnds while(c-- && *d && *d++ == *s++) {}; 12889c547eeSrahnds if(c < 0) { 12989c547eeSrahnds return(0); 13089c547eeSrahnds } 13189c547eeSrahnds return(d[-1] - s[-1]); 13289c547eeSrahnds } 13389c547eeSrahnds 13489c547eeSrahnds static inline int 13589c547eeSrahnds _dl_strcmp(const char *d, const char *s) 13689c547eeSrahnds { 13789c547eeSrahnds while(*d && *d++ == *s++) {}; 13889c547eeSrahnds return(d[-1] - s[-1]); 13989c547eeSrahnds } 14089c547eeSrahnds 14189c547eeSrahnds static inline const char * 14289c547eeSrahnds _dl_strchr(const char *p, const int c) 14389c547eeSrahnds { 14489c547eeSrahnds while(*p) { 14589c547eeSrahnds if(*p == c) { 14689c547eeSrahnds return(p); 14789c547eeSrahnds } 14889c547eeSrahnds p++; 14989c547eeSrahnds } 15089c547eeSrahnds return(0); 15189c547eeSrahnds } 15289c547eeSrahnds 15389c547eeSrahnds static inline void 15489c547eeSrahnds RELOC_RELA(Elf32_Rela *r, 15589c547eeSrahnds const Elf32_Sym *s, Elf32_Addr *p, int v) 15689c547eeSrahnds { 15789c547eeSrahnds if(ELF32_R_TYPE((r)->r_info) == RELOC_RELATIVE) { 15889c547eeSrahnds if((ELF32_ST_BIND((s)->st_info) == STB_LOCAL) && 15989c547eeSrahnds ((ELF32_ST_TYPE((s)->st_info) == STT_SECTION) || 16089c547eeSrahnds (ELF32_ST_TYPE((s)->st_info) == STT_NOTYPE)) ) { 16189c547eeSrahnds *(p) = (v) + (r)->r_addend; 16289c547eeSrahnds } else { 16389c547eeSrahnds *(p) = (v) + (s)->st_value + (r)->r_addend; 16489c547eeSrahnds } 16589c547eeSrahnds } else if(ELF32_R_TYPE((r)->r_info) == RELOC_JMP_SLOT) { 16689c547eeSrahnds Elf32_Addr val = (v) + (s)->st_value + (r)->r_addend - 16789c547eeSrahnds (Elf32_Addr)(p); 16889c547eeSrahnds if (((val & 0xfe000000) != 0) && 16989c547eeSrahnds ((val & 0xfe000000) != 0xfe000000)) 17089c547eeSrahnds { 17189c547eeSrahnds /* invalid offset */ 17289c547eeSrahnds _dl_exit(20); 17389c547eeSrahnds } 17489c547eeSrahnds val &= ~0xfc000000; 17589c547eeSrahnds val |= 0x48000000; 17689c547eeSrahnds *(p) = val; 17789c547eeSrahnds _dl_dcbf(p); 17889c547eeSrahnds } else if(ELF32_R_TYPE((r)->r_info) == RELOC_GLOB_DAT) { 17989c547eeSrahnds *(p) = (v) + (s)->st_value + (r)->r_addend; 18089c547eeSrahnds } else { 18189c547eeSrahnds /* error */ 18289c547eeSrahnds } 18389c547eeSrahnds } 18489c547eeSrahnds 18589c547eeSrahnds #endif /* _POWERPC_ARCHDEP_H_ */ 186