aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
Diffstat (limited to 'com32')
-rw-r--r--com32/Makefile21
-rw-r--r--com32/chain/Makefile4
-rw-r--r--com32/cmenu/Makefile29
-rw-r--r--com32/elflink/ldlinux/Makefile13
-rw-r--r--com32/elflink/ldlinux/adv.c15
-rw-r--r--com32/elflink/ldlinux/advwrite.c10
-rw-r--r--com32/gfxboot/Makefile17
-rw-r--r--com32/gpllib/Makefile16
-rw-r--r--com32/hdt/Makefile9
-rw-r--r--com32/include/bitsize/limits.h12
-rw-r--r--com32/include/bitsize/stddef.h14
-rw-r--r--com32/include/bitsize/stdint.h25
-rw-r--r--com32/include/bitsize/stdintconst.h18
-rw-r--r--com32/include/bitsize/stdintlimits.h22
-rw-r--r--com32/include/bitsize32/limits.h14
-rw-r--r--com32/include/bitsize32/stddef.h9
-rw-r--r--com32/include/bitsize32/stdint.h24
-rw-r--r--com32/include/bitsize32/stdintconst.h13
-rw-r--r--com32/include/bitsize32/stdintlimits.h23
-rw-r--r--com32/include/bitsize64/limits.h14
-rw-r--r--com32/include/bitsize64/stddef.h10
-rw-r--r--com32/include/bitsize64/stdint.h24
-rw-r--r--com32/include/bitsize64/stdintconst.h13
-rw-r--r--com32/include/bitsize64/stdintlimits.h23
-rw-r--r--com32/include/com32.h4
-rw-r--r--com32/include/dprintf.h8
-rw-r--r--com32/include/klibc/i386/archsetjmp.h19
-rw-r--r--com32/include/klibc/x86_64/archsetjmp.h21
-rw-r--r--com32/include/netinet/in.h8
-rw-r--r--com32/include/setjmp.h8
-rw-r--r--com32/include/sys/bitops.h30
-rw-r--r--com32/include/sys/cpu.h140
-rw-r--r--com32/include/sys/elfcommon.h50
-rw-r--r--com32/include/sys/i386/bitops.h54
-rw-r--r--com32/include/sys/i386/cpu.h135
-rw-r--r--com32/include/sys/i386/module.h35
-rw-r--r--com32/include/sys/module.h48
-rw-r--r--com32/include/sys/x86_64/bitops.h55
-rw-r--r--com32/include/sys/x86_64/cpu.h148
-rw-r--r--com32/include/sys/x86_64/module.h35
-rw-r--r--com32/include/syslinux/firmware.h72
-rw-r--r--com32/include/syslinux/linux.h99
-rw-r--r--com32/include/syslinux/memscan.h1
-rw-r--r--com32/include/syslinux/version.h6
-rw-r--r--com32/lib/Makefile153
-rw-r--r--com32/lib/i386/elf.ld178
-rw-r--r--com32/lib/i386/setjmp.S63
-rw-r--r--com32/lib/libgcc/__muldi3.S49
-rw-r--r--com32/lib/memcpy.S4
-rw-r--r--com32/lib/memcpy.c29
-rw-r--r--com32/lib/memmove.S4
-rw-r--r--com32/lib/memmove.c36
-rw-r--r--com32/lib/mempcpy.S4
-rw-r--r--com32/lib/mempcpy.c14
-rw-r--r--com32/lib/memset.S4
-rw-r--r--com32/lib/memset.c30
-rw-r--r--com32/lib/setjmp.S11
-rw-r--r--com32/lib/sys/ansicon_write.c93
-rw-r--r--com32/lib/sys/farcall.c10
-rw-r--r--com32/lib/sys/i386/x86_init_fpu.c58
-rw-r--r--com32/lib/sys/module/common.c83
-rw-r--r--com32/lib/sys/module/common.h11
-rw-r--r--com32/lib/sys/module/elf_module.c334
-rw-r--r--com32/lib/sys/module/elfutils.h19
-rw-r--r--com32/lib/sys/module/i386/elf_module.c341
-rw-r--r--com32/lib/sys/module/i386/shallow_module.c161
-rw-r--r--com32/lib/sys/module/x86_64/elf_module.c372
-rw-r--r--com32/lib/sys/module/x86_64/shallow_module.c161
-rw-r--r--com32/lib/sys/vesa/initvesa.c218
-rw-r--r--com32/lib/sys/vesa/screencpy.c46
-rw-r--r--com32/lib/sys/vesa/vesa.h1
-rw-r--r--com32/lib/sys/vesa/video.h10
-rw-r--r--com32/lib/sys/vesacon_write.c3
-rw-r--r--com32/lib/sys/x86_64/x86_init_fpu.c58
-rw-r--r--com32/lib/sys/x86_init_fpu.c22
-rw-r--r--com32/lib/syslinux/cleanup.c2
-rw-r--r--com32/lib/syslinux/dsinfo.c9
-rw-r--r--com32/lib/syslinux/load_linux.c82
-rw-r--r--com32/lib/syslinux/memscan.c8
-rw-r--r--com32/lib/syslinux/serial.c15
-rw-r--r--com32/lib/syslinux/shuffle.c9
-rw-r--r--com32/lib/syslinux/version.c2
-rw-r--r--com32/lib/x86_64/elf.ld180
-rw-r--r--com32/lib/x86_64/setjmp.S54
-rw-r--r--com32/libupload/Makefile10
-rw-r--r--com32/libutil/Makefile3
-rw-r--r--com32/lua/src/Makefile3
-rw-r--r--com32/mboot/Makefile5
-rw-r--r--com32/menu/Makefile13
-rw-r--r--com32/modules/Makefile3
-rw-r--r--com32/modules/ls.c2
-rw-r--r--com32/modules/zzjson.c6
-rw-r--r--com32/rosh/Makefile10
-rw-r--r--com32/rosh/rosh.c2
-rw-r--r--com32/samples/Makefile13
-rw-r--r--com32/samples/advdump.c6
-rw-r--r--com32/samples/entrydump.c6
-rw-r--r--com32/samples/resolv.c6
-rw-r--r--com32/samples/serialinfo.c6
-rw-r--r--com32/sysdump/Makefile11
-rw-r--r--com32/sysdump/cpuid.c11
-rw-r--r--com32/tools/Makefile4
102 files changed, 3174 insertions, 1255 deletions
diff --git a/com32/Makefile b/com32/Makefile
index c4699cfd..7ea1b01c 100644
--- a/com32/Makefile
+++ b/com32/Makefile
@@ -1,5 +1,22 @@
SUBDIRS = libupload tools lib elflink/ldlinux gpllib libutil modules mboot \
menu samples elflink rosh cmenu hdt gfxboot sysdump lua/src chain
-all tidy dist clean spotless install:
- set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
+.PHONY: subdirs $(SUBDIRS)
+subdirs: $(SUBDIRS)
+$(SUBDIRS):
+ @mkdir -p $(OBJ)/$@
+ $(MAKE) -C $(OBJ)/$@ SRC="$(SRC)"/$@ OBJ="$(OBJ)"/$@/ \
+ -f $(SRC)/$@/Makefile $(MAKECMDGOALS)
+
+all tidy dist clean spotless install: subdirs
+
+# Parallel dependencies
+chain lua/src mboot menu: libutil gpllib
+cmenu: lib libutil
+elflink/ldlinux: lib
+gfxboot: libutil
+hdt: lib libupload cmenu gpllib libutil
+modules: lib libutil gpllib
+rosh: lib libutil
+samples: libutil elflink/ldlinux
+sysdump: libupload gpllib
diff --git a/com32/chain/Makefile b/com32/chain/Makefile
index 9a298fae..32385509 100644
--- a/com32/chain/Makefile
+++ b/com32/chain/Makefile
@@ -11,9 +11,7 @@
##
## -----------------------------------------------------------------------
-
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
OBJS = chain.o partiter.o utility.o options.o mangle.o
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index 181937bd..7ff1ff6e 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -18,31 +18,34 @@
NOGPL := 1
LIBS = libmenu/libmenu.c32 \
- $(com32)/libutil/libutil_com.c32 \
- $(com32)/lib/libcom32.c32
+ $(objdir)/com32/libutil/libutil_com.c32 \
+ $(objdir)/com32/lib/libcom32.c32
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-CFLAGS += -I./libmenu
+CFLAGS += -I$(SRC)/libmenu
-LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
- libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o \
- $(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
+LIBMENU = $(objdir)/com32/libutil/libutil_com.c32 \
+ $(objdir)/com32/lib/libcom32.c32 \
+ libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
+ libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o
-CMENUS = $(patsubst %.c,%.c32,$(wildcard *.c))
-IMENUS = $(patsubst %.menu,%.c32,$(wildcard *.menu))
+CMENUS = $(patsubst %.c,%.c32,$(wildcard $(SRC)/*.c))
+IMENUS = $(patsubst %.menu,%.c32,$(wildcard $(SRC)/*.menu))
-MENUS = $(LIBS) $(CMENUS) $(IMENUS)
+MENUS = $(LIBS) $(subst $(SRC)/,,$(CMENUS) $(IMENUS))
.SUFFIXES: .S .c .o .elf .c32 .menu
.PRECIOUS: %.c
%.c: %.menu adv_menu.tpl
- $(PYTHON) menugen.py --input=$< --output=$@ --template=adv_menu.tpl
+ $(PYTHON) $(SRC)/menugen.py --input=$< --output=$@ --template=$(SRC)/adv_menu.tpl
-all: menus
+all: makeoutputdirs menus
+
+makeoutputdirs:
+ @mkdir -p $(OBJ)/libmenu
libmenu/libmenu.c32: $(LIBMENU)
$(LD) -shared $(LDFLAGS) -o $@ $^
diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index 93ca127d..aa35f475 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -10,18 +10,19 @@
##
## -----------------------------------------------------------------------
-topdir = ../../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib -fvisibility=hidden
-LIBS = --whole-archive $(com32)/lib/libcom32min.a
+LIBS = --whole-archive $(objdir)/com32/lib/libcom32min.a
+
+OBJS = ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o adv.o \
+ execute.o chainboot.o kernel.o get_key.o advwrite.o setadv.o \
+ eprintf.o loadhigh.o msg.o
all: ldlinux.c32 ldlinux_lnx.a
-ldlinux.c32 : ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o \
- adv.o execute.o chainboot.o kernel.o get_key.o \
- advwrite.o setadv.o eprintf.o loadhigh.o msg.o
+ldlinux.c32 : $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
diff --git a/com32/elflink/ldlinux/adv.c b/com32/elflink/ldlinux/adv.c
index 4c3ad508..677fe92d 100644
--- a/com32/elflink/ldlinux/adv.c
+++ b/com32/elflink/ldlinux/adv.c
@@ -32,24 +32,13 @@
*/
#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
#include <klibc/compiler.h>
-#include <inttypes.h>
-#include <com32.h>
__export void *__syslinux_adv_ptr;
__export size_t __syslinux_adv_size;
-extern void adv_init(void);
void __constructor __syslinux_init(void)
{
- static com32sys_t reg;
-
- /* Initialize the ADV structure */
- reg.eax.w[0] = 0x0025;
- __intcall(0x22, &reg, NULL);
-
- reg.eax.w[0] = 0x001c;
- __intcall(0x22, &reg, &reg);
- __syslinux_adv_ptr = MK_PTR(reg.es, reg.ebx.w[0]);
- __syslinux_adv_size = reg.ecx.w[0];
+ firmware->adv_ops->init();
}
diff --git a/com32/elflink/ldlinux/advwrite.c b/com32/elflink/ldlinux/advwrite.c
index 35829c1c..47e45534 100644
--- a/com32/elflink/ldlinux/advwrite.c
+++ b/com32/elflink/ldlinux/advwrite.c
@@ -31,15 +31,11 @@
* Write back the ADV
*/
-#include <syslinux/adv.h>
#include <klibc/compiler.h>
-#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
__export int syslinux_adv_write(void)
{
- static com32sys_t reg;
-
- reg.eax.w[0] = 0x001d;
- __intcall(0x22, &reg, &reg);
- return (reg.eflags.l & EFLAGS_CF) ? -1 : 0;
+ return firmware->adv_ops->write();
}
diff --git a/com32/gfxboot/Makefile b/com32/gfxboot/Makefile
index f2a73762..98d6a032 100644
--- a/com32/gfxboot/Makefile
+++ b/com32/gfxboot/Makefile
@@ -11,24 +11,35 @@
##
## -----------------------------------------------------------------------
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
MODULES = gfxboot.c32
all: $(MODULES)
-gfxboot.c32 : gfxboot.o realmode_callback.o $(LIBS) $(C_LIBS)
+OBJS = gfxboot.o realmode_callback.o
+
+gfxboot.c32 : $(OBJS) $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
realmode_callback.o: realmode_callback.asm
+ifeq ($(ARCH),i386)
$(NASM) -f bin -O99 -o $*.tmp -l $*.lst $<
$(OBJCOPY) -B i386 -I binary -O elf32-i386 \
--redefine-sym _binary_$*_tmp_start=$*_start \
--redefine-sym _binary_$*_tmp_end=$*_end \
--strip-symbol _binary_$*_tmp_size \
$*.tmp $@
+endif
+ifeq ($(ARCH),x86_64)
+ $(NASM) -f bin -O99 -o $*.tmp -l $*.lst $<
+ $(OBJCOPY) -B i386:x86-64 -I binary -O elf64-x86-64 \
+ --redefine-sym _binary_$*_tmp_start=$*_start \
+ --redefine-sym _binary_$*_tmp_end=$*_end \
+ --strip-symbol _binary_$*_tmp_size \
+ $*.tmp $@
+endif
tidy dist:
rm -f *.o *.lo *.a *.lst .*.d *.tmp
diff --git a/com32/gpllib/Makefile b/com32/gpllib/Makefile
index 92dd20f2..71f335da 100644
--- a/com32/gpllib/Makefile
+++ b/com32/gpllib/Makefile
@@ -3,14 +3,12 @@
#
# Include configuration rules
-topdir = ../..
-MAKEDIR = $(topdir)/mk
include $(MAKEDIR)/lib.mk
-REQFLAGS += -I../gplinclude -I../gplinclude/zzjson
+REQFLAGS += -I$(SRC)/../gplinclude -I$(SRC)/../gplinclude/zzjson
-GPLDIRS := . disk dmi vpd acpi zzjson
-LIBOBJS := $(foreach dir,$(GPLDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
+GPLDIRS := $(SRC) $(addprefix $(SRC)/,disk dmi vpd acpi zzjson)
+LIBOBJS := $(subst $(SRC)/,,$(foreach dir,$(GPLDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c))))
BINDIR = /usr/bin
LIBDIR = /usr/lib
@@ -19,7 +17,11 @@ AUXDIR = $(DATADIR)/syslinux
INCDIR = /usr/include
COM32DIR = $(AUXDIR)/com32
-all: libcom32gpl.c32
+all: makeoutputdirs libcom32gpl.c32
+
+makeoutputdirs:
+ @mkdir -p $(foreach b, \
+ $(addprefix $(OBJ),$(sort $(dir $(LIBOBJS)))),$(b))
libcom32gpl.c32 : $(LIBOBJS)
$(LD) -shared $(LDFLAGS) -o $@ $^
@@ -38,6 +40,6 @@ install: all
mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
install -m 644 libcom32gpl.c32 $(INSTALLROOT)$(COM32DIR)
mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
- cp -r ../gplinclude $(INSTALLROOT)$(COM32DIR)/include/
+ cp -r $(SRC)/../gplinclude $(INSTALLROOT)$(COM32DIR)/include/
-include .*.d */.*.d */*/.*.d
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index d264b5ba..362b4874 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -15,18 +15,17 @@
## Hardware Detection Tool
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-LIBS = ../libupload/libcom32upload.a
-C_LIBS += $(com32)/cmenu/libmenu/libmenu.c32
+LIBS = $(objdir)/com32/libupload/libcom32upload.a
+C_LIBS += $(objdir)/com32/cmenu/libmenu/libmenu.c32
CFLAGS += -I$(com32)/cmenu/libmenu -I$(com32)
MODULES = hdt.c32
TESTFILES =
-OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
+OBJS = $(subst $(SRC)/,,$(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
VERSION = $(shell $(SED) -n 's/\#define VERSION \"\(.*\)\"/\1/p' hdt.h)
CODENAME = $(shell $(SED) -n 's/\#define CODENAME \"\(.*\)\"/\1/p' hdt.h)
NODASH_VERSION = $(shell echo $(VERSION) | $(SED) -e 's/-/_/g' | $(SED) -e 's/\./_/g')
diff --git a/com32/include/bitsize/limits.h b/com32/include/bitsize/limits.h
index f90e524b..7129c4a6 100644
--- a/com32/include/bitsize/limits.h
+++ b/com32/include/bitsize/limits.h
@@ -5,10 +5,12 @@
#ifndef _BITSIZE_LIMITS_H
#define _BITSIZE_LIMITS_H
-#define LONG_BIT 32
-
-#define LONG_MIN (-2147483647L-1)
-#define LONG_MAX 2147483647L
-#define ULONG_MAX 4294967295UL
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/limits.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/limits.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITSIZE_LIMITS_H */
diff --git a/com32/include/bitsize/stddef.h b/com32/include/bitsize/stddef.h
index 213e8ab7..04418a04 100644
--- a/com32/include/bitsize/stddef.h
+++ b/com32/include/bitsize/stddef.h
@@ -1,14 +1,16 @@
/*
- * bits32/stddef.h
+ * Include stddef.h as appropriate for architecture
*/
#ifndef _BITSIZE_STDDEF_H
#define _BITSIZE_STDDEF_H
-#define _SIZE_T
-typedef unsigned int size_t;
-
-#define _PTRDIFF_T
-typedef signed long ptrdiff_t;
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stddef.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stddef.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITSIZE_STDDEF_H */
diff --git a/com32/include/bitsize/stdint.h b/com32/include/bitsize/stdint.h
index 8e444b6d..7e7b2355 100644
--- a/com32/include/bitsize/stdint.h
+++ b/com32/include/bitsize/stdint.h
@@ -8,27 +8,16 @@
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
-typedef long long int int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
-
-typedef int int_fast16_t;
-typedef int int_fast32_t;
-
-typedef unsigned int uint_fast16_t;
-typedef unsigned int uint_fast32_t;
-
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
-
-#define __INT64_C(c) c ## LL
-#define __UINT64_C(c) c ## ULL
-
-#define __PRI64_RANK "ll"
-#define __PRIFAST_RANK ""
-#define __PRIPTR_RANK ""
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdint.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdint.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITSIZE_STDINT_H */
diff --git a/com32/include/bitsize/stdintconst.h b/com32/include/bitsize/stdintconst.h
index 7db63bdf..b2f3141a 100644
--- a/com32/include/bitsize/stdintconst.h
+++ b/com32/include/bitsize/stdintconst.h
@@ -1,18 +1,16 @@
/*
- * bits32/stdintconst.h
+ * bitsize/stdintconst.h
*/
#ifndef _BITSIZE_STDINTCONST_H
#define _BITSIZE_STDINTCONST_H
-#define INT_FAST16_C(c) INT32_C(c)
-#define INT_FAST32_C(c) INT32_C(c)
-
-#define UINT_FAST16_C(c) UINT32_C(c)
-#define UINT_FAST32_C(c) UINT32_C(c)
-
-#define INTPTR_C(c) INT32_C(c)
-#define UINTPTR_C(c) UINT32_C(c)
-#define PTRDIFF_C(c) INT32_C(c)
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdintconst.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdintconst.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITSIZE_STDINTCONST_H */
diff --git a/com32/include/bitsize/stdintlimits.h b/com32/include/bitsize/stdintlimits.h
index d85094d9..c342c448 100644
--- a/com32/include/bitsize/stdintlimits.h
+++ b/com32/include/bitsize/stdintlimits.h
@@ -1,22 +1,16 @@
/*
- * bits32/stdintlimits.h
+ * bitsize/stdintlimits.h
*/
#ifndef _BITSIZE_STDINTLIMITS_H
#define _BITSIZE_STDINTLIMITS_H
-#define INT_FAST16_MIN INT32_MIN
-#define INT_FAST32_MIN INT32_MIN
-#define INT_FAST16_MAX INT32_MAX
-#define INT_FAST32_MAX INT32_MAX
-#define UINT_FAST16_MAX UINT32_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-
-#define INTPTR_MIN INT32_MIN
-#define INTPTR_MAX INT32_MAX
-#define UINTPTR_MAX UINT32_MAX
-
-#define PTRDIFF_MIN INT32_MIN
-#define PTRDIFF_MAX INT32_MAX
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdintlimits.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdintlimits.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITSIZE_STDINTLIMITS_H */
diff --git a/com32/include/bitsize32/limits.h b/com32/include/bitsize32/limits.h
new file mode 100644
index 00000000..f19205fe
--- /dev/null
+++ b/com32/include/bitsize32/limits.h
@@ -0,0 +1,14 @@
+/*
+ * bits32/limits.h
+ */
+
+#ifndef _BITSIZE32_LIMITS_H
+#define _BITSIZE32_LIMITS_H
+
+#define LONG_BIT 32
+
+#define LONG_MIN (-2147483647L-1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 4294967295UL
+
+#endif /* _BITSIZE_LIMITS_H */
diff --git a/com32/include/bitsize32/stddef.h b/com32/include/bitsize32/stddef.h
new file mode 100644
index 00000000..c34c675c
--- /dev/null
+++ b/com32/include/bitsize32/stddef.h
@@ -0,0 +1,9 @@
+/*
+ * bits32/stddef.h
+ */
+
+#define _SIZE_T
+typedef unsigned int size_t;
+
+#define _PTRDIFF_T
+typedef signed long ptrdiff_t;
diff --git a/com32/include/bitsize32/stdint.h b/com32/include/bitsize32/stdint.h
new file mode 100644
index 00000000..bdc69705
--- /dev/null
+++ b/com32/include/bitsize32/stdint.h
@@ -0,0 +1,24 @@
+/*
+ * bits32/stdint.h
+ */
+
+
+typedef long long int int64_t;
+
+typedef unsigned long long int uint64_t;
+
+typedef int int_fast16_t;
+typedef int int_fast32_t;
+
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
+
+#define __PRI64_RANK "ll"
+#define __PRIFAST_RANK ""
+#define __PRIPTR_RANK ""
diff --git a/com32/include/bitsize32/stdintconst.h b/com32/include/bitsize32/stdintconst.h
new file mode 100644
index 00000000..71ece423
--- /dev/null
+++ b/com32/include/bitsize32/stdintconst.h
@@ -0,0 +1,13 @@
+/*
+ * bits32/stdintconst.h
+ */
+
+#define INT_FAST16_C(c) INT32_C(c)
+#define INT_FAST32_C(c) INT32_C(c)
+
+#define UINT_FAST16_C(c) UINT32_C(c)
+#define UINT_FAST32_C(c) UINT32_C(c)
+
+#define INTPTR_C(c) INT32_C(c)
+#define UINTPTR_C(c) UINT32_C(c)
+#define PTRDIFF_C(c) INT32_C(c)
diff --git a/com32/include/bitsize32/stdintlimits.h b/com32/include/bitsize32/stdintlimits.h
new file mode 100644
index 00000000..175cdcd4
--- /dev/null
+++ b/com32/include/bitsize32/stdintlimits.h
@@ -0,0 +1,23 @@
+/*
+ * bits32/stdintlimits.h
+ */
+
+#define INT_FAST16_MIN INT32_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST16_MAX INT32_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+
+/* sig_atomic_t limit */
+# define SIG_ATOMIC_MIN INT32_MIN //(-2147483647-1)
+# define SIG_ATOMIC_MAX INT32_MAX //(2147483647)
+/* size_t limit */
+# define SIZE_MAX UINT32_MAX //(4294967295U)
diff --git a/com32/include/bitsize64/limits.h b/com32/include/bitsize64/limits.h
new file mode 100644
index 00000000..1acb1bc8
--- /dev/null
+++ b/com32/include/bitsize64/limits.h
@@ -0,0 +1,14 @@
+/*
+ * bits64/limits.h
+ */
+
+#ifndef _BITSIZE64_LIMITS_H
+#define _BITSIZE64_LIMITS_H
+
+#define LONG_BIT 64
+
+#define LONG_MIN (-9223372036854775807L-1)
+#define LONG_MAX 9223372036854775807L
+#define ULONG_MAX 18446744073709551615UL
+
+#endif /* _BITSIZE_LIMITS_H */
diff --git a/com32/include/bitsize64/stddef.h b/com32/include/bitsize64/stddef.h
new file mode 100644
index 00000000..c61bf8ce
--- /dev/null
+++ b/com32/include/bitsize64/stddef.h
@@ -0,0 +1,10 @@
+/*
+ * bits64/stddef.h
+ */
+
+#define _SIZE_T
+typedef unsigned long size_t;
+
+#define _PTRDIFF_T
+typedef signed long ptrdiff_t;
+
diff --git a/com32/include/bitsize64/stdint.h b/com32/include/bitsize64/stdint.h
new file mode 100644
index 00000000..91930003
--- /dev/null
+++ b/com32/include/bitsize64/stdint.h
@@ -0,0 +1,24 @@
+/*
+ * bits64/stdint.h
+ */
+
+
+typedef long int int64_t;
+
+typedef unsigned long int uint64_t;
+
+typedef long int int_fast16_t;
+typedef long int int_fast32_t;
+
+typedef unsigned long int uint_fast16_t;
+typedef unsigned long int uint_fast32_t;
+
+typedef long int intptr_t;
+typedef unsigned long int uintptr_t;
+
+#define __INT64_C(c) c ## L
+#define __UINT64_C(c) c ## UL
+
+#define __PRI64_RANK "l"
+#define __PRIFAST_RANK "l"
+#define __PRIPTR_RANK "l"
diff --git a/com32/include/bitsize64/stdintconst.h b/com32/include/bitsize64/stdintconst.h
new file mode 100644
index 00000000..139ab203
--- /dev/null
+++ b/com32/include/bitsize64/stdintconst.h
@@ -0,0 +1,13 @@
+/*
+ * bits64/stdintconst.h
+ */
+
+#define INT_FAST16_C(c) INT64_C(c)
+#define INT_FAST32_C(c) INT64_C(c)
+
+#define UINT_FAST16_C(c) UINT64_C(c)
+#define UINT_FAST32_C(c) UINT64_C(c)
+
+#define INTPTR_C(c) INT64_C(c)
+#define UINTPTR_C(c) UINT64_C(c)
+#define PTRDIFF_C(c) INT64_C(c)
diff --git a/com32/include/bitsize64/stdintlimits.h b/com32/include/bitsize64/stdintlimits.h
new file mode 100644
index 00000000..a775a7fd
--- /dev/null
+++ b/com32/include/bitsize64/stdintlimits.h
@@ -0,0 +1,23 @@
+/*
+ * bits64/stdintlimits.h
+ */
+
+#define INT_FAST16_MIN INT64_MIN
+#define INT_FAST32_MIN INT64_MIN
+#define INT_FAST16_MAX INT64_MAX
+#define INT_FAST32_MAX INT64_MAX
+#define UINT_FAST16_MAX UINT64_MAX
+#define UINT_FAST32_MAX UINT64_MAX
+
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+
+/* sig_atomic_t limit */
+# define SIG_ATOMIC_MAX INT32_MAX //(2147483647)
+# define SIG_ATOMIC_MIN (-SIG_ATOMIC_MAX-1) //(-2147483647-1)
+/* size_t limit */
+# define SIZE_MAX UINT64_MAX
diff --git a/com32/include/com32.h b/com32/include/com32.h
index 148d08eb..c5d60176 100644
--- a/com32/include/com32.h
+++ b/com32/include/com32.h
@@ -135,7 +135,7 @@ char *lstrdup(const char *);
* specific segment. OFFS_VALID() will return whether or not the
* pointer is actually reachable from the target segment.
*/
-#if defined(DEBUG) && (defined(__COM32__) || defined(__SYSLINUX_CORE__))
+#if defined(CORE_DEBUG) && (defined(__COM32__) || defined(__SYSLINUX_CORE__))
__noreturn __bad_SEG(const volatile void *);
static inline uint16_t SEG(const volatile void *__p)
@@ -176,7 +176,7 @@ static inline bool _OFFS_VALID(const volatile void *__p, size_t __s,
static inline void *MK_PTR(uint16_t __seg, uint16_t __offs)
{
- return (void *)((__seg << 4) + __offs);
+ return (void *)(unsigned long)((__seg << 4) + __offs);
}
/* Some tools to handle 16:16 far pointers in memory */
diff --git a/com32/include/dprintf.h b/com32/include/dprintf.h
index 26ca734b..de4625bc 100644
--- a/com32/include/dprintf.h
+++ b/com32/include/dprintf.h
@@ -6,10 +6,10 @@
#define _DPRINTF_H
#if !defined(DEBUG_PORT) && !defined(DEBUG_STDIO)
-# undef DEBUG
+# undef CORE_DEBUG
#endif
-#ifdef DEBUG
+#ifdef CORE_DEBUG
# include <stdio.h>
@@ -26,9 +26,9 @@ void vdprintf(const char *, va_list);
# define dprintf(fmt, ...) ((void)(0))
# define vdprintf(fmt, ap) ((void)(0))
-#endif /* DEBUG */
+#endif /* CORE_DEBUG */
-# if DEBUG >= 2
+# if CORE_DEBUG >= 2
/* Really verbose debugging... */
# define dprintf2 dprintf
# define vdprintf2 vdprintf
diff --git a/com32/include/klibc/i386/archsetjmp.h b/com32/include/klibc/i386/archsetjmp.h
new file mode 100644
index 00000000..a0def6a1
--- /dev/null
+++ b/com32/include/klibc/i386/archsetjmp.h
@@ -0,0 +1,19 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned int __ebx;
+ unsigned int __esp;
+ unsigned int __ebp;
+ unsigned int __esi;
+ unsigned int __edi;
+ unsigned int __eip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/com32/include/klibc/x86_64/archsetjmp.h b/com32/include/klibc/x86_64/archsetjmp.h
new file mode 100644
index 00000000..454fc60a
--- /dev/null
+++ b/com32/include/klibc/x86_64/archsetjmp.h
@@ -0,0 +1,21 @@
+/*
+ * arch/x86_64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __rbx;
+ unsigned long __rsp;
+ unsigned long __rbp;
+ unsigned long __r12;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+ unsigned long __rip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/com32/include/netinet/in.h b/com32/include/netinet/in.h
index d2af351f..d3fba17f 100644
--- a/com32/include/netinet/in.h
+++ b/com32/include/netinet/in.h
@@ -27,8 +27,16 @@ static inline __constfunc uint16_t __htons(uint16_t v)
static inline __constfunc uint32_t __htonl(uint32_t v)
{
+#if __SIZEOF_POINTER__ == 4
asm("xchgb %h0,%b0 ; roll $16,%0 ; xchgb %h0,%b0"
: "+q" (v));
+#elif __SIZEOF_POINTER__ == 8
+ asm("bswap %0"
+ : "=r" (v)
+ : "0" (v));
+#else
+#error "unable to build for architecture"
+#endif
return v;
}
diff --git a/com32/include/setjmp.h b/com32/include/setjmp.h
index 11b18fbd..e7090955 100644
--- a/com32/include/setjmp.h
+++ b/com32/include/setjmp.h
@@ -9,7 +9,13 @@
#include <klibc/compiler.h>
#include <stddef.h>
-#include <klibc/archsetjmp.h>
+#if __SIZEOF_POINTER__ == 4
+#include <klibc/i386/archsetjmp.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <klibc/x86_64/archsetjmp.h>
+#else
+#error "unsupported architecture"
+#endif
__extern int setjmp(jmp_buf);
__extern __noreturn longjmp(jmp_buf, int);
diff --git a/com32/include/sys/bitops.h b/com32/include/sys/bitops.h
index 40e09fe7..de30d932 100644
--- a/com32/include/sys/bitops.h
+++ b/com32/include/sys/bitops.h
@@ -36,27 +36,11 @@
#include <klibc/compiler.h>
-static inline void set_bit(long __bit, void *__bitmap)
-{
- asm volatile("btsl %1,%0"
- : "+m" (*(unsigned char *)__bitmap)
- : "Ir" (__bit) : "memory");
-}
-
-static inline void clr_bit(long __bit, void *__bitmap)
-{
- asm volatile("btcl %1,%0"
- : "+m" (*(unsigned char *)__bitmap)
- : "Ir" (__bit) : "memory");
-}
-
-static inline int __purefunc test_bit(long __bit, const void *__bitmap)
-{
- unsigned char __r;
- asm("btl %2,%1; setc %0"
- : "=qm" (__r)
- : "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
- return __r;
-}
-
+#if __SIZEOF_POINTER__ == 4
+#include <i386/bitops.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/bitops.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
#endif /* _BITOPS_H */
diff --git a/com32/include/sys/cpu.h b/com32/include/sys/cpu.h
index 53a6250e..05c98843 100644
--- a/com32/include/sys/cpu.h
+++ b/com32/include/sys/cpu.h
@@ -5,138 +5,12 @@
#include <stdint.h>
#include <klibc/compiler.h>
-static inline uint64_t rdtsc(void)
-{
- uint64_t v;
- asm volatile("rdtsc" : "=A" (v));
- return v;
-}
-
-static inline uint32_t rdtscl(void)
-{
- uint32_t v;
- asm volatile("rdtsc" : "=a" (v) : : "edx");
- return v;
-}
-
-static inline void cpuid_count(uint32_t op, uint32_t cnt,
- uint32_t * eax, uint32_t * ebx,
- uint32_t * ecx, uint32_t * edx)
-{
- asm volatile("movl %%ebx,%1 ; "
- "cpuid ; "
- "xchgl %1,%%ebx"
- : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "a"(op), "c"(cnt));
-}
-
-static inline void cpuid(uint32_t op, uint32_t * eax, uint32_t * ebx,
- uint32_t * ecx, uint32_t * edx)
-{
- cpuid_count(op, 0, eax, ebx, ecx, edx);
-}
-
-static inline __constfunc uint32_t cpuid_eax(uint32_t level)
-{
- uint32_t v;
-
- asm volatile("pushl %%ebx ; "
- "cpuid ; "
- "popl %%ebx"
- : "=a" (v)
- : "a"(level)
- : "ecx", "edx");
- return v;
-}
-
-static inline __constfunc uint32_t cpuid_ebx(uint32_t level)
-{
- uint32_t v;
-
- asm volatile("movl %%ebx,%0 ; "
- "cpuid ; "
- "xchgl %0,%%ebx"
- : "=SD" (v), "+a" (level)
- : : "ecx", "edx");
- return v;
-}
-
-static inline __constfunc uint32_t cpuid_ecx(uint32_t level)
-{
- uint32_t v;
-
- asm volatile("pushl %%ebx ; "
- "cpuid ; "
- "popl %%ebx"
- : "=c" (v), "+a" (level)
- : : "edx");
- return v;
-}
-
-static inline __constfunc uint32_t cpuid_edx(uint32_t level)
-{
- uint32_t v;
-
- asm volatile("pushl %%ebx ; "
- "cpuid ; "
- "popl %%ebx"
- : "=d" (v), "+a" (level)
- : : "ecx");
- return v;
-}
-
-/* Standard macro to see if a specific flag is changeable */
-static inline __constfunc bool cpu_has_eflag(uint32_t flag)
-{
- uint32_t f0, f1;
-
- asm("pushfl ; "
- "pushfl ; "
- "popl %0 ; "
- "movl %0,%1 ; "
- "xorl %2,%1 ; "
- "pushl %1 ; "
- "popfl ; "
- "pushfl ; "
- "popl %1 ; "
- "popfl"
- : "=&r" (f0), "=&r" (f1)
- : "ri" (flag));
-
- return !!((f0^f1) & flag);
-}
-
-static inline uint64_t rdmsr(uint32_t msr)
-{
- uint64_t v;
-
- asm volatile("rdmsr" : "=A" (v) : "c"(msr));
- return v;
-}
-
-static inline void wrmsr(uint64_t v, uint32_t msr)
-{
- asm volatile("wrmsr" : : "A" (v), "c" (msr));
-}
-
-static inline void cpu_relax(void)
-{
- asm volatile("rep ; nop");
-}
-
-static inline void hlt(void)
-{
- asm volatile("hlt");
-}
-
-static inline void cli(void)
-{
- asm volatile("cli");
-}
-
-static inline void sti(void)
-{
- asm volatile("sti");
-}
+#if __SIZEOF_POINTER__ == 4
+#include <i386/cpu.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/cpu.h>
+#else
+#error "unsupported architecture"
+#endif
#endif
diff --git a/com32/include/sys/elfcommon.h b/com32/include/sys/elfcommon.h
index 8d6ddb05..99b5ad10 100644
--- a/com32/include/sys/elfcommon.h
+++ b/com32/include/sys/elfcommon.h
@@ -361,4 +361,54 @@
/* Keep this the last entry. */
#define R_386_NUM 38
+/* AMD x86-64 relocations. */
+#define R_X86_64_NONE 0 /* No reloc */
+#define R_X86_64_64 1 /* Direct 64 bit */
+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
+ offset to GOT */
+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
+ to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
+ to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
+ to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
+#define R_X86_64_PC64 24 /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
+ offset to GOT */
+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
+ to GOT entry */
+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
+ to PLT entry */
+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
+ descriptor. */
+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+
+#define R_X86_64_NUM 38
+
#endif /* _SYS_ELFCOMMON_H */
diff --git a/com32/include/sys/i386/bitops.h b/com32/include/sys/i386/bitops.h
new file mode 100644
index 00000000..663b267a
--- /dev/null
+++ b/com32/include/sys/i386/bitops.h
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010-2011 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * i386 bitops.h
+ *
+ * Simple bitwise operations
+ */
+static inline void set_bit(long __bit, void *__bitmap)
+{
+ asm volatile("btsl %1,%0"
+ : "+m" (*(unsigned char *)__bitmap)
+ : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+ asm volatile("btcl %1,%0"
+ : "+m" (*(unsigned char *)__bitmap)
+ : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+ unsigned char __r;
+ asm("btl %2,%1; setc %0"
+ : "=qm" (__r)
+ : "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
+ return __r;
+}
diff --git a/com32/include/sys/i386/cpu.h b/com32/include/sys/i386/cpu.h
new file mode 100644
index 00000000..63d0f5ed
--- /dev/null
+++ b/com32/include/sys/i386/cpu.h
@@ -0,0 +1,135 @@
+/* i386 cpu.h */
+
+static inline uint64_t rdtsc(void)
+{
+ uint64_t v;
+ asm volatile("rdtsc" : "=A" (v));
+ return v;
+}
+
+static inline uint32_t rdtscl(void)
+{
+ uint32_t v;
+ asm volatile("rdtsc" : "=a" (v) : : "edx");
+ return v;
+}
+
+static inline void cpuid_count(uint32_t op, uint32_t cnt,
+ uint32_t * eax, uint32_t * ebx,
+ uint32_t * ecx, uint32_t * edx)
+{
+ asm volatile("movl %%ebx,%1 ; "
+ "cpuid ; "
+ "xchgl %1,%%ebx"
+ : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "a"(op), "c"(cnt));
+}
+
+static inline void cpuid(uint32_t op, uint32_t * eax, uint32_t * ebx,
+ uint32_t * ecx, uint32_t * edx)
+{
+ cpuid_count(op, 0, eax, ebx, ecx, edx);
+}
+
+static inline __constfunc uint32_t cpuid_eax(uint32_t level)
+{
+ uint32_t v;
+
+ asm volatile("pushl %%ebx ; "
+ "cpuid ; "
+ "popl %%ebx"
+ : "=a" (v)
+ : "a"(level)
+ : "ecx", "edx");
+ return v;
+}
+
+static inline __constfunc uint32_t cpuid_ebx(uint32_t level)
+{
+ uint32_t v;
+
+ asm volatile("movl %%ebx,%0 ; "
+ "cpuid ; "
+ "xchgl %0,%%ebx"
+ : "=SD" (v), "+a" (level)
+ : : "ecx", "edx");
+ return v;
+}
+
+static inline __constfunc uint32_t cpuid_ecx(uint32_t level)
+{
+ uint32_t v;
+
+ asm volatile("pushl %%ebx ; "
+ "cpuid ; "
+ "popl %%ebx"
+ : "=c" (v), "+a" (level)
+ : : "edx");
+ return v;
+}
+
+static inline __constfunc uint32_t cpuid_edx(uint32_t level)
+{
+ uint32_t v;
+
+ asm volatile("pushl %%ebx ; "
+ "cpuid ; "
+ "popl %%ebx"
+ : "=d" (v), "+a" (level)
+ : : "ecx");
+ return v;
+}
+
+/* Standard macro to see if a specific flag is changeable */
+static inline __constfunc bool cpu_has_eflag(uint32_t flag)
+{
+ uint32_t f0, f1;
+
+ asm("pushfl ; "
+ "pushfl ; "
+ "popl %0 ; "
+ "movl %0,%1 ; "
+ "xorl %2,%1 ; "
+ "pushl %1 ; "
+ "popfl ; "
+ "pushfl ; "
+ "popl %1 ; "
+ "popfl"
+ : "=&r" (f0), "=&r" (f1)
+ : "ri" (flag));
+
+ return !!((f0^f1) & flag);
+}
+
+static inline uint64_t rdmsr(uint32_t msr)
+{
+ uint64_t v;
+
+ asm volatile("rdmsr" : "=A" (v) : "c"(msr));
+ return v;
+}
+
+static inline void wrmsr(uint64_t v, uint32_t msr)
+{
+ asm volatile("wrmsr" : : "A" (v), "c" (msr));
+}
+
+static inline void cpu_relax(void)
+{
+ asm volatile("rep ; nop");
+}
+
+static inline void hlt(void)
+{
+ asm volatile("hlt");
+}
+
+static inline void cli(void)
+{
+ asm volatile("cli");
+}
+
+static inline void sti(void)
+{
+ asm volatile("sti");
+}
diff --git a/com32/include/sys/i386/module.h b/com32/include/sys/i386/module.h
new file mode 100644
index 00000000..21988ead
--- /dev/null
+++ b/com32/include/sys/i386/module.h
@@ -0,0 +1,35 @@
+/**
+ * syslinux/module.h
+ *
+ * Dynamic ELF modules definitions and services.
+ */
+
+#ifndef I386_MODULE_H_
+#define I386_MODULE_H_
+
+#include <elf.h>
+
+/*
+ * Accepted values for various ELF header parameters found in an ELF dynamic
+ * object.
+ */
+#define MODULE_ELF_CLASS ELFCLASS32 // 32-bit modules
+#define MODULE_ELF_CLASS_SIZE 32 // Size of a word value
+#define MODULE_ELF_DATA ELFDATA2LSB // Word endianess
+#define MODULE_ELF_VERSION EV_CURRENT // Object version
+#define MODULE_ELF_TYPE ET_DYN // Executable type (shared object - .so)
+#define MODULE_ELF_MACHINE EM_386 // Target architecture
+
+#define ELF_MOD_SYS "32 bit"
+
+typedef Elf32_Addr Elf_Addr;
+typedef Elf32_Dyn Elf_Dyn;
+typedef Elf32_Word Elf_Word;
+typedef Elf32_Off Elf_Off;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Word Elf_Bword;
+
+#endif // I386_MODULE_H_
diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
index ea11a88f..02778fbf 100644
--- a/com32/include/sys/module.h
+++ b/com32/include/sys/module.h
@@ -4,7 +4,6 @@
* Dynamic ELF modules definitions and services.
*/
-
#ifndef MODULE_H_
#define MODULE_H_
@@ -15,6 +14,14 @@
#include <stdbool.h>
#include <linux/list.h>
+#if __SIZEOF_POINTER__ == 4
+#include <i386/module.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/module.h>
+#else
+#error "unsupported architecture"
+#endif
+
/*
* The maximum length of the module file name (including path), stored
* in the struct module descriptor.
@@ -91,26 +98,26 @@ struct elf_module {
module_main_t main_func; // The main function (for executable modules)
void *module_addr; // The module location in the memory
- Elf32_Addr base_addr; // The base address of the module
- Elf32_Word module_size; // The module size in memory
+ Elf_Addr base_addr; // The base address of the module
+ Elf_Word module_size; // The module size in memory
- Elf32_Word *hash_table; // The symbol hash table
- Elf32_Word *ghash_table; // The GNU style hash table
+ Elf_Word *hash_table; // The symbol hash table
+ Elf_Word *ghash_table; // The GNU style hash table
char *str_table; // The string table
void *sym_table; // The symbol table
void *got; // The Global Offset Table
- Elf32_Dyn *dyn_table; // Dynamic loading information table
+ Elf_Dyn *dyn_table; // Dynamic loading information table
- Elf32_Word strtable_size; // The size of the string table
- Elf32_Word syment_size; // The size of a symbol entry
- Elf32_Word symtable_size; // The size of the symbol table
+ Elf_Word strtable_size; // The size of the string table
+ Elf_Word syment_size; // The size of a symbol entry
+ Elf_Word symtable_size; // The size of the symbol table
union {
// Transient - Data available while the module is loading
struct {
FILE *_file; // The file object of the open file
- Elf32_Off _cr_offset; // The current offset in the open file
+ Elf_Off _cr_offset; // The current offset in the open file
} l;
// Process execution data
@@ -122,7 +129,7 @@ struct elf_module {
// ELF DT_NEEDED entries for this module
int nr_needed;
- Elf32_Word needed[MAX_NR_DEPS];
+ Elf_Word needed[MAX_NR_DEPS];
};
/**
@@ -167,17 +174,6 @@ extern FILE *findpath(char *name);
* This portion is included by the core COM32 module.
*/
-/*
- * Accepted values for various ELF header parameters found in an ELF dynamic
- * object.
- */
-#define MODULE_ELF_CLASS ELFCLASS32 // 32-bit modules
-#define MODULE_ELF_CLASS_SIZE 32 // Size of a word value
-#define MODULE_ELF_DATA ELFDATA2LSB // Word endianess
-#define MODULE_ELF_VERSION EV_CURRENT // Object version
-#define MODULE_ELF_TYPE ET_DYN // Executable type (shared object - .so)
-#define MODULE_ELF_MACHINE EM_386 // Target architecture
-
/**
* Names of symbols with special meaning (treated as special cases at linking)
*/
@@ -255,7 +251,7 @@ extern int module_load(struct elf_module *module);
* Its current use is to describe the root COM32 module to the rest of the
* module subsystem.
*/
-extern int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr);
+extern int module_load_shallow(struct elf_module *module, Elf_Addr base_addr);
/**
* module_unload - unloads the module from the system.
@@ -329,7 +325,7 @@ extern struct elf_module *module_find(const char *name);
* If the symbol is found, a pointer to its descriptor structure is returned, and
* NULL otherwise.
*/
-extern Elf32_Sym *module_find_symbol(const char *name, struct elf_module *module);
+extern Elf_Sym *module_find_symbol(const char *name, struct elf_module *module);
/**
* global_find_symbol - searches for a symbol definition in the entire module namespace.
@@ -346,7 +342,7 @@ extern Elf32_Sym *module_find_symbol(const char *name, struct elf_module *module
* a pointer to the symbol descriptor structure. If the module parameter is not NULL,
* it is filled with the address of the module descriptor where the symbol is defined.
*/
-extern Elf32_Sym *global_find_symbol(const char *name, struct elf_module **module);
+extern Elf_Sym *global_find_symbol(const char *name, struct elf_module **module);
/**
* module_get_absolute - converts an memory address relative to a module base address
@@ -356,7 +352,7 @@ extern Elf32_Sym *global_find_symbol(const char *name, struct elf_module **modul
*
* The function returns a pointer to the absolute memory address.
*/
-static inline void *module_get_absolute(Elf32_Addr addr, struct elf_module *module) {
+static inline void *module_get_absolute(Elf_Addr addr, struct elf_module *module) {
return (void*)(module->base_addr + addr);
}
diff --git a/com32/include/sys/x86_64/bitops.h b/com32/include/sys/x86_64/bitops.h
new file mode 100644
index 00000000..7b1cc2b6
--- /dev/null
+++ b/com32/include/sys/x86_64/bitops.h
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010-2011 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bitops.h - i386
+ *
+ * Simple bitwise operations
+ */
+
+static inline void set_bit(long __bit, void *__bitmap)
+{
+ asm volatile("bts %1,%0"
+ : "+m" (*(unsigned char *)__bitmap)
+ : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+ asm volatile("btcl %1,%0"
+ : "+m" (*(unsigned char *)__bitmap)
+ : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+ unsigned char __r;
+ asm("bt %2,%1; setc %0"
+ : "=qm" (__r)
+ : "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
+ return __r;
+}
diff --git a/com32/include/sys/x86_64/cpu.h b/com32/include/sys/x86_64/cpu.h
new file mode 100644
index 00000000..89d79154
--- /dev/null
+++ b/com32/include/sys/x86_64/cpu.h
@@ -0,0 +1,148 @@
+#ifndef _CPU_X86_64_H
+#define _CPU_X86_64_H
+
+/* x86_64 cpu.h */
+
+static inline uint64_t rdtsc(void)
+{
+ uint64_t v;
+ asm volatile("rdtsc" : "=A" (v));
+ return v;
+}
+
+static inline uint32_t rdtscl(void)
+{
+ uint32_t v;
+ asm volatile("rdtsc" : "=a" (v) : : "edx");
+ return v;
+}
+
+static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ /* ecx is often an input as well as an output. */
+ asm volatile("cpuid"
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (*eax), "2" (*ecx)
+ : "memory");
+}
+/*
+ * Generic CPUID function
+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+ * resulting in stale register contents being returned.
+ */
+static inline void cpuid(uint32_t op,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ *eax = op;
+ *ecx = 0;
+ native_cpuid(eax, ebx, ecx, edx);
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline uint32_t cpuid_eax(uint32_t op)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid(op, &eax, &ebx, &ecx, &edx);
+
+ return eax;
+}
+
+static inline uint32_t cpuid_ebx(uint32_t op)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid(op, &eax, &ebx, &ecx, &edx);
+
+ return ebx;
+}
+
+static inline uint32_t cpuid_ecx(uint32_t op)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid(op, &eax, &ebx, &ecx, &edx);
+
+ return ecx;
+}
+
+static inline uint32_t cpuid_edx(uint32_t op)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid(op, &eax, &ebx, &ecx, &edx);
+
+ return edx;
+}
+
+static inline void cpuid_count(uint32_t op, uint32_t cnt,
+ uint32_t * eax, uint32_t * ebx,
+ uint32_t * ecx, uint32_t * edx)
+{
+ asm volatile("movl %%ebx,%1 ; "
+ "cpuid ; "
+ "xchgl %1,%%ebx"
+ : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "a"(op), "c"(cnt));
+}
+
+/* Standard macro to see if a specific flag is changeable */
+static inline __constfunc bool cpu_has_eflag(uint32_t flag)
+{
+ /* x86_64 */
+ uint64_t f0, f1;
+ asm("pushf ; "
+ "pushf ; "
+ "pop %0 ; "
+ "mov %0,%1 ; "
+ "xor %2,%1 ; "
+ "push %1 ; "
+ "popf ; "
+ "pushf ; "
+ "pop %1 ; "
+ "popf"
+ : "=&r" (f0), "=&r" (f1)
+ : "ri" (flag));
+ return !!((f0^f1) & flag);
+}
+
+static inline uint64_t rdmsr(uint32_t msr)
+{
+ uint64_t v;
+
+ asm volatile("rdmsr" : "=A" (v) : "c"(msr));
+ return v;
+}
+
+static inline void wrmsr(uint64_t v, uint32_t msr)
+{
+ asm volatile("wrmsr" : : "A" (v), "c" (msr));
+}
+
+static inline void cpu_relax(void)
+{
+ asm volatile("rep ; nop");
+}
+
+static inline void hlt(void)
+{
+ asm volatile("hlt");
+}
+
+static inline void cli(void)
+{
+ asm volatile("cli");
+}
+
+static inline void sti(void)
+{
+ asm volatile("sti");
+}
+#endif
diff --git a/com32/include/sys/x86_64/module.h b/com32/include/sys/x86_64/module.h
new file mode 100644
index 00000000..203a6cd0
--- /dev/null
+++ b/com32/include/sys/x86_64/module.h
@@ -0,0 +1,35 @@
+/**
+ * syslinux/module.h
+ *
+ * Dynamic ELF64 modules definitions and services.
+ */
+
+#ifndef _X86_64_MODULE_H_
+#define _X86_64_MODULE_H_
+
+#include <elf.h>
+
+/*
+ * Accepted values for various ELF header parameters found in an ELF dynamic
+ * object.
+ */
+#define MODULE_ELF_CLASS ELFCLASS64 // 64-bit modules
+#define MODULE_ELF_CLASS_SIZE 64 // Size of a word value
+#define MODULE_ELF_DATA ELFDATA2LSB // Word endianess
+#define MODULE_ELF_VERSION EV_CURRENT // Object version
+#define MODULE_ELF_TYPE ET_DYN // Executable type (shared object - .so)
+#define MODULE_ELF_MACHINE EM_X86_64 // Target architecture
+
+#define ELF_MOD_SYS "64 bit"
+
+typedef Elf64_Addr Elf_Addr;
+typedef Elf64_Dyn Elf_Dyn;
+typedef Elf64_Word Elf_Word;
+typedef Elf64_Off Elf_Off;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Phdr Elf_Phdr;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Xword Elf_Bword;
+
+#endif // _X86_64_MODULE_H_
diff --git a/com32/include/syslinux/firmware.h b/com32/include/syslinux/firmware.h
new file mode 100644
index 00000000..13ba1591
--- /dev/null
+++ b/com32/include/syslinux/firmware.h
@@ -0,0 +1,72 @@
+#ifndef _SYSLINUX_FIRMWARE_H
+#define _SYSLINUX_FIRMWARE_H
+
+#include <syslinux/memscan.h>
+
+struct term_state;
+
+struct output_ops {
+ void (*erase) (int, int, int, int, uint8_t);
+ void (*write_char) (uint8_t, uint8_t);
+ void (*showcursor) (const struct term_state *);
+ void (*scroll_up) (uint8_t, uint8_t, uint8_t);
+ void (*set_cursor) (int, int, bool);
+ void (*beep) (void);
+ void (*get_mode)(int *, int *);
+ void (*set_mode)(uint16_t);
+ void (*get_cursor)(int *, int *);
+};
+
+struct input_ops {
+ char (*getchar)(char *);
+ int (*pollchar)(void);
+};
+
+struct adv_ops {
+ void (*init)(void);
+ int (*write)(void);
+};
+
+struct vesa_info;
+enum vesa_pixel_format;
+struct win_info;
+
+struct vesa_ops {
+ int (*set_mode)(struct vesa_info *, int *, int *, enum vesa_pixel_format *);
+ void (*screencpy)(size_t, const uint32_t *, size_t, struct win_info *);
+ int (*font_query)(uint8_t **);
+};
+
+enum heap;
+struct mem_ops {
+ void *(*malloc)(size_t, enum heap, size_t);
+ void *(*realloc)(void *, size_t);
+ void (*free)(void *);
+ int (*scan_memory)(scan_memory_callback_t, void *);
+};
+
+struct initramfs;
+struct setup_data;
+
+struct firmware {
+ void (*init)(void);
+ void (*adjust_screen)(void);
+ void (*cleanup)(void);
+ struct disk *(*disk_init)(void *);
+ struct output_ops *o_ops;
+ struct input_ops *i_ops;
+ void (*get_serial_console_info)(uint16_t *, uint16_t *, uint16_t *);
+ bool (*ipappend_strings)(char **, int *);
+ struct adv_ops *adv_ops;
+ int (*boot_linux)(void *, size_t, struct initramfs *,
+ struct setup_data *, char *);
+ struct vesa_ops *vesa;
+ struct mem_ops *mem;
+};
+
+extern struct firmware *firmware;
+
+extern void syslinux_register_bios(void);
+extern void init(void);
+
+#endif /* _SYSLINUX_FIRMWARE_H */
diff --git a/com32/include/syslinux/linux.h b/com32/include/syslinux/linux.h
index f5f95fb0..a8c6f2f5 100644
--- a/com32/include/syslinux/linux.h
+++ b/com32/include/syslinux/linux.h
@@ -37,6 +37,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <klibc/compiler.h>
/* A chunk of an initramfs. These are kept as a doubly-linked
circular list with headnode; the headnode is distinguished by
@@ -68,6 +69,87 @@ struct setup_data {
#define SETUP_E820_EXT 1
#define SETUP_DTB 2
+struct linux_header {
+ uint8_t boot_sector_1[0x0020];
+ uint16_t old_cmd_line_magic;
+ uint16_t old_cmd_line_offset;
+ uint8_t boot_sector_2[0x01f1 - 0x0024];
+ uint8_t setup_sects;
+ uint16_t root_flags;
+ uint32_t syssize;
+ uint16_t ram_size;
+ uint16_t vid_mode;
+ uint16_t root_dev;
+ uint16_t boot_flag;
+ uint16_t jump;
+ uint32_t header;
+ uint16_t version;
+ uint32_t realmode_swtch;
+ uint16_t start_sys;
+ uint16_t kernel_version;
+ uint8_t type_of_loader;
+ uint8_t loadflags;
+ uint16_t setup_move_size;
+ uint32_t code32_start;
+ uint32_t ramdisk_image;
+ uint32_t ramdisk_size;
+ uint32_t bootsect_kludge;
+ uint16_t heap_end_ptr;
+ uint16_t pad1;
+ uint32_t cmd_line_ptr;
+ uint32_t initrd_addr_max;
+ uint32_t kernel_alignment;
+ uint8_t relocatable_kernel;
+ uint8_t pad2[3];
+ uint32_t cmdline_max_len;
+ uint32_t hardware_subarch;
+ uint64_t hardware_subarch_data;
+ uint32_t payload_offset;
+ uint32_t payload_length;
+ uint64_t setup_data;
+ uint64_t pref_address;
+ uint32_t init_size;
+} __packed;
+
+struct screen_info {
+ uint8_t orig_x; /* 0x00 */
+ uint8_t orig_y; /* 0x01 */
+ uint16_t ext_mem_k; /* 0x02 */
+ uint16_t orig_video_page; /* 0x04 */
+ uint8_t orig_video_mode; /* 0x06 */
+ uint8_t orig_video_cols; /* 0x07 */
+ uint8_t flags; /* 0x08 */
+ uint8_t unused2; /* 0x09 */
+ uint16_t orig_video_ega_bx;/* 0x0a */
+ uint16_t unused3; /* 0x0c */
+ uint8_t orig_video_lines; /* 0x0e */
+ uint8_t orig_video_isVGA; /* 0x0f */
+ uint16_t orig_video_points;/* 0x10 */
+
+ /* VESA graphic mode -- linear frame buffer */
+ uint16_t lfb_width; /* 0x12 */
+ uint16_t lfb_height; /* 0x14 */
+ uint16_t lfb_depth; /* 0x16 */
+ uint32_t lfb_base; /* 0x18 */
+ uint32_t lfb_size; /* 0x1c */
+ uint16_t cl_magic, cl_offset; /* 0x20 */
+ uint16_t lfb_linelength; /* 0x24 */
+ uint8_t red_size; /* 0x26 */
+ uint8_t red_pos; /* 0x27 */
+ uint8_t green_size; /* 0x28 */
+ uint8_t green_pos; /* 0x29 */
+ uint8_t blue_size; /* 0x2a */
+ uint8_t blue_pos; /* 0x2b */
+ uint8_t rsvd_size; /* 0x2c */
+ uint8_t rsvd_pos; /* 0x2d */
+ uint16_t vesapm_seg; /* 0x2e */
+ uint16_t vesapm_off; /* 0x30 */
+ uint16_t pages; /* 0x32 */
+ uint16_t vesa_attributes; /* 0x34 */
+ uint32_t capabilities; /* 0x36 */
+ uint8_t _reserved[6]; /* 0x3a */
+} __packed;
+
int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
struct initramfs *initramfs,
struct setup_data *setup_data,
@@ -89,6 +171,23 @@ int initramfs_load_file(struct initramfs *ihead, const char *src_filename,
int initramfs_add_trailer(struct initramfs *ihead);
int initramfs_load_archive(struct initramfs *ihead, const char *filename);
+/* Get the combined size of the initramfs */
+static inline uint32_t initramfs_size(struct initramfs *initramfs)
+{
+ struct initramfs *ip;
+ uint32_t size = 0;
+
+ if (!initramfs)
+ return 0;
+
+ for (ip = initramfs->next; ip->len; ip = ip->next) {
+ size = (size + ip->align - 1) & ~(ip->align - 1); /* Alignment */
+ size += ip->len;
+ }
+
+ return size;
+}
+
/* Setup data manipulation functions */
struct setup_data *setup_data_init(void);
diff --git a/com32/include/syslinux/memscan.h b/com32/include/syslinux/memscan.h
index db795439..c3ebf847 100644
--- a/com32/include/syslinux/memscan.h
+++ b/com32/include/syslinux/memscan.h
@@ -34,5 +34,6 @@
typedef int (*scan_memory_callback_t) (void *, addr_t, addr_t, bool);
int syslinux_scan_memory(scan_memory_callback_t callback, void *data);
+int bios_scan_memory(scan_memory_callback_t callback, void *data);
#endif /* _SYSLINUX_MEMSCAN_H */
diff --git a/com32/include/syslinux/version.h b/com32/include/syslinux/version.h
new file mode 100644
index 00000000..762db371
--- /dev/null
+++ b/com32/include/syslinux/version.h
@@ -0,0 +1,6 @@
+#ifndef _SYSLINUX_VERSION_H
+#define _SYSLINUX_VERSION_H
+
+#define __STDC_VERSION__ 200000L
+
+#endif /* _SYSLINUX_VERSION_H */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 84f65c1f..46a53b5c 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -4,8 +4,7 @@
# Include configuration rules
NOGPL := 1
-topdir = ../../
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/lib.mk
## OPTIONAL OBJECTS, AVAILABLE AS DYNAMIC LINKED MODULES
@@ -17,13 +16,6 @@ LIBPNG_OBJS = \
libpng/pngrtran.o libpng/pngwtran.o libpng/pngmem.o \
libpng/pngerror.o libpng/pngpread.o
-# ZIP library object files
-LIBZLIB_OBJS = \
- zlib/adler32.o zlib/compress.o zlib/crc32.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 \
- sys/zfile.o sys/zfopen.o
-
# JPG library object files
LIBJPG_OBJS = \
jpeg/tinyjpeg.o jpeg/jidctflt.o jpeg/decode1.o jpeg/decode3.o \
@@ -33,7 +25,7 @@ LIBJPG_OBJS = \
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 \
+ sys/vesa/alphatbl.o sys/vesa/fmtpixel.o \
sys/vesa/i915resolution.o
LIBMISC_OBJS = \
@@ -51,134 +43,9 @@ LIBSYSLINUX_OBJS = \
syslinux/pxe_dns.o \
syslinux/video/fontquery.o syslinux/video/reportmode.o
-LIBLOAD_OBJS = \
- syslinux/addlist.o syslinux/freelist.o syslinux/memmap.o \
- syslinux/movebits.o syslinux/shuffle.o syslinux/shuffle_pm.o \
- syslinux/shuffle_rm.o syslinux/zonelist.o \
- syslinux/dump_mmap.o syslinux/dump_movelist.o \
- \
- 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/load_linux.o syslinux/initramfs.o \
- syslinux/initramfs_file.o syslinux/initramfs_loadfile.o \
- syslinux/initramfs_archive.o
-
DYNENTRY_OBJS = \
atexit.o onexit.o abort.o
-## CORE OBJECTS, INCLUDED IN THE ROOT COM32 MODULE
-LIBENTRY_OBJS = \
- sys/intcall.o sys/farcall.o sys/cfarcall.o sys/zeroregs.o \
- sys/argv.o sys/sleep.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/openmem.o \
- sys/isatty.o sys/fstat.o \
- \
- dprintf.o vdprintf.o \
- \
- syslinux/idle.o \
- \
- exit.o
-
-LIBMODULE_OBJS = \
- sys/module/common.o sys/module/elf_module.o \
- sys/module/shallow_module.o sys/module/elfutils.o \
- sys/module/exec.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/rawcon_read.o \
- sys/rawcon_write.o \
- sys/null_write.o sys/serial_write.o \
- \
- sys/xserial_write.o \
- \
- sys/ansi.o \
- \
- sys/ansicon_write.o sys/ansiserial_write.o \
- \
- syslinux/serial.o
-
-LIBOTHER_OBJS = \
- atoi.o atol.o atoll.o calloc.o creat.o \
- fgets.o fprintf.o fputc.o \
- putchar.o \
- getopt.o getopt_long.o \
- lrand48.o stack.o memccpy.o memchr.o \
- mempcpy.o memmem.o memmove.o memswap.o \
- perror.o qsort.o seed48.o \
- srand48.o sscanf.o strcasecmp.o strcat.o \
- strerror.o errlist.o \
- strnlen.o \
- strncat.o strndup.o \
- stpncpy.o \
- strntoimax.o strntoumax.o strsep.o strspn.o strstr.o \
- strtoimax.o strtok.o strtol.o strtoll.o strtoul.o strtoull.o \
- strtoumax.o vprintf.o vsprintf.o \
- asprintf.o vasprintf.o \
- vsscanf.o \
- skipspace.o \
- chrreplace.o \
- bufprintf.o \
- inet.o dhcppack.o dhcpunpack.o \
- strreplace.o \
- lstrdup.o \
- \
- suffix_number.o \
- \
- getcwd.o fdopendir.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/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 \
- \
- pci/cfgtype.o pci/scan.o pci/bios.o \
- pci/readb.o pci/readw.o pci/readl.o \
- pci/writeb.o pci/writew.o pci/writel.o \
- \
- sys/x86_init_fpu.o math/pow.o math/strtod.o \
- syslinux/disk.o \
- \
- syslinux/setup_data.o
-
-CORELIBOBJS = \
- memcpy.o memset.o memcmp.o printf.o strncmp.o vfprintf.o \
- strlen.o vsnprintf.o snprintf.o stpcpy.o strcmp.o strdup.o \
- strcpy.o strncpy.o setjmp.o fopen.o fread.o fread2.o puts.o \
- sprintf.o strlcat.o strchr.o strlcpy.o strncasecmp.o ctypes.o \
- fputs.o fwrite2.o fwrite.o fgetc.o fclose.o errno.o lmalloc.o \
- sys/err_read.o sys/err_write.o sys/null_read.o \
- sys/stdcon_write.o \
- syslinux/memscan.o strrchr.o \
- 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 \
- $(LIBENTRY_OBJS) \
- $(LIBMODULE_OBJS)
-
MINLIBOBJS = \
syslinux/ipappend.o \
syslinux/dsinfo.o \
@@ -189,7 +56,6 @@ MINLIBOBJS = \
$(LIBZLIB_OBJS)
# $(LIBVESA_OBJS)
-
DYNLIBOBJS = \
$(LIBZLIB_OBJS) \
$(LIBPNG_OBJS) \
@@ -202,8 +68,7 @@ DYNLIBOBJS = \
$(DYNENTRY_OBJS)
-LIBOBJS = \
- $(DYNLIBOBJS)
+LIBOBJS = $(DYNLIBOBJS)
BINDIR = /usr/bin
LIBDIR = /usr/lib
@@ -212,7 +77,11 @@ AUXDIR = $(DATADIR)/syslinux
INCDIR = /usr/include
COM32DIR = $(AUXDIR)/com32
-all: libcom32.c32 libcom32min.a libcom32core.a
+all: makeoutputdirs libcom32.c32 libcom32min.a libcom32core.a
+
+makeoutputdirs:
+ @mkdir -p $(foreach b, \
+ $(addprefix $(OBJ)/,$(sort $(dir $(LIBOBJS) $(MINLIBOBJS) $(CORELIBOBJS)))),$(b))
libcom32.c32 : $(LIBOBJS)
rm -f $@
@@ -239,11 +108,11 @@ spotless: clean
install: all
mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
- install -m 644 com32.ld $(INSTALLROOT)$(COM32DIR)
+ install -m 644 $(SRC)/com32.ld $(INSTALLROOT)$(COM32DIR)
-rm -rf $(INSTALLROOT)$(COM32DIR)/include
- cp -r ../include $(INSTALLROOT)$(COM32DIR)
+ cp -r $(SRC)/../include $(INSTALLROOT)$(COM32DIR)
-errlist.c: makeerrlist.pl ../include/errno.h
+errlist.c: makeerrlist.pl $(SRC)/../include/errno.h
$(PERL) $< $(CFLAGS) -errlist > $@ || rm -f $@
# These files are performance critical, and doesn't compile well with -Os
diff --git a/com32/lib/i386/elf.ld b/com32/lib/i386/elf.ld
new file mode 100644
index 00000000..fc2e7db5
--- /dev/null
+++ b/com32/lib/i386/elf.ld
@@ -0,0 +1,178 @@
+/*
+ * Linker script for ELF dynamic loaded modules.
+ */
+
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386",
+ "elf32-i386")
+OUTPUT_ARCH(i386)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0 + SIZEOF_HEADERS;
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0x90909090
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0x90909090
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0x90909090
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ . = ALIGN(4);
+ .preinit_array :
+ {
+ KEEP (*(.preinit_array))
+ }
+ .init_array :
+ {
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ }
+ .fini_array :
+ {
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ }
+
+ .ctors :
+ {
+ __ctors_start = .;
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.ctors_modinit))
+ KEEP (*(.ctors_modmain))
+ __ctors_end = .;
+ }
+
+ .dtors :
+ {
+ __dtors_start = .;
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.dtors_modexit))
+ __dtors_end = .;
+ }
+
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got) }
+ /*. = DATA_SEGMENT_RELRO_END (12, .); -> This gives a "invalid assignment to location counter" error */
+ .got.plt : { *(.got.plt) }
+ .data :
+ {
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ PROVIDE (edata = .);
+ PROVIDE (_edata = .);
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
+ }
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ PROVIDE (_end = .);
+ PROVIDE (end = .);
+ /*. = DATA_SEGMENT_END (.); -> This gives a "invalid assignment to location counter" error */
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.eh_frame) }
+}
diff --git a/com32/lib/i386/setjmp.S b/com32/lib/i386/setjmp.S
new file mode 100644
index 00000000..658df485
--- /dev/null
+++ b/com32/lib/i386/setjmp.S
@@ -0,0 +1,63 @@
+/*
+ * arch/i386/setjmp.S
+ *
+ * setjmp/longjmp for the i386 architecture
+ *
+ *
+ *
+ * The jmp_buf is assumed to contain the following, in order:
+ * %ebx
+ * %esp
+ * %ebp
+ * %esi
+ * %edi
+ * <return address>
+ */
+
+ .text
+ .align 4
+
+ .globl _setjmp
+ .type _setjmp, @function
+_setjmp: # gcc 4.0.1 wants this as an alias?
+
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+#ifdef REGPARM
+ movl %eax,%edx
+#else
+ movl 4(%esp),%edx
+#endif
+ popl %ecx # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movl %ebx,(%edx)
+ movl %esp,4(%edx) # Post-return %esp!
+ pushl %ecx # Make the call/return stack happy
+ movl %ebp,8(%edx)
+ movl %esi,12(%edx)
+ movl %edi,16(%edx)
+ movl %ecx,20(%edx) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+#ifdef REGPARM
+ xchgl %eax,%edx
+#else
+ movl 4(%esp),%edx # jmp_ptr address
+ movl 8(%esp),%eax # Return value
+#endif
+ movl (%edx),%ebx
+ movl 4(%edx),%esp
+ movl 8(%edx),%ebp
+ movl 12(%edx),%esi
+ movl 16(%edx),%edi
+ jmp *20(%edx)
+
+ .size longjmp,.-longjmp
diff --git a/com32/lib/libgcc/__muldi3.S b/com32/lib/libgcc/__muldi3.S
index 648a88ad..424787c8 100644
--- a/com32/lib/libgcc/__muldi3.S
+++ b/com32/lib/libgcc/__muldi3.S
@@ -9,6 +9,8 @@
.globl __muldi3
.type __muldi3,@function
__muldi3:
+#if __SIZEOF_POINTER__ == 4
+ /* i386 */
push %esi
#ifndef REGPARM
movl 8(%esp),%eax
@@ -31,4 +33,51 @@ __muldi3:
#endif
pop %esi
ret
+#elif __SIZEOF_POINTER__ == 8
+ /* x86_64 */
+ push %rsi
+#ifndef REGPARM
+/*
+ movl 8(%esp),%eax
+ movl %eax,%esi
+ movl 16(%esp),%ecx
+ mull %ecx
+ imull 12(%esp),%ecx
+ imull 20(%esp),%esi
+ addl %ecx,%edx
+ addl %esi,%edx
+*/
+ movq 8(%rsp),%rax
+ movq %rax,%rsi
+ movq 16(%rsp),%rcx
+ mulq %rcx
+ imulq 12(%rsp),%rcx
+ imulq 20(%rsp),%rsi
+ addq %rcx,%rdx
+ addq %rsi,%rdx
+#else
+/*
+ movl %eax,%esi
+ push %edx
+ mull %ecx
+ imull 8(%esp),%esi
+ addl %esi,%edx
+ pop %rsi
+ imull %esi,%ecx
+ addl %ecx,%edx
+*/
+ movq %rax,%rsi
+ pushq %rdx
+ mulq %rcx
+ imulq 8(%rsp),%rsi
+ addq %rsi,%rdx
+ popq %rsi
+ imulq %rsi,%rcx
+ addq %rcx,%rdx
+#endif
+ pop %rsi
+ ret
+#else
+#error "Unsupported architecture for __muldi3.S"
+#endif
.size __muldi3,.-__muldi3
diff --git a/com32/lib/memcpy.S b/com32/lib/memcpy.S
index 6b986a0d..9b5306dd 100644
--- a/com32/lib/memcpy.S
+++ b/com32/lib/memcpy.S
@@ -36,6 +36,10 @@
.globl memcpy
.type memcpy, @function
memcpy:
+ movl 0xc(%esp),%ecx
+ movl 0x8(%esp),%edx
+ movl 0x4(%esp),%eax
+
jecxz 1f
pushl %esi
diff --git a/com32/lib/memcpy.c b/com32/lib/memcpy.c
new file mode 100644
index 00000000..5ce206d0
--- /dev/null
+++ b/com32/lib/memcpy.c
@@ -0,0 +1,29 @@
+/*
+ * memcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memcpy(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile ("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb":"+c" (nl),
+ "+S"(p), "+D"(q)
+ :"r"(n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile ("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb":"+c"
+ (nq), "+S"(p), "+D"(q)
+ :"r"((uint32_t) (n & 7)));
+#else
+ while (n--) {
+ *q++ = *p++;
+ }
+#endif
+
+ return dst;
+}
diff --git a/com32/lib/memmove.S b/com32/lib/memmove.S
index e97299f2..2094e4aa 100644
--- a/com32/lib/memmove.S
+++ b/com32/lib/memmove.S
@@ -37,6 +37,10 @@
.type memmove,@function
.text
memmove:
+ movl 0xc(%esp),%ecx
+ movl 0x8(%esp),%edx
+ movl 0x4(%esp),%eax
+
jecxz 4f
pushl %esi
diff --git a/com32/lib/memmove.c b/com32/lib/memmove.c
new file mode 100644
index 00000000..a398cd8d
--- /dev/null
+++ b/com32/lib/memmove.c
@@ -0,0 +1,36 @@
+/*
+ * memmove.c
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__) || defined(__x86_64__)
+ if (q < p) {
+ asm volatile("cld; rep; movsb"
+ : "+c" (n), "+S"(p), "+D"(q));
+ } else {
+ p += (n - 1);
+ q += (n - 1);
+ asm volatile("std; rep; movsb; cld"
+ : "+c" (n), "+S"(p), "+D"(q));
+ }
+#else
+ if (q < p) {
+ while (n--) {
+ *q++ = *p++;
+ }
+ } else {
+ p += n;
+ q += n;
+ while (n--) {
+ *--q = *--p;
+ }
+ }
+#endif
+
+ return dst;
+}
diff --git a/com32/lib/mempcpy.S b/com32/lib/mempcpy.S
index cad7b983..2096f132 100644
--- a/com32/lib/mempcpy.S
+++ b/com32/lib/mempcpy.S
@@ -36,6 +36,10 @@
.globl mempcpy
.type mempcpy, @function
mempcpy:
+ movl 0xc(%esp),%ecx
+ movl 0x8(%esp),%edx
+ movl 0x4(%esp),%eax
+
jecxz 1f
pushl %esi
diff --git a/com32/lib/mempcpy.c b/com32/lib/mempcpy.c
new file mode 100644
index 00000000..be23b667
--- /dev/null
+++ b/com32/lib/mempcpy.c
@@ -0,0 +1,14 @@
+/*
+ * mempcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+/* simply a wrapper around memcpy implementation */
+
+void *mempcpy(void *dst, const void *src, size_t n)
+{
+
+ return (char *)memcpy(dst, src, n) + n;
+}
diff --git a/com32/lib/memset.S b/com32/lib/memset.S
index e641415d..fd42842a 100644
--- a/com32/lib/memset.S
+++ b/com32/lib/memset.S
@@ -36,6 +36,10 @@
.type memset,@function
.text
memset:
+ movl 0xc(%esp),%ecx
+ movl 0x8(%esp),%edx
+ movl 0x4(%esp),%eax
+
jecxz 6f
pushl %edi
diff --git a/com32/lib/memset.c b/com32/lib/memset.c
new file mode 100644
index 00000000..aa00b5b1
--- /dev/null
+++ b/com32/lib/memset.c
@@ -0,0 +1,30 @@
+/*
+ * memset.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dst, int c, size_t n)
+{
+ char *q = dst;
+
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile ("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb"
+ : "+c" (nl), "+D" (q)
+ : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile ("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb"
+ :"+c" (nq), "+D" (q)
+ : "a" ((unsigned char)c * 0x0101010101010101U),
+ "r" ((uint32_t) n & 7));
+#else
+ while (n--) {
+ *q++ = c;
+ }
+#endif
+
+ return dst;
+}
diff --git a/com32/lib/setjmp.S b/com32/lib/setjmp.S
index 658df485..2fb5c234 100644
--- a/com32/lib/setjmp.S
+++ b/com32/lib/setjmp.S
@@ -13,7 +13,7 @@
* %edi
* <return address>
*/
-
+/*
.text
.align 4
@@ -61,3 +61,12 @@ longjmp:
jmp *20(%edx)
.size longjmp,.-longjmp
+*/
+#if __SIZEOF_POINTER__ == 4
+#include <i386/setjmp.S>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/setjmp.S>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c
index e5483fbc..74add717 100644
--- a/com32/lib/sys/ansicon_write.c
+++ b/com32/lib/sys/ansicon_write.c
@@ -35,13 +35,13 @@
#include <errno.h>
#include <string.h>
-#include <com32.h>
#include <minmax.h>
#include <colortbl.h>
#include <klibc/compiler.h>
#include <syslinux/config.h>
#include "file.h"
#include "ansi.h"
+#include <syslinux/firmware.h>
#include "graphics.h"
static void ansicon_erase(const struct term_state *, int, int, int, int);
@@ -66,23 +66,15 @@ static struct term_info ti = {
.op = &__ansicon_ops
};
-#define BIOS_CURXY ((struct curxy *)0x450) /* Array for each page */
-#define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */
-#define BIOS_COLS (*(uint16_t *)0x44A)
-#define BIOS_PAGE (*(uint8_t *)0x462)
+#define TEXT_MODE 0x0005
/* Reference counter to the screen, to keep track of if we need
reinitialization. */
static int ansicon_counter = 0;
-static uint16_t cursor_type; /* Saved cursor pattern */
-
/* Common setup */
int __ansicon_open(struct file_info *fp)
{
- static com32sys_t ireg; /* Auto-initalized to all zero */
- com32sys_t oreg;
-
if (!ansicon_counter) {
/* Are we disabled? */
if (syslinux_serial_console_info()->flowctl & 0x8000) {
@@ -91,20 +83,14 @@ int __ansicon_open(struct file_info *fp)
ti.cols = 80;
} else {
/* Force text mode */
- syslinux_force_text_mode();
+ firmware->o_ops->set_mode(TEXT_MODE);
/* Initial state */
- ti.rows = BIOS_ROWS ? BIOS_ROWS + 1 : 25;
- ti.cols = BIOS_COLS;
+ firmware->o_ops->get_mode(&ti.cols, &ti.rows);
__ansi_init(&ti);
/* Get cursor shape and position */
- ireg.eax.b[1] = 0x03;
- ireg.ebx.b[1] = BIOS_PAGE;
- __intcall(0x10, &ireg, &oreg);
- cursor_type = oreg.ecx.w[0];
- ti.ts->xy.x = oreg.edx.b[0];
- ti.ts->xy.y = oreg.edx.b[1];
+ firmware->o_ops->get_cursor(&ti.ts->xy.x, &ti.ts->xy.y);
}
}
@@ -155,69 +141,45 @@ static uint8_t ansicon_attribute(const struct term_state *st)
static void ansicon_erase(const struct term_state *st,
int x0, int y0, int x1, int y1)
{
- static com32sys_t ireg;
-
- ireg.eax.w[0] = 0x0600; /* Clear window */
- ireg.ebx.b[1] = ansicon_attribute(st);
- ireg.ecx.b[0] = x0;
- ireg.ecx.b[1] = y0;
- ireg.edx.b[0] = x1;
- ireg.edx.b[1] = y1;
- __intcall(0x10, &ireg, NULL);
+ uint8_t attribute = ansicon_attribute(st);
+
+ if (firmware->o_ops->erase)
+ firmware->o_ops->erase(x0, y0, x1, y1, attribute);
}
/* Show or hide the cursor */
static void ansicon_showcursor(const struct term_state *st)
{
- static com32sys_t ireg;
-
- ireg.eax.b[1] = 0x01;
- ireg.ecx.w[0] = st->cursor ? cursor_type : 0x2020;
- __intcall(0x10, &ireg, NULL);
+ firmware->o_ops->showcursor(st);
}
static void ansicon_set_cursor(int x, int y, bool visible)
{
- const int page = BIOS_PAGE;
- struct curxy xy = BIOS_CURXY[page];
- static com32sys_t ireg;
-
- (void)visible;
-
- if (xy.x != x || xy.y != y) {
- ireg.eax.b[1] = 0x02;
- ireg.ebx.b[1] = page;
- ireg.edx.b[1] = y;
- ireg.edx.b[0] = x;
- __intcall(0x10, &ireg, NULL);
- }
+ firmware->o_ops->set_cursor(x, y, visible);
}
static void ansicon_write_char(int x, int y, uint8_t ch,
const struct term_state *st)
{
- static com32sys_t ireg;
-
+ uint8_t attribute = ansicon_attribute(st);
ansicon_set_cursor(x, y, false);
- ireg.eax.b[1] = 0x09;
- ireg.eax.b[0] = ch;
- ireg.ebx.b[1] = BIOS_PAGE;
- ireg.ebx.b[0] = ansicon_attribute(st);
- ireg.ecx.w[0] = 1;
- __intcall(0x10, &ireg, NULL);
+ firmware->o_ops->write_char(ch, attribute);
}
static void ansicon_scroll_up(const struct term_state *st)
{
- static com32sys_t ireg;
-
- ireg.eax.w[0] = 0x0601;
- ireg.ebx.b[1] = ansicon_attribute(st);
- ireg.ecx.w[0] = 0;
- ireg.edx.b[1] = ti.rows - 1;
- ireg.edx.b[0] = ti.cols - 1;
- __intcall(0x10, &ireg, NULL); /* Scroll */
+ uint8_t rows, cols, attribute;
+
+ /*
+ * Earlier code set ti.cols to 1 causing console output one char
+ * per line.
+ */
+ cols = 1;
+ rows = ti.rows - 1;
+ attribute = ansicon_attribute(st);
+
+ firmware->o_ops->scroll_up(cols, rows, attribute);
}
ssize_t __ansicon_write(struct file_info *fp, const void *buf, size_t count)
@@ -240,11 +202,8 @@ ssize_t __ansicon_write(struct file_info *fp, const void *buf, size_t count)
void __ansicon_beep(void)
{
- static com32sys_t ireg;
-
- ireg.eax.w[0] = 0x0e07;
- ireg.ebx.b[1] = BIOS_PAGE;
- __intcall(0x10, &ireg, NULL);
+ if (firmware->o_ops->beep)
+ firmware->o_ops->beep();
}
const struct output_dev dev_ansicon_w = {
diff --git a/com32/lib/sys/farcall.c b/com32/lib/sys/farcall.c
index 988ee6d2..2749083e 100644
--- a/com32/lib/sys/farcall.c
+++ b/com32/lib/sys/farcall.c
@@ -6,9 +6,17 @@
static inline uint32_t eflags(void)
{
- uint32_t v;
+ //uint32_t v;
+#if __SIZEOF_POINTER__ == 4
+ uint32_t v;
asm volatile("pushfl ; popl %0" : "=rm" (v));
+#elif __SIZEOF_POINTER__ == 8
+ uint64_t v;
+ asm volatile("pushfq ; pop %0" : "=rm" (v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
return v;
}
diff --git a/com32/lib/sys/i386/x86_init_fpu.c b/com32/lib/sys/i386/x86_init_fpu.c
new file mode 100644
index 00000000..cf336932
--- /dev/null
+++ b/com32/lib/sys/i386/x86_init_fpu.c
@@ -0,0 +1,58 @@
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+ uint32_t v;
+asm("movl %%cr0,%0":"=r"(v));
+ return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+ asm volatile ("movl %0,%%cr0"::"r" (v));
+}
+
+#define CR0_PE 0x00000001
+#define CR0_MP 0x00000002
+#define CR0_EM 0x00000004
+#define CR0_TS 0x00000008
+#define CR0_ET 0x00000010
+#define CR0_NE 0x00000020
+#define CR0_WP 0x00010000
+#define CR0_AM 0x00040000
+#define CR0_NW 0x20000000
+#define CR0_CD 0x40000000
+#define CR0_PG 0x80000000
+
+int x86_init_fpu(void)
+{
+ uint32_t cr0;
+ uint16_t fsw = 0xffff;
+ uint16_t fcw = 0xffff;
+
+ cr0 = get_cr0();
+ cr0 &= ~(CR0_EM | CR0_TS);
+ cr0 |= CR0_MP;
+ set_cr0(cr0);
+
+ asm volatile ("fninit");
+ asm volatile ("fnstsw %0":"+m" (fsw));
+ if (fsw != 0)
+ return -1;
+
+ asm volatile ("fnstcw %0":"+m" (fcw));
+ if ((fcw & 0x103f) != 0x3f)
+ return -1;
+
+ /* Techically, this could be a 386 with a 287. We could add a check
+ for that here... */
+
+ return 0;
+}
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index d72dd702..5b0d9ee8 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -23,7 +23,7 @@ LIST_HEAD(modules_head);
// User-space debugging routines
#ifdef ELF_DEBUG
-void print_elf_ehdr(Elf32_Ehdr *ehdr) {
+void print_elf_ehdr(Elf_Ehdr *ehdr) {
int i;
fprintf(stderr, "Identification:\t");
@@ -38,18 +38,18 @@ void print_elf_ehdr(Elf32_Ehdr *ehdr) {
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));
+ //fprintf(stderr, "Header size:\t%u (Structure size: %u)\n", ehdr->e_ehsize,sizeof(Elf_Ehdr));
fprintf(stderr, "phnum: %d shnum: %d\n", ehdr->e_phnum,
ehdr->e_shnum);
}
void print_elf_symbols(struct elf_module *module) {
unsigned int i;
- Elf32_Sym *crt_sym;
+ Elf_Sym *crt_sym;
for (i = 1; i < module->symtable_size/module->syment_size; i++)
{
- crt_sym = (Elf32_Sym*)(module->sym_table + i*module->syment_size);
+ crt_sym = (Elf_Sym*)(module->sym_table + i*module->syment_size);
fprintf(stderr,"%s %d\n", module->str_table + crt_sym->st_name, crt_sym->st_value);
@@ -163,7 +163,7 @@ int image_skip(size_t size, struct elf_module *module) {
return 0;
}
-int image_seek(Elf32_Off offset, struct elf_module *module) {
+int image_seek(Elf_Off offset, struct elf_module *module) {
if (offset < module->u.l._cr_offset) // Cannot seek backwards
return -1;
@@ -218,9 +218,14 @@ struct elf_module *module_find(const char *name) {
}
+// Mouli: This is checking the header for 32bit machine
+// Support 64bit architecture as well.
+// Parts of the ELF header checked are common to both ELF32 and ELF64
+// Adding simple checks for both 32bit and 64bit should work (hopefully)
+//
// Performs verifications on ELF header to assure that the open file is a
// valid SYSLINUX ELF module.
-int check_header_common(Elf32_Ehdr *elf_hdr) {
+int check_header_common(Elf_Ehdr *elf_hdr) {
// Check the header magic
if (elf_hdr->e_ident[EI_MAG0] != ELFMAG0 ||
elf_hdr->e_ident[EI_MAG1] != ELFMAG1 ||
@@ -231,7 +236,8 @@ int check_header_common(Elf32_Ehdr *elf_hdr) {
return -1;
}
- if (elf_hdr->e_ident[EI_CLASS] != MODULE_ELF_CLASS) {
+ if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32 &&
+ elf_hdr->e_ident[EI_CLASS] != ELFCLASS64) {
DBG_PRINT("Invalid ELF class code\n");
return -1;
}
@@ -247,7 +253,8 @@ int check_header_common(Elf32_Ehdr *elf_hdr) {
return -1;
}
- if (elf_hdr->e_machine != MODULE_ELF_MACHINE) {
+ if (elf_hdr->e_machine != EM_386 &&
+ elf_hdr->e_machine != EM_X86_64) {
DBG_PRINT("Invalid ELF architecture\n");
return -1;
}
@@ -256,6 +263,7 @@ int check_header_common(Elf32_Ehdr *elf_hdr) {
}
+
int enforce_dependency(struct elf_module *req, struct elf_module *dep) {
struct module_dep *crt_dep;
struct module_dep *new_dep;
@@ -312,7 +320,7 @@ int clear_dependency(struct elf_module *req, struct elf_module *dep) {
int check_symbols(struct elf_module *module)
{
unsigned int i;
- Elf32_Sym *crt_sym = NULL, *ref_sym = NULL;
+ Elf_Sym *crt_sym = NULL, *ref_sym = NULL;
char *crt_name;
struct elf_module *crt_module;
@@ -360,7 +368,6 @@ int check_symbols(struct elf_module *module)
if (strong_count == 0 && weak_count == 0)
{
DBG_PRINT("Symbol %s is undefined\n", crt_name);
- printf("Undef symbol FAIL: %s\n",crt_name);
return -1;
}
}
@@ -420,7 +427,7 @@ int _module_unload(struct elf_module *module) {
int module_unload(struct elf_module *module) {
module_ctor_t *dtor;
- for (dtor = module->dtors; *dtor; dtor++)
+ for (dtor = module->dtors; dtor && *dtor; dtor++)
(*dtor) ();
return _module_unload(module);
@@ -450,18 +457,18 @@ struct elf_module *unload_modules_since(const char *name) {
return begin;
}
-static Elf32_Sym *module_find_symbol_sysv(const char *name, struct elf_module *module) {
+static Elf_Sym *module_find_symbol_sysv(const char *name, struct elf_module *module) {
unsigned long h = elf_hash((const unsigned char*)name);
- Elf32_Word *cr_word = module->hash_table;
+ Elf_Word *cr_word = module->hash_table;
- Elf32_Word nbucket = *cr_word++;
+ Elf_Word nbucket = *cr_word++;
cr_word++; // Skip nchain
- Elf32_Word *bkt = cr_word;
- Elf32_Word *chn = cr_word + nbucket;
+ Elf_Word *bkt = cr_word;
+ Elf_Word *chn = cr_word + nbucket;
- Elf32_Word crt_index = bkt[h % module->hash_table[0]];
- Elf32_Sym *crt_sym;
+ Elf_Word crt_index = bkt[h % module->hash_table[0]];
+ Elf_Sym *crt_sym;
while (crt_index != STN_UNDEF) {
@@ -476,32 +483,32 @@ static Elf32_Sym *module_find_symbol_sysv(const char *name, struct elf_module *m
return NULL;
}
-static Elf32_Sym *module_find_symbol_gnu(const char *name, struct elf_module *module) {
+static Elf_Sym *module_find_symbol_gnu(const char *name, struct elf_module *module) {
unsigned long h = elf_gnu_hash((const unsigned char*)name);
// Setup code (TODO: Optimize this by computing only once)
- Elf32_Word *cr_word = module->ghash_table;
- Elf32_Word nbucket = *cr_word++;
- Elf32_Word symbias = *cr_word++;
- Elf32_Word bitmask_nwords = *cr_word++;
+ Elf_Word *cr_word = module->ghash_table;
+ Elf_Word nbucket = *cr_word++;
+ Elf_Word symbias = *cr_word++;
+ Elf_Word bitmask_nwords = *cr_word++;
if ((bitmask_nwords & (bitmask_nwords - 1)) != 0) {
DBG_PRINT("Invalid GNU Hash structure\n");
return NULL;
}
- Elf32_Word gnu_shift = *cr_word++;
+ Elf_Word gnu_shift = *cr_word++;
- Elf32_Addr *gnu_bitmask = (Elf32_Addr*)cr_word;
+ Elf_Addr *gnu_bitmask = (Elf_Addr*)cr_word;
cr_word += MODULE_ELF_CLASS_SIZE / 32 * bitmask_nwords;
- Elf32_Word *gnu_buckets = cr_word;
+ Elf_Word *gnu_buckets = cr_word;
cr_word += nbucket;
- Elf32_Word *gnu_chain_zero = cr_word - symbias;
+ Elf_Word *gnu_chain_zero = cr_word - symbias;
// Computations
- Elf32_Word bitmask_word = gnu_bitmask[(h / MODULE_ELF_CLASS_SIZE) &
+ Elf_Bword bitmask_word = gnu_bitmask[(h / MODULE_ELF_CLASS_SIZE) &
(bitmask_nwords - 1)];
unsigned int hashbit1 = h & (MODULE_ELF_CLASS_SIZE - 1);
@@ -509,18 +516,18 @@ static Elf32_Sym *module_find_symbol_gnu(const char *name, struct elf_module *mo
if ((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1) {
unsigned long rem;
- Elf32_Word bucket;
+ Elf_Word bucket;
rem = h % nbucket;
bucket = gnu_buckets[rem];
if (bucket != 0) {
- const Elf32_Word* hasharr = &gnu_chain_zero[bucket];
+ const Elf_Word* hasharr = &gnu_chain_zero[bucket];
do {
if (((*hasharr ^ h ) >> 1) == 0) {
- Elf32_Sym *crt_sym = symbol_get_entry(module, (hasharr - gnu_chain_zero));
+ Elf_Sym *crt_sym = symbol_get_entry(module, (hasharr - gnu_chain_zero));
if (strcmp(name, module->str_table + crt_sym->st_name) == 0) {
return crt_sym;
@@ -533,11 +540,11 @@ static Elf32_Sym *module_find_symbol_gnu(const char *name, struct elf_module *mo
return NULL;
}
-static Elf32_Sym *module_find_symbol_iterate(const char *name,struct elf_module *module)
+static Elf_Sym *module_find_symbol_iterate(const char *name,struct elf_module *module)
{
unsigned int i;
- Elf32_Sym *crt_sym;
+ Elf_Sym *crt_sym;
for (i = 1; i < module->symtable_size/module->syment_size; i++)
{
@@ -551,8 +558,8 @@ static Elf32_Sym *module_find_symbol_iterate(const char *name,struct elf_module
return NULL;
}
-Elf32_Sym *module_find_symbol(const char *name, struct elf_module *module) {
- Elf32_Sym *result = NULL;
+Elf_Sym *module_find_symbol(const char *name, struct elf_module *module) {
+ Elf_Sym *result = NULL;
if (module->ghash_table != NULL)
result = module_find_symbol_gnu(name, module);
@@ -574,10 +581,10 @@ Elf32_Sym *module_find_symbol(const char *name, struct elf_module *module) {
return result;
}
-Elf32_Sym *global_find_symbol(const char *name, struct elf_module **module) {
+Elf_Sym *global_find_symbol(const char *name, struct elf_module **module) {
struct elf_module *crt_module;
- Elf32_Sym *crt_sym = NULL;
- Elf32_Sym *result = NULL;
+ Elf_Sym *crt_sym = NULL;
+ Elf_Sym *result = NULL;
for_each_module(crt_module) {
crt_sym = module_find_symbol(name, crt_module);
diff --git a/com32/lib/sys/module/common.h b/com32/lib/sys/module/common.h
index 54f0ec4b..652c9735 100644
--- a/com32/lib/sys/module/common.h
+++ b/com32/lib/sys/module/common.h
@@ -15,7 +15,6 @@
#include "elfutils.h"
-
// Performs an operation and jumps to a given label if an error occurs
#define CHECKED(res, expr, error) \
do { \
@@ -27,12 +26,12 @@
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
-static inline Elf32_Sym *symbol_get_entry(struct elf_module *module, int entry)
+static inline Elf_Sym *symbol_get_entry(struct elf_module *module, int entry)
{
char *sym_table = (char *)module->sym_table;
int index = entry * module->syment_size;
- return (Elf32_Sym *)(sym_table + index);
+ return (Elf_Sym *)(sym_table + index);
}
//#define ELF_DEBUG
@@ -45,7 +44,7 @@ static inline Elf32_Sym *symbol_get_entry(struct elf_module *module, int entry)
// User-space debugging routines
#ifdef ELF_DEBUG
-extern void print_elf_ehdr(Elf32_Ehdr *ehdr);
+extern void print_elf_ehdr(Elf_Ehdr *ehdr);
extern void print_elf_symbols(struct elf_module *module);
#endif //ELF_DEBUG
@@ -58,11 +57,11 @@ extern int image_load(struct elf_module *module);
extern int image_unload(struct elf_module *module);
extern int image_read(void *buff, size_t size, struct elf_module *module);
extern int image_skip(size_t size, struct elf_module *module);
-extern int image_seek(Elf32_Off offset, struct elf_module *module);
+extern int image_seek(Elf_Off offset, struct elf_module *module);
extern struct module_dep *module_dep_alloc(struct elf_module *module);
-extern int check_header_common(Elf32_Ehdr *elf_hdr);
+extern int check_header_common(Elf_Ehdr *elf_hdr);
extern int enforce_dependency(struct elf_module *req, struct elf_module *dep);
extern int clear_dependency(struct elf_module *req, struct elf_module *dep);
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 24da2209..0d27c92b 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -20,7 +20,7 @@
#include "elfutils.h"
#include "common.h"
-static int check_header(Elf32_Ehdr *elf_hdr) {
+static int check_header(Elf_Ehdr *elf_hdr) {
int res;
res = check_header_common(elf_hdr);
@@ -47,162 +47,10 @@ static int check_header(Elf32_Ehdr *elf_hdr) {
* in the PHT sorted by their offsets, so that only forward seeks would
* be necessary.
*/
-static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
- int i;
- int res = 0;
- char *pht = NULL;
- char *sht = NULL;
- Elf32_Phdr *cr_pht;
- Elf32_Shdr *cr_sht;
-
- Elf32_Addr min_addr = 0x00000000; // Min. ELF vaddr
- Elf32_Addr max_addr = 0x00000000; // Max. ELF vaddr
- Elf32_Word max_align = sizeof(void*); // Min. align of posix_memalign()
- Elf32_Addr min_alloc, max_alloc; // Min. and max. aligned allocables
-
- Elf32_Addr dyn_addr = 0x00000000;
-
- // Get to the PHT
- image_seek(elf_hdr->e_phoff, module);
-
- // Load the PHT
- pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
- image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
-
- // Compute the memory needings of the module
- for (i=0; i < elf_hdr->e_phnum; i++) {
- cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
-
- switch (cr_pht->p_type) {
- case PT_LOAD:
- if (i == 0) {
- min_addr = cr_pht->p_vaddr;
- } else {
- min_addr = MIN(min_addr, cr_pht->p_vaddr);
- }
-
- max_addr = MAX(max_addr, cr_pht->p_vaddr + cr_pht->p_memsz);
- max_align = MAX(max_align, cr_pht->p_align);
- break;
- case PT_DYNAMIC:
- dyn_addr = cr_pht->p_vaddr;
- break;
- default:
- // Unsupported - ignore
- break;
- }
- }
-
- if (max_addr - min_addr == 0) {
- // No loadable segments
- DBG_PRINT("No loadable segments found\n");
- goto out;
- }
-
- if (dyn_addr == 0) {
- DBG_PRINT("No dynamic information segment found\n");
- goto out;
- }
-
- // The minimum address that should be allocated
- min_alloc = min_addr - (min_addr % max_align);
-
- // The maximum address that should be allocated
- max_alloc = max_addr - (max_addr % max_align);
- if (max_addr % max_align > 0)
- max_alloc += max_align;
-
-
- if (elf_malloc(&module->module_addr,
- max_align,
- max_alloc-min_alloc) != 0) {
-
- DBG_PRINT("Could not allocate segments\n");
- goto out;
- }
-
- module->base_addr = (Elf32_Addr)(module->module_addr) - min_alloc;
- module->module_size = max_alloc - min_alloc;
-
- // Zero-initialize the memory
- memset(module->module_addr, 0, module->module_size);
-
- for (i = 0; i < elf_hdr->e_phnum; i++) {
- cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
-
- if (cr_pht->p_type == PT_LOAD) {
- // Copy the segment at its destination
- if (cr_pht->p_offset < module->u.l._cr_offset) {
- // The segment contains data before the current offset
- // It can be discarded without worry - it would contain only
- // headers
- Elf32_Off aux_off = module->u.l._cr_offset - cr_pht->p_offset;
-
- if (image_read((char *)module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
- cr_pht->p_filesz - aux_off, module) < 0) {
- res = -1;
- goto out;
- }
- } else {
- if (image_seek(cr_pht->p_offset, module) < 0) {
- res = -1;
- goto out;
- }
-
- if (image_read(module_get_absolute(cr_pht->p_vaddr, module),
- cr_pht->p_filesz, module) < 0) {
- res = -1;
- goto out;
- }
- }
-
- /*
- 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));
- */
- }
- }
-
- // Get to the SHT
- image_seek(elf_hdr->e_shoff, module);
-
- // Load the SHT
- sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
- image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
-
- // Setup the symtable size
- for (i = 0; i < elf_hdr->e_shnum; i++) {
- cr_sht = (Elf32_Shdr*)(sht + i * elf_hdr->e_shentsize);
-
- if (cr_sht->sh_type == SHT_DYNSYM) {
- module->symtable_size = cr_sht->sh_size;
- break;
- }
- }
-
- free(sht);
-
- // Setup dynamic segment location
- module->dyn_table = module_get_absolute(dyn_addr, module);
-
- /*
- DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr,
- max_align);
- DBG_PRINT("Module size: 0x%08x\n", module->module_size);
- */
-
-out:
- // Free up allocated memory
- if (pht != NULL)
- free(pht);
-
- return res;
-}
+extern int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr);
static int prepare_dynlinking(struct elf_module *module) {
- Elf32_Dyn *dyn_entry = module->dyn_table;
+ Elf_Dyn *dyn_entry = module->dyn_table;
while (dyn_entry->d_tag != DT_NULL) {
switch (dyn_entry->d_tag) {
@@ -222,11 +70,11 @@ static int prepare_dynlinking(struct elf_module *module) {
break;
case DT_HASH:
module->hash_table =
- (Elf32_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ (Elf_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
break;
case DT_GNU_HASH:
module->ghash_table =
- (Elf32_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ (Elf_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
break;
case DT_STRTAB:
module->str_table =
@@ -259,168 +107,12 @@ void undefined_symbol(void)
kaboom();
}
-static int perform_relocation(struct elf_module *module, Elf32_Rel *rel) {
- Elf32_Word *dest = module_get_absolute(rel->r_offset, module);
-
- // The symbol reference index
- Elf32_Word sym = ELF32_R_SYM(rel->r_info);
- unsigned char type = ELF32_R_TYPE(rel->r_info);
-
- // The symbol definition (if applicable)
- Elf32_Sym *sym_def = NULL;
- struct elf_module *sym_module = NULL;
- Elf32_Addr sym_addr = 0x0;
-
- if (sym > 0) {
- // Find out details about the symbol
-
- // The symbol reference
- Elf32_Sym *sym_ref = symbol_get_entry(module, sym);
-
- // The symbol definition
- sym_def =
- global_find_symbol(module->str_table + sym_ref->st_name,
- &sym_module);
-
- if (sym_def == NULL) {
- DBG_PRINT("Cannot perform relocation for symbol %s\n",
- module->str_table + sym_ref->st_name);
-
- if (ELF32_ST_BIND(sym_ref->st_info) != STB_WEAK)
- return -1;
-
- // This must be a derivative-specific
- // function. We're OK as long as we never
- // execute the function.
- sym_def = global_find_symbol("undefined_symbol", &sym_module);
- }
-
- // Compute the absolute symbol virtual address
- sym_addr = (Elf32_Addr)module_get_absolute(sym_def->st_value, sym_module);
-
- if (sym_module != module) {
- // Create a dependency
- enforce_dependency(sym_module, module);
- }
- }
-
- switch (type) {
- case R_386_NONE:
- // Do nothing
- break;
- case R_386_32:
- *dest += sym_addr;
- break;
- case R_386_PC32:
- *dest += sym_addr - (Elf32_Addr)dest;
- break;
- case R_386_COPY:
- if (sym_addr > 0) {
- memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
- }
- break;
- case R_386_GLOB_DAT:
- case R_386_JMP_SLOT:
- // Maybe TODO: Keep track of the GOT entries allocations
- *dest = sym_addr;
- break;
- case R_386_RELATIVE:
- *dest += module->base_addr;
- break;
- default:
- DBG_PRINT("Relocation type %d not supported\n", type);
- return -1;
- }
-
- return 0;
-}
-
-static int resolve_symbols(struct elf_module *module) {
- Elf32_Dyn *dyn_entry = module->dyn_table;
- unsigned int i;
- int res;
-
- Elf32_Word plt_rel_size = 0;
- char *plt_rel = NULL;
-
- char *rel = NULL;
- Elf32_Word rel_size = 0;
- Elf32_Word rel_entry = 0;
-
- // The current relocation
- Elf32_Rel *crt_rel;
-
- while (dyn_entry->d_tag != DT_NULL) {
- switch(dyn_entry->d_tag) {
-
- // PLT relocation information
- case DT_PLTRELSZ:
- plt_rel_size = dyn_entry->d_un.d_val;
- break;
- case DT_PLTREL:
- if (dyn_entry->d_un.d_val != DT_REL) {
- DBG_PRINT("Unsupported PLT relocation\n");
- return -1;
- }
- case DT_JMPREL:
- plt_rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
- break;
-
- // Standard relocation information
- case DT_REL:
- rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
- break;
- case DT_RELSZ:
- rel_size = dyn_entry->d_un.d_val;
- break;
- case DT_RELENT:
- rel_entry = dyn_entry->d_un.d_val;
- break;
-
- // Module initialization and termination
- case DT_INIT:
- // TODO Implement initialization functions
- break;
- case DT_FINI:
- // TODO Implement finalization functions
- break;
- }
-
- dyn_entry++;
- }
-
- if (rel_size > 0) {
- // Process standard relocations
- for (i = 0; i < rel_size/rel_entry; i++) {
- crt_rel = (Elf32_Rel*)(rel + i*rel_entry);
-
- res = perform_relocation(module, crt_rel);
-
- if (res < 0)
- return res;
- }
-
- }
-
- if (plt_rel_size > 0) {
- // TODO: Permit this lazily
- // Process PLT relocations
- for (i = 0; i < plt_rel_size/sizeof(Elf32_Rel); i++) {
- crt_rel = (Elf32_Rel*)(plt_rel + i*sizeof(Elf32_Rel));
-
- res = perform_relocation(module, crt_rel);
-
- if (res < 0)
- return res;
- }
- }
-
- return 0;
-}
+extern int perform_relocation(struct elf_module *module, Elf_Rel *rel);
+extern int resolve_symbols(struct elf_module *module);
static int extract_operations(struct elf_module *module) {
- Elf32_Sym *ctors_start, *ctors_end;
- Elf32_Sym *dtors_start, *dtors_end;
+ Elf_Sym *ctors_start, *ctors_end;
+ Elf_Sym *dtors_start, *dtors_end;
module_ctor_t *ctors = NULL;
module_ctor_t *dtors = NULL;
@@ -489,8 +181,8 @@ static int extract_operations(struct elf_module *module) {
// Loads the module into the system
int module_load(struct elf_module *module) {
int res;
- Elf32_Sym *main_sym;
- Elf32_Ehdr elf_hdr;
+ Elf_Sym *main_sym;
+ Elf_Ehdr elf_hdr;
module_ctor_t *ctor;
struct elf_module *head = NULL;
@@ -510,7 +202,7 @@ int module_load(struct elf_module *module) {
// The module is a fully featured dynamic library
module->shallow = 0;
- CHECKED(res, image_read(&elf_hdr, sizeof(Elf32_Ehdr), module), error);
+ CHECKED(res, image_read(&elf_hdr, sizeof(Elf_Ehdr), module), error);
//printf("check... 1\n");
//print_elf_ehdr(&elf_hdr);
@@ -596,7 +288,7 @@ int module_load(struct elf_module *module) {
(module->exit_func == NULL) ? NULL : *(module->exit_func));
*/
- for (ctor = module->ctors; *ctor; ctor++)
+ for (ctor = module->ctors; ctor && *ctor; ctor++)
(*ctor) ();
return 0;
diff --git a/com32/lib/sys/module/elfutils.h b/com32/lib/sys/module/elfutils.h
index a901ff48..91bdcb3f 100644
--- a/com32/lib/sys/module/elfutils.h
+++ b/com32/lib/sys/module/elfutils.h
@@ -3,23 +3,24 @@
#include <elf.h>
#include <stdlib.h>
+#include <sys/module.h>
/**
* elf_get_header - Returns a pointer to the ELF header structure.
* @elf_image: pointer to the ELF file image in memory
*/
-static inline Elf32_Ehdr *elf_get_header(void *elf_image) {
- return (Elf32_Ehdr*)elf_image;
+static inline Elf_Ehdr *elf_get_header(void *elf_image) {
+ return (Elf_Ehdr*)elf_image;
}
/**
* elf_get_pht - Returns a pointer to the first entry in the PHT.
* @elf_image: pointer to the ELF file image in memory
*/
-static inline Elf32_Phdr *elf_get_pht(void *elf_image) {
- Elf32_Ehdr *elf_hdr = elf_get_header(elf_image);
+static inline Elf_Phdr *elf_get_pht(void *elf_image) {
+ Elf_Ehdr *elf_hdr = elf_get_header(elf_image);
- return (Elf32_Phdr*)((Elf32_Off)elf_hdr + elf_hdr->e_phoff);
+ return (Elf_Phdr*)((Elf_Off)elf_hdr + elf_hdr->e_phoff);
}
//
@@ -28,11 +29,11 @@ static inline Elf32_Phdr *elf_get_pht(void *elf_image) {
* @elf_image: pointer to the ELF file image in memory
* @index: the index of the PHT entry to look for
*/
-static inline Elf32_Phdr *elf_get_ph(void *elf_image, int index) {
- Elf32_Phdr *elf_pht = elf_get_pht(elf_image);
- Elf32_Ehdr *elf_hdr = elf_get_header(elf_image);
+static inline Elf_Phdr *elf_get_ph(void *elf_image, int index) {
+ Elf_Phdr *elf_pht = elf_get_pht(elf_image);
+ Elf_Ehdr *elf_hdr = elf_get_header(elf_image);
- return (Elf32_Phdr*)((Elf32_Off)elf_pht + index * elf_hdr->e_phentsize);
+ return (Elf_Phdr*)((Elf_Off)elf_pht + index * elf_hdr->e_phentsize);
}
/**
diff --git a/com32/lib/sys/module/i386/elf_module.c b/com32/lib/sys/module/i386/elf_module.c
new file mode 100644
index 00000000..a3792554
--- /dev/null
+++ b/com32/lib/sys/module/i386/elf_module.c
@@ -0,0 +1,341 @@
+/*
+ * elf_module.c
+ *
+ * Created on: Aug 11, 2008
+ * Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <elf.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#include "elfutils.h"
+#include "../common.h"
+
+/*
+ *
+ * The implementation assumes that the loadable segments are present
+ * in the PHT sorted by their offsets, so that only forward seeks would
+ * be necessary.
+ */
+int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
+ int i;
+ int res = 0;
+ char *pht = NULL;
+ char *sht = NULL;
+ Elf32_Phdr *cr_pht;
+ Elf32_Shdr *cr_sht;
+
+ Elf32_Addr min_addr = 0x00000000; // Min. ELF vaddr
+ Elf32_Addr max_addr = 0x00000000; // Max. ELF vaddr
+ Elf32_Word max_align = sizeof(void*); // Min. align of posix_memalign()
+ Elf32_Addr min_alloc, max_alloc; // Min. and max. aligned allocables
+
+ Elf32_Addr dyn_addr = 0x00000000;
+
+ // Get to the PHT
+ image_seek(elf_hdr->e_phoff, module);
+
+ // Load the PHT
+ pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+ image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
+
+ // Compute the memory needings of the module
+ for (i=0; i < elf_hdr->e_phnum; i++) {
+ cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+ switch (cr_pht->p_type) {
+ case PT_LOAD:
+ if (i == 0) {
+ min_addr = cr_pht->p_vaddr;
+ } else {
+ min_addr = MIN(min_addr, cr_pht->p_vaddr);
+ }
+
+ max_addr = MAX(max_addr, cr_pht->p_vaddr + cr_pht->p_memsz);
+ max_align = MAX(max_align, cr_pht->p_align);
+ break;
+ case PT_DYNAMIC:
+ dyn_addr = cr_pht->p_vaddr;
+ break;
+ default:
+ // Unsupported - ignore
+ break;
+ }
+ }
+
+ if (max_addr - min_addr == 0) {
+ // No loadable segments
+ DBG_PRINT("No loadable segments found\n");
+ goto out;
+ }
+
+ if (dyn_addr == 0) {
+ DBG_PRINT("No dynamic information segment found\n");
+ goto out;
+ }
+
+ // The minimum address that should be allocated
+ min_alloc = min_addr - (min_addr % max_align);
+
+ // The maximum address that should be allocated
+ max_alloc = max_addr - (max_addr % max_align);
+ if (max_addr % max_align > 0)
+ max_alloc += max_align;
+
+
+ if (elf_malloc(&module->module_addr,
+ max_align,
+ max_alloc-min_alloc) != 0) {
+
+ DBG_PRINT("Could not allocate segments\n");
+ goto out;
+ }
+
+ module->base_addr = (Elf32_Addr)(module->module_addr) - min_alloc;
+ module->module_size = max_alloc - min_alloc;
+
+ // Zero-initialize the memory
+ memset(module->module_addr, 0, module->module_size);
+
+ for (i = 0; i < elf_hdr->e_phnum; i++) {
+ cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+ if (cr_pht->p_type == PT_LOAD) {
+ // Copy the segment at its destination
+ if (cr_pht->p_offset < module->u.l._cr_offset) {
+ // The segment contains data before the current offset
+ // It can be discarded without worry - it would contain only
+ // headers
+ Elf32_Off aux_off = module->u.l._cr_offset - cr_pht->p_offset;
+
+ if (image_read((char *)module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
+ cr_pht->p_filesz - aux_off, module) < 0) {
+ res = -1;
+ goto out;
+ }
+ } else {
+ if (image_seek(cr_pht->p_offset, module) < 0) {
+ res = -1;
+ goto out;
+ }
+
+ if (image_read(module_get_absolute(cr_pht->p_vaddr, module),
+ cr_pht->p_filesz, module) < 0) {
+ res = -1;
+ goto out;
+ }
+ }
+
+ /*
+ 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));
+ */
+ }
+ }
+
+ // Get to the SHT
+ image_seek(elf_hdr->e_shoff, module);
+
+ // Load the SHT
+ sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+ // Setup the symtable size
+ for (i = 0; i < elf_hdr->e_shnum; i++) {
+ cr_sht = (Elf32_Shdr*)(sht + i * elf_hdr->e_shentsize);
+
+ if (cr_sht->sh_type == SHT_DYNSYM) {
+ module->symtable_size = cr_sht->sh_size;
+ break;
+ }
+ }
+
+ free(sht);
+
+ // Setup dynamic segment location
+ module->dyn_table = module_get_absolute(dyn_addr, module);
+
+ /*
+ DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr,
+ max_align);
+ DBG_PRINT("Module size: 0x%08x\n", module->module_size);
+ */
+
+out:
+ // Free up allocated memory
+ if (pht != NULL)
+ free(pht);
+
+ return res;
+}
+
+int perform_relocation(struct elf_module *module, Elf_Rel *rel) {
+ Elf32_Word *dest = module_get_absolute(rel->r_offset, module);
+
+ // The symbol reference index
+ Elf32_Word sym = ELF32_R_SYM(rel->r_info);
+ unsigned char type = ELF32_R_TYPE(rel->r_info);
+
+ // The symbol definition (if applicable)
+ Elf32_Sym *sym_def = NULL;
+ struct elf_module *sym_module = NULL;
+ Elf32_Addr sym_addr = 0x0;
+
+ if (sym > 0) {
+ // Find out details about the symbol
+
+ // The symbol reference
+ Elf32_Sym *sym_ref = symbol_get_entry(module, sym);
+
+ // The symbol definition
+ sym_def =
+ global_find_symbol(module->str_table + sym_ref->st_name,
+ &sym_module);
+
+ if (sym_def == NULL) {
+ DBG_PRINT("Cannot perform relocation for symbol %s\n",
+ module->str_table + sym_ref->st_name);
+
+ if (ELF32_ST_BIND(sym_ref->st_info) != STB_WEAK)
+ return -1;
+
+ // This must be a derivative-specific
+ // function. We're OK as long as we never
+ // execute the function.
+ sym_def = global_find_symbol("undefined_symbol", &sym_module);
+ }
+
+ // Compute the absolute symbol virtual address
+ sym_addr = (Elf32_Addr)module_get_absolute(sym_def->st_value, sym_module);
+
+ if (sym_module != module) {
+ // Create a dependency
+ enforce_dependency(sym_module, module);
+ }
+ }
+
+ switch (type) {
+ case R_386_NONE:
+ // Do nothing
+ break;
+ case R_386_32:
+ *dest += sym_addr;
+ break;
+ case R_386_PC32:
+ *dest += sym_addr - (Elf32_Addr)dest;
+ break;
+ case R_386_COPY:
+ if (sym_addr > 0) {
+ memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
+ }
+ break;
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ // Maybe TODO: Keep track of the GOT entries allocations
+ *dest = sym_addr;
+ break;
+ case R_386_RELATIVE:
+ *dest += module->base_addr;
+ break;
+ default:
+ DBG_PRINT("Relocation type %d not supported\n", type);
+ return -1;
+ }
+
+ return 0;
+}
+
+int resolve_symbols(struct elf_module *module) {
+ Elf32_Dyn *dyn_entry = module->dyn_table;
+ unsigned int i;
+ int res;
+
+ Elf32_Word plt_rel_size = 0;
+ char *plt_rel = NULL;
+
+ char *rel = NULL;
+ Elf32_Word rel_size = 0;
+ Elf32_Word rel_entry = 0;
+
+ // The current relocation
+ Elf32_Rel *crt_rel;
+
+ while (dyn_entry->d_tag != DT_NULL) {
+ switch(dyn_entry->d_tag) {
+
+ // PLT relocation information
+ case DT_PLTRELSZ:
+ plt_rel_size = dyn_entry->d_un.d_val;
+ break;
+ case DT_PLTREL:
+ if (dyn_entry->d_un.d_val != DT_REL) {
+ DBG_PRINT("Unsupported PLT relocation\n");
+ return -1;
+ }
+ case DT_JMPREL:
+ plt_rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ break;
+
+ // Standard relocation information
+ case DT_REL:
+ rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ break;
+ case DT_RELSZ:
+ rel_size = dyn_entry->d_un.d_val;
+ break;
+ case DT_RELENT:
+ rel_entry = dyn_entry->d_un.d_val;
+ break;
+
+ // Module initialization and termination
+ case DT_INIT:
+ // TODO Implement initialization functions
+ break;
+ case DT_FINI:
+ // TODO Implement finalization functions
+ break;
+ }
+
+ dyn_entry++;
+ }
+
+ if (rel_size > 0) {
+ // Process standard relocations
+ for (i = 0; i < rel_size/rel_entry; i++) {
+ crt_rel = (Elf32_Rel*)(rel + i*rel_entry);
+
+ res = perform_relocation(module, crt_rel);
+
+ if (res < 0)
+ return res;
+ }
+
+ }
+
+ if (plt_rel_size > 0) {
+ // TODO: Permit this lazily
+ // Process PLT relocations
+ for (i = 0; i < plt_rel_size/sizeof(Elf32_Rel); i++) {
+ crt_rel = (Elf32_Rel*)(plt_rel + i*sizeof(Elf32_Rel));
+
+ res = perform_relocation(module, crt_rel);
+
+ if (res < 0)
+ return res;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/com32/lib/sys/module/i386/shallow_module.c b/com32/lib/sys/module/i386/shallow_module.c
new file mode 100644
index 00000000..fbcf781b
--- /dev/null
+++ b/com32/lib/sys/module/i386/shallow_module.c
@@ -0,0 +1,161 @@
+/*
+ * shallow_module.c
+ *
+ * Created on: Aug 11, 2008
+ * Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+
+#include <string.h>
+#include <sys/module.h>
+
+#include "common.h"
+#include "elfutils.h"
+
+
+static int check_header_shallow(Elf32_Ehdr *elf_hdr) {
+ int res;
+
+ res = check_header_common(elf_hdr);
+
+ if (res != 0)
+ return res;
+
+ if (elf_hdr->e_shoff == 0x00000000) {
+ DBG_PRINT("SHT missing\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
+ int i;
+ int res = 0;
+ void *sht = NULL;
+ void *buffer = NULL;
+ Elf32_Shdr *crt_sht;
+ Elf32_Off buff_offset;
+
+ Elf32_Off min_offset = 0xFFFFFFFF;
+ Elf32_Off max_offset = 0x00000000;
+ Elf32_Word max_align = 0x1;
+
+ Elf32_Off sym_offset = 0xFFFFFFFF;
+ Elf32_Off str_offset = 0xFFFFFFFF;
+
+
+ char *sh_strtable;
+
+ // We buffer the data up to the SHT
+ buff_offset = module->u.l._cr_offset;
+
+ buffer = malloc(elf_hdr->e_shoff - buff_offset);
+ // Get to the SHT
+ image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
+
+ // Load the SHT
+ sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+ // Get the string table of the section names
+ crt_sht = (Elf32_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
+ sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
+
+ for (i = 0; i < elf_hdr->e_shnum; i++) {
+ crt_sht = (Elf32_Shdr*)(sht + i*elf_hdr->e_shentsize);
+
+ if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
+ // We found the symbol table
+ min_offset = MIN(min_offset, crt_sht->sh_offset);
+ max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
+ max_align = MAX(max_align, crt_sht->sh_addralign);
+
+ sym_offset = crt_sht->sh_offset;
+
+ module->syment_size = crt_sht->sh_entsize;
+ module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
+ }
+ if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
+ // We found the string table
+ min_offset = MIN(min_offset, crt_sht->sh_offset);
+ max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
+ max_align = MAX(max_align, crt_sht->sh_addralign);
+
+ str_offset = crt_sht->sh_offset;
+
+ module->strtable_size = crt_sht->sh_size;
+ }
+ }
+
+ if (elf_malloc(&module->module_addr, max_align,
+ max_offset - min_offset) != 0) {
+ DBG_PRINT("Could not allocate sections\n");
+ goto out;
+ }
+
+ // Copy the data
+ image_seek(min_offset, module);
+ image_read(module->module_addr, max_offset - min_offset, module);
+
+ // Setup module information
+ module->module_size = max_offset - min_offset;
+ module->str_table = (char*)(module->module_addr + (str_offset - min_offset));
+ module->sym_table = module->module_addr + (sym_offset - min_offset);
+
+out:
+ // Release the SHT
+ if (sht != NULL)
+ free(sht);
+
+ // Release the buffer
+ if (buffer != NULL)
+ free(buffer);
+
+ return res;
+}
+
+
+int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr) {
+ int res;
+ Elf32_Ehdr elf_hdr;
+
+ // Do not allow duplicate modules
+ if (module_find(module->name) != NULL) {
+ DBG_PRINT("Module already loaded.\n");
+ return -1;
+ }
+
+ res = image_load(module);
+
+ if (res < 0)
+ return res;
+
+ module->shallow = 1;
+
+ CHECKED(res, image_read(&elf_hdr, sizeof(Elf32_Ehdr), module), error);
+
+ // Checking the header signature and members
+ CHECKED(res, check_header_shallow(&elf_hdr), error);
+
+ CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
+ module->base_addr = base_addr;
+
+ // Check the symbols for duplicates / missing definitions
+ CHECKED(res, check_symbols(module), error);
+
+ // Add the module at the beginning of the module list
+ list_add(&module->list, &modules_head);
+
+ // The file image is no longer needed
+ image_unload(module);
+
+ DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
+
+ return 0;
+
+error:
+ image_unload(module);
+
+ return res;
+}
diff --git a/com32/lib/sys/module/x86_64/elf_module.c b/com32/lib/sys/module/x86_64/elf_module.c
new file mode 100644
index 00000000..64404a17
--- /dev/null
+++ b/com32/lib/sys/module/x86_64/elf_module.c
@@ -0,0 +1,372 @@
+/*
+ * elf_module.c
+ *
+ * Created on: Aug 11, 2008
+ * Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <elf.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#include "elfutils.h"
+#include "../common.h"
+
+/*
+ *
+ * The implementation assumes that the loadable segments are present
+ * in the PHT sorted by their offsets, so that only forward seeks would
+ * be necessary.
+ */
+int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
+ int i;
+ int res = 0;
+ char *pht = NULL;
+ char *sht = NULL;
+ Elf64_Phdr *cr_pht;
+ Elf64_Shdr *cr_sht;
+
+ Elf64_Addr min_addr = 0x0000000000000000; // Min. ELF vaddr
+ Elf64_Addr max_addr = 0x0000000000000000; // Max. ELF vaddr
+ Elf64_Word max_align = sizeof(void*); // Min. align of posix_memalign()
+ Elf64_Addr min_alloc, max_alloc; // Min. and max. aligned allocables
+
+ Elf64_Addr dyn_addr = 0x0000000000000000;
+
+ // Get to the PHT
+ image_seek(elf_hdr->e_phoff, module);
+
+ // Load the PHT
+ pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+ image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
+
+ // Compute the memory needings of the module
+ for (i=0; i < elf_hdr->e_phnum; i++) {
+ cr_pht = (Elf64_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+ switch (cr_pht->p_type) {
+ case PT_LOAD:
+ if (i == 0) {
+ min_addr = cr_pht->p_vaddr;
+ } else {
+ min_addr = MIN(min_addr, cr_pht->p_vaddr);
+ }
+
+ max_addr = MAX(max_addr, cr_pht->p_vaddr + cr_pht->p_memsz);
+ max_align = MAX(max_align, cr_pht->p_align);
+ break;
+ case PT_DYNAMIC:
+ dyn_addr = cr_pht->p_vaddr;
+ break;
+ default:
+ // Unsupported - ignore
+ break;
+ }
+ }
+
+ if (max_addr - min_addr == 0) {
+ // No loadable segments
+ DBG_PRINT("No loadable segments found\n");
+ goto out;
+ }
+
+ if (dyn_addr == 0) {
+ DBG_PRINT("No dynamic information segment found\n");
+ goto out;
+ }
+
+ // The minimum address that should be allocated
+ min_alloc = min_addr - (min_addr % max_align);
+
+ // The maximum address that should be allocated
+ max_alloc = max_addr - (max_addr % max_align);
+ if (max_addr % max_align > 0)
+ max_alloc += max_align;
+
+
+ if (elf_malloc(&module->module_addr,
+ max_align,
+ max_alloc-min_alloc) != 0) {
+
+ DBG_PRINT("Could not allocate segments\n");
+ goto out;
+ }
+
+ module->base_addr = (Elf64_Addr)(module->module_addr) - min_alloc;
+ module->module_size = max_alloc - min_alloc;
+
+ // Zero-initialize the memory
+ memset(module->module_addr, 0, module->module_size);
+
+ for (i = 0; i < elf_hdr->e_phnum; i++) {
+ cr_pht = (Elf64_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+ if (cr_pht->p_type == PT_LOAD) {
+ // Copy the segment at its destination
+ if (cr_pht->p_offset < module->u.l._cr_offset) {
+ // The segment contains data before the current offset
+ // It can be discarded without worry - it would contain only
+ // headers
+ Elf64_Off aux_off = module->u.l._cr_offset - cr_pht->p_offset;
+
+ if (image_read((char *)module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
+ cr_pht->p_filesz - aux_off, module) < 0) {
+ res = -1;
+ goto out;
+ }
+ } else {
+ if (image_seek(cr_pht->p_offset, module) < 0) {
+ res = -1;
+ goto out;
+ }
+
+ if (image_read(module_get_absolute(cr_pht->p_vaddr, module),
+ cr_pht->p_filesz, module) < 0) {
+ res = -1;
+ goto out;
+ }
+ }
+
+ /*
+ 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,
+ (Elf64_Addr)module_get_absolute(cr_pht->p_vaddr, module));
+ */
+ }
+ }
+
+ // Get to the SHT
+ image_seek(elf_hdr->e_shoff, module);
+
+ // Load the SHT
+ sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+ // Setup the symtable size
+ for (i = 0; i < elf_hdr->e_shnum; i++) {
+ cr_sht = (Elf64_Shdr*)(sht + i * elf_hdr->e_shentsize);
+
+ if (cr_sht->sh_type == SHT_DYNSYM) {
+ module->symtable_size = cr_sht->sh_size;
+ break;
+ }
+ }
+
+ free(sht);
+
+ // Setup dynamic segment location
+ module->dyn_table = module_get_absolute(dyn_addr, module);
+
+ /*
+ DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr,
+ max_align);
+ DBG_PRINT("Module size: 0x%08x\n", module->module_size);
+ */
+
+out:
+ // Free up allocated memory
+ if (pht != NULL)
+ free(pht);
+
+ return res;
+}
+
+int perform_relocation(struct elf_module *module, Elf_Rel *rel) {
+ Elf64_Xword *dest = module_get_absolute(rel->r_offset, module);
+
+ // The symbol reference index
+ Elf64_Word sym = ELF64_R_SYM(rel->r_info);
+ unsigned char type = ELF64_R_TYPE(rel->r_info);
+
+ // The symbol definition (if applicable)
+ Elf64_Sym *sym_def = NULL;
+ struct elf_module *sym_module = NULL;
+ Elf64_Addr sym_addr = 0x0;
+
+ if (sym > 0) {
+ // Find out details about the symbol
+
+ // The symbol reference
+ Elf64_Sym *sym_ref = symbol_get_entry(module, sym);
+
+ // The symbol definition
+ sym_def =
+ global_find_symbol(module->str_table + sym_ref->st_name,
+ &sym_module);
+
+ if (sym_def == NULL) {
+ DBG_PRINT("Cannot perform relocation for symbol %s\n",
+ module->str_table + sym_ref->st_name);
+
+ if (ELF64_ST_BIND(sym_ref->st_info) != STB_WEAK)
+ return -1;
+
+ // This must be a derivative-specific
+ // function. We're OK as long as we never
+ // execute the function.
+ sym_def = global_find_symbol("undefined_symbol", &sym_module);
+ }
+
+ // Compute the absolute symbol virtual address
+ sym_addr = (Elf64_Addr)module_get_absolute(sym_def->st_value, sym_module);
+
+ if (sym_module != module) {
+ // Create a dependency
+ enforce_dependency(sym_module, module);
+ }
+ }
+
+ switch (type) {
+ case R_X86_64_NONE:
+ // Do nothing
+ break;
+ case R_X86_64_64:
+ *dest += sym_addr;
+ break;
+ case R_X86_64_PC32:
+ *dest += sym_addr - (Elf32_Addr)dest;
+ break;
+ case R_X86_64_COPY:
+ if (sym_addr > 0) {
+ memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
+ }
+ break;
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_JUMP_SLOT:
+ //Maybe TODO: Keep track of the GOT entries allocations
+ *dest = sym_addr;
+ break;
+ case R_X86_64_RELATIVE:
+ *dest += module->base_addr;
+ break;
+ default:
+ DBG_PRINT("Relocation type %d not supported\n", type);
+ return -1;
+ }
+
+ return 0;
+}
+
+int resolve_symbols(struct elf_module *module) {
+ Elf64_Dyn *dyn_entry = module->dyn_table;
+ unsigned int i;
+ int res;
+
+ Elf64_Word plt_rel_size = 0;
+ void *plt_rel = NULL;
+
+ void *rel = NULL;
+ Elf64_Word rel_size = 0;
+ Elf64_Word rel_entry = 0;
+ Elf64_Xword rela_size = 0;
+ Elf64_Xword rela_entry = 0;
+ Elf64_Xword sym_ent = 0;
+
+ // The current relocation
+ Elf64_Rel *crt_rel;
+
+ while (dyn_entry->d_tag != DT_NULL) {
+ switch(dyn_entry->d_tag) {
+
+ // PLT relocation information
+ case DT_PLTRELSZ:
+ plt_rel_size = dyn_entry->d_un.d_val;
+ break;
+ case DT_PLTREL:
+ if (dyn_entry->d_un.d_val != DT_REL && dyn_entry->d_un.d_val != DT_RELA) {
+ DBG_PRINT("Unsupported PLT relocation\n");
+ return -1;
+ }
+ //break;
+ case DT_JMPREL:
+ plt_rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ break;
+
+ // Standard relocation information
+ case DT_REL:
+ rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ break;
+ case DT_RELA:
+ rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+ break;
+ case DT_RELSZ:
+ rel_size = dyn_entry->d_un.d_val;
+ break;
+ case DT_RELASZ:
+ rela_size = dyn_entry->d_un.d_val;
+ break;
+ case DT_RELENT:
+ rel_entry = dyn_entry->d_un.d_val;
+ break;
+ case DT_RELAENT:
+ rela_entry = dyn_entry->d_un.d_val;
+ break;
+ /* FIXME: We may need to rely upon SYMENT if DT_RELAENT is missing in the object file */
+ case DT_SYMENT:
+ sym_ent = dyn_entry->d_un.d_val;
+ break;
+
+ // Module initialization and termination
+ case DT_INIT:
+ // TODO Implement initialization functions
+ break;
+ case DT_FINI:
+ // TODO Implement finalization functions
+ break;
+ }
+
+ dyn_entry++;
+ }
+
+ if (rel_size > 0) {
+ // Process standard relocations
+ for (i = 0; i < rel_size/rel_entry; i++) {
+ crt_rel = (Elf64_Rel*)(rel + i*rel_entry);
+
+ res = perform_relocation(module, crt_rel);
+
+ if (res < 0)
+ return res;
+ }
+
+ }
+
+ if (rela_size > 0) {
+ // Process standard relocations
+ for (i = 0; i < rela_size/rela_entry; i++) {
+ crt_rel = (Elf64_Rel*)(rel + i*rela_entry);
+
+ res = perform_relocation(module, crt_rel);
+
+ if (res < 0)
+ return res;
+ }
+ }
+ if (plt_rel_size > 0) {
+ // TODO: Permit this lazily
+ // Process PLT relocations
+ /* some modules do not have DT_SYMENT, set it sym_ent in such cases */
+ if (!rela_entry) rela_entry = sym_ent;
+ //for (i = 0; i < plt_rel_size/sizeof(Elf64_Rel); i++) {
+ for (i = 0; i < plt_rel_size/rela_entry; i++) {
+ //crt_rel = (Elf64_Rel*)(plt_rel + i*sizeof(Elf64_Rel));
+ crt_rel = (Elf64_Rel*)(plt_rel + i*rela_entry);
+
+ res = perform_relocation(module, crt_rel);
+
+ if (res < 0)
+ return res;
+ }
+ }
+
+ return 0;
+}
diff --git a/com32/lib/sys/module/x86_64/shallow_module.c b/com32/lib/sys/module/x86_64/shallow_module.c
new file mode 100644
index 00000000..b7248150
--- /dev/null
+++ b/com32/lib/sys/module/x86_64/shallow_module.c
@@ -0,0 +1,161 @@
+/*
+ * shallow_module.c
+ *
+ * Created on: Aug 11, 2008
+ * Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+
+#include <string.h>
+#include <sys/module.h>
+
+#include "common.h"
+#include "elfutils.h"
+
+
+static int check_header_shallow(Elf64_Ehdr *elf_hdr) {
+ int res;
+
+ res = check_header_common(elf_hdr);
+
+ if (res != 0)
+ return res;
+
+ if (elf_hdr->e_shoff == 0x00000000) {
+ DBG_PRINT("SHT missing\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int load_shallow_sections(struct elf_module *module, Elf64_Ehdr *elf_hdr) {
+ int i;
+ int res = 0;
+ void *sht = NULL;
+ void *buffer = NULL;
+ Elf64_Shdr *crt_sht;
+ Elf64_Off buff_offset;
+
+ Elf64_Off min_offset = 0xFFFFFFFFFFFFFFFF;
+ Elf64_Off max_offset = 0x0000000000000000;
+ Elf64_Word max_align = 0x1;
+
+ Elf64_Off sym_offset = 0xFFFFFFFFFFFFFFFF;
+ Elf64_Off str_offset = 0xFFFFFFFFFFFFFFFF;
+
+
+ char *sh_strtable;
+
+ // We buffer the data up to the SHT
+ buff_offset = module->u.l._cr_offset;
+
+ buffer = malloc(elf_hdr->e_shoff - buff_offset);
+ // Get to the SHT
+ image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
+
+ // Load the SHT
+ sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+ // Get the string table of the section names
+ crt_sht = (Elf64_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
+ sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
+
+ for (i = 0; i < elf_hdr->e_shnum; i++) {
+ crt_sht = (Elf64_Shdr*)(sht + i*elf_hdr->e_shentsize);
+
+ if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
+ // We found the symbol table
+ min_offset = MIN(min_offset, crt_sht->sh_offset);
+ max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
+ max_align = MAX(max_align, crt_sht->sh_addralign);
+
+ sym_offset = crt_sht->sh_offset;
+
+ module->syment_size = crt_sht->sh_entsize;
+ module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
+ }
+ if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
+ // We found the string table
+ min_offset = MIN(min_offset, crt_sht->sh_offset);
+ max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
+ max_align = MAX(max_align, crt_sht->sh_addralign);
+
+ str_offset = crt_sht->sh_offset;
+
+ module->strtable_size = crt_sht->sh_size;
+ }
+ }
+
+ if (elf_malloc(&module->module_addr, max_align,
+ max_offset - min_offset) != 0) {
+ DBG_PRINT("Could not allocate sections\n");
+ goto out;
+ }
+
+ // Copy the data
+ image_seek(min_offset, module);
+ image_read(module->module_addr, max_offset - min_offset, module);
+
+ // Setup module information
+ module->module_size = max_offset - min_offset;
+ module->str_table = (char*)(module->module_addr + (str_offset - min_offset));
+ module->sym_table = module->module_addr + (sym_offset - min_offset);
+
+out:
+ // Release the SHT
+ if (sht != NULL)
+ free(sht);
+
+ // Release the buffer
+ if (buffer != NULL)
+ free(buffer);
+
+ return res;
+}
+
+
+int module_load_shallow(struct elf_module *module, Elf64_Addr base_addr) {
+ int res;
+ Elf64_Ehdr elf_hdr;
+
+ // Do not allow duplicate modules
+ if (module_find(module->name) != NULL) {
+ DBG_PRINT("Module already loaded.\n");
+ return -1;
+ }
+
+ res = image_load(module);
+
+ if (res < 0)
+ return res;
+
+ module->shallow = 1;
+
+ CHECKED(res, image_read(&elf_hdr, sizeof(Elf64_Ehdr), module), error);
+
+ // Checking the header signature and members
+ CHECKED(res, check_header_shallow(&elf_hdr), error);
+
+ CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
+ module->base_addr = base_addr;
+
+ // Check the symbols for duplicates / missing definitions
+ CHECKED(res, check_symbols(module), error);
+
+ // Add the module at the beginning of the module list
+ list_add(&module->list, &modules_head);
+
+ // The file image is no longer needed
+ image_unload(module);
+
+ DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
+
+ return 0;
+
+error:
+ image_unload(module);
+
+ return res;
+}
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index 9a1ae384..c2721b8d 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -69,37 +69,12 @@ static void unpack_font(uint8_t * dst, uint8_t * src, int height)
}
}
-static int __constfunc is_power_of_2(unsigned int x)
+static int vesacon_set_mode(int *x, int *y)
{
- return x && !(x & (x - 1));
-}
-
-static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
-{
- int i;
-
- if (!is_power_of_2(mi->win_size) ||
- !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size)
- return 0; /* Impossible... */
-
- for (i = 0; i < 2; i++) {
- if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i])
- return 1; /* Usable window */
- }
-
- return 0; /* Nope... */
-}
-
-static int vesacon_set_mode(int x, int y)
-{
- com32sys_t rm;
uint8_t *rom_font;
- uint16_t mode, bestmode, *mode_ptr;
- struct vesa_info *vi;
- struct vesa_general_info *gi;
struct vesa_mode_info *mi;
- enum vesa_pixel_format pxf, bestpxf;
- int err = 0;
+ enum vesa_pixel_format bestpxf;
+ int rv;
debug("Hello, World!\r\n");
@@ -113,172 +88,22 @@ static int vesacon_set_mode(int x, int y)
__vesacon_shadowfb = NULL;
}
- /* Allocate space in the bounce buffer for these structures */
- vi = lzalloc(sizeof *vi);
- if (!vi) {
- err = 10; /* Out of memory */
- goto exit;
- }
- gi = &vi->gi;
- mi = &vi->mi;
-
- memset(&rm, 0, sizeof rm);
-
- gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
- rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
- rm.edi.w[0] = OFFS(gi);
- rm.es = SEG(gi);
- __intcall(0x10, &rm, &rm);
-
- if (rm.eax.w[0] != 0x004F) {
- err = 1; /* Function call failed */
- goto exit;
- }
- if (gi->signature != VESA_MAGIC) {
- err = 2; /* No magic */
- goto exit;
- }
- if (gi->version < 0x0102) {
- err = 3; /* VESA 1.2+ required */
- goto exit;
- }
-
- /* Copy general info */
- memcpy(&__vesa_info.gi, gi, sizeof *gi);
-
- /* Search for the proper mode with a suitable color and memory model... */
-
- mode_ptr = GET_PTR(gi->video_mode_ptr);
- bestmode = 0;
- bestpxf = PXF_NONE;
-
- while ((mode = *mode_ptr++) != 0xFFFF) {
- mode &= 0x1FF; /* The rest are attributes of sorts */
-
- debug("Found mode: 0x%04x\r\n", mode);
-
- memset(mi, 0, sizeof *mi);
- rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
- rm.ecx.w[0] = mode;
- rm.edi.w[0] = OFFS(mi);
- rm.es = SEG(mi);
- __intcall(0x10, &rm, &rm);
-
- /* Must be a supported mode */
- if (rm.eax.w[0] != 0x004f)
- continue;
-
- debug
- ("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n",
- mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout,
- mi->rpos, mi->gpos, mi->bpos);
-
- /* Must be an LFB color graphics mode supported by the hardware.
-
- The bits tested are:
- 4 - graphics mode
- 3 - color mode
- 1 - mode information available (mandatory in VBE 1.2+)
- 0 - mode supported by hardware
- */
- if ((mi->mode_attr & 0x001b) != 0x001b)
- continue;
-
- /* Must be the chosen size */
- if (mi->h_res != x || mi->v_res != y)
- continue;
-
- /* We don't support multibank (interlaced memory) modes */
- /*
- * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the
- * specification which states that banks == 1 for unbanked modes;
- * fortunately it does report bank_size == 0 for those.
- */
- if (mi->banks > 1 && mi->bank_size) {
- debug("bad: banks = %d, banksize = %d, pages = %d\r\n",
- mi->banks, mi->bank_size, mi->image_pages);
- continue;
- }
-
- /* Must be either a flat-framebuffer mode, or be an acceptable
- paged mode */
- if (!(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi)) {
- debug("bad: invalid paged mode\r\n");
- continue;
- }
-
- /* Must either be a packed-pixel mode or a direct color mode
- (depending on VESA version ); must be a supported pixel format */
- pxf = PXF_NONE; /* Not usable */
-
- if (mi->bpp == 32 &&
- (mi->memory_layout == 4 ||
- (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
- mi->bpos == 0)))
- pxf = PXF_BGRA32;
- else if (mi->bpp == 24 &&
- (mi->memory_layout == 4 ||
- (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
- mi->bpos == 0)))
- pxf = PXF_BGR24;
- else if (mi->bpp == 16 &&
- (mi->memory_layout == 4 ||
- (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 &&
- mi->bpos == 0)))
- pxf = PXF_LE_RGB16_565;
- else if (mi->bpp == 15 &&
- (mi->memory_layout == 4 ||
- (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 &&
- mi->bpos == 0)))
- pxf = PXF_LE_RGB15_555;
-
- if (pxf < bestpxf) {
- debug("Best mode so far, pxf = %d\r\n", pxf);
-
- /* Best mode so far... */
- bestmode = mode;
- bestpxf = pxf;
-
- /* Copy mode info */
- memcpy(&__vesa_info.mi, mi, sizeof *mi);
- }
- }
-
- if (bestpxf == PXF_NONE) {
- err = 4; /* No mode found */
- goto exit;
- }
+ rv = firmware->vesa->set_mode(&__vesa_info, x, y, &bestpxf);
+ if (rv)
+ return rv;
mi = &__vesa_info.mi;
- mode = bestmode;
__vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3;
__vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf];
- /* Download the SYSLINUX- or BIOS-provided font */
+ /* Download the SYSLINUX- or firmware-provided font */
__vesacon_font_height = syslinux_font_query(&rom_font);
- if (!__vesacon_font_height) {
- /* Get BIOS 8x16 font */
-
- rm.eax.w[0] = 0x1130; /* Get Font Information */
- rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */
- __intcall(0x10, &rm, &rm);
- rom_font = MK_PTR(rm.es, rm.ebp.w[0]);
- __vesacon_font_height = 16;
- }
+ if (!__vesacon_font_height)
+ __vesacon_font_height = firmware->vesa->font_query(&rom_font);
+
unpack_font((uint8_t *) __vesacon_graphics_font, rom_font,
__vesacon_font_height);
- /* Now set video mode */
- rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */
- if (mi->mode_attr & 0x0080)
- mode |= 0x4000; /* Request linear framebuffer if supported */
- rm.ebx.w[0] = mode;
- __intcall(0x10, &rm, &rm);
- if (rm.eax.w[0] != 0x004F) {
- err = 9; /* Failed to set mode */
- goto exit;
- }
-
__vesacon_background = calloc(mi->h_res*mi->v_res, 4);
__vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4);
@@ -295,13 +120,17 @@ static int vesacon_set_mode(int x, int y)
__vesacon_pixel_format = bestpxf;
-exit:
- if (vi)
- lfree(vi);
-
- return err;
+ return 0;
}
+/* FIXME:
+ * Does init_text_display need an EFI counterpart?
+ * e.g. vesa_char may need to setup UNICODE char for EFI
+ * and the number of screen chars may need to be sized up
+ * accordingly. This may also require turning byte strings
+ * into unicode strings in the framebuffer
+ * Possibly, revisit vesacon_fill() for EFI.
+ */
static int init_text_display(void)
{
size_t nchars;
@@ -329,7 +158,12 @@ static int init_text_display(void)
return 0;
}
-int __vesacon_init(int x, int y)
+/*
+ * On input, VESA initialization is passed a desirable resolution. On
+ * return, either the requested resolution is set or the system
+ * supported default resolution is set and returned to the caller.
+ */
+int __vesacon_init(int *x, int *y)
{
int rv;
@@ -340,7 +174,7 @@ int __vesacon_init(int x, int y)
rv = vesacon_set_mode(x, y);
if (rv) {
/* Try to see if we can just patch the BIOS... */
- if (__vesacon_i915resolution(x, y))
+ if (__vesacon_i915resolution(*x, *y))
return rv;
if (vesacon_set_mode(x, y))
return rv;
diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c
index 32dce9e6..5c6d9151 100644
--- a/com32/lib/sys/vesa/screencpy.c
+++ b/com32/lib/sys/vesa/screencpy.c
@@ -34,13 +34,8 @@
#include "vesa.h"
#include "video.h"
-static struct win_info {
- char *win_base;
- size_t win_pos;
- size_t win_size;
- int win_gshift;
- int win_num;
-} wi;
+
+static struct win_info wi;
void __vesacon_init_copy_to_screen(void)
{
@@ -71,47 +66,12 @@ void __vesacon_init_copy_to_screen(void)
}
}
-static void set_window_pos(size_t win_pos)
-{
- static com32sys_t ireg;
-
- wi.win_pos = win_pos;
-
- if (wi.win_num < 0)
- return; /* This should never happen... */
-
- ireg.eax.w[0] = 0x4F05;
- ireg.ebx.b[0] = wi.win_num;
- ireg.edx.w[0] = win_pos >> wi.win_gshift;
-
- __intcall(0x10, &ireg, NULL);
-}
-
void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels)
{
- size_t win_pos, win_off;
- size_t win_size = wi.win_size;
- size_t omask = win_size - 1;
- char *win_base = wi.win_base;
- size_t l;
size_t bytes = npixels * __vesacon_bytes_per_pixel;
char rowbuf[bytes + 4] __aligned(4);
const char *s;
s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels);
-
- while (bytes) {
- win_off = dst & omask;
- win_pos = dst & ~omask;
-
- if (__unlikely(win_pos != wi.win_pos))
- set_window_pos(win_pos);
-
- l = min(bytes, win_size - win_off);
- memcpy(win_base + win_off, s, l);
-
- bytes -= l;
- s += l;
- dst += l;
- }
+ firmware->vesa->screencpy(dst, s, bytes, &wi);
}
diff --git a/com32/lib/sys/vesa/vesa.h b/com32/lib/sys/vesa/vesa.h
index 3926c329..7a3d87ae 100644
--- a/com32/lib/sys/vesa/vesa.h
+++ b/com32/lib/sys/vesa/vesa.h
@@ -28,6 +28,7 @@
#ifndef LIB_SYS_VESA_H
#define LIB_SYS_VESA_H
+#include <syslinux/firmware.h>
#include <inttypes.h>
#include <com32.h>
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index d14494b1..f57e34f9 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -51,6 +51,14 @@ struct vesa_char {
attr_t attr; /* Color table index */
};
+struct win_info {
+ char *win_base;
+ size_t win_pos;
+ size_t win_size;
+ int win_gshift;
+ int win_num;
+};
+
/* Pixel formats in order of decreasing preference; PXF_NONE should be last */
/* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */
enum vesa_pixel_format {
@@ -81,7 +89,7 @@ extern const uint8_t __vesacon_linear_to_srgb[4080];
int __vesacon_init_background(void);
int vesacon_load_background(const char *);
-int __vesacon_init(int, int);
+int __vesacon_init(int *, int *);
void __vesacon_init_cursor(int);
void __vesacon_erase(int, int, int, int, attr_t);
void __vesacon_scroll_up(int, attr_t);
diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c
index 37693177..823a66af 100644
--- a/com32/lib/sys/vesacon_write.c
+++ b/com32/lib/sys/vesacon_write.c
@@ -98,7 +98,8 @@ int __vesacon_open(struct file_info *fp)
ti.cols = 80;
} else {
/* Switch mode */
- if (__vesacon_init(vesacon_resolution.x, vesacon_resolution.y)) {
+ /* Deal with a resolution different from default build */
+ if (__vesacon_init(&vesacon_resolution.x, &vesacon_resolution.y)) {
vesacon_counter = -1;
return EAGAIN;
}
diff --git a/com32/lib/sys/x86_64/x86_init_fpu.c b/com32/lib/sys/x86_64/x86_init_fpu.c
new file mode 100644
index 00000000..c5d3946c
--- /dev/null
+++ b/com32/lib/sys/x86_64/x86_init_fpu.c
@@ -0,0 +1,58 @@
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+ uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+ return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+ asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+}
+
+#define CR0_PE 0x00000001
+#define CR0_MP 0x00000002
+#define CR0_EM 0x00000004
+#define CR0_TS 0x00000008
+#define CR0_ET 0x00000010
+#define CR0_NE 0x00000020
+#define CR0_WP 0x00010000
+#define CR0_AM 0x00040000
+#define CR0_NW 0x20000000
+#define CR0_CD 0x40000000
+#define CR0_PG 0x80000000
+
+int x86_init_fpu(void)
+{
+ uint32_t cr0;
+ uint16_t fsw = 0xffff;
+ uint16_t fcw = 0xffff;
+
+ cr0 = get_cr0();
+ cr0 &= ~(CR0_EM | CR0_TS);
+ cr0 |= CR0_MP;
+ set_cr0(cr0);
+
+ asm volatile ("fninit");
+ asm volatile ("fnstsw %0":"+m" (fsw));
+ if (fsw != 0)
+ return -1;
+
+ asm volatile ("fnstcw %0":"+m" (fcw));
+ if ((fcw & 0x103f) != 0x3f)
+ return -1;
+
+ /* Techically, this could be a 386 with a 287. We could add a check
+ for that here... */
+
+ return 0;
+}
diff --git a/com32/lib/sys/x86_init_fpu.c b/com32/lib/sys/x86_init_fpu.c
index cf336932..cacb4ea3 100644
--- a/com32/lib/sys/x86_init_fpu.c
+++ b/com32/lib/sys/x86_init_fpu.c
@@ -4,19 +4,40 @@
* Test for an x86 FPU, and do any necessary setup.
*/
+#if __SIZEOF_POINTER__ == 4
+#include <i386/x86_init_fpu.c>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/x86_init_fpu.c>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+#if 0
#include <inttypes.h>
#include <sys/fpu.h>
static inline uint64_t get_cr0(void)
{
+#if __SIZEOF_POINTER__ == 4
uint32_t v;
asm("movl %%cr0,%0":"=r"(v));
+#elif __SIZEOF_POINTER__ == 8
+ uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
return v;
}
static inline void set_cr0(uint32_t v)
{
+#if __SIZEOF_POINTER__ == 4
asm volatile ("movl %0,%%cr0"::"r" (v));
+#elif __SIZEOF_POINTER__ == 8
+ asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
}
#define CR0_PE 0x00000001
@@ -56,3 +77,4 @@ int x86_init_fpu(void)
return 0;
}
+#endif
diff --git a/com32/lib/syslinux/cleanup.c b/com32/lib/syslinux/cleanup.c
index 066f174f..7d8581e4 100644
--- a/com32/lib/syslinux/cleanup.c
+++ b/com32/lib/syslinux/cleanup.c
@@ -29,8 +29,6 @@
#include <syslinux/config.h>
#include <syslinux/pxe_api.h>
#include <stddef.h>
-#include <bios.h>
-#include <com32.h>
#include <core.h>
void syslinux_final_cleanup(uint16_t flags)
diff --git a/com32/lib/syslinux/dsinfo.c b/com32/lib/syslinux/dsinfo.c
index c1f02a59..f7126bfe 100644
--- a/com32/lib/syslinux/dsinfo.c
+++ b/com32/lib/syslinux/dsinfo.c
@@ -34,12 +34,5 @@ union syslinux_derivative_info __syslinux_derivative_info;
void __constructor __syslinux_get_derivative_info(void)
{
- com32sys_t *const r = &__syslinux_derivative_info.rr.r;
-
- r->eax.w[0] = 0x000A;
- __intcall(0x22, r, r);
-
- __syslinux_derivative_info.r.esbx = MK_PTR(r->es, r->ebx.w[0]);
- __syslinux_derivative_info.r.fssi = MK_PTR(r->fs, r->esi.w[0]);
- __syslinux_derivative_info.r.gsdi = MK_PTR(r->gs, r->edi.w[0]);
+ get_derivative_info(&__syslinux_derivative_info);
}
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index c0335dc9..4a8a1fd3 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -47,48 +47,7 @@
#include <syslinux/linux.h>
#include <syslinux/bootrm.h>
#include <syslinux/movebits.h>
-
-struct linux_header {
- uint8_t boot_sector_1[0x0020];
- uint16_t old_cmd_line_magic;
- uint16_t old_cmd_line_offset;
- uint8_t boot_sector_2[0x01f1 - 0x0024];
- uint8_t setup_sects;
- uint16_t root_flags;
- uint32_t syssize;
- uint16_t ram_size;
- uint16_t vid_mode;
- uint16_t root_dev;
- uint16_t boot_flag;
- uint16_t jump;
- uint32_t header;
- uint16_t version;
- uint32_t realmode_swtch;
- uint16_t start_sys;
- uint16_t kernel_version;
- uint8_t type_of_loader;
- uint8_t loadflags;
- uint16_t setup_move_size;
- uint32_t code32_start;
- uint32_t ramdisk_image;
- uint32_t ramdisk_size;
- uint32_t bootsect_kludge;
- uint16_t heap_end_ptr;
- uint16_t pad1;
- uint32_t cmd_line_ptr;
- uint32_t initrd_addr_max;
- uint32_t kernel_alignment;
- uint8_t relocatable_kernel;
- uint8_t pad2[3];
- uint32_t cmdline_max_len;
- uint32_t hardware_subarch;
- uint64_t hardware_subarch_data;
- uint32_t payload_offset;
- uint32_t payload_length;
- uint64_t setup_data;
- uint64_t pref_address;
- uint32_t init_size;
-} __packed;
+#include <syslinux/firmware.h>
#define BOOT_MAGIC 0xAA55
#define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24))
@@ -130,23 +89,6 @@ static inline uint32_t saturate32(unsigned long long v)
return (v > 0xffffffff) ? 0xffffffff : (uint32_t) v;
}
-/* Get the combined size of the initramfs */
-static addr_t initramfs_size(struct initramfs *initramfs)
-{
- struct initramfs *ip;
- addr_t size = 0;
-
- if (!initramfs)
- return 0;
-
- for (ip = initramfs->next; ip->len; ip = ip->next) {
- size = (size + ip->align - 1) & ~(ip->align - 1); /* Alignment */
- size += ip->len;
- }
-
- return size;
-}
-
/* Create the appropriate mappings for the initramfs */
static int map_initramfs(struct syslinux_movelist **fraglist,
struct syslinux_memmap **mmap,
@@ -182,10 +124,10 @@ static int map_initramfs(struct syslinux_movelist **fraglist,
return 0;
}
-int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
- struct initramfs *initramfs,
- struct setup_data *setup_data,
- char *cmdline)
+int bios_boot_linux(void *kernel_buf, size_t kernel_size,
+ struct initramfs *initramfs,
+ struct setup_data *setup_data,
+ char *cmdline)
{
struct linux_header hdr, *whdr;
size_t real_mode_size, prot_mode_size;
@@ -534,3 +476,17 @@ bail:
syslinux_free_memmap(amap);
return -1;
}
+
+int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
+ struct initramfs *initramfs,
+ struct setup_data *setup_data,
+ char *cmdline)
+{
+ if (!firmware->boot_linux) {
+ printf("No linux boot function registered for firmware\n");
+ return -1;
+ }
+
+ firmware->boot_linux(kernel_buf, kernel_size, initramfs,
+ setup_data, cmdline);
+}
diff --git a/com32/lib/syslinux/memscan.c b/com32/lib/syslinux/memscan.c
index fc676cbf..0ff25d7f 100644
--- a/com32/lib/syslinux/memscan.c
+++ b/com32/lib/syslinux/memscan.c
@@ -40,6 +40,7 @@
#include <com32.h>
#include <syslinux/memscan.h>
+#include <syslinux/firmware.h>
struct e820_entry {
uint64_t start;
@@ -47,7 +48,7 @@ struct e820_entry {
uint32_t type;
};
-int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
+int bios_scan_memory(scan_memory_callback_t callback, void *data)
{
static com32sys_t ireg;
com32sys_t oreg;
@@ -156,3 +157,8 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
return 0;
}
+
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
+{
+ return firmware->mem->scan_memory(callback, data);
+}
diff --git a/com32/lib/syslinux/serial.c b/com32/lib/syslinux/serial.c
index bb92222f..bc41acfc 100644
--- a/com32/lib/syslinux/serial.c
+++ b/com32/lib/syslinux/serial.c
@@ -32,24 +32,19 @@
*/
#include <klibc/compiler.h>
+#include <syslinux/firmware.h>
#include <syslinux/config.h>
#include <string.h>
-#include <bios.h>
-#include <core.h>
struct syslinux_serial_console_info __syslinux_serial_console_info;
void __constructor __syslinux_get_serial_console_info(void)
{
- uint16_t flowctl;
+ uint16_t iobase, divisor, flowctl;
- __syslinux_serial_console_info.iobase = SerialPort;
- __syslinux_serial_console_info.divisor = BaudDivisor;
-
- flowctl = FlowOutput | FlowInput | (FlowIgnore << 4);
-
- if (!DisplayCon)
- flowctl |= (0x80 << 8);
+ firmware->get_serial_console_info(&iobase, &divisor, &flowctl);
+ __syslinux_serial_console_info.iobase = iobase;
+ __syslinux_serial_console_info.divisor = divisor;
__syslinux_serial_console_info.flowctl = flowctl;
}
diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c
index 544915a3..d014340c 100644
--- a/com32/lib/syslinux/shuffle.c
+++ b/com32/lib/syslinux/shuffle.c
@@ -50,10 +50,12 @@ struct shuffle_descriptor {
static int shuffler_size;
-static void __constructor __syslinux_get_shuffer_size(void)
+static void __syslinux_get_shuffer_size(void)
{
- /* +15 padding is to guarantee alignment */
- shuffler_size = __bcopyxx_len + 15;
+ if (!shuffler_size) {
+ /* +15 padding is to guarantee alignment */
+ shuffler_size = __bcopyxx_len + 15;
+ }
}
/*
@@ -114,6 +116,7 @@ int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
if (!rxmap)
goto bail;
+ __syslinux_get_shuffer_size();
desc_blocks = (nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE;
for (;;) {
/* We want (desc_blocks) allocation blocks, plus the terminating
diff --git a/com32/lib/syslinux/version.c b/com32/lib/syslinux/version.c
index 1cd2efd3..6f0554d5 100644
--- a/com32/lib/syslinux/version.c
+++ b/com32/lib/syslinux/version.c
@@ -28,7 +28,7 @@
#include <syslinux/config.h>
#include <klibc/compiler.h>
#include <core.h>
-#include <../../../version.h>
+#include <version.h>
struct syslinux_version __syslinux_version;
diff --git a/com32/lib/x86_64/elf.ld b/com32/lib/x86_64/elf.ld
new file mode 100644
index 00000000..4e88bcb0
--- /dev/null
+++ b/com32/lib/x86_64/elf.ld
@@ -0,0 +1,180 @@
+/*
+ * Linker script for ELF dynamic loaded modules.
+ * This simply mirrors the 32bit linker script with minimal x86_64 changes
+ */
+
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0 + SIZEOF_HEADERS;
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+/* mouli: introduce alignment for various segments */
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+ .rel.plt : { *(.rel.plt); }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0x90909090
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0x90909090
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0x90909090
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ . = ALIGN(4);
+ .preinit_array :
+ {
+ KEEP (*(.preinit_array))
+ }
+ .init_array :
+ {
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ }
+ .fini_array :
+ {
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ }
+
+ .ctors :
+ {
+ __ctors_start = .;
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.ctors_modinit))
+ KEEP (*(.ctors_modmain))
+ __ctors_end = .;
+ }
+
+ .dtors :
+ {
+ __dtors_start = .;
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.dtors_modexit))
+ __dtors_end = .;
+ }
+
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got) }
+ /*. = DATA_SEGMENT_RELRO_END (12, .); -> This gives a "invalid assignment to location counter" error */
+ .got.plt : { *(.got.plt) }
+ .data :
+ {
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ PROVIDE (edata = .);
+ PROVIDE (_edata = .);
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ /*. = ALIGN(. != 0 ? 32 / 8 : 1);*/
+ . = ALIGN(. != 0 ? 64 / 8 : 1);
+ }
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ PROVIDE (_end = .);
+ PROVIDE (end = .);
+ /*. = DATA_SEGMENT_END (.); -> This gives a "invalid assignment to location counter" error */
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.eh_frame) }
+}
diff --git a/com32/lib/x86_64/setjmp.S b/com32/lib/x86_64/setjmp.S
new file mode 100644
index 00000000..45f547b4
--- /dev/null
+++ b/com32/lib/x86_64/setjmp.S
@@ -0,0 +1,54 @@
+#
+# arch/x86_64/setjmp.S
+#
+# setjmp/longjmp for the x86-64 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# %rbx
+# %rsp (post-return)
+# %rbp
+# %r12
+# %r13
+# %r14
+# %r15
+# <return address>
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ pop %rsi # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movq %rbx,(%rdi)
+ movq %rsp,8(%rdi) # Post-return %rsp!
+ push %rsi # Make the call/return stack happy
+ movq %rbp,16(%rdi)
+ movq %r12,24(%rdi)
+ movq %r13,32(%rdi)
+ movq %r14,40(%rdi)
+ movq %r15,48(%rdi)
+ movq %rsi,56(%rdi) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ movl %esi,%eax # Return value (int)
+ movq (%rdi),%rbx
+ movq 8(%rdi),%rsp
+ movq 16(%rdi),%rbp
+ movq 24(%rdi),%r12
+ movq 32(%rdi),%r13
+ movq 40(%rdi),%r14
+ movq 48(%rdi),%r15
+ jmp *56(%rdi)
+
+ .size longjmp,.-longjmp
diff --git a/com32/libupload/Makefile b/com32/libupload/Makefile
index 83053350..f9440c57 100644
--- a/com32/libupload/Makefile
+++ b/com32/libupload/Makefile
@@ -1,12 +1,10 @@
# Include configuration rules
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/com32.mk
-REQFLAGS += -I./
+REQFLAGS += -I$(SRC)
-SUBDIRS := .
-LIBOBJS := $(foreach dir,$(SUBDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
+LIBOBJS := $(notdir $(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
BINDIR = /usr/bin
LIBDIR = /usr/lib
@@ -34,6 +32,6 @@ install: all
mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
install -m 644 libcom32upload.a $(INSTALLROOT)$(COM32DIR)
mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
- cp -r *.h $(INSTALLROOT)$(COM32DIR)/include/
+ cp -r $(SRC)/*.h $(INSTALLROOT)$(COM32DIR)/include/
-include .*.d */.*.d */*/.*.d
diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile
index 93c0c11c..535b4aba 100644
--- a/com32/libutil/Makefile
+++ b/com32/libutil/Makefile
@@ -29,8 +29,7 @@
## Utility companion library for the COM32 library
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
LIBOBJS = ansiline.o ansiraw.o keyname.o \
diff --git a/com32/lua/src/Makefile b/com32/lua/src/Makefile
index 01d1f81c..70a7e808 100644
--- a/com32/lua/src/Makefile
+++ b/com32/lua/src/Makefile
@@ -15,8 +15,7 @@
## Lua Makefile
##
-topdir = ../../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
LNXLIBS =
diff --git a/com32/mboot/Makefile b/com32/mboot/Makefile
index 02e9f49e..a3f61ba8 100644
--- a/com32/mboot/Makefile
+++ b/com32/mboot/Makefile
@@ -15,11 +15,10 @@
## Multiboot module
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-LNXLIBS = ../libutil/libutil_lnx.a
+LNXLIBS = $(objdir)/com32/libutil/libutil_lnx.a
MODULES = mboot.c32
TESTFILES =
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index b7719456..9f7a0e46 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -14,24 +14,23 @@
## Simple menu system
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-LNXLIBS = ../libutil/libutil_lnx.a
+LNXLIBS = $(objdir)/com32/libutil/libutil_lnx.a
MODULES = menu.c32 vesamenu.c32
TESTFILES =
-COMMONOBJS = menumain.o readconfig.o passwd.o drain.o printmsg.o colors.o \
- background.o refstr.o
+COMMONOBJS = menumain.o readconfig.o passwd.o drain.o \
+ printmsg.o colors.o background.o refstr.o
all: $(MODULES) $(TESTFILES)
-menu.c32 : menu.o $(COMMONOBJS) $(C_LIBS)
+vesamenu.c32: vesamenu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
-vesamenu.c32 : vesamenu.o $(COMMONOBJS) $(C_LIBS)
+menu.c32: menu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 9cf4da8e..e794b3b9 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -15,8 +15,7 @@
## COM32 standard modules
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
diff --git a/com32/modules/ls.c b/com32/modules/ls.c
index 11c18ae0..47eacdbc 100644
--- a/com32/modules/ls.c
+++ b/com32/modules/ls.c
@@ -172,4 +172,4 @@ int main(int argc, char *argv[])
return rv ? 1 : 0;
}
-
+
diff --git a/com32/modules/zzjson.c b/com32/modules/zzjson.c
index e2516fa1..a126b8f0 100644
--- a/com32/modules/zzjson.c
+++ b/com32/modules/zzjson.c
@@ -21,7 +21,13 @@ static void myerror(void *ehandle, const char *format, ...) {
int main(int argc, char *argv[])
{
+#if 0
+ /* this hangs! */
openconsole(&dev_rawcon_r, &dev_stdcon_w);
+#else
+ /* this works */
+ openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
(void) argc;
(void) argv;
ZZJSON *tmp;
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index a894c847..a4c0bc28 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -16,10 +16,10 @@
## ROSH Read Only Shell
##
-LIBS = $(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
+LIBS = $(objdir)/com32/libutil/libutil_com.c32 \
+ $(objdir)/com32/lib/libcom32.c32
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/rosh.mk
# from com32/sysdump/Makefile
@@ -36,12 +36,12 @@ endif
CFLAGS += -DDATE='"$(DATE)"'
LNXCFLAGS += -DDATE='"$(DATE)"'
+all: rosh.c32
+
rosh.o: rosh.h
rosh.lo: rosh.h
-all: rosh.c32
-
allgrc: rosh.c32 rosh.lnx
tidy dist:
diff --git a/com32/rosh/rosh.c b/com32/rosh/rosh.c
index 68dad3f3..8198a2ba 100644
--- a/com32/rosh/rosh.c
+++ b/com32/rosh/rosh.c
@@ -37,7 +37,7 @@
* debugging enabled; Comment to remove.
*/
#include "rosh.h"
-#include "../../version.h"
+#include "version.h"
#define APP_LONGNAME "Read-Only Shell"
#define APP_NAME "rosh"
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index c7abaddb..ca04f644 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -14,17 +14,16 @@
## samples for syslinux users
##
-LIBS = $(com32)/libutil/libutil_com.c32
+LIBS = $(objdir)/com32/libutil/libutil_com.c32
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
all: hello.c32 resolv.c32 serialinfo.c32 \
- localboot.c32 \
- fancyhello.c32 fancyhello.lnx \
- keytest.c32 keytest.lnx \
- advdump.c32 entrydump.c32
+ localboot.c32 \
+ fancyhello.c32 fancyhello.lnx \
+ keytest.c32 keytest.lnx \
+ advdump.c32 entrydump.c32
tidy dist:
rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
diff --git a/com32/samples/advdump.c b/com32/samples/advdump.c
index 2c786416..83fe8381 100644
--- a/com32/samples/advdump.c
+++ b/com32/samples/advdump.c
@@ -27,7 +27,13 @@ int main(void)
size_t s = syslinux_adv_size();
char buf[256];
+#if 0
+ /* this hangs! */
openconsole(&dev_stdcon_r, &dev_stdcon_w);
+#else
+ /* this works */
+ openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
p = syslinux_adv_ptr();
diff --git a/com32/samples/entrydump.c b/com32/samples/entrydump.c
index d50859f4..56a683e3 100644
--- a/com32/samples/entrydump.c
+++ b/com32/samples/entrydump.c
@@ -36,7 +36,13 @@ int main(void)
const union syslinux_derivative_info *di;
const struct stack_frame *sf;
+#if 0
+ /* this hangs! */
openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+ /* this works */
+ openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
di = syslinux_derivative_info();
diff --git a/com32/samples/resolv.c b/com32/samples/resolv.c
index f4a0e52a..8f062d19 100644
--- a/com32/samples/resolv.c
+++ b/com32/samples/resolv.c
@@ -32,7 +32,13 @@ int main(int argc, char *argv[])
{
uint32_t ip;
+#if 0
+ /* this hangs! */
openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+ /* this works */
+ openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
if (argc < 2) {
fputs("Usage: resolv hostname\n", stderr);
diff --git a/com32/samples/serialinfo.c b/com32/samples/serialinfo.c
index 10d02521..2936b4e5 100644
--- a/com32/samples/serialinfo.c
+++ b/com32/samples/serialinfo.c
@@ -25,7 +25,13 @@ int main(void)
{
const struct syslinux_serial_console_info *si;
+#if 0
+ /* this hangs! */
openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+ /* this works */
+ openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
si = syslinux_serial_console_info();
diff --git a/com32/sysdump/Makefile b/com32/sysdump/Makefile
index 8763b3c8..dca5d717 100644
--- a/com32/sysdump/Makefile
+++ b/com32/sysdump/Makefile
@@ -15,21 +15,20 @@
## Simple menu system
##
-topdir = ../..
-MAKEDIR = $(topdir)/mk
+VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-include $(topdir)/version.mk
-LIBS = ../libupload/libcom32upload.a
-LNXLIBS = ../libutil/libutil_lnx.a
+LIBS = $(objdir)/com32/libupload/libcom32upload.a
+LNXLIBS = $(objdir)/com32/libutil/libutil_lnx.a
CFLAGS += -I$(com32) -I$(topdir)
MODULES = sysdump.c32
TESTFILES =
-SRCS = $(wildcard *.c)
-OBJS = $(patsubst %.c,%.o,$(SRCS))
+SRCS = $(wildcard $(SRC)/*.c)
+OBJS = $(subst $(SRC)/,,$(patsubst %.c,%.o,$(SRCS)))
# The DATE is set on the make command line when building binaries for
# official release. Otherwise, substitute a hex string that is pretty much
diff --git a/com32/sysdump/cpuid.c b/com32/sysdump/cpuid.c
index e7fc5767..846b5408 100644
--- a/com32/sysdump/cpuid.c
+++ b/com32/sysdump/cpuid.c
@@ -20,10 +20,21 @@ struct cpuid_info {
static void get_cpuid(uint32_t eax, uint32_t ecx, struct cpuid_data *data)
{
+#if __SIZEOF_POINTER__ == 4
asm("pushl %%ebx ; cpuid ; movl %%ebx,%1 ; popl %%ebx"
: "=a" (data->eax), "=r" (data->ebx),
"=c" (data->ecx), "=d" (data->edx)
: "a" (eax), "c" (ecx));
+#elif __SIZEOF_POINTER__ == 8
+ asm volatile("push %%rbx; cpuid; movl %%ebx, %1; pop %%rbx"
+ : "=a" (data->eax),
+ "=b" (data->ebx),
+ "=c" (data->ecx),
+ "=d" (data->edx)
+ : "a" (eax), "c" (ecx));
+#else
+#error "unsupported architecture"
+#endif
}
#define CPUID_CHUNK 128
diff --git a/com32/tools/Makefile b/com32/tools/Makefile
index 0161baf1..9c0ea708 100644
--- a/com32/tools/Makefile
+++ b/com32/tools/Makefile
@@ -10,12 +10,12 @@
##
## -----------------------------------------------------------------------
-MAKEDIR = ../../mk
+VPATH = $(SRC)
include $(MAKEDIR)/build.mk
BINS = relocs
-INCLUDES += -I./include
+INCLUDES += -I$(SRC)/include
all : $(BINS)