Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / Midas_samy / Segment.pm
CommitLineData
86530b38
AT
1# -*- perl -*-
2
3package Midas::Segment;
4use strict;
5use warnings;
6use Carp;
7use Tie::IxHash;
8use Midas::Command;
9use Midas::Error;
10
11use fields qw(type);
12
13use constant
14 {
15 SEG_UNDEF => 0,
16 SEG_TEXT => 1,
17 SEG_DATA => 2,
18 SEG_BSS => 3,
19 };
20
21require Exporter;
22
23our @ISA = qw(Exporter);
24our @EXPORT = qw(SEG_UNDEF SEG_TEXT SEG_DATA SEG_BSS);
25
26
27
28our %Segments =
29 (
30 SEG_TEXT() => {
31 name => 'text',
32 link_suffix => 't',
33 va_name => 'text_va',
34 elfname => '.text',
35 include_elf => [qw(.rodata)],
36 elfname_out => '.text .rodata',
37 },
38 SEG_DATA() => {
39 name => 'data',
40 link_suffix => 'd',
41 va_name => 'data_va',
42 elfname => '.data',
43 },
44 SEG_BSS() => {
45 name => 'bss',
46 link_suffix => 'b',
47 va_name => 'bss_va',
48 elfname => '.bss',
49 },
50 );
51
52
53
54our %RevNames = map { ( $Segments{$_}{name}, $_) } keys %Segments;
55our %ElfNames = map
56 { defined $Segments{$_}{elfname} ?
57 ( $Segments{$_}{elfname}, $Segments{$_}{name} ) : () } keys %Segments;
58
59foreach my $code (keys %Segments) {
60 next unless exists $Segments{$code}{include_elf};
61 foreach my $included (@{$Segments{$code}{include_elf}}) {
62 $ElfNames{$included} = $Segments{$code}{name};
63 }
64}
65
66our %LinkSuffixes = map
67 { ( $Segments{$_}{link_suffix}, $Segments{$_}{name} ) } keys %Segments;
68
69# rodata must appear before text or the linker will merge them
70#our @Names = qw(rodata text data bss);
71our @Names = qw(text data bss);
72
73my @keys = keys %Segments;
74if(@keys > @Names) {
75 fatal "In Midas::Segment, @Names is incomplete.\n", M_CODE;
76} elsif(@Names > @keys) {
77 fatal "In Midas::Segment, @Names has extra entry\n", M_CODE;
78}
79foreach my $name (@Names) {
80 fatal "Segment name '$name' is not set up correctly in Midas::Segment\n",
81 M_CODE unless exists $RevNames{$name};
82}
83
84###############################################################################
85
86sub new {
87 my $class = shift;
88 my $type = shift;
89
90 $type = $class->name2type($type) if $type =~ /[a-zA-Z]/;
91
92 my $this;
93 if(ref $class) {
94 my $classtype = ref $class;
95 $this = fields::new($classtype);
96 $this->{type} = $class->type() if defined $class->type();
97 } else {
98 $this = fields::new($class);
99 $this->{type} = $type if defined $type;
100 }
101 return $this;
102}
103
104###############################################################################
105
106sub type {
107 my $this = shift;
108 my $set = shift;
109
110 if(defined $set) {
111 fatal Carp::longmess("No such segment type '$set'.\n"), M_CODE
112 unless exists $Segments{$set}{name};
113 $this->{type} = $set;
114 }
115 return $this->{type};
116}
117
118###############################################################################
119
120sub name {
121 my $this = shift;
122 my $set = shift;
123
124 if(defined $set) {
125 $this->type($this->name2type($set));
126 }
127 return $this->type2name($this->{type});
128}
129
130###############################################################################
131###############################################################################
132
133sub is_segment_name {
134 my $class = shift;
135 my $name = shift;
136
137 return 1 if exists $RevNames{$name};
138 return 0;
139}
140
141###############################################################################
142
143sub name2type {
144 my $class = shift;
145 my $name = shift;
146
147 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
148 unless exists $RevNames{$name};
149
150 return $RevNames{$name};
151}
152
153###############################################################################
154
155sub name2va_name {
156 my $class = shift;
157 my $name = shift;
158
159 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
160 unless exists $RevNames{$name};
161
162 return $Segments{$RevNames{$name}}{va_name};
163}
164
165###############################################################################
166
167sub name2elf_name {
168 my $class = shift;
169 my $name = shift;
170
171 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
172 unless exists $RevNames{$name};
173
174 return exists $Segments{$RevNames{$name}}{elfname_out} ?
175 $Segments{$RevNames{$name}}{elfname_out} :
176 $Segments{$RevNames{$name}}{elfname};
177}
178
179###############################################################################
180
181sub name2link_suffix {
182 my $class = shift;
183 my $name = shift;
184
185 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
186 unless exists $RevNames{$name};
187
188 return $Segments{$RevNames{$name}}{link_suffix};
189}
190
191###############################################################################
192
193sub type2name {
194 my $class = shift;
195 my $type = shift;
196
197 fatal Carp::longmess("No such segment type '$type'.\n"), M_CODE
198 unless exists $Segments{$type}{name};
199
200 return $Segments{$type}{name};
201}
202
203###############################################################################
204
205sub all_names {
206 my $class = shift;
207 return @Names;
208}
209
210###############################################################################
211
212sub all_va_names {
213 my $class = shift;
214 return map { $Segments{$_}{va_name} } keys %Segments;
215}
216
217###############################################################################
218###############################################################################
2191;