about summary refs log blame commit diff stats
path: root/linux/dash.html
blob: a9aebee725fcfdcfbda48f73e151b98861b4629b (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                              
                                  




                                              
                            









                                                                   


                                                          



                                                                                            
<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset='utf-8'>
        <title>2.5.1. Dash</title>
    </head>
    <body>

        <a href="index.html">Core OS Index</a>

        <h1>2.5.1. Dash</h1>


        <p>By default dash installed as /bin/sh, if not relink;</p>

        <pre>
        # ln -sfT dash /bin/sh
        </pre>


        <a href="index.html">Core OS Index</a>
        <p>This is part of the Tribu System Documentation.
        Copyright (C) 2020
        Tribu Team.
        See the file <a href="../fdl-1.3-standalone.html">Gnu Free Documentation License</a>
        for copying conditions.</p>
    </body>
</html>
span> ^
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

                                                                                              









                                                         



                                    








                                        
                             
                                     

                            
                                       

                                    
       
                                                
                                                              

                                                

                                                                  




                                                                                     
                                                                                                    
                                                     
                                                                                                                    

                                  







                                                                                                              




                                                                                                     
     
   
 













































































                                                                                   
//:: Check that the different operands of an instruction aren't too large for their bitfields.

void test_check_bitfield_sizes() {
  Hide_errors = true;
  run(
      "== 0x1\n"  // code segment
      "01/add 4/mod 3/rm32 1/r32\n"  // add ECX to EBX
  );
  CHECK_TRACE_CONTENTS(
      "error: '4/mod' too large to fit in bitfield mod\n"
  );
}

:(before "End Globals")
map<string, uint32_t> Operand_bound;
:(before "End One-time Setup")
put_new(Operand_bound, "subop", 1<<3);
put_new(Operand_bound, "mod", 1<<2);
put_new(Operand_bound, "rm32", 1<<3);
put_new(Operand_bound, "base", 1<<3);
put_new(Operand_bound, "index", 1<<3);
put_new(Operand_bound, "scale", 1<<2);
put_new(Operand_bound, "r32", 1<<3);
put_new(Operand_bound, "disp8", 1<<8);
put_new(Operand_bound, "disp16", 1<<16);
// no bound needed for disp32
put_new(Operand_bound, "imm8", 1<<8);
// no bound needed for imm32

:(before "Pack Operands(segment code)")
check_operand_bounds(code);
if (trace_contains_errors()) return;
:(code)
void check_operand_bounds(const segment& code) {
  trace(3, "transform") << "-- check operand bounds" << end();
  for (int i = 0;  i < SIZE(code.lines);  ++i) {
    const line& inst = code.lines.at(i);
    for (int j = first_operand(inst);  j < SIZE(inst.words);  ++j)
      check_operand_bounds(inst.words.at(j));
    if (trace_contains_errors()) return;  // stop at the first mal-formed instruction
  }
}

void check_operand_bounds(const word& w) {
  for (map<string, uint32_t>::iterator p = Operand_bound.begin();  p != Operand_bound.end();  ++p) {
    if (!has_operand_metadata(w, p->first)) continue;
    if (!looks_like_hex_int(w.data)) continue;  // later transforms are on their own to do their own bounds checking
    int32_t x = parse_int(w.data);
    if (x >= 0) {
      if (p->first == "disp8" || p->first == "disp16") {
        if (static_cast<uint32_t>(x) >= p->second/2)
          raise << "'" << w.original << "' too large to fit in signed bitfield " << p->first << '\n' << end();
      }
      else {
        if (static_cast<uint32_t>(x) >= p->second)
          raise << "'" << w.original << "' too large to fit in bitfield " << p->first << '\n' << end();
      }
    }
    else {
      // hacky? assuming bound is a power of 2
      if (x < -1*static_cast<int32_t>(p->second/2))
        raise << "'" << w.original << "' too large to fit in bitfield " << p->first << '\n' << end();
    }
  }
}

void test_check_bitfield_sizes_for_imm8() {
  run(
      "== 0x1\n"  // code segment
      "c1/shift 4/subop/left 3/mod/direct 1/rm32/ECX 0xff/imm8"  // shift EBX left
  );
  CHECK(!trace_contains_errors());
}

void test_check_bitfield_sizes_for_imm8_error() {
  Hide_errors = true;
  run(
      "== 0x1\n"  // code segment
      "c1/shift 4/subop/left 3/mod/direct 1/rm32/ECX 0x100/imm8"  // shift EBX left
  );
  CHECK_TRACE_CONTENTS(
      "error: '0x100/imm8' too large to fit in bitfield imm8\n"
  );
}

void test_check_bitfield_sizes_for_negative_imm8() {
  run(
      "== 0x1\n"  // code segment
      "c1/shift 4/subop/left 3/mod/direct 1/rm32/ECX -0x80/imm8"  // shift EBX left
  );
  CHECK(!trace_contains_errors());
}

void test_check_bitfield_sizes_for_negative_imm8_error() {
  Hide_errors = true;
  run(
      "== 0x1\n"  // code segment
      "c1/shift 4/subop/left 3/mod/direct 1/rm32/ECX -0x81/imm8"  // shift EBX left
  );
  CHECK_TRACE_CONTENTS(
      "error: '-0x81/imm8' too large to fit in bitfield imm8\n"
  );
}

void test_check_bitfield_sizes_for_disp8() {
  // not bothering to run
  transform(
      "== 0x1\n"  // code segment
      "01/add 1/mod/*+disp8 3/rm32 1/r32 0x7f/disp8\n"  // add ECX to *(EBX+0x7f)
  );
  CHECK(!trace_contains_errors());
}

void test_check_bitfield_sizes_for_disp8_error() {
  Hide_errors = true;
  run(
      "== 0x1\n"  // code segment
      "01/add 1/mod/*+disp8 3/rm32 1/r32 0x80/disp8\n"  // add ECX to *(EBX+0x80)
  );
  CHECK_TRACE_CONTENTS(
      "error: '0x80/disp8' too large to fit in signed bitfield disp8\n"
  );
}

void test_check_bitfield_sizes_for_negative_disp8() {
  // not bothering to run
  transform(
      "== 0x1\n"  // code segment
      "01/add 1/mod/*+disp8 3/rm32 1/r32 -0x80/disp8\n"  // add ECX to *(EBX-0x80)
  );
  CHECK(!trace_contains_errors());
}

void test_check_bitfield_sizes_for_negative_disp8_error() {
  Hide_errors = true;
  run(
      "== 0x1\n"  // code segment
      "01/add 1/mod/*+disp8 3/rm32 1/r32 -0x81/disp8\n"  // add ECX to *(EBX-0x81)
  );
  CHECK_TRACE_CONTENTS(
      "error: '-0x81/disp8' too large to fit in bitfield disp8\n"
  );
}