aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Bucur <stefanb@zytor.com>2008-07-25 20:04:25 -0700
committerStefan Bucur <stefan@stefan-ubumac.(none)>2009-03-15 10:10:02 +0200
commitf2dadf00542d104f98977249618b37c1362fd960 (patch)
treeebf29d0214ca89720a9830149964d7d30fc56aff
parent4f01f5f493a83d3e04d380895be16931c3c3b9e4 (diff)
downloadsyslinux-elf-f2dadf00542d104f98977249618b37c1362fd960.tar.gz
syslinux-elf-f2dadf00542d104f98977249618b37c1362fd960.tar.xz
syslinux-elf-f2dadf00542d104f98977249618b37c1362fd960.zip
Dynamic loading of klibc fully functional.
-rw-r--r--com32/elflink/Makefile4
-rw-r--r--com32/elflink/elf_module.c107
-rw-r--r--com32/elflink/elf_utils.c19
-rw-r--r--com32/lib/Makefile95
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