am 86229aa6: Merge "libbcc: Fix build with gcc 4.8+"
* commit '86229aa68095a84aaab1ed53188e377d4df89b50':
libbcc: Fix build with gcc 4.8+
diff --git a/Android.mk b/Android.mk
index f9aa1ff..99fcb78 100644
--- a/Android.mk
+++ b/Android.mk
@@ -34,6 +34,9 @@
libmcldTarget \
libmcldLDVariant \
libmcldMC \
+ libmcldObject \
+ libmcldFragment \
+ libmcldCore \
libmcldSupport \
libmcldADT \
libmcldLD
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 319c5f4..a7ef88d 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -56,6 +56,7 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore_neon.bc_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore*.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libbcinfo_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/include/bcc/AndroidBitcode/ABCCompiler.h b/include/bcc/AndroidBitcode/ABCCompiler.h
index 91b8009..7164149 100644
--- a/include/bcc/AndroidBitcode/ABCCompiler.h
+++ b/include/bcc/AndroidBitcode/ABCCompiler.h
@@ -28,7 +28,10 @@
const ABCCompilerDriver &mDriver;
public:
- ABCCompiler(const ABCCompilerDriver &pDriver) : mDriver(pDriver) { }
+ ABCCompiler(const ABCCompilerDriver &pDriver) : mDriver(pDriver) {
+ // Disable LTO
+ enableLTO(false);
+ }
virtual ~ABCCompiler() { }
diff --git a/include/bcc/AndroidBitcode/ABCCompilerDriver.h b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
index 5f5ad7f..a740330 100644
--- a/include/bcc/AndroidBitcode/ABCCompilerDriver.h
+++ b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
@@ -39,7 +39,6 @@
CompilerConfig *mCompilerConfig;
LinkerConfig *mLinkerConfig;
- std::string mTriple;
std::string mAndroidSysroot;
private:
@@ -52,6 +51,10 @@
bool link(const Script &pScript, const std::string &input_relocatable,
int pOutputFd);
+private:
+ virtual CompilerConfig *createCompilerConfig() const = 0;
+ virtual LinkerConfig *createLinkerConfig() const = 0;
+
protected:
virtual const char **getNonPortableList() const {
return NULL;
@@ -61,7 +64,7 @@
virtual ABCExpandVAArgPass *createExpandVAArgPass() const = 0;
protected:
- ABCCompilerDriver(const std::string &pTriple);
+ ABCCompilerDriver();
public:
static ABCCompilerDriver *Create(const std::string &pTriple);
@@ -76,10 +79,6 @@
mAndroidSysroot = pAndroidSysroot;
}
- inline const std::string &getTriple() const {
- return mTriple;
- }
-
// Compile the bitcode and link the shared object
bool build(int pInputFd, int pOutputFd);
};
diff --git a/include/bcc/Linker.h b/include/bcc/Linker.h
index 6a3d7d1..6d824b4 100644
--- a/include/bcc/Linker.h
+++ b/include/bcc/Linker.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2012, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,17 @@
namespace mcld {
+class Module;
class TargetLDBackend;
-class MCLDDriver;
-class MemoryFactory;
-class MCLDInfo;
+class ObjectLinker;
+class ContextFactory;
+class LinkerConfig;
class TreeIteratorBase;
class Input;
+class InputFactory;
+class InputBuilder;
+class MemoryArea;
+class MemoryAreaFactory;
namespace sys { namespace fs {
@@ -38,7 +43,6 @@
namespace bcc {
-class MemoryFactory;
class LinkerConfig;
class Linker {
@@ -57,19 +61,23 @@
kReadSections,
kReadSymbols,
kAddAdditionalSymbols,
- kMaxErrorCode,
+ kMaxErrorCode
};
static const char *GetErrorString(enum ErrorCode pErrCode);
private:
+ const mcld::LinkerConfig *mLDConfig;
+ mcld::Module *mModule;
mcld::TargetLDBackend *mBackend;
- mcld::MCLDDriver *mDriver;
- MemoryFactory *mMemAreaFactory;
- mcld::MCLDInfo *mLDInfo;
+ mcld::ObjectLinker *mObjLinker;
+ mcld::InputFactory *mInputFactory;
+ mcld::MemoryAreaFactory *mMemAreaFactory;
+ mcld::ContextFactory *mContextFactory;
+ mcld::InputBuilder *mBuilder;
mcld::TreeIteratorBase *mRoot;
- bool mShared;
std::string mSOName;
+ mcld::MemoryArea* mOutput;
public:
Linker();
diff --git a/include/bcc/Renderscript/RSCompilerDriver.h b/include/bcc/Renderscript/RSCompilerDriver.h
index 66a60e4..e42ee73 100644
--- a/include/bcc/Renderscript/RSCompilerDriver.h
+++ b/include/bcc/Renderscript/RSCompilerDriver.h
@@ -49,7 +49,9 @@
RSExecutable *compileScript(RSScript &pScript,
const char* pScriptName,
const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps);
+ const char *pRuntimePath,
+ const RSInfo::DependencyTableTy &pDeps,
+ bool pSkipLoad);
public:
RSCompilerDriver();
@@ -61,12 +63,23 @@
inline void setRSRuntimeLookupContext(void *pContext)
{ mRSRuntime.setContext(pContext); }
+ RSCompiler *getCompiler() {
+ return &mCompiler;
+ }
+
+ void setConfig(CompilerConfig *config) {
+ mConfig = config;
+ }
+
// FIXME: This method accompany with loadScriptCache and compileScript should
// all be const-methods. They're not now because the getAddress() in
// SymbolResolverInterface is not a const-method.
RSExecutable *build(BCCContext &pContext,
const char *pCacheDir, const char *pResName,
- const char *pBitcode, size_t pBitcodeSize);
+ const char *pBitcode, size_t pBitcodeSize,
+ const char *pRuntimePath);
+ RSExecutable *build(RSScript &pScript, const char *pOut,
+ const char *pRuntimePath);
};
} // end namespace bcc
diff --git a/include/bcc/Renderscript/RSInfo.h b/include/bcc/Renderscript/RSInfo.h
index 91f4d7b..71be3c8 100644
--- a/include/bcc/Renderscript/RSInfo.h
+++ b/include/bcc/Renderscript/RSInfo.h
@@ -153,7 +153,7 @@
public:
// Calculate or load the SHA-1 information of the built-in dependencies.
- static void LoadBuiltInSHA1Information();
+ static bool LoadBuiltInSHA1Information();
// Return the path of the RS info file corresponded to the given output
// executable file.
diff --git a/include/bcc/Renderscript/RSScript.h b/include/bcc/Renderscript/RSScript.h
index 4522ada..7a6e07d 100644
--- a/include/bcc/Renderscript/RSScript.h
+++ b/include/bcc/Renderscript/RSScript.h
@@ -44,33 +44,49 @@
OptimizationLevel mOptimizationLevel;
+ bool mEmbedInfo;
+
private:
// This will be invoked when the containing source has been reset.
virtual bool doReset();
public:
- static bool LinkRuntime(RSScript &pScript);
+ static bool LinkRuntime(RSScript &pScript, const char *rt_path = NULL);
RSScript(Source &pSource);
// Set the associated RSInfo of the script.
- void setInfo(const RSInfo *pInfo)
- { mInfo = pInfo; }
+ void setInfo(const RSInfo *pInfo) {
+ mInfo = pInfo;
+ }
- const RSInfo *getInfo() const
- { return mInfo; }
+ const RSInfo *getInfo() const {
+ return mInfo;
+ }
- void setCompilerVersion(unsigned pCompilerVersion)
- { mCompilerVersion = pCompilerVersion; }
+ void setCompilerVersion(unsigned pCompilerVersion) {
+ mCompilerVersion = pCompilerVersion;
+ }
- unsigned getCompilerVersion() const
- { return mCompilerVersion; }
+ unsigned getCompilerVersion() const {
+ return mCompilerVersion;
+ }
- void setOptimizationLevel(OptimizationLevel pOptimizationLevel)
- { mOptimizationLevel = pOptimizationLevel; }
+ void setOptimizationLevel(OptimizationLevel pOptimizationLevel) {
+ mOptimizationLevel = pOptimizationLevel;
+ }
- OptimizationLevel getOptimizationLevel() const
- { return mOptimizationLevel; }
+ OptimizationLevel getOptimizationLevel() const {
+ return mOptimizationLevel;
+ }
+
+ void setEmbedInfo(bool pEnable) {
+ mEmbedInfo = pEnable;
+ }
+
+ bool getEmbedInfo() const {
+ return mEmbedInfo;
+ }
};
} // end namespace bcc
diff --git a/include/bcc/Renderscript/RSTransforms.h b/include/bcc/Renderscript/RSTransforms.h
index 79b7bd7..3094ba9 100644
--- a/include/bcc/Renderscript/RSTransforms.h
+++ b/include/bcc/Renderscript/RSTransforms.h
@@ -29,6 +29,8 @@
createRSForEachExpandPass(const RSInfo::ExportForeachFuncListTy &pForeachFuncs,
bool pEnableStepOpt);
+llvm::ModulePass * createRSEmbedInfoPass(const RSInfo *info);
+
} // end namespace bcc
#endif // BCC_RS_TRANSFORMS_H
diff --git a/include/bcc/Support/FileBase.h b/include/bcc/Support/FileBase.h
index c201f97..637ced2 100644
--- a/include/bcc/Support/FileBase.h
+++ b/include/bcc/Support/FileBase.h
@@ -38,15 +38,10 @@
};
enum FlagEnum {
- // The openning file is a binary file.
kBinary = 1 << 0,
-
- // The openning file will be truncated to length 0.
kTruncate = 1 << 1,
-
- // The openning file will put its file pointer to the end of the file before
- // each write.
kAppend = 1 << 2,
+ kDeleteOnClose = 1 << 3
};
enum LockModeEnum {
@@ -82,6 +77,9 @@
// True true if we should call unlock() in destructor.
bool mShouldUnlock;
+ // True if file should be deleted in destructor.
+ bool mShouldDelete;
+
// Open mName with flag mOpenFlags (using POSIX open().)
bool open();
diff --git a/include/bcc/Support/FileMutex.h b/include/bcc/Support/FileMutex.h
index 15c9f01..82f14b0 100644
--- a/include/bcc/Support/FileMutex.h
+++ b/include/bcc/Support/FileMutex.h
@@ -27,7 +27,7 @@
class FileMutex : public FileBase {
public:
FileMutex(const std::string &pFileToLock)
- : FileBase(pFileToLock + ".lock", O_RDONLY | O_CREAT, 0) { }
+ : FileBase(pFileToLock + ".lock", O_RDONLY | O_CREAT, kDeleteOnClose) { }
// Provide a lock() interface filled with default configuration.
inline bool lock(bool pNonblocking = true,
diff --git a/include/bcc/Support/LinkerConfig.h b/include/bcc/Support/LinkerConfig.h
index d1ab0b1..dfd2d91 100644
--- a/include/bcc/Support/LinkerConfig.h
+++ b/include/bcc/Support/LinkerConfig.h
@@ -19,7 +19,7 @@
#include <string>
-#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LinkerConfig.h>
#include <mcld/Support/TargetRegistry.h>
#include <mcld/LD/DiagnosticLineInfo.h>
#include <mcld/LD/DiagnosticPrinter.h>
@@ -32,7 +32,6 @@
// Available Configurations
//===--------------------------------------------------------------------===//
const std::string mTriple;
- bool mShared;
std::string mSOName;
private:
@@ -42,7 +41,7 @@
const mcld::Target *mTarget;
bool initializeTarget();
- mcld::MCLDInfo *mLDInfo;
+ mcld::LinkerConfig *mLDConfig;
bool initializeLDInfo();
mcld::DiagnosticLineInfo *mDiagLineInfo;
@@ -50,6 +49,26 @@
bool initializeDiagnostic();
public:
+ enum ZOptionEnum {
+ kCombReloc = 1 << 0, ///< [on] -z combreloc, [off] -z nocombreloc
+ kDefs = 1 << 1, ///< -z defs
+ kExecStack = 1 << 2, ///< [on] -z execstack, [off] -z noexecstack
+ kInitFirst = 1 << 3, ///< -z initfirst
+ kInterPose = 1 << 4, ///< -z interpose
+ kLoadFltr = 1 << 5, ///< -z loadfltr
+ kMulDefs = 1 << 6, ///< -z muldefs
+ kNoCopyReloc = 1 << 7, ///< -z nocopyreloc
+ kNoDefaultLib = 1 << 8, ///< -z nodefaultlib
+ kNoDelete = 1 << 9, ///< -z nodelete
+ kNoDLOpen = 1 << 10, ///< -z nodlopen
+ kNoDump = 1 << 11, ///< -z nodump
+ kRelro = 1 << 12, ///< [on] -z relro, [off] -z norelro
+ kLazy = 1 << 13, ///< [on] -z lazy, [off] -z now
+ kOrigin = 1 << 14, ///< -z origin
+ kZOptionMask = 0xFFFF
+ };
+
+public:
//===--------------------------------------------------------------------===//
// Getters
//===--------------------------------------------------------------------===//
@@ -59,14 +78,13 @@
inline const mcld::Target *getTarget() const
{ return mTarget; }
- inline mcld::MCLDInfo* getLDInfo()
- { return mLDInfo; }
+ inline mcld::LinkerConfig* getLDConfig()
+ { return mLDConfig; }
- inline const mcld::MCLDInfo* getLDInfo() const
- { return mLDInfo; }
+ inline const mcld::LinkerConfig* getLDConfig() const
+ { return mLDConfig; }
- inline bool isShared() const
- { return mShared; }
+ bool isShared() const;
inline std::string getSOName() const
{ return mSOName; }
@@ -81,6 +99,8 @@
void setSysRoot(const std::string &pSysRoot);
+ void setZOption(unsigned int pOptions);
+
void addWrap(const std::string &pWrapSymbol);
void addPortable(const std::string &pPortableSymbol);
diff --git a/include/bcc/Support/TargetCompilerConfigs.h b/include/bcc/Support/TargetCompilerConfigs.h
index 181fd80..391a0eb 100644
--- a/include/bcc/Support/TargetCompilerConfigs.h
+++ b/include/bcc/Support/TargetCompilerConfigs.h
@@ -26,18 +26,39 @@
// ARM
//===----------------------------------------------------------------------===//
#if defined(PROVIDE_ARM_CODEGEN)
-class ARMCompilerConfig : public CompilerConfig {
+class ARMBaseCompilerConfig : public CompilerConfig {
private:
bool mEnableNEON;
+ bool mInThumbMode;
+
+ static bool HasThumb2();
static void GetFeatureVector(std::vector<std::string> &pAttributes,
- bool pEnableNEON);
+ bool pInThumbMode, bool pEnableNEON);
+
+protected:
+ ARMBaseCompilerConfig(const std::string &pTriple, bool pInThumbMode);
public:
- ARMCompilerConfig();
-
// Return true if config has been changed after returning from this function.
bool enableNEON(bool pEnable = true);
+
+ bool isInThumbMode() const
+ { return mInThumbMode; }
+};
+
+class ARMCompilerConfig : public ARMBaseCompilerConfig {
+public:
+ ARMCompilerConfig()
+ : ARMBaseCompilerConfig(DEFAULT_ARM_TRIPLE_STRING,
+ /* pInThumbMode */false) { }
+};
+
+class ThumbCompilerConfig : public ARMBaseCompilerConfig {
+public:
+ ThumbCompilerConfig()
+ : ARMBaseCompilerConfig(DEFAULT_THUMB_TRIPLE_STRING,
+ /* pInThumbMode */true) { }
};
#endif // defined(PROVIDE_ARM_CODEGEN)
diff --git a/include/bcc/Support/TargetLinkerConfigs.h b/include/bcc/Support/TargetLinkerConfigs.h
index c0b488b..fd7b7df 100644
--- a/include/bcc/Support/TargetLinkerConfigs.h
+++ b/include/bcc/Support/TargetLinkerConfigs.h
@@ -81,6 +81,16 @@
#endif
{ };
+#if !defined(TARGET_BUILD)
+//===----------------------------------------------------------------------===//
+// General target
+//===----------------------------------------------------------------------===//
+class GeneralLinkerConfig : public LinkerConfig {
+public:
+ GeneralLinkerConfig(const std::string& pTriple);
+};
+#endif // !defined(TARGET_BUILD)
+
} // end namespace bcc
#endif // BCC_SUPPORT_LINKER_CONFIG_H
diff --git a/lib/AndroidBitcode/ABCCompilerDriver.cpp b/lib/AndroidBitcode/ABCCompilerDriver.cpp
index 4eb33e6..1e5e906 100644
--- a/lib/AndroidBitcode/ABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/ABCCompilerDriver.cpp
@@ -44,10 +44,9 @@
namespace bcc {
-ABCCompilerDriver::ABCCompilerDriver(const std::string &pTriple)
+ABCCompilerDriver::ABCCompilerDriver()
: mContext(), mCompiler(*this), mLinker(),
- mCompilerConfig(NULL), mLinkerConfig(NULL),
- mTriple(pTriple), mAndroidSysroot("/") {
+ mCompilerConfig(NULL), mLinkerConfig(NULL), mAndroidSysroot("/") {
}
ABCCompilerDriver::~ABCCompilerDriver() {
@@ -60,7 +59,7 @@
return true;
}
- mCompilerConfig = new (std::nothrow) CompilerConfig(mTriple);
+ mCompilerConfig = createCompilerConfig();
if (mCompilerConfig == NULL) {
ALOGE("Out of memory when create the compiler configuration!");
return false;
@@ -88,7 +87,7 @@
return true;
}
- mLinkerConfig = new (std::nothrow) LinkerConfig(mTriple);
+ mLinkerConfig = createLinkerConfig();
if (mLinkerConfig == NULL) {
ALOGE("Out of memory when create the linker configuration!");
return false;
@@ -118,6 +117,11 @@
// -Bsymbolic.
mLinkerConfig->setBsymbolic(true);
+ // Set kRelro for -z relro
+ // Not set kExecStack for -z noexecstack
+ // Not set kLazy for -z now
+ mLinkerConfig->setZOption(LinkerConfig::kRelro);
+
// Config the linker.
Linker::ErrorCode result = mLinker.config(*mLinkerConfig);
if (result != Linker::kSuccess) {
@@ -230,19 +234,21 @@
switch (llvm::Triple::getArchTypeForLLVMName(target->getName())) {
#if defined(PROVIDE_ARM_CODEGEN)
- case llvm::Triple::arm:
+ case llvm::Triple::arm: {
+ return new ARMABCCompilerDriver(/* pInThumbMode */false);
+ }
case llvm::Triple::thumb: {
- return new ARMABCCompilerDriver(pTriple);
+ return new ARMABCCompilerDriver(/* pInThumbMode */true);
}
#endif
#if defined(PROVIDE_MIPS_CODEGEN)
case llvm::Triple::mipsel: {
- return new MipsABCCompilerDriver(pTriple);
+ return new MipsABCCompilerDriver();
}
#endif
#if defined(PROVIDE_X86_CODEGEN)
case llvm::Triple::x86: {
- return new X86ABCCompilerDriver(pTriple);
+ return new X86ABCCompilerDriver();
}
#endif
default: {
diff --git a/lib/AndroidBitcode/ABCExpandVAArgPass.cpp b/lib/AndroidBitcode/ABCExpandVAArgPass.cpp
index 7b89ced..1f0debf 100644
--- a/lib/AndroidBitcode/ABCExpandVAArgPass.cpp
+++ b/lib/AndroidBitcode/ABCExpandVAArgPass.cpp
@@ -19,6 +19,7 @@
#include "bcc/AndroidBitcode/ABCExpandVAArgPass.h"
+#include <llvm/ADT/STLExtras.h>
#include <llvm/Instructions.h>
#include <llvm/Support/InstIterator.h>
@@ -33,7 +34,8 @@
// process va_arg inst
for (llvm::inst_iterator inst = llvm::inst_begin(pFunc),
- inst_end = llvm::inst_end(pFunc); inst != inst_end; inst++) {
+ inst_end = llvm::inst_end(pFunc), next_inst = llvm::next(inst);
+ inst != inst_end; inst = next_inst++) {
if (inst->getOpcode() == llvm::Instruction::VAArg) {
llvm::Value *v = expandVAArg(&*inst);
inst->replaceAllUsesWith(v);
diff --git a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp
new file mode 100644
index 0000000..f019bde
--- /dev/null
+++ b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ARM/ARMABCCompilerDriver.h"
+
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
+namespace bcc {
+
+CompilerConfig *ARMABCCompilerDriver::createCompilerConfig() const {
+ if (mInThumbMode) {
+ return new (std::nothrow) ThumbCompilerConfig();
+ } else {
+ return new (std::nothrow) ARMCompilerConfig();
+ }
+}
+
+LinkerConfig *ARMABCCompilerDriver::createLinkerConfig() const {
+ return new (std::nothrow) ARMLinkerConfig();
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
index 29f4f0a..97e5f8d 100644
--- a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
+++ b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
@@ -22,13 +22,24 @@
namespace bcc {
class ARMABCCompilerDriver : public ABCCompilerDriver {
+private:
+ bool mInThumbMode;
+
public:
- ARMABCCompilerDriver(const std::string &pTriple)
- : ABCCompilerDriver(pTriple) { }
+ ARMABCCompilerDriver(bool pInThumbMode)
+ : ABCCompilerDriver(), mInThumbMode(pInThumbMode) { }
virtual ~ARMABCCompilerDriver() { }
+public:
+ inline bool IsInThumbMode() const {
+ return mInThumbMode;
+ }
+
private:
+ virtual CompilerConfig *createCompilerConfig() const;
+ virtual LinkerConfig *createLinkerConfig() const;
+
virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
};
diff --git a/lib/AndroidBitcode/Android.mk b/lib/AndroidBitcode/Android.mk
index 806202c..0befc55 100644
--- a/lib/AndroidBitcode/Android.mk
+++ b/lib/AndroidBitcode/Android.mk
@@ -27,6 +27,7 @@
ABCCompilerDriver.cpp
libbcc_arm_androidbitcode_SRC_FILES := \
+ ARM/ARMABCCompilerDriver.cpp \
ARM/ARMABCExpandVAArg.cpp
libbcc_mips_androidbitcode_SRC_FILES := \
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
index 54b9d61..326920a 100644
--- a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
@@ -16,6 +16,9 @@
#include "Mips/MipsABCCompilerDriver.h"
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
namespace {
static const char *MipsNonPortableList[] = {
@@ -37,6 +40,14 @@
namespace bcc {
+CompilerConfig *MipsABCCompilerDriver::createCompilerConfig() const {
+ return new (std::nothrow) MipsCompilerConfig();
+}
+
+LinkerConfig *MipsABCCompilerDriver::createLinkerConfig() const {
+ return new (std::nothrow) MipsLinkerConfig();
+}
+
const char **MipsABCCompilerDriver::getNonPortableList() const {
return MipsNonPortableList;
}
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
index 7cfc34f..6cdecc5 100644
--- a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
@@ -23,12 +23,14 @@
class MipsABCCompilerDriver : public ABCCompilerDriver {
public:
- MipsABCCompilerDriver(const std::string &pTriple)
- : ABCCompilerDriver(pTriple) { }
+ MipsABCCompilerDriver() : ABCCompilerDriver() { }
virtual ~MipsABCCompilerDriver() { }
private:
+ virtual CompilerConfig *createCompilerConfig() const;
+ virtual LinkerConfig *createLinkerConfig() const;
+
virtual const char **getNonPortableList() const;
virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
index 171da7c..e8f0159 100644
--- a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
@@ -16,6 +16,9 @@
#include "X86/X86ABCCompilerDriver.h"
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
namespace {
static const char *X86NonPortableList[] = {
@@ -36,6 +39,16 @@
namespace bcc {
+CompilerConfig *X86ABCCompilerDriver::createCompilerConfig() const {
+ // x86-64 is currently unsupported.
+ return new (std::nothrow) X86_32CompilerConfig();
+}
+
+LinkerConfig *X86ABCCompilerDriver::createLinkerConfig() const {
+ // x86-64 is currently unsupported.
+ return new (std::nothrow) X86_32LinkerConfig();
+}
+
const char **X86ABCCompilerDriver::getNonPortableList() const {
return X86NonPortableList;
}
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
index af52866..aed2f56 100644
--- a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
@@ -23,12 +23,14 @@
class X86ABCCompilerDriver : public ABCCompilerDriver {
public:
- X86ABCCompilerDriver(const std::string &pTriple)
- : ABCCompilerDriver(pTriple) { }
+ X86ABCCompilerDriver() : ABCCompilerDriver() { }
virtual ~X86ABCCompilerDriver() { }
private:
+ virtual CompilerConfig *createCompilerConfig() const;
+ virtual LinkerConfig *createLinkerConfig() const;
+
virtual const char **getNonPortableList() const;
virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
diff --git a/lib/Core/Linker.cpp b/lib/Core/Linker.cpp
index e6cbc95..775be70 100644
--- a/lib/Core/Linker.cpp
+++ b/lib/Core/Linker.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2012, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,18 @@
#include "bcc/Linker.h"
#include "bcc/Support/LinkerConfig.h"
-#include "bcc/Support/MemoryFactory.h"
#include "bcc/Support/Log.h"
#include <llvm/Support/ELF.h>
-#include <mcld/MC/MCLDDriver.h>
-#include <mcld/MC/InputTree.h>
-#include <mcld/MC/MCLinker.h>
-#include <mcld/MC/InputTree.h>
+#include <mcld/Module.h>
+#include <mcld/IRBuilder.h>
+#include <mcld/InputTree.h>
+#include <mcld/Object/ObjectLinker.h>
+#include <mcld/Fragment/FragmentLinker.h>
+#include <mcld/MC/InputFactory.h>
+#include <mcld/MC/ContextFactory.h>
+#include <mcld/MC/InputBuilder.h>
#include <mcld/LD/LDSection.h>
#include <mcld/LD/LDContext.h>
#include <mcld/Target/TargetLDBackend.h>
@@ -79,13 +82,15 @@
// Linker
//===----------------------------------------------------------------------===//
Linker::Linker()
- : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
- mRoot(NULL), mShared(false) {
+ : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
+ mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
+ mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
}
Linker::Linker(const LinkerConfig& pConfig)
- : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
- mRoot(NULL), mShared(false) {
+ : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
+ mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
+ mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
const std::string &triple = pConfig.getTriple();
@@ -99,42 +104,57 @@
}
Linker::~Linker() {
- delete mDriver;
+ delete mModule;
+ delete mObjLinker;
+ // FIXME: current implementation can not change the order of deleting
+ // ObjectLinker and TargetLDBackend. Because the deletion of relocation list
+ // in FragmentLinker (FragmentLinker is deleted by ObjectLinker) depends on
+ // RelocationFactory in TargetLDBackend
delete mBackend;
- delete mMemAreaFactory;
+ delete mBuilder;
delete mRoot;
}
enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
- mLDInfo = const_cast<mcld::MCLDInfo*>(pConfig.getLDInfo());
- if (mLDInfo == NULL) {
+ mLDConfig = pConfig.getLDConfig();
+ if (mLDConfig == NULL) {
return kDelegateLDInfo;
}
-
- mRoot = new mcld::InputTree::iterator(mLDInfo->inputs().root());
- mShared = pConfig.isShared();
- mSOName = pConfig.getSOName();
-
return kSuccess;
}
enum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) {
- if (mLDInfo != NULL) {
+ if (mLDConfig != NULL) {
return kDoubleConfig;
}
extractFiles(pConfig);
- mBackend = pConfig.getTarget()->createLDBackend(pConfig.getTriple());
+ mBackend = pConfig.getTarget()->createLDBackend(*mLDConfig);
if (mBackend == NULL) {
return kCreateBackend;
}
- mMemAreaFactory = new MemoryFactory();
+ mInputFactory = new mcld::InputFactory(32, *mLDConfig);
- mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend, *mMemAreaFactory);
+ mContextFactory = new mcld::ContextFactory(32);
+ /* 32 is a magic number, the estimated number of input files **/
- mDriver->initMCLinker();
+ mMemAreaFactory = new mcld::MemoryAreaFactory(32);
+
+ mBuilder = new mcld::InputBuilder(*mLDConfig,
+ *mInputFactory,
+ *mContextFactory,
+ *mMemAreaFactory,
+ true); // delegated
+
+ mModule = new mcld::Module(mLDConfig->options().soname());
+
+ mRoot = new mcld::InputTree::iterator(mModule->getInputTree().root());
+
+ mObjLinker = new mcld::ObjectLinker(*mLDConfig, *mModule, *mBuilder, *mBackend);
+
+ mObjLinker->initFragmentLinker();
return kSuccess;
}
@@ -160,43 +180,42 @@
return pCode;
}
- mcld::LDContext *input_context = mLDInfo->contextFactory().produce(pPath);
- pInput.setContext(input_context);
+ mBuilder->setContext(pInput);
return kSuccess;
}
enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) {
- mcld::sys::fs::Path* path = NULL;
+ const mcld::sys::fs::Path* path = NULL;
// find out the real path of the namespec.
- if (mLDInfo->attrFactory().constraint().isSharedSystem()) {
+ if (mLDConfig->attribute().constraint().isSharedSystem()) {
// In the system with shared object support, we can find both archive
// and shared object.
- if (mLDInfo->attrFactory().last().isStatic()) {
+ if (mInputFactory->attr().isStatic()) {
// with --static, we must search an archive.
- path = mLDInfo->options().directories().find(pNameSpec,
- mcld::Input::Archive);
+ path = mLDConfig->options().directories().find(pNameSpec,
+ mcld::Input::Archive);
}
else {
// otherwise, with --Bdynamic, we can find either an archive or a
// shared object.
- path = mLDInfo->options().directories().find(pNameSpec,
- mcld::Input::DynObj);
+ path = mLDConfig->options().directories().find(pNameSpec,
+ mcld::Input::DynObj);
}
}
else {
// In the system without shared object support, we only look for an
// archive.
- path = mLDInfo->options().directories().find(pNameSpec,
+ path = mLDConfig->options().directories().find(pNameSpec,
mcld::Input::Archive);
}
if (NULL == path)
return kFindNameSpec;
- mcld::Input* input = mLDInfo->inputFactory().produce(pNameSpec, *path,
- mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
+ mcld::Input* input = mInputFactory->produce(pNameSpec, *path,
+ mcld::Input::Unknown);
+ mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -205,11 +224,11 @@
/// addObject - Add a object file by the filename.
enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) {
- mcld::Input* input = mLDInfo->inputFactory().produce(pObjectPath,
- pObjectPath,
- mcld::Input::Unknown);
+ mcld::Input* input = mInputFactory->produce(pObjectPath,
+ pObjectPath,
+ mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
+ mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -219,165 +238,120 @@
/// addObject - Add a piece of memory. The memory is of ELF format.
enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) {
- mcld::Input* input = mLDInfo->inputFactory().produce("memory object",
- "NAN",
- mcld::Input::Unknown);
+ mcld::Input* input = mInputFactory->produce("memory object", "NAN",
+ mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
+ mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
input->setMemArea(input_memory);
- mcld::LDContext *input_context = mLDInfo->contextFactory().produce();
+ mcld::LDContext *input_context = mContextFactory->produce();
input->setContext(input_context);
return kSuccess;
}
enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) {
- mcld::Input* input = mLDInfo->inputFactory().produce("code object",
- "NAN",
- mcld::Input::External);
+ mcld::Input* input = mInputFactory->produce("code object", "NAN",
+ mcld::Input::External);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
+ mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
input->setMemArea(input_memory);
- mcld::LDContext *input_context = mLDInfo->contextFactory().produce();
+ mcld::LDContext *input_context = mContextFactory->produce();
input->setContext(input_context);
- // FIXME: So far, MCLinker must set up output before add input files.
+ // FIXME: So far, FragmentLinker must set up output before add input files.
// set up LDContext
- if (mDriver->hasInitLinker()) {
+ if (mObjLinker->hasInitLinker()) {
return kNotConfig;
}
- if (!mLDInfo->output().hasContext()) {
- return kNotSetUpOutput;
- }
-
// create NULL section
- mcld::LDSection& null =
- mDriver->getLinker()->createSectHdr("",
- mcld::LDFileFormat::Null,
- llvm::ELF::SHT_NULL,
- 0);
-
- null.setSize(0);
- null.setOffset(0);
- null.setIndex(0);
- null.setInfo(0);
- null.setAlign(0);
-
- input_context->getSectionTable().push_back(&null);
+ mcld::LDSection* null = mcld::IRBuilder::CreateELFHeader(*input, "",
+ llvm::ELF::SHT_NULL, 0, 0);
+ null->setSize(0);
+ null->setOffset(0);
+ null->setInfo(0);
// create .text section
- mcld::LDSection& text = mDriver->getLinker()->createSectHdr(".text",
- mcld::LDFileFormat::Regular,
+ mcld::LDSection* text = mcld::IRBuilder::CreateELFHeader(*input, ".text",
llvm::ELF::SHT_PROGBITS,
- llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR);
+ llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+ 1);
- text.setSize(pSize);
- text.setOffset(0x0);
- text.setIndex(1);
- text.setInfo(0);
- text.setAlign(1);
-
- input_context->getSectionTable().push_back(&text);
+ text->setSize(pSize);
+ text->setOffset(0x0);
+ text->setInfo(0);
return kSuccess;
}
enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) {
- if (mLDInfo->output().hasContext()) {
- return kDoubleConfig;
- }
-
// ----- initialize output file ----- //
-
mcld::FileHandle::Permission perm = 0755;
- mcld::MemoryArea* out_area = mMemAreaFactory->produce(
+ mOutput = mMemAreaFactory->produce(
pPath,
mcld::FileHandle::ReadWrite |
mcld::FileHandle::Truncate |
mcld::FileHandle::Create,
perm);
- if (!out_area->handler()->isGood()) {
+ if (!mOutput->handler()->isGood()) {
return kOpenOutput;
}
- if (mShared) {
- mLDInfo->output().setType(mcld::Output::DynObj);
- } else {
- mLDInfo->output().setType(mcld::Output::Exec);
- }
-
- mLDInfo->output().setSOName(mSOName);
- mLDInfo->output().setMemArea(out_area);
- mLDInfo->output().setContext(mLDInfo->contextFactory().produce(pPath));
-
- // FIXME: We must initialize MCLinker before setOutput, and initialize
- // standard sections here. This is because we have to build the section
- // map before input files using it.
- if (!mDriver->hasInitLinker()) {
- return kNotConfig;
- }
-
- mDriver->initStdSections();
-
return kSuccess;
}
enum Linker::ErrorCode Linker::setOutput(int pFileHandler) {
- if (mLDInfo->output().hasContext()) {
- return kDoubleConfig;
+ mOutput = mMemAreaFactory->produce(pFileHandler, mcld::FileHandle::ReadWrite);
+
+ if (!mOutput->handler()->isGood()) {
+ return kOpenOutput;
}
- // ----- initialize output file ----- //
- mcld::MemoryArea* out_area = mMemAreaFactory->produce(pFileHandler);
-
- mLDInfo->output().setType(mcld::Output::DynObj);
- mLDInfo->output().setMemArea(out_area);
- mLDInfo->output().setContext(mLDInfo->contextFactory().produce());
-
- // FIXME: We must initialize MCLinker before setOutput, and initialize
- // standard sections here. This is because we have to build the section
- // map before input files using it.
- if (!mDriver->hasInitLinker()) {
- return kNotConfig;
- }
-
- mDriver->initStdSections();
-
return kSuccess;
}
enum Linker::ErrorCode Linker::link() {
- mDriver->normalize();
+ if (NULL == mOutput)
+ return kNotSetUpOutput;
- if (!mDriver->mergeSections()) {
- return kReadSections;
+ if (!mObjLinker->hasInitLinker()) {
+ return kNotConfig;
}
- if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) {
+ mObjLinker->initStdSections();
+
+ mObjLinker->normalize();
+
+ if (!mObjLinker->readRelocations())
+ return kReadSections;
+
+ if (!mObjLinker->mergeSections())
+ return kReadSections;
+
+ if (!mObjLinker->addStandardSymbols() || !mObjLinker->addTargetSymbols()) {
return kAddAdditionalSymbols;
}
- mDriver->readRelocations();
- mDriver->prelayout();
- mDriver->layout();
- mDriver->postlayout();
- mDriver->finalizeSymbolValue();
- mDriver->relocation();
- mDriver->emitOutput();
- mDriver->postProcessing();
+ mObjLinker->scanRelocations();
+ mObjLinker->prelayout();
+ mObjLinker->layout();
+ mObjLinker->postlayout();
+ mObjLinker->finalizeSymbolValue();
+ mObjLinker->relocation();
+ mObjLinker->emitOutput(*mOutput);
+ mObjLinker->postProcessing(*mOutput);
return kSuccess;
}
diff --git a/lib/Renderscript/Android.mk b/lib/Renderscript/Android.mk
index 6989d5b..bbd1e64 100644
--- a/lib/Renderscript/Android.mk
+++ b/lib/Renderscript/Android.mk
@@ -24,6 +24,7 @@
libbcc_renderscript_SRC_FILES := \
RSCompiler.cpp \
RSCompilerDriver.cpp \
+ RSEmbedInfo.cpp \
RSExecutable.cpp \
RSForEachExpand.cpp \
RSInfo.cpp \
diff --git a/lib/Renderscript/RSCompiler.cpp b/lib/Renderscript/RSCompiler.cpp
index 7ba1cff..ce43e8b 100644
--- a/lib/Renderscript/RSCompiler.cpp
+++ b/lib/Renderscript/RSCompiler.cpp
@@ -106,6 +106,9 @@
// Expand ForEach on CPU path to reduce launch overhead.
rs_passes.add(createRSForEachExpandPass(info->getExportForeachFuncs(),
/* pEnableStepOpt */ true));
+ if (script.getEmbedInfo()) {
+ rs_passes.add(createRSEmbedInfoPass(info));
+ }
// Execute the pass.
rs_passes.run(module);
diff --git a/lib/Renderscript/RSCompilerDriver.cpp b/lib/Renderscript/RSCompilerDriver.cpp
index c854b69..1251c3c 100644
--- a/lib/Renderscript/RSCompilerDriver.cpp
+++ b/lib/Renderscript/RSCompilerDriver.cpp
@@ -184,7 +184,9 @@
RSCompilerDriver::compileScript(RSScript &pScript,
const char* pScriptName,
const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps) {
+ const char *pRuntimePath,
+ const RSInfo::DependencyTableTy &pDeps,
+ bool pSkipLoad) {
android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
RSExecutable *result = NULL;
RSInfo *info = NULL;
@@ -209,7 +211,7 @@
//===--------------------------------------------------------------------===//
// Link RS script with Renderscript runtime.
//===--------------------------------------------------------------------===//
- if (!RSScript::LinkRuntime(pScript)) {
+ if (!RSScript::LinkRuntime(pScript, pRuntimePath)) {
ALOGE("Failed to link script '%s' with Renderscript runtime!", pScriptName);
return NULL;
}
@@ -276,6 +278,12 @@
return NULL;
}
+ // No need to produce an RSExecutable in this case.
+ // TODO: Error handling in this case is nonexistent.
+ if (pSkipLoad) {
+ return NULL;
+ }
+
//===--------------------------------------------------------------------===//
// Create the RSExecutable.
//===--------------------------------------------------------------------===//
@@ -317,7 +325,8 @@
const char *pCacheDir,
const char *pResName,
const char *pBitcode,
- size_t pBitcodeSize) {
+ size_t pBitcodeSize,
+ const char *pRuntimePath) {
android::StopWatch build_time("bcc: RSCompilerDriver::build time");
//===--------------------------------------------------------------------===//
// Check parameters.
@@ -393,7 +402,8 @@
//===--------------------------------------------------------------------===//
// Compile the script
//===--------------------------------------------------------------------===//
- result = compileScript(*script, pResName, output_path.c_str(), dep_info);
+ result = compileScript(*script, pResName, output_path.c_str(), pRuntimePath,
+ dep_info, false);
// Script is no longer used. Free it to get more memory.
delete script;
@@ -404,3 +414,23 @@
return result;
}
+
+
+RSExecutable *RSCompilerDriver::build(RSScript &pScript, const char *pOut,
+ const char *pRuntimePath) {
+ RSInfo::DependencyTableTy dep_info;
+ RSInfo *info = RSInfo::ExtractFromSource(pScript.getSource(), dep_info);
+ if (info == NULL) {
+ return NULL;
+ }
+ pScript.setInfo(info);
+
+ // Embed the info string directly in the ELF, since this path is for an
+ // offline (host) compilation.
+ pScript.setEmbedInfo(true);
+
+ RSExecutable *result = compileScript(pScript, pOut, pOut, pRuntimePath,
+ dep_info, true);
+ return result;
+}
+
diff --git a/lib/Renderscript/RSEmbedInfo.cpp b/lib/Renderscript/RSEmbedInfo.cpp
new file mode 100644
index 0000000..faa71bf
--- /dev/null
+++ b/lib/Renderscript/RSEmbedInfo.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcc/Assert.h"
+#include "bcc/Renderscript/RSTransforms.h"
+
+#include <cstdlib>
+#include <vector>
+
+#include <llvm/DerivedTypes.h>
+#include <llvm/Function.h>
+#include <llvm/Instructions.h>
+#include <llvm/IRBuilder.h>
+#include <llvm/Module.h>
+#include <llvm/Pass.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Type.h>
+
+#include "bcc/Config/Config.h"
+#include "bcc/Renderscript/RSInfo.h"
+#include "bcc/Support/Log.h"
+
+using namespace bcc;
+
+namespace {
+
+/* RSForEachExpandPass - This pass operates on functions that are able to be
+ * called via rsForEach() or "foreach_<NAME>". We create an inner loop for the
+ * ForEach-able function to be invoked over the appropriate data cells of the
+ * input/output allocations (adjusting other relevant parameters as we go). We
+ * support doing this for any ForEach-able compute kernels. The new function
+ * name is the original function name followed by ".expand". Note that we
+ * still generate code for the original function.
+ */
+class RSEmbedInfoPass : public llvm::ModulePass {
+private:
+ static char ID;
+
+ llvm::Module *M;
+ llvm::LLVMContext *C;
+
+ const RSInfo *mInfo;
+
+public:
+ RSEmbedInfoPass(const RSInfo *info)
+ : ModulePass(ID),
+ mInfo(info) {
+ }
+
+ virtual bool runOnModule(llvm::Module &M) {
+ this->M = &M;
+ C = &M.getContext();
+
+ std::string str;
+ llvm::raw_string_ostream s(str);
+
+ // We use a simple text format here that the compatibility library can
+ // easily parse. Each section starts out with its name followed by a count.
+ // The count denotes the number of lines to parse for that particular
+ // category. Variables and Functions merely put the appropriate identifier
+ // on the line, while ForEach kernels have the encoded int signature,
+ // followed by a hyphen followed by the identifier (function to look up).
+ // Object Slots are just listed as one integer per line.
+ const RSInfo::ExportVarNameListTy &export_vars = mInfo->getExportVarNames();
+ s << "exportVarCount: " << (unsigned int) export_vars.size() << "\n";
+ for (RSInfo::ExportVarNameListTy::const_iterator
+ export_var_iter = export_vars.begin(),
+ export_var_end = export_vars.end();
+ export_var_iter != export_var_end; export_var_iter++) {
+ s << *export_var_iter << "\n";
+ }
+
+ const RSInfo::ExportFuncNameListTy &export_funcs =
+ mInfo->getExportFuncNames();
+ s << "exportFuncCount: " << (unsigned int) export_funcs.size() << "\n";
+ for (RSInfo::ExportFuncNameListTy::const_iterator
+ export_func_iter = export_funcs.begin(),
+ export_func_end = export_funcs.end();
+ export_func_iter != export_func_end; export_func_iter++) {
+ s << *export_func_iter << "\n";
+ }
+
+ const RSInfo::ExportForeachFuncListTy &export_foreach_funcs =
+ mInfo->getExportForeachFuncs();
+ s << "exportForEachCount: "
+ << (unsigned int) export_foreach_funcs.size() << "\n";
+ for (RSInfo::ExportForeachFuncListTy::const_iterator
+ foreach_func_iter = export_foreach_funcs.begin(),
+ foreach_func_end = export_foreach_funcs.end();
+ foreach_func_iter != foreach_func_end; foreach_func_iter++) {
+ std::string name(foreach_func_iter->first);
+ s << foreach_func_iter->second << " - "
+ << foreach_func_iter->first << "\n";
+ }
+
+ std::vector<unsigned int> object_slot_numbers;
+ unsigned int i = 0;
+ const RSInfo::ObjectSlotListTy &object_slots = mInfo->getObjectSlots();
+ for (RSInfo::ObjectSlotListTy::const_iterator
+ slots_iter = object_slots.begin(),
+ slots_end = object_slots.end();
+ slots_iter != slots_end; slots_iter++) {
+ if (*slots_iter) {
+ object_slot_numbers.push_back(i);
+ }
+ i++;
+ }
+ s << "objectSlotCount: " << (unsigned int) object_slot_numbers.size()
+ << "\n";
+ for (i = 0; i < object_slot_numbers.size(); i++) {
+ s << object_slot_numbers[i] << "\n";
+ }
+
+ s.flush();
+
+ // Embed this as the global variable .rs.info so that it will be
+ // accessible from the shared object later.
+ llvm::Constant *Init = llvm::ConstantDataArray::getString(*C, str);
+ llvm::GlobalVariable *InfoGV =
+ new llvm::GlobalVariable(M, Init->getType(), true,
+ llvm::GlobalValue::ExternalLinkage, Init,
+ ".rs.info");
+ (void) InfoGV;
+
+ return true;
+ }
+
+ virtual const char *getPassName() const {
+ return "Embed Renderscript Info";
+ }
+
+}; // end RSEmbedInfoPass
+
+} // end anonymous namespace
+
+char RSEmbedInfoPass::ID = 0;
+
+namespace bcc {
+
+llvm::ModulePass *
+createRSEmbedInfoPass(const RSInfo *info) {
+ return new RSEmbedInfoPass(info);
+}
+
+} // end namespace bcc
diff --git a/lib/Renderscript/RSExecutable.cpp b/lib/Renderscript/RSExecutable.cpp
index c73fd5e..b918835 100644
--- a/lib/Renderscript/RSExecutable.cpp
+++ b/lib/Renderscript/RSExecutable.cpp
@@ -28,11 +28,11 @@
using namespace bcc;
const char *RSExecutable::SpecialFunctionNames[] = {
- "root",
- "init",
- ".rs.dtor",
- // Must be NULL-terminated.
- NULL
+ "root", // Graphics drawing function or compute kernel.
+ "init", // Initialization routine called implicitly on startup.
+ ".rs.dtor", // Static global destructor for a script instance.
+ ".rs.info", // Variable containing string of RS metadata info.
+ NULL // Must be NULL-terminated.
};
RSExecutable *RSExecutable::Create(RSInfo &pInfo,
diff --git a/lib/Renderscript/RSInfo.cpp b/lib/Renderscript/RSInfo.cpp
index dbf8657..ff6a0a2 100644
--- a/lib/Renderscript/RSInfo.cpp
+++ b/lib/Renderscript/RSInfo.cpp
@@ -21,6 +21,7 @@
#include <cstring>
#include <new>
+#include <string>
#include "bcc/Support/FileBase.h"
#include "bcc/Support/Log.h"
@@ -43,17 +44,18 @@
const uint8_t *RSInfo::LibCLCoreNEONSHA1 = NULL;
#endif
-void RSInfo::LoadBuiltInSHA1Information() {
+bool RSInfo::LoadBuiltInSHA1Information() {
+#ifdef TARGET_BUILD
if (LibBCCSHA1 != NULL) {
// Loaded before.
- return;
+ return true;
}
void *h = ::dlopen("/system/lib/libbcc.sha1.so", RTLD_LAZY | RTLD_NOW);
if (h == NULL) {
ALOGE("Failed to load SHA-1 information from shared library '"
"/system/lib/libbcc.sha1.so'! (%s)", ::dlerror());
- return;
+ return false;
}
LibBCCSHA1 = reinterpret_cast<const uint8_t *>(::dlsym(h, "libbcc_so_SHA1"));
@@ -65,7 +67,10 @@
reinterpret_cast<const uint8_t *>(::dlsym(h, "libclcore_neon_bc_SHA1"));
#endif
- return;
+ return true;
+#else // TARGET_BUILD
+ return false;
+#endif // TARGET_BUILD
}
android::String8 RSInfo::GetPath(const FileBase &pFile) {
@@ -315,33 +320,36 @@
RSInfo::FloatPrecision RSInfo::getFloatPrecisionRequirement() const {
// Check to see if we have any FP precision-related pragmas.
- static const char relaxed_pragma[] = "rs_fp_relaxed";
- static const char imprecise_pragma[] = "rs_fp_imprecise";
- static const char full_pragma[] = "rs_fp_full";
+ std::string relaxed_pragma("rs_fp_relaxed");
+ std::string imprecise_pragma("rs_fp_imprecise");
+ std::string full_pragma("rs_fp_full");
bool relaxed_pragma_seen = false;
- RSInfo::FloatPrecision result;
+ bool imprecise_pragma_seen = false;
+ RSInfo::FloatPrecision result = FP_Full;
for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
pragma_end = mPragmas.end(); pragma_iter != pragma_end;
pragma_iter++) {
const char *pragma_key = pragma_iter->first;
- if (::strcmp(pragma_key, relaxed_pragma) == 0) {
- relaxed_pragma_seen = true;
- } else if (::strcmp(pragma_key, imprecise_pragma) == 0) {
- if (relaxed_pragma_seen) {
- ALOGW("Multiple float precision pragmas specified!");
+ if (!relaxed_pragma.compare(pragma_key)) {
+ if (relaxed_pragma_seen || imprecise_pragma_seen) {
+ ALOGE("Multiple float precision pragmas specified!");
}
- // Fast return when there's rs_fp_imprecise specified.
- result = FP_Imprecise;
+ relaxed_pragma_seen = true;
+ } else if (!imprecise_pragma.compare(pragma_key)) {
+ if (relaxed_pragma_seen || imprecise_pragma_seen) {
+ ALOGE("Multiple float precision pragmas specified!");
+ }
+ imprecise_pragma_seen = true;
}
}
// Imprecise is selected over Relaxed precision.
// In the absence of both, we stick to the default Full precision.
- if (relaxed_pragma_seen) {
+ if (imprecise_pragma_seen) {
+ result = FP_Imprecise;
+ } else if (relaxed_pragma_seen) {
result = FP_Relaxed;
- } else {
- result = FP_Full;
}
// Provide an override for precsion via adb shell setprop
@@ -352,13 +360,13 @@
property_get("debug.rs.precision", precision_prop_buf, "");
if (precision_prop_buf[0]) {
- if (::strcmp(precision_prop_buf, relaxed_pragma) == 0) {
+ if (!relaxed_pragma.compare(precision_prop_buf)) {
ALOGI("Switching to RS FP relaxed mode via setprop");
result = FP_Relaxed;
- } else if (::strcmp(precision_prop_buf, imprecise_pragma) == 0) {
+ } else if (!imprecise_pragma.compare(precision_prop_buf)) {
ALOGI("Switching to RS FP imprecise mode via setprop");
result = FP_Imprecise;
- } else if (::strcmp(precision_prop_buf, full_pragma) == 0) {
+ } else if (!full_pragma.compare(precision_prop_buf)) {
ALOGI("Switching to RS FP full mode via setprop");
result = FP_Full;
}
diff --git a/lib/Renderscript/RSInfoExtractor.cpp b/lib/Renderscript/RSInfoExtractor.cpp
index 4ba5703..c0775b5 100644
--- a/lib/Renderscript/RSInfoExtractor.cpp
+++ b/lib/Renderscript/RSInfoExtractor.cpp
@@ -360,46 +360,46 @@
}
#undef FOR_EACH_NODE_IN
- //===--------------------------------------------------------------------===//
- // Record built-in dependency information.
- //===--------------------------------------------------------------------===//
- LoadBuiltInSHA1Information();
-
- if (!writeDependency(LibBCCPath, LibBCCSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-
- if (!writeDependency(LibRSPath, LibRSSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-
- if (!writeDependency(LibCLCorePath, LibCLCoreSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-
-#if defined(ARCH_ARM_HAVE_NEON)
- if (!writeDependency(LibCLCoreNEONPath, LibCLCoreNEONSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-#endif
-
- //===--------------------------------------------------------------------===//
- // Record dependency information.
- //===--------------------------------------------------------------------===//
- for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
- if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second,
+ if (LoadBuiltInSHA1Information()) {
+ //===------------------------------------------------------------------===//
+ // Record built-in dependency information.
+ //===------------------------------------------------------------------===//
+ if (!writeDependency(LibBCCPath, LibBCCSHA1,
result->mStringPool, &cur_string_pool_offset,
result->mDependencyTable)) {
goto bail;
}
+
+ if (!writeDependency(LibRSPath, LibRSSHA1,
+ result->mStringPool, &cur_string_pool_offset,
+ result->mDependencyTable)) {
+ goto bail;
+ }
+
+ if (!writeDependency(LibCLCorePath, LibCLCoreSHA1,
+ result->mStringPool, &cur_string_pool_offset,
+ result->mDependencyTable)) {
+ goto bail;
+ }
+
+#if defined(ARCH_ARM_HAVE_NEON)
+ if (!writeDependency(LibCLCoreNEONPath, LibCLCoreNEONSHA1,
+ result->mStringPool, &cur_string_pool_offset,
+ result->mDependencyTable)) {
+ goto bail;
+ }
+#endif
+
+ //===------------------------------------------------------------------===//
+ // Record dependency information.
+ //===------------------------------------------------------------------===//
+ for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
+ if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second,
+ result->mStringPool, &cur_string_pool_offset,
+ result->mDependencyTable)) {
+ goto bail;
+ }
+ }
}
//===--------------------------------------------------------------------===//
diff --git a/lib/Renderscript/RSScript.cpp b/lib/Renderscript/RSScript.cpp
index 75cfff9..53c8946 100644
--- a/lib/Renderscript/RSScript.cpp
+++ b/lib/Renderscript/RSScript.cpp
@@ -22,7 +22,7 @@
using namespace bcc;
-bool RSScript::LinkRuntime(RSScript &pScript) {
+bool RSScript::LinkRuntime(RSScript &pScript, const char *rt_path) {
// Using the same context with the source in pScript.
BCCContext &context = pScript.getSource().getContext();
const char* core_lib = RSInfo::LibCLCorePath;
@@ -37,6 +37,10 @@
}
#endif
+ if (rt_path != NULL) {
+ core_lib = rt_path;
+ }
+
Source *libclcore_source = Source::CreateFromFile(context, core_lib);
if (libclcore_source == NULL) {
ALOGE("Failed to load Renderscript library '%s' to link!", core_lib);
diff --git a/lib/Renderscript/runtime/math.ll b/lib/Renderscript/runtime/math.ll
index 4ea2b10..dd4dc4b 100644
--- a/lib/Renderscript/runtime/math.ll
+++ b/lib/Renderscript/runtime/math.ll
@@ -3,14 +3,35 @@
declare float @llvm.sqrt.f32(float)
declare float @llvm.pow.f32(float, float)
+declare float @llvm.fabs.f32(float)
+declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
+declare <3 x float> @llvm.fabs.v3f32(<3 x float>)
+declare <4 x float> @llvm.fabs.v4f32(<4 x float>)
-define float @_Z4sqrtf(float %v) {
+define float @_Z4sqrtf(float %v) nounwind readnone alwaysinline {
%1 = tail call float @llvm.sqrt.f32(float %v)
ret float %1
}
-define float @_Z3powf(float %v1, float %v2) {
+define float @_Z3powf(float %v1, float %v2) nounwind readnone alwaysinline {
%1 = tail call float @llvm.pow.f32(float %v1, float %v2)
ret float %1
}
+define float @_Z4fabsf(float %v) nounwind readnone alwaysinline {
+ %1 = tail call float @llvm.fabs.f32(float %v)
+ ret float %1
+}
+define <2 x float> @_Z4fabsDv2_f(<2 x float> %v) nounwind readnone alwaysinline {
+ %1 = tail call <2 x float> @llvm.fabs.v2f32(<2 x float> %v)
+ ret <2 x float> %1
+}
+define <3 x float> @_Z4fabsDv3_f(<3 x float> %v) nounwind readnone alwaysinline {
+ %1 = tail call <3 x float> @llvm.fabs.v3f32(<3 x float> %v)
+ ret <3 x float> %1
+}
+define <4 x float> @_Z4fabsDv4_f(<4 x float> %v) nounwind readnone alwaysinline {
+ %1 = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %v)
+ ret <4 x float> %1
+}
+
diff --git a/lib/Renderscript/runtime/rs_allocation.c b/lib/Renderscript/runtime/rs_allocation.c
index dbfb76e..949b7b3 100644
--- a/lib/Renderscript/runtime/rs_allocation.c
+++ b/lib/Renderscript/runtime/rs_allocation.c
@@ -36,7 +36,7 @@
extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a, uint32_t x) {
Allocation_t *alloc = (Allocation_t *)a.p;
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
return &p[eSize * x];
}
@@ -44,18 +44,18 @@
extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
Allocation_t *alloc = (Allocation_t *)a.p;
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
- const uint32_t stride = alloc->mHal.drvState.stride;
+ const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
return &p[(eSize * x) + (y * stride)];
}
extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
Allocation_t *alloc = (Allocation_t *)a.p;
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
- const uint32_t stride = alloc->mHal.drvState.stride;
+ const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
const uint32_t dimY = alloc->mHal.state.dimensionY;
return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
}
@@ -71,3 +71,88 @@
rs_element returnElem = {type->mHal.state.element};
return returnElem;
}
+
+// TODO: this needs to be optimized, obviously
+static void memcpy(void* dst, void* src, size_t size) {
+ char* dst_c = (char*) dst, *src_c = (char*) src;
+ for (; size > 0; size--) {
+ *dst_c++ = *src_c++;
+ }
+}
+
+extern void __attribute__((overloadable))
+ rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
+ Allocation_t *alloc = (Allocation_t *)a.p;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
+ const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
+ memcpy((void*)&p[eSize * x], ptr, eSize);
+}
+
+extern void __attribute__((overloadable))
+ rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
+ Allocation_t *alloc = (Allocation_t *)a.p;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
+ const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
+ const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
+ memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
+}
+
+#define SET_ELEMENT_AT(T) \
+ extern void __attribute__((overloadable)) \
+ __rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) { \
+ Allocation_t *alloc = (Allocation_t *)a.p; \
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; \
+ const uint32_t eSize = sizeof(T); \
+ *((T*)&p[(eSize * x)]) = val; \
+ } \
+ extern void __attribute__((overloadable)) \
+ __rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
+ Allocation_t *alloc = (Allocation_t *)a.p; \
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; \
+ const uint32_t eSize = sizeof(T); \
+ const uint32_t stride = alloc->mHal.drvState.lod[0].stride; \
+ *((T*)&p[(eSize * x) + (y * stride)]) = val; \
+ }
+
+SET_ELEMENT_AT(char)
+SET_ELEMENT_AT(char2)
+SET_ELEMENT_AT(char3)
+SET_ELEMENT_AT(char4)
+SET_ELEMENT_AT(uchar)
+SET_ELEMENT_AT(uchar2)
+SET_ELEMENT_AT(uchar3)
+SET_ELEMENT_AT(uchar4)
+SET_ELEMENT_AT(short)
+SET_ELEMENT_AT(short2)
+SET_ELEMENT_AT(short3)
+SET_ELEMENT_AT(short4)
+SET_ELEMENT_AT(ushort)
+SET_ELEMENT_AT(ushort2)
+SET_ELEMENT_AT(ushort3)
+SET_ELEMENT_AT(ushort4)
+SET_ELEMENT_AT(int)
+SET_ELEMENT_AT(int2)
+SET_ELEMENT_AT(int3)
+SET_ELEMENT_AT(int4)
+SET_ELEMENT_AT(uint)
+SET_ELEMENT_AT(uint2)
+SET_ELEMENT_AT(uint3)
+SET_ELEMENT_AT(uint4)
+SET_ELEMENT_AT(long)
+SET_ELEMENT_AT(long2)
+SET_ELEMENT_AT(long3)
+SET_ELEMENT_AT(long4)
+SET_ELEMENT_AT(ulong)
+SET_ELEMENT_AT(ulong2)
+SET_ELEMENT_AT(ulong3)
+SET_ELEMENT_AT(ulong4)
+SET_ELEMENT_AT(float)
+SET_ELEMENT_AT(float2)
+SET_ELEMENT_AT(float3)
+SET_ELEMENT_AT(float4)
+SET_ELEMENT_AT(double)
+SET_ELEMENT_AT(double2)
+SET_ELEMENT_AT(double3)
+SET_ELEMENT_AT(double4)
+
+#undef SET_ELEMENT_AT
diff --git a/lib/Renderscript/runtime/rs_cl.c b/lib/Renderscript/runtime/rs_cl.c
index b6c2b6a..858161d 100644
--- a/lib/Renderscript/runtime/rs_cl.c
+++ b/lib/Renderscript/runtime/rs_cl.c
@@ -404,8 +404,10 @@
extern float __attribute__((overloadable)) expm1(float);
FN_FUNC_FN(expm1)
-extern float __attribute__((overloadable)) fabs(float);
-FN_FUNC_FN(fabs)
+extern float __attribute__((overloadable)) fabs(float v);
+extern float2 __attribute__((overloadable)) fabs(float2 v);
+extern float3 __attribute__((overloadable)) fabs(float3 v);
+extern float4 __attribute__((overloadable)) fabs(float4 v);
extern float __attribute__((overloadable)) fdim(float, float);
FN_FUNC_FN_FN(fdim)
diff --git a/lib/Renderscript/runtime/rs_sample.c b/lib/Renderscript/runtime/rs_sample.c
index b41e7f1..6c34368 100644
--- a/lib/Renderscript/runtime/rs_sample.c
+++ b/lib/Renderscript/runtime/rs_sample.c
@@ -9,7 +9,7 @@
getElementAt(rs_allocation a, uint32_t x, uint32_t lod) {
Allocation_t *alloc = (Allocation_t *)a.p;
const Type_t *type = (const Type_t*)alloc->mHal.state.type;
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
const uint32_t offset = type->mHal.state.lodOffset[lod];
const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
@@ -21,13 +21,13 @@
getElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t lod) {
Allocation_t *alloc = (Allocation_t *)a.p;
const Type_t *type = (const Type_t*)alloc->mHal.state.type;
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
+ const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
const uint32_t offset = type->mHal.state.lodOffset[lod];
uint32_t stride;
if(lod == 0) {
- stride = alloc->mHal.drvState.stride;
+ stride = alloc->mHal.drvState.lod[0].stride;
} else {
stride = type->mHal.state.lodDimX[lod] * eSize;
}
diff --git a/lib/Renderscript/runtime/rs_structs.h b/lib/Renderscript/runtime/rs_structs.h
index 710dd31..3d90463 100644
--- a/lib/Renderscript/runtime/rs_structs.h
+++ b/lib/Renderscript/runtime/rs_structs.h
@@ -47,8 +47,16 @@
} state;
struct DrvState {
- void * mallocPtr;
- uint32_t stride;
+ struct LodState {
+ void * mallocPtr;
+ size_t stride;
+ uint32_t dimX;
+ uint32_t dimY;
+ uint32_t dimZ;
+ } lod[16/*android::renderscript::Allocation::MAX_LOD*/];
+ size_t faceOffset;
+ uint32_t lodCount;
+ uint32_t faceCount;
} drvState;
} mHal;
} Allocation_t;
diff --git a/lib/Support/FileBase.cpp b/lib/Support/FileBase.cpp
index 579d78f..5dc9944 100644
--- a/lib/Support/FileBase.cpp
+++ b/lib/Support/FileBase.cpp
@@ -16,11 +16,14 @@
#include "bcc/Support/FileBase.h"
+#include "bcc/Support/Log.h"
+
#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cerrno>
+#include <cstring>
#include <new>
#include <utils/FileMap.h>
@@ -33,7 +36,8 @@
: mFD(-1),
mError(),
mName(pFilename), mOpenFlags(pOpenFlags),
- mShouldUnlock(false) {
+ mShouldUnlock(false),
+ mShouldDelete(false) {
// Process pFlags
#ifdef O_BINARY
if (pFlags & kBinary) {
@@ -48,6 +52,10 @@
mOpenFlags |= O_APPEND;
}
+ if (pFlags & kDeleteOnClose) {
+ mShouldDelete = true;
+ }
+
// Open the file.
open();
@@ -282,5 +290,11 @@
::close(mFD);
mFD = -1;
}
+ if (mShouldDelete) {
+ int res = ::remove(mName.c_str());
+ if (res != 0) {
+ ALOGE("Failed to remove file: %s - %s", mName.c_str(), ::strerror(res));
+ }
+ }
return;
}
diff --git a/lib/Support/Initialization.cpp b/lib/Support/Initialization.cpp
index 6951a05..32be882 100644
--- a/lib/Support/Initialization.cpp
+++ b/lib/Support/Initialization.cpp
@@ -55,10 +55,10 @@
LLVMInitializeARMTargetMC();
LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget();
- LLVMInitializeARMLDTargetInfo();
- LLVMInitializeARMLDTarget();
- LLVMInitializeARMLDBackend();
- LLVMInitializeARMDiagnosticLineInfo();
+ MCLDInitializeARMLDTargetInfo();
+ MCLDInitializeARMLDTarget();
+ MCLDInitializeARMLDBackend();
+ MCLDInitializeARMDiagnosticLineInfo();
#endif
#if defined(PROVIDE_MIPS_CODEGEN)
@@ -69,10 +69,10 @@
LLVMInitializeMipsTargetMC();
LLVMInitializeMipsTargetInfo();
LLVMInitializeMipsTarget();
- LLVMInitializeMipsLDTargetInfo();
- LLVMInitializeMipsLDTarget();
- LLVMInitializeMipsLDBackend();
- LLVMInitializeMipsDiagnosticLineInfo();
+ MCLDInitializeMipsLDTargetInfo();
+ MCLDInitializeMipsLDTarget();
+ MCLDInitializeMipsLDBackend();
+ MCLDInitializeMipsDiagnosticLineInfo();
#endif
#if defined(PROVIDE_X86_CODEGEN)
@@ -83,10 +83,10 @@
LLVMInitializeX86TargetMC();
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
- LLVMInitializeX86LDTargetInfo();
- LLVMInitializeX86LDTarget();
- LLVMInitializeX86LDBackend();
- LLVMInitializeX86DiagnosticLineInfo();
+ MCLDInitializeX86LDTargetInfo();
+ MCLDInitializeX86LDTarget();
+ MCLDInitializeX86LDBackend();
+ MCLDInitializeX86DiagnosticLineInfo();
#endif
is_initialized = true;
diff --git a/lib/Support/LinkerConfig.cpp b/lib/Support/LinkerConfig.cpp
index bdbde23..70ba64f 100644
--- a/lib/Support/LinkerConfig.cpp
+++ b/lib/Support/LinkerConfig.cpp
@@ -19,9 +19,9 @@
#include <llvm/Support/Signals.h>
-#include <mcld/MC/MCLDInfo.h>
-#include <mcld/MC/MCLDFile.h>
+#include <mcld/LinkerConfig.h>
#include <mcld/MC/MCLDDirectory.h>
+#include <mcld/MC/ZOption.h>
#include <mcld/LD/TextDiagnosticPrinter.h>
#include <mcld/Support/Path.h>
#include <mcld/Support/MsgHandling.h>
@@ -30,7 +30,7 @@
using namespace bcc;
LinkerConfig::LinkerConfig(const std::string &pTriple)
- : mTriple(pTriple), mShared(false), mSOName(), mTarget(NULL), mLDInfo(NULL),
+ : mTriple(pTriple), mSOName(), mTarget(NULL), mLDConfig(NULL),
mDiagLineInfo(NULL), mDiagPrinter(NULL) {
initializeTarget();
@@ -39,7 +39,7 @@
}
LinkerConfig::~LinkerConfig() {
- delete mLDInfo;
+ delete mLDConfig;
if (mDiagPrinter->getNumErrors() != 0) {
// If here, the program failed ungracefully. Run the interrupt handlers to
@@ -66,58 +66,219 @@
}
bool LinkerConfig::initializeLDInfo() {
- if (NULL != mLDInfo) {
+ if (NULL != mLDConfig) {
ALOGE("Cannot initialize mcld::MCLDInfo for given triple '%s!\n",
mTriple.c_str());
return false;
}
- mLDInfo = new mcld::MCLDInfo(getTriple(), 1, 32);
+ mLDConfig = new mcld::LinkerConfig(getTriple());
+ mLDConfig->setCodeGenType(mcld::LinkerConfig::Exec);
+
+ struct NameMap {
+ const char* from;
+ const char* to;
+ };
+
+ static const NameMap map[] =
+ {
+ {".text", ".text"},
+ {".rodata", ".rodata"},
+ {".data.rel.ro.local", ".data.rel.ro.local"},
+ {".data.rel.ro", ".data.rel.ro"},
+ {".data", ".data"},
+ {".bss", ".bss"},
+ {".tdata", ".tdata"},
+ {".tbss", ".tbss"},
+ {".init_array", ".init_array"},
+ {".fini_array", ".fini_array"},
+ // TODO: Support DT_INIT_ARRAY for all constructors?
+ {".ctors", ".ctors"},
+ {".dtors", ".dtors"},
+ // FIXME: in GNU ld, if we are creating a shared object .sdata2 and .sbss2
+ // sections would be handled differently.
+ {".sdata2", ".sdata"},
+ {".sbss2", ".sbss"},
+ {".sdata", ".sdata"},
+ {".sbss", ".sbss"},
+ {".lrodata", ".lrodata"},
+ {".ldata", ".ldata"},
+ {".lbss", ".lbss"},
+ {".gcc_except_table", ".gcc_except_table"},
+ {".gnu.linkonce.d.rel.ro.local", ".data.rel.ro.local"},
+ {".gnu.linkonce.d.rel.ro", ".data.rel.ro"},
+ {".gnu.linkonce.r", ".rodata"},
+ {".gnu.linkonce.d", ".data"},
+ {".gnu.linkonce.b", ".bss"},
+ {".gnu.linkonce.sb2", ".sbss"},
+ {".gnu.linkonce.sb", ".sbss"},
+ {".gnu.linkonce.s2", ".sdata"},
+ {".gnu.linkonce.s", ".sdata"},
+ {".gnu.linkonce.wi", ".debug_info"},
+ {".gnu.linkonce.td", ".tdata"},
+ {".gnu.linkonce.tb", ".tbss"},
+ {".gnu.linkonce.t", ".text"},
+ {".gnu.linkonce.lr", ".lrodata"},
+ {".gnu.linkonce.lb", ".lbss"},
+ {".gnu.linkonce.l", ".ldata"},
+ };
+
+ if (mLDConfig->codeGenType() != mcld::LinkerConfig::Object) {
+ const unsigned int map_size = (sizeof(map) / sizeof(map[0]) );
+ for (unsigned int i = 0; i < map_size; ++i) {
+ bool exist = false;
+ mLDConfig->scripts().sectionMap().append(map[i].from,
+ map[i].to,
+ exist);
+ }
+ }
return true;
}
bool LinkerConfig::initializeDiagnostic() {
// Set up MsgHandler.
+ mDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *mLDConfig);
+
+ mcld::InitializeDiagnosticEngine(*mLDConfig, mDiagPrinter);
+
mDiagLineInfo = mTarget->createDiagnosticLineInfo(*mTarget, mTriple);
- mDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *mLDInfo);
-
- mcld::InitializeDiagnosticEngine(*mLDInfo, mDiagLineInfo, mDiagPrinter);
-
+ mcld::getDiagnosticEngine().setLineInfo(*mDiagLineInfo);
return true;
}
+bool LinkerConfig::isShared() const {
+ return (mcld::LinkerConfig::DynObj == mLDConfig->codeGenType());
+}
+
void LinkerConfig::setShared(bool pEnable) {
- mShared = pEnable;
+ if (pEnable)
+ mLDConfig->setCodeGenType(mcld::LinkerConfig::DynObj);
+ else
+ mLDConfig->setCodeGenType(mcld::LinkerConfig::Exec);
return;
}
void LinkerConfig::setBsymbolic(bool pEnable) {
- mLDInfo->options().setBsymbolic(pEnable);
+ mLDConfig->options().setBsymbolic(pEnable);
return;
}
void LinkerConfig::setSOName(const std::string &pSOName) {
- mSOName = pSOName;
+ mLDConfig->options().setSOName(pSOName);
return;
}
void LinkerConfig::setDyld(const std::string &pDyld) {
- mLDInfo->options().setDyld(pDyld);
+ mLDConfig->options().setDyld(pDyld);
return;
}
void LinkerConfig::setSysRoot(const std::string &pSysRoot) {
- mLDInfo->options().setSysroot(mcld::sys::fs::Path(pSysRoot));
+ mLDConfig->options().setSysroot(mcld::sys::fs::Path(pSysRoot));
return;
}
+void LinkerConfig::setZOption(unsigned int pOptions) {
+ mcld::ZOption option;
+ if (pOptions & kCombReloc) {
+ option.setKind(mcld::ZOption::CombReloc);
+ mLDConfig->options().addZOption(option);
+ }
+ else {
+ option.setKind(mcld::ZOption::NoCombReloc);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kDefs) {
+ option.setKind(mcld::ZOption::Defs);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kExecStack) {
+ option.setKind(mcld::ZOption::ExecStack);
+ mLDConfig->options().addZOption(option);
+ }
+ else {
+ option.setKind(mcld::ZOption::NoExecStack);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kInitFirst) {
+ option.setKind(mcld::ZOption::InitFirst);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kInterPose) {
+ option.setKind(mcld::ZOption::InterPose);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kLoadFltr) {
+ option.setKind(mcld::ZOption::LoadFltr);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kMulDefs) {
+ option.setKind(mcld::ZOption::MulDefs);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kNoCopyReloc) {
+ option.setKind(mcld::ZOption::NoCopyReloc);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kNoDefaultLib) {
+ option.setKind(mcld::ZOption::NoDefaultLib);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kNoDelete) {
+ option.setKind(mcld::ZOption::NoDelete);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kNoDLOpen) {
+ option.setKind(mcld::ZOption::NoDLOpen);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kNoDump) {
+ option.setKind(mcld::ZOption::NoDump);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kRelro) {
+ option.setKind(mcld::ZOption::Relro);
+ mLDConfig->options().addZOption(option);
+ }
+ else {
+ option.setKind(mcld::ZOption::NoRelro);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kLazy) {
+ option.setKind(mcld::ZOption::Lazy);
+ mLDConfig->options().addZOption(option);
+ }
+ else {
+ option.setKind(mcld::ZOption::Now);
+ mLDConfig->options().addZOption(option);
+ }
+
+ if (pOptions & kOrigin) {
+ option.setKind(mcld::ZOption::Origin);
+ mLDConfig->options().addZOption(option);
+ }
+}
+
void LinkerConfig::addWrap(const std::string &pWrapSymbol) {
bool exist = false;
// Add wname -> __wrap_wname.
mcld::StringEntry<llvm::StringRef>* to_wrap =
- mLDInfo->scripts().renameMap().insert(pWrapSymbol, exist);
+ mLDConfig->scripts().renameMap().insert(pWrapSymbol, exist);
std::string to_wrap_str = "__wrap_" + pWrapSymbol;
to_wrap->setValue(to_wrap_str);
@@ -129,7 +290,7 @@
// Add __real_wname -> wname.
std::string from_real_str = "__real_" + pWrapSymbol;
mcld::StringEntry<llvm::StringRef>* from_real =
- mLDInfo->scripts().renameMap().insert(from_real_str, exist);
+ mLDConfig->scripts().renameMap().insert(from_real_str, exist);
from_real->setValue(pWrapSymbol);
if (exist) {
@@ -144,7 +305,7 @@
// Add pname -> pname_portable.
mcld::StringEntry<llvm::StringRef>* to_port =
- mLDInfo->scripts().renameMap().insert(pPortableSymbol, exist);
+ mLDConfig->scripts().renameMap().insert(pPortableSymbol, exist);
std::string to_port_str = pPortableSymbol + "_portable";
to_port->setValue(to_port_str);
@@ -156,7 +317,7 @@
// Add __real_pname -> pname.
std::string from_real_str = "__real_" + pPortableSymbol;
mcld::StringEntry<llvm::StringRef>* from_real =
- mLDInfo->scripts().renameMap().insert(from_real_str, exist);
+ mLDConfig->scripts().renameMap().insert(from_real_str, exist);
from_real->setValue(pPortableSymbol);
@@ -169,17 +330,7 @@
void LinkerConfig::addSearchDir(const std::string &pDirPath) {
// SearchDirs will remove the created MCLDDirectory.
- mcld::MCLDDirectory* sd = new mcld::MCLDDirectory(pDirPath);
-
- if (sd->isInSysroot()) {
- sd->setSysroot(mLDInfo->options().sysroot());
+ if (!mLDConfig->options().directories().insert(pDirPath)) {
+ mcld::warning(mcld::diag::warn_cannot_open_search_dir) << pDirPath;
}
-
- if (exists(sd->path()) && is_directory(sd->path())) {
- mLDInfo->options().directories().add(*sd);
- } else {
- mcld::warning(mcld::diag::warn_cannot_open_search_dir) << sd->name();
- }
-
- return;
}
diff --git a/lib/Support/TargetCompilerConfigs.cpp b/lib/Support/TargetCompilerConfigs.cpp
index df78637..2dcd173 100644
--- a/lib/Support/TargetCompilerConfigs.cpp
+++ b/lib/Support/TargetCompilerConfigs.cpp
@@ -16,6 +16,11 @@
#include "bcc/Support/TargetCompilerConfigs.h"
+// Get ARM version number (i.e., __ARM_ARCH__)
+#ifdef __arm__
+#include <machine/cpu-features.h>
+#endif
+
using namespace bcc;
//===----------------------------------------------------------------------===//
@@ -23,8 +28,28 @@
//===----------------------------------------------------------------------===//
#if defined(PROVIDE_ARM_CODEGEN)
-void ARMCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
- bool pEnableNEON) {
+bool ARMBaseCompilerConfig::HasThumb2() {
+#if !defined(TARGET_BUILD)
+ // Cross-compiler can always generate Thumb-2 instructions.
+ return true;
+#else // defined(TARGET_BUILD)
+# if defined(ARCH_ARM_HAVE_THUMB_SUPPORT)
+# if (__ARM_ARCH__ >= 7) || defined(__ARM_ARCH_6T2__)
+ return true;
+# else
+ // ARM prior to V6T2 doesn't support Thumb-2.
+ return false;
+# endif
+# else // !defined(ARCH_ARM_HAVE_THUMB_SUPPORT)
+ // Target that doesn't support Thumb feature won't support Thumb-2, either.
+ return false;
+# endif
+#endif
+}
+
+void
+ARMBaseCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
+ bool pInThumbMode, bool pEnableNEON) {
#if defined(ARCH_ARM_HAVE_VFP)
pAttributes.push_back("+vfp3");
# if !defined(ARCH_ARM_HAVE_VFP_D32)
@@ -32,6 +57,14 @@
# endif
#endif
+ if (pInThumbMode) {
+ if (HasThumb2()) {
+ pAttributes.push_back("+thumb2");
+ } else {
+ pAttributes.push_back("-thumb2");
+ }
+ }
+
#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
if (pEnableNEON) {
pAttributes.push_back("+neon");
@@ -48,24 +81,25 @@
return;
}
-ARMCompilerConfig::ARMCompilerConfig()
- : CompilerConfig(DEFAULT_ARM_TRIPLE_STRING) {
+ARMBaseCompilerConfig::ARMBaseCompilerConfig(const std::string &pTriple,
+ bool pInThumbMode)
+ : CompilerConfig(pTriple), mInThumbMode(pInThumbMode) {
// Enable NEON by default.
mEnableNEON = true;
std::vector<std::string> attributes;
- GetFeatureVector(attributes, /* pEnableNEON */mEnableNEON);
+ GetFeatureVector(attributes, mInThumbMode, mEnableNEON);
setFeatureString(attributes);
return;
}
-bool ARMCompilerConfig::enableNEON(bool pEnable) {
+bool ARMBaseCompilerConfig::enableNEON(bool pEnable) {
#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
if (mEnableNEON != pEnable) {
std::vector<std::string> attributes;
- GetFeatureVector(attributes, pEnable);
+ GetFeatureVector(attributes, mInThumbMode, pEnable);
setFeatureString(attributes);
mEnableNEON = pEnable;
return true;
diff --git a/lib/Support/TargetLinkerConfigs.cpp b/lib/Support/TargetLinkerConfigs.cpp
index b57e81a..38febb6 100644
--- a/lib/Support/TargetLinkerConfigs.cpp
+++ b/lib/Support/TargetLinkerConfigs.cpp
@@ -17,6 +17,8 @@
#include "bcc/Config/Config.h"
#include "bcc/Support/TargetLinkerConfigs.h"
+#include <mcld/MC/InputFactory.h>
+
using namespace bcc;
#ifdef TARGET_BUILD
@@ -34,21 +36,29 @@
ARMLinkerConfig::ARMLinkerConfig() : LinkerConfig(DEFAULT_ARM_TRIPLE_STRING) {
// set up target-dependent constraints of attributes
- getLDInfo()->attrFactory().constraint().enableWholeArchive();
- getLDInfo()->attrFactory().constraint().disableAsNeeded();
- getLDInfo()->attrFactory().constraint().setSharedSystem();
+ getLDConfig()->attribute().constraint().enableWholeArchive();
+ getLDConfig()->attribute().constraint().disableAsNeeded();
+ getLDConfig()->attribute().constraint().setSharedSystem();
// set up the predefined attributes
- getLDInfo()->attrFactory().predefined().setWholeArchive();
- getLDInfo()->attrFactory().predefined().setDynamic();
+ getLDConfig()->attribute().predefined().unsetWholeArchive();
+ getLDConfig()->attribute().predefined().setDynamic();
// set up target dependent options
- if (getLDInfo()->options().sysroot().empty()) {
- getLDInfo()->options().setSysroot(gDefaultSysroot);
+ if (getLDConfig()->options().sysroot().empty()) {
+ getLDConfig()->options().setSysroot(gDefaultSysroot);
}
- if (!getLDInfo()->options().hasDyld()) {
- getLDInfo()->options().setDyld(gDefaultDyld);
+ if (!getLDConfig()->options().hasDyld()) {
+ getLDConfig()->options().setDyld(gDefaultDyld);
+ }
+
+ // set up section map
+ if (getLDConfig()->codeGenType() != mcld::LinkerConfig::Object) {
+ bool exist = false;
+ getLDConfig()->scripts().sectionMap().append(".ARM.exidx", ".ARM.exidx", exist);
+ getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
+ getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
}
}
#endif // defined(PROVIDE_ARM_CODEGEN)
@@ -61,21 +71,21 @@
: LinkerConfig(DEFAULT_MIPS_TRIPLE_STRING) {
// set up target-dependent constraints of attibutes
- getLDInfo()->attrFactory().constraint().enableWholeArchive();
- getLDInfo()->attrFactory().constraint().disableAsNeeded();
- getLDInfo()->attrFactory().constraint().setSharedSystem();
+ getLDConfig()->attribute().constraint().enableWholeArchive();
+ getLDConfig()->attribute().constraint().disableAsNeeded();
+ getLDConfig()->attribute().constraint().setSharedSystem();
// set up the predefined attributes
- getLDInfo()->attrFactory().predefined().setWholeArchive();
- getLDInfo()->attrFactory().predefined().setDynamic();
+ getLDConfig()->attribute().predefined().unsetWholeArchive();
+ getLDConfig()->attribute().predefined().setDynamic();
// set up target dependent options
- if (getLDInfo()->options().sysroot().empty()) {
- getLDInfo()->options().setSysroot(gDefaultSysroot);
+ if (getLDConfig()->options().sysroot().empty()) {
+ getLDConfig()->options().setSysroot(gDefaultSysroot);
}
- if (!getLDInfo()->options().hasDyld()) {
- getLDInfo()->options().setDyld(gDefaultDyld);
+ if (!getLDConfig()->options().hasDyld()) {
+ getLDConfig()->options().setDyld(gDefaultDyld);
}
}
#endif // defined(PROVIDE_MIPS_CODEGEN)
@@ -87,21 +97,21 @@
X86FamilyLinkerConfigBase::X86FamilyLinkerConfigBase(const std::string& pTriple)
: LinkerConfig(pTriple) {
// set up target-dependent constraints of attibutes
- getLDInfo()->attrFactory().constraint().enableWholeArchive();
- getLDInfo()->attrFactory().constraint().disableAsNeeded();
- getLDInfo()->attrFactory().constraint().setSharedSystem();
+ getLDConfig()->attribute().constraint().enableWholeArchive();
+ getLDConfig()->attribute().constraint().disableAsNeeded();
+ getLDConfig()->attribute().constraint().setSharedSystem();
// set up the predefined attributes
- getLDInfo()->attrFactory().predefined().setWholeArchive();
- getLDInfo()->attrFactory().predefined().setDynamic();
+ getLDConfig()->attribute().predefined().unsetWholeArchive();
+ getLDConfig()->attribute().predefined().setDynamic();
// set up target dependent options
- if (getLDInfo()->options().sysroot().empty()) {
- getLDInfo()->options().setSysroot(gDefaultSysroot);
+ if (getLDConfig()->options().sysroot().empty()) {
+ getLDConfig()->options().setSysroot(gDefaultSysroot);
}
- if (!getLDInfo()->options().hasDyld()) {
- getLDInfo()->options().setDyld(gDefaultDyld);
+ if (!getLDConfig()->options().hasDyld()) {
+ getLDConfig()->options().setDyld(gDefaultDyld);
}
}
@@ -113,3 +123,29 @@
: X86FamilyLinkerConfigBase(DEFAULT_X86_64_TRIPLE_STRING) {
}
#endif // defined(PROVIDE_X86_CODEGEN)
+
+#if !defined(TARGET_BUILD)
+//===----------------------------------------------------------------------===//
+// General
+//===----------------------------------------------------------------------===//
+GeneralLinkerConfig::GeneralLinkerConfig(const std::string& pTriple)
+ : LinkerConfig(pTriple) {
+ // set up target-dependent constraints of attributes
+ getLDConfig()->attribute().constraint().enableWholeArchive();
+ getLDConfig()->attribute().constraint().disableAsNeeded();
+ getLDConfig()->attribute().constraint().setSharedSystem();
+
+ // set up the predefined attributes
+ getLDConfig()->attribute().predefined().unsetWholeArchive();
+ getLDConfig()->attribute().predefined().setDynamic();
+
+ // set up section map
+ if (llvm::Triple::arm == getLDConfig()->triple().getArch() &&
+ getLDConfig()->codeGenType() != mcld::LinkerConfig::Object) {
+ bool exist = false;
+ getLDConfig()->scripts().sectionMap().append(".ARM.exidx", ".ARM.exidx", exist);
+ getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
+ getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
+ }
+}
+#endif // defined(TARGET_BUILD)
diff --git a/tools/abcc/Main.cpp b/tools/abcc/Main.cpp
index 44ceadd..d783ca9 100644
--- a/tools/abcc/Main.cpp
+++ b/tools/abcc/Main.cpp
@@ -102,7 +102,12 @@
#endif
if (triple == NULL) {
- triple = DEFAULT_TARGET_TRIPLE_STRING;
+#ifdef DEFAULT_ARM_CODEGEN
+ // Generate Thumb instead of ARM.
+ triple = DEFAULT_THUMB_TRIPLE_STRING;
+#else
+ triple = DEFAULT_TARGET_TRIPLE_STRING;
+#endif
}
if (sysroot == NULL) {
diff --git a/tools/bcc/Android.mk b/tools/bcc/Android.mk
index 6f95eec..0799c61 100644
--- a/tools/bcc/Android.mk
+++ b/tools/bcc/Android.mk
@@ -45,7 +45,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := bcc
-LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := Main.cpp
diff --git a/tools/bcc_compat/Android.mk b/tools/bcc_compat/Android.mk
new file mode 100644
index 0000000..601ca7e
--- /dev/null
+++ b/tools/bcc_compat/Android.mk
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# Executable for host
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bcc_compat
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+LOCAL_CFLAGS := -DFORCE_ARM_CODEGEN
+
+LOCAL_SRC_FILES := \
+ main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libbcc
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../../include
+
+LOCAL_LDLIBS = -ldl
+LOCAL_SRC_FILES := Main.cpp
+
+include $(LIBBCC_HOST_BUILD_MK)
+include $(LIBBCC_GEN_CONFIG_MK)
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/bcc_compat/Main.cpp b/tools/bcc_compat/Main.cpp
new file mode 100644
index 0000000..25e7964
--- /dev/null
+++ b/tools/bcc_compat/Main.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <vector>
+
+#include <stdlib.h>
+
+#include <llvm/ADT/STLExtras.h>
+#include <llvm/ADT/SmallString.h>
+#include <llvm/Config/config.h>
+#include <llvm/Support/CommandLine.h>
+#include <llvm/Support/FileSystem.h>
+#include <llvm/Support/Path.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/system_error.h>
+
+#include <bcc/BCCContext.h>
+#include <bcc/Compiler.h>
+#include <bcc/Config/BuildInfo.h>
+#include <bcc/Config/Config.h>
+#include <bcc/ExecutionEngine/BCCRuntimeSymbolResolver.h>
+#include <bcc/ExecutionEngine/ObjectLoader.h>
+#include <bcc/ExecutionEngine/SymbolResolverProxy.h>
+#include <bcc/ExecutionEngine/SymbolResolvers.h>
+#include <bcc/Renderscript/RSCompilerDriver.h>
+#include <bcc/Script.h>
+#include <bcc/Source.h>
+#include <bcc/Support/CompilerConfig.h>
+#include <bcc/Support/Initialization.h>
+#include <bcc/Support/InputFile.h>
+#include <bcc/Support/OutputFile.h>
+#include <bcc/Support/TargetCompilerConfigs.h>
+
+using namespace bcc;
+
+//===----------------------------------------------------------------------===//
+// General Options
+//===----------------------------------------------------------------------===//
+namespace {
+
+llvm::cl::list<std::string>
+OptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
+ llvm::cl::desc("<input bitcode files>"));
+
+llvm::cl::opt<std::string>
+OptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
+ llvm::cl::value_desc("filename"));
+
+llvm::cl::opt<std::string>
+OptRuntimePath("rt-path", llvm::cl::desc("Specify the runtime library path"),
+ llvm::cl::value_desc("path"));
+
+#ifdef TARGET_BUILD
+const std::string OptTargetTriple(DEFAULT_TARGET_TRIPLE_STRING);
+#else
+llvm::cl::opt<std::string>
+OptTargetTriple("mtriple",
+ llvm::cl::desc("Specify the target triple (default: "
+ DEFAULT_TARGET_TRIPLE_STRING ")"),
+ llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
+ llvm::cl::value_desc("triple"));
+
+llvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
+ llvm::cl::desc("Alias for -mtriple"),
+ llvm::cl::aliasopt(OptTargetTriple));
+#endif
+
+//===----------------------------------------------------------------------===//
+// Compiler Options
+//===----------------------------------------------------------------------===//
+llvm::cl::opt<bool>
+OptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
+ " code"));
+
+llvm::cl::opt<char>
+OptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+ "(default: -O2)"),
+ llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('2'));
+
+llvm::cl::opt<bool>
+OptC("c", llvm::cl::desc("Compile and assemble, but do not link."));
+
+//===----------------------------------------------------------------------===//
+// Linker Options
+//===----------------------------------------------------------------------===//
+// FIXME: this option will be removed in the future when MCLinker is capable
+// of generating shared library directly from given bitcode. It only
+// takes effect when -shared is supplied.
+llvm::cl::opt<std::string>
+OptImmObjectOutput("or", llvm::cl::desc("Specify the filename for output the "
+ "intermediate relocatable when linking "
+ "the input bitcode to the shared "
+ "library"), llvm::cl::ValueRequired);
+
+llvm::cl::opt<bool>
+OptShared("shared", llvm::cl::desc("Create a shared library from input bitcode "
+ "files"));
+
+
+// Override "bcc -version" since the LLVM version information is not correct on
+// Android build.
+void BCCVersionPrinter() {
+ llvm::raw_ostream &os = llvm::outs();
+ os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
+ << " Build time: " << BuildInfo::GetBuildTime() << "\n"
+ << " Build revision: " << BuildInfo::GetBuildRev() << "\n"
+ << " Build source blob: " << BuildInfo::GetBuildSourceBlob() << "\n"
+ << " Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
+
+ os << "\n";
+
+ os << "LLVM (http://llvm.org/):\n"
+ << " Version: " << PACKAGE_VERSION << "\n";
+ return;
+}
+
+} // end anonymous namespace
+
+RSScript *PrepareRSScript(BCCContext &pContext,
+ const llvm::cl::list<std::string> &pBitcodeFiles) {
+ RSScript *result = NULL;
+
+ for (unsigned i = 0; i < pBitcodeFiles.size(); i++) {
+ const std::string &input_bitcode = pBitcodeFiles[i];
+ Source *source = Source::CreateFromFile(pContext, input_bitcode);
+ if (source == NULL) {
+ llvm::errs() << "Failed to load llvm module from file `" << input_bitcode
+ << "'!\n";
+ return NULL;
+ }
+
+ if (result != NULL) {
+ if (!result->mergeSource(*source, /* pPreserveSource */false)) {
+ llvm::errs() << "Failed to merge the llvm module `" << input_bitcode
+ << "' to compile!\n";
+ delete source;
+ return NULL;
+ }
+ } else {
+ result = new (std::nothrow) RSScript(*source);
+ if (result == NULL) {
+ llvm::errs() << "Out of memory when create script for file `"
+ << input_bitcode << "'!\n";
+ delete source;
+ return NULL;
+ }
+ }
+ }
+
+ return result;
+}
+
+static inline
+bool ConfigCompiler(RSCompilerDriver &pCompilerDriver) {
+ RSCompiler *compiler = pCompilerDriver.getCompiler();
+ CompilerConfig *config = NULL;
+
+#ifdef TARGET_BUILD
+ config = new (std::nothrow) DefaultCompilerConfig();
+#else
+ config = new (std::nothrow) CompilerConfig(OptTargetTriple);
+#endif
+ if (config == NULL) {
+ llvm::errs() << "Out of memory when create the compiler configuration!\n";
+ return false;
+ }
+
+ // Setup the config according to the value of command line option.
+ if (OptPIC) {
+ config->setRelocationModel(llvm::Reloc::PIC_);
+ }
+ switch (OptOptLevel) {
+ case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
+ case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
+ case '3': config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive); break;
+ case '2':
+ default: {
+ config->setOptimizationLevel(llvm::CodeGenOpt::Default);
+ break;
+ }
+ }
+
+ pCompilerDriver.setConfig(config);
+ Compiler::ErrorCode result = compiler->config(*config);
+
+ if (result != Compiler::kSuccess) {
+ llvm::errs() << "Failed to configure the compiler! (detail: "
+ << Compiler::GetErrorString(result) << ")\n";
+ return false;
+ }
+
+ return true;
+}
+
+#define DEFAULT_OUTPUT_PATH "/sdcard/a.out"
+static inline
+std::string DetermineOutputFilename(const std::string &pOutputPath) {
+ if (!pOutputPath.empty()) {
+ return pOutputPath;
+ }
+
+ // User doesn't specify the value to -o.
+ if (OptInputFilenames.size() > 1) {
+ llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
+ return DEFAULT_OUTPUT_PATH;
+ }
+
+ // There's only one input bitcode file.
+ const std::string &input_path = OptInputFilenames[0];
+ llvm::SmallString<200> output_path(input_path);
+
+ llvm::error_code err = llvm::sys::fs::make_absolute(output_path);
+ if (err != llvm::errc::success) {
+ llvm::errs() << "Failed to determine the absolute path of `" << input_path
+ << "'! (detail: " << err.message() << ")\n";
+ return "";
+ }
+
+ if (OptC) {
+ // -c was specified. Replace the extension to .o.
+ llvm::sys::path::replace_extension(output_path, "o");
+ } else {
+ // Use a.out under current working directory when compile executable or
+ // shared library.
+ llvm::sys::path::remove_filename(output_path);
+ llvm::sys::path::append(output_path, "a.out");
+ }
+
+ return output_path.c_str();
+}
+
+int main(int argc, char **argv) {
+ llvm::cl::SetVersionPrinter(BCCVersionPrinter);
+ llvm::cl::ParseCommandLineOptions(argc, argv);
+ init::Initialize();
+
+ if (OptRuntimePath.empty()) {
+ fprintf(stderr, "You must set \"-rt-path </path/to/libclcore.bc>\" with "
+ "this tool\n");
+ return EXIT_FAILURE;
+ }
+
+ BCCContext context;
+ RSCompilerDriver rscd;
+ Compiler compiler;
+
+ if (!ConfigCompiler(rscd)) {
+ return EXIT_FAILURE;
+ }
+
+ std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
+ if (OutputFilename.empty()) {
+ return EXIT_FAILURE;
+ }
+
+ RSScript *s = NULL;
+ s = PrepareRSScript(context, OptInputFilenames);
+ rscd.build(*s, OutputFilename.c_str(), OptRuntimePath.c_str());
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/mcld/Android.mk b/tools/mcld/Android.mk
index b8213d0..3e53c42 100644
--- a/tools/mcld/Android.mk
+++ b/tools/mcld/Android.mk
@@ -21,7 +21,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := mcld
-LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := Main.cpp
@@ -40,7 +39,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := mcld
-LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := Main.cpp
diff --git a/tools/mcld/Main.cpp b/tools/mcld/Main.cpp
index 8e20312..c87a393 100644
--- a/tools/mcld/Main.cpp
+++ b/tools/mcld/Main.cpp
@@ -189,7 +189,7 @@
#ifdef TARGET_BUILD
config = new (std::nothrow) DefaultLinkerConfig();
#else
- config = new (std::nothrow) LinkerConfig(OptTargetTriple);
+ config = new (std::nothrow) GeneralLinkerConfig(OptTargetTriple);
#endif
if (config == NULL) {
llvm::errs() << "Out of memory when create the linker configuration!\n";