MIPS assembler complains about "Branch out of range" with PIC

Seva Alekseyev

I'm trying to build an assembly source file for Android/MIPSEL32. It's a test case for a weird Pascal compiler issue; but the bug might be in assembler after all.

How does the MIPS assembler implement the j command in PIC mode? I have a j-to-label statement, where the label is 184200 bytes away from the current instruction; when assembling in PIC mode, the assembler errors out:

 a.s:67: Error: Branch out of range

My trusty MIPS manual says that j takes an absolute offset, applied within a 256-MB block. The size of the whole code block is much less than 256 MB. I don't see what's wrong with this j. When not compiling for PIC, it works as expected. And why is talking about a branch? Branch and jump are explicitly distinct on MIPS.

The PC-relative offset would be 18 bits long in this case. Can't help noticing that it's just above the limit for the b. Would the assembler quietly convert j to b in PIC mode? It's not unheard of that an assembler-level command is implemented as a macro with the same name as the underlying architectural command. But there's a set .nomacro in the function prologue, isn't there?

Please explain, and maybe offer a workaround. I don't mind an additional step of scripted assembly fixup on the build path.

A similar problem is discussed here, here, here.

For the sake of repro steps, the assembly source goes like this:

.section .text.n_main
.balign 4
.globl  PASCALMAIN
.type   PASCALMAIN,@function
PASCALMAIN:
.globl  main
.type   main,@function
main:
.ent main
.set    nomips16
.frame  $sp,112,$ra
.mask   0xC0010000,-40
.fmask  0x00000000,0
.set    noreorder
.cpload $t9
.set    nomacro
addiu   $sp,$sp,-112
sw  $ra,72($sp)
sw  $fp,68($sp)
addiu   $fp,$sp,112
.cprestore  104
sw  $s0,64($sp)
lw  $t9,%call16(FPC_INITIALIZEUNITS)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
lw  $t9,%call16(fpc_get_input)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
move    $s0,$v0
lw  $a1,%got(U_$P$A_$$_S)($gp)
addiu   $a1,$a1,%lo(U_$P$A_$$_S)
move    $a0,$s0
addiu   $a2,$zero,255
lw  $t9,%call16(fpc_read_text_shortstr)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
lw  $t9,%call16(FPC_IOCHECK)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
move    $a0,$s0
lw  $t9,%call16(fpc_readln_end)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
lw  $t9,%call16(FPC_IOCHECK)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
lw  $v0,%got(U_$P$A_$$_I)($gp)
sw  $zero,%lo(U_$P$A_$$_I)($v0)
lw  $v0,%got(U_$P$A_$$_S)($gp)
lbu $v0,%lo(U_$P$A_$$_S)($v0)
beq $v0,$zero,.Lj15
nop
# fixup_jmps, A_BA changed into A_J
j   .Lj16
nop
.Lj15:
##### Then there's the following fragment, repeated 9210 times:
lw  $v0,%got(U_$P$A_$$_I)($gp)
lw  $v1,%lo(U_$P$A_$$_I)($v0)
addiu   $v1,$v1,1
lw  $v0,%got(U_$P$A_$$_I)($gp)
sw  $v1,%lo(U_$P$A_$$_I)($v0)
##### End of repeating fragment
.Lj16:
lw  $t9,%call16(FPC_DO_EXIT)($gp)
jalr    $t9
nop
lw  $gp,104($sp)
lw  $s0,64($sp)
lw  $fp,68($sp)
lw  $ra,72($sp)
jr  $ra
addiu   $sp,$sp,112
.set    macro
.set    reorder
.end main

The assembler invokation command is:

mipsel-linux-android-as.exe -mabi=32 -march=mips32 -W -EL -KPIC -o a.o a.s

EDIT: the Free Pascal folks have fixed the underlying issue. Now this should not arise, at least not in this particular context.

Seva Alekseyev

EDIT: the Free Pascal folks have fixed the issue, my thanks to them. The workaround below is not necessary anymore for this particular case, but might be of interest to others affected.


Lame workaround: I scan the assembly, for every j where the target label is more than 32000 lines away, I replace with the following:

la $t9, TargetLabel
jr $t9

At least the assembler does not complain anymore. And I still have to find a cite regarding the j/b substitution.

EDIT: la is implemented as a macro. The assembler replaces it, in PIC mode, with something along the lines of:

lw $t9, CurrentFunctionsBase($gp)
addiu $t9, $t9, OffsetWithinFunction

Probably more than that if the offset is large. So it's PIC friendly.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Assembler Messages: Branch out of range

From Dev

PHPUnit complains about Selenium

From Dev

PHPUnit complains about Selenium

From Dev

Gradle complains about bracket

From Dev

MARS, MIPS assembler, linking two files together?

From Dev

Attempt to execute non-instruction in mips assembler?

From Dev

how to write octal constants in MIPS (MARS assembler)

From Dev

Is all MIPS code on Linux supposed to be PIC?

From Dev

fltk complains about gcc on windows

From Dev

Linker complains about missing -fPIC

From Dev

Why isn't the bits shifting in this PIC assembler code?

From Dev

Why MIPS assembler has more that one register for return value?

From Dev

Xcode complains about Unused functions that are used

From Dev

split now complains about missing "isSeparator"

From Dev

embedFonts complains about “Unknown device: pswrite”

From Dev

Aida Web install complains about missing "SecureHashAlgorithm"

From Dev

GHC complains about overlapping instances when in fact they are not

From Dev

PyCharm complains about patch.object but why?

From Dev

Spyder complains about some basic commands

From Dev

ggplot complains about applying code to the data

From Dev

Juicy Pixels complains about not having enough memory

From Dev

Doxygen complains about recursive C++ class

From Dev

Stringer tool complains about wrong archive header

From Dev

Why Netbeans complains about "incorrect credentials" with Git?

From Dev

Tuple struct constructor complains about private fields

From Dev

ESlint Airbnb Config Complains about Quotes

From Dev

Sonar complains about Spring Boot configuration

From Dev

Jacoco complains about unlikely missing branch coverage

From Dev

Pylint complains about comparing a string to a literal with 'is'

Related Related

  1. 1

    Assembler Messages: Branch out of range

  2. 2

    PHPUnit complains about Selenium

  3. 3

    PHPUnit complains about Selenium

  4. 4

    Gradle complains about bracket

  5. 5

    MARS, MIPS assembler, linking two files together?

  6. 6

    Attempt to execute non-instruction in mips assembler?

  7. 7

    how to write octal constants in MIPS (MARS assembler)

  8. 8

    Is all MIPS code on Linux supposed to be PIC?

  9. 9

    fltk complains about gcc on windows

  10. 10

    Linker complains about missing -fPIC

  11. 11

    Why isn't the bits shifting in this PIC assembler code?

  12. 12

    Why MIPS assembler has more that one register for return value?

  13. 13

    Xcode complains about Unused functions that are used

  14. 14

    split now complains about missing "isSeparator"

  15. 15

    embedFonts complains about “Unknown device: pswrite”

  16. 16

    Aida Web install complains about missing "SecureHashAlgorithm"

  17. 17

    GHC complains about overlapping instances when in fact they are not

  18. 18

    PyCharm complains about patch.object but why?

  19. 19

    Spyder complains about some basic commands

  20. 20

    ggplot complains about applying code to the data

  21. 21

    Juicy Pixels complains about not having enough memory

  22. 22

    Doxygen complains about recursive C++ class

  23. 23

    Stringer tool complains about wrong archive header

  24. 24

    Why Netbeans complains about "incorrect credentials" with Git?

  25. 25

    Tuple struct constructor complains about private fields

  26. 26

    ESlint Airbnb Config Complains about Quotes

  27. 27

    Sonar complains about Spring Boot configuration

  28. 28

    Jacoco complains about unlikely missing branch coverage

  29. 29

    Pylint complains about comparing a string to a literal with 'is'

HotTag

Archive