On Tue, 29 Oct 2019, Guild Navigator wrote:
> Program prints first two strings directly.
> But it does not print the third string (1st array string).
> 
> And debugging says why.
> The address of msg1 and msg2 is not stored correctly in the array.
> So when I access the address of msg1 from the array:
> movq array (%rip), %rsi
> it is NOT the address of msg1.
> 
> I dont know if it is a linker problem?
> I could kind of do "manual relocation" of sorts to manually
> correct the addresses put in the array.

In general, if you're going to exclude all the C startup bits that the 
operating system has provided, then you've signed up for handling all the 
possible ELF bits yourself.  If you haven't boned up on ELF and its 
variations yet, then you should do so, if just so you can recognize when 
stuff has gone wrong.

In particular, the OpenBSD linker defaults to PIE.  To quote 
clang-local(1) (similar text is in gcc-local(1)):
     -   clang will generate PIE code by default, allowing the system to load
         the resulting binary at a random location.  This behavior can be
         turned off by passing -fno-pie to the compiler and -nopie to the
         linker.  It is also turned off when the -pg flag is used.

This means that yes, your executable has relocations.  You've left out the 
rcrt0.o code that OpenBSD provides that handles such relocations, 
therefore you must either do the relocation processing yourself, or invoke 
the linker with the -nopie flag to instead generate a staticly positioned 
binary.

If you want to handle the relocations yourself, then eyeball the code in 
/usr/src/lib/csu/, particularly boot.h and amd64/md_init.h, and read the 
ELF spec and the amd64 ABI spec for structure definitions and similar.


> But what would be the OpenBSD correct way to
> write such simple print-from-the-array-of-strings program?

The answer to that literal question is "write it in C", but you obviously 
have another requirement of "...in ASM".

There are *zero* places in OpenBSD where we write pure assembler programs.  
There are only two places where we do process bootstrap bits, lib/csu and 
libexec/ld.so/, and for both of those we do _just_ enough ASM to make 
calling a limited subset of C possible, and then call a C routine to do 
self-relocation.  Improving the C version of the self-relocation code is 
*much* faster than trying improve N assembly versions.  Heck, I did so 
just this month.

ASM is cool for stuff that C can't do, but if C can do it the developer's 
time (and the time of future openbsd maintainers!) is much better spent in 
C than in ASM.  I've touched ASM on every single current OpenBSD arch, so 
I understand the high cost of doing that when it _has_ been necessary and 
I have no interest in borking around in ASM for stuff C can reasonably do.


Philip Guenther

Reply via email to