[syslinux] [GIT PULL] elflink bug fixes

Matt Fleming matt at console-pimps.org
Tue Jun 26 09:46:15 PDT 2012


Hi Peter,

Please pull the following changes.

Paulo, I had to revert your "pxe: resolve names via DNS from
protected-mode code" change because dns_resolv() is only implemented for
PXELINUX and causes undefined symbol references for ISOLINUX, etc. Feel
free to make the change again on top of the revert.

The following changes since commit e7bd19def830e8341b1a100956345f1028740b9e:

  Merge remote-tracking branch 'mfleming/merge/elflink/master' into elflink (2012-06-07 15:54:09 -0700)

are available in the git repository at:

  git://git.zytor.com/users/mfleming/syslinux.git elflink

Andre Ericson (1):
      ldlinux: fixes bug that happens when using fullpath for a COM32 module

Matt Fleming (10):
      module: Actually use last component of DT_NEEDED pathname
      Delete all references to __com32.cs_bounce
      pxechn: Fix merge botch s/pxe_dns/pxe_dns_resolv/
      com32: Add missing DHCP pack/unpack files
      elflink: Fix compiler warning
      fs: Add .copy_super to struct fs_ops
      com32: Per-object file LDFLAGS
      Revert "pxe: resolve names via DNS from protected-mode code"
      ldlinux: Don't lfree() 'kernel' twice
      module: Make list of DT_NEEDED entries per-module

 com32/chain/utility.c                              |   24 +++++---
 com32/cmenu/Makefile                               |   17 +++++-
 com32/cmenu/libmenu/syslnx.c                       |   25 ++++++--
 com32/elflink/ldlinux/chainboot.c                  |    4 +-
 com32/elflink/ldlinux/execute.c                    |    1 -
 com32/gpllib/disk/geom.c                           |   11 +++-
 com32/gpllib/disk/read.c                           |   25 ++++++--
 com32/gpllib/disk/write.c                          |   26 ++++++--
 com32/gpllib/memory.c                              |   15 ++++-
 com32/hdt/Makefile                                 |    3 +
 com32/hdt/hdt-common.c                             |   20 +++++--
 com32/include/sys/module.h                         |    5 ++
 com32/include/syslinux/pxe.h                       |    4 +-
 com32/lib/Makefile                                 |    7 +-
 com32/lib/sys/module/common.c                      |   13 +---
 com32/lib/sys/module/elf_module.c                  |   38 +++++-------
 com32/lib/syslinux/disk.c                          |   63 +++++++++++++++----
 core/include/pxe.h => com32/lib/syslinux/pxe_dns.c |   50 +++++++++++++---
 com32/libupload/upload_tftp.c                      |    2 +-
 com32/lua/src/vesa.c                               |   31 +++++++---
 com32/mboot/initvesa.c                             |   24 +++++---
 com32/mboot/mem.c                                  |   35 ++++++++---
 com32/modules/Makefile                             |   15 +++++
 com32/modules/gpxecmd.c                            |    5 +-
 com32/modules/host.c                               |   35 +----------
 com32/modules/pxechn.c                             |    8 +--
 com32/modules/sanboot.c                            |    5 +-
 com32/rosh/Makefile                                |    2 +
 com32/samples/Makefile                             |    3 +
 com32/samples/resolv.c                             |   21 +++++-
 core/fs/fat/fat.c                                  |    3 +-
 core/include/fs.h                                  |    7 +-
 mk/com32.mk                                        |    3 +-
 mk/elf.mk                                          |    2 +-
 34 files changed, 368 insertions(+), 184 deletions(-)
 rename core/include/pxe.h => com32/lib/syslinux/pxe_dns.c (62%)

diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index fb59551..b54e0cd 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -94,24 +94,30 @@ void lba2chs(disk_chs *dst, const struct disk_info *di, uint64_t lba, uint32_t m
 uint32_t get_file_lba(const char *filename)
 {
     com32sys_t inregs;
-    uint32_t lba;
+    uint32_t lba = 0;
+    int size = 65536;
+    char *buf;
 
     /* Start with clean registers */
     memset(&inregs, 0, sizeof(com32sys_t));
 
+    buf = lmalloc(size);
+    if (!buf)
+	return 0;
+
     /* Put the filename in the bounce buffer */
-    strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
+    strlcpy(buf, filename, size);
 
     /* Call comapi_open() which returns a structure pointer in SI
      * to a structure whose first member happens to be the LBA.
      */
     inregs.eax.w[0] = 0x0006;
-    inregs.esi.w[0] = OFFS(__com32.cs_bounce);
-    inregs.es = SEG(__com32.cs_bounce);
+    inregs.esi.w[0] = OFFS(buf);
+    inregs.es = SEG(buf);
     __com32.cs_intcall(0x22, &inregs, &inregs);
 
     if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) {
-	return 0;		/* Filename not found */
+	goto fail;		/* Filename not found */
     }
 
     /* Since the first member is the LBA, we simply cast */
@@ -121,14 +127,16 @@ uint32_t get_file_lba(const char *filename)
     memset(&inregs, 0, sizeof(com32sys_t));
 
     /* Put the filename in the bounce buffer */
-    strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
+    strlcpy(buf, filename, size);
 
     /* Call comapi_close() to free the structure */
     inregs.eax.w[0] = 0x0008;
-    inregs.esi.w[0] = OFFS(__com32.cs_bounce);
-    inregs.es = SEG(__com32.cs_bounce);
+    inregs.esi.w[0] = OFFS(buf);
+    inregs.es = SEG(buf);
     __com32.cs_intcall(0x22, &inregs, &inregs);
 
+fail:
+    lfree(buf);
     return lba;
 }
 
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index 00825b4..40a09d1 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -26,13 +26,26 @@ include $(MAKEDIR)/elf.mk
 
 CFLAGS	  += -I./libmenu
 
+LDFLAGS_complex.o = $(com32)/cmenu/libmenu/libmenu.c32 \
+		    $(com32)/libutil/libutil_com.c32 \
+		    $(com32)/lib/libcom32.c32
+LDFLAGS_display.o = $(com32)/cmenu/libmenu/libmenu.c32 \
+		$(com32)/libutil/libutil_com.c32 \
+		$(com32)/lib/libcom32.c32
+LDFLAGS_simple.o = $(com32)/cmenu/libmenu/libmenu.c32 \
+		   $(com32)/libutil/libutil_com.c32 \
+		   $(com32)/lib/libcom32.c32
+LDFLAGS_test.o = $(com32)/cmenu/libmenu/libmenu.c32
+LDFLAGS_test2.o = $(com32)/cmenu/libmenu/libmenu.c32
+
 LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
-	libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o
+	libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o \
+	$(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
 
 CMENUS = $(patsubst %.c,%.c32,$(wildcard *.c))
 IMENUS = $(patsubst %.menu,%.c32,$(wildcard *.menu))
 
-MENUS = $(CMENUS) $(IMENUS) $(LIBS)
+MENUS = $(LIBS) $(CMENUS) $(IMENUS)
 
 .SUFFIXES: .S .c .o .elf .c32 .menu
 
diff --git a/com32/cmenu/libmenu/syslnx.c b/com32/cmenu/libmenu/syslnx.c
index 53e2401..27823df 100644
--- a/com32/cmenu/libmenu/syslnx.c
+++ b/com32/cmenu/libmenu/syslnx.c
@@ -28,10 +28,16 @@ char issyslinux(void)
 
 void runsyslinuxcmd(const char *cmd)
 {
-    strcpy(__com32.cs_bounce, cmd);
+    char *bounce;
+
+    bounce = lmalloc(strlen(cmd) + 1);
+    if (!bounce)
+	return;
+
+    strcpy(bounce, cmd);
     REG_AX(inreg) = 0x0003;	// Run command
-    REG_BX(inreg) = OFFS(__com32.cs_bounce);
-    REG_ES(inreg) = SEG(__com32.cs_bounce);
+    REG_BX(inreg) = OFFS(bounce);
+    REG_ES(inreg) = SEG(bounce);
     __intcall(0x22, &inreg, &outreg);
 }
 
@@ -62,6 +68,7 @@ void runsyslinuximage(const char *cmd, long ipappend)
 {
     unsigned int numfun = 0;
     char *ptr, *cmdline;
+    char *bounce;
 
     (void)ipappend;		// XXX: Unused?!
 
@@ -71,8 +78,12 @@ void runsyslinuximage(const char *cmd, long ipappend)
 	runsyslinuxcmd(cmd);
     // Try the Run Kernel Image function
     // Split command line into
-    strcpy(__com32.cs_bounce, cmd);
-    ptr = __com32.cs_bounce;
+    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++;
@@ -87,8 +98,8 @@ void runsyslinuximage(const char *cmd, long ipappend)
     // Now call the interrupt
     REG_BX(inreg) = OFFS(cmdline);
     REG_ES(inreg) = SEG(cmdline);
-    REG_SI(inreg) = OFFS(__com32.cs_bounce);
-    REG_DS(inreg) = SEG(__com32.cs_bounce);
+    REG_SI(inreg) = OFFS(bounce);
+    REG_DS(inreg) = SEG(bounce);
     REG_EDX(inreg) = 0;
 
     __intcall(0x22, &inreg, &outreg);	// If successful does not return
diff --git a/com32/elflink/ldlinux/chainboot.c b/com32/elflink/ldlinux/chainboot.c
index cdaafb8..c1efadf 100644
--- a/com32/elflink/ldlinux/chainboot.c
+++ b/com32/elflink/ldlinux/chainboot.c
@@ -85,7 +85,7 @@ void chainboot_file(const char *file, enum kernel_type type)
     if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX ||
 	sdi->c.filesystem == SYSLINUX_FS_EXTLINUX) {
 	if (syslinux_add_movelist(&fraglist, 0x800 - 18,
-				  (const void *)sdi->r.esbx, 16))
+				  (addr_t)sdi->r.esbx, 16))
 	    goto bail;
 
 	/* DS:SI points to partition info */
@@ -97,7 +97,7 @@ void chainboot_file(const char *file, enum kernel_type type)
      * superblock.
      */
     if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX &&
-	type == KT_BSS && vfat_copy_superblock(buf))
+	type == KT_BSS && this_fs->fs_ops->copy_super(buf))
 	goto bail;
 
     if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 97e5116..f713eb1 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -92,7 +92,6 @@ void execute(const char *cmdline, enum kernel_type type)
 
 	if (type == KT_COM32) {
 		/* new entry for elf format c32 */
-		lfree((void *)kernel);
 		create_args_and_load((char *)cmdline);
 	} else if (type == KT_CONFIG) {
 		char *argv[] = { "ldlinux.c32", NULL };
diff --git a/com32/gpllib/disk/geom.c b/com32/gpllib/disk/geom.c
index 9e673ed..e109520 100644
--- a/com32/gpllib/disk/geom.c
+++ b/com32/gpllib/disk/geom.c
@@ -120,7 +120,7 @@ static int detect_extensions(struct driveinfo *drive_info)
 static int get_drive_parameters_with_extensions(struct driveinfo *drive_info)
 {
     com32sys_t inreg, outreg;
-    struct edd_device_parameters *dp = __com32.cs_bounce;
+    struct edd_device_parameters *dp;
 
     memset(&inreg, 0, sizeof inreg);
 
@@ -134,6 +134,10 @@ static int get_drive_parameters_with_extensions(struct driveinfo *drive_info)
      * If the buffer length is less than 26 on entry an error shall be
      * returned.
      */
+    dp = lmalloc(sizeof *dp);
+    if (!dp)
+	return -1;
+
     dp->len = sizeof(struct edd_device_parameters);
 
     inreg.esi.w[0] = OFFS(dp);
@@ -144,10 +148,13 @@ static int get_drive_parameters_with_extensions(struct driveinfo *drive_info)
     __intcall(0x13, &inreg, &outreg);
 
     /* CF set on error */
-    if (outreg.eflags.l & EFLAGS_CF)
+    if (outreg.eflags.l & EFLAGS_CF) {
+	lfree(dp);
 	return outreg.eax.b[1];
+    }
 
     memcpy(&drive_info->edd_params, dp, sizeof drive_info->edd_params);
+    lfree(dp);
 
     return 0;
 }
diff --git a/com32/gpllib/disk/read.c b/com32/gpllib/disk/read.c
index 7a6cc43..541957f 100644
--- a/com32/gpllib/disk/read.c
+++ b/com32/gpllib/disk/read.c
@@ -76,13 +76,22 @@ int read_sectors(struct driveinfo *drive_info, void *data,
 		 const unsigned int lba, const int sectors)
 {
     com32sys_t inreg, outreg;
-    struct ebios_dapa *dapa = __com32.cs_bounce;
-    void *buf = (char *)__com32.cs_bounce + sectors * SECTOR;
+    struct ebios_dapa *dapa;
+    void *buf;
     char *bufp = data;
+    int rv = -1;
 
     if (get_drive_parameters(drive_info) == -1)
 	return -1;
 
+    buf = lmalloc(sectors * SECTOR);
+    if (!buf)
+	return -1;
+
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto fail;
+
     memset(&inreg, 0, sizeof inreg);
 
     if (drive_info->ebios) {
@@ -102,7 +111,7 @@ int read_sectors(struct driveinfo *drive_info, void *data,
 	if (!drive_info->cbios) {	// XXX errno
 	    /* We failed to get the geometry */
 	    if (lba)
-		return -1;	/* Can only read MBR */
+		goto fail;	/* Can only read MBR */
 
 	    s = 1;
 	    h = 0;
@@ -112,7 +121,7 @@ int read_sectors(struct driveinfo *drive_info, void *data,
 
 	// XXX errno
 	if (s > 63 || h > 256 || c > 1023)
-	    return -1;
+	    goto fail;
 
 	inreg.eax.w[0] = 0x0201;	/* Read one sector */
 	inreg.ecx.b[1] = c & 0xff;
@@ -126,10 +135,14 @@ int read_sectors(struct driveinfo *drive_info, void *data,
     /* Perform the read */
     if (int13_retry(&inreg, &outreg)) {
 	errno_disk = outreg.eax.b[1];
-	return -1;		/* Give up */
+	goto fail;		/* Give up */
     }
 
     memcpy(bufp, buf, sectors * SECTOR);
+    rv = sectors;
 
-    return sectors;
+fail:
+    lfree(dapa);
+    lfree(buf);
+    return rv;
 }
diff --git a/com32/gpllib/disk/write.c b/com32/gpllib/disk/write.c
index 89e530d..d183ade 100644
--- a/com32/gpllib/disk/write.c
+++ b/com32/gpllib/disk/write.c
@@ -36,8 +36,17 @@ int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
 		  const void *data, const int size)
 {
     com32sys_t inreg, outreg;
-    struct ebios_dapa *dapa = __com32.cs_bounce;
-    void *buf = (char *)__com32.cs_bounce + size;
+    struct ebios_dapa *dapa;
+    void *buf;
+    int rv = -1;
+
+    buf = lmalloc(size);
+    if (!buf)
+	return -1;
+
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto out;
 
     memcpy(buf, data, size);
     memset(&inreg, 0, sizeof inreg);
@@ -59,7 +68,7 @@ int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
 	if (!drive_info->cbios) {	// XXX errno
 	    /* We failed to get the geometry */
 	    if (lba)
-		return -1;	/* Can only write MBR */
+		goto out;	/* Can only write MBR */
 
 	    s = 1;
 	    h = 0;
@@ -69,7 +78,7 @@ int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
 
 	// XXX errno
 	if (s > 63 || h > 256 || c > 1023)
-	    return -1;
+	    goto out;
 
 	inreg.eax.w[0] = 0x0301;	/* Write one sector */
 	inreg.ecx.b[1] = c & 0xff;
@@ -82,10 +91,13 @@ int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
 
     /* Perform the write */
     if (int13_retry(&inreg, &outreg)) {
-	errno_disk = outreg.eax.b[1];
-	return -1;		/* Give up */
+	errno_disk = outreg.eax.b[1];	/* Give up */
     } else
-	return size;
+	rv = size;
+out:
+    lfree(dapa);
+    lfree(buf);
+    return rv;
 }
 
 /**
diff --git a/com32/gpllib/memory.c b/com32/gpllib/memory.c
index 28a95ff..06c746d 100644
--- a/com32/gpllib/memory.c
+++ b/com32/gpllib/memory.c
@@ -87,15 +87,20 @@ void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found)
 {
     int count = 0;
     static struct e820_ext_entry buf;	/* static so it is zeroed */
+    void *bounce;
 
     com32sys_t ireg, oreg;
     memset(&ireg, 0, sizeof ireg);
 
+    bounce = lmalloc(sizeof buf);
+    if (!bounce)
+	goto out;
+
     ireg.eax.w[0] = 0xe820;
     ireg.edx.l = SMAP;
     ireg.ecx.l = sizeof(struct e820_ext_entry);
-    ireg.edi.w[0] = OFFS(__com32.cs_bounce);
-    ireg.es = SEG(__com32.cs_bounce);
+    ireg.edi.w[0] = OFFS(bounce);
+    ireg.es = SEG(bounce);
 
     /*
      * Set this here so that if the BIOS doesn't change this field
@@ -105,7 +110,7 @@ void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found)
     buf.ext_flags = 1;
 
     do {
-	memcpy(__com32.cs_bounce, &buf, sizeof buf);
+	memcpy(bounce, &buf, sizeof buf);
 
 	/* Important: %edx and %esi are clobbered by some BIOSes,
 	   so they must be either used for the error output
@@ -126,7 +131,7 @@ void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found)
 	if (oreg.eflags.l & EFLAGS_CF || oreg.ecx.l < 20)
 	    break;
 
-	memcpy(&buf, __com32.cs_bounce, sizeof buf);
+	memcpy(&buf, bounce, sizeof buf);
 
 	/*
 	 * ACPI 3.0 added the extended flags support.  If bit 0
@@ -143,6 +148,8 @@ void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found)
 	ireg.ebx.l = oreg.ebx.l;
     } while (ireg.ebx.l && count < size_map);
 
+out:
+    lfree(bounce);
     *size_found = count;
 }
 
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 36206cd..ff0fa2e 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -20,6 +20,9 @@ MAKEDIR = $(topdir)/mk
 include $(MAKEDIR)/elf.mk
 
 LIBS      = ../libupload/libcom32upload.a
+C_LIBS    += $(com32)/cmenu/libmenu/libmenu.c32 \
+	     $(com32)/libutil/libutil_com.c32 \
+	     $(com32)/lib/libcom32.c32 $(com32)/gpllib/libcom32gpl.c32
 CFLAGS    += -I$(com32)/cmenu/libmenu -I$(com32)
 
 MODULES	  = hdt.c32
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 8e9a9e6..f729a10 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -312,6 +312,7 @@ int detect_vesa(struct s_hardware *hardware)
     struct vesa_mode_info *mi;
     uint16_t mode, *mode_ptr;
     char *oem_ptr;
+    int rv = -1;
 
     if (hardware->vesa_detection == true)
 	return -1;
@@ -319,9 +320,13 @@ int detect_vesa(struct s_hardware *hardware)
     hardware->vesa_detection = true;
     hardware->is_vesa_valid = false;
 
-    /* Allocate space in the bounce buffer for these structures */
-    gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
-    mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
+    gi = lmalloc(sizeof(*gi));
+    if (!gi)
+	return -1;
+
+    mi = lmalloc(sizeof(*mi));
+    if (!mi)
+	goto out;
 
     gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
     rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
@@ -330,7 +335,7 @@ int detect_vesa(struct s_hardware *hardware)
     __intcall(0x10, &rm, &rm);
 
     if (rm.eax.w[0] != 0x004F) {
-	return -1;
+	goto out;
     };
 
     mode_ptr = GET_PTR(gi->video_mode_ptr);
@@ -369,7 +374,12 @@ int detect_vesa(struct s_hardware *hardware)
 	hardware->vesa.vmi_count++;
     }
     hardware->is_vesa_valid = true;
-    return 0;
+
+    rv = 0;
+out:
+    lfree(mi);
+    lfree(gi);
+    return rv;
 }
 
 /* Try to detect disks from port 0x80 to 0xff */
diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
index fb6a1eb..eabc9e0 100644
--- a/com32/include/sys/module.h
+++ b/com32/include/sys/module.h
@@ -27,6 +27,8 @@
 #define EXEC_MODULE			0		
 #define LIB_MODULE			1
 
+#define MAX_NR_DEPS			64
+
 /*
  * Initialization and finalization function signatures
  */
@@ -118,6 +120,9 @@ struct elf_module {
 		} x;
 	} u;
 
+	// ELF DT_NEEDED entries for this module
+	int				nr_needed;
+	Elf32_Word			needed[MAX_NR_DEPS];
 };
 
 /**
diff --git a/com32/include/syslinux/pxe.h b/com32/include/syslinux/pxe.h
index 156f4cf..4e8a336 100644
--- a/com32/include/syslinux/pxe.h
+++ b/com32/include/syslinux/pxe.h
@@ -34,11 +34,11 @@
 #ifndef _SYSLINUX_PXE_H
 #define _SYSLINUX_PXE_H
 
-#include <pxe.h>
 #include <syslinux/pxe_api.h>
 
 /* SYSLINUX-defined PXE utility functions */
 int pxe_get_cached_info(int level, void **buf, size_t *len);
-int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt);
+int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE * gnt);
+uint32_t pxe_dns(const char *hostname);
 
 #endif /* _SYSLINUX_PXE_H */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index daa7284..57e9c2f 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -49,6 +49,7 @@ LIBSYSLINUX_OBJS = \
 	syslinux/features.o syslinux/config.o	\
 	syslinux/version.o	\
 	syslinux/pxe_get_cached.o syslinux/pxe_get_nic.o		\
+	syslinux/pxe_dns.o						\
 	syslinux/video/fontquery.o syslinux/video/reportmode.o
 
 LIBLOAD_OBJS = \
@@ -125,7 +126,7 @@ LIBOTHER_OBJS = \
 	strnlen.o							\
 	strncat.o strndup.o		\
 	stpncpy.o						\
-	strntoimax.o strntoumax.o strrchr.o strsep.o strspn.o strstr.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			\
@@ -133,7 +134,7 @@ LIBOTHER_OBJS = \
 	skipspace.o							\
 	chrreplace.o							\
 	bufprintf.o							\
-	inet.o								\
+	inet.o dhcppack.o dhcpunpack.o					\
 	strreplace.o							\
 	lstrdup.o						\
 	\
@@ -169,7 +170,7 @@ CORELIBOBJS = \
 	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 sys/openconsole.o				\
-	syslinux/memscan.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	\
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index eeb2607..19742e6 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -64,6 +64,10 @@ static FILE *findpath(char *name)
 	char *p, *n;
 	int i;
 
+	f = fopen(name, "rb"); /* for full path */
+	if (f)
+		return f;
+
 	p = PATH;
 again:
 	i = 0;
@@ -74,15 +78,6 @@ again:
 	if (*p == ':')
 		p++;
 
-	if (path[0] == '.' && i == 1) {
-		if (!core_getcwd(path, sizeof(path))) {
-			DBG_PRINT("Could not get cwd\n");
-			return NULL;
-		}
-
-		i = strlen(path);
-	}
-
 	n = name;
 	while (*n && i < FILENAME_MAX)
 		path[i++] = *n++;
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 3e37384..d8009aa 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -19,8 +19,6 @@
 #include "elfutils.h"
 #include "common.h"
 
-#define MAX_NR_DEPS	64
-
 static int check_header(Elf32_Ehdr *elf_hdr) {
 	int res;
 
@@ -181,9 +179,6 @@ out:
 	return res;
 }
 
-static int nr_needed;
-static Elf32_Word needed[MAX_NR_DEPS];;
-
 static int prepare_dynlinking(struct elf_module *module) {
 	Elf32_Dyn  *dyn_entry = module->dyn_table;
 
@@ -196,8 +191,8 @@ static int prepare_dynlinking(struct elf_module *module) {
 			 * are then inform the user that we ran out of
 			 * space.
 			 */
-			if (nr_needed < MAX_NR_DEPS)
-				needed[nr_needed++] = dyn_entry->d_un.d_ptr;
+			if (module->nr_needed < MAX_NR_DEPS)
+				module->needed[module->nr_needed++] = dyn_entry->d_un.d_ptr;
 			else {
 				printf("Too many dependencies!\n");
 				return -1;
@@ -502,40 +497,37 @@ int module_load(struct elf_module *module) {
 	CHECKED(res, load_segments(module, &elf_hdr), error);
 	//printf("bleah... 3\n");
 	// Obtain dynamic linking information
-	nr_needed = 0;
 	CHECKED(res, prepare_dynlinking(module), error);
 	//printf("check... 4\n");
 
 	/* Find modules we need to load as dependencies */
 	if (module->str_table) {
-		int i, n;
+		int i;
 
 		/*
-		 * nr_needed can be modified by recursive calls to
-		 * module_load() so keep a local copy on the stack.
+		 * Note that we have to load the dependencies in
+		 * reverse order.
 		 */
-		n = nr_needed;
-		for (i = 0; i < n; i++) {
+		for (i = module->nr_needed - 1; i >= 0; i--) {
 			size_t len, j;
 			char *dep, *p;
+			char *argv[2] = { NULL, NULL };
 
-			dep = module->str_table + needed[i];
+			dep = module->str_table + module->needed[i];
 
 			/* strip everything but the last component */
 			j = len = strlen(dep);
 			if (!len)
 				continue;
 
-			p = dep + len - 1;
-			while (j > 0 && *p && *p != '/') {
-				p--;
-				j--;
-			}
+			if (strchr(dep, '/')) {
+				p = strrchr(dep, '/');
+				p++;
+			} else
+				p = dep;
 
-			if (*p++ == '/') {
-				char *argv[2] = { p, NULL };
-				spawn_load(p, 1, argv);
-			}
+			argv[0] = p;
+			spawn_load(p, 1, argv);
 		}
 	}
 
diff --git a/com32/lib/syslinux/disk.c b/com32/lib/syslinux/disk.c
index d6409af..093751a 100644
--- a/com32/lib/syslinux/disk.c
+++ b/com32/lib/syslinux/disk.c
@@ -73,7 +73,8 @@ int disk_int13_retry(const com32sys_t * inreg, com32sys_t * outreg)
 int disk_get_params(int disk, struct disk_info *const diskinfo)
 {
     static com32sys_t inreg, outreg;
-    struct disk_ebios_eparam *eparam = __com32.cs_bounce;
+    struct disk_ebios_eparam *eparam;
+    int rv = 0;
 
     memset(diskinfo, 0, sizeof *diskinfo);
     diskinfo->disk = disk;
@@ -93,6 +94,10 @@ int disk_get_params(int disk, struct disk_info *const diskinfo)
 	diskinfo->ebios = 1;
     }
 
+    eparam = lmalloc(sizeof *eparam);
+    if (!eparam)
+	return -1;
+
     /* Get extended disk parameters if ebios == 1 */
     if (diskinfo->ebios) {
 	memset(&inreg, 0, sizeof inreg);
@@ -127,8 +132,10 @@ int disk_get_params(int disk, struct disk_info *const diskinfo)
 
     __intcall(0x13, &inreg, &outreg);
 
-    if (outreg.eflags.l & EFLAGS_CF)
-	return diskinfo->ebios ? 0 : -1;
+    if (outreg.eflags.l & EFLAGS_CF) {
+	rv = diskinfo->ebios ? 0 : -1;
+	goto out;
+    }
 
     diskinfo->spt = 0x3f & outreg.ecx.b[0];
     diskinfo->head = 1 + outreg.edx.b[1];
@@ -145,7 +152,9 @@ int disk_get_params(int disk, struct disk_info *const diskinfo)
     if (!diskinfo->lbacnt)
 	diskinfo->lbacnt = diskinfo->cyl * diskinfo->head * diskinfo->spt;
 
-    return 0;
+out:
+    lfree(eparam);
+    return rv;
 }
 
 /**
@@ -163,17 +172,26 @@ void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba,
 			uint8_t count)
 {
     com32sys_t inreg;
-    struct disk_ebios_dapa *dapa = __com32.cs_bounce;
-    void *buf = (char *)__com32.cs_bounce + diskinfo->bps;
-    void *data;
+    struct disk_ebios_dapa *dapa;
+    void *buf;
+    void *data = NULL;
     uint32_t maxcnt;
+    uint32_t size = 65536;
 
-    maxcnt = (__com32.cs_bounce_size - diskinfo->bps) / diskinfo->bps;
+    maxcnt = (size - diskinfo->bps) / diskinfo->bps;
     if (!count || count > maxcnt || lba + count > diskinfo->lbacnt)
 	return NULL;
 
     memset(&inreg, 0, sizeof inreg);
 
+    buf = lmalloc(count * diskinfo->bps);
+    if (!buf)
+	return NULL;
+
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto out;
+
     if (diskinfo->ebios) {
 	dapa->len = sizeof(*dapa);
 	dapa->count = count;
@@ -209,11 +227,14 @@ void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba,
     }
 
     if (disk_int13_retry(&inreg, NULL))
-	return NULL;
+	goto out;
 
     data = malloc(count * diskinfo->bps);
     if (data)
 	memcpy(data, buf, count * diskinfo->bps);
+out:
+    lfree(dapa);
+    lfree(buf);
     return data;
 }
 
@@ -233,17 +254,27 @@ int disk_write_sectors(const struct disk_info *const diskinfo, uint64_t lba,
 		       const void *data, uint8_t count)
 {
     com32sys_t inreg;
-    struct disk_ebios_dapa *dapa = __com32.cs_bounce;
-    void *buf = (char *)__com32.cs_bounce + diskinfo->bps;
+    struct disk_ebios_dapa *dapa;
+    void *buf;
     uint32_t maxcnt;
+    uint32_t size = 65536;
+    int rv = -1;
 
-    maxcnt = (__com32.cs_bounce_size - diskinfo->bps) / diskinfo->bps;
+    maxcnt = (size - diskinfo->bps) / diskinfo->bps;
     if (!count || count > maxcnt || lba + count > diskinfo->lbacnt)
 	return -1;
 
+    buf = lmalloc(count * diskinfo->bps);
+    if (!buf)
+	return -1;
+
     memcpy(buf, data, count * diskinfo->bps);
     memset(&inreg, 0, sizeof inreg);
 
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto out;
+
     if (diskinfo->ebios) {
 	dapa->len = sizeof(*dapa);
 	dapa->count = count;
@@ -279,9 +310,13 @@ int disk_write_sectors(const struct disk_info *const diskinfo, uint64_t lba,
     }
 
     if (disk_int13_retry(&inreg, NULL))
-	return -1;
+	goto out;
 
-    return 0;			/* ok */
+    rv = 0;			/* ok */
+out:
+    lfree(dapa);
+    lfree(buf);
+    return rv;
 }
 
 /**
diff --git a/core/include/pxe.h b/com32/lib/syslinux/pxe_dns.c
similarity index 62%
rename from core/include/pxe.h
rename to com32/lib/syslinux/pxe_dns.c
index 86d6cfc..6620396 100644
--- a/core/include/pxe.h
+++ b/com32/lib/syslinux/pxe_dns.c
@@ -1,7 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
  *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
- *   Copyright 2012 Paulo Alcantara <pcacjr at zytor.com>
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
@@ -26,18 +25,51 @@
  *
  * ----------------------------------------------------------------------- */
 
-#ifndef PXE_H_
-#define PXE_H_
+/*
+ * pxe_dns.c
+ *
+ * Resolve a hostname via DNS
+ */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdint.h>
+#include <string.h>
+#include <com32.h>
 
-extern uint32_t dns_resolv(const char *);
+#include <syslinux/pxe.h>
 
-/* Resolve a hostname via DNS */
-static inline uint32_t pxe_dns_resolv(const char *name)
+/* Returns the status code from PXE (0 on success),
+   or -1 on invocation failure */
+uint32_t pxe_dns(const char *hostname)
 {
-    return dns_resolv(name);
-}
+    com32sys_t regs;
+    union {
+	unsigned char b[4];
+	uint32_t ip;
+    } q;
+    char *lm_hostname;
+
+    /* Is this a dot-quad? */
+    if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu",
+	       &q.b[0], &q.b[1], &q.b[2], &q.b[3]) == 4)
+	return q.ip;
+
+    lm_hostname = lstrdup(hostname);
+    if (!lm_hostname)
+	return 0;
+
+    memset(&regs, 0, sizeof regs);
+    regs.eax.w[0] = 0x0010;
+    regs.es = SEG(lm_hostname);
+    /* regs.ebx.w[0] = OFFS(lm_hostname); */
 
-#endif /* PXE_H_ */
+    __intcall(0x22, &regs, &regs);
+
+    lfree(lm_hostname);
+
+    if (regs.eflags.l & EFLAGS_CF)
+	return 0;
+
+    return regs.eax.l;
+}
diff --git a/com32/libupload/upload_tftp.c b/com32/libupload/upload_tftp.c
index 10427ac..5e73c1c 100644
--- a/com32/libupload/upload_tftp.c
+++ b/com32/libupload/upload_tftp.c
@@ -153,7 +153,7 @@ static int upload_tftp_write(struct upload_backend *be)
     tftp.seq      = 0;
 
     if (be->argv[1]) {
-	tftp.srv_ip = pxe_dns_resolv(be->argv[1]);
+	tftp.srv_ip   = pxe_dns(be->argv[1]);
 	if (!tftp.srv_ip) {
 //	    printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
 	    return -TFTP_ERR_UNABLE_TO_RESOLVE;
diff --git a/com32/lua/src/vesa.c b/com32/lua/src/vesa.c
index 9f28134..06649e1 100644
--- a/com32/lua/src/vesa.c
+++ b/com32/lua/src/vesa.c
@@ -17,10 +17,15 @@ static int vesa_getmodes(lua_State *L)
   struct vesa_general_info *gi;
   struct vesa_mode_info *mi;
   int nmode = 1;
+  int rv = -1;
 
-  /* Allocate space in the bounce buffer for these structures */
-  gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
-  mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
+  gi = lmalloc(sizeof *gi);
+  if (!gi)
+      return -1;
+
+  mi = lmalloc(sizeof *mi);
+  if (!mi)
+      goto out;
 
   memset(&rm, 0, sizeof rm);
   memset(gi, 0, sizeof *gi);
@@ -32,11 +37,15 @@ static int vesa_getmodes(lua_State *L)
   __intcall(0x10, &rm, &rm);
 
   if ( rm.eax.w[0] != 0x004F )
-    return -1;                   /* Function call failed */
-  if ( gi->signature != VESA_MAGIC )
-    return -2;                   /* No magic */
-  if ( gi->version < 0x0102 )
-    return -3;                   /* VESA 1.2+ required */
+    goto out;                   /* Function call failed */
+  if ( gi->signature != VESA_MAGIC ) {
+    rv = -2;                   /* No magic */
+    goto out;
+  }
+  if ( gi->version < 0x0102 ) {
+    rv = -3;                   /* VESA 1.2+ required */
+    goto out;
+  }
 
   lua_newtable(L);      /* list of modes */
 
@@ -86,7 +95,11 @@ static int vesa_getmodes(lua_State *L)
 
   }
 
-  return 1;
+  rv = 1;
+out:
+  lfree(mi);
+  lfree(gi);
+  return rv;
 }
 
 
diff --git a/com32/mboot/initvesa.c b/com32/mboot/initvesa.c
index bb3a846..bd869e3 100644
--- a/com32/mboot/initvesa.c
+++ b/com32/mboot/initvesa.c
@@ -62,9 +62,13 @@ void set_graphics_mode(const struct multiboot_header *mbh,
     if (!(mbh->flags & MULTIBOOT_VIDEO_MODE) || mbh->mode_type != 0)
 	return;
 
-    /* Allocate space in the bounce buffer for these structures */
-    gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
-    mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
+    gi = lmalloc(sizeof *gi);
+    if (!gi)
+	return;
+
+    mi = lmalloc(sizeof *mi);
+    if (!mi)
+	goto out;
 
     memset(&rm, 0, sizeof rm);
     memset(gi, 0, sizeof *gi);
@@ -76,11 +80,11 @@ void set_graphics_mode(const struct multiboot_header *mbh,
     __intcall(0x10, &rm, &rm);
 
     if (rm.eax.w[0] != 0x004F)
-	return;			/* Function call failed */
+	goto out;		/* Function call failed */
     if (gi->signature != VESA_MAGIC)
-	return;			/* No magic */
+	goto out;		/* No magic */
     if (gi->version < 0x0102)
-	return;			/* VESA 1.2+ required */
+	goto out;		/* VESA 1.2+ required */
 
     memcpy(&vesa_info.gi, gi, sizeof *gi);
 
@@ -183,7 +187,7 @@ void set_graphics_mode(const struct multiboot_header *mbh,
     }
 
     if (!bestpxf)
-	return;			/* No mode found */
+	goto out;		/* No mode found */
 
     mi = &vesa_info.mi;
     mode = bestmode;
@@ -194,7 +198,7 @@ void set_graphics_mode(const struct multiboot_header *mbh,
     rm.ebx.w[0] = mode;
     __intcall(0x10, &rm, &rm);
     if (rm.eax.w[0] != 0x004F)
-	return;			/* Failed to set mode */
+	goto out;		/* Failed to set mode */
 
     mbi->flags |= MB_INFO_VIDEO_INFO;
     mbi->vbe_mode = mode;
@@ -220,4 +224,8 @@ void set_graphics_mode(const struct multiboot_header *mbh,
      * output in VESA modes actually do that...
      */
     graphics_using_vga(0x0F, vesa_info.mi.h_res, vesa_info.mi.v_res);
+
+out:
+    lfree(mi);
+    lfree(gi);
 }
diff --git a/com32/mboot/mem.c b/com32/mboot/mem.c
index 6a31fac..6e3995b 100644
--- a/com32/mboot/mem.c
+++ b/com32/mboot/mem.c
@@ -49,9 +49,10 @@ struct e820_entry {
 static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 {
     com32sys_t ireg, oreg;
-    struct e820_entry *e820buf = __com32.cs_bounce;
+    struct e820_entry *e820buf;
     struct AddrRangeDesc *ard;
     size_t ard_count, ard_space;
+    int rv = 0;
 
     /* Use INT 12h to get DOS memory */
     __intcall(0x12, &__com32_zero_regs, &oreg);
@@ -65,10 +66,14 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 	    *dosmem = 640 * 1024;	/* Hope for the best... */
     }
 
+    e820buf = lmalloc(sizeof(*e820buf));
+    if (!e820buf)
+	return 0;
+
     /* Allocate initial space */
     *ardp = ard = malloc(RANGE_ALLOC_BLOCK * sizeof *ard);
     if (!ard)
-	return 0;
+	goto out;
 
     ard_count = 0;
     ard_space = RANGE_ALLOC_BLOCK;
@@ -93,8 +98,10 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 	if (ard_count >= ard_space) {
 	    ard_space += RANGE_ALLOC_BLOCK;
 	    *ardp = ard = realloc(ard, ard_space * sizeof *ard);
-	    if (!ard)
-		return ard_count;
+	    if (!ard) {
+		rv = ard_count;
+		goto out;
+	    }
 	}
 
 	ard[ard_count].size = 20;
@@ -106,8 +113,10 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 	ireg.ebx.l = oreg.ebx.l;
     } while (oreg.ebx.l);
 
-    if (ard_count)
-	return ard_count;
+    if (ard_count) {
+	rv = ard_count;
+	goto out;
+    };
 
     ard[0].size = 20;
     ard[0].BaseAddr = 0;
@@ -129,10 +138,12 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 	    ard[2].BaseAddr = 16 << 20;
 	    ard[2].Length = oreg.edx.w[0] << 16;
 	    ard[2].Type = 1;
-	    return 3;
+	    rv = 3;
 	} else {
-	    return 2;
+	    rv = 2;
 	}
+
+	goto out;
     }
 
     /* Finally try INT 15h AH=88h */
@@ -142,10 +153,14 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
 	ard[1].BaseAddr = 1 << 20;
 	ard[1].Length = oreg.ecx.w[0] << 10;
 	ard[1].Type = 1;
-	return 2;
+	rv = 2;
+	goto out;
     }
 
-    return 1;			/* ... problematic ... */
+    rv = 1;			/* ... problematic ... */
+out:
+    lfree(e820buf);
+    return rv;
 }
 
 void mboot_make_memmap(void)
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 017d6db..8d94cfe 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -28,6 +28,21 @@ MODULES	  = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
 
 TESTFILES =
 
+LDFLAGS_cpuidtest.o = $(com32)/gpllib/libcom32gpl.c32
+LDFLAGS_disk.o = $(com32)/gpllib/libcom32gpl.c32
+LDFLAGS_ethersel.o = $(com32)/lib/libcom32.c32
+LDFLAGS_gpxecmd.o = $(com32)/lib/libcom32.c32
+LDFLAGS_host.o = $(com32)/lib/libcom32.c32
+LDFLAGS_ifcpu.o = $(com32)/libutil/libutil_com.c32 \
+		  $(com32)/gpllib/libcom32gpl.c32
+LDFLAGS_kbdmap.o = $(com32)/lib/libcom32.c32
+LDFLAGS_linux.o = $(com32)/lib/libcom32.c32
+LDFLAGS_pxechn.o = $(com32)/lib/libcom32.c32 \
+	$(com32)/libutil/libutil_com.c32
+LDFLAGS_sanboot.o = $(com32)/lib/libcom32.c32
+LDFLAGS_vpdtest.o = $(com32)/gpllib/libcom32gpl.c32
+LDFLAGS_zzjson.o = $(com32)/gpllib/libcom32gpl.c32
+
 all: $(MODULES) $(TESTFILES)
 
 .PRECIOUS: %.o
diff --git a/com32/modules/gpxecmd.c b/com32/modules/gpxecmd.c
index fe414b9..9d4f456 100644
--- a/com32/modules/gpxecmd.c
+++ b/com32/modules/gpxecmd.c
@@ -43,7 +43,10 @@ static void gpxecmd(const char **args)
 
     memset(&reg, 0, sizeof reg);
 
-    fx = __com32.cs_bounce;
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
     q = (char *)(fx + 1);
 
     fx->Status = 1;
diff --git a/com32/modules/host.c b/com32/modules/host.c
index df51725..d70efff 100644
--- a/com32/modules/host.c
+++ b/com32/modules/host.c
@@ -1,43 +1,14 @@
-/* ----------------------------------------------------------------------- *
- *
- *   Copyright 2009 Liu Aleaxander <Aleaxander at gmail.com>
- *   Copyright 2012 Paulo Alcantara <pcacjr at zytor.com>
- *
- *   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.
- *
- * ----------------------------------------------------------------------- */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <console.h>
-#include <com32.h>
-
 #include <netinet/in.h>
+#include <com32.h>
 #include <syslinux/pxe.h>
 
 static inline uint32_t dns_resolve(const char *hostname)
 {
-    return pxe_dns_resolv(hostname);
+    return pxe_dns(hostname);
 }
 
 static inline void usage(const char *s)
@@ -54,7 +25,7 @@ int main(int argc, char *argv[])
 
     if (argc < 2) {
         usage(argv[0]);
-        exit(1);
+        return 1;
     }
 
     for (i = 1; i < argc; i++) {
diff --git a/com32/modules/pxechn.c b/com32/modules/pxechn.c
index 3f9ebd3..1902d4e 100644
--- a/com32/modules/pxechn.c
+++ b/com32/modules/pxechn.c
@@ -1031,10 +1031,7 @@ int pxe_restart(char *ifn)
     }
     printf("  Attempting to boot '%s'...\n\n", pxe.fn);
     memset(&reg, 0, sizeof reg);
-    if (sizeof(t_PXENV_TFTP_READ_FILE) <= __com32.cs_bounce_size) {
-	pxep = __com32.cs_bounce;
-	memset(pxep, 0, sizeof(t_PXENV_RESTART_TFTP));
-    } else if (!(pxep = lzalloc(sizeof(t_PXENV_RESTART_TFTP)))){
+    if (!(pxep = lzalloc(sizeof(t_PXENV_RESTART_TFTP)))){
 	dprintf("Unable to lzalloc() for PXE call structure\n");
 	goto ret;
     }
@@ -1055,8 +1052,7 @@ int pxe_restart(char *ifn)
     __intcall(0x22, &reg, &reg);
 
     printf("PXENV_RESTART_TFTP returned %d\n", pxep->Status);
-    if (pxep != __com32.cs_bounce)
-	lfree(pxep);
+    lfree(pxep);
 
 ret:
     return rv;
diff --git a/com32/modules/sanboot.c b/com32/modules/sanboot.c
index a2fbbd6..d55fbc0 100644
--- a/com32/modules/sanboot.c
+++ b/com32/modules/sanboot.c
@@ -43,7 +43,10 @@ static void sanboot(const char **args)
 
     memset(&reg, 0, sizeof reg);
 
-    fx = __com32.cs_bounce;
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
     q = (char *)(fx + 1);
 
     fx->Status = 1;
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index 766f68d..f328395 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -34,6 +34,8 @@ endif
 CFLAGS		+= -DDATE='"$(DATE)"'
 LNXCFLAGS	+= -DDATE='"$(DATE)"'
 
+LDFLAGS_rosh.o = $(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
+
 rosh.o:	rosh.h
 
 rosh.lo:	rosh.h
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index 167c638..bca197e 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -18,6 +18,9 @@ topdir = ../..
 MAKEDIR = $(topdir)/mk
 include $(MAKEDIR)/elf.mk
 
+LDFLAGS_fancyhello.o = $(com32)/libutil/libutil_com.c32
+LDFLAGS_keytest.o = $(com32)/libutil/libutil_com.c32
+
 all:	hello.c32 resolv.c32 serialinfo.c32 \
 	localboot.c32 \
 	fancyhello.c32 fancyhello.lnx \
diff --git a/com32/samples/resolv.c b/com32/samples/resolv.c
index 3446bd6..bd49d9f 100644
--- a/com32/samples/resolv.c
+++ b/com32/samples/resolv.c
@@ -22,11 +22,23 @@
 #include <stdlib.h>
 #include <com32.h>
 
-#include <syslinux/pxe.h>
-
-static inline uint32_t resolv(const char *name)
+uint32_t resolv(const char *name)
 {
-    return pxe_dns_resolv(name);
+    com32sys_t reg;
+
+    strcpy((char *)__com32.cs_bounce, name);
+
+    memset(&reg, 0, sizeof reg);
+    reg.eax.w[0] = 0x0010;
+    reg.ebx.w[0] = OFFS(__com32.cs_bounce);
+    reg.es = SEG(__com32.cs_bounce);
+
+    __intcall(0x22, &reg, &reg);
+
+    if (reg.eflags.l & EFLAGS_CF)
+	return 0;
+    else
+	return reg.eax.l;
 }
 
 int main(int argc, char *argv[])
@@ -41,6 +53,7 @@ int main(int argc, char *argv[])
     }
 
     ip = resolv(argv[1]);
+
     if (ip) {
 	printf("%s = %u.%u.%u.%u\n", argv[1],
 	       (ip & 0xff), (ip >> 8) & 0xff,
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 2c8dc31..127a24d 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -779,7 +779,7 @@ static int vfat_fs_init(struct fs_info *fs)
     return fs->block_shift;
 }
 
-int vfat_copy_superblock(void *buf)
+static int vfat_copy_superblock(void *buf)
 {
 	struct fat_bpb fat;
 	struct disk *disk;
@@ -821,4 +821,5 @@ const struct fs_ops vfat_fs_ops = {
     .iget_root     = vfat_iget_root,
     .iget          = vfat_iget,
     .next_extent   = fat_next_extent,
+    .copy_super    = vfat_copy_superblock,
 };
diff --git a/core/include/fs.h b/core/include/fs.h
index 481e085..08ac738 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -72,6 +72,8 @@ struct fs_ops {
     int	     (*readdir)(struct file *, struct dirent *);
 
     int      (*next_extent)(struct inode *, uint32_t);
+
+    int      (*copy_super)(void *buf);
 };
 
 /*
@@ -179,7 +181,7 @@ static inline struct file *handle_to_file(uint16_t handle)
     return handle ? &files[handle-1] : NULL;
 }
 
-#define PATH_DEFAULT	".:/boot/syslinux/:/boot/"
+#define PATH_DEFAULT	"/boot/syslinux/:/boot/"
 extern char *PATH;
 
 /* fs.c */
@@ -234,7 +236,4 @@ uint32_t generic_getfssec(struct file *file, char *buf,
 /* nonextextent.c */
 int no_next_extent(struct inode *, uint32_t);
 
-/* fat.c */
-int vfat_copy_superblock(void *buf);
-
 #endif /* FS_H */
diff --git a/mk/com32.mk b/mk/com32.mk
index 6e7e9a6..262d2a6 100644
--- a/mk/com32.mk
+++ b/mk/com32.mk
@@ -48,8 +48,7 @@ endif
 CFLAGS     = $(GCCOPT) $(GCCWARN) -march=i386 \
 	     -fomit-frame-pointer -D__COM32__ \
 	     -nostdinc -iwithprefix include \
-	     -I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE) \
-	     -I../../core/include
+	     -I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
 SFLAGS     = $(GCCOPT) $(GCCWARN) -march=i386 \
 	     -fomit-frame-pointer -D__COM32__ \
 	     -nostdinc -iwithprefix include \
diff --git a/mk/elf.mk b/mk/elf.mk
index 5242b2d..ea4344d 100644
--- a/mk/elf.mk
+++ b/mk/elf.mk
@@ -82,4 +82,4 @@ C_LNXLIBS  = $(com32)/libutil/libutil_lnx.a \
 	$(CC) $(LNXCFLAGS) -o $@ $^
 
 %.c32: %.o
-	$(LD) $(LDFLAGS) -o $@ $^
+	$(LD) $(LDFLAGS_$^) $(LDFLAGS) -o $@ $^





More information about the Syslinux mailing list