VOGONS

Common searches


First post, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie

Trying to better understand MS-DOS executable headers and what relocation items are I looked at the DOSBox source code and found this in the .\dosbox\src\dos\dos_execute.cpp file:

		pos=head.reloctable;DOS_SeekFile(fhandle,&pos,0);
for (i=0;i<head.relocations;i++) {
readsize=4;DOS_ReadFile(fhandle,(Bit8u *)&relocpt,&readsize);
relocpt=host_readd((HostPt)&relocpt); //Endianize
PhysPt address=PhysMake(RealSeg(relocpt)+loadseg,RealOff(relocpt));
mem_writew(address,mem_readw(address)+relocate);
}
}

As far as I understand C++ it's iterating through each relocation item in the header and calling a function called "PhysMake". What exactly is going on in the above code?

Do not read if you don't like attention seeking self-advertisements!

Did you read it anyway? Well, you can find all sorts of stuff I made using various programming languages over here:
https://github.com/peterswinkels

Reply 1 of 3, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

When the executable is built it doesn't know what its base address will be when it gets run. So a lot of memory references in the code are placeholder values ("relocations") that have to be corrected when DOS loads the program.

Reply 2 of 3, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie
jmarsh wrote on 2020-04-20, 12:31:

When the executable is built it doesn't know what its base address will be when it gets run. So a lot of memory references in the code are placeholder values ("relocations") that have to be corrected when DOS loads the program.

Can you be more specific? Are the relocation items in the header the addresses of these place holders? How are these placeholder values modified?

Do not read if you don't like attention seeking self-advertisements!

Did you read it anyway? Well, you can find all sorts of stuff I made using various programming languages over here:
https://github.com/peterswinkels

Reply 3 of 3, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie

Here is some vb.net code I wrote in attempt to interpret an executable's (meant for MS-DOS) relocation table:

Option Compare Binary
Option Explicit On
Option Infer Off
Option Strict On

Imports System
Imports System.IO

Public Module Module1
'This enumeration list the MS-DOS executable header's items.
Public Enum MSDOSHeaderE As Integer
Signature = &H0% 'The MS-DOS executable's signature.
ImageSizeModulo = &H2% 'The executable's image size modulo of 0x200 bytes.
ImageSize = &H4% 'The executable's image size in pages of 0x200 bytes.
RelocationCount = &H6% 'The executable's number or relocation items.
HeaderSize = &H8% 'The executable's header size in paragraphs of 0x10 bytes.
MinimumParagraphs = &HA% 'The executable's minimum memory requirement in paragraphs of 0x10 bytes.
MaximumParagraphs = &HC% 'The executable's maximum memory requirement in paragraphs of 0x10 bytes.
StackSegment = &HE% 'The stack segment (SS) register's initial value.
StackPointer = &H10% 'The stack pointer (SP) register's initial value.
Checksum = &H12% 'The executable's negative pgm checksum.
InstructionPointer = &H14% 'The instruction pointer (IP) register's initial value.
CodeSegment = &H16% 'The code segment (CS) register's initial value.
RelocationTableOffset = &H18% 'The relocation table's offset.
OverlayNumber = &H1A% 'The overlay number.
End Enum

Public Sub Main()
Dim Executable() As Byte = File.ReadAllBytes("D:\Other\Cartoons.exe")
Dim StartOfTable As Integer = GetWord(Executable, MSDOSHeaderE.RelocationTableOffset)
Dim RelocationItemCount As Integer = GetWord(Executable, MSDOSHeaderE.RelocationCount)
Dim EndOfTable As Integer = (RelocationItemCount * &H4%) + StartOfTable
Dim Position As Integer = StartOfTable
Dim RelocationItemPosition As New Integer

For Index As Integer = &H0% To RelocationItemCount - &H1%
RelocationItemPosition = EndOfTable + GetWord(Executable, Position) + (GetWord(Executable, Position + &H2%) << &H4%)
Console.WriteLine(RelocationItemPosition)
Position += &H4%
Next Index
End Sub

Private Function GetWord(Data() As Byte, Address As Integer) As Integer
Return Data(Address) Or (CInt(Data(Address + &H1%)) << &H8%)
End Function
End Module

Is this the proper way to go about it?

Do not read if you don't like attention seeking self-advertisements!

Did you read it anyway? Well, you can find all sorts of stuff I made using various programming languages over here:
https://github.com/peterswinkels