Skip to content

Instantly share code, notes, and snippets.

@cr1901
Created October 14, 2015 18:57
Show Gist options
  • Save cr1901/3fef6d6755191a4024c1 to your computer and use it in GitHub Desktop.
Save cr1901/3fef6d6755191a4024c1 to your computer and use it in GitHub Desktop.
OMF-LD Pattern Match
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#define CHAR_ARRAY_2_SHORT_LE(_x) ((_x)[0] << 0) | ((_x)[1] << 8)
static char string_buf[256];
static char record_buf[1024];
typedef struct omf_record
{
union
{
struct header
{
unsigned char strlen;
char * strname;
}theadr;
struct header lheadr;
struct
{
unsigned char type;
unsigned char class;
char * string;
}coment;
}fields;
enum
{
THEADR = 0x80,
LHEADR = 0x82,
COMENT = 0x88,
MODEND = 0x8A,
EXTDEF = 0x8C,
PUBDEF = 0x90,
LNAMES = 0x96,
SEGDEF = 0x98,
GRPDEF = 0x9A,
FIXUPP = 0x9C,
LEDATA = 0xA0,
LIDATA = 0xA2,
LEXTDEF = 0xB4,
LPUBDEF = 0xB6,
ALIAS = 0xC6,
OOB_LIBHEADER = 0xF0,
OOB_LIBEND = 0xF1
}type;
unsigned short length;
unsigned char checksum;
}OMF_RECORD;
int get_new_record(FILE * omf_file, OMF_RECORD * rec);
int main(int argc, char * argv[])
{
/* Check if valid OMF modules */
/* Create symbol table- figure out whether all symbols are defined. */
/* Write actual code/data segments into either temp file or memmapped file. */
/* Construct program header */
/* Concatenate */
FILE * curr_module;
OMF_RECORD curr_rec;
int lib_mode = 0;
if(argc < 2 || (curr_module = fopen(argv[1], "rb")) == NULL)
{
return EXIT_FAILURE;
}
printf("OBJ stats:\n");
while(get_new_record(curr_module, &curr_rec) >= 0)
{
if(curr_rec.type == THEADR)
{
printf("Obj Name: %s\n", curr_rec.fields.theadr.strname);
}
else if(curr_rec.type == LHEADR)
{
printf("Library Name: %s\n", curr_rec.fields.lheadr.strname);
}
else if(curr_rec.type == COMENT)
{
printf("Comment class: %X, string: %s\n", \
curr_rec.fields.coment.class, curr_rec.fields.coment.string);
}
else if(curr_rec.type == MODEND)
{
if(lib_mode)
{
unsigned long curr_pos = ftell(curr_module);
fseek(curr_module, ((16 - (curr_pos % 16)) % 16), SEEK_CUR);
}
}
else if(curr_rec.type == OOB_LIBHEADER)
{
printf("Found Out-of-Band Library Header...\n");
lib_mode = 1;
}
else if(curr_rec.type == OOB_LIBEND)
{
printf("Found Out-of-Band Library End... breaking!\n");
break;
}
}
if(curr_rec.type == MODEND)
{
printf("End of file reached. Parse okay.\n");
return EXIT_SUCCESS;
}
else
{
return EXIT_FAILURE;
}
}
int store_symbol(char * name, long unsigned int address)
{
(void) name;
(void) address;
return 0;
}
long unsigned int get_symbol_address(char * name)
{
(void) name;
return 0uL;
}
/* int try_read(FILE * fp, */
/* Convert string with known size (<= 255) to null-terminated C string. */
unsigned short pstrcpy(char * dest, char * src)
{
unsigned char str_length = src[0];
memcpy(dest, &src[1], str_length);
dest[str_length] = '\0';
return str_length;
}
/* If function fails, file pointer is not modified, and rec is last successfully parsed. */
int get_new_record(FILE * omf_file, OMF_RECORD * rec)
{
long int initial_fpos;
unsigned char buf[3];
initial_fpos = ftell(omf_file);
if(!fread(buf, 3, 1, omf_file))
{
/* Don't even bother checking-
something went seriously wrong. */
fseek(omf_file, initial_fpos, SEEK_SET);
return -1;
}
rec->type = buf[0];
rec->length = CHAR_ARRAY_2_SHORT_LE(&buf[1]);
if(rec->length > 1024)
{
fprintf(stderr, "Records > 1024 not yet supported.\n"
"Record type %X\n", rec->type);
return -2;
}
if(!fread(record_buf, rec->length, 1, omf_file))
{
fseek(omf_file, initial_fpos, SEEK_SET);
return -1;
}
rec->checksum = record_buf[rec->length];
/* We are at the start of the actual record if we got here... */
switch(rec->type)
{
int rc = 0;
case THEADR:
rec->fields.theadr.strlen = \
pstrcpy(string_buf, record_buf);
rec->fields.theadr.strname = string_buf;
break;
case LHEADR:
rec->fields.lheadr.strlen = \
pstrcpy(string_buf, record_buf);
rec->fields.lheadr.strname = string_buf;
break;
case COMENT:
rec->fields.coment.type = record_buf[0];
rec->fields.coment.class = record_buf[1];
memcpy(string_buf, &record_buf[2], rec->length - 3);
string_buf[rec->length - 3] = '\0'; /* Some compilers do not null-terminate comments (Watcom). */
break;
case MODEND:
break;
case EXTDEF:
break;
case PUBDEF:
break;
case LNAMES:
break;
case SEGDEF:
break;
case GRPDEF:
break;
case FIXUPP:
break;
case LEDATA:
break;
case LIDATA:
break;
case LEXTDEF:
break;
case LPUBDEF:
break;
case ALIAS:
break;
case OOB_LIBHEADER:
break;
case OOB_LIBEND:
break;
default:
fprintf(stderr, "Undefined record type: %X!\n", rec->type);
rc = -1;
if(rc)
{
return rc;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment