Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/Readers/BinaryFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ eld::Expected<void> BinaryFileParser::parseFile(InputFile &inputFile) {
ObjectFile *objFile = llvm::cast<ObjectFile>(&inputFile);
objFile->addSection(S);
addDescriptionSymbols(inputFile, S);
// Binary files carry no architecture flags. Explicitly set flags to 0.
if (m_Module.getLinker()->getBackend())
m_Module.getBackend().getInfo().checkFlags(0, &inputFile, false);
return {};
}

Expand Down
18 changes: 18 additions & 0 deletions lib/Target/ARM/ARMInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,21 @@ bool ARMInfo::InitializeDefaultMappings(Module &pModule) {
}

std::string ARMInfo::flagString(uint64_t flag) const { return "arm"; }

uint64_t ARMInfo::flags() const {
// checkFlags() was never called. This means the linker was given a lone empty
// .o file or a lone symdef file, etc. In either case, we want the result to
// have flags.
if (!OutputFlags)
return llvm::ELF::EF_ARM_EABI_VER5;
assert(*OutputFlags == 0 || *OutputFlags == llvm::ELF::EF_ARM_EABI_VER5);
return *OutputFlags;
}

bool ARMInfo::checkFlags(uint64_t Flags, const InputFile *I, bool) const {
if (!OutputFlags && Flags == 0 && I->isBinaryFile())
OutputFlags = Flags;
else
OutputFlags = llvm::ELF::EF_ARM_EABI_VER5;
return true;
}
7 changes: 6 additions & 1 deletion lib/Target/ARM/ARMInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ARMInfo : public TargetInfo {
: 0x4;
}

uint64_t flags() const override { return llvm::ELF::EF_ARM_EABI_VER5; }
uint64_t flags() const override;

uint64_t startAddr(bool linkerScriptHasSectionsCommand, bool isDynExec,
bool loadPhdr) const override {
Expand Down Expand Up @@ -81,6 +81,11 @@ class ARMInfo : public TargetInfo {
m_Config.options().setWarnMismatch(false);
}
}

bool checkFlags(uint64_t Flag, const InputFile *I, bool) const override;

private:
mutable std::optional<uint64_t> OutputFlags;
};

} // namespace eld
Expand Down
12 changes: 9 additions & 3 deletions lib/Target/Hexagon/HexagonInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ bool HexagonInfo::initialize() {
return false;
}

m_OutputFlag = m_CmdLineFlag;

return true;
}

Expand Down Expand Up @@ -255,8 +253,14 @@ HexagonInfo::ArchSupport HexagonInfo::getArchSupport(uint64_t pFlag) const {

bool HexagonInfo::checkFlags(uint64_t pFlag, const InputFile *pInputFile,
bool) const {
if (!pFlag)
if (!pFlag) {
if (pInputFile->isBinaryFile())
ZeroFlagsOK = true;
return true;
}

if (m_CmdLineFlag != LINK_UNKNOWN)
m_OutputFlag = m_CmdLineFlag;

HexagonInfo::ArchSupport archSupport = getArchSupport(pFlag);

Expand Down Expand Up @@ -310,6 +314,8 @@ bool HexagonInfo::checkFlags(uint64_t pFlag, const InputFile *pInputFile,

/// flags - the value of ElfXX_Ehdr::e_flags
uint64_t HexagonInfo::flags() const {
if (m_OutputFlag == LINK_UNKNOWN && ZeroFlagsOK)
return 0;
int32_t OutputFlag = m_OutputFlag;
if (m_CmdLineFlag != LINK_UNKNOWN) {
if (OutputFlag == LINK_UNKNOWN)
Expand Down
1 change: 1 addition & 0 deletions lib/Target/Hexagon/HexagonInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class HexagonInfo : public TargetInfo {
private:
int32_t m_CmdLineFlag;
mutable int32_t m_OutputFlag;
mutable bool ZeroFlagsOK = false;
};

} // namespace eld
Expand Down
38 changes: 15 additions & 23 deletions lib/Target/RISCV/RISCVInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

using namespace eld;

#define UNKNOWN -1

std::string RISCVInfo::flagString(uint64_t flag) const {
#define INTOEFLAGSTR(ns, enum, str) \
if ((flag & ns::enum) == ns::enum) { \
Expand All @@ -36,9 +34,7 @@ llvm::StringRef RISCVInfo::getOutputMCPU() const {
//===----------------------------------------------------------------------===//
// RISCVInfo
//===----------------------------------------------------------------------===//
RISCVInfo::RISCVInfo(LinkerConfig &pConfig) : TargetInfo(pConfig) {
m_OutputFlag = UNKNOWN;
}
RISCVInfo::RISCVInfo(LinkerConfig &pConfig) : TargetInfo(pConfig) {}

uint64_t RISCVInfo::translateFlag(uint64_t pFlag) const { return pFlag; }

Expand All @@ -49,34 +45,35 @@ bool RISCVInfo::isABIFlagSet(uint64_t inputFlag, uint32_t ABIFlag) const {
}

bool RISCVInfo::isCompatible(uint64_t pFlag, const std::string &pFile) const {
assert(m_OutputFlag);
if (isABIFlagSet(pFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SOFT) ^
isABIFlagSet(m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SOFT)) {
isABIFlagSet(*m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SOFT)) {
m_Config.raise(Diag::incompatible_architecture_versions)
<< flagString(pFlag) << pFile << flagString(m_OutputFlag);
<< flagString(pFlag) << pFile << flagString(*m_OutputFlag);
return false;
}
if (isABIFlagSet(pFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ^
isABIFlagSet(m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)) {
isABIFlagSet(*m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)) {
m_Config.raise(Diag::incompatible_architecture_versions)
<< flagString(pFlag) << pFile << flagString(m_OutputFlag);
<< flagString(pFlag) << pFile << flagString(*m_OutputFlag);
return false;
}
if (isABIFlagSet(pFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ^
isABIFlagSet(m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)) {
isABIFlagSet(*m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)) {
m_Config.raise(Diag::incompatible_architecture_versions)
<< flagString(pFlag) << pFile << flagString(m_OutputFlag);
<< flagString(pFlag) << pFile << flagString(*m_OutputFlag);
return false;
}
if (isABIFlagSet(pFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ^
isABIFlagSet(m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)) {
isABIFlagSet(*m_OutputFlag, llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)) {
m_Config.raise(Diag::incompatible_architecture_versions)
<< flagString(pFlag) << pFile << flagString(m_OutputFlag);
<< flagString(pFlag) << pFile << flagString(*m_OutputFlag);
return false;
}
if ((pFlag & llvm::ELF::EF_RISCV_RVE) ^
(m_OutputFlag & llvm::ELF::EF_RISCV_RVE)) {
(*m_OutputFlag & llvm::ELF::EF_RISCV_RVE)) {
m_Config.raise(Diag::incompatible_architecture_versions)
<< flagString(pFlag) << pFile << flagString(m_OutputFlag);
<< flagString(pFlag) << pFile << flagString(*m_OutputFlag);
return false;
}
return true;
Expand All @@ -85,28 +82,23 @@ bool RISCVInfo::isCompatible(uint64_t pFlag, const std::string &pFile) const {
bool RISCVInfo::checkFlags(uint64_t flag, const InputFile *pInputFile,
bool hasExecutableSections) const {
// If flag is empty and no executable sections found in the ELF file
// skip checking for compatibility
// skip checking for compatibility.
if (!flag && !hasExecutableSections)
return true;

// Choose the default architecture from the input files, only if mcpu option
// is not specified on the command line.
if (m_OutputFlag == UNKNOWN)
if (!m_OutputFlag)
m_OutputFlag = flag;

if (!isCompatible(flag, pInputFile->getInput()->decoratedPath()))
return false;

m_OutputFlag |= flag;
*m_OutputFlag |= flag;

InputFlags[pInputFile] = flag;

return true;
}

/// flags - the value of ElfXX_Ehdr::e_flags
uint64_t RISCVInfo::flags() const { return m_OutputFlag; }

uint8_t RISCVInfo::OSABI() const { return llvm::ELF::ELFOSABI_NONE; }

bool RISCVInfo::InitializeDefaultMappings(Module &pModule) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/RISCV/RISCVInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RISCVInfo : public TargetInfo {
std::string getMachineStr() const override { return "RISC-V"; }

/// flags - the value of ElfXX_Ehdr::e_flags
uint64_t flags() const override;
uint64_t flags() const override { return m_OutputFlag ? *m_OutputFlag : 0; }

uint8_t OSABI() const override;

Expand Down Expand Up @@ -53,7 +53,7 @@ class RISCVInfo : public TargetInfo {

private:
uint64_t translateFlag(uint64_t pFlag) const;
mutable int64_t m_OutputFlag;
mutable std::optional<uint64_t> m_OutputFlag;
mutable llvm::DenseMap<const InputFile *, uint64_t> InputFlags;
};

Expand Down
1 change: 1 addition & 0 deletions test/ARM/standalone/EFlags/Inputs/1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int foo() {return 0;}
11 changes: 11 additions & 0 deletions test/ARM/standalone/EFlags/Inputs/binary.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#---binary.test--------------------- Executable---------------------#
#BEGIN_COMMENT
# Checks output flags are set when there is a binary input
# combined with an object input.
#END_COMMENT
#START_TEST
RUN: %link %emulation %linkopts --format=binary %s -o %t.out
RUN: %readelf -h %t.out | %filecheck %s
#END_TEST

CHECK: Flags: 0x0
12 changes: 12 additions & 0 deletions test/ARM/standalone/EFlags/binaryflags.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#---binaryflags.test--------------------- Executable---------------------#
#BEGIN_COMMENT
# Checks output flags are set for a link that has a binary file
# and object file.
#END_COMMENT
#START_TEST
RUN: %clang -c %clangopts %p/Inputs/1.c -o %t.o
RUN: %link %emulation %linkopts %t.o --format=binary %s -o %t.out
RUN: %readelf -h %t.out | %filecheck %s
#END_TEST

CHECK: Flags: 0x5000000
10 changes: 10 additions & 0 deletions test/Common/standalone/BinaryFormatInputFiles/flags.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#---flags.test--------------------- Executable---------------------#
#BEGIN_COMMENT
# Checks output flags are 0 for binary inputs
#END_COMMENT
#START_TEST
RUN: %link %emulation %linkopts --format=binary %s -o %t.out
RUN: %readelf -h %t.out | %filecheck %s
#END_TEST

CHECK: Flags: 0x0
1 change: 1 addition & 0 deletions test/Hexagon/standalone/EFlags/Inputs/1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int foo() {return 0;}
12 changes: 12 additions & 0 deletions test/Hexagon/standalone/EFlags/binaryflags.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#---binaryflags.test--------------------- Executable---------------------#
#BEGIN_COMMENT
# Checks output flags are set for a link that has a binary file
# and object file.
#END_COMMENT
#START_TEST
RUN: %clang -c %clangopts %p/Inputs/1.c -o %t.o
RUN: %link -mv75 %linkopts %t.o --format=binary %s -o %t.out
RUN: %readelf -h %t.out | %filecheck %s
#END_TEST

CHECK: Flags: 0x75

This file was deleted.

11 changes: 0 additions & 11 deletions test/Hexagon/standalone/Elfcopy/ObjCopyBinary/ObjCopyBinary.test

This file was deleted.

Loading