diff --git a/compiler-rt/lib/builtins/os_version_check.c b/compiler-rt/lib/builtins/os_version_check.c index ebfb2dfc72ddd3ae2dd3d2c97142bd79aeaebe79..b1a3dd0f3d989623daaf8ba05be9c8126cc25a8a 100644 --- a/compiler-rt/lib/builtins/os_version_check.c +++ b/compiler-rt/lib/builtins/os_version_check.c @@ -316,6 +316,38 @@ int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) { (IsPreRelease && Major == __ANDROID_API_FUTURE__); } +#elif __OHOS__ + +#include +#include +#include +#include + +static int OHVersion; +static int DistOsVersion; + +extern __attribute__((weak)) int OH_GetSdkApiVersion(void); +extern __attribute__((weak)) int OH_GetDistributionOSApiVersion(void); + +static void readOHOSVersion(void) { + OHVersion = OH_GetSdkApiVersion(); + DistOsVersion = OH_GetDistributionOSApiVersion(); +} + +int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) { + // `OH_GetSdkApiVersion()` and `OH_GetDistributionOSApiVersion()` are begining + // from API10. There are no longer any devices below API12 now. If there really + // is an API10 device (theoretically), we set the default value to 1 here. + if (Major < 10) + return 1; + + // Just readOHOSVersion once When first call `__isOSVersionAtLeast` + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, readOHOSVersion); + + return OHVersion > Major || (OHVersion == Major && DistOsVersion >= Subminor); +} + #else // Silence an empty translation unit warning. diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index d6babe9f74c256bcf7f16f29389bf7b6712413c2..04a1155ee402e988d8601df751b064271f4d2a16 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -150,6 +150,7 @@ struct Configuration { std::vector symbolOrderingFile; std::vector thinLTOModulesToCompile; std::vector undefined; + std::vector weakLibrary; // OHOS_LOCAL std::vector dynamicList; std::vector buildIdVector; llvm::MapVector, diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index daf16ed3ca444ad4c336df0c0201d7d8b672584c..22d0670cd2e8dc448bebadc938ff8f267604f8f9 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1081,6 +1081,7 @@ static void readConfigs(opt::InputArgList &args) { OPT_no_android_memtag_stack, false); config->androidMemtagMode = getMemtagMode(args); config->auxiliaryList = args::getStrings(args, OPT_auxiliary); + config->weakLibrary = args::getStrings(args, OPT_weak_library); // OHOS_LOCAL if (opt::Arg *arg = args.getLastArg(OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions, OPT_Bsymbolic_functions, OPT_Bsymbolic)) { diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 4e6c20f5c7f6014f4f23ed17b0962212966989c6..c2d5272d35942ccfb51fed6c6c7636318e0a8a35 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -362,6 +362,8 @@ defm rosegment: BB<"rosegment", defm rpath: Eq<"rpath", "Add a DT_RUNPATH to the output">; +defm weak_library: Eq<"ohos-weak-library", "Mark library and its references as weak imports">; // OHOS_LOCAL + def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; defm retain_symbols_file: diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 2d73481c417f6704f1edf48d632782db327fa06f..51e755eb17e5b048bc2d4259ce634e253b758ffa 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1416,9 +1416,20 @@ DynamicSection::computeContents() { addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH, part.dynStrTab->addString(config->rpath)); - for (SharedFile *file : ctx->sharedFiles) - if (file->isNeeded) - addInt(DT_NEEDED, part.dynStrTab->addString(file->soName)); + // OHOS_LOCAL begin + for (SharedFile *file : ctx->sharedFiles) { + if (file->isNeeded) { + StringRef fileSoName = file->soName; + // If this dylib is set as weak-library, we don't place it in DT_NEEDED + // rather in DT_OHOS_WEAK_LIBRARY. + if (llvm::any_of(config->weakLibrary, + [&](StringRef s) { return fileSoName.equals(s); })) + addInt(DT_OHOS_WEAK_LIBRARY, part.dynStrTab->addString(fileSoName)); + else + addInt(DT_NEEDED, part.dynStrTab->addString(fileSoName)); + } + } + // OHOS_LOCAL end if (isMain) { if (!config->soName.empty()) diff --git a/llvm/include/llvm/BinaryFormat/DynamicTags.def b/llvm/include/llvm/BinaryFormat/DynamicTags.def index ae25ec53813c7066ef6ea02e4896094bf3bcdcad..6abbfafa148ba12d203af27e84c8c040a2574359 100644 --- a/llvm/include/llvm/BinaryFormat/DynamicTags.def +++ b/llvm/include/llvm/BinaryFormat/DynamicTags.def @@ -91,6 +91,9 @@ DYNAMIC_TAG_MARKER(HIOS, 0x6FFFFFFF) // End of environment specific tags. DYNAMIC_TAG_MARKER(LOPROC, 0x70000000) // Start of processor specific tags. DYNAMIC_TAG_MARKER(HIPROC, 0x7FFFFFFF) // End of processor specific tags. +// OHOS_LOCAL begin +DYNAMIC_TAG(OHOS_WEAK_LIBRARY, 0x60000000) // weak library +// OHOS_LOCAL end // Android packed relocation section tags. // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#31 DYNAMIC_TAG(ANDROID_REL, 0x6000000F) diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp index 68c635abf99c43ada159ed57acd1a2a4116d62b7..b90cb9d0b75ff2cfbfc947637389e8a99d198fcf 100644 --- a/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/llvm/tools/llvm-objdump/ELFDump.cpp @@ -14,6 +14,7 @@ #include "ELFDump.h" #include "llvm-objdump.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Format.h" @@ -196,7 +197,9 @@ static void printDynamicSection(const ELFFile &Elf, StringRef Filename) { ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n"; if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH || Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME || - Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) { + Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER || + // OHOS_LOCAL + Dyn.d_tag == ELF::DT_OHOS_WEAK_LIBRARY) { Expected StrTabOrErr = getDynamicStrTab(Elf); if (StrTabOrErr) { const char *Data = StrTabOrErr.get().data(); diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index cf69601eab9356983238f8f7c3661b213cc8fc33..c373efe2303945c94939d72a0d048d62bdb6a928 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2429,6 +2429,7 @@ std::string ELFDumper::getDynamicEntry(uint64_t Type, case DT_ANDROID_RELASZ: return std::to_string(Value) + " (bytes)"; case DT_NEEDED: + case DT_OHOS_WEAK_LIBRARY: // OHOS_LOCAL case DT_SONAME: case DT_AUXILIARY: case DT_USED: @@ -2440,6 +2441,9 @@ std::string ELFDumper::getDynamicEntry(uint64_t Type, {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"}, {DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"}, {DT_RUNPATH, "Library runpath"}, + // OHOS_LOCAL begin + {DT_OHOS_WEAK_LIBRARY, "Weak Library"}, + // OHOS_LOCAL end }; return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")