ABI Register Names for RISC-V Calling Convention - cpu-registers

I'm confused about the RISC-V ABI Register Names. For example, Table 18.2 in the "RISC-V Instruction Set Manual, Volume I: User-Level ISA, Version 2.0" at page 85 specifies that the stack pointer sp is register x14. However, the instruction
addi sp,zero,0
is compiled to 0x00000113 by riscv64-unknown-elf-as (-m32 does not make a difference). In binary:
000000000000 00000 000 00010 0010011
^imm ^rs1 ^f3 ^rd ^opcode
So here sp seems to be x2. Then I googled a bit and found the RISC-V Linux User's Manual. This document states that sp is x30.
So what is it? Are there different ABIs? Can I set the ABI with a command line option to riscv64-unknown-elf-*? Is there a comprehensive table somewhere?

The stack pointer is now x2.
Here is the current ABI documentation, which has been moved out of the User-Level ISA specification, which now contains that same link.
The ABI was modified to better accommodate the new RISC-V compressed spec, which puts the 8 most-used registers next to each other in x8-x15.
Note: do not trust ANY non riscv.org webpage. Quan Nguyen makes this clear in his introduction that the "RISC-V Linux User's Manual" is for documenting the porting process and that accuracy is NOT guaranteed.

Related

API for ldd (or objdump)?

I need to programmatically inspect the library dependencies of a given executable. Is there a better way than running the ldd (or objdump) commands and parsing their output? Is there an API available which gives the same results as ldd ?
I need to programmatically inspect the library dependencies of a given executable.
I am going to assume that you are using an ELF system (probably Linux).
Dynamic library dependencies of an executable or a shared library are encoded as a table on Elf{32_,64}_Dyn entries in the PT_DYNAMIC segment of the library or executable. The ldd (indirectly, but that's an implementation detail) interprets these entries and then uses various details of system configuration and/or LD_LIBRARY_PATH environment variable to locate the needed libraries.
You can print the contents of PT_DYNAMIC with readelf -d a.out. For example:
$ readelf -d /bin/date
Dynamic section at offset 0x19df8 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x3000
0x000000000000000d (FINI) 0x12780
0x0000000000000019 (INIT_ARRAY) 0x1a250
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1a258
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x308
0x0000000000000005 (STRTAB) 0xb38
0x0000000000000006 (SYMTAB) 0x358
0x000000000000000a (STRSZ) 946 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x1b000
0x0000000000000002 (PLTRELSZ) 1656 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x2118
0x0000000000000007 (RELA) 0x1008
0x0000000000000008 (RELASZ) 4368 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffb (FLAGS_1) Flags: PIE
0x000000006ffffffe (VERNEED) 0xf98
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0xeea
0x000000006ffffff9 (RELACOUNT) 170
0x0000000000000000 (NULL) 0x0
This tells you that the only library needed for this binary is libc.so.6 (the NEEDED entry).
If your real question is "what other libraries does this ELF binary require", then that is pretty easy to obtain: just look for DT_NEEDED entries in the dynamic symbol table. Doing this programmatically is rather easy:
Locate the table of program headers (the ELF file header .e_phoff tells you where it starts).
Iterate over them to find the one with PT_DYNAMIC .p_type.
That segment contains a set of fixed sized Elf{32,64}_Dyn records.
Iterate over them, looking for ones with .d_tag == DT_NEEDED.
Voila.
P.S. There is a bit of a complication: the strings, such as libc.so.6 are not part of the PT_DYNAMIC. But there is a pointer to where they are in the .d_tag == DT_STRTAB entry. See this answer for example code.

Turbo Pascal BGI Error: Graphics not initialized (use InitGraph)

I'm making a Turbo Pascal 7.0 program for my class, it has to be on Graphic Mode.
A message pops up
BGI Error: Graphics not initialized (use InitGraph).
I'm already using InitGraph and graph.tpu and I specified the route as "C:\TP7\BGI".
My S.O is Windows 7 and I'm using DosBox 0.74, I already tried to paste all the files from the folder BGI into BIN.
What should I do?
Since dos doesn't have system graphic drivers, the BGI functions as such for BP7.
So in short, use a BGI suitable for your videocard. The ones supplied with BP7 are very old, there are newer, VESA ones that you could try.
Afaik 3rd party BGI needs to be registered explicitly in code though.
At first I have had this "missing Graph.tpu"- ... and later the "Use Initgraph"-issue too.
After hours trying (and reading some not politeful comments in the internet) I finally got Turbo Pascal 7 succesfully running (in Windows 10, x64). In summary I want to share "some secrets":
install the "TP(WDB)-7.3.5-Setup.msi" (comes from clever people in Vietnam)
make sure, that there's the CORRECT PATH to the "BGI"-directory in your program-code. For example:
driver := Detect;
InitGraph (driver, modus, 'c:\TPWDB\BGI');
(By the way: This is ALL, what's there to do with "Initgraph".)
make sure, that in TP7 under "Options" --> "Directories" are the CORRECT PATHS both to "C:\TPWDB\UNITS" and Your actual working dir e.g. "C:\TPWDB\myPrograms"
THAT's IT.
Annotations: The "Graph.TPU" (usually) is already in "UNITS" (together with "Graph3.tpu" by the way).
Hazzling around old driver's isn't needed even... :)
Just the correct paths... :)
Hope, that can help ...

Is there a working distribution of sqlite available for OpenVMS?

I am looking for a working distribution of SQLite for OpenVMS. I tried building SQLite 3.7.9 from the amalgamation file, using patches I found in a mailing list, but it does not quite work.
I am using HP C V7.1-015 on OpenVMS Alpha 7.3-2.
Since I cannot install python, which seems to include SQLite3, I have to build from sources.
I compile using the following commands:
$ CC /OPTIMIZE -
/DEFINE=(SQLITE_THREADSAFE=0, -
SQLITE_OMIT_LOAD_EXTENSION=1, -
SQLITE_OMIT_COMPILEOPTION_DIAGS=1, -
SQLITE_OMIT_MEMORYDB=1, -
SQLITE_OMIT_TEMPDB=1, -
SQLITE_OMIT_DEPRECATED=1, -
SQLITE_OMIT_SHARED_CACHE=1, -
_USE_STD_STAT=ENABLE) -
/FLOAT=IEEE_FLOAT -
sqlite3.c
$ CC /OPTIMIZE -
/DEFINE=(SQLITE_THREADSAFE=0, -
SQLITE_OMIT_LOAD_EXTENSION=1, -
SQLITE_OMIT_COMPILEOPTION_DIAGS=1, -
SQLITE_OMIT_MEMORYDB=1, -
SQLITE_OMIT_TEMPDB=1, -
SQLITE_OMIT_DEPRECATED=1, -
SQLITE_OMIT_SHARED_CACHE=1, -
_USE_STD_STAT=ENABLE) -
/FLOAT=IEEE_FLOAT -
shell.c
I copied the defines from the mailing list, and added /FLOAT=IEEE_FLOAT to get rid of most warnings regarding floating points (related to overflows due to exponent 308).
During compilation I got some informationals and warnings.
I get the following messages while linking:
$ LINK shell.obj,sqlite3.obj
...
%LINK-W-NUDFSYMS, 2 undefined symbols:
%LINK-I-UDFSYM, __STD_FSTAT
%LINK-I-UDFSYM, __STD_STAT
...
Since I am a little bit lost here, I rather have SQLite3 sources which compile on OpenVMS.
The specific problem you're getting from the linker arises from the fact that you've requested capability at compile time that your system doesn't have. I believe the _USE_STD_STAT option first became available in OpenVMS v8.2, yet you're on 7.3-2. Your compiler and your headers know what to do when _USE_STD_STAT is defined, but the functions to process the X/Open-compliant stat structure do not exist in the C run-time (CRTL in VMS parlance) on your system, and your linker is telling you, "ain't got those functions."
Ideally you would be able to upgrade your operating system. Current as of this writing is v8.4. v7.3-2 was released eight and a half years ago and v8.2 over seven years ago. I understand that there are technical, budgetary, and even political reason that upgrades aren't always possible. If it were me, and I were stuck on OpenVMS Alpha v7.3-2, I would try removing the _USE_STD_STAT=ENABLE from the compilation and see what blows up.
One of the side effects of enabling _USE_STD_STAT is that you also get _LARGEFILE along with it. If that's the only reason SQLite needs the option, you may be fine but limited to 4GB databases. I suspect there's more to it than that, i.e., SQLite very likely makes use of elements in the stat structure that do actually require the newer structure.
You can read up on the differences in the traditional and standards-compliant stat structures at http://h71000.www7.hp.com/doc/84final/5763/5763profile_062.html#index_x_1699.
I've recently improved my VMSish patch for SQLite and made it available for SQLite version 3.7.14.1: http://www.mail-archive.com/sqlite-users#sqlite.org/msg73570.html (or http://sqlite.1065341.n5.nabble.com/Building-SQLite-3-7-14-1-for-OpenVMS-td65277.html).
POSIX locking still doesn't work though, and I was unable to find out why.
Well, there was a message on the sqlite-users mailing list on getting SQLite 3.7.9 working on OpenVMS. I don't know how relevant that is to the version you've got (or if the patch was adopted by the SQLite developers; they're a bit picky for legal reasons IIRC) but it looks likely to be useful. Good luck.

Ada 95: Modifying output of dictionary program

I've found this dictionary by William Whitaker on the Internet and I like its parsing capabilities. But the output doesn't fit for me.
The issue (challenge for me):
Given an input form such as "audiam", the program returns the following output (plain text):
audi.am V 4 1 PRES ACTIVE SUB 1 S
audi.am V 4 1 FUT ACTIVE IND 1 S
audio, audire, audivi, auditus V (4th) [XXXAO]
hear, listen, accept, agree with; obey; harken, pay attention; be able to hear;
But I just want to receive the following text output (same input: audiam):
audiam=audio, audire, audivi, auditus
That is:
InputWord=Dictionary_Forms
So some pieces of information are needless for me.
How can I change the output of this program by modifying the Ada code?
I don't have any Ada knowledge, but I know Delphi/Pascal so it's quite easy to understand the code, isn't it? So the parts causing the text output seem to be the TEXT_IO.PUT(...) statements, right? They're all called in list_package.adb so this is probably the source file to look at.
What has to be changed in particular?
The full Ada 95 source code of this program is available on this page.
I hope some of you are able to understand Ada 95 code. Thank you very much in advance!
My compiling problems:
For use on a windows machine, I downloaded MinGW and tried to compile the source files using "MinGW Shell". But this was my input and the shell's reponse:
Compiling with the latest Cygwin version:
When I compile the program using the latest version of Cygwin, there is no error message:
There is even an .exe file which is created. Its size is 1.6 MB (1,682,616 bytes). But when I open it, it closes right away. What has gone wrong?
William Whitaker's Words is a handy tool. You may be able to find a version already built for your platform. I've not changed the code, but you can alter some things using various parameters. It's even hosted online. If you get an Ada compiler, I've included the last Makefile I used. It's a little thin on abstraction, but it includes the essential steps to compile the program and utilities, along with the steps to build the dictionaries.
TARG = words
ARGS = -O
$(TARG): *.ad[bs]
gnatmake $(TARG) $(ARGS)
all: $(TARG)
gnatmake makedict $(ARGS)
gnatmake makeinfl $(ARGS)
gnatmake makestem $(ARGS)
gnatmake makeefil $(ARGS)
#echo Please make the dicitionary
#echo ./makedict DICTLINE.GEN
#echo ./makestem STEMLIST.GEN
#echo ./makeefil EWDSLIST.GEN
#echo ./makeinfl INFLECTS.GEN
debug:
gnatmake -g $(TARG)
clean:
rm -f *.o *.ali b~* core
cleaner: clean
rm -f *.s makedict makeinfl makestem makeefil
cleanest: cleaner
rm -f $(TARG)
Addendum: One approach is to use gcc 4.4.3 on Ubuntu 10.04 with the updated Makefile above. For convenience, I used VirtualBox to host the linux instance.
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here's a quick test using the title of my second favorite passage from Catulli Carmina.
$ ./words odi et amo
odi V 6 1 PRES ACTIVE IMP 2 S
odeo, odire, odivi(ii), - V TRANS [EXXCW] Later
od.i V 4 1 PRES ACTIVE IMP 2 S
odio, odire, odivi, - V (4th) TRANS [FXXCF] Medieval
hate; dislike; be disinclined/reluctant/adverse to; (usu. PREFDEF);
odi N 2 4 GEN S N Early
odium, odi(i) N (2nd) N [XXXAO]
hate/hatred/dislike/antipathy; odium, unpopularity; boredom/impatience;
hatred (manifested by/towards group), hostility; object of hate/odium;
od.i V 3 1 PERF ACTIVE IND 1 S
odi, odisse, osus V (3rd) PERFDEF [XXXBX]
hate (PERF form, PRES force), dislike; be disinclined/reluctant/adverse to;
et CONJ
et CONJ [XXXAX]
and, and even; also, even; (et ... et = both ... and);
am.o V 1 1 PRES ACTIVE IND 1 S
amo, amare, amavi, amatus V (1st) [XXXAO]
love, like; fall in love with; be fond of; have a tendency to;
Addendum: Once you've got it running, the problem of modifying it remains. A grep for Put_Line\( shows 629 hits; most are in line_stuff and list*. That's where I'd start. As you are learning Ada, there are several good tutorials here.
As much as I like Ada and would encourage you to learn the minimal amount it would require to hack it the way you want...
Really, you are asking for a simple data filter, which it would be quite easy to accomplish by piping your output to awk. If you are running on any flavor of Linux you have awk already (and really should learn to use it). If you are on Windows, you can get awk and all sorts of other useful goodies from MinGW, which is one of the places you'd need to go to get an Ada compiler anyway.
If you do want a Windows Ada compiler, I'd suggest getting GNAT/GCC from there. The two other flavors available, GNAT/GPL and GNAT/PRO are available from AdaCore (the maintainers). However, GNAT/PRO must be purchased and GNAT/GPL renders distributions of any program compiled using it GPL. You might not mind the GPL applying to your program I suppose, but I'm guessing this isn't a serious enough need to spring for commercial support.
If you are on Linux, the GNAT Ada compiler should be available with GCC as an option (if not installed by default). The same two other options from AdaCore are available there too of course, if you like.
Well, you asked about learning Ada. Really, if you are familiar with other compiled procedural languages (eg: C/C++, Java, Pascal, Modula-2, etc.) you shouldn't have too much trouble picking it up. This question covers Ada books. For myself, I generally just use the official LRM as a reference. Unlike most languages, Ada has an internationally standardized Language Reference Manual that is available online for free. It is also quite readable, as such things go.
About compiling: you can use GNAT. It supports Ada83, Ada95, and Ada05. To tell it to use Ada95, use the -gnat95 switch.
You can get it on http://libre.adacore.com/

Who know the history of unix fork?

Fork is a great tool in unix.We can use it to generate our copy and change its behaviour.But I don't know the history of fork.
Does someone can tell me the story?
Actually, unlike many of the basic UNIX features, fork was a relative latecomer (a).
The earliest existence of multiple processes within UNIX consisted of a few (fixed number of) processes, one per terminal that was attached to the PDP-7 machine (b).
The basic idea was that the shell process for a given terminal would accept a command from the user, locate the program file, load a small bootstrap program into high memory and jump to it, passing enough details for the bootstrap code to load the program file.
The bootstrap code, after loading the program into low memory (overwriting the shell), would then jump to it.
When the program was finished, it would call exit but it wasn't like the exit we know and love today. This exit would simply reload the shell and run it using pretty much the same method used to load the program in the first place.
So it was really more like a rudimentary exec command, the one that replaces your current program with another, in the same process space.
The shell would exec your program then, when your program was done, it would again exec the shell by calling exit.
This method was similar to that found in many other interactive systems at the time, including the Multics from whence UNIX got its name.
From the two-way exec, it was actually not that big a leap to adding fork as a process duplicator to work in conjunction. While many systems run another program directly, it's this "just add what's needed" method which is responsible for the separation of duties between fork and exec in UNIX. It also resulted in a very simple fork function.
If you're interested in the early history of various features(c) of Unix, you cannot go past the article The Evolution of the Unix Time-Sharing System by Dennis Ritchie, presented at a 1979 conference in Australia, and subsequently published by AT&T.
(a) Though I mean latecomer in the sense that the separation of the four fundamental forces in the universe was "late", happening some 0.00000000001 seconds after the big bang.</humour>.
(b) Since a question was raised in a comment as to how the shells were originally started off, there's a great resource holding very early source code for Unix over at The Unix Heritage Society, specifically the source code archives and, in particular, the first edition.
The init.s file from the first edition shows how the fixed number of shell processes were created (slightly reformatted):
...
mov $itab, r1 / address of table to r1
1:
mov (r1)+, r0 / 'x, x=0, 1... to r0
beq 1f / branch if table end
movb r0, ttyx+8 / put symbol in ttyx
jsr pc, dfork / go to make new init for this ttyx
mov r0, (r1)+ / save child id in word offer '0, '1, etc
br 1b / set up next child
1:
...
itab:
'0; ..
'1; ..
'2; ..
'3; ..
'4; ..
'5; ..
'6; ..
'7; ..
0
Here you can see the snippet which creates the processes for each connected terminal. These are the days of hard-coded values, no auto detection of terminal quantity involved. The zero-terminated table at itab is used to create a number of processes and hopefully the comments from the code explain how (the only possibly tricky bit is the labels - though there are multiple 1 labels, you branch to the nearest one in a given direction, hence 1b means the closest 1 label in the backwards direction).
The code shown simply processes the table, calling dfork to create a process for each terminal and start getty, the login prompt. The getty program, in turn, eventually started the shell. From that point, it's as I described in the main part of this answer.
(c) No paths (and use of temporary links to get around this limitation), limited processes, why there's a GECOS field in the password file, and all sorts of other trivia, generally interesting only to uber-geeks, of course.

Resources