voodoo 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/voodooc CHANGED
@@ -24,17 +24,31 @@ Valid options are:
24
24
  Select output format. Use -a <architecture> -f help to get a list of
25
25
  supported output formats for architecture.
26
26
 
27
+ --features
28
+ Lists the features supported by this implementation. The features
29
+ are listed in the format <feature name><tab><version>, ordered
30
+ by feature name. The program exits after printing the list of
31
+ features; no compilation is performed.
32
+
33
+ -h
34
+ --help
35
+ Display usage information and exit. No compilation will be performed.
36
+
27
37
  -o <output file>
28
38
  --output <output file>
29
39
  --output-file <output file>
30
40
  Set output file name. The special name '-' causes voodooc to write
31
41
  to standard output.
42
+
43
+ --version
44
+ Display version information and exit. No compilation will be performed.
32
45
  EOT
33
46
 
34
47
  input_file = nil
35
48
  output_file = nil
36
49
  architecture = Voodoo::Config.default_architecture
37
50
  output_format = Voodoo::Config.default_format
51
+ show_features = false
38
52
 
39
53
  #
40
54
  # Process command line
@@ -43,8 +57,10 @@ output_format = Voodoo::Config.default_format
43
57
  opts = GetoptLong.new(
44
58
  ['--help', '-h', GetoptLong::NO_ARGUMENT ],
45
59
  ['--arch', '--architecture', '-a', GetoptLong::REQUIRED_ARGUMENT ],
60
+ ['--features', GetoptLong::NO_ARGUMENT],
46
61
  ['--output-file', '--output', '-o', GetoptLong::REQUIRED_ARGUMENT ],
47
- ['--output-format', '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ]
62
+ ['--output-format', '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
63
+ ['--version', GetoptLong::NO_ARGUMENT]
48
64
  )
49
65
 
50
66
  # Process options
@@ -56,10 +72,16 @@ opts.each do |opt, arg|
56
72
  exit
57
73
  when '--arch'
58
74
  architecture = arg.to_sym
75
+ when '--features'
76
+ show_features = true
59
77
  when '--output-file'
60
78
  output_file = arg
61
79
  when '--output-format'
62
80
  output_format = arg.to_sym
81
+ when '--version'
82
+ puts "#{Voodoo::Config::IMPLEMENTATION_NAME} version " +
83
+ Voodoo::Config::IMPLEMENTATION_VERSION
84
+ exit
63
85
  end
64
86
  end
65
87
 
@@ -77,19 +99,6 @@ if output_format == :help
77
99
  exit
78
100
  end
79
101
 
80
- # Get input file name
81
- if ARGV.length == 1
82
- input_file = ARGV[0]
83
- else
84
- if ARGV.length < 1
85
- $stderr.puts "no input files"
86
- else
87
- $stderr.puts "Too many arguments"
88
- end
89
- $stderr.puts usage
90
- exit 0x80
91
- end
92
-
93
102
  # Select code generator based on output format
94
103
  begin
95
104
  generator = Voodoo::CodeGenerator.get_generator :architecture => architecture,
@@ -107,6 +116,28 @@ rescue NotImplementedError
107
116
  exit 1
108
117
  end
109
118
 
119
+ # If requested, show features and exit
120
+ if show_features
121
+ generator.features.to_a.sort{|x,y| x[0].to_s <=> y[0].to_s}.each do |feature|
122
+ puts "#{feature[0]}\t#{feature[1]}"
123
+ end
124
+ exit
125
+ end
126
+
127
+ # Get input file name
128
+ if ARGV.length == 1
129
+ input_file = ARGV[0]
130
+ else
131
+ if ARGV.length < 1
132
+ $stderr.puts "no input files"
133
+ else
134
+ $stderr.puts "Too many arguments"
135
+ end
136
+ $stderr.puts usage
137
+ exit 0x80
138
+ end
139
+
140
+
110
141
 
111
142
  #
112
143
  # Compile
@@ -135,11 +166,35 @@ begin
135
166
  compiler = Voodoo::Compiler.new parser, generator, outfile
136
167
 
137
168
  compiler.compile
138
- rescue
169
+ rescue => e
139
170
  if output_file != '-'
140
171
  File::unlink(output_file) if File::exists?(output_file)
141
172
  end
142
- raise
173
+
174
+ # If e is a compiler error, iterate over all child errors and
175
+ # print user-friendly messages. Else, re-raise so that the default
176
+ # handling is performed.
177
+ if e.kind_of? Voodoo::Compiler::Error
178
+ e.errors.each do |error|
179
+ message = ''
180
+ if error.start_line != nil
181
+ message << "#{error.start_line}: "
182
+ if error.input_name != nil
183
+ message = "#{error.input_name}:#{message}"
184
+ else
185
+ message = "line #{message}"
186
+ end
187
+ end
188
+ message << error.message
189
+ $stderr.puts message
190
+ if error.text != nil
191
+ $stderr.print "\n #{error.text.gsub("\n", "\n ")}\n"
192
+ end
193
+ end
194
+ exit 1
195
+ else
196
+ raise
197
+ end
143
198
  ensure
144
199
  outfile.close
145
200
  infile.close
@@ -1,3 +1,5 @@
1
+ require 'voodoo/parser'
2
+
1
3
  module Voodoo
2
4
  # Voodoo compiler driver.
3
5
  # The compiler driver reads input from a parser (see
@@ -7,6 +9,20 @@ module Voodoo
7
9
  # An example of its usage can be found on the main page for the
8
10
  # Voodoo module.
9
11
  class Compiler
12
+ class Error < StandardError
13
+ def initialize errors
14
+ @errors = errors
15
+ end
16
+
17
+ attr_reader :errors
18
+
19
+ def message
20
+ msg = ""
21
+ @errors.each {|e| msg << e.message << "\n"}
22
+ msg
23
+ end
24
+ end
25
+
10
26
  # Initialize a compiler.
11
27
  #
12
28
  # Parameters:
@@ -23,23 +39,35 @@ module Voodoo
23
39
  # Perform the compilation.
24
40
  def compile
25
41
  section = :code
42
+ errors = []
26
43
  while true
27
- statement = @parser.parse_top_level
28
-
29
- break if statement == nil
30
- next if statement.empty?
31
-
32
- case statement[0]
33
- when :section
34
- section = statement[1]
35
- when :function
36
- @generator.add section, [:function, statement[1]] + statement[2]
37
- else
38
- @generator.add section, statement
44
+ begin
45
+ statement = @parser.parse_top_level
46
+
47
+ break if statement == nil
48
+ next if statement.empty?
49
+
50
+ case statement[0]
51
+ when :section
52
+ section = statement[1]
53
+ else
54
+ @generator.add section, statement
55
+ end
56
+
57
+ rescue Parser::ParseError => e
58
+ errors << e
59
+ if errors.length >= 100
60
+ raise Error.new(errors)
61
+ end
39
62
  end
63
+
40
64
  end
41
65
 
42
- @generator.write @output
66
+ if errors.empty?
67
+ @generator.write @output
68
+ else
69
+ raise Error.new(errors)
70
+ end
43
71
  end
44
72
  end
45
73
  end
data/lib/voodoo/config.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  module Voodoo
2
2
  # Methods to get and set configuration parameters
3
3
  module Config
4
+ IMPLEMENTATION_NAME = 'Voodoo Compiler'
5
+ IMPLEMENTATION_VERSION = '1.0.0'
6
+
4
7
  # Class that holds configuration parameters
5
8
  class Configuration
6
9
  def initialize
@@ -35,6 +38,8 @@ module Voodoo
35
38
  case arch
36
39
  when 'x86_64', 'amd64'
37
40
  :amd64
41
+ when 'arm'
42
+ :arm
38
43
  when 'i386', 'i686'
39
44
  :i386
40
45
  when 'mips'
@@ -81,6 +81,10 @@ module Voodoo
81
81
  # Stack pointer
82
82
  @SP = 'rsp'
83
83
  super params
84
+ @features.merge! \
85
+ :'bits-per-word' => '64',
86
+ :'byte-order' => 'little-endian',
87
+ :'bytes-per-word' => '8'
84
88
  end
85
89
 
86
90
  #
@@ -0,0 +1,33 @@
1
+ require 'delegate'
2
+ require 'tempfile'
3
+ require 'voodoo/generators/arm_gas_generator'
4
+ require 'voodoo/generators/gas_elf_generator'
5
+
6
+ module Voodoo
7
+ # Generator that produces ELF objects for arm
8
+ class ARMELFGenerator < DelegateClass(ARMGasGenerator)
9
+ def initialize params = {}
10
+ @asmgenerator = ARMGasGenerator.new params
11
+ super(@asmgenerator)
12
+ @elfgenerator = GasELFGenerator.new @asmgenerator
13
+ end
14
+
15
+ def output_file_name input_name
16
+ @elfgenerator.output_file_name input_name
17
+ end
18
+
19
+ def output_file_suffix
20
+ @elfgenerator.output_file_suffix
21
+ end
22
+
23
+ def write io
24
+ @elfgenerator.write io
25
+ end
26
+ end
27
+
28
+ # Register class for arm
29
+ Voodoo::CodeGenerator.register_generator ARMELFGenerator,
30
+ :architecture => :arm,
31
+ :format => :elf
32
+
33
+ end