
Alexander
12.06.2018
08:06:09
и я не сказал, что builtin_unreachable не используется. просто я сомневаюсь, что он действительно делает какие-то крутые оптимизацииэ

Assasin
12.06.2018
08:50:30

Александр
12.06.2018
08:50:51

Assasin
12.06.2018
08:50:52
если сделать <= 9, то код становится идентичен

Google

Assasin
12.06.2018
08:51:58

Александр
12.06.2018
08:53:01

Assasin
12.06.2018
08:53:28
а, понял, окей
сначала подумал, что речь именно об контракте [0..9]

Александр
12.06.2018
08:54:40
Ну на контракте [0; 9] оптимизация не видна, поэтому пришлось костылить

Rafael
12.06.2018
08:58:43
добрый день, кто может помочь разобраться в библиотеке xmlsec ?

Alexander
12.06.2018
09:03:45

Rafael
12.06.2018
09:04:43
как получить доступ к алгоритмам гост
пишет not implemented

Konstantin
12.06.2018
09:06:22
Видимо собрать с правильными флагами

Rafael
12.06.2018
09:07:16

Konstantin
12.06.2018
09:07:28
Несомненно

Rafael
12.06.2018
09:08:23
спасибо, автоматом конфигуратор вроде находит openssl крипто движок или этого мало?

Google

Konstantin
12.06.2018
09:08:57
А в OpenSSL оно включено?


Radio
12.06.2018
09:09:26
Добрый день, давайте разберемся, как устроена виртуальная память процесса. Понял, что плаваю, а среди коллег никто не плавает лучше.
0. В момент создания, инструкции и константы (в том числе нуллптр) загружаются в защищенную часть. Любая попытка изменения которой приводит к access violation.
1. Помимо этого выделяется участок под стек (10 мб, но может меняться в зависимости от флагов бинарника и оси) и остальное — куча.
2. виртуалка в разделе кучи маппируется в РАМ по мере нужды, это отдельная песня. Под стек и защищенную часть она маппируется сразу, верно?
3. в защищенной части (как она называется правильно?) лежат структуры, функции (те из них, что члены класса и не статичны — имеют скрытый параметр self для передачи указатель на конкретный класс), все варианты виртуальных таблиц, константы, что-то еще?
4. когда в коде дергается метод класса, по его типу в защищенной зоне находится конкретная функция, в которую передается экземпляр конкретного класса первым параметром.
5. если у класса есть виртуальные методы, то указатель на таблицу с виртуальными методами хранится в экземпляре класса.
6. если есть иерархия классов с виртуальными методами, то дочерний тип копирует таблицу родителя, а потом заменяет в ней те методы, которые может. Таким образом в защищенной части памяти процесса будет реально две таблицы. На которые будут ссылаться все экземпляры этих классов.
кто-то может дополнить интересным "фактом", который я не заметил, или исправить написанное?


Rafael
12.06.2018
09:09:36

Konstantin
12.06.2018
09:10:08
Значит должно быть достаточно, просто включить при сборке

Rafael
12.06.2018
09:10:35
спасибо, сейчас попробую

Alexander
12.06.2018
09:11:05
я смотрю, что вроде либа интересная, хоть и с ужасной билд-системой

Konstantin
12.06.2018
09:11:25
Xmlsec вроде нет
Надо запилить

Alexander
12.06.2018
09:13:57
а спонсора так и не нашли?


Konstantin
12.06.2018
09:14:20
Добрый день, давайте разберемся, как устроена виртуальная память процесса. Понял, что плаваю, а среди коллег никто не плавает лучше.
0. В момент создания, инструкции и константы (в том числе нуллптр) загружаются в защищенную часть. Любая попытка изменения которой приводит к access violation.
1. Помимо этого выделяется участок под стек (10 мб, но может меняться в зависимости от флагов бинарника и оси) и остальное — куча.
2. виртуалка в разделе кучи маппируется в РАМ по мере нужды, это отдельная песня. Под стек и защищенную часть она маппируется сразу, верно?
3. в защищенной части (как она называется правильно?) лежат структуры, функции (те из них, что члены класса и не статичны — имеют скрытый параметр self для передачи указатель на конкретный класс), все варианты виртуальных таблиц, константы, что-то еще?
4. когда в коде дергается метод класса, по его типу в защищенной зоне находится конкретная функция, в которую передается экземпляр конкретного класса первым параметром.
5. если у класса есть виртуальные методы, то указатель на таблицу с виртуальными методами хранится в экземпляре класса.
6. если есть иерархия классов с виртуальными методами, то дочерний тип копирует таблицу родителя, а потом заменяет в ней те методы, которые может. Таким образом в защищенной части памяти процесса будет реально две таблицы. На которые будут ссылаться все экземпляры этих классов.
кто-то может дополнить интересным "фактом", который я не заметил, или исправить написанное?
Если речь про винду - читай про pe format и секции. Права можно выделять только по секциям. Например секции инициализированных данных и неинициализированных данных. Но это уже условности и зависит от конкретного компоновщика. Ничего не мешает все вообще в одну секцию запилить и сделать доступным на запись.


Alexander
12.06.2018
09:14:24
я краем уха слышал, что сейчас в активном поиске, но чот никто не хочет в это деньги вкладывать

Konstantin
12.06.2018
09:14:59

Alexander
12.06.2018
09:15:37
было бы неплохо. а то там буквально пару человек сидят и пакетят постоянно

Konstantin
12.06.2018
09:15:58
И то когда время есть ага
Надо хотя бы одного фул тайм
Спонсорство щас есть для ci пока только

Radio
12.06.2018
09:16:32

Konstantin
12.06.2018
09:17:37
Обычно код всегда в секции .data с правами page execute read
Но никто не заставляет

Google

Konstantin
12.06.2018
09:18:03
А так ничто не мешает подгрузить код из секции данных и выдать права
Какой нибудь upx так примерно и делает
Нужная тебе функция - virtual protect
Читай спецификацию на pe формат, статью об упаковщиках в последний раз, и прочее по теме
Там подробно все рассказывается

Radio
12.06.2018
09:21:33
спасибо, направление чтения принято =)


Александр
12.06.2018
09:30:35
Добрый день, давайте разберемся, как устроена виртуальная память процесса. Понял, что плаваю, а среди коллег никто не плавает лучше.
0. В момент создания, инструкции и константы (в том числе нуллптр) загружаются в защищенную часть. Любая попытка изменения которой приводит к access violation.
1. Помимо этого выделяется участок под стек (10 мб, но может меняться в зависимости от флагов бинарника и оси) и остальное — куча.
2. виртуалка в разделе кучи маппируется в РАМ по мере нужды, это отдельная песня. Под стек и защищенную часть она маппируется сразу, верно?
3. в защищенной части (как она называется правильно?) лежат структуры, функции (те из них, что члены класса и не статичны — имеют скрытый параметр self для передачи указатель на конкретный класс), все варианты виртуальных таблиц, константы, что-то еще?
4. когда в коде дергается метод класса, по его типу в защищенной зоне находится конкретная функция, в которую передается экземпляр конкретного класса первым параметром.
5. если у класса есть виртуальные методы, то указатель на таблицу с виртуальными методами хранится в экземпляре класса.
6. если есть иерархия классов с виртуальными методами, то дочерний тип копирует таблицу родителя, а потом заменяет в ней те методы, которые может. Таким образом в защищенной части памяти процесса будет реально две таблицы. На которые будут ссылаться все экземпляры этих классов.
кто-то может дополнить интересным "фактом", который я не заметил, или исправить написанное?
0. nullptr в защищенной части - это круто сказано.
4. "По типу класса находится конкретная функция" - чушь. Метод с точки зрения скомпилированного кода ничем не отличается от функции с дополнительным аргументом. Идёт самый обычный вызов метода (call какой-нибудь, если привязываться к конкретной реализации).
6. Все эти замены происходят во время компиляции, а после запуска в простейшем случае каждый полиморфный объект хранит указатель на одну из таблиц (в конструкторах/деструкторах идёт перезапись одного поля объекта, а не модификация таблицы).


Xessao
12.06.2018
09:32:47
Есть отдельный чат по бусту?

Konstantin
12.06.2018
09:33:05
В Слаке cpplang есть

Radio
12.06.2018
09:36:00


Konstantin
12.06.2018
09:37:38
Никаких имён нет после компиляции, только адреса
Если только не импорт, тогда да есть таблица адрес-имя

Побитый
12.06.2018
09:38:35
Там не эксепшн, а undefined behaviour

Konstantin
12.06.2018
09:39:00
Имена могут сохраниться только в секции с отладочной информацией но оно не используется для поиска адресов никак

Radio
12.06.2018
09:39:26


Александр
12.06.2018
09:40:39
Спапсибо за развернутый ответ.
0 — а что не так? Стандарт даже гарантирует, что разименование нуллптр-а должно давать эксепшн. Сам он физически разве не среди прочих констант?
4 — принято, а как вообще тогда поиск функций происходит? Там где-то хэш таблица с именами и указателями? И как задают неймспейс (мемберство в классе)?
6 — непонятно возражение: т.е. они *копируют* исходную таблицу, а потом *модифицируют* те поля, которые виртуальные и совпадают по имени + деструктор, если есть. Т.е. модифицируют скопированную таблицу.
Вы не из питона?)
0. Все числовые константы превращаются в конкретные значения и "вшиваются" в код. Одно дело - это static const int my_value = 1;, но все используемые напрямую в коде (влезающие в регистры) - это готовые числа. int* p = nullptr; -> mov dword [esp + 10], 0 (грубый пример).
4. Как уже написали выше, никаких имён нет после компиляции. Вы себе представляете, куда бы скатилась производительность (в питон), если бы при каждом вызове функции нужен был поиск? Потыкайтесь в дизассемблере, вопросы отпадут.
6. Да, модифицируют копию, но не в рантайме, а в компайл-тайме. На выходе весь оверхед от vtable превращается в парочку операций записи в объект и лишнее чтение памяти при вызове виртуальной функции


Konstantin
12.06.2018
09:40:40
Если мы говорим про нативный код - да

Google

Aidar
12.06.2018
09:44:27

Konstantin
12.06.2018
09:44:56

Aidar
12.06.2018
09:45:13

Konstantin
12.06.2018
09:45:21
Как скажете


Radio
12.06.2018
09:47:36
Вы не из питона?)
0. Все числовые константы превращаются в конкретные значения и "вшиваются" в код. Одно дело - это static const int my_value = 1;, но все используемые напрямую в коде (влезающие в регистры) - это готовые числа. int* p = nullptr; -> mov dword [esp + 10], 0 (грубый пример).
4. Как уже написали выше, никаких имён нет после компиляции. Вы себе представляете, куда бы скатилась производительность (в питон), если бы при каждом вызове функции нужен был поиск? Потыкайтесь в дизассемблере, вопросы отпадут.
6. Да, модифицируют копию, но не в рантайме, а в компайл-тайме. На выходе весь оверхед от vtable превращается в парочку операций записи в объект и лишнее чтение памяти при вызове виртуальной функции
нет, не из питона. Не владеть подноготной уровня ассемблера очень частое явление, т.к. есть множество вариантов приложения навыков в сях, где просто не возникает необходимости, или она поверхностная.
0. Т.е. nullptr это тот же 0, что и NULL. А нулевой адрес, как водится, находится в защищенной области. Но разве стандарт обязует его быть именно нулем?
6. это да, понятно. Собсно, отсюда и вытекал вопрос: это одна таблица, модифицируемая в райнтайме, или множество таблиц на все возможные варианты, которые в компайл тайме будут сформированы и готовы к работе. Я не знаком с тем, что требует от этого стандарт, и как именно могут изголяться разрабы, но второй вариант очевидно более быстрый и более вероятный.


Konstantin
12.06.2018
09:48:50
Никак не требует, на откуп конкретного компилятора


Александр
12.06.2018
09:49:21
нет, не из питона. Не владеть подноготной уровня ассемблера очень частое явление, т.к. есть множество вариантов приложения навыков в сях, где просто не возникает необходимости, или она поверхностная.
0. Т.е. nullptr это тот же 0, что и NULL. А нулевой адрес, как водится, находится в защищенной области. Но разве стандарт обязует его быть именно нулем?
6. это да, понятно. Собсно, отсюда и вытекал вопрос: это одна таблица, модифицируемая в райнтайме, или множество таблиц на все возможные варианты, которые в компайл тайме будут сформированы и готовы к работе. Я не знаком с тем, что требует от этого стандарт, и как именно могут изголяться разрабы, но второй вариант очевидно более быстрый и более вероятный.
0. Не путайте значение адреса и данные, располагаемые по этому адресу. Память по адресу nullptr является запрещенной для чтения, да. А сам адрес - это просто константа. И она нигде не лежит.

Radio
12.06.2018
09:50:21

Konstantin
12.06.2018
09:50:54

ilynxy
12.06.2018
09:51:22
6. стандарт вроде не описывает конкретную реализацию виртуальных вызовов, но всё что я видел — сформированные на этапе компиляции таблицы и в экземплярах классов указатель на конкретную таблицу.

Konstantin
12.06.2018
09:51:57
А нуллптр скорее всего просто подставится и будет в секции кода как часть инструкции, типа mov eax, 0 или даже просто xor eax, eax
Если компилятор совсем деревянный - отляжет в секцию инициализированных данных

ilynxy
12.06.2018
09:52:34
/me видел системы где 0 вполне себе такой RW адрес

Matwey
12.06.2018
09:53:31

Konstantin
12.06.2018
09:54:29
А нормальное чтение запись в nullptr - просто частный случай ub

Radio
12.06.2018
09:57:46

ilynxy
12.06.2018
09:58:45
не обязан
и может не быть

Radio
12.06.2018
10:00:06
стандарт лишь требует, чтобы его нельзя было разименовывать. И обычно его делают указывающим на защищенную область памяти (не обязательно по адресу 0), и при разименовании сыперся эксепшн. Или нет?

ilynxy
12.06.2018
10:01:14
разыменование nullptr *всегда* UB, разыменование 0 UB (но конкретный компилятор может сделать DB для 0)

Google

Konstantin
12.06.2018
10:02:12
Просто ub. Конкретная платформа может в принципе не поддерживать защищённую память и все всегда доступно на запись.

ilynxy
12.06.2018
10:03:36
а это вроде не относится к защите и возможности записи
чото сложно, насколько я понял (void *)0 не обязательно прям нуль

Mikhail Voronov
12.06.2018
10:12:07

ilynxy
12.06.2018
10:12:52
в стандарте как-то хитро

Konstantin
12.06.2018
10:13:25
На ассемблере можно написать кусок если контроль нужен

ilynxy
12.06.2018
10:15:26
вот есть (void *)0, то его приведение к, скажем, (int *)(void *)0 — это UB, то есть до разыменования даже не доходит

Mikhail Voronov
12.06.2018
10:17:01
https://stackoverflow.com/a/48371424

ilynxy
12.06.2018
10:27:35
товарищ говорит, что в стандарте должно быть implementation defined для этих случаев, правильно я понял?
то есть (void *)0 == (int *)0 может быть false

Mikhail Voronov
12.06.2018
10:28:53
ага, я тоже так понял

ilynxy
12.06.2018
10:36:51
clang интересная штука: https://godbolt.org/g/iyfN5v
gcc на оба говорит UB, msvc и icc доверяют погромистам =)

InsidE
12.06.2018
10:38:01
/stat@combot

Combot
12.06.2018
10:38:01
combot.org/c/-1001031904034

Alexander
12.06.2018
10:39:12
вообще хотелоь бы, чтобы компиляторы делали намного больше проверок ?
пусть и ценой времени компиляции. но не всё сразу, к сожалению

ilynxy
12.06.2018
10:42:24
для avr gcc генерирует норм код. вощем только согласица с товарищем, которые говорит, что это должно быть implementation defined, нежли ub

Alexander
12.06.2018
10:48:32