|
компилятор ТСС. Tiny c compiler by Fabrice Bellard Описание алгоритмов
unsigned long offset, int type) Если в переданном символе поле c содержит не нулевое значение, вызывается put_extern_sym(), т. е. обертка над put_extern_sym2() Выхываеься put_elf_reloc() static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol) Если в переданной секции указатель reloc, создается новая секция с помощью new_section(). В ней заполняются неоходимые поля Экземплян Elf32_Rel получается с помощью section_ptr_add() в нем обновляется смещение переданным значением и поле r_info с помощью макроса ELF32_R_INFO(), котрорый кодирует в одном значении код символа и его тип Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) Для секции и ее имени выделяется память с помощью tcc_mallocz() Заполняются необходимые поля. Если флаг SHF_PRIVATE не установлен, секции присваивается глобальный номер и она добавляется в глобальную цепочку sections static void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore) Может быть передан пустой указатель на символ, тогда sh_num принимает знаечение SHN_UNDEF Если передан указатель на SECTION_ABS, то sh_num присваивается SHN_ABS Иначе номер берется из section->sh_num Если часть кода типа связанного с переданным символом, ответственная за простые типы кодирует VT_FUNC, то переменной sym_type присваивается STT_FUNC Заполняются переменные attr и other. В втором устанавливаются соответствующие биты, при проверке мокросами FUNC_EXPORT() и FUNC_CALL(), которые просто возвращают соответствующе поля. Иеаче усиаеавоиваеися тип STT_OBJECT В оставшейся части поля проверяется наличие бита VT_STATIC. В зависимости от него sym_bind принимает значение STB_LOCAL или STB_GLOBAL В переданном символе поле c обнулено, ищется его имя get_tok_str() Если установлены флаг can_add_underscore и соответсвтующий бит в переменной other, то формируется соответствующая строка и записывается в name Иначе в глобальном состоняии компилятора проверяется флаг leading_underscore и глобальная переменная-флаг can_add_underscore. Если оба установлены в начало name добавляется '_' Инфотпация о символе получается с помощью ELF32_ST_INFO (сдвигает переданные значения и суммирует их) и записывается в файл с помощью add_elf_sym() Если поле c установлено, то в соответствующем элементе symtab_section устанавливаются нобходимые поля static int add_elf_sym(Section *s, unsigned long value, unsigned long size, int info, int other, int sh_num, const char *name) Переменны sym_bind, sym_type, sym_vis заполняются макросами получающими данные из необходимых полей переданного символа. Если sym_bind оличается от STB_LOCAL, происходит следующая обработка Если при поиски символа с помощью find_elf_sym(), получен нулевой результат, то присходит переход на метку do_def. Если символ найден, мы получаем его адрес в переданной секции по найденному индексу и призводим следующие действиея. Если поле st_shndx содержит занчение отличное от SHN_UNDEF, призводим следующие действия: Обновляем значения esym_bind и seym_vis теми же макросами, но теперь для найденного символа. Второй макрос отвечает за видимость символа. Мы устанавливаем минимальное из двух найденных значений видимости. Целиком поле st_other сохраняется во временном файле. Далее происходит проверка допустимости значений и при необходимости присходит переход на do_patch Если пле st_shndx найденного символва, содержит SHN_UNDEF или управление передано на метку do_patch, обновляются значения полей символа. Если символ не найднен, он добавляется с помощью put_elf_sym() |
|
|