Modify value at given address with linker script - linker

I have a symbol that points to some value:
$ nm t3 | grep AAA
000000000040a140 D AAA
I want to modify the value at address [AAA] (the value at address 0x40a140) using linker script. But I do no not see how to evaluate expressions with memory dereference. Are there any ways to do this with linker script?

Related

Understanding the use of local command in Randomization Check

I am trying to run a do-file for an RCT. The authors are using the local command.
They create a local macro taking the value 1. Based on that, they are creating missing values for the var variable. However, after that, I cannot understand why they are adding 1 to it. Moreover, why are the numvar and numvarse being used for mean and sd?
Any explanation would be really helpful.
The code:
*RANDOMIZATION CHECK
local numvar=1
foreach var in T1_Client_Age T1_Client_Married T1_HH_Size T1_Client_Literate T1_Client_Education T1_muslim ///
T1_Hindu_SC_Kat T1_rest3 T1_Log_HH_Income T1_Household_Business ///
T1_Client_Wage_Salaried_2 T1_Client_Bus_PR_Employed_2 T1_Client_Housewife_2 {
replace `var'=. if miss_`var'==1
local numvarse = `numvar' + 1
replace varname="`var'" in `numvar'
*MEAN AND SD FOR CONTROL
quietly: sum `var' if Treated_All==0
replace Control=r(mean) in `numvar'
replace Control=r(sd) in `numvarse'
*MEAN AND SD FOR TREATED
quietly:sum `var' if Treated_All==1
replace Treat=r(mean) in `numvar'
replace Treat=r(sd) in `numvarse'
*MEAN AND SD FOR TREATED WITH FRIEND
quietly:sum `var' if Treatment_Peer==1
replace Treat_Peer=r(mean) in `numvar'
replace Treat_Peer=r(sd) in `numvarse'
*MEAN DIFFERENCES BETWEEN TREATED AND CONTROL
xi:reg `var' Treated_All i.sewa_center*i.baseline i.t_month , cluster(t_group)
replace Diff_Control_Treat=_b[Treated_All] in `numvar'
replace Diff_Control_Treat=_se[Treated_All] in `numvarse'
*MEAN DIFFERENCES BETWEEN TREATED ALONE AND WITH FRIEND
xi:reg `var' Treated_All Treatment_Peer i.sewa_center*i.baseline i.t_month , cluster(t_group)
replace Diff_Alone_Peer=_b[Treatment_Peer] in `numvar'
replace Diff_Alone_Peer=_se[Treatment_Peer] in `numvarse'
local numvar = `numvarse' + 1
}
The principle can be understood by looking at just a few commands.
local numvar=1
foreach var in ... {
replace `var'=. if miss_`var'==1
local numvarse = `numvar' + 1
replace varname="`var'" in `numvar'
*MEAN AND SD FOR CONTROL
quietly: sum `var' if Treated_All==0
replace Control=r(mean) in `numvar'
replace Control=r(sd) in `numvarse'
*MEAN AND SD FOR TREATED
quietly:sum `var' if Treated_All==1
replace Treat=r(mean) in `numvar'
replace Treat=r(sd) in `numvarse'
*MEAN AND SD FOR TREATED WITH FRIEND
quietly:sum `var' if Treatment_Peer==1
replace Treat_Peer=r(mean) in `numvar'
replace Treat_Peer=r(sd) in `numvarse'
local numvar = `numvarse' + 1
}
numvar is initialised to 1. Within the loop, numvarse is set to 1 more than numvar.
The code then puts results for each of a series of variables in observations numvar and numvarse, including the name of the variable AND its mean and SD for various groups.
The key is to focus on
replace ... in ...
where the in qualifier specifies replace only in that observation.
Towards the end of the loop numvar is bumped yet again.
In short, results for the first variable named go in observations 1 and 2; for the second variable named go in observations 3 and 4; and so on.
Minimally, this process depends on
There being enough observations for this to be possible. I count 13 variables, so there must be at least 26 observations in the dataset, which seems overwhelmingly likely.
There being an understanding that the variables being written to are not aligned with any other variables.
Some might find #2 and even #1 poor ways of working. They would want results to be written to a new dataset or to a new frame.
The code is not state of the art: using xi with xtreg has been outdated practice since Stata 11 (2009), but still works for many purposes.
(Detail: The code overwrites values in variable X with missing if separately there is a variable miss_X indicating that variable X is missing. I don't think any remote observers can explain that.)

How to slice a variable into array indexes?

There is this typical problem: given a list of values, check if they are present in an array.
In awk, the trick val in array does work pretty well. Hence, the typical idea is to store all the data in an array and then keep doing the check. For example, this will print all lines in which the first column value is present in the array:
awk 'BEGIN {<<initialize the array>>} $1 in array_var' file
However, it is initializing the array takes some time because val in array checks if the index val is in array, and what we normally have stored in array is a set of values.
This becomes more relevant when providing values from command line, where those are the elements that we want to include as indexes of an array. For example, in this basic example (based on a recent answer of mine, which triggered my curiosity):
$ cat file
hello 23
bye 45
adieu 99
$ awk -v values="hello adieu" 'BEGIN {split(values,v); for (i in v) names[v[i]]} $1 in names' file
hello 23
adieu 99
split(values,v) slices the variable values into an array v[1]="hello"; v[2]="adieu"
for (i in v) names[v[i]] initializes another array names[] with names["hello"] and names["adieu"] with empty value. This way, we are ready for
$1 in names that checks if the first column is any of the indexes in names[].
As you see, we slice into a temp variable v to later on initialize the final and useful variable names[].
Is there any faster way to initialize the indexes of an array instead of setting one up and then using its values as indexes of the definitive?
No, that is the fastest (due to hash lookup) and most robust (due to string comparison) way to do what you want.
This:
BEGIN{split(values,v); for (i in v) names[v[i]]}
happens once on startup and will take close to no time while this:
$1 in array_var
which happens once for every line of input (and so is the place that needs to have optimal performance) is a hash lookup and so the fastest way to compare a string value to a set of strings.
not an array solution but one trick is to use pattern matching. To eliminate partial matches wrap the search and array values with the delimiter. For your example,
$ awk -v values="hello adieu" 'FS values FS ~ FS $1 FS' file
hello 23
adieu 99

How do I initialize an array of arrays in BCPL?

I tried let stringArr = newvec(12); and then attempted to initialize each spot in the array as such: let stringArr!i = newvec(5); but that returns an error telling me I cannot do that. Is there anyone here who can help me with this dinosaur language?
You're stretching my memory a bit (to the extent of about three decades) but I seem to recall that let was used only for creating new local variables (also functions and possibly other things, but that's not really relevant for your question).
So the statement let stringArr = newvec(12) is valid in creating the new variable stringArr or, more precisely, a 12-cell anonymous vector and the stringArr variable holding the address of that vector.
However, let stringArr!i = newvec(5) is not valid, because stringArr!i isn't actually a new variable. It's simply the memory contents of cell number i in the already-existing stringArr vector.
In other words, the statement let stringArr = newvec(12) creates both the initial pointer cell and the second layer of pointers, which won't point anywhere useful yet:
+-----------+
| stringArr | ---+
+-----------+ | +-------------+
+--> | stringArr!0 | --> ?
+-------------+
| stringArr!1 | --> ?
+-------------+
: : :
+-------------+
| stringArr!N | --> ?
+-------------+
And, since the pointers already exist, you shouldn't be using let to set them.
It's similar in C in that you wouldn't write:
int xyzzy[10]; // Make array of ten elements.
int xyzzy[0] = 42; // Set first element to something.
since the second line isn't supposed to be defining a new variable, rather it's intent is simply to set one of the existing elements to a given value, done with xyzzy[0] = 42.
Hence the right way to do what you're trying to achieve in BCPL is to avoid using the let keyword for that second class of statements:
let stringArr = newvec(12) // Create new vector AND new variable,
// put vector address into cell for
// that variable.
stringArr!i := newvec(5) // Create new vector, put vector
// address into EXISTING cell.
The solution is sound but both of my versions of BCPL (Martin Richard's and Robert Nordier's obcpl) complain about newvec() and also require := rather than = in the second line. I got it working with:
let stringArr = getvec(12)
stringArr!i := getvec(12)
John Boutland

Shell Script, sh only - no bash - Trying to add associative value with integer - "expr: non-numeric argument"

Hi I'm trying to add two values together, one which is an input from a file and another is a previous stored value in an associative array.
example of associative array:
moo -> 56
boo -> 34
foo -> 57
moo -> 45
I have all the code to detect wither the associative array value previously exists, but when I attempt to add them to the current value of the same key I receive an "expr: non-numeric argument" error.
This is the line I am using to add the two values:
c=`expr $i + eval $a$b`
sh does not have associative arrays. If you have implemented your own, you have to specify how you did that.
Let's say you did it through a prefix and key, e.g. arr_moo=56:
i=4
arr_moo=56
a=arr_
b=moo
and given i, a and b you want to add the values of i and arr_moo, you can use:
c=$((i + $a$b))
echo "$c"
which will print 60.

Was this feature made available in a recent Fortran Standard?

I was unpleasantly surprised to find that a code I work with would not run when built with gcc v. 4.4.6 because of array size mismatches. It worked fine when built with gcc v. 4.7.3. I created a minimal working example to show the root of the problem:
program main
implicit none
integer, allocatable, dimension(:,:) :: array_a
integer, allocatable, dimension(:,:) :: array_b
allocate(array_a(5,2))
allocate(array_b(2,1))
array_a = 1
array_b = array_a
print *, array_a
print *, array_b
end program main
When built with gcc v. 4.4.6, it crashes during runtime with error:
At line 13 of file main.f90 Fortran runtime error: Array bound
mismatch, size mismatch for dimension 1 of array 'array_b' (1/4)
When build with gcc v. 4.7.3, it produces the following output:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
Note, it automatically resized 'array_b' to match the size of 'array_a'. Is this a 'feature' that is offered by a newer Fortran standard that I'm seeing?
You are using a Fortran 2003 feature - automatic array reallocation on assignment. It was not yet implemented in gcc-4.4.
This feature means that the array b, which was allocated to a nonconforming shape before is automatically reallocated to the shape of the right hand side of the assignment. You have to use recent compiler versions (not only GCC), for Fortran 2003 features.
As Vladimir says, it's a feature of Fortran 2003. If you look at Section 7.4.1.3 of the 2003 working document you'll see,
If variable is an allocated allocatable variable, it is deallocated if expr is an array of different shape or any of the corresponding length type parameter values of variable and expr differ. If variable is or becomes an unallocated allocatable variable, then it is allocated with each deferred type parameter equal to the corresponding type parameters of expr, with the shape of expr, and with each lower bound equal to the corresponding element of LBOUND(expr).
Note 7.36 shows that if you want array_b to keep its shape, you need to declare the line as
array_b(1:2,1) = array_a(3:4,2)
of whatever elements of array_a you want.

Resources