can't understand how to use sim folder in binutils - binutils

I am porting binutils to a new arch. What is the sim folder for ? and how can I use it ? If I understand correctly, the sim folder suppose to build some kind of simulator for the new arch but I can't find any information about it. Is there more information anywhere ?

The sim directory is indeed for simulators. When you build gdb, you can choose to enable a simulator, if one exists, for the primary target (there's no support for building multiple simulators). The simulator is then linked into gdb and can be accessed using target sim. There's a section in the manual explaining more about this.
It's certainly possible to write a new sim. However, if I was doing a port to a new arch, I would instead consider writing a qemu port. Qemu is faster and useful for more things than the gdb sims.

Related

Is there a way to fix an xcframework so it works on M1 and Intel simulators?

Edit: Selecting Xcode in Finder, getting info, and ticking the box for Open using Rosetta makes things work, but surely there is a better way…
I have an iOS project with a static framework containing three variants in it; ios-armv7_armv7s_arm64, ios-i386_x86_64-simulator, and ios-x86_64-maccatalyst. I do not have any access to the source code for this framework and asking for a new build of the framework is not a practical option. As a result I need to work with the xcframework that I have in hand.
The framework works just fine on my colleagues machines as they are using Intel based Macs. As a new addition to the team I have been given an M1 machine. While I can build to a physical device, building to the simulator fails with missing symbols. This makes complete sense given that the simulator variant doesn't have arm64 in it.
Simply adding a new definition to the info.plist to cover the M1 chip doesn't work as that means there are two simulator definitions. (There are also other issues with this route)
If I duplicate the ios-armv7_armv7s_arm64 folder, add -simulator to the copies name, and replace the existing definition for the simulator framework with info from the ios-armv7_armv7s_arm64 definition I get an error about building for the simulator but linking in a file built for iOS. This means that no matter what I can't simply copy the existing M1 framework to get things going.
The only things I can think of both involve the need to somehow edit the M1 copy of the compiled framework so that it will work on the simulator, and I rather doubt there is a way to do that. If it is possible to do though I would then need to either come up with some nested framework trick that allowed me to have two definitions for the simulator but for two different architectures; or I would need to write a script that used uname -m to decide how to edit the framework's info.plist file (This feels very hacky, but would be the simplest way of making the project 'just work' on both Intel and M1 machines without the need to make manual adjustments and remember not to commit them.
Anyone have any brilliant ideas on how to get this framework working in the simulator without having a new copy built? (I haven't even found a clear method for how it would need to be built to work on both architectures.)
Xcode: 13.3.1

Architecture-Specific Build Settings in Xcode 13

I'm trying to use architecture-specific build settings in my Xcode Framework so that I can handle the case of the Apple Silicon Mac and the Intel Mac separately. I need to use this build setting as a macro in Metal to check whether the half data type is supported on the CPU (it's supported on Apple Silicon but not supported on Intel).
My current implementation uses an xcconfig file with the following line:
IS_X86_64[arch=x86_64] = 1
Then, in my build settings I have the following user-defined condition (from the xcconfig):
I then create the macro IS_INTEL so it can be used in Metal:
Here's The Problem
In theory I feel like this should work. However, running my Metal app on my Intel mac yields 0 for IS_X86_64. The first thing I did was check whether I set up my build setting correctly and replaced
IS_X86_64[arch=x86_64] = 1
with
IS_X86_64[arch=*] = 1
This worked so I knew that the problem had to be that my current architecture wasn't being represented correctly. Diving further into why this was happening, it turns out that the value for CURRENT_ARCH (which should hold the value for the current device architecture that the project is being run on) is undefined_arch.
In their Xcode 10 release notes, apple mentioned something about undefined_arch saying:
The new build system passes undefined_arch as the value for the ARCH environment variable when running shell script build phases. The value was previously not well defined. Any shell scripts depending on this value must behave correctly for all defined architectures being built, available via the ARCHS environment variable.
However, I'm not building my project on the shell and I don't have any shell scripts.
Does anyone know how I can fix this so that architecture-specific build settings behave as they should?
You can check the architecture via built-in macros. You can see how they are used in usr/include/TargetConditionals.h:
#if __is_target_arch(x86_64)
...
#endif
More macros:
__is_target_arch(arm64)
__is_target_arch(arm64e)
__is_target_os(ios)
__is_target_environment(macabi)
__is_target_environment(simulator)

Extract dyld_shared_cache on iOS7.1?

I was trying to get the header files from the ToneKit framework on iOS7.1, but I found that I cannot use class-dump because there are no executable files inside the framework. From what I have found after some research, it seems as if the actual executable file is inside the dyld_shared_cache on the device. After reading this article, it seems as if there are some tools to decrypt the cache, but since iOS 3, Apple has implemented ASLR which has made the decryption tools not work. How can I extract the Frameworks from inside the dyld_shared_cache on iOS7.1?
I am very new to jailbroken ios development so please bear with me.
If you're interested in how they got those headers then the answer is very simple - iOS SDK. SDK contains ARM binaries of public and private frameworks because they are required to compile iOS applications. Class-dump them and you will get headers you need. ToneKit.framework binary is also in there.
Usually you don't need dyld_shared_cache, almost everything you need is either in iOS SDK or on a device itself like SpringBoard, other system applications etc.
Of course there are rare cases when dyld_shared_cache is the only place you can find certain binaries as they are missing from both iOS SDK and device. In that case I use IDA. It has free demo version that can open dyld_shared_cache files - you can even open individual binaries inside it rather than dump everything. You just need to copy dyld_shared_cache on your PC.
I think Elias Limneos's classdump-dyld can help you. If not, check out RuntimeBrowser. Failing that, even, weak-classdump has proven to be a very useful runtime tool for me.

Script for checking Build Mode in Xcode

I am creating a iOS Static Library in Xcode. I will be distributing two separate binaries, one for running in simulators(x86 architecture) & other for devices(ARM architecture).
I am aware of aggregate target, but I want to know whether it is possible to write a script to check whether the code is running in Debug or Release mode, i.e in Simulator(debug) or Device(Release) in ideal scenario.
Depending on this, I can put some check in my respective binary to compile or not.
Devices do not run in debug or release. The user chooses to build their target in debug or release. You can supply a debug version of your library, if you'd like, though. That is something I have seen other vendors do, and is greatly appreciated by developers.

Debug iOS application on device without symbols

I need to debug the startup for an ios application on an actual device... and by start up I mean the very first instruction that is is executed when the OS hands control over to the app. Not "main". Also, this application doesn't have any symbols (ie. the debug information isn't available.. yet). I don't care if I have to debug at the CPU instruction level. I know how to do that (done it for over 30 years). I want the debugger to stop when control is about to transfer to the app. When I use the Attach|by Name command and run, it just says "Finished running".
Oh, and this application was not built in XCode. It is, however an application I built, signed and provisioned and moved to the device. The application does run since I can see the console output. Just in case you're thinking I'm some hacker trying to debug someone's application.
How's that for a tall order? I'll bet nobody can answer this... I've not been able to find any information on how I could do this with an XCode-built project. I wonder if it is simply not possible or "allowed" by the Apple overlords?
What do you say, Stack Overflow gods?
UPDATE: I should clarify something. This application is not built with any commercially available or open-source tool. I work with a tools vendor creating compilers, frameworks, and IDEs. IOW, you cannot get this tool... yet. In the process of bootstrapping a new tool chain, one regularly must resort to some very low-level raw debugging. Especially if there are bugs in the code generated by the tools.
I'm going to answer my own question because I think I've stumbled upon a solution. If anyone has anything more elegant and simple than this, please answer as well. On to the steps:
Starting with a raw monolithic iOS executable (not a bundled .app, but the actual binary mach-o file that is the machine code).
Create a new like-named empty Xcode project. Build and run it on the device.
Locate the output bundle's .app folder.
Copy the above raw iOS executable over the existing one in the .app bundle's folder.
The application will now have an invalid signature and cannot be deployed and run.
Run codesign against the app bundle (you can find out the command-line by running xcodebuild on the above Xcode project).
In the bundle's .app folder, run otool -h -l on the binary image. Locate the LC_UNIXTHREAD load command and find the value associated with the 'pc' register. This is address where the os loader will jump to your application. If this address is odd, then these are Thumb instructions otherwise it will be ARM (I think that's how it works).
Add a symbolic breakpoint (I used GDB instead of LLDB) and enter the address as '*0x00001234' as the symbol.
Select Product|Perform Action|Run Without Building.
Assuming that GDB is able to evaluate the breakpoint expression and set the break point, and you've selected Product|Debug Workflow|Show Disassembly When Debugging, the process should break at the very first instruction to be executed in the application.
You can now single step the instructions and use the GDB console to get/set register values.
Your question does not make sense - main is the entry point into the application. It is the first code that should be encountered, unless possibly you have initialize() overridden for some classes (but even then I think main would get hit before the runtime).
I think you are seeing some kind of odd error on launch and you think you want to set a breakpoint on entry to catch it, but far more likely what would help you is to describe the problem on launch and let one of the 4000 people who have seen and fixed the same crash help you...
However, if you really want to use GDB to break on an application with no symbols (but that you launch from XCode) you can have GDB break on an assembly address as per:
How to break on assembly instruction at a given address in gdb?
To find the address of main (or other methods) you can use tool or atos, some examples in this question:
Matching up offsets in iOS crash dump to disassembled binary
ADDITION:
If for some reason XCode cannot launch your application for debugging, you could also jailbreak and install GDB on the device itself which would give complete control over debugging. If XCode can launch you application I see no reason why being able to break at an arbitrary memory address does not give you the ability you seek...
One solution for applications with webviews is to run them in the iOS Simulator, and connect to that with the remote-debugger in macOS Safari. This is off-topic but maybe the one or other could benefit.
http://hiediutley.com/2011/11/22/debugging-ios-apps-using-safari-web-inspector/
Or use NetCat for iOS... not the most perfect solution, but at least you see what's going on.

Resources