From a685ddf1d104b3ce9d53cf420521f5aaff429630 Mon Sep 17 00:00:00 2001 From: Amilendra Kodithuwakku Date: Wed, 21 Jun 2023 16:10:08 +0100 Subject: [PATCH] Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support" MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This reverts commit c4fea3905617af89d1ad87319893e250f5b72dd6. I am reverting this for now until I figure out how to fix the build bot errors and warnings. Errors: llvm-project/lld/ELF/Arch/ARM.cpp:1300:29: error: expected primary-expression before ‘>’ token osec->writeHeaderTo(++sHdrs); Warnings: llvm-project/lld/ELF/Arch/ARM.cpp:1306:31: warning: left operand of comma operator has no effect [-Wunused-value] --- lld/ELF/Arch/ARM.cpp | 410 ---------------------------------- lld/ELF/Config.h | 5 - lld/ELF/Driver.cpp | 30 --- lld/ELF/InputFiles.cpp | 21 +- lld/ELF/InputFiles.h | 10 - lld/ELF/LinkerScript.cpp | 9 - lld/ELF/LinkerScript.h | 1 - lld/ELF/MarkLive.cpp | 4 - lld/ELF/Options.td | 12 - lld/ELF/SymbolTable.h | 17 -- lld/ELF/SyntheticSections.cpp | 1 - lld/ELF/SyntheticSections.h | 46 ---- lld/ELF/Target.h | 3 - lld/ELF/Writer.cpp | 10 - lld/test/ELF/Inputs/arm-cmse-macros.s | 32 --- lld/test/ELF/aarch64-cmse.s | 16 -- lld/test/ELF/arm-cmse-diagnostics.s | 281 ----------------------- lld/test/ELF/arm-cmse-implib.s | 114 ---------- lld/test/ELF/arm-cmse-keep-sections.s | 55 ----- lld/test/ELF/arm-cmse-noveneers.s | 30 --- lld/test/ELF/arm-cmse-secure.s | 68 ------ lld/test/ELF/arm-cmse-veneers.s | 42 ---- 22 files changed, 2 insertions(+), 1215 deletions(-) delete mode 100644 lld/test/ELF/Inputs/arm-cmse-macros.s delete mode 100644 lld/test/ELF/aarch64-cmse.s delete mode 100644 lld/test/ELF/arm-cmse-diagnostics.s delete mode 100644 lld/test/ELF/arm-cmse-implib.s delete mode 100644 lld/test/ELF/arm-cmse-keep-sections.s delete mode 100644 lld/test/ELF/arm-cmse-noveneers.s delete mode 100644 lld/test/ELF/arm-cmse-secure.s delete mode 100644 lld/test/ELF/arm-cmse-veneers.s diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 93e999f..79635a2 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -6,14 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "InputFiles.h" -#include "OutputSections.h" -#include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "lld/Common/ErrorHandler.h" -#include "lld/Common/Filesystem.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Endian.h" @@ -23,7 +19,6 @@ using namespace llvm::support; using namespace llvm::ELF; using namespace lld; using namespace lld::elf; -using namespace llvm::object; namespace { class ARM final : public TargetInfo { @@ -915,413 +910,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const { } } -// The Arm Cortex-M Security Extensions (CMSE) splits a system into two parts; -// the non-secure and secure states with the secure state inaccessible from the -// non-secure state, apart from an area of memory in secure state called the -// secure gateway which is accessible from non-secure state. The secure gateway -// contains one or more entry points which must start with a landing pad -// instruction SG. Arm recommends that the secure gateway consists only of -// secure gateway veneers, which are made up of a SG instruction followed by a -// branch to the destination in secure state. Full details can be found in Arm -// v8-M Security Extensions Requirements on Development Tools. -// -// The CMSE model of software development requires the non-secure and secure -// states to be developed as two separate programs. The non-secure developer is -// provided with an import library defining symbols describing the entry points -// in the secure gateway. No additional linker support is required for the -// non-secure state. -// -// Development of the secure state requires linker support to manage the secure -// gateway veneers. The management consists of: -// - Creation of new secure gateway veneers based on symbol conventions. -// - Checking the address of existing secure gateway veneers. -// - Warning when existing secure gateway veneers removed. -// -// The secure gateway veneers are created in an import library, which is just an -// ELF object with a symbol table. The import library is controlled by two -// command line options: -// --in-implib (specify an input import library from a previous revision of the -// program). -// --out-implib (specify an output import library to be created by the linker). -// -// The input import library is used to manage consistency of the secure entry -// points. The output import library is for new and updated secure entry points. -// -// The symbol convention that identifies secure entry functions is the prefix -// __acle_se_ for a symbol called name the linker is expected to create a secure -// gateway veneer if symbols __acle_se_name and name have the same address. -// After creating a secure gateway veneer the symbol name labels the secure -// gateway veneer and the __acle_se_name labels the function definition. -// -// The LLD implementation: -// - Reads an existing import library with importCmseSymbols(). -// - Determines which new secure gateway veneers to create and redirects calls -// within the secure state to the __acle_se_ prefixed symbol with -// processArmCmseSymbols(). -// - Models the SG veneers as a synthetic section. - -// Initialize symbols. symbols is a parallel array to the corresponding ELF -// symbol table. -template void ObjFile::importCmseSymbols() { - ArrayRef eSyms = getELFSyms(); - // Error for local symbols. The symbol at index 0 is LOCAL. So skip it. - for (size_t i = 1, end = firstGlobal; i != end; ++i) { - errorOrWarn("CMSE symbol '" + CHECK(eSyms[i].getName(stringTable), this) + - "' in import library '" + toString(this) + "' is not global"); - } - - for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { - const Elf_Sym &eSym = eSyms[i]; - Defined *sym = reinterpret_cast(make()); - - // Initialize symbol fields. - memset(sym, 0, sizeof(Symbol)); - sym->setName(CHECK(eSyms[i].getName(stringTable), this)); - sym->value = eSym.st_value; - sym->size = eSym.st_size; - sym->type = eSym.getType(); - sym->binding = eSym.getBinding(); - sym->stOther = eSym.st_other; - - if (eSym.st_shndx != SHN_ABS) { - error("CMSE symbol '" + sym->getName() + "' in import library '" + - toString(this) + "' is not absolute"); - continue; - } - - if (!(eSym.st_value & 1) || (eSym.getType() != STT_FUNC)) { - error("CMSE symbol '" + sym->getName() + "' in import library '" + - toString(this) + "' is not a Thumb function definition"); - continue; - } - - if (symtab.cmseImportLib.count(sym->getName())) { - error("CMSE symbol '" + sym->getName() + - "' is multiply defined in import library '" + toString(this) + "'"); - continue; - } - - if (eSym.st_size != ACLESESYM_SIZE) { - warn("CMSE symbol '" + sym->getName() + "' in import library '" + - toString(this) + "' does not have correct size of " + - Twine(ACLESESYM_SIZE) + " bytes"); - } - - symtab.cmseImportLib[sym->getName()] = sym; - } -} - -// Check symbol attributes of the acleSeSym, sym pair. -// Both symbols should be global/weak Thumb code symbol definitions. -static std::string checkCmseSymAttributes(Symbol *acleSeSym, Symbol *sym) { - auto check = [](Symbol *s, StringRef type) -> std::optional { - auto d = dyn_cast_or_null(s); - if (!(d && d->isFunc() && (d->value & 1))) - return (Twine(toString(s->file)) + ": cmse " + type + " symbol '" + - s->getName() + "' is not a Thumb function definition") - .str(); - if (!d->section) - return (Twine(toString(s->file)) + ": cmse " + type + " symbol '" + - s->getName() + "' cannot be an absolute symbol") - .str(); - return std::nullopt; - }; - for (auto [sym, type] : - {std::make_pair(acleSeSym, "special"), std::make_pair(sym, "entry")}) - if (auto err = check(sym, type)) - return *err; - return ""; -} - -// Look for [__acle_se_, ] pairs, as specified in the Cortex-M -// Security Extensions specification. -// 1) : A standard function name. -// 2) __acle_se_ : A special symbol that prefixes the standard function -// name with __acle_se_. -// Both these symbols are Thumb function symbols with external linkage. -// may be redefined in .gnu.sgstubs. -void elf::processArmCmseSymbols() { - if (!config->cmseImplib) - return; - // Only symbols with external linkage end up in symtab, so no need to do - // linkage checks. Only check symbol type. - for (Symbol *acleSeSym : symtab.getSymbols()) { - if (!acleSeSym->getName().startswith(ACLESESYM_PREFIX)) - continue; - // If input object build attributes do not support CMSE, error and disable - // further scanning for , __acle_se_ pairs. - if (!config->armCMSESupport) { - error("CMSE is only supported by ARMv8-M architecture or later"); - config->cmseImplib = false; - break; - } - - // Try to find the associated symbol definition. - // Symbol must have external linkage. - StringRef name = acleSeSym->getName().substr(std::strlen(ACLESESYM_PREFIX)); - Symbol *sym = symtab.find(name); - if (!sym) { - error(toString(acleSeSym->file) + ": cmse special symbol '" + - acleSeSym->getName() + - "' detected, but no associated entry function definition '" + name + - "' with external linkage found"); - continue; - } - - std::string errMsg = checkCmseSymAttributes(acleSeSym, sym); - if (!errMsg.empty()) { - error(errMsg); - continue; - } - - // may be redefined later in the link in .gnu.sgstubs - symtab.cmseSymMap[name] = {acleSeSym, sym}; - } - - // If this is an Arm CMSE secure app, replace references to entry symbol - // with its corresponding special symbol __acle_se_. - parallelForEach(ctx.objectFiles, [&](InputFile *file) { - MutableArrayRef syms = file->getMutableSymbols(); - for (size_t i = 0, e = syms.size(); i != e; ++i) { - StringRef symName = syms[i]->getName(); - if (symtab.cmseSymMap.count(symName)) - syms[i] = symtab.cmseSymMap[symName].acleSeSym; - } - }); -} - -ArmCmseSGSection::ArmCmseSGSection() - : SyntheticSection(llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, - llvm::ELF::SHT_PROGBITS, - /*alignment=*/32, ".gnu.sgstubs") { - entsize = ACLESESYM_SIZE; - // The range of addresses used in the CMSE import library should be fixed. - for (auto &[_, sym] : symtab.cmseImportLib) { - if (impLibMaxAddr <= sym->value) - impLibMaxAddr = sym->value + sym->size; - } - if (symtab.cmseSymMap.empty()) - return; - addMappingSymbol(); - for (auto &[_, entryFunc] : symtab.cmseSymMap) - addSGVeneer(cast(entryFunc.acleSeSym), - cast(entryFunc.sym)); - for (auto &[_, sym] : symtab.cmseImportLib) { - if (!symtab.inCMSEOutImpLib.count(sym->getName())) - warn("entry function '" + sym->getName() + - "' from CMSE import library is not present in secure application"); - } - - if (!symtab.cmseImportLib.empty() && config->cmseOutputLib.empty()) { - for (auto &[_, entryFunc] : symtab.cmseSymMap) { - Symbol *sym = entryFunc.sym; - if (!symtab.inCMSEOutImpLib.count(sym->getName())) - warn("new entry function '" + sym->getName() + - "' introduced but no output import library specified"); - } - } -} - -void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) { - entries.emplace_back(acleSeSym, sym); - if (symtab.cmseImportLib.count(sym->getName())) - symtab.inCMSEOutImpLib[sym->getName()] = true; - // Symbol addresses different, nothing to do. - if (acleSeSym->file != sym->file || - cast(*acleSeSym).value != cast(*sym).value) - return; - // Only secure symbols with values equal to that of it's non-secure - // counterpart needs to be in the .gnu.sgstubs section. - ArmCmseSGVeneer *ss = nullptr; - if (symtab.cmseImportLib.count(sym->getName())) { - Defined *impSym = symtab.cmseImportLib[sym->getName()]; - ss = make(sym, acleSeSym, impSym->value); - } else { - ss = make(sym, acleSeSym); - ++newEntries; - } - ss->parent = this; - sgSections.emplace_back(ss); -} - -void ArmCmseSGSection::writeTo(uint8_t *buf) { - for (ArmCmseSGVeneer *s : sgSections) - s->writeTo(buf + s->outSecOff - getVA()); -} - -void ArmCmseSGSection::addMappingSymbol() { - addSyntheticLocal("$t", STT_NOTYPE, /*off=*/0, /*size=*/0, *this); -} - -size_t ArmCmseSGSection::getSize() const { - if (sgSections.empty()) - return (impLibMaxAddr ? impLibMaxAddr - getVA() : 0) + newEntries * entsize; - - return entries.size() * entsize; -} - -void ArmCmseSGSection::finalizeContents() { - if (sgSections.empty()) - return; - - auto it = - std::stable_partition(sgSections.begin(), sgSections.end(), - [](auto *i) { return i->getAddr().has_value(); }); - std::sort(sgSections.begin(), it, [](auto *a, auto *b) { - return a->getAddr().value() < b->getAddr().value(); - }); - - // This is the partition of the veneers with fixed addresses. - uint64_t addr = (*sgSections.begin())->getAddr().has_value() - ? (*sgSections.begin())->getAddr().value() - : getVA(); - // Check if the start address of '.gnu.sgstubs' correspond to the - // linker-synthesized veneer with the lowest address. - if ((getVA() & ~1) != (addr & ~1)) { - error("start address of '.gnu.sgstubs' is different from previous link"); - return; - } - - for (ArmCmseSGVeneer *s : sgSections) { - if (!s->getAddr().has_value()) - break; - s->outSecOff = s->getAddr().value() & ~1; - Defined(s->file, StringRef(), s->sym->binding, s->sym->stOther, - s->sym->type, (s->outSecOff - getVA()) | 1, entsize, this) - .overwrite(*s->sym); - } - // This is the partition of veneers newly synthesized by the linker. - size_t off = std::max(getVA(), impLibMaxAddr); - for (ArmCmseSGVeneer *s : llvm::reverse(sgSections)) { - if (s->getAddr().has_value()) - break; - s->outSecOff = off & ~1; - Defined(s->file, StringRef(), s->sym->binding, s->sym->stOther, - s->sym->type, (s->outSecOff - getVA()) | 1, entsize, this) - .overwrite(*s->sym); - off += s->entsize; - } -} - -void ArmCmseSGVeneer::writeTo(uint8_t *buf) { - write16(buf + 0, 0xe97f); // SG - write16(buf + 2, 0xe97f); - write16(buf + 4, 0xf000); // B.W S - write16(buf + 6, 0xb000); - target->relocateNoSym(buf + 4, R_ARM_THM_JUMP24, - acleSeSym->getVA() - getVA() - 8); -} - -// Write the CMSE import library to disk. -// The CMSE import library is a relocatable object with only a symbol table. -// The symbols are copies of the (absolute) symbols of the secure gateways -// in the executable output by this link. -// See Arm® v8-M Security Extensions: Requirements on Development Tools -// https://developer.arm.com/documentation/ecm0359818/latest -template void elf::writeARMCmseImportLib() { - StringTableSection *shstrtab = - make(".shstrtab", /*dynamic=*/false); - StringTableSection *strtab = - make(".strtab", /*dynamic=*/false); - SymbolTableBaseSection *impSymTab = make>(*strtab); - - SmallVector, 0> osIsPairs; - osIsPairs.emplace_back(make(strtab->name, 0, 0), strtab); - osIsPairs.emplace_back(make(impSymTab->name, 0, 0), impSymTab); - osIsPairs.emplace_back(make(shstrtab->name, 0, 0), shstrtab); - - std::sort(symtab.cmseSymMap.begin(), symtab.cmseSymMap.end(), - [](const auto &a, const auto &b) -> bool { - return a.second.sym->getVA() < b.second.sym->getVA(); - }); - // Copy the secure gateway entry symbols to the import library symbol table. - for (auto &p : symtab.cmseSymMap) { - Defined *d = cast(p.second.sym); - impSymTab->addSymbol(makeDefined(nullptr, d->getName(), d->computeBinding(), - /*stOther=*/0, STT_FUNC, d->getVA(), - d->getSize(), nullptr)); - } - - size_t idx = 0; - uint64_t off = sizeof(typename ELFT::Ehdr); - for (auto &[osec, isec] : osIsPairs) { - osec->sectionIndex = ++idx; - osec->recordSection(isec); - osec->finalizeInputSections(); - osec->shName = shstrtab->addString(osec->name); - osec->size = isec->getSize(); - isec->finalizeContents(); - osec->offset = alignToPowerOf2(off, osec->addralign); - off = osec->offset + osec->size; - } - - const uint64_t sectionHeaderOff = alignToPowerOf2(off, config->wordsize); - const auto shnum = osIsPairs.size() + 1; - const uint64_t fileSize = - sectionHeaderOff + shnum * sizeof(typename ELFT::Shdr); - const unsigned flags = - config->mmapOutputFile ? 0 : (unsigned)FileOutputBuffer::F_no_mmap; - unlinkAsync(config->cmseOutputLib); - Expected> bufferOrErr = - FileOutputBuffer::create(config->cmseOutputLib, fileSize, flags); - if (!bufferOrErr) { - error("failed to open " + config->cmseOutputLib + ": " + - llvm::toString(bufferOrErr.takeError())); - return; - } - - // Write the ELF Header - std::unique_ptr &buffer = *bufferOrErr; - uint8_t *const buf = buffer->getBufferStart(); - memcpy(buf, "\177ELF", 4); - auto *eHdr = reinterpret_cast(buf); - eHdr->e_type = ET_REL; - eHdr->e_entry = 0; - eHdr->e_shoff = sectionHeaderOff; - eHdr->e_ident[EI_CLASS] = ELFCLASS32; - eHdr->e_ident[EI_DATA] = config->isLE ? ELFDATA2LSB : ELFDATA2MSB; - eHdr->e_ident[EI_VERSION] = EV_CURRENT; - eHdr->e_ident[EI_OSABI] = config->osabi; - eHdr->e_ident[EI_ABIVERSION] = 0; - eHdr->e_machine = EM_ARM; - eHdr->e_version = EV_CURRENT; - eHdr->e_flags = config->eflags; - eHdr->e_ehsize = sizeof(typename ELFT::Ehdr); - eHdr->e_phnum = 0; - eHdr->e_shentsize = sizeof(typename ELFT::Shdr); - eHdr->e_phoff = 0; - eHdr->e_phentsize = 0; - eHdr->e_shnum = shnum; - eHdr->e_shstrndx = shstrtab->getParent()->sectionIndex; - - // Write the section header table. - auto *sHdrs = reinterpret_cast(buf + eHdr->e_shoff); - for (auto &[osec, _] : osIsPairs) - osec->writeHeaderTo(++sHdrs); - - // Write section contents to a mmap'ed file. - { - parallel::TaskGroup tg; - for (auto &[osec, _] : osIsPairs) - osec->writeTo(buf + osec->offset, tg); - } - - if (auto e = buffer->commit()) - fatal("failed to write output '" + buffer->getPath() + - "': " + toString(std::move(e))); -} - TargetInfo *elf::getARMTargetInfo() { static ARM target; return ⌖ } -template void elf::writeARMCmseImportLib(); -template void elf::writeARMCmseImportLib(); -template void elf::writeARMCmseImportLib(); -template void elf::writeARMCmseImportLib(); - -template void ObjFile::importCmseSymbols(); -template void ObjFile::importCmseSymbols(); -template void ObjFile::importCmseSymbols(); -template void ObjFile::importCmseSymbols(); diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 699c9d3..9565300 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -129,7 +129,6 @@ private: std::unique_ptr lto; std::vector files; - std::optional armCmseImpLib; public: SmallVector, 0> archiveFiles; @@ -174,8 +173,6 @@ struct Config { llvm::StringRef thinLTOCacheDir; llvm::StringRef thinLTOIndexOnlyArg; llvm::StringRef whyExtract; - llvm::StringRef cmseInputLib; - llvm::StringRef cmseOutputLib; StringRef zBtiReport = "none"; StringRef zCetReport = "none"; llvm::StringRef ltoBasicBlockSections; @@ -198,13 +195,11 @@ struct Config { llvm::MapVector, uint64_t> callGraphProfile; - bool cmseImplib = false; bool allowMultipleDefinition; bool androidPackDynRelocs = false; bool armHasBlx = false; bool armHasMovtMovw = false; bool armJ1J2BranchEncoding = false; - bool armCMSESupport = false; bool asNeeded = false; BsymbolicKind bsymbolic = BsymbolicKind::None; bool callGraphProfileSort; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 2dbc2f2..4eb10fc 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -345,22 +345,6 @@ static void checkOptions() { if (config->emachine == EM_MIPS && config->gnuHash) error("the .gnu.hash section is not compatible with the MIPS target"); - if (config->emachine == EM_ARM) { - if (!config->cmseImplib) { - if (!config->cmseInputLib.empty()) - error("--in-implib may not be used without --cmse-implib"); - if (!config->cmseOutputLib.empty()) - error("--out-implib may not be used without --cmse-implib"); - } - } else { - if (config->cmseImplib) - error("--cmse-implib is only supported on ARM targets"); - if (!config->cmseInputLib.empty()) - error("--in-implib is only supported on ARM targets"); - if (!config->cmseOutputLib.empty()) - error("--out-implib is only supported on ARM targets"); - } - if (config->fixCortexA53Errata843419 && config->emachine != EM_AARCH64) error("--fix-cortex-a53-843419 is only supported on AArch64 targets"); @@ -1177,9 +1161,6 @@ static void readConfigs(opt::InputArgList &args) { config->fini = args.getLastArgValue(OPT_fini, "_fini"); config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419) && !args.hasArg(OPT_relocatable); - config->cmseImplib = args.hasArg(OPT_cmse_implib); - config->cmseInputLib = args.getLastArgValue(OPT_in_implib); - config->cmseOutputLib = args.getLastArgValue(OPT_out_implib); config->fixCortexA8 = args.hasArg(OPT_fix_cortex_a8) && !args.hasArg(OPT_relocatable); config->fortranCommon = @@ -1757,12 +1738,6 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { files.back()->justSymbols = true; } break; - case OPT_in_implib: - if (armCmseImpLib) - error("multiple CMSE import libraries not supported"); - else if (std::optional mb = readFile(arg->getValue())) - armCmseImpLib = createObjFile(*mb); - break; case OPT_start_group: if (InputFile::isInGroup) error("nested --start-group"); @@ -2642,8 +2617,6 @@ void LinkerDriver::link(opt::InputArgList &args) { llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName()); parseFile(files[i]); } - if (armCmseImpLib) - parseArmCMSEImportLib(*armCmseImpLib); } // Now that we have every file, we can decide if we will need a @@ -2808,9 +2781,6 @@ void LinkerDriver::link(opt::InputArgList &args) { if (args.hasArg(OPT_exclude_libs)) excludeLibs(args); - // Record [__acle_se_, ] pairs for later processing. - processArmCmseSymbols(); - // Apply symbol renames for --wrap and combine foo@v1 and foo@@v1. redirectSymbols(wrapped); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 7c50291..5f24af5 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -177,15 +177,6 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) { config->armHasMovtMovw = true; break; } - - // Only ARMv8-M or later architectures have CMSE support. - std::optional profile = - attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); - if (!profile) - return; - if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base && - profile == ARMBuildAttrs::MicroControllerProfile) - config->armCMSESupport = true; } InputFile::InputFile(Kind k, MemoryBufferRef m) @@ -326,14 +317,6 @@ template static void doParseFile(InputFile *file) { // Add symbols in File to the symbol table. void elf::parseFile(InputFile *file) { invokeELFT(doParseFile, file); } -template static void doParseArmCMSEImportLib(InputFile *file) { - cast>(file)->importCmseSymbols(); -} - -void elf::parseArmCMSEImportLib(InputFile *file) { - invokeELFT(doParseArmCMSEImportLib, file); -} - // Concatenates arguments to construct a string representing an error location. static std::string createFileLineMsg(StringRef path, unsigned line) { std::string filename = std::string(path::filename(path)); @@ -1048,8 +1031,8 @@ InputSectionBase *ObjFile::createInputSection(uint32_t idx, return makeThreadLocal(*this, sec, name); } -// Initialize symbols. symbols is a parallel array to the corresponding ELF -// symbol table. +// Initialize this->Symbols. this->Symbols is a parallel array as +// its corresponding ELF symbol table. template void ObjFile::initializeSymbols(const object::ELFFile &obj) { ArrayRef eSyms = this->getELFSyms(); diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index cc658bd..2ee15e8 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -48,8 +48,6 @@ std::optional readFile(StringRef path); // Add symbols in File to the symbol table. void parseFile(InputFile *file); -void parseArmCMSEImportLib(InputFile *file); - // The root class of input files. class InputFile { protected: @@ -90,12 +88,6 @@ public: return {symbols.get(), numSymbols}; } - MutableArrayRef getMutableSymbols() { - assert(fileKind == BinaryKind || fileKind == ObjKind || - fileKind == BitcodeKind); - return {symbols.get(), numSymbols}; - } - // Get filename to use for linker script processing. StringRef getNameForScript() const; @@ -288,8 +280,6 @@ public: void initSectionsAndLocalSyms(bool ignoreComdats); void postParse(); - void importCmseSymbols(); - void redirectCmseSymbols(); private: void initializeSections(bool ignoreComdats, diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 28e9f04..777f1f2 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -896,15 +896,6 @@ void LinkerScript::diagnoseOrphanHandling() const { } } -void LinkerScript::diagnoseMissingSGSectionAddress() const { - if (!config->cmseImplib || !in.armCmseSGSection->isNeeded()) - return; - - OutputSection *sec = findByName(sectionCommands, ".gnu.sgstubs"); - if (sec && !sec->addrExpr && !config->sectionStartMap.count(".gnu.sgstubs")) - error("no address assigned to the veneers output section " + sec->name); -} - // This function searches for a memory region to place the given output // section in. If found, a pointer to the appropriate memory region is // returned in the first member of the pair. Otherwise, a nullptr is returned. diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 8b8320f..ee0985a 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -318,7 +318,6 @@ public: void addOrphanSections(); void diagnoseOrphanHandling() const; - void diagnoseMissingSGSectionAddress() const; void adjustOutputSections(); void adjustSectionsAfterSorting(); diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 353c7ea..7db7d1c 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -230,10 +230,6 @@ template void MarkLive::run() { markSymbol(symtab.find(s)); for (StringRef s : script->referencedSymbols) markSymbol(symtab.find(s)); - for (auto [symName, _] : symtab.cmseSymMap) { - markSymbol(symtab.cmseSymMap[symName].sym); - markSymbol(symtab.cmseSymMap[symName].acleSeSym); - } // Mark .eh_frame sections as live because there are usually no relocations // that point to .eh_frames. Otherwise, the garbage collector would drop diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index e9fbe23..0c6884a 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -80,18 +80,6 @@ defm split_stack_adjust_size def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">; -def cmse_implib: FF<"cmse-implib">, - HelpText<"Make the output library to be a CMSE secure code import library">; - -defm in_implib: EEq<"in-implib", - "Read an existing CMSE secure code import library and preserve entry function addresses in the " - "resulting new CMSE secure code import library (optional when creating a CMSE secure image)">, - MetaVarName<"">; - -defm out_implib: EEq<"out-implib", - "Output the CMSE secure code import library to (required when creating a CMSE secure image)">, - MetaVarName<"">; - defm Tbss: Eq<"Tbss", "Same as --section-start with .bss as the sectionname">; defm Tdata: Eq<"Tdata", "Same as --section-start with .data as the sectionname">; diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 37e31d2..9c93ae1 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -19,11 +19,6 @@ namespace lld::elf { class InputFile; class SharedFile; -struct ArmCmseEntryFunction { - Symbol *acleSeSym; - Symbol *sym; -}; - // SymbolTable is a bucket of all known symbols, including defined, // undefined, or lazy symbols (the last one is symbols in archive // files whose archive members are not yet loaded). @@ -65,18 +60,6 @@ public: // is used to uniquify them. llvm::DenseMap comdatGroups; - // The Map of __acle_se_, pairs found in the input objects. - // Key is the name. - llvm::SmallMapVector cmseSymMap; - - // Map of symbols defined in the Arm CMSE import library. The linker must - // preserve the addresses in the output objects. - llvm::StringMap cmseImportLib; - - // True if from the input Arm CMSE import library is written to the - // output Arm CMSE import library. - llvm::StringMap inCMSEOutImpLib; - private: SmallVector findByVersion(SymbolVersion ver); SmallVector findAllByVersion(SymbolVersion ver, diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 678b130..48f3012 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3828,7 +3828,6 @@ void InStruct::reset() { got.reset(); gotPlt.reset(); igotPlt.reset(); - armCmseSGSection.reset(); ppc64LongBranchTarget.reset(); mipsAbiFlags.reset(); mipsGot.reset(); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index de07aee..a2554c7 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1143,51 +1143,6 @@ private: size_t size = 0; }; -// Cortex-M Security Extensions. Prefix for functions that should be exported -// for the non-secure world. -const char ACLESESYM_PREFIX[] = "__acle_se_"; -const int ACLESESYM_SIZE = 8; - -class ArmCmseSGVeneer : public SyntheticSection { -public: - ArmCmseSGVeneer(Symbol *sym, Symbol *acleSeSym, - std::optional addr = std::nullopt) - : SyntheticSection(llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, - llvm::ELF::SHT_PROGBITS, - /*alignment=*/32, ".gnu.sgstubs"), - sym(sym), acleSeSym(acleSeSym), entAddr{addr} { - entsize = ACLESESYM_SIZE; - } - - void writeTo(uint8_t *buf) override; - size_t getSize() const override { return entsize; }; - const std::optional getAddr() const { return entAddr; }; - - Symbol *sym; - Symbol *acleSeSym; - -private: - const std::optional entAddr; -}; - -class ArmCmseSGSection : public SyntheticSection { -public: - ArmCmseSGSection(); - bool isNeeded() const override { return !entries.empty(); } - size_t getSize() const override; - void writeTo(uint8_t *buf) override; - void addSGVeneer(Symbol *sym, Symbol *ext_sym); - void addMappingSymbol(); - void finalizeContents() override; - void exportEntries(SymbolTableBaseSection *symTab); - uint64_t impLibMaxAddr = 0; - -private: - SmallVector, 0> entries; - SmallVector sgSections; - uint64_t newEntries = 0; -}; - // Used to compute outSecOff of .got2 in each object file. This is needed to // synthesize PLT entries for PPC32 Secure PLT ABI. class PPC32Got2Section final : public SyntheticSection { @@ -1324,7 +1279,6 @@ struct InStruct { std::unique_ptr got; std::unique_ptr gotPlt; std::unique_ptr igotPlt; - std::unique_ptr armCmseSGSection; std::unique_ptr ppc64LongBranchTarget; std::unique_ptr mipsAbiFlags; std::unique_ptr mipsGot; diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index cec105f..59534ab 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -200,8 +200,6 @@ static inline std::string getErrorLocation(const uint8_t *loc) { return getErrorPlace(loc).loc; } -void processArmCmseSymbols(); - void writePPC32GlinkSection(uint8_t *buf, size_t numEntries); unsigned getPPCDFormOp(unsigned secondaryOp); @@ -223,7 +221,6 @@ void writePrefixedInstruction(uint8_t *loc, uint64_t insn); void addPPC64SaveRestore(); uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t expr); -template void writeARMCmseImportLib(); void riscvFinalizeRelax(int passes); void mergeRISCVAttributesSections(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 361e0ab..3630b19 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -454,11 +454,6 @@ template void elf::createSyntheticSections() { in.igotPlt = std::make_unique(); add(*in.igotPlt); - if (config->emachine == EM_ARM) { - in.armCmseSGSection = std::make_unique(); - add(*in.armCmseSGSection); - } - // _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat // it as a relocation and ensure the referenced section is created. if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) { @@ -600,9 +595,6 @@ template void Writer::run() { if (auto e = buffer->commit()) fatal("failed to write output '" + buffer->getPath() + "': " + toString(std::move(e))); - - if (!config->cmseOutputLib.empty()) - writeARMCmseImportLib(); } } @@ -1991,7 +1983,6 @@ template void Writer::finalizeSections() { removeUnusedSyntheticSections(); script->diagnoseOrphanHandling(); - script->diagnoseMissingSGSectionAddress(); sortSections(); @@ -2143,7 +2134,6 @@ template void Writer::finalizeSections() { // static symbol table. finalizeSynthetic(in.symTab.get()); finalizeSynthetic(in.ppc64LongBranchTarget.get()); - finalizeSynthetic(in.armCmseSGSection.get()); } // Relaxation to delete inter-basic block jumps created by basic block diff --git a/lld/test/ELF/Inputs/arm-cmse-macros.s b/lld/test/ELF/Inputs/arm-cmse-macros.s deleted file mode 100644 index bfa3dcf..0000000 --- a/lld/test/ELF/Inputs/arm-cmse-macros.s +++ /dev/null @@ -1,32 +0,0 @@ -/// Because the addresses of __acle_se_\sym_name and \sym_name are equal, -/// the linker creates a secure gateway in ".gnu.sgstubs". -.macro cmse_veneer sym_name, sym_type, sym_binding, acle_sym_type, acle_sym_binding -.align 2 -.\sym_binding \sym_name -.\acle_sym_binding __acle_se_\sym_name -.type \sym_name, %\sym_type -.type __acle_se_\sym_name, %\acle_sym_type -\sym_name: -__acle_se_\sym_name: - nop -.size \sym_name, .-\sym_name -.size __acle_se_\sym_name, .-__acle_se_\sym_name -.endm - -/// Because the addresses of __acle_se_\sym_name and \sym_name are not equal, -/// the linker considers that an inline secure gateway exists and does not -/// create one. -.macro cmse_no_veneer sym_name, sym_type, sym_binding, acle_sym_type, acle_sym_binding -.align 2 -.\sym_binding \sym_name -.\acle_sym_binding __acle_se_\sym_name -.type \sym_name, %\sym_type -.type __acle_se_\sym_name, %\acle_sym_type -\sym_name: - sg - nop -__acle_se_\sym_name: - nop -.size \sym_name, .-\sym_name -.size __acle_se_\sym_name, .-__acle_se_\sym_name -.endm diff --git a/lld/test/ELF/aarch64-cmse.s b/lld/test/ELF/aarch64-cmse.s deleted file mode 100644 index a360d48..0000000 --- a/lld/test/ELF/aarch64-cmse.s +++ /dev/null @@ -1,16 +0,0 @@ -# REQUIRES: aarch64 -# RUN: yaml2obj %s -o %t.o -# RUN: not ld.lld --cmse-implib %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR_CMSE_IMPLIB -# RUN: not ld.lld --in-implib=%t.o %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR_IN_IMPLIB -# RUN: not ld.lld --out-implib=out.lib %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR_OUT_IMPLIB - -# ERR_CMSE_IMPLIB: error: --cmse-implib is only supported on ARM targets -# ERR_IN_IMPLIB: error: --in-implib is only supported on ARM targets -# ERR_OUT_IMPLIB: error: --out-implib is only supported on ARM targets - -!ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_AARCH64 diff --git a/lld/test/ELF/arm-cmse-diagnostics.s b/lld/test/ELF/arm-cmse-diagnostics.s deleted file mode 100644 index 579cc40..0000000 --- a/lld/test/ELF/arm-cmse-diagnostics.s +++ /dev/null @@ -1,281 +0,0 @@ -// REQUIRES: arm -/// Test CMSE diagnostics. - -// RUN: rm -rf %t && split-file %s %t && cd %t - -/// Test diagnostics emitted during checks of the CMSE import library -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.base lib -o lib.o -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.base app -I %S/Inputs -o app.o -// RUN: llvm-objcopy --redefine-sym=entry7_duplicate=entry6_duplicate lib.o -// RUN: not ld.lld --cmse-implib --in-implib=lib.o app.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_IMPLIB -// RUN: not ld.lld --cmse-implib --in-implib=lib.o --in-implib=lib.o app.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_MULT_INIMPLIB -// RUN: not ld.lld --in-implib=lib.o app.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_IN_IMPLIB -// RUN: not ld.lld --out-implib=out.lib app.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_OUT_IMPLIB -// RUN: not ld.lld --out-implib=out.lib --in-implib=lib.o app.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_IN_IMPLIB,ERR_OUT_IMPLIB - -// ERR_IMPLIB: error: CMSE symbol 'entry_not_external' in import library '{{.*}}' is not global -// ERR_IMPLIB: error: CMSE symbol 'entry_not_absolute' in import library '{{.*}}' is not absolute -// ERR_IMPLIB: error: CMSE symbol 'entry_not_function' in import library '{{.*}}' is not a Thumb function definition -// ERR_IMPLIB: error: CMSE symbol 'entry_not_thumb' in import library '{{.*}}' is not a Thumb function definition -// ERR_IMPLIB: warning: CMSE symbol 'entry5_incorrect_size' in import library '{{.*}}' does not have correct size of 8 bytes -// ERR_IMPLIB: error: CMSE symbol 'entry6_duplicate' is multiply defined in import library '{{.*}}' -// ERR_MULT_INIMPLIB: error: multiple CMSE import libraries not supported -// ERR_IN_IMPLIB: error: --in-implib may not be used without --cmse-implib -// ERR_OUT_IMPLIB: error: --out-implib may not be used without --cmse-implib - -/// CMSE Only supported by ARMv8-M architecture or later. -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv8m.base app -I %S/Inputs -o app1.o -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app1 app1.o 2>&1 | FileCheck /dev/null --implicit-check-not=error: - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv8m.main app -I %S/Inputs -o app2.o -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app2 app2.o 2>&1 | FileCheck /dev/null --implicit-check-not=error: - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv8.1m.main app -I %S/Inputs -o app3.o -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app3 app3.o 2>&1 | FileCheck /dev/null --implicit-check-not=error: - -/// Expect errors for other architectures. -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv9a app -I %S/Inputs -o app4.o -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app4 app4.o 2>&1 | FileCheck %s --check-prefixes=ERR_ARCH - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7-m app -I %S/Inputs -o app5.o -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app5 app5.o 2>&1 | FileCheck %s --check-prefixes=ERR_ARCH - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv8-m app -I %S/Inputs -o app6.o -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app6 app6.o 2>&1 | FileCheck %s --check-prefixes=ERR_ARCH - -/// Invalid triple defaults to v4T. Error. -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumb app -I %S/Inputs -o app7.o -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app7 app7.o 2>&1 | FileCheck %s --check-prefixes=ERR_ARCH - -/// No build attributes. Error. -// RUN: llvm-mc -filetype=obj -triple=thumb app -I %S/Inputs -o app8.o -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o app8 app8.o 2>&1 | FileCheck %s --check-prefixes=ERR_ARCH - -// ERR_ARCH: CMSE is only supported by ARMv8-M architecture or later - -/// Test that the linker diagnoses cases where the linker synthesized veneer addresses -/// specified by the CMSE input library cannot be placed at the .gnu.sgstubs section address. - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main app -I %S/Inputs -o 1.o -/// Create a CMSE import library with a secure gateway veneer at 0x10000 -// RUN: ld.lld --cmse-implib --section-start .gnu.sgstubs=0x10000 1.o -o 1 --out-implib=1.lib 2>&1 | FileCheck /dev/null --implicit-check-not=error: -/// Create a new import library with the secure gateway veneer and .gnu.sgstubs specified at the same address -// RUN: ld.lld --cmse-implib --section-start .gnu.sgstubs=0x10000 1.o -o 2 --out-implib=2.lib --in-implib=1.lib 2>&1 | FileCheck /dev/null --implicit-check-not=error: -/// Create a new import library with the secure gateway veneer specified at a same address but .gnu.sgstubs at a higher address. -// RUN: not ld.lld --cmse-implib --section-start .gnu.sgstubs=0x11000 1.o -o 3 --out-implib=3.lib --in-implib=1.lib 2>&1 | FileCheck %s --check-prefixes=ERR_ADDR -/// Create a new import library with the secure gateway veneer specified at a same address but .gnu.sgstubs at a lower address. -// RUN: not ld.lld --cmse-implib --section-start .gnu.sgstubs=0x9000 1.o -o 4 --out-implib=4.lib --in-implib=1.lib 2>&1 | FileCheck %s --check-prefixes=ERR_ADDR - -// ERR_ADDR: error: start address of '.gnu.sgstubs' is different from previous link - -/// Test that the address of .gnu.sgstubs can be specified via command line or linker script. -/// Test that the linker errors when the address of .gnu.sgstubs is not specified using either method. - -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 --script with_sgstubs.script 1.o -o 1 2>&1 | FileCheck /dev/null --implicit-check-not=error: -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 --script wout_sgstubs.script 1.o -o 2 2>&1 | FileCheck /dev/null --implicit-check-not=error: -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 1.o -o 3 2>&1 | FileCheck /dev/null --implicit-check-not=error: -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --script with_sgstubs.script 1.o -o 4 2>&1 | FileCheck /dev/null --implicit-check-not=error: -// RUN: not ld.lld --cmse-implib -Ttext=0x8000 --script wout_sgstubs.script 1.o -o 5 2>&1 | FileCheck %s --check-prefixes=ERR_NOADDR - -// RUN: llvm-readelf -S 1 | FileCheck %s --check-prefixes=ADDRCMDLINE -// RUN: llvm-readelf -S 2 | FileCheck %s --check-prefixes=ADDRCMDLINE -// RUN: llvm-readelf -S 3 | FileCheck %s --check-prefixes=ADDRCMDLINE -// RUN: llvm-readelf -S 4 | FileCheck %s --check-prefixes=ADDRLNKSCRIPT - -// ERR_NOADDR: error: no address assigned to the veneers output section .gnu.sgstubs - -/// Name Type Address Off Size ES Flg Lk Inf Al -// ADDRCMDLINE: .gnu.sgstubs PROGBITS 00020000 020000 000008 08 AX 0 0 32 -// ADDRLNKSCRIPT: .gnu.sgstubs PROGBITS 00040000 040000 000008 08 AX 0 0 32 - -/// Test diagnostics emitted during symbol attribute checks. - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -I %S/Inputs --triple=thumbv8m.base symattr -o symattr.o -// RUN: not ld.lld --cmse-implib symattr.o -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR_SYMATTR - -// ERR_SYMATTR-NOT: __acle_se_valid_{{.*}} -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_1' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_2' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse entry symbol 'invalid_3' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse entry symbol 'invalid_4' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_5' detected, but no associated entry function definition 'invalid_5' with external linkage found -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_6' detected, but no associated entry function definition 'invalid_6' with external linkage found -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_7' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_8' detected, but no associated entry function definition 'invalid_8' with external linkage found -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_9' cannot be an absolute symbol -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_10' cannot be an absolute symbol -// ERR_SYMATTR: error: {{.*}}: cmse special symbol '__acle_se_invalid_11' is not a Thumb function definition -// ERR_SYMATTR: error: {{.*}}: cmse entry symbol 'invalid_12' is not a Thumb function definition - -/// Test diagnostics emitted when a symbol is removed from a later version of the import library. -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -I %S/Inputs --triple=thumbv8m.base libv1 -o libv1.o -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -I %S/Inputs --triple=thumbv8m.base libv2 -o libv2.o -// RUN: ld.lld -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 --cmse-implib libv1.o --out-implib=libv1.lib -o /dev/null -// RUN: ld.lld -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 --cmse-implib libv2.o --in-implib=libv1.lib --out-implib=libv2.lib -o /dev/null 2>&1 | FileCheck %s --check-prefixes=WARN_MISSING -// RUN: ld.lld -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 --cmse-implib libv1.o --in-implib=libv2.lib -o /dev/null 2>&1 | FileCheck %s --check-prefixes=WARN_NEWENTRY - -// WARN_MISSING: warning: entry function 'foo' from CMSE import library is not present in secure application -// WARN_NEWENTRY: warning: new entry function 'foo' introduced but no output import library specified - -//--- with_sgstubs.script -SECTIONS { - .text : { *(.text) } - .gnu.sgstubs 0x40000 : { *(.gnu.sgstubs*) } -} - -//--- wout_sgstubs.script -SECTIONS { - .text : { *(.text) } -} - -//--- app - .include "arm-cmse-macros.s" - .text - .thumb - -cmse_veneer entry, function, global, function, global - -//--- lib - .text - .thumb - -/// Symbol not absolute. - .global entry_not_absolute - .type entry_not_absolute, STT_FUNC - .thumb_func -entry_not_absolute: - .size entry_not_absolute, 8 - -/// Symbol not global or weak. - .local entry_not_external - .type entry_not_external, STT_FUNC -entry_not_external=0x1001 - .size entry_not_external, 8 - -/// Symbol not the function type. - .global entry_not_function - .type entry_not_function, STT_NOTYPE -entry_not_function=0x1001 - .size entry_not_function, 8 - -/// Symbol not a Thumb code symbol. - .global entry_not_thumb - .type entry_not_thumb, STT_FUNC -entry_not_thumb=0x1000 - .size entry_not_thumb, 8 - -/// Symbol with incorrect size. - .global entry5_incorrect_size - .type entry5_incorrect_size, STT_FUNC -entry5_incorrect_size=0x1009 - .size entry5_incorrect_size, 6 - -/// Duplicate symbols. - .global entry6_duplicate - .type entry6_duplicate, STT_FUNC -entry6_duplicate=0x1001 - .size entry6_duplicate, 8 - -/// entry7_duplicate gets renamed to entry6_duplicate by llvm-objcopy. - .global entry7_duplicate - .type entry7_duplicate, STT_FUNC -entry7_duplicate=0x1009 - .size entry7_duplicate, 8 - -//--- symattr -.include "arm-cmse-macros.s" - - .text - .thumb - -/// Valid sequences -/// both sym and __acle_se_sym should be global or weak Thumb code symbols. - cmse_veneer valid_1, function, global, function, global - cmse_veneer valid_2, function, weak, function, weak - cmse_veneer valid_3, function, weak, function, global - cmse_veneer valid_4, function, global, function, weak - -/// Invalid sequences -/// __acle_se_sym is an object - cmse_veneer invalid_1, function, global, object, global - cmse_veneer invalid_2, function, global, object, weak -/// sym is an object - cmse_veneer invalid_3, object, global, function, global - cmse_veneer invalid_4, object, global, function, weak -/// sym is local - cmse_veneer invalid_5, function, local, function, global - cmse_veneer invalid_6, function, local, function, weak - -/// __acle_se_invalid_7 not defined. - .global invalid_7 - .type invalid_7, %function - .global __acle_se_invalid_7 - .thumb_func -invalid_7: - -/// invalid_8 not defined. - .global __acle_se_invalid_8 - .thumb_func -__acle_se_invalid_8: - -// Absolute symbols with same values - .global invalid_9 - .global __acle_se_invalid_9 - .type __acle_se_invalid_9, %function - .type invalid_9, %function -__acle_se_invalid_9=0x1001 -invalid_9=0x1001 - .size invalid_9, 0 - .size __acle_se_invalid_9, 0 - -// Absolute symbols with different values - .align 2 - .global __acle_se_invalid_10 - .global invalid_10 - .type __acle_se_invalid_10, %function - .type invalid_10, %function -__acle_se_invalid_10 = 0x10001 -invalid_10 = 0x10005 - .size invalid_10, 0 - .size __acle_se_invalid_10, 0 - - .section nonthumb - .thumb - .align 2 - .global invalid_11 - .global __acle_se_invalid_11 - .type invalid_11, %function - .type __acle_se_invalid_11, %function -invalid_11: - .size invalid_11, .-invalid_11 -/// Invalid non-thumb function symbol __acle_se_invalid_11 -__acle_se_invalid_11=0x1000 - - .global invalid_12 - .global __acle_se_invalid_12 - .type invalid_12, %function - .type __acle_se_invalid_12, %function -/// Invalid non-thumb function symbol invalid_12 -invalid_12=0x1000 - .thumb -__acle_se_invalid_12: - .size __acle_se_invalid_12, .-__acle_se_invalid_12 - -//--- libv1 -.include "arm-cmse-macros.s" - - .text - .thumb - -/// Import library version 1 with foo and bar - cmse_veneer foo, function, global, function, global - cmse_veneer bar, function, weak, function, weak - -//--- libv2 -.include "arm-cmse-macros.s" - - .text - .thumb - -/// Import library version 2 with bar missing. - cmse_veneer bar, function, weak, function, weak diff --git a/lld/test/ELF/arm-cmse-implib.s b/lld/test/ELF/arm-cmse-implib.s deleted file mode 100644 index 3f643a1..0000000 --- a/lld/test/ELF/arm-cmse-implib.s +++ /dev/null @@ -1,114 +0,0 @@ -// REQUIRES: arm -/// Test that addresses of secure gateways in an old import library are maintained in new import libraries. - -// RUN: rm -rf %t && split-file %s %t && cd %t -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.base app -o app.o -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.base implib-v1 -I %S/Inputs -o 1.o -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.base implib-v2 -I %S/Inputs -o 2.o - -// RUN: ld.lld -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o 1 app.o --out-implib=1.lib --cmse-implib 1.o -// RUN: llvm-readelf -s 1 1.lib | FileCheck %s --check-prefixes=CHECK1 - -// RUN: ld.lld -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 -o 2 app.o --out-implib=2.lib --in-implib=1.lib --cmse-implib 2.o -// RUN: llvm-readelf -s 2 2.lib | FileCheck %s --check-prefixes=CHECK2 - -//--- app - - .align 2 - .global secure_entry - .type secure_entry, %function -secure_entry: - nop - .size secure_entry, .-secure_entry - -//--- implib-v1 - - .include "arm-cmse-macros.s" - - .syntax unified - .text - - cmse_veneer foo, function, global, function, global - cmse_veneer bar, function, weak, function, global - cmse_no_veneer no_veneer1, function, weak, function, global - cmse_no_veneer no_veneer2, function, weak, function, weak - -//--- implib-v2 - - .include "arm-cmse-macros.s" - - .syntax unified - .text - - cmse_veneer baz, function, weak, function, global - cmse_veneer foo, function, global, function, global - cmse_veneer bar, function, weak, function, global - cmse_veneer qux, function, global, function, global - cmse_no_veneer no_veneer1, function, weak, function, global - cmse_no_veneer no_veneer2, function, weak, function, weak - -/// Executable 1 -// CHECK1: File: -// CHECK1: Symbol table '.symtab' contains 13 entries: -// CHECK1-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK1-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK1-NEXT: 1: 00020000 0 NOTYPE LOCAL DEFAULT 2 $t -// CHECK1-NEXT: 2: 00008000 0 NOTYPE LOCAL DEFAULT 1 $t.0 -// CHECK1-NEXT: 3: 00008004 0 NOTYPE LOCAL DEFAULT 1 $t.0 -// CHECK1-NEXT: 4: 00008001 2 FUNC GLOBAL DEFAULT 1 secure_entry -// CHECK1-NEXT: 5: 00020009 8 FUNC GLOBAL DEFAULT 2 foo -// CHECK1-NEXT: 6: 00008005 2 FUNC GLOBAL DEFAULT 1 __acle_se_foo -// CHECK1-NEXT: 7: 00020001 8 FUNC WEAK DEFAULT 2 bar -// CHECK1-NEXT: 8: 00008009 2 FUNC GLOBAL DEFAULT 1 __acle_se_bar -// CHECK1-NEXT: 9: 0000800d 8 FUNC WEAK DEFAULT 1 no_veneer1 -// CHECK1-NEXT: 10: 00008013 2 FUNC GLOBAL DEFAULT 1 __acle_se_no_veneer1 -// CHECK1-NEXT: 11: 00008015 8 FUNC WEAK DEFAULT 1 no_veneer2 -// CHECK1-NEXT: 12: 0000801b 2 FUNC WEAK DEFAULT 1 __acle_se_no_veneer2 - - -/// Import library 1 -// CHECK1: File: -// CHECK1: Symbol table '.symtab' contains 5 entries: -// CHECK1-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK1-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK1-NEXT: 1: 0000800d 8 FUNC WEAK DEFAULT ABS no_veneer1 -// CHECK1-NEXT: 2: 00008015 8 FUNC WEAK DEFAULT ABS no_veneer2 -// CHECK1-NEXT: 3: 00020001 8 FUNC WEAK DEFAULT ABS bar -// CHECK1-NEXT: 4: 00020009 8 FUNC GLOBAL DEFAULT ABS foo - -/// Executable 2 -// CHECK2: File: -// CHECK2: Symbol table '.symtab' contains 17 entries: -// CHECK2-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK2-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK2-NEXT: 1: 00020000 0 NOTYPE LOCAL DEFAULT 2 $t -// CHECK2-NEXT: 2: 00008000 0 NOTYPE LOCAL DEFAULT 1 $t.0 -// CHECK2-NEXT: 3: 00008004 0 NOTYPE LOCAL DEFAULT 1 $t.0 -// CHECK2-NEXT: 4: 00008001 2 FUNC GLOBAL DEFAULT 1 secure_entry -// CHECK2-NEXT: 5: 00020019 8 FUNC WEAK DEFAULT 2 baz -// CHECK2-NEXT: 6: 00008005 2 FUNC GLOBAL DEFAULT 1 __acle_se_baz -// CHECK2-NEXT: 7: 00020009 8 FUNC GLOBAL DEFAULT 2 foo -// CHECK2-NEXT: 8: 00008009 2 FUNC GLOBAL DEFAULT 1 __acle_se_foo -// CHECK2-NEXT: 9: 00020001 8 FUNC WEAK DEFAULT 2 bar -// CHECK2-NEXT: 10: 0000800d 2 FUNC GLOBAL DEFAULT 1 __acle_se_bar -// CHECK2-NEXT: 11: 00020011 8 FUNC GLOBAL DEFAULT 2 qux -// CHECK2-NEXT: 12: 00008011 2 FUNC GLOBAL DEFAULT 1 __acle_se_qux -// CHECK2-NEXT: 13: 00008015 8 FUNC WEAK DEFAULT 1 no_veneer1 -// CHECK2-NEXT: 14: 0000801b 2 FUNC GLOBAL DEFAULT 1 __acle_se_no_veneer1 -// CHECK2-NEXT: 15: 0000801d 8 FUNC WEAK DEFAULT 1 no_veneer2 -// CHECK2-NEXT: 16: 00008023 2 FUNC WEAK DEFAULT 1 __acle_se_no_veneer2 - - -/// Note that foo retains its address from Import library 1 (0x000020009) -/// New entry functions, baz and qux, use addresses not used by Import library 1. -/// Import library 2 -// CHECK2: File: -// CHECK2: Symbol table '.symtab' contains 7 entries: -// CHECK2-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK2-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK2-NEXT: 1: 00008015 8 FUNC WEAK DEFAULT ABS no_veneer1 -// CHECK2-NEXT: 2: 0000801d 8 FUNC WEAK DEFAULT ABS no_veneer2 -// CHECK2-NEXT: 3: 00020001 8 FUNC WEAK DEFAULT ABS bar -// CHECK2-NEXT: 4: 00020009 8 FUNC GLOBAL DEFAULT ABS foo -// CHECK2-NEXT: 5: 00020011 8 FUNC GLOBAL DEFAULT ABS qux -// CHECK2-NEXT: 6: 00020019 8 FUNC WEAK DEFAULT ABS baz diff --git a/lld/test/ELF/arm-cmse-keep-sections.s b/lld/test/ELF/arm-cmse-keep-sections.s deleted file mode 100644 index 5157da7..0000000 --- a/lld/test/ELF/arm-cmse-keep-sections.s +++ /dev/null @@ -1,55 +0,0 @@ -// REQUIRES: arm -/// Create a secure app and import library using CMSE. -/// Create a non-secure app that refers symbols in the import library. - -// RUN: rm -rf %t && split-file %s %t && cd %t -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main cmse-implib.s -o implib.o -I%S/Inputs/ -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main cmse-secure-app.s -o secureapp.o -/// Create the secure app and import library. -// RUN: ld.lld -e secure_entry --section-start .gnu.sgstubs=0x1000000 --section-start SECURE1=0x10 --section-start SECURE2=0x2000000 --cmse-implib implib.o secureapp.o --out-implib=implib.lib -o secureapp --gc-sections -// RUN: llvm-readelf -s implib.lib | FileCheck %s -// RUN: llvm-objdump -d --no-show-raw-insn secureapp | FileCheck %s --check-prefix=DISS - - -// DISS-LABEL: <__acle_se_entry1>: -// DISS-NEXT: 10: nop - -// DISS-LABEL: : -// DISS-NEXT: 1000000: sg -// DISS-LABEL: b.w {{.*}} <__acle_se_entry2> - -// DISS-LABEL: : -// DISS-NEXT: 1000008: sg -// DISS-LABEL: b.w {{.*}} <__acle_se_entry1> - -// DISS-LABEL: <__acle_se_entry2>: -// DISS-NEXT: 2000000: nop - -// CHECK: Symbol table '.symtab' contains {{.*}} entries: -// CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK-NEXT: 1: 01000001 8 FUNC GLOBAL DEFAULT ABS entry2 -// CHECK-NEXT: 2: 01000009 8 FUNC GLOBAL DEFAULT ABS entry1 - -//--- cmse-implib.s - .include "arm-cmse-macros.s" - - .syntax unified - .section SECURE1, "ax" - - cmse_veneer entry1, function, global, function, global - - .syntax unified - .section SECURE2, "ax" - - cmse_veneer entry2, function, global, function, global - -//--- cmse-secure-app.s - .text - .align 2 - // Main entry point. - .global secure_entry - .thumb_func -secure_entry: - bx lr - .size secure_entry, .-secure_entry diff --git a/lld/test/ELF/arm-cmse-noveneers.s b/lld/test/ELF/arm-cmse-noveneers.s deleted file mode 100644 index 19e7a45..0000000 --- a/lld/test/ELF/arm-cmse-noveneers.s +++ /dev/null @@ -1,30 +0,0 @@ -// REQUIRES: arm -/// Test that addresses of existing secure gateway veneers are output in the CMSE import library. -/// Test that .gnu.sgstubs is size 0 when no linker synthesized secure gateway veneers are created. - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main %s -I %S/Inputs -o %t.o -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 %t.o -o %t --out-implib=%t.lib -// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s -// RUN: llvm-readelf -S %t | FileCheck %s --check-prefixes=SGSTUBSSIZE -// RUN: llvm-readelf -s %t.lib | FileCheck %s --check-prefixes=IMPLIBSYMS - -// CHECK: Disassembly of section .text: - -// CHECK-LABEL: : -// CHECK-NEXT: 8000: sg -// CHECK-NEXT: 8004: nop - -// CHECK-LABEL: <__acle_se_existing_veneer>: -// CHECK-NEXT: 8006: nop - - .include "arm-cmse-macros.s" - - cmse_no_veneer existing_veneer, function, global, function, global - -/// Name Type Address Off Size ES Flg Lk Inf Al -// SGSTUBSSIZE: .gnu.sgstubs PROGBITS 00020000 020000 000000 08 AX 0 0 32 - -// IMPLIBSYMS: Symbol table '.symtab' contains 2 entries: -// IMPLIBSYMS-NEXT: Num: Value Size Type Bind Vis Ndx Name -// IMPLIBSYMS-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// IMPLIBSYMS-NEXT: 1: 00008001 8 FUNC GLOBAL DEFAULT ABS existing_veneer diff --git a/lld/test/ELF/arm-cmse-secure.s b/lld/test/ELF/arm-cmse-secure.s deleted file mode 100644 index d6fb661..0000000 --- a/lld/test/ELF/arm-cmse-secure.s +++ /dev/null @@ -1,68 +0,0 @@ -// REQUIRES: arm -/// Create a secure app and import library using CMSE. -/// Create a non-secure app that refers symbols in the import library. - -// RUN: rm -rf %t && split-file %s %t && cd %t -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main cmse-implib.s -o implib.o -I%S/Inputs/ -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main cmse-secure-app.s -o secureapp.o -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main cmse-non-secure-app.s -o nonsecureapp.o -/// Create the secure app and import library. -// RUN: ld.lld -e secure_entry --section-start .gnu.sgstubs=0x20000 --cmse-implib implib.o secureapp.o --out-implib=implib.lib -o secureapp -/// Link the non-secure app against the import library. -// RUN: ld.lld -e nonsecure_entry -Ttext=0x8000 implib.lib nonsecureapp.o -o nonsecureapp -// RUN: llvm-readelf -s implib.lib | FileCheck %s -// RUN: llvm-objdump -d --no-show-raw-insn secureapp | FileCheck %s --check-prefixes=SECUREDISS -// RUN: llvm-objdump -d --no-show-raw-insn nonsecureapp | FileCheck %s --check-prefixes=NONSECUREDISS - -// SECUREDISS-LABEL: : -// SECUREDISS-NEXT: 20000: sg -// SECUREDISS-NEXT: b.w {{.*}} <__acle_se_entry> - -// SECUREDISS-LABEL: <__acle_se_entry>: -// SECUREDISS-NEXT: 20008: nop - -// SECUREDISS-LABEL: : -// SECUREDISS-NEXT: 2000c: bl {{.*}} <__acle_se_entry> -// SECUREDISS-NEXT: bx lr - -// NONSECUREDISS-LABEL: : -// NONSECUREDISS-NEXT: 8000: push {r0, lr} -// NONSECUREDISS-NEXT: bl 0x20000 -// NONSECUREDISS-NEXT: pop.w {r0, lr} -// NONSECUREDISS-NEXT: bx lr - -// CHECK: Symbol table '.symtab' contains 2 entries: -// CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name -// CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -// CHECK-NEXT: 1: 00020001 8 FUNC GLOBAL DEFAULT ABS entry - -//--- cmse-implib.s - .include "arm-cmse-macros.s" - - .syntax unified - .text - - cmse_veneer entry, function, global, function, global - -//--- cmse-secure-app.s - .align 2 - // Main entry point. - .global secure_entry - .thumb_func -secure_entry: - bl entry - bx lr - .size secure_entry, .-secure_entry - -//--- cmse-non-secure-app.s - .align 2 - .global nonsecure_entry - .thumb - .thumb_func - .type nonsecure_entry, %function -nonsecure_entry: - push {r0,lr} - bl entry - pop {r0,lr} - bx lr - .size nonsecure_entry, .-nonsecure_entry diff --git a/lld/test/ELF/arm-cmse-veneers.s b/lld/test/ELF/arm-cmse-veneers.s deleted file mode 100644 index e9b4e6d..0000000 --- a/lld/test/ELF/arm-cmse-veneers.s +++ /dev/null @@ -1,42 +0,0 @@ -// REQUIRES: arm -/// Test that symbol visibilities of pairs in the objects -/// are preserved in the executable. - -// RUN: llvm-mc -arm-add-build-attributes -filetype=obj --triple=thumbv8m.main %s -I %S/Inputs -o %t.o -// RUN: ld.lld --cmse-implib -Ttext=0x8000 --section-start .gnu.sgstubs=0x20000 %t.o -o %t -// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s -// RUN: llvm-readelf -s %t | FileCheck %s --check-prefixes=SYM - -// CHECK: Disassembly of section .gnu.sgstubs: - -// CHECK-LABEL: : -// CHECK-NEXT: 20000: sg -// CHECK-NEXT: b.w {{.*}} <__acle_se_weak_qux> -// CHECK-EMPTY: -// CHECK-LABEL: : -// CHECK-NEXT: 20008: sg -// CHECK-NEXT: b.w {{.*}} <__acle_se_global_baz> -// CHECK-EMPTY: -// CHECK-LABEL: : -// CHECK-NEXT: 20010: sg -// CHECK-NEXT: b.w {{.*}} <__acle_se_weak_bar> -// CHECK-EMPTY: -// CHECK-LABEL: : -// CHECK-NEXT: 20018: sg -// CHECK-NEXT: b.w {{.*}} <__acle_se_global_foo> - -// SYM: 00020019 {{.*}} GLOBAL {{.*}} global_foo -// SYM: 00008001 {{.*}} GLOBAL {{.*}} __acle_se_global_foo -// SYM: 00020011 {{.*}} WEAK {{.*}} weak_bar -// SYM: 00008005 {{.*}} WEAK {{.*}} __acle_se_weak_bar -// SYM: 00020009 {{.*}} GLOBAL {{.*}} global_baz -// SYM: 00008009 {{.*}} WEAK {{.*}} __acle_se_global_baz -// SYM: 00020001 {{.*}} WEAK {{.*}} weak_qux -// SYM: 0000800d {{.*}} GLOBAL {{.*}} __acle_se_weak_qux - - .include "arm-cmse-macros.s" - - cmse_veneer global_foo, function, global, function, global - cmse_veneer weak_bar, function, weak, function, weak - cmse_veneer global_baz, function, global, function, weak - cmse_veneer weak_qux, function, weak, function, global -- 2.7.4