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 <sparc/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,".global ");
104
  fprintf(of,INIT_FUNC_NAME);
105
  fprintf(of,"\n");
106
  fprintf(of,"\t.seg\t\"text\"\n");
107
  fprintf(of,"\t.align\t4\n");
108
  fprintf(of,INIT_FUNC_NAME);
109
  fprintf(of,":\n");
110
  fprintf(of,"\tsave\t%%sp,-64,%%sp\n");
111
  return;
112
}
113
 
114
void print_ass_postlude
115
    PROTO_N((of))
116
    PROTO_T(FILE *of)
117
{
118
  fprintf(of,"\tret\n\trestore\n");
119
}
120
 
121
void construct_init_proc
122
    PROTO_N((fp,symtab_pos,stringtab_pos,header,outname))
123
    PROTO_T(FILE *fp X long symtab_pos X long stringtab_pos X
124
	    EXEC_STRUCT header X char *outname)
125
{
126
  int i;
127
  char str[256];
128
  long keeppos;
129
  FILE *outfile;
130
  if(!(outfile = open_file_write(outname))){
131
    fail("Cannot Open output file");
132
  }
133
  fseek(fp,symtab_pos,0);
134
  print_ass_preamble(outfile);
135
  for(i=0;i<header.a_syms/sizeof(SYMBOL_STRUCT);++i){
136
    fread(&symbol,sizeof(SYMBOL_STRUCT),1,fp);
137
    if(is_function(symbol)){
138
      keeppos = ftell(fp);
139
      fseek(fp,stringtab_pos+symbol.n_un.n_strx,0);
140
      fgets(str,256,fp);
141
      if(is_intitialisation_function(str)){
142
	fprintf(outfile,"\tcall\t%s,0\n\tnop\n",str);
143
      }
144
      fseek(fp,keeppos,0);
145
    }
146
  }
147
  print_ass_postlude(outfile);
148
  return;
149
}
150
 
151
void process_flag
152
    PROTO_N((option))
153
    PROTO_T(char *option)
154
{
155
  switch(option[1]) {
156
    case 'V':
157
    case 'v': {
158
      (void)fprintf(stderr,"Dynamic initialisation linker V%d.%d\n",
159
		    MAJOR_VERSION,MINOR_VERSION);
160
      break;
161
    }
162
    default: {
163
      (void)fprintf(stderr,"Error: unknown option %s\n",option);
164
    }
165
  }
166
  return;
167
}
168
 
169
 
170
int main
171
    PROTO_N((argc,argv))
172
    PROTO_T(int argc X char **argv)
173
{
174
  FILE *fp;
175
  long symtab_pos,stringtab_pos;
176
  int i;
177
  int symsize;
178
  char str[80];
179
  long keeppos;
180
  int num_flags = 0;
181
 
182
  for(i=1;i<argc;++i) {
183
    if(argv[i][0] == '-') {
184
      num_flags++;
185
      process_flag(argv[i]);
186
    }
187
  }
188
  if(argc - num_flags < 3) {
189
    fprintf(stderr,"*fail*: syntax is %s [-options] <input filename> <output filename>\n",argv[0]);
190
    exit(1);
191
  }
192
  fp = open_file_read(argv[1+num_flags]);
193
 
194
  fread(&header,sizeof(EXEC_STRUCT),1,fp);
195
  if(N_BADMAG(header)){
196
    fail("Bad magic number\n");
197
  }
198
  symtab_pos = N_SYMOFF(header);
199
 
200
  stringtab_pos = N_STROFF(header);
201
  construct_init_proc(fp,symtab_pos,stringtab_pos,header,argv[2+num_flags]);
202
  return 0;
203
}