Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Dec 1, 2024
1 parent 1d90028 commit 1258f39
Show file tree
Hide file tree
Showing 37 changed files with 810 additions and 363 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ jni = { path = "jni" }
jni_sys = { path = "jni/sys" }
symbols = { path = "symbols" }

byteorder = "1.5.0"
byte-slice-cast = "1.2.2"
cesu8 = "1.1.0"
const_format = "0.2.33"
libc = "0.2"
libloading = "0.8.5"
ouroboros = "0.18.4"
tracing = "0.1.41"
paste = "1.0.15"
zip = "2.2.1"
Expand Down
2 changes: 1 addition & 1 deletion classfile/src/fieldinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct FieldInfo {
pub access_flags: FieldAccessFlags,
pub name_index: u2,
pub descriptor_index: u2,
pub attributes: Vec<Attribute>,
pub attributes: Box<[Attribute]>,
}

impl FieldInfo {
Expand Down
2 changes: 1 addition & 1 deletion classfile/src/methodinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct MethodInfo {
pub access_flags: MethodAccessFlags,
pub name_index: u2,
pub descriptor_index: u2,
pub attributes: Vec<Attribute>,
pub attributes: Box<[Attribute]>,
}

impl MethodInfo {
Expand Down
2 changes: 1 addition & 1 deletion classfile/src/parse/fieldinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ where
access_flags: FieldAccessFlags::from(access_flags),
name_index,
descriptor_index,
attributes,
attributes: attributes.into_boxed_slice(),
})
}
2 changes: 1 addition & 1 deletion classfile/src/parse/methodinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ where
access_flags: MethodAccessFlags::from(access_flags),
name_index,
descriptor_index,
attributes,
attributes: attributes.into_boxed_slice(),
})
}
1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
byteorder.workspace = true
21 changes: 21 additions & 0 deletions common/src/endian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ pub enum Endian {
}

impl Endian {
pub fn native() -> Self {
#[cfg(target_endian = "little")]
return Endian::Little;
#[cfg(target_endian = "big")]
return Endian::Big;
}

pub fn invert(self) -> Self {
match self {
Self::Little => Self::Big,
Expand Down Expand Up @@ -51,4 +58,18 @@ impl<R: Read> JavaEndianAwareRead<R> for Endian {
Endian::Big => JavaReadExt::read_s4(reader),
}
}

fn read_s4_into(self, reader: &mut R, dst: &mut [s4]) -> Result<()> {
match self {
Endian::Little => JavaLittleEndianRead::read_s4_into(reader, dst),
Endian::Big => JavaReadExt::read_s4_into(reader, dst),
}
}

fn read_u4_into(self, reader: &mut R, dst: &mut [u4]) -> Result<()> {
match self {
Endian::Little => JavaLittleEndianRead::read_u4_into(reader, dst),
Endian::Big => JavaReadExt::read_u4_into(reader, dst),
}
}
}
21 changes: 21 additions & 0 deletions common/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::int_types::{s4, u1, u2, u4, u8};

use std::io::Read;

use byteorder::{BigEndian, LittleEndian, ReadBytesExt};

pub trait JavaReadExt: Read {
fn read_u1(&mut self) -> Result<u1> {
let mut buf = [0u8; 1];
Expand Down Expand Up @@ -33,6 +35,14 @@ pub trait JavaReadExt: Read {
self.read_exact(&mut buf)?;
Ok(s4::from_be_bytes(buf))
}

fn read_s4_into(&mut self, dst: &mut [s4]) -> Result<()> {
Ok(self.read_i32_into::<BigEndian>(dst)?)
}

fn read_u4_into(&mut self, dst: &mut [u4]) -> Result<()> {
Ok(self.read_u32_into::<BigEndian>(dst)?)
}
}

impl<R: Read> JavaReadExt for R {}
Expand All @@ -55,6 +65,14 @@ pub trait JavaLittleEndianRead: Read {
self.read_exact(&mut buf)?;
Ok(s4::from_le_bytes(buf))
}

fn read_s4_into(&mut self, dst: &mut [s4]) -> Result<()> {
Ok(self.read_i32_into::<LittleEndian>(dst)?)
}

fn read_u4_into(&mut self, dst: &mut [u4]) -> Result<()> {
Ok(self.read_u32_into::<LittleEndian>(dst)?)
}
}

impl<R: Read> JavaLittleEndianRead for R {}
Expand All @@ -64,6 +82,9 @@ pub trait JavaEndianAwareRead<R: Read> {
fn read_u4(self, reader: &mut R) -> Result<u4>;
fn read_u8(self, reader: &mut R) -> Result<u8>;
fn read_s4(self, reader: &mut R) -> Result<s4>;

fn read_s4_into(self, reader: &mut R, dst: &mut [s4]) -> Result<()>;
fn read_u4_into(self, reader: &mut R, dst: &mut [u4]) -> Result<()>;
}

pub trait PtrType<T, RefType> {
Expand Down
2 changes: 0 additions & 2 deletions jimage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
byte-slice-cast.workspace = true
common.workspace = true
ouroboros.workspace = true
zip.workspace = true
2 changes: 1 addition & 1 deletion jimage/src/decompressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub fn decompress_resource(

has_header = header.__magic == ResourceHeader::RESOURCE_HEADER_MAGIC;
if !has_header {
resource = unsafe { resource.sub(core::mem::size_of::<ResourceHeader>()) };
resource = unsafe { resource.sub(size_of::<ResourceHeader>()) };
break;
}

Expand Down
22 changes: 14 additions & 8 deletions jimage/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
use std::error::Error;
use std::fmt::{Display, Formatter};

pub type Result<T> = std::result::Result<T, JImageError>;
pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub enum JImageError {
pub enum Error {
InvalidMagic,
InvalidTableSize,
BadIndexSize,

Common(common::error::CommonError),
Io(std::io::Error),
Utf8(core::str::Utf8Error),
}

impl Display for JImageError {
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidMagic => write!(f, "File has an invalid magic signature!"),
Self::InvalidTableSize => write!(f, "Encountered invalid table size!"),
Self::BadIndexSize => write!(
f,
"The index does not match the size provided in the header"
),

Self::Common(err) => write!(f, "{}", err),
Self::Io(err) => write!(f, "{}", err),
Expand All @@ -24,21 +30,21 @@ impl Display for JImageError {
}
}

impl Error for JImageError {}
impl core::error::Error for Error {}

impl From<common::error::CommonError> for JImageError {
impl From<common::error::CommonError> for Error {
fn from(value: common::error::CommonError) -> Self {
Self::Common(value)
}
}

impl From<std::io::Error> for JImageError {
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self::Io(value)
}
}

impl From<core::str::Utf8Error> for JImageError {
impl From<core::str::Utf8Error> for Error {
fn from(value: core::str::Utf8Error) -> Self {
Self::Utf8(value)
}
Expand Down
73 changes: 54 additions & 19 deletions jimage/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,102 @@ pub const JIMAGE_MINOR_VERSION: u1 = 0;
#[derive(Copy, Clone, Debug)]
pub struct JImageHeader {
#[doc(hidden)]
pub __magic: u4, // Only here to make it the correct size
pub version: u4,
pub flags: u4,
pub resource_count: u4,
pub table_length: u4,
pub locations_size: u4,
pub strings_size: u4,
pub(crate) __magic: u4, // Only here to make it the correct size
pub(crate) version: u4,
pub(crate) flags: u4,
pub(crate) resource_count: u4,
pub(crate) table_length: u4,
pub(crate) locations_size: u4,
pub(crate) strings_size: u4,
}

impl JImageHeader {
/// Get the major version number for the JImage file
#[inline(always)]
pub fn major_version(&self) -> u2 {
(self.version >> 16) as u2
}

/// Get the minor version number for the JImage file
#[inline(always)]
pub fn minor_version(&self) -> u2 {
(self.version & 0xFFFF) as u2
}

/// Get the flags
///
/// Currently unused
#[inline(always)]
pub fn redirect_table_offset(&self) -> usize {
core::mem::size_of::<Self>()
pub fn flags(&self) -> u4 {
self.flags
}

/// Get the resource count
///
/// This is the number of resources in the JImage file.
#[inline(always)]
pub fn offset_table_offset(&self) -> usize {
self.redirect_table_offset() + self.table_length()
pub fn resource_count(&self) -> u4 {
self.resource_count
}

/// The length of the lookup tables in the [`JImageIndex`](crate::JImageIndex) (**in elements, not bytes!**)
#[inline(always)]
pub fn location_table_offset(&self) -> usize {
self.offset_table_offset() + self.table_length()
pub fn table_length(&self) -> usize {
self.table_length as usize
}

/// The start of the redirect table, relative to the beginning of the file
#[inline(always)]
pub fn string_table_offset(&self) -> usize {
self.location_table_offset() + self.locations_size as usize
pub fn redirect_table_offset(&self) -> usize {
size_of::<Self>()
}

/// The size of the redirect table, in bytes
#[inline(always)]
pub fn table_length(&self) -> usize {
self.table_length as usize * core::mem::size_of::<u4>()
pub fn redirect_table_length(&self) -> usize {
self.table_length() * size_of::<u4>()
}

/// The start of the offset table, relative to the beginning of the file
#[inline(always)]
pub fn offset_table_offset(&self) -> usize {
self.redirect_table_offset() + self.table_length()
}

/// The size of the offset table, in bytes
#[inline(always)]
pub fn offset_table_length(&self) -> usize {
self.location_table_offset() - self.offset_table_offset()
self.table_length() * size_of::<u4>()
}

/// The start of the location table, relative to the beginning of the file
#[inline(always)]
pub fn location_table_offset(&self) -> usize {
self.offset_table_offset() + self.table_length()
}

/// The size of the location table, in bytes
#[inline(always)]
pub fn location_table_length(&self) -> u4 {
self.locations_size
}

/// The start of the string table, relative to the beginning of the file
#[inline(always)]
pub fn string_table_offset(&self) -> usize {
self.location_table_offset() + self.locations_size as usize
}

/// The size of the string table, in bytes
#[inline(always)]
pub fn string_table_length(&self) -> u4 {
self.strings_size
}

/// The size of the entire index
pub fn index_length(&self) -> usize {
core::mem::size_of::<Self>()
+ self.table_length()
+ self.redirect_table_length()
+ self.offset_table_length()
+ self.locations_size as usize
+ self.strings_size as usize
Expand Down
Loading

0 comments on commit 1258f39

Please sign in to comment.