mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-18 00:38:31 +00:00
COFF: Move machine type auto-detection to SymbolTable.
The new mechanism is less code, and fixes the case where all inputs are archives. Differential Revision: http://reviews.llvm.org/D10136 llvm-svn: 238618
This commit is contained in:
parent
4d37b2a259
commit
246ccc5f51
@ -87,24 +87,6 @@ std::string findFile(StringRef Filename) {
|
||||
return Filename;
|
||||
}
|
||||
|
||||
// Peeks at the file header to get architecture (e.g. i386 or AMD64).
|
||||
// Returns "unknown" if it's not a valid object file.
|
||||
static MachineTypes getFileMachineType(StringRef Path) {
|
||||
file_magic Magic;
|
||||
if (identify_magic(Path, Magic))
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
if (Magic != file_magic::coff_object)
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path);
|
||||
if (BufOrErr.getError())
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
std::error_code EC;
|
||||
llvm::object::COFFObjectFile Obj(BufOrErr.get()->getMemBufferRef(), EC);
|
||||
if (EC)
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
return static_cast<MachineTypes>(Obj.getMachine());
|
||||
}
|
||||
|
||||
// Returns /machine's value.
|
||||
ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args) {
|
||||
if (auto *Arg = Args->getLastArg(OPT_machine)) {
|
||||
@ -118,13 +100,6 @@ ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args) {
|
||||
return make_dynamic_error_code("unknown /machine argument" + S);
|
||||
return MT;
|
||||
}
|
||||
// If /machine option is missing, we need to take a look at
|
||||
// the magic byte of the first object file to infer machine type.
|
||||
for (auto *Arg : Args->filtered(OPT_INPUT)) {
|
||||
MachineTypes MT = getFileMachineType(Arg->getValue());
|
||||
if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
|
||||
return MT;
|
||||
}
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,9 @@ public:
|
||||
// order to create the import descriptor table.
|
||||
std::vector<std::unique_ptr<ImportFile>> ImportFiles;
|
||||
|
||||
// The writer needs to infer the machine type from the object files.
|
||||
std::vector<std::unique_ptr<ObjectFile>> ObjectFiles;
|
||||
|
||||
private:
|
||||
std::error_code addObject(ObjectFile *File);
|
||||
std::error_code addArchive(ArchiveFile *File);
|
||||
@ -63,7 +66,6 @@ private:
|
||||
void addInitialSymbol(SymbolBody *Body);
|
||||
|
||||
std::unordered_map<StringRef, Symbol *> Symtab;
|
||||
std::vector<std::unique_ptr<ObjectFile>> ObjectFiles;
|
||||
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
|
||||
std::vector<std::unique_ptr<SymbolBody>> OwnedSymbols;
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
|
@ -227,6 +227,17 @@ void Writer::assignAddresses() {
|
||||
RoundUpToAlignment(FileOff - SizeOfHeaders, FileAlignment);
|
||||
}
|
||||
|
||||
static MachineTypes
|
||||
inferMachineType(std::vector<std::unique_ptr<ObjectFile>> &ObjectFiles) {
|
||||
for (std::unique_ptr<ObjectFile> &File : ObjectFiles) {
|
||||
// Try to infer machine type from the magic byte of the object file.
|
||||
auto MT = static_cast<MachineTypes>(File->getCOFFObj()->getMachine());
|
||||
if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
|
||||
return MT;
|
||||
}
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
}
|
||||
|
||||
void Writer::writeHeader() {
|
||||
// Write DOS stub
|
||||
uint8_t *Buf = Buffer->getBufferStart();
|
||||
@ -241,10 +252,15 @@ void Writer::writeHeader() {
|
||||
memcpy(Buf, PEMagic, sizeof(PEMagic));
|
||||
Buf += sizeof(PEMagic);
|
||||
|
||||
// Determine machine type, infer if needed. TODO: diagnose conflicts.
|
||||
MachineTypes MachineType = Config->MachineType;
|
||||
if (MachineType == IMAGE_FILE_MACHINE_UNKNOWN)
|
||||
MachineType = inferMachineType(Symtab->ObjectFiles);
|
||||
|
||||
// Write COFF header
|
||||
auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
|
||||
Buf += sizeof(*COFF);
|
||||
COFF->Machine = Config->MachineType;
|
||||
COFF->Machine = MachineType;
|
||||
COFF->NumberOfSections = OutputSections.size();
|
||||
COFF->Characteristics =
|
||||
(IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED |
|
||||
|
BIN
lld/test/COFF/Inputs/ret42.lib
Normal file
BIN
lld/test/COFF/Inputs/ret42.lib
Normal file
Binary file not shown.
@ -1,6 +1,15 @@
|
||||
# RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \
|
||||
# RUN: %p/Inputs/ret42.obj
|
||||
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
|
||||
# RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \
|
||||
# RUN: %p/Inputs/ret42.lib
|
||||
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
|
||||
# RUN: lld -flavor link2 /entry:main /out:%t.exe \
|
||||
# RUN: %p/Inputs/ret42.obj
|
||||
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
|
||||
# RUN: lld -flavor link2 /entry:main /out:%t.exe \
|
||||
# RUN: %p/Inputs/ret42.lib
|
||||
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
|
||||
|
||||
AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user