GDB bit position bit-values - c
I'm trying to determine address values and sizes using ARM .elf output in GDB.
With the usual p& and print functions I can determine most of the addresses and and variable sizes, but I can't figure out if the variable is a bitValue or not.
To give an example:
typedef struct
{
bool_t start;
bool_t running :1;
bool_t objectpoolUsable :1;
bool_t ready :1;
bool_t test :1;
bool_t stop :1;
uint8_t defaultMachine;
}bitFieldTest;
bitFieldTest bitValues;
When asking GDB for the address of "bitValues.ready" or "bitValues.running" it will return the same address (since it uses the same address), but doesn't give me the bit position. Neither do I know if it really is a bitvalue or just a boolean taking the space of a uint8_t.
To clarify what I need to do: Give GDB only a single name, what might be a bitValue, and return me the right address and type. If this type is a bitValue, I need to find the bit position. For non-bitValues this works fine, bitValues are causing trouble for now.
Is GDB able to give some kind of output to solve this problem?
There's no way to get this information directly using the gdb expression API. There's no really deep reason for this -- certainly gdb knows the bit position -- but it is a consequence of the fact that gdb expressions mimic the language being debugged, plus just that nobody ever bothered to expose it. Since I've never heard of anyone wanting this before, I think it's safe to say that it is a rare request.
The information is available via gdb's Python API. In particular, if you iterate over the fields of a type, the Field object will have a bitpos member that has the bit offset of the data. Note that the offset is from the start of the enclosing struct.
It would be a relatively simple matter to write a new command in Python that prints this information.
I've solved this problem myself already.
Since I don't know how, and there doesn't seem to be a direct way to return the bit position it can be calculated by asking multiple addresses of GDB.
Using the p& command can determine the address of the variable, but not of its a bitField or the bit-position of it.
By using the print command of GDB on a struct, the location of the bitValue I need, it will return all the available values in this struct, example:
I am looking for the bitField: MachineToUi.tramlining.sensorBoutAdvance
MachineToUi will return the following:
$1 = {speedPls = {present = 0 '\000', time = 0, count = 0, noPulseCount = 0,
value = 0, calDist = 0, calPulses = 0,END DATA ALL DATA: sampleTime = 0}, output = {
trackMarkerL = 0 '\000', trackMarkerR = 0 '\000',
workingLights = 0 '\000', foldingFrame = 0 '\000',
tramlineShutoffL1 = 0 '\000', tramlineShutoffR1 = 0 '\000'}, input = {
fanPpm = 0, workswitch1 = 0 '\000', workswitch2 = 0 '\000',
speedSensor = 0 '\000', fanSensor = 0 '\000', meteringEncL = 0 '\000',
motorEncL = 0 '\000', trackMarkerL = 0 '\000', trackMarkerR = 0 '\000',
lowLvlHopperL = 0 '\000', venturiFlapL = 0 '\000',
calButtonL = 0 '\000'}, hssoOutput = HSSO_IDLE, tramlining = {
active = 0 '\000', restoreCfg = 0 '\000', updateCfg = 0 '\000',
boutAdvance = 0 '\000', boutDecrement = 0 '\000',
noTramlineIncDec = 0 '\000', displaySfks = 0 '\000',
sensorBoutAdvance = 0 '\000', bout = 0 '\000'}, tramlineLeft = 0 '\000',
tramlineRight = 0 '\000', diagOutputs = '\000' <repeats 11 times>,
markerAutoDown = 0 '\000', fanRpm = 0, fanOffTime = 0, speed = 0,
fsAlarmSensorNr = 0 '\000', fsAlarmDisconnectedSensorNr = 0 '\000',
fsAlarmType = 0 '\000', seeding = 0 '\000', actMinSpeed = 0,
actMaxSpeed = 0, lastSensorBout = 0 '\000', ctrMLeftUpFlash = 0 '\000',
ctrMRightUpFlash = 0 '\000', folding = 0 '\000', startLeftOff = 0 '\000',
startRightOff = 0 '\000', halfSideShutOff = 0 '\000',
oldMarkerPosL = 0 '\000', oldMarkerPosR = 0 '\000',
timeDateActive = 0 '\000', licVtCheck = 0 '\000', trialVtCheck = 0 '\000',
trialAlarmActive = 0 '\000', workBeep = 0 '\000', warningBeep = 0 '\000',
errorBeep = 0 '\000', runLed = 0 '\000', tcLicenseOk = 0 '\000',
WDI_start = 0 '\000', newViewSeedCalRecRead = 0 '\000',
MotorStopMarkerDelay = 0}
I'm interested in variable: sensorBoutAdvance.
By listing all the variables around sensorBoutAdvance within a range of at least 8 before the value you want to read and 1 behind the value you want to read, and make GDB return their addresses:
* calButtonL 0x2000435A
* hssoOutput 0x2000435B
* tramlining 0x2000435C
* restoreCfg 0x2000435D
* updateCfg 0x2000435E
* boutAdvance 0x2000435F (Same address! Stop search!)
* boutDecrement
* noTramlineIncDec
* displaySfks
* sensorBoutAdvance (Known address by &p = 0x2000435F)
* bout
* tramlineLeft
* tramlineRight
* diagOutputs
* markerAutoDown
* fanRpm
* fanOffTime
* speed
* fsAlarmSensorNr
* fsAlarmDisconnectedSensorNr
As soon as the same address is found, a bitField is detected. And in this case sensorBoutAdvance can be found on bit 5. If no double address is found, it might not be a bitField, but at least the bit-position won't matter. If the same Address is found right after your the variable you want to read (and not before), your bit position is on the first bit.
It sure requires some parsing, but works for me without having to add external programs or different languages.
Note: This method will only work when all bit-field are only 1-bit long.
import gdb
class Offsets(gdb.Command):
outfile = None
def __init__(self):
super (Offsets, self).__init__ ('offsets-of', gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
if len(argv) != 2:
raise gdb.GdbError('offsets-of takes exactly 2 arguments.')
self.outfile = open (argv[1], "w")
self.traverse(gdb.lookup_type(argv[0] + '_t').fields(), argv[0], 0)
self.outfile.close()
def traverse(self, branch, fqn, address):
for field in branch:
if field.type.code == gdb.TYPE_CODE_STRUCT:
self.traverse(field.type.fields(), fqn + '.' + field.name, address + field.bitpos//8)
else:
self.outfile.write (('fqn=' + fqn + '.%s offset=%d, size=%d\n' % (field.name, address + field.bitpos//8, field.type.sizeof)))
Offsets()
Related
macOS: Getting number of used inodes in volume programmatically
I'd like to get the number of used inodes for specified volume using function API rather then using the output of df shell command. I've looked at the man page of getattrlist and found the following attribute, but it may also refer to hard links, but they point to existing inodes, and I don't want to count them more than once. ATTR_VOL_FILECOUNT A u_int32_t containing the number of files on the volume. I also tried to run dtruss df and search for the exact sys call which retrieves this value, but I couldn't put my finger on it : csops(0x872, 0x7, 0x7FFEEE4C8E80) = 0 0 sysctl([CTL_KERN, 14, 1, 2162, 0, 0] (4), 0x7FFEEE4C8FC8, 0x7FFEEE4C8FC0, 0x0, 0x0) = 0 0 csops(0x872, 0x7, 0x7FFEEE4C8770) = 0 0 getfsstat64(0x0, 0x0, 0x2) = 6 0 getfsstat64(0x7FFD41001600, 0x3B48, 0x2) = 6 0 getfsstat64(0x7FFD41001600, 0x3B48, 0x1) = 6 0 getrlimit(0x1008, 0x7FFEEE4C9EC0, 0x0) = 0 0 fstat64(0x1, 0x7FFEEE4C9ED8, 0x0) = 0 0 ioctl(0x1, 0x4004667A, 0x7FFEEE4C9F24) = 0 0 Here's df output (notice the iused field) Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk1s1 976695384 757288824 211770792 79% 2000778 9223372036852775029 0% / Any ideas where can I find the source code of df or to other API for this task. thanks
I think I found the source and it does this: if (iflag) { inodes = sfsp->f_files; used = inodes - sfsp->f_ffree; (void)printf(" %*llu %*llu %4.0f%% ", mwp->iused, used, mwp->ifree, sfsp->f_ffree, inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0); where sfsp is a pointer to a struct statfs instance, from statfs() like you'd expect.
Storing values from a loop in a function in Matlab
I am writing a function in Matlab to model the length of stay in hospital of stroke patients. I am having difficulty in storing my output values. Here is my function: function [] = losdf(age, strokeType, dest) % function to mdetermine length of stay in hospitaal of stroke patients % t = time since admission (days); % age = age of patient; % strokeType = 1. Haemorhagic, 2. Cerebral Infarction, 3. TIA; % dest = 5.Death 6.Nursing Home 7. Usual Residence; alpha1 = 6.63570; beta1 = -0.03652; alpha2 = -3.06931; beta2 = 0.07153; theta0 = -8.66118; theta1 = 0.08801; mu1 = 22.10156; mu2 = 2.48820; mu3 = 1.56162; mu4 = 0; nu1 = 0; nu2 = 0; nu3 = 1.27849; nu4 = 0; rho1 = 0; rho2 = 11.76860; rho3 = 3.41989; rho4 = 63.92514; for t = 1:1:365 p = (exp(-exp(theta0 + (theta1.*age)))); if strokeType == 1 initialstatevec = [1 0 0 0 0 0 0]; elseif strokeType == 2 initialstatevec = [0 1 0 0 0 0 0]; else initialstatevec = [0 0 (1-p) p 0 0 0]; end lambda1 = exp(alpha1 + (beta1.*age)); lambda2 = exp(alpha2 + (beta2.*age)); Q = [ -(lambda1+mu1+nu1+rho1) lambda1 0 0 mu1 nu1 rho1; 0 -(lambda2+mu2+nu2+rho2) lambda2 0 mu2 nu2 rho2; 0 0 -(mu3+nu3+rho3) 0 mu3 nu3 rho3; 0 0 0 -(mu4+nu4+rho4) mu4 nu4 rho4; 0 0 0 0 0 0 0; 0 0 0 0 0 0 0; 0 0 0 0 0 0 0]; Pt = expm(t./365.*Q); Pt = Pt(strokeType, dest); Ft = sum(initialstatevec.*Pt); Ft end end Then to run my function I use: losdf(75,3,7) I want to plot my values of Ft in a graph from from 0 to 365 days. What is the best way to do this? Do I need to store the values in an array first and if so what is the best way to do this?
Many ways to do this, one straightforward way is to save each data point to a vector while in the loop and plot that vector after you exit your loop. ... Ft = zeros(365,1); % Preallocate Ft as a vector of 365 zeros for t = 1:365 ... Ft(t) = sum(initialstatevec.*Pt); % At index "t", store your output ... end plot(1:365,Ft);
In matlab, find the frequency at which unique rows appear in a matrix
In Matlab, say I have the following matrix, which represents a population of 10 individuals: pop = [0 0 0 0 0; 1 1 1 0 0; 1 1 1 1 1; 1 1 1 0 0; 0 0 0 0 0; 0 0 0 0 0; 1 0 0 0 0; 1 1 1 1 1; 0 0 0 0 0; 0 0 0 0 0]; Where rows of ones and zeros define 6 different 'types' of individuals. a = [0 0 0 0 0]; b = [1 0 0 0 0]; c = [1 1 0 0 0]; d = [1 1 1 0 0]; e = [1 1 1 1 0]; f = [1 1 1 1 1]; I want to define the proportion/frequency of a, b, c, d, e and f in pop. I want to end up with the following list: a = 0.5; b = 0.1; c = 0; d = 0.2; e = 0; f = 0.2; One way I can think of is by summing the rows, then counting the number of times each appears, and then sorting and indexing sum_pop = sum(pop')'; x = unique(sum_pop); N = numel(x); count = zeros(N,1); for l = 1:N count(l) = sum(sum_pop==x(l)); end pop_frequency = [x(:) count/10]; But this doesn't quite get me what I want (i.e. when frequency = 0) and it seems there must be a faster way?
You can use pdist2 (Statistics Toolbox) to get all frequencies: indiv = [a;b;c;d;e;f]; %// matrix with all individuals result = mean(pdist2(pop, indiv)==0, 1); This gives, in your example, result = 0.5000 0.1000 0 0.2000 0 0.2000 Equivalently, you can use bsxfun to manually compute pdist2(pop, indiv)==0, as in Divakar's answer. For the specific individuals in your example (that can be identified by the number of ones) you could also do result = histc(sum(pop, 2), 0:size(pop,2)) / size(pop,1);
There is some functionality in unique that can be used for this. If [q,w,e] = unique(pop,'rows'); q is the matrix of unique rows, w is the index of the row first appears in the matrix. The third element e contains indices of q so that pop = q(e,:). Armed with this, the rest of the problem should be straight forward. The probability of a value in e should be the probability that this row appears in pop. The counting can be done with histc histc(e,1:max(e))/length(e) and the non occuring rows can be found with ismember(a,q,'rows') There is of course other ways as well, maybe (probably) faster ways, or oneliners. Why I post this is because it provides a way that is easy to understand, readable and that does not require any special toolboxes. EDIT This example gives expected output a = [0,0,0,0,0;1,0,0,0,0;1,1,0,0,0;1,1,1,0,0;1,1,1,1,0;1,1,1,1,1]; % catenated a-f [q,w,e] = unique(pop,'rows'); prob = histc(e,1:max(e))/length(e); out = zeros(size(a,1),1); out(ismember(a,q,'rows')) = prob;
Approach #1 With bsxfun - A = cat(1,a,b,c,d,e,f) out = squeeze(sum(all(bsxfun(#eq,pop,permute(A,[3 2 1])),2),1))/size(pop,1) Output - out = 0.5000 0.1000 0 0.2000 0 0.2000 Approach #2 If those elements are binary numbers, you can convert them into decimal format. Thus, decimal format for pop becomes - >> bi2de(pop) ans = 0 7 31 7 0 0 1 31 0 0 And that of the concatenated array, A becomes - >> bi2de(A) ans = 0 1 3 7 15 31 Finally, you need to count the decimal formatted numbers from A in that of pop, which you can do with histc. Here's the code - A = cat(1,a,b,c,d,e,f) out = histc(bi2de(pop),bi2de(A))/size(pop,1) Output - out = 0.5000 0.1000 0 0.2000 0 0.2000
I think ismember is the most direct and general way to do this. If your groups were more complicated, this would be the way to go: population = [0,0,0,0,0; 1,1,1,0,0; 1,1,1,1,1; 1,1,1,0,0; 0,0,0,0,0; 0,0,0,0,0; 1,0,0,0,0; 1,1,1,1,1; 0,0,0,0,0; 0,0,0,0,0]; groups = [0,0,0,0,0; 1,0,0,0,0; 1,1,0,0,0; 1,1,1,0,0; 1,1,1,1,0; 1,1,1,1,1]; [~, whichGroup] = ismember(population, groups, 'rows'); freqOfGroup = accumarray(whichGroup, 1)/size(groups, 1); In your special case the groups can be represented by their sums, so if this generic solution is not fast enough, use the sum-histc simplification Luis used.
How can I generate this matrix (containing only 0s and ±1s)?
I would like to generate matrix of size (n(n-1)/2, n) that looks like this (n=5 in this case): -1 1 0 0 0 -1 0 1 0 0 -1 0 0 1 0 -1 0 0 0 1 0 -1 1 0 0 0 -1 0 1 0 0 -1 0 0 1 0 0 -1 1 0 0 0 -1 0 1 0 0 0 -1 1 This is what I, quickly, came up with: G = []; for i = 1:n-1; for j = i+1:n v = sparse(1,i,-1,1,n); w = sparse(1,j,1,1,n); vw = v+w; G = [G; vw]; end end G = full(G); It works, but is there a faster/cleaner way of doing it?
Use nchoosek to generate the indices of the columns that will be nonzero: n = 5; %// number of columns ind = nchoosek(1:n,2); %// ind(:,1): columns with "-1". ind(:,2): with "1". m = size(ind,1); rows = (1:m).'; %'// row indices G = zeros(m,n); G(rows + m*(ind(:,1)-1)) = -1; G(rows + m*(ind(:,2)-1)) = 1;
You have two nested loops, which leads to O(N^2) complexity of non-vectorized operations, which is too much for this task. Take a look that your matrix actually has a rectursive pattern: G(n+1) = [ -1 I(n)] [ 0 G(n)]; where I(n) is identity matrix of size n. That's how you can express this pattern in matlab: function G = mat(n) % Treat original call as G(n+1) n = n - 1; % Non-recursive branch for trivial case if n == 1 G = [-1 1]; return; end RT = eye(n); % Right-top: I(n) LT = repmat(-1, n, 1); % Left-top: -1 RB = mat(n); % Right-bottom: G(n), recursive LB = zeros(size(RB, 1), 1); % Left-bottom: 0 G = [LT RT; LB RB]; end And it gives us O(N) complexity of non-vectorized operations. It probably will waste some memory during recursion and matrix composition if Matlab is not smart enought to factor these out. If it is critical, you may unroll recursion into loop and iteratively fill up corresponding places in your original pre-allocated matrix.
Understanding condition code flag setting in assembly
If I have the following table: Case 1: x: 42 y: -15 (y-x) = -57 Case 2: x: -17 y: -17 (y-x) = 0 Case 3: x: 0x7ffffffd y: -67 (y-x) = 2147483584 Case 4: x: 67 y: -0x7fffffffd (y-x) = 2147483584 What would the condition code flags set (zero or one, per flag) for ZF SF OF and CF when considering the instruction: cmp1 %eax %ecx if %eax contains x and %ecx contains y? I understand that cmp1 ...,... is executed by: cmp1 SRC2,SRC1 which means: "sets condition codes of SRC1 – SRC2" I understand that the flags represent: OF = overflow (?) ZF = zero flag i.e. zero... CF = carry out from msb SF - sign flag i.e. negative For my four cases in the table, I believe the flags would be: 1) ZF = 0 SF = 1 CF = 0 OF = ? 2) ZF = 1 SF = 0 CF = 0 OF = ? 3) ZF = 0 SF = 0 CF = 1 OF = ? 4) ZF = 0 SF = 0 CF = 1 OF = ? Am I correct? Please explain what CF and OF are and how to determine if either will be set TRUE, and correct any of my flawed understanding. Thank you.
Carry overflow occurs when an arithmetic operation generates a carry that cannot fit into the register. So if you had 8-bit registers, and wanted to add 10000000 and 10000000 (unsigned): 10000000 10000000 -------- 100000000 This 1 is the carry from most significant bit, and thus sets CF = 1. You might also want to check this other answer.