компилятор ТСС. Tiny c compiler by Fabrice Bellard Описание алгоритмов
Скачать 191.99 Kb.
|
static void dynarray_add(void ***ptab, int *nb_ptr, void *data) (nb & (nb - 1)) это выражение — «побитовое и». Как только в старшем разряде появляется единица, удваивается размер массива переданного в уазателе. В любом случае для массива вызывается tcc_realloc(), с увеличением на 1 или в два раза. Обновляется уазатель на массив после работы tcc_realloc(). Данные переданные в указателе data записываются во вносвь созданную ячейку. Количество, переданное через ссылку так же обновляется. text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); С помощью tcc_mallocz выделяется место для экземпляра структуры Section. Поля name , sh_type и sh_flags заполняются значениями переданными в качестве параметра sh_addralign зависит от типа сеции. Для SHT_HASH, SHT_REL, SHT_DYNSYM, SHT_SYMTAB, SHT_DYNAMIC это 4, для SHT_STRTAB это 1, по умолчанию 32. Если не выствлен флаг SHF_PRIVATE, sh_num будет равен полю nb_sections состояния TCCState переданного в качестве параметра, т. е. порядковому номеру секции, который увеличится вызванной здесь же функцией dynarray_add(). Таким образом мы создаем в памяти секции и записываем указатели text_section, data_section, bss_section symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, ".strtab", ".hashtab", SHF_PRIVATE); static Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags) В переменную symtab записывается адрес секции созданной с помощью new_section() Полю sh_entsize пирсваивается размер структуры Elf32_Sym В переменную strtab записывается адрес еще одной секции, созданной с помощью new_section() В strtab записывается пустая строка с помощью put_elf_str() В поле link экземляра структуры symtab, записывается адрес symtab. В symtab записывается пустрой символ с помощью put_elf_sym() В переменную hash записывается адрес еще одной секции, созданной с помощью new_section() В поле sh_entsize этой структуры записывается размер типа int. В поле hash экземляра структуры symtab, записывается адрес hash. В поле link экземляра структуры hash, записывается адрес symtab В секции hash создается указатель с помощью section_ptr_add. Эта функция возвращает адрес указателя и он помещается в переменную ptr В ptr[0] записывается nb_buckets (в нашем случае единица) В ptr[1] тоже записывается единица. Данные за этими двумя адресами заполняются нулями вплоть до адреса двух переменных типа int. Переменной strtab_section присваивается поле link только что созданной symtab_section. С помощью той же new_symtab() создается s->dynsymtab_section tcc_new() на этом заканчивается, возвращая текущее состояние компилятора. Мы не рассмотрили часть функций вызванных в new_symtab() static int put_elf_str(Section *s, const char *sym) Функция принимает на входе секцию и помещает внутрь нее данные переданные в параметре. Для этого в секции создается указать с помощью section_ptr_add() static int put_elf_sym(Section *s, |