Commit 0108d838 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Fixed winebuild to work on non-Intel architectures.

parent acefd16b
......@@ -13,6 +13,7 @@
struct _CONTEXT86;
struct _STACK16FRAME;
#ifdef __i386__
#include "pshpack1.h"
typedef struct
......@@ -38,6 +39,20 @@ typedef struct
} CALLFROM16;
#include "poppack.h"
#else
typedef struct
{
void (*target)();
int callfrom16;
} ENTRYPOINT16;
typedef struct
{
LPCSTR profile;
} CALLFROM16;
#endif
typedef struct
{
......
......@@ -1022,8 +1022,6 @@ typedef CONTEXT *PCONTEXT;
/* Macros to retrieve the current context */
#ifdef __i386__
#ifdef NEED_UNDERSCORE_PREFIX
# define __ASM_NAME(name) "_" name
#else
......@@ -1054,6 +1052,8 @@ typedef CONTEXT *PCONTEXT;
}
#endif /* __GNUC__ */
#ifdef __i386__
#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \
__ASM_GLOBAL_FUNC( name, \
"call " __ASM_NAME("CALL32_Regs") "\n\t" \
......
......@@ -59,7 +59,8 @@ inline static const char *find_symbol( const char *name, char **table, int size
/* sort a symbol table */
inline static void sort_symbols( char **table, int size )
{
qsort( table, size, sizeof(*table), name_cmp );
if (table )
qsort( table, size, sizeof(*table), name_cmp );
}
/* open the .so library for a given dll in a specified path */
......@@ -292,7 +293,8 @@ void read_undef_symbols( const char *name )
char *p = buffer + strlen(buffer) - 1;
if (p < buffer) continue;
if (*p == '\n') *p-- = 0;
add_undef_symbol( buffer );
p = buffer; while (*p == ' ') p++;
add_undef_symbol( p );
}
if ((err = pclose( f ))) fatal_error( "nm -u %s error %d\n", name, err );
}
......@@ -394,7 +396,7 @@ static int output_immediate_imports( FILE *outfile )
fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" );
pos = 20 * (nb_imm + 1); /* offset of imports.data from start of imports */
fprintf( outfile, "asm(\".align 8\\n\"\n" );
fprintf( outfile, "asm(\".data\\n\\t.align 8\\n\"\n" );
for (i = 0; i < nb_imports; i++)
{
if (dll_imports[i]->delay) continue;
......@@ -404,15 +406,42 @@ static int output_immediate_imports( FILE *outfile )
dll_imports[i]->imports[j] );
fprintf( outfile, " \"\\t.globl " PREFIX "%s\\n\"\n",
dll_imports[i]->imports[j] );
fprintf( outfile, " \"" PREFIX "%s:\\t", dll_imports[i]->imports[j] );
fprintf( outfile, " \"" PREFIX "%s:\\n\\t", dll_imports[i]->imports[j] );
#if defined(__i386__)
if (strstr( dll_imports[i]->imports[j], "__wine_call_from_16" ))
fprintf( outfile, ".byte 0x2e\\n\\tjmp *(imports+%d)\\n\\tnop\\n\"\n", pos );
fprintf( outfile, ".byte 0x2e\\n\\tjmp *(imports+%d)\\n\\tnop\\n", pos );
else
fprintf( outfile, "jmp *(imports+%d)\\n\\tmovl %%esi,%%esi\\n", pos );
#elif defined(__sparc__)
if ( !UsePIC )
{
fprintf( outfile, "sethi %%hi(imports+%d), %%g1\\n\\t", pos );
fprintf( outfile, "ld [%%g1+%%lo(imports+%d)], %%g1\\n\\t", pos );
fprintf( outfile, "jmp %%g1\\n\\tnop\\n" );
}
else
fprintf( outfile, "jmp *(imports+%d)\\n\\tmovl %%esi,%%esi\\n\"\n", pos );
{
/* Hmpf. Stupid sparc assembler always interprets global variable
names as GOT offsets, so we have to do it the long way ... */
fprintf( outfile, "save %%sp, -96, %%sp\\n" );
fprintf( outfile, "0:\\tcall 1f\\n\\tnop\\n" );
fprintf( outfile, "1:\\tsethi %%hi(imports+%d-0b), %%g1\\n\\t", pos );
fprintf( outfile, "or %%g1, %%lo(imports+%d-0b), %%g1\\n\\t", pos );
fprintf( outfile, "ld [%%g1+%%o7], %%g1\\n\\t" );
fprintf( outfile, "jmp %%g1\\n\\trestore\\n" );
}
#else
#error You need to define import thunks for your architecture!
#endif
fprintf( outfile, "\"\n" );
}
pos += 4;
}
fprintf( outfile, ");\n#ifndef __GNUC__\n}\n#endif\n\n" );
fprintf( outfile, "\".previous\");\n#ifndef __GNUC__\n}\n#endif\n\n" );
done:
return nb_imm;
......
......@@ -18,6 +18,7 @@
#include "build.h"
#ifdef __i386__
/*******************************************************************
* BuildCallFrom16Core
......@@ -440,7 +441,6 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
* core routine.
*
*/
static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
{
char *name = reg_func == 2 ? "regs_long" :
......@@ -1138,8 +1138,6 @@ void BuildRelays( FILE *outfile )
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" );
#ifdef __i386__
#ifdef USE_STABS
if (output_file_name)
{
......@@ -1218,20 +1216,14 @@ void BuildRelays( FILE *outfile )
/* End of Call16_Ret segment */
fprintf( outfile, "\n\t.globl " PREFIX "Call16_Ret_End\n" );
fprintf( outfile, PREFIX "Call16_Ret_End:\n" );
}
#else /* __i386__ */
fprintf( outfile, PREFIX"Call16_Start:\n" );
fprintf( outfile, "\t.globl "PREFIX"Call16_Start\n" );
fprintf( outfile, "\t.byte 0\n\n" );
fprintf( outfile, PREFIX"Call16_End:\n" );
fprintf( outfile, "\t.globl "PREFIX"Call16_End\n" );
#else /* __i386__ */
fprintf( outfile, "\t.globl " PREFIX "Call16_Ret_Start\n" );
fprintf( outfile, PREFIX "Call16_Ret_Start:\n" );
fprintf( outfile, "\t.byte 0\n\n" );
fprintf( outfile, "\n\t.globl " PREFIX "Call16_Ret_End\n" );
fprintf( outfile, PREFIX "Call16_Ret_End:\n" );
void BuildRelays( FILE *outfile )
{
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
}
#endif /* __i386__ */
}
......@@ -89,17 +89,26 @@ static WORD get_byte(void)
static WORD get_word(void)
{
/* might not be aligned */
/* FIXME: should we change this on big-endian machines? */
#ifdef WORDS_BIGENDIAN
unsigned char high = get_byte();
unsigned char low = get_byte();
#else
unsigned char low = get_byte();
unsigned char high = get_byte();
#endif
return low | (high << 8);
}
/* get the next dword from the current resource file */
static DWORD get_dword(void)
{
#ifdef WORDS_BIGENDIAN
WORD high = get_word();
WORD low = get_word();
#else
WORD low = get_word();
WORD high = get_word();
#endif
return low | (high << 16);
}
......@@ -207,8 +216,13 @@ inline static void put_byte( unsigned char **buffer, unsigned char val )
inline static void put_word( unsigned char **buffer, WORD val )
{
#ifdef WORDS_BIGENDIAN
put_byte( buffer, HIBYTE(val) );
put_byte( buffer, LOBYTE(val) );
#else
put_byte( buffer, LOBYTE(val) );
put_byte( buffer, HIBYTE(val) );
#endif
}
/* output a string preceded by its length */
......
......@@ -12,6 +12,7 @@
#include <ctype.h>
#include "config.h"
#include "wine/port.h"
#include "wine/exception.h"
#include "builtin16.h"
#include "module.h"
......@@ -22,8 +23,6 @@
#ifdef __i386__
extern unsigned short __get_cs(void);
__ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" );
#else
static inline unsigned short __get_cs(void) { return 0; }
#endif /* __i386__ */
......@@ -71,7 +70,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
OFSTRUCT *pFileInfo;
BYTE *pstr;
ET_BUNDLE *bundle = 0;
ET_ENTRY *entry = 0;
ET_ENTRY entry;
/* Module layout:
* NE_MODULE Module
......@@ -85,9 +84,9 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
*/
buffer = xmalloc( 0x10000 );
memset( buffer, 0, 0x10000 );
pModule = (NE_MODULE *)buffer;
memset( pModule, 0, sizeof(*pModule) );
pModule->magic = IMAGE_OS2_SIGNATURE;
pModule->count = 1;
pModule->next = 0;
......@@ -126,11 +125,10 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
+ strlen(DLLFileName);
strcpy( pFileInfo->szPathName, DLLFileName );
pstr = (char *)pFileInfo + pFileInfo->cBytes + 1;
#ifdef __i386__ /* FIXME: Alignment problems! */
/* Segment table */
pstr = (char *)(((long)pstr + 3) & ~3);
pSegment = (SEGTABLEENTRY *)pstr;
pModule->seg_table = (int)pSegment - (int)pModule;
pSegment->filepos = 0;
......@@ -151,23 +149,26 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
/* Resource table */
pstr = (char *)pSegment;
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->res_table = (int)pstr - (int)pModule;
pstr += output_res16_directory( pstr );
/* Imported names table */
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->import_table = (int)pstr - (int)pModule;
*pstr++ = 0;
*pstr++ = 0;
/* Resident names table */
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->name_table = (int)pstr - (int)pModule;
/* First entry is module name */
*pstr = strlen(DLLName );
*pstr = strlen( DLLName );
strcpy( pstr + 1, DLLName );
pstr += *pstr + 1;
*(WORD *)pstr = 0;
PUT_UA_WORD( pstr, 0 );
pstr += sizeof(WORD);
/* Store all ordinals */
for (i = 1; i <= Limit; i++)
......@@ -178,13 +179,14 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
strcpy( pstr + 1, odp->name );
strupper( pstr + 1 );
pstr += *pstr + 1;
*(WORD *)pstr = i;
PUT_UA_WORD( pstr, i );
pstr += sizeof(WORD);
}
*pstr++ = 0;
/* Entry table */
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->entry_table = (int)pstr - (int)pModule;
for (i = 1; i <= Limit; i++)
{
......@@ -223,6 +225,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
bundle->last++;
else
{
pstr = (char *)(((long)pstr + 1) & ~1);
if ( bundle )
bundle->next = (char *)pstr - (char *)pModule;
......@@ -234,18 +237,18 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
}
/* FIXME: is this really correct ?? */
entry = (ET_ENTRY *)pstr;
entry->type = 0xff; /* movable */
entry->flags = 3; /* exported & public data */
entry->segnum = selector;
entry->offs = odp->offset;
entry.type = 0xff; /* movable */
entry.flags = 3; /* exported & public data */
entry.segnum = selector;
entry.offs = odp->offset;
memcpy( pstr, &entry, sizeof(ET_ENTRY) );
pstr += sizeof(ET_ENTRY);
}
*pstr++ = 0;
#endif
/* Dump the module content */
pstr = (char *)(((long)pstr + 3) & ~3);
dump_bytes( outfile, (char *)pModule, (int)pstr - (int)pModule, "Module", 0 );
return (int)pstr - (int)pModule;
}
......@@ -557,7 +560,9 @@ void BuildSpec16File( FILE *outfile )
int i, nFuncs, nTypes;
int code_offset, data_offset, module_size, res_size;
unsigned char *data;
#ifdef __i386__
unsigned short code_selector = __get_cs();
#endif
/* File header */
......@@ -613,7 +618,7 @@ void BuildSpec16File( FILE *outfile )
}
/* Output CallFrom16 routines needed by this .spec file */
#ifdef __i386__
for ( i = 0; i < nTypes; i++ )
{
char profile[101];
......@@ -627,6 +632,7 @@ void BuildSpec16File( FILE *outfile )
BuildCallFrom16Func( outfile, profile, DLLName, TRUE );
}
#endif
/* Output the DLL functions prototypes */
......@@ -686,6 +692,7 @@ void BuildSpec16File( FILE *outfile )
if ( typelist[i]->type == TYPE_INTERRUPT )
argsize += 2;
#ifdef __i386__
fprintf( outfile, " { 0x68, %s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n",
DLLName, profile,
(typelist[i]->type == TYPE_REGISTER
......@@ -697,6 +704,9 @@ void BuildSpec16File( FILE *outfile )
else
fprintf( outfile, " 0x%04x, 0x66, 0xcb, 0x9090, \"%s\" },\n",
code_selector, profile );
#else
fprintf( outfile, " { \"%s\" },\n", profile );
#endif
code_offset += sizeof(CALLFROM16);
}
......@@ -727,7 +737,11 @@ void BuildSpec16File( FILE *outfile )
assert( type );
fprintf( outfile, " /* %s.%d */ ", DLLName, i );
#ifdef __i386__
fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s_%s_%s */ },\n",
#else
fprintf( outfile, "{ %s, %d, /* %s_%s_%s */ },\n",
#endif
odp->link_name,
(type-typelist)*sizeof(CALLFROM16) -
(code_offset + sizeof(ENTRYPOINT16)),
......@@ -736,6 +750,7 @@ void BuildSpec16File( FILE *outfile )
(odp->type == TYPE_INTERRUPT) ? "intr" :
(odp->type == TYPE_PASCAL_16) ? "word" : "long",
odp->u.func.arg_types );
odp->offset = code_offset;
code_offset += sizeof(ENTRYPOINT16);
break;
......@@ -772,20 +787,32 @@ void BuildSpec16File( FILE *outfile )
/* Output the DLL constructor */
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
#if defined(__i386__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#elif defined(__sparc__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#else
#error You need to define the DLL constructor for your architecture
#endif
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
fprintf( outfile,
"#ifndef __GNUC__\n"
"static void __asm__dummy_dll_init(void) {\n"
"#endif /* defined(__GNUC__) */\n"
"asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n"
" \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n"
" \"\\t.previous\\n\");\n"
"#ifndef __GNUC__\n"
"}\n"
"#endif /* defined(__GNUC__) */\n\n"
"void __wine_spec_%s_init(void)\n"
"{\n"
" __wine_register_dll_16( &descriptor );\n"
"}\n", DLLName, DLLName );
"}\n", DLLName );
}
......@@ -843,3 +870,4 @@ void BuildGlue( FILE *outfile, FILE *infile )
fclose( infile );
}
......@@ -670,6 +670,8 @@ void BuildSpec32File( FILE *outfile )
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
#if defined(__i386__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
......@@ -679,6 +681,22 @@ void BuildSpec32File( FILE *outfile )
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_fini\\n\"\n", DLLName );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
#elif defined(__sparc__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
if (nr_debug)
{
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_fini\\n\"\n", DLLName );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
#else
#error You need to define the DLL constructor for your architecture
#endif
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment