A Long Digression
I once tried to write to write a BASIC machine language subroutine
for the San Leandro Computer Club (SLCC).  The program was to wordwrap
lines to fit the 8-bit ATARI's 40 column screen.  I wanted it to be
fast and bi-directional.  And I found out it's true: pride does cometh
before the fall.

Some of the jumps were large, so I made chain of little islands to reach
a routine.  The islands consisted of a branch and another branch around
it.  This is an example of an island that had to be embedded in the code.

As the program grew, the islands had to be moved as the code I wrote
pushed the islands beyond the 128 byte barrier.

When I ran the wordwrap program without BASIC, it worked.  I used a BASIC
program, BINSTRIN, that I had written, to convert the wordwrap program to
BASIC strings, and then I merged it with the SLCC BASIC program.  When I
would run the SLCC BASIC program, it would always crash when my assembly
language subroutine was executed.

I found out much later that the MAC/65 assembler assembles files in 256
byte portions.  As BINSTRIN converted the binary files to BASIC strings
it discarded the initial $FFFF; it calculated the first addresses ok but
copied the following addresses along with the code.  No wonder the
program crashed.
Atari Binary File Stucture
SALB = start address low byte
SAHB = start address high byte
EALB = end address low byte
EAHB = end address high byte

This disaster doesn't have anything to do with relocatable code but I kept
thinking about those horrible island chains.  Later I was looking at the
code in "SpeedScript, The Word Processor for Atari Computers, by Charles
Brannon, Compute! Publications, Inc."  On page 78, a RTS is used to
simulate BASIC's ON-GOTO.  This was really an eye-opener.  A RTS used
as a jump instead of a return.  This and those islands gave me the
idea to use RTS for relocatable JMPs and JSRs.