C宏用于标记函数的开头和结尾

时间:2014-02-16 02:04:54

标签: c assembly c-preprocessor

这没什么大不了的,只是为了我的实验,但从来没有让我感到烦恼的是我无法编译这段代码:

#include <stdio.h>

#define MARK_ENCRYPTED_FUNCTION_START(NAME) \
    __asm__ __volatile__ (#NAME "_enc_start:")

#define MARK_ENCRYPTED_FUNCTION_END(NAME) \
    __asm__ __volatile__ (#NAME "_enc_end:")

#define GET_ENCRYPTED_FUNCTION_ADDRESS_AND_LENGHT(NAME, ADDR, LENGHT) \
    __asm__ __volatile__ (\
        "movl  $" #NAME "_enc_start, %0\n\t"\
        "movl  $" #NAME "_enc_end, %1\n\t"\
        : "=r"(ADDR), "=r"(LENGHT)\
    )

int f()
{
    MARK_ENCRYPTED_FUNCTION_START(f);

    {
        int sum = 0;
        int i = 0;
        for (i = 0; i < 11; ++i)
        {
            sum += i;
        }

        return sum;
    }

    MARK_ENCRYPTED_FUNCTION_END(f);
}


int main()
{
    unsigned int f_addr, f_len;
    GET_ENCRYPTED_FUNCTION_ADDRESS_AND_LENGHT(f, f_addr, f_len);

    printf("f - addr start: %x; addr end: %d\n", f_addr, f_len);

    return 0;
}

gcc -E test.c的输出是:

int f()
{
 __asm__ __volatile__ ("f" "_enc_start:");

 {
  int sum = 0;
  int i = 0;
  for (i = 0; i < 11; ++i)
  {
   sum += i;
  }

  return sum;
 }

 __asm__ __volatile__ ("f" "_enc_end:");
}


int main()
{
 unsigned int f_addr, f_len;
 __asm__ __volatile__ ( "movl  $" "f" "_enc_start, %0\n\t" "movl  $" "f" "_enc_end, %1\n\t" : "=r"(f_addr), "=r"(f_len) );

 printf("f - addr start: %x; addr end: %d\n", f_addr, f_len);

 return 0;
}

我不明白为什么链接器找不到“f_enc_end”。链接器错误是:

  

/tmp/ccqB886f.o:在函数`main'中:   test.c :(。text + 0x41):对`f_enc_end'的未定义引用。

这更令人费解,因为它可以找到以类似方式构建的f_enc_start

  

collect2:错误:ld返回1退出状态

任何建议,无论在正确的方向上有多小,都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我想我最终找到了解决方案。我不得不用这种方式重写C代码:

#include <stdio.h>

#define MARK_ENCRYPTED_FUNCTION_START(NAME) \
    __asm__ (#NAME "_enc_start:")

#define MARK_ENCRYPTED_FUNCTION_END(NAME) \
    __asm__ (#NAME "_enc_end:")

#define GET_ENCRYPTED_FUNCTION_ADDRESS_AND_LENGHT(NAME, ADDR, LENGHT) \
    __asm__ __volatile__ (\
        "movl  $" #NAME "_enc_start, %0\n\t"\
        "movl  $" #NAME "_enc_end, %1\n\t"\
        : "=r"(ADDR), "=r"(LENGHT)\
    )

MARK_ENCRYPTED_FUNCTION_START(f);
    int f()
    {

        int sum = 0;
        int i = 0;
        for (i = 0; i < 11; ++i)
        {
            sum += i;
        }

        return sum;
    }
MARK_ENCRYPTED_FUNCTION_END(f);

int main()
{
    unsigned int f_addr, f_len;
    GET_ENCRYPTED_FUNCTION_ADDRESS_AND_LENGHT(f, f_addr, f_len);

    printf("f - addr start: %x; addr end: %x\n", f_addr, f_len);

    return 0;
}

现在它编译并报告开始和结束地址。现在我必须实现实际的加密。

如果有人要分享的话,问题将继续存在。