I've attempted to create a linker for assembly files, what the program does is not the issue here though, I havent used pointer arithmetic in a few years and am definitely rusty in doing so. I'm getting a segmentation fault when I attempt to run the file and would like to at least make a few strides in figuring out why. My code is currently as follows, any input on the pointer arithmetic errors would be helpful, and if you need to know more on what the input files need to look like or what the output needs to look like I can give that information.
The struct might also be a little off... so insight on how to clean things up a bit would be helpful just to make things look prettier.
The program compiles fine with no warnings or errors.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct nament {
char name[26];
int addr;
struct nament *next;
} SYMTABENTRY;
void add_symbol( char *symbol, int linenum );
char* generate_code( int );
void append_table( void );
int search_table( char *symbol );
SYMTABENTRY *symtab = NULL;
SYMTABENTRY *finder = NULL;
FILE *p1, *p2, *p3;
char cstr_21[18];
int main( int argc, char *argv[] ) {
int start = 1, end, pc_offset = 0, pc = 0;
int linenum, dump_tab = 1;
int new_pc, exit = 0;
char instruction[18];
char symbol[26];
char executable[18];
symtab = (SYMTABENTRY *)malloc(sizeof(SYMTABENTRY));
if( strcmp( argv[argc - 2], ">" ) == 0){
end = argc - 3;
dump_tab = 0;
}
p1 = fopen( "/tmp/passone", "w+" );
unlink( "/tmp/passone" );
p3 = fopen( argv[argc-1], "w" );
for( start = 0; start < end; start++ ){
p2 = fopen("argv[start]","r");
if( argv == NULL ) break;
while( fscanf( p2, "%d %s", &pc, &instruction[0] ) != EOF) {
if( instruction[0] == 'x' ){
while( fscanf( p2, "%s %d", &symbol[0], &linenum) != EOF){
add_symbol( symbol, linenum + pc_offset );
}
exit = 1;
}
if(exit == 1)
break;
new_pc = pc + pc_offset;
symbol[0] = '\0';
if( instruction[0] == 'U' ){
fscanf( p2, "%s", &symbol[0]);
fprintf( p1, "%d %s %s", new_pc, instruction, symbol);
}
else
fprintf( p1, "%d %s", new_pc, instruction );
}
pc_offset = new_pc;
fclose( p2 );
}
fseek( p1, 0, SEEK_SET );
while( fscanf( p1, "%d %s", &linenum, &instruction[0] ) != EOF ){
symbol[0] = '\0';
if( instruction[0] == 'U' ){
fscanf( p1, "%s", &symbol[0] );
executable[0] = atoi(generate_code( search_table( symbol ) ));
if(dump_tab){
printf( "%s\n", executable );
}
else{
fprintf( p3, "%s\n", executable );
}
}
else{
if(dump_tab){
printf( "%s\n", instruction );
}
else{
fprintf( p3, "%s\n", instruction );
}
}
}
return 0;
}
void add_symbol( char *symbol, int linenum ){
append_table();
finder->name[0] = atoi(symbol);
finder->addr = linenum;
finder->next = NULL;
}
void append_table(){
finder = symtab;
if( finder != NULL )
while( finder->next != NULL )
finder = finder->next;
finder->next = (SYMTABENTRY *)malloc( sizeof( SYMTABENTRY ));
}
int search_table( char* symbol ){
finder = symtab;
if( finder != NULL ){
while( finder->next != NULL ){
if( strcmp( symbol, finder->name ) == 0 )
return( finder->addr );
}
}
printf( "Unrecognized token %s", symbol );
exit(1);
}
char* generate_code( int linenum ){
int i = 17, tmp;
char binnum[18];
binnum[17] = '\0';
for( i = 17; i >= 0; i--){
tmp = linenum % 2;
binnum[i] = tmp;
linenum /= 2;
}
cstr_21[0] = atoi(binnum);
return cstr_21;
}