//! Native Linker — 不依赖外部 link.exe 的完整链接器
//!
//! 功能：
//! 1. 解析多个 COFF .obj 文件
//! 2. 合并节区（.text, .data, .rdata, .bss）
//! 3. 构建全局符号表，解析外部符号引用
//! 4. 处理 x64 重定位（REL32, ADDR32NB, ADDR64）
//! 5. 生成导入表（kernel32.dll 等系统 DLL）
//! 6. 输出完整 PE .exe 文件

use anyhow::{Result, bail};
use std::collections::HashMap;
use crate::coff::*;

// === TSN 格式支持（暂移除，等待后续实现）===
// 原 tsn_format 模块引用已移除

/// 链接器配置
#[derive(Debug, Clone, Default)]
pub struct NativeLinkConfig {
    pub entry_point: String,
    pub subsystem: Subsystem,
    pub image_base: u64,
    pub stack_reserve: u64,
    pub stack_commit: u64,
    pub heap_reserve: u64,
    pub heap_commit: u64,
    pub imports: Vec<DllImport>,
    
    // === 新增：Runtime 自动注入配置 ===
    /// 是否自动注入 runtime（默认 true）
    pub auto_inject_runtime: bool,
    /// runtime 对象文件列表（如 ["start_nocrt.o", "runtime_nocrt.o"]）
    pub runtime_objects: Vec<String>,
}

#[derive(Debug, Clone, Copy)]
pub enum Subsystem {
    Console,
    Windows,
}

impl Default for Subsystem {
    fn default() -> Self { Subsystem::Console }
}

/// DLL 导入描述
#[derive(Debug, Clone)]
pub struct DllImport {
    pub dll_name: String,
    pub functions: Vec<String>,
}

/// 全局符号表中的条目
#[derive(Debug, Clone)]
struct SymbolEntry {
    name: String,
    /// 符号所在节区索引（在 merged_sections 中）
    section_idx: usize,
    /// 符号在节区内的偏移
    section_offset: u32,
    /// 符号的 RVA（在最终 PE 中）
    rva: u32,
    /// 是否外部可见
    is_global: bool,
}

/// 合并后的节区
#[derive(Debug, Clone)]
struct MergedSection {
    name: String,
    data: Vec<u8>,
    characteristics: u32,
    /// 该节区在 PE 中的 RVA
    rva: u32,
    /// 该节区在文件中的偏移
    file_offset: u32,
}

/// 需要导入的外部符号
#[derive(Debug, Clone)]
struct ImportSymbol {
    name: String,
    dll_name: String,
    /// 在导入地址表（IAT）中的索引
    iat_index: u32,
    /// IAT 条目的 RVA
    iat_rva: u32,
    /// 跳转桩（thunk）的 RVA（用于 E8 直接调用）
    thunk_rva: u32,
    /// IAT 条目在导入数据中的偏移（用于调试和验证）
    iat_offset: usize,
}

/// 重定位条目
#[derive(Debug, Clone)]
struct RelocEntry {
    /// 需要重定位的位置 RVA
    rva: u32,
    /// 重定位类型 (AMD64: 10=DIR64, 4=REL32)
    typ: u16,
}

/// 链接器诊断反馈
#[derive(Debug, Clone, Default)]
pub struct LinkerFeedback {
    /// 警告信息
    pub warnings: Vec<String>,
    /// 错误信息
    pub errors: Vec<String>,
    /// 建议信息
    pub suggestions: Vec<String>,
    /// 统计信息
    pub stats: LinkerStats,
}

/// 链接器统计信息
#[derive(Debug, Clone, Default)]
pub struct LinkerStats {
    /// 节区数量
    pub section_count: usize,
    /// 符号数量
    pub symbol_count: usize,
    /// 导入函数数量
    pub import_count: usize,
    /// 重定位数量
    pub relocation_count: usize,
    /// 未使用符号数量
    pub unused_symbol_count: usize,
}

/// 链接器状态
pub struct NativeLinker {
    config: NativeLinkConfig,
    objects: Vec<CoffObject>,
    merged_sections: Vec<MergedSection>,
    obj_section_map: HashMap<(usize, usize), (usize, u32)>,
    symbol_table: HashMap<String, SymbolEntry>,
    imports: Vec<ImportSymbol>,
    entry_rva: u32,
    import_data_rva: u32,
    import_directory_rva: u32,
    // 重定位表
    reloc_entries: Vec<RelocEntry>,
}

impl NativeLinker {
    pub fn new(config: NativeLinkConfig) -> Self {
        Self {
            config,
            objects: Vec::new(),
            merged_sections: Vec::new(),
            obj_section_map: HashMap::new(),
            symbol_table: HashMap::new(),
            imports: Vec::new(),
            entry_rva: 0,
            import_data_rva: 0,
            import_directory_rva: 0,
            reloc_entries: Vec::new(),
        }
    }

    /// 自动注入 runtime 对象文件
    fn auto_inject_runtime(&mut self) -> Result<()> {
        eprintln!("  [Runtime] 自动注入 runtime 对象文件...");
        
        // 克隆 runtime_objects 避免借用冲突
        let runtime_objects = self.config.runtime_objects.clone();
        eprintln!("  [Runtime] 文件列表: {:?}", runtime_objects);
        
        for runtime_obj in &runtime_objects {
            eprintln!("    - 查找: {}", runtime_obj);
            
            // 查找 runtime 对象文件
            let paths = vec![
                runtime_obj.clone(),
                format!("../{}", runtime_obj),
            ];
            
            let mut found = false;
            for path in &paths {
                if std::path::Path::new(path).exists() {
                    eprintln!("    ✅ 找到: {}", path);
                    let data = std::fs::read(path)
                        .map_err(|e| anyhow::anyhow!("无法读取 {}: {}", path, e))?;
                    let obj_count_before = self.objects.len();
                    self.add_object(&data)
                        .map_err(|e| anyhow::anyhow!("解析 {} 失败: {}", path, e))?;
                    let obj_count_after = self.objects.len();
                    eprintln!("    ✅ 已加载: {} ({} -> {} 个对象)", runtime_obj, obj_count_before, obj_count_after);
                    found = true;
                    break; // 找到当前文件的一个路径后，继续处理下一个 runtime 文件
                }
            }
            
            if !found {
                eprintln!("    ⚠️  警告: 未找到 {}", runtime_obj);
            }
        }
        
        Ok(())
    }

    /// 分析链接结果，生成诊断反馈
    pub fn analyze_linking(&self) -> LinkerFeedback {
        let mut feedback = LinkerFeedback::default();
        
        // 统计信息
        feedback.stats.section_count = self.merged_sections.len();
        feedback.stats.symbol_count = self.symbol_table.len();
        feedback.stats.import_count = self.imports.len();
        
        // === 诊断 1: 检查 .pdata 节区（异常处理数据）===
        let has_pdata = self.merged_sections.iter().any(|s| s.name == ".pdata");
        if !has_pdata {
            feedback.warnings.push(
                "缺少 .pdata 节区（异常处理数据）\n".to_string() +
                "  影响: 可能导致运行时崩溃 (0xC0000005)\n" +
                "  建议: 检查 merge_sections 是否跳过了 .pdata 节区\n" +
                "  修复: 从 skip_sections 列表中移除 .pdata"
            );
        }
        
        // === 诊断 2: 检查节区特征值 ===
        for sec in &self.merged_sections {
            // 检查 LINK_COMDAT 标志 (0x00001000)
            if sec.characteristics & 0x00001000 != 0 {
                feedback.warnings.push(
                    format!("节区 '{}' 包含 LINK_COMDAT 标志 (0x00001000)\n", sec.name) +
                    "  影响: 与 MSVC 生成的 PE 不一致\n" +
                    "  建议: 在 merge_sections 中清除该标志\n" +
                    "  修复: chars & !0x00001000"
                );
            }
            
            // 检查对齐标志 (0x00F00000)
            if sec.characteristics & 0x00F00000 != 0 {
                feedback.warnings.push(
                    format!("节区 '{}' 包含对齐标志 (0x{:08X})\n", sec.name, sec.characteristics & 0x00F00000) +
                    "  影响: 对齐标志不应该累积\n" +
                    "  建议: 在 merge_sections 中清除对齐标志\n" +
                    "  修复: chars & !0x00F00000"
                );
            }
        }
        
        // === 诊断 3: 检查 .rdata 节区是否可写 ===
        if let Some(rdata) = self.merged_sections.iter().find(|s| s.name == ".rdata") {
            let is_writable = (rdata.characteristics & 0x80000000) != 0;
            if !is_writable {
                feedback.errors.push(
                    ".rdata 节区不可写\n".to_string() +
                    "  影响: IAT 无法被 Windows 加载器填充\n" +
                    "  建议: 确保 .rdata 节区包含 IMAGE_SCN_MEM_WRITE 标志\n" +
                    "  修复: characteristics | 0x80000000"
                );
            }
        }
        
        // === 诊断 4: 检查导入表 ===
        if self.imports.is_empty() {
            feedback.suggestions.push(
                "没有导入任何 DLL 函数\n".to_string() +
                "  这可能是不正常的，除非程序完全不使用 Windows API"
            );
        }
        
        // === 诊断 5: 检查入口点 ===
        if self.config.entry_point == "main" {
            feedback.suggestions.push(
                "使用 'main' 作为入口点\n".to_string() +
                "  建议: 如果有 start_nocrt.o，应该使用 '_start' 作为入口点"
            );
        }
        
        // === 诊断 6: SizeOfHeaders 检查 ===
        // 在 build_pe 中计算，这里只提供建议
        feedback.suggestions.push(
            "确保 SizeOfHeaders >= 0x400 (MSVC 标准)".to_string()
        );
        
        feedback
    }

    /// 添加 COFF 对象文件
    pub fn add_object(&mut self, data: &[u8]) -> Result<()> {
        let obj = CoffObject::parse(data)?;
        self.objects.push(obj);
        Ok(())
    }

    /// 通用添加文件函数（自动检测格式）
    pub fn add_input(&mut self, path: &str) -> Result<()> {
        let data = std::fs::read(path)?;
        
        if path.ends_with(".tsn") {
            bail!("TSN format is deprecated")
        } else if path.ends_with(".obj") || path.ends_with(".o") {
            // COFF 格式
            self.add_object(&data)?;
        } else {
            bail!("不支持的文件格式: {} (支持 .obj, .o)", path);
        }
        
        Ok(())
    }

    /// 执行链接
    pub fn link(&mut self) -> Result<Vec<u8>> {
        // 0. 自动注入 runtime（如果启用）
        if self.config.auto_inject_runtime && !self.config.runtime_objects.is_empty() {
            self.auto_inject_runtime()?;
        }
        
        // 1. 合并节区
        self.merge_sections()?;

        // 2. 建立对象文件节区到合并节区的映射（在排序前）
        self.build_obj_section_map()?;

        // 2.5 对节区排序：代码节区在前，数据节区在后
        // Windows 加载器期望 .text 在 .rdata 之前
        self.merged_sections.sort_by(|a, b| {
            let a_code = (a.characteristics & section_flags::IMAGE_SCN_CNT_CODE) != 0;
            let b_code = (b.characteristics & section_flags::IMAGE_SCN_CNT_CODE) != 0;
            b_code.cmp(&a_code) // 代码节区排前面
        });

        // 3. 构建符号表
        self.build_symbol_table()?;

        // 4. 解析外部符号
        self.resolve_imports()?;

        // 5. 确保 .rdata 节区存在（用于后续导入数据）
        self.ensure_rdata_section()?;

        // 6. 分配 RVA
        self.assign_rvas()?;

        // 7. 附加导入表数据到 .rdata（在 RVA 分配之后）
        self.append_import_data()?;

        // 8. 处理重定位
        self.apply_relocations()?;
        
        // 8.5 收集并生成重定位表
        self.collect_relocations();
        self.add_reloc_section();

        // 9. 生成 PE 文件
        let pe = self.build_pe()?;
        
        // 10. 诊断分析（始终输出）
        let feedback = self.analyze_linking();
        
        // 输出警告
        for warning in &feedback.warnings {
            eprintln!("\n⚠️  [链接器诊断] 警告:\n{}", warning);
        }
        
        // 输出错误
        for error in &feedback.errors {
            eprintln!("\n❌ [链接器诊断] 错误:\n{}", error);
        }
        
        // 输出建议
        if !feedback.suggestions.is_empty() {
            eprintln!("\n💡 [链接器诊断] 建议:");
            for suggestion in &feedback.suggestions {
                eprintln!("  - {}", suggestion);
            }
        }
        
        // 输出统计
        eprintln!("\n📊 [链接器诊断] 统计:");
        eprintln!("  节区数量: {}", feedback.stats.section_count);
        eprintln!("  符号数量: {}", feedback.stats.symbol_count);
        eprintln!("  导入函数: {}", feedback.stats.import_count);

        Ok(pe)
    }

    /// 合并所有对象文件的节区
    fn merge_sections(&mut self) -> Result<()> {
        // 直接使用 Vec 按对象添加顺序拼装，不用 Map
        // 结构: (节区名, 数据, 特征值)
        let mut sections: Vec<(String, Vec<u8>, u32)> = Vec::new();

        // 需要跳过的节区
        let skip_sections: &[&str] = &[
            ".drectve",
            ".debug$S",
            ".debug$T",
            ".chks64",
            ".voltbl",
        ];

        for (obj_idx, obj) in self.objects.iter().enumerate() {
            for (sec_idx, sec) in obj.sections.iter().enumerate() {
                let mut name = String::from_utf8_lossy(&sec.header.name)
                    .trim_end_matches('\0')
                    .to_string();

                // 跳过辅助节区
                if skip_sections.iter().any(|s| name.starts_with(s)) {
                    continue;
                }

                // 子节区合并到主节区
                if let Some(dollar_pos) = name.find('$') {
                    name = name[..dollar_pos].to_string();
                }

                // 跳过空 BSS
                if sec.data.is_empty() && (sec.header.characteristics & section_flags::IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0 {
                    continue;
                }

                // 查找是否已有同名节区
                if let Some(existing) = sections.iter_mut().find(|(n, _, _)| n == &name) {
                    // 对齐到 16 字节
                    while existing.1.len() % 16 != 0 {
                        existing.1.push(0);
                    }
                    // 调试: 输出前 4 字节
                    if name == ".text" && sec.data.len() >= 4 {
                        eprintln!("[MERGE] 追加 .text 数据: {:02X} {:02X} {:02X} {:02X}", 
                            sec.data[0], sec.data[1], sec.data[2], sec.data[3]);
                    }
                    // 追加数据
                    if name == ".text" {
                        eprintln!("[MERGE] 追加到 .text: obj={}, sec={}, size={}, 当前总大小={}", 
                            obj_idx, sec_idx, sec.data.len(), existing.1.len());
                    }
                    existing.1.extend_from_slice(&sec.data);
                    existing.2 |= sec.header.characteristics;
                } else {
                    // 新建节区
                    if name == ".text" && sec.data.len() >= 4 {
                        eprintln!("[MERGE] 新建 .text: obj={}, sec={}, size={}, data={:02X} {:02X} {:02X} {:02X}", 
                            obj_idx, sec_idx, sec.data.len(),
                            sec.data[0], sec.data[1], sec.data[2], sec.data[3]);
                    } else if name == ".text" {
                        eprintln!("[MERGE] 新建 .text: obj={}, sec={}, size={}", obj_idx, sec_idx, sec.data.len());
                    }
                    sections.push((name, sec.data.clone(), sec.header.characteristics));
                }
            }
        }

        // 创建合并后的节区
        for (name, data, chars) in sections {
            // 跳过完全空的节区
            if data.is_empty() && (chars & section_flags::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
                continue;
            }
            
            // 清除对齐标志（bit 20-23），这些标志不应该累积
            // IMAGE_SCN_ALIGN_* = 0x00F00000
            let mut cleaned_chars = chars & !0x00F00000;
            
            // 清除 LINK_COMDAT 标志（bit 12），与 MSVC 保持一致
            // IMAGE_SCN_LNK_COMDAT = 0x00001000
            cleaned_chars &= !0x00001000;
            
            self.merged_sections.push(MergedSection {
                name,
                data,
                characteristics: cleaned_chars,
                rva: 0,
                file_offset: 0,
            });
        }

        // 确保 .text 是第一个节区
        self.merged_sections.sort_by(|a, b| {
            let order = |name: &str| match name {
                ".text" => 0,
                ".data" => 1,
                ".rdata" => 2,
                ".bss" => 3,
                _ => 4,
            };
            order(&a.name).cmp(&order(&b.name))
        });

        Ok(())
    }

    /// 建立对象文件节区到合并节区的映射（全局一次）
    fn build_obj_section_map(&mut self) -> Result<()> {
        // sec_offsets 是全局的，跨所有对象文件累积
        let mut sec_offsets: HashMap<usize, u32> = HashMap::new();

        for (obj_idx, obj) in self.objects.iter().enumerate() {
            for (sec_idx, sec) in obj.sections.iter().enumerate() {
                let mut name = String::from_utf8_lossy(&sec.header.name)
                    .trim_end_matches('\0')
                    .to_string();

                // 将子节区名称合并到主节区（与 merge_sections 保持一致）
                if let Some(dollar_pos) = name.find('$') {
                    name = name[..dollar_pos].to_string();
                }

                if let Some(merged_idx) = self.merged_sections.iter().position(|s| s.name == name) {
                    let offset = sec_offsets.get(&merged_idx).copied().unwrap_or(0);
                    let aligned = (offset + 15) & !15;
                    self.obj_section_map.insert((obj_idx, sec_idx), (merged_idx, aligned));
                    sec_offsets.insert(merged_idx, aligned + sec.data.len() as u32);
                }
            }
        }
        Ok(())
    }

    /// 构建全局符号表
    fn build_symbol_table(&mut self) -> Result<()> {
        // 收集所有符号
        for (obj_idx, obj) in self.objects.iter().enumerate() {
            for sym in &obj.symbols {
                // 跳过未定义符号（section_number <= 0）
                // 注意：coff.rs 解析时已经跳过了辅助记录，不需要再检查 num_aux_symbols
                if sym.section_number <= 0 {
                    continue;
                }

                let sec_idx = (sym.section_number - 1) as usize;
                if let Some(&(merged_sec_idx, sec_offset)) = self.obj_section_map.get(&(obj_idx, sec_idx)) {
                    let is_external = sym.storage_class == storage_class::IMAGE_SYM_CLASS_EXTERNAL;
                    let is_static = sym.storage_class == storage_class::IMAGE_SYM_CLASS_STATIC;
                    
                    // 记录全局符号和静态函数符号（nocrt 的 js_memcpy/js_malloc 等是 static 的）
                    if is_external || is_static {
                        // 静态符号只在全局表中不存在同名外部符号时才添加
                        if is_static && self.symbol_table.contains_key(&sym.name) {
                            continue;
                        }
                        self.symbol_table.insert(sym.name.clone(), SymbolEntry {
                            name: sym.name.clone(),
                            section_idx: merged_sec_idx,
                            section_offset: sec_offset + sym.value,
                            rva: 0, // 稍后计算
                            is_global: is_external,
                        });
                    }
                }
            }
        }

        Ok(())
    }

    /// 解析外部符号，确定需要导入的 DLL 函数
    fn resolve_imports(&mut self) -> Result<()> {
        // 收集所有未定义符号
        let mut undefined: Vec<String> = Vec::new();
        for obj in &self.objects {
            for sym in obj.undefined_symbols() {
                if !self.symbol_table.contains_key(&sym.name) {
                    undefined.push(sym.name.clone());
                }
            }
        }

        // 调试：打印符号表中的 js_ 开头符号
        eprintln!("  [DEBUG] 符号表中 js_ 开头的符号:");
        for (name, entry) in &self.symbol_table {
            if name.starts_with("js_") {
                eprintln!("    - {} (section={}, offset=0x{:x})", name, entry.section_idx, entry.section_offset);
            }
        }
        
        // 调试：打印未定义符号中的 js_ 开头符号
        eprintln!("  [DEBUG] 未定义符号中 js_ 开头的符号:");
        let mut js_undefined_count = 0;
        for sym in &undefined {
            if sym.starts_with("js_") || sym.starts_with("__imp_js_") {
                eprintln!("    - {}", sym);
                js_undefined_count += 1;
            }
        }
        if js_undefined_count == 0 {
            eprintln!("    (无)");
        }

        // 去重
        undefined.sort();
        undefined.dedup();

        // 匹配到导入配置
        let mut iat_index = 0u32;
        for sym_name in &undefined {
            // 特殊符号：__ImageBase 是 MSVC 链接器自动提供的，表示 PE 基地址
            if sym_name == "__ImageBase" {
                // 将 __ImageBase 作为已定义符号处理（指向 image_base）
                self.symbol_table.insert("__ImageBase".to_string(), SymbolEntry {
                    name: "__ImageBase".to_string(),
                    section_idx: 0, // 特殊值，表示不在任何节区
                    section_offset: 0,
                    rva: 0, // RVA 0 对应 image_base
                    is_global: true,
                });
                continue;
            }

            // _fltused: MSVC 浮点支持符号，链接器直接提供
            if sym_name == "_fltused" {
                continue;
            }

            // nocrt 符号别名：MSVC 优化可能绕过 #define 生成外部引用
            // 首先尝试映射到 runtime_nocrt.c 中的 js_xxx/tsn_xxx 实现
            let nocrt_aliases: &[(&str, &str)] = &[
                ("memcpy", "js_memcpy"),
                ("memset", "js_memset"),
                ("malloc", "js_malloc"),
                ("free", "js_free"),
                ("realloc", "js_realloc"),
                ("strstr", "tsn_strstr"),
            ];
            
            let mut aliased = false;
            for (alias, target) in nocrt_aliases {
                if sym_name == *alias {
                    if let Some(entry) = self.symbol_table.get(*target).cloned() {
                        self.symbol_table.insert(alias.to_string(), SymbolEntry {
                            name: alias.to_string(),
                            section_idx: entry.section_idx,
                            section_offset: entry.section_offset,
                            rva: entry.rva,
                            is_global: true,
                        });
                        aliased = true;
                    }
                    break;
                }
            }
            if aliased {
                continue;
            }

            // 如果别名映射失败（js_xxx 不存在），直接在 .text 节区注入实现
            let nocrt_inject: &[&str] = &["memcpy", "memset", "malloc", "free", "realloc", "strstr"];
            if nocrt_inject.contains(&sym_name.as_str()) {
                if let Some((section_idx, section_offset)) = self.inject_nocrt_function(sym_name)? {
                    self.symbol_table.insert(sym_name.clone(), SymbolEntry {
                        name: sym_name.clone(),
                        section_idx,
                        section_offset,
                        rva: 0, // 稍后计算
                        is_global: true,
                    });
                    continue;
                }
            }

            // COFF 中的导入符号通常带 __imp_ 前缀，去掉前缀匹配
            let plain_name = if sym_name.starts_with("__imp_") {
                &sym_name[6..]
            } else {
                sym_name.as_str()
            };

            // main 是入口点，由用户代码提供。如果当前没有定义，创建一个桩
            if plain_name == "main" {
                // 创建一个返回 0 的桩 main 函数
                // 在实际使用中，main 应该由用户代码提供
                // 这里只是为了测试链接器能完成链接
                bail!("未定义 main 函数 - 用户代码必须提供 main 函数");
            }

            let mut found = false;
            for dll in &self.config.imports {
                if dll.functions.iter().any(|f| f == plain_name) {
                    // 检查是否已经添加过这个导入符号（避免重复）
                    if !self.imports.iter().any(|i| i.name == plain_name) {
                        eprintln!("  [导入] {} (from {})", plain_name, dll.dll_name);
                        self.imports.push(ImportSymbol {
                            name: plain_name.to_string(),
                            dll_name: dll.dll_name.clone(),
                            iat_index,
                            iat_rva: 0, // 稍后计算
                            thunk_rva: 0, // 稍后在 generate_import_thunks 中计算
                            iat_offset: 0, // 稍后在 build_import_data 中计算
                        });
                        iat_index += 1;
                    }
                    found = true;
                    break;
                }
            }
            if !found {
                bail!("未定义的符号: {} (plain: {}) (没有对应的导入配置)", sym_name, plain_name);
            }
        }

        Ok(())
    }

    /// 在 .text 节区中注入 nocrt 函数实现
    fn inject_nocrt_function(&mut self, name: &str) -> Result<Option<(usize, u32)>> {
        // 找到或创建 .text 节区
        let text_idx = self.merged_sections.iter().position(|s| s.name == ".text")
            .unwrap_or_else(|| {
                self.merged_sections.push(MergedSection {
                    name: ".text".to_string(),
                    data: Vec::new(),
                    characteristics: section_flags::IMAGE_SCN_CNT_CODE | section_flags::IMAGE_SCN_MEM_EXECUTE | section_flags::IMAGE_SCN_MEM_READ,
                    rva: 0,
                    file_offset: 0,
                });
                self.merged_sections.len() - 1
            });

        let text_sec = &mut self.merged_sections[text_idx];
        let offset = text_sec.data.len() as u32;

        // 注入对应的 x64 机器码实现
        let code: Vec<u8> = match name {
            "memcpy" => {
                // x64: memcpy(dst=rcx, src=rdx, len=r8)
                // 使用 rep movsb（需要 CLD 确保 DF=0）
                vec![
                    0xFC,                   // cld
                    0x48, 0x89, 0xC8,       // mov rax, rcx  (save dst for return)
                    0x48, 0x89, 0xD6,       // mov rsi, rdx  (src -> rsi)
                    0x48, 0x89, 0xC7,       // mov rdi, rax  (dst -> rdi)
                    0x4C, 0x89, 0xC1,       // mov rcx, r8   (len -> rcx)
                    0xF3, 0xA4,             // rep movsb
                    0xC3,                   // ret (rax = dst)
                ]
            }
            "memset" => {
                // x64: memset(dst=rcx, val=edx, len=r8)
                vec![
                    0xFC,                   // cld
                    0x48, 0x89, 0xC8,       // mov rax, rcx  (save dst for return)
                    0x48, 0x89, 0xC7,       // mov rdi, rax  (dst -> rdi)
                    0x4C, 0x89, 0xC1,       // mov rcx, r8   (len -> rcx)
                    0x88, 0xD0,             // mov al, dl    (val -> al)
                    0xF3, 0xAA,             // rep stosb
                    0xC3,                   // ret (rax = dst)
                ]
            }
            "malloc" => {
                // x64: malloc(size=rcx)
                // 调用 GetProcessHeap() + HeapAlloc(heap, 0, size)
                // 需要通过 IAT 间接调用
                // 简化 stub：返回 NULL（实际使用中 runtime 会提供 js_malloc）
                vec![
                    0x48, 0x31, 0xC0,       // xor rax, rax (return NULL)
                    0xC3,                   // ret
                ]
            }
            "free" => {
                // x64: free(ptr=rcx) -> 无操作 stub
                vec![
                    0xC3,                   // ret
                ]
            }
            "realloc" => {
                // x64: realloc(ptr=rcx, size=rdx) -> stub
                vec![
                    0x48, 0x31, 0xC0,       // xor rax, rax (return NULL)
                    0xC3,                   // ret
                ]
            }
            "strstr" => {
                // x64: strstr(haystack=rcx, needle=rdx)
                // 简化 stub：返回 NULL（未找到）
                vec![
                    0x48, 0x31, 0xC0,       // xor rax, rax (return NULL)
                    0xC3,                   // ret
                ]
            }
            _ => {
                // 其他函数暂不支持注入
                return Ok(None);
            }
        };

        text_sec.data.extend_from_slice(&code);
        
        Ok(Some((text_idx, offset)))
    }

    /// 分配 RVA（相对虚拟地址）
    fn assign_rvas(&mut self) -> Result<()> {
        let section_alignment = 0x1000; // 4KB
        let mut current_rva = 0x1000u32; // 第一个节区从 0x1000 开始（header 占一页）

        for (sec_idx, sec) in self.merged_sections.iter_mut().enumerate() {
            sec.rva = current_rva;
            
            // 更新该节区中所有符号的 RVA
            for entry in self.symbol_table.values_mut() {
                if entry.section_idx == sec_idx {
                    entry.rva = sec.rva + entry.section_offset;
                }
            }

            // 对齐到下一页（至少一页，即使节区为空）
            let size = sec.data.len() as u32;
            let aligned_size = if size == 0 {
                section_alignment
            } else {
                (size + section_alignment - 1) & !(section_alignment - 1)
            };
            current_rva += aligned_size;
        }

        // 分配导入表的 RVA（放在所有节区之后）
        let iat_rva = current_rva;
        for imp in &mut self.imports {
            imp.iat_rva = iat_rva + imp.iat_index * 8; // 每个 IAT 条目 8 字节（x64）
        }

        // 设置入口点（尝试多种名称）
        let entry_names = [
            &self.config.entry_point,
            "_start", "_main", "WinMain", "wWinMain",
        ];
        let mut found_entry = false;
        
        eprintln!("\n[ENTRY] 查找入口点...");
        eprintln!("[ENTRY] 符号表大小: {}", self.symbol_table.len());
        
        // 调试: 打印符号表中所有包含 "start" 的符号
        for (name, entry) in &self.symbol_table {
            if name.to_lowercase().contains("start") {
                eprintln!("[ENTRY] 找到符号: {} -> section_idx={}, offset={}, rva={:#x}", 
                    name, entry.section_idx, entry.section_offset, entry.rva);
            }
        }
        
        for name in &entry_names {
            eprintln!("[ENTRY] 尝试: {}", name);
            if let Some(entry) = self.symbol_table.get(*name) {
                self.entry_rva = entry.rva;
                eprintln!("[ENTRY] ✅ 找到入口点: {} at rva={:#x}", name, entry.rva);
                found_entry = true;
                break;
            }
        }
        if !found_entry {
            bail!("找不到入口点 '{}'（已尝试: {}）", self.config.entry_point, entry_names.join(", "));
        }

        Ok(())
    }

    /// 为导入符号生成跳转桩（thunk）
    /// x64 COFF 中，E8（call rel32）不能直接跳转到 IAT 地址（那是数据不是代码）
    /// 需要在代码节区末尾添加 thunk: jmp [rip+disp32] 指向 IAT 条目
    /// 然后将符号表中导入符号的 RVA 改为 thunk 的 RVA
    fn generate_import_thunks(&mut self) -> Result<()> {
        if self.imports.is_empty() {
            return Ok(());
        }

        // 找到代码节区（.text 或 .text$mn）
        let text_idx = self.merged_sections.iter().position(|s| {
            (s.characteristics & section_flags::IMAGE_SCN_CNT_CODE) != 0
        });

        let text_idx = match text_idx {
            Some(idx) => idx,
            None => return Ok(()), // 没有代码节区，不需要 thunk
        };

        // 对齐到 16 字节
        let text = &mut self.merged_sections[text_idx];
        while text.data.len() % 16 != 0 {
            text.data.push(0xCC); // INT3 padding
        }

        let sec_rva = text.rva;

        // 为每个导入符号生成 thunk
        for i in 0..self.imports.len() {
            let imp_name = self.imports[i].name.clone();
            let imp_iat_rva = self.imports[i].iat_rva;
            let thunk_rva = sec_rva + text.data.len() as u32;
            
            // 始终输出关键导入的调试信息
            if imp_name == "GetProcessHeap" || imp_name == "HeapAlloc" || imp_name == "SetConsoleOutputCP" || imp_name == "ExitProcess" {
                let disp = imp_iat_rva as i32 - (thunk_rva as i32 + 6);
                eprintln!("  [关键导入] {} IAT_RVA=0x{:08X} thunk_RVA=0x{:08X} disp={}", imp_name, imp_iat_rva, thunk_rva, disp);
            }
            
            // thunk: jmp [rip+disp32]  ->  FF 25 xx xx xx xx
            // disp32 = IAT_RVA - (thunk_RVA + 6)  （RIP 在 thunk 结束后指向下一条指令）
            let disp = imp_iat_rva as i32 - (thunk_rva as i32 + 6);
            let disp_bytes = (disp as u32).to_le_bytes();
            
            // FF 25 = jmp QWORD PTR [rip+disp32]
            text.data.extend_from_slice(&[0xFF, 0x25]);
            text.data.extend_from_slice(&disp_bytes);
            
            // 更新符号表中该导入符号的 RVA 为 thunk 的 RVA
            // 这样 REL32 重定位会指向 thunk 而不是 IAT
            if let Some(entry) = self.symbol_table.get_mut(&imp_name) {
                entry.rva = thunk_rva;
            }
            // 同时更新 __imp_ 版本
            let imp_imp_name = format!("__imp_{}", imp_name);
            if let Some(entry) = self.symbol_table.get_mut(&imp_imp_name) {
                entry.rva = thunk_rva;
            }
            // 记录 thunk RVA 到 ImportSymbol（用于 apply_relocations 后备路径）
            self.imports[i].thunk_rva = thunk_rva;

            #[cfg(test)]
            eprintln!("  Generated thunk for {} at RVA {:#x} -> jmp [rip+{:#x}] -> IAT {:#x}", 
                imp_name, thunk_rva, disp, imp_iat_rva);
        }

        Ok(())
    }

    /// 应用重定位
    fn apply_relocations(&mut self) -> Result<()> {
        // 第一步：为导入符号的 REL32 重定位生成跳转桩（thunk）
        // x64 COFF 模型中，E8（直接调用）不能直接跳转到 IAT 地址
        // 需要生成 thunk: jmp [IAT_entry] (FF 25 00 00 00 00)
        // 然后将 E8 的目标改为 thunk 地址
        self.generate_import_thunks()?;

        // 第二步：处理每个对象文件的每个节区的重定位
        for (obj_idx, obj) in self.objects.iter().enumerate() {
            for (sec_idx, sec) in obj.sections.iter().enumerate() {
                let name = String::from_utf8_lossy(&sec.header.name).trim_end_matches('\0').to_string();
                
                #[cfg(test)]
                if sec.relocations.len() > 0 {
                    eprintln!("Checking obj[{}] sec[{}] {} relocs={} map={:?}", 
                        obj_idx, sec_idx, name, sec.relocations.len(), 
                        self.obj_section_map.get(&(obj_idx, sec_idx)));
                }
                
                let Some(&(merged_sec_idx, sec_base_offset)) = self.obj_section_map.get(&(obj_idx, sec_idx)) else {
                    continue;
                };
                
                #[cfg(test)]
                eprintln!("Processing obj[{}] sec[{}] {} relocs={} base={:#x}", 
                    obj_idx, sec_idx, name, sec.relocations.len(), sec_base_offset);

                for rel in &sec.relocations {
                    let rel_offset = (sec_base_offset + rel.virtual_address) as usize;
                    
                    // 根据重定位类型检查所需空间
                    let required_space = match rel.rel_type {
                        reloc_types::IMAGE_REL_AMD64_ADDR64 => 8,
                        _ => 4,
                    };
                    if rel_offset + required_space > self.merged_sections[merged_sec_idx].data.len() {
                        #[cfg(test)]
                        eprintln!("  reloc {} out of bounds (need {} have {})", rel_offset, required_space, self.merged_sections[merged_sec_idx].data.len());
                        continue;
                    }

                    // 查找重定位引用的符号（使用 COFF 原始索引）
                    let sym_idx = rel.symbol_table_index as usize;
                    let sym = match obj.symbols.iter().find(|s| s.coff_index as usize == sym_idx) {
                        Some(s) => s,
                        None => {
                            #[cfg(test)]
                            eprintln!("  Symbol {} not found", sym_idx);
                            continue;
                        }
                    };

                    // 计算目标地址
                    let target_rva = if let Some(entry) = self.symbol_table.get(&sym.name) {
                        #[cfg(test)]
                        eprintln!("  reloc {} -> symbol {} RVA {:#x}", rel_offset, sym.name, entry.rva);
                        entry.rva
                    } else if let Some(imp) = self.imports.iter().find(|i| i.name == sym.name) {
                        // 使用 thunk RVA（如果已生成），否则回退到 IAT RVA
                        let rva = if imp.thunk_rva != 0 { imp.thunk_rva } else { imp.iat_rva };
                        #[cfg(test)]
                        eprintln!("  reloc {} -> import {} RVA {:#x} (thunk={:#x})", rel_offset, sym.name, rva, imp.thunk_rva);
                        rva
                    } else if sym.name.starts_with("__imp_") {
                        // __imp_XXX 符号：去掉前缀后查找导入
                        let plain = &sym.name[6..];
                        if let Some(imp) = self.imports.iter().find(|i| i.name == plain) {
                            let rva = if imp.thunk_rva != 0 { imp.thunk_rva } else { imp.iat_rva };
                            #[cfg(test)]
                            eprintln!("  reloc {} -> __imp_ {} RVA {:#x} (thunk={:#x})", rel_offset, plain, rva, imp.thunk_rva);
                            rva
                        } else {
                            #[cfg(test)]
                            eprintln!("  reloc {} -> __imp_ {} NOT FOUND", rel_offset, plain);
                            continue;
                        }
                    } else {
                        // Fallback: 对于已定义的局部符号（如 $LNxx 标签），
                        // 直接根据 section_number 和 value 计算 RVA
                        if sym.section_number > 0 {
                            let sym_sec_idx = (sym.section_number - 1) as usize;
                            if let Some(&(merged_sec_idx, sec_offset)) = self.obj_section_map.get(&(obj_idx, sym_sec_idx)) {
                                let rva = self.merged_sections[merged_sec_idx].rva + sec_offset + sym.value;
                                #[cfg(test)]
                                eprintln!("  reloc {} -> local {} sec={} val={} RVA {:#x}", 
                                    rel_offset, sym.name, sym.section_number, sym.value, rva);
                                rva
                            } else {
                                #[cfg(test)]
                                eprintln!("  reloc {} -> {} local but no section map", rel_offset, sym.name);
                                continue;
                            }
                        } else {
                            #[cfg(test)]
                            eprintln!("  reloc {} -> {} NOT FOUND (imports count={})", rel_offset, sym.name, self.imports.len());
                            continue;
                        }
                    };

                    // 对于间接调用/跳转（FF 15 / FF 25），不需要 thunk
                    // 直接使用 IAT RVA，因为指令本身就是间接寻址
                    let mut target_rva = target_rva; // 使其可变
                    
                    if rel.rel_type == reloc_types::IMAGE_REL_AMD64_REL32 && rel_offset >= 2 {
                        let data = &self.merged_sections[merged_sec_idx].data;
                        // 检查是否是 FF 15 (call [rip+disp32]) 或 FF 25 (jmp [rip+disp32])
                        if data[rel_offset - 2] == 0xFF && (data[rel_offset - 1] == 0x15 || data[rel_offset - 1] == 0x25) {
                            // 这是间接调用/跳转，不需要 thunk，直接使用 IAT RVA
                            let imp_name = if sym.name.starts_with("__imp_") {
                                sym.name[6..].to_string()
                            } else {
                                sym.name.clone()
                            };
                            if let Some(imp) = self.imports.iter().find(|i| i.name == imp_name) {
                                #[cfg(test)]
                                eprintln!("  reloc {} -> indirect call/jmp, using IAT {:#x} (not thunk {:#x})", 
                                    rel_offset, imp.iat_rva, target_rva);
                                target_rva = imp.iat_rva;
                            }
                        }
                    }
                    let sec_rva = self.merged_sections[merged_sec_idx].rva;
                    let data = &mut self.merged_sections[merged_sec_idx].data;

                    match rel.rel_type {
                        reloc_types::IMAGE_REL_AMD64_REL32 => {
                            // RIP-relative addressing
                            // 修正值 = 目标RVA - (节区RVA + 重定位偏移 + 4)
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 4);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_REL32_1 => {
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 5);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_REL32_2 => {
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 6);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_REL32_3 => {
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 7);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_REL32_4 => {
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 8);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_REL32_5 => {
                            let current = read_u32(data, rel_offset);
                            let fixup = target_rva as i32 - (sec_rva as i32 + rel_offset as i32 + 9);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_ADDR32NB => {
                            // 相对于 image base 的 32 位地址（RVA）
                            let current = read_u32(data, rel_offset);
                            let fixup = (target_rva as i32) - (current as i32);
                            write_u32(data, rel_offset, current.wrapping_add(fixup as u32));
                        }
                        reloc_types::IMAGE_REL_AMD64_ADDR64 => {
                            // 写入目标的全局虚拟地址 (VA = ImageBase + RVA)
                            let va = self.config.image_base + target_rva as u64;
                            write_u64(data, rel_offset, va);
                        }
                        reloc_types::IMAGE_REL_AMD64_SECTION => {
                            // 节区索引
                            write_u16(data, rel_offset, (merged_sec_idx + 1) as u16);
                        }
                        reloc_types::IMAGE_REL_AMD64_SECREL => {
                            // 相对于节区的偏移
                            let fixup = target_rva - sec_rva;
                            write_u32(data, rel_offset, fixup);
                        }
                        _ => {
                            // 忽略其他重定位类型
                        }
                    }
                }
            }
        }

        Ok(())
    }

    /// 确保 .rdata 节区存在（用于存放导入数据）
    fn ensure_rdata_section(&mut self) -> Result<()> {
        if self.merged_sections.iter().any(|s| s.name == ".rdata") {
            // .rdata 需要可写（IAT 需要被 Windows 加载器填充）
            if let Some(idx) = self.merged_sections.iter().position(|s| s.name == ".rdata") {
                self.merged_sections[idx].characteristics |= section_flags::IMAGE_SCN_MEM_WRITE;
            }
            return Ok(());
        }
        self.merged_sections.push(MergedSection {
            name: ".rdata".to_string(),
            data: Vec::new(),
            characteristics: section_flags::IMAGE_SCN_CNT_INITIALIZED_DATA | section_flags::IMAGE_SCN_MEM_READ | section_flags::IMAGE_SCN_MEM_WRITE,
            rva: 0,
            file_offset: 0,
        });
        Ok(())
    }

    /// 将导入表数据附加到 .rdata 节区
    fn append_import_data(&mut self) -> Result<()> {
        if self.imports.is_empty() {
            return Ok(());
        }

        let rdata_idx = self.merged_sections.iter().position(|s| s.name == ".rdata")
            .expect("ensure_rdata_section 应该在前面被调用");

        let rdata = &mut self.merged_sections[rdata_idx];

        // 对齐到 8 字节
        while rdata.data.len() % 8 != 0 {
            rdata.data.push(0);
        }

        // 计算导入数据在 .rdata 中的 RVA（此时 rdata.rva 已经分配）
        let import_rva = rdata.rva + rdata.data.len() as u32;
        self.import_data_rva = import_rva;
        self.import_directory_rva = import_rva;  // Import Directory 就在导入数据的开头

        // 更新所有导入符号的 IAT RVA
        let num_dlls = self.imports.iter().map(|i| i.dll_name.clone()).collect::<std::collections::HashSet<_>>().len();
        let idt_size = (num_dlls + 1) * 20;
        let ilt_size = (self.imports.len() + num_dlls) * 8;
        let iat_offset_in_import = idt_size + ilt_size;

        for imp in &mut self.imports {
            imp.iat_rva = import_rva + iat_offset_in_import as u32 + imp.iat_index * 8;
        }

        // 释放 rdata 借用
        drop(rdata);

        // 重新构建导入数据（使用更新后的 RVA）
        let (import_data, iat_offset_map) = self.build_import_data()?;
        
        // 更新 ImportSymbol 的 iat_offset
        for (iat_index, iat_offset) in iat_offset_map {
            if iat_index < self.imports.len() {
                self.imports[iat_index].iat_offset = iat_offset;
            }
        }
        
        #[cfg(test)]
        eprintln!("Import data size: {} (0x{:x})", import_data.len(), import_data.len());
        
        // 调试：输出 IAT 条目的初始值
        eprintln!("\n=== IAT 条目初始值 ===");
        
        for imp in &self.imports {
            let iat_offset = imp.iat_offset; // 使用记录的偏移
            if iat_offset == 0 || iat_offset >= import_data.len() {
                eprintln!("  {} iat_idx={} offset=INVALID value=SKIPPED", imp.name, imp.iat_index);
                continue;
            }
            // IAT 条目是 8 字节（u64）
            let iat_value = u64::from_le_bytes([
                import_data[iat_offset],
                import_data[iat_offset + 1],
                import_data[iat_offset + 2],
                import_data[iat_offset + 3],
                import_data[iat_offset + 4],
                import_data[iat_offset + 5],
                import_data[iat_offset + 6],
                import_data[iat_offset + 7],
            ]);
            eprintln!("  {} iat_idx={} offset=0x{:X} value=0x{:016X}", 
                     imp.name, imp.iat_index, iat_offset, iat_value);
        }
        eprintln!();

        // 附加到 .rdata 节区
        self.merged_sections[rdata_idx].data.extend_from_slice(&import_data);
        
        // .rdata 应该保持只读，不要添加 WRITE 标志
        // Windows 加载器会正确处理 IAT，即使节区是只读的
        
        #[cfg(test)]
        eprintln!(".rdata total size after append: {} (0x{:x})", 
            self.merged_sections[rdata_idx].data.len(), 
            self.merged_sections[rdata_idx].data.len());

        Ok(())
    }

    /// 构建 PE 文件
    /// 收集需要重定位的位置
    fn collect_relocations(&mut self) {
        eprintln!("\n[RELOC] 收集重定位信息...");
        
        // 1. 收集 IAT 调用的重定位
        // IAT 调用使用 RIP-relative 寻址，需要重定位
        for imp in &self.imports {
            // IAT 条目的 RVA 需要重定位
            self.reloc_entries.push(RelocEntry {
                rva: imp.iat_rva,
                typ: 10, // IMAGE_REL_BASED_DIR64
            });
        }
        
        // 2. 收集代码中的重定位
        // 遍历所有代码节区，查找重定位指令
        for sec in &self.merged_sections {
            if (sec.characteristics & section_flags::IMAGE_SCN_CNT_CODE) != 0 {
                // 扫描代码查找 RIP-relative 寻址模式
                // FF 15 xx xx xx xx = call qword [rip+offset]
                // FF 25 xx xx xx xx = jmp qword [rip+offset]
                // 48 8D 05 xx xx xx xx = lea rax, [rip+offset]
                
                let code = &sec.data;
                let mut i = 0;
                while i < code.len().saturating_sub(6) {
                    // 检测 FF 15 (call qword [rip+offset])
                    if code[i] == 0xFF && code[i+1] == 0x15 {
                        let reloc_rva = sec.rva + i as u32 + 2;
                        self.reloc_entries.push(RelocEntry {
                            rva: reloc_rva,
                            typ: 4, // IMAGE_REL_BASED_REL32
                        });
                        i += 6;
                        continue;
                    }
                    
                    // 检测 FF 25 (jmp qword [rip+offset])
                    if code[i] == 0xFF && code[i+1] == 0x25 {
                        let reloc_rva = sec.rva + i as u32 + 2;
                        self.reloc_entries.push(RelocEntry {
                            rva: reloc_rva,
                            typ: 4,
                        });
                        i += 6;
                        continue;
                    }
                    
                    // 检测 48 8D 05 (lea rax, [rip+offset])
                    if code[i] == 0x48 && code[i+1] == 0x8D && code[i+2] == 0x05 {
                        let reloc_rva = sec.rva + i as u32 + 3;
                        self.reloc_entries.push(RelocEntry {
                            rva: reloc_rva,
                            typ: 4,
                        });
                        i += 7;
                        continue;
                    }
                    
                    i += 1;
                }
            }
        }
        
        eprintln!("[RELOC] 收集到 {} 个重定位条目", self.reloc_entries.len());
    }
    
    /// 构建重定位表 (.reloc 节区)
    fn build_reloc_section(&self) -> Vec<u8> {
        if self.reloc_entries.is_empty() {
            return Vec::new();
        }
        
        eprintln!("\n[RELOC] 构建重定位表...");
        
        // 按 4KB 页分组
        let mut pages: HashMap<u32, Vec<u16>> = HashMap::new();
        
        for entry in &self.reloc_entries {
            let page_rva = entry.rva & !0xFFF; // 页对齐
            let offset = entry.rva & 0xFFF;    // 页内偏移 (12 位)
            
            // TypeOffset: 高 4 位是类型，低 12 位是偏移
            // 这是 16 位的值，但先用 u32 存储方便计算
            let type_offset: u16 = ((entry.typ as u16) << 12) | (offset as u16);
            
            pages.entry(page_rva).or_insert_with(Vec::new)
                .push(type_offset);
        }
        
        // 生成重定位数据
        let mut reloc_data = Vec::new();
        
        // 排序页
        let mut sorted_pages: Vec<_> = pages.iter().collect();
        sorted_pages.sort_by_key(|(page_rva, _)| **page_rva);
        
        let num_pages = sorted_pages.len();
        
        for (page_rva, entries) in sorted_pages {
            // 每个页块大小: 8 (头部) + entries.len() * 2 (每个 TypeOffset 2 字节)
            let block_size = 8 + entries.len() * 2;
            // 对齐到 4 字节
            let aligned_block_size = (block_size + 3) & !3;
            
            // VirtualAddress
            reloc_data.extend_from_slice(&page_rva.to_le_bytes());
            // SizeOfBlock
            reloc_data.extend_from_slice(&(aligned_block_size as u32).to_le_bytes());
            
            // TypeOffset entries
            for type_offset in entries {
                // type_offset 已经是 16 位的 TypeOffset 值
                reloc_data.extend_from_slice(&type_offset.to_le_bytes());
            }
            
            // 填充到 4 字节对齐
            while reloc_data.len() % 4 != 0 {
                reloc_data.push(0);
            }
        }
        
        eprintln!("[RELOC] 重定位表大小: {} 字节", reloc_data.len());
        eprintln!("[RELOC] 页数: {}", num_pages);
        
        reloc_data
    }
    
    /// 添加 .reloc 节区
    fn add_reloc_section(&mut self) {
        let reloc_data = self.build_reloc_section();
        
        if reloc_data.is_empty() {
            eprintln!("[RELOC] 无重定位数据，跳过 .reloc 节区");
            return;
        }
        
        // 计算 .reloc 节区的 RVA
        let last_rva = if let Some(last) = self.merged_sections.last() {
            last.rva + ((last.data.len() as u32 + 0xFFF) & !0xFFF)
        } else {
            0x1000
        };
        
        self.merged_sections.push(MergedSection {
            name: ".reloc".to_string(),
            characteristics: section_flags::IMAGE_SCN_CNT_INITIALIZED_DATA
                | section_flags::IMAGE_SCN_MEM_READ,
            data: reloc_data,
            rva: last_rva,
            file_offset: 0,
        });
        
        eprintln!("[RELOC] 添加 .reloc 节区, RVA=0x{:X}", last_rva);
    }

    fn build_pe(&self) -> Result<Vec<u8>> {
        // 调试：打印 .text 节区的前 4 字节
        if let Some(text_sec) = self.merged_sections.iter().find(|s| s.name == ".text") {
            if text_sec.data.len() >= 4 {
                eprintln!("[BUILD_PE] .text 前 4 字节: {:02X} {:02X} {:02X} {:02X}", 
                    text_sec.data[0], text_sec.data[1], text_sec.data[2], text_sec.data[3]);
            }
        }
        
        // 调试：打印所有节区的特征值
        eprintln!("\n=== 节区特征值 (build_pe) ===");
        for sec in &self.merged_sections {
            let has_write = (sec.characteristics & 0x80000000) != 0;
            eprintln!("  {} characteristics=0x{:08X} WRITE={}", sec.name, sec.characteristics, has_write);
        }
        eprintln!();
        
        let mut pe = Vec::new();

        // === DOS Header ===
        pe.extend_from_slice(&self.build_dos_header());

        // DOS Stub
        let dos_stub = b"This program cannot be run in DOS mode.\r\n$";
        pe.extend_from_slice(dos_stub);
        while pe.len() % 8 != 0 {
            pe.push(0);
        }

        // 确保 PE header 在 0x80
        while pe.len() < 0x80 {
            pe.push(0);
        }

        // === PE Signature ===
        pe.extend_from_slice(b"PE\0\0");

        let num_sections = self.merged_sections.len() as u16;

        // === COFF File Header ===
        pe.extend_from_slice(&self.build_coff_header(num_sections));

        // === Optional Header ===
        let _opt_header_offset = pe.len();
        let _opt_header_size = self.build_optional_header(&mut pe)?;

        // === Section Headers ===
        let section_headers_offset = pe.len();
        for sec in &self.merged_sections {
            pe.extend_from_slice(&self.build_section_header(sec));
        }

        // === 计算文件偏移 ===
        let file_alignment = 0x200usize; // 512 bytes
        let mut current_file_offset = ((pe.len() + file_alignment - 1) / file_alignment) * file_alignment;
        
        // 计算每个节区的文件偏移（跳过空节区）
        let mut sections_with_offset: Vec<(usize, usize)> = Vec::new();
        for (sec_idx, sec) in self.merged_sections.iter().enumerate() {
            if sec.data.is_empty() {
                // 空节区：PointerToRawData = 0
                let header_offset = section_headers_offset + sec_idx * 40;
                pe[header_offset + 20..header_offset + 24].copy_from_slice(&0u32.to_le_bytes());
                continue;
            }
            let file_offset = current_file_offset;
            let aligned_size = ((sec.data.len() + file_alignment - 1) / file_alignment) * file_alignment;
            current_file_offset = current_file_offset + aligned_size;
            sections_with_offset.push((sec_idx, file_offset));
        }

        // 回写 Section Header 的 PointerToRawData
        for (sec_idx, file_offset) in &sections_with_offset {
            let header_offset = section_headers_offset + sec_idx * 40;
            // PointerToRawData 在节区头偏移 20
            pe[header_offset + 20..header_offset + 24].copy_from_slice(&(*file_offset as u32).to_le_bytes());
        }

        // === 写入节区数据 ===
        for (sec_idx, file_offset) in &sections_with_offset {
            let sec = &self.merged_sections[*sec_idx];
            while pe.len() < *file_offset {
                pe.push(0);
            }
            pe.extend_from_slice(&sec.data);
            let aligned_size = ((sec.data.len() + file_alignment - 1) / file_alignment) * file_alignment;
            while pe.len() < file_offset + aligned_size {
                pe.push(0);
            }
        }

        // Import Directory 已经在 build_optional_header 中设置，不需要重复设置
        // if !self.imports.is_empty() { ... }

        Ok(pe)
    }

    fn build_dos_header(&self) -> [u8; 64] {
        let mut dos = [0u8; 64];
        dos[0] = 0x4D; // 'M'
        dos[1] = 0x5A; // 'Z'
        dos[60] = 0x80; // PE header offset
        dos
    }

    fn build_coff_header(&self, num_sections: u16) -> [u8; 20] {
        let mut coff = [0u8; 20];
        
        // Machine: AMD64
        coff[0] = 0x64;
        coff[1] = 0x86;
        
        // Number of sections
        coff[2..4].copy_from_slice(&num_sections.to_le_bytes());
        
        // Time date stamp
        let timestamp = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap_or_default()
            .as_secs() as u32;
        coff[4..8].copy_from_slice(&timestamp.to_le_bytes());
        
        // Pointer to symbol table (0 = none)
        // Number of symbols (0 = none)
        
        // Size of optional header (PE32+ = 240)
        coff[16] = 0xF0;
        coff[17] = 0x00;
        
        // Characteristics: executable image | large address aware
        coff[18] = 0x22;
        coff[19] = 0x00;
        
        coff
    }

    fn build_optional_header(&self, pe: &mut Vec<u8>) -> Result<usize> {
        let start = pe.len();
        let mut opt = vec![0u8; 240];

        // Magic: PE32+ (0x20b)
        opt[0] = 0x0B;
        opt[1] = 0x02;

        // Major/Minor linker version
        opt[2] = 0x0E;
        opt[3] = 0x1C;

        // Size of code
        let code_size: u32 = self.merged_sections.iter()
            .filter(|s| (s.characteristics & section_flags::IMAGE_SCN_CNT_CODE) != 0)
            .map(|s| s.data.len() as u32)
            .sum();
        opt[4..8].copy_from_slice(&code_size.to_le_bytes());

        // Size of initialized data
        let data_size: u32 = self.merged_sections.iter()
            .filter(|s| (s.characteristics & section_flags::IMAGE_SCN_CNT_INITIALIZED_DATA) != 0)
            .map(|s| s.data.len() as u32)
            .sum();
        opt[8..12].copy_from_slice(&data_size.to_le_bytes());

        // Size of uninitialized data (BSS)
        let bss_size: u32 = self.merged_sections.iter()
            .filter(|s| (s.characteristics & section_flags::IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
            .map(|s| s.data.len() as u32)
            .sum();
        opt[12..16].copy_from_slice(&bss_size.to_le_bytes());

        // Entry point
        opt[16..20].copy_from_slice(&self.entry_rva.to_le_bytes());

        // Base of code (第一个代码节区)
        let code_sec = self.merged_sections.iter().find(|s| {
            s.name == ".text" || s.name == ".text$mn"
        });
        if let Some(text) = code_sec {
            opt[20..24].copy_from_slice(&text.rva.to_le_bytes());
        }

        // Image base
        opt[24..32].copy_from_slice(&self.config.image_base.to_le_bytes());

        // Section alignment (4KB)
        opt[32..36].copy_from_slice(&0x1000u32.to_le_bytes());

        // File alignment (512 bytes)
        opt[36..40].copy_from_slice(&0x200u32.to_le_bytes());

        // OS version
        opt[40] = 0x06;
        opt[42] = 0x00;

        // Image version
        // Subsystem version
        opt[48] = 0x06;
        opt[50] = 0x00;

        // Size of image
        let image_size = if let Some(last) = self.merged_sections.last() {
            last.rva + ((last.data.len() as u32 + 0xFFF) & !0xFFF)
        } else {
            0x1000
        };
        opt[56..60].copy_from_slice(&image_size.to_le_bytes());

        // Size of headers (DOS Header + PE Sig + COFF + Optional + Section Headers, aligned to FileAlignment)
        // 使用 0x400 作为最小值（MSVC 的标准）
        let file_alignment = 0x200u32;
        let num_sections = self.merged_sections.len() as u32;
        let pe_header_size = 4 + 20 + 240; // PE sig + COFF + Optional
        let calculated_size = (pe_header_size + num_sections * 40 + file_alignment - 1) / file_alignment * file_alignment;
        let actual_header_size = calculated_size.max(0x400); // 至少 0x400
        eprintln!("[DEBUG] Size of headers: num_sections={} calculated={} final={}", num_sections, calculated_size, actual_header_size);
        opt[60..64].copy_from_slice(&actual_header_size.to_le_bytes());

        // Checksum (0)

        // Subsystem
        let subsystem = match self.config.subsystem {
            Subsystem::Console => 3u16,
            Subsystem::Windows => 2u16,
        };
        opt[68..70].copy_from_slice(&subsystem.to_le_bytes());

        // DLL characteristics
        // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
        // IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040  // 启用 ASLR
        // IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100
        // IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400
        // IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
        let dll_chars: u16 = 0x0020 | 0x0040 | 0x0100 | 0x8000; // HIGH_ENTROPY_VA | DYNAMIC_BASE | NX_COMPAT | TERMINAL_SERVER_AWARE
        opt[70..72].copy_from_slice(&dll_chars.to_le_bytes());

        // Stack reserve
        opt[72..80].copy_from_slice(&self.config.stack_reserve.to_le_bytes());
        // Stack commit
        opt[80..88].copy_from_slice(&self.config.stack_commit.to_le_bytes());
        // Heap reserve
        opt[88..96].copy_from_slice(&self.config.heap_reserve.to_le_bytes());
        // Heap commit
        opt[96..104].copy_from_slice(&self.config.heap_commit.to_le_bytes());

        // LoaderFlags (偏移 104, 4 bytes) - 必须为 0
        opt[104..108].copy_from_slice(&0u32.to_le_bytes());

        // NumberOfRvaAndSizes (偏移 108, 4 bytes)
        opt[108..112].copy_from_slice(&16u32.to_le_bytes());

        // Data directories (偏移 112 开始，每个 8 字节：RVA + Size)
        // [0] Export table
        // [1] Import table
        // [2] Resource table
        // [3] Exception table (.pdata)
        // ...
        // [12] IAT
        // ...
        
        // 设置 Import Directory (索引 1)
        if !self.imports.is_empty() {
            let import_dir_rva = self.import_directory_rva;
            // IMPORT_DESCRIPTOR 的数量 = DLL 的数量 + 1 (终止符)
            let num_dlls = self.imports.iter().map(|i| i.dll_name.clone()).collect::<std::collections::HashSet<_>>().len();
            let import_dir_size = ((num_dlls + 1) * 20) as u32;
            let import_dir_offset = 112 + 1 * 8;
            opt[import_dir_offset..import_dir_offset+4].copy_from_slice(&import_dir_rva.to_le_bytes());
            opt[import_dir_offset+4..import_dir_offset+8].copy_from_slice(&import_dir_size.to_le_bytes());
            
            eprintln!("[OPTHDR] Import Directory: RVA=0x{:X}, Size={}, num_dlls={}", 
                import_dir_rva, import_dir_size, num_dlls);
            
            // 调试：输出 IMPORT_DESCRIPTOR 的内容
            eprintln!("[OPTHDR] 第 1 个 IMPORT_DESCRIPTOR:");
            eprintln!("  OriginalFirstThunk (ILT RVA): 将从导入数据中读取");
            eprintln!("  TimeDateStamp: 0");
            eprintln!("  ForwarderChain: 0");
            eprintln!("  Name RVA: 将从导入数据中读取");
            eprintln!("  FirstThunk (IAT RVA): 将从导入数据中读取");
        }
        
        // 设置 Exception Directory (索引 3) - .pdata 节区
        if let Some(pdata) = self.merged_sections.iter().find(|s| s.name == ".pdata") {
            let pdata_rva = pdata.rva;
            let pdata_size = pdata.data.len() as u32;
            let exc_dir_offset = 112 + 3 * 8;
            opt[exc_dir_offset..exc_dir_offset+4].copy_from_slice(&pdata_rva.to_le_bytes());
            opt[exc_dir_offset+4..exc_dir_offset+8].copy_from_slice(&pdata_size.to_le_bytes());
        }
        
        // 设置 Base Relocation Directory (索引 5) - .reloc 节区
        if let Some(reloc) = self.merged_sections.iter().find(|s| s.name == ".reloc") {
            let reloc_rva = reloc.rva;
            let reloc_size = reloc.data.len() as u32;
            let reloc_dir_offset = 112 + 5 * 8;
            opt[reloc_dir_offset..reloc_dir_offset+4].copy_from_slice(&reloc_rva.to_le_bytes());
            opt[reloc_dir_offset+4..reloc_dir_offset+8].copy_from_slice(&reloc_size.to_le_bytes());
            eprintln!("[OPTHDR] Base Relocation Directory: RVA=0x{:X}, Size={}", reloc_rva, reloc_size);
        }

        pe.extend_from_slice(&opt);
        Ok(pe.len() - start)
    }

    fn build_section_header(&self, sec: &MergedSection) -> [u8; 40] {
        let mut header = [0u8; 40];
        
        // Name (8 bytes)
        let name_bytes = sec.name.as_bytes();
        let len = name_bytes.len().min(8);
        header[..len].copy_from_slice(&name_bytes[..len]);
        
        // Virtual size
        header[8..12].copy_from_slice(&(sec.data.len() as u32).to_le_bytes());
        
        // Virtual address (RVA)
        header[12..16].copy_from_slice(&sec.rva.to_le_bytes());
        
        // Size of raw data (文件中对齐后的大小)
        let file_size = ((sec.data.len() as u32 + 0x1FF) / 0x200) * 0x200;
        header[16..20].copy_from_slice(&file_size.to_le_bytes());
        
        // Pointer to raw data (稍后更新)
        // 这里简化，实际需要计算文件偏移
        
        // Characteristics
        header[36..40].copy_from_slice(&sec.characteristics.to_le_bytes());
        
        header
    }

    /// 构建导入表数据
    fn build_import_data(&self) -> Result<(Vec<u8>, Vec<(usize, usize)>)> {
        if self.imports.is_empty() {
            return Ok((Vec::new(), Vec::new()));
        }

        // 按 DLL 分组
        let mut dll_groups: Vec<(String, Vec<&ImportSymbol>)> = Vec::new();
        let mut dll_order: Vec<String> = Vec::new();
        for imp in &self.imports {
            if !dll_order.contains(&imp.dll_name) {
                dll_order.push(imp.dll_name.clone());
            }
        }
        for dll_name in &dll_order {
            let funcs: Vec<&ImportSymbol> = self.imports.iter().filter(|i| i.dll_name == *dll_name).collect();
            dll_groups.push((dll_name.clone(), funcs));
        }

        let num_dlls = dll_groups.len();

        // 第一步：计算各部分大小
        let idt_size = (num_dlls + 1) * 20; // IDT (包括 NULL 终止符)
        
        // 计算 ILT/IAT 大小
        let mut total_funcs = 0u32;
        for (_, funcs) in &dll_groups {
            total_funcs += funcs.len() as u32;
        }
        let ilt_size = (total_funcs + num_dlls as u32) * 8; // ILT (每个 DLL 一个 NULL 终止符)
        let iat_size = ilt_size; // IAT 大小与 ILT 相同

        // 第二步：先构建 Hint/Name 和 DLL 名称数据，得到实际大小
        let mut hint_name_data = Vec::new();
        let mut dll_name_data = Vec::new();
        let mut hint_name_offsets: Vec<usize> = Vec::new(); // 每个函数的 Hint/Name 在 hint_name_data 中的偏移

        for (_dll_name, funcs) in &dll_groups {
            #[cfg(test)]
            eprintln!("  DLL: {} funcs={}", _dll_name, funcs.len());
            for func in funcs {
                #[cfg(test)]
                eprintln!("    func: {} iat_idx={}", func.name, func.iat_index);
                let start = hint_name_data.len();
                hint_name_offsets.push(start);
                hint_name_data.extend_from_slice(&[0u8, 0]); // Hint (ordinal)
                hint_name_data.extend_from_slice(func.name.as_bytes());
                hint_name_data.push(0);
                // 对齐到 2 字节
                if hint_name_data.len() % 2 != 0 {
                    hint_name_data.push(0);
                }
                #[cfg(test)]
                eprintln!("      hint_name entry: start={} size={} name_len={}", start, hint_name_data.len() - start, func.name.len());
            }
        }

        for (dll_name, _) in &dll_groups {
            dll_name_data.extend_from_slice(dll_name.as_bytes());
            dll_name_data.push(0);
        }

        // 第三步：计算各部分在导入数据中的偏移
        let ilt_start = idt_size as usize;
        let iat_start = ilt_start + ilt_size as usize;
        let hint_name_start = iat_start + iat_size as usize;
        let dll_name_start = hint_name_start + hint_name_data.len();
        let total_size = dll_name_start + dll_name_data.len();
        
        #[cfg(test)]
        eprintln!("build_import_data: idt={} ilt={} iat={} hint={} dll={} total={}", 
            idt_size, ilt_size, iat_size, hint_name_data.len(), dll_name_data.len(), total_size);

        // 收集 IAT 偏移映射
        let mut iat_offset_map: Vec<(usize, usize)> = Vec::new(); // (iat_index, iat_offset)

        // 第四步：组装数据
        let mut data = vec![0u8; total_size];

        // 填充 IDT
        let mut current_ilt = ilt_start;
        let mut current_iat = iat_start;
        let mut current_hint_name = hint_name_start;
        let mut current_dll_name = dll_name_start;
        let mut func_idx = 0;

        for (dll_name, functions) in &dll_groups {
            let idt_entry = (dll_groups.iter().position(|(n, _)| n == dll_name).unwrap()) * 20;

            // ILT RVA
            let ilt_rva = (self.import_data_rva + current_ilt as u32).to_le_bytes();
            data[idt_entry..idt_entry + 4].copy_from_slice(&ilt_rva);

            // Name RVA
            let name_rva = (self.import_data_rva + current_dll_name as u32).to_le_bytes();
            data[idt_entry + 12..idt_entry + 16].copy_from_slice(&name_rva);

            // IAT RVA
            let iat_rva = (self.import_data_rva + current_iat as u32).to_le_bytes();
            data[idt_entry + 16..idt_entry + 20].copy_from_slice(&iat_rva);

            // 写入 DLL 名称
            data[current_dll_name..current_dll_name + dll_name.len()].copy_from_slice(dll_name.as_bytes());
            current_dll_name += dll_name.len() + 1;

            // 写入 ILT 和 IAT 条目
            for func in functions {
                let hint_name_rva = self.import_data_rva + current_hint_name as u32;

                // ILT 条目 (64-bit: 最高位为0表示按名称导入)
                let ilt_entry = hint_name_rva as u64;
                data[current_ilt..current_ilt + 8].copy_from_slice(&ilt_entry.to_le_bytes());
                // IAT 条目 (初始值与 ILT 相同)
                data[current_iat..current_iat + 8].copy_from_slice(&ilt_entry.to_le_bytes());
                
                // 调试：输出所有函数的 ILT/IAT 写入
                eprintln!("  [写入ILT/IAT] {} iat_idx={} ILT_offset=0x{:X} IAT_offset=0x{:X} hint_name_RVA=0x{:X} ilt_entry=0x{:016X}",
                         func.name, func.iat_index, current_ilt, current_iat, hint_name_rva, ilt_entry);
                
                // 记录 IAT 偏移
                iat_offset_map.push((func.iat_index as usize, current_iat));

                // 写入 Hint/Name
                let hn_offset = hint_name_offsets[func_idx];
                // 计算这个 hint/name 条目的大小（到下一个条目或末尾）
                let next_hn_offset = if func_idx + 1 < hint_name_offsets.len() {
                    hint_name_offsets[func_idx + 1]
                } else {
                    hint_name_data.len()
                };
                let hn_size = next_hn_offset - hn_offset;
                data[current_hint_name..current_hint_name + hn_size]
                    .copy_from_slice(&hint_name_data[hn_offset..hn_offset + hn_size]);

                current_hint_name += hn_size;
                current_ilt += 8;
                current_iat += 8;
                func_idx += 1;
            }

            // ILT/IAT NULL 终止符
            current_ilt += 8;
            current_iat += 8;
        }

        // 不截断数据，保持完整大小
        // data.truncate(current_hint_name.max(current_dll_name).max(ilt_start + ilt_size as usize));
        
        Ok((data, iat_offset_map))
    }

    /// 获取导入数据在 PE 中的 RVA
    fn get_import_rva(&self, offset_in_import_data: usize) -> u32 {
        self.import_data_rva + offset_in_import_data as u32
    }
}

fn read_u32(data: &[u8], offset: usize) -> u32 {
    u32::from_le_bytes([data[offset], data[offset + 1], data[offset + 2], data[offset + 3]])
}

fn read_u64(data: &[u8], offset: usize) -> u64 {
    u64::from_le_bytes([
        data[offset], data[offset + 1], data[offset + 2], data[offset + 3],
        data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7],
    ])
}

fn write_u16(data: &mut [u8], offset: usize, value: u16) {
    data[offset..offset + 2].copy_from_slice(&value.to_le_bytes());
}

fn write_u32(data: &mut [u8], offset: usize, value: u32) {
    data[offset..offset + 4].copy_from_slice(&value.to_le_bytes());
}

fn write_u64(data: &mut [u8], offset: usize, value: u64) {
    data[offset..offset + 8].copy_from_slice(&value.to_le_bytes());
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_native_linker_basic() {
        // 读取 start_nocrt.o 和 runtime_nocrt.o
        let start_o = std::fs::read("start_nocrt.o").expect("找不到 start_nocrt.o");
        let runtime_o = std::fs::read("runtime_nocrt.o").expect("找不到 runtime_nocrt.o");

        println!("start_nocrt.o: {} bytes", start_o.len());
        println!("runtime_nocrt.o: {} bytes", runtime_o.len());

        // 首先解析所有 .o 文件，获取所有未定义符号
        let runtime_coff = CoffObject::parse(&runtime_o).expect("解析 runtime_nocrt.o 失败");
        let start_coff = CoffObject::parse(&start_o).expect("解析 start_nocrt.o 失败");
        
        let mut undefined_symbols: Vec<String> = Vec::new();
        for sym in runtime_coff.undefined_symbols() {
            undefined_symbols.push(sym.name.clone());
        }
        for sym in start_coff.undefined_symbols() {
            undefined_symbols.push(sym.name.clone());
        }
        undefined_symbols.sort();
        undefined_symbols.dedup();
        
        println!("所有未定义符号: {:?}", undefined_symbols);

        // 构建导入配置（包含所有未定义符号）
        let mut kernel32_funcs = Vec::new();
        let mut shell32_funcs = Vec::new();
        
        for sym in &undefined_symbols {
            let plain = if sym.starts_with("__imp_") { &sym[6..] } else { sym.as_str() };
            match plain {
                "ExitProcess" | "SetConsoleOutputCP" | "GetStdHandle" | "WriteFile" | "WriteConsoleA"
                | "HeapAlloc" | "HeapFree" | "HeapReAlloc" | "GetProcessHeap"
                | "CreateFileA" | "ReadFile" | "CloseHandle" | "GetFileSizeEx"
                | "Sleep" | "GetTickCount64" | "GetEnvironmentVariableA"
                | "GetCommandLineA" | "GetCommandLineW" | "VirtualAlloc" | "VirtualFree"
                | "GetSystemTimeAsFileTime" | "QueryPerformanceCounter" | "QueryPerformanceFrequency"
                | "InitializeSListHead" | "RtlCaptureContext" | "RtlVirtualUnwind"
                | "UnhandledExceptionFilter" | "SetUnhandledExceptionFilter"
                | "GetCurrentProcess" | "TerminateProcess" | "IsProcessorFeaturePresent"
                | "GetModuleHandleA" | "GetModuleHandleW" | "GetProcAddress"
                | "LoadLibraryA" | "FreeLibrary" | "MultiByteToWideChar" | "WideCharToMultiByte"
                | "FormatMessageA" | "LocalFree" | "GetLastError" | "SetLastError"
                | "TlsAlloc" | "TlsGetValue" | "TlsSetValue" | "TlsFree"
                | "GetCurrentThreadId" | "GetCurrentProcessId"
                | "DeleteCriticalSection" | "EnterCriticalSection" | "LeaveCriticalSection"
                | "InitializeCriticalSection" | "InitializeCriticalSectionAndSpinCount" => {
                    if !kernel32_funcs.contains(&plain.to_string()) {
                        kernel32_funcs.push(plain.to_string());
                    }
                }
                "CommandLineToArgvW" => {
                    if !shell32_funcs.contains(&plain.to_string()) {
                        shell32_funcs.push(plain.to_string());
                    }
                }
                "main" => {
                    // main 由用户代码提供，跳过
                }
                _ => {
                    println!("警告: 未处理的符号: {}", plain);
                }
            }
        }

        let mut imports = vec![
            DllImport {
                dll_name: "kernel32.dll".to_string(),
                functions: kernel32_funcs,
            },
        ];
        if !shell32_funcs.is_empty() {
            imports.push(DllImport {
                dll_name: "shell32.dll".to_string(),
                functions: shell32_funcs,
            });
        }

        let mut linker = NativeLinker::new(NativeLinkConfig {
            entry_point: "main".to_string(),
            subsystem: Subsystem::Console,
            image_base: 0x140000000,
            stack_reserve: 0x100000,
            stack_commit: 0x1000,
            heap_reserve: 0x100000,
            heap_commit: 0x1000,
            imports,
            // 测试中禁自动注入 runtime（手动添加）
            auto_inject_runtime: false,
            runtime_objects: vec![],
        });

        linker.add_object(&start_o).expect("解析 start_nocrt.o 失败");
        linker.add_object(&runtime_o).expect("解析 runtime_nocrt.o 失败");

        println!("开始链接...");
        
        // 由于缺少 main 函数，链接会失败。这是预期的，因为测试没有用户代码。
        // 我们验证链接器能正确检测到缺失的 main 函数。
        match linker.link() {
            Ok(pe) => {
                println!("✅ 链接成功! 生成 PE 文件: {} bytes", pe.len());
                
                // 验证 PE 文件头
                assert_eq!(pe[0], 0x4D); // 'M'
                assert_eq!(pe[1], 0x5A); // 'Z'
                
                // 验证 PE 签名位置
                let pe_offset = u32::from_le_bytes([pe[60], pe[61], pe[62], pe[63]]) as usize;
                assert_eq!(&pe[pe_offset..pe_offset+4], b"PE\0\0");
                
                // 验证机器类型
                assert_eq!(u16::from_le_bytes([pe[pe_offset+4], pe[pe_offset+5]]), 0x8664);
                
                println!("✅ PE 文件头验证通过");
                
                // 保存到文件以便手动检查
                std::fs::write("test_native_linker.exe", &pe).expect("写入文件失败");
                println!("已保存到 test_native_linker.exe");
            }
            Err(e) => {
                let err_msg = e.to_string();
                if err_msg.contains("main") {
                    println!("✅ 链接器正确检测到缺失的 main 函数: {}", err_msg);
                    println!("   这是预期的 - 用户代码需要提供 main 函数");
                } else {
                    panic!("链接失败: {}", e);
                }
            }
        }
    }

    #[test]
    fn test_native_linker_asm() {
        // 最小化测试：只链接 test_asm.obj（纯汇编，无 CRT）
        let asm_o = std::fs::read("test_asm.obj").expect("找不到 test_asm.obj");

        let mut linker = NativeLinker::new(NativeLinkConfig {
            entry_point: "main".to_string(),
            subsystem: Subsystem::Console,
            image_base: 0x140000000,
            stack_reserve: 0x100000,
            stack_commit: 0x1000,
            heap_reserve: 0x100000,
            heap_commit: 0x1000,
            imports: vec![
                DllImport {
                    dll_name: "kernel32.dll".to_string(),
                    functions: vec!["ExitProcess".to_string()],
                },
            ],
            // 测试中禁自动注入 runtime
            auto_inject_runtime: false,
            runtime_objects: vec![],
        });

        linker.add_object(&asm_o).expect("解析 test_asm.obj 失败");

        println!("开始链接...");
        let pe = linker.link().expect("链接失败");
        
        println!("✅ 链接成功! PE: {} bytes", pe.len());
        
        // 保存
        std::fs::write("test_asm.exe", &pe).expect("写入失败");
        println!("已保存到 test_asm.exe");
        
        // 运行
        match std::process::Command::new(".\\test_asm.exe").output() {
            Ok(output) => {
                let code = output.status.code().unwrap_or(-1);
                println!("退出码: {}", code);
                if code == 42 {
                    println!("✅ 汇编测试通过！ExitProcess(42) 返回了 42");
                } else {
                    println!("❌ 期望退出码 42，实际 {}", code);
                }
            }
            Err(e) => {
                println!("无法运行: {}", e);
            }
        }
    }

    #[test]
    fn test_native_linker_minimal() {
        // 最小化测试：链接 start_nocrt.o + test_empty_main.obj
        let start_o = std::fs::read("start_nocrt.o").expect("start_nocrt.o");
        let main_o = std::fs::read("test_empty_main.obj").expect("test_empty_main.obj");

        let mut linker = NativeLinker::new(NativeLinkConfig {
            entry_point: "_start".to_string(),
            subsystem: Subsystem::Console,
            image_base: 0x140000000,
            stack_reserve: 0x100000,
            stack_commit: 0x1000,
            heap_reserve: 0x100000,
            heap_commit: 0x1000,
            imports: vec![
                DllImport {
                    dll_name: "kernel32.dll".to_string(),
                    functions: vec![
                        "ExitProcess".to_string(),
                        "SetConsoleOutputCP".to_string(),
                    ],
                },
            ],
            // 测试中禁自动注入 runtime
            auto_inject_runtime: false,
            runtime_objects: vec![],
        });

        linker.add_object(&start_o).expect("start_nocrt.o");
        linker.add_object(&main_o).expect("test_empty_main.obj");

        println!("开始链接...");
        let pe = linker.link().expect("链接失败");
        
        println!("✅ 链接成功! PE: {} bytes", pe.len());
        
        // 保存
        std::fs::write("test_minimal.exe", &pe).expect("写入失败");
        println!("已保存到 test_minimal.exe");
        
        // 运行
        match std::process::Command::new(".\\test_minimal.exe").output() {
            Ok(output) => {
                let code = output.status.code().unwrap_or(-1);
                println!("退出码: {}", code);
                if code == 42 {
                    println!("✅ 最小化测试通过！ExitProcess(42) 返回了 42");
                } else {
                    println!("❌ 期望退出码 42，实际 {}", code);
                }
            }
            Err(e) => {
                println!("无法运行: {}", e);
            }
        }
    }

    #[test]
    fn test_native_linker_with_main() {
        // 读取所有 .o 文件
        let start_o = std::fs::read("start_nocrt.o").expect("找不到 start_nocrt.o");
        let runtime_o = std::fs::read("runtime_nocrt.o").expect("找不到 runtime_nocrt.o");
        let main_o = std::fs::read("test_main.obj").expect("找不到 test_main.obj，先编译: cl /c /O2 /GS- test_main.c");

        println!("start_nocrt.o: {} bytes", start_o.len());
        println!("runtime_nocrt.o: {} bytes", runtime_o.len());
        println!("test_main.obj: {} bytes", main_o.len());

        // 收集所有未定义符号
        let mut all_undefined = Vec::new();
        for data in [&start_o, &runtime_o, &main_o] {
            let coff = CoffObject::parse(data).expect("解析失败");
            for sym in coff.undefined_symbols() {
                all_undefined.push(sym.name.clone());
            }
        }
        all_undefined.sort();
        all_undefined.dedup();
        println!("所有未定义符号: {:?}", all_undefined);

        // 构建导入配置
        let mut kernel32_funcs = Vec::new();
        let mut shell32_funcs = Vec::new();
        
        for sym in &all_undefined {
            let plain = if sym.starts_with("__imp_") { &sym[6..] } else { sym.as_str() };
            match plain {
                "ExitProcess" | "SetConsoleOutputCP" | "GetStdHandle" | "WriteFile" | "WriteConsoleA"
                | "HeapAlloc" | "HeapFree" | "HeapReAlloc" | "GetProcessHeap"
                | "CreateFileA" | "ReadFile" | "CloseHandle" | "GetFileSizeEx"
                | "Sleep" | "GetTickCount64" | "GetEnvironmentVariableA"
                | "GetCommandLineA" | "GetCommandLineW" | "VirtualAlloc" | "VirtualFree"
                | "GetSystemTimeAsFileTime" | "QueryPerformanceCounter" | "QueryPerformanceFrequency"
                | "InitializeSListHead" | "RtlCaptureContext" | "RtlVirtualUnwind"
                | "UnhandledExceptionFilter" | "SetUnhandledExceptionFilter"
                | "GetCurrentProcess" | "TerminateProcess" | "IsProcessorFeaturePresent"
                | "GetModuleHandleA" | "GetModuleHandleW" | "GetProcAddress"
                | "LoadLibraryA" | "FreeLibrary" | "MultiByteToWideChar" | "WideCharToMultiByte"
                | "FormatMessageA" | "LocalFree" | "GetLastError" | "SetLastError"
                | "TlsAlloc" | "TlsGetValue" | "TlsSetValue" | "TlsFree"
                | "GetCurrentThreadId" | "GetCurrentProcessId"
                | "DeleteCriticalSection" | "EnterCriticalSection" | "LeaveCriticalSection"
                | "InitializeCriticalSection" | "InitializeCriticalSectionAndSpinCount" => {
                    if !kernel32_funcs.contains(&plain.to_string()) {
                        kernel32_funcs.push(plain.to_string());
                    }
                }
                "CommandLineToArgvW" => {
                    if !shell32_funcs.contains(&plain.to_string()) {
                        shell32_funcs.push(plain.to_string());
                    }
                }
                "main" | "__ImageBase" | "_fltused" | "malloc" | "memcpy" | "memset" | "strstr" => {
                    // 特殊符号，跳过
                }
                _ => {
                    println!("警告: 未处理的符号: {}", plain);
                }
            }
        }

        let mut imports = vec![
            DllImport {
                dll_name: "kernel32.dll".to_string(),
                functions: kernel32_funcs,
            },
        ];
        if !shell32_funcs.is_empty() {
            imports.push(DllImport {
                dll_name: "shell32.dll".to_string(),
                functions: shell32_funcs,
            });
        }

        let mut linker = NativeLinker::new(NativeLinkConfig {
            entry_point: "main".to_string(),
            subsystem: Subsystem::Console,
            image_base: 0x140000000,
            stack_reserve: 0x100000,
            stack_commit: 0x1000,
            heap_reserve: 0x100000,
            heap_commit: 0x1000,
            imports,
            // 测试中禁自动注入 runtime（手动添加）
            auto_inject_runtime: false,
            runtime_objects: vec![],
        });

        linker.add_object(&start_o).expect("解析 start_nocrt.o 失败");
        linker.add_object(&runtime_o).expect("解析 runtime_nocrt.o 失败");
        linker.add_object(&main_o).expect("解析 test_main.obj 失败");

        println!("开始链接...");
        let pe = linker.link().expect("链接失败");
        
        println!("✅ 链接成功! 生成 PE 文件: {} bytes", pe.len());
        
        // 验证 PE 文件头
        assert_eq!(pe[0], 0x4D); // 'M'
        assert_eq!(pe[1], 0x5A); // 'Z'
        
        let pe_offset = u32::from_le_bytes([pe[60], pe[61], pe[62], pe[63]]) as usize;
        assert_eq!(&pe[pe_offset..pe_offset+4], b"PE\0\0");
        assert_eq!(u16::from_le_bytes([pe[pe_offset+4], pe[pe_offset+5]]), 0x8664);
        
        println!("✅ PE 文件头验证通过");
        
        // 保存到文件
        std::fs::write("test_native_linker.exe", &pe).expect("写入文件失败");
        println!("已保存到 test_native_linker.exe");
        
        // 尝试运行（如果系统允许）
        println!("尝试运行生成的可执行文件...");
        match std::process::Command::new(".\\test_native_linker.exe").output() {
            Ok(output) => {
                let stdout = String::from_utf8_lossy(&output.stdout);
                let stderr = String::from_utf8_lossy(&output.stderr);
                println!("退出码: {}", output.status.code().unwrap_or(-1));
                if !stdout.is_empty() {
                    println!("stdout: {}", stdout.trim());
                }
                if !stderr.is_empty() {
                    println!("stderr: {}", stderr.trim());
                }
            }
            Err(e) => {
                println!("无法运行: {} (这是正常的，链接器生成的 PE 可能需要更多调试)", e);
            }
        }
    }
}
