xserver/hw/xorg/loader Imakefile, NONE, 1.1 SparcMulDiv.S, NONE, 1.1 aout.h, NONE, 1.1 aoutloader.c, NONE, 1.1 aoutloader.h, NONE, 1.1 ar.h, NONE, 1.1 coff.h, NONE, 1.1 coffloader.c, NONE, 1.1 coffloader.h, NONE, 1.1 dixsym.c, NONE, 1.1 dlloader.c, NONE, 1.1 dlloader.h, NONE, 1.1 elf.h, NONE, 1.1 elfloader.c, NONE, 1.1 elfloader.h, NONE, 1.1 extsym.c, NONE, 1.1 fontsym.c, NONE, 1.1 hash.c, NONE, 1.1 hash.h, NONE, 1.1 loader.c, NONE, 1.1 loader.h, NONE, 1.1 loaderProcs.h, NONE, 1.1 loadext.c, NONE, 1.1 loadfont.c, NONE, 1.1 loadmod.c, NONE, 1.1 misym.c, NONE, 1.1 os.c, NONE, 1.1 os2funcs.c, NONE, 1.1 sym.h, NONE, 1.1 xf86sym.c, NONE, 1.1

Daniel Stone xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:17 EST 2004


Committed by: daniel

Update of /cvs/xserver/xserver/hw/xorg/loader
In directory pdx:/tmp/cvs-serv17025/hw/xorg/loader

Added Files:
	Imakefile SparcMulDiv.S aout.h aoutloader.c aoutloader.h ar.h 
	coff.h coffloader.c coffloader.h dixsym.c dlloader.c 
	dlloader.h elf.h elfloader.c elfloader.h extsym.c fontsym.c 
	hash.c hash.h loader.c loader.h loaderProcs.h loadext.c 
	loadfont.c loadmod.c misym.c os.c os2funcs.c sym.h xf86sym.c 
Log Message:
Xizzle is dead, long live Xorg.

Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.

Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.


--- NEW FILE: Imakefile ---
XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/loader/Imakefile,v 1.38 2003/10/02 13:30:02 eich Exp $ */




#include <Server.tmpl>
#ifdef LoaderTest
#define IHaveSubdirs
SUBDIRS = test
#endif

#define UseDBMalloc	NO

#if UseDBMalloc
SYS_LIBRARIES=-ldbmalloc
DBMALLOCDEFINE=-DDBMALLOC
#endif

#if HasDlopen
DLOPENDEFINES = -DDLOPEN_SUPPORT
DLSRC=dlloader.c
DLOBJ=dlloader.o
#endif

#if FontencCompatibility
 COMPAT_DEFINES = -DFONTENC_COMPATIBILITY
#endif

#if BuildFontCache
 FONTCACHE_DEFINES = -DFONTCACHE
#endif

#if HasShm
    SHM_DEFINES = -DHAS_SHM
#endif

#if defined (AMD64Architecture) && defined(linux)
ARCHDEFINES = -DDoMMAPedMerge -DMmapPageAlign
#endif

DEFINES = $(DBMALLOCDEFINE) $(DLOPENDEFINES) $(OS_DEFINES) $(COMPAT_DEFINES) \
	  $(SHM_DEFINES) $(FONTCACHE_DEFINES) $(ARCHDEFINES)

MODULEDEFINES = -DDEFAULT_MODULE_PATH=\"$(MODULEDIR)\"

   INCLUDES = -I. -I.. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC)/vbe \
		-I$(SERVERSRC)/dbe -I$(SERVERSRC)/Xext -I$(XF86SRC)/int10 \
		-I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
		-I$(SERVERSRC)/os -I$(XINCLUDESRC) -I$(FONTINCSRC) \
		-I$(FONTLIBSRC)/include -I$(FONTLIBSRC)/fontcache \
		-I$(EXTINCSRC) -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
		-I$(SERVERSRC)/render

#ifdef OS2Architecture
SRCS1 = os2funcs.c
OBJS1 = os2funcs.o
#endif

#ifdef SparcArchitecture
SRCS1 = SparcMulDiv.S
OBJS1 = SparcMulDiv.o
#endif

SRCS = aoutloader.c coffloader.c $(DLSRC) elfloader.c hash.c loader.c \
	loadmod.c loadfont.c loadext.c os.c dixsym.c misym.c xf86sym.c \
	fontsym.c extsym.c $(SRCS1)
OBJS = aoutloader.o coffloader.o $(DLOBJ) elfloader.o hash.o loader.o \
	loadmod.o loadfont.o loadext.o os.o dixsym.o misym.o xf86sym.o \
	fontsym.o extsym.o $(OBJS1)
XOBJS =  aoutloader.o coffloader.o $(DLOBJ) elfloader.o hash.o loader.o \
	loadmod.o loadfont.o loadext.o os.o $(OBJS1)

NormalAsmObjectRule()

NormalLibraryObjectRule()
NormalLibraryTarget(loader,$(OBJS) )
NormalLibraryTarget(xloader,$(XOBJS) )

SpecialCObjectRule(loadmod,NullParameter,$(MODULEDEFINES) $(EXT_DEFINES))
SpecialCObjectRule(xf86sym,NullParameter,$(EXT_DEFINES))
SpecialCObjectRule(dixsym,NullParameter,$(EXT_DEFINES))

#ifdef SparcArchitecture
ObjectFromAsmSource(SparcMulDiv,NullParameter)
#endif

DependTarget()

--- NEW FILE: SparcMulDiv.S ---
/*
 * Hardware integer division and multiplication routines for SPARC v8 and higher.
 *
 * Copyright (C) 1996 David S. Miller (davem at redhat.com)
 * Copyright (C) 1999 Jakub Jelinek (jj at ultra.linux.cz)
 *
 * 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
 * JAKUB JELINEK OR DAVID MILLER 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.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S,v 1.1 1999/07/10 07:24:51 dawes Exp $ */

	.globl	urem_sparcv89, umul_sparcv89, udiv_sparcv89
	.globl	rem_sparcv89, mul_sparcv89, div_sparcv89

	.align	32
urem_sparcv89:
	wr	%g0, 0x0, %y
	nop
	nop
	nop
	udiv	%o0, %o1, %o2
	umul	%o2, %o1, %o2
	retl
	 sub	%o0, %o2, %o0

	.align	32
umul_sparcv89:
	umul	%o0, %o1, %o0
	retl
	 rd	%y, %o1

	.align	32
udiv_sparcv89:
	wr	%g0, 0x0, %y
	nop
	nop
	retl
	 udiv	%o0, %o1, %o0

	.align	32
rem_sparcv89:
	sra	%o0, 0x1f, %o4
	wr	%o4, 0x0, %y
	nop
	nop
	nop
	sdivcc	%o0, %o1, %o2
	bvs,a	1f
	 xnor	%o2, %g0, %o2
1:	smul	%o2, %o1, %o2
	retl
	 sub	%o0, %o2, %o0

	.align	32
mul_sparcv89:
	smul	%o0, %o1, %o0
	retl
	 rd	%y, %o1
	nop

	.align	32
div_sparcv89:
	sra	%o0, 0x1f, %o2
	wr	%o2, 0x0, %y
	nop
	nop
	nop
	sdivcc	%o0, %o1, %o0
	bvs,a	1f
	 xnor	%o0, %g0, %o0
1:	retl
	 nop

--- NEW FILE: aout.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aout.h,v 1.7 2002/05/31 18:46:00 dawes Exp $ */

/*
 * Borrowed from NetBSD's exec_aout.h
 *
 * Copyright (c) 1993, 1994 Christopher G. Demetriou
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Christopher G. Demetriou.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _AOUT_H
#define _AOUT_H

#include "Xos.h"

/* Get prototype for ntohl. */
#include <ctype.h>

/* OS/2 EMX has ntohl in this file */
#ifdef __UNIXOS2__
#include <sys/param.h>
#endif

#define __LDPGSZ        4096U
#ifndef AOUT_PAGSIZ
#define AOUT_PAGSIZ(ex)    (__LDPGSZ)
#endif

/* 
 * a.out  header 
 */
typedef struct AOUT_exec {
    unsigned long a_midmag;	/* htonl(flags<<26 | mid<<16 | magic) */
    unsigned long a_text;	/* text segment size */
    unsigned long a_data;	/* initialized data size */
    unsigned long a_bss;	/* uninitialized data size */
    unsigned long a_syms;	/* symbol table size */
    unsigned long a_entry;	/* entry point */
    unsigned long a_trsize;	/* text relocation size */
    unsigned long a_drsize;	/* data relocation size */
} AOUTHDR;

/* a_magic */
#define OMAGIC          0407	/* old impure format */
#define NMAGIC          0410	/* read-only text */
#define ZMAGIC          0413	/* demand load format */
#define QMAGIC          0314	/* "compact" demand load format; deprecated */

/*
 * a_mid - keep sorted in numerical order for sanity's sake
 * ensure that: 0 < mid < 0x3ff
 */
#define MID_ZERO        0	/* unknown - implementation dependent */
#define MID_SUN010      1	/* sun 68010/68020 binary */
#define MID_SUN020      2	/* sun 68020-only binary */
#define MID_PC386       100	/* 386 PC binary. (so quoth BFD) */
#define MID_HP200       200	/* hp200 (68010) BSD binary */
#define MID_I386        134	/* i386 BSD binary */
#define MID_M68K        135	/* m68k BSD binary with 8K page sizes */
#define MID_M68K4K      136	/* m68k BSD binary with 4K page sizes */
#define MID_NS32532     137	/* ns32532 */
#define MID_SPARC       138	/* sparc */
#define MID_PMAX        139	/* pmax */
#define MID_VAX         140	/* vax */
#define MID_ALPHA       141	/* Alpha BSD binary */
#define MID_MIPS        142	/* big-endian MIPS */
#define MID_ARM6        143	/* ARM6 */
#define MID_HP300       300	/* hp300 (68020+68881) BSD binary */
#define MID_HPUX        0x20C	/* hp200/300 HP-UX binary */
#define MID_HPUX800     0x20B	/* hp800 HP-UX binary */

/*
 * a_flags
 */
#define EX_DYNAMIC      0x20
#define EX_PIC          0x10
#define EX_DPMASK       0x30
/*
 * Interpretation of the (a_flags & EX_DPMASK) bits:
 *
 *      00              traditional executable or object file
 *      01              object file contains PIC code (set by `as -k')
 *      10              dynamic executable
 *      11              position independent executable image
 *                      (eg. a shared library)
 *
 */

/*
 * The a.out structure's a_midmag field is a network-byteorder encoding
 * of this int
 *      FFFFFFmmmmmmmmmmMMMMMMMMMMMMMMMM
 * Where `F' is 6 bits of flag like EX_DYNAMIC,
 *       `m' is 10 bits of machine-id like MID_I386, and
 *       `M' is 16 bits worth of magic number, ie. ZMAGIC.
 * The macros below will set/get the needed fields.
 */
#define AOUT_GETMAGIC(ex) \
    ( (((ex)->a_midmag)&0xffff0000U) ? (ntohl(((ex)->a_midmag))&0xffffU) : ((ex)->a_midmag))
#define AOUT_GETMAGIC2(ex) \
    ( (((ex)->a_midmag)&0xffff0000U) ? (ntohl(((ex)->a_midmag))&0xffffU) : \
    (((ex)->a_midmag) | 0x10000) )
#define AOUT_GETMID(ex) \
    ( (((ex)->a_midmag)&0xffff0000U) ? ((ntohl(((ex)->a_midmag))>>16)&0x03ffU) : MID_ZERO )
#define AOUT_GETFLAG(ex) \
    ( (((ex)->a_midmag)&0xffff0000U) ? ((ntohl(((ex)->a_midmag))>>26)&0x3fU) : 0 )
#define AOUT_SETMAGIC(ex,mag,mid,flag) \
    ( (ex)->a_midmag = htonl( (((flag)&0x3fU)<<26) | (((mid)&0x03ffU)<<16) | \
    (((mag)&0xffffU)) ) )

#define AOUT_ALIGN(ex,x) \
        (AOUT_GETMAGIC(ex) == ZMAGIC || AOUT_GETMAGIC(ex) == QMAGIC ? \
        ((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x))

/* Valid magic number check. */
#define AOUT_BADMAG(ex) \
        (AOUT_GETMAGIC(ex) != NMAGIC && AOUT_GETMAGIC(ex) != OMAGIC && \
        AOUT_GETMAGIC(ex) != ZMAGIC && AOUT_GETMAGIC(ex) != QMAGIC)

/* Address of the bottom of the text segment. */
#define AOUT_TXTADDR(ex)   (AOUT_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)

/* Address of the bottom of the data segment. */
#define AOUT_DATADDR(ex) \
        (AOUT_GETMAGIC(ex) == OMAGIC ? AOUT_TXTADDR(ex) + (ex)->a_text : \
        (AOUT_TXTADDR(ex) + (ex)->a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1))

/* Address of the bottom of the bss segment. */
#define AOUT_BSSADDR(ex) \
        (AOUT_DATADDR(ex) + (ex)->a_data)

/* Text segment offset. */
#define AOUT_TXTOFF(ex) \
        ( AOUT_GETMAGIC2(ex)==ZMAGIC || AOUT_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
        0 : (AOUT_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : \
        sizeof(struct AOUT_exec)) )

/* Data segment offset. */
#define AOUT_DATOFF(ex) \
        AOUT_ALIGN(ex, AOUT_TXTOFF(ex) + (ex)->a_text)

/* Text relocation table offset. */
#define AOUT_TRELOFF(ex) \
        (AOUT_DATOFF(ex) + (ex)->a_data)

/* Data relocation table offset. */
#define AOUT_DRELOFF(ex) \
        (AOUT_TRELOFF(ex) + (ex)->a_trsize)

/* Symbol table offset. */
#define AOUT_SYMOFF(ex) \
        (AOUT_DRELOFF(ex) + (ex)->a_drsize)

/* String table offset. */
#define AOUT_STROFF(ex) \
        (AOUT_SYMOFF(ex) + (ex)->a_syms)

/* Relocation format. */
struct relocation_info_i386 {
    int r_address;		/* offset in text or data segment */
    unsigned int r_symbolnum:24,	/* ordinal number of add symbol */
        r_pcrel:1,		/* 1 if value should be pc-relative */
        r_length:2,		/* log base 2 of value's width */
        r_extern:1,		/* 1 if need to add symbol to value */
        r_baserel:1,		/* linkage table relative */
        r_jmptable:1,		/* relocate to jump table */
        r_relative:1,		/* load address relative */
        r_copy:1;		/* run time copy */
};

#define relocation_info relocation_info_i386

/*
 * Symbol table entry format.  The #ifdef's are so that programs including
 * nlist.h can initialize nlist structures statically.
 */
typedef struct AOUT_nlist {
    union {
	char *n_name;		/* symbol name (in memory) */
	long n_strx;		/* file string table offset (on disk) */
    } n_un;

#define AOUT_UNDF  0x00		/* undefined */
#define AOUT_ABS   0x02		/* absolute address */
#define AOUT_TEXT  0x04		/* text segment */
#define AOUT_DATA  0x06		/* data segment */
#define AOUT_BSS   0x08		/* bss segment */
#define AOUT_INDR  0x0a		/* alias definition */
#define AOUT_SIZE  0x0c		/* pseudo type, defines a symbol's size */
#define AOUT_COMM  0x12		/* common reference */
#define AOUT_FN    0x1e		/* file name (AOUT_EXT on) */
#define AOUT_WARN  0x1e		/* warning message (AOUT_EXT off) */

#define AOUT_EXT   0x01		/* external (global) bit, OR'ed in */
#define AOUT_TYPE  0x1e		/* mask for all the type bits */
    unsigned char n_type;	/* type defines */

    char n_other;		/* spare */
#define n_hash  n_desc		/* used internally by ld(1); XXX */
    short n_desc;		/* used by stab entries */
    unsigned long n_value;	/* address/value of the symbol */
} AOUT_nlist;

#define AOUT_FORMAT        "%08x"	/* namelist value format; XXX */
#define AOUT_STAB          0x0e0	/* mask for debugger symbols -- stab(5) */

#endif

--- NEW FILE: aoutloader.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aoutloader.c,v 1.19 2003/10/15 16:58:34 dawes Exp $ */

/*
 *
 * Copyright (c) 1997 Matthieu Herrb
 * Copyright 1995-1998 Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * Modified 21/02/97 by Sebastien Marineau to support OS/2 a.out objects
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __QNX__
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#endif
#include <sys/stat.h>
#include <netinet/in.h>

#ifdef DBMALLOC
#include <debug/malloc.h>
#define Xalloc(size) malloc(size)
#define Xcalloc(size) calloc(1,(size))
#define Xfree(size) free(size)
#endif

#include "Xos.h"
#include "os.h"
#include "aout.h"

#include "sym.h"
#include "loader.h"
#include "aoutloader.h"

#ifndef LOADERDEBUG
#define LOADERDEBUG 0
#endif

#if LOADERDEBUG
#define AOUTDEBUG ErrorF
#endif

#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif

/*
 * This structure contains all of the information about a module
 * that has been loaded.
 */

typedef struct {
    int handle;
    int module;
    int fd;
    loader_funcs *funcs;
    AOUTHDR *header;		/* file header */
    unsigned char *text;	/* Start address of the text section */
    unsigned int textsize;	/* Size of the text section */
    unsigned char *data;	/* Start address of the data section */
    unsigned int datasize;	/* Size of the data section */
    unsigned char *bss;		/* Start address of the bss data */
    unsigned int bsssize;	/* Size of the bss section */
    struct relocation_info *txtrel;	/* Start address of the text relocation table */
    struct relocation_info *datarel;	/* Start address of the data relocation table */
    AOUT_nlist *symtab;		/* Start address of the symbol table */
    unsigned char *strings;	/* Start address of the string table */
    unsigned long strsize;	/* size of string table */
    unsigned char *common;	/* Start address of the common data */
    unsigned long comsize;	/* size of common data */
} AOUTModuleRec, *AOUTModulePtr;

/*
 * If an relocation is unable to be satisfied, then put it on a list
 * to try later after more modules have been loaded.
 */
typedef struct AOUT_RELOC {
    AOUTModulePtr file;
    struct relocation_info *rel;
    int type;			/* AOUT_TEXT or AOUT_DATA */
    struct AOUT_RELOC *next;
} AOUTRelocRec;

/*
 * Symbols with a section number of 0 (N_UNDF) but a value of non-zero
 * need to have space allocated for them.
 *
 * Gather all of these symbols together, and allocate one chunk when we
 * are done.
 */

typedef struct AOUT_COMMON {
    struct AOUT_nlist *sym;
    int index;
    struct AOUT_COMMON *next;
} AOUTCommonRec;

static AOUTCommonPtr listCOMMON = NULL;

/* prototypes for static functions */
static int AOUTHashCleanOut(void *, itemPtr);
static char *AOUTGetSymbolName(AOUTModulePtr, struct AOUT_nlist *);
static void *AOUTGetSymbolValue(AOUTModulePtr, int);
static AOUTCommonPtr AOUTAddCommon(struct AOUT_nlist *, int);
static LOOKUP *AOUTCreateCommon(AOUTModulePtr);
static LOOKUP *AOUT_GetSymbols(AOUTModulePtr);
static AOUTRelocPtr AOUTDelayRelocation(AOUTModulePtr, int,
					struct relocation_info_i386 *);
static AOUTRelocPtr AOUTCollectRelocations(AOUTModulePtr);
static void AOUT_Relocate(unsigned long *, unsigned long, int);
static AOUTRelocPtr AOUT_RelocateEntry(AOUTModulePtr, int,
				       struct relocation_info_i386 *);

/*
 * Return 1 if the symbol in item belongs to aoutfile
 */
static int
AOUTHashCleanOut(void *voidptr, itemPtr item)
{
    AOUTModulePtr aoutfile = (AOUTModulePtr) voidptr;

    return (aoutfile->handle == item->handle);
}

/*
 * Manage listResolv 
 */
static AOUTRelocPtr
AOUTDelayRelocation(AOUTModulePtr aoutfile, int type,
		    struct relocation_info *rel)
{
    AOUTRelocPtr reloc;

    if ((reloc = xf86loadermalloc(sizeof(AOUTRelocRec))) == NULL) {
	ErrorF("AOUTDelayRelocation() Unable to allocate memory\n");
	return NULL;
    }
    if ((unsigned long)rel < 0x200) {
	ErrorF("bug");
    }
    reloc->file = aoutfile;
    reloc->type = type;
    reloc->rel = rel;
    reloc->next = 0;
    return reloc;
}

/*
 * Manage listCOMMON
 */

static AOUTCommonPtr
AOUTAddCommon(struct AOUT_nlist *sym, int index)
{
    AOUTCommonPtr common;

    if ((common = xf86loadermalloc(sizeof(AOUTCommonRec))) == NULL) {
	ErrorF("AOUTAddCommon() Unable to allocate memory\n");
	return 0;
    }
    common->sym = sym;
    common->index = index;
    common->next = 0;
    return common;
}

static LOOKUP *
AOUTCreateCommon(AOUTModulePtr aoutfile)
{
    int numsyms = 0, size = 0, l = 0;
    int offset = 0;
    AOUTCommonPtr common;
    LOOKUP *lookup;

    if (listCOMMON == NULL)
	return NULL;

    common = listCOMMON;
    for (common = listCOMMON; common; common = common->next) {
	/* Ensure long word alignment */
	if ((common->sym->n_value & (sizeof(long) - 1)) != 0)
	    common->sym->n_value = (common->sym->n_value + (sizeof(long) - 1))
		    & ~(sizeof(long) - 1);

	/* accumulate the sizes */
	size += common->sym->n_value;
	numsyms++;
    }				/* while */

#ifdef AOUTDEBUG
    AOUTDEBUG("AOUTCreateCommon() %d entries (%d bytes) of COMMON data\n",
	      numsyms, size);
#endif

    if ((lookup = xf86loadermalloc((numsyms + 1) * sizeof(LOOKUP))) == NULL) {
	ErrorF("AOUTCreateCommon() Unable to allocate memory\n");
	return NULL;
    }

    aoutfile->comsize = size;
    if ((aoutfile->common = xf86loadercalloc(1, size)) == NULL) {
	ErrorF("AOUTCreateCommon() Unable to allocate memory\n");
	return NULL;
    }

    while (listCOMMON) {
	common = listCOMMON;
	lookup[l].symName = AOUTGetSymbolName(aoutfile, common->sym);
	lookup[l].offset = (funcptr) (aoutfile->common + offset);
#ifdef AOUTDEBUG
	AOUTDEBUG("Adding %p %s\n", (void *)lookup[l].offset,
		  lookup[l].symName);
#endif
	listCOMMON = common->next;
	offset += common->sym->n_value;
	xf86loaderfree(common);
	l++;
    }				/* while */
    /* listCOMMON == NULL */

    lookup[l].symName = NULL;	/* Terminate the list */
    return lookup;
}

/*
 * Symbol Table
 */

static char *
AOUTGetString(AOUTModulePtr aoutfile, int index)
{
    char *symname = (char *)&(aoutfile->strings[index]);

    if (symname[0] == '_') {
	symname++;
    }

    return symname;
}

/*
 * Return the name of a symbol 
 */
static char *
AOUTGetSymbolName(AOUTModulePtr aoutfile, struct AOUT_nlist *sym)
{
    char *symname = AOUTGetString(aoutfile, sym->n_un.n_strx);
    char *name;

    name = xf86loadermalloc(strlen(symname) + 1);
    if (!name)
	FatalError("AOUTGetSymbolName: Out of memory\n");

    strcpy(name, symname);

    return name;
}

/*
 * Return the value of a symbol in the loader's symbol table
 */
static void *
AOUTGetSymbolValue(AOUTModulePtr aoutfile, int index)
{
    void *symval = NULL;	/* value of the indicated symbol */
    itemPtr symbol = NULL;	/* name/value of symbol */
    char *name = NULL;

    name = AOUTGetSymbolName(aoutfile, aoutfile->symtab + index);

    if (name)
	symbol = LoaderHashFind(name);

    if (symbol)
	symval = (unsigned char *)symbol->address;

    xf86loaderfree(name);
    return symval;
}

/*
 * Perform the actual relocation 
 */
static void
AOUT_Relocate(unsigned long *destl, unsigned long val, int pcrel)
{
#ifdef AOUTDEBUG
    AOUTDEBUG("AOUT_Relocate %p : %08lx %s",
	      (void *)destl, *destl, pcrel == 1 ? "rel" : "abs");

#endif
    if (pcrel) {
	/* relative to PC */
	*destl = val - ((unsigned long)destl + sizeof(long));
    } else {
	*destl += val;
    }
#ifdef AOUTDEBUG
    AOUTDEBUG(" -> %08lx\n", *destl);
#endif
}

/*
 * Fix the relocation for text or data section
 */
static AOUTRelocPtr
AOUT_RelocateEntry(AOUTModulePtr aoutfile, int type,
		   struct relocation_info *rel)
{
    AOUTHDR *header = aoutfile->header;
    AOUT_nlist *symtab = aoutfile->symtab;
    int symnum;
    void *symval;
    unsigned long *destl;	/* address of the location to be modified */

    symnum = rel->r_symbolnum;
#ifdef AOUTDEBUG
    {
	char *name;

	if (rel->r_extern) {
	    AOUTDEBUG("AOUT_RelocateEntry: extern %s\n",
		      name = AOUTGetSymbolName(aoutfile, symtab + symnum));
	    xf86loaderfree(name);
	} else {
	    AOUTDEBUG("AOUT_RelocateEntry: intern\n");
	}
	AOUTDEBUG("  pcrel: %d", rel->r_pcrel);
	AOUTDEBUG("  length: %d", rel->r_length);
	AOUTDEBUG("  baserel: %d", rel->r_baserel);
	AOUTDEBUG("  jmptable: %d", rel->r_jmptable);
	AOUTDEBUG("  relative: %d", rel->r_relative);
	AOUTDEBUG("  copy: %d\n", rel->r_copy);
    }
#endif /* AOUTDEBUG */

    if (rel->r_length != 2) {
	ErrorF("AOUT_ReloateEntry: length != 2\n");
    }
    /* 
     * First find the address to modify
     */
    switch (type) {
    case AOUT_TEXT:
	/* Check that the relocation offset is in the text segment */
	if (rel->r_address > header->a_text) {
	    ErrorF("AOUT_RelocateEntry(): "
		   "text relocation out of text section\n");
	}
	destl = (unsigned long *)(aoutfile->text + rel->r_address);
	break;
    case AOUT_DATA:
	/* Check that the relocation offset is in the data segment */
	if (rel->r_address > header->a_data) {
	    ErrorF("AOUT_RelocateEntry():"
		   "data relocation out of data section\n");
	}
	destl = (unsigned long *)(aoutfile->data + rel->r_address);
	break;
    default:
	ErrorF("AOUT_RelocateEntry(): unknown section type %d\n", type);
	return 0;
    }				/* switch */

    /*
     * Now handle the relocation 
     */
    if (rel->r_extern) {
	/* Lookup the symbol in the loader's symbol table */
	symval = AOUTGetSymbolValue(aoutfile, symnum);
	if (symval != 0) {
	    /* we've got the value */
	    AOUT_Relocate(destl, (unsigned long)symval, rel->r_pcrel);
	    return 0;
	} else {
	    /* The symbol should be undefined */
	    switch (symtab[symnum].n_type & AOUT_TYPE) {
	    case AOUT_UNDF:
#ifdef AOUTDEBUG
		AOUTDEBUG("  extern AOUT_UNDEF\n");
#endif
		/* Add this relocation back to the global list */
		return AOUTDelayRelocation(aoutfile, type, rel);

	    default:
		ErrorF("AOUT_RelocateEntry():"
		       " impossible intern relocation type: %d\n",
		       symtab[symnum].n_type);
		return 0;
	    }			/* switch */
	}
    } else {
	/* intern */
	switch (rel->r_symbolnum) {
	case AOUT_TEXT:
#ifdef AOUTDEBUG
	    AOUTDEBUG("  AOUT_TEXT\n");
#endif
	    /* Only absolute intern text relocations need to be handled */
	    if (rel->r_pcrel == 0)
		AOUT_Relocate(destl, (unsigned long)aoutfile->text,
			      rel->r_pcrel);
	    return 0;
	case AOUT_DATA:
#ifdef AOUTDEBUG
	    AOUTDEBUG("  AOUT_DATA\n");
#endif
	    if (rel->r_pcrel == 0)
		AOUT_Relocate(destl, (unsigned long)aoutfile->data
			      - header->a_text, rel->r_pcrel);
	    else
		ErrorF("AOUT_RelocateEntry(): "
		       "don't know how to handle data pc-relative reloc\n");

	    return 0;
	case AOUT_BSS:
#ifdef AOUTDEBUG
	    AOUTDEBUG("  AOUT_BSS\n");
#endif
	    if (rel->r_pcrel == 0)
		AOUT_Relocate(destl, (unsigned long)aoutfile->bss
			      - header->a_text - header->a_data,
			      rel->r_pcrel);
	    else
		ErrorF("AOUT_RelocateEntry(): "
		       "don't know how to handle bss pc-relative reloc\n");

	    return 0;
	default:
	    ErrorF("AOUT_RelocateEntry():"
		   " unknown intern relocation type: %d\n", rel->r_symbolnum);
	    return 0;
	}			/* switch */
    }
}				/* AOUT_RelocateEntry */

static AOUTRelocPtr
AOUTCollectRelocations(AOUTModulePtr aoutfile)
{
    AOUTHDR *header = aoutfile->header;
    int i, nreloc;
    struct relocation_info *rel;
    AOUTRelocPtr reloc_head = NULL;
    AOUTRelocPtr tmp;

    /* Text relocations */
    if (aoutfile->text != NULL && aoutfile->txtrel != NULL) {
	nreloc = header->a_trsize / sizeof(struct relocation_info);

	for (i = 0; i < nreloc; i++) {
	    rel = aoutfile->txtrel + i;
	    tmp = AOUTDelayRelocation(aoutfile, AOUT_TEXT, rel);
	    if (tmp) {
		tmp->next = reloc_head;
		reloc_head = tmp;
	    }
	}			/* for */
    }
    /* Data relocations */
    if (aoutfile->data != NULL && aoutfile->datarel != NULL) {
	nreloc = header->a_drsize / sizeof(struct relocation_info);

	for (i = 0; i < nreloc; i++) {
	    rel = aoutfile->datarel + i;
	    tmp = AOUTDelayRelocation(aoutfile, AOUT_DATA, rel);
	    tmp->next = reloc_head;
	    reloc_head = tmp;
	}			/* for */
    }
    return reloc_head;
}				/* AOUTCollectRelocations */

/*
 * AOUT_GetSymbols()
 * 
 * add the symbols to the loader's symbol table
 */
static LOOKUP *
AOUT_GetSymbols(AOUTModulePtr aoutfile)
{
    int fd = aoutfile->fd;
    AOUTHDR *header = aoutfile->header;
    int nsyms, soff, i, l;
    char *symname;
    AOUT_nlist *s;
    LOOKUP *lookup, *lookup_common;
    AOUTCommonPtr tmp;

    aoutfile->symtab = (AOUT_nlist *) _LoaderFileToMem(fd,
						       AOUT_SYMOFF(header),
						       header->a_syms,
						       "symbols");
    nsyms = header->a_syms / sizeof(AOUT_nlist);
    lookup = xf86loadermalloc(nsyms * sizeof(LOOKUP));
    if (lookup == NULL) {
	ErrorF("AOUT_GetSymbols(): can't allocate memory\n");
	return NULL;
    }
    for (i = 0, l = 0; i < nsyms; i++) {
	s = aoutfile->symtab + i;
	soff = s->n_un.n_strx;
	if (soff == 0 || (s->n_type & AOUT_STAB) != 0)
	    continue;
	symname = AOUTGetSymbolName(aoutfile, s);
#ifdef AOUTDEBUG
	AOUTDEBUG("AOUT_GetSymbols(): %s %02x %02x %08lx\n",
		  symname, s->n_type, s->n_other, s->n_value);
#endif
	switch (s->n_type & AOUT_TYPE) {
	case AOUT_UNDF:
	    if (s->n_value != 0) {
		if (!LoaderHashFind(symname)) {
#ifdef AOUTDEBUG
		    AOUTDEBUG("Adding common %s\n", symname);
#endif
		    tmp = AOUTAddCommon(s, i);
		    if (tmp) {
			tmp->next = listCOMMON;
			listCOMMON = tmp;
		    }
		}
	    } else {
#ifdef AOUTDEBUG
		AOUTDEBUG("Adding undef %s\n", symname);
#endif
	    }
	    xf86loaderfree(symname);
	    break;
	case AOUT_TEXT:
	    if (s->n_type & AOUT_EXT) {
		lookup[l].symName = symname;
		/* text symbols start at 0 */
		lookup[l].offset = (funcptr) (aoutfile->text + s->n_value);
#ifdef AOUTDEBUG
		AOUTDEBUG("Adding text %s %p\n", symname,
			  (void *)lookup[l].offset);
#endif
		l++;
	    } else {
		xf86loaderfree(symname);
	    }
	    break;
	case AOUT_DATA:
	    if (s->n_type & AOUT_EXT) {
		lookup[l].symName = symname;
		/* data symbols are following text */
		lookup[l].offset = (funcptr) (aoutfile->data +
					      s->n_value - header->a_text);
#ifdef AOUTDEBUG
		AOUTDEBUG("Adding data %s %p\n", symname,
			  (void *)lookup[l].offset);
#endif
		l++;
	    } else {
		xf86loaderfree(symname);
	    }
	    break;
	case AOUT_BSS:
	    if (s->n_type & AOUT_EXT) {
		lookup[l].symName = symname;
		/* bss symbols follow both text and data */
		lookup[l].offset = (funcptr) (aoutfile->bss + s->n_value
					      - (header->a_data
						 + header->a_text));
#ifdef AOUTDEBUG
		AOUTDEBUG("Adding bss %s %p\n", symname,
			  (void *)lookup[l].offset);
#endif
		l++;
	    } else {
		xf86loaderfree(symname);
	    }
	    break;
	case AOUT_FN:
#ifdef AOUTDEBUG
	    if (s->n_type & AOUT_EXT) {
		AOUTDEBUG("Ignoring AOUT_FN %s\n", symname);
	    } else {
		AOUTDEBUG("Ignoring AOUT_WARN %s\n", symname);
	    }
#endif
	    xf86loaderfree(symname);
	    break;
	default:
	    ErrorF("Unknown symbol type %x\n", s->n_type & AOUT_TYPE);
	    xf86loaderfree(symname);
	}			/* switch */
    }				/* for */
    lookup[l].symName = NULL;

    lookup_common = AOUTCreateCommon(aoutfile);
    if (lookup_common) {
	LOOKUP *p;

	for (i = 0, p = lookup_common; p->symName; i++, p++) ;
	memcpy(&(lookup[l]), lookup_common, i * sizeof(LOOKUP));

	xf86loaderfree(lookup_common);
	l += i;
	lookup[l].symName = NULL;
    }
    return lookup;
}				/* AOUT_GetSymbols */

/*
 * Public API for the a.out implementation of the loader
 */
void *
AOUTLoadModule(loaderPtr modrec, int aoutfd, LOOKUP ** ppLookup)
{
    AOUTModulePtr aoutfile = NULL;
    AOUTHDR *header;
    AOUTRelocPtr reloc, tail;
    void *v;

#ifdef AOUTDEBUG
    AOUTDEBUG("AOUTLoadModule(%s, %d, %d)\n",
	      modrec->name, modrec->handle, aoutfd);
#endif
    if ((aoutfile = xf86loadercalloc(1, sizeof(AOUTModuleRec))) == NULL) {
	ErrorF("Unable to allocate AOUTModuleRec\n");
	return NULL;
    }

    aoutfile->handle = modrec->handle;
    aoutfile->module = modrec->module;
    aoutfile->fd = aoutfd;
    v = aoutfile->funcs = modrec->funcs;

    /*
     *  Get the a.out header
     */
    aoutfile->header =
	    (AOUTHDR *) _LoaderFileToMem(aoutfd, 0, sizeof(AOUTHDR),
					 "header");
    header = (AOUTHDR *) aoutfile->header;

    /* 
     * Load the 6 other sections 
     */
    /* text */
    if (header->a_text != 0) {
	aoutfile->text = _LoaderFileToMem(aoutfile->fd,
					  AOUT_TXTOFF(header),
					  header->a_text, "text");
	aoutfile->textsize = header->a_text;
    } else {
	aoutfile->text = NULL;
    }
    /* data */
    if (header->a_data != 0) {
	aoutfile->data = _LoaderFileToMem(aoutfile->fd,
					  AOUT_DATOFF(header),
					  header->a_data, "data");
	aoutfile->datasize = header->a_data;
    } else {
	aoutfile->data = NULL;
    }
    /* bss */
    if (header->a_bss != 0) {
	aoutfile->bss = xf86loadercalloc(1, header->a_bss);
	aoutfile->bsssize = header->a_bss;
    } else {
	aoutfile->bss = NULL;
    }
    /* Text Relocations */
    if (header->a_trsize != 0) {
	aoutfile->txtrel = _LoaderFileToMem(aoutfile->fd,
					    AOUT_TRELOFF(header),
					    header->a_trsize, "txtrel");
    } else {
	aoutfile->txtrel = NULL;
    }
    /* Data Relocations */
    if (header->a_drsize != 0) {
	aoutfile->datarel = _LoaderFileToMem(aoutfile->fd,
					     AOUT_DRELOFF(header),
					     header->a_drsize, "datarel");
    } else {
	aoutfile->datarel = NULL;
    }
    /* String table */
    _LoaderFileRead(aoutfile->fd, AOUT_STROFF(header),
		    &(aoutfile->strsize), sizeof(int));
    if (aoutfile->strsize != 0) {
	aoutfile->strings = _LoaderFileToMem(aoutfile->fd,
					     AOUT_STROFF(header),
					     aoutfile->strsize, "strings");
    } else {
	aoutfile->strings = NULL;
    }
    /* load symbol table */
    *ppLookup = AOUT_GetSymbols(aoutfile);

    /* Do relocations */
    reloc = AOUTCollectRelocations(aoutfile);

    if (reloc) {
	for (tail = reloc; tail->next; tail = tail->next) ;
	tail->next = _LoaderGetRelocations(v)->aout_reloc;
	_LoaderGetRelocations(v)->aout_reloc = reloc;
    }

    return (void *)aoutfile;
}

void
AOUTResolveSymbols(void *mod)
{
    AOUTRelocPtr newlist, p, tmp;

#ifdef AOUTDEBUG
    AOUTDEBUG("AOUTResolveSymbols()\n");
#endif

    newlist = 0;
    for (p = _LoaderGetRelocations(mod)->aout_reloc; p;) {
	tmp = AOUT_RelocateEntry(p->file, p->type, p->rel);
	if (tmp) {
	    /* Failed to relocate.  Keep it in the list. */
	    tmp->next = newlist;
	    newlist = tmp;
	}
	tmp = p;
	p = p->next;
	xf86loaderfree(tmp);
    }
    _LoaderGetRelocations(mod)->aout_reloc = newlist;
}				/* AOUTResolveSymbols */

int
AOUTCheckForUnresolved(void *mod)
{
    int symnum;
    AOUTRelocPtr crel;
    char *name;
    int fatalsym = 0, flag;

#ifdef AOUTDEBUG
    AOUTDEBUG("AOUTCheckForUnResolved()\n");
#endif
    if ((crel = _LoaderGetRelocations(mod)->aout_reloc) == NULL)
	return 0;

    while (crel) {
	if (crel->type == AOUT_TEXT) {
	    /* Attempt to make unresolved  text references 
	     * point to a default function */
	    AOUT_Relocate((unsigned long *)(crel->file->text
					    + crel->rel->r_address),
			  (unsigned long)LoaderDefaultFunc,
			  crel->rel->r_pcrel);
	}
	symnum = crel->rel->r_symbolnum;
	name = AOUTGetSymbolName(crel->file, crel->file->symtab + symnum);
	flag = _LoaderHandleUnresolved(name,
				       _LoaderHandleToName(crel->file->
							   handle));
	xf86loaderfree(name);
	if (flag)
	    fatalsym = 1;
	crel = crel->next;
    }
    return fatalsym;
}

void
AOUTUnloadModule(void *modptr)
{
    AOUTModulePtr aoutfile = (AOUTModulePtr) modptr;
    AOUTRelocPtr relptr, *prevptr;

#ifdef AOUTDEBUG
    AOUTDEBUG("AOUTUnLoadModule(0x%p)\n", modptr);
#endif

/*
 * Delete any unresolved relocations
 */

    relptr = _LoaderGetRelocations(aoutfile->funcs)->aout_reloc;
    prevptr = &(_LoaderGetRelocations(aoutfile->funcs)->aout_reloc);

    while (relptr) {
	if (relptr->file == aoutfile) {
	    *prevptr = relptr->next;
	    xf86loaderfree(relptr);
	    relptr = *prevptr;
	} else {
	    prevptr = &(relptr->next);
	    relptr = relptr->next;
	}
    }				/* while */

    /* clean the symbols table */
    LoaderHashTraverse((void *)aoutfile, AOUTHashCleanOut);

#define CheckandFree(ptr,size)  if(ptr) _LoaderFreeFileMem((ptr),(size))

    CheckandFree(aoutfile->strings, aoutfile->strsize);
    CheckandFree(aoutfile->symtab, aoutfile->header->a_syms);
    CheckandFree(aoutfile->datarel, aoutfile->header->a_drsize);
    CheckandFree(aoutfile->txtrel, aoutfile->header->a_trsize);
    CheckandFree(aoutfile->data, aoutfile->header->a_data);
    CheckandFree(aoutfile->text, aoutfile->header->a_text);
    /* Free allocated sections */
    if (aoutfile->bss != NULL) {
	xf86loaderfree(aoutfile->bss);
    }
    if (aoutfile->common != NULL) {
	xf86loaderfree(aoutfile->common);
    }

    /* Free header */
    _LoaderFreeFileMem(aoutfile->header, sizeof(AOUTHDR));

    /* Free the module structure itself */
    xf86loaderfree(aoutfile);

    return;
}

char *
AOUTAddressToSection(void *modptr, unsigned long address)
{
    AOUTModulePtr aoutfile = (AOUTModulePtr) modptr;

    if (address >= (unsigned long)aoutfile->text &&
	address <= (unsigned long)aoutfile->text + aoutfile->textsize) {
	return "text";
    }
    if (address >= (unsigned long)aoutfile->data &&
	address <= (unsigned long)aoutfile->data + aoutfile->datasize) {
	return "data";
    }
    if (address >= (unsigned long)aoutfile->bss &&
	address <= (unsigned long)aoutfile->bss + aoutfile->bsssize) {
	return "bss";
    }

    return NULL;
}

--- NEW FILE: aoutloader.h ---
/*
 * Copyright 1997,1998 Metro Link, Inc.
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aoutloader.h,v 1.3 1998/09/20 14:41:03 dawes Exp $ */

#ifndef _AOUTLOADER_H
#define _AOUTLOADER_H
extern void *AOUTLoadModule(loaderPtr, int, LOOKUP **);
extern void AOUTResolveSymbols(void *);
extern int AOUTCheckForUnresolved(void *);
extern char *AOUTAddressToSection(void *, unsigned long);
extern void AOUTUnloadModule(void *);
#endif

--- NEW FILE: ar.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/ar.h,v 1.3 1998/07/25 16:56:12 dawes Exp $ */

#ifndef _AR_H
#define _AR_H

#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"

#if !(defined(__powerpc__) && defined(Lynx))
struct ar_hdr {
    char ar_name[16];
    char ar_date[12];
    char ar_uid[6];
    char ar_gid[6];
    char ar_mode[8];
    char ar_size[10];
    char ar_fmag[2];
};

#else

#define AIAMAG "<aiaff>\n"
#define SAIAMAG 8
#define AIAFMAG "`\n"

struct fl_hdr {			/* archive fixed length header - printable ascii */
    char fl_magic[SAIAMAG];	/* Archive file magic string */
    char fl_memoff[12];		/* Offset to member table */
    char fl_gstoff[12];		/* Offset to global symbol table */
    char fl_fstmoff[12];	/* Offset to first archive member */
    char fl_lstmoff[12];	/* Offset to last archive member */
    char fl_freeoff[12];	/* Offset to first mem on free list */
};

#define FL_HDR struct fl_hdr
#define FL_HSZ sizeof(FL_HDR)

struct ar_hdr {			/* archive file member header - printable ascii */
    char ar_size[12];		/* file member size - decimal */
    char ar_nxtmem[12];		/* pointer to next member -  decimal */
    char ar_prvmem[12];		/* pointer to previous member -  decimal */
    char ar_date[12];		/* file member date - decimal */
    char ar_uid[12];		/* file member user id - decimal */
    char ar_gid[12];		/* file member group id - decimal */
    char ar_mode[12];		/* file member mode - octal */
    char ar_namlen[4];		/* file member name length - decimal */
    union {
	char an_name[2];	/* variable length member name */
	char an_fmag[2];	/* AIAFMAG - string to end header */
    } _ar_name;			/*      and variable length name */
};

#define ar_name _ar_name.an_name

/*
 *	Note: 	'ar_namlen' contains the length of the member name which
 *		may be up to 255 chars.  The character string containing
 *		the name begins at '_ar_name.ar_name'.  The terminating
 *		string AIAFMAG, is only cosmetic. File member contents begin
 *		at the first even byte boundary past 'header position + 
 *		sizeof(struct ar_hdr) + ar_namlen',  and continue for
 *		'ar_size' bytes.
*/

#define AR_HDR struct ar_hdr
#define AR_HSZ sizeof(AR_HDR)

#endif /* !__powerpc__ && Lynx */

#endif /* _AR_H */

--- NEW FILE: coff.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coff.h,v 1.5 1998/07/25 16:56:12 dawes Exp $ */

/* This file was implemented from the information in the book
   Understanding and Using COFF
   Gintaras R. Gircys
   O'Reilly, 1988
   and by looking at the Linux kernel code.

   It is therefore most likely free to use...

   If the file format changes in the COFF object, this file should be
   subsequently updated to reflect the changes.

   The actual loader module only uses a few of the COFF structures. 
   Only those are included here.  If you wish more information about 
   COFF, thein check out the book mentioned above.
*/

#ifndef _COFF_H
#define _COFF_H

#define  E_SYMNMLEN  8		/* Number of characters in a symbol name         */
/*
 * Intel 386/486  
 */

/*
 * FILE HEADER 
 */

typedef struct COFF_filehdr {
    unsigned short f_magic;	/* magic number                 */
    unsigned short f_nscns;	/* number of sections           */
    long f_timdat;		/* time & date stamp            */
    long f_symptr;		/* file pointer to symtab       */
    long f_nsyms;		/* number of symtab entries     */
    unsigned short f_opthdr;	/* sizeof(optional hdr)         */
    unsigned short f_flags;	/* flags                        */
} FILHDR;

#define	FILHSZ	sizeof(FILHDR)

/*
 * SECTION HEADER 
 */

typedef struct COFF_scnhdr {
    char s_name[8];		/* section name                 */
    long s_paddr;		/* physical address             */
    long s_vaddr;		/* virtual address              */
    long s_size;		/* section size                 */
    long s_scnptr;		/* raw data for section         */
    long s_relptr;		/* relocation                   */
    long s_lnnoptr;		/* line numbers                 */
    unsigned short s_nreloc;	/* number of relocation entries */
    unsigned short s_nlnno;	/* number of line number entries */
    long s_flags;		/* flags                        */
} SCNHDR;

#define	COFF_SCNHDR	struct COFF_scnhdr
#define	COFF_SCNHSZ	sizeof(COFF_SCNHDR)
#define SCNHSZ		COFF_SCNHSZ

/*
 * the optional COFF header as used by Linux COFF
 */

typedef struct {
    char magic[2];		/* type of file                  */
    char vstamp[2];		/* version stamp                 */
    char tsize[4];		/* text size in bytes            */
    char dsize[4];		/* initialized data              */
    char bsize[4];		/* uninitialized data            */
    char entry[4];		/* entry point                   */
    char text_start[4];		/* base of text                  */
    char data_start[4];		/* base of data                  */
} AOUTHDR;

/*
 * SYMBOLS 
 */

typedef struct COFF_syment {
    union {
	char _n_name[E_SYMNMLEN];	/* Symbol name (first 8 chars)  */
	struct {
	    long _n_zeroes;	/* Leading zeros               */
	    long _n_offset;	/* Offset for a header section */
	} _n_n;
	char *_n_nptr[2];	/* allows for overlaying       */
    } _n;

    long n_value;		/* address of the segment       */
    short n_scnum;		/* Section number               */
    unsigned short n_type;	/* Type of section              */
    char n_sclass;		/* Loader class                 */
    char n_numaux;		/* Number of aux entries following */
} SYMENT;

#define n_name		_n._n_name
#define n_nptr		_n._n_nptr[1]
#define n_zeroes	_n._n_n._n_zeroes
#define n_offset	_n._n_n._n_offset

#define COFF_E_SYMNMLEN	 8	/* characters in a short symbol name    */
#define COFF_E_FILNMLEN	14	/* characters in a file name            */
#define COFF_E_DIMNUM	 4	/* array dimensions in aux entry        */
#define SYMNMLEN	COFF_E_SYMNMLEN
#define SYMESZ		18	/* not really sizeof(SYMENT) due to padding */

/* Special section number found in the symbol section */
#define	N_UNDEF	0
#define	N_ABS	-1
#define	N_DEBUG	-2

/* Symbol storage class values */
#define C_NULL		0
#define C_EXT		2
#define C_FILE		103
#define C_HIDEXT	107

/*
 * AUX Entries
 */
typedef struct COFF_auxent {
    long x_scnlen;
    long x_parmhash;
    unsigned short x_snhash;
    unsigned char x_smtyp;
    unsigned char x_smclas;
    long x_stab;
    unsigned short x_snstab;
} AUXENT;

/* Auxillary Symbol type values */
#define XTY_ER	0		/* Enternal Reference */
#define XTY_SD	1		/* csect section definition */
#define XTY_LD	2		/* Label definition */
#define XTY_CM	3		/* common csect definition */

/* Auxillary Symbol storage mapping class values */
#define XMC_PR	0		/* Program code */
#define XMC_RO	1		/* Read-only constant */
#define XMC_DB	2		/* Debug dictionary */
#define XMC_TC	3		/* TOC entry */
#define XMC_UA	4		/* Unclassified */
#define XMC_RW	5		/* Read/write data */
#define XMC_GL	6		/* Global linkage */
#define XMC_XO	7		/* Extended operation */
#define XMC_SV	8		/* Supervisor call descriptor */
#define XMC_BS	9		/* BSS class */
#define XMC_DS	10		/* Function descriptor csect */
#define XMC_UC	11		/* Unnamed FORTRAN comon */
#define XMC_TI	12		/* Reserved */
#define XMC_TB	13		/* Reserved */
#define XMC_TC0	15		/* TOC anchor */
#define XMC_TD	16		/* Scalar data entry in TOC */

/*
 * RELOCATION DIRECTIVES
 */

typedef struct COFF_reloc {
    long r_vaddr;		/* Virtual address of item    */
    long r_symndx;		/* Symbol index in the symtab */
#if defined(__powerpc__)
    union {
	unsigned short _r_type;	/* old style coff relocation type */
	struct {
	    char _r_rsize;	/* sign and reloc bit len */
	    char _r_rtype;	/* toc relocation type */
	} _r_r;
    } _r;
#define r_otype  _r._r_type	/* old style reloc - original name */
#define r_rsize _r._r_r._r_rsize	/* extract sign and bit len    */
#define r_type _r._r_r._r_rtype	/* extract toc relocation type */
#else
    unsigned short r_type;	/* Relocation type             */
#endif
} RELOC;

#define COFF_RELOC	struct COFF_reloc
#define COFF_RELSZ	10
#define RELSZ		COFF_RELSZ

/*
 * x86 Relocation types 
 */
#define	R_ABS		000
#define	R_DIR32		006
#define	R_PCRLONG	024

#if defined(__powerpc__)
/*
 * Power PC
 */
#define R_LEN	0x1F		/* extract bit-length field */
#define R_SIGN	0x80		/* extract sign of relocation */
#define R_FIXUP	0x40		/* extract code-fixup bit */

#define RELOC_RLEN(x)	((x)._r._r_r._r_rsize & R_LEN)
#define RELOC_RSIGN(x)	((x)._r._r_r._r_rsize & R_SIGN)
#define RELOC_RFIXUP(x)	((x)._r._r_r._r_rsize & R_FIXUP)
#define RELOC_RTYPE(x)	((x)._r._r_r._r_rtype)

/*
 * POWER and PowerPC - relocation types
 */
#define R_POS	0x00	/* A(sym) Positive Relocation */
#define R_NEG	0x01	/* -A(sym) Negative Relocation */
#define R_REL	0x02	/* A(sym-*) Relative to self */
#define R_TOC	0x03	/* A(sym-TOC) Relative to TOC */
#define R_TRL	0x12	/* A(sym-TOC) TOC Relative indirect load. */
					/* modifiable instruction */
#define R_TRLA	0x13	/* A(sym-TOC) TOC Rel load address. modifiable inst */
#define R_GL	0x05	/* A(external TOC of sym) Global Linkage */
#define R_TCL	0x06	/* A(local TOC of sym) Local object TOC address */
#define R_RL	0x0C	/* A(sym) Pos indirect load. modifiable instruction */
#define R_RLA	0x0D	/* A(sym) Pos Load Address. modifiable instruction */
#define R_REF	0x0F	/* AL0(sym) Non relocating ref. No garbage collect */
#define R_BA	0x08	/* A(sym) Branch absolute. Cannot modify instruction */
#define R_RBA	0x18	/* A(sym) Branch absolute. modifiable instruction */
#define R_RBAC	0x19	/* A(sym) Branch absolute constant. modifiable instr */
#define R_BR	0x0A	/* A(sym-*) Branch rel to self. non modifiable */
#define R_RBR	0x1A	/* A(sym-*) Branch rel to self. modifiable instr */
#define R_RBRC	0x1B	/* A(sym-*) Branch absolute const. */
						/* modifiable to R_RBR */
#define R_RTB	0x04	/* A((sym-*)/2) RT IAR Rel Branch. non modifiable */
#define R_RRTBI	0x14	/* A((sym-*)/2) RT IAR Rel Br. modifiable to R_RRTBA */
#define R_RRTBA	0x15	/* A((sym-*)/2) RT absolute br. modifiable to R_RRTBI */
#endif /* __powerpc */

#endif /* _COFF_H */

--- NEW FILE: coffloader.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coffloader.c,v 1.21tsi Exp $ */

/*
 *
 * Copyright 1995,96 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
[...1316 lines suppressed...]
 */
    xf86loaderfree(cofffile);

    return;
}

char *
COFFAddressToSection(void *modptr, unsigned long address)
{
    COFFModulePtr cofffile = (COFFModulePtr) modptr;
    int i;

    for (i = 1; i < cofffile->numsh; i++) {
	if (address >= (unsigned long)cofffile->saddr[i] &&
	    address <= (unsigned long)cofffile->saddr[i] + SecSize(i)) {
	    return cofffile->sections[i].s_name;
	}
    }
    return NULL;
}

--- NEW FILE: coffloader.h ---
/*
 *
 * Copyright 1997,1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coffloader.h,v 1.3 1998/09/20 14:41:04 dawes Exp $ */

#ifndef _COFFLOADER_H
#define _COFFLOADER_H
/* coffloader.c */
extern void *COFFLoadModule(loaderPtr, int, LOOKUP **);
extern void COFFResolveSymbols(void *);
extern int COFFCheckForUnresolved(void *);
extern char *COFFAddressToSection(void *, unsigned long);
extern void COFFUnloadModule(void *);
#endif /* _COFFLOADER_H */

--- NEW FILE: dixsym.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/loader/dixsym.c,v 1.1.4.4.4.2 2004/03/04 17:48:07 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dixsym.c,v 1.63 2003/12/03
 * 17:11:29 tsi Exp $ */

/*
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
/*
 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#undef DBMALLOC
#include "sym.h"
#include "colormap.h"
#include "cursor.h"
#include "dix.h"
#include "dixevents.h"
#include "dixfont.h"
#include "dixstruct.h"
#include "misc.h"
#include "globals.h"
#include "os.h"
#include "osdep.h"
#include "resource.h"
#include "servermd.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "extension.h"
#define EXTENSION_PROC_ARGS void *
#include "extnsionst.h"
#include "swaprep.h"
#include "swapreq.h"
#include "inputstr.h"
#include "XIproto.h"
#include "exevents.h"
#include "extinit.h"
#ifdef XV
#include "xvmodproc.h"
#endif
#include "dgaproc.h"
#ifdef RENDER
#include "mipict.h"
#endif
#include "selection.h"
#ifdef XKB
#include <X11/extensions/XKBsrv.h>
#endif

extern Selection *CurrentSelections;
extern int NumCurrentSelections;

/* DIX things */

LOOKUP dixLookupTab[] = {

    /* dix */
    /* atom.c */
    SYMFUNC(MakeAtom)
    SYMFUNC(ValidAtom)
    /* colormap.c */
    SYMFUNC(AllocColor)
    SYMFUNC(CreateColormap)
    SYMFUNC(FakeAllocColor)
    SYMFUNC(FakeFreeColor)
    SYMFUNC(FreeColors)
    SYMFUNC(StoreColors)
    SYMFUNC(TellLostMap)
    SYMFUNC(TellGainedMap)
    SYMFUNC(QueryColors)
    /* cursor.c */
    SYMFUNC(FreeCursor)
    /* devices.c */
    SYMFUNC(Ones)
    SYMFUNC(InitButtonClassDeviceStruct)
    SYMFUNC(InitFocusClassDeviceStruct)
    SYMFUNC(InitLedFeedbackClassDeviceStruct)
    SYMFUNC(InitPtrFeedbackClassDeviceStruct)
    SYMFUNC(InitKbdFeedbackClassDeviceStruct)
    SYMFUNC(InitIntegerFeedbackClassDeviceStruct)
    SYMFUNC(InitStringFeedbackClassDeviceStruct)
    SYMFUNC(InitBellFeedbackClassDeviceStruct)
    SYMFUNC(InitValuatorClassDeviceStruct)
    SYMFUNC(InitKeyClassDeviceStruct)
    SYMFUNC(InitKeyboardDeviceStruct)
    SYMFUNC(SendMappingNotify)
    /* dispatch.c */
    SYMFUNC(SetInputCheck)
    SYMFUNC(SendErrorToClient)
    SYMFUNC(UpdateCurrentTime)
    SYMFUNC(UpdateCurrentTimeIf)
    SYMFUNC(ProcBadRequest)
    SYMVAR(dispatchException)
    SYMVAR(isItTimeToYield)
    SYMVAR(ClientStateCallback)
    SYMVAR(ServerGrabCallback)
    SYMVAR(CurrentSelections)
    SYMVAR(NumCurrentSelections)
    /* dixfonts.c */
    SYMFUNC(CloseFont)
    SYMFUNC(FontToXError)
    SYMFUNC(LoadGlyphs)
    SYMVAR(fpe_functions)
    /* dixutils.c */
    SYMFUNC(AddCallback)
    SYMFUNC(ClientSleep)
    SYMFUNC(ClientTimeToServerTime)
    SYMFUNC(ClientWakeup)
    SYMFUNC(CompareTimeStamps)
    SYMFUNC(CopyISOLatin1Lowered)
    SYMFUNC(DeleteCallback)
    SYMFUNC(LookupClient)
    SYMFUNC(LookupDrawable)
    SYMFUNC(LookupWindow)
    SYMFUNC(NoopDDA)
    SYMFUNC(QueueWorkProc)
    SYMFUNC(RegisterBlockAndWakeupHandlers)
    SYMFUNC(RemoveBlockAndWakeupHandlers)
#ifdef XCSECURITY
    SYMFUNC(SecurityLookupDrawable)
    SYMFUNC(SecurityLookupWindow)
#endif
    /* events.c */
    SYMFUNC(CheckCursorConfinement)
    SYMFUNC(DeliverEvents)
    SYMFUNC(NewCurrentScreen)
    SYMFUNC(PointerConfinedToScreen)
    SYMFUNC(TryClientEvents)
    SYMFUNC(WriteEventsToClient)
    SYMVAR(DeviceEventCallback)
    SYMVAR(EventCallback)
    SYMVAR(inputInfo)
    SYMVAR(SetCriticalEvent)
#ifdef PANORAMIX
    SYMVAR(XineramaGetCursorScreen)
#endif
    /* property.c */
    SYMFUNC(ChangeWindowProperty)
    /* extension.c */
    SYMFUNC(AddExtension)
    SYMFUNC(AddExtensionAlias)
    SYMFUNC(CheckExtension)
    SYMFUNC(DeclareExtensionSecurity)
    SYMFUNC(MinorOpcodeOfRequest)
    SYMFUNC(StandardMinorOpcode)
    /* gc.c */
    SYMFUNC(CopyGC)
    SYMFUNC(CreateGC)
    SYMFUNC(CreateScratchGC)
    SYMFUNC(ChangeGC)
    SYMFUNC(dixChangeGC)
    SYMFUNC(DoChangeGC)
    SYMFUNC(FreeGC)
    SYMFUNC(FreeScratchGC)
    SYMFUNC(GetScratchGC)
    SYMFUNC(SetClipRects)
    SYMFUNC(ValidateGC)
    SYMFUNC(VerifyRectOrder)
    SYMFUNC(SetDashes)
    /* globals.c */
    SYMVAR(DPMSEnabled)
    SYMVAR(DPMSCapableFlag)
    SYMVAR(DPMSOffTime)
    SYMVAR(DPMSPowerLevel)
    SYMVAR(DPMSStandbyTime)
    SYMVAR(DPMSSuspendTime)
    SYMVAR(DPMSEnabledSwitch)
    SYMVAR(DPMSDisabledSwitch)
    SYMVAR(defaultDPMSEnabled)
    /* bigreq */
    SYMVAR(maxBigRequestSize)
#ifdef XV
    /* XXX These are exported from the DDX, not DIX. */
    SYMVAR(XvScreenInitProc)
    SYMVAR(XvGetScreenIndexProc)
    SYMVAR(XvGetRTPortProc)
    SYMVAR(XvMCScreenInitProc)
#endif
    SYMVAR(ScreenSaverBlanking)
    SYMVAR(WindowTable)
    SYMVAR(clients)
    SYMVAR(currentMaxClients)
    SYMVAR(currentTime)
    SYMVAR(defaultColorVisualClass)
    SYMVAR(globalSerialNumber)
    SYMVAR(lastDeviceEventTime)
    SYMVAR(monitorResolution)
    SYMVAR(permitOldBugs)
    SYMVAR(screenInfo)
    SYMVAR(serverClient)
    SYMVAR(serverGeneration)
    /* main.c */
    SYMFUNC(NotImplemented)
    /* pixmap.c */
    SYMFUNC(AllocatePixmap)
    SYMFUNC(GetScratchPixmapHeader)
    SYMFUNC(FreeScratchPixmapHeader)
    SYMVAR(PixmapWidthPaddingInfo)
    /* privates.c */
    SYMFUNC(AllocateClientPrivate)
    SYMFUNC(AllocateClientPrivateIndex)
    SYMFUNC(AllocateGCPrivate)
    SYMFUNC(AllocateGCPrivateIndex)
    SYMFUNC(AllocateWindowPrivate)
    SYMFUNC(AllocateWindowPrivateIndex)
    SYMFUNC(AllocateScreenPrivateIndex)
    SYMFUNC(AllocateColormapPrivateIndex)
#ifdef PIXPRIV
    SYMFUNC(AllocatePixmapPrivateIndex)
    SYMFUNC(AllocatePixmapPrivate)
#endif
    /* resource.c */
    SYMFUNC(AddResource)
    SYMFUNC(ChangeResourceValue)
    SYMFUNC(CreateNewResourceClass)
    SYMFUNC(CreateNewResourceType)
    SYMFUNC(FakeClientID)
    SYMFUNC(FreeResource)
    SYMFUNC(FreeResourceByType)
    SYMFUNC(GetXIDList)
    SYMFUNC(GetXIDRange)
    SYMFUNC(LookupIDByType)
    SYMFUNC(LookupIDByClass)
    SYMFUNC(LegalNewID)
#ifdef XCSECURITY
    SYMFUNC(SecurityLookupIDByClass)
    SYMFUNC(SecurityLookupIDByType)
#endif
    SYMFUNC(FindClientResourcesByType)
    SYMFUNC(FindAllClientResources)
    SYMVAR(lastResourceType)
    SYMVAR(TypeMask)
#ifdef RES
    SYMFUNC(RegisterResourceName)
    SYMVAR(ResourceNames)
#endif
    /* swaprep.c */
    SYMFUNC(CopySwap32Write)
    SYMFUNC(Swap32Write)
    SYMFUNC(SwapConnSetupInfo)
    SYMFUNC(SwapConnSetupPrefix)
    SYMFUNC(SwapShorts)
    SYMFUNC(SwapLongs)
    /* swapreq.c */
    SYMFUNC(SwapColorItem)
    /* tables.c */
    SYMVAR(EventSwapVector)
    SYMVAR(ReplySwapVector)
    SYMVAR(ProcVector)
    /* window.c */
    SYMFUNC(ChangeWindowAttributes)
    SYMFUNC(CheckWindowOptionalNeed)
    SYMFUNC(CreateUnclippedWinSize)
    SYMFUNC(CreateWindow)
    SYMFUNC(FindWindowWithOptional)
    SYMFUNC(GravityTranslate)
    SYMFUNC(MakeWindowOptional)
    SYMFUNC(MapWindow)
    SYMFUNC(MoveWindowInStack)
    SYMFUNC(NotClippedByChildren)
    SYMFUNC(ResizeChildrenWinSize)
    SYMFUNC(SaveScreens)
    SYMFUNC(SendVisibilityNotify)
    SYMFUNC(SetWinSize)
    SYMFUNC(SetBorderSize)
    SYMFUNC(TraverseTree)
    SYMFUNC(UnmapWindow)
    SYMFUNC(WalkTree)
    SYMFUNC(WindowsRestructured)
    SYMVAR(deltaSaveUndersViewable)
    SYMVAR(numSaveUndersViewable)
    SYMVAR(savedScreenInfo)
    SYMVAR(screenIsSaved)

    /*os/ */
    /* access.c */
    SYMFUNC(LocalClient)
    /* utils.c */
    SYMFUNC(Xstrdup)
    SYMFUNC(XNFstrdup)
    SYMVAR(Must_have_memory)
    SYMFUNC(AdjustWaitForDelay)
    SYMVAR(noTestExtensions)
    SYMFUNC(GiveUp)
    /* log.c */
    SYMFUNC(LogVWrite)
    SYMFUNC(LogWrite)
    SYMFUNC(LogVMessageVerb)
    SYMFUNC(LogMessageVerb)
    SYMFUNC(LogMessage)
    SYMFUNC(FatalError)
    SYMFUNC(VErrorF)
    SYMFUNC(ErrorF)
    SYMFUNC(Error)
    /* xalloc.c */
    SYMFUNC(XNFalloc)
    SYMFUNC(XNFcalloc)
    SYMFUNC(XNFrealloc)
    SYMFUNC(Xalloc)
    SYMFUNC(Xcalloc)
    SYMFUNC(Xfree)
    SYMFUNC(Xrealloc)
    /* WaitFor.c */
    SYMFUNC(ScreenSaverTime)
    SYMFUNC(TimerFree)
    SYMFUNC(TimerSet)
    SYMFUNC(TimerCancel)
    SYMFUNC(SetDPMSTimers)
    /* io.c */
    SYMFUNC(WriteToClient)
    SYMFUNC(SetCriticalOutputPending)
    SYMVAR(FlushCallback)
    SYMVAR(ReplyCallback)
    SYMVAR(SkippedRequestsCallback)
    SYMFUNC(ResetCurrentRequest)
    /* connection.c */
    SYMFUNC(IgnoreClient)
    SYMFUNC(AttendClient)
    SYMFUNC(AddEnabledDevice)
    SYMFUNC(RemoveEnabledDevice)
    SYMFUNC(MakeClientGrabPervious)
    SYMFUNC(MakeClientGrabImpervious)
    SYMVAR(GrabInProgress)

    /* devices.c */
    SYMFUNC(InitPointerDeviceStruct)
    SYMFUNC(LookupKeyboardDevice)
    SYMFUNC(LookupPointerDevice)

#ifdef XKB
    /* xkb/xkbInit.c */
    SYMFUNC(XkbInitKeyboardDeviceStruct)
    SYMFUNC(XkbSetRulesDflts)
    SYMVAR(noXkbExtension)
#endif

#ifdef XINPUT
    /* Xi */
    /* exevents.c */
    SYMFUNC(InitValuatorAxisStruct)
    SYMFUNC(InitProximityClassDeviceStruct)
    /* extinit.c */
    SYMFUNC(AssignTypeAndName)
#endif

    /* xf86DGA.c */
    /* XXX This is exported from the DDX, not DIX. */
    SYMVAR(XDGAEventBase)

    /* librender.a */
#ifdef RENDER
    SYMFUNC(PictureInit)
    SYMFUNC(miPictureInit)
    SYMFUNC(miComputeCompositeRegion)
    SYMFUNC(miGlyphs)
    SYMFUNC(miCompositeRects)
    SYMVAR(PictureScreenPrivateIndex)
    SYMFUNC(PictureTransformPoint)
    SYMFUNC(PictureAddFilter)
    SYMFUNC(PictureSetFilterAlias)
    SYMFUNC(PictureGetSubpixelOrder)
    SYMFUNC(PictureSetSubpixelOrder)
#endif

    {0, 0}
};

--- NEW FILE: dlloader.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dlloader.c,v 1.13 2003/10/15 16:29:02 dawes Exp $ */

/*
 *
 * Copyright (c) 1997 The XFree86 Project, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of the
 * XFree86 Project, Inc. not be used in advertising or publicity
 * pertaining to distribution of the software without specific,
 * written prior permission.  The Xfree86 Project, Inc. makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied
 * warranty.
 *
 * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL THE XFREE86 PROJECT, INC. BE LIABLE
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.  */

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

#include "Xos.h"
#include "os.h"

#include "sym.h"
#include "loader.h"
#include "dlloader.h"

#ifdef DL_LAZY
#define DLOPEN_LAZY DL_LAZY
#else
#ifdef RTLD_LAZY
#define DLOPEN_LAZY RTLD_LAZY
#else
#ifdef __FreeBSD__
#define DLOPEN_LAZY 1
#else
#define DLOPEN_LAZY 0
#endif
#endif
#endif
#ifdef LD_GLOBAL
#define DLOPEN_GLOBAL LD_GLOBAL
#else
#ifdef RTLD_GLOBAL
#define DLOPEN_GLOBAL RTLD_GLOBAL
#else
#define DLOPEN_GLOBAL 0
#endif
#endif

#define DLOPEN_FLAGS ( DLOPEN_LAZY | DLOPEN_GLOBAL )

#if defined(CSRG_BASED) && !defined(__ELF__)
#define NEED_UNDERSCORE_FOR_DLLSYM
#endif

/*
 * This structure contains all of the information about a module
 * that has been loaded.
 */
typedef struct {
    int handle;
    void *dlhandle;
} DLModuleRec, *DLModulePtr;

/* 
 * a list of loaded modules XXX can be improved
 */
typedef struct DLModuleList {
    DLModulePtr module;
    struct DLModuleList *next;
} DLModuleList;

DLModuleList *dlModuleList = NULL;

/*
 * Search a symbol in the module list
 */
void *
DLFindSymbol(const char *name)
{
    DLModuleList *l;
    void *p;

#ifdef NEED_UNDERSCORE_FOR_DLLSYM
    char *n;

    n = xf86loadermalloc(strlen(name) + 2);
    sprintf(n, "_%s", name);
#endif

    (void)dlerror();		/* Clear out any previous error */
    for (l = dlModuleList; l != NULL; l = l->next) {
#ifdef NEED_UNDERSCORE_FOR_DLLSYM
	p = dlsym(l->module->dlhandle, n);
#else
	p = dlsym(l->module->dlhandle, name);
#endif
	if (dlerror() == NULL) {
#ifdef NEED_UNDERSCORE_FOR_DLLSYM
	    xf86loaderfree(n);
#endif
	    return p;
	}
    }
#ifdef NEED_UNDERSCORE_FOR_DLLSYM
    xf86loaderfree(n);
#endif

    return NULL;
}

/*
 * public interface
 */
void *
DLLoadModule(loaderPtr modrec, int fd, LOOKUP ** ppLookup)
{
    DLModulePtr dlfile;
    DLModuleList *l;

    if ((dlfile = xf86loadercalloc(1, sizeof(DLModuleRec))) == NULL) {
	ErrorF("Unable  to allocate DLModuleRec\n");
	return NULL;
    }
    dlfile->handle = modrec->handle;
    dlfile->dlhandle = dlopen(modrec->name, DLOPEN_FLAGS);
    if (dlfile->dlhandle == NULL) {
	ErrorF("dlopen: %s\n", dlerror());
	xf86loaderfree(dlfile);
	return NULL;
    }
    /* Add it to the module list */
    l = xf86loadermalloc(sizeof(DLModuleList));
    l->module = dlfile;
    l->next = dlModuleList;
    dlModuleList = l;
    *ppLookup = NULL;

    return (void *)dlfile;
}

void
DLResolveSymbols(void *mod)
{
    return;
}

int
DLCheckForUnresolved(void *mod)
{
    return 0;
}

void
DLUnloadModule(void *modptr)
{
    DLModulePtr dlfile = (DLModulePtr) modptr;
    DLModuleList *l, *p;

    /*  remove it from dlModuleList */
    if (dlModuleList->module == modptr) {
	l = dlModuleList;
	dlModuleList = l->next;
	xf86loaderfree(l);
    } else {
	p = dlModuleList;
	for (l = dlModuleList->next; l != NULL; l = l->next) {
	    if (l->module == modptr) {
		p->next = l->next;
		xf86loaderfree(l);
		break;
	    }
	    p = l;
	}
    }
    dlclose(dlfile->dlhandle);
    xf86loaderfree(modptr);
}

--- NEW FILE: dlloader.h ---
/*
 * Copyright 1997 Metro Link, Inc.
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dlloader.h,v 1.2 1998/07/25 16:56:14 dawes Exp $ */

#ifndef _DLLOADER_H
#define _DLLOADER_H
extern void *DLLoadModule(loaderPtr, int, LOOKUP **);
extern void DLResolveSymbols(void *);
extern int DLCheckForUnresolved(void *);
extern void DLUnloadModule(void *);
extern void *DLFindSymbol(const char *name);

#endif

--- NEW FILE: elf.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elf.h,v 1.16 2003/06/12 14:12:34 eich Exp $ */

typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef long Elf32_Sword;
typedef unsigned int Elf32_Word;

typedef unsigned long Elf64_Addr;
typedef unsigned short Elf64_Half;
typedef unsigned long Elf64_Off;
typedef int Elf64_Sword;
typedef unsigned int Elf64_Word;
typedef unsigned long Elf64_Xword;
typedef long Elf64_Sxword;

/* These constants are for the segment types stored in the image headers */
#define PT_NULL    0
#define PT_LOAD    1
#define PT_DYNAMIC 2
#define PT_INTERP  3
#define PT_NOTE    4
#define PT_SHLIB   5
#define PT_PHDR    6
#define PT_LOPROC  0x70000000
#define PT_HIPROC  0x7fffffff

/* These constants define the different elf file types */
#define ET_NONE   0
#define ET_REL    1
#define ET_EXEC   2
#define ET_DYN    3
#define ET_CORE   4
#define ET_LOPROC 5
#define ET_HIPROC 6

/* These constants define the various ELF target machines */
#define EM_NONE  	0
#define EM_M32   	1
#define EM_SPARC 	2
#define EM_386   	3
#define EM_68K   	4
#define EM_88K   	5
#define EM_486   	6	/* Perhaps disused */
#define EM_860   	7
#define EM_MIPS		8
#define EM_MIPS_RS4_BE 10
#define EM_PARISC      15
#define EM_SPARC32PLUS 18
#define EM_PPC	       20
#define EM_SPARCV9     43
#define EM_IA_64       50
#define EM_ALPHA       0x9026

/* This is the info that is needed to parse the dynamic section of the file */
#define DT_NULL		0
#define DT_NEEDED	1
#define DT_PLTRELSZ	2
#define DT_PLTGOT	3
#define DT_HASH		4
#define DT_STRTAB	5
#define DT_SYMTAB	6
#define DT_RELA		7
#define DT_RELASZ	8
#define DT_RELAENT	9
#define DT_STRSZ	10
#define DT_SYMENT	11
#define DT_INIT		12
#define DT_FINI		13
#define DT_SONAME	14
#define DT_RPATH 	15
#define DT_SYMBOLIC	16
#define DT_REL	        17
#define DT_RELSZ	18
#define DT_RELENT	19
#define DT_PLTREL	20
#define DT_DEBUG	21
#define DT_TEXTREL	22
#define DT_JMPREL	23
#define DT_LOPROC	0x70000000
#define DT_HIPROC	0x7fffffff

/* This info is needed when parsing the symbol table */
#define STB_LOCAL  0
#define STB_GLOBAL 1
#define STB_WEAK   2

#define STT_NOTYPE  0
#define STT_OBJECT  1
#define STT_FUNC    2
#define STT_SECTION 3
#define STT_FILE    4
#define STT_LOPROC  13
#define STT_HIPROC  15

#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)

#define ELF64_ST_BIND(x) ELF32_ST_BIND (x)
#define ELF64_ST_TYPE(x) ELF32_ST_TYPE (x)

typedef struct dynamic32 {
    Elf32_Sword d_tag;
    union {
	Elf32_Sword d_val;
	Elf32_Addr d_ptr;
    } d_un;
} Elf32_Dyn;

typedef struct dynamic64 {
    Elf64_Sxword d_tag;
    union {
	Elf64_Xword d_val;
	Elf64_Addr d_ptr;
    } d_un;
} Elf64_Dyn;

#ifndef QNX4
extern Elf32_Dyn _DYNAMIC[];
#endif

/* The following are used with relocations */
#define ELF32_R_SYM(x) ((x) >> 8)
#define ELF32_R_TYPE(x) ((x) & 0xff)

#define ELF64_R_SYM(x)  ((x) >> 32)
#define ELF64_R_TYPE(x)  ((x) & 0xffffffff)

/* x86 Relocation Types */
#define R_386_NONE	0
#define R_386_32	1
#define R_386_PC32	2
#define R_386_GOT32	3
#define R_386_PLT32	4
#define R_386_COPY	5
#define R_386_GLOB_DAT	6
#define R_386_JMP_SLOT	7
#define R_386_RELATIVE	8
#define R_386_GOTOFF	9
#define R_386_GOTPC	10
#define R_386_NUM	11

/* AMD64 Relocation Types */
#define R_X86_64_NONE                   0
#define R_X86_64_64                     1
#define R_X86_64_PC32                   2
#define R_X86_64_GOT32                  3
#define R_X86_64_PLT32                  4
#define R_X86_64_COPY                   5
#define R_X86_64_GLOB_DAT               6
#define R_X86_64_JUMP_SLOT              7
#define R_X86_64_RELATIVE               8
#define R_X86_64_GOTPCREL               9
#define R_X86_64_32                    10
#define R_X86_64_32S                   11
#define R_X86_64_16                    12
#define R_X86_64_PC16                  13
#define R_X86_64_8                     14
#define R_X86_64_PC8                   15
#define R_X86_64_GNU_VTINHERIT         250
#define R_X86_64_GNU_VTENTRY           251

/* sparc Relocation Types */
#define	R_SPARC_NONE		0
#define	R_SPARC_8		1
#define	R_SPARC_16		2
#define	R_SPARC_32		3
#define	R_SPARC_DISP8		4
#define	R_SPARC_DISP16		5
#define	R_SPARC_DISP32		6
#define	R_SPARC_WDISP30		7
#define	R_SPARC_WDISP22		8
#define	R_SPARC_HI22		9
#define	R_SPARC_22		10
#define	R_SPARC_13		11
#define	R_SPARC_LO10		12
#define	R_SPARC_GOT10		13
#define	R_SPARC_GOT13		14
#define	R_SPARC_GOT22		15
#define	R_SPARC_PC10		16
#define	R_SPARC_PC22		17
#define	R_SPARC_WPLT30		18
#define	R_SPARC_COPY		19
#define	R_SPARC_GLOB_DAT	20
#define	R_SPARC_JMP_SLOT	21
#define	R_SPARC_RELATIVE	22
#define	R_SPARC_UA32		23
#define	R_SPARC_PLT32		24
#define	R_SPARC_HIPLT22		25
#define	R_SPARC_LOPLT10		26
#define	R_SPARC_PCPLT32		27
#define	R_SPARC_PCPLT22		28
#define	R_SPARC_PCPLT10		29
#define	R_SPARC_10		30
#define	R_SPARC_11		31
#define	R_SPARC_64		32
#define	R_SPARC_OLO10		33
#define	R_SPARC_HH22		34
#define	R_SPARC_HM10		35
#define	R_SPARC_LM22		36
#define	R_SPARC_PC_HH22		37
#define	R_SPARC_PC_HM10		38
#define	R_SPARC_PC_LM22		39
#define	R_SPARC_WDISP16		40
#define	R_SPARC_WDISP19		41
#define	R_SPARC_GLOB_JMP	42
#define	R_SPARC_7		43
#define	R_SPARC_5		44
#define	R_SPARC_6		45
#define	R_SPARC_DISP64		46
#define	R_SPARC_PLT64		47
#define	R_SPARC_HIX22		48
#define	R_SPARC_LOX10		49
#define	R_SPARC_H44		50
#define	R_SPARC_M44		51
#define	R_SPARC_L44		52
#define	R_SPARC_REGISTER	53
#define	R_SPARC_UA64		54
#define	R_SPARC_UA16		55
#define	R_SPARC_NUM		56

/* m68k Relocation Types */
#define R_68K_NONE	0	/* No reloc */
#define R_68K_32	1	/* Direct 32 bit  */
#define R_68K_16	2	/* Direct 16 bit  */
#define R_68K_8		3	/* Direct 8 bit  */
#define R_68K_PC32	4	/* PC relative 32 bit */
#define R_68K_PC16	5	/* PC relative 16 bit */
#define R_68K_PC8	6	/* PC relative 8 bit */
#define R_68K_GOT32	7	/* 32 bit PC relative GOT entry */
#define R_68K_GOT16	8	/* 16 bit PC relative GOT entry */
#define R_68K_GOT8	9	/* 8 bit PC relative GOT entry */
#define R_68K_GOT32O	10	/* 32 bit GOT offset */
#define R_68K_GOT16O	11	/* 16 bit GOT offset */
#define R_68K_GOT8O	12	/* 8 bit GOT offset */
#define R_68K_PLT32	13	/* 32 bit PC relative PLT address */
#define R_68K_PLT16	14	/* 16 bit PC relative PLT address */
#define R_68K_PLT8	15	/* 8 bit PC relative PLT address */
#define R_68K_PLT32O	16	/* 32 bit PLT offset */
#define R_68K_PLT16O	17	/* 16 bit PLT offset */
#define R_68K_PLT8O	18	/* 8 bit PLT offset */
#define R_68K_COPY	19	/* Copy symbol at runtime */
#define R_68K_GLOB_DAT	20	/* Create GOT entry */
#define R_68K_JMP_SLOT	21	/* Create PLT entry */
#define R_68K_RELATIVE	22	/* Adjust by program base */

/* Alpha Relocation Types */
#define R_ALPHA_NONE		0	/* No reloc */
#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
#define R_ALPHA_OP_PUSH		12	/* OP stack push */
#define R_ALPHA_OP_STORE	13	/* OP stack pop and store */
#define R_ALPHA_OP_PSUB		14	/* OP stack subtract */
#define R_ALPHA_OP_PRSHIFT	15	/* OP stack right shift */
#define R_ALPHA_GPVALUE		16
#define R_ALPHA_GPRELHIGH	17
#define R_ALPHA_GPRELLOW	18
#define R_ALPHA_GPREL16		19
#define R_ALPHA_IMMED_GP_HI32	20
#define R_ALPHA_IMMED_SCN_HI32	21
#define R_ALPHA_IMMED_BR_HI32	22
#define R_ALPHA_IMMED_LO32	23
#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
#define R_ALPHA_RELATIVE	27	/* Adjust by program base */

/* IA-64 relocations.  */
#define R_IA64_NONE		0x00	/* none */
#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
#define R_IA64_LTV32MSB		0x70	/* symbol + addend, data4 MSB */
#define R_IA64_LTV32LSB		0x71	/* symbol + addend, data4 LSB */
#define R_IA64_LTV64MSB		0x72	/* symbol + addend, data8 MSB */
#define R_IA64_LTV64LSB		0x73	/* symbol + addend, data8 LSB */
#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */

#define R_IA64_TYPE(R)		((R) & -8)
#define R_IA64_FORMAT(R)	((R) & 7)

/*
 * Apparantly, Linux and PowerMAXOS use different version of ELF as the
 * Relocation types are very different.
 */
#if defined(PowerMAX_OS)
/* PPC Relocation Types */
#define R_PPC_NONE              0
#define R_PPC_COPY              1
#define R_PPC_GOTP_ENT          2
#define R_PPC_8                 4
#define R_PPC_8S                5
#define R_PPC_16S               7
#define R_PPC_14                8
#define R_PPC_DISP14            9
#define R_PPC_24                10
#define R_PPC_DISP24            11
#define R_PPC_PLT_DISP24        14
#define R_PPC_BBASED_16HU       15
#define R_PPC_BBASED_32         16
#define R_PPC_BBASED_32UA       17
#define R_PPC_BBASED_16H        18
#define R_PPC_BBASED_16L        19
#define R_PPC_ABDIFF_16HU       23
#define R_PPC_ABDIFF_32         24
#define R_PPC_ABDIFF_32UA       25
#define R_PPC_ABDIFF_16H        26
#define R_PPC_ABDIFF_16L        27
#define R_PPC_ABDIFF_16         28
#define R_PPC_16HU              31
#define R_PPC_32                32
#define R_PPC_32UA              33
#define R_PPC_16H               34
#define R_PPC_16L               35
#define R_PPC_16                36
#define R_PPC_GOT_16HU          39
#define R_PPC_GOT_32            40
#define R_PPC_GOT_32UA          41
#define R_PPC_GOT_16H           42
#define R_PPC_GOT_16L           43
#define R_PPC_GOT_16            44
#define R_PPC_GOTP_16HU         47
#define R_PPC_GOTP_32           48
#define R_PPC_GOTP_32UA         49
#define R_PPC_GOTP_16H          50
#define R_PPC_GOTP_16L          51
#define R_PPC_GOTP_16           52
#define R_PPC_PLT_16HU          55
#define R_PPC_PLT_32            56
#define R_PPC_PLT_32UA          57
#define R_PPC_PLT_16H           58
#define R_PPC_PLT_16L           59
#define R_PPC_PLT_16            60
#define R_PPC_ABREL_16HU        63
#define R_PPC_ABREL_32          64
#define R_PPC_ABREL_32UA        65
#define R_PPC_ABREL_16H         66
#define R_PPC_ABREL_16L         67
#define R_PPC_ABREL_16          68
#define R_PPC_GOT_ABREL_16HU    71
#define R_PPC_GOT_ABREL_32      72
#define R_PPC_GOT_ABREL_32UA    73
#define R_PPC_GOT_ABREL_16H     74
#define R_PPC_GOT_ABREL_16L     75
#define R_PPC_GOT_ABREL_16      76
#define R_PPC_GOTP_ABREL_16HU   79
#define R_PPC_GOTP_ABREL_32     80
#define R_PPC_GOTP_ABREL_32UA   81
#define R_PPC_GOTP_ABREL_16H    82
#define R_PPC_GOTP_ABREL_16L    83
#define R_PPC_GOTP_ABREL_16     84
#define R_PPC_PLT_ABREL_16HU    87
#define R_PPC_PLT_ABREL_32      88
#define R_PPC_PLT_ABREL_32UA    89
#define R_PPC_PLT_ABREL_16H     90
#define R_PPC_PLT_ABREL_16L     91
#define R_PPC_PLT_ABREL_16      92
#define R_PPC_SREL_16HU         95
#define R_PPC_SREL_32           96
#define R_PPC_SREL_32UA         97
#define R_PPC_SREL_16H          98
#define R_PPC_SREL_16L          99
#else
/*
 * The Linux version
 */
#define R_PPC_NONE		0
#define R_PPC_ADDR32		1
#define R_PPC_ADDR24		2
#define R_PPC_ADDR16		3
#define R_PPC_ADDR16_LO		4
#define R_PPC_ADDR16_HI		5
#define R_PPC_ADDR16_HA		6
#define R_PPC_ADDR14		7
#define R_PPC_ADDR14_BRTAKEN	8
#define R_PPC_ADDR14_BRNTAKEN	9
#define R_PPC_REL24		10
#define R_PPC_REL14		11
#define R_PPC_REL14_BRTAKEN	12
#define R_PPC_REL14_BRNTAKEN	13
#define R_PPC_GOT16		14
#define R_PPC_GOT16_LO		15
#define R_PPC_GOT16_HI		16
#define R_PPC_GOT16_HA		17
#define R_PPC_PLTREL24		18
#define R_PPC_COPY		19
#define R_PPC_GLOB_DAT		20
#define R_PPC_JMP_SLOT		21
#define R_PPC_RELATIVE		22
#define R_PPC_LOCAL24PC		23
#define R_PPC_UADDR32		24
#define R_PPC_UADDR16		25
#define R_PPC_REL32		26
#define R_PPC_PLT32		27
#define R_PPC_PLTREL32		28
#define R_PPC_PLT16_LO		29
#define R_PPC_PLT16_HI		30
#define R_PPC_PLT16_HA		31
#define R_PPC_SDAREL16		32
#define R_PPC_SECTOFF		33
#define R_PPC_SECTOFF_LO	34
#define R_PPC_SECTOFF_HI	35
#define R_PPC_SECTOFF_HA	36
#endif

/* ARM relocs.  */
#define R_ARM_NONE		0	/* No reloc */
#define R_ARM_PC24		1	/* PC relative 26 bit branch */
#define R_ARM_ABS32		2	/* Direct 32 bit  */
#define R_ARM_REL32		3	/* PC relative 32 bit */
#define R_ARM_PC13		4
#define R_ARM_ABS16		5	/* Direct 16 bit */
#define R_ARM_ABS12		6	/* Direct 12 bit */
#define R_ARM_THM_ABS5		7
#define R_ARM_ABS8		8	/* Direct 8 bit */
#define R_ARM_SBREL32		9
#define R_ARM_THM_PC22		10
#define R_ARM_THM_PC8		11
#define R_ARM_AMP_VCALL9	12
#define R_ARM_SWI24		13
#define R_ARM_THM_SWI8		14
#define R_ARM_XPC25		15
#define R_ARM_THM_XPC22		16
#define R_ARM_COPY		20	/* Copy symbol at runtime */
#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
#define R_ARM_RELATIVE		23	/* Adjust by program base */
#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
#define R_ARM_GOT32		26	/* 32 bit GOT entry */
#define R_ARM_PLT32		27	/* 32 bit PLT address */
#define R_ARM_GNU_VTENTRY	100
#define R_ARM_GNU_VTINHERIT	101
#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
#define R_ARM_THM_PC9		103	/* thumb conditional branch */
#define R_ARM_RXPC25		249
#define R_ARM_RSBREL32		250
#define R_ARM_THM_RPC22		251
#define R_ARM_RREL32		252
#define R_ARM_RABS22		253
#define R_ARM_RPC24		254
#define R_ARM_RBASE		255

typedef struct elf32_rel {
    Elf32_Addr r_offset;
    Elf32_Word r_info;
} Elf32_Rel;

typedef struct elf64_rel {
    Elf64_Addr r_offset;
    Elf64_Xword r_info;
} Elf64_Rel;

typedef struct elf32_rela {
    Elf32_Addr r_offset;
    Elf32_Word r_info;
    Elf32_Sword r_addend;
} Elf32_Rela;

typedef struct elf64_rela {
    Elf64_Addr r_offset;
    Elf64_Xword r_info;
    Elf64_Sxword r_addend;
} Elf64_Rela;

typedef struct elf32_sym {
    Elf32_Word st_name;
    Elf32_Addr st_value;
    Elf32_Word st_size;
    unsigned char st_info;
    unsigned char st_other;
    Elf32_Half st_shndx;
} Elf32_Sym;

typedef struct elf64_sym {
    Elf64_Word st_name;
    unsigned char st_info;
    unsigned char st_other;
    Elf64_Half st_shndx;
    Elf64_Addr st_value;
    Elf64_Xword st_size;
} Elf64_Sym;

#define EI_NIDENT	16

typedef struct elf32hdr {
    unsigned char e_ident[EI_NIDENT];
    Elf32_Half e_type;
    Elf32_Half e_machine;
    Elf32_Word e_version;
    Elf32_Addr e_entry;		/* Entry point */
    Elf32_Off e_phoff;
    Elf32_Off e_shoff;
    Elf32_Word e_flags;
    Elf32_Half e_ehsize;
    Elf32_Half e_phentsize;
    Elf32_Half e_phnum;
    Elf32_Half e_shentsize;
    Elf32_Half e_shnum;
    Elf32_Half e_shstrndx;
} Elf32_Ehdr;

typedef struct elf64hdr {
    unsigned char e_ident[EI_NIDENT];
    Elf64_Half e_type;
    Elf64_Half e_machine;
    Elf64_Word e_version;
    Elf64_Addr e_entry;
    Elf64_Off e_phoff;
    Elf64_Off e_shoff;
    Elf64_Word e_flags;
    Elf64_Half e_ehsize;
    Elf64_Half e_phentsize;
    Elf64_Half e_phnum;
    Elf64_Half e_shentsize;
    Elf64_Half e_shnum;
    Elf64_Half e_shstrndx;
} Elf64_Ehdr;

/* These constants define the permissions on sections in the program
   header, p_flags. */
#define PF_R		0x4
#define PF_W		0x2
#define PF_X		0x1

typedef struct elf_phdr {
    Elf32_Word p_type;
    Elf32_Off p_offset;
    Elf32_Addr p_vaddr;
    Elf32_Addr p_paddr;
    Elf32_Word p_filesz;
    Elf32_Word p_memsz;
    Elf32_Word p_flags;
    Elf32_Word p_align;
} Elf32_Phdr;

typedef struct {
    Elf64_Word p_type;
    Elf64_Word p_flags;
    Elf64_Off p_offset;
    Elf64_Addr p_vaddr;
    Elf64_Addr p_paddr;
    Elf64_Xword p_filesz;
    Elf64_Xword p_memsz;
    Elf64_Xword p_align;
} Elf64_Phdr;

/* sh_type */
#define SHT_NULL	0
#define SHT_PROGBITS	1
#define SHT_SYMTAB	2
#define SHT_STRTAB	3
#define SHT_RELA	4
#define SHT_HASH	5
#define SHT_DYNAMIC	6
#define SHT_NOTE	7
#define SHT_NOBITS	8
#define SHT_REL		9
#define SHT_SHLIB	10
#define SHT_DYNSYM	11
#define SHT_NUM		12
#define SHT_LOPROC	0x70000000
#define SHT_HIPROC	0x7fffffff
#define SHT_LOUSER	0x80000000
#define SHT_HIUSER	0xffffffff

#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1)	/* unwind bits */

/* sh_flags */
#define SHF_WRITE	0x1
#define SHF_ALLOC	0x2
#define SHF_EXECINSTR	0x4
#define SHF_MASKPROC	0xf0000000

/* special section indexes */
#define SHN_UNDEF	0
#define SHN_LORESERVE	0xff00
#define SHN_LOPROC	0xff00
#define SHN_HIPROC	0xff1f
#define SHN_ABS		0xfff1
#define SHN_COMMON	0xfff2
#define SHN_HIRESERVE	0xffff

typedef struct {
    Elf32_Word sh_name;
    Elf32_Word sh_type;
    Elf32_Word sh_flags;
    Elf32_Addr sh_addr;
    Elf32_Off sh_offset;
    Elf32_Word sh_size;
    Elf32_Word sh_link;
    Elf32_Word sh_info;
    Elf32_Word sh_addralign;
    Elf32_Word sh_entsize;
} Elf32_Shdr;

typedef struct {
    Elf64_Word sh_name;
    Elf64_Word sh_type;
    Elf64_Xword sh_flags;
    Elf64_Addr sh_addr;
    Elf64_Off sh_offset;
    Elf64_Xword sh_size;
    Elf64_Word sh_link;
    Elf64_Word sh_info;
    Elf64_Xword sh_addralign;
    Elf64_Xword sh_entsize;
} Elf64_Shdr;

#define	EI_MAG0		0	/* e_ident[] indexes */
#define	EI_MAG1		1
#define	EI_MAG2		2
#define	EI_MAG3		3
#define	EI_CLASS	4
#define	EI_DATA		5
#define	EI_VERSION	6
#define	EI_PAD		7

#define	ELFMAG0		0x7f	/* EI_MAG */
#define	ELFMAG1		'E'
#define	ELFMAG2		'L'
#define	ELFMAG3		'F'
#define	ELFMAG		"\177ELF"
#define	SELFMAG		4

#define	ELFDLMAG	3
#define	ELFDLOFF	16

#define	ELFCLASSNONE	0	/* EI_CLASS */
#define	ELFCLASS32	1
#define	ELFCLASS64	2
#define	ELFCLASSNUM	3

#define ELFDATANONE	0	/* e_ident[EI_DATA] */
#define ELFDATA2LSB	1
#define ELFDATA2MSB	2

#define EV_NONE		0	/* e_version, EI_VERSION */
#define EV_CURRENT	1
#define EV_NUM		2

/* Notes used in ET_CORE */
#define NT_PRSTATUS	1
#define NT_PRFPREG	2
#define NT_PRPSINFO	3
#define NT_TASKSTRUCT	4

/* Note header in a PT_NOTE section */
typedef struct elf_note {
    Elf32_Word n_namesz;	/* Name size */
    Elf32_Word n_descsz;	/* Content size */
    Elf32_Word n_type;		/* Content type */
} Elf32_Nhdr;

#define ELF_START_MMAP 0x80000000

--- NEW FILE: elfloader.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/loader/elfloader.c,v 1.1.4.1.6.5 2004/04/02 17:25:21 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elfloader.c,v 1.61tsi Exp $ */
/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
[...3218 lines suppressed...]
 */
    xf86loaderfree(elffile);

    return;
}

char *
ELFAddressToSection(void *modptr, unsigned long address)
{
    ELFModulePtr elffile = (ELFModulePtr) modptr;
    int i;

    for (i = 1; i < elffile->numsh; i++) {
	if (address >= (unsigned long)elffile->saddr[i] &&
	    address <= (unsigned long)elffile->saddr[i] + SecSize(i)) {
	    return ElfGetSectionName(elffile, elffile->sections[i].sh_name);
	}
    }
    return NULL;
}

--- NEW FILE: elfloader.h ---
/*
 *
 * Copyright 1997,1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elfloader.h,v 1.3 1998/09/20 14:41:05 dawes Exp $ */

#ifndef _ELFLOADER_H
#define _ELFLOADER_H
/* elfloader.c */
extern void *ELFLoadModule(loaderPtr, int, LOOKUP **);
extern void ELFResolveSymbols(void *);
extern int ELFCheckForUnresolved(void *);
extern char *ELFAddressToSection(void *, unsigned long);
extern void ELFUnloadModule(void *);
#endif /* _ELFLOADER_h */

--- NEW FILE: extsym.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/loader/extsym.c,v 1.1.4.3.2.1 2004/02/27 21:31:00 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/extsym.c,v 1.9 2003/10/15 16:29:03 dawes Exp $ */

/*
 *
 * Copyright 1999-2003 by The XFree86 Project, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of The XFree86 Project, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission. The XFree86 Project, Inc. makes no
 * representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 *
 * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL THE XFREE86 PROJECT, INC. BE LIABLE
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include "resource.h"
#include "sym.h"
#include "misc.h"
#ifdef PANORAMIX
#include "panoramiX.h"
#endif
#include "sleepuntil.h"

#ifdef HAS_SHM
extern int ShmCompletionCode;
extern int BadShmSegCode;
extern RESTYPE ShmSegType, ShmPixType;
#endif

#ifdef PANORAMIX
extern Bool noPanoramiXExtension;
extern int PanoramiXNumScreens;
extern PanoramiXData *panoramiXdataPtr;
extern XID *PanoramiXVisualTable;
extern unsigned long XRT_WINDOW;
extern unsigned long XRT_PIXMAP;
extern unsigned long XRT_GC;
extern unsigned long XRT_COLORMAP;
extern unsigned long XRC_DRAWABLE;
extern Bool XineramaRegisterConnectionBlockCallback(void (*func) (void));
extern int XineramaDeleteResource(pointer, XID);
#endif

LOOKUP extLookupTab[] = {

    SYMFUNC(ClientSleepUntil)

#ifdef HAS_SHM
    SYMVAR(ShmCompletionCode)
    SYMVAR(BadShmSegCode)
    SYMVAR(ShmSegType)
#endif

#ifdef PANORAMIX
    SYMFUNC(XineramaRegisterConnectionBlockCallback)
    SYMFUNC(XineramaDeleteResource)
    SYMVAR(noPanoramiXExtension)
    SYMVAR(PanoramiXNumScreens)
    SYMVAR(panoramiXdataPtr)
    SYMVAR(PanoramiXVisualTable)
    SYMVAR(XRT_WINDOW)
    SYMVAR(XRT_PIXMAP)
    SYMVAR(XRT_GC)
    SYMVAR(XRT_COLORMAP)
    SYMVAR(XRC_DRAWABLE)
#endif

    {0, 0}
};

--- NEW FILE: fontsym.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/fontsym.c,v 1.14 2003/12/20 20:04:34 dawes Exp $ */
/*
 * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#include "font.h"
#include "sym.h"
#include "fntfilst.h"
#include "fontenc.h"
#ifdef FONTENC_COMPATIBILITY
#include "fontencc.h"
#endif
#include "fntfilio.h"
#include "fntfil.h"
#include "fontutil.h"
#include "fontxlfd.h"
#ifdef FONTCACHE
#define _FONTCACHE_SERVER_
#include "fontcache.h"
#endif

LOOKUP fontLookupTab[] = {

    SYMFUNC(TwoByteSwap)
    SYMFUNC(FourByteSwap)
    SYMFUNC(FontCouldBeTerminal)
    SYMFUNC(BufFileRead)
    SYMFUNC(BufFileWrite)
    SYMFUNC(CheckFSFormat)
    SYMFUNC(FontFileOpen)
    SYMFUNC(FontFilePriorityRegisterRenderer)
    SYMFUNC(FontFileRegisterRenderer)
    SYMFUNC(FontParseXLFDName)
    SYMFUNC(FontFileCloseFont)
    SYMFUNC(FontFileOpenBitmap)
    SYMFUNC(FontFileCompleteXLFD)
    SYMFUNC(FontFileCountDashes)
    SYMFUNC(FontFileFindNameInDir)
    SYMFUNC(FontFileClose)
    SYMFUNC(FontComputeInfoAccelerators)
    SYMFUNC(FontDefaultFormat)
    SYMFUNC(NameForAtom)
    SYMFUNC(BitOrderInvert)
    SYMFUNC(FontFileMatchRenderer)
    SYMFUNC(RepadBitmap)
    SYMFUNC(FontEncName)
    SYMFUNC(FontEncRecode)
    SYMFUNC(FontEncFind)
    SYMFUNC(FontMapFind)
    SYMFUNC(FontEncMapFind)
    SYMFUNC(FontEncFromXLFD)
    SYMFUNC(FontEncDirectory)
    SYMFUNC(FontMapReverse)
    SYMFUNC(FontMapReverseFree)
    SYMFUNC(CreateFontRec)
    SYMFUNC(DestroyFontRec)
    SYMFUNC(GetGlyphs)
    SYMFUNC(QueryGlyphExtents)

    SYMVAR(FontFileBitmapSources)

#ifdef FONTENC_COMPATIBILITY
    /* Obsolete backwards compatibility symbols -- fontencc.c */
    SYMFUNC(font_encoding_from_xlfd)
    SYMFUNC(font_encoding_find)
    SYMFUNC(font_encoding_recode)
    SYMFUNC(font_encoding_name)
    SYMFUNC(identifyEncodingFile)
#endif

#ifdef FONTCACHE
    /* fontcache.c */
    SYMFUNC(FontCacheGetSettings)
    SYMFUNC(FontCacheGetStatistics)
    SYMFUNC(FontCacheChangeSettings)
    SYMFUNC(FontCacheOpenCache)
    SYMFUNC(FontCacheCloseCache)
    SYMFUNC(FontCacheSearchEntry)
    SYMFUNC(FontCacheGetEntry)
    SYMFUNC(FontCacheInsertEntry)
    SYMFUNC(FontCacheGetBitmap)
#endif

    {0, 0}
};

--- NEW FILE: hash.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/loader/hash.c,v 1.1.4.2.4.2 2004/03/04 20:16:43 kaleb Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/hash.c,v 1.24 2003/11/17 22:20:40 dawes Exp $ */

/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "os.h"
#include "Xos.h"
#undef abs
#include <stdlib.h>
#include "sym.h"
#include "loader.h"
#include "hash.h"

#if defined(Lynx)
#define MAXINT	32000
#else
#include <limits.h>
#undef MAXINT
#define MAXINT INT_MAX
#endif

/* Prototypes for static functions. */
static unsigned int hashFunc(const char *);
static itemPtr LoaderHashFindNearest(unsigned long);

static itemPtr LoaderhashTable[HASHSIZE];

#ifdef DEBUG
static int hashhits[HASHSIZE];

void
DumpHashHits(void)
{
    int i;
    int depth = 0;
    int dev = 0;

    for (i = 0; i < HASHSIZE; i++) {
	ErrorF("hashhits[%d]=%d\n", i, hashhits[i]);
	depth += hashhits[i];
    }

    depth /= HASHSIZE;
    ErrorF("Average hash depth=%d\n", depth);

    for (i = 0; i < HASHSIZE; i++) {
	if (hashhits[i] < depth)
	    dev += depth - hashhits[i];
	else
	    dev += hashhits[i] - depth;
    }

    dev /= HASHSIZE;
    ErrorF("Average hash deviation=%d\n", dev);
}
#endif

static unsigned int
hashFunc(const char *string)
{
    int i = 0;

    while (i < 10 && string[i])
	i++;

    if (i < 5) {
#ifdef DEBUG
	hashhits[i]++;
#endif
	return i;
    }

/*
 * Original has function
#define HASH ((string[ i-4 ] * string[i-3] + string[i-2] ) & (HASHSIZE-1))
 */

#define HASH ((string[i-5] * string[ i-4 ] + string[i-3] * string[i-2] ) & (HASHSIZE-1))

#ifdef DEBUG
    hashhits[HASH]++;
#endif

    return HASH;
}

void
LoaderHashAdd(itemPtr entry)
{
    int bucket = hashFunc(entry->name);
    itemPtr oentry;

    if ((oentry = LoaderHashFind(entry->name)) != NULL)
	LoaderDuplicateSymbol(entry->name, oentry->handle);

    entry->next = LoaderhashTable[bucket];
    LoaderhashTable[bucket] = entry;
    return;
}

void
LoaderAddSymbols(int handle, int module, LOOKUP *list)
{
    LOOKUP *l = list, *exports = NULL;
    itemPtr i, exportsItem = NULL;
    char *modname;

    if (!list)
	return;

    /*
     * First look for a symbol called <name>ExportedSymbols.  If it exists,
     * only export the symbols that are listed in that array.  Otherwise
     * export all of the external symbols.
     */
    modname = _LoaderHandleToCanonicalName(handle);
    if (modname) {
	char *exportname;

	exportname = xf86loadermalloc(strlen("ExportedSymbols") +
				      strlen(modname) + 1);
	if (exportname) {
	    sprintf(exportname, "%sExportedSymbols", modname);
	    while (l->symName) {
		if (strcmp(l->symName, exportname) == 0) {
		    exports = l;
		    ErrorF("LoaderAddSymbols: %s: %s found\n", modname,
			   exportname);
		    break;
		}
		l++;
	    }
	    xf86loaderfree(exportname);
	}
    }

    /*
     * Allocate the exports list item first.
     */
    if (exports) {
	exportsItem = xf86loadermalloc(sizeof(itemRec));
	exportsItem->name = exports->symName;
	exportsItem->address = (char *)exports->offset;
	exportsItem->handle = handle;
	exportsItem->module = module;
	exportsItem->exports = NULL;
	LoaderHashAdd(exportsItem);
    }

    /*
     * Visit every symbol in the lookup table, tagging it with the
     * reference to the export list, if present.
     */
    l = list;
    while (l->symName) {
	if (l != exports) {
	    i = xf86loadermalloc(sizeof(itemRec));
	    i->name = l->symName;
	    i->address = (char *)l->offset;
	    i->handle = handle;
	    i->module = module;
	    i->exports = exportsItem;
	    LoaderHashAdd(i);
	}
	l++;
    }
}

itemPtr
LoaderHashDelete(const char *string)
{
    int bucket = hashFunc(string);
    itemPtr entry;
    itemPtr *entry2;

    entry = LoaderhashTable[bucket];
    entry2 = &(LoaderhashTable[bucket]);
    while (entry) {
	if (!strcmp(entry->name, string)) {
	    *entry2 = entry->next;
	    xf86loaderfree(entry->name);
	    xf86loaderfree(entry);
	    return 0;
	}
	entry2 = &(entry->next);
	entry = entry->next;
    }
    return 0;
}

itemPtr
LoaderHashFind(const char *string)
{
    int bucket = hashFunc(string);
    itemPtr entry;

    entry = LoaderhashTable[bucket];
    while (entry) {
	if (!strcmp(entry->name, string)) {
	    return entry;
	}
	entry = entry->next;
    }
    return 0;
}

static itemPtr
LoaderHashFindNearest(unsigned long address)
{
    int i;
    itemPtr entry, best_entry = 0;
    long best_difference = MAXINT;

    for (i = 0; i < HASHSIZE; i++) {
	entry = LoaderhashTable[i];
	while (entry) {
	    long difference = (long)address - (long)entry->address;

	    if (difference >= 0) {
		if (best_entry) {
		    if (difference < best_difference) {
			best_entry = entry;
			best_difference = difference;
		    }
		} else {
		    best_entry = entry;
		    best_difference = difference;
		}
	    }
	    entry = entry->next;
	}
    }
    return best_entry;
}

void
LoaderPrintSymbol(unsigned long address)
{
    itemPtr entry;

    entry = LoaderHashFindNearest(address);
    if (entry) {
	const char *module, *section;

#if defined(__alpha__) || defined(__ia64__)
	ErrorF("0x%016lx %s+%lx\n", (unsigned long)entry->address,
	       entry->name, address - (unsigned long)entry->address);
#else
	ErrorF("0x%lx %s+%lx\n", (unsigned long)entry->address, entry->name,
	       address - (unsigned long)entry->address);
#endif

	if (_LoaderAddressToSection(address, &module, &section))
	    ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n", module, section);
    } else {
	ErrorF("(null)\n");
    }
}

void
LoaderPrintItem(itemPtr pItem)
{
    if (pItem) {
	const char *module, *section;

#if defined(__alpha__) || defined(__ia64__)
	ErrorF("0x%016lx %s\n", (unsigned long)pItem->address, pItem->name);
#else
	ErrorF("0x%lx %s\n", (unsigned long)pItem->address, pItem->name);
#endif
	if (_LoaderAddressToSection((unsigned long)pItem->address,
				    &module, &section))
	    ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n", module, section);
    } else
	ErrorF("(null)\n");
}

void
LoaderPrintAddress(const char *symbol)
{
    itemPtr entry;

    entry = LoaderHashFind(symbol);
    LoaderPrintItem(entry);
}

void
LoaderHashTraverse(void *card, int (*fnp)(void *, itemPtr))
{
    int i;
    itemPtr entry, last_entry = 0;

    for (i = 0; i < HASHSIZE; i++) {
	last_entry = 0;
	entry = LoaderhashTable[i];
	while (entry) {
	    if ((*fnp) (card, entry)) {
		if (last_entry) {
		    last_entry->next = entry->next;
		    xf86loaderfree(entry->name);
		    xf86loaderfree(entry);
		    entry = last_entry->next;
		} else {
		    LoaderhashTable[i] = entry->next;
		    xf86loaderfree(entry->name);
		    xf86loaderfree(entry);
		    entry = LoaderhashTable[i];
		}
	    } else {
		last_entry = entry;
		entry = entry->next;
	    }
	}
    }
}

void
LoaderDumpSymbols()
{
    itemPtr entry;
    int j;

    for (j = 0; j < HASHSIZE; j++) {
	entry = LoaderhashTable[j];
	while (entry) {
	    LoaderPrintItem(entry);
	    entry = entry->next;
	}
    }

}

--- NEW FILE: hash.h ---
/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/hash.h,v 1.2.2.2 1998/07/04 13:32:45 dawes Exp $ */

#ifndef _HASH_H
#define _HASH_H

#include "loader.h"

typedef struct _HashIterator {
    itemPtr pItem;
    int bucket;
} HashIteratorRec, *HashIteratorPtr;

#endif /* _HASH_H */

--- NEW FILE: loader.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.c,v 1.71 2003/11/06 18:38:13 tsi Exp $ */

/*
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
[...1422 lines suppressed...]

unsigned long LoaderOptions = 0;

void
LoaderResetOptions(void)
{
    LoaderOptions = 0;
}

void
LoaderSetOptions(unsigned long opts)
{
    LoaderOptions |= opts;
}

void
LoaderClearOptions(unsigned long opts)
{
    LoaderOptions &= ~opts;
}

--- NEW FILE: loader.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.h,v 1.28 2003/11/06 18:38:14 tsi Exp $ */

/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
/*
 * Copyright (c) 1997-2001 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#ifndef _LOADER_H
#define _LOADER_H

#include "sym.h"

#if defined(Lynx) && defined(sun)
#define const /**/
#endif
#if (defined(__i386__) || defined(__ix86)) && !defined(i386)
#define i386
#endif
#include <X11/Xosdefs.h>
#include <X11/Xfuncproto.h>
#include <X11/Xmd.h>
/* For LOOKUP definition */
#include "sym.h"
#define LD_UNKNOWN	-1
#define LD_ARCHIVE	0
#define LD_ELFOBJECT	1
#define LD_COFFOBJECT	2
#define LD_XCOFFOBJECT	3
#define LD_AOUTOBJECT   4
#define LD_AOUTDLOBJECT	5
#define LD_ELFDLOBJECT	6
#define LD_PROCESSED_ARCHIVE -1
/* #define UNINIT_SECTION */
#define HANDLE_IN_HASH_ENTRY
/*
 * COFF Section nmumbers
 */
#define N_TEXT       1
#define N_DATA       2
#define N_BSS        3
#define N_COMMENT    4
#define TestFree(a) if (a) { xfree (a); a = NULL; }
#define HASHDIV 10
#define HASHSIZE (1<<HASHDIV)
typedef struct _elf_reloc *ELFRelocPtr;
typedef struct _elf_COMMON *ELFCommonPtr;
typedef struct _coff_reloc *COFFRelocPtr;
typedef struct _coff_COMMON *COFFCommonPtr;
typedef struct AOUT_RELOC *AOUTRelocPtr;
typedef struct AOUT_COMMON *AOUTCommonPtr;

typedef struct _LoaderReloc {
    int modtype;
    struct _LoaderReloc *next;
    COFFRelocPtr coff_reloc;
    ELFRelocPtr elf_reloc;
    AOUTRelocPtr aout_reloc;
} LoaderRelocRec, *LoaderRelocPtr;

typedef struct _loader_item *itemPtr;
typedef struct _loader_item {
    char *name;
    void *address;
    itemPtr next;
    int handle;
    int module;
    itemPtr exports;
#if defined(__powerpc__)
    /*
     * PowerPC file formats require special routines in some circumstances
     * to assist in the linking process. See the specific loader for
     * more details.
     */
    union {
	unsigned short plt[8];	/* ELF */
	unsigned short glink[14];	/* XCOFF */
    } code;
#endif
} itemRec;

/* The following structures provide an interface to GDB (note that GDB
   has copies of the definitions - if you change anything here make
   sure that the changes are also made to GDB */

typedef struct {
    char *name;			/* Name of this symbol */
    unsigned int namelen;	/* Name of this module */
    void *addr;			/* Start address of the .text section */
} LDRCommon, *LDRCommonPtr;

typedef struct x_LDRModuleRec {
    unsigned int version;	/* Version of this struct */
    char *name;			/* Name of this module */
    unsigned int namelen;	/* Length of name */
    void *text;			/* Start address of the .text section */
    void *data;			/* Start address of the .data section */
    void *rodata;		/* Start address of the .rodata section */
    void *bss;			/* Start address of the .bss section */
    LDRCommonPtr commons;	/* List of commmon symbols */
    int commonslen;		/* Number of common symbols */
    struct x_LDRModuleRec *next;	/* Next module record in chain */
} LDRModuleRec, *LDRModulePtr;

extern char DebuggerPresent;
extern LDRModulePtr ModList;
extern LDRCommonPtr ldrCommons;
extern int nCommons;

/*
 * The loader uses loader specific alloc/calloc/free functions that
 * are mapped to either to the regular Xserver functions, or in a couple
 * of special cases, mapped to the C library functions.
 */
#if !defined(PowerMAX_OS) && !(defined(linux) && (defined(__alpha__) || defined(__powerpc__) || defined(__ia64__))) && 0
#define xf86loadermalloc(size) xalloc(size)
#define xf86loaderrealloc(ptr,size) xrealloc(ptr,size)
#define xf86loadercalloc(num,size) xcalloc(num,size)
#define xf86loaderfree(ptr) xfree(ptr)
#define xf86loaderstrdup(ptr) xstrdup(ptr)
#else
/*
 * On Some OSes, xalloc() et al uses mmap to allocate space for large
 * allocation. This has the effect of placing the text section of some
 * modules very far away from the rest which are placed on the heap.
 * Certain relocations are limited in the size of the offsets that can be
 * handled, and this seperation causes these relocation to overflow. This
 * is fixed by just using the C library allocation functions for the loader
 * to ensure that all text sections are located on the heap. OSes that have
 * this problem are:
 *	PowerMAX_OS/PPC
 * 	Linux/Alpha
 * 	Linux/PPC
 *	Linux/IA-64
 */
#define xf86loadermalloc(size) malloc(size)
#define xf86loaderrealloc(ptr,size) realloc(ptr,size)
#define xf86loadercalloc(num,size) calloc(num,size)
#define xf86loaderfree(ptr) free(ptr)
#define xf86loaderstrdup(ptr) strdup(ptr)
#endif

typedef struct _loader *loaderPtr;

/*
 * _loader_funcs hold the entry points for a module format.
 */

typedef void *(*LoadModuleProcPtr) (loaderPtr modrec, int fd, LOOKUP **);
typedef void (*ResolveSymbolsProcPtr) (void *);
typedef int (*CheckForUnresolvedProcPtr) (void *);
typedef char *(*AddressToSectionProcPtr) (void *, unsigned long);
typedef void (*LoaderUnloadProcPtr) (void *);

typedef struct _loader_funcs {
    LoadModuleProcPtr LoadModule;
    ResolveSymbolsProcPtr ResolveSymbols;
    CheckForUnresolvedProcPtr CheckForUnresolved;
    AddressToSectionProcPtr AddressToSection;
    LoaderUnloadProcPtr LoaderUnload;
    LoaderRelocRec pRelocs;	/* type specific relocations */
} loader_funcs;

/* Each module loaded has a loaderRec */
typedef struct _loader {
    int handle;			/* Unique id used to remove symbols from
				 * this module when it is unloaded */
    int module;			/* Unique id to identify compilation units */
    char *name;
    char *cname;
    void *private;		/* format specific data */
    loader_funcs *funcs;	/* funcs for operating on this module */
    loaderPtr next;
} loaderRec;

/* Compiled-in version information */
typedef struct {
    int xf86Version;
    int ansicVersion;
    int videodrvVersion;
    int xinputVersion;
    int extensionVersion;
    int fontVersion;
} ModuleVersions;
extern ModuleVersions LoaderVersionInfo;

extern unsigned long LoaderOptions;

/* Internal Functions */

void LoaderAddSymbols(int, int, LOOKUP *);
void LoaderDefaultFunc(void);
void LoaderDuplicateSymbol(const char *, const int);

#if 0
void LoaderFixups(void);
#endif
void LoaderResolve(void);
int LoaderResolveSymbols(void);
int _LoaderHandleUnresolved(char *, char *);
void LoaderHashAdd(itemPtr);
itemPtr LoaderHashDelete(const char *);
itemPtr LoaderHashFind(const char *);
void LoaderHashTraverse(void *, int (*)(void *, itemPtr));
void LoaderPrintAddress(const char *);
void LoaderPrintItem(itemPtr);
void LoaderPrintSymbol(unsigned long);
void LoaderDumpSymbols(void);
char *_LoaderModuleToName(int);
int _LoaderAddressToSection(const unsigned long, const char **,
			    const char **);
int LoaderOpen(const char *, const char *, int, int *, int *, int *);
int LoaderHandleOpen(int);

/*
 * File interface functions
 */
void *_LoaderFileToMem(int fd, unsigned long offset, int size, char *label);
void _LoaderFreeFileMem(void *addr, int size);
int _LoaderFileRead(int fd, unsigned int offset, void *addr, int size);

/*
 * Relocation list manipulation routines
 */
LoaderRelocPtr _LoaderGetRelocations(void *);

/*
 * object to name lookup routines
 */
char *_LoaderHandleToName(int handle);
char *_LoaderHandleToCanonicalName(int handle);

/*
 * Entry points for the different loader types
 */
#include "aoutloader.h"
#include "coffloader.h"
#include "elfloader.h"
#include "dlloader.h"
/* LD_ARCHIVE */
void *ARCHIVELoadModule(loaderPtr, int, LOOKUP **);

extern void _loader_debug_state(void);

#endif /* _LOADER_H */

--- NEW FILE: loaderProcs.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h,v 1.21 2003/10/15 16:29:04 dawes Exp $ */

/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
/*
 * Copyright (c) 1997-2002 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#ifndef _LOADERPROCS_H
#define _LOADERPROCS_H

#define IN_LOADER
#include "xf86Module.h"
#include "fontmod.h"

typedef struct module_desc {
    struct module_desc *child;
    struct module_desc *sib;
    struct module_desc *parent;
    struct module_desc *demand_next;
    char *name;
    char *filename;
    char *identifier;
    XID client_id;
    int in_use;
    int handle;
    ModuleSetupProc SetupProc;
    ModuleTearDownProc TearDownProc;
    void *TearDownData;		/* returned from SetupProc */
    const char *path;
    const XF86ModuleVersionInfo *VersionInfo;
} ModuleDesc, *ModuleDescPtr;

/*
 * Extenal API for the loader 
 */

void LoaderInit(void);

ModuleDescPtr LoadDriver(const char *, const char *, int, pointer, int *,
			 int *);
ModuleDescPtr LoadModule(const char *, const char *, const char **,
			 const char **, pointer, const XF86ModReqInfo *,
			 int *, int *);
ModuleDescPtr LoadSubModule(ModuleDescPtr, const char *,
			    const char **, const char **, pointer,
			    const XF86ModReqInfo *, int *, int *);
ModuleDescPtr DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent);
void LoadFont(FontModule *);
void UnloadModule(ModuleDescPtr);
void UnloadSubModule(ModuleDescPtr);
void UnloadDriver(ModuleDescPtr);
void FreeModuleDesc(ModuleDescPtr mod);
ModuleDescPtr NewModuleDesc(const char *);
ModuleDescPtr AddSibling(ModuleDescPtr head, ModuleDescPtr new);
void LoaderSetPath(const char *path);
void LoaderSortExtensions(void);

void LoaderVReqSymLists(const char **, va_list args);
void LoaderVReqSymbols(const char *, va_list args);
void LoaderVRefSymLists(const char **, va_list args);
void LoaderVRefSymbols(const char *, va_list args);

void LoaderShowStack(void);
void *LoaderSymbolHandle(const char *, int);
int LoaderUnload(int);
unsigned long LoaderGetModuleVersion(ModuleDescPtr mod);

void LoaderResetOptions(void);
void LoaderSetOptions(unsigned long);
void LoaderClearOptions(unsigned long);

/* Options for LoaderSetOptions */
#define LDR_OPT_ABI_MISMATCH_NONFATAL		0x0001

#endif /* _LOADERPROCS_H */

--- NEW FILE: loadext.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadext.c,v 1.8 2003/10/15 16:29:04 dawes Exp $ */
/*
 * Copyright (c) 2000 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

/* Maybe this file belongs elsewhere? */

#define LOADERDECLARATIONS
#include "loaderProcs.h"
#include "misc.h"
#include "xf86.h"

ExtensionModule *ExtensionModuleList = NULL;
static int numExtensionModules = 0;

static ExtensionModule *
NewExtensionModule(void)
{
    ExtensionModule *save = ExtensionModuleList;
    int n;

    /* Sanity check */
    if (!ExtensionModuleList)
	numExtensionModules = 0;

    n = numExtensionModules + 1;
    ExtensionModuleList = xrealloc(ExtensionModuleList,
				   (n + 1) * sizeof(ExtensionModule));
    if (ExtensionModuleList == NULL) {
	ExtensionModuleList = save;
	return NULL;
    } else {
	numExtensionModules++;
	ExtensionModuleList[numExtensionModules].name = NULL;
	return ExtensionModuleList + (numExtensionModules - 1);
    }
}

void
LoadExtension(ExtensionModule * e, Bool builtin)
{
    ExtensionModule *newext;

    if (e == NULL || e->name == NULL)
	return;

    if (!(newext = NewExtensionModule()))
	return;

    if (builtin)
	xf86MsgVerb(X_INFO, 2, "Initializing built-in extension %s\n",
		    e->name);
    else
	xf86MsgVerb(X_INFO, 2, "Loading extension %s\n", e->name);

    newext->name = e->name;
    newext->initFunc = e->initFunc;
    newext->disablePtr = e->disablePtr;
    newext->setupFunc = e->setupFunc;
    newext->initDependencies = e->initDependencies;

    if (e->setupFunc != NULL)
	e->setupFunc();
}

/*
 * Sort ExtensionModuleList according to the initialisation order
 * dependencies.  The code for this is taken from BSD's tsort,
 * and carries the following copyright/license:
 *
 *
 * Copyright (c) 1989, 1993, 1994
 *      The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Michael Rendell of Memorial University of Newfoundland.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#define	NF_MARK		0x1	/* marker for cycle detection */
#define	NF_ACYCLIC	0x2	/* this node is cycle free */
#define	NF_NODEST	0x4	/* Unreachable */

typedef struct node_str NODE;
struct node_str {
    NODE **n_prevp;		/* pointer to previous node's n_next */
    NODE *n_next;		/* next node in graph */
    NODE **n_arcs;		/* array of arcs to other nodes */
    int n_narcs;		/* number of arcs in n_arcs[] */
    int n_arcsize;		/* size of n_arcs[] array */
    int n_refcnt;		/* # of arcs pointing to this node */
    int n_flags;		/* NF_* */
    const char *n_name;		/* name of this node */
};

static NODE *graph = NULL, **cycle_buf = NULL, **longest_cycle = NULL;
static int longest = 0;
static NODE *sorted = NULL, *last = NULL;

/* Find a node in the graph (insert if not found) and return a pointer to it. */
static NODE *
get_node(const char *name)
{
    NODE *n;

    for (n = graph; n && n->n_name && strcmp(n->n_name, name);
	 n = n->n_next) ;
    if (n)
	return (n);

    n = xnfalloc(sizeof(NODE));

    n->n_narcs = 0;
    n->n_arcsize = 0;
    n->n_arcs = NULL;
    n->n_refcnt = 0;
    n->n_flags = 0;
    n->n_name = name;

    /* Add to linked list. */
    if ((n->n_next = graph) != NULL)
	graph->n_prevp = &n->n_next;
    n->n_prevp = &graph;
    graph = n;

    return (n);
}

/*
 * add an arc from node s1 to node s2 in the graph.  If s1 or s2 are not in
 * the graph, then add them.
 */
static void
add_arc(const char *s1, const char *s2)
{
    NODE *n1;
    NODE *n2;
    int bsize, i;

    n1 = get_node(s1);

    if (!strcmp(s1, s2))
	return;

    n2 = get_node(s2);

    /*
     * Check if this arc is already here.
     */
    for (i = 0; i < n1->n_narcs; i++)
	if (n1->n_arcs[i] == n2)
	    return;
    /*
     * Add it.
     */
    if (n1->n_narcs == n1->n_arcsize) {
	if (!n1->n_arcsize)
	    n1->n_arcsize = 10;
	bsize = n1->n_arcsize * sizeof(*n1->n_arcs) * 2;
	n1->n_arcs = xnfrealloc(n1->n_arcs, bsize);
	n1->n_arcsize = bsize / sizeof(*n1->n_arcs);
    }
    n1->n_arcs[n1->n_narcs++] = n2;
    ++n2->n_refcnt;
}

/*
 * Clear the NODEST flag from all nodes.
 */
static void
clear_cycle(void)
{
    NODE *n;

    for (n = graph; n != NULL; n = n->n_next)
	n->n_flags &= ~NF_NODEST;
}

/* print node and remove from graph (does not actually free node) */
static void
remove_node(NODE * n)
{
    NODE **np;
    NODE *newnode;
    int i;

#ifdef DEBUG
    ErrorF("%s\n", n->n_name);
#endif
    newnode = xnfalloc(sizeof(NODE));
    memcpy(newnode, n, sizeof(NODE));
    if (last)
	last->n_next = newnode;
    else
	sorted = newnode;
    last = newnode;
    newnode->n_next = NULL;

    for (np = n->n_arcs, i = n->n_narcs; --i >= 0; np++)
	--(*np)->n_refcnt;
    n->n_narcs = 0;
    *n->n_prevp = n->n_next;
    if (n->n_next)
	n->n_next->n_prevp = n->n_prevp;
}

static void
free_nodes(NODE * nodelist)
{
    NODE *n, *nextnode;

    for (n = nodelist; n;) {
	nextnode = n->n_next;
	xfree(n);
	n = nextnode;
    }
}

/* look for the longest? cycle from node from to node to. */
static int
find_cycle(NODE * from, NODE * to, int longest_len, int depth)
{
    NODE **np;
    int i, len;

    /*
     * avoid infinite loops and ignore portions of the graph known
     * to be acyclic
     */
    if (from->n_flags & (NF_NODEST | NF_MARK | NF_ACYCLIC))
	return (0);
    from->n_flags |= NF_MARK;

    for (np = from->n_arcs, i = from->n_narcs; --i >= 0; np++) {
	cycle_buf[depth] = *np;
	if (*np == to) {
	    if (depth + 1 > longest_len) {
		longest_len = depth + 1;
		memcpy((char *)longest_cycle,
		       (char *)cycle_buf, longest_len * sizeof(NODE *));
	    }
	} else {
	    if ((*np)->n_flags & (NF_MARK | NF_ACYCLIC | NF_NODEST))
		continue;
	    len = find_cycle(*np, to, longest_len, depth + 1);

#ifdef DEBUG
	    ErrorF("%*s %s->%s %d\n", depth, "",
		   from->n_name, to->n_name, len);
#endif

	    if (len == 0)
		(*np)->n_flags |= NF_NODEST;

	    if (len > longest_len)
		longest_len = len;

	    if (len > 0 && !longest)
		break;
	}
    }
    from->n_flags &= ~NF_MARK;
    return (longest_len);
}

/* do topological sort on graph */
static void
tsort(void)
{
    NODE *n, *next;
    int cnt, i;

    while (graph != NULL) {
	/*
	 * Keep getting rid of simple cases until there are none left,
	 * if there are any nodes still in the graph, then there is
	 * a cycle in it.
	 */
	do {
	    for (cnt = 0, n = graph; n != NULL; n = next) {
		next = n->n_next;
		if (n->n_refcnt == 0) {
		    remove_node(n);
		    ++cnt;
		}
	    }
	} while (graph != NULL && cnt);

	if (graph == NULL)
	    break;

	if (!cycle_buf) {
	    /*
	     * Allocate space for two cycle logs - one to be used
	     * as scratch space, the other to save the longest
	     * cycle.
	     */
	    for (cnt = 0, n = graph; n != NULL; n = n->n_next)
		++cnt;
	    cycle_buf = xnfalloc(sizeof(NODE *) * cnt);
	    longest_cycle = xnfalloc(sizeof(NODE *) * cnt);
	    if (cycle_buf == NULL || longest_cycle == NULL)
		return;
	}
	for (n = graph; n != NULL; n = n->n_next)
	    if (!(n->n_flags & NF_ACYCLIC)) {
		if ((cnt = find_cycle(n, n, 0, 0))) {
		    ErrorF("tsort: cycle in data");
		    for (i = 0; i < cnt; i++)
			ErrorF("%s", longest_cycle[i]->n_name);
		    remove_node(n);
		    clear_cycle();
		    break;
		} else {
		    /* to avoid further checks */
		    n->n_flags |= NF_ACYCLIC;
		    clear_cycle();
		}
	    }

	if (n == NULL)
	    ErrorF("tsort: internal error -- could not find cycle");
    }
    if (cycle_buf)
	xfree(cycle_buf);
    if (longest_cycle)
	xfree(longest_cycle);
    if (graph)
	free_nodes(graph);
}

void
LoaderSortExtensions()
{
    int i, j;
    ExtensionModule *ext, *newList;
    NODE *node;

    graph = NULL;
    longest = 0;
    sorted = NULL;
    last = NULL;
    cycle_buf = NULL;
    longest_cycle = NULL;

    /*
     * Parse list and build the graph.  Enter them in reverse order
     * because tsort() will reverse those that have no depedencies.
     */
    for (i = numExtensionModules - 1; i >= 0; i--) {
	ext = &ExtensionModuleList[i];
	add_arc(ext->name, ext->name);
#ifdef DEBUG
	ErrorF("Extension %s:\n", ext->name);
#endif
	if (ext->initDependencies)
	    for (j = 0; ext->initDependencies[j]; j++) {
		add_arc(ext->initDependencies[j], ext->name);
#ifdef DEBUG
		ErrorF("\t%s\n", ext->initDependencies[j]);
#endif
	    }
    }
    tsort();
    newList = xnfalloc((numExtensionModules + 1) * sizeof(ExtensionModule));
    i = 0;
    for (node = sorted; node; node = node->n_next) {
	for (j = 0; j < numExtensionModules; j++)
	    if (!strcmp(node->n_name, ExtensionModuleList[j].name))
		break;
	if (j != numExtensionModules)
	    newList[i++] = ExtensionModuleList[j];
    }
    if (sorted)
	free_nodes(sorted);
    newList[i].name = NULL;
    xfree(ExtensionModuleList);
    ExtensionModuleList = newList;
#ifdef DEBUG
    for (i = 0; ExtensionModuleList[i].name; i++)
	ErrorF("Extension %s\n", ExtensionModuleList[i].name);
#endif
}

--- NEW FILE: loadfont.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadfont.c,v 1.4 2003/10/15 16:29:04 dawes Exp $ */
/*
 * Copyright (c) 1998 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

/* Maybe this file belongs in lib/font/fontfile/module/ ? */

#define LOADERDECLARATIONS
#include "loaderProcs.h"
#include "misc.h"
#include "xf86.h"

FontModule *FontModuleList = NULL;
static int numFontModules = 0;

static FontModule *
NewFontModule(void)
{
    FontModule *save = FontModuleList;
    int n;

    /* Sanity check */
    if (!FontModuleList)
	numFontModules = 0;

    n = numFontModules + 1;
    FontModuleList = xrealloc(FontModuleList, (n + 1) * sizeof(FontModule));
    if (FontModuleList == NULL) {
	FontModuleList = save;
	return NULL;
    } else {
	numFontModules++;
	FontModuleList[numFontModules].name = NULL;
	return FontModuleList + (numFontModules - 1);
    }
}

void
LoadFont(FontModule * f)
{
    FontModule *newfont;

    if (f == NULL)
	return;

    if (!(newfont = NewFontModule()))
	return;

    xf86MsgVerb(X_INFO, 2, "Loading font %s\n", f->name);

    newfont->name = f->name;
    newfont->initFunc = f->initFunc;
    newfont->module = f->module;
}

--- NEW FILE: loadmod.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.73 2003/11/03 05:11:51 tsi Exp $ */

/*
 *
 * Copyright 1995-1998 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
[...1273 lines suppressed...]
	    return str;
	}

    /* If there is no match, return the whole name minus the leading path */
    return xstrdup(s);
}

/*
 * Return the module version information.
 */
unsigned long
LoaderGetModuleVersion(ModuleDescPtr mod)
{
    if (!mod || !mod->VersionInfo)
	return 0;

    return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion,
				  mod->VersionInfo->minorversion,
				  mod->VersionInfo->patchlevel);
}

--- NEW FILE: misym.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/loader/misym.c,v 1.1.4.2.4.1 2004/02/27 21:31:00 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/misym.c,v 1.38 2003/10/15 16:29:04 dawes Exp $ */

/*
 *
 * Copyright 1995,96 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#include "sym.h"
#include "misc.h"
#include "mi.h"
#include "mibank.h"
#include "miwideline.h"
#include "mibstore.h"
#include "cursor.h"
#include "mipointer.h"
#include "migc.h"
#include "miline.h"
#include "mizerarc.h"
#include "mifillarc.h"
#include "micmap.h"
#include "mioverlay.h"
#ifdef PANORAMIX
#include "resource.h"
#include "panoramiX.h"
#endif
#ifdef RENDER
#include "mipict.h"
#endif

/* mi things */

extern miPointerSpriteFuncRec miSpritePointerFuncs;

LOOKUP miLookupTab[] = {
    SYMFUNC(miClearToBackground)
    SYMFUNC(miSendGraphicsExpose)
    SYMFUNC(miModifyPixmapHeader)
    SYMFUNC(miHandleValidateExposures)
    SYMFUNC(miSetShape)
    SYMFUNC(miChangeBorderWidth)
    SYMFUNC(miShapedWindowIn)
    SYMFUNC(miRectIn)
    SYMFUNC(miZeroClipLine)
    SYMFUNC(miZeroDashLine)
    SYMFUNC(miClearDrawable)
    SYMFUNC(miPolyPoint)
    SYMFUNC(miStepDash)
    SYMFUNC(miEmptyBox)
    SYMFUNC(miEmptyData)
    SYMFUNC(miIntersect)
    SYMFUNC(miRegionAppend)
    SYMFUNC(miRegionCopy)
    SYMFUNC(miRegionDestroy)
    SYMFUNC(miRegionEmpty)
    SYMFUNC(miRegionExtents)
    SYMFUNC(miRegionInit)
    SYMFUNC(miRegionNotEmpty)
    SYMFUNC(miRegionEqual)
    SYMFUNC(miRegionReset)
    SYMFUNC(miRegionUninit)
    SYMFUNC(miRegionValidate)
    SYMFUNC(miTranslateRegion)
    SYMFUNC(miHandleExposures)
    SYMFUNC(miPolyFillRect)
    SYMFUNC(miPolyFillArc)
    SYMFUNC(miImageGlyphBlt)
    SYMFUNC(miPolyGlyphBlt)
    SYMFUNC(miFillPolygon)
    SYMFUNC(miFillConvexPoly)
    SYMFUNC(miPolySegment)
    SYMFUNC(miZeroLine)
    SYMFUNC(miWideLine)
    SYMFUNC(miWideDash)
    SYMFUNC(miZeroPolyArc)
    SYMFUNC(miPolyArc)
    SYMFUNC(miCreateGCOps)
    SYMFUNC(miDestroyGCOps)
    SYMFUNC(miComputeCompositeClip)
    SYMFUNC(miChangeGC)
    SYMFUNC(miCopyGC)
    SYMFUNC(miDestroyGC)
    SYMFUNC(miChangeClip)
    SYMFUNC(miDestroyClip)
    SYMFUNC(miCopyClip)
    SYMFUNC(miPolyRectangle)
    SYMFUNC(miPolyText8)
    SYMFUNC(miPolyText16)
    SYMFUNC(miImageText8)
    SYMFUNC(miImageText16)
    SYMFUNC(miRegionCreate)
    SYMFUNC(miPaintWindow)
    SYMFUNC(miZeroArcSetup)
    SYMFUNC(miFillArcSetup)
    SYMFUNC(miFillArcSliceSetup)
    SYMFUNC(miFindMaxBand)
    SYMFUNC(miClipSpans)
    SYMFUNC(miAllocateGCPrivateIndex)
    SYMFUNC(miScreenInit)
    SYMFUNC(miGetScreenPixmap)
    SYMFUNC(miSetScreenPixmap)
    SYMFUNC(miPointerCurrentScreen)
    SYMFUNC(miRectAlloc)
    SYMFUNC(miInitializeBackingStore)
    SYMFUNC(miInitializeBanking)
    SYMFUNC(miModifyBanking)
    SYMFUNC(miCopyPlane)
    SYMFUNC(miCopyArea)
    SYMFUNC(miCreateScreenResources)
    SYMFUNC(miGetImage)
    SYMFUNC(miPutImage)
    SYMFUNC(miPushPixels)
    SYMFUNC(miPointerInitialize)
    SYMFUNC(miPointerPosition)
    SYMFUNC(miRecolorCursor)
    SYMFUNC(miPointerWarpCursor)
    SYMFUNC(miDCInitialize)
    SYMFUNC(miRectsToRegion)
    SYMFUNC(miPointInRegion)
    SYMFUNC(miInverse)
    SYMFUNC(miSubtract)
    SYMFUNC(miUnion)
    SYMFUNC(miPolyBuildEdge)
    SYMFUNC(miPolyBuildPoly)
    SYMFUNC(miRoundJoinClip)
    SYMFUNC(miRoundCapClip)
    SYMFUNC(miSetZeroLineBias)
    SYMFUNC(miResolveColor)
    SYMFUNC(miInitializeColormap)
    SYMFUNC(miInstallColormap)
    SYMFUNC(miUninstallColormap)
    SYMFUNC(miListInstalledColormaps)
    SYMFUNC(miExpandDirectColors)
    SYMFUNC(miCreateDefColormap)
    SYMFUNC(miClearVisualTypes)
    SYMFUNC(miSetVisualTypes)
    SYMFUNC(miSetVisualTypesAndMasks)
    SYMFUNC(miGetDefaultVisualMask)
    SYMFUNC(miSetPixmapDepths)
    SYMFUNC(miInitVisuals)
    SYMFUNC(miWindowExposures)
    SYMFUNC(miSegregateChildren)
    SYMFUNC(miClipNotify)
    SYMFUNC(miHookInitVisuals)
    SYMFUNC(miPointerAbsoluteCursor)
    SYMFUNC(miPointerGetMotionEvents)
    SYMFUNC(miPointerGetMotionBufferSize)
    SYMFUNC(miOverlayCopyUnderlay)
    SYMFUNC(miOverlaySetTransFunction)
    SYMFUNC(miOverlayCollectUnderlayRegions)
    SYMFUNC(miInitOverlay)
    SYMFUNC(miOverlayComputeCompositeClip)
    SYMFUNC(miOverlayGetPrivateClips)
    SYMFUNC(miOverlaySetRootClip)
    SYMVAR(miZeroLineScreenIndex)
    SYMVAR(miSpritePointerFuncs)
    SYMVAR(miPointerScreenIndex)
    SYMVAR(miInstalledMaps)
    SYMVAR(miInitVisualsProc)
#ifdef RENDER
    SYMVAR(miGlyphExtents)
#endif

    {0, 0}
};

--- NEW FILE: os.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/os.c,v 1.4 2003/10/15 16:29:04 dawes Exp $ */

/*
 * Copyright (c) 1999-2002 by The XFree86 Project, Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#include "loaderProcs.h"

/*
 * OSNAME is a standard form of the OS name that may be used by the
 * loader and by OS-specific modules.
 */

#if defined(__linux__)
#define OSNAME "linux"
#elif defined(__FreeBSD__)
#define OSNAME "freebsd"
#elif defined(__NetBSD__)
#define OSNAME "netbsd"
#elif defined(__OpenBSD__)
#define OSNAME "openbsd"
#elif defined(Lynx)
#define OSNAME "lynxos"
#elif defined(__GNU__)
#define OSNAME "hurd"
#elif defined(SCO)
#define OSNAME "sco"
#elif defined(DGUX)
#define OSNAME "dgux"
#elif defined(ISC)
#define OSNAME "isc"
#elif defined(SVR4) && defined(sun)
#define OSNAME "solaris"
#elif defined(SVR4)
#define OSNAME "svr4"
#elif defined(__UNIXOS2__)
#define OSNAME "os2"
#else
#define OSNAME "unknown"
#endif

/* Return the OS name, and run-time OS version */

void
LoaderGetOS(const char **name, int *major, int *minor, int *teeny)
{
    if (name)
	*name = OSNAME;

    /* reporting runtime versions isn't supported yet */
}

--- NEW FILE: os2funcs.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/os2funcs.c,v 1.7 2003/03/25 04:18:22 dawes Exp $ */
/*
 * (c) Copyright 1997 by Sebastien Marineau
 *                      <marineau at genie.uottawa.ca>
 *
 * 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
 * SEBASTIEN MARINEAU 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.
 *
 * Except as contained in this notice, the name of Sebastien Marineau shall not be
 * used in advertising or otherwise to promote the sale, use or other dealings
 * in this Software without prior written authorization from Sebastien Marineau.
 *
 */

/* Implements some OS/2 memory allocation functions to allow 
 * execute permissions for modules. We allocate some mem using DosAllocMem
 * and then use the EMX functions to create a heap from which we allocate
 * the requests. We create a heap of 2 megs, hopefully enough for now.
 */

#define I_NEED_OS2_H
#define INCL_DOSMEMMGR
#include <os2.h>
#include <sys/types.h>
#include <umalloc.h>
#include "os.h"
#undef ADDRESS
#include "xf86str.h"

#define RESERVED_BLOCKS 4096	/* reserve 16MB memory for modules */

void *os2ldAddToHeap(Heap_t, size_t *, int *);
void os2ldRemoveFromHeap(Heap_t, void *, size_t);

PVOID os2ldCommitedTop;
PVOID os2ldBase;
Heap_t os2ldHeap;
int os2ldTotalCommitedBlocks;
static BOOL FirstTime = TRUE;

void *
os2ldcalloc(size_t num_elem, size_t size_elem)
{
    APIRET rc;
    int ret;

    if (FirstTime) {
	if ((rc = DosAllocMem(&os2ldBase, RESERVED_BLOCKS * 4096,
			      PAG_READ | PAG_WRITE | PAG_EXECUTE)) != 0) {
	    xf86Msg(X_ERROR, "OS2LD: DosAllocMem failed, rc=%d\n", rc);
	    return NULL;
	}

	/* Now commit the first 128Kb, the rest will 
	 * be done dynamically */
	if ((rc = DosSetMem(os2ldBase,
			    32 * 4096, PAG_DEFAULT | PAG_COMMIT)) != 0) {
	    xf86Msg(X_ERROR, "OS2LD: DosSetMem failed, rc=%d\n", rc);
	    DosFreeMem(os2ldBase);
	    return NULL;
	}
	os2ldCommitedTop = os2ldBase + 32 * 4096;
	os2ldTotalCommitedBlocks = 32;
#ifdef DEBUG
	xf86Msg(X_INFO, "OS2LD: Initial heap at addr=%p\n", os2ldBase);
#endif

	if ((os2ldHeap = _ucreate(os2ldBase,
				  32 * 4096, _BLOCK_CLEAN,
				  _HEAP_REGULAR, os2ldAddToHeap,
				  os2ldRemoveFromHeap)) == NULL) {
	    xf86Msg(X_ERROR, "OS2LD: heap creation failed\n");
	    DosFreeMem(os2ldBase);
	    return NULL;
	}

	if ((ret = _uopen(os2ldHeap)) != 0) {
	    xf86Msg(X_ERROR, "OS2LD: heap open failed\n");
	    ret = _udestroy(os2ldHeap, _FORCE);
	    DosFreeMem(os2ldBase);
	    return (NULL);
	}

	FirstTime = FALSE;

#ifdef DEBUG
	xf86Msg(X_INFO, "OS2LD: Created module heap at addr=%p\n", os2ldHeap);
#endif
    }

    return _ucalloc(os2ldHeap, num_elem, size_elem);
}

void *
os2ldAddToHeap(Heap_t H, size_t * new_size, int *PCLEAN)
{
    PVOID NewBase;
    long adjusted_size;
    long blocks;
    APIRET rc;

    if (H != os2ldHeap) {
	xf86Msg(X_ERROR, "OS2LD: Heap corruption in GrowHeap, p=%08x\n", H);
	return NULL;
    }
    NewBase = os2ldCommitedTop;
    adjusted_size = (*new_size / 65536) * 65536;
    if ((*new_size % 65536) > 0)
	adjusted_size += 65536;
    blocks = adjusted_size / 4096;

    if ((os2ldTotalCommitedBlocks + blocks) > RESERVED_BLOCKS) {
	xf86Msg(X_ERROR, "OS2LD: Out of memory in GrowHeap\n");
	xf86Msg(X_ERROR,
		"OS2LD: Max available memory is of %ld bytes\n",
		RESERVED_BLOCKS * 4096);
	return NULL;
    }
    if ((rc =
	 DosSetMem(NewBase, adjusted_size, PAG_DEFAULT | PAG_COMMIT)) != 0) {
	xf86Msg(X_ERROR,
		"OS2LD: DosSetMem failed in GrowHeap, size req'd=%d, rc=%d\n",
		adjusted_size, rc);
	return NULL;
    }

    os2ldCommitedTop += adjusted_size;
    os2ldTotalCommitedBlocks += blocks;
    *PCLEAN = _BLOCK_CLEAN;
    *new_size = adjusted_size;
#ifdef DEBUG
    xf86Msg(X_INFO, "OS2LD: Heap extended by %d bytes, addr=%p\n",
	    adjusted_size, NewBase);
#endif
    return NewBase;
}

void
os2ldRemoveFromHeap(Heap_t H, void *memory, size_t size)
{
    if (H != os2ldHeap) {
	xf86Msg(X_ERROR, "OS2LD: Heap corruption in ShrinkHeap, p=%08x\n", H);
	return;
    }

    /* Currently we do nothing, as we do not keep track of the
     * commited memory */

    /* Only handle it if it is the base address */
    if (memory == os2ldBase) {
	DosFreeMem(os2ldBase);
#ifdef DEBUG
	xf86Msg(X_INFO, "OS2LD: total heap area deallocated\n");
#endif
	os2ldBase = 0;
	FirstTime = TRUE;
    }
}

--- NEW FILE: sym.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/sym.h,v 1.6 2000/10/24 00:06:55 anderson Exp $ */

/*
 *
 * Copyright 1995,96 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _SYM_H
#define _SYM_H

/*
 * This structure is used to pass in symbol information that is being
 * added to the symbol table.
 */

typedef void (*funcptr) (void);

typedef struct {
    char *symName;
    funcptr offset;
} LOOKUP;

#define SYMFUNC( func ) { #func, (funcptr)&func },
#define SYMFUNCALIAS( name, func ) { name, (funcptr)&func },
#define SYMVAR( var ) { #var, (funcptr)&var },
#define SYMVARALIAS( name, var ) { name, (funcptr)&var },

#endif /* _SYM_H */

--- NEW FILE: xf86sym.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v 1.242 2003/10/27 20:51:16 herrb Exp $ */

/*
 *
 * Copyright 1995,96 by Metro Link, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Metro Link, Inc. not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Metro Link, Inc. makes no
 * representations about the suitability of this software for any purpose.
 *  It is provided "as is" without express or implied warranty.
 *
 * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
[...1109 lines suppressed...]
    SYMVAR(resVgaSparseShared)
    SYMVAR(res8514Exclusive)
    SYMVAR(res8514Shared)
    SYMVAR(PciAvoid)

#if defined(__powerpc__) && (!defined(NO_INLINE) || defined(Lynx))
    SYMVAR(ioBase)
#endif

    /* Globals from xf86Globals.c and xf86Priv.h */
    SYMVAR(xf86ConfigDRI)

    /* Globals from xf86Configure.c */
    SYMVAR(ConfiguredMonitor)

    /* Pci.c */
    SYMVAR(pciNumBuses)

    {0, 0}
};




More information about the xserver-commit mailing list