The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libkern/kxld/kxld_sect.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2008 Apple Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 #include <string.h>
   29 #include <mach-o/loader.h>
   30 #include <mach-o/reloc.h>
   31 #include <sys/types.h>
   32 
   33 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
   34 #include <AssertMacros.h>
   35 
   36 #include "kxld_reloc.h"
   37 #include "kxld_sect.h"
   38 #include "kxld_seg.h"
   39 #include "kxld_symtab.h"
   40 #include "kxld_util.h"
   41 
   42 static kern_return_t export_macho(const KXLDSect *sect, u_char *buf, u_long offset, 
   43     u_long bufsize, boolean_t is_32_bit);
   44 #if KXLD_USER_OR_ILP32
   45 static kern_return_t sect_export_macho_header_32(const KXLDSect *sect, u_char *buf, 
   46     u_long *header_offset, u_long header_size, u_long data_offset);
   47 #endif
   48 #if KXLD_USER_OR_LP64
   49 static kern_return_t sect_export_macho_header_64(const KXLDSect *sect, u_char *buf, 
   50     u_long *header_offset, u_long header_size, u_long data_offset);
   51 #endif
   52 
   53 #if KXLD_USER_OR_ILP32
   54 /*******************************************************************************
   55 *******************************************************************************/
   56 kern_return_t
   57 kxld_sect_init_from_macho_32(KXLDSect *sect, u_char *macho, u_long *sect_offset,
   58     u_int sectnum, const KXLDRelocator *relocator)
   59 {
   60     kern_return_t rval = KERN_FAILURE;
   61     struct section *src = (struct section *) (macho + *sect_offset);
   62     struct relocation_info *relocs = NULL;
   63 
   64     check(sect);
   65     check(macho);
   66     check(src);
   67 
   68     strlcpy(sect->segname, src->segname, sizeof(sect->segname));
   69     strlcpy(sect->sectname, src->sectname, sizeof(sect->sectname));
   70     sect->base_addr = src->addr;
   71     sect->link_addr = src->addr;
   72     sect->size = src->size;
   73     sect->sectnum = sectnum;
   74     sect->flags = src->flags;
   75     sect->align = src->align;
   76     sect->reserved1 = src->reserved1;
   77     sect->reserved2 = src->reserved2;
   78 
   79     if (src->offset) {
   80         sect->data = macho + src->offset;
   81     } else {
   82         sect->data = NULL;
   83     }
   84 
   85     relocs = (struct relocation_info *) (macho + src->reloff);
   86 
   87     rval = kxld_reloc_create_macho(&sect->relocs, relocator, 
   88         relocs, src->nreloc);
   89     require_noerr(rval, finish);
   90 
   91     *sect_offset += sizeof(*src);
   92     rval = KERN_SUCCESS;
   93 
   94 finish:
   95     if (rval) kxld_sect_deinit(sect);
   96 
   97     return rval;
   98 }
   99 #endif /* KXLD_USER_OR_ILP32 */
  100 
  101 #if KXLD_USER_OR_LP64
  102 /*******************************************************************************
  103 *******************************************************************************/
  104 kern_return_t
  105 kxld_sect_init_from_macho_64(KXLDSect *sect, u_char *macho, u_long *sect_offset,
  106     u_int sectnum, const KXLDRelocator *relocator)
  107 {
  108     kern_return_t rval = KERN_FAILURE;
  109     struct section_64 *src = (struct section_64 *) (macho + *sect_offset);
  110     struct relocation_info *relocs = NULL;
  111 
  112     check(sect);
  113     check(macho);
  114     check(src);
  115 
  116     strlcpy(sect->segname, src->segname, sizeof(sect->segname));
  117     strlcpy(sect->sectname, src->sectname, sizeof(sect->sectname));
  118     sect->base_addr = src->addr;
  119     sect->link_addr = src->addr;
  120     sect->size = src->size;
  121     sect->sectnum = sectnum;
  122     sect->flags = src->flags;
  123     sect->align = src->align;
  124     sect->reserved1 = src->reserved1;
  125     sect->reserved2 = src->reserved2;
  126 
  127     if (src->offset) {
  128         sect->data = macho + src->offset;
  129     } else {
  130         sect->data = NULL;
  131     }
  132 
  133     relocs = (struct relocation_info *) (macho + src->reloff);
  134 
  135     rval = kxld_reloc_create_macho(&sect->relocs, relocator, 
  136         relocs, src->nreloc);
  137     require_noerr(rval, finish);
  138 
  139     *sect_offset += sizeof(*src);
  140     rval = KERN_SUCCESS;
  141 
  142 finish:
  143     if (rval) kxld_sect_deinit(sect);
  144 
  145     return rval;
  146 }
  147 #endif /* KXLD_USER_OR_LP64 */
  148 
  149 #if KXLD_USER_OR_GOT
  150 /*******************************************************************************
  151 * Assumes GOT is comprised of kxld_addr_t entries
  152 *******************************************************************************/
  153 kern_return_t
  154 kxld_sect_init_got(KXLDSect *sect, u_int ngots)
  155 {
  156     kern_return_t rval = KERN_FAILURE;
  157 
  158     check(sect);
  159 
  160     strlcpy(sect->segname, KXLD_SEG_GOT, sizeof(sect->segname));
  161     strlcpy(sect->sectname, KXLD_SECT_GOT, sizeof(sect->sectname));
  162     sect->base_addr = 0;
  163     sect->link_addr = 0;
  164     sect->flags = 0;
  165     sect->align = 4;
  166     sect->reserved1 = 0;
  167     sect->reserved2 = 0;
  168 
  169     sect->size = ngots * sizeof(kxld_addr_t);
  170     sect->data = kxld_alloc((u_long) sect->size);
  171     require_action(sect->data, finish, rval=KERN_RESOURCE_SHORTAGE);
  172 
  173     sect->allocated = TRUE;
  174 
  175     rval = KERN_SUCCESS;
  176 
  177 finish:
  178     return rval;
  179 }
  180 #endif /* KXLD_USER_OR_GOT */
  181 
  182 #if KXLD_USER_OR_COMMON
  183 /*******************************************************************************
  184 *******************************************************************************/
  185 void
  186 kxld_sect_init_zerofill(KXLDSect *sect, const char *segname, 
  187     const char *sectname, kxld_size_t size, u_int align)
  188 {
  189     check(sect);
  190     check(segname);
  191     check(sectname);
  192 
  193     strlcpy(sect->segname, segname, sizeof(sect->segname));
  194     strlcpy(sect->sectname, sectname, sizeof(sect->sectname));
  195     sect->size = size;
  196     sect->align = align;
  197     sect->base_addr = 0;
  198     sect->link_addr = 0;
  199     sect->flags = S_ZEROFILL;
  200 }
  201 #endif /* KXLD_USER_OR_COMMON */
  202 
  203 /*******************************************************************************
  204 *******************************************************************************/
  205 void
  206 kxld_sect_clear(KXLDSect *sect)
  207 {
  208     check(sect);
  209 
  210     if (sect->allocated) {
  211         kxld_free(sect->data, (u_long) sect->size);
  212         sect->allocated = FALSE;
  213     }
  214 
  215     bzero(sect->sectname, sizeof(sect->sectname));
  216     bzero(sect->segname, sizeof(sect->segname));
  217     sect->data = NULL;
  218     sect->base_addr = 0;
  219     sect->link_addr = 0;
  220     sect->size = 0;
  221     sect->flags = 0;
  222     sect->align = 0;
  223     sect->reserved1 = 0;
  224     sect->reserved2 = 0;
  225     kxld_array_clear(&sect->relocs);
  226 }
  227 
  228 /*******************************************************************************
  229 *******************************************************************************/
  230 void
  231 kxld_sect_deinit(KXLDSect *sect)
  232 {
  233     check(sect);
  234 
  235     if (streq_safe(sect->sectname, KXLD_SECT_GOT, sizeof(KXLD_SECT_GOT))) {
  236         kxld_free(sect->data, (u_long) sect->size);
  237     }
  238 
  239     kxld_array_deinit(&sect->relocs);
  240     bzero(sect, sizeof(*sect));
  241 }
  242 
  243 /*******************************************************************************
  244 *******************************************************************************/
  245 u_int 
  246 kxld_sect_get_num_relocs(const KXLDSect *sect)
  247 {
  248     check(sect);
  249 
  250     return sect->relocs.nitems;
  251 }
  252 
  253 /*******************************************************************************
  254 *******************************************************************************/
  255 u_long
  256 kxld_sect_get_macho_header_size(boolean_t is_32_bit)
  257 {
  258     if (is_32_bit) {
  259         return sizeof(struct section);
  260     } else {
  261         return sizeof(struct section_64);
  262     }
  263 }
  264 
  265 /*******************************************************************************
  266 *******************************************************************************/
  267 u_long
  268 kxld_sect_get_macho_data_size(const KXLDSect *sect)
  269 {
  270     u_long size = 0;
  271 
  272     check(sect);
  273 
  274     if (sect->data) {
  275         size = (u_long) sect->size;
  276     }
  277 
  278     return size;
  279 }
  280 
  281 #if KXLD_USER_OR_GOT
  282 /*******************************************************************************
  283 *******************************************************************************/
  284 u_int
  285 kxld_sect_get_ngots(const KXLDSect *sect, const KXLDRelocator *relocator,
  286     const KXLDSymtab *symtab)
  287 {
  288     const KXLDReloc *reloc = NULL;
  289     KXLDSym *sym = NULL;
  290     u_int ngots = 0;
  291     u_int i = 0;
  292     
  293     for (i = 0; i < sect->relocs.nitems; ++i) {
  294         reloc = kxld_array_get_item(&sect->relocs, i);
  295 
  296         if (relocator->reloc_has_got(reloc->reloc_type)) {
  297             /* @TODO This assumes 64-bit symbols (which is valid at the
  298              * moment since only x86_64 has a GOT)
  299              */
  300             sym = kxld_reloc_get_symbol(relocator, reloc, sect->data, symtab);
  301             if (!kxld_sym_is_got(sym)) {
  302                 kxld_sym_set_got(sym);
  303                 ++ngots;
  304             }
  305         }
  306     }
  307 
  308     return ngots;
  309 }
  310 #endif /* KXLD_USER_OR_GOT */
  311 
  312 /*******************************************************************************
  313 * Each section must be aligned at a certain power of two.  To figure out that 
  314 * alignment, we mask for the low bits that may need to be adjusted.  If they are 
  315 * non zero, we then subtract them from the target alignment to find the offset, 
  316 * and then add that offset to the link address.
  317 *******************************************************************************/
  318 kxld_addr_t
  319 kxld_sect_align_address(const KXLDSect *sect, kxld_addr_t address)
  320 {
  321     return kxld_align_address(address, sect->align);
  322 }
  323 
  324 /*******************************************************************************
  325 *******************************************************************************/
  326 kern_return_t
  327 kxld_sect_export_macho_to_file_buffer(const KXLDSect *sect, u_char *buf,
  328     u_long *header_offset, u_long header_size, u_long *data_offset, 
  329     u_long data_size, boolean_t is_32_bit)
  330 {
  331     kern_return_t rval = KERN_FAILURE;
  332 
  333     check(sect);
  334     check(buf);
  335     check(header_offset);
  336     check(data_offset);
  337 
  338     /* If there is no data to export, we only need to write the header.  We
  339      * make it a separate call so that we don't modify data_offset.
  340      */
  341     if (!sect->data) {
  342         KXLD_3264_FUNC(is_32_bit, rval,
  343             sect_export_macho_header_32, sect_export_macho_header_64,
  344             sect, buf, header_offset, header_size, /* data_offset */ 0);
  345         require_noerr(rval, finish);
  346     } else {
  347         *data_offset = (u_long) kxld_sect_align_address(sect, *data_offset);
  348 
  349         KXLD_3264_FUNC(is_32_bit, rval,
  350             sect_export_macho_header_32, sect_export_macho_header_64,
  351             sect, buf, header_offset, header_size, *data_offset);
  352         require_noerr(rval, finish);
  353 
  354         rval = export_macho(sect, buf, *data_offset, data_size, is_32_bit);
  355         require_noerr(rval, finish);
  356 
  357         *data_offset += (u_long) sect->size;
  358     }
  359         
  360     rval = KERN_SUCCESS;
  361 
  362 finish:
  363     return rval;
  364 }
  365 
  366 /*******************************************************************************
  367 *******************************************************************************/
  368 kern_return_t
  369 kxld_sect_export_macho_to_vm(const KXLDSect *sect, u_char *buf, 
  370     u_long *header_offset, u_long header_size, 
  371     kxld_addr_t link_addr, u_long data_size, 
  372     boolean_t is_32_bit)
  373 {
  374     kern_return_t rval = KERN_FAILURE;
  375     u_long data_offset = (u_long) (sect->link_addr - link_addr);
  376 
  377     check(sect);
  378     check(buf);
  379     check(header_offset);
  380 
  381     KXLD_3264_FUNC(is_32_bit, rval,
  382         sect_export_macho_header_32, sect_export_macho_header_64,
  383         sect, buf, header_offset, header_size, data_offset);
  384     require_noerr(rval, finish);
  385 
  386     rval = export_macho(sect, buf, data_offset, data_size, is_32_bit);
  387     require_noerr(rval, finish);
  388 
  389     rval = KERN_SUCCESS;
  390 
  391 finish:
  392     return rval;
  393 }
  394 
  395 /*******************************************************************************
  396 *******************************************************************************/
  397 static kern_return_t
  398 export_macho(const KXLDSect *sect, u_char *buf, u_long offset, u_long bufsize,
  399     boolean_t is_32_bit)
  400 {
  401     kern_return_t rval = KERN_FAILURE;
  402 
  403     check(sect);
  404     check(buf);
  405 
  406     if (!sect->data) {
  407         rval = KERN_SUCCESS;
  408         goto finish;
  409     }
  410 
  411     /* Verify that the section is properly aligned */
  412 
  413     require_action(kxld_sect_align_address(sect, offset) == offset, finish,
  414         rval = KERN_FAILURE);
  415 
  416     /* Verify that we have enough space to copy */
  417 
  418     require_action(sect->size <= bufsize - offset, finish,
  419         rval=KERN_FAILURE);
  420 
  421     /* Copy section data */
  422 
  423     switch (sect->flags & SECTION_TYPE) {
  424     case S_NON_LAZY_SYMBOL_POINTERS:
  425     case S_MOD_INIT_FUNC_POINTERS:
  426     case S_MOD_TERM_FUNC_POINTERS:
  427         require_action(!is_32_bit, finish, rval=KERN_FAILURE;
  428             kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
  429                 "Invalid section type in 32-bit kext: %u.", 
  430                 sect->flags & SECTION_TYPE));
  431         /* Fall through */
  432     case S_REGULAR:
  433     case S_CSTRING_LITERALS:
  434     case S_4BYTE_LITERALS:
  435     case S_8BYTE_LITERALS:
  436     case S_LITERAL_POINTERS:
  437     case S_COALESCED:
  438     case S_16BYTE_LITERALS:
  439         memcpy(buf + offset, sect->data, (size_t)sect->size);
  440         break;
  441     case S_ZEROFILL: /* sect->data should be NULL, so we'll never get here */
  442     case S_LAZY_SYMBOL_POINTERS:
  443     case S_SYMBOL_STUBS:
  444     case S_GB_ZEROFILL:
  445     case S_INTERPOSING:
  446     case S_DTRACE_DOF:
  447     default:
  448         rval = KERN_FAILURE;
  449         kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
  450             "Invalid section type: %u.", sect->flags & SECTION_TYPE);
  451         goto finish;
  452     }
  453 
  454     rval = KERN_SUCCESS;
  455 
  456 finish:
  457     return rval;
  458 }
  459 
  460 #if KXLD_USER_OR_ILP32
  461 /*******************************************************************************
  462 *******************************************************************************/
  463 static kern_return_t
  464 sect_export_macho_header_32(const KXLDSect *sect, u_char *buf, 
  465     u_long *header_offset, u_long header_size, u_long data_offset)
  466 {
  467     kern_return_t rval = KERN_FAILURE;
  468     struct section *secthdr = NULL;
  469 
  470     check(sect);
  471     check(buf);
  472     check(header_offset);
  473     
  474     require_action(sizeof(*secthdr) <= header_size - *header_offset, finish,
  475         rval=KERN_FAILURE);
  476     secthdr = (struct section *) (buf + *header_offset);
  477     *header_offset += sizeof(*secthdr);
  478 
  479     /* Initalize header */
  480 
  481     strlcpy(secthdr->sectname, sect->sectname, sizeof(secthdr->sectname));
  482     strlcpy(secthdr->segname, sect->segname, sizeof(secthdr->segname));
  483     secthdr->addr = (uint32_t) sect->link_addr;
  484     secthdr->size = (uint32_t) sect->size;
  485     secthdr->offset = (uint32_t) ((sect->data) ? data_offset : 0);
  486     secthdr->align = sect->align;
  487     secthdr->reloff = 0;
  488     secthdr->nreloc = 0;
  489     secthdr->flags = sect->flags;
  490     secthdr->reserved1 = sect->reserved1;
  491     secthdr->reserved2 = sect->reserved2;
  492 
  493     rval = KERN_SUCCESS;
  494 
  495 finish:
  496     return rval;
  497 }
  498 #endif /* KXLD_USER_OR_ILP32 */
  499 
  500 #if KXLD_USER_OR_LP64
  501 /*******************************************************************************
  502 *******************************************************************************/
  503 static kern_return_t
  504 sect_export_macho_header_64(const KXLDSect *sect, u_char *buf, 
  505     u_long *header_offset, u_long header_size, u_long data_offset)
  506 {
  507     kern_return_t rval = KERN_FAILURE;
  508     struct section_64 *secthdr = NULL;
  509 
  510     check(sect);
  511     check(buf);
  512     check(header_offset);
  513     
  514     require_action(sizeof(*secthdr) <= header_size - *header_offset, finish,
  515         rval=KERN_FAILURE);
  516     secthdr = (struct section_64 *) (buf + *header_offset);
  517     *header_offset += sizeof(*secthdr);
  518 
  519     /* Initalize header */
  520 
  521     strlcpy(secthdr->sectname, sect->sectname, sizeof(secthdr->sectname));
  522     strlcpy(secthdr->segname, sect->segname, sizeof(secthdr->segname));
  523     secthdr->addr = (uint64_t) sect->link_addr;
  524     secthdr->size = (uint64_t) sect->size;
  525     secthdr->offset = (uint32_t) ((sect->data) ? data_offset : 0);
  526     secthdr->align = sect->align;
  527     secthdr->reloff = 0;
  528     secthdr->nreloc = 0;
  529     secthdr->flags = sect->flags;
  530     secthdr->reserved1 = sect->reserved1;
  531     secthdr->reserved2 = sect->reserved2;
  532 
  533     rval = KERN_SUCCESS;
  534 
  535 finish:
  536     return rval;
  537 }
  538 #endif /* KXLD_USER_OR_LP64 */
  539 
  540 #if KXLD_USER_OR_COMMON
  541 /*******************************************************************************
  542 *******************************************************************************/
  543 kxld_size_t
  544 kxld_sect_grow(KXLDSect *sect, kxld_size_t nbytes, u_int align)
  545 {
  546     kxld_size_t size = kxld_align_address(sect->size, align);
  547 
  548     if (align > sect->align) sect->align = align;
  549     sect->size = size + nbytes;
  550 
  551     return size;
  552 }
  553 #endif /* KXLD_USER_OR_COMMON */
  554 
  555 /*******************************************************************************
  556 *******************************************************************************/
  557 void
  558 kxld_sect_relocate(KXLDSect *sect, kxld_addr_t link_addr)
  559 {
  560     sect->link_addr = kxld_sect_align_address(sect, 
  561         sect->link_addr + link_addr);
  562 }
  563 
  564 #if KXLD_USER_OR_GOT
  565 /*******************************************************************************
  566 *******************************************************************************/
  567 kern_return_t
  568 kxld_sect_populate_got(KXLDSect *sect, KXLDSymtab *symtab, 
  569     boolean_t swap __unused)
  570 {
  571     kern_return_t rval = KERN_FAILURE;
  572     KXLDSymtabIterator iter;
  573     KXLDSym *sym = NULL;
  574     kxld_addr_t *entry = NULL;
  575     kxld_addr_t entry_addr = 0;
  576 
  577     check(sect);
  578     check(symtab);
  579     require(streq_safe(sect->segname, KXLD_SEG_GOT, sizeof(KXLD_SEG_GOT)), 
  580         finish);
  581     require(streq_safe(sect->sectname, KXLD_SECT_GOT, sizeof(KXLD_SECT_GOT)), 
  582         finish);
  583 
  584     kxld_symtab_iterator_init(&iter, symtab, kxld_sym_is_got, FALSE);
  585     
  586     entry = (kxld_addr_t *) sect->data;
  587     entry_addr = sect->link_addr;
  588     while ((sym = kxld_symtab_iterator_get_next(&iter))) {
  589         *entry = sym->link_addr;
  590         sym->got_addr = entry_addr;
  591 
  592 #if !KERNEL
  593         if (swap) *entry = OSSwapInt64(*entry);
  594 #endif /* !KERNEL */
  595 
  596         ++entry;
  597         entry_addr += sizeof(*entry);
  598     }
  599 
  600     rval = KERN_SUCCESS;
  601 
  602 finish:
  603     return rval;
  604 }
  605 #endif /* KXLD_USER_OR_GOT */
  606 
  607 /*******************************************************************************
  608 *******************************************************************************/
  609 kern_return_t
  610 kxld_sect_process_relocs(KXLDSect *sect, const KXLDRelocator *relocator,
  611     const KXLDArray *sectarray, const KXLDSymtab *symtab)
  612 {
  613     kern_return_t rval = KERN_FAILURE;
  614     KXLDReloc *reloc = NULL;
  615     u_int i = 0;
  616 
  617     for (i = 0; i < sect->relocs.nitems; ++i) {
  618         reloc = kxld_array_get_item(&sect->relocs, i);
  619         rval = kxld_relocator_process_sect_reloc(relocator, reloc, sect, 
  620             sectarray, symtab);
  621         require_noerr(rval, finish);
  622     }
  623 
  624     rval = KERN_SUCCESS;
  625 
  626 finish:
  627     return rval;
  628 }
  629 

Cache object: 7a82a8d5d72ee31a2abcc0c28d316d62


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.