Последовательности кода для TLS на ARM

В документе Обработка ELF для локального хранилища потоков приведены последовательности сборки для различных моделей (локальный exec /initial exec/general dynamic) для различных архитектур. Но не ARM — можно ли где-нибудь увидеть такие последовательности кода для ARM? Я работаю над компилятором и хочу сгенерировать код, который будет правильно работать с компоновщиками платформы (как программными, так и динамическими).

Для ясности предположим, что процессор ARMv7, довольно новое ядро ​​и glibc (скажем, 3.13+/2.19+), но мне также было бы интересно, что должно измениться для более старого аппаратного/программного обеспечения, если это легко объяснить.


person mwhudson    schedule 23.04.2015    source источник
comment
Я бы немного дизассемблировал (goo.gl/TPiQCX), а затем использовал их для поиска в Google. gcc.gnu.org/ml/gcc-patches/2005- 03/msg02375.html sourcery.mentor.com/public /publications/RFC-TLSDESC-ARM.txt lxr.free-electrons.com/source/arch/arm/include/asm/tls.h   -  person auselen    schedule 23.04.2015
comment
Возможно, дубликат stackoverflow.com/questions/12878698/, но у этого нет правильного ответа.   -  person unixsmurf    schedule 23.04.2015
comment
@unixsmurf Я думаю, что ответ R на его вопрос и как получить «реестр потоков» в ARM-Linux, отвечает на этот вопрос?   -  person artless noise    schedule 23.04.2015
comment
@artlessnoise: Не аспект ABI/ELF.   -  person unixsmurf    schedule 23.04.2015
comment
@unixsmurf Я не понимаю, что ты имеешь в виду. изменения gcc Ослена — еще одна часть. Материал ELF является спецификацией и является стандартным? Вы используете .tlsdescseq tls-variable чтобы добавить его в раздел ELF на ассемблере (или это делает компилятор). Куча записей R_ARM_TLS_ (но они не являются кодом согласно ОП). Загрузчик должен организовать карту памяти в соответствии с PDF. Вы укореняете это в реестре TLS. Джаз на батуте, если вы хотите это лениво или нет, зависит от набора инструментов.   -  person artless noise    schedule 23.04.2015


Ответы (1)


Я не совсем понимаю, что вы хотите. Однако последовательности ассемблера (для ARMv6+ и поддерживающего ядра) таковы:

mrc p15, 0, rX, c13, c0, 2  @ get the user r/w register

В некоторых руководствах по ARM это называется TPIDRURW. Ваши таблицы/структура TLS должны быть порождены этим значением (возможно, указателем). Использование mcr быстрее, но вы также можете вызвать помощника (см. ниже), если вы не установили HWCAP_TLS в своем ELF (который можно использовать на всех процессорах ARM, поддерживаемых Linux).

Цель адреса 0xffff0fe8 похоже заключается в том, что вы можете использовать эти 4 байта вместо использования вышеупомянутого ассемблера напрямую с (rX == r0), поскольку, возможно, где-то на какой-то машине он отличается.


Это зависит от типа процессора. Существует помощник в векторной странице @0xffff0fe0 в entry-armv.S; он находится в структуре процесса/потока, если аппаратное обеспечение не поддерживает его. Документация находится в kernel_user_helpers.txt

Пример использования:

typedef void * (__kuser_get_tls_t)(void);
#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)

void foo()
{
    void *tls = __kuser_get_tls();
    printf("TLS = %p\n", tls);
}

Вы делаете системный вызов, чтобы установить материал TLS. clone — это способ настроить контекст потока. thread_info содержит все регистры для потока; он может совместно использовать mm (управление памятью или представление памяти процесса) с другими task_struct. Т.е. thread_info имеет tp_value для каждого созданного потока.

Вот обсуждение реализации ARM. Задействованы ELF/nptl/glibc и ядро ​​Linux (и/или поисковые запросы для более подробного изучения). Системный вызов для get_tls(), вероятно, был слишком дорогим, а в текущей основной ветке есть помощник векторной страницы (отображенный всеми потоками/процессами).

Некоторый источник glibc, tls-macros.h, tlsdesc.c и т. д. Скорее всего, полный/краткий ответ будет зависеть от версии,

  1. Ваш процессор ARM.
  2. Ваше ядро ​​Linux.
  3. Ваш glibc.
  4. Ваш компилятор (и флаги!).
person artless noise    schedule 23.04.2015
comment
TCB в PDF-файле, на который вы ссылаетесь, представляет собой структуру thread_info в ARM-Linux. О, и, конечно же, задействован 'ld' (загрузчик). CP15 c13,c0 используется на ARMv6+. Есть три регистра. Пользователь r/w, пользователь только для чтения и привилегированный (только ядро); конечно, ядро ​​должно иметь возможность записывать их все. ARM Linux использует только два (например, tp_values); помимо этого, другие последовательности ассемблера зависят от вашего воображения, если вы реализуете это на ARM. Т.е. ваш вопрос мне не совсем ясен; Вы хотите повторно использовать загрузчик glibc или самостоятельно записать все пространство пользователя? - person artless noise; 23.04.2015
comment
Спасибо за ответ. Думаю, больше всего меня смутила инструкция mrc. И я всегда забываю беспорядок с версиями процессоров ARM. Я отредактирую вопрос, а затем, возможно, вы сможете отредактировать ответ по своему вкусу. - person mwhudson; 28.04.2015