1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 1994-2002 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 /*
  30  * Miscellaneous ISA-specific code.
  31  */
  32 #include <sys/types.h>
  33 #include <sys/elf.h>
  34 #include <sys/kobj.h>
  35 #include <sys/kobj_impl.h>
  36 
  37 /*
  38  * Check that an ELF header corresponds to this machine's
  39  * instruction set architecture.  Used by kobj_load_module()
  40  * to not get confused by a misplaced driver or kernel module
  41  * built for a different ISA.
  42  */
  43 int
  44 elf_mach_ok(Elf32_Ehdr *h)
  45 {
  46         return ((h->e_ident[EI_DATA] == ELFDATA2LSB) &&
  47             (h->e_machine == EM_386));
  48 }
  49 
  50 /*
  51  * return non-zero for a bad address
  52  */
  53 int
  54 kobj_addrcheck(void *xmp, caddr_t adr)
  55 {
  56         struct module *mp;
  57 
  58         mp = (struct module *)xmp;
  59 
  60         if ((adr >= mp->text && adr < mp->text + mp->text_size) ||
  61             (adr >= mp->data && adr < mp->data + mp->data_size))
  62                 return (0); /* ok */
  63         if (mp->bss && adr >= (caddr_t)mp->bss &&
  64             adr < (caddr_t)mp->bss + mp->bss_size)
  65                 return (0);
  66         return (1);
  67 }
  68 
  69 
  70 /*
  71  * Flush instruction cache after updating text
  72  *      This is a nop for this machine arch.
  73  */
  74 /*ARGSUSED*/
  75 void
  76 kobj_sync_instruction_memory(caddr_t addr, size_t len)
  77 {}
  78 
  79 /*
  80  * Calculate memory image required for relocable object.
  81  */
  82 /* ARGSUSED3 */
  83 int
  84 get_progbits_size(struct module *mp, struct proginfo *tp, struct proginfo *dp,
  85         struct proginfo *sdp)
  86 {
  87         struct proginfo *pp;
  88         uint_t shn;
  89         Shdr *shp;
  90 
  91         /*
  92          * loop through sections to find out how much space we need
  93          * for text, data, (also bss that is already assigned)
  94          */
  95         for (shn = 1; shn < mp->hdr.e_shnum; shn++) {
  96                 shp = (Shdr *)(mp->shdrs + shn * mp->hdr.e_shentsize);
  97                 if (!(shp->sh_flags & SHF_ALLOC))
  98                         continue;
  99                 if (shp->sh_addr != 0) {
 100                         _kobj_printf(ops,
 101                             "%s non-zero sect addr in input file\n",
 102                             mp->filename);
 103                         return (-1);
 104                 }
 105                 pp = (shp->sh_flags & SHF_WRITE)? dp : tp;
 106 
 107                 if (shp->sh_addralign > pp->align)
 108                         pp->align = shp->sh_addralign;
 109                 pp->size = ALIGN(pp->size, shp->sh_addralign);
 110                 pp->size += ALIGN(shp->sh_size, 8);
 111         }
 112         tp->size = ALIGN(tp->size, 8);
 113         dp->size = ALIGN(dp->size, 8);
 114         return (0);
 115 }