2020-09-30 17:12:29 +02:00

2001 lines
63 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
mip2coff.c
Abstract:
Converts a mips object into a standard coff object.
Author:
Mike O'Leary (mikeol) 04-Apr-1990
Revision History:
Wim Colgate 06-April-1992
Rewritten to convert an alpha object into NT standard coff object.
--*/
//
// Define base types required by ntcoff.h
//
#include <excpt.h>
#include "ntdef.h"
#include <string.h>
#include <stdlib.h>
#include "ntimage.h"
#include <stddef.h>
#include <stdio.h>
#include "a2coff.h"
#if 0
#define IMAGE_SYM_ABSOLUTE -1 //hack until compiler fix (wkc)
#define IMAGE_SYM_DEBUG -2 //hack until compiler fix (wkc)
#endif
//
// Define forward referenced function prototypes.
//
BOOLEAN Convert ( PCHAR infile );
VOID dump_file_header( ALPHA_IMAGE_FILE_HEADER *ptr );
VOID dump_opt_header( ALPHA_OPT_HDR *ptr );
VOID dump_section_header( ALPHA_SECTION_HEADER *ptr );
VOID dump_reloc( ALPHARELOC *ptr );
VOID dump_fdes( ALPHA_FDES *ptr );
VOID dump_pdes( ALPHA_PDES *ptr, int num );
VOID dump_symbol_header( ALPHA_SYMBOL_HEADER *ptr ) ;
VOID convert_symbol( ALPHA_SYML *symbol, ULONG symbol_type,
ULONG symbol_class, ULONG *return_index,
ULONG *return_value, SHORT *section_number ) ;
//
// Define initialization values for COFF section headers and static
// storage for COFF section headers.
//
IMAGE_SECTION_HEADER InitSectionHdr[MAX_SECTIONS+1] = {
{ "", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, 0L},
{".text", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_CODE},
{".rdata", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ},
{".data", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA},
{".sdata", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA},
{".sbss", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_UNINITIALIZED_DATA},
{".bss", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_UNINITIALIZED_DATA},
{".init", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_CODE},
{".lit8", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA},
{".lit4", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA},
{".xdata", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_TYPE_NO_PAD |
IMAGE_SCN_MEM_READ},
{".pdata", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_TYPE_NO_PAD |
IMAGE_SCN_MEM_READ},
//
// add fini and lita sections for ALPHA - what are their correct attributes?
//
{".fini", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA},
{".lita", 0L, 0L, 0L, 0L, 0L, 0L, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA}
};
IMAGE_SECTION_HEADER CoffSectionHdr[MAX_SECTIONS+1];
ALPHA_SECTION_HEADER AlphaSectionHdr[MAX_SECTIONS+1];
//
// Define static storage for the object input and output files.
//
FILE *objIn, *objOut;
//
// Define static storage for the relocation pair value table, the
// symbol index table, and the precedure descriptor table.
//
ALPHA_PDES pdes[5000];
ALPHA_FDES fdes;
ULONG SymbolIndex[NUMSYMINDEX];
BOOLEAN verbose = FALSE ;
BOOLEAN warnings = FALSE ;
VOID main ( int argc,
char *argv[] )
{
int i, j;
BOOLEAN cvt;
UCHAR infile[100], outfile[100], buffer[1024];
int outflag = FALSE ;
//
// No args? then print out the version number only
//
if (argc == 1)
{
printf("Version 2.0\n");
exit(0);
}
//
// Loop through the arguments;
//
// -v verbose mode; dump contents (to stdout) as we go
// -w tell us when we get a bogus hi longword of a 64 bit value
// -o use output file as temporary
//
// followed by one or more input files
//
for( i=1; i < argc ; i++ )
{
if (strcmp(argv[i], "-v") == 0)
verbose = TRUE ;
else
if (strcmp(argv[i], "-w") == 0)
warnings = TRUE ;
else
if (strcmp(argv[i], "-o") == 0)
{
if (i < argc+1)
{
strcpy( outfile, argv[i+1] );
if (!(objOut = fopen(outfile, "wb")))
{
printf("Can't open %s, not converted\n", outfile);
return;
}
i++ ;
outflag = TRUE ;
}
else
{
printf("Need a file name after -o.\n");
return;
}
}
else // must be input file
{
strcpy( infile, argv[i] );
if (!(objIn = fopen(infile, "rb")))
{
printf("Can't open %s, not converted\n", infile);
return;
}
//
// use a temporary name ?
//
if (outflag == FALSE)
{
strcpy( outfile, "a2c" );
if (!(objOut = fopen(outfile, "wb")))
{
printf("Can't open %s, not converted\n", outfile);
return;
}
}
//
// Convert the file from alpha to NT coff
//
cvt = Convert(infile);
fclose(objIn);
fclose(objOut);
//
// If we were successful, copy the file back onto itself
//
if (cvt)
{
if (remove(infile)) // first remove the original
{
printf("Can't remove %s, not converted\n", infile);
remove(outfile);
continue;
}
if (rename(outfile, infile)) // Can't rename? then copy
{
objIn = fopen(outfile, "rb");
objOut = fopen(infile, "wb");
if (!objIn || !objOut)
{
printf("Can't rename %s to %s\n", outfile, infile);
fclose(objIn);
fclose(objOut);
}
do // buffer at a time copy.
{
j = fread(buffer, 1, sizeof(buffer), objIn);
if (j)
{
fwrite(buffer, j, 1, objOut);
}
} while (j);
fclose(objIn);
fclose(objOut);
remove(outfile);
}
}
else // failed to convert, remove temp file
{
remove(outfile);
}
}
}
return;
}
VOID copy_optional_file_header( IMAGE_OPTIONAL_HEADER *destination,
ALPHA_OPT_HDR *source )
{
//
// copy the contents of the optional file header
//
destination->Magic = source->o_magic ;
memcpy (&destination->MajorLinkerVersion, // one-to-two field byte copy
&source->o_vstamp, sizeof( source->o_vstamp) );
destination->SizeOfCode = source->o_tsize_lo ;
destination->SizeOfInitializedData = source->o_dsize_lo ;
destination->SizeOfUninitializedData = source->o_bsize_lo ;
destination->AddressOfEntryPoint = source->o_entry_lo ;
destination->BaseOfCode = source->o_text_start_lo ;
destination->BaseOfData = source->o_data_start_lo ;
// (wkc)??? we also have bss_start(Q), gpmask, fpmask, gp_value(Q)
// to unload somewhere
#if 0
if (source->o_gp_value_lo != GP_VAL)
printf("Warning: compiler GP value %x, a2coff GP value %x\n",
source->o_gp_value_lo, GP_VAL);
#endif
//
// Sanity check the high longwords - should only be 0 or -1
//
if (warnings == TRUE)
{
if ( source->o_tsize_hi != 0x0 &&
source->o_tsize_hi != 0xffffffff )
printf("Warning: High longword of text size not-valid.\n");
if ( source->o_dsize_hi != 0x0 &&
source->o_dsize_hi != 0xffffffff )
printf("Warning: High longword of initialed data size not-valid.\n");
if ( source->o_bsize_hi != 0x0 &&
source->o_bsize_hi != 0xffffffff )
printf("Warning: High longword of uninitialed data size not-valid.\n");
if ( source->o_entry_hi != 0x0 &&
source->o_entry_hi != 0xffffffff )
printf("Warning: High longword of entry point not-valid.\n");
if ( source->o_text_start_hi != 0x0 &&
source->o_text_start_hi != 0xffffffff )
printf("Warning: High longword of text start not-valid.\n");
if ( source->o_data_start_hi != 0x0 &&
source->o_data_start_hi != 0xffffffff )
printf("Warning: High longword of data start not-valid.\n");
if ( source->o_bss_start_hi != 0x0 &&
source->o_bss_start_hi != 0xffffffff )
printf("Warning: High longword of bss start not-valid.\n");
if ( source->o_gp_value_hi != 0x0 &&
source->o_gp_value_hi != 0xffffffff )
printf("Warning: High longword of gp_value not-valid.\n");
}
if (verbose == TRUE)
dump_opt_header( source ) ;
}
VOID copy_file_header( IMAGE_FILE_HEADER *destination,
ALPHA_IMAGE_FILE_HEADER *source )
{
//
// Copy the contents of the file header
//
destination->Machine = source->a_magic ;
destination->NumberOfSections = source->a_nscns ;
destination->TimeDateStamp = source->a_timdat ;
destination->PointerToSymbolTable = source->a_symptr_lo ;
destination->NumberOfSymbols = 0 ; // set later on.
destination->SizeOfOptionalHeader = IMAGE_SIZEOF_STD_OPTIONAL_HEADER ;
destination->Characteristics = source->a_flags ;
//
// Sanity check the high longwords - should only be 0 or -1
//
if (warnings == TRUE)
if ( source->a_symptr_hi != 0x0 &&
source->a_symptr_hi != 0xffffffff )
printf("Warning: High longword of symbol table pointer not-valid.\n");
if (verbose == TRUE)
dump_file_header( source ) ;
}
VOID check_fd ( ALPHA_FDES *fdes )
{
//
// Sanity check the file description
//
if ( fdes->f_addr_hi != 0x0 &&
fdes->f_addr_hi != 0xffffffff )
printf("Warning: High longword of fdes addr not-valid.\n");
if ( fdes->f_cbLineOffset_hi != 0x0 &&
fdes->f_cbLineOffset_hi != 0xffffffff )
printf("Warning: High longword of fdes cbLineOffset not-valid.\n");
if ( fdes->f_cbLine_hi != 0x0 &&
fdes->f_cbLine_hi != 0xffffffff )
printf("Warning: High longword of fdes cbLine not-valid.\n");
if ( fdes->f_cbSs_hi != 0x0 &&
fdes->f_cbSs_hi != 0xffffffff )
printf("Warning: High longword of fdes cbSs not-valid.\n");
}
VOID check_symbol_header( ALPHA_SYMBOL_HEADER *sym )
{
//
// Sanity check the symbol table header
//
if ( sym->s_cbLine_hi != 0x0 &&
sym->s_cbLine_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbLine not-valid.\n");
if ( sym->s_cbLineOffset_hi != 0x0 &&
sym->s_cbLineOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbLineOffset not-valid.\n");
if ( sym->s_cbDnOffset_hi != 0x0 &&
sym->s_cbDnOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbDnOffset not-valid.\n");
if ( sym->s_cbPdOffset_hi != 0x0 &&
sym->s_cbPdOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbPdOffset not-valid.\n");
if ( sym->s_cbSymOffset_hi != 0x0 &&
sym->s_cbSymOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbSymOffset not-valid.\n");
if ( sym->s_cbOptOffset_hi != 0x0 &&
sym->s_cbOptOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbOptOffset not-valid.\n");
if ( sym->s_cbAuxOffset_hi != 0x0 &&
sym->s_cbAuxOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbAuxOffset not-valid.\n");
if ( sym->s_cbSsOffset_hi != 0x0 &&
sym->s_cbSsOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbSsOffset not-valid.\n");
if ( sym->s_cbSsExtOffset_hi != 0x0 &&
sym->s_cbSsExtOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbSsExtOffset not-valid.\n");
if ( sym->s_cbFdOffset_hi != 0x0 &&
sym->s_cbFdOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbFdOffset not-valid.\n");
if ( sym->s_cbRfdOffset_hi != 0x0 &&
sym->s_cbRfdOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbRfdOffset not-valid.\n");
if ( sym->s_cbExtOffset_hi != 0x0 &&
sym->s_cbExtOffset_hi != 0xffffffff )
printf("Warning: High longword of symbol header cbExtOffset not-valid.\n");
}
VOID check_pdes( ALPHA_PDES *pdes, int items )
{
int i ;
//
// Sanity Check pdes
//
for (i=0; i<items; i++)
{
if ( pdes->p_addr_hi != 0x0 &&
pdes->p_addr_hi != 0xffffffff )
printf("Warning: High longword of pdes addr not-valid.\n");
if ( pdes->p_cbLineOffset_hi != 0x0 &&
pdes->p_cbLineOffset_hi != 0xffffffff )
printf("Warning: High longword of pdes cbLineOffset not-valid.\n");
pdes++ ;
}
}
VOID check_section_hdr( ALPHA_SECTION_HEADER *ptr )
{
//
// Sanitiy check the hi longwords in the section header
//
if ( ptr->s_paddr_hi != 0x0 &&
ptr->s_paddr_hi != 0xffffffff )
printf("Warning: section: hi longword of p-addr not valid.\n");
if ( ptr->s_vaddr_hi != 0x0 &&
ptr->s_vaddr_hi != 0xffffffff )
printf("Warning: section: hi longword of v-addr not valid.\n");
if ( ptr->s_size_hi != 0x0 &&
ptr->s_size_hi != 0xffffffff )
printf("Warning: section: hi longword of size not valid.\n");
if ( ptr->s_scnptr_hi != 0x0 &&
ptr->s_scnptr_hi != 0xffffffff )
printf("Warning: section: hi longword of rawdata not valid.\n");
if ( ptr->s_relptr_hi != 0x0 &&
ptr->s_relptr_hi != 0xffffffff )
printf("Warning: section: hi longword of relptr not valid.\n");
if ( ptr->s_lnnoptr_hi != 0x0 &&
ptr->s_lnnoptr_hi != 0xffffffff )
printf("Warning: section: hi longword of lineptr not valid.\n");
}
VOID check_reloc( ALPHARELOC *ptr )
{
//
// Sanitiy check the hi longwords in the relocation entry
//
if ( ptr->r_vaddr_hi != 0x0 &&
ptr->r_vaddr_hi != 0xffffffff )
printf("Warning: relocation: hi longword of virtual address not valid.\n");
}
BOOLEAN Convert ( char *infile )
{
ULONG numP, li, ji;
ULONG i, j, k;
ULONG nextAddr, numAuxFileEntries;
USHORT nextLinenum, lastLinenum ;
size_t len;
UCHAR *strE, *raw, *name, *location ;
UCHAR *lineNum, c ;
LONG oldValue, sectionVA;
LONG Value ;
UCHAR *strTab, *strOut;
LONG found;
ULONG SbssOffset;
UCHAR filename[FILENAMELEN];
IMAGE_FILE_HEADER fh ;
IMAGE_OPTIONAL_HEADER oh;
IMAGE_RELOCATION coffReloc;
IMAGE_SYMBOL sym;
IMAGE_AUX_SYMBOL aux;
IMAGE_LINENUMBER line;
ALPHA_IMAGE_FILE_HEADER afh;
ALPHA_OPT_HDR aoh;
ALPHARELOC AlphaReloc;
ALPHA_SYMBOL_HEADER asymtab ;
ALPHA_SYML *asymL;
ALPHA_SYME asymE;
ULONG return_index ;
ULONG return_value ;
//
// Initialize the symbol index table.
//
for (i = 0; i < NUMSYMINDEX; i++)
{
SymbolIndex[i] = NOTUSED;
}
//
// Initialize the COFF section headers for all possible sections. This
// will have to change later when general named sectioning is provided.
//
for (i = 1; i <= MAX_SECTIONS; i++)
{
CoffSectionHdr[i] = InitSectionHdr[i];
}
//
// Read the object file header and convert the object type if it is
// an Alpha object. We can check by the magic number and size of
// the optional header.
//
if (fread(&afh, sizeof(ALPHA_IMAGE_FILE_HEADER), 1, objIn) != 1)
{
printf("Failed to read header.\n");
return(FALSE);
}
//
// Check to make sure the magic number is in the fileheader
//
if ( afh.a_magic != ALPHA_MAGIC )
{
printf("Not alpha magic number.\n");
return(FALSE);
}
//
// Make sure that the optional header size is valid
//
if ( afh.a_opthdr != sizeof(ALPHA_OPT_HDR) )
{
printf("Not alpha optional header size: got (%x) expected (%x).\n",
afh.a_opthdr, sizeof(ALPHA_OPT_HDR) );
return(FALSE);
}
//
// Copy the file header from alpha to COFF format
//
copy_file_header( &fh, &afh ) ;
//
// Read the Alpha optional header
//
if (fread(&aoh, afh.a_opthdr, 1, objIn) != 1)
{
printf("Failed to read optional header.\n");
return(FALSE);
}
//
// Copy the optional header from alpha to COFF format
//
copy_optional_file_header( &oh, &aoh ) ;
//
// Read the Alpha section headers.
//
if ( fread(&AlphaSectionHdr[1],
sizeof(ALPHA_SECTION_HEADER),
afh.a_nscns,
objIn) != afh.a_nscns )
{
printf("Failed to read section headers.\n");
return(FALSE);
}
//
// Seek to the start of the COFF section data in the output file.
//
if ( fseek(objOut,
(sizeof(IMAGE_FILE_HEADER) +
IMAGE_SIZEOF_STD_OPTIONAL_HEADER +
(MAX_SECTIONS * sizeof(IMAGE_SECTION_HEADER))),
SEEK_SET) == -1)
{
printf("fseek failed: to start of COFF section in output file.\n");
return(FALSE);
}
//
// Scan through the Alpha section headers and copy the information to
// the COFF section headers. All the section headers are written to
// the COFF object file, but not necessarily all the section headers
// are included in the Alpha object file.
//
for (i = 1; i <= afh.a_nscns; i++)
{
if (warnings == TRUE)
check_section_hdr( &AlphaSectionHdr[i]) ;
if (verbose == TRUE)
dump_section_header( &AlphaSectionHdr[i]) ;
for (j = 1; j <= MAX_SECTIONS; j++)
{
if (strcmp(AlphaSectionHdr[i].s_name, CoffSectionHdr[j].Name) == 0)
{
CoffSectionHdr[j].VirtualAddress = AlphaSectionHdr[i].s_vaddr_lo ;
CoffSectionHdr[j].SizeOfRawData = AlphaSectionHdr[i].s_size_lo ;
CoffSectionHdr[j].NumberOfRelocations = AlphaSectionHdr[i].s_nreloc;
//
// hide away the index in the hi longword of the physical address.
// seems that NT doesn't use physical address
//
AlphaSectionHdr[i].s_paddr_hi = j;
break;
}
}
}
//
// If the .sbss section has data and the .sdata section has data, then
// set the virtual base of the .sbss section to the virtual base of the
// .sdata section. Otherwise, if the .sbss section has data, but the
// .sdata section does not have data, then set the virtual base of the
// .sdata section to the virtual base of the .sbss section. These values
// are used during the resolution of relocation values.
//
if (CoffSectionHdr[SBSS].SizeOfRawData != 0)
{
if (CoffSectionHdr[SDATA].SizeOfRawData != 0)
{
SbssOffset = CoffSectionHdr[SBSS].VirtualAddress -
CoffSectionHdr[SDATA].VirtualAddress;
CoffSectionHdr[SBSS].VirtualAddress =
CoffSectionHdr[SDATA].VirtualAddress;
}
else
{
SbssOffset = 0;
CoffSectionHdr[SDATA].VirtualAddress =
CoffSectionHdr[SBSS].VirtualAddress;
}
}
//
// Scan through the Alpha section headers, read the appropriate data,
// reduce internal relocations, and write the data to the output file
// if appropriate.
//
for (i = 1; i <= afh.a_nscns; i++)
{
//
// If the section has data, then allocate a buffer and read the
// data into memory, perform necessary relocations, and write
// the data into the COFF file. Otherwise, check if the section
// is the .sbss section.
//
if (AlphaSectionHdr[i].s_scnptr_lo != 0)
{
if (!(raw = (UCHAR *)malloc(AlphaSectionHdr[i].s_size_lo)))
{
printf("ERROR - raw data to large in %s\n", infile);
return(FALSE);
}
memset( raw, 0, AlphaSectionHdr[i].s_size_lo ) ;
//
// Seek to the raw data in the Alpha file and read into memory.
//
if (fseek(objIn, AlphaSectionHdr[i].s_scnptr_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to raw data section.\n");
return(FALSE);
}
if (fread(raw, 1, AlphaSectionHdr[i].s_size_lo, objIn) !=
AlphaSectionHdr[i].s_size_lo )
{
printf("Failed to read section %d, %x hex bytes.\n", i,
AlphaSectionHdr[i].s_size_lo ) ;
return(FALSE);
}
//
// Seek to the relocations entries for the section.
//
if (fseek(objIn, AlphaSectionHdr[i].s_relptr_lo, SEEK_SET) == -1 )
{
printf("Failed to fseek to pointer relocation section.\n");
return(FALSE);
}
//
// Process the relocations entries for the section.
//
for (j = 0; j < AlphaSectionHdr[i].s_nreloc; j++)
{
//
// Read the next relocation entry.
//
if (fread(&AlphaReloc, sizeof(ALPHARELOC), 1, objIn) != 1)
{
printf("Failed to read relocation entry.\n");
return(FALSE);
}
if (warnings == TRUE)
check_reloc( &AlphaReloc ) ;
if (verbose == TRUE )
dump_reloc( &AlphaReloc ) ;
//
//
// external relocations first
// (revisit (wkc))
//
if (AlphaReloc.r_external)
{
// what do we do with external relocations in our conversion??
// mip2coff checks for a REFHI relocation type and adjusts the *next*
// relocation type. (wkc)
if (AlphaReloc.r_type == IMAGE_REL_ALPHA_GPDISP)
printf("Warning: external GPDISP relocation detected\n");
SymbolIndex[AlphaReloc.r_symindex] = USED;
}
else
{
location = raw +
(AlphaReloc.r_vaddr_lo - AlphaSectionHdr[i].s_vaddr_lo);
sectionVA = CoffSectionHdr[AlphaReloc.r_symindex].VirtualAddress;
if (AlphaReloc.r_type == IMAGE_REL_ALPHA_BRADDR)
{
LONG branch_displacement ;
branch_displacement = *(PULONG)location & 0x001fffff ;
*(PULONG)location = *(PULONG)location & 0xffe00000 ;
//
// for a local branch, add in the current virtual address
// The linker will subtract it back during the fixups.
//
branch_displacement +=
(AlphaReloc.r_vaddr_lo
- AlphaSectionHdr[i].s_vaddr_lo
+ 4) >> 2 ;
*(PULONG)location |= branch_displacement & 0x001fffff ;
}
else
if (AlphaReloc.r_type == IMAGE_REL_ALPHA_LITERAL)
{
SHORT val = *(PSHORT)location ;
USHORT new_val ;
//
// adjust val to be relative to the beginning
// of the GP section as an unsigned value
//
new_val = (USHORT)(aoh.o_gp_value_lo + val - sectionVA);
*(PSHORT)location = new_val ;
}
else
if ( AlphaReloc.r_type == IMAGE_REL_ALPHA_REFQUAD ||
AlphaReloc.r_type == IMAGE_REL_ALPHA_REFLONG ) {
*(PLONG)location = *(PLONG)location - sectionVA ;
}
else
if (AlphaReloc.r_type == IMAGE_REL_ALPHA_GPREL32)
{
//
// adjust val to be relative to the beginning
// of the GP section as an unsigned value
//
// Offset is a negative displacement
LONG Offset = *(PLONG)location ;
*(PLONG)location = aoh.o_gp_value_lo + Offset - sectionVA;
}
else
if ( AlphaReloc.r_type == IMAGE_REL_ALPHA_INLINE_REFLONG )
{
LONG address ;
ALPHARELOC NextReloc;
PSHORT next_location;
//
// get the low part (and place it in next location)
//
if (fread(&NextReloc, sizeof(ALPHARELOC), 1, objIn) != 1)
{
printf("Failed to read relocation entry.\n");
return(FALSE);
}
j++; // update count for the relocation just read
if (warnings == TRUE)
check_reloc( &NextReloc ) ;
if (verbose == TRUE )
dump_reloc( &NextReloc ) ;
next_location = (PSHORT)(raw + (NextReloc.r_vaddr_lo
- AlphaSectionHdr[i].s_vaddr_lo));
//
// Normalize LOCAL inline references to the section
// they are contained in.
//
address = *(PUSHORT)location ;
if (*next_location & 0x8000)
address += 1 ;
address = (address << 16) + *next_location ;
address -= sectionVA ;
*(PUSHORT)location = address >> 16 ;
*next_location = address & 0x0000FFFF ;
}
#if 0
---------------------
location = raw +
(AlphaReloc.r_vaddr_lo - AlphaSectionHdr[i].s_vaddr_lo);
if ( AlphaReloc.r_type == IMAGE_REL_ALPHA_GPDISP )
{
UCHAR *next_location = location + AlphaReloc.r_symindex ;
SHORT low = *(PSHORT)next_location ;
SHORT gp_offset = (SHORT)aoh.o_gp_value_lo ;
//
// calculate distance between a full 64K chunk
// and the 'end' of the text and data sections,
//
// basically, this means how far +/- are we from the
// middle of a 64K section.
//
*(PSHORT)next_location = low - ((1<<15) - gp_offset) ;
}
else
if ( AlphaReloc.r_type == IMAGE_REL_ALPHA_GPDISP )
{
UCHAR *next_location = location + AlphaReloc.r_symindex ;
SHORT low = *(PSHORT)next_location ;
if ((low - (SHORT)aoh.o_gp_value_lo + GP_VAL) < -0x8000L
|| (low - (SHORT)aoh.o_gp_value_lo + GP_VAL) > 0x8000L)
printf("Warning: compiler gerated GP larger than 16 bit displacement\n");
if (AlphaReloc.r_symindex != 4)
printf("Warning: byte offset to 2nd instruction is not 4, it is %x\n", AlphaReloc.r_symindex ) ;
low = low - (SHORT)(aoh.o_gp_value_lo) + GP_VAL ;
*(PSHORT)next_location = low ;
}
switch (AlphaReloc.r_type)
{
case IMAGE_REL_ALPHA_ABSOLUTE:
case IMAGE_REL_ALPHA_REFQUAD:
case IMAGE_REL_ALPHA_REFLONG:
case IMAGE_REL_ALPHA_LITUSE:
case IMAGE_REL_ALPHA_BRADDR:
case IMAGE_REL_ALPHA_HINT:
break ;
case IMAGE_REL_ALPHA_GPREL32:
*(PLONG)location += (USHORT)aoh.o_gp_value_lo - GP_VAL;
break ;
case IMAGE_REL_ALPHA_LITERAL:
{
SHORT val = *(PSHORT)location ;
val += (USHORT)aoh.o_gp_value_lo - GP_VAL ;
*(PSHORT)location = val ;
break ;
}
case IMAGE_REL_ALPHA_GPDISP:
UCHAR next_instruction_operand = location + 4 ;
SHORT val = *(PSHORT)(next_instruction_operand);
break ;
default:
printf("Warning: Don't understand relocation type %d\n",
AlphaReloc.r_type) ;
break ;
}
#endif
}
}
//
// Write data to the COFF file and free the data buffer.
//
k = AlphaSectionHdr[i].s_paddr_hi ; // stored in scan
CoffSectionHdr[k].PointerToRawData = ftell(objOut);
if (fwrite(raw, 1, AlphaSectionHdr[i].s_size_lo, objOut) !=
AlphaSectionHdr[i].s_size_lo )
{
printf("Failed to write section.\n");
return(FALSE);
}
free(raw);
}
else if (strcmp(AlphaSectionHdr[i].s_name, ".sbss") == 0)
{
//
// Allocate a zero data buffer for the .sbss data, write it
// to the COFF file, and free the data buffer.
//
if (!(raw = (UCHAR *)calloc(1, AlphaSectionHdr[i].s_size_lo)))
{
printf("ERROR - raw data to large in %s\n", infile);
return(FALSE);
}
if (fwrite(raw, 1, AlphaSectionHdr[i].s_size_lo, objOut) !=
AlphaSectionHdr[i].s_size_lo )
{
printf("Failed to write section.\n");
return(FALSE);
}
free(raw);
}
}
//
// Combine the storage allocation for the .sdata and .sbss sections and
// adjust the size of initialized and uninitilized data in the optional
// header.
//
CoffSectionHdr[SDATA].SizeOfRawData += CoffSectionHdr[SBSS].SizeOfRawData;
oh.SizeOfInitializedData += CoffSectionHdr[SBSS].SizeOfRawData;
oh.SizeOfUninitializedData -= CoffSectionHdr[SBSS].SizeOfRawData;
//
// Scan through the Alpha section headers and allocate space in the COFF
// object file for relocation entries. At the end of the scan the file
// pointer will be pointing to the position in the file where linenumber
// entries are to be written.
//
for (i = 1; i <= afh.a_nscns; i++)
{
if (AlphaSectionHdr[i].s_relptr_lo != 0)
{
k = AlphaSectionHdr[i].s_paddr_hi ; // stored in scan
CoffSectionHdr[k].PointerToRelocations = ftell(objOut);
if (fseek(objOut,
CoffSectionHdr[k].NumberOfRelocations *
IMAGE_SIZEOF_RELOCATION,
SEEK_CUR) == -1)
{
printf("Failed to fseek past relocation table.\n");
return(FALSE);
}
}
}
//
// Seek to and Read the symbol table header
//
if (fseek(objIn, afh.a_symptr_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to symbol table.\n");
return(FALSE);
}
if (fread(&asymtab, sizeof(ALPHA_SYMBOL_HEADER), 1, objIn) != 1)
{
printf("Failed to read symbol table header.\n");
return(FALSE);
}
if (warnings == TRUE)
check_symbol_header( &asymtab ) ;
if (verbose == TRUE)
dump_symbol_header( &asymtab ) ;
//
// If we have file descriptor entries....
//
if (asymtab.s_ifdMax > 0)
{
if (fseek(objIn, asymtab.s_cbFdOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to file descriptor entries.\n");
return(FALSE);
}
if (fread(&fdes, sizeof(ALPHA_FDES), 1, objIn) != 1)
{
printf("Failed to read fdescriptor.\n");
return(FALSE);
}
if (warnings == TRUE)
check_fd( &fdes ) ;
if (verbose == TRUE)
dump_fdes( &fdes ) ;
if (fseek(objIn, asymtab.s_cbSsOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to local string entries.\n");
return(FALSE);
}
//
// in VERY sparse files, the filename length may read past
// EOF. so we will not check the return code here; it's OK
// to read past EOF, because we will fseek back to the correct
// file location a few lines down from here
//
fread(filename, FILENAMELEN, 1, objIn) ;
}
//
// Read the procedure descriptors into memory.
//
numP = asymtab.s_ipdMax;
if (fseek(objIn, asymtab.s_cbPdOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to PdOffset.\n");
return(FALSE);
}
if (fread(&pdes[0], sizeof(ALPHA_PDES), numP, objIn) != numP)
{
printf("Failed to read Pdes.\n");
return(FALSE);
}
if (warnings == TRUE)
check_pdes( &pdes[0], numP ) ;
if (verbose == TRUE)
dump_pdes( &pdes[0], numP ) ;
//
// Read the linenumbers into memory.
//
if (!(lineNum = malloc(asymtab.s_cbLine_lo)))
{
printf("ERROR - to many linenumbers in %s\n", infile);
return(FALSE);
}
if (fseek(objIn, asymtab.s_cbLineOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to PdOffset.\n");
return(FALSE);
}
if (fread(lineNum, sizeof(UCHAR), asymtab.s_cbLine_lo, objIn) !=
asymtab.s_cbLine_lo)
{
printf("Failed to read line numbers.\n");
return(FALSE);
}
//
// Write linenumbers to the COFF object file.
//
CoffSectionHdr[TEXT].PointerToLinenumbers = ftell(objOut);
for (li = 0; li < numP; li++)
{
/* Convert the linenumbers */
nextLinenum = lastLinenum = (USHORT)pdes[li].p_lnLow;
nextAddr = pdes[li].p_addr_lo;
// printf("offset %ld start %ld end %ld addr %lx iline %lx\n", pdes[li].cbLineOffset, pdes[li].lnLow, pdes[li].lnHigh, pdes[li].addr, pdes[li].iline);
line.Type.VirtualAddress = pdes[li].p_addr_lo;
line.Linenumber = nextLinenum;
if (fwrite(&line, IMAGE_SIZEOF_LINENUMBER, 1, objOut) != 1)
{
printf("Failed to write line number.\n");
return(FALSE);
}
++CoffSectionHdr[TEXT].NumberOfLinenumbers;
for (ji = pdes[li].p_cbLineOffset_lo; ji <= asymtab.s_cbLine_lo; ji++)
{
INT delta ; // -7 .. +7
UINT count ; // 0 .. 15
INT large_delta ; // -32767 .. +32767
//
// get the first byte of the line number
// and extract the delta (bits 4-7) and count (bits 0-3)
//
c = lineNum[ji];
delta = c >> 4 ;
count = (c & 0x0f ) + 1 ;
if ( delta == 0x8 ) // 8 indicates extended format
{
//
// get the next two bytes, shifting the hsb and
// or-ing in the lsb.
//
large_delta = lineNum[++ji] << 8 ;
large_delta |= lineNum[++ji] ;
nextLinenum += large_delta ;
}
else
if ( delta != 0x0 )
{
//
// because c was an unsigned char, we do the sign extension
//
if ( delta > 7) // negative!
nextLinenum = nextLinenum - (16 - delta) ;
else
nextLinenum = nextLinenum + delta ;
}
if (nextLinenum > (USHORT)pdes[li].p_lnHigh)
{
break;
}
if ( delta != 0x0 )
{
if (nextLinenum > lastLinenum)
{
lastLinenum = nextLinenum;
line.Type.VirtualAddress = nextAddr;
line.Linenumber = nextLinenum;
if (fwrite(&line, IMAGE_SIZEOF_LINENUMBER, 1, objOut) != 1)
{
printf("Failed to write line number.\n");
return(FALSE);
}
++CoffSectionHdr[TEXT].NumberOfLinenumbers;
}
}
nextAddr += (count * 4);
}
}
if (!CoffSectionHdr[TEXT].NumberOfLinenumbers)
{
CoffSectionHdr[TEXT].PointerToLinenumbers = 0;
}
free(lineNum);
//
// Set the pointer to the symbol table in the file header.
//
fh.PointerToSymbolTable = ftell(objOut);
//
// Write the .file symbol into the COFF object file.
//
sym.Value = 0;
sym.Type = IMAGE_SYM_TYPE_NULL;
strncpy(sym.N.ShortName, ".file", 8);
sym.SectionNumber = IMAGE_SYM_DEBUG;
sym.StorageClass = IMAGE_SYM_CLASS_FILE;
name = filename + fdes.f_rss;
len = strlen(name);
if (len % IMAGE_SIZEOF_AUX_SYMBOL) //wkc - which SIZE ??
{
numAuxFileEntries = (len / IMAGE_SIZEOF_AUX_SYMBOL) + 1;
}
else
{
numAuxFileEntries = len / IMAGE_SIZEOF_AUX_SYMBOL;
}
fh.NumberOfSymbols = numAuxFileEntries + 1;
sym.NumberOfAuxSymbols = (UCHAR)(numAuxFileEntries);
if (fwrite(&sym, (ULONG)IMAGE_SIZEOF_SYMBOL, 1, objOut) != 1)
{
printf("Failed to write file name symbol.\n");
return(FALSE);
}
while (*name)
{
len = 0;
memset((char *)&aux, 0, IMAGE_SIZEOF_AUX_SYMBOL);
while (*name && len < IMAGE_SIZEOF_AUX_SYMBOL)
{
aux.File.Name[len++] = *name++;
}
if (fwrite(&aux, (ULONG)IMAGE_SIZEOF_AUX_SYMBOL, 1, objOut) != 1)
{
printf("Failed to write file name symbol.\n");
return(FALSE);
}
}
//
// Change the name of the .lit4 and .lit8 sections to .sdata so that
// they will be combined with the rest of the .sdata.
//
if (CoffSectionHdr[LIT8].SizeOfRawData != 0)
{
strcpy(CoffSectionHdr[LIT8].Name, ".rdata");
}
if (CoffSectionHdr[LIT4].SizeOfRawData != 0)
{
strcpy(CoffSectionHdr[LIT4].Name, ".rdata");
}
// if (CoffSectionHdr[RDATA].SizeOfRawData != 0)
// {
// strcpy(CoffSectionHdr[RDATA].Name, ".sdata");
// }
if (CoffSectionHdr[LITA].SizeOfRawData != 0)
{
strcpy(CoffSectionHdr[LITA].Name, ".sdata");
}
//
// Write the section name symbols into the COFF object file.
//
fh.NumberOfSymbols += (MAX_SECTIONS * 2);
sym.Value = 0;
sym.StorageClass = IMAGE_SYM_CLASS_STATIC;
sym.NumberOfAuxSymbols = 1;
for (i = 1; i <= MAX_SECTIONS; i++)
{
strncpy(sym.N.ShortName, CoffSectionHdr[i].Name, 8);
sym.SectionNumber = i;
fwrite(&sym, (ULONG)IMAGE_SIZEOF_SYMBOL, 1, objOut);
aux.Section.Length = CoffSectionHdr[i].SizeOfRawData;
aux.Section.NumberOfRelocations = CoffSectionHdr[i].NumberOfRelocations;
aux.Section.NumberOfLinenumbers = CoffSectionHdr[i].NumberOfLinenumbers;
if (fwrite(&aux, (ULONG)IMAGE_SIZEOF_AUX_SYMBOL, 1, objOut) != 1)
{
printf("Failed to write auxiliary symbol.\n");
return(FALSE);
}
}
//
// Allocate a buffer and read the local symbol table into memory.
//
if (!(asymL = (ALPHA_SYML *)malloc(asymtab.s_isymMax*sizeof(ALPHA_SYML))))
{
printf("ERROR - unable to allocate local symbol table %s\n", infile);
return(FALSE);
}
if (fseek(objIn, asymtab.s_cbSymOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to local symbol table.\n");
return(FALSE);
}
if (fread(asymL, sizeof(ALPHA_SYML), asymtab.s_isymMax, objIn) !=
asymtab.s_isymMax)
{
printf("Failed to read local symbol table.\n");
return(FALSE);
}
//
// Store frame symbols
//
for (li=0; li<numP; li++)
{
pdes[li].p_addr_lo = asymL[pdes[li].p_isym].s_value_lo;
pdes[li].p_isym = NOTUSED;
// printf("addr %lx, fp %d pc %d framesize %lx regmask %lx regoffset %x\n", pdes[li].addr, pdes[li].framereg, pdes[li].pcreg, pdes[li].frameoffset, pdes[li].regmask, pdes[li].regoffset);
}
//
// Free the local symbol table.
//
free(asymL);
//
// Allocate a buffer and read the external string table into memory.
//
if (!(strE = (UCHAR *)malloc(asymtab.s_issExtMax * sizeof(UCHAR))))
{
printf("ERROR - unable to allocate external string table in %s\n", infile);
return(FALSE);
}
if (fseek(objIn, asymtab.s_cbSsExtOffset_lo, SEEK_SET) == -1)
{
printf("Failed to fseek to external string table.\n");
return(FALSE);
}
if (fread(strE, sizeof(UCHAR), asymtab.s_issExtMax, objIn) !=
asymtab.s_issExtMax)
{
printf("Failed to read external string table.\n");
return(FALSE);
}
//
// Allocate a buffer for the external string output table.
//
if (!(strTab = (UCHAR *)malloc((asymtab.s_issExtMax * sizeof(UCHAR)) + sizeof(ULONG)))) {
printf("ERROR - unable to allocate output string table in %s\n", infile);
return(FALSE);
}
strOut = strTab + sizeof(ULONG);
//
// Seek to the start of the external symbol table and process each
// entry in the table.
//
fseek(objIn, asymtab.s_cbExtOffset_lo, SEEK_SET);
sym.NumberOfAuxSymbols = 0;
for (li = 0; li < asymtab.s_iextMax; li++)
{
SHORT section_number ;
//
// Read next external symbol table entry, compute the offset in
// the external string table, and convert to COFF symbol table
// format.
//
if (fread(&asymE, sizeof(ALPHA_SYME), 1, objIn) != 1)
{
printf("Failed to read one external string table.\n");
return(FALSE);
}
name = strE + asymE.e_asym.s_iss;
if (*name && (len = strlen(name)))
{
if (len > 8)
{
sym.N.Name.Short = 0;
sym.N.Name.Long = strOut - strTab;
strcpy(strOut, name);
strOut += len + 1;
}
else
{
strncpy(sym.N.ShortName, name, 8);
}
//
// convert symbol value. given a symbol type and storage
// class, we compute index and value. (we pass along the
// symbol for any other necessary tweaking).
//
convert_symbol( &asymE.e_asym,
asymE.e_asym.s_st,
asymE.e_asym.s_sc,
&return_index,
&return_value,
&section_number ) ;
sym.Value = return_value ;
//
// Set the COFF section number, storage class, and symbol type.
//
// shouldn't we pass along stuff generate by acc instead of
// always putting either NULL or EXTERNAL in the storage class?
// also type is always NULL. (wkc - this is how mip2coff did it)
sym.SectionNumber = section_number ;
sym.StorageClass =
(UCHAR)(section_number == IMAGE_SYM_DEBUG ?
IMAGE_SYM_TYPE_NULL : IMAGE_SYM_CLASS_EXTERNAL);
//
// map alpha types into NT types ??
//
sym.Type = IMAGE_SYM_TYPE_NULL;
//
// Scan the procedure descriptor table for a procedure address
// that matches the symbol value.
//
found = FALSE;
if (i == TEXT)
{
for (ji = 0; ji < numP; ji++)
{
//
// ****** this doesn't appear to work since the addr
// value will not be relative?
//
if (pdes[ji].p_isym == NOTUSED && pdes[ji].p_addr_lo == sym.Value)
{
pdes[ji].p_isym = USED;
found = TRUE;
break;
}
}
}
// sym.NumberOfAuxSymbols = (UCHAR)(found ? 1 : 0);
sym.NumberOfAuxSymbols = 0;
if (i != IMAGE_SYM_DEBUG || SymbolIndex[li] != NOTUSED)
{
SymbolIndex[li] = fh.NumberOfSymbols++;
if (fwrite(&sym, (ULONG)IMAGE_SIZEOF_SYMBOL, 1, objOut) != 1)
{
printf("Failed to write image symbol.\n");
return(FALSE);
}
#if 0
if (sym.NumberOfAuxSymbols) {
frame.Mask = pdes[ji].regmask;
frame.Offset = pdes[ji].regoffset;
frame.Size = pdes[ji].frameoffset;
frame.Fp = pdes[ji].framereg;
frame.Ret = pdes[ji].pcreg;
frame.StorageClass = IMAGE_SYM_CLASS_FRAME;
frame.NumberOfAuxSymbols = 0;
frame.Pad = 0;
fwrite(&frame, (ULONG)IMAGE_SIZEOF_SYMBOL, 1, objOut);
++fh.NumberOfSymbols;
}
#endif
}
}
}
//
// Compute the size of the external string table in bytes, store the
// size in the first longword of the string table, and write the string
// table to the COFF object file.
//
li = strOut - strTab;
*(PULONG)strTab = li;
if (fwrite(strTab, li, 1, objOut) != 1)
{
printf("Failed to write string table count .\n");
return(FALSE);
}
//
// Scan through the Alpha section headers, read the Alpha relocation
// information, convert the information to COFF format, and write
// out the COFF relocation information.
//
for (i = 1; i <= afh.a_nscns; i++)
{
if (AlphaSectionHdr[i].s_relptr_lo)
{
if (fseek(objIn, AlphaSectionHdr[i].s_relptr_lo, SEEK_SET) == -1)
{
printf("Failed to seek to relocation section.\n");
return(FALSE);
}
k = AlphaSectionHdr[i].s_paddr_hi ; // stored in scan
if (fseek(objOut, CoffSectionHdr[k].PointerToRelocations,
SEEK_SET)==-1)
{
printf("Failed to seek to relocation section in outfile.\n");
return(FALSE);
}
for (j = 0; j < AlphaSectionHdr[i].s_nreloc; j++)
{
LONG last_VA;
INT last_type;
if (fread(&AlphaReloc, sizeof(ALPHARELOC), 1, objIn) != 1)
{
printf("Failed to seek to relocation section.\n");
return(FALSE);
}
coffReloc.VirtualAddress = AlphaReloc.r_vaddr_lo;
coffReloc.Type = (USHORT)AlphaReloc.r_type;
if (AlphaReloc.r_external)
{
coffReloc.SymbolTableIndex =
SymbolIndex[AlphaReloc.r_symindex];
}
else
{
k = AlphaReloc.r_symindex;
if (k == SBSS)
{
k = SDATA;
}
coffReloc.SymbolTableIndex = ((k - 1) * 2) +
numAuxFileEntries + 1;
}
//
// if the last type was INLINE_REFLONG, we munge this one from
// an ABS type to a MATCH type. The symindex takes on the offset
// between instructions.
//
if (last_type == IMAGE_REL_ALPHA_INLINE_REFLONG) {
coffReloc.Type = IMAGE_REL_ALPHA_MATCH;
coffReloc.SymbolTableIndex = coffReloc.VirtualAddress -
last_VA;
coffReloc.VirtualAddress = last_VA;
}
if (fwrite(&coffReloc, IMAGE_SIZEOF_RELOCATION, 1, objOut) !=1)
{
printf("Failed to write relocation element.\n");
return(FALSE);
}
last_type = coffReloc.Type;
last_VA = coffReloc.VirtualAddress;
}
}
}
//
// Write out the COFF file header.
//
if (fseek(objOut, 0L, SEEK_SET) == -1)
{
printf("Failed to seek to beginning of outfile.\n");
return(FALSE);
}
fh.NumberOfSections = MAX_SECTIONS;
fh.Characteristics &= ~IMAGE_FILE_EXECUTABLE_IMAGE;
if (fwrite(&fh, sizeof(IMAGE_FILE_HEADER), 1, objOut) != 1)
{
printf("Failed to write file header.\n");
return(FALSE);
}
//
// Write out the COFF optional header.
//
if (fwrite(&oh, IMAGE_SIZEOF_STD_OPTIONAL_HEADER, 1, objOut) != 1)
{
printf("Failed to write optional file header.\n");
return(FALSE);
}
//
// Compute the total number of SDATA relocation entries.
//
CoffSectionHdr[SDATA].NumberOfRelocations +=
CoffSectionHdr[SBSS].NumberOfRelocations;
//
// Clear the physical address in COFF section headers.
//
for (i = 1; i <= MAX_SECTIONS; i++) {
CoffSectionHdr[i].Misc.PhysicalAddress = 0;
}
//
// Clear information associated with the .sbss section.
//
CoffSectionHdr[SBSS].VirtualAddress = 0;
CoffSectionHdr[SBSS].SizeOfRawData = 0;
CoffSectionHdr[SBSS].PointerToRawData = 0;
CoffSectionHdr[SBSS].PointerToRelocations = 0;
CoffSectionHdr[SBSS].NumberOfRelocations = 0;
//
// Compute the correct size of the .pdata section.
//
if (CoffSectionHdr[PDATA].SizeOfRawData != 0) {
CoffSectionHdr[PDATA].SizeOfRawData =
(CoffSectionHdr[PDATA].SizeOfRawData /
SIZEOF_RUNTIME_FUNCTION) * SIZEOF_RUNTIME_FUNCTION;
}
//
// Write out the COFF section headers.
//
if (fwrite(&CoffSectionHdr[1],
sizeof(IMAGE_SECTION_HEADER),
MAX_SECTIONS,
objOut) != MAX_SECTIONS)
{
printf("Failed to write section header.\n");
return(FALSE);
}
//
// Free the string table memory.
//
free(strE);
free(strTab);
return(TRUE);
}
VOID dump_file_header( ALPHA_IMAGE_FILE_HEADER *source )
{
printf("HEADER: (size is hex %x)\n", sizeof(ALPHA_IMAGE_FILE_HEADER) ) ;
printf(" Magic number: \t%x \t(hex)\n", source->a_magic);
printf(" Num of sections:\t%x \t(hex)\n", source->a_nscns);
printf(" Date stamp: \t\n");
printf(" Symbol ptr (lo):\t%x \t(hex)\n", source->a_symptr_lo);
printf(" Symbol ptr (hi):\t%x \t(hex)\n", source->a_symptr_hi);
printf(" Size of symbols:\t%x \t(hex)\n", source->a_nsyms);
printf(" Size of opt hdr:\t%x \t(hex)\n", source->a_opthdr);
printf(" Flags: \t%x \t(hex)\n", source->a_flags);
}
VOID dump_opt_header( ALPHA_OPT_HDR *source )
{
printf("OPTIONAL HEADER: (size is hex %x)\n", sizeof(ALPHA_OPT_HDR) ) ;
printf(" Magic number: \t%x \t(hex)\n", source->o_magic);
printf(" Version stamp: \t%x \t(hex)\n", source->o_vstamp);
printf(" Quadword align: \t%x \t(hex)\n", source->o_quadwordpadding) ;
printf(" Text size (lo): \t%x \t(hex)\n", source->o_tsize_lo);
printf(" Text size (hi): \t%x \t(hex)\n", source->o_tsize_hi);
printf(" Data size (lo): \t%x \t(hex)\n", source->o_dsize_lo);
printf(" Data size (hi): \t%x \t(hex)\n", source->o_dsize_hi);
printf(" B size (lo): \t%x \t(hex)\n", source->o_bsize_lo);
printf(" B size (hi): \t%x \t(hex)\n", source->o_bsize_hi);
printf(" Entry point(lo):\t%x \t(hex)\n", source->o_entry_lo);
printf(" Entry point(hi):\t%x \t(hex)\n", source->o_entry_hi);
printf(" Text start (lo):\t%x \t(hex)\n", source->o_text_start_lo);
printf(" Text start (hi):\t%x \t(hex)\n", source->o_text_start_hi);
printf(" Data start (lo):\t%x \t(hex)\n", source->o_data_start_lo);
printf(" Data start (hi):\t%x \t(hex)\n", source->o_data_start_hi);
printf(" BSS start (lo):\t%x \t(hex)\n", source->o_bss_start_lo);
printf(" BSS start (hi):\t%x \t(hex)\n", source->o_bss_start_hi);
printf(" Gp mask: \t%x \t(hex)\n", source->o_gpmask);
printf(" Fp mask: \t%x \t(hex)\n", source->o_fpmask);
printf(" Gp Value (lo):\t%x \t(hex)\n", source->o_gp_value_lo);
printf(" Gp Value (hi):\t%x \t(hex)\n", source->o_gp_value_hi);
}
VOID dump_section_header( ALPHA_SECTION_HEADER *ptr )
{
printf("SECTION HEADER: (size is hex %x)\n", sizeof(ALPHA_SECTION_HEADER));
printf(" Name: \t%s\n", ptr->s_name );
printf(" Phys addr (lo): \t%x\n", ptr->s_paddr_lo ) ;
printf(" Phys addr (hi): \t%x\n", ptr->s_paddr_hi ) ;
printf(" Virt addr (lo): \t%x\n", ptr->s_vaddr_lo ) ;
printf(" Virt addr (hi): \t%x\n", ptr->s_vaddr_hi ) ;
printf(" Size (lo): \t%x\n", ptr->s_size_lo ) ;
printf(" Size (hi): \t%x\n", ptr->s_size_hi ) ;
printf(" Sec ptr (lo): \t%x\n", ptr->s_scnptr_lo ) ;
printf(" Sec ptr (hi): \t%x\n", ptr->s_scnptr_hi ) ;
printf(" Rel ptr (lo): \t%x\n", ptr->s_relptr_lo ) ;
printf(" Rel ptr (hi): \t%x\n", ptr->s_relptr_hi ) ;
printf(" Line ptr (lo): \t%x\n", ptr->s_lnnoptr_lo ) ;
printf(" Line ptr (hi): \t%x\n", ptr->s_lnnoptr_hi ) ;
printf(" Num relocs: \t%x\n", ptr->s_nreloc ) ;
printf(" Num lines: \t%x\n", ptr->s_nlnno ) ;
printf(" Flags: \t%x\n", ptr->s_flags ) ;
}
VOID dump_reloc( ALPHARELOC *ptr )
{
printf("RELOCATION INFO: (size is hex %x)\n", sizeof(ALPHARELOC));
printf(" Virt addr (lo):\t%x\n", ptr->r_vaddr_lo);
printf(" Virt addr (hi):\t%x\n", ptr->r_vaddr_hi);
printf(" Symbol index: \t%x\n", ptr->r_symindex);
printf(" Type: \t%x\n", ptr->r_type );
printf(" External: \t%x\n", ptr->r_external);
printf(" Reserved: \t%x\n", ptr->r_reserved);
}
VOID dump_fdes ( ALPHA_FDES *ptr )
{
printf("FILE DESCRIPTOR: (size is hex %x)\n", sizeof(ALPHA_FDES));
printf(" Address (lo):\t%x\n", ptr->f_addr_lo);
printf(" Address (hi):\t%x\n", ptr->f_addr_hi);
printf(" Line offset(lo):\t%x\n", ptr->f_cbLineOffset_lo);
printf(" Line offset(hi):\t%x\n", ptr->f_cbLineOffset_hi);
printf(" Line (lo):\t%x\n", ptr->f_cbLine_lo);
printf(" Line (hi):\t%x\n", ptr->f_cbLine_hi);
printf(" Ss (lo):\t%x\n", ptr->f_cbSs_lo);
printf(" Ss (hi):\t%x\n", ptr->f_cbSs_hi);
printf(" Rss: \t%x\n", ptr->f_rss);
printf(" Iss base: \t%x\n", ptr->f_issBase);
printf(" Isym base: \t%x\n", ptr->f_isymBase);
printf(" Csym: \t%x\n", ptr->f_csym);
printf(" Iline Base: \t%x\n", ptr->f_ilineBase);
printf(" Cline: \t%x\n", ptr->f_cline);
printf(" Iopt Base: \t%x\n", ptr->f_ioptBase);
printf(" Copt: \t%x\n", ptr->f_copt);
printf(" Ipd First: \t%x\n", ptr->f_ipdFirst);
printf(" Iaux Base: \t%x\n", ptr->f_iauxBase);
printf(" Caux: \t%x\n", ptr->f_caux);
printf(" Rfd Base: \t%x\n", ptr->f_rfdBase);
printf(" Cfd: \t%x\n", ptr->f_cfd);
printf(" Lan: \t%x\n", ptr->f_lan);
printf(" FMerge: \t%x\n", ptr->f_fMerge);
printf(" FReadin: \t%x\n", ptr->f_fReadin);
printf(" FBigEndian: \t%x\n", ptr->f_fBigEndian);
printf(" Glevel: \t%x\n", ptr->f_glevel);
printf(" Reserved: \t%x\n", ptr->f_reserved);
}
VOID dump_pdes ( ALPHA_PDES *ptr, int num )
{
printf("PDES INFO: (size is hex %x)\n", sizeof(ALPHA_PDES));
for( ; num-- > 0; ptr++ )
{
printf(" Address (lo):\t%x\n", ptr->p_addr_lo);
printf(" Address (hi):\t%x\n", ptr->p_addr_hi);
printf(" Line offset(lo):\t%x\n", ptr->p_cbLineOffset_lo);
printf(" Line offset(hi):\t%x\n", ptr->p_cbLineOffset_hi);
printf(" Isym: \t%x\n", ptr->p_isym);
printf(" Iline \t%x\n", ptr->p_iline);
printf(" Reg mask \t%x\n", ptr->p_regmask);
printf(" Reg offset \t%x\n", ptr->p_regoffset);
printf(" Iopt \t%x\n", ptr->p_iopt);
printf(" Freg mask \t%x\n", ptr->p_fregmask);
printf(" Freg offset \t%x\n", ptr->p_fregoffset);
printf(" Frame offset \t%x\n", ptr->p_frameoffset);
printf(" Line low \t%x\n", ptr->p_lnLow);
printf(" Line high \t%x\n", ptr->p_lnHigh);
printf(" GP prologue \t%x\n", ptr->p_gp_prologue);
printf(" GP used \t%x\n", ptr->p_gp_used);
printf(" Reserved \t%x\n", ptr->p_reserved);
printf(" Frame reg \t%x\n", ptr->p_framereg);
printf(" PC reg \t%x\n\n", ptr->p_pcreg);
}
}
VOID dump_symbol_header( ALPHA_SYMBOL_HEADER *sym )
{
printf("SYMBOL TABLE HEADER: (size is hex %x)\n", sizeof(ALPHA_SYMBOL_HEADER));
printf(" Magic: \t%x\n", sym->s_magic);
printf(" Vstamp: \t%x\n", sym->s_vstamp);
printf(" IlineMax: \t%x\n", sym->s_ilineMax);
printf(" IdnMax: \t%x\n", sym->s_idnMax);
printf(" IpdMax: \t%x\n", sym->s_ipdMax);
printf(" IsymMax: \t%x\n", sym->s_isymMax);
printf(" IoptMax: \t%x\n", sym->s_ioptMax);
printf(" IauxMax: \t%x\n", sym->s_iauxMax);
printf(" IssMax: \t%x\n", sym->s_issMax);
printf(" IssExtMax: \t%x\n", sym->s_issExtMax);
printf(" IfdMax: \t%x\n", sym->s_ifdMax);
printf(" Crfd: \t%x\n", sym->s_crfd);
printf(" IextMax: \t%x\n", sym->s_iextMax);
printf(" Line (lo):\t%x\n", sym->s_cbLine_lo);
printf(" Line (hi):\t%x\n", sym->s_cbLine_hi);
printf(" Line Offset(lo):\t%x\n", sym->s_cbLineOffset_lo);
printf(" Line Offset(hi):\t%x\n", sym->s_cbLineOffset_hi);
printf(" Dn Offset (lo):\t%x\n", sym->s_cbDnOffset_lo);
printf(" Dn Offset (hi):\t%x\n", sym->s_cbDnOffset_hi);
printf(" Pd Offset (lo):\t%x\n", sym->s_cbPdOffset_lo);
printf(" Pd Offset (hi):\t%x\n", sym->s_cbPdOffset_hi);
printf(" Sym Offset (lo):\t%x\n", sym->s_cbSymOffset_lo);
printf(" Sym Offset (hi):\t%x\n", sym->s_cbSymOffset_hi);
printf(" Opt Offset (lo):\t%x\n", sym->s_cbOptOffset_lo);
printf(" Opt Offset (hi):\t%x\n", sym->s_cbOptOffset_hi);
printf(" Aux Offset (lo):\t%x\n", sym->s_cbAuxOffset_lo);
printf(" Aux Offset (hi):\t%x\n", sym->s_cbAuxOffset_hi);
printf(" Ss Offset (lo):\t%x\n", sym->s_cbSsOffset_lo);
printf(" Ss Offset (hi):\t%x\n", sym->s_cbSsOffset_hi);
printf(" SsExt Offse(lo):\t%x\n", sym->s_cbSsExtOffset_lo);
printf(" SsExt Offse(hi):\t%x\n", sym->s_cbSsExtOffset_hi);
printf(" Fd Offset (lo):\t%x\n", sym->s_cbFdOffset_lo);
printf(" Fd Offset (hi):\t%x\n", sym->s_cbFdOffset_hi);
printf(" Rfd Offset (lo):\t%x\n", sym->s_cbRfdOffset_lo);
printf(" Rfd Offset (hi):\t%x\n", sym->s_cbRfdOffset_hi);
printf(" Ext Offset (lo):\t%x\n", sym->s_cbExtOffset_lo);
printf(" Ext Offset (hi):\t%x\n", sym->s_cbExtOffset_hi);
}
VOID convert_symbol( ALPHA_SYML *symbol,
ULONG symbol_type,
ULONG storage_class,
ULONG *return_index,
ULONG *return_value,
SHORT *secNum)
{
*return_value = symbol->s_value_lo ;
switch( storage_class )
{
case SC_ALPHA_NIL:
case SC_ALPHA_DBX:
*secNum = IMAGE_SYM_DEBUG;
break ;
case SC_ALPHA_TEXT:
*secNum = TEXT;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break ;
case SC_ALPHA_DATA:
*secNum = DATA;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_BSS:
*secNum = BSS;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_ABS:
*secNum = IMAGE_SYM_ABSOLUTE;
break;
case SC_ALPHA_UNDEFINED:
*secNum = IMAGE_SYM_UNDEFINED;
break;
case SC_ALPHA_SDATA:
*secNum = SDATA;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_SBSS:
*secNum = SDATA; // yup. fold sbss into sdata
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_RDATA:
*secNum = RDATA;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_COMMON:
case SC_ALPHA_SCOMMON:
*secNum = 0;
break;
case SC_ALPHA_UNDEFSMALL :
*secNum = IMAGE_SYM_UNDEFINED;
*return_value = 0;
break;
case SC_ALPHA_INIT:
*secNum = INIT;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_XDATA:
*secNum = XDATA;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
case SC_ALPHA_PDATA:
*secNum = PDATA;
*return_value -= CoffSectionHdr[*secNum].VirtualAddress;
break;
// case SC_ALPHA_VAR: ??
// case SC_ALPHA_REGISTER: ??
// case SC_ALPHA_BITS: ??
// case SC_ALPHA_REGIMAGE: ??
// case SC_ALPHA_INFO: ??
// case SC_ALPHA_USERSTRUCT: ??
// case SC_ALPHA_VARREGISTER: ??
// case SC_ALPHA_VARIANT: ??
// case SC_ALPHA_FINI: ??
default:
printf("Warning can't converting storage class %d.\n", storage_class ) ;
*secNum = 0;
break ;
}
}