LINUX.ORG.RU

История изменений

Исправление tailgunner, (текущая версия) :

void *stack = (buffer + PAGE_SZ) & ~PAGE_MASK;

Ну да, формально тоже арифметика над адресом. Но, с другой стороны, это тупо смещение в массиве. А я говорю о Ъ-хардкорной адресной арифметике в духе:

struct header {
  int32_t sign;
  int32_t nitems;
};

struct foo {
 /* ... */
};

struct bar {
  /* ... */
};

int f(void *pkt)
{
  struct header *h = pkt;

  if (h->sign == SIGNATURE) {
    int i;
    int32_t *ptag = (int32_t *)(h +1);
    struct foo *pfoo;
    struct bar *pbar;

    for (i = 0; i < h->nitems; i++) {
      void *pdata = ptag + 1;

      switch (*ptag) {
      case TAG_FOO:
        pfoo = pdata;
        process_foo(pfoo);
        ptag = (int32_t *)(pfoo+1);
        break;
      case TAG_BAR:
        pbar = pdata;
        process_bar(pbar);
        ptag = (int32_t *)(pbar+1);
        break;
      default:
        error("invalid tag %#x", *ptag);
      }
    }
    return i;
  }
  else
    return -1;
}

это разбор пакета формата (header, [(int32, foo | bar)])

Исправление tailgunner, :

void *stack = (buffer + PAGE_SZ) & ~PAGE_MASK;

Ну да, формально тоже арифметика над адресом. Но, с другой стороны, это тупо смещение в массиве. А я говорю о Ъ-хардкорной адресной арифметике в духе:

struct header {
  int32_t sign;
  int32_t nitems;
};

struct foo {
 /* ... */
};

struct bar {
  /* ... */
};

int f(void *pkt)
{
  struct header *h = pkt;

  if (h->sign == SIGNATURE) {
    int i;
    int32_t *ptag = (int *)(h +1);
    struct foo *pfoo;
    struct bar *pbar;

    for (i = 0; i < h->nitems; i++) {
      void *pdata = ptag + 1;

      switch (*ptag) {
      case TAG_FOO:
        pfoo = pdata;
        process_foo(pfoo);
        ptag = (int32_t *)(pfoo+1);
        break;
      case TAG_BAR:
        pbar = pdata;
        process_bar(pbar);
        ptag = (int32_t *)(pbar+1);
        break;
      default:
        error("invalid tag %#x", *ptag);
      }
    }
    return i;
  }
  else
    return -1;
}

это разбор пакета формата (header, [(int32, foo | bar)])

Исходная версия tailgunner, :

void *stack = (buffer + PAGE_SZ) & ~PAGE_MASK;

Ну да, формально тоже арифметика над адресом. Но, с другой стороны, это тупо смещение в массиве. А я говорю о Ъ-хардкорной адресной арифметике в духе:

struct header {
  int32_t sign;
  int32_t nitems;
};

struct foo {
 /* ... */
};

struct bar {
  /* ... */
};

int f(void *pkt)
{
  struct header *h = pkt;

  if (h->sign == SIGNATURE) {
    int i;
    int32_t *ptag = (int *)(h +1);
    struct foo *pfoo;
    struct bar *pbar;

    for (i = 0; i < h->nitems; i++) {
      void *pdata = ptag + 1;

      switch (*ptag) {
      case TAG_FOO:
        pfoo = pdata;
        process_foo(pfoo);
        ptag = (int32_t *)(pfoo+1);
        break;
      case TAG_BAR:
        pbar = pdata;
        process_bar(pbar);
        ptag = (int32_t *)(pbar+1);
        break;
      default:
        error("invalid tag %#x", *ptag);
      }
    }
    return i;
  }
  else
    return -1;
}