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_sym.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 <stdint.h>
   30 #include <sys/types.h>
   31 #include <mach-o/nlist.h>
   32 #include <mach-o/stab.h>
   33 
   34 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
   35 #include <AssertMacros.h>
   36 
   37 #include "kxld_sect.h"
   38 #include "kxld_sym.h"
   39 #include "kxld_util.h"
   40 
   41 #define CXX_PREFIX                      "__Z"
   42 #define VTABLE_PREFIX                   CXX_PREFIX "TV"
   43 #define OSOBJ_PREFIX                    CXX_PREFIX "N"
   44 #define RESERVED_TOKEN                  "_RESERVED"
   45 #define METACLASS_TOKEN                 "10gMetaClassE"
   46 #define SUPER_METACLASS_POINTER_TOKEN   "10superClassE"
   47 #define METACLASS_VTABLE_PREFIX         VTABLE_PREFIX "N"
   48 #define METACLASS_VTABLE_SUFFIX         "9MetaClassE"
   49 #define CXX_PURE_VIRTUAL                "___cxa_pure_virtual"
   50 #define FINAL_CLASS_TOKEN               "14__OSFinalClassEv"
   51 
   52 /*******************************************************************************
   53 * Prototypes
   54 *******************************************************************************/
   55 
   56 static kern_return_t init_predicates(KXLDSym *sym, u_char n_type, u_short n_desc)
   57     __attribute__((nonnull));
   58 static void init_sym_sectnum(KXLDSym *sym, u_int n_sect)
   59     __attribute__((nonnull));
   60 static kern_return_t extract_inner_string(const char *str, const char *prefix, 
   61     const char *suffix, char *buf, u_long len);
   62 
   63 #if KXLD_USER_OR_ILP32
   64 /*******************************************************************************
   65 *******************************************************************************/
   66 kern_return_t
   67 kxld_sym_init_from_macho32(KXLDSym *sym, char *strtab, const struct nlist *src) 
   68 {
   69     kern_return_t rval = KERN_FAILURE;
   70 
   71     check(sym);
   72     check(strtab);
   73     check(src);
   74 
   75     bzero(sym, sizeof(*sym));
   76     sym->name = strtab + src->n_un.n_strx;
   77     sym->type = src->n_type;
   78     sym->desc = src->n_desc;
   79     sym->base_addr = src->n_value;
   80     sym->link_addr = sym->base_addr;
   81     
   82     rval = init_predicates(sym, src->n_type, src->n_desc);
   83     require_noerr(rval, finish);
   84 
   85     (void) init_sym_sectnum(sym, src->n_sect);
   86 
   87     if (kxld_sym_is_indirect(sym)) {
   88         sym->alias = strtab + src->n_value;
   89     }
   90 
   91     rval = KERN_SUCCESS;
   92 
   93 finish:
   94     return rval;
   95 }
   96 #endif /* KXLD_USER_OR_ILP32 */
   97 
   98 #if KXLD_USER_OR_LP64
   99 /*******************************************************************************
  100 *******************************************************************************/
  101 kern_return_t
  102 kxld_sym_init_from_macho64(KXLDSym *sym, char *strtab, const struct nlist_64 *src) 
  103 {
  104     kern_return_t rval = KERN_FAILURE;
  105 
  106     check(sym);
  107     check(strtab);
  108     check(src);
  109 
  110     bzero(sym, sizeof(*sym));
  111     sym->name = strtab + src->n_un.n_strx;
  112     sym->type = src->n_type;
  113     sym->desc = src->n_desc;
  114     sym->base_addr = src->n_value;
  115     sym->link_addr = sym->base_addr;
  116 
  117     rval = init_predicates(sym, src->n_type, src->n_desc);
  118     require_noerr(rval, finish);
  119 
  120     (void) init_sym_sectnum(sym, src->n_sect);
  121 
  122     if (kxld_sym_is_indirect(sym)) {
  123         sym->alias = strtab + src->n_value;
  124     }
  125 
  126     rval = KERN_SUCCESS;
  127 
  128 finish:
  129     return rval;
  130 }
  131 #endif /* KXLD_USER_OR_LP64 */
  132 
  133 /*******************************************************************************
  134 *******************************************************************************/
  135 void 
  136 kxld_sym_init_absolute(KXLDSym *sym, char *name, kxld_addr_t link_addr)
  137 {
  138     check(sym);
  139     check(name);
  140 
  141     bzero(sym, sizeof(*sym));
  142 
  143     sym->name = name;
  144     sym->link_addr = link_addr;
  145     sym->type = N_ABS | N_EXT;
  146     sym->sectnum = NO_SECT;
  147 
  148     init_predicates(sym, N_ABS | N_EXT, 0);
  149     sym->predicates.is_resolved = TRUE;
  150 }
  151 
  152 /*******************************************************************************
  153 *******************************************************************************/
  154 static kern_return_t
  155 init_predicates(KXLDSym *sym, u_char n_type, u_short n_desc)
  156 {
  157     kern_return_t rval = KERN_FAILURE;
  158 
  159     check(sym);
  160 
  161     /* The type field is interpreted differently for normal symbols and stabs */
  162     if (n_type & N_STAB) {
  163         sym->predicates.is_stab = 1;
  164 
  165         switch (n_type) {
  166         /* Labeled as NO_SECT in stab.h */
  167         case N_GSYM:
  168         case N_FNAME:
  169         case N_RSYM:
  170         case N_SSYM:
  171         case N_LSYM:
  172         case N_BINCL:
  173         case N_PARAMS:
  174         case N_VERSION:
  175         case N_OLEVEL:
  176         case N_PSYM:
  177         case N_EINCL:
  178         case N_LBRAC:
  179         case N_EXCL:
  180         case N_RBRAC:
  181         case N_BCOMM:
  182         case N_LENG:
  183         case N_OPT:
  184         case N_OSO:
  185             sym->predicates.is_absolute = 1;
  186             break;
  187         /* Labeled as n_sect in stab.h */
  188         case N_FUN:
  189         case N_STSYM:
  190         case N_LCSYM:
  191         case N_BNSYM:
  192         case N_SLINE:
  193         case N_ENSYM:
  194         case N_SO:
  195         case N_SOL:
  196         case N_ENTRY:
  197         case N_ECOMM:
  198         case N_ECOML:
  199             sym->predicates.is_section = 1;
  200             break;
  201         default:
  202             rval = KERN_FAILURE;
  203             kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
  204                 "Invalid N_STAB symbol type: %u.", n_type);
  205             goto finish;
  206         }
  207             
  208         /* Don't care about the C++ predicates for stabs */
  209 
  210     } else {
  211         u_char type = n_type & N_TYPE;
  212 
  213         /* Set the type-independent fields */
  214         if ((n_type & N_EXT) && !(n_type & N_PEXT)) {
  215             sym->predicates.is_external = 1;
  216         }
  217 
  218         if (n_desc & N_DESC_DISCARDED) {
  219             sym->predicates.is_obsolete = 1;
  220         }
  221 
  222         if (n_desc & N_WEAK_REF) {
  223            sym->predicates.is_weak = 1;
  224         }
  225 
  226         if (n_desc & N_ARM_THUMB_DEF) {
  227            sym->predicates.is_thumb = 1;
  228         }
  229 
  230         /* The first set of type fields are mutually exclusive, so they can be
  231          * set with a switch statement.
  232          */
  233         switch (type) {
  234         case N_ABS:
  235             sym->predicates.is_absolute = 1;
  236             break;
  237         case N_SECT:
  238             sym->predicates.is_section = 1;
  239             break;
  240         case N_UNDF:
  241             if (sym->base_addr) {
  242                 sym->predicates.is_common = 1;
  243             } else {
  244                 sym->predicates.is_undefined = 1;
  245             }
  246             break;
  247         case N_INDR:
  248             sym->predicates.is_indirect = 1;
  249             break;
  250         default:
  251             rval = KERN_FAILURE;
  252             kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
  253                 "Invalid symbol type: %u.", type);
  254             goto finish;
  255         }
  256 
  257         /* Set the C++-specific fields */
  258         if ((0 == strncmp(CXX_PREFIX, sym->name, const_strlen(CXX_PREFIX)))) {
  259             sym->predicates.is_cxx = 1;
  260 
  261             if (0 == strncmp(sym->name, METACLASS_VTABLE_PREFIX, 
  262                 const_strlen(METACLASS_VTABLE_PREFIX)))
  263             {
  264                 sym->predicates.is_meta_vtable = 1;
  265             } else if (0 == strncmp(sym->name, VTABLE_PREFIX, 
  266                 const_strlen(VTABLE_PREFIX))) 
  267             {
  268                 sym->predicates.is_class_vtable = 1;
  269             } else if (kxld_strstr(sym->name, RESERVED_TOKEN)) {
  270                 sym->predicates.is_padslot = 1;
  271             } else if (kxld_strstr(sym->name, METACLASS_TOKEN)) {
  272                 sym->predicates.is_metaclass = 1;
  273             } else if (kxld_strstr(sym->name, SUPER_METACLASS_POINTER_TOKEN)) {
  274                 sym->predicates.is_super_metaclass_pointer = 1;
  275             }
  276         } else if (streq_safe(CXX_PURE_VIRTUAL, sym->name, sizeof(CXX_PURE_VIRTUAL))) {
  277             sym->predicates.is_cxx = 1;
  278             sym->predicates.is_pure_virtual = 1;
  279         }
  280     }
  281 
  282     rval = KERN_SUCCESS;
  283 
  284 finish:
  285     return rval;
  286 }
  287 
  288 /*******************************************************************************
  289 *******************************************************************************/
  290 static void
  291 init_sym_sectnum(KXLDSym *sym, u_int n_sect)
  292 {
  293     /* The n_sect field is set to 0 when the symbol is not section-based, and
  294      * the number of the section in which the symbol exists otherwise.
  295      * Sometimes, symbols can be labeled as section-based, so we make sure that
  296      * they have a valid section number, and set them as absolute if they don't.
  297      */
  298 
  299     if (kxld_sym_is_section(sym)) {
  300         if (n_sect) {
  301             /* Convert the section number to an index into the section index */
  302             sym->sectnum = n_sect - 1;
  303         } else {
  304             sym->predicates.is_absolute = 1;
  305             sym->predicates.is_section = 0;
  306         }
  307     }
  308 
  309 }
  310 
  311 /*******************************************************************************
  312 *******************************************************************************/
  313 void
  314 kxld_sym_deinit(KXLDSym *sym __unused)
  315 {
  316     check(sym);
  317 }
  318 
  319 /*******************************************************************************
  320 *******************************************************************************/
  321 void
  322 kxld_sym_destroy(KXLDSym *sym)
  323 {
  324     check(sym);
  325     kxld_sym_deinit(sym);
  326     kxld_free(sym, sizeof(*sym));
  327 }
  328 
  329 
  330 /*******************************************************************************
  331 *******************************************************************************/
  332 boolean_t
  333 kxld_sym_is_absolute(const KXLDSym *sym)
  334 {
  335     check(sym);
  336 
  337     return (0 != sym->predicates.is_absolute);
  338 }
  339 
  340 /*******************************************************************************
  341 *******************************************************************************/
  342 boolean_t
  343 kxld_sym_is_section(const KXLDSym *sym)
  344 {
  345     check(sym);
  346 
  347     return (0 != sym->predicates.is_section);
  348 }
  349 
  350 /*******************************************************************************
  351 *******************************************************************************/
  352 boolean_t
  353 kxld_sym_is_defined(const KXLDSym *sym)
  354 {
  355     check(sym);
  356 
  357     return ((kxld_sym_is_absolute(sym) || kxld_sym_is_section(sym)) && 
  358         !sym->predicates.is_replaced);
  359 }
  360 
  361 
  362 /*******************************************************************************
  363 *******************************************************************************/
  364 boolean_t
  365 kxld_sym_is_defined_locally(const KXLDSym *sym)
  366 {
  367     check(sym);
  368 
  369     return (kxld_sym_is_defined(sym) && !sym->predicates.is_resolved);
  370 }
  371 
  372 /*******************************************************************************
  373 *******************************************************************************/
  374 boolean_t
  375 kxld_sym_is_external(const KXLDSym *sym)
  376 {
  377     check(sym);
  378 
  379     return (0 != sym->predicates.is_external);
  380 }
  381 
  382 /*******************************************************************************
  383 *******************************************************************************/
  384 boolean_t
  385 kxld_sym_is_exported(const KXLDSym *sym)
  386 {
  387     check(sym);
  388 
  389     return (kxld_sym_is_defined_locally(sym) && kxld_sym_is_external(sym));
  390 }
  391 
  392 /*******************************************************************************
  393 *******************************************************************************/
  394 boolean_t
  395 kxld_sym_is_undefined(const KXLDSym *sym)
  396 {
  397     check(sym);
  398 
  399     return (0 != sym->predicates.is_undefined);
  400 }
  401 
  402 /*******************************************************************************
  403 *******************************************************************************/
  404 boolean_t
  405 kxld_sym_is_indirect(const KXLDSym *sym)
  406 {
  407     check(sym);
  408 
  409     return (0 != sym->predicates.is_indirect);
  410 }
  411 
  412 /*******************************************************************************
  413 *******************************************************************************/
  414 boolean_t
  415 kxld_sym_is_common(const KXLDSym *sym)
  416 {
  417     check(sym);
  418 
  419     return (0 != sym->predicates.is_common);
  420 }
  421 
  422 /*******************************************************************************
  423 *******************************************************************************/
  424 boolean_t
  425 kxld_sym_is_unresolved(const KXLDSym *sym)
  426 {
  427     return ((kxld_sym_is_undefined(sym) && !sym->predicates.is_replaced) ||
  428             kxld_sym_is_indirect(sym) || kxld_sym_is_common(sym));
  429 }
  430 
  431 /*******************************************************************************
  432 *******************************************************************************/
  433 boolean_t
  434 kxld_sym_is_obsolete(const KXLDSym *sym)
  435 {
  436     return (0 != sym->predicates.is_obsolete);
  437 }
  438 
  439 #if KXLD_USER_OR_GOT
  440 /*******************************************************************************
  441 *******************************************************************************/
  442 boolean_t
  443 kxld_sym_is_got(const KXLDSym *sym)
  444 {
  445     check(sym);
  446 
  447     return (0 != sym->predicates.is_got);
  448 }
  449 #endif /* KXLD_USER_OR_GOT */
  450 
  451 /*******************************************************************************
  452 *******************************************************************************/
  453 boolean_t
  454 kxld_sym_is_stab(const KXLDSym *sym)
  455 {
  456     check(sym);
  457 
  458     return (0 != sym->predicates.is_stab);
  459 }
  460 
  461 /*******************************************************************************
  462 *******************************************************************************/
  463 boolean_t
  464 kxld_sym_is_weak(const KXLDSym *sym)
  465 {
  466     check(sym);
  467 
  468     return (0 != sym->predicates.is_weak);
  469 }
  470 
  471 /*******************************************************************************
  472 *******************************************************************************/
  473 boolean_t
  474 kxld_sym_is_cxx(const KXLDSym *sym)
  475 {
  476     check(sym);
  477 
  478     return (0 != sym->predicates.is_cxx);
  479 }
  480 
  481 /*******************************************************************************
  482 *******************************************************************************/
  483 boolean_t
  484 kxld_sym_is_pure_virtual(const KXLDSym *sym)
  485 {
  486     return (0 != sym->predicates.is_pure_virtual);
  487 }
  488 
  489 /*******************************************************************************
  490 *******************************************************************************/
  491 boolean_t
  492 kxld_sym_is_vtable(const KXLDSym *sym)
  493 {
  494     check(sym);
  495 
  496     return kxld_sym_is_class_vtable(sym) || kxld_sym_is_metaclass_vtable(sym);
  497 }
  498 
  499 /*******************************************************************************
  500 *******************************************************************************/
  501 boolean_t
  502 kxld_sym_is_class_vtable(const KXLDSym *sym)
  503 {
  504     check(sym);
  505 
  506     return (0 != sym->predicates.is_class_vtable);
  507 }
  508 
  509 /*******************************************************************************
  510 *******************************************************************************/
  511 boolean_t
  512 kxld_sym_is_metaclass_vtable(const KXLDSym *sym)
  513 {
  514     check(sym);
  515 
  516     return (0 != sym->predicates.is_meta_vtable);
  517 }
  518 
  519 /*******************************************************************************
  520 *******************************************************************************/
  521 boolean_t
  522 kxld_sym_is_padslot(const KXLDSym *sym)
  523 {
  524     check(sym);
  525 
  526     return (0 != sym->predicates.is_padslot);
  527 }
  528 
  529 /*******************************************************************************
  530 *******************************************************************************/
  531 boolean_t
  532 kxld_sym_is_metaclass(const KXLDSym *sym)
  533 {
  534     check(sym);
  535 
  536     return (0 != sym->predicates.is_metaclass);
  537 }
  538 
  539 /*******************************************************************************
  540 *******************************************************************************/
  541 boolean_t
  542 kxld_sym_is_super_metaclass_pointer(const KXLDSym *sym)
  543 {
  544     check(sym);
  545 
  546     return (0 != sym->predicates.is_super_metaclass_pointer);
  547 }
  548 
  549 /*******************************************************************************
  550 *******************************************************************************/
  551 boolean_t
  552 kxld_sym_name_is_padslot(const char *name)
  553 {
  554     check(name);
  555 
  556     return (kxld_strstr(name, RESERVED_TOKEN) != 0);
  557 }
  558 
  559 /*******************************************************************************
  560 *******************************************************************************/
  561 u_int
  562 kxld_sym_get_section_offset(const KXLDSym *sym, const KXLDSect *sect)
  563 {
  564     check(sym);
  565 
  566     return (u_int) (sym->base_addr - sect->base_addr);
  567 }
  568 
  569 #if KXLD_USER_OR_COMMON
  570 /*******************************************************************************
  571 *******************************************************************************/
  572 kxld_size_t
  573 kxld_sym_get_common_size(const KXLDSym *sym)
  574 {
  575     return sym->base_addr;
  576 }
  577 
  578 /*******************************************************************************
  579 *******************************************************************************/
  580 u_int
  581 kxld_sym_get_common_align(const KXLDSym *sym)
  582 {
  583     u_int align = GET_COMM_ALIGN(sym->desc);
  584     if (!align) align = 3;
  585 
  586     return align;
  587 }
  588 #endif /* KXLD_USER_OR_COMMON */
  589 
  590 /*******************************************************************************
  591 *******************************************************************************/
  592 kern_return_t
  593 kxld_sym_get_class_name_from_metaclass(const KXLDSym *sym,
  594     char class_name[], u_long class_name_len)
  595 {
  596     kern_return_t rval = KERN_FAILURE;
  597 
  598     check(sym);
  599     require_action(kxld_sym_is_metaclass(sym), finish, rval=KERN_FAILURE);
  600 
  601     rval = extract_inner_string(sym->name, OSOBJ_PREFIX, METACLASS_TOKEN, 
  602         class_name, class_name_len);
  603     require_noerr(rval, finish);
  604 
  605     rval = KERN_SUCCESS;
  606 finish:
  607     return rval;
  608 }
  609 
  610 /*******************************************************************************
  611 *******************************************************************************/
  612 kern_return_t
  613 kxld_sym_get_class_name_from_super_metaclass_pointer(const KXLDSym *sym,
  614     char class_name[], u_long class_name_len)
  615 {
  616     kern_return_t rval = KERN_FAILURE;
  617 
  618     check(sym);
  619     require_action(kxld_sym_is_super_metaclass_pointer(sym), finish, 
  620         rval=KERN_FAILURE);
  621 
  622     rval = extract_inner_string(sym->name, OSOBJ_PREFIX, 
  623         SUPER_METACLASS_POINTER_TOKEN, class_name, class_name_len);
  624     require_noerr(rval, finish);
  625 
  626     rval = KERN_SUCCESS;
  627 finish:
  628     return rval;
  629 }
  630 
  631 /*******************************************************************************
  632 *******************************************************************************/
  633 kern_return_t
  634 kxld_sym_get_class_name_from_vtable(const KXLDSym *sym,
  635     char class_name[], u_long class_name_len)
  636 {
  637     kern_return_t rval = KERN_FAILURE;
  638     
  639     check(sym);
  640     require_action(kxld_sym_is_class_vtable(sym), finish, rval=KERN_FAILURE);
  641 
  642     rval = kxld_sym_get_class_name_from_vtable_name(sym->name,
  643         class_name, class_name_len);
  644     require_noerr(rval, finish);
  645     
  646     rval = KERN_SUCCESS;
  647 
  648 finish:
  649     return rval;
  650 }
  651 
  652 /*******************************************************************************
  653 *******************************************************************************/
  654 kern_return_t 
  655 kxld_sym_get_class_name_from_vtable_name(const char *vtable_name,
  656     char class_name[], u_long class_name_len)
  657 {
  658     kern_return_t rval = KERN_FAILURE;
  659 
  660     check(vtable_name);
  661 
  662     rval = extract_inner_string(vtable_name, VTABLE_PREFIX, NULL,
  663         class_name, class_name_len);
  664     require_noerr(rval, finish);
  665 
  666     rval = KERN_SUCCESS;
  667 finish:
  668     return rval;
  669 }
  670 
  671 /*******************************************************************************
  672 *******************************************************************************/
  673 kern_return_t
  674 kxld_sym_get_vtable_name_from_class_name(const char *class_name, 
  675     char vtable_name[], u_long vtable_name_len)
  676 {
  677     kern_return_t rval = KERN_FAILURE;
  678     u_long outlen = 0;
  679 
  680     check(class_name);
  681     check(vtable_name);
  682 
  683     outlen = strlcpy(vtable_name, VTABLE_PREFIX, vtable_name_len);
  684     require_action(outlen < vtable_name_len, finish, 
  685         rval=KERN_FAILURE);
  686 
  687     outlen = strlcat(vtable_name, class_name, vtable_name_len);
  688     require_action(outlen < vtable_name_len, finish, 
  689         rval=KERN_FAILURE);
  690 
  691     rval = KERN_SUCCESS;
  692 finish:
  693     return rval;
  694 }
  695 
  696 /*******************************************************************************
  697 *******************************************************************************/
  698 kern_return_t
  699 kxld_sym_get_meta_vtable_name_from_class_name(const char *class_name, 
  700     char meta_vtable_name[], u_long meta_vtable_name_len)
  701 {
  702     kern_return_t rval = KERN_FAILURE;
  703     u_long outlen = 0;
  704 
  705     check(class_name);
  706     check(meta_vtable_name);
  707 
  708     outlen = strlcpy(meta_vtable_name, METACLASS_VTABLE_PREFIX,
  709         meta_vtable_name_len);
  710     require_action(outlen < meta_vtable_name_len, finish,
  711         rval=KERN_FAILURE);
  712 
  713     outlen = strlcat(meta_vtable_name, class_name, meta_vtable_name_len);
  714     require_action(outlen < meta_vtable_name_len, finish, 
  715         rval=KERN_FAILURE);
  716 
  717     outlen = strlcat(meta_vtable_name, METACLASS_VTABLE_SUFFIX, 
  718         meta_vtable_name_len);
  719     require_action(outlen < meta_vtable_name_len, finish, 
  720         rval=KERN_FAILURE);
  721 
  722     rval = KERN_SUCCESS;
  723 finish:
  724     return rval;
  725 }
  726 
  727 /*******************************************************************************
  728 *******************************************************************************/
  729 kern_return_t
  730 kxld_sym_get_final_sym_name_from_class_name(const char *class_name, 
  731     char final_sym_name[], u_long final_sym_name_len)
  732 {
  733     kern_return_t rval = KERN_FAILURE;
  734     u_long outlen = 0;
  735 
  736     check(class_name);
  737     check(final_sym_name);
  738 
  739     outlen = strlcpy(final_sym_name, OSOBJ_PREFIX, final_sym_name_len);
  740     require_action(outlen < final_sym_name_len, finish, 
  741         rval=KERN_FAILURE);
  742 
  743     outlen = strlcat(final_sym_name, class_name, final_sym_name_len);
  744     require_action(outlen < final_sym_name_len, finish, 
  745         rval=KERN_FAILURE);
  746 
  747     outlen = strlcat(final_sym_name, FINAL_CLASS_TOKEN, final_sym_name_len);
  748     require_action(outlen < final_sym_name_len, finish, 
  749         rval=KERN_FAILURE);
  750 
  751     rval = KERN_SUCCESS;
  752 
  753 finish:
  754     return rval;
  755 }
  756 
  757 /*******************************************************************************
  758 *******************************************************************************/
  759 u_long
  760 kxld_sym_get_function_prefix_from_class_name(const char *class_name,
  761     char function_prefix[], u_long function_prefix_len)
  762 {
  763     u_long rval = 0;
  764     u_long outlen = 0;
  765 
  766     check(class_name);
  767     check(function_prefix);
  768 
  769     outlen = strlcpy(function_prefix, OSOBJ_PREFIX, function_prefix_len);
  770     require(outlen < function_prefix_len, finish);
  771 
  772     outlen = strlcat(function_prefix, class_name, function_prefix_len);
  773     require(outlen < function_prefix_len, finish);
  774 
  775     rval = outlen;
  776 finish:
  777     return rval;
  778 }
  779 
  780 /*******************************************************************************
  781 *******************************************************************************/
  782 static kern_return_t
  783 extract_inner_string(const char *str, const char *prefix, const char *suffix, 
  784     char *buf, u_long len)
  785 {
  786     kern_return_t rval = KERN_FAILURE;
  787     u_long prelen = 0, suflen = 0, striplen = 0;
  788 
  789     check(str);
  790     check(buf);
  791 
  792     prelen = (prefix) ? strlen(prefix) : 0;
  793     suflen = (suffix) ? strlen(suffix) : 0;
  794     striplen = strlen(str) - prelen - suflen;
  795 
  796     require_action(striplen < len, finish, rval=KERN_FAILURE);
  797 
  798     strncpy(buf, str + prelen, striplen);
  799     buf[striplen] = '\0';
  800 
  801     rval = KERN_SUCCESS;
  802 finish:
  803     return rval;
  804 }
  805 
  806 #if KXLD_USER_OR_GOT
  807 /*******************************************************************************
  808 *******************************************************************************/
  809 void
  810 kxld_sym_set_got(KXLDSym *sym)
  811 {
  812     sym->predicates.is_got = 1;
  813 }
  814 #endif /* KXLD_USER_OR_GOT */
  815 
  816 /*******************************************************************************
  817 *******************************************************************************/
  818 void
  819 kxld_sym_relocate(KXLDSym *sym, const KXLDSect *sect)
  820 {
  821     if (kxld_sym_is_section(sym)) {
  822         sym->link_addr = sym->base_addr - sect->base_addr + sect->link_addr;
  823         sym->relocated_sectnum = sect->sectnum;
  824     }
  825 }
  826 
  827 #if KXLD_USER_OR_ILP32
  828 /*******************************************************************************
  829 *******************************************************************************/
  830 kern_return_t
  831 kxld_sym_export_macho_32(const KXLDSym *sym, u_char *_nl, char *strtab, 
  832     u_long *stroff, u_long strsize, boolean_t is_link_state)
  833 {
  834     kern_return_t rval = KERN_FAILURE;
  835     struct nlist *nl = (struct nlist *) _nl;
  836     char *str = NULL;
  837     long bytes = 0;
  838 
  839     check(sym);
  840     check(nl);
  841     check(strtab);
  842     check(stroff);
  843 
  844     bytes = strlen(sym->name) + 1;
  845     require_action((u_long)bytes <= strsize - *stroff, finish,
  846         rval = KERN_FAILURE);
  847 
  848     if (is_link_state) {
  849         nl->n_type = N_ABS | N_EXT;
  850         nl->n_sect = NO_SECT;
  851         nl->n_desc = 0;
  852     } else {
  853         nl->n_type = sym->type;
  854         nl->n_sect = (kxld_sym_is_section(sym)) ? sym->relocated_sectnum + 1 : 0;
  855         nl->n_desc = sym->desc;
  856     }
  857     nl->n_un.n_strx = (uint32_t) *stroff;
  858     nl->n_value = (uint32_t) sym->link_addr;
  859 
  860     str = (char *) (strtab + *stroff);
  861     strlcpy(str, sym->name, strsize - *stroff);
  862 
  863     *stroff += bytes;
  864     rval = KERN_SUCCESS;
  865 
  866 finish:
  867     return rval;
  868 }
  869 #endif /* KXLD_USER_OR_ILP32 */
  870 
  871 #if KXLD_USER_OR_LP64
  872 /*******************************************************************************
  873 *******************************************************************************/
  874 kern_return_t
  875 kxld_sym_export_macho_64(const KXLDSym *sym, u_char *_nl, char *strtab,
  876     u_long *stroff, u_long strsize, boolean_t is_link_state)
  877 {
  878     kern_return_t rval = KERN_FAILURE;
  879     struct nlist_64 *nl = (struct nlist_64 *) _nl;
  880     char *str = NULL;
  881     long bytes = 0;
  882 
  883     check(sym);
  884     check(nl);
  885     check(strtab);
  886     check(stroff);
  887 
  888     bytes = strlen(sym->name) + 1;
  889     require_action((u_long)bytes <= strsize - *stroff, finish,
  890         rval = KERN_FAILURE);
  891 
  892     if (is_link_state) {
  893         nl->n_type = N_ABS | N_EXT;
  894         nl->n_sect = NO_SECT;
  895         nl->n_desc = 0;
  896     } else {
  897         nl->n_type = sym->type;
  898         nl->n_sect = (kxld_sym_is_section(sym)) ? sym->relocated_sectnum + 1 : 0;
  899         nl->n_desc = sym->desc;
  900     }
  901     nl->n_un.n_strx = (uint32_t) *stroff;
  902     nl->n_value = (uint64_t) sym->link_addr;
  903 
  904     str = (char *) (strtab + *stroff);
  905     strlcpy(str, sym->name, strsize - *stroff);
  906 
  907     *stroff += bytes;
  908     rval = KERN_SUCCESS;
  909 
  910 finish:
  911     return rval;
  912 }
  913 #endif /* KXLD_USER_OR_LP64 */
  914 
  915 /*******************************************************************************
  916 *******************************************************************************/
  917 kern_return_t
  918 kxld_sym_resolve(KXLDSym *sym, kxld_addr_t addr, boolean_t export_sym) 
  919 {
  920     kern_return_t rval = KERN_FAILURE;
  921 
  922     check(sym);
  923 
  924     require_action(kxld_sym_is_undefined(sym) || kxld_sym_is_indirect(sym), 
  925         finish, rval=KERN_FAILURE);
  926 
  927     /* Set the n_list data types */
  928 
  929     sym->link_addr = addr;
  930     sym->type = N_ABS | N_EXT;
  931     sym->sectnum = NO_SECT;
  932  
  933     /* Set the predicate bits for an externally resolved symbol.  We re-export
  934      * indirect symbols and any symbols that the caller wants re-exported (for
  935      * example, symbols from a pseudo-kext). */
  936     
  937     sym->predicates.is_external = TRUE;
  938     sym->predicates.is_absolute = TRUE;
  939     sym->predicates.is_resolved = !(kxld_sym_is_indirect(sym) || export_sym);
  940   
  941     /* Clear the predicate bits for types that can be resolved */
  942 
  943     sym->predicates.is_undefined = FALSE;
  944     sym->predicates.is_indirect = FALSE;
  945 
  946     rval = KERN_SUCCESS;
  947 
  948 finish:
  949 
  950     return rval;
  951 }
  952 
  953 #if KXLD_USER_OR_COMMON
  954 /*******************************************************************************
  955 *******************************************************************************/
  956 kern_return_t
  957 kxld_sym_resolve_common(KXLDSym *sym, u_int sectnum, kxld_addr_t base_addr)
  958 {
  959     kern_return_t rval = KERN_FAILURE;
  960 
  961     check(sym);
  962 
  963     require_action(kxld_sym_is_common(sym), finish, 
  964         rval=KERN_FAILURE);
  965 
  966     sym->base_addr = base_addr;
  967     sym->link_addr = base_addr;
  968     sym->type = N_SECT | N_EXT;
  969     sym->sectnum = sectnum;
  970     sym->desc = 0;
  971 
  972     sym->predicates.is_absolute = FALSE;
  973     sym->predicates.is_section = TRUE;
  974     sym->predicates.is_undefined = FALSE;
  975     sym->predicates.is_indirect = FALSE;
  976     sym->predicates.is_common = FALSE;
  977     sym->predicates.is_external = TRUE;
  978 
  979     rval = KERN_SUCCESS;
  980 
  981 finish:
  982 
  983     return rval;
  984 }
  985 #endif /* KXLD_USER_OR_COMMON */
  986 
  987 /*******************************************************************************
  988 *******************************************************************************/
  989 void
  990 kxld_sym_delete(KXLDSym *sym)
  991 {
  992     check(sym);
  993 
  994     bzero(sym, sizeof(*sym));
  995     sym->predicates.is_replaced = TRUE;
  996 }
  997 
  998 
  999 /*******************************************************************************
 1000 *******************************************************************************/
 1001 void
 1002 kxld_sym_patch(KXLDSym *sym)
 1003 {
 1004     check(sym);
 1005 
 1006     sym->predicates.is_replaced = TRUE;
 1007 }
 1008 
 1009 /*******************************************************************************
 1010 *******************************************************************************/
 1011 void
 1012 kxld_sym_mark_private(KXLDSym *sym)
 1013 {
 1014     check(sym);
 1015 
 1016     sym->type |= N_PEXT;
 1017     sym->predicates.is_external = FALSE;
 1018 }
 1019 

Cache object: 556462317ceda5483f3febdbff5eb6cb


[ 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.