Skip to content

Commit

Permalink
RISC-V: add R_RISCV_CALL_PLT relocation
Browse files Browse the repository at this point in the history
  • Loading branch information
janvrany committed Jun 21, 2024
1 parent 5dd77a4 commit d6c5014
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/ArchC-Core/AcRelocation.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ AcRelocation >> address: anIntegerOrNil [
address := anIntegerOrNil.
]

{ #category : #processing }
AcRelocation >> calculate: finalAddress [
self subclassResponsibility
]

{ #category : #'printing & storing' }
AcRelocation >> disassembleOn: aStream [
aStream nextPutAll: self class name.
Expand All @@ -72,6 +77,16 @@ AcRelocation >> disassembleOn: aStream [
].
]

{ #category : #processing }
AcRelocation >> fixupBinaryCode: memory finalAddress: finalAddress [
self fixupBinaryCode: memory value: (self calculate: finalAddress).
]

{ #category : #processing }
AcRelocation >> fixupBinaryCode: memory value: value [
self subclassResponsibility
]

{ #category : #processing }
AcRelocation >> fixupCode: bytes address: finalAddress [
self subclassResponsibility
Expand Down
30 changes: 30 additions & 0 deletions src/ArchC-Core/ByteArray.extension.st
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
Extension { #name : #ByteArray }

{ #category : #'*ArchC-Core' }
ByteArray >> bitAnd: aByteArray [
| answer |

answer := self copy.
1 to: (self size min: aByteArray size) do: [ :i |
answer at: i put: ((self at: i) bitAnd: (aByteArray at: i))
].
^ answer

"
#[0 255 0 255] bitAnd: #[255 0 255 0]
"
]

{ #category : #'*ArchC-Core' }
ByteArray >> bitOr: aByteArray [
| answer |

answer := self copy.
1 to: (self size min: aByteArray size) do: [ :i |
answer at: i put: ((self at: i) bitOr: (aByteArray at: i))
].
^ answer

"
#[0 255 0 255] bitOr: #[255 0 255 0]
"
]

{ #category : #'*ArchC-Core' }
ByteArray >> toBitVector: xlen endian: endian startingAt: startIndex [
self assert: (xlen \\ 8) == 0.
Expand Down
59 changes: 59 additions & 0 deletions src/ArchC-RISCV/R_RISCV_CALL_PLT.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Class {
#name : #'R_RISCV_CALL_PLT',
#superclass : #AcRelocation,
#pools : [
'AcIntLimits',
'AcRISCVISALimits'
],
#category : #'ArchC-RISCV-Relocations'
}

{ #category : #queries }
R_RISCV_CALL_PLT class >> isValidForInstruction: insn [
^ insn name = 'auipc'
]

{ #category : #processing }
R_RISCV_CALL_PLT >> calculate: finalAddress [
"
S + A - P
S = finalAddress # Value of the symbol in the symbol table
A = addend # Addend field in the relocation entry associated with the symbol
P = address # Position of the relocation
See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#relocations
"

| value |

value := finalAddress + addend - address.
(value between: INT32_MIN and: INT32_MAX) ifFalse:[
"We better throw OverflowError but it does not exist in Pharo, sign"
self error: 'Relocated value overflow / underflow'.
].
^ value
]

{ #category : #processing }
R_RISCV_CALL_PLT >> fixupBinaryCode: memory value: value [
| lo hi code imms |

lo := value & (16rFFFFFFFF << RISCV_IMM_BITS) bitInvert32.
hi := value & (16rFFFFFFFF << RISCV_IMM_BITS).

(lo & (1 << (RISCV_IMM_BITS - 1))) ~~ 0 ifTrue: [
hi := hi + (1 << RISCV_IMM_BITS).
].

imms := ByteArray new: 8.
imms unsignedLongAt: 1 put: hi bigEndian: false.
imms unsignedLongAt: 5 put: lo << RISCV_IMM_SHIFT bigEndian: false.

code := memory copyFrom: address to: address + 4"auipc" + 4"jalr".
code := code bitOr: imms.
memory replaceFrom: address to: address + 4"auipc" + 4"jalr" - 1 with: code.
"
AcProcessorDescriptions riscv64 decode: code
"
]

0 comments on commit d6c5014

Please sign in to comment.