unsigned long value, unsigned long size, int info, int other, int shndx, const char *name) Указатель на символ Elf32_Sym генерируется с помощю той же section_ptr_add() Если в параметре передано имя оно помещается по адресу взятому из поля link секции с помощью put_elf_str(). Адрес возращаемый этой функцией помещается в переменную name_offset. Если имя функции не передано, в name_offset записывается 0. В любом случае это значение записывается в поле символа st_name. Поля символа st_value, st_size, st_info, st_other и st_shndx заполняются значениями переданными в параметрах. Т.к. мы выделили указатель внутри секции, мы отнимаем от полученного адреса, значение из поля data, чтобы получить номер символа. Это значение записывается в переменную sym_index Если к секции привязана хэшь таблица (поле hash не пустое), то в эту таблицу с помощью section_ptr_add() добавляется указатель. База шешей берется из поля data хешь таблицы Прядковый номер символа берется из base[0] и записывается в переменную nbuckets Высчитывается хэшь с пмощью elf_hash(). От полученого числа вычисляется остаток от деленя на nbuckets (результат в h) В хешь-таблицу по адресу base[2 + h] записывется sym_index Увеличивается количество символов, оно хранится по адресу base[1]. Увеличивается значение поля nb_hashed_syms и при необходимости вызывается rebuild_hash() В параметре info может быть передан флаг STB_LOCAL, тогда в адрес, содержащийся в созданном указателе записывается 0, а base[1] просто увеличивается, отражая общее количество символов, включая локальные. elf_hash() - простая функция, основаня на сложении кодов символов со сдвигом результата и защитой от переполнения. static void rebuild_hash(Section *s, unsigned int nb_buckets) Количество символов в секции, служашей хэшь таблицей (s->data_offset / sizeof(Elf32_Sym)) записывается в переменную nb_syms Мы перестраиваеме хэшь таблицу, по этому обнуляем s->hash->data_offset В таблице s->hash деляется пространство с помощью section_ptr_add() способное хранить вычесленное количество nb_syms, переданное в параметре nb_buckets плюс 2. Сумма умножатеся на размер типа int. Первые два значения по выделеному адресу заполняются значениями nb_buckets и nb_syms Последующи данные вплоть до адреса nb_buckets плюс 1 обнуляются. Хэши вызовом elf_hash() с учетом STB_LOCAL так же пересчитывается. static void *section_ptr_add(Section *sec, unsigned long size) Функция прибавляет к текущему смещению секции (поле data_offset) размер переданный в параметре. Если результат больше чем уже выделенный объем (поле data_allocated), вызывается section_realloc() Поле data_offset обновляется. Теперь оно указывает но пространство после выделенного объема. Функция же возвращает указатель на начало выделенного объема. static void section_realloc(Section *sec, unsigned long new_size) tcc_realloc() вызывается для нового размера. Размер увеличивается каждый раз в два раза, если только на предыдущем шаге размер не увеличен достаточно для нового сайта. Добавленный объем заполняется нулями. Общий объем выделенных в секции данных (поле data_allocated) обновляется. Поле data обновляется значением, возвращенным tcc_realloc() int parse_args(TCCState *s, int argc, char **argv) Если разбор аргументов закончился (optind >= argc), но входных файлов не передано, компилятор закрывается. Если параметр начинается не с '-' и не оборывается ('\0') на втором символе, то этот параметр расценивается как имя файла. Он добавляется в массив файлов files Дальнейший разбор параметров может быть прекрашен, если флаг multiple_files был сброшен. Массив tcc_options содержит все допустимые опции. Имя текущего параметра сравнивается со всеми элементами массива. Как только одна из букв не совпадает, заканчиваем сравнение с текущим элементом масиисва. Если в процессе сравнения достигнут конец строки, значит опция найдена. Т.к. текущий элемент массива является тек который мы ищем, мы проверяем его флаги. Если опция предусматривает передачу ей параметр (флаг TCC_OPTION_HAS_ARG) Опция может быть не отделена пробелом от параметра (флаг TCC_OPTION_NOSEP) или отделена. В любом случае, записываем опцию в переменную optarg После опции (или опции и сцепленного с ней параметра) должен идти пробел иначе выполнение компилятора прекращается. Опция TCC_OPTION_HELP приводит к выводу подсказки. Опция TCC_OPTION_I приводит к вызову tcc_add_include_path() Опция TCC_OPTION_D приводит к вызову tcc_define_symbol() Опция TCC_OPTION_U приводит к вызову tcc_undefine_symbol() Опция TCC_OPTION_L приводит к вызову tcc_add_library_path() Опция TCC_OPTION_B принимает параметр и устанваливает его в качестве значения tcc_lib_path Опция TCC_OPTION_l приводит к вызову dynarray_add() для добавления библиотеки в массив файлов и увеличивает счетчик nb_libraries TCC_OPTION_bench включает бенчмаркинг (флаг do_bench) TCC_OPTION_bt принимает параметр и устанваливает его в качестве значения num_callers TCC_OPTION_b устанавливает флаги do_bounds_check и do_debug TCC_OPTION_g устанавливает флаг do_debug TCC_OPTION_c устанавливает флаг multiple_files TCC_OPTION_static устанавливает флаг static_link TCC_OPTION_shared устанавливает output_type в TCC_OUTPUT_DLL; TCC_OPTION_soname принимает параметр и устанваливает его в качестве значения soname TCC_OPTION_o принимает параметр и устанваливает его в качестве значения outfile, и устанавливает флаг multiple_files TCC_OPTION_r устанавливает output_type в TCC_OUTPUT_OBJ и флаг reloc_output TCC_OPTION_nostdinc устанавливает флаг nostdinc TCC_OPTION_nostdlib устанавливает флаг nostdlib TCC_OPTION_print_search_dirs устанавливает флаг print_search_dirs TCC_OPTION_run подготавливает параметры для образа с помощью expand_args(), разбирает их с помощью parse_args(), устанавливает флаг, multiple_files и переменну output_type в TCC_OUTPUT_MEMORY TCC_OPTION_v постфиксное увеличение переменной verbose позволяет однократно вывести версию компилятора. TCC_OPTION_f с помощью tcc_set_flag() позволяет установить флаг, имя которого передано в параметре и проверить не вызвало ли это ошибку (поле warn_unsupported состояния компилятора) TCC_OPTION_W с помощью tcc_set_warning() позволяет установить предупреждение, имя которого передано в параметре и проверить не вызвало ли это ошибку (поле warn_unsupported состояния компилятора) TCC_OPTION_w устанавливает флаг warn_none TCC_OPTION_rdynamic устанавливает флаг rdynamic = 1; TCC_OPTION_Wl позволяет с помощью "-Ttext," устанвить значение поля text_addr и флаг has_text_addr. С помощью "--oformat," установить поле output_format. Другие опции линкера не поддерживаются. TCC_OPTION_E выставляет output_type в TCC_OUTPUT_PREPROCESS |