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\" ($!)";
|