boringssl DEFINE_LOCAL_DATA

DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) 
{
  memset(out, 0, sizeof(EVP_CIPHER));

  out->nid = NID_aes_192_ecb;
  out->block_size = 16;
  out->key_len = 24;
  out->ctx_size = sizeof(EVP_AES_KEY);
  out->flags = EVP_CIPH_ECB_MODE;
  out->init = aes_init_key;
  out->cipher = aes_ecb_cipher;
}

代码看着有点别扭,就是怕别人看懂了,写出这么个玩意。

看DEFINE_LOCAL_DATA 定义 !

#define DEFINE_LOCAL_DATA(type, name) DEFINE_DATA(type, name, static const)

所以DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) = 

DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, static const)

#define DEFINE_DATA(type, name, accessor_decorations)                         \
  DEFINE_BSS_GET(type, name##_storage)                                        \
  DEFINE_STATIC_ONCE(name##_once)                                             \
  static void name##_do_init(type *out);                                      \
  static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \
  accessor_decorations type *name(void) {                                     \
    CRYPTO_once(name##_once_bss_get(), name##_init);                          \
    /* See http://c-faq.com/ansi/constmismatch.html for why the following     \
     * cast is needed. */                                                     \
    return (const type *)name##_storage_bss_get();                            \
  }                                                                           \
  static void name##_do_init(type *out)

DEFINE_DATA定义见上面的代码,继续拆~

#define DEFINE_BSS_GET(type, name) \
  static type name;                \
  static type *name##_bss_get(void) { return &name; }

#define DEFINE_STATIC_ONCE(name)                \
  static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \
  static CRYPTO_once_t *name##_bss_get(void) { return &name; }

void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
  if (*once) {
    return;
  }
  *once = 1;
  init();
}

#define DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, accessor_decorations)    
// 以下当做一个代码块 { }括起来
{
    //1. DEFINE_BSS_GET(type, name##_storage)  
    {
        //1.1 定义变量aes_192_ecb_generic##_storage;
        static EVP_CIPHER aes_192_ecb_generic##_storage;    
        //1.2 定义函数aes_192_ecb_generic##_storage##_bss_get
        static EVP_CIPHER *aes_192_ecb_generic##_storage##_bss_get(void) 
        { 
            return &aes_192_ecb_generic##_storage; 
        }
    }
                                     
    //2. DEFINE_STATIC_ONCE(name##_once) 
    {
        //2.1 定义变量aes_192_ecb_generic##_once
        static CRYPTO_once_t aes_192_ecb_generic##_once = CRYPTO_ONCE_INIT;
        //2.2 定义函数aes_192_ecb_generic##_once##_bss_get
        static CRYPTO_once_t *aes_192_ecb_generic##_once##_bss_get(void) 
        { 
            return &aes_192_ecb_generic##_once; 
        }
    }

                                       
    //3. static void name##_do_init(type *out); 
    //3.1 声明函数 aes_192_ecb_generic##_do_init(type *out)
    static void aes_192_ecb_generic##_do_init(type *out); 
                                     
    //4. static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } 
    //4.1 定义函数aes_192_ecb_generic##_init
    static void aes_192_ecb_generic##_init(void)
    {
        aes_192_ecb_generic##_do_init(aes_192_ecb_generic##_storage_bss_get()); 
    }

    //5. accessor_decorations type *name(void) 
    {                                     
        CRYPTO_once(name##_once_bss_get(), name##_init);                                                                              
        return (const type *)name##_storage_bss_get();                            
    }
    //5.1 定义函数aes_192_ecb_generic
    static const EVP_CIPHER *aes_192_ecb_generic(void) 
    {
        CRYPTO_once(aes_192_ecb_generic##_once_bss_get(), aes_192_ecb_generic##_init);
        return (const type *)aes_192_ecb_generic##_storage_bss_get(); 
    }
                                                                              
    //6. static void name##_do_init(type *out)
    //6.1 static void   aes_192_ecb_generic##_do_init(EVP_CIPHER *out)   

## 运算符用于在预处理期粘连两个标识符
## 的连接作用是在预处理期完成的,因此只在宏定义中有效
编译器不知道 ## 运算符的存在
汇总下
 

static EVP_CIPHER aes_192_ecb_generic_storage;  

        

static EVP_CIPHER *aes_192_ecb_generic_storage_bss_get(void) 
{ 
        return &aes_192_ecb_generic_storage; 
}



static CRYPTO_once_t aes_192_ecb_generic_once = CRYPTO_ONCE_INIT;

static CRYPTO_once_t *aes_192_ecb_generic_once_bss_get(void) 
{ 
        return &aes_192_ecb_generic_once; 
}



static void aes_192_ecb_generic_do_init(type *out);

static void aes_192_ecb_generic_init(void)
{
        aes_192_ecb_generic_do_init(aes_192_ecb_generic_storage_bss_get()); 
}



static const EVP_CIPHER *aes_192_ecb_generic(void) 
{
        CRYPTO_once(aes_192_ecb_generic_once_bss_get(), aes_192_ecb_generic_init);
         return (const type *)aes_192_ecb_generic_storage_bss_get(); 
}



static void aes_192_ecb_generic_do_init(EVP_CIPHER *out)   
{
         memset(out, 0, sizeof(EVP_CIPHER));

        out->nid = NID_aes_192_ecb;
        out->block_size = 16;
        out->key_len = 24;
        out->ctx_size = sizeof(EVP_AES_KEY);
        out->flags = EVP_CIPH_ECB_MODE;
        out->init = aes_init_key;
        out->cipher = aes_ecb_cipher;
}

aes_192_ecb_generic -》 

aes_192_ecb_generic_init -》

aes_192_ecb_generic_do_init 初始化EVP_CIPHER 结构体

你可能感兴趣的:(linux,boringssl)