80C188 relocation register addressing mystery - embedded

I'm reverse-engineering an embedded system using the 80C188 and the way the relocation register (RELREG) is used mystifies me.
One of the first steps at initialization is to move the processor control registers by writing a new value to the RELREG.
By default, the RELREG has the value 20FFH which places the register block at the top of I/O space at address 0FFxxH. The example given in the Intel app note describes writing the value of 1100H to the RELREG which then places the register block in memory space at 100xxH. Clear enough.
However, in the system I am examining, the value is written is 1804H which I would expect to place the register block in memory space at the address 804xxH, yet the following writes to initialize the registers to operating values are all to 0F4xxH in memory space. The processor is operating fine in the system so this is not a programming bug.
I am absolutely sure about these addresses as not only do I see them in the code itself on the EPROM but also in logic analyzer traces of code execution at startup.
Does anyone have an explanation for this?

The address in the code is the address offset and must be combined with the appropriate segment register to map to a physical address. The mapping is performed by:
(seg * 16) + offset
So if the seg were 7100h, then the seg:off address 7100:f400 refers to the physical address 80400h.

Related

how does JVM know the current method through PC

In 8086, we can know the next instruction to execute through CS:PC, where PC is the offset in the current code segement(CS).
However, I'm not sure how JVM knows which instruction to execute.
PC register in JVM only indicates the offset in the current method, but how does it know which method it's in?
Thanks!
I notice the codes for each method start from 0, like thisenter image description here
So, if there are many methods in a class, how can I know which method the current frame is in?
I'm new to Java, so my question may be silly and my explaination is wrong. Thanks for bear with me!
OK, so I assume that you are asking about the JVM in relation to the Java Virtual Machine Specification (JVMS). The most directly relevant part of the spec says this:
2.5.1. The pc Register
The Java Virtual Machine can support many threads of execution at once
(JLS §17). Each Java Virtual Machine thread has its own pc (program
counter) register. At any point, each Java Virtual Machine thread is
executing the code of a single method, namely the current method
(§2.6) for that thread. If that method is not native, the pc register
contains the address of the Java Virtual Machine instruction currently
being executed. If the method currently being executed by the thread
is native, the value of the Java Virtual Machine's pc register is
undefined. The Java Virtual Machine's pc register is wide enough to
hold a returnAddress or a native pointer on the specific platform.
Note the emphasized sentence. It says the address of the instruction being executed. It does not say the instruction's offset from the start of the method's code segment ... as you seem to be saying.
Furthermore, there is no obvious reference to a register holding a pointer to the current method. And the section describing the call stack doesn't mention any pointer to the current method in the stack frame.
Having said all of that, the JVM specification is really a behavioral specification that JVM implementations need to conform to. It doesn't directly mandate that the specified behavior must be implemented in any particular way.
So while it seems to state that the abstract JVM has a register called a PC that contains an "address", it doesn't state categorically what an address means in this context. For instance, it does not preclude the possibility that the interpreter represents the "address" in the PC as a tuple consisting of a method address and a bytecode offset within the method. Or something else. All that really matters is that the JVM implementation can somehow use the PC to get the bytecode instruction to be executed.

How to use dexlib2 to instrument certain methods, especially allocating registers to add new instructions?

I'm using dexlib2 to programmatically instrument some methods in a dex file, for example, if I find some instructions like this:
invoke-virtual {v8, v9, v10}, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
I'd like to insert an instruction before it, and therefore at runtime I can know the exact arguments of Class.getMethod().
However, now I run into some questions about how to allocate registers to be used in my inserted monitoring instruction?
I know of two ways, but either way has its problems:
I can use DexRewriter to increase the registerCount of this method (e.g from .register 6 to .register 9), so that I can have extra (3) registers to be used. But first this is restricted by 16 registers; second when I increase the registerCount, the parameters will be passed into the last ones, and therefore I have to rewrite all instructions in this method that use parameters, which is tiring.
Or I can reuse registers. This way I have to analysis the liveness of every registers, while dexlib2 seems does not have existing API to construct CFG and def-use chain, which means I have to write it myself.
Besides, I doubt whether by this way I can get enough available registers.
So am I understanding this problem right? are there any existing tools/algorithms to do this? Or any advice that I can do it in a better way?
Thanks.
A few points:
You're not limited to 16 registers in the method. Most instructions can only address the first 16 registers, but there are mov instructions that can can use to swap values out with higher registers
If you can get away with not having to allocate any new registers, your life will be much easier. One approach is to create a new static method with your instrumented logic, and then add a call to that static method with the appropriate values from the target method.
One approach I've seen used is to increase the register count, and then add a series of move instructions at the beginning of the method to move all the parameter registers back down to the same registers they were in before you incremented the register count. This makes it so that you don't have to rewrite all the existing instructions, and guarantees that the new registers at the end of the range are unused. The main annoyance with this approach is when the new registers are v16 or higher, you'll have to do some swaps before and after the point at where they're used to get the value back down into a low register, and then restore whatever was in that register afterward.
You may code like this:
if (it.opcode == Opcode.INVOKE_VIRTUAL || it.opcode == Opcode.INVOKE_STATIC) { logger.warn("${it.opcode.name} ${(it as DexBackedInstruction35c).reference}") }
Format of Opcode.INVOKE_VIRTUAL is Format35c, so the type of instruction is DexBackedInstruction35c.

When a dll is loaded into memory, which part(s) can be shared between processes?

I meet a question about the interview test:
When a dll is loaded into memory, which part(s) can be shared between processes?
A. code segment
B. static variable global variable
C. external difinitions and references for linking
D. BSS segment
who can give me an answer and a clear explation?
Processes are actually isolated programs running multiple threads in an OS. Generally operating system policy says, All processes are memory isolated from each other.
Code Segment : [NOT SHARED]
BSS and Static Fields : [NOT SHARED]
Reason is very simple, why a operating system allow process A to access process B's binary? that's security and memory protection violation. process A could corrupt (if write access is given) process B memory.
what about External Definitions?
Here comes the interesting part, External definitions could be statically or dynamically linked.
statically linked library implies definitions are linked at compiled time and programs binary contains It's machine code.
dynamically linked implies definitions are linked just after user commands to load any program in memory. OS calls dynamic library loader to resolve external dependencies of the program by providing shared object's path.
This shared object is cached by operating system in a different page frame, and every time when a program demands for this library, It simply copy It's page frame to process's virtual memory; and do required dynamic linking. This way multiple process have same binary of a single library.
It save RAM memory and time in loading library from disk, Also dynamic linking reduces binary size of the program.
It is also possible that the OS choose to load library again from disk, and thus make two copies of same library. This is a part of dynamic linking operation. I don't go into more depth, but if you are really interested https://en.wikipedia.org/wiki/Dynamic_linker or just ping me in comments section.
But regarding BSS and static fields, It is again not shared; Whenever a write operation is performed on such region (which is shared). Operating System create a new copy of that region for the other process. This makes sure that both process have their own copy of BSS and static fields.

IJVM using a local variable for GOTO statement

I am working with IJVM and trying to use the GOTO instruction using a local variable in place of a static offset (or label). It won't work. I suppose it is simply treating the variable name as a label and trying to branch to it, but no such label exists. Is there any way I can force it to read the contents of the variable (which contains an offset), or some other solution?
Thanks in advance.
For security reasons, JVM bytecode doesn't let you jump to arbitrary instructions based on the contents of a variable. This restriction makes it possible for the JVM to verify various security properties of the bytecode by statically enumerating all control paths through a particular method. If you were able to jump anywhere, the static analyzer couldn't prove that all necessary program invariants held.
If you do need to jump to an arbitrary index, consider looking into the tableswitch or lookupswitch instructions, which would let you enumerate possible destinations in advance. It's not exactly what you're looking for, but to the best of my knowledge the sort of arbitrary jump you're trying to make isn't possible in JVM bytecode.
Hope this helps!
The GOTO instruction is implemented in MIC1. It interprets the 2 bytes after the opcode as an offset to the PC at the start of the instruction.
I think that the assignment must be asking you to write a new GOTO in MIC1 that interprets the byte after the opcode as the offset to a local variable that contains the branch offset.

STM32 programming tips and questions

I could not find any good document on internet about STM32 programming. STM's own documents do not explain anything more than register functions. I will greatly appreciate if anyone can explain my following questions?
I noticed that in all example programs that STM provides, local variables for main() are always defined outside of the main() function (with occasional use of static keyword). Is there any reason for that? Should I follow a similar practice? Should I avoid using local variables inside the main?
I have a gloabal variable which is updated within the clock interrupt handle. I am using the same variable inside another function as a loop condition. Don't I need to access this variable using some form of atomic read operation? How can I know that a clock interrupt does not change its value in the middle of the function execution? Should I need to cancel clock interrupt everytime I need to use this variable inside a function? (However, this seems extremely ineffective to me as I use it as loop condition. I believe there should be better ways of doing it).
Keil automatically inserts a startup code which is written in assembly (i.e. startup_stm32f4xx.s). This startup code has the following import statements:
IMPORT SystemInit
IMPORT __main
.In "C", it makes sense. However, in C++ both main and system_init have different names (e.g. _int_main__void). How can this startup code can still work in C++ even without using "extern "C" " (I tried and it worked). How can the c++ linker (armcc --cpp) can associate these statements with the correct functions?
you can use local or global variables, using local in embedded systems has a risk of your stack colliding with your data. with globals you dont have that problem. but this is true no matter where you are, embedded microcontroller, desktop, etc.
I would make a copy of the global in the foreground task that uses it.
unsigned int myglobal;
void fun ( void )
{
unsigned int myg;
myg=myglobal;
and then only use myg for the rest of the function. Basically you are taking a snapshot and using the snapshot. You would want to do the same thing if you are reading a register, if you want to do multiple things based on a sample of something take one sample of it and make decisions on that one sample, otherwise the item can change between samples. If you are using one global to communicate back and forth to the interrupt handler, well I would use two variables one foreground to interrupt, the other interrupt to foreground. yes, there are times where you need to carefully manage a shared resource like that, normally it has to do with times where you need to do more than one thing, for example if you had several items that all need to change as a group before the handler can see them change then you need to disable the interrupt handler until all the items have changed. here again there is nothing special about embedded microcontrollers this is all basic stuff you would see on a desktop system with a full blown operating system.
Keil knows what they are doing if they support C++ then from a system level they have this worked out. I dont use Keil I use gcc and llvm for microcontrollers like this one.
Edit:
Here is an example of what I am talking about
https://github.com/dwelch67/stm32vld/tree/master/stm32f4d/blinker05
stm32 using timer based interrupts, the interrupt handler modifies a variable shared with the foreground task. The foreground task takes a single snapshot of the shared variable (per loop) and if need be uses the snapshot more than once in the loop rather than the shared variable which can change. This is C not C++ I understand that, and I am using gcc and llvm not Keil. (note llvm has known problems optimizing tight while loops, very old bug, dont know why they have no interest in fixing it, llvm works for this example).
Question 1: Local variables
The sample code provided by ST is not particularly efficient or elegant. It gets the job done, but sometimes there are no good reasons for the things they do.
In general, you use always want your variables to have the smallest scope possible. If you only use a variable in one function, define it inside that function. Add the "static" keyword to local variables if and only if you need them to retain their value after the function is done.
In some embedded environments, like the PIC18 architecture with the C18 compiler, local variables are much more expensive (more program space, slower execution time) than global. On the Cortex M3, that is not true, so you should feel free to use local variables. Check the assembly listing and see for yourself.
Question 2: Sharing variables between interrupts and the main loop
People have written entire chapters explaining the answers to this group of questions. Whenever you share a variable between the main loop and an interrupt, you should definitely use the volatile keywords on it. Variables of 32 or fewer bits can be accessed atomically (unless they are misaligned).
If you need to access a larger variable, or two variables at the same time from the main loop, then you will have to disable the clock interrupt while you are accessing the variables. If your interrupt does not require precise timing, this will not be a problem. When you re-enable the interrupt, it will automatically fire if it needs to.
Question 3: main function in C++
I'm not sure. You can use arm-none-eabi-nm (or whatever nm is called in your toolchain) on your object file to see what symbol name the C++ compiler assigns to main(). I would bet that C++ compilers refrain from mangling the main function for this exact reason, but I'm not sure.
STM's sample code is not an exemplar of good coding practice, it is merely intended to exemplify use of their standard peripheral library (assuming those are the examples you are talking about). In some cases it may be that variables are declared external to main() because they are accessed from an interrupt context (shared memory). There is also perhaps a possibility that it was done that way merely to allow the variables to be watched in the debugger from any context; but that is not a reason to copy the technique. My opinion of STM's example code is that it is generally pretty poor even as example code, let alone from a software engineering point of view.
In this case your clock interrupt variable is atomic so long as it is 32bit or less so long as you are not using read-modify-write semantics with multiple writers. You can safely have one writer, and multiple readers regardless. This is true for this particular platform, but not necessarily universally; the answer may be different for 8 or 16 bit systems, or for multi-core systems for example. The variable should be declared volatile in any case.
I am using C++ on STM32 with Keil, and there is no problem. I am not sure why you think that the C++ entry points are different, they are not here (Keil ARM-MDK v4.22a). The start-up code calls SystemInit() which initialises the PLL and memory timing for example, then calls __main() which performs global static initialisation then calls C++ constructors for global static objects before calling main(). If in doubt, step through the code in the debugger. It is important to note that __main() is not the main() function you write for your application, it is a wrapper with different behaviour for C and C++, but which ultimately calls your main() function.