LINUX.ORG.RU

Glibc 2.14

 ,


0

0

31-го мая вышла новая версия системной библиотеки Glibc-2.14
Изменения:

  • Исправлено более 90 ошибок
  • Реализация RPC объявлена устаревшей. На смену пришла TI-RPC
  • Поддержка программных интерфейсов новых версий ядра: clock_adjtime, name_to_handle_at, open_by_handle_at, syncfs, setns, sendmmsg
  • Новые локали: os_RU, bem_ZA, en_ZA, ff_SN, sw_KE, sw_TZ, lb_LU, wae_CH, yue_HK, lij_IT, mhr_RU
  • Новые кодировки: CP770, CP771, CP772, CP773, CP774
  • Новая утилита sotruss для отслеживания вызовов через PLT
  • Возможность установки хука на вызов malloc объявлена устаревшей и будет удалена в следующей версии

исходный код

>>> Подробности

★★★★

Проверено: JB ()

Ответ на: комментарий от vasily_pupkin

косяк в софте!
баг был и в арче и в сюзе, например
проблема не в дистре!!!

megabaks ★★★★ ()
Ответ на: комментарий от vadic

Если можно, зачем Линус писал с movsq?

Ну, например, для портабельности на более старые процы?
Ведь уж movsb-то там точно был, на 386.
Да и не утверждаю я, что movsb бы тоже прооптимизировался,
именно как раз по тому, что, из-за портабельности, мало кто
бы пользовался такой оптимизацией, и, по этому, вряд ли её
вообще добавили в новые процы.
А вы, кстати, можете задать эти вопросы в багзилле. Вероятность
получить ответ от Линуса, весьма велика.

Элементарный пример – блиты в/из фреймбуфера. По-хорошему ими должен

dma engine в видюхе заниматься, но если драйвер не ускоренный (типа

xorg-video-vesa или, например, консольный uvesa), придется блитить

процом.

Если драйвер блитит процом, а DMA остановлен, то смысл использовать
некешируемый доступ?

anonymous ()

> Возможность установки хука на вызов malloc объявлена устаревшей и будет удалена в следующей версии

Почему устаревшей и что предлагается использовать взамен?

bbk123 ★★★★★ ()
Ответ на: комментарий от anonymous

>> Если можно, зачем Линус писал с movsq?

Ну, например, для портабельности на более старые процы? Ведь уж movsb-то там точно был, на 386.

Жжоте. Линус писал с movsq ради портабельности на старые процы, на которых movsq нет. Ога-ога.

Да и не утверждаю я, что movsb бы тоже прооптимизировался, именно как раз по тому, что, из-за портабельности, мало кто бы пользовался такой оптимизацией, и, по этому, вряд ли её вообще добавили в новые процы.

Как раз movsb был и есть во всех процах, и, казалось бы, именно его и было бы наиболее эффективно прооптимизировать. И, кстати, предполагаю, что скомбинировать однобайтовые трансферы movsb в правильные группы было бы проще, чем перекомбинировать восьмибайтные трансферы movsq.

Элементарный пример – блиты в/из фреймбуфера. По-хорошему ими должен dma engine в видюхе заниматься, но если драйвер не ускоренный (типа xorg-video-vesa или, например, консольный uvesa), придется блитить процом.

Если драйвер блитит процом, а DMA остановлен, то смысл использовать некешируемый доступ?

Любая память, которая может быть изменена незаметно от процессора, всегда объявляется некэшируемой. Это никак не связано с наличием или использованием DMA. Даже если DMA не используется, видюха потенциально может что-то менять в своей памяти.

Или вот еще пример: насколько я понимаю, DRM предоставляет юзерспейсу возможность мэпать буферы, находящиеся в памяти видюхи. Таким образом, потенциально любая программа, использующая opengl, может иметь смэпанную некэшируемую память.

vadic ()
Ответ на: комментарий от vadic

Жжоте. Линус писал с movsq ради портабельности на старые процы,

на которых movsq нет. Ога-ога.

Я не аккуратно выразился, но, из-за портабельности, предполагаю
отсутствие оптимизации в movsb. Все знают, когда её использовать,
а когда - нет, и вряд ли будут это менять.

кстати, предполагаю, что скомбинировать однобайтовые трансферы movsb

в правильные группы было бы проще, чем перекомбинировать

восьмибайтные трансферы movsq.

Так кто сказал, что такой оптимизации нету то? Может есть, может
нет, главное, чтобы по movsq была.

Любая память, которая может быть изменена незаметно от процессора,

всегда объявляется некэшируемой.

Вы про vesa говорили - будете утверждать, что, при работе с VBE,
есть шанс, что GPU будет модифицировать память? Не вижу никаких
проблем сделать фреймбуфер кешируемым, по крайней мере при работе
с VESA, а может и в других случаях тоже.

anonymous ()
Ответ на: комментарий от vadic

Жжоте. Линус писал с movsq ради портабельности на старые процы, на

которых movsq нет. Ога-ога.

На самом деле, я имел ввиду выбор конкретной реализации, в
зависимости от проца. В glibc такой механизм имеется: для каждого
проца своя реализация memcpy(). Так вот, Линусовский вариант
сейчас не портабельный, и это хорошо: для других процов будет
выбираться другой вариант, например, movsd для 386. Если бы он
сделал всё на movsb, то вариант стал бы портабельным, и, в случае
какой-то небрежности, мог бы попасть на 386, где movsd гораздо
эффективнее.
Вот примерно это я пытался сказать той запутанной фразой. :)
Правда, при использовании LD_PRELOAD, выбор в glibc всё равно
вряд ли сработает...

anonymous ()
Ответ на: комментарий от anonymous

и, в случае какой-то небрежности, мог бы попасть на 386

Собственно, люди бы просто потестили на 386, и сказали
бы «ты чо тут накатал, дятел чтоль?». А так, непортабельную
версию будут только там, где надо, тестировать.
Так что всё логично, зря придираетесь.

anonymous ()
Ответ на: комментарий от anonymous

>> Жжоте. Линус писал с movsq ради портабельности на старые процы, на которых movsq нет. Ога-ога.

Я не аккуратно выразился, но, из-за портабельности, предполагаю отсутствие оптимизации в movsb. Все знают, когда её использовать, а когда - нет, и вряд ли будут это менять.

А как наличие или отсутсвие оптимизации влияет на портабельность?

кстати, предполагаю, что скомбинировать однобайтовые трансферы movsb в правильные группы было бы проще, чем перекомбинировать восьмибайтные трансферы movsq.

Так кто сказал, что такой оптимизации нету то? Может есть, может нет, главное, чтобы по movsq была.

А кто сказал, что для movsq она есть? Если ее нет для movsb, для которого ее сделать проще, какой смысл делать ее для movsq?

Любая память, которая может быть изменена незаметно от процессора, всегда объявляется некэшируемой.

Вы про vesa говорили - будете утверждать, что, при работе с VBE, есть шанс, что GPU будет модифицировать память?

vesa – это только один из примеров. И, да, надо еще посмотреть, не предоставляет ли vesa bios операций типа блитов, которые вполне могут быть реализованы используя ускорение.

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

А еще я и про DRI говорил.

Не вижу никаких проблем сделать фреймбуфер кешируемым, по крайней мере при работе с VESA, а может и в других случаях тоже.

Вы что, реально не понимаете, почему нельзя кэшировать память, которая может изменяться незаметно от проца, или это оговорка?

vadic ()
Ответ на: комментарий от vadic

А как наличие или отсутсвие оптимизации влияет на портабельность?

Наличие оптимизации на одном проце, и отсутствие её на другом -
плохая комбинация. Кто-то мог бы попробовать реализацию с movsb
на 386, а с movsq такого не будет.

А кто сказал, что для movsq она есть?

Тоже никто, однако это совсем не исключено.
Я просто вам указал на то, что, прежде, чем критиковать
предложенный Линусом пример, надо хотя бы ознакомиться с
предметной областью. Если вы уже _выяснили_, что её нет -
тогда это другое дело. А экстраполировать это из _недоказанного_
её отсутствия для movsb - вариант не практичный.

vesa – это только один из примеров. И, да, надо еще посмотреть, не

предоставляет ли vesa bios операций типа блитов, которые вполне могут

быть реализованы используя ускорение.

Если только это не VBE/AF, который нигде не поддерживается, то,
какие бы вы операции ни нашли, они будут выполняться хостовым процом.

А еще я и про DRI говорил.

Что-то я вообще очень сомневаюсь, что кто-то будет делать рендеринг
средствами GPU, и, одновременно, работать _с этим же регионом памяти_
через FB, и, при этом, закладываться не на какие-то реальные
механизмы синхронизации, а на некешируемость... По-моему, пример из
пальца высосан. Есть page flipping, shadow fb, TLB flush, да что
угодно есть, но нет, кто-то полезет одни и те же пиксели
переписывать одновременно процом и GPU...

Вы что, реально не понимаете, почему нельзя кэшировать память,

которая может изменяться незаметно от проца, или это оговорка?

Не надо передёргивать.

anonymous ()
Ответ на: комментарий от anonymous

>> А кто сказал, что для movsq она есть?

Тоже никто, однако это совсем не исключено. Я просто вам указал на то, что, прежде, чем критиковать предложенный Линусом пример, надо хотя бы ознакомиться с предметной областью. Если вы уже _выяснили_, что её нет - тогда это другое дело. А экстраполировать это из _недоказанного_ её отсутствия для movsb - вариант не практичный.

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

vesa – это только один из примеров. И, да, надо еще посмотреть, не предоставляет ли vesa bios операций типа блитов, которые вполне могут быть реализованы используя ускорение.

Если только это не VBE/AF, который нигде не поддерживается, то, какие бы вы операции ни нашли, они будут выполняться хостовым процом.

Кроме vesa я приводил пример и ускоренных линуксных фреймбуферов, которые тоже можно мэпать в юзерспейс.

А еще я и про DRI говорил.

Что-то я вообще очень сомневаюсь, что кто-то будет делать рендеринг средствами GPU, и, одновременно, работать _с этим же регионом памяти_ через FB,

При чем здесь FB? DRM выделяет буферы в памяти видюхи, например, текстуры, и позволяет opengl программам мэпать их в свое адресное пространство.

и, при этом, закладываться не на какие-то реальные механизмы синхронизации, а на некешируемость...

При чем здесь синхронизация вообще? Вы что, отрицаете, что *внутренняя память* видюхи с точки зрения проца является некэшируемой? Или вы отрицаете, что юзерспейсный код может получать *непосредственный* доступ к буферам в видюхе?

По-моему, пример из пальца высосан. Есть page flipping,

Page flipping – это просто переключение с одного scanout буфера на другой, к теме разговора прямого отношения не имеет.

shadow fb,

ShadowFB тоже может быть в памяти видюхи, а не только в системной.

TLB flush,

TLB – это другой кэш, он кэширует не содержимое памяти, а записи в таблицах страниц. ;) И я не очень понимаю, причем он тут.

да что угодно есть, но нет, кто-то полезет одни и те же пиксели переписывать одновременно процом и GPU...

Вы удивитесь, но такое возможно. Мигрировать буфер из VRAM в system ram и обратно, только для того чтоб проц мог в нем что-то посмотреть совсем необязательно.

Не вижу никаких проблем сделать фреймбуфер кешируемым, по крайней мере при работе с VESA, а может и в других случаях тоже.

Вы что, реально не понимаете, почему нельзя кэшировать память, которая может изменяться незаметно от проца, или это оговорка?

Не надо передёргивать.

" а может и в других случаях тоже." – это не вы сказали?

И, в любом случае, я показал, что по крайней мере в некоторых случаях мой вариант может быть лучше линусовского. Хотите привести реально эффективное возражение – покажите, чем он хуже. :)

vadic ()
Ответ на: комментарий от vadic

Независимо от наличия или отсутствия мифических оптимизаций, они в

любом случае неприминимы в случае некэшируемой памяти.

А должны?
Если вы хотите, при работе с некешируемой памятью, гнаться за
каждым тактом - используйте _отдельную_ реализацию memcpy().

Вы что, отрицаете, что *внутренняя память* видюхи с точки зрения

проца является некэшируемой?

Я не уверен, что, без DMA, кто-то реально будет писать данные
в буфер через GPU, и читать оттуда их процом. Если это кому-то надо -
я не против.

И, в любом случае, я показал, что по крайней мере в некоторых

случаях мой вариант может быть лучше линусовского.

А в большинстве (при кешировании) - может быть хуже из-за
значительно большего числа операций.

При чем здесь синхронизация вообще?

При том, что, проц может инвалидировать кеш вручную, синхронизируя
это выполнением операций на GPU. Но, конечно, это никому не нужно,
если они оба пишут/читают из одного региона.

TLB – это другой кэш, он кэширует не содержимое памяти, а записи

в таблицах страниц. ;)

Насколько я помню, TLB Flush так же и кеш, относящийся к данным
этих страницам сбрасывает... разве нет? Ну не суть...

anonymous ()
Ответ на: комментарий от anonymous

>> Независимо от наличия или отсутствия мифических оптимизаций, они в любом случае неприминимы в случае некэшируемой памяти.

А должны?

Нет конечно. В этом как раз мой пойнт: с некэшируемой памятью ничего кроме выравнивания вручную не поможет.

Если вы хотите, при работе с некешируемой памятью, гнаться за каждым тактом - используйте _отдельную_ реализацию memcpy().

Во-первых, это не гонка за каждым тактом, оценку производительности см. ниже. Во-вторых, юзерлэнд может не знать, кэшируется конкретный кусок памяти, или нет, и, соответственно, выбирать правильную функцию он не может. И, в-третьих, юзерлэндному коду вообще не должно быть дела до таких низкоуровневых вещей, библиотечные функции должны делать the right thing в любом случае.

Вы что, отрицаете, что *внутренняя память* видюхи с точки зрения проца является некэшируемой?

Я не уверен, что, без DMA, кто-то реально будет писать данные в буфер через GPU, и читать оттуда их процом. Если это кому-то надо - я не против.

Почему без DMA?

И, в любом случае, я показал, что по крайней мере в некоторых случаях мой вариант может быть лучше линусовского.

А в большинстве (при кешировании) - может быть хуже из-за значительно большего числа операций.

Таки значительного, да? Вы бы хоть код посмотрели сначала. Полдюжины тривиальных целочисленных операций, плюс один маленький rep movsb.

При больших размерах и в худшем случае (при некэшируемом источнике) мой код дает линейное преимущество, по сравнению с линусовским, потому что *каждый* оборот rep movsq будет выполняться быстрее.

В случае кэшируемой памяти мой код медленнее на небольшое константное время, которое, опять же, пренебрежимо при больших size.

А на маленьких размерах в обоих случаях будут доминировать затраты на вызов функции. Вызов динамически слинкованной функции – дело недешевое даже при не первом обращении, требует нескольких обращений в разные места в памяти (PLT, GOT) (которые совершенно не обязательно cache-hot), нескольких переходов (что может повлечь простои конвееров) etc. (При первом обращении вообще происходит вызов еще одной функции в линкере).

При чем здесь синхронизация вообще?

При том, что, проц может инвалидировать кеш вручную, синхронизируя это выполнением операций на GPU.

Чтобы обеспечить подобную синхронизацию почти наверняка потребуются обращения к ядру, что гораздо дороже простого обращения к некэшируемой памяти.

И чтобы уж совсем закрыть тему, посмотрите, что у вас говорит cat /proc/mtrr. Почти наверняка вы увидите достаточно большие области, объявленные write-combining или uncached. Это как раз и есть некэшируемая память. (По хорошему, надо смотреть не mtrr, а pat, но для этого надо парсить /proc/<pid>/pagemap)

Но, конечно, это никому не нужно, если они оба пишут/читают из одного региона.

Как раз именно в этом случае и надо обеспечивать когерентность кэша.

TLB – это другой кэш, он кэширует не содержимое памяти, а записи в таблицах страниц. ;)

Насколько я помню, TLB Flush так же и кеш, относящийся к данным этих страницам сбрасывает... разве нет?

Нет. INVLPG инвалидирует только TLB entry (AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions, p. 263). А INVD, WBINVD и CLFLUSH инвалидируют обычные кэши.

И даже если бы INVLPG инвалидировал и обычный кэш, все равно, если не изменялись таблицы страниц, TLB сбрасывать нет смысла, это только все замедлит.

vadic ()
Ответ на: комментарий от vadic

Во-вторых, юзерлэнд может не знать, кэшируется конкретный кусок

памяти, или нет, и, соответственно, выбирать правильную функцию

он не может.

Это вот как раз и предмет спора.
По мне - так он отлично знает, что его память кешируемая. А
если речь идёт об экзотических случаях взаимодействия с GPU, так
это он знает и подавно.

И, в-третьих, юзерлэндному коду вообще не должно быть дела до таких

низкоуровневых вещей, библиотечные функции должны делать the right

thing в любом случае.

В том-то и дело, что обращение к некешируемой памяти для юзерспейса -
дело совсем не обычное, и знать он об этом обязан.

А на маленьких размерах в обоих случаях будут доминировать затраты

на вызов функции.

Да тоже не факт. Это ж не сисколл, а «Полдюжины тривиальных
целочисленных операций» - это тоже совсем не ноп. :) Всё надо
смотреть и бенчмаркать. А что касается GOT - вы всё с fPIC
компилите? LD_BIND_NOW делайте, чтобы не было «тормозов при
первом вызове». Да, на длинных массивах разницы не будет, но вот
чего вы до некешируемой докопались - мне не понятно: случай для
юзерспейса не характерный, и вполне себе требует использования
особых инструментов. В ядре же есть memcpy_toio(), не так ли?
В юзерспейсе тоже накатают, если будет необходимость (пока, видать,
не было прецедентов).
Кстати, сдаётся мне, что с обычной некешируемой памятью ничего не
случится, если менять размер блоков пересылки. Это только
мемори-маппед регистрам может не понравиться, но для юзерспейса
это уж точно совсем вряд ли актуально.

Почему без DMA?

Это вы писали?
---
По-хорошему ими должен dma engine в видюхе заниматься, но если драйвер не ускоренный (типа xorg-video-vesa или, например, консольный uvesa), придется блитить процом.
---
Всё начиналось с работы без DMA. Что для DMA память не надо
кешировать, мало кто спорит.

anonymous ()
Ответ на: комментарий от anonymous

И, в-третьих, юзерлэндному коду вообще не должно быть дела до таких низкоуровневых вещей, библиотечные функции должны делать the right thing в любом случае.

В том-то и дело, что обращение к некешируемой памяти для юзерспейса - дело совсем не обычное, и знать он об этом обязан.

А зачем он должен об этом знать? Точнее, почему он для этого должен использовать отдельную функцию, если тот же функционал можно внести в стандартный memcpy практически бесплатно?

А на маленьких размерах в обоих случаях будут доминировать затраты на вызов функции.

Да тоже не факт. Это ж не сисколл,

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

а «Полдюжины тривиальных целочисленных операций» - это тоже совсем не ноп. :) Всё надо смотреть и бенчмаркать.

Это почти nop. Вы понимаете разницу между O(n) и O(1)?

А что касается GOT - вы всё с fPIC компилите?

Открою тайну: любая не статически слинкованная программа использует GOT и PLT. Пример надо приводить, или на слово поверите? Ну или можете в amd64 psABI посмотреть. С ia32 насколько я помню ситуация такая же.

LD_BIND_NOW делайте, чтобы не было «тормозов при первом вызове».

Это всего лишь переносит те же тормоза на момент запуска программы. Механизм все равно один и тот же.

Да, на длинных массивах разницы не будет, но вот чего вы до некешируемой докопались - мне не понятно: случай для юзерспейса не характерный, и вполне себе требует использования особых инструментов. В ядре же есть memcpy_toio(), не так ли?

А вы знаете, чем оно отличается от обычного memcpy? Только несколькими атрибутами для указателей. Причем эти атрибуты ничего не значат для gcc, а используются только sparse. Вот, например, версия для amd64:

static inline void
memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
{
        memcpy((void __force *)dst, src, count);
}

В юзерспейсе тоже накатают, если будет необходимость (пока, видать, не было прецедентов). Кстати, сдаётся мне, что с обычной некешируемой памятью ничего не случится, если менять размер блоков пересылки.

Дело не в размере, а в выравнивании.

Почему без DMA?

Это вы писали?

По-хорошему ими должен dma engine в видюхе заниматься, но если драйвер не ускоренный (типа xorg-video-vesa или, например, консольный uvesa), придется блитить процом.

Всё начиналось с работы без DMA. Что для DMA память не надо

кешировать, мало кто спорит.

Это был только один из примеров, про блиты. Я приводил и другие, например DRM'ные буферы, используемые для текстур, шейдеров и всего чего угодно.

vadic ()
Ответ на: комментарий от vadic

А зачем он должен об этом знать? Точнее, почему он для этого должен

использовать отдельную функцию, если тот же функционал можно внести

в стандартный memcpy практически бесплатно?

Даже если можно, лучше сделать 2 функции, которые будут делать
одно и то же.
1. Другим программистам потом будет понятнее, что тут с некешируемой
памятью работают.
2. Может быть архитектура проца, которая, к примеру, вместа битика
в странице памяти, использует разные инструкции для доступа с/без
кеширования.
То есть, в принципе, это лучше. И то, что в ядре эти функции
идентичны, как раз и говорит о том, что их всё равно лучше разделить.
Предлагаю всё-таки на эту тему не спорить, так как тут мы не
договоримся.

Это почти nop. Вы понимаете разницу между O(n) и O(1)?

Вы исходите из того, что функция _должна_ быть одна.
Мы не договоримся.

Открою тайну: любая не статически слинкованная программа

использует GOT и PLT.

Для чего ей GOT, если библиотека по фиксированному адресу
загружается?

Дело не в размере, а в выравнивании.

Выравнивание влияет только на скорость. А причиной, почему, в
случае некешируемого доступа, проц вряд ли бы рискнул делать
оптимизации с выравниванием, является как раз возможное изменение
размера.

anonymous ()
Ответ на: комментарий от anonymous

А зачем он должен об этом знать? Точнее, почему он для этого должен использовать отдельную функцию, если тот же функционал можно внести в стандартный memcpy практически бесплатно?

Даже если можно, лучше сделать 2 функции, которые будут делать

одно и то же.

Оккам не согласен.

2. Может быть архитектура проца, которая, к примеру, вместа битика в странице памяти, использует разные инструкции для доступа с/без кеширования.

Вы это серьезно? И, да, не «битика в странице памяти», а «битиков в таблице страниц» (ну и битиков в MTRR и в PAT тоже). Я начинаю сомневаться, что вы достаточно понимаете предметную область.

То есть, в принципе, это лучше. И то, что в ядре эти функции идентичны, как раз и говорит о том, что их всё равно лучше разделить.

Железная логика. Из того, что в ядре они ничем не отличаются (с точки зрения генерируемого кода), следует, что они должны отличаться? Жгете.

Предлагаю всё-таки на эту тему не спорить, так как тут мы не договоримся.

Да я уж понял, что вы не вполне понимаете, о чем говорите.

Открою тайну: любая не статически слинкованная программа использует GOT и PLT.

Для чего ей GOT, если библиотека по фиксированному адресу загружается?

А с чего это ей загружаться по фиксированному адресу? Shared object должен быть position-independent. А вдруг этот адрес уже занят? Только не предлагайте text relocs, это еще худший костыль.

И, да, фиксированные адреса облегчают эксплойты. Вы возможно удивитесь, но даже бинарники многие сейчас компиляются в PIE. Сравните:

$ file /usr/sbin/sshd /usr/bin/ssh /bin/ls
/usr/sbin/sshd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
/usr/bin/ssh:   ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
/bin/ls:        ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Видите разницу между ELF executable и ELF shared object?

Дело не в размере, а в выравнивании.

Выравнивание влияет только на скорость. А причиной, почему, в случае некешируемого доступа, проц вряд ли бы рискнул делать оптимизации с выравниванием, является как раз возможное изменение размера.

Причиной является то, что проц не имеет права *вообще никак* изменять операции с некэшируемой памятью: ни менять размер, ни порядок, и ни что другое.

vadic ()
Ответ на: комментарий от anonymous

> Открою тайну: любая не статически слинкованная программа использует GOT и PLT.

Для чего ей GOT, если библиотека по фиксированному адресу загружается?

И, да, даже если библиотека загружается по фиксированному адресу GOT и PLT все равно используются. Всякие prelink'и их никуда не убирают, а только заранее обсчитывают reloc'и.

vadic ()
Ответ на: комментарий от vadic

Вы это серьезно?

Вполне.

Я начинаю сомневаться, что вы достаточно понимаете предметную область.

Ваше право.

Железная логика. Из того, что в ядре они ничем не отличаются (с точки

зрения генерируемого кода), следует, что они должны отличаться?

Жгете.

Не говорите бред.
Из того, что, в ядре они не чем не отличаются по коду, однако же
разделены по названию, следует, что это имеет смысл. И для
юзерспейса - тоже, вполне.
Хватит искажать мои слова - на нервы действует.

А с чего это ей загружаться по фиксированному адресу?

$ ldd `which vncviewer`
   linux-vdso.so.1 => (0x00007fff5e3f4000)
   libSM.so.6 => /usr/lib64/libSM.so.6 (0x00007f9bbb229000)
   libICE.so.6 => /usr/lib64/libICE.so.6 (0x00007f9bbb00d000)
   libXext.so.6 => /usr/lib64/libXext.so.6 (0x00007f9bbadfb000)
   libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007f9bbaabc000)
И не надо мне тут втирать про address space randomization. :)

И, да, фиксированные адреса облегчают эксплойты.

Рад за них.

Причиной является то, что проц не имеет права *вообще никак*

изменять операции с некэшируемой памятью: ни менять размер, ни

порядок, и ни что другое.

Я вам уже сказал, что это только в случае mmapped register
актуально, а просто для памяти устройств, с которой и работает
юзерспейс - не особо актуально. Правда, к делу это не относится,
просто вы дёргаете с темы на тему всё время.

anonymous ()
Ответ на: комментарий от anonymous

Железная логика. Из того, что в ядре они ничем не отличаются (с точки зрения генерируемого кода), следует, что они должны отличаться? Жгете.

Не говорите бред. Из того, что, в ядре они не чем не отличаются по коду, однако же разделены по названию,

А вы знаете, для чего это сделано? Чтобы sparse мог обнаруживать ошибки в ядре. И, заметьте, разделение там не между кэшируемой и некэшируемой памятью, а между ядерным адресным пространством и пространством MMIO.

следует, что это имеет смысл. И для юзерспейса - тоже, вполне. Хватит искажать мои слова - на нервы действует.

Выпейте нервоуспокаивающих веществ.

А с чего это ей загружаться по фиксированному адресу?

[code] $ ldd `which vncviewer`

linux-vdso.so.1 => (0x00007fff5e3f4000) libSM.so.6 => /usr/lib64/libSM.so.6 (0x00007f9bbb229000) libICE.so.6 => /usr/lib64/libICE.so.6 (0x00007f9bbb00d000) libXext.so.6 => /usr/lib64/libXext.so.6 (0x00007f9bbadfb000) libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007f9bbaabc000)

И в чем ваш пойнт? ld.so просто показал, по каким адресам он в конкретном случае загрузил библиотеки. Нет никаких гарантий, что в следующий раз он их не загрузит по другим адресам:

$ ldd `which bash`
        linux-vdso.so.1 =>  (0x00007fffbd12a000)
        libncurses.so.5 => /lib/libncurses.so.5 (0x00007fa78cae4000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007fa78c8e0000)
        libc.so.6 => /lib/libc.so.6 (0x00007fa78c55c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa78cd50000)
$ ldd `which bash`
        linux-vdso.so.1 =>  (0x00007fffd85ff000)
        libncurses.so.5 => /lib/libncurses.so.5 (0x00007f21dda8a000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f21dd886000)
        libc.so.6 => /lib/libc.so.6 (0x00007f21dd502000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f21ddcf6000)

И не надо мне тут втирать про address space randomization. :)

Почему?

Причиной является то, что проц не имеет права *вообще никак* изменять операции с некэшируемой памятью: ни менять размер, ни порядок, и ни что другое.

Я вам уже сказал, что это только в случае mmapped register актуально, а просто для памяти устройств, с которой и работает юзерспейс - не особо актуально.

Я не знаю, что там для вас актуально, но процессоры таки никак не меняют обращения к некэшируемой памяти. Если вам это не нравится – жалуйтесь в amd и intel.

vadic ()
Ответ на: комментарий от vadic

А вы знаете, для чего это сделано? Чтобы sparse мог обнаруживать

ошибки в ядре.

А я вам какой пример приводил? «чтобы программист знал, что здесь
идёт работа с памятью устройства». Мало чем отличается от примера
со sparse.
Кроме того, если есть возможность их по-разному оптимизировать,
сейчас или в будущем, то тоже надо разделить. Одну из таких
возможностей мы и обсуждаем.
Вполне допускаю и создание/наличие проца, у которого доступ
будет выполняться и разными инструкциями.

Почему?

По тому, что это относительно недавно придумали, и не все используют.
И вайну пришлось писать свой прелоадер, чтобы эту мега-фичу
обходить, и есть персоналити флаг для её отключения (к счастью).
Если все либы будут PIC - это медленнее, как минимум.

anonymous ()
Ответ на: комментарий от anonymous

>> А вы знаете, для чего это сделано? Чтобы sparse мог обнаруживать ошибки в ядре.

А я вам какой пример приводил? «чтобы программист знал, что здесь идёт работа с памятью устройства».

Дыг проблема в том, что, например, opengl'ный программист может и не знать, с чем идет работа. Насколько я понимаю, DRM может мигрировать буферы из vram в cистемную память и обратно по своему усмотрению.

Мало чем отличается от примера со sparse. Кроме того, если есть возможность их по-разному оптимизировать, сейчас или в будущем, то тоже надо разделить. Одну из таких возможностей мы и обсуждаем. Вполне допускаю и создание/наличие проца, у которого доступ будет выполняться и разными инструкциями.

Квантовая физика учит нас, что в принципе допускать надо вообще почти все что угодно. Это не аргумент.

И не надо мне тут втирать про address space randomization. :)

Почему?

По тому, что это относительно недавно придумали, и не все используют. И вайну пришлось писать свой прелоадер, чтобы эту мега-фичу обходить, и есть персоналити флаг для её отключения (к счастью). Если все либы будут PIC - это медленнее, как минимум.

Открою вам очередную страшную тайну: все эльфовые shared objects всегда компилировались в PIC. Если вы откроете ia32 ELF psABI от 19xx-бородатого года, то вы увидите там: «To maximize text sharing, shared objects conventionally use position-independent code, in which instructions contain no absolute addresses.»

И даже до появления address space randomization один и тот же so мог быть одновременно смэпан в разные процессы по разным адресам, просто потому, что разные процессы могли загружать до него разное количество других so, и, соответственно, доступные адреса могли быть разными.

--------

В общем, слив зосчитан. Я таки надеялся, что вы приведете действительно корректное возражение, но вы так и пропустили все мои (иногда довольно толстые) намеки.

А на самом деле, я все время подменял типы кэширования. Во всех приведенных мной пример на самом деле память объявляется не uncacheable, а write-combining, а для WC разрешены спекулятивные чтения, поэтому и без выравнивания rep movsq будет тормозить только на первом обороте, а не на всех.

You've been trolled. Поздравляю.

vadic ()
Ответ на: комментарий от vadic

Дыг проблема в том, что, например, opengl'ный программист может и

не знать, с чем идет работа.

Он не знает, выделил ли он память маллоком, или нет?
Если какой-то регион может быть кешируемым, а может быть не
кешируемым, то конечно нужно предполагать, что он не кешируемый.

Открою вам очередную страшную тайну: все эльфовые shared objects

всегда компилировались в PIC.

Мы говорим про вызов функции бинарник->so, а не so->so, не так ли?
Так вот вышеозначенный бинарник не собран с -fPIC, умник вы наш.

И даже до появления address space randomization один и тот же so мог

быть одновременно смэпан в разные процессы по разным адресам

Вот именно, что в разные процессы, с разными бинарниками.
Но для одного бинарника он не менялся.
Короче, вы уже ахинею начали нести, похоже.

You've been trolled. Поздравляю.

То, что вы тролль - я давно понял, но мне как-то не интересно
обсуждать вашу личность. По теме вам сказать больше нечего -
ну и до свидания.

anonymous ()
Ответ на: комментарий от anonymous

Дыг проблема в том, что, например, opengl'ный программист может и не знать, с чем идет работа.

Он не знает, выделил ли он память маллоком, или нет?

Он естественно не выделял память malloc'ом, а получил ее от DRM.

Если какой-то регион может быть кешируемым, а может быть не кешируемым, то конечно нужно предполагать, что он не кешируемый.

Я не о том говорю. Программист может не знать, в каком регионе *физической памяти* в данный момент находится буфер. Виртуальный адрес у него постоянный, но при этом он может мигрировать из vram в system ram и обратно.

Открою вам очередную страшную тайну: все эльфовые shared objects всегда компилировались в PIC.

Мы говорим про вызов функции бинарник->so, а не so->so, не так ли? Так вот вышеозначенный бинарник не собран с -fPIC, умник вы наш.

Я уже говорил, что даже если сам бинарник не собран в PIC, он все равно содержит в себе GOT и PLT. Например:

#include <stdlib.h>

int main (int argc, char **argv)
{
    exit(0);
}

Компилируем его без PIC. Вызов exit() в результате выглядит так:

  4004f3:       bf 00 00 00 00          mov    $0x0,%edi
  4004f8:       e8 e3 fe ff ff          callq  4003e0 <exit@plt>

А вот exit@plt:

Disassembly of section .plt:

00000000004003d0 <exit@plt-0x10>:
  4003d0:       ff 35 92 04 20 00       pushq  0x200492(%rip)        # 600868 <_GLOBAL_OFFSET_TABLE_+0x8>
  4003d6:       ff 25 94 04 20 00       jmpq   *0x200494(%rip)        # 600870 <_GLOBAL_OFFSET_TABLE_+0x10>
  4003dc:       0f 1f 40 00             nopl   0x0(%rax)

00000000004003e0 <exit@plt>:
  4003e0:       ff 25 92 04 20 00       jmpq   *0x200492(%rip)        # 600878 <_GLOBAL_OFFSET_TABLE_+0x18>
  4003e6:       68 00 00 00 00          pushq  $0x0
  4003eb:       e9 e0 ff ff ff          jmpq   4003d0 <_init+0x18>

Изначально в GOT+0x18 записан адрес pushq, переход на <_init+0x18> это на самом деле переход на PLT+0, т.е. обращение к dl.so, который уже записывает в GOT+0x18 адрес exit(). Как видите, и GOT, и PLT присутствуют.

И даже до появления address space randomization один и тот же so мог быть одновременно смэпан в разные процессы по разным адресам

Вот именно, что в разные процессы, с разными бинарниками. Но для одного бинарника он не менялся.

И что, что в разные? Все равно в оба бинарника мэпалась *одна и та же* копия .text из so, поэтому он обязан был быть PIC.

Короче, вы уже ахинею начали нести, похоже.

Из того, что вы что-то не понимаете, не следует, что это ахинея.

vadic ()
Ответ на: комментарий от vadic

Он естественно не выделял память malloc'ом, а получил ее от DRM.

Тогда ему лучше думать, что она не кешируемая.

Компилируем его без PIC. Вызов exit() в результате выглядит так:

Не охота проверять... В гугле нашёл только вот это:
http://gcc.gnu.org/ml/gcc-help/2004-10/msg00178.html
---
I tried compiling our shared libraries without -fPIC and it works fine
on an x86. We took a small hit relocating the shared libraries when
they were loaded, but after that our performance is comparable to code
linked into the application.
---
И там ещё он пишет, что избавился от GOT.

anonymous ()

Обновился... Firefox,epiphany и Chrome теперь не работают. Работает только lynx и Opera. Жалуются все на неожиданное поведение glibc...

lucentcode ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.