File: ldscript_patcher.pl

package info (click to toggle)
faumachine 20100527-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 53,836 kB
  • ctags: 20,552
  • sloc: ansic: 179,550; asm: 3,645; makefile: 3,611; perl: 2,103; sh: 1,529; python: 600; xml: 563; lex: 210; vhdl: 204
file content (117 lines) | stat: -rwxr-xr-x 3,087 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/perl -w
# 
# $Id: ldscript_patcher.pl,v 1.8 2009-01-28 14:57:22 potyra Exp $
#
# Copyright (C) 2005-2009 FAUmachine Team <info@faumachine.org>.
# This program is free software. You can redistribute it and/or modify it
# under the terms of the GNU General Public License, either version 2 of
# the License, or (at your option) any later version. See COPYING.

$DEBUG = 0;

$PROGRAM = "ldscript_patcher.pl";
$NM = "nm";
$NM_ARGS = "-o ";
$SIZE = "size";
$SIZE_ARGS = " ";
##$OBJ_PREFIX =  "bios_elf1-";

#$script_name = $ARGV[0];
$in_script = shift(@ARGV);
$out_script = shift(@ARGV);
@obj_files = @ARGV;

%sym_table = ();

foreach $obj_file (@obj_files) {
	open(SYM_LISTING, "${NM} ${NM_ARGS} ${obj_file} |") 
		|| die "$PROGRAM: unable to use process inputfile \"$obj_file\" ($!)";

	#Read symbol table
	while (defined($line = <SYM_LISTING>)) {
		# Look for entries
		if ($line =~ /(\S*):(\S*)\s*(\w)\s*(\S*)\s*.*/) {
			$module = $1;
			$address = $2;
			$type= $3;
			$symbol = $4;
			if ($DEBUG) {
				print "module: $module address: $address symbol: $symbol type: $type\n";
			}
			# add just global symbol
			if ($type eq "T" or $type eq "C") { 
				$sym_table{$symbol} = $module;
			}
		}
	}
	close(SYM_LISTING) 
		|| die "$PROGRAM: unable to close object file \"$in_script\" ($!)";
}


open(IN, $in_script) 
	|| die "$PROGRAM: unable to open input file \"$in_script\" ($!)";

open(OUT, ">$out_script") 
	|| die "$PROGRAM: unable to open output file \"$out_script\" ($!)";

while (defined($line = <IN>)) {

	if ($line =~ /\bCREATE_SEGOFF_SYMBOLS\b/) {
		foreach $sym_entry (keys (%sym_table)) {
			# FIXME JOSEF: segment = SEG(OBJECT_FILE)
			print OUT "SEG_$sym_entry =  ($sym_entry >> 4) - 0x800;\n";
			print OUT "OFF_$sym_entry =  ($sym_entry & 0x000f) | 0x8000;\n";
		}
	}elsif ($line =~ /(.*)OBJCODE_SIZE\((.*)\)(.*)/) {
		$line_head = $1;
		$obj_file = $2;
		$line_tail = $3;
		$total_size = 0;

		# Use 'size' to get total size of objectcode
		open(SIZE_LISTING, "${SIZE} ${SIZE_ARGS} ${obj_file} |") 
			|| die "$PROGRAM: unable to get size of file \"$obj_file\" ($!)";

		while (defined($line = <SIZE_LISTING>)) {
			# Look for entries
			if ($line =~ /\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\w+)\s*.*/) {
				$size_text = $1;
				$size_data = $2;
				$size_bss = $3;
				$size_dec = $4;
				$size_hex = $5;

				# Add text section size plus max. alignment of 4bytes
				if ($size_text ne 0) {
					$total_size += $size_text + 4;
				}
				if ($size_data ne 0) {
					$total_size += $size_data + 4;
				}

				if ($DEBUG) {
					print "text size: $size_text data size: $size_data "
						. "bss size: $size_bss "
						. "dec size: $size_dec hex size: $size_hex "
						. "sum: $total_size\n";
				}

			}
		}
		close(SIZE_LISTING) 
			|| die "$PROGRAM: unable to close size listing of \"$obj_file\" ($!)";


		print OUT "${line_head} ${total_size} ${line_tail}";

	} else {
		print OUT "$line";
	}
}

close(IN) 
	|| die "$PROGRAM: unable to close input file \"$in_script\" ($!)";
close(OUT) 
	|| die "$PROGRAM: unable to close output file \"$in_script\" ($!)";