非PIC x86_64代码的内联汇编语言的正确性

时间:2012-10-29 02:27:22

标签: assembly x86-64 sbrk

我必须在FreeBSD上为sbrk编写以下包装器。不幸的是,FreeBSD没有提供_sbrk符号,就像在Linux上找到的那样。此外,在链接时提供包装也不是一种选择。所有使用x86_64 PIC和i386的测试似乎都能正常工作。但是,我在下面的非PIC x86_64内联汇编中看到间歇性崩溃。我不是一个集会的人,只是想要第二眼看它,以确定我是否遗漏了一些明显的东西。此外,如果任何人都可以从amd64的角度发表评论,也会受到赞赏。

static inline void* do_sbrk(intptr_t increment) {
  void* curbrk = 0;

#if defined(__x86_64__) || defined(__amd64__)
# ifdef PIC
  __asm__ __volatile__(
      "movq .curbrk@GOTPCREL(%%rip), %%rdx;"
      "movq (%%rdx), %%rax;"
      "movq %%rax, %0;"
      : "=r" (curbrk)
      :: "%rdx", "%rax");
# else
  __asm__ __volatile__(
      "movq .curbrk(%%rip), %%rax;"
      "movq %%rax, %0;"
      : "=r" (curbrk)
      :: "%rax");
# endif
#else
  __asm__ __volatile__(
      "movl .curbrk, %%eax;"
      "movl %%eax, %0;"
      : "=r" (curbrk)
      :: "%eax");
#endif

  if (increment == 0) {
    return curbrk;
  }

  char* prevbrk = static_cast<char*>(curbrk);
  void* newbrk = prevbrk + increment;

  if (brk(newbrk) == -1) {
    return reinterpret_cast<void*>(static_cast<intptr_t>(-1));
  }

  return prevbrk;
}

0 个答案:

没有答案