Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/*
32
  dyninit
33
 
34
  This program extracts all the initialisation procedures from a SunOS
35
  object file.  It then writes out a .s file containing a function 
36
  (___TDF_main) which contains calls to each of these procedures.
37
  Initialisation procedures are identified by the ___I.TDF prefix.
38
  Note: the actual prefix starts with two '_'s but SunOS inserts
39
  an extra one.
40
 
41
  the command line syntax is
42
 
43
  dyninit <name of object file> <name of destination (.s) file>
44
 
45
*/
46
 
47
#include <stdio.h>
48
#include <sun3/a.out.h>
49
#include "ossg.h"
50
 
51
#define MAJOR_VERSION		1
52
#define MINOR_VERSION		1
53
 
54
void fail PROTO_S((char *));
55
FILE *open_file PROTO_S((char *,char *));
56
#define open_file_read(x)	open_file(x,"r")
57
#define open_file_write(x)	open_file(x,"w")
58
 
59
 
60
FILE *open_file
61
    PROTO_N((filename,option))
62
    PROTO_T(char *filename X char *option)
63
{
64
  FILE * ret_fp;
65
  if(ret_fp = fopen(filename,option)){
66
    return ret_fp;
67
  }
68
  else{
69
    fprintf(stderr,"Cannot open file <%s>\n",filename);
70
    exit(1);
71
  }
72
}
73
 
74
 
75
typedef struct exec EXEC_STRUCT;
76
 
77
typedef struct nlist SYMBOL_STRUCT;
78
 
79
#define INIT_FUNC_NAME "___TDF_main"
80
 
81
EXEC_STRUCT header;
82
SYMBOL_STRUCT symbol;
83
 
84
 
85
void fail
86
    PROTO_N((message))
87
    PROTO_T(char *message)
88
{
89
  fprintf(stderr,"*fail* : %s\n",message);
90
  exit(1);
91
}
92
 
93
 
94
/*#define symbol_is_function(x) (x.n_type & N_TEXT)*/
95
#define is_intitialisation_function(x) (!strncmp(x+1,"__I.TDF",7))
96
#define is_function(x) 1
97
 
98
 
99
void print_ass_preamble
100
    PROTO_N((of))
101
    PROTO_T(FILE *of)
102
{
103
  fprintf(of,".text\n");
104
  fprintf(of,"\t.even\n");
105
  fprintf(of,".globl %s\n",INIT_FUNC_NAME);
106
  fprintf(of,"%s:\n",INIT_FUNC_NAME);
107
  return;
108
}
109
 
110
void print_ass_postlude
111
    PROTO_N((of))
112
    PROTO_T(FILE *of)
113
{
114
  fprintf(of,"\trts\n");
115
}
116
 
117
void construct_init_proc
118
    PROTO_N((fp,symtab_pos,stringtab_pos,header,outname))
119
    PROTO_T(FILE *fp X long symtab_pos X long stringtab_pos X
120
	    EXEC_STRUCT header X char *outname)
121
{
122
  int i;
123
  char str[256];
124
  long keeppos;
125
  FILE *outfile;
126
  if(!(outfile = open_file_write(outname))){
127
    fail("Cannot Open output file");
128
  }
129
  fseek(fp,symtab_pos,0);
130
  print_ass_preamble(outfile);
131
  for(i=0;i<header.a_syms/sizeof(SYMBOL_STRUCT);++i){
132
    fread(&symbol,sizeof(SYMBOL_STRUCT),1,fp);
133
    if(is_function(symbol)){
134
      keeppos = ftell(fp);
135
      fseek(fp,stringtab_pos+symbol.n_un.n_strx,0);
136
      fgets(str,256,fp);
137
      if(is_intitialisation_function(str)){
138
	fprintf(outfile,"\tjbsr\t%s\n",str);
139
      }
140
      fseek(fp,keeppos,0);
141
    }
142
  }
143
  print_ass_postlude(outfile);
144
  return;
145
}
146
 
147
void process_flag
148
    PROTO_N((option))
149
    PROTO_T(char *option)
150
{
151
  switch(option[1]) {
152
    case 'V':
153
    case 'v': {
154
      (void)fprintf(stderr,"Dynamic initialisation linker V%d.%d\n",
155
		    MAJOR_VERSION,MINOR_VERSION);
156
      break;
157
    }
158
    default: {
159
      (void)fprintf(stderr,"Error: unknown option %s\n",option);
160
    }
161
  }
162
  return;
163
}
164
 
165
 
166
int main
167
    PROTO_N((argc,argv))
168
    PROTO_T(int argc X char **argv)
169
{
170
  FILE *fp;
171
  long symtab_pos,stringtab_pos;
172
  int i;
173
  int symsize;
174
  char str[80];
175
  long keeppos;
176
  int num_flags = 0;
177
 
178
  for(i=1;i<argc;++i) {
179
    if(argv[i][0] == '-') {
180
      num_flags++;
181
      process_flag(argv[i]);
182
    }
183
  }
184
  if(argc - num_flags < 3) {
185
    fprintf(stderr,"*fail*: syntax is %s [-options] <input filename> <output filename>\n",argv[0]);
186
    exit(1);
187
  }
188
  fp = open_file_read(argv[1+num_flags]);
189
 
190
  fread(&header,sizeof(EXEC_STRUCT),1,fp);
191
  if(N_BADMAG(header)){
192
    fail("Bad magic number\n");
193
  }
194
  symtab_pos = N_SYMOFF(header);
195
 
196
  stringtab_pos = N_STROFF(header);
197
  construct_init_proc(fp,symtab_pos,stringtab_pos,header,argv[2+num_flags]);
198
  return 0;
199
}