What are ‘I Space’ and ‘D Space’ on osx and the difference between them - ios

In sys/ptrace.h, i saw something like:
#define PT_READ_I 1 /* read world in child's I space*/
#define PT_READ_D 2 /* read world in child's D space*/
#define PT_READ_U 3 /* read world in child's user structure*/
What are ‘I Space’ and ‘D Space’ and 'user structure'?

Quoting the man page:
Traditionally, ptrace() has
allowed for machines with distinct address spaces for
instruction and data, which is why there are two requests:
conceptually, PT_READ_I reads from the instruction space
and PT_READ_D reads from the data space. In the current
NetBSD implementation, these two requests are completely
identical.
Now about PT_READ_U:
This space contains the registers and other information about the
process; its layout corresponds to the user structure in the system.

Related

Why are printed memory addresses in Rust a mix of both 40-bit and 48-bit addresses?

I'm trying to understand the way Rust deals with memory and I've a little program that prints some memory addresses:
fn main() {
let a = &&&5;
let x = 1;
println!(" {:p}", &x);
println!(" {:p} \n {:p} \n {:p} \n {:p}", &&&a, &&a, &a, a);
}
This prints the following (varies for different runs):
0x235d0ff61c
0x235d0ff710
0x235d0ff728
0x235d0ff610
0x7ff793f4c310
This is actually a mix of both 40-bit and 48-bit addresses. Why this mix? Also, can somebody please tell me why the addresses (2, 3, 4) do not fall in locations separated by 8-bytes (since std::mem::size_of_val(&a) gives 8)? I'm running Windows 10 on an AMD x-64 processor (Phenom || X4) with 24GB RAM.
All the addresses do have the same size, Rust is just not printing trailing 0-digits.
The actual memory layout is an implementation detail of your OS, but the reason that a prints a location in a different memory area than all the other variables is, that a actually lives in your loaded binary, because it is a value that can already be calculated by the compiler. All the other variables are calculated at runtime and live on the stack.
See the compilation result on https://godbolt.org/z/kzSrDr:
.L__unnamed_4 contains the value 5; .L__unnamed_5, .L__unnamed_6 and .L__unnamed_1 are &5 &&5 and &&&5.
So .L__unnamed_1 is what on your system is at 0x7ff793f4c310. While 0x235d0ff??? is on your stack and calculated in the red and blue areas of the code.
This is actually a mix of both 40-bit and 48-bit addresses. Why this mix?
It's not really a mix, Rust just doesn't display leading zeroes. It's really about where the OS maps the various components of the program (data, bss, heap and stack) in the address space.
Also, can somebody please tell me why the addresses (2, 3, 4) do not fall in locations separated by 8-bytes (since std::mem::size_of_val(&a) gives 8)?
Because println! is a macro which expands to a bunch of stuff in the stackframe, so your values are not defined next to one another in the frame final code (https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5b812bf11e51461285f51f95dd79236b). Though even if they were there'd be no guarantee the compiler wouldn't e.g. be reusing now-dead memory to save up on frame size.

Why is "no code allowed to be all ones" in libjpeg's Huffman decoding?

I'm trying to satisfy myself that METEOSAT images I'm getting from their FTP server are actually valid images. My doubt arises because all the tools I've used so far complain about "Bogus Huffman table definition" - yet when I simply comment out that error message, the image appears quite plausible (a greyscale segment of the Earth's disc).
From https://github.com/libjpeg-turbo/libjpeg-turbo/blob/jpeg-8d/jdhuff.c#L379:
while (huffsize[p]) {
while (((int) huffsize[p]) == si) {
huffcode[p++] = code;
code++;
}
/* code is now 1 more than the last code used for codelength si; but
* it must still fit in si bits, since no code is allowed to be all ones.
*/
if (((INT32) code) >= (((INT32) 1) << si))
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
code <<= 1;
si++;
}
If I simply comment out the check, or add a check for huffsize[p] to be nonzero (as in the containing loop's controlling expression), then djpeg manages to convert the image to a BMP which I can view with few problems.
Why does the comment claim that all-ones codes are not allowed?
It claims that because they are not allowed. That doesn't mean that there can't be images out there that don't comply with the standard.
The reason they are not allowed is this (from the standard):
Making entropy-coded segments an integer number of bytes is performed
as follows: for Huffman coding, 1-bits are used, if necessary, to pad
the end of the compressed data to complete the final byte of a
segment.
If the all 1's code was allowed, then you could end up with an ambiguity in the last byte of compressed data where the padded 1's could be another coded symbol.

How to calculate RPG Level Progression as percentage

I'm designing an RPG game where a user may accumulate experience points (XP) and level up, based on XP. Calculating the current level is trivial; if else seems to be most efficent.
I would like to calculate percent of progression for the current level. Based on the assumption that I have 10 levels, where each level is capped at a somewhat exponential value:
typedef NS_ENUM(NSInteger, RPGLevelCap) {
RPGLevelCap1=499,
RPGLevelCap2=1249,
RPGLevelCap3=2249,
RPGLevelCap4=3499,
RPGLevelCap5=4999,
RPGLevelCap6=6999,
RPGLevelCap7=9999,
RPGLevelCap8=14999,
RPGLevelCap9=19999,
RPGLevelCap10=19999 // Anything beyond previous level is Lvl 10; display as 100%
};
What's an efficient, yet easily understandable way, to calculate a user's level progression based on their current level?
An if else statement is both hard to understand and maintain, but may be fairly efficient:
float levelProgression=0;
// Calculate level progression as a fraction of 1
if(xp <= RPGLevelCap1)
{
levelProgression = ((float)xp / RPGLevelCap1);
}
else if (xp <=RPGLevelCap2)
{
levelProgression = ((float)(xp-RPGLevelCap1) / (RPGLevelCap2-RPGLevelCap1));
}
else if (xp <=RPGLevelCap3)
{
levelProgression = ((float)(xp-RPGLevelCap2) / (RPGLevelCap3-RPGLevelCap2));
}
...
else if (xp>RPGLevelCap10)
{
levelProgression = 1;
}
Given that the level caps are inconsistent...how should I handle this problem?
Hmm. A simple way would be to store the level cap values in an array. Find the player's current level based on the largest value it's less than. (level one is 0 to 499, level two is 500 to 1249, etc.) Use a loop to find the user's level rather than a set of if/else statements.
Then calculate the range of the player's current level, (end_of_range - start_of_range)
0 - 499 = 499
500 - 1249 = 749,
etc.
If a player is at 600 points, he's a level 2 character, in the 500-1249 range.
He's at 600-500 or 100 points into the range. (600-500)/749*100 is the player's percent complete in that range. 13.35% complete, in this example.
There are a few ways you can approach this. My weapon of choice here is to embody the XP values within the concept of LevelData versus using an enum, array of XP values, etc. The benefit of something like this is that for each level, you'll typically have many configurable values (for example level based multipliers) based on level. This way they are all in once place.
In your LevelData, there are different ways you can encode XP. These range from the XP total for the next level, or the beginning and end XP total for the next level. Obviously there are other permutations of this.
I usually use the later, mainly because it prevents me from having to "know" the LevelData for the previous level.
So I would typically have this in JSON
{
"levelData": [
{
"levelStartXP": "0",
"levelUpXP": "250",
"levelUpBonus": 0
},
{
"levelStartXP": "250",
"levelUpXP": "1000",
"levelUpBonus": 50
},
{
"levelStartXP": "1000",
"levelUpXP": "2500",
"levelUpBonus": 100
},
]
}
This is just a boring example. I then of course have a LevelData class which is embodies each level. I also have a LevelDataManager. That manager is used to vend out information per level. Having convenience methods help. For examples, good ones to have are:
- (NSInteger)levelWithXP:(NSInteger)xp; // for a given XP, give me the appropriate level
- (LevelData *)levelDataWithXP:(NSInteger)xp; //for a given XP, give me the appropriate LevelData
- (LevelData *)levelDataWithLevel:(NSInteger)level; // for a given level, give me the appropriate LevelData
- (NSInteger)levelUpXPForLevel:(NSInteger)level; // for a given level, give me the XP value needed for the next level)
I just arbitrarily used NSInteger, use the appropriate data type for your case.
Just what you want to support is really up to you.
The gist of the whole thing is try not to store individual level components. Rather aggregate them in LevelData or some other collection, so you have all the info per level at your disposal and create some form of manager/interface to get you the information you need.
So back to you your question. Let's say we have a class for LevelData (assume it is using the JSON above, and those fields are represented by properties) and a LevelDataManager instance called theLevelDataMgr, you could compute the % based on something like:
LevelData *levelData = [theLevelDataMgr levelDataWithLevel:currLevel]; // currLevel is the current level
float xpDiffInLevel = levelData.levelUpXP - levelStartXP;
float xpInLevel = currXP - levelStartXP; // currXP is the current XP of the user
float pctOfXP = xpInLevel / xpDiffInLevel; // You should add divide by zero check
And yes, if you wanted, you could have the LevelData class contain a method to do this calculation for you to help encapsulate it even better.
Code isn't tested and is listed to just give you a better idea on how to do it. Also, how you decide to store your XP for each level dictates how this would work. This code is based on the method I usually use.

Using Non-zero indexed Memory in Quartus (Verilog)

I am writing a memory system for a basic 16-bit educational CPU and am running into issues with Quartus Synthesis of my module. Specifically, I have broken down the address space into a few different parts and one of them (which is a ROM) is not synthesizing properly. (NOTE: I am synthesizing for a DE2-115 Altera board, QuartusII 12.1, SystermVerilog code)
So, in order to make the memory-mapped VRAM (a memory module that is dual-ported to allow VGA output while the CPU writes colors) more usable, I included a small ROM in the address space that includes code (assembled functions) that allow you to write characters into memory, ie a print_char function. This ROM is located in memory at a specific address, so in order to simplify the SV, I implemented the ROM (and all the memory modules) like so:
module printROM
(input rd_cond_code_t re_L,
input wr_cond_code_t we_L,
input logic [15:0] memAddr,
input logic clock,
input logic reset_L,
inout wire [15:0] memBus,
output mem_status_t memStatus);
reg [15:0] rom[`VROM_ADDR_LO:`VROM_ADDR_HI];
reg [15:0] dataOut;
/* The ROM */
always #(posedge clock) begin
if (re_L == MEM_RD) begin
dataOut <= rom[memAddr];
end
end
/* Load the rom data */
initial $readmemh("printROM.hex", rom);
/* Drive the line */
tridrive #(.WIDTH(16)) romOut(.data(dataOut),
.bus(memBus),
.en_L(re_L));
/* Manage asserting completion of a read or a write */
always_ff #(posedge clock, negedge reset_L) begin
if (~reset_L) begin
memStatus <= MEM_NOT_DONE;
end
else begin
if ((we_L == MEM_WR) | (re_L == MEM_RD)) begin
memStatus <= MEM_DONE;
end
else begin
memStatus <= MEM_NOT_DONE;
end
end
end
endmodule // printROM
Where VROM_ADDR_LO and VROM_ADDR_HI are two macros defining the addresses of this ROM, namely 'hEB00 and 'hEFFF. Thus, when an address in that range is read/written to by the CPU, this module is able to properly index into the rom memory. This technique works fine in VCS simulation.
However, when I go to synthesize this module, Quartus correctly implies a ROM but has issues initializing it. I get this error:
Error (113012): Address at line 11 exceeds the specified depth (1280) in the Memory Initialization File "psx18240.ram0_printROM_38938673.hdl.mif"
It looks like Quartus is converting the .hex file I give as the ROM code (ie printROM.hex) and using the CPU visible addresses (ie starting at 'hEB00) for the generated .mif file even though the size of rom is obviously too small. Does Quartus not support this syntax or am I doing something wrong?
It would appear that Quartus does not like what you're doing. Probably better would be if you only want a rom with 1280 entries, then you should just create one from 0:1279, and address it using that range (this is what your logic would have to synthesize into anyway).
reg [15:0] rom[0:`VROM_ADDR_HI-`VROM_ADDR_LO];
assign romAddr = (memAddr - `VROM_ADDR_LO);
always #(posedge clock) begin
if (re_L == MEM_RD) begin
dataOut <= rom[romAddr];
end
end
Go for ROM Megafunctions in mega wizard plugin manager in quartus. Its is a GUI based ipcore generater. There you can paramterize all the options even including the hex file. But you have to follow Intel hex file format. This also available in file->new.
For hdl based instantiation
http://quartushelp.altera.com/12.1/mergedProjects/hdl/mega/mega_file_lpm_rom.htm
User guide.
https://www.google.co.in/url?sa=t&source=web&rct=j&ei=nVAGVKvSDcu9ugTMooCQDQ&url=http://www.altera.com/literature/ug/ug_ram_rom.pdf&cd=1&ved=0CBsQFjAA&usg=AFQjCNE2ZXM1gIsMZ5BvkKTHanX1E7vamg

Can I get a list of all currently-registered atoms?

My project has blown through the max 1M atoms, we've cranked up the limit, but I need to apply some sanity to the code that people are submitting with regard to list_to_atom and its friends. I'd like to start by getting a list of all the registered atoms so I can see where the largest offenders are. Is there any way to do this. I'll have to be creative about how I do it so I don't end up trying to dump 1-2M lines in a live console.
You can get hold of all atoms by using an undocumented feature of the external term format.
TL;DR: Paste the following line into the Erlang shell of your running node. Read on for explanation and a non-terse version of the code.
(fun F(N)->try binary_to_term(<<131,75,N:24>>) of A->[A]++F(N+1) catch error:badarg->[]end end)(0).
Elixir version by Ivar Vong:
for i <- 0..:erlang.system_info(:atom_count)-1, do: :erlang.binary_to_term(<<131,75,i::24>>)
An Erlang term encoded in the external term format starts with the byte 131, then a byte identifying the type, and then the actual data. I found that EEP-43 mentions all the possible types, including ATOM_INTERNAL_REF3 with type byte 75, which isn't mentioned in the official documentation of the external term format.
For ATOM_INTERNAL_REF3, the data is an index into the atom table, encoded as a 24-bit integer. We can easily create such a binary: <<131,75,N:24>>
For example, in my Erlang VM, false seems to be the zeroth atom in the atom table:
> binary_to_term(<<131,75,0:24>>).
false
There's no simple way to find the number of atoms currently in the atom table*, but we can keep increasing the number until we get a badarg error.
So this little module gives you a list of all atoms:
-module(all_atoms).
-export([all_atoms/0]).
atom_by_number(N) ->
binary_to_term(<<131,75,N:24>>).
all_atoms() ->
atoms_starting_at(0).
atoms_starting_at(N) ->
try atom_by_number(N) of
Atom ->
[Atom] ++ atoms_starting_at(N + 1)
catch
error:badarg ->
[]
end.
The output looks like:
> all_atoms:all_atoms().
[false,true,'_',nonode#nohost,'$end_of_table','','fun',
infinity,timeout,normal,call,return,throw,error,exit,
undefined,nocatch,undefined_function,undefined_lambda,
'DOWN','UP','EXIT',aborted,abs_path,absoluteURI,ac,accessor,
active,all|...]
> length(v(-1)).
9821
* In Erlang/OTP 20.0, you can call erlang:system_info(atom_count):
> length(all_atoms:all_atoms()) == erlang:system_info(atom_count).
true
I'm not sure if there's a way to do it on a live system, but if you can run it in a test environment you should be able to get a list via crash dump. The atom table is near the end of the crash dump format. You can create a crash dump via erlang:halt/1, but that will bring down the whole runtime system.
I dare say that if you use more than 1M atoms, then you are doing something wrong. Atoms are intended to be static as soon as the application runs or at least upper bounded by some small number, 3000 or so for a medium sized application.
Be very careful when an enemy can generate atoms in your vm. especially calls like list_to_atom/1 is somewhat dangerous.
EDITED (wrong answer..)
You can adjust number of atoms with +t
http://www.erlang.org/doc/efficiency_guide/advanced.html
..but I know very few use cases when it is necessary.
You can track atom stats with erlang:memory()

Resources