I have been recently dealing with the internals of Address Sanitizer(ASAN) and I came to know about the code instrumentation by ASAN.
When instrumenting 1,2,4 byte accesses the instrumentation is:
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k))
ReportAndCrash(Addr);
I couldn't understand what AccessSize in line 3 does and why is it used there.
As explained in AddressSanitizerAlgorithm wiki each byte of shadow memory encodes the state of corresponding 7 bytes of user memory:
0 means that all 8 bytes are valid
k=1..7 means that k bytes are valid
(other values also mean something but we omit them for brevity)
Thus condition
if (k != 0 && ((Addr & 7) + AccessSize > k))
ReportAndCrash(Addr);
means that if less than 8 bytes are valid (k != 0) and accessed memory range does not fit into valid bytes ((Addr & 7) + AccessSize > k) the access is incorrect and should be reported.
Related
I'm trying to concatenate leading 0s to the hundreds place.
001 ones
010 tens
100 hundreds
for i = 1 to 100
let x =
if i < 10 then sprintf "Hello World 00%i" i
elif (i >= 10) && (i < 100) then sprintf "Hello World 0%i" i
Squigglies on the elif - The expression expected to have have unit but
it has string
The problem is that an if without an else must have type unit. That is, if you want your if to have a meaningful value (such as your concatenated string), it must have an else.
If you're wondering why, just ask yourself this: What would the value of x be when i is 100 or greater?
I want to apply a bitwise AND operation in 64 bits in Lua 5.1. Is there an algorithm for it? (I have no idea on how to do it.)
Note: I only need to operate on 48 bits at total, and I am not having trouble with them.
In the game's Lua I'm scripting there's the bit32 library only.
local function band48 (x, y)
local xl = x % 4294967296
local yl = y % 4294967296
local xh = (x - xl) / 4294967296
local yh = (y - yl) / 4294967296
return bit32.band(xh, yh) * 4294967296 + bit32.band(xl, yl)
end
print(band48(7 * 2^33 + 3, 5*2^33 + 5)) --> 5*2^33+1 = 42949672961
Lua is using double floating numbers internally by default. It has only 52 bits for mantissa, so you can't safely store 64-bit integers without risking to get invalid floating point values. With 32 bits it's quite safe. Lua 5.2 manuals describe what happens in bit32 lib with the numbers:
Unless otherwise stated, all functions accept numeric arguments in the
range (-2^51,+2^51); each argument is normalized to the remainder of its
division by 2^32 and truncated to an integer (in some unspecified way),
so that its final value falls in the range [0,2^32 - 1]. Similarly, all
results are in the range [0,2^32 - 1].
You'll have to work in 32-bit chunks.Or maybe introduce your own 64-bits type, probably hosted with userdata, and define 64-bit actions for that type.
So i have this question in my homework assignment that i have struggling a bit with. I looked over my lecture content/notes and have been able to utilize those to answer the questions, however, i am not 100% sure that i did everything correctly. There are two parts (part C and D) in the question that i was not able to figure out even after consulting my notes and online sources. I am not looking for a solution for those two parts by any means, but it would be greatly appreciated if i could get, at least, a nudge in the right direction in how i can go about solving it.
I know this is a rather large question, however, i hope someone could possibly check my answers and tell me if all my work and methods of looking at this problem is correct. As always, thank you for any help :)
Alright, so now that we have the formalities out of the way,
--------------------------Here is the Question:--------------------------
Suppose a small direct-mapped cache of blocks with 32 blocks is constructed. Each cache block stores
eight 32-bit words. The main memory—which is byte addressable1—is 16,384 bytes in size. 32-bit words are stored
word aligned in memory, i.e., at an address that is divisible by 4.
(a) How many 32-bit words can the memory store (in decimal)?
(b) How many address bits would be required to address each byte of memory?
(c) What is the range of memory addresses, in hex? That is, what are the addresses of the first and last bytes of
memory? I'll give you a hint: memory addresses are numbered starting at 0.
(d) What would be the address of the last word in memory?
(e) Using the cache mapping scheme discussed in the Chapter 5 lecture notes, how many and which address bits
would be used to form the block offset?
(f) How many and which memory address bits would be used to form the cache index?
(g) How many and which address bits would be used to form the tag field for each cache block?
(h) To which cache block (in decimal) would memory address 0x2A5C map to?
(i) What would be the block offset (in decimal) for 0x2A5C?
(j) How many other main memory words would map to the same block as 0x2A5C?
(k) When the word at 0x2A5C is moved into a cache block, what are the memory addresses (in hex) of the other
words which will also be moved into this block? Express your answer as a range, e.g., [0x0000, 0x0200].
(l) The first word of a main memory block that is mapped to a cache block will always be at an address that is
divisible by __ (in decimal)?
(m) Including the V and tag bits of each cache block, what would be the total size of the cache (in bytes)
(n) what would be the size allocated for the data bits (in bytes)?
----------------------My answers and work-----------------------------------
a) memory = 16384 bytes. 16384 bytes into bits = 131072 bits. 131072/32 = 4096 32-bit words
b) 2^14 (main memory) * 2^2 (4 bits/word) = 2^16. take log(base2)(2^16) = 16 bits
c) couldnt figure this part out (would appreciate some input (NOT A SOLUTION) on how i can go about looking at this problem
d)could not figure this part out either :(
e)8 words in each cache line. 8 * 4(2^2 bits/word) = 32 bits in each cache line. log(base2)(2^5) = 5 bits used for block offset.
f) # of blocks = 2^5 = 32 blocks. log(base2)(2^5) = 5 bits for cache index
g) tag = 16 - 5 - 5 - 2(word alignment) = 4 bits
h) 0x2A5C
0010 10100 10111 00
tag index offset word aligned bits
maps to cache block index = 10100 = 0x14
i) maps to block offset = 10111 = 0x17
j) 4 tag bits, 5 block offset = 2^9 other main memory words
k) it is a permutation of the block offsets. so it maps the memory addresses with the same tag and cache index bits and block offsets of 0x00 0x01 0x02 0x04 0x08 0x10 0x11 0x12 0x14 0x18 0x1C 0x1E 0x1F
l)divisible by 4
m) 2(V+tag+data) = 2(1+4+2^3*2^5) = 522 bits = 65.25 bytes
n)data bits = 2^5 blocks * 2^3 words per block = 256 bits = 32 bytes
Part C:
If a memory has M bytes, and the memory is byte addressable, the the memory addresses range from 0 to M - 1.
For your question, this means that memory addresses range from 0 to 16383, or in hex 0x0 to 0x3FFF.
Part D:
Words are 4 bytes long. So given your answer to C, the last word is at:
(0x3FFFF - 3) -> 0x3FFC.
You can see that this is correct because the lowest 2 bits of the address are 0, which must be true of any 4 byte aligned address.
i want to konw this data struct will use how much memory in Erlang VM?
[{"3GPP-UTRAN-FDD", [{"utran-cell-id-3gpp","CID1000"}, "1996-12-19t16%3a39%3a57-08%3a00", "1996-12-19t15%3a39%3a27%2e20-08%3a00"]}]
In my application, every process will store this data in self's loop data, and the numbert of this proces will be 120000.
The result which i test:
don't store this data, the memory will be:
memory[kB]: proc 1922806, atom 2138, bin 24890, code 72757, ets 459321
store this data, the momory will be:
memory[kB]: proc 1684032, atom 2138, bin 24102, code 72757, ets 459080
So the big difference is the memoery used by proc: (1922806 - 1684032) / 1024 = 233M.
After research, i find an insterting thing:
L = [{"3GPP-UTRAN-FDD", [{"utran-cell-id-3gpp","CID1000"}, "1996-12-19t16%3a39%3a57-08%3a00", "1996-12-19t15%3a39%3a27%2e20-08%3a00"]}].
B = list_to_binary(io_lib:format("~p", L)).
erts_debug:size(B). % The output is 6
The memory just use 6 words after using binary? How to explain this?
There are two useful functions for measuring the size of an Erlang term: erts_debug:size/1 and erts_debug:flat_size/1. Both of these functions return the size of the term in words.
erts_debug:flat_size/1 gives you the total size of a message without term-sharing optimization. This is guaranteed to be the size of the term if it is copied to a new heap, as with message passing and ets tables.
erts_debug:size/1 gives you the size of the term as it is in the current process' heap, allowing for memory usage optimization by sharing repeated terms.
Here is a demonstration of the differences:
1> MyTerm = {atom, <<"binary">>, 1}.
{atom,<<"binary">>,1}
2> MyList = [ MyTerm || _ <- lists:seq(1, 100) ].
[{atom,<<"binary">>,1}|...]
3> erts_debug:size(MyList).
210
4> erts_debug:flat_size(MyList).
1200
As you can see, there is a significant difference in the sizes due to term sharing.
As for your specific term, I used the Erlang shell (R16B03) and measured the term with flat_size. According to this, the memory usage of your term is: 226 words (1808B, 1.77KB).
This is a lot of memory to use for what appears to be a simple term, but that is outside of the scope of this question.
the size of the whole binary is 135 bytes when you do it list_to_binary(io_lib:format("~p", L))., if you are on a 64 bit system it represents 4.375 words so 6 words should be the correct size, but you have lost the direct access to the internal structure.
Strange but can be understood:
19> erts_debug:flat_size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,1000)])).
6
20> erts_debug:flat_size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).
6
21> size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).
10000
22> (list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).
<<"myeyrltgyfnytajecrgtonkdcxlnaoqcsswdnepnmdxfrwnnlbzdaxknqarfyiwewlugrtgjgklblpdkvgpecglxmfrertdfanzukfolpphqvkkwrpmb"...>>
23> erts_debug:display({list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])}).
{<<10000 bytes>>}
"{<<10000 bytes>>}\n"
24>
This means that the erts_debug:flat_size return the size of the variable (which is roughly a type information, a pointer to the data and its size), but not the size of the binary data itself. The binary data is stored elsewhere and can be shared by different variables.
Formula which I wanna solve looks like this in C:
#define foo(w,x,y) ((((w)*(x)*(y)+31) & ~31) / 8)
WORD w,x,y,z;
y = 24;
if( (foo(w,x,y) * z) == -1 )
printf("yeah!");
I rewrite it to z3py in the following way:
from z3 import *
w= BitVec('w',16)
x= BitVec('x',16)
z= BitVec('z',16)
y= BitVecVal(24,16)
solve( (UDiv( (w*x*y+31) & ~31, 8 )) * z == 0xffffffff)
Any suggestions ?
PS: Please notice that trying to solve formula in that form:
solve( (UDiv( (w*x*y+31), 8 )) * z == 0xffffffff)
is possible, so I can't belive that bit-wise operation causes this formula Unsatisfiable.
I don't see anything wrong in Z3 behavior. Why do you think the formula should be satisfiable?
A = (w*x*y+31) & ~31 -- imply that the 5 rightmost bits will be always zero
B = UDiv( A & ~31, 8 ) (equal to a logical shift right by 3) -- imply that the 2 rightmost bits will be always zero.
C = B * z -- this will always have the 2 rightmost bits zero
c == 0xffffffff -- that's impossible
If you change the constant to 0xfffffffc, then you'll get a solution.
The C program doesn't print anything for me. And Z3 says "no solution". So, it's consistent.
Does your C program prints "yeah!"? If so, aren't you on a big-endian machine? I've tried your example in an x86 machine.