diff options
-rw-r--r-- | com32/elflink/Makefile | 4 | ||||
-rw-r--r-- | com32/elflink/elf_module.c | 107 | ||||
-rw-r--r-- | com32/elflink/elf_utils.c | 19 | ||||
-rw-r--r-- | com32/lib/Makefile | 95 |
4 files changed, 143 insertions, 82 deletions
diff --git a/com32/elflink/Makefile b/com32/elflink/Makefile index fa3be12c..bf50a2eb 100644 --- a/com32/elflink/Makefile +++ b/com32/elflink/Makefile @@ -89,8 +89,8 @@ test_memalign.elf : test_memalign.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ test_com32.elf: CFLAGS += -DELF_DEBUG -test_com32.elf: test_com32.o elf_module.o elf_utils.o $(LIBS) - $(LD) -n $(LDFLAGS) -o $@ $^ +test_com32.elf: test_com32.o elf_module.o elf_utils.o ../libutil/libutil_com.a ../lib/libcom32min.a $(LIBGCC) + $(LD) -n $(LDFLAGS) -o $@ test_com32.o elf_module.o elf_utils.o ../libutil/libutil_com.a $(LIBGCC) --whole-archive ../lib/libcom32min.a $(OBJCOPY) --extract-symbol $@ _root_.dyn tidy dist: diff --git a/com32/elflink/elf_module.c b/com32/elflink/elf_module.c index 4d4d2b2a..758a0631 100644 --- a/com32/elflink/elf_module.c +++ b/com32/elflink/elf_module.c @@ -21,25 +21,31 @@ // The list of loaded modules static LIST_HEAD(modules); +#ifdef ELF_DEBUG +#define DBG_PRINT(fmt, args...) fprintf(stderr, "[DBG] " fmt, ##args) +#else +#define DBG_PRINT(fmt, args...) // Expand to nothing +#endif + // User-space debugging routines #ifdef ELF_DEBUG static void print_elf_ehdr(Elf32_Ehdr *ehdr) { int i; - printf("Identification:\t"); + fprintf(stderr, "Identification:\t"); for (i=0; i < EI_NIDENT; i++) { printf("%d ", ehdr->e_ident[i]); } - printf("\n"); - printf("Type:\t\t%u\n", ehdr->e_type); - printf("Machine:\t%u\n", ehdr->e_machine); - printf("Version:\t%u\n", ehdr->e_version); - printf("Entry:\t\t0x%08x\n", ehdr->e_entry); - printf("PHT Offset:\t0x%08x\n", ehdr->e_phoff); - printf("SHT Offset:\t0x%08x\n", ehdr->e_shoff); - printf("Flags:\t\t%u\n", ehdr->e_flags); - printf("Header size:\t%u (Structure size: %u)\n", ehdr->e_ehsize, + fprintf(stderr, "\n"); + fprintf(stderr, "Type:\t\t%u\n", ehdr->e_type); + fprintf(stderr, "Machine:\t%u\n", ehdr->e_machine); + fprintf(stderr, "Version:\t%u\n", ehdr->e_version); + fprintf(stderr, "Entry:\t\t0x%08x\n", ehdr->e_entry); + fprintf(stderr, "PHT Offset:\t0x%08x\n", ehdr->e_phoff); + fprintf(stderr, "SHT Offset:\t0x%08x\n", ehdr->e_shoff); + fprintf(stderr, "Flags:\t\t%u\n", ehdr->e_flags); + fprintf(stderr, "Header size:\t%u (Structure size: %u)\n", ehdr->e_ehsize, sizeof(Elf32_Ehdr)); } @@ -50,7 +56,7 @@ static void print_elf_symbols(struct elf_module *module) { for (i = 1; i < module->symtable_size; i++) { crt_sym = (Elf32_Sym*)(module->sym_table + i*module->syment_size); - printf("%s\n", module->str_table + crt_sym->st_name); + fprintf(stderr, "%s\n", module->str_table + crt_sym->st_name); } } @@ -60,7 +66,7 @@ static int image_load(struct elf_module *module) { module->_file = fopen(module->name, "rb"); if (module->_file == NULL) { - perror("Could not open object file"); + DBG_PRINT("Could not open object file '%s'\n", module->name); goto error; } @@ -94,7 +100,7 @@ static int image_read(void *buff, size_t size, struct elf_module *module) { if (result < 1) return -1; - printf("[DBG] Read %u\n", size); + DBG_PRINT("[I/O] Read %u\n", size); module->_cr_offset += size; return 0; } @@ -113,7 +119,7 @@ static int image_skip(size_t size, struct elf_module *module) { if (result < 1) return -1; - printf("[DBG] Skipped %u\n", size); + DBG_PRINT("[I/O] Skipped %u\n", size); module->_cr_offset += size; return 0; } @@ -181,28 +187,28 @@ static int check_header_common(Elf32_Ehdr *elf_hdr) { elf_hdr->e_ident[EI_MAG2] != ELFMAG2 || elf_hdr->e_ident[EI_MAG3] != ELFMAG3) { - fprintf(stderr, "The file is not an ELF object\n"); + DBG_PRINT("The file is not an ELF object\n"); return -1; } if (elf_hdr->e_ident[EI_CLASS] != MODULE_ELF_CLASS) { - fprintf(stderr, "Invalid ELF class code\n"); + DBG_PRINT("Invalid ELF class code\n"); return -1; } if (elf_hdr->e_ident[EI_DATA] != MODULE_ELF_DATA) { - fprintf(stderr, "Invalid ELF data encoding\n"); + DBG_PRINT("Invalid ELF data encoding\n"); return -1; } if (elf_hdr->e_ident[EI_VERSION] != MODULE_ELF_VERSION || elf_hdr->e_version != MODULE_ELF_VERSION) { - fprintf(stderr, "Invalid ELF file version\n"); + DBG_PRINT("Invalid ELF file version\n"); return -1; } if (elf_hdr->e_machine != MODULE_ELF_MACHINE) { - fprintf(stderr, "Invalid ELF architecture\n"); + DBG_PRINT("Invalid ELF architecture\n"); return -1; } @@ -218,12 +224,12 @@ static int check_header(Elf32_Ehdr *elf_hdr) { return res; if (elf_hdr->e_type != MODULE_ELF_TYPE) { - fprintf(stderr, "The ELF file must be a shared object\n"); + DBG_PRINT("The ELF file must be a shared object\n"); return -1; } if (elf_hdr->e_phoff == 0x00000000) { - fprintf(stderr, "PHT missing\n"); + DBG_PRINT("PHT missing\n"); return -1; } @@ -239,7 +245,7 @@ static int check_header_shallow(Elf32_Ehdr *elf_hdr) { return res; if (elf_hdr->e_shoff == 0x00000000) { - fprintf(stderr, "SHT missing\n"); + DBG_PRINT("SHT missing\n"); return -1; } @@ -297,12 +303,12 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { if (max_addr - min_addr == 0) { // No loadable segments - fprintf(stderr, "No loadable segments found\n"); + DBG_PRINT("No loadable segments found\n"); goto out; } if (dyn_addr == 0) { - fprintf(stderr, "No dynamic information segment found\n"); + DBG_PRINT("No dynamic information segment found\n"); goto out; } @@ -319,7 +325,7 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { max_align, max_alloc-min_alloc) != 0) { - fprintf(stderr, "Could not allocate segments\n"); + DBG_PRINT("Could not allocate segments\n"); goto out; } @@ -358,7 +364,7 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { } } - printf("Loadable segment of size 0x%08x copied from vaddr 0x%08x at 0x%08x\n", + DBG_PRINT("Loadable segment of size 0x%08x copied from vaddr 0x%08x at 0x%08x\n", cr_pht->p_filesz, cr_pht->p_vaddr, (Elf32_Addr)module_get_absolute(cr_pht->p_vaddr, module)); @@ -368,9 +374,9 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { // Setup dynamic segment location module->dyn_table = module_get_absolute(dyn_addr, module); - printf("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr, + DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr, max_align); - printf("Module size: 0x%08x\n", module->module_size); + DBG_PRINT("Module size: 0x%08x\n", module->module_size); out: // Free up allocated memory @@ -441,7 +447,7 @@ static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) if (elf_malloc(&module->module_addr, max_align, max_offset - min_offset) != 0) { - fprintf(stderr, "Could not allocate sections\n"); + DBG_PRINT("Could not allocate sections\n"); goto out; } @@ -593,10 +599,10 @@ static int perform_relocation(struct elf_module *module, Elf32_Rel *rel) { if (sym_def == NULL) { // This should never happen - fprintf(stderr, "Warning: Cannot perform relocation for symbol %s\n", + DBG_PRINT("Cannot perform relocation for symbol %s\n", module->str_table + sym_ref->st_name); - // TODO: Return an error - return 0; + + return -1; } // Compute the absolute symbol virtual address @@ -632,8 +638,8 @@ static int perform_relocation(struct elf_module *module, Elf32_Rel *rel) { *dest += module->base_addr; break; default: - fprintf(stderr, "Warning: Relocation type %d not supported\n", type); - break; + DBG_PRINT("Relocation type %d not supported\n", type); + return -1; } return 0; @@ -663,7 +669,7 @@ static int resolve_symbols(struct elf_module *module) { break; case DT_PLTREL: if (dyn_entry->d_un.d_val != DT_REL) { - fprintf(stderr, "Unsupported PLT relocation\n"); + DBG_PRINT("Unsupported PLT relocation\n"); return -1; } case DT_JMPREL: @@ -757,14 +763,14 @@ static int check_symbols(struct elf_module *module) { if (crt_sym->st_shndx == SHN_UNDEF) { // We have an undefined symbol if (strong_count == 0 && weak_count == 0) { - fprintf(stderr, "Symbol %s is undefined\n", crt_name); - // TODO: Return an error - //return -1; + DBG_PRINT("Symbol %s is undefined\n", crt_name); + return -1; } } else { if (strong_count > 0 && ELF32_ST_BIND(ref_sym->st_info) == STB_GLOBAL) { - fprintf(stderr, "Warning: Symbol %s is defined more than once\n", crt_name); - //return -1; + // It's not an error - at relocation, the most recent symbol + // will be considered + DBG_PRINT("Symbol %s is defined more than once\n", crt_name); } } } @@ -792,11 +798,6 @@ int module_load(struct elf_module *module) { // Checking the header signature and members CHECKED(res, check_header(&elf_hdr), error); - // DEBUG -#ifdef ELF_DEBUG - print_elf_ehdr(&elf_hdr); -#endif // ELF_DEBUG - // Load the segments in the memory CHECKED(res, load_segments(module, &elf_hdr), error); // Obtain dynamic linking information @@ -814,6 +815,7 @@ int module_load(struct elf_module *module) { // The file image is no longer needed image_unload(module); + DBG_PRINT("MODULE %s LOADED SUCCESSFULLY\n", module->name); return 0; @@ -847,18 +849,8 @@ int module_load_shallow(struct elf_module *module) { // Checking the header signature and members CHECKED(res, check_header_shallow(&elf_hdr), error); - // DEBUG -#ifdef ELF_DEBUG - print_elf_ehdr(&elf_hdr); -#endif // ELF_DEBUG - CHECKED(res, load_shallow_sections(module, &elf_hdr), error); - // DEBUG -#ifdef ELF_DEBUG - print_elf_symbols(module); -#endif // ELF_DEBUG - // Check the symbols for duplicates / missing definitions CHECKED(res, check_symbols(module), error); @@ -868,6 +860,7 @@ int module_load_shallow(struct elf_module *module) { // The file image is no longer needed image_unload(module); + DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name); return 0; @@ -882,7 +875,7 @@ int module_unload(struct elf_module *module) { struct module_dep *crt_dep, *tmp; // Make sure nobody needs us if (!list_empty(&module->dependants)) { - fprintf(stderr, "Module is required by other modules.\n"); + DBG_PRINT("Module is required by other modules.\n"); return -1; } @@ -939,7 +932,7 @@ static Elf32_Sym *module_find_symbol_gnu(const char *name, struct elf_module *mo Elf32_Word bitmask_nwords = *cr_word++; if ((bitmask_nwords & (bitmask_nwords - 1)) != 0) { - fprintf(stderr, "Warning: Invalid GNU Hash structure\n"); + DBG_PRINT("Invalid GNU Hash structure\n"); return NULL; } diff --git a/com32/elflink/elf_utils.c b/com32/elflink/elf_utils.c index 97f27b95..b957b5da 100644 --- a/com32/elflink/elf_utils.c +++ b/com32/elflink/elf_utils.c @@ -29,6 +29,7 @@ unsigned long elf_gnu_hash(const unsigned char *name) { return h & 0xFFFFFFFF; } +#ifdef ELF_NO_POSIX_MEMALIGN struct memalign_info { void *start_addr; @@ -68,3 +69,21 @@ void elf_free(void *memptr) { free(info->start_addr); } + +#else + +int elf_malloc(void **memptr, size_t alignment, size_t size) { + if ((alignment & (alignment - 1)) != 0) + return EINVAL; + + if (alignment % sizeof(void*) != 0) + alignment = sizeof(void*); + + return posix_memalign(memptr, alignment, size); +} + +void elf_free(void *memptr) { + free(memptr); +} + +#endif //ELF_NO_POSIX_MEMALIGN diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 717e2e56..f55d233e 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -7,36 +7,49 @@ NOGPL := 1 topdir = ../.. include MCONFIG -LIBPNGOBJS = \ +# PNG library object files +LIBPNG_OBJS = \ libpng/png.o libpng/pngset.o libpng/pngget.o libpng/pngrutil.o \ libpng/pngtrans.o libpng/pngwutil.o libpng/pngread.o \ libpng/pngrio.o libpng/pngwio.o libpng/pngwrite.o \ libpng/pngrtran.o libpng/pngwtran.o libpng/pngmem.o \ libpng/pngerror.o libpng/pngpread.o -LIBZLIBOBJS = \ +# ZIP library object files +LIBZLIB_OBJS = \ zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ - zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o\ + \ + sys/zfile.o sys/zfopen.o \ + \ + syslinux/zloadfile.o -LIBJPGOBJS = \ +# JPG library object files +LIBJPG_OBJS = \ jpeg/tinyjpeg.o jpeg/jidctflt.o jpeg/decode1.o jpeg/decode3.o \ jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o \ jpeg/rgba32.o jpeg/bgra32.o -LIBENTRYOBJS = \ +LIBVESA_OBJS = \ + sys/vesacon_write.o sys/vesaserial_write.o \ + sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \ + sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o + +LIBPCI_OBJS = \ + pci/cfgtype.o pci/scan.o \ + pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \ + pci/writeb.o pci/writew.o pci/writel.o pci/writebios.o + +# COM32 core object files +LIBENTRY_OBJS = \ sys/intcall.o sys/farcall.o sys/cfarcall.o sys/zeroregs.o \ sys/entry.o sys/exit.o sys/argv.o sys/times.o \ sys/fileinfo.o sys/opendev.o sys/read.o sys/write.o sys/ftell.o \ sys/close.o sys/open.o sys/fileread.o sys/fileclose.o \ sys/isatty.o sys/fstat.o -LIBVESAOBJS = \ - sys/vesacon_write.o sys/vesaserial_write.o \ - sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \ - sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \ - -LIBSYSLINUXOBJS = \ +LIBSYSLINUX_OBJS = \ syslinux/idle.o syslinux/reboot.o \ syslinux/features.o syslinux/config.o syslinux/serial.o \ syslinux/ipappend.o syslinux/dsinfo.o syslinux/version.o \ @@ -49,7 +62,7 @@ LIBSYSLINUXOBJS = \ syslinux/run_default.o syslinux/run_command.o \ syslinux/cleanup.o syslinux/localboot.o syslinux/runimage.o \ \ - syslinux/loadfile.o syslinux/floadfile.o syslinux/zloadfile.o \ + syslinux/loadfile.o syslinux/floadfile.o \ \ syslinux/load_linux.o syslinux/initramfs.o \ syslinux/initramfs_file.o syslinux/initramfs_loadfile.o \ @@ -59,8 +72,29 @@ LIBSYSLINUXOBJS = \ \ syslinux/adv.o syslinux/advwrite.o syslinux/getadv.o \ syslinux/setadv.o + +LIBGCC_OBJS = \ + libgcc/__ashldi3.o libgcc/__udivdi3.o \ + libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o \ + libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o \ + libgcc/__divdi3.o libgcc/__moddi3.o + +LIBCONSOLE_OBJS = \ + \ + sys/openconsole.o sys/line_input.o \ + sys/colortable.o sys/screensize.o \ + \ + sys/stdcon_read.o sys/stdcon_write.o sys/rawcon_read.o \ + sys/rawcon_write.o sys/err_read.o sys/err_write.o \ + sys/null_read.o sys/null_write.o sys/serial_write.o \ + \ + sys/xserial_write.o \ + \ + sys/ansi.o \ + \ + sys/ansicon_write.o sys/ansiserial_write.o -LIBOTHEROBJS = \ +LIBOTHER_OBJS = \ abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o \ ctypes.o errno.o fgetc.o fgets.o fopen.o fprintf.o fputc.o \ fclose.o putchar.o setjmp.o \ @@ -108,14 +142,24 @@ LIBOTHEROBJS = \ \ sys/x86_init_fpu.o math/pow.o math/strtod.o +MINLIBOBJS = \ + $(LIBOTHER_OBJS) \ + $(LIBENTRY_OBJS) \ + $(LIBSYSLINUX_OBJS) \ + $(LIBGCC_OBJS) \ + $(LIBCONSOLE_OBJS) + +DYNLIBOBJS = \ + $(LIBZLIB_OBJS) \ + $(LIBPNG_OBJS) \ + $(LIBJPG_OBJS) \ + $(LIBPCI_OBJS) \ + $(LIBVESA_OBJS) + LIBOBJS = \ - $(LIBOTHEROBJS) \ - $(LIBENTRYOBJS) \ - $(LIBZLIBOBJS) \ - $(LIBPNGOBJS) \ - $(LIBVESAOBJS) \ - $(LIBJPGOBJS) \ - $(LIBSYSLINUXOBJS) + $(MINLIBOBJS) \ + $(DYNLIBOBJS) + BINDIR = /usr/bin LIBDIR = /usr/lib @@ -124,16 +168,21 @@ AUXDIR = $(DATADIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 -all: libcom32.a klibc.dyn +all: libcom32.a libcom32min.a klibc.dyn libcom32.a : $(LIBOBJS) rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ + +libcom32min.a : $(MINLIBOBJS) + rm -f $@ + $(AR) cq $@ $^ + $(RANLIB) $@ -klibc.dyn : $(LIBOTHEROBJS) +klibc.dyn : $(DYNLIBOBJS) rm -f $@ - $(LD) -shared -o $@ $(LIBOTHEROBJS) + $(LD) -shared -o $@ $(DYNLIBOBJS) tidy dist: rm -f sys/vesa/alphatbl.c |