Ошибка компиляции и связывания моей общей библиотеки в C/NASM ⇐ Linux
-
Anonymous
Ошибка компиляции и связывания моей общей библиотеки в C/NASM
В настоящее время я переписываю общую библиотеку на C и NASM, аналогичную GLIBC для Linux x64.
Я заметил, что когда мы компилируем исполняемый файл с флагом -nostdlib, нам приходится самим добавлять оболочку C (пример: asm(".global _start; _start: call main ; movq %rax, %rdi; movq $60, %rax; syscall");), поэтому я делаю вывод, что именно GLIBC заботится о загрузке int main(int argc, char *argv[] , char *envp[]).
Поэтому я перекодировал оболочку для exit(int status) в NASM, обертку «main()». Но я получаю много предупреждений/ошибок LD.
Вот коды:
vlibc-wrapper.h
#ifdef __linux__ #ifdef __x86_64__ #ifndef написать #define write(fd, buf, count) extern int _write(int fd, const void *buf, size_t count); #endif #ifndef выход #define exit(status) extern void _exit(int status); #endif #ifndef блок #define brk(addr) extern int _brk(void *addr); #endif #endif #endif exit.asm
бит 64 раздел .текст глобальный _exit:функция _Выход: Мов Ракс, 60 лет системный вызов main.asm
бит 64 раздел .текст глобальный _start внешний основной внешний _exit _начинать: позвони в главный WRT ..plt Мов Рди, Ракс позвоните _exit по адресу ..plt Вот мой Makefile:
ASM_DIR = ./src/ASM C_DIR = ./src/C TEST_DIR = ./тест BUILD_DIR = ./build TMP_DIR = ./.tmp INCLUDE_DIR = ./включить ASM_FILES = $(подстановочный знак $(ASM_DIR)/*.asm) C_FILES = $(подстановочный знак $(C_DIR)/*.c) TEST_FILES = $(подстановочный знак $(TEST_DIR)/*.c) ASM_OBJECTS = $(patsubst $(ASM_DIR)/%.asm,$(TMP_DIR)/%.o,$(ASM_FILES)) C_OBJECTS = $(patsubst $(C_DIR)/%.c,$(TMP_DIR)/%.o,$(C_FILES)) TEST_OBJECTS = $(patsubst $(TEST_DIR)/%.c,$(TMP_DIR)/%.o,$(TEST_FILES)) БИБЛИОТЕКА = $(BUILD_DIR)/libvlibc.so TEST_EXECUTABLE = $(BUILD_DIR)/тест НАСМ = НАСМ NASM_FLAGS = -f elf64 CC = gcc CFLAGS = -m64 -fPIC -pedantic -fno-builtin -nostdlib -Wall -Wextra -Werror -ggdb3 -I$(INCLUDE_DIR) ЛД = лд LDFLAGS = -shared -I$(INCLUDE_DIR) все: $(LIBRARY) $(TEST_EXECUTABLE) $(БИБЛИОТЕКА): $(ASM_OBJECTS) $(C_OBJECTS) $(LD) $(LDFLAGS) -o $@ $^ $(TMP_DIR)/%.o: $(ASM_DIR)/%.asm $(NASM) $(NASM_FLAGS) $< -o $@ $(TMP_DIR)/%.o: $(C_DIR)/%.c $(CC) $(CFLAGS) -c $< -o $@ $(TEST_EXECUTABLE): $(TEST_OBJECTS) $(БИБЛИОТЕКА) $(CC) $(CFLAGS) -o $@ $^ -L$(BUILD_DIR) -lvlibc re: очистить все чистый: rm -f $(TMP_DIR)/*.o fclean: чистый rm -f $(БИБЛИОТЕКА) $(TEST_EXECUTABLE) тест: $(TEST_EXECUTABLE) ./$(TEST_EXECUTABLE) .PHONY: все чисто, повторный тест fclean Дерево
. ├── строить │ └── libvlibc.so ├── включать │ ├── vlibc-def.h │ ├── vlibc.h │ └── vlibc-wrapper.h ├── Makefile ├── источник │ ├── АСМ │ │ ├── brk.asm │ │ ├── exit.asm │ │ ├── main.asm │ │ └── write.asm │ └── С └── тест Вот предупреждения:
/usr/bin/ld: предупреждение: тип и размер динамического символа «_start» не определены /usr/bin/ld: предупреждение: входной символ _start не найден; нет инициализации стартового адреса /usr/bin/ld: build/libvlibc.so: неопределенная ссылка на «основной Collect2: ошибка: ld вернул статус вывода 1 make: *** [Makefile:40: сборка/тест] Ошибка 1 Думаю, предупреждение об отсутствии функции main() — это нормально, но можно ли это исправить? Поскольку технически функция main() будет обнаружена после связывания.
Поэтому я пытаюсь решить все эти проблемы, чтобы иметь возможность четко кодировать свою общую библиотеку. Вы можете мне помочь?
В настоящее время я переписываю общую библиотеку на C и NASM, аналогичную GLIBC для Linux x64.
Я заметил, что когда мы компилируем исполняемый файл с флагом -nostdlib, нам приходится самим добавлять оболочку C (пример: asm(".global _start; _start: call main ; movq %rax, %rdi; movq $60, %rax; syscall");), поэтому я делаю вывод, что именно GLIBC заботится о загрузке int main(int argc, char *argv[] , char *envp[]).
Поэтому я перекодировал оболочку для exit(int status) в NASM, обертку «main()». Но я получаю много предупреждений/ошибок LD.
Вот коды:
vlibc-wrapper.h
#ifdef __linux__ #ifdef __x86_64__ #ifndef написать #define write(fd, buf, count) extern int _write(int fd, const void *buf, size_t count); #endif #ifndef выход #define exit(status) extern void _exit(int status); #endif #ifndef блок #define brk(addr) extern int _brk(void *addr); #endif #endif #endif exit.asm
бит 64 раздел .текст глобальный _exit:функция _Выход: Мов Ракс, 60 лет системный вызов main.asm
бит 64 раздел .текст глобальный _start внешний основной внешний _exit _начинать: позвони в главный WRT ..plt Мов Рди, Ракс позвоните _exit по адресу ..plt Вот мой Makefile:
ASM_DIR = ./src/ASM C_DIR = ./src/C TEST_DIR = ./тест BUILD_DIR = ./build TMP_DIR = ./.tmp INCLUDE_DIR = ./включить ASM_FILES = $(подстановочный знак $(ASM_DIR)/*.asm) C_FILES = $(подстановочный знак $(C_DIR)/*.c) TEST_FILES = $(подстановочный знак $(TEST_DIR)/*.c) ASM_OBJECTS = $(patsubst $(ASM_DIR)/%.asm,$(TMP_DIR)/%.o,$(ASM_FILES)) C_OBJECTS = $(patsubst $(C_DIR)/%.c,$(TMP_DIR)/%.o,$(C_FILES)) TEST_OBJECTS = $(patsubst $(TEST_DIR)/%.c,$(TMP_DIR)/%.o,$(TEST_FILES)) БИБЛИОТЕКА = $(BUILD_DIR)/libvlibc.so TEST_EXECUTABLE = $(BUILD_DIR)/тест НАСМ = НАСМ NASM_FLAGS = -f elf64 CC = gcc CFLAGS = -m64 -fPIC -pedantic -fno-builtin -nostdlib -Wall -Wextra -Werror -ggdb3 -I$(INCLUDE_DIR) ЛД = лд LDFLAGS = -shared -I$(INCLUDE_DIR) все: $(LIBRARY) $(TEST_EXECUTABLE) $(БИБЛИОТЕКА): $(ASM_OBJECTS) $(C_OBJECTS) $(LD) $(LDFLAGS) -o $@ $^ $(TMP_DIR)/%.o: $(ASM_DIR)/%.asm $(NASM) $(NASM_FLAGS) $< -o $@ $(TMP_DIR)/%.o: $(C_DIR)/%.c $(CC) $(CFLAGS) -c $< -o $@ $(TEST_EXECUTABLE): $(TEST_OBJECTS) $(БИБЛИОТЕКА) $(CC) $(CFLAGS) -o $@ $^ -L$(BUILD_DIR) -lvlibc re: очистить все чистый: rm -f $(TMP_DIR)/*.o fclean: чистый rm -f $(БИБЛИОТЕКА) $(TEST_EXECUTABLE) тест: $(TEST_EXECUTABLE) ./$(TEST_EXECUTABLE) .PHONY: все чисто, повторный тест fclean Дерево
. ├── строить │ └── libvlibc.so ├── включать │ ├── vlibc-def.h │ ├── vlibc.h │ └── vlibc-wrapper.h ├── Makefile ├── источник │ ├── АСМ │ │ ├── brk.asm │ │ ├── exit.asm │ │ ├── main.asm │ │ └── write.asm │ └── С └── тест Вот предупреждения:
/usr/bin/ld: предупреждение: тип и размер динамического символа «_start» не определены /usr/bin/ld: предупреждение: входной символ _start не найден; нет инициализации стартового адреса /usr/bin/ld: build/libvlibc.so: неопределенная ссылка на «основной Collect2: ошибка: ld вернул статус вывода 1 make: *** [Makefile:40: сборка/тест] Ошибка 1 Думаю, предупреждение об отсутствии функции main() — это нормально, но можно ли это исправить? Поскольку технически функция main() будет обнаружена после связывания.
Поэтому я пытаюсь решить все эти проблемы, чтобы иметь возможность четко кодировать свою общую библиотеку. Вы можете мне помочь?
Мобильная версия