Path: blob/main/tools/build/cross-build/include/mac/sys/linker_set.h
39587 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 1999 John D. Polstra4* Copyright (c) 1999,2001 Peter Wemm <[email protected]>5* All rights reserved.6* Copyright (c) 2023 Jessica Clarke <[email protected]>7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*/2930#ifndef _SYS_LINKER_SET_H_31#define _SYS_LINKER_SET_H_3233#include <mach-o/dyld.h>34#include <mach-o/getsect.h>3536/*37* The following macros are used to declare global sets of objects, which38* are collected by the linker into a `linker_set' as defined below.39* For Mach-O, this is done by constructing a separate section for each set.40*/4142#define __MAKE_SET_CONST const4344/*45* Private macros, not to be used outside this header file.46*/4748/*49* The userspace address sanitizer inserts redzones around global variables,50* violating the assumption that linker set elements are packed.51*/52#define __NOASAN __nosanitizeaddress5354#define __MAKE_SET_QV(set, sym, qv) \55static void const * qv \56__NOASAN \57__set_##set##_sym_##sym __section("__DATA,set_" #set) \58__used = &(sym)59#define __MAKE_SET(set, sym) __MAKE_SET_QV(set, sym, __MAKE_SET_CONST)6061static inline __pure2 uint8_t *62__set_getsectiondata(const char *segname, const char *sectname,63unsigned long *size)64{65uint32_t image_count, image_index;66const struct mach_header *mh;67uint8_t *ret;6869image_count = _dyld_image_count();70for (image_index = 0; image_index < image_count; ++image_index) {71mh = _dyld_get_image_header(image_index);72if (mh == NULL)73continue;7475ret = getsectiondata((const struct mach_header_64 *)mh,76segname, sectname, size);77if (ret != NULL)78return (ret);79}8081return (NULL);82}8384#define __SET_RANGE(set) ({ \85unsigned long __set_size; \86char *__set_data; \87__set_data = __set_getsectiondata("__DATA", \88"set_" #set, &__set_size); \89(struct { \90__CONCAT(__typeof_set_,set) **begin; \91__CONCAT(__typeof_set_,set) **limit; \92}){ \93.begin = (__CONCAT(__typeof_set_,set) **)__set_data, \94.limit = (__CONCAT(__typeof_set_,set) **)(__set_data + \95__set_size) \96}; \97})9899/*100* Public macros.101*/102#define TEXT_SET(set, sym) __MAKE_SET(set, sym)103#define DATA_SET(set, sym) __MAKE_SET(set, sym)104#define DATA_WSET(set, sym) __MAKE_SET_QV(set, sym, )105#define BSS_SET(set, sym) __MAKE_SET(set, sym)106#define ABS_SET(set, sym) __MAKE_SET(set, sym)107#define SET_ENTRY(set, sym) __MAKE_SET(set, sym)108109/*110* Initialize before referring to a given linker set.111*/112#define SET_DECLARE(set, ptype) \113typedef ptype __CONCAT(__typeof_set_,set)114115#define SET_BEGIN(set) \116(__SET_RANGE(set).begin)117#define SET_LIMIT(set) \118(__SET_RANGE(set).limit)119120/*121* Iterate over all the elements of a set.122*123* Sets always contain addresses of things, and "pvar" points to words124* containing those addresses. Thus is must be declared as "type **pvar",125* and the address of each set item is obtained inside the loop by "*pvar".126*/127#define SET_FOREACH(pvar, set) \128for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)129130#define SET_ITEM(set, i) \131((SET_BEGIN(set))[i])132133/*134* Provide a count of the items in a set.135*/136#define SET_COUNT(set) \137(SET_LIMIT(set) - SET_BEGIN(set))138139#endif /* _SYS_LINKER_SET_H_ */140141142