Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Необычное использование языка С



Внутри ядра Linux действует множество соглашений, требующих много чего прочитать и изучить для понимания их использования и назначения. Этот раздел освещает неко­торые неясности или неточности использования С, фокусируясь на принятых С-соглаше-ниях, используемых в ядре Linux 2.6.


Необычное использование языка С



Asmlinkage

asmlinkage указывает компилятору передавать параметры в локальный стек. Это свя­зано с макросом FASTCALL, который указывает компилятору (аппаратно-зависимому) передавать параметры в регистры общего назначения. Вот макрос из include /asm/ linkage, с:

include/asm/linkage.h

4 #define asmlinkage CPP_ASMLINKAGE _ attribute_ ((regparm(O) ) )

5 #define FASTCALL(x) x_ attribute_ ((regparm(3)))

6 #define fastcall _ attribute_ ((regparm(3)))

Далее представлен пример asmlinkage.

asmlinkage long sys_gettimeofday (struct timeval _________ user *tv, struct

timezone ___ user *tz)

UL

UL часто вставляется в конце численных констант для обозначения «unsigned long». UL (или L для long) необходимо вставлять для того, чтобы указать компилятору считать значение имеющим тип long1. На некоторых архитектурах таким образом можно избе­жать переполнения и выхода за границы типа. Например, 16-битовое целое может пред­ставлять числа от -32768 до +32767; беззнаковое целое может представлять числа от 0 до 65535. При использовании UL вы пишете архитектурно-независимый код для длинных чисел или длинных битовых масок.

Вот некоторые демонстрирующие это примеры из ядра:

include/linux/hash.h

18 idefine GOLDEN_RATIO_PRIME 0x9e37000lUL

include/linux/kernel.h

23 #define ULONG_MAX (-OUL)

include/linux/slab, h

39 #define SLAB_POISON 0x00000800UL /* Ядовитые объекты */

1 Очевидно, имеется в виду unsigned long. Примеч. науч. ред.



Глава 2 • Исследовательский инструментарий


Inline

Ключевое слово inline необходимо для оптимизации выполнения функций, интег­рируя код этих функций в вызывающий код. Ядро Linux использует множество inline-функций, объявленных статическими; «static тНпе»-функция заставляет компилятор стараться внедрять код функции во все вызывающие ее участки кода и, если это возмож­но, избегать ассемблирования кода этой функции. Иногда компилятор не может обойтись без ассемблирования кода (в случае рекурсий), но в большинстве случаев функции, объ­явленные как static inline, полностью внедряются в вызывающий код.

Целью такого внедрения является устранение всех лишних операций, выполняемых при вызове функции. Выражение # define также позволяет убрать связанные с вызовом функции операции и обычно используется для обеспечения портируемости на другие ком­пиляторы и встраиваемые системы.

Так почему бы не сделать встроенными все функции? Недостатком использования встраивания является увеличение бинарного кода и иногда замедление доступа к кешу процессора.

Const и volatile

Эти два ключевых слова игнорируются многими начинающими программистами. Ключе­вое слово const не следует понимать как константу, а скорее как только для чтения. Например, const int be - это указатель на const-целое. При этом указатель может быть изменен, а целое число - нет. С другой стороны, int const *jc обозначает const-указатель на целое, когда число может быть изменено, а указатель - нет. Вот пример использования const:

include/asm-i3 86/processor.h

62 8 static inline void prefetch(const void *x)

629 {

630 __ asm____ volatile_ (" debt 0, %0" : : " r" (x) );

631 }

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

include/linux/spinlock.h 51 typedef struct {


Короткий обзор инструментария для исследования ядра



volatile unsigned int lock; 58 } spinlock_t;

Учитывая то, что const следует трактовать как только для чтения, мы видим, что не­которые переменные могут быть одновременно const и volatile (например, перемен­ная, хранящая содержимое регулярно обновляемого аппаратного регистра с доступом только для чтения).

Этот краткий обзор позволит начинающим хакерам ядра Linux чувствовать себя увереннее при изучении исходных кодов ядра.

Короткий обзор инструментария для исследования ядра

После успешной компиляции и сборки вашего ядра Linux вы можете захотеть посмотреть его «внутренности» до, после или даже во время процесса этой операции. Этот раздел коротко рассказывает об инструментах, используемых обычно для просмотра различных файлов ядра Linux.

Objdump/readelf

Утилиты objdump и readelf отображают информацию об объектных файлах (obj-dump) или ELF-файлах (readelf). С помощью аргументов командной строки вы може­те использовать команды для просмотра заголовков, размера или архитектуры данного объектного файла. Например, вот дамп для ELF-заголовка простой С-программы (а. out), полученный с помощью флага -h readelf:

Lwp> readelf -h a.out

ELF Header:

Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Class: ELF32

Data: 2's complement, little endian

Version: 1 (current)

OS/ABI: UNIX - System V

ABI Version: 0

Type: EXEC (Executable file)

Machine: Intel 80386

Version: 0x1

Entry point address: 0x8048310

Start of program headers: 52 (bytes into file)

Start of section headers: 10596 (bytes into file)

Flags: 0x0

Size of this header: 52 (bytes)



Глава 2 • Исследовательский инструментарий


Size of program headers: 32 (bytes)

Number of program headers: 6

Size of section headers: 40 (bytes)

Number of section headers: 29

Section header string table index: 2 6

А вот дамп заголовка программы, полученный с помощью readelf с флагом -1:

Lwp> readelf -l a.out

Elf file type is EXEC (Executable file)

Entry point 0x8048310

There are 6 program headers, starting at offset 52

Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Fig Align PHDR 0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4

INTERP 0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2]

LOAD 0x000000 0x08048000 0x08048000 0x00498 0x00498 R E 0x1000

LOAD 0x000498 0x08049498 0x08049498 0x00108 0x00120 RW 0x1000

DYNAMIC 0x0004ac 0x080494ac 0x080494ac 0x000c8 0x000c8 RW 0x4

NOTE 0x000108 0x08048108 0x08048108 0x00020 0x00020 R 0x4 Section to

Segment mapping:

Segment Sections...

1.interp

2.interp.note.ABI-tag.hash.dynsym.dynstr.gnu.version.gnu.version_r rel.dyn.rel.plt.init.pit.text.fini.rodata

3.data.eh_frame.dynamic.ctors.dtors.got.bss

4.dynamic

5.note.ABI-tag

Hexdump

Команда hexdump отображает содержимое указанного файла в шестнадцатеричном, ASCII или восьмеричном формате. [Обратите внимание: на старых версиях Linux также использовался od (восьмеричный дамп). Теперь большинство систем используют вместо него hexdump.]

Например, чтобы посмотреть первые 64 бита ELF-файла a.out в шестнадца­теричном режиме, нужно набрать следующее:

Lwp> hexdump -x -n 64 a.out

F 151c 0101 0001 0000 0000 0000 0000

0000010 0002 0003 0001 0000 8310 0804 0034 0000

0000020 2964 0000 0000 0000 0034 0020 0006 0028

OOld 001a 0006 0000 0034 0000 8034 0804


Говорит ядро: прослушивание сообщений ядра



Обратите внимание на магическое число заголовка ELF (с поменянными местами байтами) по адресу 0x0000000.

Это очень полезно при отладке действий; когда аппаратное устройство сбрасывает свое состояние в файл, обычный текстовый редактор интерпретирует его как набор управ­ляющих символов. Hexdump позволяет вам увидеть, что же на самом деле содержится в файле без промежуточного преобразования редактором; hexdump - это редактор, ко­торый позволяет вам напрямую модифицировать файл без преобразования его содержи­мого в ASCII (или Unicode).

Nm

Утилита run перечисляет все символы, находящиеся в объектном файле. Она отображает значения символов, их тип и имя. Эта утилита не так полезна, как остальные, но тем не менее может быть полезна при отладке файлов библиотек.

Objcopy

Команда obj copy используется, когда вам нужно скопировать объектный файл и при этом пропустить или изменить некоторые его компоненты. Обычно objcopy использу­ется для получения отладочных символов от тестируемого и работающего объектного файла. В результате размер объектного файла уменьшается и становится возможным его использование на встраиваемых системах.

Аг

Команда аг, или archive (архивация), помогает поддерживать индексированные биб­лиотеки, используемые компоновщиком. Команда аг собирает один или несколько объ­ектных файлов в одну библиотеку. Кроме этого, она может выделять отдельный объект­ный файл из библиотеки. Чаще всего команду аг можно увидеть в Make-файле. Она час­то используется для объединения используемых функций в одну библиотеку. Например, предположим, что у вас есть функция, выполняющая парсинг командного файла и из­влечение некоторых данных или вызов для извлечения информации для указанных аппаратных регистров. Эта функция необходима нескольким исполнимым программам. Архивирование этой функции в отдельную библиотеку облегчит вам контроль за версия­ми, поместив функцию только в одно место.


Поделиться:



Популярное:

  1. Hfr-клетки. Использование их в картировании бактериальных генов.
  2. I. Использование средств индивидуальной и коллективной защиты в ЧС.
  3. IV. Сравните параллельные тексты, проанализировав использование приема приближенного перевода.
  4. Анализ денежных потоков и использование
  5. Антимонопольная политика проводится с использованием различных инструментов, но основными ее задачами являются снижение цен и увеличение объемов продаж на рынке.
  6. Безответственное использование ресурсов
  7. Биологическое значение размножения. Способы размножения, их использование в практике выращивания сельскохозяйственных растений и животных, микроорганизмов.
  8. Валовый доход, его формирование и использование
  9. Виды масличных растений. Их значение и использование.
  10. Вопрос №62. Понятие и состав земель населенных пунктов. Использование земель населенных пунктов. Территориальное зонирование
  11. Временные ряды с использованием процесса скользящего среднего могут иметь место, когда уровни динамического ряда характеризуются случайной колеблемостью.
  12. Вычисления в Excel. Использование функций даты и времени: ГОД( ), ДАТА( ), ДЕНЬ( ), СЕГОДНЯ( ), РАЗНДАТ( ).


Последнее изменение этой страницы: 2016-03-25; Просмотров: 646; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.022 с.)
Главная | Случайная страница | Обратная связь