#![allow(deprecated)]

use super::mystd::ffi::{CStr, OsStr};
use super::mystd::os::unix::prelude::*;
use super::mystd::prelude::v1::*;
use super::{Library, LibrarySegment};
use core::convert::TryInto;
use core::mem;

pub(super) fn native_libraries() -> Vec<Library> {
    let mut ret = Vec::new();
    let images = unsafe { libc::_dyld_image_count() };
    for i in 0..images {
        ret.extend(native_library(i));
    }
    return ret;
}

fn native_library(i: u32) -> Option<Library> {
    use object::macho;
    use object::read::macho::{MachHeader, Segment};
    use object::NativeEndian;

    // Fetch the name of this library which corresponds to the path of
    // where to load it as well.
    let name = unsafe {
        let name = libc::_dyld_get_image_name(i);
        if name.is_null() {
            return None;
        }
        CStr::from_ptr(name)
    };

    // Load the image header of this library and delegate to `object` to
    // parse all the load commands so we can figure out all the segments
    // involved here.
    let (mut load_commands, endian) = unsafe {
        let header = libc::_dyld_get_image_header(i);
        if header.is_null() {
            return None;
        }
        match (*header).magic {
            macho::MH_MAGIC => {
                let endian = NativeEndian;
                let header = &*(header as *const macho::MachHeader32<NativeEndian>);
                let data = core::slice::from_raw_parts(
                    header as *const _ as *const u8,
                    mem::size_of_val(header) + header.sizeofcmds.get(endian) as usize,
                );
                (header.load_commands(endian, data, 0).ok()?, endian)
            }
            macho::MH_MAGIC_64 => {
                let endian = NativeEndian;
                let header = &*(header as *const macho::MachHeader64<NativeEndian>);
                let data = core::slice::from_raw_parts(
                    header as *const _ as *const u8,
                    mem::size_of_val(header) + header.sizeofcmds.get(endian) as usize,
                );
                (header.load_commands(endian, data, 0).ok()?, endian)
            }
            _ => return None,
        }
    };

    // Iterate over the segments and register known regions for segments
    // that we find. Additionally record information bout text segments
    // for processing later, see comments below.
    let mut segments = Vec::new();
    let mut first_text = 0;
    let mut text_fileoff_zero = false;
    while let Some(cmd) = load_commands.next().ok()? {
        if let Some((seg, _)) = cmd.segment_32().ok()? {
            if seg.name() == b"__TEXT" {
                first_text = segments.len();
                if seg.fileoff(endian) == 0 && seg.filesize(endian) > 0 {
                    text_fileoff_zero = true;
                }
            }
            segments.push(LibrarySegment {
                len: seg.vmsize(endian).try_into().ok()?,
                stated_virtual_memory_address: seg.vmaddr(endian).try_into().ok()?,
            });
        }
        if let Some((seg, _)) = cmd.segment_64().ok()? {
            if seg.name() == b"__TEXT" {
                first_text = segments.len();
                if seg.fileoff(endian) == 0 && seg.filesize(endian) > 0 {
                    text_fileoff_zero = true;
                }
            }
            segments.push(LibrarySegment {
                len: seg.vmsize(endian).try_into().ok()?,
                stated_virtual_memory_address: seg.vmaddr(endian).try_into().ok()?,
            });
        }
    }

    // Determine the "slide" for this library which ends up being the
    // bias we use to figure out where in memory objects are loaded.
    // This is a bit of a weird computation though and is the result of
    // trying a few things in the wild and seeing what sticks.
    //
    // The general idea is that the `bias` plus a segment's
    // `stated_virtual_memory_address` is going to be where in the
    // actual address space the segment resides. The other thing we rely
    // on though is that a real address minus the `bias` is the index to
    // look up in the symbol table and debuginfo.
    //
    // It turns out, though, that for system loaded libraries these
    // calculations are incorrect. For native executables, however, it
    // appears correct. Lifting some logic from LLDB's source it has
    // some special-casing for the first `__TEXT` section loaded from
    // file offset 0 with a nonzero size. For whatever reason when this
    // is present it appears to mean that the symbol table is relative
    // to just the vmaddr slide for the library. If it's *not* present
    // then the symbol table is relative to the the vmaddr slide plus
    // the segment's stated address.
    //
    // To handle this situation if we *don't* find a text section at
    // file offset zero then we increase the bias by the first text
    // sections's stated address and decrease all stated addresses by
    // that amount as well. That way the symbol table is always appears
    // relative to the library's bias amount. This appears to have the
    // right results for symbolizing via the symbol table.
    //
    // Honestly I'm not entirely sure whether this is right or if
    // there's something else that should indicate how to do this. For
    // now though this seems to work well enough (?) and we should
    // always be able to tweak this over time if necessary.
    //
    // For some more information see #318
    let mut slide = unsafe { libc::_dyld_get_image_vmaddr_slide(i) as usize };
    if !text_fileoff_zero {
        let adjust = segments[first_text].stated_virtual_memory_address;
        for segment in segments.iter_mut() {
            segment.stated_virtual_memory_address -= adjust;
        }
        slide += adjust;
    }

    Some(Library {
        name: OsStr::from_bytes(name.to_bytes()).to_owned(),
        segments,
        bias: slide,
    })
}
