Closed pfalcon closed 4 years ago
It might not be required to have inline assembly, the compiler driver program (ppci-cc in this case) should include just about enough runtime libraries as are required for the program to function. In the case of c source code like this:
#include <stdio.h>
int main() {
printf("Hello world\n");
}
This would require that the proper C header (stdio.h) is available, for the starting of the program no assembly sourcecode has to be passed, but a runtime library should be linked which calls the main function.
Choices we have here:
For a working hello world, take a look at this example folder: https://github.com/windelbouwman/ppci-mirror/tree/master/examples/linux64/hello . This has a far less out of box experience than the scenario outlined, and as I would expect it to work as well.
Note: I absolutely agree with the scenario ppci-cc hello.c -o hello; ./hello
. This should work out of the box.
@windelbouwman, Thanks for reply. As a prelude, I'd like to say that ~20 tickets I posted in Aug-Sep 2019, can be categorized in 2 groups:
This ticket is exactly the example of the latter.
Let me now go over your reply:
It might not be required to have inline assembly
It will be absolutely to have inline assembly to have an "anyhow usable" compiler. It's just the matter as inline assembly used in real-world C programs. So, that's https://github.com/windelbouwman/ppci-mirror/issues/23. Now "we" haven't yet decided whether we want to target "real-world use", and that's why there's https://github.com/windelbouwman/ppci-mirror/issues/11. These paradigmatic questions are very-very important for future of the project.
the compiler driver program (ppci-cc in this case) should include just about enough runtime libraries as are required for the program to function.
It should. But to the best of my understanding, there's hardly any runtime/standard library available now. And then we come to the 2 types of tickets I submitted: a) paradigmatic; b) very easy to implement. As you noticed, I didn't submit tickets for medium-sized tasks, and settling matters with runtime and C standard libraries would be such.
Choices we have here: 1... 2...
Trust me, there're many more choices and many more decisions to do. So again, this is swampish medium sized task. I'm personally not ready to even discuss that, because for me, ppci is in "rather not working state, despite all the great work done". I'm looking for a quick (but not dirty) ways to get it into a state I'd consider "working". Then once it's in a state of "working, but lacks runtime/standard library", I'd be happy to give 2 cents into resolving that next task.
For a working hello world, take a look at this example folder: https://github.com/windelbouwman/ppci-mirror/tree/master/examples/linux64/hello
No worries, of course I did. And let me be straight with what I see: obscure NIH tools required to build sample, lack of README (but yeah, docs point to this dir somewhere and give few guiding words), XML (srsly, in 2019-2020?), source code spread around the tree, source code with obscure and esoteric ".c3" extension, and similarly esoteric content - all the stuff which I summed up as "rather not working state, despite all the great work done", sorry again to putting it in such a blatant way.
And again, I'm looking for a ways to find points of understanding between you, the original author, and a random representative of community who'd like to put PPCI to the greater use, which it fully deserves, and contribute to that growth. So, hopefully the feedback is more positive.
So, to clarify further, what this tickets seeks for is to implement absolutely minimal inline asm support, as would be required to develop as standalone hello-world style app. More complete work on supporting all the (gcc-compatible, what else?) inline asm options would be subject of work of the following years.
I'd expect thus formulated task to take a week of work maximum, and for someone familiar with the codebase, like yourself, @windelbouwman - likely a day.
Allright, clear enough, let's place the race to ppci-cc hello.c -o hello; ./hello
and how to achieve it in a seperate ticket, and discuss there further. I can probably start a minimal inline assembly support for the C frontend, would be a cool feature as well!
Thanks for the honest feedback, really appreciated!
@pfalcon your right, it took me less than a day to add basic inline asm syntax, I implemented this in commit a730206abfd5c659ef74e964dec9c22c83bf5e18. In and output parameters are still missing, those would be a cool addition. The approach I took was pass the inline assembly through the ir-code into the backend, and then invoke the assembler over there. I think it will work like this!
I implemented this in commit a730206
Thanks, and looks good! That was my idea either - to introduce a kind of "quote" operator to tunnel asm thru the IR down to arch-specific codegen. Going forward, that "quote" operator may need to acquire support for various "properties", like for those register constraints, whether it was asm volatile
, etc. etc. But yeah, that can be added incrementally.
So, now just need to see if "single source to executable" idea will actually work ;-).
Oh, btw, somehow I never had a chance to learn how LLVM deals with that. Let's do that now:
$ cat asm.c
int main()
{
asm("foo");
}
$ clang -S -emit-llvm asm.c asm.c
$ cat asm.ll
; ModuleID = 'asm.c'
source_filename = "asm.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
; Function Attrs: noinline nounwind optnone uwtable
define i32 @main() #0 {
call void asm sideeffect "foo", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !2
ret i32 0
}
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)"}
!2 = !{i32 23}
They hide it behind a "call", smartasses ;-).
Ok, so I went to put this into use - to build an executable from a single C source file, again. Well, there were crazy workarounds and reverse-engineerings of how things work. It should all just work as "expected" (https://github.com/windelbouwman/ppci-mirror/issues/23). The end result is here: https://github.com/pfalcon/ppci-mirror/tree/pfalcon/examples/linux64/hello-anti-nih . Of course, that also includes a linker script. Which for some reason has a ".mmap" extension and weird NIH syntax instead of what everyone knows: https://sourceware.org/binutils/docs/ld/Simple-Example.html#Simple-Example . We'll need to talk about it too ;-). I'll be happy to submit that example, but I think https://github.com/windelbouwman/ppci-mirror/issues/36 needs to be fixed first.
In the meantime, closing this, thanks for implementing it!
I added extra inline asm support with input variable support (47322e3c5e1f7d63bc49087d2afc3cd5c180f2e7). Output variables are still a bit cumbersome, no real solution for those yet.
My understanding that C frontend currently doesn't have inline asm support. Which means that any asm must be in a separate source, which means that currently it's not possible to compile a single C source and get an executable with one command. Rounded up to "integer digits" that in turn means "PPCI doesn't really work".
I'd humbly suggest that a race to get following scenario work (
ppci-cc hello.c -o hello; ./hello
) should be the first task for the project.And for that, apparently inline asm support is needed. Per https://github.com/windelbouwman/ppci-mirror/issues/23, it should be implemented in GCC-compatible manner, which of course likely will take time and effort.
As a stop-gap measure, might just introduce adhoc
__ppci_asm("mov rax, rdi")
to get that syscall() func up and running. (With a social contract that__ppci_asm
will be removed once normalasm
is implemented, to keep the codebase clean).