Skip to content

Commit a1bbf7e

Browse files
committed
Initial LoongArch64 support
Signed-off-by: Bingwu Zhang <[email protected]>
1 parent cff58e1 commit a1bbf7e

File tree

30 files changed

+3515
-37
lines changed

30 files changed

+3515
-37
lines changed

.github/workflows/ci.yml

+8-7
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
run: |
3737
git fetch origin
3838
git log --oneline --graph -10
39-
39+
4040
- name: Fix libcdb-cache permissions
4141
id: fix-perms
4242
run: |
@@ -66,7 +66,7 @@ jobs:
6666
sudo apt-get update && sudo apt-get install -y python3-pip gdb gdbserver
6767
/usr/bin/python -m pip install --break-system-packages rpyc || /usr/bin/python -m pip install rpyc
6868
gdb --batch --quiet --nx --nh --ex 'py import rpyc; print(rpyc.version.version)'
69-
69+
7070
- name: Cache for pip
7171
uses: actions/cache@v4
7272
if: matrix.python_version == '2.7'
@@ -113,6 +113,7 @@ jobs:
113113
- name: Install Linux dependencies
114114
run: |
115115
sudo apt-get update
116+
# binutils-loongarch64-linux-gnu is not in Ubuntu 22.04
116117
sudo apt-get install -y --no-install-recommends -o Acquire::Retries=3 \
117118
ash bash-static dash ksh mksh zsh \
118119
gdb gdbserver socat \
@@ -129,7 +130,7 @@ jobs:
129130
libc6-dbg \
130131
elfutils \
131132
patchelf
132-
133+
133134
- name: Testing Corefiles
134135
run: |
135136
ulimit -a
@@ -260,7 +261,7 @@ jobs:
260261
name: coverage-${{ matrix.python_version }}
261262
path: .coverage*
262263
include-hidden-files: true
263-
264+
264265
- name: Fix libcdb-cache permissions
265266
run: |
266267
container_id=$(docker ps --filter volume=/home/runner/libcdb-cache --no-trunc --format "{{.ID}}")
@@ -283,15 +284,15 @@ jobs:
283284
run: |
284285
pip install --upgrade pip
285286
pip install --upgrade --editable .
286-
287+
287288
- name: Install documentation dependencies
288289
run: pip install -r docs/requirements.txt
289-
290+
290291
- name: Sanity checks
291292
run: |
292293
python -bb -c 'from pwn import *'
293294
python -bb examples/text.py
294-
295+
295296
- name: Coverage doctests
296297
run: |
297298
python -bb -m coverage run -m sphinx -b doctest docs/source docs/build/doctest

CHANGELOG.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,14 @@ The table below shows which release corresponds to each branch, and what date th
7979
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
8080
- [#2526][2526] Properly make use of extra arguments in `packing` utilities. `sign` parameter requires keyword syntax to specify it.
8181
- [#2517][2517] Allow to passthru kwargs on `ssh.__getattr__` convenience function to fix SSH motd problems
82+
- [#2529][2529] Add LoongArch64 support
8283

8384
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
8485
[2522]: https://github.com/Gallopsled/pwntools/pull/2522
8586
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
8687
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
8788
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
89+
[2529]: https://github.com/Gallopsled/pwntools/pull/2529
8890

8991
## 4.15.0 (`beta`)
9092
- [#2508][2508] Ignore a warning when compiling with asm on nix
@@ -194,7 +196,7 @@ The table below shows which release corresponds to each branch, and what date th
194196
- [#2308][2308] Fix WinExec shellcraft to make sure it's 16 byte aligned
195197
- [#2279][2279] Make `pwn template` always set context.binary
196198
- [#2310][2310] Add support to start a process on Windows
197-
- [#2335][2335] Add lookup optimizations in DynELF
199+
- [#2335][2335] Add lookup optimizations in DynELF
198200
- [#2334][2334] Speed up disasm commandline tool with colored output
199201
- [#2328][2328] Lookup using $PATHEXT file extensions in `which` on Windows
200202
- [#2189][2189] Explicitly define p64/u64 functions for IDE support
@@ -281,7 +283,7 @@ The table below shows which release corresponds to each branch, and what date th
281283

282284
## 4.11.0
283285

284-
- [#2185][2185] make fmtstr module able to create payload without $ notation
286+
- [#2185][2185] make fmtstr module able to create payload without $ notation
285287
- [#2103][2103] Add search for libc binary by leaked function addresses `libcdb.search_by_symbol_offsets()`
286288
- [#2177][2177] Support for RISC-V 64-bit architecture
287289
- [#2186][2186] Enhance `ELF.nx` and `ELF.execstack`
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.. testsetup:: *
2+
3+
from pwn import *
4+
context.clear(arch='loongarch64')
5+
6+
import doctest
7+
doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']
8+
9+
:mod:`pwnlib.shellcraft.loongarch64` --- Shellcode for LoongArch64
10+
==========================================================
11+
12+
:mod:`pwnlib.shellcraft.loongarch64`
13+
--------------------------------
14+
15+
.. automodule:: pwnlib.shellcraft.loongarch64
16+
:members:
17+
18+
:mod:`pwnlib.shellcraft.loongarch64.linux`
19+
--------------------------------------
20+
21+
.. automodule:: pwnlib.shellcraft.loongarch64.linux
22+
:members:

extra/docker/base/Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Based on Ubuntu
44
############################################################
55

6-
FROM ubuntu:jammy
6+
FROM ubuntu:noble
77
MAINTAINER Maintainer Gallopsled et al.
88

99
ENV LANG en_US.UTF-8
@@ -36,6 +36,7 @@ RUN apt-get update \
3636
binutils-powerpc64-linux-gnu \
3737
binutils-sparc64-linux-gnu \
3838
binutils-riscv64-linux-gnu \
39+
binutils-loongarch64-linux-gnu \
3940
tmux \
4041
patchelf \
4142
&& locale-gen en_US.UTF-8 \

pwnlib/abi.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ class ABI(object):
2727
#: Indicates that this ABI returns to the next address on the slot
2828
returns = True
2929

30-
def __init__(self, stack, regs, align, minimum):
30+
def __init__(self, stack, arg_regs, align, minimum):
3131
self.stack = stack
32-
self.register_arguments = regs
32+
self.register_arguments = arg_regs
3333
self.arg_alignment = align
3434
self.stack_minimum = minimum
3535

@@ -50,6 +50,7 @@ def default():
5050
(64, 'powerpc', 'linux'): linux_ppc64,
5151
(32, 'riscv32', 'linux'): linux_riscv32,
5252
(64, 'riscv64', 'linux'): linux_riscv64,
53+
(64, 'loongarch64', 'linux'): linux_loongarch64,
5354
(32, 'i386', 'freebsd'): freebsd_i386,
5455
(64, 'aarch64', 'freebsd'): freebsd_aarch64,
5556
(64, 'amd64', 'freebsd'): freebsd_amd64,
@@ -82,6 +83,7 @@ def syscall():
8283
(64, 'powerpc', 'linux'): linux_ppc64_syscall,
8384
(32, 'riscv32', 'linux'): linux_riscv32_syscall,
8485
(64, 'riscv64', 'linux'): linux_riscv64_syscall,
86+
(64, 'loongarch64', 'linux'): linux_loongarch64_syscall,
8587
(32, 'i386', 'freebsd'): freebsd_i386_syscall,
8688
(64, 'amd64', 'freebsd'): freebsd_amd64_syscall,
8789
(64, 'aarch64', 'freebsd'): freebsd_aarch64_syscall,
@@ -109,6 +111,7 @@ def sigreturn():
109111
(64, 'aarch64', 'linux'): linux_aarch64_sigreturn,
110112
(32, 'riscv32', 'linux'): linux_riscv32_sigreturn,
111113
(64, 'riscv64', 'linux'): linux_riscv64_sigreturn,
114+
(64, 'loongarch64', 'linux'): linux_loongarch64_sigreturn,
112115
(32, 'i386', 'freebsd'): freebsd_i386_sigreturn,
113116
(64, 'amd64', 'freebsd'): freebsd_amd64_sigreturn,
114117
(32, 'arm', 'freebsd'): freebsd_arm_sigreturn,
@@ -148,6 +151,7 @@ class SigreturnABI(SyscallABI):
148151
linux_ppc64 = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 8, 0)
149152
linux_riscv32 = ABI('sp', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], 8, 0)
150153
linux_riscv64 = ABI('sp', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], 8, 0)
154+
linux_loongarch64 = ABI('sp', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], 8, 0)
151155

152156
sysv_i386 = linux_i386
153157
sysv_amd64 = linux_amd64
@@ -158,6 +162,7 @@ class SigreturnABI(SyscallABI):
158162
sysv_ppc64 = linux_ppc64
159163
sysv_riscv32 = linux_riscv32
160164
sysv_riscv64 = linux_riscv64
165+
sysv_loongarch64 = linux_loongarch64
161166

162167
# Docs: https://man7.org/linux/man-pages/man2/syscall.2.html
163168
linux_i386_syscall = SyscallABI('esp', ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'], 4, 0)
@@ -169,20 +174,23 @@ class SigreturnABI(SyscallABI):
169174
linux_ppc64_syscall = SyscallABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8'], 8, 0)
170175
linux_riscv32_syscall = SyscallABI('sp', ['a7', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5'], 4, 0)
171176
linux_riscv64_syscall = SyscallABI('sp', ['a7', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5'], 8, 0)
177+
linux_loongarch64_syscall = SyscallABI('sp', ['a7', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6'], 8, 0)
172178

173179
linux_i386_sigreturn = SigreturnABI('esp', ['eax'], 4, 0)
174180
linux_amd64_sigreturn = SigreturnABI('rsp', ['rax'], 8, 0)
175181
linux_arm_sigreturn = SigreturnABI('sp', ['r7'], 4, 0)
176182
linux_aarch64_sigreturn = SigreturnABI('sp', ['x8'], 16, 0)
177183
linux_riscv32_sigreturn = SigreturnABI('sp', ['a7'], 4, 0)
178184
linux_riscv64_sigreturn = SigreturnABI('sp', ['a7'], 8, 0)
185+
linux_loongarch64_sigreturn = SigreturnABI('sp', ['a7'], 8, 0)
179186

180187
sysv_i386_sigreturn = linux_i386_sigreturn
181188
sysv_amd64_sigreturn = linux_amd64_sigreturn
182189
sysv_arm_sigreturn = linux_arm_sigreturn
183190
sysv_aarch64_sigreturn = linux_aarch64_sigreturn
184191
sysv_riscv32_sigreturn = linux_riscv32_sigreturn
185192
sysv_riscv64_sigreturn = linux_riscv64_sigreturn
193+
sysv_loongarch64_sigreturn = linux_loongarch64_sigreturn
186194

187195
freebsd_i386 = sysv_i386
188196
freebsd_amd64 = sysv_amd64

pwnlib/asm.py

+6
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def which_binutils(util, check_version=False):
190190
'sparc64': ['sparc'],
191191
'riscv32': ['riscv32', 'riscv64', 'riscv'],
192192
'riscv64': ['riscv64', 'riscv32', 'riscv'],
193+
'loongarch64': ['loongarch64', 'loong64'],
193194
}.get(arch, [])
194195

195196
# If one of the candidate architectures matches the native
@@ -275,6 +276,9 @@ def _assembler():
275276
# riscv64-unknown-elf-as supports riscv32 as well as riscv64
276277
'riscv32': [gas, '-march=rv32gc', '-mabi=ilp32'],
277278
'riscv64': [gas, '-march=rv64gc', '-mabi=lp64'],
279+
280+
# loongarch64 supports none of -64, -EB, -EL or -march
281+
'loongarch64' : [gas],
278282
}
279283

280284
assembler = assemblers.get(context.arch, [gas])
@@ -376,6 +380,7 @@ def _bfdname():
376380
'powerpc64' : 'elf64-powerpc',
377381
'riscv32' : 'elf%d-%sriscv' % (context.bits, E),
378382
'riscv64' : 'elf%d-%sriscv' % (context.bits, E),
383+
'loongarch64' : 'elf%d-loongarch' % context.bits,
379384
'vax' : 'elf32-vax',
380385
's390' : 'elf%d-s390' % context.bits,
381386
'sparc' : 'elf32-sparc',
@@ -400,6 +405,7 @@ def _bfdarch():
400405
'thumb': 'arm',
401406
'riscv32': 'riscv',
402407
'riscv64': 'riscv',
408+
'loongarch64': 'loongarch64'
403409
}
404410

405411
if arch in convert:

0 commit comments

Comments
 (0)