Skip to content

Commit 75e48d8

Browse files
authored
Parse elf file to find out string table (#598)
Parse .o file is not the best approach as some string can get optimized out in link stage. LTO .o file even doesn't contain a string table. * Move rodata into a separate section to make parsing easier. * Support both flooder and elf file.
1 parent aa32d71 commit 75e48d8

4 files changed

Lines changed: 86 additions & 52 deletions

File tree

src/Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ endif
287287
%.fs_wrapper: $(LAST_MODEL)
288288
true
289289

290-
.PHONY: $(PRE_FS) $(LAST_MODEL)
290+
.PHONY: $(PRE_FS) $(LAST_MODEL) $(TARGET).elf
291291
$(LAST_MODEL): model_template.ini tx_template.ini $(FONTS) $(PRE_FS)
292292
@echo " + Copying template files for $(FILESYSTEM)"
293293
mkdir -p filesystem/$(FILESYSTEM) || true
@@ -301,15 +301,19 @@ $(LAST_MODEL): model_template.ini tx_template.ini $(FONTS) $(PRE_FS)
301301
cp model_template.ini filesystem/$(FILESYSTEM)/models/default.ini
302302
ifdef LANGUAGE
303303
mkdir filesystem/$(FILESYSTEM)/language 2> /dev/null; \
304-
../utils/extract_strings.pl -fs $(FILESYSTEM) -targets $(LANGUAGE) -update -objdir $(ODIR)
304+
../utils/extract_strings.pl -fs $(FILESYSTEM) -targets $(LANGUAGE) -update -elffile $(TARGET).elf
305305
endif
306306
export tx=$(FILESYSTEM); \
307307
number=2 ; while [ $$number -le $(NUM_MODELS) ] ; do \
308308
cp model_template.ini filesystem/$$tx/models/model$$number.ini; \
309309
number=`expr $$number + 1`; \
310310
done
311311
@echo " + Checking string list length for $(FILESYSTEM)"
312-
../utils/check_string_size.pl -target $(FILESYSTEM) -objdir $(ODIR) -quiet
312+
ifeq "$(TYPE)" "dev"
313+
../utils/check_string_size.pl -target $(FILESYSTEM) -elffile $(TARGET).elf
314+
else
315+
../utils/check_string_size.pl -target $(FILESYSTEM) -elffile $(TARGET).elf -quiet
316+
endif
313317

314318
######################
315319
#Necessary Font files#

src/target/common/devo/devo.ld

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ SECTIONS
3434
*(.vectors) /* Vector table */
3535
INCLUDE optimize.ld
3636
. = _crc_offset;
37-
KEEP(*(.crc))
37+
KEEP(*(.crc))
3838
*(.text*) /* Program code */
39+
} >rom
40+
.rodata :{
3941
. = ALIGN(4);
4042
*(.rodata*) /* Read-only data */
41-
. = ALIGN(4);
4243
} >rom
43-
4444
/* C++ Static constructors/destructors, also used for __attribute__
4545
* ((constructor)) and the likes */
4646
.preinit_array : {

utils/check_string_size.pl

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
my $target;
99
my $quiet;
1010
my $objdir;
11+
my $elffile;
1112
my $log = "";
12-
GetOptions("target=s" => \$target, "quiet" => \$quiet, "objdir=s" => \$objdir);
13+
GetOptions("target=s" => \$target, "quiet" => \$quiet, "objdir=s" => \$objdir, "elffile=s" => \$elffile);
1314

1415
my @dirs = grep {$_ !~ /common/ && (! $target || $_ =~ /$target/)} glob("filesystem/*");
1516
my $max_line_length = 0;
@@ -33,29 +34,45 @@
3334
my $bytes = 0;
3435
my $count = 0;
3536
my $line_length = 0;
36-
for (my $idx = 0; $idx < $#lines; $idx++) {
37-
if($lines[$idx] =~ /^:/) {
38-
my $hashval = fnv(substr($lines[$idx], 1));
39-
if($hash{$hashval}) {
40-
print "Found hash collision between:\n $hash{$hashval}\n " . substr($lines[$idx], 1) . "\n";
41-
$error = 1;
37+
if ($lines[0] =~ /^:/) {
38+
# language v1 format
39+
for (my $idx = 0; $idx < $#lines; $idx++) {
40+
if($lines[$idx] =~ /^:/) {
41+
my $hashval = fnv(substr($lines[$idx], 1));
42+
if($hash{$hashval}) {
43+
print "Found hash collision between:\n $hash{$hashval}\n " . substr($lines[$idx], 1) . "\n";
44+
$error = 1;
45+
}
46+
#printf "%6d: %s\n", $hashval, substr($lines[$idx], 1);
47+
$hash{$hashval} ||= substr($lines[$idx], 1);
48+
my $len = length($lines[$idx+1]) + 1; #Count the NULL too
49+
$bytes += $len;
50+
$line_length = $len if($len > $line_length);
51+
$count++;
52+
$idx++;
4253
}
43-
#printf "%6d: %s\n", $hashval, substr($lines[$idx], 1);
44-
$hash{$hashval} ||= substr($lines[$idx], 1);
45-
my $len = length($lines[$idx+1]) + 1; #Count the NULL too
54+
}
55+
}
56+
else {
57+
# language V2 format
58+
for (my $idx = 0; $idx < $#lines; $idx++) {
59+
my $len = length($lines[$idx]) - 1;
4660
$bytes += $len;
47-
$line_length = $len if($len > $line_length);
61+
$line_length = $len if ($len > $line_length);
4862
$count++;
49-
$idx++;
5063
}
5164
}
65+
5266
$log .= sprintf("%-35s: %5d lines, %5d bytes, %4d bytes/line\n", $file, $count, $bytes, $line_length);
5367
$target_bytes = $bytes if($bytes > $target_bytes);
5468
$target_count = $count if($count > $target_count);
5569
$target_line_length = $line_length if($line_length > $target_line_length);
5670
}
5771
my $cmd = "../utils/extract_strings.pl -target $target";
5872
$cmd .= " -objdir $objdir" if($objdir);
73+
$cmd .= " -elffile $elffile" if($elffile);
74+
print $cmd;
75+
print "\n";
5976
my @lines = `$cmd`;
6077
my $count = scalar(@lines);
6178
$log .= sprintf("%-35s: %5d lines\n", $target, $count);

utils/extract_strings.pl

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
my $fs;
1010
my $target_list;
1111
my $objdir;
12+
my $elffile;
1213
my $count;
1314
# The following are legal alternatives to the default string
1415
my @targets = ("devo8", "devo10", "devo12");
@@ -30,7 +31,9 @@ sub fnv_16 {
3031
}
3132

3233
$ENV{CROSS} ||= "";
33-
GetOptions("update" => \$update, "language=s" => \$lang, "fs=s" => \$fs, "targets=s" => \$target_list, "count" => \$count, "objdir=s" => \$objdir);
34+
GetOptions("update" => \$update, "language=s" => \$lang, "fs=s" => \$fs,
35+
"targets=s" => \$target_list, "count" => \$count,
36+
"objdir=s" => \$objdir, "elffile=s" => \$elffile);
3437
my @requested_targets = ();
3538
@requested_targets = split(/,/, $target_list) if($target_list);
3639
if($fs || @requested_targets) {
@@ -92,41 +95,49 @@ sub fnv_16 {
9295
#}
9396
#build string list
9497
my @out;
98+
@files = ();
9599
#Filter out any strings that do not appear in any obj files
96-
if($objdir) {
100+
if ($objdir) {
101+
print $objdir;
102+
push @files, glob("$objdir/*.o");
103+
}
104+
105+
if ($elffile) {
106+
print "add $elffile";
107+
push @files, $elffile;
108+
}
109+
110+
foreach my $file (@files) {
97111
my %allstr;
98-
my @files = glob("$objdir/*.o");
99-
foreach my $file (@files) {
100-
#Parse all strings from the object files and add to the allstr hash
101-
my @od = `$ENV{CROSS}objdump -s $file`;
102-
my $str = "";
103-
my $state = 0;
104-
foreach(@od) {
105-
my $orig = $_;
106-
if(/section \.ro?data/) {
107-
$str = "";
108-
$state = 1;
109-
next;
110-
} elsif(/^Contents/ && ! /\.ro?data/) {
111-
$str = "";
112-
$state = 0;
113-
} elsif($state) {
114-
#Strip off everything but hex data
115-
s/^\s+\S+\s//;
116-
s/\s\s.*//;
117-
s/ //g;
118-
while(/(\S\S)/g) {
119-
#Iterate over each ascii character
120-
if($1 eq "00") {
121-
#NULL termination
122-
if($str) {
123-
$str =~ s/\n/\\n/g; #Convert <CR> to \n
124-
$allstr{$str} = 1;
125-
$str = "";
126-
}
127-
} else {
128-
$str .= chr(hex($1));
112+
#Parse all strings from the object files and add to the allstr hash
113+
my @od = `$ENV{CROSS}objdump -s $file`;
114+
my $str = "";
115+
my $state = 0;
116+
foreach(@od) {
117+
my $orig = $_;
118+
if(/section \.ro?data/) {
119+
$str = "";
120+
$state = 1;
121+
next;
122+
} elsif(/^Contents/ && ! /\.ro?data/) {
123+
$str = "";
124+
$state = 0;
125+
} elsif($state) {
126+
#Strip off everything but hex data
127+
s/^\s+\S+\s//;
128+
s/\s\s.*//;
129+
s/ //g;
130+
while(/(\S\S)/g) {
131+
#Iterate over each ascii character
132+
if($1 eq "00") {
133+
#NULL termination
134+
if($str) {
135+
$str =~ s/\n/\\n/g; #Convert <CR> to \n
136+
$allstr{$str} = 1;
137+
$str = "";
129138
}
139+
} else {
140+
$str .= chr(hex($1));
130141
}
131142
}
132143
}
@@ -138,7 +149,9 @@ sub fnv_16 {
138149
#print STDERR "Ignoring unused string '$_'\n";
139150
}
140151
}
141-
} else {
152+
}
153+
154+
if (!$objdir && !$elffile) {
142155
@out = values(%filemap);
143156
}
144157
#append template names

0 commit comments

Comments
 (0)