LINUX.ORG.RU

Декларации типов остаются в библиотеках?

 ,


0

6

Здравствуйте

Подскажите, пожалуйста. Такой странный вопрос. Вот наопределял я структуры и enum-ы в файле, скомпилировал в .so или в .a. Эти определения где-то сохранились в либе?

Нужно ли мне декларировать имена типов структур с префиксами, чтобы не было пересечений или эти имена не вылезут за пределы compilation unit?

И вообще, какие еще символы в либах сохраняются кроме определений функций и глобальных переменных?

★★★★★

Последнее исправление: makoven (всего исправлений: 3)

Это уровень компилятора.

Для 99% компиляторов Си работает следующее:

После того как Си компилируется в машкод, единственным осмысленным артефактом в полученном объектном файле остаются лишь «символы», которые используются при линковке и dl*, для того чтобы взять адрес функции/переменной по имени. Типы же, структуры, итп, исчезают из дискурса навсегда. И остаются лишь в хедерах, для чего собственно последние и нужны.

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

Чтобы обойти это, Microsoft например в свое время придумала COM/OLE, в частности концепцию typelib, а потом аж целый .NET

А некоторые другие придумали Java

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

Понял. А обращение к полям структуры - это получается просто адрес в памяти плюс смещение? Тогда получается, все компиляторы и дистрибутивы солидарны относительно размеров int, long и проч?

makoven ★★★★★
() автор топика

Нет, конечно. C типов в рантайме не знает. Но они есть в заголовочниках, конечно.

Так что если есть видимая снаружи функция, которая принимает или возвращает такой тип, то лучше, чтоб и на нём были префиксы

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

Первый пункт - да.

Второй пункт - нет. Но, как правило, на одной платформе и с одним компилятором, получается что да. Т.е. если у тебя линукс и GCC, можешь быть уверен. А вот если код переносишь на винду - уже нет. Там, например, long это всегда 32 бита, итд.

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

А обращение к полям структуры - это получается просто адрес в памяти плюс смещение

Типа того, да.

Тогда получается, все компиляторы и дистрибутивы солидарны относительно размеров int, long и проч?

Если они придерживаются одного какого-то ABI, то да.

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

Сохраню, может почитаю когда скучно будет)

makoven ★★★★★
() автор топика
Ответ на: комментарий от lovesan

хочешь сказать, шланг с гцц сильно различаются? Хотя в чём-то наверняка да, гцц вообще много что не умеет, но в целом-то один хрен.

А то тс испугается всего этого зоопарка

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

Компиляю и шлангом и гцц. Разницы не замечал. По крайней мере с либами из арчика линкуется без проблем)

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

Ну естесственно. Так что можешь считать, что на одной архитектуре и ОС все соглашения, размеры, выравнивания и прочее одно и то же. Поэтому, всё со всем линкуется и работает.

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

А вот взять x86 и x86-64 — разница уже есть. Поэтому, когда запускаешь x86 приложение под x86-64 платформу, нужны x86 библиотеки.

Потому что если бы теоретически x86 и x86-64 слинковались бы, работать бы не смогли, потому что там ABI разное

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

Потому что в пределах одной платформы гцц со шлангом обычно компилируется с поддержкой одного и того же ABI. В случае линукса это делается мейнтейнерами твоего дистрибутива, но тебе совершенно никто не мешает собрать себе свою собственную версию gcc, которая будет несовместима со всей остальной системой. шланг, вроде бы, даже пересобирать не надо, у него можно платформу менять на лету через --target

Gvidon ★★★★
()
Последнее исправление: Gvidon (всего исправлений: 1)
Ответ на: комментарий от tailgunner

В специальных секциях отладочной информации.

Которые не выкидываются только в специальных отладочных сборках на компьютерах разработчиков

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

Которые не выкидываются только в специальных отладочных сборках на компьютерах разработчиков

Капитан, вы поставляете .a без отладочной информации? Надеюсь, вы сгорите в аду, Капитан.

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

А если это например библиотека secure-drm-модуля, который под NDA?
Боюсь что с дебагом он будет бесполезен.
Казалось бы, DRM можно смело сжечь в аду, но иногда они работают на благо.
Например, античиты в играх. Не вижу им альтернативы кроме как не играть по сети. Не ужели придётся отказаться от мультиплеера в игорях?

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

А если это например библиотека secure-drm-модуля, который под NDA?

Я же сказал - в специальных секциях отладочной информации.Ты можешь их вырезать.

Боюсь что с дебагом он будет бесполезен.

А я боюсь, что это вообще будет не ELF, а зашифрованная фигня.

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

Ты ссылку-то мою открывал? Вот это всё и действует на линуксе, бсд и куче прочих осей с x86-64 процессором. А под другие оси по-любому придется перекомпилировать.

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

Только нигде кроме как при отладке эта инфа не пригодится. Прототип функции или тип переменной в рантайме всё равно не узнать

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

Только нигде кроме как при отладке эта инфа не пригодится

Стандартно да.

Прототип функции или тип переменной в рантайме всё равно не узнать

Всегда было любопытно - почему на DWARF не сделали рефлексию.

tailgunner ★★★★★
()

ещё если интересно, можешь про elf формат почитать. хоть к теме это мало относится. а так тебе сказали - только компилятор видит прототип функции (из .h файлов), а «понимают» вызывающая и вызываемая функция друг-друга благодаря общему ABI, поэтому рантайму о типах не надо знать — компилятор всё сделал

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

Всегда было любопытно - почему на DWARF не сделали рефлексию.

Это прям таки загадка века. А вообще я понятия не имею, как он устроен. Там что, прям прототипы функций хранятся? Или тупо соответствие ассемблерного кода строкам на си?

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

В аду должны гореть те кто «поставляет» бинарники в любом виде, а остальные соберут как им требуется. Кроме того, статические библиотеки не нужны.

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

Ну по-моему так (на «поставке бинарников») 95% ляликсов устроено

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

В аду должны гореть те кто «поставляет» бинарники в любом виде

Ты уже собираешь компилятор пошаговым выполнением исходников?

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

Там что, прям прототипы функций хранятся?

Не знаю, что для тебя «прям», но прототипы там хранятся.

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

почему на DWARF не сделали рефлексию

Делали, какие-то варианты даже гуглятся. Не нужно.

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

Ты правда хочешь развязать тут ещё и этот срач? :)

Динамическая линковка грозит усложненим реализации языка и потерей производительности, иногда - довольно серьёзной. Если мы говорим о простом C, то здесь это не так критично, потому как полность отсутствует полиморфизм. Как только мы переходим к более интересным языкам, хотя бы к C++, то статическая линковка становится необходимой. Темплейты в C++ - это классический пример статической линковки, и динамическая в данном случае была бы довольно сложно реализуема: пришлось бы по сути запиливать боксинг и добавлять таблицу виртуальных функций ко всем типам.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Ты правда хочешь развязать тут ещё и этот срач? :)

Для срача надо хоть немного разбираться в теме. А я полный профан)

Темплейты в C++ - это классический пример статической линковки, и динамическая в данном случае была бы довольно сложно реализуема

А как объяснить то, что boost-libs поставляются в виде набора so-шек?

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

А как объяснить то, что boost-libs поставляются в виде набора so-шек?

Boost - не только темплейты же.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

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

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

А как объяснить то, что boost-libs поставляются в виде набора so-шек?

Да так, что автор того псто просто не знает, о чём рассуждает. Темплейты, фигейты, полиморфизм к линковке не относятся вообще никак. Это вообще заморочки языка C++, а задача линковки — собрать одну программу из множества мелких модулей. Такая задача есть и в C, и в C++, и в фортране — короче ещё в целой куче языков.

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

Ок. Еще вопрос возник. А вот эти символы в библиотеках и и сами библиотеки - они актуальны на каком уровне? Есть ли поддержка их в процессоре? Или, может, в ядре? Или еще где-то? Я так понимаю, на каком-то уровне символы и so-шки исчезают и остаются только адреса памяти?

makoven ★★★★★
() автор топика
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от makoven

Ну конечно не в процессоре))) Ну и вопрос)

Когда ты пишешь в консоли имя комманды, происходит некий системный вызов (man 2 execve). Ядро смотрит, что за тип исполняемого файла ты ему скормил, читает содержимое этого файла, создает новый процесс, новое адресное пространство, стек, кучу итд, устанавливает специальным образом регистры (%rsp, %rip, итд) и либо передает управление в новый процесс, либо запускает интерпретатор. Такой интерпретатор нужен, например, если есть шебанг. Для динамически слинкованных программ тоже нужен интерпретатор. В ELF файле полный путь к интерпретатору записан в program header PT_INTERP.

Для динамических бинарных ELF файлов интерпретатор — это динамический линковщик, который загружает все библиотеки, которые нужны программе, а также делает релокацию символов. Релокация — это процесс исправления адресов, записаных в файле на адреса, которые реально будут в памяти процесса. Это нужно, потому что заранее до запуска программы ты не можешь гарантировать, что библиотека загрузится в какое-то конкретное место в памяти. Релокация осуществляется на основе секций .plt и .got (и других :)) в ELF файле, а также base address'а, куда была загружена программа/библиотека. После этого процесс почти готов и управление передается ему по адресу, находящемуся в поле e_entry в ELF header'е

Этот адрес ещё не main, но уже внутри твоего нового процесса. Обычно эту функцию называют _start. Она достает из памяти значения argc, argv и env и копирует их в соответствующие регистры для вызова main, вызывает библиотечные конструкторы и зовёт main.

После return в main вызываются деструкторы, функция, переданная atexit, зовётся ядро, чтобы уничтожить процесс

В статических бинарниках интерпретатор не нужен

Полезные ссылки: http://www.mindfruit.co.uk/2012/06/relocations-relocations.html

http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf

Ну и SystemV x86-64 abi выше

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

Мне нужно логиниться, чтобы уличить тебя в безграмотности? Может и ты по имени-отчеству назовешься?

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

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

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

Спасибо большое. Стало понятнее. А libc.so точно так-же обрабатывается линковщиком или ей отведена какая-то особая роль?

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

libc.so

Да, абсолютно точно так же. В этом плане она ничем не выделяется на фоне других. Кстати, динамический линкер (у меня в FreeBSD /libexec/ld-elf.so.1) тоже имеет расширение .so, но на самом деле особая программа, как я уже написал. Все остальные .so одинаковы. А вот точка входа _start находится в файле с названием crt1.o или crt0.o Есть либо такой вариант, либо такой, эти названия по большей части исторические. crt0.o не поддерживает библиотечные конструкторы/деструкторы, а crt1.o поддерживает.

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

Расскажи почему шаблонные функции в C++ нельзя вынести в динамическую библиотеку и почему их обязательно нужно писать в хидерах.

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