├── .editorconfig
├── .gitattributes
├── .github
├── FUNDING.yml
└── workflows
│ ├── CI.yml
│ ├── check_wsl.yml
│ └── nuget_org_only.config
├── .gitignore
├── doc
├── PE.png
├── ar_class_diagram.png
├── elf_class_diagram.png
└── readme.md
├── img
├── banner.png
├── libobjectfile.pdn
└── libobjectfile.png
├── license.txt
├── readme.md
└── src
├── .dockerignore
├── Directory.Build.props
├── Directory.Packages.props
├── Dockerfile
├── LibObjectFile.Bench
├── LibObjectFile.Bench.csproj
└── Program.cs
├── LibObjectFile.CodeGen
├── LibObjectFile.CodeGen.csproj
├── Program.Dwarf.cs
├── Program.cs
├── dwarf.h
└── elf.h
├── LibObjectFile.Tests
├── Ar
│ ├── ArTestBase.cs
│ └── ArTests.cs
├── ByteArrayAssert.cs
├── Dwarf
│ └── DwarfTests.cs
├── Elf
│ ├── ElfSimpleTests.cs
│ ├── ElfTestBase.cs
│ ├── compile_files.sh
│ ├── helloworld
│ ├── helloworld.cpp
│ ├── helloworld.o
│ ├── helloworld_debug
│ ├── lib_a.cpp
│ ├── lib_b.cpp
│ ├── lib_debug.so
│ ├── libhelloworld.a
│ ├── libstdc++.so
│ ├── multiple_functions.cpp
│ ├── multiple_functions_debug.o
│ ├── small.cpp
│ └── small_debug.o
├── IO
│ └── TestBatchDataReaderWriter.cs
├── LibObjectFile.Tests.csproj
├── LinuxUtil.cs
├── PE
│ ├── NativeConsole2Win64.exe
│ ├── NativeConsoleWin64.exe
│ ├── NativeLibraryWin64.dll
│ ├── PEReaderTests.cs
│ └── RawNativeConsoleWin64.exe
├── TestFiles
│ └── cmnlib.b00
├── TestsInitializer.cs
└── Verified
│ ├── ArTests.CheckCreateArLibrary.verified.txt
│ ├── ElfSimpleTests.SimpleCodeSection.verified.txt
│ ├── ElfSimpleTests.SimpleCodeSectionAndSymbolSection.verified.txt
│ ├── ElfSimpleTests.SimpleEmpty.verified.txt
│ ├── ElfSimpleTests.SimpleEmptyWithDefaultSections.verified.txt
│ ├── ElfSimpleTests.SimpleProgramHeaderAndCodeSectionAndSymbolSection.verified.txt
│ ├── ElfSimpleTests.SimpleProgramHeaderAndCodeSectionAndSymbolSectionAndRelocation.verified.txt
│ ├── ElfSimpleTests.TestAlignedSection.verified.txt
│ ├── ElfSimpleTests.TestBss.verified.txt
│ ├── ElfSimpleTests.TestElf_name=helloworld.verified.txt
│ ├── ElfSimpleTests.TestElf_name=helloworld_debug.verified.txt
│ ├── ElfSimpleTests.TestElf_name=lib_debug.so.verified.txt
│ ├── ElfSimpleTests.TestElf_name=libstdc++.so.verified.txt
│ ├── ElfSimpleTests.TestElf_name=multiple_functions_debug.o.verified.txt
│ ├── ElfSimpleTests.TestElf_name=small_debug.o.verified.txt
│ ├── PEReaderTests.TestPrinter_name=NativeConsole2Win64.exe.verified.txt
│ ├── PEReaderTests.TestPrinter_name=NativeConsoleWin64.exe.verified.txt
│ ├── PEReaderTests.TestPrinter_name=NativeLibraryWin64.dll.verified.txt
│ ├── PEReaderTests.TestPrinter_name=RawNativeConsoleWin64.exe.verified.txt
│ └── PEReaderTests.TestTinyExe97Bytes.verified.txt
├── LibObjectFile.sln
├── LibObjectFile.sln.DotSettings
├── LibObjectFile
├── Ar
│ ├── Ar.cd
│ ├── ArArchiveFile.cs
│ ├── ArArchiveFileReader.cs
│ ├── ArArchiveFileReaderOptions.cs
│ ├── ArArchiveFileWriter.cs
│ ├── ArArchiveKind.cs
│ ├── ArBinaryFile.cs
│ ├── ArElfFile.cs
│ ├── ArFile.cs
│ ├── ArFileEntry.Constants.cs
│ ├── ArLongNamesTable.cs
│ ├── ArObject.cs
│ ├── ArSymbol.cs
│ ├── ArSymbolTable.cs
│ └── ArVisitorContext.cs
├── Collections
│ ├── ObjectList.cs
│ ├── ReadOnlyList.cs
│ ├── SortedObjectList.cs
│ └── TempSpan.cs
├── Diagnostics
│ ├── DiagnosticBag.cs
│ ├── DiagnosticId.cs
│ ├── DiagnosticKind.cs
│ └── DiagnosticMessage.cs
├── Dwarf
│ ├── DwarfAbbreviation.cs
│ ├── DwarfAbbreviationItem.cs
│ ├── DwarfAbbreviationItemKey.cs
│ ├── DwarfAbbreviationTable.cs
│ ├── DwarfAccessibility.cs
│ ├── DwarfAddressRange.cs
│ ├── DwarfAddressRangeTable.cs
│ ├── DwarfAddressSize.cs
│ ├── DwarfArrayOrderingKind.cs
│ ├── DwarfAttribute.cs
│ ├── DwarfAttributeDescriptor.cs
│ ├── DwarfAttributeDescriptors.cs
│ ├── DwarfAttributeEncoding.cs
│ ├── DwarfAttributeFormEx.cs
│ ├── DwarfAttributeKindEx.cs
│ ├── DwarfAttributeValue.cs
│ ├── DwarfCallingConventionEx.cs
│ ├── DwarfCompilationUnit.cs
│ ├── DwarfConstant.cs
│ ├── DwarfContainer.cs
│ ├── DwarfDIE.cs
│ ├── DwarfDIEDeclaration.cs
│ ├── DwarfDiscriminantListKind.cs
│ ├── DwarfElfContext.cs
│ ├── DwarfExpression.cs
│ ├── DwarfFile.cs
│ ├── DwarfFileName.cs
│ ├── DwarfHelper.cs
│ ├── DwarfIdentifierCaseKind.cs
│ ├── DwarfInfoSection.cs
│ ├── DwarfInlineKind.cs
│ ├── DwarfInteger.cs
│ ├── DwarfLanguageKindEx.cs
│ ├── DwarfLayoutConfig.cs
│ ├── DwarfLayoutContext.cs
│ ├── DwarfLine.cs
│ ├── DwarfLineProgramTable.cs
│ ├── DwarfLineSection.cs
│ ├── DwarfLineSequence.cs
│ ├── DwarfLineState.cs
│ ├── DwarfLocation.cs
│ ├── DwarfLocationList.cs
│ ├── DwarfLocationListEntry.cs
│ ├── DwarfLocationSection.cs
│ ├── DwarfObject.cs
│ ├── DwarfOperation.cs
│ ├── DwarfOperationKindEx.cs
│ ├── DwarfPrinter.cs
│ ├── DwarfReader.cs
│ ├── DwarfReaderContext.cs
│ ├── DwarfReaderWriter.cs
│ ├── DwarfReaderWriterContext.cs
│ ├── DwarfRelocatableSection.cs
│ ├── DwarfRelocation.cs
│ ├── DwarfRelocationTarget.cs
│ ├── DwarfSection.cs
│ ├── DwarfSectionLink.cs
│ ├── DwarfStreamExtensions.cs
│ ├── DwarfStringTable.cs
│ ├── DwarfTagEx.cs
│ ├── DwarfUnit.cs
│ ├── DwarfUnitKind.cs
│ ├── DwarfVirtuality.cs
│ ├── DwarfVisibility.cs
│ ├── DwarfWriter.cs
│ └── DwarfWriterContext.cs
├── Elf
│ ├── Elf.cd
│ ├── ElfArch.cs
│ ├── ElfContent.cs
│ ├── ElfContentData.cs
│ ├── ElfContentRange.cs
│ ├── ElfDecoderDirect.cs
│ ├── ElfDecoderSwap.cs
│ ├── ElfEncoderDirect.cs
│ ├── ElfEncoderSwap.cs
│ ├── ElfEncoding.cs
│ ├── ElfFile.Read.cs
│ ├── ElfFile.Write.cs
│ ├── ElfFile.cs
│ ├── ElfFileClass.cs
│ ├── ElfFileLayout.cs
│ ├── ElfFileType.cs
│ ├── ElfHeaderContent.cs
│ ├── ElfHeaderFlags.cs
│ ├── ElfNativeExtensions.cs
│ ├── ElfOSABIEx.cs
│ ├── ElfObjectFileExtensions.cs
│ ├── ElfOffsetCalculationMode.cs
│ ├── ElfPrinter.cs
│ ├── ElfProgramHeaderTable.cs
│ ├── ElfProgramHeaderTable32.cs
│ ├── ElfProgramHeaderTable64.cs
│ ├── ElfReader.cs
│ ├── ElfReaderDirect.cs
│ ├── ElfReaderOptions.cs
│ ├── ElfReaderSwap.cs
│ ├── ElfReader{TDecoder}.cs
│ ├── ElfSection.cs
│ ├── ElfSectionExtension.cs
│ ├── ElfSectionFlags.cs
│ ├── ElfSectionHeaderTable.cs
│ ├── ElfSectionLink.cs
│ ├── ElfSectionSpecialType.cs
│ ├── ElfSectionType.cs
│ ├── ElfSegment.cs
│ ├── ElfSegmentFlags.cs
│ ├── ElfSegmentFlagsCore.cs
│ ├── ElfSegmentType.cs
│ ├── ElfSegmentTypeCore.cs
│ ├── ElfStreamContentData.cs
│ ├── ElfString.cs
│ ├── ElfVisitorContext.cs
│ ├── ElfWriter.cs
│ ├── ElfWriterDirect.cs
│ ├── ElfWriterSwap.cs
│ ├── ElfWriter{TEncoder}.cs
│ ├── IElfDecoder.cs
│ ├── IElfEncoder.cs
│ └── Sections
│ │ ├── ElfCustomNote.cs
│ │ ├── ElfGnuNote.cs
│ │ ├── ElfGnuNoteABITag.cs
│ │ ├── ElfGnuNoteBuildId.cs
│ │ ├── ElfGnuNoteOSKind.cs
│ │ ├── ElfNoBitsSection.cs
│ │ ├── ElfNote.cs
│ │ ├── ElfNoteTable.cs
│ │ ├── ElfNoteType.cs
│ │ ├── ElfNullSection.cs
│ │ ├── ElfRelocation.cs
│ │ ├── ElfRelocationContext.cs
│ │ ├── ElfRelocationTable.cs
│ │ ├── ElfRelocationTableExtensions.cs
│ │ ├── ElfRelocationType.cs
│ │ ├── ElfSectionHeaderStringTable.cs
│ │ ├── ElfStreamSection.cs
│ │ ├── ElfStringTable.cs
│ │ ├── ElfSymbol.cs
│ │ ├── ElfSymbolBind.cs
│ │ ├── ElfSymbolTable.cs
│ │ ├── ElfSymbolTableSectionHeaderIndices.cs
│ │ ├── ElfSymbolType.cs
│ │ └── ElfSymbolVisibility.cs
├── IO
│ ├── BatchDataReader.cs
│ ├── BatchDataWriter.cs
│ ├── StreamExtensions.cs
│ ├── SubStream.cs
│ └── TextWriterIndenter.cs
├── LibObjectFile.csproj
├── LibObjectFile.csproj.DotSettings
├── ObjectElement.cs
├── ObjectFileElement.cs
├── ObjectFileElementHolder.cs
├── ObjectFileException.cs
├── ObjectFileReaderWriter.cs
├── PE
│ ├── DataDirectory
│ │ ├── PEArchitectureDirectory.cs
│ │ ├── PEBaseRelocation.cs
│ │ ├── PEBaseRelocationBlock.cs
│ │ ├── PEBaseRelocationDirectory.cs
│ │ ├── PEBaseRelocationType.cs
│ │ ├── PEBlobDataLink.cs
│ │ ├── PEBoundImportAddressTable.cs
│ │ ├── PEBoundImportAddressTable32.cs
│ │ ├── PEBoundImportAddressTable64.cs
│ │ ├── PEBoundImportDirectory.cs
│ │ ├── PEBoundImportDirectoryEntry.cs
│ │ ├── PEBoundImportForwarderRef.cs
│ │ ├── PEClrMetadata.cs
│ │ ├── PECompositeSectionData.cs
│ │ ├── PEDataDirectory.cs
│ │ ├── PEDataDirectoryKind.cs
│ │ ├── PEDebugDirectory.cs
│ │ ├── PEDebugDirectoryEntry.cs
│ │ ├── PEDebugKnownType.cs
│ │ ├── PEDebugSectionData.cs
│ │ ├── PEDebugSectionDataRSDS.cs
│ │ ├── PEDebugStreamExtraData.cs
│ │ ├── PEDebugStreamSectionData.cs
│ │ ├── PEDebugType.cs
│ │ ├── PEDelayImportDirectory.cs
│ │ ├── PEDelayImportDirectoryEntry.cs
│ │ ├── PEDirectoryTable.cs
│ │ ├── PEExceptionDirectory.cs
│ │ ├── PEExceptionFunctionEntry.cs
│ │ ├── PEExceptionFunctionEntryArm.cs
│ │ ├── PEExceptionFunctionEntryX86.cs
│ │ ├── PEExportAddressTable.cs
│ │ ├── PEExportDirectory.cs
│ │ ├── PEExportFunctionEntry.cs
│ │ ├── PEExportNameTable.cs
│ │ ├── PEExportOrdinalTable.cs
│ │ ├── PEGlobalPointerDirectory.cs
│ │ ├── PEGuardFlags.cs
│ │ ├── PEImportAddressTable.cs
│ │ ├── PEImportAddressTable32.cs
│ │ ├── PEImportAddressTable64.cs
│ │ ├── PEImportAddressTableDirectory.cs
│ │ ├── PEImportDirectory.cs
│ │ ├── PEImportDirectoryEntry.cs
│ │ ├── PEImportFunctionEntry.cs
│ │ ├── PEImportFunctionTable.cs
│ │ ├── PEImportLookupTable.cs
│ │ ├── PEImportLookupTable32.cs
│ │ ├── PEImportLookupTable64.cs
│ │ ├── PELoadConfigCodeIntegrity.cs
│ │ ├── PELoadConfigDirectory.cs
│ │ ├── PELoadConfigDirectory32.cs
│ │ ├── PELoadConfigDirectory64.cs
│ │ ├── PELoadConfigDirectoryData32.cs
│ │ ├── PELoadConfigDirectoryData64.cs
│ │ ├── PERawDataDirectory.cs
│ │ ├── PEResourceData.cs
│ │ ├── PEResourceDataEntry.cs
│ │ ├── PEResourceDirectory.cs
│ │ ├── PEResourceDirectoryEntry.cs
│ │ ├── PEResourceDirectoryEntryById.cs
│ │ ├── PEResourceDirectoryEntryByName.cs
│ │ ├── PEResourceEntry.cs
│ │ ├── PEResourceId.cs
│ │ ├── PEResourceString.cs
│ │ ├── PESectionVirtualSizeMode.cs
│ │ ├── PESecurityCertificate.cs
│ │ ├── PESecurityCertificateDirectory.cs
│ │ ├── PESecurityCertificateRevision.cs
│ │ ├── PESecurityCertificateType.cs
│ │ ├── PEThunkAddressTable.cs
│ │ ├── PETlsCharacteristics.cs
│ │ ├── PETlsDirectory.cs
│ │ ├── PETlsDirectory32.cs
│ │ ├── PETlsDirectory64.cs
│ │ ├── PETlsDirectoryData32.cs
│ │ ├── PETlsDirectoryData64.cs
│ │ └── PEUnknownDirectory.cs
│ ├── IPELink.cs
│ ├── Internal
│ │ ├── RawDelayLoadDescriptor.cs
│ │ ├── RawExceptionFunctionEntryARM.cs
│ │ ├── RawExceptionFunctionEntryX86.cs
│ │ ├── RawImageDataDirectory.cs
│ │ ├── RawImageDataDirectoryArray.cs
│ │ ├── RawImageDebugDirectory.cs
│ │ ├── RawImageOptionalHeader32.cs
│ │ ├── RawImageOptionalHeader64.cs
│ │ ├── RawImageOptionalHeaderBase32.cs
│ │ ├── RawImageOptionalHeaderBase64.cs
│ │ ├── RawImageOptionalHeaderCommonPart1.cs
│ │ ├── RawImageOptionalHeaderCommonPart2.cs
│ │ ├── RawImageOptionalHeaderCommonPart3.cs
│ │ ├── RawImageOptionalHeaderSize32.cs
│ │ ├── RawImageOptionalHeaderSize64.cs
│ │ ├── RawImageResourceDirectoryEntry.cs
│ │ ├── RawImageSectionHeader.cs
│ │ ├── RawImportDirectoryEntry.cs
│ │ ├── RawImportFunctionEntry32.cs
│ │ ├── RawImportFunctionEntry64.cs
│ │ ├── RawPEBoundImportDirectory.cs
│ │ └── RawPEBoundImportForwarderRef.cs
│ ├── PE.cd
│ ├── PEAsciiStringLink.cs
│ ├── PECoffHeader.cs
│ ├── PEDosHeader.cs
│ ├── PEDosMagic.cs
│ ├── PEExtraData.cs
│ ├── PEFile.Layout.cs
│ ├── PEFile.Read.cs
│ ├── PEFile.Relocate.cs
│ ├── PEFile.Verify.cs
│ ├── PEFile.Write.cs
│ ├── PEFile.cs
│ ├── PEFunctionAddressLink.cs
│ ├── PEImageReader.cs
│ ├── PEImageReaderOptions.cs
│ ├── PEImageWriter.cs
│ ├── PEImageWriterOptions.cs
│ ├── PEImportHintName.cs
│ ├── PEImportHintNameLink.cs
│ ├── PEModuleHandleLink.cs
│ ├── PEObject.cs
│ ├── PEObjectBase.cs
│ ├── PEObjectBaseExtensions.cs
│ ├── PEObjectExtensions.cs
│ ├── PEOptionalHeader.cs
│ ├── PEOptionalHeaderMagic.cs
│ ├── PEPrinter.cs
│ ├── PESection.cs
│ ├── PESectionData.cs
│ ├── PESectionDataExtensions.cs
│ ├── PESectionDataLink.cs
│ ├── PESectionLink.cs
│ ├── PESectionName.Defaults.cs
│ ├── PESectionName.cs
│ ├── PESignature.cs
│ ├── PEStreamExtraData.cs
│ ├── PEStreamSectionData.cs
│ ├── PEVisitorContext.cs
│ ├── RVA.cs
│ ├── RVO.cs
│ ├── VA32.cs
│ └── VA64.cs
├── Utils
│ ├── AlignHelper.cs
│ └── DataUtils.cs
├── VisitorContextBase.cs
└── generated
│ ├── LibObjectFile.Dwarf.generated.cs
│ └── LibObjectFile.Elf.generated.cs
├── dotnet-releaser.toml
├── global.json
├── native
└── Win64
│ └── NativeProjects
│ ├── NativeConsole2Win64
│ ├── NativeConsole2Win64.cpp
│ ├── NativeConsole2Win64.vcxproj
│ └── NativeConsole2Win64.vcxproj.filters
│ ├── NativeConsoleWin64
│ ├── NativeConsoleWin64.cpp
│ ├── NativeConsoleWin64.vcxproj
│ └── NativeConsoleWin64.vcxproj.filters
│ ├── NativeLibraryWin64
│ ├── NativeLibraryWin64.vcxproj
│ ├── NativeLibraryWin64.vcxproj.filters
│ ├── dllmain.cpp
│ ├── framework.h
│ ├── pch.cpp
│ └── pch.h
│ ├── NativeProjects.sln
│ └── RawNativeConsoleWin64
│ ├── RawNativeConsoleWin64.cpp
│ ├── RawNativeConsoleWin64.vcxproj
│ └── RawNativeConsoleWin64.vcxproj.filters
├── objdasm
├── ObjDisasmApp.cs
├── Program.cs
└── objdasm.csproj
└── test-with-docker.sh
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text=auto
3 | *.sh text eol=lf
4 | *.verified.txt text eol=lf working-tree-encoding=UTF-8
5 | *.verified.xml text eol=lf working-tree-encoding=UTF-8
6 | *.verified.json text eol=lf working-tree-encoding=UTF-8
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [xoofx] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on:
4 | push:
5 | paths-ignore:
6 | - 'doc/**'
7 | - 'changelog.md'
8 | - 'readme.md'
9 | pull_request:
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-22.04
14 | steps:
15 | - name: "Build, Test, Pack and Publish"
16 | uses: xoofx/.github/.github/actions/dotnet-releaser-action@main
17 | with:
18 | NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }}
19 |
--------------------------------------------------------------------------------
/.github/workflows/check_wsl.yml:
--------------------------------------------------------------------------------
1 | name: check_wsl
2 | on:
3 | # Run this workflow only manually
4 | workflow_dispatch:
5 | jobs:
6 | build:
7 | runs-on: windows-latest
8 | steps:
9 | - uses: Vampire/setup-wsl@v3
10 | with:
11 | distribution: Ubuntu-22.04
12 | - name: List installed WSL distributions
13 | run: wsl -l -v
14 |
--------------------------------------------------------------------------------
/.github/workflows/nuget_org_only.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/doc/PE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/doc/PE.png
--------------------------------------------------------------------------------
/doc/ar_class_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/doc/ar_class_diagram.png
--------------------------------------------------------------------------------
/doc/elf_class_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/doc/elf_class_diagram.png
--------------------------------------------------------------------------------
/img/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/img/banner.png
--------------------------------------------------------------------------------
/img/libobjectfile.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/img/libobjectfile.pdn
--------------------------------------------------------------------------------
/img/libobjectfile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/img/libobjectfile.png
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019, Alexandre Mutel
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification
5 | , are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/src/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 | .dockerignore
3 | **/bin/
4 | **/obj/
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | True
4 | True
5 | $(NoWarn);CS1591;CS1573;CS1574;CS1734;CS0419
6 |
7 |
--------------------------------------------------------------------------------
/src/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | false
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:18.04
2 |
3 | RUN apt-get update && apt-get -y install \
4 | # .NET Core SDK needs: https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?pivots=os-linux&tabs=netcore31#supported-operating-systems
5 | curl libcurl4 libssl1.0.0 zlib1g libicu60 libkrb5-3 liblttng-ust0 \
6 | # Tests need:
7 | build-essential gcc
8 |
9 | ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
10 | RUN curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version 3.0.100
11 |
12 | ENV PATH="/root/.dotnet:${PATH}"
13 | RUN dotnet --info
14 |
15 | WORKDIR /src
16 |
17 | CMD dotnet test
--------------------------------------------------------------------------------
/src/LibObjectFile.Bench/LibObjectFile.Bench.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/LibObjectFile.CodeGen/LibObjectFile.CodeGen.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | Exe
5 | false
6 | $(NETCoreSdkRuntimeIdentifier)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | PreserveNewest
18 |
19 |
20 | PreserveNewest
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Ar/ArTestBase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using LibObjectFile.Diagnostics;
7 | using LibObjectFile.Tests.Elf;
8 |
9 | namespace LibObjectFile.Tests.Ar;
10 |
11 | public abstract class ArTestBase : ElfTestBase
12 | {
13 | protected static void ExpectNoDiagnostics(DiagnosticBag diagnostics)
14 | {
15 | if (diagnostics.Messages.Count != 0)
16 | {
17 | Console.WriteLine(diagnostics);
18 | Assert.AreEqual(0, diagnostics.Messages.Count, $"Invalid number of diagnostics found, expecting no diagnostics");
19 | }
20 | }
21 |
22 | protected static void ExpectDiagnostics(DiagnosticBag diagnostics, params DiagnosticId[] ids)
23 | {
24 | if (diagnostics.Messages.Count != ids.Length)
25 | {
26 | Console.WriteLine(diagnostics);
27 | Assert.AreEqual(ids.Length, diagnostics.Messages.Count, $"Invalid number of diagnostics found, expecting {ids.Length} entries [{string.Join(", ", ids)}]");
28 | }
29 |
30 | for (var i = 0; i < diagnostics.Messages.Count; i++)
31 | {
32 | var diagnosticsMessage = diagnostics.Messages[i];
33 | var expectedId = ids[i];
34 |
35 | if (expectedId != diagnosticsMessage.Id)
36 | {
37 | Console.WriteLine(diagnostics);
38 | Assert.AreEqual(expectedId, diagnosticsMessage.Id, $"Invalid Id {diagnosticsMessage.Id} found for diagnostics [{i}] while expecting {expectedId} from entries [{string.Join(", ", ids)}]");
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/compile_files.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | gcc helloworld.cpp -o helloworld
3 | gcc helloworld.cpp -c -o helloworld.o
4 | ar rcs libhelloworld.a helloworld.o
5 | gcc helloworld.cpp -gdwarf-4 -o helloworld_debug
6 | gcc lib_a.cpp lib_b.cpp -gdwarf-4 -shared -o lib_debug.so
7 | gcc small.cpp -gdwarf-4 -c -o small_debug.o
8 | gcc multiple_functions.cpp -gdwarf-4 -c -o multiple_functions_debug.o
9 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/helloworld:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/helloworld
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/helloworld.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | int main(int argc, char** argv)
3 | {
4 | printf("HelloWorld!\n");
5 | }
6 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/helloworld.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/helloworld.o
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/helloworld_debug:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/helloworld_debug
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/lib_a.cpp:
--------------------------------------------------------------------------------
1 | int process_add(int a, int b)
2 | {
3 | return a + b;
4 | }
5 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/lib_b.cpp:
--------------------------------------------------------------------------------
1 | float process_add2(float a, float b)
2 | {
3 | return a + b;
4 | }
5 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/lib_debug.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/lib_debug.so
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/libhelloworld.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/libhelloworld.a
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/libstdc++.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/libstdc++.so
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/multiple_functions.cpp:
--------------------------------------------------------------------------------
1 | int process_add(int a, int b)
2 | {
3 | return a + b;
4 | }
5 |
6 | float process_add2(float a, float b)
7 | {
8 | return a + b;
9 | }
10 |
11 | float process_both(int a, float b)
12 | {
13 | return (float)process_add(a, (int)b) + process_add2((float)a, b);
14 | }
15 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/multiple_functions_debug.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/multiple_functions_debug.o
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/small.cpp:
--------------------------------------------------------------------------------
1 | struct MyStruct
2 | {
3 | unsigned char* str;
4 |
5 | int count;
6 | };
7 |
8 | typedef char (*TransformCharDelegate)(char);
9 |
10 | int ProcessStructs(MyStruct* input, MyStruct* output, TransformCharDelegate transform)
11 | {
12 | int acc = 0;
13 | for(int i = 0; i < input->count; i++)
14 | {
15 | auto value1 = input->str[i];
16 | auto value2 = output->str[i];
17 | auto value3 = transform(value1) + transform(value2);
18 |
19 | acc += value1 + value2 + value3;
20 | }
21 | return acc;
22 | }
23 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Elf/small_debug.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/Elf/small_debug.o
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/PE/NativeConsole2Win64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/PE/NativeConsole2Win64.exe
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/PE/NativeConsoleWin64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/PE/NativeConsoleWin64.exe
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/PE/NativeLibraryWin64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/PE/NativeLibraryWin64.dll
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/PE/RawNativeConsoleWin64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/PE/RawNativeConsoleWin64.exe
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/TestFiles/cmnlib.b00:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xoofx/LibObjectFile/1d110e2181af9f4792a0b52b84faafe9df43c433/src/LibObjectFile.Tests/TestFiles/cmnlib.b00
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/TestsInitializer.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Runtime.CompilerServices;
3 | using VerifyMSTest;
4 | using VerifyTests;
5 | using VerifyTests.DiffPlex;
6 |
7 | namespace LibObjectFile.Tests;
8 |
9 | internal static class TestsInitializer
10 | {
11 | [ModuleInitializer]
12 | public static void Initialize()
13 | {
14 | VerifyDiffPlex.Initialize(OutputType.Compact);
15 | CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
16 | Verifier.UseProjectRelativeDirectory("Verified");
17 | DiffEngine.DiffRunner.Disabled = true;
18 | VerifierSettings.DontScrubSolutionDirectory();
19 | }
20 | }
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Verified/ArTests.CheckCreateArLibrary.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | filenames:
3 | file2.txt
4 | file3.txt
5 | file4.txt
6 | file5.txt
7 | long_file_name_large_file6.txt,
8 | filecontent: this is filethis is file3this is file4this is file5this is file6 yoyo
9 | }
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Verified/ElfSimpleTests.SimpleEmpty.verified.txt:
--------------------------------------------------------------------------------
1 | ELF Header:
2 | Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
3 | Class: ELF64
4 | Data: 2's complement, little endian
5 | Version: 1 (current)
6 | OS/ABI: UNIX - System V
7 | ABI Version: 0
8 | Type: REL (Relocatable file)
9 | Machine: Advanced Micro Devices X86-64
10 | Version: 0x1
11 | Entry point address: 0x0
12 | Start of program headers: 0 (bytes into file)
13 | Start of section headers: 0 (bytes into file)
14 | Flags: 0x0
15 | Size of this header: 0 (bytes)
16 | Size of program headers: 0 (bytes)
17 | Number of program headers: 0
18 | Size of section headers: 0 (bytes)
19 | Number of section headers: 0
20 | Section header string table index: 0
21 |
22 | There are no sections in this file.
23 |
24 | There are no section groups in this file.
25 |
26 | There are no program headers in this file.
27 |
28 | There is no dynamic section in this file.
29 |
30 | There are no relocations in this file.
31 | No processor specific unwind information to decode
32 |
33 | Dynamic symbol information is not available for displaying symbols.
34 |
35 | No version information found in this file.
36 |
--------------------------------------------------------------------------------
/src/LibObjectFile.Tests/Verified/ElfSimpleTests.SimpleEmptyWithDefaultSections.verified.txt:
--------------------------------------------------------------------------------
1 | ELF Header:
2 | Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
3 | Class: ELF64
4 | Data: 2's complement, little endian
5 | Version: 1 (current)
6 | OS/ABI: UNIX - System V
7 | ABI Version: 0
8 | Type: REL (Relocatable file)
9 | Machine: Advanced Micro Devices X86-64
10 | Version: 0x1
11 | Entry point address: 0x0
12 | Start of program headers: 0 (bytes into file)
13 | Start of section headers: 0 (bytes into file)
14 | Flags: 0x0
15 | Size of this header: 0 (bytes)
16 | Size of program headers: 0 (bytes)
17 | Number of program headers: 0
18 | Size of section headers: 0 (bytes)
19 | Number of section headers: 1
20 | Section header string table index: 0
21 |
22 | Section Header:
23 | [Nr] Name Type Address Off Size ES Flg Lk Inf Al
24 | [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
25 | Key to Flags:
26 | W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
27 | L (link order), O (extra OS processing required), G (group), T (TLS),
28 | C (compressed), x (unknown), o (OS specific), E (exclude),
29 | D (mbind), l (large), p (processor specific)
30 |
31 | There are no section groups in this file.
32 |
33 | There are no program headers in this file.
34 |
35 | There is no dynamic section in this file.
36 |
37 | There are no relocations in this file.
38 | No processor specific unwind information to decode
39 |
40 | No version information found in this file.
41 |
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArArchiveFileReaderOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Ar;
6 |
7 | ///
8 | /// Reader options used by and other methods.
9 | ///
10 | public class ArArchiveFileReaderOptions
11 | {
12 | ///
13 | /// Initializes a new instance.
14 | ///
15 | /// Type of the 'ar' file to load (GNU, BSD...)
16 | public ArArchiveFileReaderOptions(ArArchiveKind archiveKind)
17 | {
18 | ArchiveKind = archiveKind;
19 | ProcessObjectFiles = true;
20 | }
21 |
22 | ///
23 | /// Gets or sets a boolean indicating if the file entries must keep a readonly view
24 | /// on the original stream for the content of the file entries, or it should copy
25 | /// them to modifiable .
26 | ///
27 | public bool IsReadOnly { get; set; }
28 |
29 | ///
30 | /// Gets or sets the type of file to load
31 | ///
32 | public ArArchiveKind ArchiveKind { get; set; }
33 |
34 | ///
35 | /// Gets or sets a boolean indicating if object files are being processed to return
36 | /// typed entries () instead of generic binary file entry ().
37 | /// Default is true
38 | ///
39 | public bool ProcessObjectFiles { get; set; }
40 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArArchiveKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Ar;
6 |
7 | ///
8 | /// The type of archive.
9 | ///
10 | public enum ArArchiveKind
11 | {
12 | ///
13 | /// The common variant, used for example by 'deb' package files.
14 | /// Supports only file names up to 16 characters.
15 | ///
16 | Common,
17 |
18 | ///
19 | /// The GNU variant, used by the `ar` utility on GNU and other systems (including Windows)
20 | /// Based on file format, but using a different strategy
21 | /// for storing long file names, incompatible with format.
22 | ///
23 | GNU,
24 |
25 | ///
26 | /// The BSD variant, used by the `ar` utility on BSD systems (including MacOS)
27 | /// Based on file format and backward compatible with it,
28 | /// but allows to store longer file names and file names containing space.
29 | ///
30 | BSD,
31 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArBinaryFile.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Ar;
8 |
9 | ///
10 | /// An binary stream .
11 | ///
12 | public sealed class ArBinaryFile : ArFile
13 | {
14 | ///
15 | /// Gets or sets the stream associated to this entry.
16 | ///
17 | public Stream? Stream { get; set; }
18 |
19 | public override void Read(ArArchiveFileReader reader)
20 | {
21 | Stream = reader.ReadAsStream(Size);
22 | }
23 |
24 | public override void Write(ArArchiveFileWriter writer)
25 | {
26 | if (Stream != null)
27 | {
28 | writer.Write(Stream);
29 | }
30 | }
31 |
32 | protected override void UpdateLayoutCore(ArVisitorContext context)
33 | {
34 | Size = Stream != null ? (ulong) Stream.Length : 0;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArElfFile.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Elf;
6 | using LibObjectFile.IO;
7 |
8 | namespace LibObjectFile.Ar;
9 |
10 | ///
11 | /// An ELF file entry.
12 | ///
13 | public sealed class ArElfFile : ArFile
14 | {
15 | public ArElfFile()
16 | {
17 | }
18 |
19 | public ArElfFile(ElfFile elfFile)
20 | {
21 | ElfFile = elfFile;
22 | }
23 |
24 | ///
25 | /// Gets or sets the ELF object file.
26 | ///
27 | public ElfFile? ElfFile { get; set; }
28 |
29 | public override void Read(ArArchiveFileReader reader)
30 | {
31 | var startPosition = reader.Stream.Position;
32 | var endPosition = startPosition + (long) Size;
33 | ElfFile = ElfFile.Read(new SubStream(reader.Stream, reader.Stream.Position, (long)Size));
34 | reader.Stream.Position = endPosition;
35 | }
36 |
37 | public override void Write(ArArchiveFileWriter writer)
38 | {
39 | if (ElfFile != null)
40 | {
41 | ElfFile.TryWrite(writer.Stream, out var diagnostics);
42 | diagnostics.CopyTo(writer.Diagnostics);
43 | }
44 | }
45 |
46 | protected override void UpdateLayoutCore(ArVisitorContext context)
47 | {
48 | Size = 0;
49 |
50 | if (ElfFile != null)
51 | {
52 | ElfFile.UpdateLayout(context.Diagnostics);
53 | if (!context.HasErrors)
54 | {
55 | Size = ElfFile.Layout.TotalSize;
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArObject.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 | using LibObjectFile.Elf;
8 |
9 | namespace LibObjectFile.Ar;
10 |
11 | public abstract class ArObjectBase : ObjectFileElement
12 | {
13 | }
14 |
15 | public abstract class ArObject : ArObjectBase
16 | {
17 | ///
18 | /// Gets the containing . Might be null if this section or segment
19 | /// does not belong to an existing .
20 | ///
21 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
22 | public new ArArchiveFile? Parent
23 | {
24 | get => (ArArchiveFile?)base.Parent;
25 | internal set => base.Parent = value;
26 | }
27 |
28 | protected override void ValidateParent(ObjectElement parent)
29 | {
30 | if (!(parent is ArArchiveFile))
31 | {
32 | throw new ArgumentException($"Parent must inherit from type {nameof(ArArchiveFile)}");
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArSymbol.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Ar;
6 |
7 | ///
8 | /// A symbol stored in a
9 | ///
10 | public struct ArSymbol
11 | {
12 | ///
13 | /// Initializes a new instance.
14 | ///
15 | /// The name of the symbol.
16 | /// The associated file entry this symbol is coming from .
17 | public ArSymbol(string name, ArFile file) : this()
18 | {
19 | Name = name;
20 | File = file;
21 | }
22 |
23 | ///
24 | /// Gets or sets the name of this symbol.
25 | ///
26 | public string Name { get; set; }
27 |
28 | ///
29 | /// Internal offset for the name (used for reading)
30 | ///
31 | internal uint NameOffset { get; set; }
32 |
33 | ///
34 | /// Gets or sets the associated file entry this symbol is coming from .
35 | ///
36 | public ArFile File { get; set; }
37 |
38 | ///
39 | /// Internal offset of the file (used for reading)
40 | ///
41 | internal ulong FileOffset { get; set; }
42 |
43 | public override string ToString()
44 | {
45 | return $"Symbol: {Name} => {nameof(File)}: {File}";
46 | }
47 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Ar/ArVisitorContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 |
7 | namespace LibObjectFile.Ar;
8 |
9 | public class ArVisitorContext : VisitorContextBase
10 | {
11 | internal ArVisitorContext(ArArchiveFile file, DiagnosticBag diagnostics) : base(file, diagnostics)
12 | {
13 | }
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Diagnostics/DiagnosticKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Diagnostics;
6 |
7 | ///
8 | /// Defines the kind of a
9 | ///
10 | public enum DiagnosticKind
11 | {
12 | ///
13 | /// A warning message.
14 | ///
15 | Warning,
16 |
17 | ///
18 | /// An error message.
19 | ///
20 | Error,
21 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Diagnostics/DiagnosticMessage.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.Diagnostics;
8 |
9 | ///
10 | /// A diagnostic message.
11 | ///
12 | public readonly struct DiagnosticMessage
13 | {
14 | public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message)
15 | {
16 | Kind = kind;
17 | Id = id;
18 | Context = null;
19 | Message = message;
20 | }
21 |
22 | public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message, object? context)
23 | {
24 | Kind = kind;
25 | Id = id;
26 | Context = context;
27 | Message = message;
28 | }
29 |
30 | ///
31 | /// Gets the kind of this message.
32 | ///
33 | public DiagnosticKind Kind { get; }
34 |
35 | ///
36 | /// Gets the id of this message.
37 | ///
38 | public DiagnosticId Id { get; }
39 |
40 | ///
41 | /// Gets the context of this message.
42 | ///
43 | public object? Context { get; }
44 |
45 | ///
46 | /// Gets the associated text of this message.
47 | ///
48 | public string Message { get; }
49 |
50 | ///
51 | /// Gets the associated stack trace of this message.
52 | ///
53 | public StackTrace? StackTrace { get; init; }
54 |
55 | public override string ToString()
56 | {
57 | if (StackTrace is not null)
58 | {
59 | return $"{Kind} LB{(uint)Id:0000}: {Message}\n{StackTrace}";
60 | }
61 | else
62 | {
63 | return $"{Kind} LB{(uint)Id:0000}: {Message}";
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAccessibility.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfAccessibility : byte
8 | {
9 | Public = DwarfNative.DW_ACCESS_public,
10 |
11 | Private = DwarfNative.DW_ACCESS_private,
12 |
13 | Protected = DwarfNative.DW_ACCESS_protected,
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAddressRange.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public struct DwarfAddressRange
8 | {
9 | public DwarfAddressRange(ulong segment, ulong address, ulong length)
10 | {
11 | Segment = segment;
12 | Address = address;
13 | Length = length;
14 | }
15 |
16 | public ulong Segment { get; set; }
17 |
18 | public ulong Address { get; set; }
19 |
20 | public ulong Length { get; set; }
21 |
22 | public override string ToString()
23 | {
24 | return $"{nameof(Segment)}: 0x{Segment:x16}, {nameof(Address)}: 0x{Address:x16}, {nameof(Length)}: 0x{Length:x16}";
25 | }
26 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAddressSize.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfAddressSize : byte
8 | {
9 | None = 0,
10 |
11 | Bit8 = 1,
12 |
13 | Bit16 = 2,
14 |
15 | Bit32 = 4,
16 |
17 | Bit64 = 8,
18 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfArrayOrderingKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfArrayOrderingKind : byte
8 | {
9 | RowMajor = DwarfNative.DW_ORD_row_major,
10 |
11 | ColumnMajor = DwarfNative.DW_ORD_col_major,
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAttributeDescriptor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 |
8 | namespace LibObjectFile.Dwarf;
9 |
10 | [DebuggerDisplay("{Kind} {Form}")]
11 | public readonly struct DwarfAttributeDescriptor : IEquatable
12 | {
13 | public static readonly DwarfAttributeDescriptor Empty = new DwarfAttributeDescriptor();
14 |
15 | public DwarfAttributeDescriptor(DwarfAttributeKindEx kind, DwarfAttributeFormEx form)
16 | {
17 | Kind = kind;
18 | Form = form;
19 | }
20 |
21 | public readonly DwarfAttributeKindEx Kind;
22 |
23 | public readonly DwarfAttributeFormEx Form;
24 |
25 | public bool IsNull => Kind.Value == 0 && Form.Value == 0;
26 |
27 | public bool Equals(DwarfAttributeDescriptor other)
28 | {
29 | return Kind.Equals(other.Kind) && Form.Equals(other.Form);
30 | }
31 |
32 | public override bool Equals(object? obj)
33 | {
34 | return obj is DwarfAttributeDescriptor other && Equals(other);
35 | }
36 |
37 | public override int GetHashCode()
38 | {
39 | unchecked
40 | {
41 | return (Kind.GetHashCode() * 397) ^ Form.GetHashCode();
42 | }
43 | }
44 |
45 | public static bool operator ==(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
46 | {
47 | return left.Equals(right);
48 | }
49 |
50 | public static bool operator !=(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
51 | {
52 | return !left.Equals(right);
53 | }
54 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAttributeEncoding.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | [Flags]
10 | public enum DwarfAttributeEncoding
11 | {
12 | None,
13 |
14 | Address = 1,
15 |
16 | Block = 1 << 1,
17 |
18 | Constant = 1 << 2,
19 |
20 | ExpressionLocation = 1 << 3,
21 |
22 | Flag = 1 << 4,
23 |
24 | LinePointer = 1 << 5,
25 |
26 | LocationListPointer = 1 << 6,
27 |
28 | MacroPointer = 1 << 7,
29 |
30 | RangeListPointer = 1 << 8,
31 |
32 | Reference = 1 << 9,
33 |
34 | String = 1 << 10,
35 |
36 | RangeList = 1 << 11,
37 |
38 | Indirect = 1 << 12,
39 |
40 | LocationList = 1 << 13,
41 |
42 | AddressPointer = 1 << 14,
43 |
44 | LocationListsPointer = 1 << 15,
45 |
46 | RangeListsPointer = 1 << 16,
47 |
48 | StringOffsetPointer = 1 << 17,
49 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfAttributeValue.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public class DwarfAttributeValue
8 | {
9 | public DwarfAttributeValue(object value)
10 | {
11 | Value = value;
12 | }
13 |
14 | public object Value { get; set; }
15 |
16 | public override string ToString()
17 | {
18 | return $"{nameof(Value)}: {Value}";
19 | }
20 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfCallingConventionEx.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public readonly partial struct DwarfCallingConventionEx : IEquatable
10 | {
11 | public DwarfCallingConventionEx(byte value)
12 | {
13 | Value = (DwarfCallingConvention)value;
14 | }
15 |
16 | public DwarfCallingConventionEx(DwarfCallingConvention value)
17 | {
18 | Value = value;
19 | }
20 |
21 | public readonly DwarfCallingConvention Value;
22 |
23 | public override string ToString()
24 | {
25 | return ToStringInternal() ?? $"Unknown {nameof(DwarfCallingConvention)} (0x{Value:x2})";
26 | }
27 |
28 | public bool Equals(DwarfCallingConventionEx other)
29 | {
30 | return Value == other.Value;
31 | }
32 |
33 | public override bool Equals(object? obj)
34 | {
35 | return obj is DwarfCallingConventionEx other && Equals(other);
36 | }
37 |
38 | public override int GetHashCode()
39 | {
40 | return Value.GetHashCode();
41 | }
42 |
43 | public static bool operator ==(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
44 | {
45 | return left.Equals(right);
46 | }
47 |
48 | public static bool operator !=(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
49 | {
50 | return !left.Equals(right);
51 | }
52 |
53 | public static explicit operator uint(DwarfCallingConventionEx callConv) => (uint)callConv.Value;
54 |
55 | public static implicit operator DwarfCallingConventionEx(DwarfCallingConvention callConv) => new DwarfCallingConventionEx(callConv);
56 |
57 | public static implicit operator DwarfCallingConvention(DwarfCallingConventionEx callConv) => callConv.Value;
58 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfContainer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public abstract class DwarfContainer : DwarfObject
8 | {
9 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfDIEDeclaration.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public abstract class DwarfDIEDeclaration : DwarfDIE
8 | {
9 | // DW_AT_decl_column, DW_AT_decl_file, and DW_AT_decl_line
10 | public ulong? DeclColumn
11 | {
12 | get => GetAttributeValueOpt(DwarfAttributeKind.DeclColumn);
13 | set => SetAttributeValueOpt(DwarfAttributeKind.DeclColumn, value);
14 | }
15 |
16 | public DwarfFileName? DeclFile
17 | {
18 | get => GetAttributeValue(DwarfAttributeKind.DeclFile);
19 | set => SetAttributeValue(DwarfAttributeKind.DeclFile, value);
20 | }
21 |
22 | public ulong? DeclLine
23 | {
24 | get => GetAttributeValueOpt(DwarfAttributeKind.DeclLine);
25 | set => SetAttributeValueOpt(DwarfAttributeKind.DeclLine, value);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfDiscriminantListKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfDiscriminantListKind : byte
8 | {
9 | Label = DwarfNative.DW_DSC_label,
10 |
11 | Range = DwarfNative.DW_DSC_range,
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfFileName.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public sealed class DwarfFileName
10 | {
11 | public DwarfFileName(string name)
12 | {
13 | Name = name;
14 | }
15 |
16 | public string Name { get; }
17 |
18 | public string? Directory { get; set; }
19 |
20 | public ulong Time { get; set; }
21 |
22 | public ulong Size { get; set; }
23 |
24 | public override string ToString()
25 | {
26 | if (Directory != null)
27 | {
28 | return Directory.Contains(Path.AltDirectorySeparatorChar) ? $"{Directory}{Path.AltDirectorySeparatorChar}{Name}" : $"{Directory}{Path.DirectorySeparatorChar}{Name}";
29 | }
30 |
31 | return Name;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfIdentifierCaseKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfIdentifierCaseKind : byte
8 | {
9 | Sensitive = DwarfNative.DW_ID_case_sensitive,
10 |
11 | UpCase = DwarfNative.DW_ID_up_case,
12 |
13 | DownCase = DwarfNative.DW_ID_down_case,
14 |
15 | Insensitive = DwarfNative.DW_ID_case_insensitive,
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfInlineKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfInlineKind : byte
8 | {
9 | NotInlined = DwarfNative.DW_INL_not_inlined,
10 |
11 | Inlined = DwarfNative.DW_INL_inlined,
12 |
13 | DeclaredNotInlined = DwarfNative.DW_INL_declared_not_inlined,
14 |
15 | DeclaredInlined = DwarfNative.DW_INL_declared_inlined,
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfInteger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | [StructLayout(LayoutKind.Explicit)]
10 | public struct DwarfInteger
11 | {
12 | [FieldOffset(0)]
13 | public ulong U64;
14 |
15 | [FieldOffset(0)]
16 | public long I64;
17 |
18 | [FieldOffset(0)]
19 | public sbyte I8;
20 |
21 | [FieldOffset(0)]
22 | public byte U8;
23 |
24 | [FieldOffset(0)]
25 | public short I16;
26 |
27 | [FieldOffset(0)]
28 | public ushort U16;
29 |
30 | [FieldOffset(0)]
31 | public int I32;
32 |
33 | [FieldOffset(0)]
34 | public uint U32;
35 |
36 | public override string ToString()
37 | {
38 | return $"0x{U64:x16}";
39 | }
40 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfLanguageKindEx.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public readonly partial struct DwarfLanguageKindEx : IEquatable
10 | {
11 | public DwarfLanguageKindEx(ushort value)
12 | {
13 | Value = (DwarfLanguageKind)value;
14 | }
15 |
16 | public DwarfLanguageKindEx(DwarfLanguageKind value)
17 | {
18 | Value = value;
19 | }
20 |
21 | public readonly DwarfLanguageKind Value;
22 |
23 | public override string ToString()
24 | {
25 | return ToStringInternal() ?? $"Unknown {nameof(DwarfLanguageKind)} (0x{Value:x4})";
26 | }
27 |
28 | public bool Equals(DwarfLanguageKindEx other)
29 | {
30 | return Value == other.Value;
31 | }
32 |
33 | public override bool Equals(object? obj)
34 | {
35 | return obj is DwarfLanguageKindEx other && Equals(other);
36 | }
37 |
38 | public override int GetHashCode()
39 | {
40 | return Value.GetHashCode();
41 | }
42 |
43 | public static bool operator ==(DwarfLanguageKindEx left, DwarfLanguageKindEx right)
44 | {
45 | return left.Equals(right);
46 | }
47 |
48 | public static bool operator !=(DwarfLanguageKindEx left, DwarfLanguageKindEx right)
49 | {
50 | return !left.Equals(right);
51 | }
52 |
53 | public static explicit operator uint(DwarfLanguageKindEx kind) => (uint)kind.Value;
54 |
55 | public static implicit operator DwarfLanguageKindEx(DwarfLanguageKind kind) => new DwarfLanguageKindEx(kind);
56 |
57 | public static implicit operator DwarfLanguageKind(DwarfLanguageKindEx kind) => kind.Value;
58 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfLayoutConfig.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public class DwarfLayoutConfig
10 | {
11 | private DwarfAttributeForm _defaultAttributeFormForReference;
12 |
13 | public DwarfLayoutConfig()
14 | {
15 | DefaultAttributeFormForReference = DwarfAttributeForm.Ref4;
16 | }
17 |
18 | public DwarfAttributeFormEx DefaultAttributeFormForReference
19 | {
20 | get => _defaultAttributeFormForReference;
21 | set
22 | {
23 | switch (value.Value)
24 | {
25 | case DwarfAttributeForm.Ref1:
26 | case DwarfAttributeForm.Ref2:
27 | case DwarfAttributeForm.Ref4:
28 | break;
29 | default:
30 | throw new ArgumentOutOfRangeException(nameof(value));
31 | }
32 |
33 | _defaultAttributeFormForReference = value;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfLayoutContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 |
10 |
11 | public abstract class DwarfVisitorContext : VisitorContextBase
12 | {
13 | internal DwarfVisitorContext(DwarfFile file, DiagnosticBag diagnostics) : base(file, diagnostics)
14 | {
15 | }
16 | }
17 |
18 |
19 | public sealed class DwarfLayoutContext : DwarfVisitorContext
20 | {
21 | internal DwarfLayoutContext(DwarfFile file, DwarfLayoutConfig config, DiagnosticBag diagnostics) : base(file, diagnostics)
22 | {
23 | Config = config;
24 | }
25 |
26 | public DwarfLayoutConfig Config { get; }
27 |
28 | public DwarfUnit? CurrentUnit { get; internal set; }
29 | }
30 |
31 | public sealed class DwarfVerifyContext : DwarfVisitorContext
32 | {
33 | internal DwarfVerifyContext(DwarfFile file, DiagnosticBag diagnostics) : base(file, diagnostics)
34 | {
35 | }
36 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfLineSequence.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Collections;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using LibObjectFile.Collections;
9 |
10 | namespace LibObjectFile.Dwarf;
11 |
12 | ///
13 | /// A sequence of
14 | ///
15 | [DebuggerDisplay("Count = {Lines.Count,nq}")]
16 | public class DwarfLineSequence : DwarfObject, IEnumerable
17 | {
18 | private readonly ObjectList _lines;
19 |
20 | public DwarfLineSequence()
21 | {
22 | _lines = new ObjectList(this);
23 | }
24 |
25 | public ObjectList Lines => _lines;
26 |
27 | public void Add(DwarfLine line)
28 | {
29 | _lines.Add(line);
30 | }
31 |
32 | protected override void UpdateLayoutCore(DwarfLayoutContext context)
33 | {
34 | // This is implemented in DwarfLineSection
35 | }
36 |
37 | public override void Read(DwarfReader reader)
38 | {
39 | // This is implemented in DwarfLineSection
40 | }
41 |
42 | public override void Write(DwarfWriter writer)
43 | {
44 | // This is implemented in DwarfLineSection
45 | }
46 |
47 | public List.Enumerator GetEnumerator()
48 | {
49 | return _lines.GetEnumerator();
50 | }
51 |
52 | IEnumerator IEnumerable.GetEnumerator()
53 | {
54 | return GetEnumerator();
55 | }
56 |
57 | IEnumerator IEnumerable.GetEnumerator()
58 | {
59 | return ((IEnumerable) _lines).GetEnumerator();
60 | }
61 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfLocation.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public struct DwarfLocation
8 | {
9 | public DwarfLocation(int value)
10 | {
11 | AsValue = new DwarfInteger() { I64 = value };
12 | AsObject = null;
13 | }
14 |
15 | public DwarfLocation(DwarfExpression expression)
16 | {
17 | AsValue = default;
18 | AsObject = expression;
19 | }
20 |
21 | public DwarfLocation(DwarfLocationList locationList)
22 | {
23 | AsValue = default;
24 | AsObject = locationList;
25 | }
26 |
27 | public DwarfInteger AsValue;
28 |
29 | public object? AsObject;
30 |
31 | public DwarfExpression? AsExpression => AsObject as DwarfExpression;
32 |
33 | public DwarfLocationList? AsLocationList => AsObject as DwarfLocationList;
34 |
35 | public DwarfDIE? AsReference => AsObject as DwarfDIE;
36 |
37 | public override string ToString()
38 | {
39 | if (AsExpression != null) return $"Location Expression: {AsExpression}";
40 | if (AsLocationList != null) return $"Location List: {AsLocationList}";
41 | if (AsReference != null) return $"Location Reference: {AsReference}";
42 | return $"Location Constant: {AsValue}";
43 | }
44 |
45 | public static implicit operator DwarfLocation(DwarfExpression value)
46 | {
47 | return new DwarfLocation(value);
48 | }
49 |
50 | public static implicit operator DwarfLocation(DwarfLocationList value)
51 | {
52 | return new DwarfLocation(value);
53 | }
54 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfOperationKindEx.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public readonly partial struct DwarfOperationKindEx : IEquatable
10 | {
11 | public DwarfOperationKindEx(byte value)
12 | {
13 | Value = (DwarfOperationKind)value;
14 | }
15 |
16 | public DwarfOperationKindEx(DwarfOperationKind value)
17 | {
18 | Value = value;
19 | }
20 |
21 | public readonly DwarfOperationKind Value;
22 |
23 | public override string ToString()
24 | {
25 | return ToStringInternal() ?? $"Unknown {nameof(DwarfOperationKindEx)} ({(uint)Value:x2})";
26 | }
27 |
28 | public bool Equals(DwarfOperationKindEx other)
29 | {
30 | return Value == other.Value;
31 | }
32 |
33 | public override bool Equals(object? obj)
34 | {
35 | return obj is DwarfOperationKindEx other && Equals(other);
36 | }
37 |
38 | public override int GetHashCode()
39 | {
40 | return Value.GetHashCode();
41 | }
42 |
43 | public static bool operator ==(DwarfOperationKindEx left, DwarfOperationKindEx right)
44 | {
45 | return left.Equals(right);
46 | }
47 |
48 | public static bool operator !=(DwarfOperationKindEx left, DwarfOperationKindEx right)
49 | {
50 | return !left.Equals(right);
51 | }
52 |
53 | public static explicit operator uint(DwarfOperationKindEx kind) => (uint)kind.Value;
54 |
55 | public static implicit operator DwarfOperationKindEx(DwarfOperationKind kind) => new DwarfOperationKindEx(kind);
56 |
57 | public static implicit operator DwarfOperationKind(DwarfOperationKindEx kind) => kind.Value;
58 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfReaderContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public class DwarfReaderContext : DwarfReaderWriterContext
10 | {
11 | public DwarfReaderContext()
12 | {
13 | }
14 |
15 | public DwarfReaderContext(DwarfElfContext elfContext)
16 | {
17 | if (elfContext == null) throw new ArgumentNullException(nameof(elfContext));
18 | IsLittleEndian = elfContext.IsLittleEndian;
19 | AddressSize = elfContext.AddressSize;
20 | DebugLineStream = elfContext.LineTable?.Stream;
21 | DebugStringStream = elfContext.StringTable?.Stream;
22 | DebugAbbrevStream = elfContext.AbbreviationTable?.Stream;
23 | DebugInfoStream = elfContext.InfoSection?.Stream;
24 | DebugAddressRangeStream = elfContext.AddressRangeTable?.Stream;
25 | DebugLocationStream = elfContext.LocationSection?.Stream;
26 | }
27 |
28 | public bool IsInputReadOnly { get; set; }
29 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfReaderWriterContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public abstract class DwarfReaderWriterContext
10 | {
11 | public bool IsLittleEndian { get; set; }
12 |
13 | public DwarfAddressSize AddressSize { get; set; }
14 |
15 | public Stream? DebugAbbrevStream { get; set; }
16 |
17 | public Stream? DebugStringStream { get; set; }
18 |
19 | public Stream? DebugAddressRangeStream { get; set; }
20 |
21 | public Stream? DebugLineStream { get; set; }
22 |
23 | public TextWriter? DebugLinePrinter { get; set; }
24 |
25 | public Stream? DebugInfoStream { get; set; }
26 |
27 | public Stream? DebugLocationStream { get; set; }
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfRelocation.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | [DebuggerDisplay("{" + nameof(ToString) + "(),nq}")]
10 | public struct DwarfRelocation
11 | {
12 | public DwarfRelocation(ulong offset, DwarfRelocationTarget target, DwarfAddressSize size, ulong addend)
13 | {
14 | Offset = offset;
15 | Target = target;
16 | Size = size;
17 | Addend = addend;
18 | }
19 |
20 | public ulong Offset { get; set; }
21 |
22 | public DwarfRelocationTarget Target { get; set; }
23 |
24 | public DwarfAddressSize Size { get; set; }
25 |
26 | public ulong Addend { get; set; }
27 |
28 | public override string ToString()
29 | {
30 | return $"{nameof(Offset)}: {Offset}, {nameof(Target)}: {Target}, {nameof(Size)}: {Size}, {nameof(Addend)}: {Addend}";
31 | }
32 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfRelocationTarget.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfRelocationTarget
8 | {
9 | Code,
10 |
11 | DebugString,
12 |
13 | DebugAbbrev,
14 |
15 | DebugInfo,
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfSection.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 |
8 | namespace LibObjectFile.Dwarf;
9 |
10 | public abstract class DwarfSection : DwarfContainer
11 | {
12 | protected override void ValidateParent(ObjectElement parent)
13 | {
14 | if (!(parent is DwarfFile))
15 | {
16 | throw new ArgumentException($"Parent must inherit from type {nameof(DwarfFile)}");
17 | }
18 | }
19 |
20 | ///
21 | /// Gets the containing . Might be null if this section or segment
22 | /// does not belong to an existing .
23 | ///
24 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
25 | public new DwarfFile? Parent
26 | {
27 | get => (DwarfFile?)base.Parent;
28 | internal set => base.Parent = value;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfSectionLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public struct DwarfSectionLink : IEquatable
10 | {
11 | public DwarfSectionLink(ulong offset)
12 | {
13 | Offset = offset;
14 | }
15 |
16 | public readonly ulong Offset;
17 |
18 | public override string ToString()
19 | {
20 | return $"SectionLink {nameof(Offset)}: 0x{Offset:x}";
21 | }
22 |
23 | public bool Equals(DwarfSectionLink other)
24 | {
25 | return Offset == other.Offset;
26 | }
27 |
28 | public override bool Equals(object? obj)
29 | {
30 | return obj is DwarfSectionLink other && Equals(other);
31 | }
32 |
33 | public override int GetHashCode()
34 | {
35 | return Offset.GetHashCode();
36 | }
37 |
38 | public static bool operator ==(DwarfSectionLink left, DwarfSectionLink right)
39 | {
40 | return left.Equals(right);
41 | }
42 |
43 | public static bool operator !=(DwarfSectionLink left, DwarfSectionLink right)
44 | {
45 | return !left.Equals(right);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfTagEx.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | ///
10 | /// Defines the tag of an .
11 | ///
12 | public readonly partial struct DwarfTagEx : IEquatable
13 | {
14 | public DwarfTagEx(uint value)
15 | {
16 | Value = (DwarfTag)value;
17 | }
18 |
19 | public DwarfTagEx(DwarfTag value)
20 | {
21 | Value = value;
22 | }
23 |
24 | public readonly DwarfTag Value;
25 |
26 | public bool Equals(DwarfTagEx other)
27 | {
28 | return Value == other.Value;
29 | }
30 |
31 | public override bool Equals(object? obj)
32 | {
33 | return obj is DwarfTagEx other && Equals(other);
34 | }
35 |
36 | public override int GetHashCode()
37 | {
38 | return (int) Value;
39 | }
40 |
41 | public static bool operator ==(DwarfTagEx left, DwarfTagEx right)
42 | {
43 | return left.Equals(right);
44 | }
45 |
46 | public static bool operator !=(DwarfTagEx left, DwarfTagEx right)
47 | {
48 | return !left.Equals(right);
49 | }
50 |
51 | public override string ToString()
52 | {
53 | return ToStringInternal() ?? $"Unknown {nameof(DwarfTagEx)} (0x{Value:X4})";
54 | }
55 |
56 | public static explicit operator uint(DwarfTagEx tag) => (uint)tag.Value;
57 |
58 | public static implicit operator DwarfTagEx(DwarfTag tag) => new DwarfTagEx(tag);
59 |
60 | public static implicit operator DwarfTag(DwarfTagEx tag) => tag.Value;
61 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfUnitKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public readonly partial struct DwarfUnitKindEx : IEquatable
10 | {
11 | public DwarfUnitKindEx(byte value)
12 | {
13 | Value = (DwarfUnitKind)value;
14 | }
15 |
16 | public DwarfUnitKindEx(DwarfUnitKind value)
17 | {
18 | Value = value;
19 | }
20 |
21 | public readonly DwarfUnitKind Value;
22 |
23 | public override string ToString()
24 | {
25 | if ((byte)Value >= DwarfNative.DW_UT_lo_user)
26 | {
27 | return $"User {nameof(DwarfUnitKindEx)} (0x{Value:x2})";
28 | }
29 | return ToStringInternal() ?? $"Unknown {nameof(DwarfUnitKindEx)} (0x{Value:x2})";
30 | }
31 |
32 | public bool Equals(DwarfUnitKindEx other)
33 | {
34 | return Value == other.Value;
35 | }
36 |
37 | public override bool Equals(object? obj)
38 | {
39 | return obj is DwarfUnitKindEx other && Equals(other);
40 | }
41 |
42 | public override int GetHashCode()
43 | {
44 | return Value.GetHashCode();
45 | }
46 |
47 | public static bool operator ==(DwarfUnitKindEx left, DwarfUnitKindEx right)
48 | {
49 | return left.Equals(right);
50 | }
51 |
52 | public static bool operator !=(DwarfUnitKindEx left, DwarfUnitKindEx right)
53 | {
54 | return !left.Equals(right);
55 | }
56 |
57 | public static explicit operator uint(DwarfUnitKindEx kind) => (uint)kind.Value;
58 |
59 | public static implicit operator DwarfUnitKindEx(DwarfUnitKind kind) => new DwarfUnitKindEx(kind);
60 |
61 | public static implicit operator DwarfUnitKind(DwarfUnitKindEx kind) => kind.Value;
62 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfVirtuality.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfVirtuality : byte
8 | {
9 | None = DwarfNative.DW_VIRTUALITY_none,
10 |
11 | Virtual = DwarfNative.DW_VIRTUALITY_virtual,
12 |
13 | PureVirtual = DwarfNative.DW_VIRTUALITY_pure_virtual,
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfVisibility.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Dwarf;
6 |
7 | public enum DwarfVisibility : byte
8 | {
9 | Local = DwarfNative.DW_VIS_local,
10 |
11 | Exported = DwarfNative.DW_VIS_exported,
12 |
13 | Qualified = DwarfNative.DW_VIS_qualified,
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfWriter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using LibObjectFile.Diagnostics;
7 |
8 | namespace LibObjectFile.Dwarf;
9 |
10 | public sealed class DwarfWriter : DwarfReaderWriter
11 | {
12 | internal DwarfWriter(DwarfFile file, bool isLittleEndian, DiagnosticBag diagnostics) : base(file, diagnostics)
13 | {
14 | IsLittleEndian = isLittleEndian;
15 | }
16 |
17 | public override bool KeepOriginalStreamForSubStreams => false;
18 |
19 | public bool EnableRelocation { get; internal set; }
20 |
21 | public void RecordRelocation(DwarfRelocationTarget target, DwarfAddressSize addressSize, ulong address)
22 | {
23 | if (CurrentSection is DwarfRelocatableSection relocSection)
24 | {
25 |
26 | relocSection.Relocations.Add(new DwarfRelocation(Position, target, addressSize, address));
27 |
28 | }
29 | else
30 | {
31 | throw new InvalidOperationException($"Invalid {nameof(CurrentSection)} in {nameof(DwarfWriter)}. It must be a {nameof(DwarfRelocatableSection)}.");
32 | }
33 | }
34 |
35 | public void WriteAddress(DwarfRelocationTarget target, ulong address)
36 | {
37 | if (EnableRelocation)
38 | {
39 | RecordRelocation(target, AddressSize, address);
40 | // If the relocation is recorded, we write 0 as an address
41 | address = 0;
42 | }
43 | WriteUInt(address);
44 | }
45 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Dwarf/DwarfWriterContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Dwarf;
8 |
9 | public class DwarfWriterContext : DwarfReaderWriterContext
10 | {
11 | public DwarfWriterContext() : this(new DwarfLayoutConfig())
12 | {
13 | }
14 |
15 | public DwarfWriterContext(DwarfLayoutConfig layoutConfig)
16 | {
17 | LayoutConfig = layoutConfig ?? throw new ArgumentNullException(nameof(layoutConfig));
18 | EnableRelocation = true;
19 | }
20 |
21 | public DwarfLayoutConfig LayoutConfig { get; }
22 |
23 | public bool EnableRelocation { get; set; }
24 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfArch.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines a machine architecture.
11 | /// This is the value seen in or
12 | /// as well as the various machine defines (e.g ).
13 | ///
14 | public readonly partial struct ElfArchEx : IEquatable
15 | {
16 | public ElfArchEx(ushort value)
17 | {
18 | Value = (ElfArch)value;
19 | }
20 |
21 | public ElfArchEx(ElfArch value)
22 | {
23 | Value = value;
24 | }
25 |
26 | ///
27 | /// Raw value.
28 | ///
29 | public readonly ElfArch Value;
30 |
31 | public override string ToString()
32 | {
33 | return ToStringInternal() ?? $"Unknown {nameof(ElfArchEx)} (0x{Value:X4})";
34 | }
35 |
36 | public bool Equals(ElfArchEx other)
37 | {
38 | return Value == other.Value;
39 | }
40 |
41 | public override bool Equals(object? obj)
42 | {
43 | return obj is ElfArchEx other && Equals(other);
44 | }
45 |
46 | public override int GetHashCode()
47 | {
48 | return Value.GetHashCode();
49 | }
50 |
51 | public static bool operator ==(ElfArchEx left, ElfArchEx right)
52 | {
53 | return left.Equals(right);
54 | }
55 |
56 | public static bool operator !=(ElfArchEx left, ElfArchEx right)
57 | {
58 | return !left.Equals(right);
59 | }
60 |
61 | public static explicit operator uint(ElfArchEx arch) => (uint)arch.Value;
62 |
63 | public static implicit operator ElfArchEx(ElfArch arch) => new ElfArchEx(arch);
64 |
65 | public static implicit operator ElfArch(ElfArchEx arch) => arch.Value;
66 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfContentData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// A shadow section is a section that will not be saved to the section header table but can contain data
9 | /// that will be saved with the .
10 | /// A shadow section is usually associated with an that is referencing a portion of
11 | /// data that is not owned by a visible section.
12 | ///
13 | public abstract class ElfContentData : ElfContent
14 | {
15 | protected ElfContentData()
16 | {
17 | }
18 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfEncoding.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Encoding of an .
9 | /// This is the value seen in the ident part of an Elf header at index
10 | /// It is associated with , and
11 | ///
12 | public enum ElfEncoding : byte
13 | {
14 | ///
15 | /// Invalid data encoding. Equivalent of
16 | ///
17 | None = ElfNative.ELFDATANONE,
18 |
19 | ///
20 | /// 2's complement, little endian. Equivalent of
21 | ///
22 | Lsb = ElfNative.ELFDATA2LSB,
23 |
24 | ///
25 | /// 2's complement, big endian. Equivalent of
26 | ///
27 | Msb = ElfNative.ELFDATA2MSB,
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfFile.Write.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Runtime.InteropServices;
9 | using LibObjectFile.Diagnostics;
10 |
11 | namespace LibObjectFile.Elf;
12 |
13 | partial class ElfFile
14 | {
15 | public override void Write(ElfWriter writer)
16 | {
17 | writer.Position = 0;
18 | var contentList = Content.UnsafeList;
19 |
20 | // We write the content all sections including shadows
21 | for (var i = 0; i < contentList.Count; i++)
22 | {
23 | var content = contentList[i];
24 | if (content is ElfSection section && section.Type == ElfSectionType.NoBits)
25 | {
26 | continue;
27 | }
28 |
29 | if (content.Position > writer.Position)
30 | {
31 | writer.WriteZero((int)(content.Position - writer.Position));
32 | }
33 | content.Write(writer);
34 | }
35 |
36 | // Write trailing zeros
37 | if (writer.Position < Layout.TotalSize)
38 | {
39 | writer.WriteZero((int)(Layout.TotalSize - writer.Position));
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfFileClass.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines the File class byte index (32bit or 64bits) of an .
9 | /// This is the value seen in the ident part of an Elf header at index
10 | /// It is associated with , and
11 | ///
12 | public enum ElfFileClass : byte
13 | {
14 | ///
15 | /// Invalid class. Equivalent of .
16 | ///
17 | None = ElfNative.ELFCLASSNONE,
18 |
19 | ///
20 | /// 32-bit objects. Equivalent of .
21 | ///
22 | Is32 = ElfNative.ELFCLASS32,
23 |
24 | ///
25 | /// 64-bit objects. Equivalent of .
26 | ///
27 | Is64 = ElfNative.ELFCLASS64,
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfFileLayout.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Contains the layout of an object available after reading an
9 | /// or after calling
10 | ///
11 | public sealed class ElfFileLayout
12 | {
13 | internal ElfFileLayout()
14 | {
15 | }
16 |
17 | ///
18 | /// Size of ELF Header.
19 | ///
20 | public ushort SizeOfElfHeader { get; internal set; }
21 |
22 | ///
23 | /// Offset of the program header table.
24 | ///
25 | public ulong OffsetOfProgramHeaderTable { get; internal set; }
26 |
27 | ///
28 | /// Size of a program header entry.
29 | ///
30 | public ushort SizeOfProgramHeaderEntry { get; internal set; }
31 |
32 | ///
33 | /// The number of header entries.
34 | ///
35 | public uint ProgramHeaderCount { get; internal set; }
36 |
37 | ///
38 | /// Offset of the section header table.
39 | ///
40 | public ulong OffsetOfSectionHeaderTable { get; internal set; }
41 |
42 | ///
43 | /// Size of a section header entry.
44 | ///
45 | public ushort SizeOfSectionHeaderEntry { get; internal set; }
46 |
47 | ///
48 | /// The number of section header entries.
49 | ///
50 | public uint SectionHeaderCount { get; internal set; }
51 |
52 | ///
53 | /// Size of the entire file
54 | ///
55 | public ulong TotalSize { get; internal set; }
56 |
57 | ///
58 | /// The index of the section string table.
59 | ///
60 | public uint SectionStringTableIndex { get; internal set; }
61 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfFileType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines the file type of an .
9 | /// This is the value seen in or
10 | /// as well as the various machine defines (e.g ).
11 | ///
12 | public enum ElfFileType : ushort
13 | {
14 | ///
15 | /// No file type
16 | ///
17 | None = ElfNative.ET_NONE,
18 |
19 | ///
20 | /// Relocatable file
21 | ///
22 | Relocatable = ElfNative.ET_REL,
23 |
24 | ///
25 | /// Executable file
26 | ///
27 | Executable = ElfNative.ET_EXEC,
28 |
29 | ///
30 | /// Shared object file
31 | ///
32 | Dynamic = ElfNative.ET_DYN,
33 |
34 | ///
35 | /// Core file
36 | ///
37 | Core = ElfNative.ET_CORE,
38 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfHeaderFlags.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines the flags of an .
11 | /// This is the value seen in or .
12 | /// This is currently not used.
13 | ///
14 | public readonly struct ElfHeaderFlags : IEquatable
15 | {
16 | public ElfHeaderFlags(uint value)
17 | {
18 | Value = value;
19 | }
20 |
21 | public readonly uint Value;
22 |
23 |
24 | public bool Equals(ElfHeaderFlags other)
25 | {
26 | return Value == other.Value;
27 | }
28 |
29 | public override bool Equals(object? obj)
30 | {
31 | return obj is ElfHeaderFlags other && Equals(other);
32 | }
33 |
34 | public override int GetHashCode()
35 | {
36 | return (int) Value;
37 | }
38 |
39 | public static bool operator ==(ElfHeaderFlags left, ElfHeaderFlags right)
40 | {
41 | return left.Equals(right);
42 | }
43 |
44 | public static bool operator !=(ElfHeaderFlags left, ElfHeaderFlags right)
45 | {
46 | return !left.Equals(right);
47 | }
48 |
49 | public override string ToString()
50 | {
51 | return $"0x{Value:x}";
52 | }
53 |
54 | public static explicit operator uint(ElfHeaderFlags flags) => flags.Value;
55 |
56 | public static implicit operator ElfHeaderFlags(uint flags) => new ElfHeaderFlags(flags);
57 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfOSABIEx.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines an OS ABI.
11 | /// This is the value seen in the ident part of an Elf header at index
12 | /// as well as the various machine defines (e.g ).
13 | ///
14 | public readonly partial struct ElfOSABIEx : IEquatable
15 | {
16 | public ElfOSABIEx(byte value)
17 | {
18 | Value = (ElfOSABI)value;
19 | }
20 |
21 | public ElfOSABIEx(ElfOSABI value)
22 | {
23 | Value = value;
24 | }
25 |
26 | public readonly ElfOSABI Value;
27 |
28 | public override string ToString()
29 | {
30 | return ToStringInternal() ?? $"Unknown {nameof(ElfOSABIEx)} (0x{Value:X4})";
31 | }
32 |
33 | public bool Equals(ElfOSABIEx other)
34 | {
35 | return Value == other.Value;
36 | }
37 |
38 | public override bool Equals(object? obj)
39 | {
40 | return obj is ElfOSABIEx other && Equals(other);
41 | }
42 |
43 | public override int GetHashCode()
44 | {
45 | return Value.GetHashCode();
46 | }
47 |
48 | public static bool operator ==(ElfOSABIEx left, ElfOSABIEx right)
49 | {
50 | return left.Equals(right);
51 | }
52 |
53 | public static bool operator !=(ElfOSABIEx left, ElfOSABIEx right)
54 | {
55 | return !left.Equals(right);
56 | }
57 |
58 | public static explicit operator byte(ElfOSABIEx osABI) => (byte)osABI.Value;
59 |
60 | public static implicit operator ElfOSABIEx(ElfOSABI osABI) => new ElfOSABIEx(osABI);
61 |
62 | public static implicit operator ElfOSABI(ElfOSABIEx osABI) => osABI.Value;
63 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfOffsetCalculationMode.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines the way a value is calculated.
9 | ///
10 | public enum ElfOffsetCalculationMode
11 | {
12 | ///
13 | /// The associated value is automatically calculated by the system.
14 | ///
15 | Auto,
16 |
17 | ///
18 | /// The associated value is set manually.
19 | ///
20 | Manual,
21 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfReaderDirect.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Internal implementation of with a .
11 | ///
12 | internal sealed class ElfReaderDirect : ElfReader
13 | {
14 | public ElfReaderDirect(ElfFile elfFile, Stream stream, ElfReaderOptions options) : base(elfFile, stream, options)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfReaderSwap.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Internal implementation of with a .
11 | ///
12 | internal sealed class ElfReaderSwap : ElfReader
13 | {
14 | public ElfReaderSwap(ElfFile elfFile, Stream stream, ElfReaderOptions options) : base(elfFile, stream, options)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfSectionFlags.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines the flag of a section.
11 | ///
12 | [Flags]
13 | public enum ElfSectionFlags : uint
14 | {
15 | None = 0,
16 |
17 | ///
18 | /// Writable
19 | ///
20 | Write = ElfNative.SHF_WRITE,
21 |
22 | ///
23 | /// Occupies memory during execution
24 | ///
25 | Alloc = ElfNative.SHF_ALLOC,
26 |
27 | ///
28 | /// Executable
29 | ///
30 | Executable = ElfNative.SHF_EXECINSTR,
31 |
32 | ///
33 | /// Might be merged
34 | ///
35 | Merge = ElfNative.SHF_MERGE,
36 |
37 | ///
38 | /// Contains nul-terminated strings
39 | ///
40 | Strings = ElfNative.SHF_STRINGS,
41 |
42 | ///
43 | /// `sh_info' contains SHT index
44 | ///
45 | InfoLink = ElfNative.SHF_INFO_LINK,
46 |
47 | ///
48 | /// Preserve order after combining
49 | ///
50 | LinkOrder = ElfNative.SHF_LINK_ORDER,
51 |
52 | ///
53 | /// Non-standard OS specific handling required
54 | ///
55 | OsNonConforming = ElfNative.SHF_OS_NONCONFORMING,
56 |
57 | ///
58 | /// Section is member of a group.
59 | ///
60 | Group = ElfNative.SHF_GROUP,
61 |
62 | ///
63 | /// Section hold thread-local data.
64 | ///
65 | Tls = ElfNative.SHF_TLS,
66 |
67 | ///
68 | /// Section with compressed data.
69 | ///
70 | Compressed = ElfNative.SHF_COMPRESSED,
71 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfSegmentFlags.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines a segment flags
11 | ///
12 | public readonly struct ElfSegmentFlags : IEquatable
13 | {
14 | public ElfSegmentFlags(uint value)
15 | {
16 | Value = value;
17 | }
18 |
19 | public ElfSegmentFlags(ElfSegmentFlagsCore value)
20 | {
21 | Value = (uint)value;
22 | }
23 |
24 | public readonly uint Value;
25 |
26 | public bool Equals(ElfSegmentFlags other)
27 | {
28 | return Value == other.Value;
29 | }
30 |
31 | public override bool Equals(object? obj)
32 | {
33 | return obj is ElfSegmentFlags other && Equals(other);
34 | }
35 |
36 | public override int GetHashCode()
37 | {
38 | return (int) Value;
39 | }
40 |
41 | public static bool operator ==(ElfSegmentFlags left, ElfSegmentFlags right)
42 | {
43 | return left.Equals(right);
44 | }
45 |
46 | public static bool operator !=(ElfSegmentFlags left, ElfSegmentFlags right)
47 | {
48 | return !left.Equals(right);
49 | }
50 |
51 | public override string ToString()
52 | {
53 | return $"SegmentFlags {((ElfSegmentFlagsCore)(Value&3))} 0x{Value:X8}";
54 | }
55 |
56 | public static implicit operator ElfSegmentFlags(ElfSegmentFlagsCore segmentFlagsCore)
57 | {
58 | return new ElfSegmentFlags(segmentFlagsCore);
59 | }
60 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfSegmentFlagsCore.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines the core part of
11 | ///
12 | [Flags]
13 | public enum ElfSegmentFlagsCore : uint
14 | {
15 | ///
16 | /// Segment flags is undefined
17 | ///
18 | None = 0,
19 |
20 | ///
21 | /// Segment is executable
22 | ///
23 | Executable = ElfNative.PF_X,
24 |
25 | ///
26 | /// Segment is writable
27 | ///
28 | Writable = ElfNative.PF_W,
29 |
30 | ///
31 | /// Segment is readable
32 | ///
33 | Readable = ElfNative.PF_R,
34 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfSegmentType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Defines a segment type
11 | ///
12 | public readonly struct ElfSegmentType : IEquatable
13 | {
14 | public ElfSegmentType(uint value)
15 | {
16 | Value = value;
17 | }
18 |
19 | public ElfSegmentType(ElfSegmentTypeCore value)
20 | {
21 | Value = (uint)value;
22 | }
23 |
24 | public readonly uint Value;
25 |
26 | public bool Equals(ElfSegmentType other)
27 | {
28 | return Value == other.Value;
29 | }
30 |
31 | public override bool Equals(object? obj)
32 | {
33 | return obj is ElfSegmentType other && Equals(other);
34 | }
35 |
36 | public override int GetHashCode()
37 | {
38 | return (int) Value;
39 | }
40 |
41 | public static bool operator ==(ElfSegmentType left, ElfSegmentType right)
42 | {
43 | return left.Equals(right);
44 | }
45 |
46 | public static bool operator !=(ElfSegmentType left, ElfSegmentType right)
47 | {
48 | return !left.Equals(right);
49 | }
50 |
51 | public override string ToString()
52 | {
53 | return Value < ElfNative.PT_NUM ? $"SegmentType {((ElfSegmentTypeCore) Value)}" : $"SegmentType 0x{Value:X8}";
54 | }
55 |
56 | public static implicit operator ElfSegmentType(ElfSegmentTypeCore segmentTypeCore)
57 | {
58 | return new ElfSegmentType(segmentTypeCore);
59 | }
60 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfSegmentTypeCore.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines a core
9 | ///
10 | public enum ElfSegmentTypeCore : uint
11 | {
12 | ///
13 | /// Program header table entry unused
14 | ///
15 | Null = ElfNative.PT_NULL,
16 |
17 | ///
18 | /// Loadable program segment
19 | ///
20 | Load = ElfNative.PT_LOAD,
21 |
22 | ///
23 | /// Dynamic linking information
24 | ///
25 | Dynamic = ElfNative.PT_DYNAMIC,
26 |
27 | ///
28 | /// Program interpreter
29 | ///
30 | Interpreter = ElfNative.PT_INTERP,
31 |
32 | ///
33 | /// Auxiliary information
34 | ///
35 | Note = ElfNative.PT_NOTE,
36 |
37 | ///
38 | /// Reserved
39 | ///
40 | SectionHeaderLib = ElfNative.PT_SHLIB,
41 |
42 | ///
43 | /// Entry for header table itself
44 | ///
45 | ProgramHeader = ElfNative.PT_PHDR,
46 |
47 | ///
48 | /// Thread-local storage segment
49 | ///
50 | Tls = ElfNative.PT_TLS,
51 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfStreamContentData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.IO;
7 |
8 | namespace LibObjectFile.Elf;
9 |
10 | ///
11 | /// Equivalent of but used for shadow.
12 | ///
13 | public sealed class ElfStreamContentData : ElfContentData
14 | {
15 | private Stream _stream;
16 |
17 | public ElfStreamContentData() : this(new MemoryStream())
18 | {
19 | }
20 |
21 | public ElfStreamContentData(Stream stream)
22 | {
23 | _stream = stream;
24 | Size = (ulong)stream.Length;
25 | }
26 |
27 | internal ElfStreamContentData(bool unused)
28 | {
29 | _stream = Stream.Null;
30 | }
31 |
32 | public Stream Stream
33 | {
34 | get => _stream;
35 | set
36 | {
37 | ArgumentNullException.ThrowIfNull(value);
38 | _stream = value;
39 | Size = (ulong)value.Length;
40 | }
41 | }
42 |
43 | public override void Read(ElfReader reader)
44 | {
45 | reader.Position = Position;
46 | Stream = reader.ReadAsStream(Size);
47 | }
48 |
49 | public override void Write(ElfWriter writer)
50 | {
51 | writer.Write(Stream);
52 | }
53 |
54 | protected override void UpdateLayoutCore(ElfVisitorContext context)
55 | {
56 | Size = (ulong)Stream.Length;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfString.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 |
8 | namespace LibObjectFile.Elf;
9 |
10 | ///
11 | /// Defines a string with the associated index in the string table.
12 | ///
13 | [DebuggerDisplay("{ToString(),nq}")]
14 | public readonly record struct ElfString
15 | {
16 | [Obsolete("This constructor cannot be used. Create an ElfString from a ElfStringTable", error: true)]
17 | public ElfString()
18 | {
19 | Value = string.Empty;
20 | }
21 | public ElfString(string text)
22 | {
23 | Value = text;
24 | Index = 0;
25 | }
26 |
27 | internal ElfString(string text, uint index)
28 | {
29 | Value = text;
30 | Index = index;
31 | }
32 |
33 | internal ElfString(uint index)
34 | {
35 | Value = string.Empty;
36 | Index = index;
37 | }
38 |
39 | public bool IsEmpty => string.IsNullOrEmpty(Value) && Index == 0;
40 |
41 | ///
42 | /// Gets the text of the string.
43 | ///
44 | public string Value { get; }
45 |
46 | ///
47 | /// Gets the index of the string in the string table.
48 | ///
49 | public uint Index { get; }
50 |
51 | public override string ToString() => string.IsNullOrEmpty(Value) ? $"0x{Index:x8}" : Value;
52 |
53 | public static implicit operator ElfString(string text) => new(text);
54 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfVisitorContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 | using System.Xml.Linq;
7 |
8 | namespace LibObjectFile.Elf;
9 |
10 | public class ElfVisitorContext : VisitorContextBase
11 | {
12 | internal ElfVisitorContext(ElfFile elfFile, DiagnosticBag diagnostics) : base(elfFile, diagnostics)
13 | {
14 | }
15 |
16 | public ElfString ResolveName(ElfString name)
17 | {
18 | var stringTable = File.SectionHeaderStringTable;
19 | if (stringTable is null)
20 | {
21 | Diagnostics.Error(DiagnosticId.ELF_ERR_SectionHeaderStringTableNotFound, $"The section header string table is not found. Cannot resolve {name}.");
22 | return name;
23 | }
24 |
25 | return stringTable.Resolve(name);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfWriterDirect.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Internal implementation of with a .
11 | ///
12 | internal sealed class ElfWriterDirect : ElfWriter
13 | {
14 | public ElfWriterDirect(ElfFile elfFile, Stream stream) : base(elfFile, stream)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/ElfWriterSwap.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Internal implementation of with a .
11 | ///
12 | internal sealed class ElfWriterSwap : ElfWriter
13 | {
14 | public ElfWriterSwap(ElfFile elfFile, Stream stream) : base(elfFile, stream)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/IElfDecoder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// A decoder interface for the various Elf types that provides decoding of data based on LSB/MSB.
9 | ///
10 | ///
11 | public interface IElfDecoder
12 | {
13 | ushort Decode(ElfNative.Elf32_Half src);
14 |
15 | ushort Decode(ElfNative.Elf64_Half src);
16 |
17 | uint Decode(ElfNative.Elf32_Word src);
18 |
19 | uint Decode(ElfNative.Elf64_Word src);
20 |
21 | int Decode(ElfNative.Elf32_Sword src);
22 |
23 | int Decode(ElfNative.Elf64_Sword src);
24 |
25 | ulong Decode(ElfNative.Elf32_Xword src);
26 |
27 | long Decode(ElfNative.Elf32_Sxword src);
28 |
29 | ulong Decode(ElfNative.Elf64_Xword src);
30 |
31 | long Decode(ElfNative.Elf64_Sxword src);
32 |
33 | uint Decode(ElfNative.Elf32_Addr src);
34 |
35 | ulong Decode(ElfNative.Elf64_Addr src);
36 |
37 | uint Decode(ElfNative.Elf32_Off src);
38 |
39 | ulong Decode(ElfNative.Elf64_Off src);
40 |
41 | ushort Decode(ElfNative.Elf32_Section src);
42 |
43 | ushort Decode(ElfNative.Elf64_Section src);
44 |
45 | ushort Decode(ElfNative.Elf32_Versym src);
46 |
47 | ushort Decode(ElfNative.Elf64_Versym src);
48 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/IElfEncoder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// An encoder interface for the various Elf types that provides encoding of data based on LSB/MSB.
9 | ///
10 | ///
11 | public interface IElfEncoder
12 | {
13 | void Encode(out ElfNative.Elf32_Half dest, ushort value);
14 |
15 | void Encode(out ElfNative.Elf64_Half dest, ushort value);
16 |
17 | void Encode(out ElfNative.Elf32_Word dest, uint value);
18 |
19 | void Encode(out ElfNative.Elf64_Word dest, uint value);
20 |
21 | void Encode(out ElfNative.Elf32_Sword dest, int value);
22 |
23 | void Encode(out ElfNative.Elf64_Sword dest, int value);
24 |
25 | void Encode(out ElfNative.Elf32_Xword dest, ulong value);
26 |
27 | void Encode(out ElfNative.Elf32_Sxword dest, long value);
28 |
29 | void Encode(out ElfNative.Elf64_Xword dest, ulong value);
30 |
31 | void Encode(out ElfNative.Elf64_Sxword dest, long value);
32 |
33 | void Encode(out ElfNative.Elf32_Addr dest, uint value);
34 |
35 | void Encode(out ElfNative.Elf64_Addr dest, ulong value);
36 |
37 | void Encode(out ElfNative.Elf32_Off dest, uint offset);
38 |
39 | void Encode(out ElfNative.Elf64_Off dest, ulong offset);
40 |
41 | void Encode(out ElfNative.Elf32_Section dest, ushort index);
42 |
43 | void Encode(out ElfNative.Elf64_Section dest, ushort index);
44 |
45 | void Encode(out ElfNative.Elf32_Versym dest, ushort value);
46 |
47 | void Encode(out ElfNative.Elf64_Versym dest, ushort value);
48 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfGnuNote.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | public abstract class ElfGnuNote : ElfNote
8 | {
9 | public override string GetName()
10 | {
11 | return "GNU";
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfGnuNoteBuildId.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Buffers;
6 | using System.IO;
7 | using System.Text;
8 |
9 | namespace LibObjectFile.Elf;
10 |
11 | public class ElfGnuNoteBuildId : ElfGnuNote
12 | {
13 | public override ElfNoteTypeEx GetNoteType() => new ElfNoteTypeEx(ElfNoteType.GNU_BUILD_ID);
14 |
15 | public Stream? BuildId { get; set; }
16 |
17 | public override uint GetDescriptorSize() => BuildId != null ? (uint)BuildId.Length : 0;
18 |
19 | public override string GetDescriptorAsText()
20 | {
21 | var builder = new StringBuilder();
22 | builder.Append("Build ID: ");
23 |
24 | if (BuildId != null)
25 | {
26 | BuildId.Position = 0;
27 | var length = (int)BuildId.Length;
28 | var buffer = ArrayPool.Shared.Rent(length);
29 | length = BuildId.Read(buffer, 0, length);
30 | BuildId.Position = 0;
31 |
32 | for (int i = 0; i < length; i++)
33 | {
34 | builder.Append($"{buffer[i]:x2}");
35 | }
36 | }
37 |
38 | return builder.ToString();
39 | }
40 |
41 |
42 | protected override void ReadDescriptor(ElfReader reader, uint descriptorLength)
43 | {
44 | if (descriptorLength > 0)
45 | {
46 | BuildId = reader.ReadAsStream(descriptorLength);
47 | }
48 | }
49 |
50 | protected override void WriteDescriptor(ElfWriter writer)
51 | {
52 | if (BuildId != null)
53 | {
54 | writer.Write(BuildId);
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfGnuNoteOSKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Type of Operating System for a
9 | ///
10 | public enum ElfGnuNoteOSKind : uint
11 | {
12 | ///
13 | /// Linux operating system.
14 | ///
15 | Linux = ElfNative.ELF_NOTE_OS_LINUX,
16 |
17 | ///
18 | /// A Gnu operating system.
19 | ///
20 | Gnu = ElfNative.ELF_NOTE_OS_GNU,
21 |
22 | ///
23 | /// Solaris operating system.
24 | ///
25 | Solaris = ElfNative.ELF_NOTE_OS_SOLARIS2,
26 |
27 | ///
28 | /// FreeBSD operating system.
29 | ///
30 | FreeBSD = ElfNative.ELF_NOTE_OS_FREEBSD,
31 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfNoBitsSection.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | public sealed class ElfNoBitsSection : ElfSection
8 | {
9 | public ElfNoBitsSection() : base(ElfSectionType.NoBits)
10 | {
11 | }
12 |
13 | public ulong PositionOffsetFromPreviousContent { get; set; }
14 |
15 | public override void Read(ElfReader reader)
16 | {
17 | }
18 |
19 | public override void Write(ElfWriter writer)
20 | {
21 | }
22 |
23 | protected override void UpdateLayoutCore(ElfVisitorContext context)
24 | {
25 | }
26 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfNote.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// A Note entry in
9 | ///
10 | public abstract class ElfNote
11 | {
12 | protected ElfNote()
13 | {
14 | }
15 |
16 | ///
17 | /// Gets or sets the name of this note.
18 | ///
19 | public abstract string GetName();
20 |
21 | ///
22 | /// Gets or sets the type of this note.
23 | ///
24 | public abstract ElfNoteTypeEx GetNoteType();
25 |
26 | public abstract uint GetDescriptorSize();
27 |
28 | public abstract string GetDescriptorAsText();
29 |
30 | public override string ToString()
31 | {
32 | return $"{nameof(ElfNote)} {GetName()}, Type: {GetNoteType()}";
33 | }
34 |
35 | internal void ReadDescriptorInternal(ElfReader reader, uint descriptorLength)
36 | {
37 | ReadDescriptor(reader, descriptorLength);
38 | }
39 |
40 | internal void WriteDescriptorInternal(ElfWriter writer)
41 | {
42 | WriteDescriptor(writer);
43 | }
44 | protected abstract void ReadDescriptor(ElfReader reader, uint descriptorLength);
45 |
46 | protected abstract void WriteDescriptor(ElfWriter writer);
47 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfNoteType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// Gets the type of a .
11 | ///
12 | public readonly partial struct ElfNoteTypeEx : IEquatable
13 | {
14 | public ElfNoteTypeEx(uint value)
15 | {
16 | Value = (ElfNoteType)value;
17 | }
18 |
19 | public ElfNoteTypeEx(ElfNoteType value)
20 | {
21 | Value = value;
22 | }
23 |
24 | ///
25 | /// The value of this note type.
26 | ///
27 | public readonly ElfNoteType Value;
28 |
29 | public override string ToString()
30 | {
31 | return ToStringInternal() ?? $"Unknown {nameof(ElfNoteTypeEx)} (0x{(uint)Value:X4})";
32 | }
33 |
34 | public bool Equals(ElfNoteTypeEx other)
35 | {
36 | return Value == other.Value;
37 | }
38 |
39 | public override bool Equals(object? obj)
40 | {
41 | return obj is ElfNoteTypeEx other && Equals(other);
42 | }
43 |
44 | public override int GetHashCode()
45 | {
46 | return (int)Value;
47 | }
48 |
49 | public static bool operator ==(ElfNoteTypeEx left, ElfNoteTypeEx right)
50 | {
51 | return left.Equals(right);
52 | }
53 |
54 | public static bool operator !=(ElfNoteTypeEx left, ElfNoteTypeEx right)
55 | {
56 | return !left.Equals(right);
57 | }
58 |
59 | public static explicit operator byte(ElfNoteTypeEx noteType) => (byte)noteType.Value;
60 |
61 | public static implicit operator ElfNoteTypeEx(ElfNoteType noteType) => new ElfNoteTypeEx(noteType);
62 |
63 | public static implicit operator ElfNoteType(ElfNoteTypeEx noteType) => noteType.Value;
64 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfNullSection.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 |
7 | namespace LibObjectFile.Elf;
8 |
9 | ///
10 | /// A null section with the type .
11 | ///
12 | public sealed class ElfNullSection() : ElfSection(ElfSectionType.Null)
13 | {
14 | public override void Verify(ElfVisitorContext context)
15 | {
16 | if (Type != ElfSectionType.Null ||
17 | Flags != ElfSectionFlags.None ||
18 | !Name.IsEmpty ||
19 | VirtualAddress != 0 ||
20 | VirtualAddressAlignment != 0 ||
21 | !Link.IsEmpty ||
22 | !Info.IsEmpty ||
23 | Position != 0 ||
24 | Size != 0)
25 | {
26 | context.Diagnostics.Error(DiagnosticId.ELF_ERR_InvalidNullSection, "Invalid Null section. This section should not be modified and all properties must be null");
27 | }
28 | }
29 |
30 | protected override void UpdateLayoutCore(ElfVisitorContext context)
31 | {
32 | }
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfRelocation.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// A relocation entry in the
9 | /// This is the value seen in or
10 | ///
11 | public record struct ElfRelocation
12 | {
13 | public ElfRelocation()
14 | {
15 | }
16 |
17 | public ElfRelocation(ulong offset, ElfRelocationType type, uint symbolIndex, long addend)
18 | {
19 | Offset = offset;
20 | Type = type;
21 | SymbolIndex = symbolIndex;
22 | Addend = addend;
23 | }
24 |
25 | ///
26 | /// Gets or sets the offset.
27 | ///
28 | public ulong Offset { get; set; }
29 |
30 | ///
31 | /// Gets or sets the type of relocation.
32 | ///
33 | public ElfRelocationType Type { get; set; }
34 |
35 | ///
36 | /// Gets or sets the symbol index associated with the symbol table.
37 | ///
38 | public uint SymbolIndex { get; set; }
39 |
40 | ///
41 | /// Gets or sets the addend value.
42 | ///
43 | public long Addend { get; set; }
44 |
45 | ///
46 | /// Gets the computed Info value as expected by
47 | ///
48 | public uint Info32 =>
49 | ((uint) SymbolIndex << 8) | ((Type.Value & 0xFF));
50 |
51 | ///
52 | /// Gets the computed Info value as expected by
53 | ///
54 | public ulong Info64 =>
55 | ((ulong)SymbolIndex << 32) | (Type.Value);
56 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfRelocationContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Context used when applying relocation via .
9 | ///
10 | public struct ElfRelocationContext
11 | {
12 | public ulong BaseAddress { get; set; }
13 |
14 | public ulong GlobalObjectTableAddress { get; set; }
15 |
16 | public ulong GlobalObjectTableOffset { get; set; }
17 |
18 | public ulong ProcedureLinkageTableAddress { get; set; }
19 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfSectionHeaderStringTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// The Section Header String Table used by .
9 | ///
10 | public sealed class ElfSectionHeaderStringTable : ElfStringTable
11 | {
12 | public new const string DefaultName = ".shstrtab";
13 |
14 | public ElfSectionHeaderStringTable() : base(DefaultName)
15 | {
16 | }
17 |
18 | internal ElfSectionHeaderStringTable(bool unused) : base(unused)
19 | {
20 | }
21 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfSymbolBind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines a symbol binding
9 | /// This is the value seen compressed in or
10 | /// as well as the various defines (e.g ).
11 | ///
12 | public enum ElfSymbolBind : byte
13 | {
14 | ///
15 | /// Local symbol
16 | ///
17 | Local = ElfNative.STB_LOCAL,
18 |
19 | ///
20 | /// Global symbol
21 | ///
22 | Global = ElfNative.STB_GLOBAL,
23 |
24 | ///
25 | /// Weak symbol
26 | ///
27 | Weak = ElfNative.STB_WEAK,
28 |
29 | ///
30 | /// Unique symbol
31 | ///
32 | GnuUnique = ElfNative.STB_GNU_UNIQUE,
33 |
34 | ///
35 | /// OS-specific 0
36 | ///
37 | SpecificOS0 = ElfNative.STB_GNU_UNIQUE,
38 |
39 | ///
40 | /// OS-specific 1
41 | ///
42 | SpecificOS1 = ElfNative.STB_GNU_UNIQUE + 1,
43 |
44 | ///
45 | /// OS-specific 2
46 | ///
47 | SpecificOS2 = ElfNative.STB_GNU_UNIQUE + 2,
48 |
49 | ///
50 | /// Processor-specific 0
51 | ///
52 | SpecificProcessor0 = ElfNative.STB_LOPROC,
53 |
54 | ///
55 | /// Processor-specific 1
56 | ///
57 | SpecificProcessor1 = ElfNative.STB_LOPROC + 1,
58 |
59 | ///
60 | /// Processor-specific 2
61 | ///
62 | SpecificProcessor2 = ElfNative.STB_LOPROC + 2,
63 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Elf/Sections/ElfSymbolVisibility.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.Elf;
6 |
7 | ///
8 | /// Defines the visibility of a symbol
9 | /// This is the value seen compressed in or
10 | /// as well as the various defines (e.g ).
11 | ///
12 | public enum ElfSymbolVisibility : byte
13 | {
14 | ///
15 | /// Default symbol visibility rules
16 | ///
17 | Default = ElfNative.STV_DEFAULT,
18 |
19 | ///
20 | /// Processor specific hidden class
21 | ///
22 | Internal = ElfNative.STV_INTERNAL,
23 |
24 | ///
25 | /// Sym unavailable in other modules
26 | ///
27 | Hidden = ElfNative.STV_HIDDEN,
28 |
29 | ///
30 | /// Not preemptible, not exported
31 | ///
32 | Protected = ElfNative.STV_PROTECTED,
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/LibObjectFile.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
--------------------------------------------------------------------------------
/src/LibObjectFile/ObjectFileElementHolder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile;
8 |
9 | ///
10 | /// Helper struct to hold an element of type and ensure that it is properly set with its parent.
11 | ///
12 | /// The type of the object to hold
13 | public struct ObjectFileElementHolder
14 | where TObject : ObjectFileElement
15 | {
16 | private TObject _element;
17 |
18 | public ObjectFileElementHolder(ObjectFileElement parent, TObject element)
19 | {
20 | ArgumentNullException.ThrowIfNull(parent);
21 | ArgumentNullException.ThrowIfNull(element);
22 | _element = null!; // Avoid warning
23 | Set(parent, element);
24 | }
25 |
26 | public TObject Element => _element;
27 |
28 | public static implicit operator TObject(ObjectFileElementHolder holder) => holder._element;
29 |
30 | public void Set(ObjectFileElement parent, TObject? element)
31 | {
32 | ArgumentNullException.ThrowIfNull(parent);
33 | if (element?.Parent != null) throw new InvalidOperationException($"Cannot set the {element.GetType()} as it already belongs to another {element.Parent.GetType()} instance");
34 |
35 | if (_element is not null)
36 | {
37 | _element.Parent = null;
38 | }
39 |
40 | _element = element!;
41 |
42 | if (element != null)
43 | {
44 | element.Parent = parent;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/LibObjectFile/ObjectFileException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using LibObjectFile.Diagnostics;
7 |
8 | namespace LibObjectFile;
9 |
10 | ///
11 | /// An exception used when diagnostics error are happening during read/write.
12 | ///
13 | public sealed class ObjectFileException : Exception
14 | {
15 | public ObjectFileException(string message, DiagnosticBag diagnostics) : base(message)
16 | {
17 |
18 | Diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics));
19 | }
20 |
21 | public override string Message => base.Message + Environment.NewLine + Diagnostics;
22 |
23 | ///
24 | /// The associated diagnostics messages.
25 | ///
26 | public DiagnosticBag Diagnostics { get; }
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEArchitectureDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// Represents the Architecture directory.
11 | ///
12 | public sealed class PEArchitectureDirectory : PEDataDirectory
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public PEArchitectureDirectory() : base(PEDataDirectoryKind.Architecture)
18 | {
19 | }
20 |
21 | protected override uint ComputeHeaderSize(PELayoutContext context)
22 | {
23 | return 0;
24 | }
25 |
26 | public override void Read(PEImageReader reader)
27 | {
28 | // TBD
29 | }
30 |
31 | public override void Write(PEImageWriter writer)
32 | {
33 | }
34 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBaseRelocation.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Diagnostics;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace LibObjectFile.PE;
10 |
11 | ///
12 | /// A base relocation in a Portable Executable (PE) image.
13 | ///
14 | [DebuggerDisplay("{ToString(),nq}")]
15 | public readonly struct PEBaseRelocation
16 | {
17 | public const ushort MaxVirtualOffset = (1 << 12) - 1;
18 | private const ushort TypeMask = unchecked((ushort)~MaxVirtualOffset);
19 | private const ushort VirtualOffsetMask = MaxVirtualOffset;
20 |
21 | private readonly ushort _value;
22 |
23 | public PEBaseRelocation(ushort value)
24 | {
25 | _value = value;
26 | }
27 |
28 | public PEBaseRelocation(PEBaseRelocationType type, ushort offsetInBlock)
29 | {
30 | _value = (ushort)((ushort)type | (offsetInBlock & VirtualOffsetMask));
31 | }
32 |
33 | ///
34 | /// Gets a value indicating whether the base relocation is zero (used for padding).
35 | ///
36 | public bool IsZero => _value == 0;
37 |
38 | ///
39 | /// Gets the type of the base relocation.
40 | ///
41 | public PEBaseRelocationType Type => (PEBaseRelocationType)(_value & TypeMask);
42 |
43 | ///
44 | /// Gets the virtual offset of the base relocation relative to the offset of the associated .
45 | ///
46 | public ushort OffsetInPage => (ushort)(_value & VirtualOffsetMask);
47 |
48 | public override string ToString() => Type == PEBaseRelocationType.Absolute ? $"{Type} Zero Padding" : $"{Type} OffsetInBlock = 0x{OffsetInPage:X}";
49 | }
50 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBlobDataLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | [DebuggerDisplay("{ToString(),nq}")]
10 | public readonly record struct PEBlobDataLink(PEObjectBase? Container, RVO RVO, uint Size) : IPELink
11 | {
12 | public override string ToString() => $"{this.ToDisplayText()}, Size = 0x{Size:X}";
13 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBoundImportAddressTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public abstract class PEBoundImportAddressTable : PEThunkAddressTable
8 | {
9 | private protected PEBoundImportAddressTable(bool is32Bits) : base(is32Bits)
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBoundImportAddressTable32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 | using LibObjectFile.Utils;
9 |
10 | namespace LibObjectFile.PE;
11 |
12 | public sealed class PEBoundImportAddressTable32() : PEBoundImportAddressTable(true)
13 | {
14 | public List Entries { get; } = new();
15 |
16 | public override void Read(PEImageReader reader) => Read32(reader, Entries);
17 |
18 | public override void Write(PEImageWriter writer) => Write32(writer, Entries);
19 |
20 | public override int Count => Entries.Count;
21 |
22 | internal override void SetCount(int count) => CollectionsMarshal.SetCount(Entries, count);
23 |
24 | public override int ReadAt(uint offset, Span destination)
25 | {
26 | var buffer = MemoryMarshal.AsBytes(CollectionsMarshal.AsSpan(Entries));
27 | return DataUtils.ReadAt(buffer, offset, destination);
28 | }
29 |
30 | public override void WriteAt(uint offset, ReadOnlySpan source)
31 | {
32 | var buffer = MemoryMarshal.AsBytes(CollectionsMarshal.AsSpan(Entries));
33 | DataUtils.WriteAt(buffer, offset, source);
34 | }
35 |
36 | public override unsafe bool CanReadWriteAt(uint offset, uint size) => offset + size <= (uint)Entries.Count * sizeof(VA32);
37 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBoundImportAddressTable64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Utils;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Runtime.InteropServices;
9 |
10 | namespace LibObjectFile.PE;
11 |
12 | public sealed class PEBoundImportAddressTable64() : PEBoundImportAddressTable(false)
13 | {
14 | public List Entries { get; } = new();
15 |
16 | public override void Read(PEImageReader reader) => Read64(reader, Entries);
17 |
18 | public override void Write(PEImageWriter writer) => Write64(writer, Entries);
19 |
20 | public override int Count => Entries.Count;
21 |
22 | internal override void SetCount(int count) => CollectionsMarshal.SetCount(Entries, count);
23 |
24 | public override int ReadAt(uint offset, Span destination)
25 | {
26 | var buffer = MemoryMarshal.AsBytes(CollectionsMarshal.AsSpan(Entries));
27 | return DataUtils.ReadAt(buffer, offset, destination);
28 | }
29 |
30 | public override void WriteAt(uint offset, ReadOnlySpan source)
31 | {
32 | var buffer = MemoryMarshal.AsBytes(CollectionsMarshal.AsSpan(Entries));
33 | DataUtils.WriteAt(buffer, offset, source);
34 | }
35 |
36 | public override unsafe bool CanReadWriteAt(uint offset, uint size) => offset + size <= (uint)Entries.Count * sizeof(VA64);
37 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBoundImportDirectoryEntry.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using LibObjectFile.PE.Internal;
7 |
8 | namespace LibObjectFile.PE;
9 |
10 | ///
11 | /// Represents an entry in the Bound Import Directory of a Portable Executable (PE) file.
12 | ///
13 | public sealed class PEBoundImportDirectoryEntry
14 | {
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | public PEBoundImportDirectoryEntry()
19 | {
20 | ForwarderRefs = new List();
21 | }
22 |
23 | ///
24 | /// Gets or sets the module name for this entry.
25 | ///
26 | public PEAsciiStringLink ModuleName { get; set; }
27 |
28 | ///
29 | /// Gets the list of forwarder references for this entry.
30 | ///
31 | public List ForwarderRefs { get; }
32 |
33 | ///
34 | /// Gets the size of this entry in the Bound Import Directory.
35 | ///
36 | internal unsafe uint Size => (uint)(sizeof(RawPEBoundImportDirectory) + ForwarderRefs.Count * sizeof(RawPEBoundImportForwarderRef));
37 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEBoundImportForwarderRef.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a forwarder reference in the Bound Import Directory of a Portable Executable (PE) file.
9 | ///
10 | public readonly record struct PEBoundImportForwarderRef
11 | {
12 | ///
13 | /// Initializes a new instance of the struct.
14 | ///
15 | /// The module name of the forwarder reference.
16 | public PEBoundImportForwarderRef(PEAsciiStringLink moduleName)
17 | {
18 | ModuleName = moduleName;
19 | }
20 |
21 | ///
22 | /// Gets the module name of the forwarder reference.
23 | ///
24 | public PEAsciiStringLink ModuleName { get; }
25 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEClrMetadata.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// Represents the CLR metadata directory in a PE file.
11 | ///
12 | public sealed class PEClrMetadata : PEDataDirectory
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public PEClrMetadata() : base(PEDataDirectoryKind.ClrMetadata)
18 | {
19 | }
20 |
21 | ///
22 | protected override uint ComputeHeaderSize(PELayoutContext context) => 0;
23 |
24 | ///
25 | public override void Read(PEImageReader reader)
26 | {
27 | }
28 |
29 | ///
30 | public override void Write(PEImageWriter writer)
31 | {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEDataDirectoryKind.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines directory entry indices.
9 | ///
10 | public enum PEDataDirectoryKind : ushort
11 | {
12 | ///
13 | /// Export Directory
14 | ///
15 | Export = 0,
16 | ///
17 | /// Import Directory
18 | ///
19 | Import = 1,
20 | ///
21 | /// Resource Directory
22 | ///
23 | Resource = 2,
24 | ///
25 | /// Exception Directory
26 | ///
27 | Exception = 3,
28 | ///
29 | /// Security/Certificate Directory
30 | ///
31 | SecurityCertificate = 4,
32 | ///
33 | /// Base Relocation Table
34 | ///
35 | BaseRelocation = 5,
36 | ///
37 | /// Debug Directory
38 | ///
39 | Debug = 6,
40 | ///
41 | /// Architecture Specific Data
42 | ///
43 | Architecture = 7,
44 | ///
45 | /// RVA of GP
46 | ///
47 | GlobalPointer = 8,
48 | ///
49 | /// TLS Directory
50 | ///
51 | Tls = 9,
52 | ///
53 | /// Load Configuration Directory
54 | ///
55 | LoadConfig = 10,
56 | ///
57 | /// Bound Import Directory in headers
58 | ///
59 | BoundImport = 11,
60 | ///
61 | /// Import Address Table
62 | ///
63 | ImportAddressTable = 12,
64 | ///
65 | /// Delay Load Import Descriptors
66 | ///
67 | DelayImport = 13,
68 | ///
69 | /// .NET CLR Metadata
70 | ///
71 | ClrMetadata = 14,
72 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEDebugSectionData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public abstract class PEDebugSectionData : PESectionData
8 | {
9 | protected PEDebugSectionData()
10 | {
11 | }
12 |
13 | public override bool HasChildren => false;
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEDebugStreamExtraData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a debug directory entry in a Portable Executable (PE) file.
9 | ///
10 | public class PEDebugStreamExtraData : PEStreamExtraData
11 | {
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEDebugStreamSectionData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A debug stream section data in a Portable Executable (PE) image.
11 | ///
12 | public class PEDebugStreamSectionData : PEStreamSectionData
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public PEDebugStreamSectionData()
18 | {
19 | }
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// The stream containing the data of this section data.
25 | public PEDebugStreamSectionData(Stream stream) : base(stream)
26 | {
27 | }
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEExceptionFunctionEntry.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents an exception function entry in a Portable Executable (PE) file.
9 | ///
10 | public abstract class PEExceptionFunctionEntry
11 | {
12 | ///
13 | /// Initializes a new instance of the class with the specified begin address.
14 | ///
15 | /// The begin address of the exception function entry.
16 | internal PEExceptionFunctionEntry(PESectionDataLink beginAddress)
17 | {
18 | BeginAddress = beginAddress;
19 | }
20 |
21 | ///
22 | /// Gets or sets the begin address of the exception function entry.
23 | ///
24 | public PESectionDataLink BeginAddress { get; set; }
25 |
26 | internal virtual void Verify(PEVerifyContext context, PEExceptionDirectory exceptionDirectory, int index)
27 | {
28 | context.VerifyObject(BeginAddress.Container, exceptionDirectory, $"the {nameof(BeginAddress)} of the {nameof(PEExceptionFunctionEntry)} at #{index}", false);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEExceptionFunctionEntryArm.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents an ARM exception function entry in a Portable Executable (PE) file.
9 | ///
10 | public sealed class PEExceptionFunctionEntryARM : PEExceptionFunctionEntry
11 | {
12 | ///
13 | /// Initializes a new instance of the class with the specified begin address and unwind data.
14 | ///
15 | /// The begin address of the exception function entry.
16 | /// The unwind data.
17 | public PEExceptionFunctionEntryARM(PESectionDataLink beginAddress, uint unwindData) : base(beginAddress)
18 | {
19 | UnwindData = unwindData;
20 | }
21 |
22 | ///
23 | /// Gets or sets the unwind data.
24 | ///
25 | public uint UnwindData { get; set; }
26 |
27 | ///
28 | public override string ToString()
29 | {
30 | return $"{nameof(BeginAddress)} = {BeginAddress.RVA()}, {nameof(UnwindData)} = 0x{UnwindData:X}";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEExportFunctionEntry.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | #pragma warning disable CS0649
8 | public readonly struct PEExportFunctionEntry
9 | {
10 | private readonly PEObject? _container;
11 | private readonly uint _offset;
12 | private readonly bool _isForwarderRVA;
13 |
14 | public PEExportFunctionEntry(PEFunctionAddressLink exportRVA)
15 | {
16 | _container = exportRVA.Container;
17 | _offset = exportRVA.RVO;
18 | _isForwarderRVA = false;
19 | }
20 |
21 | public PEExportFunctionEntry(PEAsciiStringLink forwarderRVA)
22 | {
23 | _container = forwarderRVA.Container;
24 | _offset = forwarderRVA.RVO;
25 | _isForwarderRVA = true;
26 | }
27 |
28 | public bool IsForwarderRVA => _isForwarderRVA;
29 |
30 | public bool IsEmpty => _container is null && _offset == 0;
31 |
32 | public PEFunctionAddressLink ExportRVA => IsForwarderRVA ? default : new(_container, _offset);
33 |
34 | public PEAsciiStringLink ForwarderRVA => IsForwarderRVA ? new(_container as PEStreamSectionData, _offset) : default;
35 |
36 | public override string ToString() => IsEmpty ? "null" : ForwarderRVA.IsNull() ? $"{ExportRVA}" : $"{ExportRVA}, ForwarderRVA = {ForwarderRVA}";
37 |
38 |
39 | internal void Verify(PEVerifyContext context, PEExportAddressTable parent, int index)
40 | {
41 | context.VerifyObject(_container, parent, $"the object pointed by the {nameof(PEExportFunctionEntry)} at #{index}", false);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEExportOrdinalTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Runtime.InteropServices;
7 | using LibObjectFile.Diagnostics;
8 |
9 | namespace LibObjectFile.PE;
10 |
11 | public sealed class PEExportOrdinalTable : PESectionData
12 | {
13 | public PEExportOrdinalTable()
14 | {
15 | }
16 |
17 | internal PEExportOrdinalTable(int count)
18 | {
19 | CollectionsMarshal.SetCount(Values, count);
20 | }
21 |
22 | public override bool HasChildren => false;
23 |
24 | public List Values { get; } = new();
25 |
26 |
27 | protected override void UpdateLayoutCore(PELayoutContext context)
28 | {
29 | Size = (ulong)Values.Count * sizeof(ushort);
30 | }
31 |
32 | // Special method that can read from a known size
33 | public override void Read(PEImageReader reader)
34 | {
35 | reader.Position = Position;
36 | var span = CollectionsMarshal.AsSpan(Values);
37 |
38 | int read = reader.Read(MemoryMarshal.AsBytes(span));
39 | if (read != Values.Count * sizeof(ushort))
40 | {
41 | reader.Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unable to read Export Ordinal Table");
42 | return;
43 | }
44 | }
45 |
46 | public override void Write(PEImageWriter writer)
47 | {
48 | var span = CollectionsMarshal.AsSpan(Values);
49 | writer.Write(MemoryMarshal.AsBytes(span));
50 | }
51 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEGlobalPointerDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// Represents the GlobalPointer directory.
11 | ///
12 | public sealed class PEGlobalPointerDirectory : PEDataDirectory
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public PEGlobalPointerDirectory() : base(PEDataDirectoryKind.GlobalPointer)
18 | {
19 | }
20 |
21 | protected override uint ComputeHeaderSize(PELayoutContext context)
22 | {
23 | return 0;
24 | }
25 |
26 | public override void Read(PEImageReader reader)
27 | {
28 | }
29 |
30 | public override void Write(PEImageWriter writer)
31 | {
32 | }
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportAddressTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public abstract class PEImportAddressTable : PEImportFunctionTable
8 | {
9 | private protected PEImportAddressTable(bool is32Bit) : base(is32Bit)
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportAddressTable32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public sealed class PEImportAddressTable32() : PEImportAddressTable(true);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportAddressTable64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public sealed class PEImportAddressTable64() : PEImportAddressTable(false);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportAddressTableDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 | using LibObjectFile.Collections;
9 |
10 | namespace LibObjectFile.PE;
11 |
12 | public sealed class PEImportAddressTableDirectory : PEDataDirectory
13 | {
14 | public PEImportAddressTableDirectory() : base(PEDataDirectoryKind.ImportAddressTable)
15 | {
16 | }
17 |
18 | public override void Read(PEImageReader reader)
19 | {
20 | }
21 |
22 | public override void Write(PEImageWriter writer)
23 | {
24 | }
25 |
26 | protected override uint ComputeHeaderSize(PELayoutContext context) => 0;
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportLookupTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public abstract class PEImportLookupTable : PEImportFunctionTable
8 | {
9 | private protected PEImportLookupTable(bool is32Bit) : base(is32Bit)
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportLookupTable32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public sealed class PEImportLookupTable32() : PEImportLookupTable(true);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEImportLookupTable64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public sealed class PEImportLookupTable64() : PEImportLookupTable(false);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PELoadConfigCodeIntegrity.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// A structure representing the Code Integrity information in the Load Configuration Directory.
9 | ///
10 | public struct PELoadConfigCodeIntegrity
11 | {
12 | public ushort Flags; // Flags to indicate if CI information is available, etc.
13 | public ushort Catalog; // 0xFFFF means not available
14 | public uint CatalogOffset;
15 | public uint Reserved; // Additional bitmask to be defined later
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PELoadConfigDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 | using System;
7 | using System.Runtime.InteropServices;
8 | using LibObjectFile.Utils;
9 |
10 | namespace LibObjectFile.PE;
11 |
12 | ///
13 | /// Represents the Load Configuration Directory for a PE file.
14 | ///
15 | public abstract class PELoadConfigDirectory : PERawDataDirectory
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | private protected PELoadConfigDirectory(int minSize) : base(PEDataDirectoryKind.LoadConfig, minSize)
21 | {
22 | }
23 |
24 | ///
25 | /// Change the recorded size of the Load Configuration Directory.
26 | ///
27 | ///
28 | public void SetConfigSize(uint size)
29 | {
30 | SetRawDataSize(size);
31 |
32 | // Write back the configuration size
33 | MemoryMarshal.Write(RawData, size);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEResourceData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A section data that contains a resource data.
11 | ///
12 | public sealed class PEResourceData : PEStreamSectionData
13 | {
14 | public PEResourceData()
15 | {
16 | RequiredPositionAlignment = 4;
17 | RequiredSizeAlignment = 4;
18 | }
19 |
20 | ///
21 | protected override void ValidateParent(ObjectElement parent)
22 | {
23 | if (parent is not PEResourceDirectory)
24 | {
25 | throw new ArgumentException($"Invalid parent type {parent.GetType().FullName}. Expecting a parent of type {typeof(PEResourceDirectory).FullName}");
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEResourceDirectoryEntryById.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a resource directory entry with an ID in a PE file.
9 | ///
10 | /// The identifier of the resource directory entry.
11 | /// The resource entry associated with the identifier.
12 | public readonly record struct PEResourceDirectoryEntryById(PEResourceId Id, PEResourceEntry Entry);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEResourceDirectoryEntryByName.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a resource directory entry with a name in a PE file.
9 | ///
10 | /// The name of the resource directory entry.
11 | /// The resource entry associated with the name.
12 | public readonly record struct PEResourceDirectoryEntryByName(PEResourceString Name, PEResourceEntry Entry);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PESectionVirtualSizeMode.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines the way the virtual size of a section is computed.
9 | ///
10 | public enum PESectionVirtualSizeMode
11 | {
12 | ///
13 | /// The virtual size of the section is automatically computed by the raw size of its content without file alignment.
14 | ///
15 | Auto = 0,
16 |
17 | ///
18 | /// The virtual size of the section is fixed.
19 | ///
20 | ///
21 | /// This is usually the case when the virtual size is requested to be bigger than the raw size (e.g. uninitialized data).
22 | ///
23 | Fixed = 1,
24 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PESecurityCertificateRevision.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines the revision of the security certificate.
9 | ///
10 | public enum PESecurityCertificateRevision : ushort
11 | {
12 | ///
13 | /// Version 1, legacy version of the Win_Certificate structure. It is supported only for purposes of verifying legacy Authenticode signatures
14 | ///
15 | Revision1 = 0x0100,
16 |
17 | ///
18 | /// Version 2 is the current version of the Win_Certificate structure.
19 | ///
20 | Revision2 = 0x0200,
21 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PESecurityCertificateType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines the type of the security certificate.
9 | ///
10 | public enum PESecurityCertificateType : ushort
11 | {
12 | ///
13 | /// X.509 Certificate. Not Supported
14 | ///
15 | X509 = 0x0001,
16 |
17 | ///
18 | /// PKCS#7 SignedData structure.
19 | ///
20 | PKCS7 = 0x0002,
21 |
22 | ///
23 | /// Reserved. Not supported.
24 | ///
25 | Reserved = 0x0003,
26 |
27 | ///
28 | /// Terminal Server Protocol Stack Certificate signing. Not Supported
29 | ///
30 | TerminalServerProtocolStack = 0x0004,
31 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PETlsCharacteristics.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | [Flags]
10 | public enum PETlsCharacteristics : uint
11 | {
12 | Align1Bytes = 1048576, // 0x00100000
13 | Align2Bytes = 2097152, // 0x00200000
14 | Align4Bytes = Align2Bytes | Align1Bytes, // 0x00300000
15 | Align8Bytes = 4194304, // 0x00400000
16 | Align16Bytes = Align8Bytes | Align1Bytes, // 0x00500000
17 | Align32Bytes = Align8Bytes | Align2Bytes, // 0x00600000
18 | Align64Bytes = Align32Bytes | Align1Bytes, // 0x00700000
19 | Align128Bytes = 8388608, // 0x00800000
20 | Align256Bytes = Align128Bytes | Align1Bytes, // 0x00900000
21 | Align512Bytes = Align128Bytes | Align2Bytes, // 0x00A00000
22 | Align1024Bytes = Align512Bytes | Align1Bytes, // 0x00B00000
23 | Align2048Bytes = Align128Bytes | Align8Bytes, // 0x00C00000
24 | Align4096Bytes = Align2048Bytes | Align1Bytes, // 0x00D00000
25 | Align8192Bytes = Align2048Bytes | Align2Bytes, // 0x00E00000
26 | AlignMask = Align8192Bytes | Align1Bytes, // 0x00F00000
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PETlsDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 | namespace LibObjectFile.PE;
5 |
6 | ///
7 | /// Represents the Thread Local Storage (TLS) directory in a PE file.
8 | ///
9 | public abstract class PETlsDirectory : PERawDataDirectory
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | private protected PETlsDirectory(int minSize) : base(PEDataDirectoryKind.Tls, minSize)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/DataDirectory/PEUnknownDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents an unknown directory (when going beyond the known directories).
9 | ///
10 | public sealed class PEUnknownDirectory : PEDataDirectory
11 | {
12 | internal PEUnknownDirectory(int index) : base((PEDataDirectoryKind)index)
13 | {
14 | }
15 |
16 | protected override uint ComputeHeaderSize(PELayoutContext context) => 0;
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/IPELink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | // ReSharper disable once InconsistentNaming
8 |
9 |
10 | public interface IPELink;
11 |
12 | public interface IPELink : IPELink where TObject: PEObjectBase
13 | {
14 | public TObject? Container { get; }
15 |
16 | public RVO RVO { get; }
17 | }
18 |
19 |
20 | public interface IPELink : IPELink where TObject : PEObjectBase
21 | {
22 | public TData Resolve();
23 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawDelayLoadDescriptor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 | ///
9 | /// Represents a delay load descriptor in a Portable Executable (PE) image.
10 | ///
11 | internal struct RawDelayLoadDescriptor
12 | {
13 | ///
14 | /// The attributes that must be zero.
15 | ///
16 | public uint Attributes;
17 |
18 | ///
19 | /// The RVA of the name of the DLL to delay load.
20 | ///
21 | public RVA NameRVA;
22 |
23 | ///
24 | /// The RVA to the HMODULE caching location (PHMODULE)
25 | ///
26 | public RVA ModuleHandleRVA;
27 |
28 | ///
29 | /// The RVA of the delay load import address table, which contains the RVAs of the delay load import name table and the delay load import module.
30 | ///
31 | public RVA DelayLoadImportAddressTableRVA;
32 |
33 | ///
34 | /// The RVA of the delay load import name table, which contains the names of the delay load imports.
35 | ///
36 | public RVA DelayLoadImportNameTableRVA;
37 |
38 | ///
39 | /// The RVA of the bound delay load import address table. This table contains the actual addresses to use for the delay load imports.
40 | ///
41 | public RVA BoundDelayLoadImportAddressTableRVA;
42 |
43 | ///
44 | /// The RVA of the unload delay load import address table.
45 | ///
46 | public RVA UnloadDelayLoadImportAddressTableRVA;
47 |
48 | ///
49 | /// The time/date stamp of the delay load import table.
50 | ///
51 | public uint TimeDateStamp;
52 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawExceptionFunctionEntryARM.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawExceptionFunctionEntryARM
10 | {
11 | public RVA BeginAddress;
12 | public uint UnwindData;
13 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawExceptionFunctionEntryX86.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawExceptionFunctionEntryX86
10 | {
11 | public RVA BeginAddress;
12 | public RVA EndAddress;
13 | public RVA UnwindInfoAddress;
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageDataDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 | ///
11 | /// Data directory entry in the optional header of a Portable Executable (PE) file.
12 | ///
13 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
14 | internal struct RawImageDataDirectory
15 | {
16 | ///
17 | /// The relative virtual address of the data directory.
18 | ///
19 | public RVA RVA;
20 |
21 | ///
22 | /// The size of the data directory, in bytes.
23 | ///
24 | public uint Size;
25 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageDataDirectoryArray.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | using System.Runtime.CompilerServices;
7 |
8 | namespace LibObjectFile.PE.Internal;
9 |
10 | #pragma warning disable CS0649
11 |
12 | ///
13 | /// An array of entries.
14 | ///
15 | [InlineArray(16)]
16 | internal struct RawImageDataDirectoryArray
17 | {
18 | private RawImageDataDirectory _e;
19 |
20 | ///
21 | /// Gets or sets the at the specified index.
22 | ///
23 | /// The index of the to get or set.
24 | /// The at the specified index.
25 | [UnscopedRef]
26 | public ref RawImageDataDirectory this[PEDataDirectoryKind kind] => ref this[(int)kind];
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageDebugDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawImageDebugDirectory
10 | {
11 | public uint Characteristics;
12 | public uint TimeDateStamp;
13 | public ushort MajorVersion;
14 | public ushort MinorVersion;
15 | public PEDebugType Type;
16 | public uint SizeOfData;
17 | public RVA AddressOfRawData;
18 | public uint PointerToRawData;
19 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeader32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
12 | internal struct RawImageOptionalHeader32
13 | {
14 | public RawImageOptionalHeaderCommonPart1 Common;
15 | public RawImageOptionalHeaderBase32 Base32;
16 | public RawImageOptionalHeaderCommonPart2 Common2;
17 | public RawImageOptionalHeaderSize32 Size32;
18 | public RawImageOptionalHeaderCommonPart3 Common3;
19 |
20 | // In case of a PE Header with zero directories
21 | public static unsafe int MinimumSize => sizeof(RawImageOptionalHeader32) - sizeof(RawImageDataDirectoryArray);
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeader64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
12 | internal struct RawImageOptionalHeader64
13 | {
14 | public RawImageOptionalHeaderCommonPart1 Common;
15 | public RawImageOptionalHeaderBase64 Base64;
16 | public RawImageOptionalHeaderCommonPart2 Common2;
17 | public RawImageOptionalHeaderSize64 Size64;
18 | public RawImageOptionalHeaderCommonPart3 Common3;
19 |
20 | // In case of a PE Header with zero directories
21 | public static unsafe int MinimumSize => sizeof(RawImageOptionalHeader64) - sizeof(RawImageDataDirectoryArray);
22 | }
23 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderBase32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawImageOptionalHeaderBase32
10 | {
11 | ///
12 | /// The address relative to the image base of the beginning of the data section.
13 | ///
14 | public RVA BaseOfData;
15 |
16 | //
17 | // NT additional fields.
18 | //
19 |
20 | ///
21 | /// The preferred address of the first byte of the image when loaded into memory.
22 | ///
23 | public uint ImageBase;
24 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderBase64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawImageOptionalHeaderBase64
10 | {
11 | //
12 | // NT additional fields.
13 | //
14 |
15 | ///
16 | /// The preferred address of the first byte of the image when loaded into memory.
17 | ///
18 | public ulong ImageBase;
19 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderCommonPart1.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | ///
12 | /// Represents the optional header in a PE (Portable Executable) file format (32-bit).
13 | ///
14 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
15 | internal struct RawImageOptionalHeaderCommonPart1
16 | {
17 | ///
18 | /// The magic number, which identifies the file format. Expected to be 0x10b for PE32.
19 | ///
20 | public PEOptionalHeaderMagic Magic;
21 |
22 | ///
23 | /// The major version number of the linker.
24 | ///
25 | public byte MajorLinkerVersion;
26 |
27 | ///
28 | /// The minor version number of the linker.
29 | ///
30 | public byte MinorLinkerVersion;
31 |
32 | ///
33 | /// The size of the code (text) section, in bytes.
34 | ///
35 | public uint SizeOfCode;
36 |
37 | ///
38 | /// The size of the initialized data section, in bytes.
39 | ///
40 | public uint SizeOfInitializedData;
41 |
42 | ///
43 | /// The size of the uninitialized data section, in bytes.
44 | ///
45 | public uint SizeOfUninitializedData;
46 |
47 | ///
48 | /// The address of the entry point relative to the image base when the executable starts.
49 | ///
50 | public RVA AddressOfEntryPoint;
51 |
52 | ///
53 | /// The address relative to the image base of the beginning of the code section.
54 | ///
55 | public RVA BaseOfCode;
56 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderCommonPart3.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
12 | internal struct RawImageOptionalHeaderCommonPart3
13 | {
14 | ///
15 | /// Reserved; must be zero.
16 | ///
17 | public uint LoaderFlags;
18 |
19 | ///
20 | /// The number of data-directory entries in the remainder of the optional header.
21 | ///
22 | public uint NumberOfRvaAndSizes;
23 |
24 | ///
25 | /// The data directories array, which contains the location and size of special tables in the file.
26 | ///
27 | public RawImageDataDirectoryArray DataDirectory;
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderSize32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
12 | internal struct RawImageOptionalHeaderSize32
13 | {
14 | ///
15 | /// The size of the stack to reserve, in bytes.
16 | ///
17 | public uint SizeOfStackReserve;
18 |
19 | ///
20 | /// The size of the stack to commit, in bytes.
21 | ///
22 | public uint SizeOfStackCommit;
23 |
24 | ///
25 | /// The size of the local heap space to reserve, in bytes.
26 | ///
27 | public uint SizeOfHeapReserve;
28 |
29 | ///
30 | /// The size of the local heap space to commit, in bytes.
31 | ///
32 | public uint SizeOfHeapCommit;
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageOptionalHeaderSize64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace LibObjectFile.PE.Internal;
8 |
9 | #pragma warning disable CS0649
10 |
11 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
12 | internal struct RawImageOptionalHeaderSize64
13 | {
14 | ///
15 | /// The size of the stack to reserve, in bytes.
16 | ///
17 | public ulong SizeOfStackReserve;
18 |
19 | ///
20 | /// The size of the stack to commit, in bytes.
21 | ///
22 | public ulong SizeOfStackCommit;
23 |
24 | ///
25 | /// The size of the local heap space to reserve, in bytes.
26 | ///
27 | public ulong SizeOfHeapReserve;
28 |
29 | ///
30 | /// The size of the local heap space to commit, in bytes.
31 | ///
32 | public ulong SizeOfHeapCommit;
33 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImageResourceDirectoryEntry.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 | internal struct RawImageResourceDirectoryEntry
9 | {
10 | public uint NameOrId;
11 | public uint OffsetToDataOrDirectoryEntry;
12 | }
13 |
14 | internal struct RawImageResourceDataEntry
15 | {
16 | public RVA OffsetToData;
17 | public uint Size;
18 | public uint CodePage;
19 | public uint Reserved;
20 | }
21 |
22 | internal struct RawImageResourceDirectory
23 | {
24 | public uint Characteristics;
25 | public uint TimeDateStamp;
26 | public ushort MajorVersion;
27 | public ushort MinorVersion;
28 | public ushort NumberOfNamedEntries;
29 | public ushort NumberOfIdEntries;
30 | // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
31 | }
32 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImportDirectoryEntry.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | internal struct RawImportDirectoryEntry
8 | {
9 | #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
10 |
11 | ///
12 | /// The RVA of the import lookup table. This table contains a name or ordinal for each import. (The name "Characteristics" is used in Winnt.h, but no longer describes this field.)
13 | ///
14 | public RVA ImportLookupTableRVA;
15 |
16 | ///
17 | /// The stamp that is set to zero until the image is bound. After the image is bound, this field is set to the time/data stamp of the DLL.
18 | ///
19 | /// 0 if not bound,
20 | /// -1 if bound, and real date\time stamp in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
21 | /// O.W. date/time stamp of DLL bound to (Old BIND)
22 | ///
23 | public uint TimeDateStamp;
24 |
25 | ///
26 | /// The index of the first forwarder reference. -1 if no forwarders
27 | ///
28 | public uint ForwarderChain;
29 |
30 | ///
31 | /// The address of an ASCII string that contains the name of the DLL. This address is relative to the image base.
32 | ///
33 | public RVA NameRVA;
34 |
35 | ///
36 | /// The RVA of the import address table. The contents of this table are identical to the contents of the import lookup table until the image is bound.
37 | ///
38 | public RVA ImportAddressTableRVA;
39 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImportFunctionEntry32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 | internal readonly struct RawImportFunctionEntry32
9 | {
10 | private readonly uint _hintNameTableRVA;
11 |
12 | public RawImportFunctionEntry32(uint hintNameTableRVA)
13 | {
14 | _hintNameTableRVA = hintNameTableRVA;
15 | }
16 |
17 | public uint HintNameTableRVA => IsImportByOrdinal ? 0U : _hintNameTableRVA;
18 |
19 | public bool IsNull => _hintNameTableRVA == 0;
20 |
21 | public bool IsImportByOrdinal => (_hintNameTableRVA & 0x8000_0000U) != 0;
22 |
23 | public ushort Ordinal => IsImportByOrdinal ? (ushort)_hintNameTableRVA : (ushort)0;
24 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawImportFunctionEntry64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 | internal readonly struct RawImportFunctionEntry64
9 | {
10 | private readonly ulong _hintNameTableRVA;
11 |
12 | public RawImportFunctionEntry64(ulong hintNameTableRVA)
13 | {
14 | _hintNameTableRVA = hintNameTableRVA;
15 | }
16 |
17 | public ulong HintNameTableRVA => IsImportByOrdinal ? 0U : _hintNameTableRVA;
18 |
19 | public bool IsNull => _hintNameTableRVA == 0;
20 |
21 | public ushort Ordinal => IsImportByOrdinal ? (ushort)_hintNameTableRVA : (ushort)0;
22 |
23 | public bool IsImportByOrdinal => (_hintNameTableRVA & 0x8000_0000_0000_0000UL) != 0;
24 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawPEBoundImportDirectory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawPEBoundImportDirectory
10 | {
11 | public uint TimeDateStamp;
12 | public ushort OffsetModuleName;
13 | public ushort NumberOfModuleForwarderRefs;
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/Internal/RawPEBoundImportForwarderRef.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE.Internal;
6 |
7 | #pragma warning disable CS0649
8 |
9 | internal struct RawPEBoundImportForwarderRef
10 | {
11 | public uint TimeDateStamp;
12 | public ushort OffsetModuleName;
13 | public ushort Reserved;
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEAsciiStringLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A link to a null terminated ASCII string in a .
11 | ///
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly record struct PEAsciiStringLink(PEStreamSectionData? Container, RVO RVO) : IPELink
14 | {
15 | ///
16 | public override string ToString() => this.ToDisplayTextWithRVA();
17 |
18 | ///
19 | /// Resolves this link to a string.
20 | ///
21 | /// The string resolved.
22 | public string? Resolve() => Container?.ReadAsciiString(RVO);
23 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEDosMagic.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | #pragma warning disable CS0649
8 | ///
9 | /// Magic number for the >
10 | ///
11 | public enum PEDosMagic : ushort
12 | {
13 | ///
14 | /// MZ - DOS executable file signature.
15 | ///
16 | DOS = 0x5A4D,
17 | ///
18 | /// NE - OS/2 executable file signature.
19 | ///
20 | OS2 = 0x454E,
21 | ///
22 | /// LE - OS/2 LE or VXD.
23 | ///
24 | OS2OrVXD = 0x454C,
25 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEExtraData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Base class for extra data in a PE file accessible via .
9 | ///
10 | public abstract class PEExtraData : PEObjectBase
11 | {
12 | protected PEExtraData()
13 | {
14 | }
15 |
16 | public override bool HasChildren => false;
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEFile.Verify.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using LibObjectFile.Diagnostics;
7 |
8 | namespace LibObjectFile.PE;
9 |
10 | ///
11 | /// A Portable Executable file that can be read, modified and written.
12 | ///
13 | partial class PEFile
14 | {
15 | ///
16 | /// Verifies the validity of this PE file.
17 | ///
18 | /// The diagnostics to output errors.
19 | public void Verify(DiagnosticBag diagnostics)
20 | {
21 | ArgumentNullException.ThrowIfNull(diagnostics);
22 | var context = new PEVerifyContext(this, diagnostics);
23 | Verify(context);
24 | }
25 |
26 | ///
27 | public override void Verify(PEVerifyContext context)
28 | {
29 | ArgumentNullException.ThrowIfNull(context);
30 |
31 | if (!TryVerifyAlignment(context.Diagnostics))
32 | {
33 | return;
34 | }
35 |
36 | foreach (var data in ExtraDataBeforeSections)
37 | {
38 | data.Verify(context);
39 | }
40 |
41 | foreach (var section in Sections)
42 | {
43 | section.Verify(context);
44 | }
45 |
46 | foreach (var data in ExtraDataAfterSections)
47 | {
48 | data.Verify(context);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEFunctionAddressLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | #pragma warning disable CS0649
10 | [DebuggerDisplay("{ToString(),nq}")]
11 | public readonly record struct PEFunctionAddressLink(PEObject? Container, RVO RVO) : IPELink
12 | {
13 | public override string ToString() => Container is not null ? $"{Container}, Offset = {RVO}" : $"";
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImageReader.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | public sealed class PEImageReader : ObjectFileReaderWriter
10 | {
11 | internal PEImageReader(PEFile file, Stream stream, PEImageReaderOptions readerOptions) : base(file, stream)
12 | {
13 | Options = readerOptions;
14 | LayoutContext = new PELayoutContext(File, Diagnostics, true);
15 | }
16 |
17 | public new PEFile File => (PEFile)base.File;
18 |
19 | public PEImageReaderOptions Options { get; }
20 |
21 | public override bool KeepOriginalStreamForSubStreams => Options.UseSubStream;
22 |
23 | public PELayoutContext LayoutContext { get; }
24 |
25 |
26 | public static implicit operator PELayoutContext(PEImageReader reader) => reader.LayoutContext;
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImageReaderOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public class PEImageReaderOptions
8 | {
9 | public bool UseSubStream { get; init; }
10 |
11 | public bool EnableStackTrace { get; init; }
12 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImageWriter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.IO;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | public sealed class PEImageWriter : ObjectFileReaderWriter
10 | {
11 | internal PEImageWriter(PEFile file, Stream stream, PEImageWriterOptions options) : base(file, stream)
12 | {
13 | Options = options;
14 | }
15 |
16 | public PEFile PEFile => (PEFile)base.File;
17 |
18 | public PEImageWriterOptions Options { get; }
19 |
20 | public override bool KeepOriginalStreamForSubStreams => false;
21 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImageWriterOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public class PEImageWriterOptions
8 | {
9 | public static readonly PEImageWriterOptions Default = new();
10 |
11 | public bool EnableStackTrace { get; init; }
12 |
13 | public bool EnableChecksum { get; init; }
14 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImportHintName.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// A PE Import Hint Name used in .
9 | ///
10 | /// An index into the export name pointer table. A match is attempted first with this value. If it fails, a binary search is performed on the DLL's export name pointer table.
11 | /// This is the string that must be matched to the public name in the DLL
12 | public readonly record struct PEImportHintName(ushort Hint, string? Name);
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEImportHintNameLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A link to a PE Import Hint Name in a .
11 | ///
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly record struct PEImportHintNameLink(PEStreamSectionData? Container, RVO RVO) : IPELink
14 | {
15 | ///
16 | public override string ToString() => this.ToDisplayTextWithRVA();
17 |
18 | ///
19 | /// Resolves this link to a PE Import Hint Name.
20 | ///
21 | /// The PE Import Hint Name resolved.
22 | public PEImportHintName Resolve() => Container?.ReadHintName(RVO) ?? default;
23 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEModuleHandleLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A link to a module handle.
11 | ///
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly record struct PEModuleHandleLink(PESection? Container, RVO RVO) : IPELink
14 | {
15 | ///
16 | public override string ToString() => this.ToDisplayTextWithRVA();
17 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEObjectBaseExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.Runtime.CompilerServices;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace LibObjectFile.PE;
10 |
11 | public static class PEObjectBaseExtensions
12 | {
13 | public static unsafe T ReadAt(this PEObjectBase obj, uint offset) where T : unmanaged
14 | {
15 | T value = default;
16 |
17 | int read = obj.ReadAt(offset, MemoryMarshal.CreateSpan(ref Unsafe.As(ref value), sizeof(T)));
18 | if (read != sizeof(T))
19 | {
20 | throw new InvalidOperationException($"Failed to read {typeof(T).Name} at offset {offset} in {obj}");
21 | }
22 |
23 | return value;
24 | }
25 |
26 | public static unsafe void WriteAt(this PEObjectBase obj, uint offset, T value) where T : unmanaged
27 | {
28 | obj.WriteAt(offset, MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref value), sizeof(T)));
29 | }
30 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEOptionalHeaderMagic.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | public enum PEOptionalHeaderMagic : ushort
8 | {
9 | ///
10 | /// PE32
11 | ///
12 | PE32 = 0x10b,
13 |
14 | ///
15 | /// PE32+
16 | ///
17 | PE32Plus = 0x20b,
18 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PESectionData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Utils;
6 | using System;
7 | using System.Runtime.CompilerServices;
8 | using System.Text;
9 |
10 | namespace LibObjectFile.PE;
11 |
12 | ///
13 | /// Base class for data contained in a .
14 | ///
15 | public abstract class PESectionData : PEObject
16 | {
17 | protected PESectionData()
18 | {
19 | }
20 |
21 | protected override void ValidateParent(ObjectElement parent)
22 | {
23 | if (parent is not PESection && parent is not PESectionData)
24 | {
25 | throw new ArgumentException($"Invalid parent type {parent.GetType().FullName}. Expecting a parent of type {typeof(PESection).FullName} or {typeof(PESectionData).FullName}");
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PESectionDataLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A link to a section data.
11 | ///
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly record struct PESectionDataLink(PESectionData? Container, RVO RVO) : IPELink
14 | {
15 | public override string ToString() => this.ToDisplayTextWithRVA();
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PESectionLink.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace LibObjectFile.PE;
8 |
9 | ///
10 | /// A link to a section
11 | ///
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly record struct PESectionLink(PESection? Container, RVO RVO) : IPELink
14 | {
15 | public override string ToString() => this.ToDisplayTextWithRVA();
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PESignature.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines the NT signature for a PE image.
9 | ///
10 | public enum PESignature : uint
11 | {
12 | ///
13 | /// PE00
14 | ///
15 | PE = 0x00004550,
16 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/PEStreamExtraData.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 | using System.IO;
7 |
8 | namespace LibObjectFile.PE;
9 |
10 | ///
11 | /// Defines a stream extra data in the PE file .
12 | ///
13 | public class PEStreamExtraData : PEExtraData
14 | {
15 | private Stream _stream;
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | public PEStreamExtraData()
21 | {
22 | _stream = Stream.Null;
23 | }
24 |
25 | ///
26 | /// Initializes a new instance of the class.
27 | ///
28 | /// The data stream.
29 | public PEStreamExtraData(Stream stream)
30 | {
31 | ArgumentNullException.ThrowIfNull(stream);
32 | _stream = stream;
33 | Size = (uint)stream.Length;
34 | }
35 |
36 | ///
37 | /// Gets or sets the data stream.
38 | ///
39 | public Stream Stream
40 | {
41 | get => _stream;
42 | set
43 | {
44 | ArgumentNullException.ThrowIfNull(value);
45 | _stream = value;
46 | Size = (uint)value.Length;
47 | }
48 | }
49 |
50 | protected override void UpdateLayoutCore(PELayoutContext context)
51 | {
52 | Size = (uint)Stream.Length;
53 | }
54 |
55 | public override void Read(PEImageReader reader)
56 | {
57 | reader.Position = Position;
58 | Stream = reader.ReadAsStream(Size);
59 | }
60 |
61 | public override void Write(PEImageWriter writer)
62 | {
63 | Stream.Position = 0;
64 | Stream.CopyTo(writer.Stream);
65 | }
66 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/RVA.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines a Relative Virtual Address (RVA) in a Portable Executable (PE) image.
9 | ///
10 | /// The value of the address
11 | public record struct RVA(uint Value)
12 | {
13 | ///
14 | /// Converts a to a .
15 | ///
16 | /// The value to convert.
17 | public static implicit operator uint(RVA value) => value.Value;
18 |
19 | ///
20 | /// Converts a to a .
21 | ///
22 | /// The value to convert.
23 | public static implicit operator RVA(uint value) => new(value);
24 |
25 | ///
26 | public override string ToString() => $"0x{Value:X}";
27 | }
28 |
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/RVO.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Defines a Relative Virtual Offset (RVO) that is relative to a in a Portable Executable (PE) image.
9 | ///
10 | /// The value of the relative offset.
11 | public record struct RVO(uint Value)
12 | {
13 | ///
14 | /// Converts a to a .
15 | ///
16 | /// The value to convert.
17 | public static implicit operator uint(RVO value) => value.Value;
18 |
19 | ///
20 | /// Converts a to a .
21 | ///
22 | /// The value to convert.
23 | public static implicit operator RVO(uint value) => new(value);
24 |
25 | ///
26 | public override string ToString() => $"0x{Value:X}";
27 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/VA32.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a 32-bit virtual address.
9 | ///
10 | public record struct VA32(uint Value)
11 | {
12 | ///
13 | /// Implicitly converts a to a .
14 | ///
15 | /// The value to convert.
16 | /// The converted value.
17 | public static implicit operator uint(VA32 value) => value.Value;
18 |
19 | ///
20 | /// Implicitly converts a to a .
21 | ///
22 | /// The value to convert.
23 | /// The converted value.
24 | public static implicit operator VA32(uint value) => new(value);
25 |
26 | ///
27 | /// Gets a value indicating whether the is null (value is 0).
28 | ///
29 | public bool IsNull => Value == 0;
30 |
31 | ///
32 | /// Returns a string representation of the value.
33 | ///
34 | /// A string representation of the value.
35 | public override string ToString() => $"0x{Value:X}";
36 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/PE/VA64.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | namespace LibObjectFile.PE;
6 |
7 | ///
8 | /// Represents a 64-bit virtual address.
9 | ///
10 | public record struct VA64(ulong Value)
11 | {
12 | ///
13 | /// Implicitly converts a to a .
14 | ///
15 | /// The value to convert.
16 | /// The converted value.
17 | public static implicit operator ulong(VA64 value) => value.Value;
18 |
19 | ///
20 | /// Implicitly converts a to a .
21 | ///
22 | /// The value to convert.
23 | /// The converted value.
24 | public static implicit operator VA64(ulong value) => new(value);
25 |
26 | ///
27 | /// Gets a value indicating whether the is null (value is 0).
28 | ///
29 | public bool IsNull => Value == 0;
30 |
31 | ///
32 | /// Returns a string representation of the value.
33 | ///
34 | /// A string representation of the value.
35 | public override string ToString() => $"0x{Value:X}";
36 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/Utils/DataUtils.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace LibObjectFile.Utils;
8 |
9 | internal static class DataUtils
10 | {
11 | public static int ReadAt(ReadOnlySpan source, uint offset, Span destination)
12 | {
13 | ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(offset, (uint)source.Length);
14 |
15 | var lengthToCopy = Math.Min(source.Length - (int)offset, destination.Length);
16 | source.Slice((int)offset, lengthToCopy).CopyTo(destination);
17 |
18 | return lengthToCopy;
19 | }
20 |
21 | public static unsafe void WriteAt(Span destination, uint offset, ReadOnlySpan source)
22 | {
23 | ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(offset, (uint)destination.Length);
24 |
25 | if (source.Length > (destination.Length - (int)offset))
26 | {
27 | throw new ArgumentOutOfRangeException(nameof(source), $"The source buffer is too large to fit at the offset {offset} in the destination buffer");
28 | }
29 |
30 | source.CopyTo(destination.Slice((int)offset, source.Length));
31 | }
32 | }
--------------------------------------------------------------------------------
/src/LibObjectFile/VisitorContextBase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // This file is licensed under the BSD-Clause 2 license.
3 | // See the license.txt file in the project root for more information.
4 |
5 | using LibObjectFile.Diagnostics;
6 | using System.IO;
7 |
8 | namespace LibObjectFile;
9 |
10 | ///
11 | /// Base class used for layout-ing an object file.
12 | ///
13 | /// The root object file.
14 | /// The diagnostics.
15 | public abstract class VisitorContextBase(ObjectFileElement file, DiagnosticBag diagnostics)
16 | {
17 | public ObjectFileElement File { get; } = file;
18 |
19 |
20 | public DiagnosticBag Diagnostics { get; } = diagnostics;
21 |
22 |
23 | public bool HasErrors => Diagnostics.HasErrors;
24 |
25 | public TextWriter? DebugLog { get; set; }
26 | }
27 |
28 | ///
29 | /// Base class used for layout-ing an object file.
30 | ///
31 | /// The type of the object file.
32 | /// The root object file.
33 | /// The diagnostics.
34 | public abstract class VisitorContextBase(TFile file, DiagnosticBag diagnostics) : VisitorContextBase(file, diagnostics)
35 | where TFile : ObjectFileElement
36 | {
37 | public new TFile File => (TFile)base.File;
38 | }
--------------------------------------------------------------------------------
/src/dotnet-releaser.toml:
--------------------------------------------------------------------------------
1 | # configuration file for dotnet-releaser
2 | [msbuild]
3 | project = "LibObjectFile.sln"
4 | build_debug = true
5 | [test]
6 | run_tests_for_debug = true
7 | [github]
8 | user = "xoofx"
9 | repo = "LibObjectFile"
10 |
--------------------------------------------------------------------------------
/src/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.100",
4 | "rollForward": "latestMinor",
5 | "allowPrerelease": false
6 | }
7 | }
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeConsole2Win64/NativeConsole2Win64.cpp:
--------------------------------------------------------------------------------
1 | // NativeConsole2Win64.cpp : This file contains the 'main' function. Program execution begins and ends there.
2 | //
3 |
4 | #include
5 |
6 | extern "C"
7 | {
8 | __declspec(dllimport) int __cdecl HelloWorld(int a, int b);
9 | __declspec(dllexport) int __cdecl AnotherFunction();
10 | }
11 |
12 | int main()
13 | {
14 | std::cout << "HelloWorld " << HelloWorld(1 + AnotherFunction(), 2) << std::endl;
15 | }
16 |
17 | // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
18 | // Debug program: F5 or Debug > Start Debugging menu
19 |
20 | // Tips for Getting Started:
21 | // 1. Use the Solution Explorer window to add/manage files
22 | // 2. Use the Team Explorer window to connect to source control
23 | // 3. Use the Output window to see build output and other messages
24 | // 4. Use the Error List window to view errors
25 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
26 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
27 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeConsole2Win64/NativeConsole2Win64.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeConsoleWin64/NativeConsoleWin64.cpp:
--------------------------------------------------------------------------------
1 | // NativeConsoleWin64.cpp : This file contains the 'main' function. Program execution begins and ends there.
2 | //
3 |
4 | #include
5 |
6 | int main()
7 | {
8 | std::cout << "Hello World!\n";
9 | }
10 |
11 | // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
12 | // Debug program: F5 or Debug > Start Debugging menu
13 |
14 | // Tips for Getting Started:
15 | // 1. Use the Solution Explorer window to add/manage files
16 | // 2. Use the Team Explorer window to connect to source control
17 | // 3. Use the Output window to see build output and other messages
18 | // 4. Use the Error List window to view errors
19 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
20 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
21 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeConsoleWin64/NativeConsoleWin64.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeLibraryWin64/NativeLibraryWin64.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 |
26 |
27 | Source Files
28 |
29 |
30 | Source Files
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeLibraryWin64/dllmain.cpp:
--------------------------------------------------------------------------------
1 | // dllmain.cpp : Defines the entry point for the DLL application.
2 | #include "pch.h"
3 |
4 | BOOL APIENTRY DllMain( HMODULE hModule,
5 | DWORD ul_reason_for_call,
6 | LPVOID lpReserved
7 | )
8 | {
9 | switch (ul_reason_for_call)
10 | {
11 | case DLL_PROCESS_ATTACH:
12 | case DLL_THREAD_ATTACH:
13 | case DLL_THREAD_DETACH:
14 | case DLL_PROCESS_DETACH:
15 | break;
16 | }
17 | return TRUE;
18 | }
19 |
20 |
21 | extern "C"
22 | {
23 | __declspec(dllexport) int __cdecl HelloWorld(int a, int b)
24 | {
25 | return a + b;
26 | }
27 |
28 | __declspec(dllexport) int __cdecl AnotherFunction()
29 | {
30 | return 123;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeLibraryWin64/framework.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
4 | // Windows Header Files
5 | #include
6 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeLibraryWin64/pch.cpp:
--------------------------------------------------------------------------------
1 | // pch.cpp: source file corresponding to the pre-compiled header
2 |
3 | #include "pch.h"
4 |
5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
6 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/NativeLibraryWin64/pch.h:
--------------------------------------------------------------------------------
1 | // pch.h: This is a precompiled header file.
2 | // Files listed below are compiled only once, improving build performance for future builds.
3 | // This also affects IntelliSense performance, including code completion and many code browsing features.
4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds.
5 | // Do not add files here that you will be updating frequently as this negates the performance advantage.
6 |
7 | #ifndef PCH_H
8 | #define PCH_H
9 |
10 | // add headers that you want to pre-compile here
11 | #include "framework.h"
12 |
13 | #endif //PCH_H
14 |
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/RawNativeConsoleWin64/RawNativeConsoleWin64.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void mainCRTStartup(void)
4 | {
5 | ExitProcess(156);
6 | }
--------------------------------------------------------------------------------
/src/native/Win64/NativeProjects/RawNativeConsoleWin64/RawNativeConsoleWin64.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/objdasm/objdasm.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | LibObjectFile.Disasm
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/test-with-docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export TEST_TAG_NAME=libobjectfile-tests
4 |
5 | # To rebuild the image, simply delete the tag:
6 | # docker rmi $TEST_TAG_NAME
7 |
8 | if [[ "$(docker images -q ${TEST_TAG_NAME}:latest 2> /dev/null)" == "" ]]; then
9 | docker build -t ${TEST_TAG_NAME} .
10 | fi
11 |
12 | # Run unit tests in Docker - See Dockerfile
13 | docker run -v `pwd`:/src --rm -it ${TEST_TAG_NAME}
14 |
15 |
--------------------------------------------------------------------------------