aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-12-07 11:33:45 +0000
committerMatt Fleming <matt.fleming@intel.com>2012-12-07 11:33:45 +0000
commit10f6cf6eef0a7da7dad1933efdbfb101155792d0 (patch)
treed8ee3bfc6e55e739e0f135cd6d945955c670dd46 /com32
parent35928ee37da523e5f992cc462a4a4193d0bfaa4c (diff)
parentddb10ce99c327888ade4d2ba3e4c50ad12aaa059 (diff)
downloadsyslinux-10f6cf6eef0a7da7dad1933efdbfb101155792d0.tar.gz
syslinux-10f6cf6eef0a7da7dad1933efdbfb101155792d0.tar.xz
syslinux-10f6cf6eef0a7da7dad1933efdbfb101155792d0.zip
Merge tag 'syslinux-5.00' into firmwaresyslinux-6.00-pre3
Conflicts: Makefile com32/elflink/ldlinux/Makefile com32/lib/sys/module/elf_module.c core/cleanup.c core/comboot.inc core/conio.c core/fs/fs.c core/init.c core/mem/free.c core/mem/malloc.c core/timer.inc diag/geodsp/Makefile extlinux/main.c mk/embedded.mk modules/Makefile Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'com32')
-rw-r--r--com32/cmenu/libmenu/syslnx.c52
-rw-r--r--com32/elflink/ldlinux/Makefile5
-rw-r--r--com32/elflink/ldlinux/adv.c4
-rw-r--r--com32/elflink/ldlinux/advwrite.c3
-rw-r--r--com32/elflink/ldlinux/chainboot.c4
-rw-r--r--com32/elflink/ldlinux/cli.c44
-rw-r--r--com32/elflink/ldlinux/config.h2
-rw-r--r--com32/elflink/ldlinux/execute.c32
-rw-r--r--com32/elflink/ldlinux/get_key.c2
-rw-r--r--com32/elflink/ldlinux/getadv.c2
-rw-r--r--com32/elflink/ldlinux/ldlinux.c85
-rw-r--r--com32/elflink/ldlinux/msg.c214
-rw-r--r--com32/elflink/ldlinux/readconfig.c33
-rw-r--r--com32/elflink/ldlinux/setadv.c2
-rw-r--r--com32/gpllib/Makefile2
-rw-r--r--com32/hdt/hdt-cli.c2
-rw-r--r--com32/include/cli.h2
-rw-r--r--com32/include/klibc/compiler.h2
-rw-r--r--com32/include/menu.h1
-rw-r--r--com32/include/stdio.h6
-rw-r--r--com32/include/syslinux/boot.h1
-rw-r--r--com32/include/syslinux/features.h48
-rw-r--r--com32/lib/asprintf.c5
-rw-r--r--com32/lib/bufprintf.c8
-rw-r--r--com32/lib/free.c113
-rw-r--r--com32/lib/malloc.c155
-rw-r--r--com32/lib/realloc.c98
-rw-r--r--com32/lib/sys/module/common.c8
-rw-r--r--com32/lib/sys/module/elf_module.c19
-rw-r--r--com32/lib/sys/module/exec.c24
-rw-r--r--com32/lib/sys/module/i386/elf_module.c21
-rw-r--r--com32/lib/sys/module/x86_64/elf_module.c21
-rw-r--r--com32/lib/sys/screensize.c2
-rw-r--r--com32/lib/sys/vesa/background.c1
-rw-r--r--com32/lib/syslinux/runimage.c26
-rw-r--r--com32/lib/zalloc.c17
-rw-r--r--com32/menu/menumain.c10
-rw-r--r--com32/menu/readconfig.c7
-rw-r--r--com32/sysdump/README2
39 files changed, 444 insertions, 641 deletions
diff --git a/com32/cmenu/libmenu/syslnx.c b/com32/cmenu/libmenu/syslnx.c
index c681f585..5060c5db 100644
--- a/com32/cmenu/libmenu/syslnx.c
+++ b/com32/cmenu/libmenu/syslnx.c
@@ -19,16 +19,6 @@
com32sys_t inreg, outreg; // Global registers for this module
-char issyslinux(void)
-{
- REG_EAX(inreg) = 0x00003000;
- REG_EBX(inreg) = REG_ECX(inreg) = REG_EDX(inreg) = 0xFFFFFFFF;
- __intcall(0x21, &inreg, &outreg);
- return (REG_EAX(outreg) == 0x59530000) &&
- (REG_EBX(outreg) == 0x4c530000) &&
- (REG_ECX(outreg) == 0x4e490000) && (REG_EDX(outreg) == 0x58550000);
-}
-
void runsyslinuxcmd(const char *cmd)
{
char *bounce;
@@ -60,43 +50,15 @@ unsigned int getversion(char *deriv, unsigned int *numfun)
return __syslinux_version.version;
}
-void runsyslinuximage(const char *cmd, long ipappend)
+char issyslinux(void)
{
- unsigned int numfun = 0;
- char *ptr, *cmdline;
- char *bounce;
+ return !!getversion(NULL, NULL);
+}
+void runsyslinuximage(const char *cmd, long ipappend)
+{
(void)ipappend; // XXX: Unused?!
- getversion(NULL, &numfun);
- // Function 16h not supported Fall back to runcommand
- if (numfun < 0x16)
- runsyslinuxcmd(cmd);
- // Try the Run Kernel Image function
- // Split command line into
- bounce = lmalloc(strlen(cmd) + 1);
- if (!bounce)
- return;
-
- strcpy(bounce, cmd);
- ptr = bounce;
- // serach for first space or end of string
- while ((*ptr) && (*ptr != ' '))
- ptr++;
- if (!*ptr)
- cmdline = ptr; // no command line
- else {
- *ptr++ = '\0'; // terminate kernal name
- cmdline = ptr + 1;
- while (*cmdline != ' ')
- cmdline++; // find first non-space
- }
- // Now call the interrupt
- REG_BX(inreg) = OFFS(cmdline);
- REG_ES(inreg) = SEG(cmdline);
- REG_SI(inreg) = OFFS(bounce);
- REG_DS(inreg) = SEG(bounce);
- REG_EDX(inreg) = 0;
-
- __intcall(0x22, &inreg, &outreg); // If successful does not return
+ getversion(NULL, NULL);
+ runsyslinuxcmd(cmd);
}
diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index 7da6e287..aa35f475 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -13,18 +13,19 @@
VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
-CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib
+CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib -fvisibility=hidden
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
+ eprintf.o loadhigh.o msg.o
all: ldlinux.c32 ldlinux_lnx.a
ldlinux.c32 : $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
LNXLIBOBJS = get_key.lo
ldlinux_lnx.a: $(LNXLIBOBJS)
rm -f $@
diff --git a/com32/elflink/ldlinux/adv.c b/com32/elflink/ldlinux/adv.c
index ae473908..677fe92d 100644
--- a/com32/elflink/ldlinux/adv.c
+++ b/com32/elflink/ldlinux/adv.c
@@ -35,8 +35,8 @@
#include <syslinux/firmware.h>
#include <klibc/compiler.h>
-void *__syslinux_adv_ptr;
-size_t __syslinux_adv_size;
+__export void *__syslinux_adv_ptr;
+__export size_t __syslinux_adv_size;
void __constructor __syslinux_init(void)
{
diff --git a/com32/elflink/ldlinux/advwrite.c b/com32/elflink/ldlinux/advwrite.c
index 95a311a8..47e45534 100644
--- a/com32/elflink/ldlinux/advwrite.c
+++ b/com32/elflink/ldlinux/advwrite.c
@@ -31,10 +31,11 @@
* Write back the ADV
*/
+#include <klibc/compiler.h>
#include <syslinux/adv.h>
#include <syslinux/firmware.h>
-int syslinux_adv_write(void)
+__export int syslinux_adv_write(void)
{
return firmware->adv_ops->write();
}
diff --git a/com32/elflink/ldlinux/chainboot.c b/com32/elflink/ldlinux/chainboot.c
index 4a4a2e1a..ff19c530 100644
--- a/com32/elflink/ldlinux/chainboot.c
+++ b/com32/elflink/ldlinux/chainboot.c
@@ -54,10 +54,8 @@ void chainboot_file(const char *file, uint32_t type)
goto bail;
rv = open_file(file, &fd);
- if (rv == -1) {
- free(buf);
+ if (rv == -1)
goto bail;
- }
reg.eax.l = max;
reg.ebx.l = 0;
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index ebeaeece..b94c6835 100644
--- a/com32/elflink/ldlinux/cli.c
+++ b/com32/elflink/ldlinux/cli.c
@@ -119,12 +119,11 @@ static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
const char *edit_cmdline(const char *input, int top /*, int width */ ,
int (*pDraw_Menu) (int, int, int),
- void (*show_fkey) (int))
+ void (*show_fkey) (int), bool *timedout)
{
- static char cmdline[MAX_CMDLINE_LEN];
- char temp_cmdline[MAX_CMDLINE_LEN] = { };
+ char cmdline[MAX_CMDLINE_LEN] = { };
int key, len, prev_len, cursor;
- int redraw = 1; /* We enter with the menu already drawn */
+ int redraw = 0;
int x, y;
bool done = false;
const char *ret;
@@ -139,12 +138,17 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
width = 80;
}
- cmdline[MAX_CMDLINE_LEN - 1] = '\0';
-
len = cursor = 0;
prev_len = 0;
x = y = 0;
+ /*
+ * Before we start messing with the x,y coordinates print 'input'
+ * so that it follows whatever text has been written to the screen
+ * previously.
+ */
+ eprintf("%s ", input);
+
while (!done) {
if (redraw > 1) {
/* Clear and redraw whole screen */
@@ -154,6 +158,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
if (pDraw_Menu)
(*pDraw_Menu) (-1, top, 1);
prev_len = 0;
+ eprintf("\033[2J\033[H");
// printf("\033[0m\033[2J\033[H");
}
@@ -164,8 +169,6 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
/* Redraw the command line */
eprintf("\033[?7l\033[?25l");
- if (y)
- eprintf("\033[%dA", y);
eprintf("\033[1G%s ", input);
x = strlen(input);
@@ -202,6 +205,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
switch (key) {
case KEY_NONE:
/* We timed out. */
+ *timedout = true;
return NULL;
case KEY_CTRL('L'):
@@ -214,12 +218,6 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
done = true;
break;
- case KEY_ESC:
- case KEY_CTRL('C'):
- ret = NULL;
- done = true;
- break;
-
case KEY_BACKSPACE:
case KEY_DEL:
if (cursor) {
@@ -351,11 +349,9 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
comm_counter =
list_entry(next, typeof(*comm_counter), list);
- if (&comm_counter->list == &cli_history_head) {
- strcpy(cmdline, temp_cmdline);
- } else {
+ if (&comm_counter->list != &cli_history_head)
strcpy(cmdline, comm_counter->command);
- }
+
cursor = len = strlen(cmdline);
redraw = 1;
}
@@ -375,11 +371,9 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
comm_counter =
list_entry(prev, typeof(*comm_counter), list);
- if (&comm_counter->list == &cli_history_head) {
- strcpy(cmdline, temp_cmdline);
- } else {
+ if (&comm_counter->list != &cli_history_head)
strcpy(cmdline, comm_counter->command);
- }
+
cursor = len = strlen(cmdline);
redraw = 1;
}
@@ -435,9 +429,8 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
default:
if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
if (cursor == len) {
- temp_cmdline[len] = key;
cmdline[len++] = key;
- temp_cmdline[len] = cmdline[len] = '\0';
+ cmdline[len] = '\0';
putchar(key);
cursor++;
x++;
@@ -450,9 +443,6 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
} else {
memmove(cmdline + cursor + 1, cmdline + cursor,
len - cursor + 1);
- memmove(temp_cmdline + cursor + 1, temp_cmdline + cursor,
- len - cursor + 1);
- temp_cmdline[cursor] = key;
cmdline[cursor++] = key;
len++;
redraw = 1;
diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h
index 63e33b69..c551fb19 100644
--- a/com32/elflink/ldlinux/config.h
+++ b/com32/elflink/ldlinux/config.h
@@ -48,5 +48,7 @@ extern int new_linux_kernel(char *okernel, char *ocmdline);
extern void pm_load_high(com32sys_t *regs);
extern void ldlinux_enter_command(void);
+extern void ldlinux_console_init(void);
+extern const char *apply_extension(const char *kernel, const char *ext);
#endif /* __CONFIG_H__ */
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 6ccde49d..727df50a 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -39,7 +39,6 @@ const struct image_types image_boot_types[] = {
{ "bss", IMAGE_TYPE_BSS },
{ "pxe", IMAGE_TYPE_PXE },
{ "fdimage", IMAGE_TYPE_FDIMAGE },
- { "comboot", IMAGE_TYPE_COMBOOT },
{ "com32", IMAGE_TYPE_COM32 },
{ "config", IMAGE_TYPE_CONFIG },
{ NULL, 0 },
@@ -47,7 +46,7 @@ const struct image_types image_boot_types[] = {
extern int create_args_and_load(char *);
-void execute(const char *cmdline, uint32_t type)
+__export void execute(const char *cmdline, uint32_t type)
{
const char *kernel, *args;
const char *p;
@@ -84,7 +83,17 @@ void execute(const char *cmdline, uint32_t type)
const struct image_types *t;
for (t = image_boot_types; t->name; t++) {
if (!strcmp(kernel + 1, t->name)) {
- /* Strip the type specifier and retry */
+ /*
+ * Strip the type specifier, apply the
+ * filename extension if COM32 and
+ * retry.
+ */
+ if (t->type == IMAGE_TYPE_COM32) {
+ p = apply_extension(p, ".c32");
+ if (!p)
+ return;
+ }
+
execute(p, t->type);
return;
}
@@ -92,8 +101,15 @@ void execute(const char *cmdline, uint32_t type)
}
if (type == IMAGE_TYPE_COM32) {
+ /*
+ * We may be called with the console in an unknown
+ * state, so initialise it.
+ */
+ ldlinux_console_init();
+
/* new entry for elf format c32 */
- create_args_and_load((char *)cmdline);
+ if (create_args_and_load((char *)cmdline))
+ printf("Failed to load COM32 file %s\n", kernel);
/*
* The old COM32 module code would run the module then
@@ -102,9 +118,14 @@ void execute(const char *cmdline, uint32_t type)
* e.g. from vesamenu.c32.
*/
unload_modules_since("ldlinux.c32");
+
+ /* Restore the console */
+ ldlinux_console_init();
+
ldlinux_enter_command();
} else if (type == IMAGE_TYPE_CONFIG) {
char *argv[] = { "ldlinux.c32", NULL };
+ int rv;
/* kernel contains the config file name */
realpath(ConfigName, kernel, FILENAME_MAX);
@@ -113,7 +134,8 @@ void execute(const char *cmdline, uint32_t type)
if (*args)
mangle_name(config_cwd, args);
- start_ldlinux(argv);
+ rv = start_ldlinux(argv);
+ printf("Failed to exec ldlinux.c32: %s\n", strerror(rv));
} else if (type == IMAGE_TYPE_LOCALBOOT) {
local_boot(strtoul(kernel, NULL, 0));
} else if (type == IMAGE_TYPE_PXE || type == IMAGE_TYPE_BSS ||
diff --git a/com32/elflink/ldlinux/get_key.c b/com32/elflink/ldlinux/get_key.c
index 123171ae..cece0f81 100644
--- a/com32/elflink/ldlinux/get_key.c
+++ b/com32/elflink/ldlinux/get_key.c
@@ -166,7 +166,7 @@ int raw_read(int fd, void *buf, size_t count)
extern int raw_read(int fd, void *buf, size_t count);
#endif
-int get_key(FILE * f, clock_t timeout)
+__export int get_key(FILE * f, clock_t timeout)
{
char buffer[KEY_MAXLEN];
int nc, rv;
diff --git a/com32/elflink/ldlinux/getadv.c b/com32/elflink/ldlinux/getadv.c
index 5578313e..1c27f1b8 100644
--- a/com32/elflink/ldlinux/getadv.c
+++ b/com32/elflink/ldlinux/getadv.c
@@ -36,7 +36,7 @@
#include <klibc/compiler.h>
#include <inttypes.h>
-const void *syslinux_getadv(int tag, size_t * size)
+__export const void *syslinux_getadv(int tag, size_t * size)
{
const uint8_t *p;
size_t left;
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 59c55980..6f9f20fa 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -21,8 +21,6 @@ struct file_ext {
};
static const struct file_ext file_extensions[] = {
- { ".com", IMAGE_TYPE_COMBOOT },
- { ".cbt", IMAGE_TYPE_COMBOOT },
{ ".c32", IMAGE_TYPE_COM32 },
{ ".img", IMAGE_TYPE_FDIMAGE },
{ ".bss", IMAGE_TYPE_BSS },
@@ -46,7 +44,7 @@ static inline const char *find_command(const char *str)
return p;
}
-uint32_t parse_image_type(const char *kernel)
+__export uint32_t parse_image_type(const char *kernel)
{
const struct file_ext *ext;
const char *p;
@@ -102,7 +100,7 @@ static const char *get_extension(const char *kernel)
return NULL;
}
-static const char *apply_extension(const char *kernel, const char *ext)
+const char *apply_extension(const char *kernel, const char *ext)
{
const char *p;
char *k;
@@ -121,12 +119,15 @@ static const char *apply_extension(const char *kernel, const char *ext)
memcpy(k, kernel, len);
/* Append the extension */
- memcpy(k + len, ext, elen);
+ if (strncmp(p - elen, ext, elen)) {
+ memcpy(k + len, ext, elen);
+ len += elen;
+ }
/* Copy the rest of the command line */
- strcpy(k + len + elen, p);
+ strcpy(k + len, p);
- k[len + elen + strlen(p)] = '\0';
+ k[len + strlen(p)] = '\0';
return k;
}
@@ -138,7 +139,7 @@ static const char *apply_extension(const char *kernel, const char *ext)
* the the kernel. If we return the caller should call enter_cmdline()
* so that the user can help us out.
*/
-void load_kernel(const char *command_line)
+__export void load_kernel(const char *command_line)
{
struct menu_entry *me;
const char *cmdline;
@@ -201,28 +202,14 @@ bad_kernel:
* line.
*/
if (onerrorlen) {
- rsprintf(&cmdline, "%s %s", onerror, default_cmd);
- execute(cmdline, IMAGE_TYPE_COM32);
- }
-}
-
-static void enter_cmdline(void)
-{
- const char *cmdline;
-
- /* Enter endless command line prompt, should support "exit" */
- while (1) {
- cmdline = edit_cmdline("boot:", 1, NULL, cat_help_file);
- printf("\n");
-
- /* return if user only press enter or we timed out */
- if (!cmdline || cmdline[0] == '\0') {
- if (ontimeoutlen)
- load_kernel(ontimeout);
- return;
- }
-
- load_kernel(cmdline);
+ me = find_label(onerror);
+ if (me)
+ rsprintf(&cmdline, "%s %s", me->cmdline, default_cmd);
+ else
+ rsprintf(&cmdline, "%s %s", onerror, default_cmd);
+
+ type = parse_image_type(cmdline);
+ execute(cmdline, type);
}
}
@@ -241,10 +228,35 @@ void ldlinux_auto_boot(void)
load_kernel(default_cmd);
}
+static void enter_cmdline(void)
+{
+ const char *cmdline;
+
+ /* Enter endless command line prompt, should support "exit" */
+ while (1) {
+ bool to = false;
+
+ if (noescape) {
+ ldlinux_auto_boot();
+ continue;
+ }
+
+ cmdline = edit_cmdline("boot:", 1, NULL, cat_help_file, &to);
+ printf("\n");
+
+ /* return if user only press enter or we timed out */
+ if (!cmdline || cmdline[0] == '\0') {
+ if (to && ontimeoutlen)
+ load_kernel(ontimeout);
+ else
+ ldlinux_auto_boot();
+ } else
+ load_kernel(cmdline);
+ }
+}
+
void ldlinux_enter_command(void)
{
- if (noescape)
- ldlinux_auto_boot();
enter_cmdline();
}
@@ -259,14 +271,19 @@ static void __destructor close_console(void)
close(i);
}
-int main(int argc __unused, char **argv __unused)
+void ldlinux_console_init(void)
+{
+ openconsole(&dev_stdcon_r, &dev_ansiserial_w);
+}
+
+__export int main(int argc __unused, char **argv __unused)
{
const void *adv;
const char *cmdline;
size_t count = 0;
char *config_argv[2] = { NULL, NULL };
- openconsole(&dev_stdcon_r, &dev_ansiserial_w);
+ ldlinux_console_init();
if (ConfigName[0])
config_argv[0] = ConfigName;
diff --git a/com32/elflink/ldlinux/msg.c b/com32/elflink/ldlinux/msg.c
new file mode 100644
index 00000000..2efcc792
--- /dev/null
+++ b/com32/elflink/ldlinux/msg.c
@@ -0,0 +1,214 @@
+#include <com32.h>
+#include <stdio.h>
+#include <bios.h>
+#include <graphics.h>
+
+static uint8_t TextAttribute; /* Text attribute for message file */
+static uint8_t DisplayMask; /* Display modes mask */
+
+/* Routine to interpret next print char */
+static void (*NextCharJump)(uint8_t);
+
+void msg_initvars(void);
+static void msg_setfg(uint8_t data);
+static void msg_putchar(uint8_t ch);
+
+/*
+ *
+ * get_msg_file: Load a text file and write its contents to the screen,
+ * interpreting color codes.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int get_msg_file(char *filename)
+{
+ FILE *f;
+ char ch;
+
+ f = fopen(filename, "r");
+ if (!f)
+ return -1;
+
+ TextAttribute = 0x7; /* Default grey on white */
+ DisplayMask = 0x7; /* Display text in all modes */
+ msg_initvars();
+
+ /*
+ * Read the text file a byte at a time and interpret that
+ * byte.
+ */
+ while ((ch = getc(f)) != EOF) {
+ /* DOS EOF? */
+ if (ch == 0x1A)
+ break;
+
+ /*
+ * 01h = text mode
+ * 02h = graphics mode
+ */
+ UsingVGA &= 0x1;
+ UsingVGA += 1;
+
+ NextCharJump(ch); /* Do what shall be done */
+ }
+
+ fclose(f);
+ return 0;
+}
+
+static void msg_setbg(uint8_t data)
+{
+ if (unhexchar(&data) == 0) {
+ data <<= 4;
+ if (DisplayMask & UsingVGA) {
+ TextAttribute = data;
+ }
+
+ NextCharJump = msg_setfg;
+ } else {
+ TextAttribute = 0x7; /* Default attribute */
+ NextCharJump = msg_putchar;
+ }
+}
+
+static void msg_setfg(uint8_t data)
+{
+ if (unhexchar(&data) == 0) {
+ if (DisplayMask & UsingVGA) {
+ /* setbg set foreground to 0 */
+ TextAttribute |= data;
+ }
+ } else
+ TextAttribute = 0x7; /* Default attribute */
+
+ NextCharJump = msg_putchar;
+}
+
+static inline void msg_ctrl_o(void)
+{
+ NextCharJump = msg_setbg;
+}
+
+static void msg_novga(void)
+{
+ syslinux_force_text_mode();
+ msg_initvars();
+}
+
+static void msg_viewimage(void)
+{
+ FILE *f;
+
+ *VGAFilePtr = '\0'; /* Zero-terminate filename */
+
+ mangle_name(VGAFileMBuf, VGAFileBuf);
+ f = fopen(VGAFileMBuf, "r");
+ if (!f) {
+ /* Not there */
+ NextCharJump = msg_putchar;
+ return;
+ }
+
+ vgadisplayfile(f);
+ fclose(f);
+ msg_initvars();
+}
+
+/*
+ * Getting VGA filename
+ */
+static void msg_filename(uint8_t data)
+{
+ /* <LF> = end of filename */
+ if (data == 0x0A) {
+ msg_viewimage();
+ return;
+ }
+
+ /* Ignore space/control char */
+ if (data > ' ') {
+ if ((char *)VGAFilePtr < (VGAFileBuf + sizeof(VGAFileBuf)))
+ *VGAFilePtr++ = data;
+ }
+}
+
+static void msg_vga(void)
+{
+ NextCharJump = msg_filename;
+ VGAFilePtr = (uint16_t *)VGAFileBuf;
+}
+
+/* Convert ANSI colors to PC display attributes */
+static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+static void msg_normal(uint8_t data)
+{
+ uint8_t bg, fg;
+
+ /* Write to serial port */
+ if (DisplayMask & 0x4)
+ write_serial(data);
+
+ if (!(DisplayMask & UsingVGA))
+ return; /* Not screen */
+
+ if (!(DisplayCon & 0x01))
+ return;
+
+ fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
+ bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
+
+ printf("\033[");
+ if (TextAttribute & 0x40)
+ printf("1;"); /* Foreground bright */
+
+ printf("3%dm\033[", fg);
+
+ if (TextAttribute & 0x80)
+ printf("5;"); /* Foreground blink */
+
+ printf("4%dm%c\033[0m", bg, data);
+}
+
+static void msg_modectl(uint8_t data)
+{
+ data &= 0x07;
+ DisplayMask = data;
+ NextCharJump = msg_putchar;
+}
+
+static void msg_putchar(uint8_t ch)
+{
+ /* 10h to 17h are mode controls */
+ if (ch >= 0x10 && ch < 0x18) {
+ msg_modectl(ch);
+ return;
+ }
+
+ switch (ch) {
+ case 0x0F: /* ^O = color code follows */
+ msg_ctrl_o();
+ break;
+ case 0x0D: /* Ignore <CR> */
+ break;
+ case 0x19: /* <EM> = return to text mode */
+ msg_novga();
+ break;
+ case 0x18: /* <CAN> = VGA filename follows */
+ msg_vga();
+ break;
+ default:
+ msg_normal(ch);
+ break;
+ }
+}
+
+/*
+ * Subroutine to initialize variables, also needed after loading
+ * graphics file.
+ */
+void msg_initvars(void)
+{
+ /* Initialize state machine */
+ NextCharJump = msg_putchar;
+}
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index 2fa0641e..6a419c6d 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -80,12 +80,13 @@ short includelevel = 1; //nesting level
short defaultlevel = 0; //the current level of default
short vkernel = 0; //have we seen any "label" statements?
short displaycon = 1; //conio.inc
-short nohalt = 1; //idle.inc
+extern short NoHalt; //idle.c
-const char *default_cmd = NULL; //"default" command line
const char *onerror = NULL; //"onerror" command line
const char *ontimeout = NULL; //"ontimeout" command line
+__export const char *default_cmd = NULL; //"default" command line
+
/* Empty refstring */
const char *empty_string;
@@ -599,7 +600,7 @@ uint32_t parse_argb(char **p)
//static const char *append = NULL;
extern const char *append;
//static unsigned int ipappend = 0;
-unsigned int ipappend = 0;
+__export unsigned int ipappend = 0;
extern uint16_t PXERetry;
static struct labeldata ld;
@@ -636,21 +637,7 @@ static char *is_message_name(char *cmdstr, enum message_number *msgnr)
return NULL;
}
-static int cat_file(const char *filename)
-{
- FILE *f;
- char line[2048];
-
- f = fopen(filename, "r");
- if (!f)
- return -1;
-
- while (fgets(line, sizeof(line), f) != NULL)
- eprintf("%s", line);
-
- fclose(f);
- return 0;
-}
+extern void get_msg_file(char *);
void cat_help_file(int key)
{
@@ -704,7 +691,7 @@ void cat_help_file(int key)
if (cm->fkeyhelp[fkey].textname) {
eprintf("\n");
- cat_file(cm->fkeyhelp[fkey].textname);
+ get_msg_file((char *)cm->fkeyhelp[fkey].textname);
}
}
@@ -732,7 +719,7 @@ extern uint8_t FlowInput;
extern uint8_t FlowOutput;
extern uint16_t SerialPort;
extern uint16_t BaudDivisor;
-extern uint8_t SerialNotice;
+static uint8_t SerialNotice = 1;
#define DEFAULT_BAUD 9600
#define BAUD_DIVISOR 115200
@@ -748,7 +735,6 @@ static inline void io_delay(void)
outb(0, 0x80);
}
-extern void get_msg_file(char *);
extern void loadfont(char *);
extern void loadkeys(char *);
@@ -1196,7 +1182,7 @@ do_include:
} else if (looking_at(p, "nocomplete")) {
nocomplete = atoi(skipspace(p + 10));
} else if (looking_at(p, "nohalt")) {
- nohalt = atoi(skipspace(p + 8));
+ NoHalt = atoi(skipspace(p + 8));
} else if (looking_at(p, "onerror")) {
refstr_put(m->onerror);
m->onerror = refstrdup(skipspace(p + 7));
@@ -1368,7 +1354,8 @@ static int parse_one_config(const char *filename)
parse_config_file(f);
if (config_cwd[0]) {
- chdir(config_cwd);
+ if (chdir(config_cwd) < 0)
+ printf("Failed to chdir to %s\n", config_cwd);
config_cwd[0] = '\0';
}
diff --git a/com32/elflink/ldlinux/setadv.c b/com32/elflink/ldlinux/setadv.c
index 40f00a4e..2e386213 100644
--- a/com32/elflink/ldlinux/setadv.c
+++ b/com32/elflink/ldlinux/setadv.c
@@ -45,7 +45,7 @@
#include <errno.h>
#include <alloca.h>
-int syslinux_setadv(int tag, size_t size, const void *data)
+__export int syslinux_setadv(int tag, size_t size, const void *data)
{
uint8_t *p, *advtmp;
size_t rleft, left;
diff --git a/com32/gpllib/Makefile b/com32/gpllib/Makefile
index 3e2bd03d..71f335da 100644
--- a/com32/gpllib/Makefile
+++ b/com32/gpllib/Makefile
@@ -27,7 +27,7 @@ libcom32gpl.c32 : $(LIBOBJS)
$(LD) -shared $(LDFLAGS) -o $@ $^
tidy dist clean:
- find . \( -name \*.o -o -name \*.c32 -o -name .\*.d -o -name \*.tmp \) -print0 | \
+ find . \( -name \*.o -o -name .\*.d -o -name \*.tmp \) -print0 | \
xargs -0r rm -f
spotless: clean
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 7542da83..216b6bde 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -649,7 +649,7 @@ static void exec_command(char *line, struct s_hardware *hardware)
if ((current_module->nomodule == true) && ( module != NULL)) {
dprintf("CLI_DEBUG exec: Reworking arguments with argc=%d\n",argc);
char **new_argv=NULL;
- new_argv=malloc((argc + 2)*sizeof(char));
+ new_argv=malloc((argc + 2)*sizeof(char *));
for (int argc_iter=0; argc_iter<argc; argc_iter++) {
dprintf("CLI_DEBUG exec rework : copy %d to %d (%s)\n",argc_iter,argc_iter+1,argv[argc_iter]);
new_argv[argc_iter+1] = malloc(strlen(argv[argc_iter]));
diff --git a/com32/include/cli.h b/com32/include/cli.h
index 513c1719..eee4576f 100644
--- a/com32/include/cli.h
+++ b/com32/include/cli.h
@@ -14,7 +14,7 @@ extern void clear_screen(void);
extern int mygetkey(clock_t timeout);
extern const char *edit_cmdline(const char *input, int top /*, int width */ ,
int (*pDraw_Menu) (int, int, int),
- void (*show_fkey) (int));
+ void (*show_fkey) (int), bool *);
extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
#endif
diff --git a/com32/include/klibc/compiler.h b/com32/include/klibc/compiler.h
index 210971f1..e8548b59 100644
--- a/com32/include/klibc/compiler.h
+++ b/com32/include/klibc/compiler.h
@@ -139,4 +139,6 @@
/* Weak symbols */
#define __weak __attribute__((weak))
+#define __export __attribute__((visibility("default")))
+
#endif
diff --git a/com32/include/menu.h b/com32/include/menu.h
index 5a4c901e..bc0182f7 100644
--- a/com32/include/menu.h
+++ b/com32/include/menu.h
@@ -87,7 +87,6 @@ enum kernel_type {
KT_BSS, /* Boot sector with patch */
KT_PXE, /* PXE NBP */
KT_FDIMAGE, /* Floppy disk image */
- KT_COMBOOT, /* COMBOOT image */
KT_COM32, /* COM32 image */
KT_CONFIG, /* Configuration file */
};
diff --git a/com32/include/stdio.h b/com32/include/stdio.h
index 902a0e80..813a0edc 100644
--- a/com32/include/stdio.h
+++ b/com32/include/stdio.h
@@ -124,9 +124,9 @@ __extern int rename(const char *, const char *);
*
* Returns 0 if 'data' was converted succesfully, -1 otherwise.
*/
-static inline int unhexchar(char *data)
+static inline int unhexchar(unsigned char *data)
{
- char num = *data;
+ unsigned char num = *data;
if (num >= '0' && num <= '9') {
*data = num - '0';
@@ -134,7 +134,7 @@ static inline int unhexchar(char *data)
} else {
num |= 0x20; /* upper case -> lower case */
if (num >= 'a' && num <= 'f') {
- *data = num - 'a' - 10;
+ *data = num - 'a' + 10;
return 0;
}
}
diff --git a/com32/include/syslinux/boot.h b/com32/include/syslinux/boot.h
index aea32d9c..74a311df 100644
--- a/com32/include/syslinux/boot.h
+++ b/com32/include/syslinux/boot.h
@@ -61,7 +61,6 @@ extern const struct image_types image_boot_types[];
#define IMAGE_TYPE_BSS 3
#define IMAGE_TYPE_PXE 4
#define IMAGE_TYPE_FDIMAGE 5
-#define IMAGE_TYPE_COMBOOT 6
#define IMAGE_TYPE_COM32 7
#define IMAGE_TYPE_CONFIG 8
#define IMAGE_TYPE_LOCALBOOT 9
diff --git a/com32/include/syslinux/features.h b/com32/include/syslinux/features.h
deleted file mode 100644
index d25d08d5..00000000
--- a/com32/include/syslinux/features.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- * 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.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef _SYSLINUX_FEATURES_H
-#define _SYSLINUX_FEATURES_H
-
-#define SYSLINUX_FEATURE_LOCAL_BOOT (0*8+0)
-#define SYSLINUX_FEATURE_NOOP_IDLE (0*8+1)
-
-extern uint8_t feature_flags;
-extern uint8_t feature_flags_len;
-
-static inline int syslinux_has_feature(unsigned int __flag)
-{
- unsigned int __byte = __flag >> 3;
- unsigned int __bit = __flag & 7;
-
- if (__byte <= feature_flags_len)
- return (feature_flags[__byte] >> __bit) & 1;
- else
- return 0;
-}
-
-#endif /* _SYSLINUX_FEATURE_H */
diff --git a/com32/lib/asprintf.c b/com32/lib/asprintf.c
index ef5b4b2f..eab20118 100644
--- a/com32/lib/asprintf.c
+++ b/com32/lib/asprintf.c
@@ -21,9 +21,10 @@ int asprintf(char **bufp, const char *format, ...)
*bufp = p = malloc(bytes);
if (!p)
- return -1;
+ rv = -1;
+ else
+ rv = vsnprintf(p, bytes, format, ap);
- rv = vsnprintf(p, bytes, format, ap);
va_end(ap);
return rv;
diff --git a/com32/lib/bufprintf.c b/com32/lib/bufprintf.c
index 939bcec3..d2812311 100644
--- a/com32/lib/bufprintf.c
+++ b/com32/lib/bufprintf.c
@@ -17,8 +17,10 @@ int vbufprintf(struct print_buf *buf, const char *format, va_list ap)
char *newbuf;
newbuf = realloc(buf->buf, newsize);
- if (!newbuf)
- return -1;
+ if (!newbuf) {
+ rv = -1;
+ goto bail;
+ }
buf->buf = newbuf;
buf->size = newsize;
@@ -26,6 +28,8 @@ int vbufprintf(struct print_buf *buf, const char *format, va_list ap)
rv = vsnprintf(buf->buf + buf->len, buf->size - buf->len, format, ap2);
buf->len += rv;
+bail:
+ va_end(ap2);
return rv;
}
diff --git a/com32/lib/free.c b/com32/lib/free.c
deleted file mode 100644
index be23865a..00000000
--- a/com32/lib/free.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * free.c
- *
- * Very simple linked-list based malloc()/free().
- */
-
-#include <stdlib.h>
-#include "malloc.h"
-
-static struct free_arena_header *__free_block(struct free_arena_header *ah)
-{
- struct free_arena_header *pah, *nah;
-
- pah = ah->a.prev;
- nah = ah->a.next;
- if (pah->a.type == ARENA_TYPE_FREE &&
- (char *)pah + pah->a.size == (char *)ah) {
- /* Coalesce into the previous block */
- pah->a.size += ah->a.size;
- pah->a.next = nah;
- nah->a.prev = pah;
-
-#ifdef DEBUG_MALLOC
- ah->a.type = ARENA_TYPE_DEAD;
-#endif
-
- ah = pah;
- pah = ah->a.prev;
- } else {
- /* Need to add this block to the free chain */
- ah->a.type = ARENA_TYPE_FREE;
-
- ah->next_free = __malloc_head.next_free;
- ah->prev_free = &__malloc_head;
- __malloc_head.next_free = ah;
- ah->next_free->prev_free = ah;
- }
-
- /* In either of the previous cases, we might be able to merge
- with the subsequent block... */
- if (nah->a.type == ARENA_TYPE_FREE &&
- (char *)ah + ah->a.size == (char *)nah) {
- ah->a.size += nah->a.size;
-
- /* Remove the old block from the chains */
- nah->next_free->prev_free = nah->prev_free;
- nah->prev_free->next_free = nah->next_free;
- ah->a.next = nah->a.next;
- nah->a.next->a.prev = ah;
-
-#ifdef DEBUG_MALLOC
- nah->a.type = ARENA_TYPE_DEAD;
-#endif
- }
-
- /* Return the block that contains the called block */
- return ah;
-}
-
-/*
- * This is used to insert a block which is not previously on the
- * free list. Only the a.size field of the arena header is assumed
- * to be valid.
- */
-void __inject_free_block(struct free_arena_header *ah)
-{
- struct free_arena_header *nah;
- size_t a_end = (size_t) ah + ah->a.size;
- size_t n_end;
-
- for (nah = __malloc_head.a.next; nah->a.type != ARENA_TYPE_HEAD;
- nah = nah->a.next) {
- n_end = (size_t) nah + nah->a.size;
-
- /* Is nah entirely beyond this block? */
- if ((size_t) nah >= a_end)
- break;
-
- /* Is this block entirely beyond nah? */
- if ((size_t) ah >= n_end)
- continue;
-
- /* Otherwise we have some sort of overlap - reject this block */
- return;
- }
-
- /* Now, nah should point to the successor block */
- ah->a.next = nah;
- ah->a.prev = nah->a.prev;
- nah->a.prev = ah;
- ah->a.prev->a.next = ah;
-
- __free_block(ah);
-}
-
-void free(void *ptr)
-{
- struct free_arena_header *ah;
-
- if (!ptr)
- return;
-
- ah = (struct free_arena_header *)
- ((struct arena_header *)ptr - 1);
-
-#ifdef DEBUG_MALLOC
- assert(ah->a.type == ARENA_TYPE_USED);
-#endif
-
- __free_block(ah);
-
- /* Here we could insert code to return memory to the system. */
-}
diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c
deleted file mode 100644
index ce35f3d1..00000000
--- a/com32/lib/malloc.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * malloc.c
- *
- * Very simple linked-list based malloc()/free().
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <com32.h>
-#include <syslinux/memscan.h>
-#include "malloc.h"
-
-struct free_arena_header __malloc_head = {
- {
- ARENA_TYPE_HEAD,
- 0,
- &__malloc_head,
- &__malloc_head,
- },
- &__malloc_head,
- &__malloc_head
-};
-
-/* This is extern so it can be overridden by the user application */
-extern size_t __stack_size;
-extern void *__mem_end; /* Produced after argv parsing */
-
-static inline size_t sp(void)
-{
- size_t sp;
- asm volatile ("movl %%esp,%0":"=rm" (sp));
- return sp;
-}
-
-#define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */
-
-static int consider_memory_area(void *dummy, addr_t start,
- addr_t len, bool valid)
-{
- struct free_arena_header *fp;
- addr_t end;
-
- (void)dummy;
-
- if (valid && start < E820_MEM_MAX) {
- if (len > E820_MEM_MAX - start)
- len = E820_MEM_MAX - start;
-
- end = start + len;
-
- if (end > __com32.cs_memsize) {
- if (start <= __com32.cs_memsize) {
- start = __com32.cs_memsize;
- len = end - start;
- }
-
- if (len >= 2 * sizeof(struct arena_header)) {
- fp = (struct free_arena_header *)start;
- fp->a.size = len;
- __inject_free_block(fp);
- }
- }
- }
-
- return 0;
-}
-
-static void __constructor init_memory_arena(void)
-{
- struct free_arena_header *fp;
- size_t start, total_space;
-
- start = (size_t) ARENA_ALIGN_UP(__mem_end);
- total_space = sp() - start;
-
- if (__stack_size == 0 || __stack_size > total_space >> 1)
- __stack_size = total_space >> 1; /* Half for the stack, half for the heap... */
-
- if (total_space < __stack_size + 4 * sizeof(struct arena_header))
- __stack_size = total_space - 4 * sizeof(struct arena_header);
-
- fp = (struct free_arena_header *)start;
- fp->a.size = total_space - __stack_size;
-
- __inject_free_block(fp);
-
- /* Scan the memory map to look for other suitable regions */
- if (!__com32.cs_memsize)
- return; /* Old Syslinux core, can't do this... */
-
- syslinux_scan_memory(consider_memory_area, NULL);
-}
-
-static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
-{
- size_t fsize;
- struct free_arena_header *nfp, *na;
-
- fsize = fp->a.size;
-
- /* We need the 2* to account for the larger requirements of a free block */
- if (fsize >= size + 2 * sizeof(struct arena_header)) {
- /* Bigger block than required -- split block */
- nfp = (struct free_arena_header *)((char *)fp + size);
- na = fp->a.next;
-
- nfp->a.type = ARENA_TYPE_FREE;
- nfp->a.size = fsize - size;
- fp->a.type = ARENA_TYPE_USED;
- fp->a.size = size;
-
- /* Insert into all-block chain */
- nfp->a.prev = fp;
- nfp->a.next = na;
- na->a.prev = nfp;
- fp->a.next = nfp;
-
- /* Replace current block on free chain */
- nfp->next_free = fp->next_free;
- nfp->prev_free = fp->prev_free;
- fp->next_free->prev_free = nfp;
- fp->prev_free->next_free = nfp;
- } else {
- /* Allocate the whole block */
- fp->a.type = ARENA_TYPE_USED;
-
- /* Remove from free chain */
- fp->next_free->prev_free = fp->prev_free;
- fp->prev_free->next_free = fp->next_free;
- }
-
- return (void *)(&fp->a + 1);
-}
-
-void *malloc(size_t size)
-{
- struct free_arena_header *fp;
-
- if (size == 0)
- return NULL;
-
- /* Add the obligatory arena header, and round up */
- size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
-
- for (fp = __malloc_head.next_free; fp->a.type != ARENA_TYPE_HEAD;
- fp = fp->next_free) {
- if (fp->a.size >= size) {
- /* Found fit -- allocate out of this block */
- return __malloc_from_block(fp, size);
- }
- }
-
- /* Nothing found... need to request a block from the kernel */
- return NULL; /* No kernel to get stuff from */
-}
diff --git a/com32/lib/realloc.c b/com32/lib/realloc.c
deleted file mode 100644
index 2969e313..00000000
--- a/com32/lib/realloc.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * realloc.c
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <minmax.h>
-
-#include "malloc.h"
-
-void *realloc(void *ptr, size_t size)
-{
- struct free_arena_header *ah, *nah;
- void *newptr;
- size_t newsize, oldsize, xsize;
-
- if (!ptr)
- return malloc(size);
-
- if (size == 0) {
- free(ptr);
- return NULL;
- }
-
- ah = (struct free_arena_header *)
- ((struct arena_header *)ptr - 1);
-
- /* Actual size of the old block */
- oldsize = ah->a.size;
-
- /* Add the obligatory arena header, and round up */
- newsize = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
-
- if (oldsize >= newsize && newsize >= (oldsize >> 2) &&
- oldsize - newsize < 4096) {
- /* This allocation is close enough already. */
- return ptr;
- } else {
- xsize = oldsize;
-
- nah = ah->a.next;
- if ((char *)nah == (char *)ah + ah->a.size &&
- nah->a.type == ARENA_TYPE_FREE &&
- oldsize + nah->a.size >= newsize) {
- /* Merge in subsequent free block */
- ah->a.next = nah->a.next;
- ah->a.next->a.prev = ah;
- nah->next_free->prev_free = nah->prev_free;
- nah->prev_free->next_free = nah->next_free;
- xsize = (ah->a.size += nah->a.size);
- }
-
- if (xsize >= newsize) {
- /* We can reallocate in place */
- if (xsize >= newsize + 2 * sizeof(struct arena_header)) {
- /* Residual free block at end */
- nah = (struct free_arena_header *)((char *)ah + newsize);
- nah->a.type = ARENA_TYPE_FREE;
- nah->a.size = xsize - newsize;
- ah->a.size = newsize;
-
- /* Insert into block list */
- nah->a.next = ah->a.next;
- ah->a.next = nah;
- nah->a.next->a.prev = nah;
- nah->a.prev = ah;
-
- /* Insert into free list */
- if (newsize > oldsize) {
- /* Hack: this free block is in the path of a memory object
- which has already been grown at least once. As such, put
- it at the *end* of the freelist instead of the beginning;
- trying to save it for future realloc()s of the same block. */
- nah->prev_free = __malloc_head.prev_free;
- nah->next_free = &__malloc_head;
- __malloc_head.prev_free = nah;
- nah->prev_free->next_free = nah;
- } else {
- nah->next_free = __malloc_head.next_free;
- nah->prev_free = &__malloc_head;
- __malloc_head.next_free = nah;
- nah->next_free->prev_free = nah;
- }
- }
- /* otherwise, use up the whole block */
- return ptr;
- } else {
- /* Last resort: need to allocate a new block and copy */
- oldsize -= sizeof(struct arena_header);
- newptr = malloc(size);
- if (newptr) {
- memcpy(newptr, ptr, min(size, oldsize));
- free(ptr);
- }
- return newptr;
- }
- }
-}
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index 50b8a9f6..5b0d9ee8 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -71,15 +71,19 @@ FILE *findpath(char *name)
p = PATH;
again:
i = 0;
- while (*p && *p != ':' && i < FILENAME_MAX) {
+ while (*p && *p != ':' && i < FILENAME_MAX - 1) {
path[i++] = *p++;
}
if (*p == ':')
p++;
+ /* Ensure we have a '/' separator */
+ if (path[i] != '/' && i < FILENAME_MAX - 1)
+ path[i++] = '/';
+
n = name;
- while (*n && i < FILENAME_MAX)
+ while (*n && i < FILENAME_MAX - 1)
path[i++] = *n++;
path[i] = '\0';
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 4ee296c4..0d27c92b 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -98,13 +98,6 @@ static int prepare_dynlinking(struct elf_module *module) {
dyn_entry++;
}
- // Now compute the number of symbols in the symbol table
- if (module->ghash_table != NULL) {
- module->symtable_size = module->ghash_table[1];
- } else {
- module->symtable_size = module->hash_table[1];
- }
-
return 0;
}
@@ -191,6 +184,7 @@ int module_load(struct elf_module *module) {
Elf_Sym *main_sym;
Elf_Ehdr elf_hdr;
module_ctor_t *ctor;
+ struct elf_module *head = NULL;
// Do not allow duplicate modules
if (module_find(module->name) != NULL) {
@@ -224,6 +218,8 @@ int module_load(struct elf_module *module) {
CHECKED(res, prepare_dynlinking(module), error);
//printf("check... 4\n");
+ head = list_entry((&modules_head)->next, typeof(*head), list);
+
/* Find modules we need to load as dependencies */
if (module->str_table) {
int i;
@@ -249,7 +245,11 @@ int module_load(struct elf_module *module) {
p = dep;
argv[0] = p;
- spawn_load(p, 1, argv);
+ res = spawn_load(p, 1, argv);
+ if (res < 0) {
+ printf("Failed to load %s\n", p);
+ goto error;
+ }
}
}
@@ -294,6 +294,9 @@ int module_load(struct elf_module *module) {
return 0;
error:
+ if (head)
+ unload_modules_since(head->name);
+
// Remove the module from the module list (if applicable)
list_del_init(&module->list);
diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c
index 29d0a2fd..559bafc7 100644
--- a/com32/lib/sys/module/exec.c
+++ b/com32/lib/sys/module/exec.c
@@ -194,8 +194,10 @@ int spawn_load(const char *name, int argc, char **argv)
return -1;
if (get_module_type(module) == EXEC_MODULE) {
- if (!argc || !argv || strcmp(argv[0], name))
- return -1;
+ if (!argc || !argv || strcmp(argv[0], name)) {
+ res = -1;
+ goto out;
+ }
}
if (!strcmp(cur_module->name, module->name)) {
@@ -218,10 +220,8 @@ int spawn_load(const char *name, int argc, char **argv)
}
res = module_load(module);
- if (res != 0) {
- _module_unload(module);
- return res;
- }
+ if (res != 0)
+ goto out;
type = get_module_type(module);
prev_module = cur_module;
@@ -259,14 +259,14 @@ int spawn_load(const char *name, int argc, char **argv)
cur_module = prev_module;
res = module_unload(module);
- if (res != 0) {
- return res;
- }
-
- return ((unsigned int)ret_val & 0xFF);
+ if (res != 0)
+ goto out;
}
- return 0;
+out:
+ if (res)
+ _module_unload(module);
+ return res;
}
void exec_term(void)
diff --git a/com32/lib/sys/module/i386/elf_module.c b/com32/lib/sys/module/i386/elf_module.c
index d0eb1a8e..a3792554 100644
--- a/com32/lib/sys/module/i386/elf_module.c
+++ b/com32/lib/sys/module/i386/elf_module.c
@@ -30,7 +30,9 @@ 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
@@ -142,6 +144,25 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
}
}
+ // 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);
diff --git a/com32/lib/sys/module/x86_64/elf_module.c b/com32/lib/sys/module/x86_64/elf_module.c
index 9300f989..64404a17 100644
--- a/com32/lib/sys/module/x86_64/elf_module.c
+++ b/com32/lib/sys/module/x86_64/elf_module.c
@@ -30,7 +30,9 @@ 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
@@ -142,6 +144,25 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
}
}
+ // 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);
diff --git a/com32/lib/sys/screensize.c b/com32/lib/sys/screensize.c
index 340227cd..bcd4496c 100644
--- a/com32/lib/sys/screensize.c
+++ b/com32/lib/sys/screensize.c
@@ -14,7 +14,7 @@ int getscreensize(int fd, int *rows, int *cols)
*rows = fp->o.rows;
*cols = fp->o.cols;
- if (!rows || !cols) {
+ if (!*rows || !*cols) {
errno = ENOTTY;
return -1;
}
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index 93577461..15e90895 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -205,7 +205,6 @@ static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
unsigned int bytes_per_row[1];
rv = floadfile(fp, &jpeg_file, &length_of_file, header, len);
- fclose(fp);
if (rv)
goto err;
diff --git a/com32/lib/syslinux/runimage.c b/com32/lib/syslinux/runimage.c
index 4391114c..d3db75f3 100644
--- a/com32/lib/syslinux/runimage.c
+++ b/com32/lib/syslinux/runimage.c
@@ -42,26 +42,22 @@ extern unsigned int ipappend;
void syslinux_run_kernel_image(const char *filename, const char *cmdline,
uint32_t ipappend_flags, uint32_t type)
{
- char *bbfilename = NULL;
char *bbcmdline = NULL;
+ size_t len;
+ int rv;
-
- bbfilename = lstrdup(filename);
- if (!bbfilename)
- goto fail;
-
- bbcmdline = lstrdup(cmdline);
+ /* +2 for NULL and space */
+ len = strlen(filename) + strlen(cmdline) + 2;
+ bbcmdline = malloc(len);
if (!bbcmdline)
- goto fail;
+ return;
+
+ rv = snprintf(bbcmdline, len, "%s %s", filename, cmdline);
+ if (rv == -1 || (size_t)rv >= len)
+ return;
if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX)
ipappend = ipappend_flags;
- execute(bbfilename, type);
-
-fail:
- if (bbcmdline)
- lfree(bbcmdline);
- if (bbfilename)
- lfree(bbfilename);
+ execute(bbcmdline, type);
}
diff --git a/com32/lib/zalloc.c b/com32/lib/zalloc.c
deleted file mode 100644
index 0e6ed28d..00000000
--- a/com32/lib/zalloc.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * zalloc.c
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-void *zalloc(size_t size)
-{
- void *ptr;
-
- ptr = malloc(size);
- if (ptr)
- memset(ptr, 0, size);
-
- return ptr;
-}
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index 487f8299..dc99da6e 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -1110,7 +1110,7 @@ int main(int argc, char *argv[])
{
const char *cmdline;
struct menu *m;
- int rows, cols, cursorrow;
+ int rows, cols;
int i;
(void)argc;
@@ -1152,15 +1152,11 @@ int main(int argc, char *argv[])
local_cursor_enable(true);
cmdline = run_menu();
- if (clearmenu) {
+ if (clearmenu)
clear_screen();
- cursorrow = 1;
- } else {
- cursorrow = END_ROW;
- }
local_cursor_enable(false);
- printf("\033[?25h\033[%d;1H\033[0m", cursorrow);
+ printf("\033[?25h\033[%d;1H\033[0m", END_ROW);
if (cmdline) {
uint32_t type = parse_image_type(cmdline);
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 3690e480..dd6d5f91 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -35,7 +35,7 @@ struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
/* These are global parameters regardless of which menu we're displaying */
int shiftkey = 0; /* Only display menu if shift key pressed */
int hiddenmenu = 0;
-int clearmenu = 1;
+int clearmenu = 0;
long long totaltimeout = 0;
const char *hide_key[KEY_MAX];
@@ -189,9 +189,6 @@ static struct menu *new_menu(struct menu *parent,
m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
m->menu_background = refstr_get(parent->menu_background);
- refstr_put(m->title);
- m->title = refstr_get(parent->title);
-
m->color_table = copy_color_table(parent->color_table);
for (i = 0; i < 12; i++) {
@@ -749,8 +746,6 @@ static void parse_config_file(FILE * f)
refstr_put(command);
} else if ((ep = looking_at(p, "clear"))) {
clearmenu = 1;
- } else if ((ep = looking_at(p, "noclear"))) {
- clearmenu = 0;
} else if ((ep = is_message_name(p, &msgnr))) {
refstr_put(m->messages[msgnr]);
m->messages[msgnr] = refstrdup(skipspace(ep));
diff --git a/com32/sysdump/README b/com32/sysdump/README
index 2b825775..7d10e32b 100644
--- a/com32/sysdump/README
+++ b/com32/sysdump/README
@@ -1,4 +1,4 @@
-This is a very simple COMBOOT program which can be used to dump memory
+This is a very simple COM32 program which can be used to dump memory
regions over a serial port. To use it, type on the SYSLINUX command
line: