Что находится за концом слова «environ»?

Я столкнулся с проблемой с кодом запуска общей библиотеки Free Pascal на Android. В исходниках Free Pascal RTL есть следующий фрагмент:

type
  TAuxiliaryValue = cuInt32;

  TInternalUnion = record
    a_val: cuint32;           //* Integer value */
      {* We use to have pointer elements added here.  We cannot do that,
         though, since it does not work when using 32-bit definitions
         on 64-bit platforms and vice versa.  *}
  end;

  Elf32_auxv_t = record
    a_type: cuint32;              //* Entry type */
    a_un: TInternalUnion;
  end;
  TElf32AuxiliaryVector = Elf32_auxv_t;
  PElf32AuxiliaryVector = ^TElf32AuxiliaryVector;

var
  psysinfo: LongWord = 0;

procedure InitSyscallIntf;
var
  ep: PPChar;
  auxv: PElf32AuxiliaryVector;
begin

  psysinfo := 0;
  ep := envp;
  while ep^ <> nil do
    Inc(ep);

  Inc(ep);

  auxv := PElf32AuxiliaryVector(ep);

  repeat
    if auxv^.a_type = AT_SYSINFO then begin
      psysinfo := auxv^.a_un.a_val;
      if psysinfo <> 0 then
        sysenter_supported := 1; // descision factor in asm syscall routines
      Break;
    end;
    Inc(auxv);
  until auxv^.a_type = AT_NULL;
end;

Процедура InitSyscallIntf вызывается как часть последовательности запуска SO. envp — это переменная уровня модуля, которая инициализируется ранее в последовательности запуска значением environ библиотеки libc. Как мне это выглядит, код пытается просканировать массив environ за нулевым указателем (который, как я думал, обозначает конец блока среды), а затем пытается прочитать прошлую память.

Что они ожидают найти за концом массива environ? Вероятно, они делают какие-то предположения о структуре памяти загруженного ELF-файла - можно ссылочку?


person Seva Alekseyev    schedule 01.06.2013    source источник


Ответы (3)


Ссылка, размещенная Севой, это то, на что он смотрит, и в том, что он смотрит, поддерживается ли инструкция sysenter.

Эта инструкция обеспечивает более быстрые системные вызовы, а в системах на базе ядра Linux и FreeBSD программы Free Pascal обычно обращаются к ядру напрямую, а не через libc.

См. rtl/linux/i386/* и rtl/linux/x86_64 для процедур оболочки системных вызовов, и вы увидите там тест для sysenter.

person Marco van de Voort    schedule 01.06.2013
comment
Спасибо Марко; настоящая проблема, с которой я столкнулся, это это. - person Seva Alekseyev; 01.06.2013

Похоже, они использовали это. Существует набор фрагментов данных размером два DWORD, называемых вспомогательными векторами после конца среды. Первое DWORD в векторе — это его тип, второе — значение. Типы описаны в linux/auxvec.h; их около 20.

В частности, запуск FPC ищет вектор типа AT_SYSINFO (32).

Вспомогательные векторы находятся за концом блока среды, но копия блока вспомогательных векторов доступна в виде файла под /proc/me/auxv.

person Seva Alekseyev    schedule 01.06.2013

В соответствии с начальным состоянием бинарного файла ELF Linux/i386 структура сегмента бинарного файла ELF имя программы после массива окружения.

На самом деле, я не уверен, что это то, к чему обращается ваша программа. Это данные среды, массив среды (указатели на эти строки) находится в начальном кадре стека. На приведенной выше странице после этого ничего конкретного не отображается, я предполагаю, что это локальные данные для функции main().

person Barmar    schedule 01.06.2013