Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix objcopy and nm on ARM platforms (0.2.x) #30

Merged
merged 4 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest, [ubuntu-22.04, ARM64]]
runs-on: ${{ matrix.os }}

steps:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cyclors"
version = "0.2.2"
version = "0.2.3"
authors = ["kydos <angelo@icorsaro.net>"]
license = "Apache-2.0"
readme = "README.md"
Expand All @@ -25,7 +25,7 @@ serde = { version = "1.0.154", features = ["derive"] }
serde_json = "1.0.94"

[build-dependencies]
bindgen = "0.68"
bindgen = "0.69"
cmake = "0.1"

[features]
Expand Down
62 changes: 35 additions & 27 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,37 +219,42 @@ fn main() {

#[cfg(all(target_os = "linux", not(feature = "iceoryx")))]
fn get_defined_symbols(lib_dir: &Path, lib_name: &str) -> Result<HashSet<String>, String> {
use std::io::{BufRead, BufReader};

let lib_path = lib_dir.to_path_buf().join(lib_name);
let mut nm_file_name = lib_name.to_owned();
nm_file_name.push_str(".nm");
let symbol_file_path = lib_dir.to_path_buf().join(nm_file_name);

let mut nm = cmake::Config::new("nm");
nm.build_target("all")
.define("LIB_PATH", lib_path.clone())
.build();

match File::open(symbol_file_path.clone()) {
Ok(symbol_file) => {
let reader = BufReader::new(symbol_file);

let rc = Command::new("nm")
.arg("--defined-only")
.arg("--print-file-name")
.arg(lib_path)
.output();

match rc {
Ok(output) => {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

match stderr.is_empty() {
true => {
let mut result: HashSet<String> = HashSet::new();
for line in stdout.lines() {
let mut result: HashSet<String> = HashSet::new();
for line in reader.lines() {
match line {
Ok(line) => {
let tokens: Vec<&str> = line.split_whitespace().collect();
let symbol = *tokens.last().unwrap();
result.insert(String::from(symbol));
}
Ok(result)
Err(_) => return Err(format!("Failed to run nm on library {}", lib_name)),
}
false => Err(format!(
"Failed to run nm on library {} (stderr: {})",
lib_name,
String::from(stderr)
)),
}
Ok(result)
}
Err(_) => {
println!(
"nm file open problem: {}",
symbol_file_path.to_str().unwrap()
);
Err(format!("Failed to run nm on library {}", lib_name))
}
Err(_) => Err(format!("Failed to run nm on library {}", lib_name)),
}
}

Expand Down Expand Up @@ -290,11 +295,14 @@ fn prefix_symbols(
lib_name
));
}
let arg = format!("--redefine-syms={}", symbol_file_path.to_str().unwrap());
match Command::new("objcopy").arg(arg).arg(lib_file_path).output() {
Ok(_) => Ok(()),
Err(_) => Err(format!("Failed to run objcopy on library {}", lib_name)),
}

let mut objcopy = cmake::Config::new("objcopy");
objcopy
.build_target("all")
.define("LIB_PATH", lib_file_path.clone())
.define("SYMBOL_FILE_PATH", symbol_file_path.clone())
.build();
Ok(())
}
Err(_) => Err(format!(
"Failed to create symbol file for library {}",
Expand Down
39 changes: 39 additions & 0 deletions nm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.12)
project(NM)

# Include the CMakeFindBinUtils module to find nm
include(CMakeFindBinUtils)

# Ensure nm is available
if(NOT CMAKE_NM)
message(FATAL_ERROR "CMAKE_NM is not defined. Ensure nm is installed on your system!")
else()
message(STATUS "CMAKE_NM found: ${CMAKE_NM}")
endif()

# Ensure LIB_PATH is defined and exists
if(NOT DEFINED LIB_PATH)
message(FATAL_ERROR "LIB_PATH not specified!")
else()
if(NOT EXISTS ${LIB_PATH})
message(FATAL_ERROR "Library not found: ${LIB_PATH}")
else()
message(STATUS "LIB_PATH: ${LIB_PATH}")
endif()
endif()

# Custom target to run nm on the library
add_custom_target(read_symbols ALL
COMMAND ${CMAKE_COMMAND} -E echo "Running nm on ${LIB_PATH}..."

# Run nm and redirect stderr to a file
COMMAND ${CMAKE_NM} --defined-only --print-file-name ${LIB_PATH} 1> ${LIB_PATH}.nm 2> ${LIB_PATH}.stderr

# Check if stderr is empty (i.e., no errors were produced)
COMMAND ${CMAKE_COMMAND} -E echo "Checking for nm errors..."
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/check_errors.sh ${LIB_PATH}.stderr

# Clean up stderr.txt after checking for errors
COMMAND ${CMAKE_COMMAND} -E remove ${LIB_PATH}.stderr
COMMENT "Reading library symbols with nm..."
)
10 changes: 10 additions & 0 deletions nm/check_errors.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

if [ ! -s $1 ]; then
echo 'Command succeeded with no stderr output.'
exit 0
else
echo 'Command failed with errors:'
cat stderr.txt
exit 1
fi
50 changes: 50 additions & 0 deletions objcopy/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
cmake_minimum_required(VERSION 3.12)
project(Objcopy)

# Include the CMakeFindBinUtils module to find objcopy
include(CMakeFindBinUtils)

# Ensure objcopy is available
if(NOT CMAKE_OBJCOPY)
message(FATAL_ERROR "CMAKE_OBJCOPY is not defined. Ensure objcopy is installed on your system!")
else()
message(STATUS "CMAKE_OBJCOPY found: ${CMAKE_OBJCOPY}")
endif()

# Ensure LIB_PATH is defined and exists
if(NOT DEFINED LIB_PATH)
message(FATAL_ERROR "LIB_PATH not specified!")
else()
if(NOT EXISTS ${LIB_PATH})
message(FATAL_ERROR "Library not found: ${LIB_PATH}")
else()
message(STATUS "LIB_PATH: ${LIB_PATH}")
endif()
endif()

# Ensure SYMBOL_FILE_PATH is defined and exists
if(NOT DEFINED SYMBOL_FILE_PATH)
message(FATAL_ERROR "SYMBOL_FILE_PATH not specified!")
else()
if(NOT EXISTS ${SYMBOL_FILE_PATH})
message(FATAL_ERROR "Symbol file not found: ${SYMBOL_FILE_PATH}")
else()
message(STATUS "SYMBOL_FILE_PATH: ${SYMBOL_FILE_PATH}")
endif()
endif()

# Custom target to mangle the library
add_custom_target(mangle_library ALL
COMMAND ${CMAKE_COMMAND} -E echo "Running objcopy --redefine-syms on ${LIB_PATH} with symbols from ${SYMBOL_FILE_PATH}..."

# Run objcopy and redirect stderr to a file
COMMAND ${CMAKE_OBJCOPY} --redefine-syms=${SYMBOL_FILE_PATH} ${LIB_PATH} 2> ${LIB_PATH}.stderr

# Check if stderr is empty (i.e., no errors were produced)
COMMAND ${CMAKE_COMMAND} -E echo "Checking for objcopy errors..."
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/check_errors.sh ${LIB_PATH}.stderr

# Clean up stderr.txt after checking for errors
COMMAND ${CMAKE_COMMAND} -E remove ${LIB_PATH}.stderr
COMMENT "Mangling library with objcopy..."
)
10 changes: 10 additions & 0 deletions objcopy/check_errors.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

if [ ! -s $1 ]; then
echo 'Command succeeded with no stderr output.'
exit 0
else
echo 'Command failed with errors:'
cat stderr.txt
exit 1
fi
Loading