75 lines · cpp
1//===- ROCm.cpp -------------------------------------------------*- C++ -*-===//2//3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// The purpose of this test is to showcase a more singular usage of LLD as a9// library, where only one LLD driver is being used (and linked in the target10// application). We also expect that linking twice the same object files11// would yield a successfull result. When used as library, LLD always cleans its12// internal memory context after each linker call.13//===----------------------------------------------------------------------===//14 15// When this flag is on, we actually need the MinGW driver library, not the16// ELF one. Here our test only covers the case where the ELF driver is linked17// into the unit test binary.18#ifndef LLD_DEFAULT_LD_LLD_IS_MINGW19 20#include "lld/Common/Driver.h"21#include "llvm/ADT/SmallString.h"22#include "llvm/Support/FileSystem.h"23#include "llvm/Support/FileUtilities.h"24#include "llvm/Support/Path.h"25#include "gmock/gmock.h"26#include <algorithm>27 28static std::string expand(const char *path) {29 if (!llvm::StringRef(path).contains("%"))30 return std::string(path);31 32 llvm::SmallString<256> thisPath;33 thisPath.append(getenv("LLD_SRC_DIR"));34 llvm::sys::path::append(thisPath, "unittests", "AsLibELF");35 36 std::string expanded(path);37 expanded.replace(expanded.find("%S"), 2, thisPath.data(), thisPath.size());38 return expanded;39}40 41LLD_HAS_DRIVER(elf)42 43static bool lldInvoke(const char *inPath, const char *outPath) {44 std::vector<const char *> args{"ld.lld", "-shared", inPath, "-o", outPath};45 lld::Result s = lld::lldMain(args, llvm::outs(), llvm::errs(),46 {{lld::Gnu, &lld::elf::link}});47 return !s.retCode && s.canRunAgain;48}49 50static bool runLinker(const char *path) {51 // Create a temp file for HSA code object.52 int tempHsacoFD = -1;53 llvm::SmallString<128> tempHsacoFilename;54 if (llvm::sys::fs::createTemporaryFile("kernel", "hsaco", tempHsacoFD,55 tempHsacoFilename)) {56 return false;57 }58 llvm::FileRemover cleanupHsaco(tempHsacoFilename);59 // Invoke lld. Expect a true return value from lld.60 std::string expandedPath = expand(path);61 if (!lldInvoke(expandedPath.data(), tempHsacoFilename.c_str())) {62 llvm::errs() << "Failed to link: " << expandedPath << "\n";63 return false;64 }65 return true;66}67 68TEST(AsLib, ROCm) {69 EXPECT_TRUE(runLinker("%S/Inputs/kernel1.o"));70 EXPECT_TRUE(runLinker("%S/Inputs/kernel2.o"));71 EXPECT_TRUE(runLinker("%S/Inputs/kernel1.o"));72 EXPECT_TRUE(runLinker("%S/Inputs/kernel2.o"));73}74#endif75