Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perlmod / Midas / 3.32 / lib / site_perl / 5.8.0 / Midas / Segment.pm
CommitLineData
86530b38
AT
1# ========== Copyright Header Begin ==========================================
2#
3# OpenSPARC T2 Processor File: Segment.pm
4# Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5# 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6#
7# * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; version 2 of the License.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#
22# For the avoidance of doubt, and except that if any non-GPL license
23# choice is available it will apply instead, Sun elects to use only
24# the General Public License version 2 (GPLv2) at this time for any
25# software where a choice of GPL license versions is made
26# available with the language indicating that GPLv2 or any later version
27# may be used, or where a choice of which version of the GPL is applied is
28# otherwise unspecified.
29#
30# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31# CA 95054 USA or visit www.sun.com if you need additional information or
32# have any questions.
33#
34# ========== Copyright Header End ============================================
35# -*- perl -*-
36
37package Midas::Segment;
38use strict;
39use warnings;
40use Carp;
41use Tie::IxHash;
42use Midas::Command;
43use Midas::Error;
44
45use fields qw(type);
46
47use constant
48 {
49 SEG_UNDEF => 0,
50 SEG_TEXT => 1,
51 SEG_DATA => 2,
52 SEG_BSS => 3,
53 };
54
55require Exporter;
56
57our @ISA = qw(Exporter);
58our @EXPORT = qw(SEG_UNDEF SEG_TEXT SEG_DATA SEG_BSS);
59
60
61
62our %Segments =
63 (
64 SEG_TEXT() => {
65 name => 'text',
66 link_suffix => 't',
67 va_name => 'text_va',
68 elfname => '.text',
69 include_elf => [qw(.rodata)],
70 elfname_out => '.text .rodata',
71 },
72 SEG_DATA() => {
73 name => 'data',
74 link_suffix => 'd',
75 va_name => 'data_va',
76 elfname => '.data',
77 },
78 SEG_BSS() => {
79 name => 'bss',
80 link_suffix => 'b',
81 va_name => 'bss_va',
82 elfname => '.bss',
83 },
84 );
85
86
87
88our %RevNames = map { ( $Segments{$_}{name}, $_) } keys %Segments;
89our %ElfNames = map
90 { defined $Segments{$_}{elfname} ?
91 ( $Segments{$_}{elfname}, $Segments{$_}{name} ) : () } keys %Segments;
92
93foreach my $code (keys %Segments) {
94 next unless exists $Segments{$code}{include_elf};
95 foreach my $included (@{$Segments{$code}{include_elf}}) {
96 $ElfNames{$included} = $Segments{$code}{name};
97 }
98}
99
100our %LinkSuffixes = map
101 { ( $Segments{$_}{link_suffix}, $Segments{$_}{name} ) } keys %Segments;
102
103# rodata must appear before text or the linker will merge them
104#our @Names = qw(rodata text data bss);
105our @Names = qw(text data bss);
106
107my @keys = keys %Segments;
108if(@keys > @Names) {
109 fatal "In Midas::Segment, @Names is incomplete.\n", M_CODE;
110} elsif(@Names > @keys) {
111 fatal "In Midas::Segment, @Names has extra entry\n", M_CODE;
112}
113foreach my $name (@Names) {
114 fatal "Segment name '$name' is not set up correctly in Midas::Segment\n",
115 M_CODE unless exists $RevNames{$name};
116}
117
118###############################################################################
119
120sub new {
121 my $class = shift;
122 my $type = shift;
123
124 $type = $class->name2type($type) if $type =~ /[a-zA-Z]/;
125
126 my $this;
127 if(ref $class) {
128 my $classtype = ref $class;
129 $this = fields::new($classtype);
130 $this->{type} = $class->type() if defined $class->type();
131 } else {
132 $this = fields::new($class);
133 $this->{type} = $type if defined $type;
134 }
135 return $this;
136}
137
138###############################################################################
139
140sub type {
141 my $this = shift;
142 my $set = shift;
143
144 if(defined $set) {
145 fatal Carp::longmess("No such segment type '$set'.\n"), M_CODE
146 unless exists $Segments{$set}{name};
147 $this->{type} = $set;
148 }
149 return $this->{type};
150}
151
152###############################################################################
153
154sub name {
155 my $this = shift;
156 my $set = shift;
157
158 if(defined $set) {
159 $this->type($this->name2type($set));
160 }
161 return $this->type2name($this->{type});
162}
163
164###############################################################################
165###############################################################################
166
167sub is_segment_name {
168 my $class = shift;
169 my $name = shift;
170
171 return 1 if exists $RevNames{$name};
172 return 0;
173}
174
175###############################################################################
176
177sub name2type {
178 my $class = shift;
179 my $name = shift;
180
181 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
182 unless exists $RevNames{$name};
183
184 return $RevNames{$name};
185}
186
187###############################################################################
188
189sub name2va_name {
190 my $class = shift;
191 my $name = shift;
192
193 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
194 unless exists $RevNames{$name};
195
196 return $Segments{$RevNames{$name}}{va_name};
197}
198
199###############################################################################
200
201sub name2elf_name {
202 my $class = shift;
203 my $name = shift;
204
205 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
206 unless exists $RevNames{$name};
207
208 return exists $Segments{$RevNames{$name}}{elfname_out} ?
209 $Segments{$RevNames{$name}}{elfname_out} :
210 $Segments{$RevNames{$name}}{elfname};
211}
212
213###############################################################################
214
215sub name2link_suffix {
216 my $class = shift;
217 my $name = shift;
218
219 fatal Carp::longmess("No such segment name '$name'.\n"), M_CODE
220 unless exists $RevNames{$name};
221
222 return $Segments{$RevNames{$name}}{link_suffix};
223}
224
225###############################################################################
226
227sub type2name {
228 my $class = shift;
229 my $type = shift;
230
231 fatal Carp::longmess("No such segment type '$type'.\n"), M_CODE
232 unless exists $Segments{$type}{name};
233
234 return $Segments{$type}{name};
235}
236
237###############################################################################
238
239sub all_names {
240 my $class = shift;
241 return @Names;
242}
243
244###############################################################################
245
246sub all_va_names {
247 my $class = shift;
248 return map { $Segments{$_}{va_name} } keys %Segments;
249}
250
251###############################################################################
252###############################################################################
2531;