Динамические библиотеки .So
Библиотека — это набор скомпонованных особым образом объектных файлов. Библиотеки подключаются к основной программе во время линковки. По способу компоновки биб- лиотеки подразделяют на архивы (статические библиотеки, static libraries) и совместно используемые (динамические библиотеки, shared libraries). В Linux, кроме того, есть меха- низмы динамической подгрузки библиотек. Суть динамической подгрузки состоит в том, что запущенная программа может по собственному усмотрению подключить к себе какую- либо библиотеку. Благодаря этой возможности создаются программы с подключаемыми плагинами, такиекак XMMS.
Статическая библиотека — это просто архив объектных файлов, который подключается к программе во время линковки. Эффект такой же, как при компиляции файлов отдельно.
В отличие от статических библиотек, код совместно используемых (динамических) биб- лиотек не включается в бинарник.
Рассмотрим преимущества и недостатки статических и совместно используемых библиотек. Статические библиотеки делают программу более автономной: программа, скомпонован- ная со статической библиотекойможет запускаться на любом компьютере, не требуя наличия этой библиотеки (онауже «внутри»бинарника). Программа, скомпонованная с динамической библиотекой, требует наличия этой библиотеки на том компьютере, где она запускается, поскольку в бинарнике некод, а ссылка накод библиотеки. Не смотря на такую зависимость, динамические библиотеки обладают двумя существенными преиму- ществами. Во-первых, бинарник, скомпонованный с совместно используемой библиотекой меньше размером, чем такой же бинарник, с подключенной к нему статической библиотекой (статически скомпонованный бинарник). Во-вторых, любая модернизация динамической
библиотеки, отражается на всех программах, использующих ее. Таким образом, если неко- торую библиотеку foo используют 10 программ, то исправление какой-нибудь ошибки в foo или любое другое улучшение библиотеки автоматически улучшает все программы, которые используют эту библиотеку.
Именно поэтому динамические библиотеки называют совмест- но используемыми. Чтобы применить изменения, внесенные в статическую библиотеку, нужно пересобрать все 10 программ.В Linux статические библиотеки обычно имеют расширение .a (Archive), а совместно используемые библиотеки имеют расширение .so (Shared Object). Хранятся библиотеки, как правило, в каталогах /lib и /usr/lib. В случае иного расположения (относится только к совместно используемым библиотекам), приходится явно указать путь, чтобы программа запустилась[2].
В динамическую библиотеку вынесена функция, отвечающая за взаимодействие с системой. При компиляции, отдельно собирается библиотека, и отдельно исполняемый файл.
user@host$ g++ -o libparse.so -shared -fPIC -std=c++14 parse.cpp user@host$ g++ main.cpp -L. -lparse -o netmonitor
Теперь простой запуск приложения приведёт к ошибке, т.к. система ожидает наличия файла библиотеки в строго определённом месте.
user@host$ ./netmonitor
./netmonitor: error while loading shared libraries: libparse.so: cannot open shared user@host$
Отсутствие библиотеки можно легко обнаружить при запуске утилиты ldd (строка 2, листинг 6).
Листинг 6: Демонстрация работы программы ldd для приложения, использующего дина- мическую библиотеку
1
2
3
4
5
6
7Эту проблему можно обойти если явным образом перед запуском программы передать путь к библиотеке через параметры
user@host$ LD_LIBRARY_PATH=. ./netmonitor enp2s0 enp2s0:
Receive 9686554269 bytes (6645253 packets)
Transmit 645757402 bytes (3625776 packets) user@host$
Из результатов анализа распределения памяти можно сделать вывод о том, что при запуске программы ей выделяется свободное место в памяти, в следствии чего адреса, по которым располагаются точкивхода или подключения меняются при повторных запусках,однако, состав, порядок и смещения загружаемыхмодулей относительно начального адреса в выделенной памяти не изменяется.
MASM, TASM, FASM, NASM под Windows и Linux / Хабр
В данной статье я хочу рассмотреть вопросы, которые могут возникнуть у человека, приступившего к изучению ассемблера, связанные с установкой различных трансляторов и трансляцией программ под Windows и Linux, а также указать ссылки на ресурсы и книги, посвященные изучению данной темы.
MASM
Используется для создания драйверов под Windows.
По ссылке переходим на сайт и скачиваем пакет (masm32v11r.zip). После инсталляции программы на диске создается папка с нашим пакетом C:\masm32. Создадим программу prog11.asm, которая ничего не делает.
.586P .model flat, stdcall _data segment _data ends _text segment start: ret _text ends end start
Произведём ассемблирование (трансляцию) файла prog11.asm, используя ассемблер с сайта masm32.
Ключ /coff используется здесь для трансляции 32-битных программ.
Линковка производится командой link /subsystem:windows prog11.obj (link /subsystem:console prog11.obj)
Как сказано в Википедии
MASM — один из немногих инструментов разработки Microsoft, для которых не было отдельных 16- и 32-битных версий.
Также ассемблер версии 6. можно взять на сайте Кипа Ирвина kipirvine.com/asm, автора книги «Язык ассемблера для процессоров Intel».
Кстати, вот ссылка на личный сайт Владислава Пирогова, автора книги “Ассемблер для Windows”.
MASM с сайта Microsoft
Далее скачаем MASM (версия 8.0) с сайта Microsoft по ссылке. Загруженный файл носит название «MASMsetup.exe». При запуске этого файла получаем сообщение -«Microsoft Visual C++ Express Edition 2005 required».
Открываем этот файл архиватором (например 7zip). Внутри видим файл setup.exe, извлекаем его, открываем архиватором. Внутри видим два файла vc_masm.msi,vc_masm1.cab. Извлекаем файл vc_masm1.cab, открываем архиватором. Внутри видим файл FL_ml_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8. Переименовываем его в файл fl_ml.exe, далее, произведём ассемблирование файла prog11.asm, используя ассемблер fl_ml.exe.
MASM в Visual Studio
Также MASM можно найти в папке с Visual Studio (у меня VS 10) вот здесь: C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\ml.exe.
Для того, чтобы запустить на 32- или 64-разрядной системе и создавать программы, работающие как под 32-, так и под 64-разрядной Windows, подходит MASM32 (ml.exe, fl_ml.exe). Для того, чтобы работать на 32- и 64-разрядных системах и создавать программы, работающие под 64-разрядной Windows, но неработающие под 32-разрядной нужен ассемблер ml64.exe. Лежит в папке C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64 и вот здесь — C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64.
TASM
Программный пакет компании Borland, предназначенный для разработки программ на языке ассемблера для архитектуры x86. В настоящее время Borland прекратила распространение своего ассемблера.
Скачать можно, например, здесь. Инсталлятора нет, просто извлекаем программу. Вот исходник из книги Питера Абеля (рис. 3.2) «Язык Ассемблера для IBM PC и программирования».
stacksg segment para stack 'stack' db 12 dup ('stackseg') stacksg ends codesg segment para 'code' begin proc far assume ss:stacksg,cs:codesg,ds:nothing push ds sub ax,ax push ax mov ax, 0123h add ax, 0025h mov bx,ax add bx,ax mov cx,bx sub cx,ax sub ax,ax nop ret begin endp codesg ends end begin
Выполним ассемблирование (трансляцию) файла abel32.asm.
Корректность работы программы можно проверить, произведя линковку (tlink.exe) объектного файла и запустив полученный файл в отладчике.
Как было сказано выше, MASM можно использовать для работы с 16-битными программами. Выполним ассемблирование (трансляцию) программы abel32.asm с помощью ассемблера MASM:
Ключ /coff здесь не используется.
Линковка производится файлом link16.exe
Вот здесь приводится порядок действий, которые необходимо выполнить для запуска TASM в DOSbox. Для линковки понадобится файл DPMI16BI.OVL
FASM
В статье Криса Касперски «Сравнение ассемблерных трансляторов» написано, что «FASM — неординарный и весьма самобытный, но увы, игрушечный ассемблер. Пригоден для мелких задач типа „hello, world“, вирусов, демок и прочих произведений хакерского творчества.»
Скачаем FASM с официального сайта. Инсталлятора нет, просто извлекаем программу. Откроем fasm editor — C:\fasm\fasmw.exe. В папке C:\fasm\EXAMPLES\HELLO есть файл HELLO.asm.
include 'win32ax.inc' .code start: invoke MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK invoke ExitProcess,0 .end start
Откроем файл HELLO.asm из fasmw.exe. Изменим строку include ‘win32ax.inc’ на строку include ‘c:\fasm\INCLUDE\WIN32AX.
INC’. Запускаем из меню Run → Run.Вот ссылки на ресурсы, посвященные FASM:
→ FASM на Cyberforum’е
→ FASM на asmworld .com программы под Dos
→ Цикл статей «Ассемблер под Windows для чайников»
→ Сайт на narod’е
FASM в Linux
Для того, использовать FASM в Linux (у меня Ubuntu), скачаем соответствующий дистрибутив (fasm-1.71.60.tgz), распакуем его, в папке у нас будет бинарный файл fasm, копируем этот файл в /usr/local/bin для того, чтобы можно было запускать его из консоли, как любую другую команду.Выполним ассемблирование программы hello.asm из папки fasm/examples/elfexe/hello.asm.
Корректность работы программы можно проверить в отладчике.
Nasm
Nasm успешно конкурирует со стандартным в Linux- и многих других UNIX-системах ассемблером Gas.
Nasm в Linux можно установить с помощью менеджера пакетов или из командной строки: в дистрибутиве Debian (Ubuntu) командой apt-get install nasm, в дистрибутивах Fedora, CentOS, RedHat командой yum install nasm.
Создадим программу, которая 5 раз выводит сообщение “Hello”. Пример взят из книги Андрея Викторовича Столярова “Программирование на языке ассемблера NASM для ОС UNIX”. Учебник, а также библиотека “stud_io.inc” есть на личном сайте автора.
%include "stud_io.inc" global _start section .text _start: mov eax, 0 again: PRINT "Hello" PUTCHAR 10 inc eax cmp eax, 5 jl again FINISH
Выполним ассемблирование и линковку и запустим файл hello.asm.
$ nasm -f elf hello.asm $ ld hello.o -o hello $ ./hello
Для 64bit необходимо использовать команду nasm -f elf64 hello.asm
NASM для Windows
NASM для Windows можно установить, скачав соответствующий дистрибутив с соответствующего сайта.
Ассемблирование:nasm -f bin имя_файла.asm -o имя_файла.com
Ссылки на ресурсы, посвященные Nasm:
→ Сайт А.В. Столярова
→ Сайт, на котором лежит электронный учебник (в архиве)
→ То же самое
AS
Стандартный ассемблер практически во всех разновидностях UNIX, в том числе Linux и BSD. Свободная версия этого ассемблера называется GAS (GNU assembler). Позволяет транслировать программы с помощью компилятора GCC.
Из учебников удалось найти только книгу на английском «Programming from the ground up». На русском удалось найти только одну главу из книги С. Зубкова «Assembler для DOS, Windows и UNIX».
Возьмем пример программы, которая ничего не делает, с сайта. Создадим программу gas.s
.section .text .globl _start _start: movl $1, %eax movl $2, %ebx int $0x80
Выполним ассемблирование (трансляцию), линковку и запуск программы:
$ as -o gas.o gas.s $ ld -o gas gas.o $ ./gas
Если в данной программе изменить _start на main, то можно выполнить ассемблирование (трансляцию) и линковку компилятором gcc.
.section .text .globl main main: movl $1, %eax movl $2, %ebx int $0x80
Выполним ассемблирование (трансляцию), линковку и запуск программы:
$ gcc gas. s -o gas $ ./gas
Выводы: если вы изучаете программирование под Windows, то вы можете остановить свой выбор на Masm; Tasm больше не поддерживается, но для обучения по старым классическим учебникам подойдёт.
Под Linux Gas подойдет тем, кто использует GCC, а тем, кому не нравится синтаксис Gas, подойдёт Nasm.
P.S. Про обработку строк в ассемблере на примере создания транслятора простого «эзотерического» языка можно прочитать здесь.
P.P.S. Упрощенный ограниченный набор ассемблерных инструкций используется в учебной модели компьютера Little Man Computer, которому у меня также посвящено несколько статей ссылка.
gcc — невозможно связать сборку nasm с функцией libc (требуется динамическая релокация R_X86_64_PC32)
Задавать вопрос
спросил
Изменено 5 лет, 8 месяцев назад
Просмотрено 897 раз
Из учебника по nasm здесь я получил следующий код для программы сборки:
global main внешние путы раздел . текст основной: мов рди, сообщение колл ставит мов ракс, 0 рет сообщение: db "Привет, мир", 0
Я собираю его с помощью nasm -felf64 hola.asm
Однако мне не удалось связать получившийся файл hola.o.
Я пытался (согласно руководству) запустить gcc hola.o
, но это приводит к следующей ошибке:
/usr/local/bin/ld: ошибка: hola.o: требуется динамическая релокация R_X86_64_PC32 против «помещений», которая может переполниться во время выполнения; перекомпилировать с -fPIC
collect2: ошибка: ld вернул 1 статус выхода
передача -fPIC
в не помогает, как и -Wl,-I/lib/ld-2.25.so
.
Мои попытки связать напрямую с ld не увенчались успехом, я думаю, потому что я упускаю то, что на самом деле определяет символ _start
, что приводит к ошибке seg, когда я запускаю полученный исполняемый файл.
Я также пытался добавить стандартную версию
, как было предложено в разделяемой библиотеке R_X86_64_PC32, но это тоже не работает.
Я также пытался написать основной метод на C, а затем вызвать функцию, которая вызывает puts в ассемблере. Это также дает мне ошибку динамического перемещения.
Как связать файл сборки nasm, чтобы он мог вызывать функцию в libc на x86_64 linux?
- gcc
- nasm
- ld
Я смог заставить это работать, изменив 9Вызов 0017 ставит на вызов ставит wrt ..plt
.
Я понял это после прочтения раздела 9.2.5 документации nasm: http://www.nasm.us/doc/nasmdoc9.html#section-9.2.5.
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Сборка— nasm — Не удается связать объектный файл с ld в macOS Mojave
Задавать вопрос
спросил
Изменено 1 год, 5 месяцев назад
Просмотрено 12 тысяч раз
Пытаюсь собрать простой Hello World, который отлично работал в предыдущей версии macOS:
глобальный запуск раздел . текст начало: мов ракс, 0x02000004 мов рди, 1 мов рси, мсг мов рдкс, 13 системный вызов мов ракс, 0x02000001 xor рди, рди системный вызов раздел .данные msg: db "Привет, мир!", 10
Затем я использую nasm
и ld
, как и раньше:
$ nasm -f macho64 hello.asm $ ld привет.о -о привет
Но ld
выдает следующую ошибку:
ld: предупреждение: в командной строке не указана минимальная версия Неопределенные символы для архитектуры x86_64: "_main", ссылка из: неявный вход/запуск для основного исполняемого файла ld: символ(ы) не найден(ы) для предполагаемой архитектуры x86_64
Я попытался переключить start
на _main
, но получил следующее:
ld: предупреждение: в командной строке не указана минимальная версия ld: динамические основные исполняемые файлы должны быть связаны с libSystem.dylib для предполагаемой архитектуры x86_64.
Даже не знаю, что это может означать.
- macos
- сборка
- nasm
- ld
1
ld
требуется флаг -lSystem
, чтобы предотвратить появление этой ошибки. Также для удаления предупреждения требуется -macosx_version_min
. Правильный способ использования ld
: ld hello.o -o hello -macosx_version_min 10.13 -lSystem
.
Обновлен в macOS 11 и выше, вам также необходимо передать -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
, чтобы он правильно находил библиотеку -lSystem
. Вы можете использовать -L$(xcode-select -p)/SDKs/MacOSX.sdk/usr/lib
для динамической оценки правильного пути, если это необходимо.
4
В дополнение к ответу @Verloren выше (https://stackoverflow. com/a/52830915/1189569)
У меня возникла проблема с macOS Big Sur (macOS 11.1), где флаг -lSystem
не смог найти libSystem.dylib
с ошибкой
ld: библиотека не найдена для -lSystem
я узнал для macOS Big Sur, цитата из ссылки: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-release-notes
Новое в macOS Big Sur 11.0.1, система поставляется со встроенным динамическим кеш компоновщика всех предоставляемых системой библиотек. В рамках этого изменения копии динамических библиотек больше не присутствуют в файловой системе. Код, который пытается проверить наличие динамической библиотеки, просматривая для файла по пути или перечисление каталога не удастся…
что все копии динамических библиотек находятся не в usr/lib/
и подобных, поэтому флаг -lSystem
не может найти libSystem.dylib
по умолчанию.
Решение этой проблемы состояло в том, чтобы обновить/установить последнюю версию инструментов командной строки, если она еще не установлена, и установить флаг -L
команды ld
на /Library/Developer/CommandLineTools/SDKs/MacOSX.