This shouldn't be that hard that one may think, if I got it right. Specifically, I'll begin with iOS and the ELF executable format. Let's clarify that I have a jailbroken iPhone and I don't want to do this in any appstore apps, so pleas avoid "good advices" like "you can't do it as it's prohibited by Apple".
So, what I have seen is that there's a Flash player implementation, called Frash (by Comex btw, developer of recent jailbreaks). This utility requires, after installation, that Android's libflashplayer.so is present (copied to) the iPhone file system. I digged into the source code and found out that the tweak actually opens the Android (ELF) shared object file, "parses" it and executes code from it. I already asked a friend of mine wheter it is or is not actually possible and he told me that it is, because ELF on ARM and Mach-O on ARM are binary compatible (because they're both ARM). But he actually failed to explain it to me in detail, so I'd like to ask how can it be done? I can't exactly understand the source code fragment that handles, but one thing is sure:
int fd = open("libflashplayer.so", O_RDONLY);
_assert(fd > 0);
fds_init();
sandbox_me();
int symtab_size;
Elf32_Sym *symtab;
void **init_array;
Elf32_Word init_array_size;
char *strtab;
TIME(base_load_elf(fd, &symtab, &symtab_size, &init_array, &init_array_size, &strtab));
// Call the init funcs
_assert(init_array);
while(init_array_size >= 4) {
void (*x)() = *init_array++;
notice("Calling %p", x);
x();
init_array_size -= 4;
}
(from the original code, as of 02/12/2011 on GitHub)
It seems to me that he uses libelf to perform this, right? And that in an ELF file there are symbols that can be executed on a compatible processor just fine?
I'd also like to know whether it is true for all other processor architectures? So maybe one can execute symbols from Linux binaries on OS X?
The important thing about compatibility is the underlying processor architecture, not Linux vs. OS X vs. Android. If the ELF or .so are compiled for the same processor instruction set, then this can work. If not, then they are not compatible. For example, if both were built for Linux but different processors, they would not be compatible.
Related
I am trying out this MCU / SoC emulator, Renode.
I loaded their existing model template under platforms/cpus/stm32l072.repl, which just includes the repl file for stm32l071 and adds one little thing.
When I then load & run a program binary built with STM32CubeIDE and ST's LL library, and the code hits the initial function of SystemClock_Config(), where the Flash:ACR register is being probed in a loop, to observe an expected change in value, it gets stuck there, as the Renode Monitor window is outputting:
[WARNING] sysbus: Read from an unimplemented register Flash:ACR (0x40022000), returning a value from SVD: 0x0
This seems to be expected, not all existing templates model nearly everything out of the box. I also found that the stm32L071 model is missing some of the USARTs and NVIC channels. I saw how, probably, the latter might be added, but there seems to be not a single among the default models defining that Flash:ACR register that I could use as example.
How would one add such a missing register for this particular MCU model?
Note1: For this test, I'm using a STM32 firmware binary which works as intended on actual hardware, e.g. a devboard for this MCU.
Note2:
The stated advantage of Renode over QEMU, which does apparently not emulate peripherals, is also allowing to stick together a more complex system, out of mocked external e.g. I2C and other devices (apparently C# modules, not yet looked into it).
They say "use the same binary as on the real system".
Which is my reason for trying this out - sounds like a lot of potential for implementing systems where the hardware is not yet fully available, and also automatted testing.
So the obvious thing, commenting out a lot of parts in init code, to only test some hardware-independent code while sidestepping such issues, would defeat the purpose here.
If you want to just provide the ACR register for the flash to pass your init, use a tag.
You can either provide it via REPL (recommended, like here https://github.com/renode/renode/blob/master/platforms/cpus/stm32l071.repl#L175) or via RESC.
Assuming that your software would like to read value 0xDEADBEEF. In the repl you'd use:
sysbus:
init:
Tag <0x40022000, 0x40022003> "ACR" 0xDEADBEEF
In the resc or in the Monitor it would be just:
sysbus Tag <0x40022000, 0x40022003> "ACR" 0xDEADBEEF
If you want more complex logic, you can use a Python peripheral, as described in the docs (https://renode.readthedocs.io/en/latest/basic/using-python.html#python-peripherals-in-a-platform-description):
flash: Python.PythonPeripheral # sysbus 0x40022000
size: 0x1000
initable: false
filename: "script_with_complex_python_logic.py"
```
If you really need advanced implementation, then you need to create a complete C# model.
As you correctly mentioned, we do not want you to modify your binary. But we're ok with mocking some parts we're not interested in for a particular use case if the software passes with these mocks.
Disclaimer: I'm one of the Renode developers.
I am currently trying to self learn Arduino/C programming/Assembly. I am working on a project which requires a lot of data collection, and by research I discovered a chip called the "23K256" from Microchip (see here: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en539039). Moreover, I have also discovered that an Arduino library taking advantage of this chip exists (see here: http://playground.arduino.cc/Main/SpiRAM). I downloaded the "spiRAM3a.zip" file, which I believe is the one most up-to-date. Note that I have only recently downloaded the Arduino software and thus have the latest version installed (I believe it's 1.0.6). Also note that I'm using Arduino Uno, although I will eventually need to use Arduino Mega (I just want this working on ANYTHING at this point). With this library is some code that exemplifies its use to read and write to the 23K256 (the file name is "SpiRAM_Example" included in the package I downloaded), effectively increasing the SRAM on Arduino available. Here is the actual, exact code:
#include <SPI.h>
#include <SpiRAM.h>
#define SS_PIN 10
byte clock = 0;
SpiRAM SpiRam(0, SS_PIN);
void setup() {
Serial.begin(9600);
}
void loop()
{
char data_to_chip[17] = "Testing 90123456";
char data_from_chip[17] = " ";
int i = 0;
// Write some data to RAM
SpiRam.write_stream(0, data_to_chip, 16);
delay(100);
// Read it back to a different buffer
SpiRam.read_stream(0, data_from_chip, 16);
// Write it to the serial port
for (i = 0; i < 16; i++) {
Serial.print(data_from_chip[i]);
}
Serial.print("\n");
delay(1000); // wait for a second
}
My problem is that when I complie the code, to test my confguration and try to learn its use, I surprisingly get an error. This is what I get:
SpiRAM_Example:7: error: 'SpiRAM' does not name a type
SpiRAM_Example.ino: In function 'void loop()':
SpiRAM_Example:20: 'SpiRAM' was not declared in this scope
So it's basically telling me that there's something wrong with the SpiRAM SpiRam(0, SS_PIN);line of code. My question is, why? Am I misunderstanding something very fundamental about how classes work? I feel like I must not be doing something because I highly doubt an incorrect piece of code would be published on Arduino's website. How can I get this code to compile, or at least be able to simply use this library? Should I post the code for the library itself ("SpiRAM.h"), which was included in the package I downloaded?
I would really appreciate any help I can get, and sincerely apologize if this is a really dumb question. I think this is the first I've worked with classes.
Did you download Attach:spiRAM3a.zip or the original? I installed this and your code. It complies on the IDE 1.05
Since a couple of days, I constantly receive the same error while using MATLAB which happens at some point with dlopen. I am pretty new to MATLAB, and that is why I don't know what to do. Google doesn't seem to be helping me either. When I try to make an eigenvector, I get this:
Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS
I also get this while making a multiplication:
Error using *
BLAS loading error:
dlopen: cannot load any more object with static TLS
I did of course look for the solutions to this problem, but I don't understand too much and don't know what to do. These are threads I found:
How do I use the BLAS library provided by MATLAB?
http://www.mathworks.de/de/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html
Can someone help me please?
Examples of function calls demonstrating this error
>> randn(3,3)
ans =
2.7694 0.7254 -0.2050
-1.3499 -0.0631 -0.1241
3.0349 0.7147 1.4897
>> eig(ans)
Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS
That's bug no 961964 of MATLAB known since R2012b (8.0). MATLAB dynamically loads some libs with static TLS (thread local storage, e.g. see gcc compiler flag -ftls-model). Loading too many such libs => no space left.
Until now mathwork's only workaround is to load the important(!) libs first by using them early (they suggest to put "ones(10)*ones(10);" in startup.m). I better don't comment on this "solution strategy".
Since R2013b (8.2.0.701) with Linux x86_64 my experience is: Don't use "doc" (the graphical help system)! I think this doc-utility (libxul, etc.) is using a lot of static TLS memory.
Here is an update (2013/12/31)
All the following tests were done with Fedora 20 (with glibc-2.18-11.fc20) and Matlab 8.3.0.73043 (R2014a Prerelease).
For more information on TLS, see
Ulrich Drepper, ELF handling For Thread-Local Storage, Version 0.21, 2013,
currently available at Akkadia and Redhat.
What happens exactly?
MATLAB dynamically (with dlopen) loads several libraries that need tls initialization. All those libs need a slot in the dtv (dynamic thread vector). Because MATLAB loads several of these libs dynamically at runtime at compile/link time the linker (at mathworks) had no chance to count the slots needed (that's the important part). Now it's the task of the dynamic lib loader to handle such a case at runtime. But this is not easy. To cite dl-open.c:
For static TLS we have to allocate the memory here and
now. This includes allocating memory in the DTV. But we
cannot change any DTV other than our own. So, if we
cannot guarantee that there is room in the DTV we don't
even try it and fail the load.
There is a compile time constant (called DTV_SURPLUS, see glibc-source/sysdeps/generic/ldsodefs.h) in the glibc's dynamic lib loader for reserving a number of additional slots for such a mess (dynamically loading libs with static TLS in a multithreading program). In the glibc-Version of Fedora 20 this value is 14.
Here are the first libs (running MATLAB) that needed dtv slots in my case:
matlabroot/bin/glnxa64/libut.so
/lib64/libstdc++.so.6
/lib64/libpthread.so.0
matlabroot/bin/glnxa64/libunwind.so.8
/lib64/libuuid.so.1
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/server/libjvm.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libfontmanager.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libt2k.so
matlabroot/bin/glnxa64/mkl.so
matlabroot/sys/os/glnxa64/libiomp5.so
/lib64/libasound.so.2
matlabroot/sys/jxbrowser/glnxa64/xulrunner/xulrunner-linux-64/libxul.so
/lib64/libselinux.so.1
/lib64/libpixman-1.so.0
/lib64/libEGL.so.1
/lib64/libGL.so.1
/lib64/libglapi.so.0
Yes more than 14 => too many => no slot left in the dtv. That's what the error message tries to tell us and especially mathworks.
For the record: In order not to violate MATLAB's license I didn't debug, decompile or disassemble any part of the binaries shipped with MATLAB. I only debugged the free and open glibc-binaries of Fedora 20 that MATLAB were using to dynamically load the libs.
What can be done, to solve this problem?
There are 3 options:
(a)
Rebuild MATLAB and do not dynamically load those libs
(with initial-exec tls model) instead link against them (then the linker
can count the required slots!)
(b)
Rebuild those libs and ensure they are NOT using the initial-exec tls model.
(c)
Rebuild glibc and increase DTV_SURPLUS in
glibc/sysdeps/generic/ldsodefs.h
Obviously options (a) and (b) can only be done by mathworks.
For option (c) no source of MATLAB is needed and thus can be done without mathworks.
What is the status at mathworks?
I really tried to explain this to the "MathWorks Technical Support Department". But my impression is: they don't understand me. They closed my support ticket and suggested a telephone(!) conversation in January 2014 with a technical support manager.
I'll do my very best to explain this, but to be honest: I'm not very confident.
Update (2014/01/10): Currently mathworks is trying option (b).
Update (2014/03/19): For the file libiomp5.so you can download a newly compiled version (without static TLS) at mathworks, bug report 961964. And the other libs? No improvement there. So don't be suprised to get "dlopen: cannot load any more object with static TLS" with "doc", e.g. see bug report 1003952.
Restarting Matlab solved the problem for me.
long story short: in the directory that you start matlab from create a file
startup.m with content ones(10)*ones(10);. Restart matlab and it will be taken care of.
This is, as I find, an age-old problem yet unsolved by MathWorks.
Here are my two cents, which worked for me (when I wanted IT++ external libraries, with MEX).
Let the library that you found to be the cause of the problem be "libXYZ.so", and that you know where it lies on your system.
The solution is to inform MATLAB to load the specific library at the earliest of its startup. The reason for this error is apparently due to the lack of slots for this thread local storage aka tls purpose (due to they already been filled-up).
Because the latest compilations suddenly required a new library that was not loaded earlier during its startup, MATLAB throws up this error.
Pity that MATLAB never cared to resolve this problem so long.
Fortunately, the solution is a single, very simple terminal command.
Typical steps on a linux-machine should be as follows:
Open command prompt (Ctrl+Alt+T in Ubuntu)
Issue the following command
export LD_PRELOAD=<PATH-TO-libxyz.so>
e.g.: export LD_PRELOAD=/usr/local/lib/libitpp.so
Start matlab from the same terminal
matlab &
Running your program now should resolve the issue, as it is for my case.
Good luck!
Reference:
[1] http://au.mathworks.com/matlabcentral/answers/125117-openmp-mex-files-static-tls-problem
http://www.mathworks.de/support/bugreports/961964 has been updated on 30/01/2014.
There is a zip file attached with libiomp5.so
I tested it on Mageia 4 x86_64 with Matlab R2013b.
I can now use the Documentation of Matlab to open a demo without any problem.
I had the same problem and I think I just solved it.
When installing matlab use the custom installation (I did not do this the first time). Choose to create symbolic links to matlab scripts in the predefined folder (/usr/local/bin). This did the trick for me!
I had the same problem with both Matlab 2013b and Matlab 2014a. The fix provided by mathworks for libiomp5.so only removed the problem of LAPACK not working. However, I could not use external libraries which are using OpenMp (such as VL_FEAT): I still get the error
"dlopen: cannot load any more object with static TLS."
The only thing which worked for me was downgrading to Matlab 2012b.
I came across this problem after "bar" (for bar plots) with a an array gives me just a single blue block, with no errors thrown. Reboot at first solved the problem. But after a memory error (after processing a very large file), I just cannot get past this blue block problem.
Using "hist" on a matrix input gives me the "BLAS loading error" problem and led me to this thread. The Mathwork workaround fixed the hist and bar problems.
Just wanted to bring recognition to the extent of this bug's influence.
I had the same problem and solved it by increasing my Java Heap memory. Go to Preferences > General > Java-Heap Memory, and increase the allocated memory.
Increasing Java heap memory (to 512 mb) also worked for me on R2013b/Ubuntu 12.04. The "BLAS loading error" began when I processed an 11 GB file (with 16 GB RAM), and has not recurred after increasing java heap memory and restarting matlab.
I'm new to CUDA dev and I'm using NSight 5 on a MacPro.
I'm doing a very simple simulation with two particles (ver1 and ver2 here, which are two structs that have pointers to another type of structs – links)
The code compiled but seems to run into problem when reaches the end of this block, and never stepped into the integrate_functor():
...
thrust::device_vector<Vertex> d_vecGlobalVec(2);
d_vecGlobalVec[0] = ver1;
d_vecGlobalVec[1] = ver2;
thrust::for_each(
d_vecGlobalVec.begin(),
d_vecGlobalVec.end(),
integrate_functor(deltaTime)
);
...
So my questions are:
In NSight, I can see the values of member variables of ver1 and ver2; but right before the last line of the code in this block, when I expand the hierarchy of d_vecGlobalVec, I can see any of these values - the corresponding fields (e.g. of the first element in this vector) are just empty. Why is this the case? Obviously, ver1 and ver2 are on Host memo while the values in d_vecGlobalVec are on the device.
2.
A member of the NSight team posted this.
So following that, in general, does it mean that I should be able to step in and out between host and device code, and be able to see host/device variables as if there is no barrier between them?
System:
NVIDIA GeForce GT 650M 1024 MB
Mac OS X Lion 10.7.4 (11E2620)
Make sure your device code is actually called. Check all return codes and confirm that device actually worked on the output. Sometimes thrust may run the code on host if it believes it is more effective.
I would really recommend updating to 10.8 - it has the latest drivers with the best support for NVIDIA GeForce 6xx series.
Also note that for optimum experience you need to have different GPUs for display and CUDA debugging - otherwise Mac OS X may interfere and kill the debugger.
I have a Cortex-M3 chip and on it I am running a bootloader that uses eCos. The bootloader, after checking for firmware updates etc, jumps to another location (BASE_ADDRESS_OF_APP + 0x19) on the ROM where the actual application resides (also compiled with eCos).
Now instead of running the normal firmware, I want to run my CppUTests compiled for the Cortex-M3 target. So I am able to compile and link my tests for the target platform, using the ecos glibc, but not the actual operating system. But when I load it on to my board using JTAG, it doesn't run.
After some investigation using arm-eabi-objdump, I found out that the reset vector of the CppUTest firmare is at an offset of 0x490 as opposed to an offset of 0x18 for the normal firmware. My suspicion is that this is the reason why the tests are never executed. Is this correct?
How is it possible that the two firmwares have different starting addresses when I am linking them with the same linker script?
How can I make sure that the starting point of the test program is the same as the starting point of the application?
It depends on how your linker script is written, if your entry point address is not set to a static location in the linker script, then there could be the chance that other data/code is put in the object file before your entry point, effectively moving the location of your entry point and indeed causing problems.
I typically solve this by creating a new section with only 1 symbol in it, and a jump/branch instruction as follows:
.section entryPointSection
b myCodeEntryPoint
Then in your linker script put the entryPointSection at the hard coded address that your bootloader will jump to.
The myCodeEntryPoint label can be the name of a C function (or assembly label if necessary) that is in the normal .text section and can be linked anywhere within reach of the jmp. It will become your entry point, but you don't really care where it is because the linker should find it and link it properly.
Consider posting your linker script if you have further questions.