Skip to content

Commit

Permalink
read/coff: short import files (#555)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton committed Jun 26, 2023
1 parent 60c9721 commit bcbf98b
Show file tree
Hide file tree
Showing 6 changed files with 439 additions and 3 deletions.
31 changes: 29 additions & 2 deletions crates/examples/src/objdump.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use object::read::archive::ArchiveFile;
use object::read::coff;
use object::read::macho::{DyldCache, FatArch, FatHeader};
use object::{Endianness, Object, ObjectComdat, ObjectSection, ObjectSymbol};
use object::{Endianness, FileKind, Object, ObjectComdat, ObjectSection, ObjectSymbol};
use std::io::{Result, Write};

pub fn print<W: Write, E: Write>(
Expand All @@ -21,7 +22,11 @@ pub fn print<W: Write, E: Write>(
writeln!(w)?;
writeln!(w, "{}:", String::from_utf8_lossy(member.name()))?;
if let Ok(data) = member.data(file) {
dump_object(w, e, data)?;
if FileKind::parse(data) == Ok(FileKind::CoffImportFile) {
dump_import(w, e, data)?;
} else {
dump_object(w, e, data)?;
}
}
}
}
Expand Down Expand Up @@ -245,3 +250,25 @@ fn dump_parsed_object<W: Write, E: Write>(w: &mut W, e: &mut E, file: &object::F

Ok(())
}

fn dump_import<W: Write, E: Write>(w: &mut W, e: &mut E, data: &[u8]) -> Result<()> {
let file = match coff::CoffImportFile::parse(data) {
Ok(import) => import,
Err(err) => {
writeln!(e, "Failed to parse short import: {}", err)?;
return Ok(());
}
};

writeln!(w, "Format: Short Import File")?;
writeln!(w, "Architecture: {:?}", file.architecture())?;
writeln!(w, "DLL: {:?}", String::from_utf8_lossy(file.dll()))?;
writeln!(w, "Symbol: {:?}", String::from_utf8_lossy(file.symbol()))?;
write!(w, "Import: ")?;
match file.import() {
coff::ImportName::Ordinal(n) => writeln!(w, "Ordinal({})", n)?,
coff::ImportName::Name(name) => writeln!(w, "Name({:?})", String::from_utf8_lossy(name))?,
}
writeln!(w, "Type: {:?}", file.import_type())?;
Ok(())
}
256 changes: 256 additions & 0 deletions crates/examples/testfiles/coff/import_msvc.lib.objdump
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
Format: Archive (kind: Coff)

test_x64.dll:
Format: Short Import File
Architecture: X86_64
DLL: "test_x64.dll"
Symbol: "foo_x64"
Import: Name("foo_x64")
Type: Code

test_x64.dll:
Format: Short Import File
Architecture: X86_64
DLL: "test_x64.dll"
Symbol: "bar_x64"
Import: Ordinal(1)
Type: Code

test_x64.dll:
Format: Short Import File
Architecture: X86_64
DLL: "test_x64.dll"
Symbol: "FOO_x64"
Import: Name("FOO_x64")
Type: Data

test_x64.dll:
Format: Short Import File
Architecture: X86_64
DLL: "test_x64.dll"
Symbol: "BAR_x64"
Import: Name("BAR_x64")
Type: Const

test_x64.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: X86_64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$5", address: 0, size: 0 }
Segment { name: ".idata$4", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$5", address: 0, size: 8, align: 8, kind: Data, flags: Coff { characteristics: c0400040 } }
3: Section { name: ".idata$4", address: 0, size: 8, align: 8, kind: Data, flags: Coff { characteristics: c0400040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "\u{7f}test_x64_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_x64.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: X86_64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$3", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$3", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_x64.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: X86_64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$2", address: 0, size: 0 }
Segment { name: ".idata$6", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$2", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }
3: Section { name: ".idata$6", address: 0, size: e, align: 2, kind: Data, flags: Coff { characteristics: c0200040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__IMPORT_DESCRIPTOR_test_x64", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }
2: Symbol { name: ".idata$2", address: 0, size: 0, kind: Section, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None }
3: Symbol { name: ".idata$6", address: 0, size: 0, kind: Data, section: Section(SectionIndex(3)), scope: Compilation, weak: false, flags: None }
4: Symbol { name: ".idata$4", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
5: Symbol { name: ".idata$5", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
6: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }
7: Symbol { name: "\u{7f}test_x64_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }

.idata$2 relocations
(c, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(0, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(4)), addend: 0, implicit_addend: true })
(10, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true })

Dynamic symbols

test_x86.dll:
Format: Short Import File
Architecture: I386
DLL: "test_x86.dll"
Symbol: "_foo_x86"
Import: Name("foo_x86")
Type: Code

test_x86.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: I386
Flags: Coff { characteristics: 100 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$5", address: 0, size: 0 }
Segment { name: ".idata$4", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$5", address: 0, size: 4, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }
3: Section { name: ".idata$4", address: 0, size: 4, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "\u{7f}test_x86_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_x86.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: I386
Flags: Coff { characteristics: 100 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$3", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$3", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_x86.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: I386
Flags: Coff { characteristics: 100 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$2", address: 0, size: 0 }
Segment { name: ".idata$6", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 42, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$2", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }
3: Section { name: ".idata$6", address: 0, size: e, align: 2, kind: Data, flags: Coff { characteristics: c0200040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__IMPORT_DESCRIPTOR_test_x86", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }
2: Symbol { name: ".idata$2", address: 0, size: 0, kind: Section, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None }
3: Symbol { name: ".idata$6", address: 0, size: 0, kind: Data, section: Section(SectionIndex(3)), scope: Compilation, weak: false, flags: None }
4: Symbol { name: ".idata$4", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
5: Symbol { name: ".idata$5", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
6: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }
7: Symbol { name: "\u{7f}test_x86_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }

.idata$2 relocations
(c, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(0, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(4)), addend: 0, implicit_addend: true })
(10, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true })

Dynamic symbols

test_arm64ec.dll:
Format: Short Import File
Architecture: Unknown
DLL: "test_arm64ec.dll"
Symbol: "#foo_arm64ec"
Import: Name("foo_arm64ec")
Type: Code

test_arm64ec.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: Aarch64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$5", address: 0, size: 0 }
Segment { name: ".idata$4", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 46, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$5", address: 0, size: 8, align: 8, kind: Data, flags: Coff { characteristics: c0400040 } }
3: Section { name: ".idata$4", address: 0, size: 8, align: 8, kind: Data, flags: Coff { characteristics: c0400040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "\u{7f}test_arm64ec_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_arm64ec.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: Aarch64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$3", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 46, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$3", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }

Dynamic symbols

test_arm64ec.dll:
Format: Coff Little-endian 32-bit
Kind: Relocatable
Architecture: Aarch64
Flags: Coff { characteristics: 0 }
Relative Address Base: 0
Entry Address: 0
Segment { name: ".debug$S", address: 0, size: 0 }
Segment { name: ".idata$2", address: 0, size: 0 }
Segment { name: ".idata$6", address: 0, size: 0 }
1: Section { name: ".debug$S", address: 0, size: 46, align: 1, kind: Other, flags: Coff { characteristics: 42100040 } }
2: Section { name: ".idata$2", address: 0, size: 14, align: 4, kind: Data, flags: Coff { characteristics: c0300040 } }
3: Section { name: ".idata$6", address: 0, size: 12, align: 2, kind: Data, flags: Coff { characteristics: c0200040 } }

Symbols
0: Symbol { name: "@comp.id", address: 0, size: 0, kind: Data, section: Absolute, scope: Compilation, weak: false, flags: None }
1: Symbol { name: "__IMPORT_DESCRIPTOR_test_arm64ec", address: 0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None }
2: Symbol { name: ".idata$2", address: 0, size: 0, kind: Section, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None }
3: Symbol { name: ".idata$6", address: 0, size: 0, kind: Data, section: Section(SectionIndex(3)), scope: Compilation, weak: false, flags: None }
4: Symbol { name: ".idata$4", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
5: Symbol { name: ".idata$5", address: 0, size: 0, kind: Section, section: Common, scope: Compilation, weak: false, flags: None }
6: Symbol { name: "__NULL_IMPORT_DESCRIPTOR", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }
7: Symbol { name: "\u{7f}test_arm64ec_NULL_THUNK_DATA", address: 0, size: 0, kind: Data, section: Undefined, scope: Linkage, weak: false, flags: None }

.idata$2 relocations
(c, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(0, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(4)), addend: 0, implicit_addend: true })
(10, Relocation { kind: ImageOffset, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true })

Dynamic symbols
Loading

0 comments on commit bcbf98b

Please sign in to comment.