[
Страница
назад | Страница
вперед | Содержание
| Индекс
| Библиотека | Юридическая
информация | Поиск ]
Программирование: Разработка и отладка программ
В таблице имен объекта хранится информация, необходимая для поиска и
преобразования определений и ссылок на имена программы. Таблица имен
проиндексирована. Индекс 0 обозначает первую запись таблицы и служит в качестве
индекса неопределенного имени. Содержимое начальной записи описано в данном
разделе ниже.
Запись таблицы имен имеет следующий формат.
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
typedef struct {
Elf64_Word st_name;
unsigned char st_info;
unsigned char st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
|
Запись таблицы имен
- st_name
- В этом элементе хранится индекс таблицы имен объектного файла, содержащей
символьное представление имен. Ненулевое значение соответствует некоторому
имени из таблицы имен. Нулевое значение не соответствует никакому имени.
Примечание: Имена внешних имен C в языке C и объектных файлах
совпадают.
- st_value
- В этом элементе хранится значение имени. В зависимости от контекста, это
может быть абсолютное значение, адрес и т.п.
- st_size
- Со многими именами связан размер. Например, размер объекта данных - это
число байт в объекте. Если размер имени не применяется или неизвестен, в этом
элементе указано значение 0.
- st_info
- В этом элементе указан тип и атрибуты связывания имени. Список допустимых
значений и их интерпретация приведены ниже. В следующем примере показан способ
управления этими значениями для 32- и 64-разрядных объектов.
#define ELF32_ST_BIND(i) ((i)>>4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
#define ELF64_ST_BIND(i) ((i)>>4)
#define ELF64_ST_TYPE(i) ((i)&0xf)
#define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
- st_other
- В этом элементе указана область видимости имен. Список значений и их
интерпретация приведены ниже.
В следующем примере показан способ управления этими значениями для 32- и
64-разрядных объектов. Не указанные здесь биты содержат значение 0 и не
применяются.
#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
#define ELF32_ST_OTHER(v) ((v)&0x3)
#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
#define ELF64_ST_OTHER(v) ((v)&0x3)
- st_shndx
- Каждая запись таблицы имен определена в контексте некоторого
раздела. В этом элементе хранится индекс таблицы заголовков связанного
раздела. В соответствии с интерпретацией sh_link и sh_info в таблице
и описанием, некоторые индексы разделов имеют особое значение.
Если элемент содержит SHN_XINDEX, то индекс заголовка раздела не поместится
в данном поле. Действительное значение будет храниться в связанном разделе
типа SHT_SYMTAB_SHNDX.
Область видимости и поведение скомпонованного объекта определяются
параметрами связывания имен.
Связывание имен
Имя |
Значение |
STB_LOCAL |
0 |
STB_GLOBAL |
1 |
STB_WEAK |
2 |
STB_LOOS |
10 |
STB_HIOS |
12 |
STB_LOPROC |
13 |
STB_HIPROC |
15
|
- STB_LOCAL
- Локальные имена не будут видимы за пределами объектного файла, в котором
они определены. В разных файлах могут использоваться одинаковые локальные
имена.
- STB_GLOBAL
- Глобальные имена видимы для всех связанных объектных файлов. Имя,
определенное в одном объектном файле, может использоваться в любом другом
файле.
- STB_WEAK
- Область действия "слабых" имен аналогична области действия глобальных,
однако их приоритет ниже.
- STB_LOOS - STB_HIOS
- Значения в этом диапазоне зависят от типа применяемой операционной
системы.
- STB_LOPROC - STB_HIPROC
- Значения в этом диапазоне зависят от типа процессора. Их применение
описано в документации по процессору.
Есть два основных отличия глобальных имен от "слабых".
- Когда компоновщик объединяет несколько перемещаемых объектных файлов, он
не допускает определения нескольких одинаковых имен типа STB_GLOBAL. С
другой стороны, появление "слабого" имени, совпадающего с глобальным, не
приводит к ошибке. В этом случае будет применяться глобальное определение.
Аналогично, если есть общее имя (имя, поле st_shndx которого содержит
SHN_COMMON), то появление такого же "слабого" имени не приведет к
ошибке. В этом случае будет применяться общее определение.
- При просмотре архивных библиотек [см. Архивные файлы в главе 7]
компоновщик извлекает из них определения тех имен, которые еще не определены.
В таких файлах могут быть определены как глобальные, так и "слабые" имена.
Компоновщик не извлекает определения "слабых" имен. Неопределенным "слабым"
именам присваивается нулевое значение.
Примечание: Способ обработки "слабых" имен в
других ситуациях зависит от конкретной реализации компоновщика. "Слабые" имена
предназначены для использования в системном программном обеспечении. В
прикладных программах эти имена применять не рекомендуется.
В любой таблице имена типа STB_LOCAL предшествуют "слабым" и
глобальным именам. Как описано выше в разделе Разделы,
в элементе sh_info заголовка раздела таблицы имен хранится индекс таблицы
имен для первого нелокального имени.
Ниже приведена классификация имен по типам.
Типы имен
Имя |
Значение |
STT_NOTYPE |
0 |
STT_OBJECT |
1 |
STT_FUNC |
2 |
STT_SECTION |
3 |
STT_FILE |
4 |
STT_COMMON |
5 |
STT_LOOS |
10 |
STT_HIOS |
12 |
STT_LOPROC |
13 |
STT_HIPROC |
15
|
- STT_NOTYPE
- Тип имени не указывается.
- STT_OBJECT
- Имя связано с объектом данных, например, с переменной, массивом и т.п.
- STT_FUNC
- Имя связано с функцией или другим исполняемым кодом.
- STT_SECTION
- Имя связано с разделом. Записи таблицы имен этого типа предназначены для
перемещения и обычно имеют область действия STB_LOCAL.
- STT_FILE
- По соглашению, имя соответствует пути к исходному файлу, связанному с
объектным файлом. Область действия этого имени - STB_LOCAL, индекс
раздела - SHN_ABS, при этом он предшествует всем другим именам
STB_LOCAL в файле.
- STT_COMMON
- Имя помечает неинициализированный общий блок. Более подробные сведения
приведены ниже.
- STT_LOOS - STT_HIOS
- Значения в этом диапазоне зависят от типа применяемой операционной
системы.
- STT_LOPROC - STT_HIPROC
- Значения в этом диапазоне зависят от типа процессора. Их применение
описано в документации по процессору.
Имена функций (STT_FUNC) в общих объектных файлах имеют особое
значение. Когда на функцию из общего объекта ссылается другой объектный файл,
компоновщик автоматически создает запись таблицы компоновки процедур для этого
имени. Имена общих объектов с типами, отличными от STT_FUNC, не
обрабатываются автоматически.
Имена типа STT_COMMON помечают
неинициализированные общие блоки. В перемещаемых объектах эти имена не
размещаются, и для них должен существовать отдельный индекс раздела
SHN_COMMON (см. ниже).
В общих и исполняемых объектных файлах эти имена должны быть размещены в
каком-либо разделе.
В перемещаемых объектах имена типа STT_COMMON обрабатываются точно так
же, как другие имена с индексом SHN_COMMON. Если компоновщик выделяет
память для имени SHN_COMMON в разделе вывода создаваемого объекта, то он
должен сохранить тип имени STT_COMMON.
Когда динамический компоновщик встречает ссылку на имя типа
STT_COMMON, он может (хотя и не обязан) изменить правила обработки имени
следующим образом: вместо использования первого найденного имени, компоновщик
ищет первое имя с типом, отличным от STT_COMMON. Если такое имя не будет
найдено, то компоновщик ищет наибольшее по размеру определение STT_COMMON
для этого имени.
Область видимости, заданная в перемещаемом объекте,
указывает правила обращения к имени, включенному в исполняемый или общий
объектный файл.
Область видимости имени
Имя |
Значение |
STV_DEFAULT |
0 |
STV_INTERNAL |
1 |
STV_HIDDEN |
2 |
STV_PROTECTED
|
3
|
- STV_DEFAULT
- Область видимости имен с атрибутом STV_DEFAULT определяется типом
компоновки имени. Таким образом, глобальные и "слабые" имена видимы извне того
компонента (исполняемого файла или общего объекта), где они определены.
Локальные имена скрыты для внешних объектов. Кроме того, глобальные и
"слабые" имена замещаемы, то есть могут замещаться определениями с
таким же именем в других компонентах.
Примечание: Набор "слабых" и глобальных имен, видимых за пределами
компонента, может быть ограничен в конкретной реализации.
- STV_PROTECTED
- Имя, определенное в текущем компоненте, защищено, если оно видимо
из других компонентов, но не замещаемо, то есть все ссылки на такое имя внутри
компонента, где оно определено, должны разрешаться в соответствии с
определением внутри этого компонента, даже если в другом компоненте существует
определение, которое имеет более высокий приоритет. Имя типа STB_LOCAL
не может иметь область видимости STV_PROTECTED.
- STV_HIDDEN
- Имя, определенное в данном компоненте, скрыто, если оно невидимо
для других компонентов. Такие имена не обязательно защищены. Этот атрибут
может применяться для управления внешним интерфейсом компонента. Обратите
внимание, что на объект, названный таким именем, можно ссылаться из другого
компонента, если его адрес передан извне.
При включении перемещаемого объекта в исполняемый или общий файл, скрытое
имя, определенное в таком объекте, удаляется или преобразовывается
компоновщиком к типу STB_LOCAL.
- STV_INTERNAL
- Процессор может задать этот атрибут области видимости для дополнительного
ограничения скрытых имен. Определение должно быть задано таким образом, чтобы
стандартные функции могли правильно интерпретировать внутренние имена как
скрытые.
При включении перемещаемого объекта в исполняемый или общий файл,
внутреннее имя, определенное в таком объекте, удаляется или преобразовывается
компоновщиком к типу STB_LOCAL.
Атрибуты области видимости не влияют на преобразование имен в исполняемом или
общем объектном файле во время компоновки; на преобразование влияет только тип
компоновки. После того как компоновщик выполнит все преобразования, на основании
этих атрибутов будут сформированы два ограничения, связанные с тем, что ссылки в
скомпонованном коде могли быть оптимизированы.
- Во-первых, если атрибуты области видимости заданы не по умолчанию, то все
определения, применяемые в ссылках на имена, должны располагаться в текущем
исполняемом или общем файле. Если такого определения в текущем файле нет, то
ссылка должна иметь тип STB_WEAK, и она будет преобразована в нулевое
значение.
- Во-вторых, если в качестве ссылки или определения применяется имя с
атрибутом области видимости, отличным от атрибута по умолчанию, то атрибут
области видимости должен быть применен к результирующему имени в компонуемом
объекте. Если при этом задано несколько атрибутов области видимости, то к
результирующему имени будет применен самый строгий из них. В следующем списке
самый строгий атрибут указан первым, а наименее строгий - последним:
STV_PROTECTED, STV_HIDDEN и STV_INTERNAL.
Если имя ссылается на конкретное расположение в разделе, то в элементе
индекса раздела st_shndx хранится индекс таблицы заголовков раздела. При
перемещении раздела значение имени также изменяется, но ссылки на имя продолжают
указывать на тот же адрес в программе. При указании некоторых особых значений
индекса раздела возможна другая интерпретация.
- SHN_ABS
- Имени присвоено абсолютное значение, которое не изменится при перемещении.
- SHN_COMMON
- Имя указывает на общий блок, который еще не был размещен в памяти. К
значению имени применяются ограничения по выравниванию, аналогичные элементу
раздела sh_addralign. Компоновщик выделит память для имени по адресу,
кратному st_value. Размер имени определяет число выделяемых байт. Имена
с индексом раздела SHN_COMMON могут применяться только в перемещаемых
объектах.
- SHN_UNDEF
- Этот индекс таблицы раздела указывает, что имя не определено. После
объединения объектного файла с другим объектом, в котором определено данное
имя, во все ссылки будет подставлено найденное определение.
Запись таблицы имен с индексом 0 (STN_UNDEF) зарезервирована и имеет
следующее значение:
Запись:Индекс 0
Имя |
Значение |
Примечание |
st_name |
0 |
Нет имени |
st_value |
0 |
Нулевое значение |
st_size |
0 |
Нет размера |
st_info |
0 |
Нет типа, локальное
связывание |
st_other |
0 |
Область видимости по
умолчанию |
st_shndx |
SHN_UNDEF |
Нет раздела
|
В объектных файлах различных типов записи таблицы имен интерпретируют элемент
st_value по-разному.
- В перемещаемых файлах st_value содержит правила выравнивания имени,
индекс раздела которого равен SHN_COMMON.
- В перемещаемых файлах st_value содержит смещение раздела для
определенного имени. st_value - это смещение от начала раздела,
указанного st_shndx.
- В исполняемых и общих объектных файлах st_value содержит
виртуальный адрес. В целях упрощения работы динамического компоновщика,
смещение раздела (в файле) определяет виртуальный адрес (в памяти), с которым
связан данный номер раздела.
Хотя интерпретация значений из таблицы имен в объектных файлах различных
типов похожа, эти значения помогают обеспечить наиболее эффективный доступ
различных программ к данным.
[
Страница
назад | Страница
вперед | Содержание
| Индекс
| Библиотека | Юридическая
информация | Поиск ]