⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tos-ramsize

📁 tinyos-2.x.rar
💻
📖 第 1 页 / 共 3 页
字号:

    ($match, $reg1, my $sublo) = match_2args ($addr+$inc, "subi");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $reg1, my $subhi) = match_2args ($addr+$inc, "sbci");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "movw");
    if ($match) {
	$inc += 2;
    }

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "add");
    return (0, \@targets, 0) if (!$match);    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "adc");
    return (0, \@targets, 0) if (!$match);    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "lpm");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r0" || $reg2 ne "Z+");    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "lpm");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r31" || $reg2 ne "Z");    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "mov");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r30" || $reg2 ne "r0");    
    $inc += 2;

    if (match_0args ($addr+$inc, "ijmp")) {
	$inc += 2;
	push @targets, $oob_target;
	if ($verbosity > 3) {
	    printf "found a jump table of size %d\n", hex($table_size);
	}
	for (my $i=0; $i<hex($table_size); $i++) {
	    my $index = 2*($i+65536-make16($sublo,$subhi));
	    my $l = $raw_text{$index};
	    my $h = $raw_text{$index+1};
	    my $targ = 2*make16($l,$h);
	    
	    if ($verbosity > 3) {
		printf "  entry at %x pointing to %x (%s,%s)\n", $index, $targ, $l, $h;
	    }
	    
	    # this is a strong sanity check-- if we've got something
	    # wrong it's highly unlikely that all jump table entries
	    # will point to actual instructions
	    die "tos-ramsize FAIL" if (!defined($insns{$targ}));

	    push @targets, $targ;
	}
	return (1, \@targets, $inc);
    } else {
	return (0, \@targets, 0);
    }
}

# cpi	r30, 0x1D	; 29
# cpc	r31, r1
# brcs	.+4      	; 0x39d2 <SchedulerBasicP__TaskBasic__runTask+0x38>
# jmp	0x547c	; 0x547c <SchedulerBasicP__TaskBasic__runTask+0x1ae2>
# subi	r30, 0xBA	; 186
# sbci	r31, 0xFF	; 255
# add	r30, r30
# adc	r31, r31
# lpm	r0, Z+
# lpm	r31, Z
# mov	r30, r0
# ijmp

sub match_jump_table_2 ($) {
    (my $addr) = @_;
    my $match;
    my $reg1;
    my $reg2;
    my $immed;
    my $oob_target;
    my @targets;
    my $inc = 0;

    ($match, $reg1, my $table_size) = match_2args ($addr+$inc, "cpi");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;
    
    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "cpc");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $immed) = match_branch ($addr+$inc, "brcs");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $oob_target) = match_branch ($addr+$inc, "jmp");
    return (0, \@targets, 0) if (!$match);
    $inc += 4;

    ($match, $reg1, my $sublo) = match_2args ($addr+$inc, "subi");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $reg1, my $subhi) = match_2args ($addr+$inc, "sbci");
    return (0, \@targets, 0) if (!$match);
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "movw");
    if ($match) {
	$inc += 2;
    }

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "add");
    return (0, \@targets, 0) if (!$match);    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "adc");
    return (0, \@targets, 0) if (!$match);    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "lpm");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r0" || $reg2 ne "Z+");    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "lpm");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r31" || $reg2 ne "Z");    
    $inc += 2;

    ($match, $reg1, $reg2) = match_2args ($addr+$inc, "mov");
    return (0, \@targets, 0) if (!$match || $reg1 ne "r30" || $reg2 ne "r0");    
    $inc += 2;

    if (match_0args ($addr+$inc, "ijmp")) {
	$inc += 2;
	push @targets, $oob_target;
	if ($verbosity > 3) {
	    printf "found a jump table of size %d\n", hex($table_size);
	}
	for (my $i=0; $i<hex($table_size); $i++) {
	    my $index = 2*($i+65536-make16($sublo,$subhi));
	    my $l = $raw_text{$index};
	    my $h = $raw_text{$index+1};
	    my $targ = 2*make16($l,$h);
	    
	    if ($verbosity > 3) {
		printf "  entry at %x pointing to %x (%s,%s)\n", $index, $targ, $l, $h;
	    }
	    
	    # this is a strong sanity check-- if we've got something
	    # wrong it's highly unlikely that all jump table entries
	    # will point to actual instructions
	    die "tos-ramsize FAIL" if (!defined($insns{$targ}));

	    push @targets, $targ;
	}
	return (1, \@targets, $inc);
    } else {
	return (0, \@targets, 0);
    }
}

# in	r28, 0x3d	; 61 
# in	r29, 0x3e	; 62
# subi	r28, 0x9D	; 157
# sbci	r29, 0x00	; 0
# in	r0, 0x3f	; 63
# cli
# out	0x3e, r29	; 62
# out	0x3f, r0	; 63
# out	0x3d, r28	; 61

# in	r28, 0x3d	; 61
# in	r29, 0x3e	; 62
# sbiw	r28, 0x14	; 20
# in	r0, 0x3f	; 63
# cli
# out	0x3e, r29	; 62
# out	0x3f, r0	; 63
# out	0x3d, r28	; 61

sub match_constant_push_1 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $dec;
    my $inc = 0;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc +=2;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc +=2;

    ($match, $reg, $dec) = match_2args ($addr+$inc, "sbiw");
    if ($match && $reg eq "r28") {
	$dec = hex($dec);
	$inc +=2;
    } else {
	($match, $reg, my $dec1) = match_2args ($addr+$inc, "subi");
	return (0, 0) if (!$match || $reg ne "r28");
	$inc +=2;

	($match, $reg, my $dec2) = match_2args ($addr+$inc, "sbci");
	return (0, 0) if (!$match || $reg ne "r29");	
	$inc +=2;

	$dec = make16($dec1,$dec2);
    }

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc +=2;

    return (0, 0) if (!match_0args($addr+$inc, "cli"));
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc +=2;

    return (1, $dec, $inc);
}

# in	r28, 0x3d	; 61
# in	r29, 0x3e	; 62
# sbiw	r28, 0x05	; 5
# out	0x3e, r29	; 62
# out	0x3d, r28	; 61

sub match_constant_push_2 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $dec;
    my $inc = 0;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc +=2;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc +=2;

    ($match, $reg, $dec) = match_2args ($addr+$inc, "sbiw");
    return (0, 0) if (!$match || $reg ne "r28");
    $inc +=2;
    $dec = hex($dec);

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc +=2;

    return (1, $dec, $inc);
}

# rcall	.+0      	; 0x2792 <IPP__icmpv6_input+0x1e>

sub match_constant_push_3 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $dec;
    my $inc = 0;

    ($match, $reg, $immed) = match_0args ($addr+$inc, "rcall");
    return (0, 0) if (!$match);
    return (0, 0) if (get_target($addr) != $addr+$PC_SIZE{$platform});
    $inc +=2;

    return (1, $PC_SIZE{$platform}, $inc);
}

# adiw	r28, 0x14	; 20
# in	r0, 0x3f	; 63
# cli
# out	0x3e, r29	; 62
# out	0x3f, r0	; 63
# out	0x3d, r28	; 61

sub match_constant_pop_1 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $dec;
    my $inc = 0;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "adiw");
    return (0, 0, 0) if (!$match || $reg ne "r28");
    $dec = -hex($immed);
    $inc += 2;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc += 2;

    return (0, 0, 0) if (!match_0args($addr+$inc, "cli"));
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc += 2;

    return (1, $dec, $inc);
}

# adiw	r28, 0x05	; 5
# out	0x3e, r29	; 62
# out	0x3d, r28	; 61

sub match_constant_pop_2 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $dec;
    my $inc = 0;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "adiw");
    return (0, 0, 0) if (!$match || $reg ne "r28");
    $dec = -hex($immed);
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc += 2;

    return (1, $dec, $inc);
}

# in	r28, 0x3d	; 61
# in	r29, 0x3e	; 62
# subi	r28, 0x9E	; 158
# sbci	r29, 0xFF	; 255
# in	r0, 0x3f	; 63
# cli
# out	0x3e, r29	; 62
# out	0x3f, r0	; 63
# out	0x3d, r28	; 61

sub match_constant_stack_op ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $inc = 0;

    ($match, $reg, my $dec_lo) = match_2args ($addr+$inc, "subi");
    return (0, 0, 0) if (!$match || $reg ne "r28");
    $inc += 2;

    ($match, $reg, my $dec_hi) = match_2args ($addr+$inc, "sbci");
    return (0, 0, 0) if (!$match || $reg ne "r29");
    $inc += 2;
    my $dec = make16($dec_lo,$dec_hi);
    if ($dec > 32768) {
	$dec = - (65536 - $dec);
    }

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc += 2;

    return (0, 0, 0) if (!match_0args($addr+$inc, "cli"));
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r29" || $immed ne "0x3e");
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc += 2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0, 0) if (!$match || $reg ne "r28" || $immed ne "0x3d");
    $inc += 2;

    return (1, $dec, $inc);
}

# in	r24, 0x3d	; 61
# in	r25, 0x3e	; 62
# adiw	r24, 0x06	; 6
# in	r0, 0x3f	; 63
# cli
# out	0x3e, r25	; 62
# out	0x3f, r0	; 63
# out	0x3d, r24	; 61

sub match_constant_pop_4 ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    my $stack_inc;
    my $inc = 0;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r24" || $immed ne "0x3d");
    $inc +=2;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r25" || $immed ne "0x3e");
    $inc +=2;

    ($match, $reg, $stack_inc) = match_2args ($addr+$inc, "adiw");
    return (0, 0) if (!$match || $reg ne "r24");
    $stack_inc = -hex($stack_inc);
    $inc +=2;

    ($match, $reg, $immed) = match_2args ($addr+$inc, "in");
    return (0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc +=2;

    return (0, 0) if (!match_0args($addr+$inc, "cli"));
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r25" || $immed ne "0x3e");
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r0" || $immed ne "0x3f");
    $inc +=2;

    ($match, $immed, $reg) = match_2args ($addr+$inc, "out");
    return (0, 0) if (!$match || $reg ne "r24" || $immed ne "0x3d");
    $inc +=2;

    return (1, $stack_inc, $inc);
}

# ldi	r26, 0x00	; 0
# ldi	r27, 0x00	; 0
# ldi	r30, 0x97	; 151
# ldi	r31, 0x06	; 6
# jmp	0x19dc	; 0x19dc <__prologue_saves__+0x4>

sub match_prologue_saves ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $immed;
    ($match, $reg, my $im_lo) = match_2args ($addr, "ldi");
    return (0, 0, 0) if (!$match || $reg ne "r26");
    ($match, $reg, my $im_hi) = match_2args ($addr+2, "ldi");
    return (0, 0, 0) if (!$match || $reg ne "r27");
    ($match, $reg, $immed) = match_2args ($addr+4, "ldi");
    return (0, 0, 0) if (!$match || $reg ne "r30");
    ($match, $reg, $immed) = match_2args ($addr+6, "ldi");
    return (0, 0, 0) if (!$match || $reg ne "r31");
    ($match, my $target) = match_branch ($addr+8, "jmp");
    return (0, 0, 0) if (!$match);
    my $ps = $label_to_addr{"__prologue_saves__"};
    if (defined($ps) &&
	$target >= $ps &&
	$target <= ($ps+38)) {
	# this is a little conservative since we may jump into the middle
	my $st = 18+make16($im_lo, $im_hi);
	return (1, $st, 12);
    }
    return (0, 0, 0);
}

# jmp	0x2598	; 0x2598 <__epilogue_restores__+0x14>

sub match_epilogue_restores ($) {
    (my $addr) = @_;
    my $hex_addr = sprintf "%x", $addr;
    my $match;
    my $reg;
    my $inc = 0;

    ($match, my $target) = match_branch ($addr+$inc, "jmp");
    return (0,0) if (!$match);
    my $er = $label_to_addr{"__epilogue_restores__"};
    if (defined($er) &&
	$target >= $er &&
	$target <= ($er+38)) {
	$addr += 4;
	return (1, $ZERO_STACK, $inc);
    } else {
	return (0,0);
    }
}

sub replace_insn ($$$$) {
    (my $addr, my $size, my $se, my $name) = @_;
    $insns{$addr} = $name;
    $insn_size{$addr} = $size;
    $stack_effect{$addr} = $se;
    for (my $i=1; $i<$size; $i++) {
	delete ($insns{$addr+$i});
    }
}

sub make_macro_insns () {
    foreach my $addr (keys %insns) {

	my $res;
	my $stack;
	my $listref;
	my $size;

	# todo-- factor this into list of function 

	($res, $size, my $initial_depth) = match_init_sp($addr);
	if ($res) {
	    if (defined($initial_stack_depth)) {
		# FIXME: avr-gcc-412 initializes SP both in
		# crt0 and in main(), we can believe the second one
		#die "tos-ramsize FAIL: multiple initialization of SP?";
	    }
	    die "tos-ramsize FAIL" if ($initial_depth < 0 || $initial_depth >= $RAM_SIZE{$platform});
	    $initial_stack_depth = $initial_depth;
	    replace_insn ($addr, $size, 0, "init_sp");
	}

	($res, $listref, $size) = match_jump_table_1($addr);
	if ($res) {
	    replace_insn ($addr, $size, 0, "jump_table");
	    $jump_lists{$addr} = $listref;
	}	

	($res, $listref, $size) = match_jump_table_2($addr);
	if ($res) {
	    replace_insn ($addr, $size, 0, "jump_table");
	    $jump_lists{$addr} = $listref;
	}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -