/****************************************************************************** * The copyright string is composed of three parts: * 1) A copyright notice, "Copyright ©" * 2) One or more years or year ranges, e.g., "2004,2006-2008" * 3) A rights reserved notice, "Apple Inc. All Rights Reserved." * We check the validity of the string by searching for both the copyright * notice and the rights reserved notice. If both are found, we then check that * the text between the two notices contains only valid years and year ranges. ******************************************************************************/ boolean_t kxld_validate_copyright_string(const char *str) { boolean_t result = FALSE; const char *copyright = NULL; const char *rights = NULL; char *date_str = NULL; u_long len = 0; copyright = kxld_strstr(str, kCopyrightToken); rights = kxld_strstr(str, kRightsToken); if (!copyright || !rights || copyright > rights) goto finish; str = copyright + const_strlen(kCopyrightToken); len = rights - str; date_str = kxld_alloc(len+1); if (!date_str) goto finish; strncpy(date_str, str, len); date_str[len] = '\0'; if (!dates_are_valid(date_str, len)) goto finish; result = TRUE; finish: if (date_str) kxld_free(date_str, len+1); return result; }
static kern_return_t init_predicates(KXLDSym *sym, u_char n_type, u_short n_desc) { kern_return_t rval = KERN_FAILURE; check(sym); /* The type field is interpreted differently for normal symbols and stabs */ if (n_type & N_STAB) { sym->predicates.is_stab = 1; switch (n_type) { /* Labeled as NO_SECT in stab.h */ case N_GSYM: case N_FNAME: case N_RSYM: case N_SSYM: case N_LSYM: case N_BINCL: case N_PARAMS: case N_VERSION: case N_OLEVEL: case N_PSYM: case N_EINCL: case N_EXCL: case N_BCOMM: case N_LENG: case N_OPT: case N_OSO: sym->predicates.is_absolute = 1; break; /* Labeled as n_sect in stab.h */ case N_FUN: case N_STSYM: case N_LCSYM: case N_BNSYM: case N_SLINE: case N_ENSYM: case N_SO: case N_SOL: case N_ENTRY: case N_ECOMM: case N_ECOML: /* These are labeled as NO_SECT in stab.h, but they are actually * section-based on OS X. We must mark them as such so they get * relocated. */ case N_LBRAC: case N_RBRAC: sym->predicates.is_section = 1; break; default: rval = KERN_FAILURE; kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO "Invalid N_STAB symbol type: %u.", n_type); goto finish; } /* Don't care about the C++ predicates for stabs */ } else { u_char type = n_type & N_TYPE; /* Set the type-independent fields */ if ((n_type & N_EXT) && !(n_type & N_PEXT)) { sym->predicates.is_external = 1; } if (n_desc & N_DESC_DISCARDED) { sym->predicates.is_obsolete = 1; } if (n_desc & N_WEAK_REF) { sym->predicates.is_weak = 1; } if (n_desc & N_ARM_THUMB_DEF) { sym->predicates.is_thumb = 1; } /* The first set of type fields are mutually exclusive, so they can be * set with a switch statement. */ switch (type) { case N_ABS: sym->predicates.is_absolute = 1; break; case N_SECT: sym->predicates.is_section = 1; break; case N_UNDF: if (sym->base_addr) { sym->predicates.is_common = 1; } else { sym->predicates.is_undefined = 1; } break; case N_INDR: sym->predicates.is_indirect = 1; break; default: rval = KERN_FAILURE; kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO "Invalid symbol type: %u.", type); goto finish; } /* Set the C++-specific fields */ if ((0 == strncmp(CXX_PREFIX, sym->name, const_strlen(CXX_PREFIX)))) { sym->predicates.is_cxx = 1; if (0 == strncmp(sym->name, METACLASS_VTABLE_PREFIX, const_strlen(METACLASS_VTABLE_PREFIX))) { sym->predicates.is_meta_vtable = 1; } else if (0 == strncmp(sym->name, VTABLE_PREFIX, const_strlen(VTABLE_PREFIX))) { sym->predicates.is_class_vtable = 1; } else if (kxld_strstr(sym->name, RESERVED_TOKEN)) { sym->predicates.is_padslot = 1; } else if (kxld_strstr(sym->name, METACLASS_TOKEN)) { sym->predicates.is_metaclass = 1; } else if (kxld_strstr(sym->name, SUPER_METACLASS_POINTER_TOKEN)) { sym->predicates.is_super_metaclass_pointer = 1; } } else if (streq_safe(CXX_PURE_VIRTUAL, sym->name, sizeof(CXX_PURE_VIRTUAL))) { sym->predicates.is_cxx = 1; sym->predicates.is_pure_virtual = 1; } } rval = KERN_SUCCESS; finish: return rval; }