Skip to content

Commit

Permalink
add aarch64 build process
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonk000 committed Jan 22, 2024
1 parent f97adc1 commit 5d3933e
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 69 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Build linux

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3

- name: Install libelf and gdb
run: sudo apt-get install -y libelf-dev libelf1 gdb

- name: Set up hugepages
run: sudo sh -c "echo 200 > /proc/sys/vm/nr_hugepages"

- name: Build
run: cargo build

- name: Run tests
run: cargo test

- name: Run integration tests x86_64
run: sudo -E /home/${USER}/.cargo/bin/cargo test --no-fail-fast -- --include-ignored

build-for-aarch64:
runs-on: ubuntu-22.04

steps:
- name: Checkout code
uses: actions/checkout@v4

- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
corepipe/target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: build in arm64 container
uses: uraimo/[email protected]
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update -q -y
apt-get upgrade -y
apt-get install -q -y git curl rust-all libelf-dev libelf1 gdb gcc
run: |
cargo build
cargo test
cargo test --no-fail-fast -- --include-ignored
31 changes: 0 additions & 31 deletions .github/workflows/rust.yml

This file was deleted.

97 changes: 63 additions & 34 deletions src/elfmachine_aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,40 @@ use std::mem::size_of;
use anyhow::Context;
use libc::{user_fpsimd_struct, user_regs_struct, siginfo_t};
use libelf_sys::{Elf64_Half, EM_AARCH64, NT_SIGINFO, NT_PRFPREG, NT_PRSTATUS, NT_ARM_PAC_MASK};
use log::trace;
use procfs::process::{Task, Process};

use crate::{write_elf::{ElfNote, ElfNoteSpec, NOTE_NAME_CORE, NOTE_NAME_LINUX}, ptrace::{ptrace_getsiginfo, ptrace_get_regset}, linux::{Prstatus, load_prstatus_for_task}, byte_helpers::prstatus_to_bytes};

pub const ELF_MACHINE_ID: Elf64_Half = EM_AARCH64 as Elf64_Half;

pub fn collect_per_task_note_specs(_process: &Process) -> Result<Vec<ElfNoteSpec>, Box<dyn std::error::Error>> {
Ok(vec![
ElfNoteSpec{size: size_of::<Prstatus>()},
ElfNoteSpec{size: size_of::<user_fpsimd_struct>()},
ElfNoteSpec{size: 16},
ElfNoteSpec{size: size_of::<siginfo_t>()},
])
pub fn collect_per_task_note_specs(process: &Process) -> Result<Vec<ElfNoteSpec>, Box<dyn std::error::Error>> {
let main_thread = process
.task_main_thread()
.context("failed to read task_main_thread for pid")?;

let pac_mask_result = ptrace_get_regset(&main_thread, NT_ARM_PAC_MASK, 16);

let result = match pac_mask_result {
Ok(_) => {
vec![
ElfNoteSpec{size: size_of::<Prstatus>()},
ElfNoteSpec{size: size_of::<user_fpsimd_struct>()},
ElfNoteSpec{size: 16}, // pac mask
ElfNoteSpec{size: size_of::<siginfo_t>()},
]
},
Err(_) => {
trace!("pac mask area not available");
vec![
ElfNoteSpec{size: size_of::<Prstatus>()},
ElfNoteSpec{size: size_of::<user_fpsimd_struct>()},
ElfNoteSpec{size: size_of::<siginfo_t>()},
]
},
};

Ok(result)
}

pub fn collect_task_notes(task: &Task) -> Result<Vec<ElfNote>, Box<dyn std::error::Error>> {
Expand All @@ -37,33 +58,41 @@ pub fn collect_task_notes(task: &Task) -> Result<Vec<ElfNote>, Box<dyn std::erro
.context("load_prstatus_for_task")?;
let prstatus_v = prstatus_to_bytes(&prstatus).to_vec();

let pac_mask = ptrace_get_regset(task, NT_ARM_PAC_MASK, 16)
.context("ARM PAC mask thread")?.unwrap();
let pac_mask_result = ptrace_get_regset(task, NT_ARM_PAC_MASK, 16);

Ok(vec![
ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_PRSTATUS,
description: prstatus_v,
friendly: "thread user_regs_struct",
},
ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_PRFPREG,
description: fpregs,
friendly: "thread user_fpsimd_struct",
},
ElfNote {
note_name: NOTE_NAME_LINUX,
note_type: NT_ARM_PAC_MASK,
description: pac_mask,
friendly: "thread user_fpsimd_struct",
},
ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_SIGINFO,
description: siginfo,
friendly: "thread siginfo",
let mut result = vec![];

result.push(ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_PRSTATUS,
description: prstatus_v,
friendly: "thread user_regs_struct",
});
result.push(ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_PRFPREG,
description: fpregs,
friendly: "thread user_fpsimd_struct",
});

match pac_mask_result {
Ok(Some(pac_mask)) => {
result.push(ElfNote {
note_name: NOTE_NAME_LINUX,
note_type: NT_ARM_PAC_MASK,
description: pac_mask,
friendly: "thread user_fpsimd_struct",
});
},
])
_ => {},
}

result.push(ElfNote {
note_name: NOTE_NAME_CORE,
note_type: NT_SIGINFO,
description: siginfo,
friendly: "thread siginfo",
});

Ok(result)
}
6 changes: 3 additions & 3 deletions testbins/test-workload/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn main() {
fn loop_on_stack(_magic: i32) {
eprintln!("loop_on_stack with magic value: {}", _magic);
loop {
thread::yield_now();
thread::sleep_ms(10);
}
}

Expand All @@ -74,7 +74,7 @@ fn loop_on_stack(_magic: i32) {
fn loop_on_heap(_magic: Box<i32>) {
eprintln!("loop_on_heap with magic value: {}", _magic);
loop {
thread::yield_now();
thread::sleep_ms(10);
}
}

Expand Down Expand Up @@ -114,7 +114,7 @@ fn multiple_page_test(_magic: String, _nomagic: String) {
eprintln!("magic pointer: {:p}", hugemap.as_ptr());

loop {
thread::yield_now();
thread::sleep_ms(10);
}
}

Expand Down
2 changes: 2 additions & 0 deletions tests/dump_multiple_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use test_binary::build_test_binary;
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_can_read_large_page() -> Result<(), io::Error> {
let test_bin_path =
build_test_binary("test-workload", "testbins").expect("error building test-workload");
Expand Down Expand Up @@ -88,6 +89,7 @@ fn test_can_read_large_page() -> Result<(), io::Error> {
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_cannot_read_dont_dump_page() -> Result<(), io::Error> {
let test_bin_path =
build_test_binary("test-workload", "testbins").expect("error building test-workload");
Expand Down
1 change: 1 addition & 0 deletions tests/dump_multiple_threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use test_binary::build_test_binary;

#[test]
#[ignore]
#[cfg(not(target_arch="aarch64"))]
fn test_can_read_stack_on_multiple_threads() -> Result<(), io::Error> {
let test_bin_path =
build_test_binary("test-workload", "testbins").expect("error building test-workload");
Expand Down
5 changes: 4 additions & 1 deletion tests/dump_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use test_binary::build_test_binary;
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_can_read_stack() -> Result<(), io::Error> {
let test_bin_path =
build_test_binary("test-workload", "testbins").expect("error building test-workload");
Expand Down Expand Up @@ -80,6 +81,7 @@ fn test_can_read_stack() -> Result<(), io::Error> {
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_can_read_heap() -> Result<(), io::Error> {
let test_bin_path =
build_test_binary("test-workload", "testbins").expect("error building test-workload");
Expand Down Expand Up @@ -118,7 +120,8 @@ fn test_can_read_heap() -> Result<(), io::Error> {
.arg(tmpfile_name)
.arg("--batch")
.arg("-ex")
.arg("frame 1")
// since we yield, it goes through sleep() call, is a few frames down
.arg("frame 5")
.arg("-ex")
.arg("info args")
.arg("-ex")
Expand Down
3 changes: 3 additions & 0 deletions tests/dump_sleep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use subprocess::{Exec, PopenError};
#[test]
#[ignore]
#[timeout(10000)]
#[cfg(not(target_arch="aarch64"))]
fn test_sleep_sleeps() -> Result<(), PopenError> {
// shakeout test to check if sleep will run correctly

Expand All @@ -40,6 +41,7 @@ fn test_sleep_sleeps() -> Result<(), PopenError> {
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_sleep_was_not_killed() {
let mut sleep_p = Exec::cmd("sleep").arg("2").popen().unwrap();
assert_eq!(true, sleep_p.pid().is_some());
Expand All @@ -63,6 +65,7 @@ fn test_sleep_was_not_killed() {
#[test]
#[ignore]
#[timeout(20000)]
#[cfg(not(target_arch="aarch64"))]
fn test_sleep_output_is_parseable() {
let sleep_p = Exec::cmd("sleep").arg("2").popen().unwrap();
assert_eq!(true, sleep_p.pid().is_some());
Expand Down

0 comments on commit 5d3933e

Please sign in to comment.